]> git.hungrycats.org Git - linux/commitdiff
[PATCH] handle out of spec SMP athlons.
authorDave Jones <davej@suse.de>
Fri, 8 Feb 2002 09:43:16 +0000 (01:43 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 8 Feb 2002 09:43:16 +0000 (01:43 -0800)
Newer Athlons have means of checking if they are SMP capable or not.
This code adds checks that printk a warning on systems not intended
for SMP, and set the taint flag that modutils is already aware of.
The taint code is also improved to use defines instead of magic numbers.

Documentation/oops-tracing.txt
arch/i386/kernel/setup.c
arch/i386/kernel/smpboot.c
include/asm-i386/cpufeature.h
include/asm-i386/processor.h
include/linux/kernel.h
kernel/panic.c

index 0b1f791c05df08de909c01503fb9b8966ce2ec35..22014567a14f82a4852756e33773db086c3a0c26 100644 (file)
@@ -219,6 +219,11 @@ characters, each representing a particular tainted value.
   2: 'F' if any module was force loaded by insmod -f, ' ' if all
      modules were loaded normally.
 
+  3: 'S' if the oops occured on an SMP kernel running on hardware that
+      hasn't been certified as safe to run multiprocessor.
+         Currently this occurs only on various Athlons that are not
+         SMP capable.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent, even if an offending module is
index 691cd19aea2f9fad09f69973f4b412a2699c6d03..d7f8e2a1e676a29475c08dce68bf98bfac089463 100644 (file)
@@ -2652,7 +2652,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                /* AMD-defined */
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL,
+               NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
                NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
 
                /* Transmeta-defined */
index 66417cef4dfe4a75b1214eb5848721dd2a5a8a2c..b8774935f0feb671597dc33bdd95c6db40aac340 100644 (file)
  *             Tigran Aivazian :       fixed "0.00 in /proc/uptime on SMP" bug.
  *     Maciej W. Rozycki       :       Bits for genuine 82489DX APICs
  *             Martin J. Bligh :       Added support for multi-quad systems
+ *             Dave Jones      :       Report invalid combinations of Athlon CPUs.
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
@@ -160,6 +162,35 @@ void __init smp_store_cpu_info(int id)
                 * Remember we have B step Pentia with bugs
                 */
                smp_b_stepping = 1;
+
+       /*
+        * Certain Athlons might work (for various values of 'work') in SMP
+        * but they are not certified as MP capable.
+        */
+       if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
+
+               /* Athlon 660/661 is valid. */  
+               if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1)))
+                       goto valid_k7;
+
+               /* Duron 670 is valid */
+               if ((c->x86_model==7) && (c->x86_mask==0))
+                       goto valid_k7;
+
+               /* Athlon 662, Duron 671, and Athlon >model 7 have capability bit */
+               if (((c->x86_model==6) && (c->x86_mask>=2)) ||
+                   ((c->x86_model==7) && (c->x86_mask>=1)) ||
+                    (c->x86_model> 7))
+                       if (cpu_has_mp)
+                               goto valid_k7;
+
+               /* If we get here, it's not a certified SMP capable AMD system. */
+               printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n");
+               tainted |= TAINT_UNSAFE_SMP;
+               
+       }
+valid_k7:
+
 }
 
 /*
index 0cf51b706133f0b884f86019001ee7904191f115..3104bc34006170ca4fd0bd452482c0c10dac9d3a 100644 (file)
@@ -47,6 +47,7 @@
 /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
 /* Don't duplicate feature flags which are redundant with Intel! */
 #define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP         (1*32+19) /* MP Capable. */
 #define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
 #define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
 #define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
index 94f8c1748d2ced47f9fd6dba526f48baef4a80f1..d830237efb4db117a68de29c474c42e5c281d383 100644 (file)
@@ -90,6 +90,7 @@ extern struct cpuinfo_x86 cpu_data[];
 #define cpu_has_xmm    (test_bit(X86_FEATURE_XMM,  boot_cpu_data.x86_capability))
 #define cpu_has_fpu    (test_bit(X86_FEATURE_FPU,  boot_cpu_data.x86_capability))
 #define cpu_has_apic   (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
+#define cpu_has_mp (test_bit(X86_FEATURE_MP, boot_cpu_data.x86_capability))
 
 extern char ignore_irq13;
 
index 8749f6f0c302038a92c5f51f1090b7663a727194..2204760615d8059ee7ed08e572dafcb6500a6ce3 100644 (file)
@@ -91,6 +91,9 @@ extern int oops_in_progress;          /* If set, an oops, panic(), BUG() or die() is in
 
 extern int tainted;
 extern const char *print_tainted(void);
+#define TAINT_PROPRIETORY_MODULE       (1<<0)
+#define TAINT_FORCED_MODULE            (1<<1)
+#define TAINT_UNSAFE_SMP               (1<<2)
 
 #if DEBUG
 #define pr_debug(fmt,arg...) \
index 1eccb0e0c74910e968b74bfd8d898f0f866d01d0..84adabf00cf5397ad4542f3d7af10cb1251437c4 100644 (file)
@@ -103,6 +103,10 @@ NORET_TYPE void panic(const char * fmt, ...)
 /**
  *     print_tainted - return a string to represent the kernel taint state.
  *
+ *  'P' - Proprietory module has been loaded.
+ *  'F' - Module has been forcibly loaded.
+ *  'S' - SMP with CPUs not designed for SMP.
+ *
  *     The string is overwritten by the next call to print_taint().
  */
  
@@ -110,9 +114,10 @@ const char *print_tainted()
 {
        static char buf[20];
        if (tainted) {
-               snprintf(buf, sizeof(buf), "Tainted: %c%c",
-                       tainted & 1 ? 'P' : 'G',
-                       tainted & 2 ? 'F' : ' ');
+               snprintf(buf, sizeof(buf), "Tainted: %c%c%c",
+                       tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
+                       tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
+                       tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
        }
        else
                snprintf(buf, sizeof(buf), "Not tainted");