diff mbox series

[SRU,Focal,1/1] KVM: x86: Set KVM_REQ_EVENT if run is canceled with req_immediate_exit set

Message ID 20210118230232.32247-2-matthew.ruffell@canonical.com
State New
Headers show
Series kvm: Windows 2k19 with Hyper-v role gets stuck on pending hypervisor requests on cascadelake based kvm hosts | expand

Commit Message

Matthew Ruffell Jan. 18, 2021, 11:02 p.m. UTC
From: Sean Christopherson <sean.j.christopherson@intel.com>

BugLink: https://bugs.launchpad.net/bugs/1911848

Re-request KVM_REQ_EVENT if vcpu_enter_guest() bails after processing
pending requests and an immediate exit was requested.  This fixes a bug
where a pending event, e.g. VMX preemption timer, is delayed and/or lost
if the exit was deferred due to something other than a higher priority
_injected_ event, e.g. due to a pending nested VM-Enter.  This bug only
affects the !injected case as kvm_x86_ops.cancel_injection() sets
KVM_REQ_EVENT to redo the injection, but that's purely serendipitous
behavior with respect to the deferred event.

Note, emulated preemption timer isn't the only event that can be
affected, it simply happens to be the only event where not re-requesting
KVM_REQ_EVENT is blatantly visible to the guest.

Fixes: f4124500c2c13 ("KVM: nVMX: Fully emulate preemption timer")
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Message-Id: <20200423022550.15113-4-sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(backported from commit 8081ad06b68a728e676d3b08e9ab70ce4039747b)
[mruffell: minor context adjustment]
Signed-off-by: Matthew Ruffell <matthew.ruffell@canonical.com>
---
 arch/x86/kvm/x86.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Stefan Bader Jan. 21, 2021, 8:51 a.m. UTC | #1
On 19.01.21 00:02, Matthew Ruffell wrote:
> From: Sean Christopherson <sean.j.christopherson@intel.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1911848
> 
> Re-request KVM_REQ_EVENT if vcpu_enter_guest() bails after processing
> pending requests and an immediate exit was requested.  This fixes a bug
> where a pending event, e.g. VMX preemption timer, is delayed and/or lost
> if the exit was deferred due to something other than a higher priority
> _injected_ event, e.g. due to a pending nested VM-Enter.  This bug only
> affects the !injected case as kvm_x86_ops.cancel_injection() sets
> KVM_REQ_EVENT to redo the injection, but that's purely serendipitous
> behavior with respect to the deferred event.
> 
> Note, emulated preemption timer isn't the only event that can be
> affected, it simply happens to be the only event where not re-requesting
> KVM_REQ_EVENT is blatantly visible to the guest.
> 
> Fixes: f4124500c2c13 ("KVM: nVMX: Fully emulate preemption timer")
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> Message-Id: <20200423022550.15113-4-sean.j.christopherson@intel.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> (backported from commit 8081ad06b68a728e676d3b08e9ab70ce4039747b)
> [mruffell: minor context adjustment]
> Signed-off-by: Matthew Ruffell <matthew.ruffell@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
> ---

The regression potential is probably covering all bases but also sounding rather
scary that way. I would say practically the change adds an exit case from
immediate re-schedule (iiuc). So regression potential would be stuck guests with
no cpu activity instead of 100% as before. Yeah, not sure that sounds better.
But at least a little more specific.

-Stefan

>  arch/x86/kvm/x86.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e519e0af028a..dddbeb3ee2c6 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -8345,6 +8345,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  	return r;
>  
>  cancel_injection:
> +	if (req_immediate_exit)
> +		kvm_make_request(KVM_REQ_EVENT, vcpu);
>  	kvm_x86_ops->cancel_injection(vcpu);
>  	if (unlikely(vcpu->arch.apic_attention))
>  		kvm_lapic_sync_from_vapic(vcpu);
>
diff mbox series

Patch

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e519e0af028a..dddbeb3ee2c6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8345,6 +8345,8 @@  static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 	return r;
 
 cancel_injection:
+	if (req_immediate_exit)
+		kvm_make_request(KVM_REQ_EVENT, vcpu);
 	kvm_x86_ops->cancel_injection(vcpu);
 	if (unlikely(vcpu->arch.apic_attention))
 		kvm_lapic_sync_from_vapic(vcpu);