Peter Zijlstra <peterz@xxxxxxxxxxxxx> writes: > On Tue, Jun 11, 2019 at 10:20:03PM +0100, Dmitry Safonov wrote: >> KVM support may be compiled as dynamic module, which triggers the >> following splat on modprobe: >> >> KVM: vmx: using Hyper-V Enlightened VMCS >> BUG: using smp_processor_id() in preemptible [00000000] code: modprobe/466 caller is debug_smp_processor_id+0x17/0x19 >> CPU: 0 PID: 466 Comm: modprobe Kdump: loaded Not tainted 4.19.43 #1 >> Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090007 06/02/2017 >> Call Trace: >> dump_stack+0x61/0x7e >> check_preemption_disabled+0xd4/0xe6 >> debug_smp_processor_id+0x17/0x19 >> set_hv_tscchange_cb+0x1b/0x89 >> kvm_arch_init+0x14a/0x163 [kvm] >> kvm_init+0x30/0x259 [kvm] >> vmx_init+0xed/0x3db [kvm_intel] >> do_one_initcall+0x89/0x1bc >> do_init_module+0x5f/0x207 >> load_module+0x1b34/0x209b >> __ia32_sys_init_module+0x17/0x19 >> do_fast_syscall_32+0x121/0x1fa >> entry_SYSENTER_compat+0x7f/0x91 >> >> The easiest solution seems to be disabling preemption while setting up >> reenlightment MSRs. While at it, fix hv_cpu_*() callbacks. >> >> Fixes: 93286261de1b4 ("x86/hyperv: Reenlightenment notifications >> support") >> >> Cc: Andy Lutomirski <luto@xxxxxxxxxx> >> Cc: Borislav Petkov <bp@xxxxxxxxx> >> Cc: Cathy Avery <cavery@xxxxxxxxxx> >> Cc: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx> >> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> >> Cc: Ingo Molnar <mingo@xxxxxxxxxx> >> Cc: "K. Y. Srinivasan" <kys@xxxxxxxxxxxxx> >> Cc: "Michael Kelley (EOSG)" <Michael.H.Kelley@xxxxxxxxxxxxx> >> Cc: Mohammed Gamal <mmorsy@xxxxxxxxxx> >> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> >> Cc: Radim Krčmář <rkrcmar@xxxxxxxxxx> >> Cc: Roman Kagan <rkagan@xxxxxxxxxxxxx> >> Cc: Sasha Levin <sashal@xxxxxxxxxx> >> Cc: Stephen Hemminger <sthemmin@xxxxxxxxxxxxx> >> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> >> Cc: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> >> >> Cc: devel@xxxxxxxxxxxxxxxxxxxxxx >> Cc: kvm@xxxxxxxxxxxxxxx >> Cc: linux-hyperv@xxxxxxxxxxxxxxx >> Cc: x86@xxxxxxxxxx >> Reported-by: Prasanna Panchamukhi <panchamukhi@xxxxxxxxxx> >> Signed-off-by: Dmitry Safonov <dima@xxxxxxxxxx> >> --- >> arch/x86/hyperv/hv_init.c | 9 ++++++--- >> 1 file changed, 6 insertions(+), 3 deletions(-) >> >> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c >> index 1608050e9df9..0bdd79ecbff8 100644 >> --- a/arch/x86/hyperv/hv_init.c >> +++ b/arch/x86/hyperv/hv_init.c >> @@ -91,7 +91,7 @@ EXPORT_SYMBOL_GPL(hv_max_vp_index); >> static int hv_cpu_init(unsigned int cpu) >> { >> u64 msr_vp_index; >> - struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; >> + struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu]; >> void **input_arg; >> struct page *pg; >> >> @@ -103,7 +103,7 @@ static int hv_cpu_init(unsigned int cpu) >> >> hv_get_vp_index(msr_vp_index); >> >> - hv_vp_index[smp_processor_id()] = msr_vp_index; >> + hv_vp_index[cpu] = msr_vp_index; >> >> if (msr_vp_index > hv_max_vp_index) >> hv_max_vp_index = msr_vp_index; >> @@ -182,7 +182,6 @@ void set_hv_tscchange_cb(void (*cb)(void)) >> struct hv_reenlightenment_control re_ctrl = { >> .vector = HYPERV_REENLIGHTENMENT_VECTOR, >> .enabled = 1, >> - .target_vp = hv_vp_index[smp_processor_id()] >> }; >> struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1}; >> >> @@ -196,7 +195,11 @@ void set_hv_tscchange_cb(void (*cb)(void)) >> /* Make sure callback is registered before we write to MSRs */ >> wmb(); >> >> + preempt_disable(); >> + re_ctrl.target_vp = hv_vp_index[smp_processor_id()]; >> wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); >> + preempt_enable(); >> + >> wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl)); >> } >> EXPORT_SYMBOL_GPL(set_hv_tscchange_cb); > > This looks bogus, MSRs are a per-cpu resource, you had better know what > CPUs you're on and be stuck to it when you do wrmsr. This just fudges > the code to make the warning go away and doesn't fix the actual problem > afaict. Actually, we don't care which CPU will receive the reenlightenment notification and TSC Emulation in Hyper-V is, of course, global. We have code which re-assignes the notification to some other CPU in case the one it's currently assigned to goes away (see hv_cpu_die()). -- Vitaly _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel