diff options
author | Matt Amdur <mba@delphix.com> | 2011-10-31 06:14:21 -0700 |
---|---|---|
committer | John Sonnenschein <johns@joyent.com> | 2011-11-04 00:07:43 +0000 |
commit | a2eae5abcba4de352bc74ccfedc8420e6a00c106 (patch) | |
tree | b0613069da730bcca078802943177ed9283824b5 /usr/src | |
parent | df232dc5692ee20ff82f109ddeb643b4aa06ec65 (diff) | |
download | illumos-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.c | 21 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mlsetup.c | 6 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/x86_archext.h | 4 |
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); |