[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] x86/nmi: Fix mis-classification of watchdog NMIs



commit dc5a77c6c4951e8ad75c884b3b6b87a1ba46c488
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu Aug 13 16:18:59 2026 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon Aug 17 18:46:08 2026 +0100

    x86/nmi: Fix mis-classification of watchdog NMIs
    
    It used to be the case that cpu_data[] inherited the BSP's cpuid_level until
    the AP had calculated it itself.  Following the rework, cpuid_level has a
    placeholder 1 until it is calculated properly.
    
    setup_apic_nmi_watchdog() happens to be called on the BSP after SMP 
bring-up,
    meaning that the first call is on CPU1.  It is also positioned in the window
    where cpu_data[] is wrong.
    
    As a result, setup_p6_watchdog()'s one-time calculation of the performance
    counter width falls back into Pentium compatibility mode assuming 32bit
    counters.  This causes a watchdog NMI which is delayed a little (e.g. from 
an
    SMI), to appear as if it hadn't overflowed, and therefore be considered as 
not
    a watchdog NMI.  On systems where unknown NMIs are treated as fatal, this
    results in a spurious crash.
    
    Switch setup_p6_watchdog() to use boot_cpu_data.cpuid_level, which is how 
this
    is checked almost everywhere else.
    
    core2_vpmu_init() used the same pattern to look at leaf 0xa.  Despite being
    init code and only running on the BSP, {boot,current}_cpu_data are different
    objects, so switch it over to checking boot_cpu_data.cpuid_level too.
    
    Fixes: 7126b7f806d5 ("x86/CPU: re-work populating of cpu_data[]")
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/cpu/vpmu_intel.c | 2 +-
 xen/arch/x86/nmi.c            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c
index ed9f62b936..2326caee58 100644
--- a/xen/arch/x86/cpu/vpmu_intel.c
+++ b/xen/arch/x86/cpu/vpmu_intel.c
@@ -896,7 +896,7 @@ const struct arch_vpmu_ops *__init core2_vpmu_init(void)
     unsigned int version = 0;
     unsigned int i;
 
-    if ( current_cpu_data.cpuid_level >= 0xa )
+    if ( boot_cpu_data.cpuid_level >= 0xa )
         version = MASK_EXTR(cpuid_eax(0xa), PMU_VERSION_MASK);
 
     switch ( version )
diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
index 91f95fe6d0..ec85516609 100644
--- a/xen/arch/x86/nmi.c
+++ b/xen/arch/x86/nmi.c
@@ -321,7 +321,7 @@ static void setup_p6_watchdog(unsigned counter)
 {
     unsigned int evntsel;
 
-    if ( !nmi_p6_event_width && current_cpu_data.cpuid_level >= 0xa )
+    if ( !nmi_p6_event_width && boot_cpu_data.cpuid_level >= 0xa )
         nmi_p6_event_width = MASK_EXTR(cpuid_eax(0xa), P6_EVENT_WIDTH_MASK);
     if ( !nmi_p6_event_width )
         nmi_p6_event_width = P6_EVENT_WIDTH_MIN;
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.