Mercurial > illumos > illumos-gate
changeset 13498:e702644ca141
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>
author | Matt Amdur <mba@delphix.com> |
---|---|
date | Mon, 31 Oct 2011 06:14:21 -0700 |
parents | 205481e35e49 |
children | cb9d7a417470 |
files | usr/src/uts/i86pc/os/cpuid.c usr/src/uts/i86pc/os/mlsetup.c usr/src/uts/intel/sys/x86_archext.h |
diffstat | 3 files changed, 23 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/i86pc/os/cpuid.c Sat Oct 29 05:11:55 2011 +0400 +++ b/usr/src/uts/i86pc/os/cpuid.c Mon Oct 31 06:14:21 2011 -0700 @@ -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 @@ #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 @@ int get_hwenv(void) { - if (platform_type == -1) - determine_platform(); - + ASSERT(platform_type != -1); return (platform_type); } @@ -870,9 +878,6 @@ extern int idle_cpu_prefer_mwait; #endif -#if !defined(__xpv) - determine_platform(); -#endif /* * Space statically allocated for BSP, ensure pointer is set */
--- a/usr/src/uts/i86pc/os/mlsetup.c Sat Oct 29 05:11:55 2011 +0400 +++ b/usr/src/uts/i86pc/os/mlsetup.c Mon Oct 31 06:14:21 2011 -0700 @@ -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 @@ 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 /*
--- a/usr/src/uts/intel/sys/x86_archext.h Sat Oct 29 05:11:55 2011 +0400 +++ b/usr/src/uts/intel/sys/x86_archext.h Mon Oct 31 06:14:21 2011 -0700 @@ -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 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);