Commit d0b85e7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull thermal control fix from Rafael Wysocki:
 "Modify the Intel thermal throttling code to avoid updating unsupported
  status clearing mask bits which causes the kernel to complain about
  unchecked MSR access (Srinivas Pandruvada)"

* tag 'thermal-6.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: intel: Avoid updating unsupported THERM_STATUS_CLEAR mask bits
parents e251c423 117e4e5b
Loading
Loading
Loading
Loading
+66 −7
Original line number Diff line number Diff line
@@ -193,8 +193,67 @@ static const struct attribute_group thermal_attr_group = {
#define THERM_THROT_POLL_INTERVAL	HZ
#define THERM_STATUS_PROCHOT_LOG	BIT(1)

#define THERM_STATUS_CLEAR_CORE_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11) | BIT(13) | BIT(15))
#define THERM_STATUS_CLEAR_PKG_MASK  (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11))
static u64 therm_intr_core_clear_mask;
static u64 therm_intr_pkg_clear_mask;

static void thermal_intr_init_core_clear_mask(void)
{
	if (therm_intr_core_clear_mask)
		return;

	/*
	 * Reference: Intel SDM  Volume 4
	 * "Table 2-2. IA-32 Architectural MSRs", MSR 0x19C
	 * IA32_THERM_STATUS.
	 */

	/*
	 * Bit 1, 3, 5: CPUID.01H:EDX[22] = 1. This driver will not
	 * enable interrupts, when 0 as it checks for X86_FEATURE_ACPI.
	 */
	therm_intr_core_clear_mask = (BIT(1) | BIT(3) | BIT(5));

	/*
	 * Bit 7 and 9: Thermal Threshold #1 and #2 log
	 * If CPUID.01H:ECX[8] = 1
	 */
	if (boot_cpu_has(X86_FEATURE_TM2))
		therm_intr_core_clear_mask |= (BIT(7) | BIT(9));

	/* Bit 11: Power Limitation log (R/WC0) If CPUID.06H:EAX[4] = 1 */
	if (boot_cpu_has(X86_FEATURE_PLN))
		therm_intr_core_clear_mask |= BIT(11);

	/*
	 * Bit 13: Current Limit log (R/WC0) If CPUID.06H:EAX[7] = 1
	 * Bit 15: Cross Domain Limit log (R/WC0) If CPUID.06H:EAX[7] = 1
	 */
	if (boot_cpu_has(X86_FEATURE_HWP))
		therm_intr_core_clear_mask |= (BIT(13) | BIT(15));
}

static void thermal_intr_init_pkg_clear_mask(void)
{
	if (therm_intr_pkg_clear_mask)
		return;

	/*
	 * Reference: Intel SDM  Volume 4
	 * "Table 2-2. IA-32 Architectural MSRs", MSR 0x1B1
	 * IA32_PACKAGE_THERM_STATUS.
	 */

	/* All bits except BIT 26 depend on CPUID.06H: EAX[6] = 1 */
	if (boot_cpu_has(X86_FEATURE_PTS))
		therm_intr_pkg_clear_mask = (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11));

	/*
	 * Intel SDM Volume 2A: Thermal and Power Management Leaf
	 * Bit 26: CPUID.06H: EAX[19] = 1
	 */
	if (boot_cpu_has(X86_FEATURE_HFI))
		therm_intr_pkg_clear_mask |= BIT(26);
}

/*
 * Clear the bits in package thermal status register for bit = 1
@@ -207,13 +266,10 @@ void thermal_clear_package_intr_status(int level, u64 bit_mask)

	if (level == CORE_LEVEL) {
		msr  = MSR_IA32_THERM_STATUS;
		msr_val = THERM_STATUS_CLEAR_CORE_MASK;
		msr_val = therm_intr_core_clear_mask;
	} else {
		msr  = MSR_IA32_PACKAGE_THERM_STATUS;
		msr_val = THERM_STATUS_CLEAR_PKG_MASK;
		if (boot_cpu_has(X86_FEATURE_HFI))
			msr_val |= BIT(26);

		msr_val = therm_intr_pkg_clear_mask;
	}

	msr_val &= ~bit_mask;
@@ -708,6 +764,9 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
	h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
	apic_write(APIC_LVTTHMR, h);

	thermal_intr_init_core_clear_mask();
	thermal_intr_init_pkg_clear_mask();

	rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
	if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
		wrmsr(MSR_IA32_THERM_INTERRUPT,