Skip to content

Commit 9783709

Browse files
Chuansheng-Liusuryasaimadhu
authored andcommitted
x86/mce/therm_throt: Do not access uninitialized therm_work
It is relatively easy to trigger the following boot splat on an Ice Lake client platform. The call stack is like: kernel BUG at kernel/timer/timer.c:1152! Call Trace: __queue_delayed_work queue_delayed_work_on therm_throt_process intel_thermal_interrupt ... The reason is that a CPU's thermal interrupt is enabled prior to executing its hotplug onlining callback which will initialize the throttling workqueues. Such a race can lead to therm_throt_process() accessing an uninitialized therm_work, leading to the above BUG at a very early bootup stage. Therefore, unmask the thermal interrupt vector only after having setup the workqueues completely. [ bp: Heavily massage commit message and correct comment formatting. ] Fixes: f665620 ("x86/mce/therm_throt: Optimize notifications of thermal throttle") Signed-off-by: Chuansheng Liu <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Acked-by: Tony Luck <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent b3a987b commit 9783709

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

arch/x86/kernel/cpu/mce/therm_throt.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,18 @@ static int thermal_throttle_online(unsigned int cpu)
467467
{
468468
struct thermal_state *state = &per_cpu(thermal_state, cpu);
469469
struct device *dev = get_cpu_device(cpu);
470+
u32 l;
470471

471472
state->package_throttle.level = PACKAGE_LEVEL;
472473
state->core_throttle.level = CORE_LEVEL;
473474

474475
INIT_DELAYED_WORK(&state->package_throttle.therm_work, throttle_active_work);
475476
INIT_DELAYED_WORK(&state->core_throttle.therm_work, throttle_active_work);
476477

478+
/* Unmask the thermal vector after the above workqueues are initialized. */
479+
l = apic_read(APIC_LVTTHMR);
480+
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
481+
477482
return thermal_throttle_add_dev(dev, cpu);
478483
}
479484

@@ -722,10 +727,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
722727
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
723728
wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
724729

725-
/* Unmask the thermal vector: */
726-
l = apic_read(APIC_LVTTHMR);
727-
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
728-
729730
pr_info_once("CPU0: Thermal monitoring enabled (%s)\n",
730731
tm2 ? "TM2" : "TM1");
731732

0 commit comments

Comments
 (0)