diff -r 75d35d8e7fe1 sys/amd64/amd64/identcpu.c --- a/sys/amd64/amd64/identcpu.c Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/amd64/amd64/identcpu.c Thu Nov 05 12:42:35 2009 +0100 @@ -404,6 +404,10 @@ if (cpu_vendor_id == CPU_VENDOR_AMD) print_AMD_info(); +#if defined(BROKEN_OPTERON_E) + else + printf("BROKEN_OPTERON_E option in your kernel is useless with your CPU\n"); +#endif } void @@ -620,10 +624,17 @@ */ if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && CPUID_TO_MODEL(cpu_id) <= 0x3f) { +#if !defined(BROKEN_OPTERON_E) printf("WARNING: This architecture revision has known SMP " "hardware bugs which may cause random instability\n"); - printf("WARNING: For details see: " - "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); +#else + printf("WARNING: options BROKEN_OPTERON_E is in your kernel. " + "Expect performance penalties\n"); + else + + printf("WARNING: options BROKEN_OPTERON_E is useless with your CPU." + "Expect performance penalties\n"); +#endif } } diff -r 75d35d8e7fe1 sys/amd64/include/atomic.h --- a/sys/amd64/include/atomic.h Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/amd64/include/atomic.h Thu Nov 05 12:42:35 2009 +0100 @@ -36,6 +36,14 @@ #define wmb() __asm __volatile("sfence;" : : : "memory") #define rmb() __asm __volatile("lfence;" : : : "memory") +#include "opt_cpu.h" + +#if defined(BROKEN_OPTERON_E) && (defined(SMP) || !defined(_KERNEL)) + #define OPTERON_E_HACK() rmb() +#else + #define OPTERON_E_HACK() +#endif + /* * Various simple operations on memory, each of which is atomic in the * presence of interrupts and multiple processors. @@ -147,6 +155,8 @@ "m" (*dst) /* 4 */ : "memory"); + OPTERON_E_HACK(); + return (res); } @@ -168,6 +178,8 @@ "m" (*dst) /* 4 */ : "memory"); + OPTERON_E_HACK(); + return (res); } @@ -251,6 +263,8 @@ : "m" (*p) /* 2 */ \ : "memory"); \ \ + OPTERON_E_HACK(); \ + \ return (res); \ } \ \ diff -r 75d35d8e7fe1 sys/conf/options.amd64 --- a/sys/conf/options.amd64 Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/conf/options.amd64 Thu Nov 05 12:42:35 2009 +0100 @@ -49,6 +49,7 @@ # EOF # ------------------------------- HAMMER opt_cpu.h +BROKEN_OPTERON_E opt_cpu.h PSM_HOOKRESUME opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h diff -r 75d35d8e7fe1 sys/conf/options.i386 --- a/sys/conf/options.i386 Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/conf/options.i386 Thu Nov 05 12:42:35 2009 +0100 @@ -37,6 +37,7 @@ TIMER_FREQ opt_clock.h CPU_ATHLON_SSE_HACK opt_cpu.h +BROKEN_OPTERON_E opt_cpu.h CPU_BLUELIGHTNING_3X opt_cpu.h CPU_BLUELIGHTNING_FPU_OP_CACHE opt_cpu.h CPU_BTB_EN opt_cpu.h diff -r 75d35d8e7fe1 sys/i386/i386/identcpu.c --- a/sys/i386/i386/identcpu.c Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/i386/i386/identcpu.c Thu Nov 05 12:42:35 2009 +0100 @@ -904,6 +904,11 @@ print_INTEL_info(); else if (cpu_vendor_id == CPU_VENDOR_TRANSMETA) print_transmeta_info(); + +#if defined(BROKEN_OPTERON_E) + if (cpu_vendor_id != CPU_VENDOR_AMD) + printf("BROKEN_OPTERON_E option in your kernel is useless with your CPU\n"); +#endif } void @@ -1315,12 +1320,18 @@ * model and family are identified. */ if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && - CPUID_TO_MODEL(cpu_id) <= 0x3f) { + CPUID_TO_MODEL(cpu_id) <= 0x3f) +#if !defined(BROKEN_OPTERON_E) printf("WARNING: This architecture revision has known SMP " "hardware bugs which may cause random instability\n"); - printf("WARNING: For details see: " - "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); - } +#else + printf("WARNING: options BROKEN_OPTERON_E is in your kernel. " + "Expect performance penalties\n"); + else + + printf("WARNING: options BROKEN_OPTERON_E is useless with your CPU." + "Expect performance penalties\n"); +#endif } static void diff -r 75d35d8e7fe1 sys/i386/include/atomic.h --- a/sys/i386/include/atomic.h Thu Nov 05 11:18:35 2009 +0100 +++ b/sys/i386/include/atomic.h Thu Nov 05 12:42:35 2009 +0100 @@ -36,6 +36,14 @@ #define wmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory") #define rmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory") +#include "opt_cpu.h" + +#if defined(BROKEN_OPTERON_E) && (defined(SMP) || !defined(_KERNEL)) + #define OPTERON_E_HACK() rmb() +#else + #define OPTERON_E_HACK() +#endif + /* * Various simple operations on memory, each of which is atomic in the * presence of interrupts and multiple processors. @@ -174,6 +182,8 @@ "m" (*dst) /* 4 */ : "memory"); + OPTERON_E_HACK(); + return (res); } @@ -240,6 +250,8 @@ : "m" (*p) /* 2 */ \ : "memory"); \ \ + OPTERON_E_HACK(); \ + \ return (res); \ } \ \