6786943 AMD-based systems with C1E state enabled hang at boot
Contributed by <
[email protected]>.
--- a/usr/src/uts/i86pc/os/cpuid.c Fri Feb 27 13:14:47 2009 -0800
+++ b/usr/src/uts/i86pc/os/cpuid.c Fri Feb 27 13:32:45 2009 -0800
@@ -48,6 +48,8 @@
#ifdef __xpv
#include <sys/hypervisor.h>
+#else
+#include <sys/ontrap.h>
#endif
/*
@@ -3893,6 +3895,36 @@
}
}
+#endif /* !__xpv */
+
+void
+post_startup_cpu_fixups(void)
+{
+#ifndef __xpv
+ /*
+ * Some AMD processors support C1E state. Entering this state will
+ * cause the local APIC timer to stop, which we can't deal with at
+ * this time.
+ */
+ if (cpuid_getvendor(CPU) == X86_VENDOR_AMD) {
+ on_trap_data_t otd;
+ uint64_t reg;
+
+ if (!on_trap(&otd, OT_DATA_ACCESS)) {
+ reg = rdmsr(MSR_AMD_INT_PENDING_CMP_HALT);
+ /* Disable C1E state if it is enabled by BIOS */
+ if ((reg >> AMD_ACTONCMPHALT_SHIFT) &
+ AMD_ACTONCMPHALT_MASK) {
+ reg &= ~(AMD_ACTONCMPHALT_MASK <<
+ AMD_ACTONCMPHALT_SHIFT);
+ wrmsr(MSR_AMD_INT_PENDING_CMP_HALT, reg);
+ }
+ }
+ no_trap();
+ }
+#endif /* !__xpv */
+}
+
#if defined(__amd64) && !defined(__xpv)
/*
* Patch in versions of bcopy for high performance Intel Nhm processors
@@ -3914,5 +3946,3 @@
}
}
#endif /* __amd64 && !__xpv */
-
-#endif /* !__xpv */
--- a/usr/src/uts/i86pc/os/mp_startup.c Fri Feb 27 13:14:47 2009 -0800
+++ b/usr/src/uts/i86pc/os/mp_startup.c Fri Feb 27 13:32:45 2009 -0800
@@ -1578,6 +1578,8 @@
mutex_exit(&cpu_lock);
+ post_startup_cpu_fixups();
+
/*
* Enable preemption here so that contention for any locks acquired
* later in mp_startup may be preempted if the thread owning those
--- a/usr/src/uts/i86pc/os/startup.c Fri Feb 27 13:14:47 2009 -0800
+++ b/usr/src/uts/i86pc/os/startup.c Fri Feb 27 13:32:45 2009 -0800
@@ -108,7 +108,6 @@
#include <sys/kobj.h>
#include <sys/kobj_lex.h>
#include <sys/cpc_impl.h>
-#include <sys/x86_archext.h>
#include <sys/cpu_module.h>
#include <sys/smbios.h>
#include <sys/debug_info.h>
@@ -2115,6 +2114,7 @@
prom_printf("ERROR: failed to attach AMD IOMMU\n");
}
#endif
+ post_startup_cpu_fixups();
PRM_POINT("startup_end() done");
}
--- a/usr/src/uts/intel/sys/x86_archext.h Fri Feb 27 13:14:47 2009 -0800
+++ b/usr/src/uts/intel/sys/x86_archext.h Fri Feb 27 13:32:45 2009 -0800
@@ -214,6 +214,15 @@
#define REG_APIC_BASE_MSR 0x1b
#define REG_X2APIC_BASE_MSR 0x800 /* The MSR address offset of x2APIC */
+#if !defined(__xpv)
+/*
+ * AMD C1E
+ */
+#define MSR_AMD_INT_PENDING_CMP_HALT 0xC0010055
+#define AMD_ACTONCMPHALT_SHIFT 27
+#define AMD_ACTONCMPHALT_MASK 3
+#endif
+
#define MSR_DEBUGCTL 0x1d9
#define DEBUGCTL_LBR 0x01
@@ -637,6 +646,8 @@
extern char bcopy_ck_size;
#endif
+extern void post_startup_cpu_fixups(void);
+
extern uint_t workaround_errata(struct cpu *);
#if defined(OPTERON_ERRATUM_93)