6786943 AMD-based systems with C1E state enabled hang at boot
authorBill Holler <Bill.Holler@Sun.COM>
Fri, 27 Feb 2009 13:32:45 -0800
changeset 8930 02055889c73a
parent 8929 4371b592750e
child 8931 56a00eaca3d2
6786943 AMD-based systems with C1E state enabled hang at boot Contributed by <[email protected]>.
usr/src/uts/i86pc/os/cpuid.c
usr/src/uts/i86pc/os/mp_startup.c
usr/src/uts/i86pc/os/startup.c
usr/src/uts/intel/sys/x86_archext.h
--- 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)