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

[xen staging] x86/MCE: fail init more gracefully when CPU vendor isn't supported



commit c3e759967a8ae07a75c133e25f91cf94286197d1
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Feb 26 12:23:19 2025 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Feb 26 12:23:19 2025 +0100

    x86/MCE: fail init more gracefully when CPU vendor isn't supported
    
    When mcheck_init() doesn't recognize the CPU vendor, it will undo the
    all-banks allocation, and it will in particular not install the CPU
    notifier. This way APs will pointlessly try to re-establish an
    all-banks allocation, while then falling over NULL pointers due to the
    notifier not having run and hence not having allocated anything for
    them.
    
    Prevent both from happening, and additionally delay writing MCG_CTL
    until no errors can occur anymore in mca_cap_init().
    
    Fixes: 741367e77d6c ("mce: Clean-up mcheck_init handler")
    Fixes: a5e1b534ac6f ("x86: mce cleanup for both Intel and AMD mce logic")
    Fixes: 560cf418c845 ("x86/mcheck: allow varying bank counts per CPU")
    Reported-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/mce.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index 9028ccde54..1c348e557d 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -634,16 +634,13 @@ static void set_poll_bankmask(struct cpuinfo_x86 *c)
 }
 
 /* The perbank ctl/status init is platform specific because of AMD's quirk */
-static int mca_cap_init(void)
+static int mca_cap_init(bool bsp)
 {
     uint64_t msr_content;
     unsigned int nr, cpu = smp_processor_id();
 
     rdmsrl(MSR_IA32_MCG_CAP, msr_content);
 
-    if ( msr_content & MCG_CTL_P ) /* Control register present ? */
-        wrmsrl(MSR_IA32_MCG_CTL, 0xffffffffffffffffULL);
-
     per_cpu(nr_mce_banks, cpu) = nr = MASK_EXTR(msr_content, MCG_CAP_COUNT);
 
     if ( !nr )
@@ -654,8 +651,11 @@ static int mca_cap_init(void)
         return -ENODEV;
     }
 
+    if ( !bsp && !mca_allbanks )
+        return -ENODATA;
+
     /* mcabanks_alloc depends on nr_mce_banks */
-    if ( !mca_allbanks || nr > mca_allbanks->num )
+    if ( bsp || nr > mca_allbanks->num )
     {
         unsigned int i;
         struct mca_banks *all = mcabanks_alloc(nr);
@@ -667,6 +667,9 @@ static int mca_cap_init(void)
         mcabanks_free(xchg(&mca_allbanks, all));
     }
 
+    if ( msr_content & MCG_CTL_P ) /* Control register present ? */
+        wrmsrl(MSR_IA32_MCG_CTL, ~0ULL);
+
     return 0;
 }
 
@@ -751,7 +754,7 @@ void mcheck_init(struct cpuinfo_x86 *c, bool bsp)
     }
 
     /*Hardware Enable */
-    if ( mca_cap_init() )
+    if ( mca_cap_init(bsp) )
         return;
 
     if ( !bsp )
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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