diff --git a/hypervisor/arch/x86/guest/io_emul.c b/hypervisor/arch/x86/guest/io_emul.c index abfcd2b21..500e230b5 100644 --- a/hypervisor/arch/x86/guest/io_emul.c +++ b/hypervisor/arch/x86/guest/io_emul.c @@ -217,7 +217,13 @@ hv_emulate_pio(const struct acrn_vcpu *vcpu, struct io_request *io_req) if (pio_req->direction == REQUEST_WRITE) { if (handler->io_write != NULL) { - handler->io_write(vm, port, size, pio_req->value); + if (!(handler->io_write(vm, port, size, pio_req->value))) { + /* + * If io_write return false, it indicates that we need continue + * to emulate in DM. + */ + status = -ENODEV; + } } pr_dbg("IO write on port %04x, data %08x", port, pio_req->value); } else { diff --git a/hypervisor/arch/x86/guest/pm.c b/hypervisor/arch/x86/guest/pm.c index 9a0c30959..96991459f 100644 --- a/hypervisor/arch/x86/guest/pm.c +++ b/hypervisor/arch/x86/guest/pm.c @@ -142,7 +142,7 @@ static inline void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t resume_vm_from_s3(vm, guest_wakeup_vec32); /* jump back to vm */ } -static void pm1ab_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, uint32_t v) +static bool pm1ab_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, uint32_t v) { static uint32_t pm1a_cnt_ready = 0U; bool to_write = true; @@ -179,6 +179,8 @@ static void pm1ab_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, uint if (to_write) { pio_write(v, addr, width); } + + return true; } static void register_gas_io_handler(struct acrn_vm *vm, uint32_t pio_idx, const struct acpi_generic_address *gas) diff --git a/hypervisor/debug/vuart.c b/hypervisor/debug/vuart.c index 0350c21e9..c39307976 100644 --- a/hypervisor/debug/vuart.c +++ b/hypervisor/debug/vuart.c @@ -161,7 +161,7 @@ static void vuart_toggle_intr(const struct acrn_vuart *vu) vioapic_set_irqline_lock(vu->vm, vuart_com_irq, operation); } -static void vuart_write(struct acrn_vm *vm, uint16_t offset_arg, +static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg, __unused size_t width, uint32_t value) { uint16_t offset = offset_arg; @@ -244,6 +244,8 @@ static void vuart_write(struct acrn_vm *vm, uint16_t offset_arg, done: vuart_toggle_intr(vu); vuart_unlock(vu); + + return true; } static uint32_t vuart_read(struct acrn_vm *vm, uint16_t offset_arg, diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index 97966b934..bbf81490d 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -66,7 +66,7 @@ static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t by /** * @pre vm != NULL */ -static void pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) +static bool pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) { struct acrn_vpci *vpci = &vm->vpci; struct pci_addr_info *pi = &vpci->addr_info; @@ -76,6 +76,8 @@ static void pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes pi->cached_reg = val & PCI_REGMAX; pi->cached_enable = ((val & PCI_CFG_ENABLE) == PCI_CFG_ENABLE); } + + return true; } static inline bool vpci_is_valid_access_offset(uint32_t offset, uint32_t bytes) @@ -135,7 +137,7 @@ static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t by * @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) */ -static void pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) +static bool pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) { struct acrn_vpci *vpci = &vm->vpci; struct pci_addr_info *pi = &vpci->addr_info; @@ -163,6 +165,8 @@ static void pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes } pci_cfg_clear_cache(pi); } + + return true; } /** diff --git a/hypervisor/dm/vpic.c b/hypervisor/dm/vpic.c index 6dd825b66..b77359705 100644 --- a/hypervisor/dm/vpic.c +++ b/hypervisor/dm/vpic.c @@ -739,7 +739,7 @@ static uint32_t vpic_master_io_read(struct acrn_vm *vm, uint16_t addr, size_t wi return val; } -static void 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, uint32_t v) { uint32_t val = v; @@ -748,6 +748,8 @@ static void vpic_master_io_write(struct acrn_vm *vm, uint16_t addr, size_t width pr_err("%s: write port 0x%x width=%d value 0x%x failed\n", __func__, addr, width, val); } + + return true; } static int32_t vpic_slave_handler(struct acrn_vm *vm, bool in, uint16_t port, @@ -782,7 +784,7 @@ static uint32_t vpic_slave_io_read(struct acrn_vm *vm, uint16_t addr, size_t wid return val; } -static void 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, uint32_t v) { uint32_t val = v; @@ -791,6 +793,8 @@ static void vpic_slave_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, pr_err("%s: write port 0x%x width=%d value 0x%x failed\n", __func__, addr, width, val); } + + return true; } static int32_t vpic_elc_handler(struct acrn_vm *vm, bool in, uint16_t port, size_t bytes, @@ -849,7 +853,7 @@ static uint32_t vpic_elc_io_read(struct acrn_vm *vm, uint16_t addr, size_t width return val; } -static void 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, uint32_t v) { uint32_t val = v; @@ -858,6 +862,8 @@ static void vpic_elc_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, pr_err("%s: write port 0x%x width=%d value 0x%x failed\n", __func__, addr, width, val); } + + return true; } static void vpic_register_io_handler(struct acrn_vm *vm) diff --git a/hypervisor/dm/vrtc.c b/hypervisor/dm/vrtc.c index 25b0da1bb..7e3d04598 100644 --- a/hypervisor/dm/vrtc.c +++ b/hypervisor/dm/vrtc.c @@ -58,16 +58,14 @@ static uint32_t vrtc_read(struct acrn_vm *vm, uint16_t addr, __unused size_t wid return reg; } -static void 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, uint32_t value) { - - if (width != 1U) - return; - - if (addr == CMOS_ADDR_PORT) { + if ((width == 1U) && (addr == CMOS_ADDR_PORT)) { vm->vrtc_offset = value & 0x7FU; } + + return true; } void vrtc_init(struct acrn_vm *vm) diff --git a/hypervisor/include/arch/x86/io_req.h b/hypervisor/include/arch/x86/io_req.h index 986c729ae..9b5499758 100644 --- a/hypervisor/include/arch/x86/io_req.h +++ b/hypervisor/include/arch/x86/io_req.h @@ -52,7 +52,7 @@ typedef uint32_t (*io_read_fn_t)(struct acrn_vm *vm, uint16_t port, size_t size); typedef -void (*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); /** * @brief Describes a single IO handler description entry.