[PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP

Jan Beulich posted 4 patches 3 weeks, 3 days ago
There is a newer version of this series
[PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP
Posted by Jan Beulich 3 weeks, 3 days ago
There's no need to do this for every AP; just do it once when setting up
the BSP. Then both vector variables can also validly become ro-after-init.

While touching intel_init_thermal(), constify its 1st parameter, which
in turn requires touching intel_thermal_supported() as well.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
This contextually (but not functionally) collides with "x86/MCE: adjust S3
resume handling".

--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -37,7 +37,7 @@ bool is_mc_panic;
 DEFINE_PER_CPU_READ_MOSTLY(unsigned int, nr_mce_banks);
 unsigned int __read_mostly firstbank;
 unsigned int __read_mostly ppin_msr;
-uint8_t __read_mostly cmci_apic_vector;
+uint8_t __ro_after_init cmci_apic_vector;
 bool __read_mostly cmci_support;
 
 /* If mce_force_broadcast == 1, lmce_support will be disabled forcibly. */
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -87,7 +87,7 @@ static void cf_check intel_thermal_inter
 }
 
 /* Thermal monitoring depends on APIC, ACPI and clock modulation */
-static bool intel_thermal_supported(struct cpuinfo_x86 *c)
+static bool intel_thermal_supported(const struct cpuinfo_x86 *c)
 {
     if ( !cpu_has_apic )
         return false;
@@ -110,13 +110,13 @@ static void __init mcheck_intel_therm_in
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void intel_init_thermal(struct cpuinfo_x86 *c)
+static void intel_init_thermal(const struct cpuinfo_x86 *c, bool bsp)
 {
     uint64_t msr_content;
     uint32_t val;
     int tm2 = 0;
     unsigned int cpu = smp_processor_id();
-    static uint8_t thermal_apic_vector;
+    static uint8_t __ro_after_init thermal_apic_vector;
 
     if ( !intel_thermal_supported(c) )
         return; /* -ENODEV */
@@ -160,7 +160,8 @@ static void intel_init_thermal(struct cp
         return; /* -EBUSY */
     }
 
-    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
+    if ( bsp )
+        alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
 
     /* The temperature transition interrupt handler setup */
     val = thermal_apic_vector;    /* our delivery vector */
@@ -667,7 +668,7 @@ static void cf_check cmci_interrupt(void
         mctelem_dismiss(mctc);
 }
 
-static void intel_init_cmci(struct cpuinfo_x86 *c)
+static void intel_init_cmci(struct cpuinfo_x86 *c, bool bsp)
 {
     u32 l, apic;
     int cpu = smp_processor_id();
@@ -687,7 +688,8 @@ static void intel_init_cmci(struct cpuin
         return;
     }
 
-    alloc_direct_apic_vector(&cmci_apic_vector, cmci_interrupt);
+    if ( bsp )
+        alloc_direct_apic_vector(&cmci_apic_vector, cmci_interrupt);
 
     apic = cmci_apic_vector;
     apic |= (APIC_DM_FIXED | APIC_LVT_MASKED);
@@ -993,9 +995,9 @@ enum mcheck_type intel_mcheck_init(struc
 
     intel_init_mce(bsp);
 
-    intel_init_cmci(c);
+    intel_init_cmci(c, bsp);
 
-    intel_init_thermal(c);
+    intel_init_thermal(c, bsp);
 
     intel_init_ppin(c);
Re: [PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP
Posted by Andrew Cooper 3 weeks, 2 days ago
On 19/11/2025 10:50 am, Jan Beulich wrote:
> --- a/xen/arch/x86/cpu/mcheck/mce.c
> +++ b/xen/arch/x86/cpu/mcheck/mce.c
> @@ -110,13 +110,13 @@ static void __init mcheck_intel_therm_in
>  }
>  
>  /* P4/Xeon Thermal regulation detect and init */
> -static void intel_init_thermal(struct cpuinfo_x86 *c)
> +static void intel_init_thermal(const struct cpuinfo_x86 *c, bool bsp)
>  {
>      uint64_t msr_content;
>      uint32_t val;
>      int tm2 = 0;
>      unsigned int cpu = smp_processor_id();
> -    static uint8_t thermal_apic_vector;
> +    static uint8_t __ro_after_init thermal_apic_vector;
>  
>      if ( !intel_thermal_supported(c) )
>          return; /* -ENODEV */
> @@ -160,7 +160,8 @@ static void intel_init_thermal(struct cp
>          return; /* -EBUSY */
>      }
>  
> -    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
> +    if ( bsp )
> +        alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);

We really don't want both c and bsp passed in.  That can only go wrong.

Furthermore, this function has 2 other examples generating bsp locally.

The function is in desperate need of cleanup (MSRs, variable and
constant names), but right now this makes it worse.

Please either use c == &boot_cpu_data, and I'll do some cleanup later,
or generate bsp = c == &boot_cpu_data and fix up all users in the function.

~Andrew

Re: [PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP
Posted by Jan Beulich 3 weeks, 2 days ago
On 20.11.2025 12:51, Andrew Cooper wrote:
> On 19/11/2025 10:50 am, Jan Beulich wrote:
>> --- a/xen/arch/x86/cpu/mcheck/mce.c
>> +++ b/xen/arch/x86/cpu/mcheck/mce.c
>> @@ -110,13 +110,13 @@ static void __init mcheck_intel_therm_in
>>  }
>>  
>>  /* P4/Xeon Thermal regulation detect and init */
>> -static void intel_init_thermal(struct cpuinfo_x86 *c)
>> +static void intel_init_thermal(const struct cpuinfo_x86 *c, bool bsp)
>>  {
>>      uint64_t msr_content;
>>      uint32_t val;
>>      int tm2 = 0;
>>      unsigned int cpu = smp_processor_id();
>> -    static uint8_t thermal_apic_vector;
>> +    static uint8_t __ro_after_init thermal_apic_vector;
>>  
>>      if ( !intel_thermal_supported(c) )
>>          return; /* -ENODEV */
>> @@ -160,7 +160,8 @@ static void intel_init_thermal(struct cp
>>          return; /* -EBUSY */
>>      }
>>  
>> -    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
>> +    if ( bsp )
>> +        alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
> 
> We really don't want both c and bsp passed in.  That can only go wrong.
> 
> Furthermore, this function has 2 other examples generating bsp locally.
> 
> The function is in desperate need of cleanup (MSRs, variable and
> constant names), but right now this makes it worse.
> 
> Please either use c == &boot_cpu_data, and I'll do some cleanup later,
> or generate bsp = c == &boot_cpu_data and fix up all users in the function.

No, throughout mce/ this won't work as long as acpi/power.c:enter_state() has

    mcheck_init(&boot_cpu_data, false);

Jan

Re: [PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP
Posted by Andrew Cooper 3 weeks, 2 days ago
On 20/11/2025 12:11 pm, Jan Beulich wrote:
> On 20.11.2025 12:51, Andrew Cooper wrote:
>> On 19/11/2025 10:50 am, Jan Beulich wrote:
>>> --- a/xen/arch/x86/cpu/mcheck/mce.c
>>> +++ b/xen/arch/x86/cpu/mcheck/mce.c
>>> @@ -110,13 +110,13 @@ static void __init mcheck_intel_therm_in
>>>  }
>>>  
>>>  /* P4/Xeon Thermal regulation detect and init */
>>> -static void intel_init_thermal(struct cpuinfo_x86 *c)
>>> +static void intel_init_thermal(const struct cpuinfo_x86 *c, bool bsp)
>>>  {
>>>      uint64_t msr_content;
>>>      uint32_t val;
>>>      int tm2 = 0;
>>>      unsigned int cpu = smp_processor_id();
>>> -    static uint8_t thermal_apic_vector;
>>> +    static uint8_t __ro_after_init thermal_apic_vector;
>>>  
>>>      if ( !intel_thermal_supported(c) )
>>>          return; /* -ENODEV */
>>> @@ -160,7 +160,8 @@ static void intel_init_thermal(struct cp
>>>          return; /* -EBUSY */
>>>      }
>>>  
>>> -    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
>>> +    if ( bsp )
>>> +        alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
>> We really don't want both c and bsp passed in.  That can only go wrong.
>>
>> Furthermore, this function has 2 other examples generating bsp locally.
>>
>> The function is in desperate need of cleanup (MSRs, variable and
>> constant names), but right now this makes it worse.
>>
>> Please either use c == &boot_cpu_data, and I'll do some cleanup later,
>> or generate bsp = c == &boot_cpu_data and fix up all users in the function.
> No, throughout mce/ this won't work as long as acpi/power.c:enter_state() has
>
>     mcheck_init(&boot_cpu_data, false);

How's not not already broken then?  As said, intel_init_thermal() is
already using c == &boot_cpu_data.

This patch introduces a conflicting idea of bsp in this function, and
that's what I really want to avoid.

This looks like it wants splitting properly as {bsp,percpu}_init_$FOO()
like we have elsewhere.

~Andrew

Re: [PATCH 2/4] x86/MCE: restrict allocation of thermal and CMCI vector to BSP
Posted by Jan Beulich 3 weeks, 1 day ago
On 20.11.2025 18:25, Andrew Cooper wrote:
> On 20/11/2025 12:11 pm, Jan Beulich wrote:
>> On 20.11.2025 12:51, Andrew Cooper wrote:
>>> On 19/11/2025 10:50 am, Jan Beulich wrote:
>>>> --- a/xen/arch/x86/cpu/mcheck/mce.c
>>>> +++ b/xen/arch/x86/cpu/mcheck/mce.c
>>>> @@ -110,13 +110,13 @@ static void __init mcheck_intel_therm_in
>>>>  }
>>>>  
>>>>  /* P4/Xeon Thermal regulation detect and init */
>>>> -static void intel_init_thermal(struct cpuinfo_x86 *c)
>>>> +static void intel_init_thermal(const struct cpuinfo_x86 *c, bool bsp)
>>>>  {
>>>>      uint64_t msr_content;
>>>>      uint32_t val;
>>>>      int tm2 = 0;
>>>>      unsigned int cpu = smp_processor_id();
>>>> -    static uint8_t thermal_apic_vector;
>>>> +    static uint8_t __ro_after_init thermal_apic_vector;
>>>>  
>>>>      if ( !intel_thermal_supported(c) )
>>>>          return; /* -ENODEV */
>>>> @@ -160,7 +160,8 @@ static void intel_init_thermal(struct cp
>>>>          return; /* -EBUSY */
>>>>      }
>>>>  
>>>> -    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
>>>> +    if ( bsp )
>>>> +        alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
>>> We really don't want both c and bsp passed in.  That can only go wrong.
>>>
>>> Furthermore, this function has 2 other examples generating bsp locally.
>>>
>>> The function is in desperate need of cleanup (MSRs, variable and
>>> constant names), but right now this makes it worse.
>>>
>>> Please either use c == &boot_cpu_data, and I'll do some cleanup later,
>>> or generate bsp = c == &boot_cpu_data and fix up all users in the function.
>> No, throughout mce/ this won't work as long as acpi/power.c:enter_state() has
>>
>>     mcheck_init(&boot_cpu_data, false);
> 
> How's not not already broken then?  As said, intel_init_thermal() is
> already using c == &boot_cpu_data.

That's two printk()s, so not overly severe a bug. And being fixed by "x86/MCE:
adjust S3 resume handling" posted months ago. There I'm actually putting up
the question whether one of the two could/should stay as is.

> This patch introduces a conflicting idea of bsp in this function, and
> that's what I really want to avoid.
> 
> This looks like it wants splitting properly as {bsp,percpu}_init_$FOO()
> like we have elsewhere.

Without detailed checking, I'm not sure that would properly cover things.
Right now we have three modes: BSP (boot), BSP (resume), and AP.

More importantly, though: This would be more than enough content for another
series, i.e. shouldn't block the work here (which really moves things to a
more consistent state, within cpu/mcheck/, just like that other patch also
aims at doing).

Jan