|
@@ -2365,6 +2365,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
#ifdef CONFIG_X86_64
|
|
|
int cpu = raw_smp_processor_id();
|
|
|
+ unsigned long fs_base, kernel_gs_base;
|
|
|
#endif
|
|
|
int i;
|
|
|
|
|
@@ -2380,12 +2381,20 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
|
|
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
|
|
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
- save_fsgs_for_kvm();
|
|
|
- vmx->host_state.fs_sel = current->thread.fsindex;
|
|
|
- vmx->host_state.gs_sel = current->thread.gsindex;
|
|
|
-#else
|
|
|
- savesegment(fs, vmx->host_state.fs_sel);
|
|
|
- savesegment(gs, vmx->host_state.gs_sel);
|
|
|
+ if (likely(is_64bit_mm(current->mm))) {
|
|
|
+ save_fsgs_for_kvm();
|
|
|
+ vmx->host_state.fs_sel = current->thread.fsindex;
|
|
|
+ vmx->host_state.gs_sel = current->thread.gsindex;
|
|
|
+ fs_base = current->thread.fsbase;
|
|
|
+ kernel_gs_base = current->thread.gsbase;
|
|
|
+ } else {
|
|
|
+#endif
|
|
|
+ savesegment(fs, vmx->host_state.fs_sel);
|
|
|
+ savesegment(gs, vmx->host_state.gs_sel);
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+ fs_base = read_msr(MSR_FS_BASE);
|
|
|
+ kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
|
|
|
+ }
|
|
|
#endif
|
|
|
if (!(vmx->host_state.fs_sel & 7)) {
|
|
|
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
|
|
@@ -2405,10 +2414,10 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
|
|
savesegment(ds, vmx->host_state.ds_sel);
|
|
|
savesegment(es, vmx->host_state.es_sel);
|
|
|
|
|
|
- vmcs_writel(HOST_FS_BASE, current->thread.fsbase);
|
|
|
+ vmcs_writel(HOST_FS_BASE, fs_base);
|
|
|
vmcs_writel(HOST_GS_BASE, cpu_kernelmode_gs_base(cpu));
|
|
|
|
|
|
- vmx->msr_host_kernel_gs_base = current->thread.gsbase;
|
|
|
+ vmx->msr_host_kernel_gs_base = kernel_gs_base;
|
|
|
if (is_long_mode(&vmx->vcpu))
|
|
|
wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
|
|
|
#else
|