KVM: VMX: Fix host userspace gsbase corruption

We now use load_gs_index() to load gs safely; unfortunately this also
changes MSR_KERNEL_GS_BASE, which we managed separately. This resulted
in confusion and breakage running 32-bit host userspace on a 64-bit kernel.

Fix by
- saving guest MSR_KERNEL_GS_BASE before we we reload the host's gs
- doing the host save/load unconditionally, instead of only when in guest
long mode

Things can be cleaned up further, but this is the minmal fix for now.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

authored by Avi Kivity and committed by Marcelo Tosatti c8770e7b 0a77fe4c

+7 -8
+7 -8
arch/x86/kvm/vmx.c
··· 821 #endif 822 823 #ifdef CONFIG_X86_64 824 - if (is_long_mode(&vmx->vcpu)) { 825 - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 826 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); 827 - } 828 #endif 829 for (i = 0; i < vmx->save_nmsrs; ++i) 830 kvm_set_shared_msr(vmx->guest_msrs[i].index, ··· 838 839 ++vmx->vcpu.stat.host_state_reload; 840 vmx->host_state.loaded = 0; 841 if (vmx->host_state.gs_ldt_reload_needed) { 842 kvm_load_ldt(vmx->host_state.ldt_sel); 843 #ifdef CONFIG_X86_64 844 load_gs_index(vmx->host_state.gs_sel); 845 - wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); 846 #else 847 loadsegment(gs, vmx->host_state.gs_sel); 848 #endif ··· 854 loadsegment(fs, vmx->host_state.fs_sel); 855 reload_tss(); 856 #ifdef CONFIG_X86_64 857 - if (is_long_mode(&vmx->vcpu)) { 858 - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); 859 - wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 860 - } 861 #endif 862 if (current_thread_info()->status & TS_USEDFPU) 863 clts();
··· 821 #endif 822 823 #ifdef CONFIG_X86_64 824 + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 825 + if (is_long_mode(&vmx->vcpu)) 826 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); 827 #endif 828 for (i = 0; i < vmx->save_nmsrs; ++i) 829 kvm_set_shared_msr(vmx->guest_msrs[i].index, ··· 839 840 ++vmx->vcpu.stat.host_state_reload; 841 vmx->host_state.loaded = 0; 842 + #ifdef CONFIG_X86_64 843 + if (is_long_mode(&vmx->vcpu)) 844 + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); 845 + #endif 846 if (vmx->host_state.gs_ldt_reload_needed) { 847 kvm_load_ldt(vmx->host_state.ldt_sel); 848 #ifdef CONFIG_X86_64 849 load_gs_index(vmx->host_state.gs_sel); 850 #else 851 loadsegment(gs, vmx->host_state.gs_sel); 852 #endif ··· 852 loadsegment(fs, vmx->host_state.fs_sel); 853 reload_tss(); 854 #ifdef CONFIG_X86_64 855 + wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 856 #endif 857 if (current_thread_info()->status & TS_USEDFPU) 858 clts();