From 02e7edc0637d36d84dbbaf6f8a64a6ece18fdc55 Mon Sep 17 00:00:00 2001 From: Mingqiang Chi Date: Fri, 7 Sep 2018 14:11:08 +0800 Subject: [PATCH] hv: Replace dynamic memory allocation for I/O bitmaps -- Replace pointer with static memory for io_bitmap inside structure vm_arch. -- Refine allow_guest_pio_access/deny_guest_pio_access Tracked-On: #861 Signed-off-by: Mingqiang Chi Reviewed-by: Anthony Xu Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/pm.c | 2 +- hypervisor/arch/x86/io.c | 47 +++++++------------------- hypervisor/arch/x86/vmx.c | 4 +-- hypervisor/include/arch/x86/guest/vm.h | 11 +++--- hypervisor/include/arch/x86/ioreq.h | 3 +- 5 files changed, 25 insertions(+), 42 deletions(-) diff --git a/hypervisor/arch/x86/guest/pm.c b/hypervisor/arch/x86/guest/pm.c index e149bf99b..1062e201c 100644 --- a/hypervisor/arch/x86/guest/pm.c +++ b/hypervisor/arch/x86/guest/pm.c @@ -94,7 +94,7 @@ static inline void init_cx_port(struct vm *vm) if (cx_data->cx_reg.space_id == SPACE_SYSTEM_IO) { uint16_t port = (uint16_t)cx_data->cx_reg.address; - allow_guest_io_access(vm, port, 1U); + allow_guest_pio_access(vm, port, 1U); } } } diff --git a/hypervisor/arch/x86/io.c b/hypervisor/arch/x86/io.c index b00cf036c..ac635989e 100644 --- a/hypervisor/arch/x86/io.c +++ b/hypervisor/arch/x86/io.c @@ -391,44 +391,32 @@ static void empty_io_handler_list(struct vm *vm) void free_io_emulation_resource(struct vm *vm) { empty_io_handler_list(vm); - - /* Free I/O emulation bitmaps */ - free(vm->arch_vm.iobitmap[0]); - free(vm->arch_vm.iobitmap[1]); } -void allow_guest_io_access(struct vm *vm, uint32_t address_arg, uint32_t nbytes) +void allow_guest_pio_access(struct vm *vm, uint16_t port_address, + uint32_t nbytes) { - uint32_t address = address_arg; + uint16_t address = port_address; uint32_t *b; uint32_t i; - uint32_t a; - b = vm->arch_vm.iobitmap[0]; + b = (uint32_t *)vm->arch_vm.io_bitmap; for (i = 0U; i < nbytes; i++) { - if ((address & 0x8000U) != 0U) { - b = vm->arch_vm.iobitmap[1]; - } - a = address & 0x7fffU; - b[a >> 5U] &= ~(1U << (a & 0x1fU)); + b[address >> 5U] &= ~(1U << (address & 0x1fU)); address++; } } -static void deny_guest_io_access(struct vm *vm, uint32_t address_arg, uint32_t nbytes) +static void deny_guest_pio_access(struct vm *vm, uint16_t port_address, + uint32_t nbytes) { - uint32_t address = address_arg; + uint16_t address = port_address; uint32_t *b; uint32_t i; - uint32_t a; - b = vm->arch_vm.iobitmap[0]; + b = (uint32_t *)vm->arch_vm.io_bitmap; for (i = 0U; i < nbytes; i++) { - if ((address & 0x8000U) != 0U) { - b = vm->arch_vm.iobitmap[1]; - } - a = address & 0x7fffU; - b[a >> 5U] |= (1U << (a & 0x1fU)); + b[address >> 5U] |= (1U << (address & 0x1fU)); address++; } } @@ -456,20 +444,11 @@ static struct vm_io_handler *create_io_handler(uint32_t port, uint32_t len, void setup_io_bitmap(struct vm *vm) { - /* Allocate VM architecture state and IO bitmaps A and B */ - vm->arch_vm.iobitmap[0] = alloc_page(); - vm->arch_vm.iobitmap[1] = alloc_page(); - - ASSERT((vm->arch_vm.iobitmap[0] != NULL) && - (vm->arch_vm.iobitmap[1] != NULL), ""); - if (is_vm0(vm)) { - (void)memset(vm->arch_vm.iobitmap[0], 0x00U, CPU_PAGE_SIZE); - (void)memset(vm->arch_vm.iobitmap[1], 0x00U, CPU_PAGE_SIZE); + (void)memset(vm->arch_vm.io_bitmap, 0x00U, CPU_PAGE_SIZE * 2); } else { /* block all IO port access from Guest */ - (void)memset(vm->arch_vm.iobitmap[0], 0xFFU, CPU_PAGE_SIZE); - (void)memset(vm->arch_vm.iobitmap[1], 0xFFU, CPU_PAGE_SIZE); + (void)memset(vm->arch_vm.io_bitmap, 0xFFU, CPU_PAGE_SIZE * 2); } } @@ -485,7 +464,7 @@ void register_io_emulation_handler(struct vm *vm, struct vm_io_range *range, } if (is_vm0(vm)) { - deny_guest_io_access(vm, range->base, range->len); + deny_guest_pio_access(vm, range->base, range->len); } handler = create_io_handler(range->base, diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index aa54a3987..edb8f0195 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -1022,10 +1022,10 @@ static void init_exec_ctrl(struct vcpu *vcpu) exec_vmwrite32(VMX_CR3_TARGET_COUNT, 0U); /* Set up IO bitmap register A and B - pg 2902 24.6.4 */ - value64 = hva2hpa(vm->arch_vm.iobitmap[0]); + value64 = hva2hpa(vm->arch_vm.io_bitmap); exec_vmwrite64(VMX_IO_BITMAP_A_FULL, value64); pr_dbg("VMX_IO_BITMAP_A: 0x%016llx ", value64); - value64 = hva2hpa(vm->arch_vm.iobitmap[1]); + value64 = hva2hpa(&(vm->arch_vm.io_bitmap[CPU_PAGE_SIZE])); exec_vmwrite64(VMX_IO_BITMAP_B_FULL, value64); pr_dbg("VMX_IO_BITMAP_B: 0x%016llx ", value64); diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index c52f9441f..32a2036aa 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -86,6 +86,9 @@ enum vm_state { }; struct vm_arch { + /* I/O bitmaps A and B for this VM, MUST be 4-Kbyte aligned */ + uint8_t io_bitmap[CPU_PAGE_SIZE*2]; + uint64_t guest_init_pml4;/* Guest init pml4 */ /* EPT hierarchy for Normal World */ void *nworld_eptp; @@ -96,7 +99,6 @@ struct vm_arch { void *sworld_eptp; void *m2p; /* machine address to guest physical address */ void *tmp_pg_array; /* Page array for tmp guest paging struct */ - void *iobitmap[2];/* IO bitmap page array base address for this VM */ void *msr_bitmap; /* MSR bitmap page base address for this VM */ struct acrn_vioapic vioapic; /* Virtual IOAPIC base address */ struct acrn_vpic vpic; /* Virtual PIC */ @@ -111,7 +113,8 @@ struct vm_arch { struct vm_io_handler *io_handler; /* reference to virtual platform to come here (as needed) */ -}; +} __aligned(CPU_PAGE_SIZE); + #define CPUID_CHECK_SUBLEAF (1U << 0) #define MAX_VM_VCPUID_ENTRIES 64U @@ -127,11 +130,11 @@ struct vcpuid_entry { }; struct vm { + struct vm_arch arch_vm; /* Reference to this VM's arch information */ uint16_t vm_id; /* Virtual machine identifier */ struct vm_hw_info hw; /* Reference to this VM's HW information */ struct vm_sw_info sw; /* Reference to SW associated with this VM */ struct vm_pm_info pm; /* Reference to this VM's arch information */ - struct vm_arch arch_vm; /* Reference to this VM's arch information */ enum vm_state state; /* VM state */ struct acrn_vuart vuart; /* Virtual UART */ enum vpic_wire_mode wire_mode; @@ -170,7 +173,7 @@ struct vm { spinlock_t softirq_dev_lock; struct list_head softirq_dev_entry_list; -}; +} __aligned(CPU_PAGE_SIZE); #ifdef CONFIG_PARTITION_MODE struct vpci_vdev_array { diff --git a/hypervisor/include/arch/x86/ioreq.h b/hypervisor/include/arch/x86/ioreq.h index 23f5cc2de..4b3b88f85 100644 --- a/hypervisor/include/arch/x86/ioreq.h +++ b/hypervisor/include/arch/x86/ioreq.h @@ -112,7 +112,8 @@ struct mem_io_node { int32_t pio_instr_vmexit_handler(struct vcpu *vcpu); void setup_io_bitmap(struct vm *vm); void free_io_emulation_resource(struct vm *vm); -void allow_guest_io_access(struct vm *vm, uint32_t address_arg, uint32_t nbytes); +void allow_guest_pio_access(struct vm *vm, uint16_t port_address, + uint32_t nbytes); void register_io_emulation_handler(struct vm *vm, struct vm_io_range *range, io_read_fn_t io_read_fn_ptr, io_write_fn_t io_write_fn_ptr);