From 05460f151a6091ac65aabe399c39bc00db23d92e Mon Sep 17 00:00:00 2001 From: Yifan Liu Date: Thu, 21 Apr 2022 07:07:57 +0000 Subject: [PATCH] hv: Serialize WBINVD using wbinvd_lock As mentioned in previous patch, wbinvd utilizes the vcpu_make_request and signal_event call pair to stall other vcpus. Due to the fact that these two calls are not thread-safe, we need to avoid concurrent call to this API pair. This patch adds wbinvd lock to serialize wbinvd emulation. Tracked-On: #7887 Signed-off-by: Yifan Liu Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vmexit.c | 2 ++ hypervisor/include/arch/x86/asm/guest/vm.h | 1 + 2 files changed, 3 insertions(+) diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index ca4bdbf2a..fad807ba8 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -438,6 +438,7 @@ static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu) if (is_rt_vm(vcpu->vm)) { walk_ept_table(vcpu->vm, ept_flush_leaf_page); } else { + spinlock_obtain(&vcpu->vm->wbinvd_lock); /* Pause other vcpus and let them wait for the wbinvd completion */ foreach_vcpu(i, vcpu->vm, other) { if (other != vcpu) { @@ -452,6 +453,7 @@ static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu) signal_event(&other->events[VCPU_EVENT_SYNC_WBINVD]); } } + spinlock_release(&vcpu->vm->wbinvd_lock); } } diff --git a/hypervisor/include/arch/x86/asm/guest/vm.h b/hypervisor/include/arch/x86/asm/guest/vm.h index c05b9b212..d06300600 100644 --- a/hypervisor/include/arch/x86/asm/guest/vm.h +++ b/hypervisor/include/arch/x86/asm/guest/vm.h @@ -149,6 +149,7 @@ struct acrn_vm { * the initialization depends on the clear BSS section */ spinlock_t vm_state_lock; + spinlock_t wbinvd_lock; /* Spin-lock used to serialize wbinvd emulation */ spinlock_t vlapic_mode_lock; /* Spin-lock used to protect vlapic_mode modifications for a VM */ spinlock_t ept_lock; /* Spin-lock used to protect ept add/modify/remove for a VM */ spinlock_t emul_mmio_lock; /* Used to protect emulation mmio_node concurrent access for a VM */