diff options
author | Gerry Liu <jiang.liu@intel.com> | 2010-03-25 15:36:50 -0700 |
---|---|---|
committer | Gerry Liu <jiang.liu@intel.com> | 2010-03-25 15:36:50 -0700 |
commit | a31148363f598def767ac48c5d82e1572e44b935 (patch) | |
tree | 756cfb0c3c9a79f98087875bb4731e0366f895b7 /usr/src/uts/i86pc/os/cmi_hw.c | |
parent | 19843f01b1bef3453f717c23c8f89fb9313f6749 (diff) | |
download | illumos-gate-a31148363f598def767ac48c5d82e1572e44b935.tar.gz |
PSARC/2009/104 Hot-Plug Support for ACPI-based Systems
PSARC/2009/550 PSMI Extensions for CPU Hotplug
PSARC/2009/551 acpihpd ACPI Hotplug Daemon
PSARC/2009/591 Attachment Points for Hotpluggable x86 Systems
6862510 provide support for cpu hot add on x86
6883891 cmi interface needs to support dynamic reconfiguration
6884154 x2APIC and kmdb may not function properly during CPU hotplug event.
6904971 low priority acpi nexus code review feedback
6877301 lgrp should support memory hotplug flag in SRAT table
Diffstat (limited to 'usr/src/uts/i86pc/os/cmi_hw.c')
-rw-r--r-- | usr/src/uts/i86pc/os/cmi_hw.c | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/usr/src/uts/i86pc/os/cmi_hw.c b/usr/src/uts/i86pc/os/cmi_hw.c index 1c2dbeaad6..8e3ae0f0af 100644 --- a/usr/src/uts/i86pc/os/cmi_hw.c +++ b/usr/src/uts/i86pc/os/cmi_hw.c @@ -23,6 +23,10 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2010, Intel Corporation. + * All rights reserved. + */ /* * CPU Module Interface - hardware abstraction. @@ -94,6 +98,7 @@ typedef struct cmi_hdl_impl { #define HDLOPS(hdl) ((hdl)->cmih_ops) #define CMIH_F_INJACTV 0x1ULL +#define CMIH_F_DEAD 0x2ULL /* * Ops structure for handle operations. @@ -847,9 +852,18 @@ ntv_int(cmi_hdl_impl_t *hdl, int int_no) static int ntv_online(cmi_hdl_impl_t *hdl, int new_status, int *old_status) { + int rc; processorid_t cpuid = HDLPRIV(hdl)->cpu_id; - return (p_online_internal(cpuid, new_status, old_status)); + while (mutex_tryenter(&cpu_lock) == 0) { + if (hdl->cmih_flags & CMIH_F_DEAD) + return (EBUSY); + delay(1); + } + rc = p_online_internal_locked(cpuid, new_status, old_status); + mutex_exit(&cpu_lock); + + return (rc); } #else /* __xpv */ @@ -1387,15 +1401,32 @@ void cmi_hdl_rele(cmi_hdl_t ophdl) { cmi_hdl_impl_t *hdl = IMPLHDL(ophdl); - cmi_hdl_ent_t *ent; ASSERT(*hdl->cmih_refcntp > 0); + (void) atomic_dec_32_nv(hdl->cmih_refcntp); +} - if (atomic_dec_32_nv(hdl->cmih_refcntp) > 0) - return; +void +cmi_hdl_destroy(cmi_hdl_t ophdl) +{ + cmi_hdl_impl_t *hdl = IMPLHDL(ophdl); + cmi_hdl_ent_t *ent; + + /* Release the reference count held by cmi_hdl_create(). */ + ASSERT(*hdl->cmih_refcntp > 0); + (void) atomic_dec_32_nv(hdl->cmih_refcntp); + hdl->cmih_flags |= CMIH_F_DEAD; ent = cmi_hdl_ent_lookup(hdl->cmih_chipid, hdl->cmih_coreid, hdl->cmih_strandid); + /* + * Use busy polling instead of condition variable here because + * cmi_hdl_rele() may be called from #MC handler. + */ + while (cmi_hdl_canref(ent)) { + cmi_hdl_rele(ophdl); + delay(1); + } ent->cmae_hdlp = NULL; kmem_free(hdl, sizeof (*hdl)); @@ -1628,6 +1659,33 @@ cmi_ntv_hwstrandid(cpu_t *cp) return (cpuid_get_clogid(cp) % strands_per_core); } + +static void +cmi_ntv_hwdisable_mce_xc(void) +{ + ulong_t cr4; + + cr4 = getcr4(); + cr4 = cr4 & (~CR4_MCE); + setcr4(cr4); +} + +void +cmi_ntv_hwdisable_mce(cmi_hdl_t hdl) +{ + cpuset_t set; + cmi_hdl_impl_t *thdl = IMPLHDL(hdl); + cpu_t *cp = HDLPRIV(thdl); + + if (CPU->cpu_id == cp->cpu_id) { + cmi_ntv_hwdisable_mce_xc(); + } else { + CPUSET_ONLY(set, cp->cpu_id); + xc_call(NULL, NULL, NULL, CPUSET2BV(set), + (xc_func_t)cmi_ntv_hwdisable_mce_xc); + } +} + #endif /* __xpv */ void |