summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMatt Amdur <mba@delphix.com>2011-10-31 06:14:21 -0700
committerJohn Sonnenschein <johns@joyent.com>2011-11-04 00:07:43 +0000
commita2eae5abcba4de352bc74ccfedc8420e6a00c106 (patch)
treeb0613069da730bcca078802943177ed9283824b5 /usr/src
parentdf232dc5692ee20ff82f109ddeb643b4aa06ec65 (diff)
downloadillumos-joyent-a2eae5abcba4de352bc74ccfedc8420e6a00c106.tar.gz
1687 Race in determine_platform / get_hwenv causes multi-CPU VM hang at boot
Reviewed by: Adam Leventhal <Adam.Leventhal@delphix.com> Reviewed by: Eric Schrock <Eric.Schrock@delphix.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Garrett D'Amore <garrett.damore@gmail.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c21
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c6
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h4
3 files changed, 23 insertions, 8 deletions
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 09707f151c..0a389e0063 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -590,13 +591,22 @@ cpuid_free_space(cpu_t *cpu)
#if !defined(__xpv)
-static void
-determine_platform()
+/*
+ * Determine the type of the underlying platform. This is used to customize
+ * initialization of various subsystems (e.g. TSC). determine_platform() must
+ * only ever be called once to prevent two processors from seeing different
+ * values of platform_type, it must be called before cpuid_pass1(), the
+ * earliest consumer to execute.
+ */
+void
+determine_platform(void)
{
struct cpuid_regs cp;
char *xen_str;
uint32_t xen_signature[4], base;
+ ASSERT(platform_type == -1);
+
platform_type = HW_NATIVE;
if (!enable_platform_detection)
@@ -633,9 +643,7 @@ determine_platform()
int
get_hwenv(void)
{
- if (platform_type == -1)
- determine_platform();
-
+ ASSERT(platform_type != -1);
return (platform_type);
}
@@ -870,9 +878,6 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)
extern int idle_cpu_prefer_mwait;
#endif
-#if !defined(__xpv)
- determine_platform();
-#endif
/*
* Space statically allocated for BSP, ensure pointer is set
*/
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index 2f7e271c29..63b858f978 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -172,6 +173,11 @@ mlsetup(struct regs *rp)
pci_cfgspace_init();
#else
pci_cfgspace_init();
+ /*
+ * Initialize the platform type from CPU 0 to ensure that
+ * determine_platform() is only ever called once.
+ */
+ determine_platform();
#endif
/*
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index c5516be232..80c85df52f 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -762,6 +763,9 @@ extern int opteron_workaround_6323525;
extern void patch_workaround_6323525(void);
#endif
+#if !defined(__xpv)
+extern void determine_platform(void);
+#endif
extern int get_hwenv(void);
extern int is_controldom(void);