Re: [BUG] kvm crashes in 2.6.28-rc6-00007-ged31348

From: Avi Kivity
Date: Thu Dec 04 2008 - 10:36:54 EST


Avi Kivity wrote:
Steven Rostedt wrote:
The following must be available without recursion for the function
tracer to work:

local_irq_save/restore
smp_processor_id
preempt_enable/disable_notrace
atomic_inc/dec

In arch/x86/kvm/svm.c, function svm_vcpu_run(), everything between the vmrun instruction and the call to load_host_msrs() is executed without a live pda, so no smp_processor_id(). Could easily be fixed by rearranging things.



Luis, please try the attached patch.


--
error compiling committee.c: too many arguments to function

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);