hv: Support concurrent split-lock emulation on SMP.
For a SMP guest, split-lock check may happen on multiple vCPUs simultaneously. In this case, one vCPU at most can be allowed running in the split-lock emulation window. And if the vCPU is doing the emulation, it should never be blocked in the hypervisor, it should go back to the guest to execute the lock instruction immediately and trap back to the hypervisor with #DB to complete the split-lock emulation. Tracked-On: #5605 Signed-off-by: Jie Deng <jie.deng@intel.com>
This commit is contained in:
parent
0b18389d95
commit
6852438e3a
|
@ -492,6 +492,8 @@ static void vcpu_kick_splitlock_emulation(struct acrn_vcpu *cur_vcpu)
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
if (cur_vcpu->vm->hw.created_vcpus > 1U) {
|
if (cur_vcpu->vm->hw.created_vcpus > 1U) {
|
||||||
|
get_vm_lock(cur_vcpu->vm);
|
||||||
|
|
||||||
foreach_vcpu(i, cur_vcpu->vm, other) {
|
foreach_vcpu(i, cur_vcpu->vm, other) {
|
||||||
if (other != cur_vcpu) {
|
if (other != cur_vcpu) {
|
||||||
vcpu_make_request(other, ACRN_REQUEST_SPLIT_LOCK);
|
vcpu_make_request(other, ACRN_REQUEST_SPLIT_LOCK);
|
||||||
|
@ -508,9 +510,24 @@ static void vcpu_complete_splitlock_emulation(struct acrn_vcpu *cur_vcpu)
|
||||||
if (cur_vcpu->vm->hw.created_vcpus > 1U) {
|
if (cur_vcpu->vm->hw.created_vcpus > 1U) {
|
||||||
foreach_vcpu(i, cur_vcpu->vm, other) {
|
foreach_vcpu(i, cur_vcpu->vm, other) {
|
||||||
if (other != cur_vcpu) {
|
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]);
|
signal_event(&other->events[VCPU_EVENT_SPLIT_LOCK]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
put_vm_lock(cur_vcpu->vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue