public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* VMX: Fix long mode activation
@ 2009-02-20 17:23 Amit Shah
  2009-02-20 17:23 ` [PATCH 1/1] KVM: VMX: Update necessary state when guest enters long mode Amit Shah
  0 siblings, 1 reply; 3+ messages in thread
From: Amit Shah @ 2009-02-20 17:23 UTC (permalink / raw)
  To: avi; +Cc: kvm


This patch correctly sets the host vmx state to shadow guest state when
it enters long mode.

With this fix, we can have is_long_mode() test for EFER.LMA instead of EFER.LME
which was done in commit 3a001629eea909b2aa97f001a9db4700f15d986b but reverted
in commit 5e23049e86dd298b72e206b420513dbc3a240cd9 because it broke Windows x64
guests.

Please apply and then revert 5e23049e86dd298b72e206b420513dbc3a240cd9 or
re-cherry-pick 3a001629eea909b2aa97f001a9db4700f15d986b.

Amit

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/1] KVM: VMX: Update necessary state when guest enters long mode
  2009-02-20 17:23 VMX: Fix long mode activation Amit Shah
@ 2009-02-20 17:23 ` Amit Shah
  2009-02-24 10:26   ` Avi Kivity
  0 siblings, 1 reply; 3+ messages in thread
From: Amit Shah @ 2009-02-20 17:23 UTC (permalink / raw)
  To: avi; +Cc: kvm, Amit Shah

setup_msrs() should be called when entering long mode to save the
shadow state for the 64-bit guest state.

Using vmx_set_efer() in enter_lmode() removes some duplicated code
and also ensures we call setup_msrs(). We can safely pass the value
of shadow_efer to vmx_set_efer() as no other bits in the efer change
while enabling long mode (guest first sets EFER.LME, then sets CR0.PG
which causes a vmexit where we activate long mode).

With this fix, is_long_mode() can check for EFER.LMA set instead of
EFER.LME and 5e23049e86dd298b72e206b420513dbc3a240cd9 can be reverted.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 arch/x86/kvm/vmx.c |   54 +++++++++++++++++++++++----------------------------
 1 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index cb27ffc..48063a0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1430,6 +1430,29 @@ continue_rmode:
 	init_rmode(vcpu->kvm);
 }
 
+static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
+
+	vcpu->arch.shadow_efer = efer;
+	if (!msr)
+		return;
+	if (efer & EFER_LMA) {
+		vmcs_write32(VM_ENTRY_CONTROLS,
+			     vmcs_read32(VM_ENTRY_CONTROLS) |
+			     VM_ENTRY_IA32E_MODE);
+		msr->data = efer;
+	} else {
+		vmcs_write32(VM_ENTRY_CONTROLS,
+			     vmcs_read32(VM_ENTRY_CONTROLS) &
+			     ~VM_ENTRY_IA32E_MODE);
+
+		msr->data = efer & ~EFER_LME;
+	}
+	setup_msrs(vmx);
+}
+
 #ifdef CONFIG_X86_64
 
 static void enter_lmode(struct kvm_vcpu *vcpu)
@@ -1444,13 +1467,8 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
 			     (guest_tr_ar & ~AR_TYPE_MASK)
 			     | AR_TYPE_BUSY_64_TSS);
 	}
-
 	vcpu->arch.shadow_efer |= EFER_LMA;
-
-	find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME;
-	vmcs_write32(VM_ENTRY_CONTROLS,
-		     vmcs_read32(VM_ENTRY_CONTROLS)
-		     | VM_ENTRY_IA32E_MODE);
+	vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
 }
 
 static void exit_lmode(struct kvm_vcpu *vcpu)
@@ -1609,30 +1627,6 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 	vmcs_writel(GUEST_CR4, hw_cr4);
 }
 
-static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
-{
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
-
-	vcpu->arch.shadow_efer = efer;
-	if (!msr)
-		return;
-	if (efer & EFER_LMA) {
-		vmcs_write32(VM_ENTRY_CONTROLS,
-				     vmcs_read32(VM_ENTRY_CONTROLS) |
-				     VM_ENTRY_IA32E_MODE);
-		msr->data = efer;
-
-	} else {
-		vmcs_write32(VM_ENTRY_CONTROLS,
-				     vmcs_read32(VM_ENTRY_CONTROLS) &
-				     ~VM_ENTRY_IA32E_MODE);
-
-		msr->data = efer & ~EFER_LME;
-	}
-	setup_msrs(vmx);
-}
-
 static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
 {
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] KVM: VMX: Update necessary state when guest enters long mode
  2009-02-20 17:23 ` [PATCH 1/1] KVM: VMX: Update necessary state when guest enters long mode Amit Shah
@ 2009-02-24 10:26   ` Avi Kivity
  0 siblings, 0 replies; 3+ messages in thread
From: Avi Kivity @ 2009-02-24 10:26 UTC (permalink / raw)
  To: Amit Shah; +Cc: kvm

Amit Shah wrote:
> setup_msrs() should be called when entering long mode to save the
> shadow state for the 64-bit guest state.
>
> Using vmx_set_efer() in enter_lmode() removes some duplicated code
> and also ensures we call setup_msrs(). We can safely pass the value
> of shadow_efer to vmx_set_efer() as no other bits in the efer change
> while enabling long mode (guest first sets EFER.LME, then sets CR0.PG
> which causes a vmexit where we activate long mode).
>
> With this fix, is_long_mode() can check for EFER.LMA set instead of
> EFER.LME and 5e23049e86dd298b72e206b420513dbc3a240cd9 can be reverted.
>   

Applied, thanks.  Good catch.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-02-24 10:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-20 17:23 VMX: Fix long mode activation Amit Shah
2009-02-20 17:23 ` [PATCH 1/1] KVM: VMX: Update necessary state when guest enters long mode Amit Shah
2009-02-24 10:26   ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox