From 8b4f395683b023383de12eda290c0e7a5bec9459 Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Fri, 9 Nov 2018 14:06:01 -0800 Subject: [PATCH] hv: PIO emulation handler is attached to I/O port number only An I/O handler is not linked to the I/O access size, so in searching for the registered I/O handler, don't need to check the I/O request's access size. In struct vm_io_handler_desc, change fields addr and len to port_start and port_end respectively to adapt to this change. Tracked-On: #1815 Signed-off-by: Zide Chen Reviewed-by: Li, Fei1 Acked-by: Eddie Dong Acked-by: Anthony Xu --- hypervisor/arch/x86/io.c | 43 ++++++++++++----------------- hypervisor/include/arch/x86/ioreq.h | 8 +++--- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/hypervisor/arch/x86/io.c b/hypervisor/arch/x86/io.c index 732afd782..0620db0b6 100644 --- a/hypervisor/arch/x86/io.c +++ b/hypervisor/arch/x86/io.c @@ -207,33 +207,24 @@ hv_emulate_pio(const struct acrn_vcpu *vcpu, struct io_request *io_req) for (idx = 0U; idx < EMUL_PIO_IDX_MAX; idx++) { handler = &(vm->arch_vm.emul_pio[idx]); - if (handler->len == 0U) { - continue; - } - uint16_t base = handler->addr; - uint16_t end = base + (uint16_t)handler->len; - if ((port >= end) || (port + size <= base)) { + if ((port < handler->port_start) || (port >= handler->port_end)) { continue; - } else if (!((port >= base) && ((port + size) <= end))) { - pr_fatal("Err:IO, port 0x%04x, size=%hu spans devices", port, size); - status = -EIO; - break; - } else { - if (pio_req->direction == REQUEST_WRITE) { - if (handler->io_write) { - handler->io_write(vm, port, size, pio_req->value & mask); - } - pr_dbg("IO write on port %04x, data %08x", port, pio_req->value & mask); - } else { - if (handler->io_read) { - pio_req->value = handler->io_read(vm, port, size); - } - pr_dbg("IO read on port %04x, data %08x", port, pio_req->value); - } - status = 0; - break; } + + if (pio_req->direction == REQUEST_WRITE) { + if (handler->io_write) { + handler->io_write(vm, port, size, pio_req->value & mask); + } + pr_dbg("IO write on port %04x, data %08x", port, pio_req->value & mask); + } else { + if (handler->io_read) { + pio_req->value = handler->io_read(vm, port, size); + } + pr_dbg("IO read on port %04x, data %08x", port, pio_req->value); + } + status = 0; + break; } return status; @@ -466,8 +457,8 @@ void register_io_emulation_handler(struct acrn_vm *vm, uint32_t pio_idx, if (is_vm0(vm)) { deny_guest_pio_access(vm, range->base, range->len); } - vm->arch_vm.emul_pio[pio_idx].addr = range->base; - vm->arch_vm.emul_pio[pio_idx].len = range->len; + vm->arch_vm.emul_pio[pio_idx].port_start = range->base; + vm->arch_vm.emul_pio[pio_idx].port_end = range->base + range->len; vm->arch_vm.emul_pio[pio_idx].io_read = io_read_fn_ptr; vm->arch_vm.emul_pio[pio_idx].io_write = io_write_fn_ptr; } diff --git a/hypervisor/include/arch/x86/ioreq.h b/hypervisor/include/arch/x86/ioreq.h index ce151a817..dd1328987 100644 --- a/hypervisor/include/arch/x86/ioreq.h +++ b/hypervisor/include/arch/x86/ioreq.h @@ -63,14 +63,14 @@ void (*io_write_fn_t)(struct acrn_vm *vm, uint16_t port, size_t size, uint32_t v struct vm_io_handler_desc { /** - * @brief The base address of the IO range for this description. + * @brief The base port number of the IO range for this description. */ - uint16_t addr; + uint16_t port_start; /** - * @brief The number of bytes covered by this description. + * @brief The last port number of the IO range for this description (non-inclusive). */ - size_t len; + uint16_t port_end; /** * @brief A pointer to the "read" function.