1 From c8770e7ba63bb5dd8fe5f9d251275a8fa717fb78 Mon Sep 17 00:00:00 2001
2 From: Avi Kivity <avi@redhat.com>
3 Date: Thu, 11 Nov 2010 12:37:26 +0200
4 Subject: KVM: VMX: Fix host userspace gsbase corruption
6 From: Avi Kivity <avi@redhat.com>
8 commit c8770e7ba63bb5dd8fe5f9d251275a8fa717fb78 upstream.
10 We now use load_gs_index() to load gs safely; unfortunately this also
11 changes MSR_KERNEL_GS_BASE, which we managed separately. This resulted
12 in confusion and breakage running 32-bit host userspace on a 64-bit kernel.
15 - saving guest MSR_KERNEL_GS_BASE before we we reload the host's gs
16 - doing the host save/load unconditionally, instead of only when in guest
19 Things can be cleaned up further, but this is the minmal fix for now.
21 Signed-off-by: Avi Kivity <avi@redhat.com>
22 Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
23 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
26 arch/x86/kvm/vmx.c | 15 +++++++--------
27 1 file changed, 7 insertions(+), 8 deletions(-)
29 --- a/arch/x86/kvm/vmx.c
30 +++ b/arch/x86/kvm/vmx.c
31 @@ -828,10 +828,9 @@ static void vmx_save_host_state(struct k
35 - if (is_long_mode(&vmx->vcpu)) {
36 - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
37 + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
38 + if (is_long_mode(&vmx->vcpu))
39 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
42 for (i = 0; i < vmx->save_nmsrs; ++i)
43 kvm_set_shared_msr(vmx->guest_msrs[i].index,
44 @@ -846,11 +845,14 @@ static void __vmx_load_host_state(struct
46 ++vmx->vcpu.stat.host_state_reload;
47 vmx->host_state.loaded = 0;
49 + if (is_long_mode(&vmx->vcpu))
50 + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
52 if (vmx->host_state.gs_ldt_reload_needed) {
53 kvm_load_ldt(vmx->host_state.ldt_sel);
55 load_gs_index(vmx->host_state.gs_sel);
56 - wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
58 loadsegment(gs, vmx->host_state.gs_sel);
60 @@ -859,10 +861,7 @@ static void __vmx_load_host_state(struct
61 loadsegment(fs, vmx->host_state.fs_sel);
64 - if (is_long_mode(&vmx->vcpu)) {
65 - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
66 - wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
68 + wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
70 if (current_thread_info()->status & TS_USEDFPU)