# HG changeset patch # User Matt Amdur # Date 1320066861 25200 # Node ID e702644ca141f9625bc711d3c66d23e554d2bacb # Parent 205481e35e49308f542a3b4aadb2d46b896a8734 1687 Race in determine_platform / get_hwenv causes multi-CPU VM hang at boot Reviewed by: Adam Leventhal Reviewed by: Eric Schrock Reviewed by: Robert Mustacchi Reviewed by: Garrett D'Amore Approved by: Richard Lowe diff -r 205481e35e49 -r e702644ca141 usr/src/uts/i86pc/os/cpuid.c --- 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 */ diff -r 205481e35e49 -r e702644ca141 usr/src/uts/i86pc/os/mlsetup.c --- 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 /* diff -r 205481e35e49 -r e702644ca141 usr/src/uts/intel/sys/x86_archext.h --- 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);