mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-23 14:07:42 +00:00
HV: HV: make io_read_fn_t return true or false
This patch makes io_read_fn_t return true or false instead of void. Returning true means that the handler in HV process the request completely. Returning false means that we need to re-inject the request to DM after processing it in HV. Tracked-On: #2865 Signed-off-by: Kaige Fu <kaige.fu@intel.com>
This commit is contained in:
parent
3b2ad67788
commit
1c0d7f78d0
@ -196,7 +196,7 @@ static void dm_emulate_io_complete(struct acrn_vcpu *vcpu)
|
|||||||
* @retval -EIO The request spans multiple devices and cannot be emulated.
|
* @retval -EIO The request spans multiple devices and cannot be emulated.
|
||||||
*/
|
*/
|
||||||
static int32_t
|
static int32_t
|
||||||
hv_emulate_pio(const struct acrn_vcpu *vcpu, struct io_request *io_req)
|
hv_emulate_pio(struct acrn_vcpu *vcpu, struct io_request *io_req)
|
||||||
{
|
{
|
||||||
int32_t status = -ENODEV;
|
int32_t status = -ENODEV;
|
||||||
uint16_t port, size;
|
uint16_t port, size;
|
||||||
@ -215,6 +215,8 @@ hv_emulate_pio(const struct acrn_vcpu *vcpu, struct io_request *io_req)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
|
||||||
if (pio_req->direction == REQUEST_WRITE) {
|
if (pio_req->direction == REQUEST_WRITE) {
|
||||||
if (handler->io_write != NULL) {
|
if (handler->io_write != NULL) {
|
||||||
if (!(handler->io_write(vm, port, size, pio_req->value))) {
|
if (!(handler->io_write(vm, port, size, pio_req->value))) {
|
||||||
@ -228,11 +230,16 @@ hv_emulate_pio(const struct acrn_vcpu *vcpu, struct io_request *io_req)
|
|||||||
pr_dbg("IO write on port %04x, data %08x", port, pio_req->value);
|
pr_dbg("IO write on port %04x, data %08x", port, pio_req->value);
|
||||||
} else {
|
} else {
|
||||||
if (handler->io_read != NULL) {
|
if (handler->io_read != NULL) {
|
||||||
pio_req->value = handler->io_read(vm, port, size);
|
if (!(handler->io_read(vm, vcpu, port, size))) {
|
||||||
|
/*
|
||||||
|
* If io_read return false, it indicates that we need continue
|
||||||
|
* to emulate in DM.
|
||||||
|
*/
|
||||||
|
status = -ENODEV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pr_dbg("IO read on port %04x, data %08x", port, pio_req->value);
|
pr_dbg("IO read on port %04x, data %08x", port, pio_req->value);
|
||||||
}
|
}
|
||||||
status = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,9 +121,13 @@ static inline uint8_t get_slp_typx(uint32_t pm1_cnt)
|
|||||||
return (uint8_t)((pm1_cnt & 0x1fffU) >> BIT_SLP_TYPx);
|
return (uint8_t)((pm1_cnt & 0x1fffU) >> BIT_SLP_TYPx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pm1ab_io_read(__unused struct acrn_vm *vm, uint16_t addr, size_t width)
|
static bool pm1ab_io_read(__unused struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
|
||||||
{
|
{
|
||||||
return pio_read(addr, width);
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
|
pio_req->value = pio_read(addr, width);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
static inline void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||||
|
@ -248,12 +248,13 @@ done:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vuart_read(struct acrn_vm *vm, uint16_t offset_arg,
|
static bool vuart_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t offset_arg,
|
||||||
__unused size_t width)
|
__unused size_t width)
|
||||||
{
|
{
|
||||||
uint16_t offset = offset_arg;
|
uint16_t offset = offset_arg;
|
||||||
uint8_t iir, reg, intr_reason;
|
uint8_t iir, reg, intr_reason;
|
||||||
struct acrn_vuart *vu = vm_vuart(vm);
|
struct acrn_vuart *vu = vm_vuart(vm);
|
||||||
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
offset -= vu->base;
|
offset -= vu->base;
|
||||||
vuart_lock(vu);
|
vuart_lock(vu);
|
||||||
@ -323,8 +324,10 @@ static uint32_t vuart_read(struct acrn_vm *vm, uint16_t offset_arg,
|
|||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
vuart_toggle_intr(vu);
|
vuart_toggle_intr(vu);
|
||||||
|
pio_req->value = (uint32_t)reg;
|
||||||
vuart_unlock(vu);
|
vuart_unlock(vu);
|
||||||
return (uint32_t)reg;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vuart_register_io_handler(struct acrn_vm *vm)
|
static void vuart_register_io_handler(struct acrn_vm *vm)
|
||||||
|
@ -43,13 +43,14 @@ static void pci_cfg_clear_cache(struct pci_addr_info *pi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL
|
* @pre vm != NULL && vcpu != NULL
|
||||||
*/
|
*/
|
||||||
static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
|
static bool pci_cfgaddr_io_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t bytes)
|
||||||
{
|
{
|
||||||
uint32_t val = ~0U;
|
uint32_t val = ~0U;
|
||||||
struct acrn_vpci *vpci = &vm->vpci;
|
struct acrn_vpci *vpci = &vm->vpci;
|
||||||
struct pci_addr_info *pi = &vpci->addr_info;
|
struct pci_addr_info *pi = &vpci->addr_info;
|
||||||
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
if ((addr == (uint16_t)PCI_CONFIG_ADDR) && (bytes == 4U)) {
|
if ((addr == (uint16_t)PCI_CONFIG_ADDR) && (bytes == 4U)) {
|
||||||
val = (uint32_t)pi->cached_bdf.value;
|
val = (uint32_t)pi->cached_bdf.value;
|
||||||
@ -60,7 +61,9 @@ static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
pio_req->value = val;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,17 +99,18 @@ static inline bool vpci_is_valid_access(uint32_t offset, uint32_t bytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL
|
* @pre vm != NULL && vcpu != NULL
|
||||||
* @pre vm->vm_id < CONFIG_MAX_VM_NUM
|
* @pre vm->vm_id < CONFIG_MAX_VM_NUM
|
||||||
* @pre (get_vm_config(vm->vm_id)->type == PRE_LAUNCHED_VM) || (get_vm_config(vm->vm_id)->type == SOS_VM)
|
* @pre (get_vm_config(vm->vm_id)->type == PRE_LAUNCHED_VM) || (get_vm_config(vm->vm_id)->type == SOS_VM)
|
||||||
*/
|
*/
|
||||||
static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
|
static bool pci_cfgdata_io_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t bytes)
|
||||||
{
|
{
|
||||||
struct acrn_vpci *vpci = &vm->vpci;
|
struct acrn_vpci *vpci = &vm->vpci;
|
||||||
struct pci_addr_info *pi = &vpci->addr_info;
|
struct pci_addr_info *pi = &vpci->addr_info;
|
||||||
uint16_t offset = addr - PCI_CONFIG_DATA;
|
uint16_t offset = addr - PCI_CONFIG_DATA;
|
||||||
uint32_t val = ~0U;
|
uint32_t val = ~0U;
|
||||||
struct acrn_vm_config *vm_config;
|
struct acrn_vm_config *vm_config;
|
||||||
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
if (pi->cached_enable) {
|
if (pi->cached_enable) {
|
||||||
if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) {
|
if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) {
|
||||||
@ -129,7 +133,9 @@ static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t by
|
|||||||
pci_cfg_clear_cache(pi);
|
pci_cfg_clear_cache(pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
pio_req->value = val;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -728,15 +728,16 @@ static int32_t vpic_master_handler(struct acrn_vm *vm, bool in, uint16_t port,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vpic_master_io_read(struct acrn_vm *vm, uint16_t addr, size_t width)
|
static bool vpic_master_io_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
|
||||||
{
|
{
|
||||||
uint32_t val = 0U;
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
if (vpic_master_handler(vm, true, addr, width, &val) < 0) {
|
if (vpic_master_handler(vm, true, addr, width, &pio_req->value) < 0) {
|
||||||
pr_err("pic master read port 0x%x width=%d failed\n",
|
pr_err("pic master read port 0x%x width=%d failed\n",
|
||||||
addr, width);
|
addr, width);
|
||||||
}
|
}
|
||||||
return val;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vpic_master_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
static bool vpic_master_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
||||||
@ -773,15 +774,15 @@ static int32_t vpic_slave_handler(struct acrn_vm *vm, bool in, uint16_t port,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vpic_slave_io_read(struct acrn_vm *vm, uint16_t addr, size_t width)
|
static bool vpic_slave_io_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
|
||||||
{
|
{
|
||||||
uint32_t val = 0U;
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
if (vpic_slave_handler(vm, true, addr, width, &val) < 0) {
|
if (vpic_slave_handler(vm, true, addr, width, &pio_req->value) < 0) {
|
||||||
pr_err("pic slave read port 0x%x width=%d failed\n",
|
pr_err("pic slave read port 0x%x width=%d failed\n",
|
||||||
addr, width);
|
addr, width);
|
||||||
}
|
}
|
||||||
return val;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vpic_slave_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
static bool vpic_slave_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
||||||
@ -843,14 +844,15 @@ static int32_t vpic_elc_handler(struct acrn_vm *vm, bool in, uint16_t port, size
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vpic_elc_io_read(struct acrn_vm *vm, uint16_t addr, size_t width)
|
static bool vpic_elc_io_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
|
||||||
{
|
{
|
||||||
uint32_t val = 0U;
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
if (vpic_elc_handler(vm, true, addr, width, &val) < 0) {
|
if (vpic_elc_handler(vm, true, addr, width, &pio_req->value) < 0) {
|
||||||
pr_err("pic elc read port 0x%x width=%d failed", addr, width);
|
pr_err("pic elc read port 0x%x width=%d failed", addr, width);
|
||||||
}
|
}
|
||||||
return val;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vpic_elc_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
static bool vpic_elc_io_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
||||||
|
@ -43,19 +43,20 @@ static uint8_t cmos_get_reg_val(uint8_t addr)
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vrtc_read(struct acrn_vm *vm, uint16_t addr, __unused size_t width)
|
static bool vrtc_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t addr, __unused size_t width)
|
||||||
{
|
{
|
||||||
uint8_t reg;
|
|
||||||
uint8_t offset;
|
uint8_t offset;
|
||||||
|
struct pio_request *pio_req = &vcpu->req.reqs.pio;
|
||||||
|
|
||||||
offset = vm->vrtc_offset;
|
offset = vm->vrtc_offset;
|
||||||
|
|
||||||
if (addr == CMOS_ADDR_PORT) {
|
if (addr == CMOS_ADDR_PORT) {
|
||||||
return vm->vrtc_offset;
|
pio_req->value = vm->vrtc_offset;
|
||||||
|
} else {
|
||||||
|
pio_req->value = cmos_get_reg_val(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = cmos_get_reg_val(offset);
|
return true;
|
||||||
return reg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vrtc_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
static bool vrtc_write(struct acrn_vm *vm, uint16_t addr, size_t width,
|
||||||
|
@ -49,7 +49,7 @@ struct acrn_vm;
|
|||||||
struct acrn_vcpu;
|
struct acrn_vcpu;
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
uint32_t (*io_read_fn_t)(struct acrn_vm *vm, uint16_t port, size_t size);
|
bool (*io_read_fn_t)(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t port, size_t size);
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
bool (*io_write_fn_t)(struct acrn_vm *vm, uint16_t port, size_t size, uint32_t val);
|
bool (*io_write_fn_t)(struct acrn_vm *vm, uint16_t port, size_t size, uint32_t val);
|
||||||
|
Loading…
Reference in New Issue
Block a user