From dba49b38df1fb0c6082bb35cd43574b6d5401aef Mon Sep 17 00:00:00 2001 From: Jie Deng Date: Thu, 11 Mar 2021 22:34:03 +0800 Subject: [PATCH] hv: add bitmap_clear_lock of split-lock after completing emulation Suppose the current vcpu is 0, the other vcpus (1, 2, 3) may wait on the "get_split_lock", the current vcpu need clear the ACRN_REQUEST_SPLIT_LOCK explicitly here after finishing the emulation. Otherwise, it make cause dead lock. for example: 1. Once vcpu 0 "put_split_lock", let's say vcpu 1 will "get_split_lock". 2. vcpu 1 call "vcpu_make_request" to pause vcpu 0, 2, 3. 3. vcpu 1's VCPU_EVENT_SPLIT_LOCK is still not cleared because the vcpu 0 called "vcpu_make_request" ever. 4. All vcpus will wait for VCPU_EVENT_SPLIT_LOCK in acrn_handle_pending_request. We should avoid this dead lock case. Please note: this patch is only for release 2.5 test. Tracked-On: #6051 Signed-off-by: Jie Deng --- hypervisor/arch/x86/guest/splitlock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hypervisor/arch/x86/guest/splitlock.c b/hypervisor/arch/x86/guest/splitlock.c index a3f825747..d7a62326a 100644 --- a/hypervisor/arch/x86/guest/splitlock.c +++ b/hypervisor/arch/x86/guest/splitlock.c @@ -49,6 +49,19 @@ void vcpu_complete_splitlock_emulation(struct acrn_vcpu *cur_vcpu) if (cur_vcpu->vm->hw.created_vcpus > 1U) { foreach_vcpu(i, cur_vcpu->vm, other) { if (other != cur_vcpu) { + /* + * Suppose the current vcpu is 0, the other vcpus (1, 2, 3) may wait on the + * "get_vm_lock", the current vcpu need clear the ACRN_REQUEST_SPLIT_LOCK + * explicitly here after finishing the emulation. Otherwise, it make cause + * dead lock. for example: + * 1. Once vcpu 0 "put_vm_lock", let's say vcpu 1 will "get_vm_lock". + * 2. vcpu 1 call "vcpu_make_request" to pause vcpu 0, 2, 3. + * 3. vcpu 1's VCPU_EVENT_SPLIT_LOCK is still not cleared because + * the vcpu 0 called "vcpu_make_request" ever. + * 4. All vcpus will wait for VCPU_EVENT_SPLIT_LOCK in acrn_handle_pending_request. + * We should avoid this dead lock case. + */ + bitmap_clear_lock(ACRN_REQUEST_SPLIT_LOCK, &other->arch.pending_req); signal_event(&other->events[VCPU_EVENT_SPLIT_LOCK]); } }