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 <zide.chen@intel.com> Reviewed-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
2c581751de
commit
8b4f395683
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue