diff options
author | Avi Kivity <avi@redhat.com> | 2010-07-06 04:30:49 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-07-06 04:41:31 -0400 |
commit | da38f43859467a8048365b9e1cce99ccbc62b6e2 (patch) | |
tree | b36e9200ded220e1e7499dad8f64c742db451088 /arch/x86 | |
parent | 815c4163b6c8ebf8152f42b0a5fd015cfdcedc78 (diff) |
KVM: VMX: Fix host MSR_KERNEL_GS_BASE corruption
enter_lmode() and exit_lmode() modify the guest's EFER.LMA before calling
vmx_set_efer(). However, the latter function depends on the value of EFER.LMA
to determine whether MSR_KERNEL_GS_BASE needs reloading, via
vmx_load_host_state(). With EFER.LMA changing under its feet, it took the
wrong choice and corrupted userspace's %gs.
This causes 32-on-64 host userspace to fault.
Fix not touching EFER.LMA; instead ask vmx_set_efer() to change it.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/vmx.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 859a01a07dbf..ee03679efe78 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1744,18 +1744,15 @@ static void enter_lmode(struct kvm_vcpu *vcpu) | |||
1744 | (guest_tr_ar & ~AR_TYPE_MASK) | 1744 | (guest_tr_ar & ~AR_TYPE_MASK) |
1745 | | AR_TYPE_BUSY_64_TSS); | 1745 | | AR_TYPE_BUSY_64_TSS); |
1746 | } | 1746 | } |
1747 | vcpu->arch.efer |= EFER_LMA; | 1747 | vmx_set_efer(vcpu, vcpu->arch.efer | EFER_LMA); |
1748 | vmx_set_efer(vcpu, vcpu->arch.efer); | ||
1749 | } | 1748 | } |
1750 | 1749 | ||
1751 | static void exit_lmode(struct kvm_vcpu *vcpu) | 1750 | static void exit_lmode(struct kvm_vcpu *vcpu) |
1752 | { | 1751 | { |
1753 | vcpu->arch.efer &= ~EFER_LMA; | ||
1754 | |||
1755 | vmcs_write32(VM_ENTRY_CONTROLS, | 1752 | vmcs_write32(VM_ENTRY_CONTROLS, |
1756 | vmcs_read32(VM_ENTRY_CONTROLS) | 1753 | vmcs_read32(VM_ENTRY_CONTROLS) |
1757 | & ~VM_ENTRY_IA32E_MODE); | 1754 | & ~VM_ENTRY_IA32E_MODE); |
1758 | vmx_set_efer(vcpu, vcpu->arch.efer); | 1755 | vmx_set_efer(vcpu, vcpu->arch.efer & ~EFER_LMA); |
1759 | } | 1756 | } |
1760 | 1757 | ||
1761 | #endif | 1758 | #endif |