diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1452851..c10857d 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -920,13 +920,6 @@ static int svm_get_irq(struct kvm_vcpu *vcpu) return -1; } -static void load_host_msrs(struct kvm_vcpu *vcpu) -{ -#ifdef CONFIG_X86_64 - wrmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base); -#endif -} - static void save_host_msrs(struct kvm_vcpu *vcpu) { #ifdef CONFIG_X86_64 @@ -1798,10 +1791,26 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) "mov %%r14, %c[r14](%[svm]) \n\t" "mov %%r15, %c[r15](%[svm]) \n\t" #endif - "pop %%"R"bp" + "pop %%"R"bp \n\t" + /* Reload PDA early so ftrace can work */ + "mov %[fs], %%fs \n\t" + "mov %[gs], %%gs \n\t" +#ifdef CONFIG_X86_64 + "mov %c[gsbase](%[svm]), %%edi \n\t" + "mov %c[gsbase]+4(%[svm]), %%edx \n\t" + "mov %[msr_gs_base], %%ecx \n\t" + "xchg %%rax, %%rdi \n\t" + "wrmsr \n\t" + "xchg %%rax, %%rdi \n\t" +#endif : : [svm]"a"(svm), [vmcb]"i"(offsetof(struct vcpu_svm, vmcb_pa)), + [fs]"g"(fs_selector), [gs]"g"(gs_selector), +#ifdef CONFIG_X86_64 + [gsbase]"i"(offsetof(struct vcpu_svm, host_gs_base)), + [msr_gs_base]"i"(MSR_GS_BASE), +#endif [rbx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RBX])), [rcx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RCX])), [rdx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RDX])), @@ -1837,10 +1846,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) write_dr7(svm->host_dr7); kvm_write_cr2(svm->host_cr2); - kvm_load_fs(fs_selector); - kvm_load_gs(gs_selector); kvm_load_ldt(ldt_selector); - load_host_msrs(vcpu); reload_tss(vcpu);