x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted
[sfrench/cifs-2.6.git] / arch / x86 / hyperv / hv_init.c
index 4fb7c7bb164eee34ecfd233d84c1fcfb0d84b066..24f4a06ac46acd474574d79d6c849927ba40938c 100644 (file)
@@ -169,7 +169,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};
 
@@ -183,8 +182,12 @@ void set_hv_tscchange_cb(void (*cb)(void))
        /* Make sure callback is registered before we write to MSRs */
        wmb();
 
+       re_ctrl.target_vp = hv_vp_index[get_cpu()];
+
        wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
        wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl));
+
+       put_cpu();
 }
 EXPORT_SYMBOL_GPL(set_hv_tscchange_cb);