From 9d26dab6d672eca3eec7a2800ea91e2973ebc0b2 Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Thu, 31 Oct 2019 08:11:25 +0800 Subject: [PATCH] hv: mmio: add a lock to protect mmio_node access After adding PCI BAR remap support, mmio_node may unregister when there's others access it. This patch add a lock to protect mmio_node access. Tracked-On: #3475 Signed-off-by: Li, Fei1 --- hypervisor/arch/x86/guest/vm.c | 1 + hypervisor/dm/io_req.c | 9 ++++++++- hypervisor/include/arch/x86/guest/vm.h | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index b26f2e2a6..65ed18226 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -484,6 +484,7 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_ prepare_epc_vm_memmap(vm); spinlock_init(&vm->vm_lock); + spinlock_init(&vm->emul_mmio_lock); vm->arch_vm.vlapic_state = VM_VLAPIC_XAPIC; vm->intr_inject_delay_delta = 0UL; diff --git a/hypervisor/dm/io_req.c b/hypervisor/dm/io_req.c index b75435d10..df7966097 100644 --- a/hypervisor/dm/io_req.c +++ b/hypervisor/dm/io_req.c @@ -486,6 +486,7 @@ hv_emulate_mmio(struct acrn_vcpu *vcpu, struct io_request *io_req) address = mmio_req->address; size = mmio_req->size; + spinlock_obtain(&vcpu->vm->emul_mmio_lock); for (idx = 0U; idx <= vcpu->vm->max_emul_mmio_regions; idx++) { mmio_handler = &(vcpu->vm->emul_mmio[idx]); if (mmio_handler->read_write != NULL) { @@ -510,6 +511,7 @@ hv_emulate_mmio(struct acrn_vcpu *vcpu, struct io_request *io_req) if ((status == -ENODEV) && (read_write != NULL)) { status = read_write(io_req, handler_private_data); } + spinlock_release(&vcpu->vm->emul_mmio_lock); return status; } @@ -687,6 +689,7 @@ void register_mmio_emulation_handler(struct acrn_vm *vm, /* Ensure both a read/write handler and range check function exist */ if ((read_write != NULL) && (end > start)) { + spinlock_obtain(&vm->emul_mmio_lock); mmio_node = find_free_mmio_node(vm); if (mmio_node != NULL) { /* Fill in information for this node */ @@ -695,6 +698,7 @@ void register_mmio_emulation_handler(struct acrn_vm *vm, mmio_node->range_start = start; mmio_node->range_end = end; } + spinlock_release(&vm->emul_mmio_lock); } } @@ -713,9 +717,12 @@ void register_mmio_emulation_handler(struct acrn_vm *vm, void unregister_mmio_emulation_handler(struct acrn_vm *vm, uint64_t start, uint64_t end) { - struct mem_io_node *mmio_node = find_match_mmio_node(vm, start, end); + struct mem_io_node *mmio_node; + spinlock_obtain(&vm->emul_mmio_lock); + mmio_node = find_match_mmio_node(vm, start, end); if (mmio_node != NULL) { (void)memset(mmio_node, 0U, sizeof(struct mem_io_node)); } + spinlock_release(&vm->emul_mmio_lock); } diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index f422a48d4..5201db0df 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -123,8 +123,9 @@ struct acrn_vm { struct acrn_vuart vuart[MAX_VUART_NUM_PER_VM]; /* Virtual UART */ enum vpic_wire_mode wire_mode; struct iommu_domain *iommu; /* iommu domain of this VM */ - spinlock_t vm_lock; /* Spin-lock used to protect VM modifications */ + spinlock_t vm_lock; /* Spin-lock used to protect vlapic_state modifications for a VM */ + spinlock_t emul_mmio_lock; /* Used to protect emulation mmio_node concurrent access for a VM */ uint16_t max_emul_mmio_regions; /* max index of the emulated mmio_region */ struct mem_io_node emul_mmio[CONFIG_MAX_EMULATED_MMIO_REGIONS];