[v2] X86/VMX: Disable VMX preemption timer if MWAIT is not intercepted
diff mbox

Message ID 1523354922-17955-1-git-send-email-karahmed@amazon.de
State New
Headers show

Commit Message

KarimAllah Ahmed April 10, 2018, 10:08 a.m. UTC
The VMX-preemption timer is used by KVM as a way to set deadlines for the
guest (i.e. timer emulation). That was safe till very recently when
capability KVM_X86_DISABLE_EXITS_MWAIT to disable intercepting MWAIT was
introduced. According to Intel SDM 25.5.1:

"""
The VMX-preemption timer operates in the C-states C0, C1, and C2; it also
operates in the shutdown and wait-for-SIPI states. If the timer counts down
to zero in any state other than the wait-for SIPI state, the logical
processor transitions to the C0 C-state and causes a VM exit; the timer
does not cause a VM exit if it counts down to zero in the wait-for-SIPI
state. The timer is not decremented in C-states deeper than C2.
"""

Now once the guest issues the MWAIT with a c-state deeper than
C2 the preemption timer will never wake it up again since it stopped
ticking! Usually this is compensated by other activities in the system that
would wake the core from the deep C-state (and cause a VMExit). For
example, if the host itself is ticking or it received interrupts, etc!

So disable the VMX-preemption timer is MWAIT is exposed to the guest!

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: x86@kernel.org
Cc: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
---
v1 -> v2:
- Drop everything .. just return -EOPNOTSUPP (pbonzini@) :D
---
 arch/x86/kvm/vmx.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Paolo Bonzini April 10, 2018, 11:07 a.m. UTC | #1
On 10/04/2018 12:08, KarimAllah Ahmed wrote:
> @@ -11908,6 +11908,9 @@ static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)
>  	u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
>  	u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
>  
> +	if (kvm_pause_in_guest(vcpu->kvm))
> +		return -EOPNOTSUPP;
> +

This is still doing a relatively expensive kvm_read_l1_tsc, so move it
even further up. :)

Paolo
KarimAllah Ahmed April 10, 2018, 12:16 p.m. UTC | #2
On Tue, 2018-04-10 at 13:07 +0200, Paolo Bonzini wrote:
> On 10/04/2018 12:08, KarimAllah Ahmed wrote:

> > 

> > @@ -11908,6 +11908,9 @@ static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)

> >  	u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl);

> >  	u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;

> >  

> > +	if (kvm_pause_in_guest(vcpu->kvm))

> > +		return -EOPNOTSUPP;

> > +

> 

> This is still doing a relatively expensive kvm_read_l1_tsc, so move it

> even further up. :)


hehe .. done in v3 :)

> 

> Paolo

> 

Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B

Patch
diff mbox

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d2e54e7..d99008b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -11908,6 +11908,9 @@  static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)
 	u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
 	u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
 
+	if (kvm_pause_in_guest(vcpu->kvm))
+		return -EOPNOTSUPP;
+
 	/* Convert to host delta tsc if tsc scaling is enabled */
 	if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio &&
 			u64_shl_div_u64(delta_tsc,