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>
This commit is contained in:
@@ -1744,18 +1744,15 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
|
|||||||
(guest_tr_ar & ~AR_TYPE_MASK)
|
(guest_tr_ar & ~AR_TYPE_MASK)
|
||||||
| AR_TYPE_BUSY_64_TSS);
|
| AR_TYPE_BUSY_64_TSS);
|
||||||
}
|
}
|
||||||
vcpu->arch.efer |= EFER_LMA;
|
vmx_set_efer(vcpu, vcpu->arch.efer | EFER_LMA);
|
||||||
vmx_set_efer(vcpu, vcpu->arch.efer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exit_lmode(struct kvm_vcpu *vcpu)
|
static void exit_lmode(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
vcpu->arch.efer &= ~EFER_LMA;
|
|
||||||
|
|
||||||
vmcs_write32(VM_ENTRY_CONTROLS,
|
vmcs_write32(VM_ENTRY_CONTROLS,
|
||||||
vmcs_read32(VM_ENTRY_CONTROLS)
|
vmcs_read32(VM_ENTRY_CONTROLS)
|
||||||
& ~VM_ENTRY_IA32E_MODE);
|
& ~VM_ENTRY_IA32E_MODE);
|
||||||
vmx_set_efer(vcpu, vcpu->arch.efer);
|
vmx_set_efer(vcpu, vcpu->arch.efer & ~EFER_LMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user