Mercurial > unleashed > wips
changeset 20605:9b9c078a243b
Merge illumos-gate
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sun, 19 May 2019 11:36:48 -0400 |
parents | 76b6299aa623 (current diff) 7acd63403bc1 (diff) |
children | 7799eb65ec02 |
files | arch/x86/include/sys/cpu_module.h arch/x86/include/sys/x86_archext.h arch/x86/kernel/include/sys/cpu_module_impl.h arch/x86/kernel/os/cmi.c arch/x86/kernel/os/cmi_hw.c include/sys/devfm.h usr/src/boot/sys/boot/libcrypto/Makefile.com usr/src/lib/scsi/libscsi/common/scsi_engine.c usr/src/uts/i86pc/cpu/generic_cpu/gcpu_main.c |
diffstat | 19 files changed, 332 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/arch/x86/include/sys/cpu_module.h Sun May 05 16:25:23 2019 -0400 +++ b/arch/x86/include/sys/cpu_module.h Sun May 19 11:36:48 2019 -0400 @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _SYS_CPU_MODULE_H @@ -163,6 +164,8 @@ extern uint16_t cmi_hdl_smbiosid(cmi_hdl_t); extern uint_t cmi_hdl_smb_chipid(cmi_hdl_t); extern nvlist_t *cmi_hdl_smb_bboard(cmi_hdl_t); +extern uint_t cmi_hdl_chipsig(cmi_hdl_t); +extern const char *cmi_hdl_chipident(cmi_hdl_t); extern int cmi_hdl_online(cmi_hdl_t, int, int *);
--- a/arch/x86/include/sys/x86_archext.h Sun May 05 16:25:23 2019 -0400 +++ b/arch/x86/include/sys/x86_archext.h Sun May 19 11:36:48 2019 -0400 @@ -248,7 +248,7 @@ #define CPUID_INTC_ECX_7_0_AVX512VPOPCDQ 0x00004000 /* AVX512 VPOPCNTDQ */ #define CPUID_INTC_ECX_7_0_ALL_AVX512 \ - (CPUID_INTC_ECX_7_0_AVX512VBMI | CPUID_INTC_ECX_7_0_AVX512VPOPCDQ) +(CPUID_INTC_ECX_7_0_AVX512VBMI | CPUID_INTC_ECX_7_0_AVX512VPOPCDQ) #define CPUID_INTC_EDX_7_0_AVX5124NNIW 0x00000004 /* AVX512 4NNIW */ #define CPUID_INTC_EDX_7_0_AVX5124FMAPS 0x00000008 /* AVX512 4FMAPS */ @@ -348,6 +348,18 @@ #define MSR_PRP4_LBSTK_TO_15 0x6cf /* + * General Xeon based MSRs + */ +#define MSR_PPIN_CTL 0x04e +#define MSR_PPIN 0x04f +#define MSR_PLATFORM_INFO 0x0ce + +#define MSR_PLATFORM_INFO_PPIN (1 << 23) +#define MSR_PPIN_CTL_MASK 0x03 +#define MSR_PPIN_CTL_LOCKED 0x01 +#define MSR_PPIN_CTL_ENABLED 0x02 + +/* * Intel IA32_ARCH_CAPABILITIES MSR. */ #define MSR_IA32_ARCH_CAPABILITIES 0x10a @@ -712,6 +724,19 @@ #define X86_SOCKET_FS1R2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x100000) #define X86_SOCKET_FM2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x200000) + +/* + * Definitions for Intel processor models. Note, these model values can overlap + * in a given family. Processor models are added here on an as needed basis. The + * Xeon extension here is to refer to what has been called the EP/EX lines or + * E5/E7, generally multi-socket capable processors. + */ +#define INTC_MODEL_IVYBRIDGE_XEON 0x3E +#define INTC_MODEL_HASWELL_XEON 0x3F +#define INTC_MODEL_BROADWELL_XEON 0x4F +#define INTC_MODEL_BROADWELL_XEON_D 0x56 +#define INTC_MODEL_SKYLAKE_XEON 0x55 + /* * xgetbv/xsetbv support * See section 13.3 in vol. 1 of the Intel devlopers manual.
--- a/arch/x86/kernel/include/sys/cpu_module_impl.h Sun May 05 16:25:23 2019 -0400 +++ b/arch/x86/kernel/include/sys/cpu_module_impl.h Sun May 19 11:36:48 2019 -0400 @@ -22,6 +22,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _SYS_CPU_MODULE_IMPL_H @@ -64,6 +65,7 @@ void (*cmi_hdl_poke)(cmi_hdl_t); void (*cmi_fini)(cmi_hdl_t); void (*cmi_panic_callback)(void); + const char *(*cmi_ident)(cmi_hdl_t); } cmi_ops_t; /*
--- a/arch/x86/kernel/os/cmi.c Sun May 05 16:25:23 2019 -0400 +++ b/arch/x86/kernel/os/cmi.c Sun May 19 11:36:48 2019 -0400 @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ /* @@ -962,3 +963,15 @@ cmi_hdl_rele(hdl); } + + +const char * +cmi_hdl_chipident(cmi_hdl_t hdl) +{ + cmi_t *cmi = cmi_hdl_getcmi(hdl); + + if (!CMI_OP_PRESENT(cmi, cmi_ident)) + return (NULL); + + return (CMI_OPS(cmi)->cmi_ident(hdl)); +}
--- a/arch/x86/kernel/os/cmi_hw.c Sun May 05 16:25:23 2019 -0400 +++ b/arch/x86/kernel/os/cmi_hw.c Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ /* * Copyright (c) 2010, Intel Corporation. @@ -118,6 +119,7 @@ const char *(*cmio_chiprevstr)(cmi_hdl_impl_t *); uint32_t (*cmio_getsockettype)(cmi_hdl_impl_t *); const char *(*cmio_getsocketstr)(cmi_hdl_impl_t *); + uint_t (*cmio_chipsig)(cmi_hdl_impl_t *); id_t (*cmio_logical_id)(cmi_hdl_impl_t *); /* @@ -680,6 +682,12 @@ return (cpuid_getsocketstr(HDLPRIV(hdl))); } +static uint_t +ntv_chipsig(cmi_hdl_impl_t *hdl) +{ + return (cpuid_getsig(HDLPRIV(hdl))); +} + static id_t ntv_logical_id(cmi_hdl_impl_t *hdl) { @@ -1289,6 +1297,7 @@ CMI_HDL_OPFUNC(smbiosid, uint16_t) CMI_HDL_OPFUNC(smb_chipid, uint_t) CMI_HDL_OPFUNC(smb_bboard, nvlist_t *) +CMI_HDL_OPFUNC(chipsig, uint_t) /* END CSTYLED */ boolean_t @@ -1657,6 +1666,7 @@ ntv_chiprevstr, /* cmio_chiprevstr */ ntv_getsockettype, /* cmio_getsockettype */ ntv_getsocketstr, /* cmio_getsocketstr */ + ntv_chipsig, /* cmio_chipsig */ ntv_logical_id, /* cmio_logical_id */ ntv_getcr4, /* cmio_getcr4 */ ntv_setcr4, /* cmio_setcr4 */
--- a/include/sys/devfm.h Sun May 05 16:25:23 2019 -0400 +++ b/include/sys/devfm.h Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _SYS_DEVFM_H @@ -120,6 +121,7 @@ #define FM_PHYSCPU_INFO_CHIP_REV "chip_rev" #define FM_PHYSCPU_INFO_SOCKET_TYPE "socket_type" #define FM_PHYSCPU_INFO_CPU_ID "cpuid" +#define FM_PHYSCPU_INFO_CHIP_IDENTSTR "chip_identstr" #ifdef __cplusplus }
--- a/usr/src/boot/sys/boot/libcrypto/Makefile.com Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/boot/sys/boot/libcrypto/Makefile.com Sun May 19 11:36:48 2019 -0400 @@ -15,7 +15,7 @@ include $(SRC)/Makefile.master -CC= $(GCC_ROOT)/bin/gcc +CC= $(GNUC_ROOT)/bin/gcc COMDIR = ../../../../../common/crypto
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c Sun May 19 11:36:48 2019 -0400 @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ #include <unistd.h> @@ -86,6 +87,9 @@ TOPO_STABILITY_INTERNAL, a4fplus_chip_label}, { FSB2_CHIP_LBL, "Property method", 0, TOPO_STABILITY_INTERNAL, fsb2_chip_label}, + { TOPO_METH_REPLACED, TOPO_METH_REPLACED_DESC, + TOPO_METH_REPLACED_VERSION, TOPO_STABILITY_INTERNAL, + chip_fmri_replaced }, { NULL } }; @@ -143,7 +147,7 @@ static tnode_t * create_node(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth, char *name, - topo_instance_t inst, uint16_t smbios_id) + topo_instance_t inst, nvlist_t *cpu, uint16_t smbios_id) { nvlist_t *fmri; tnode_t *cnode; @@ -179,6 +183,17 @@ topo_mod_strfree(mod, (char *)serial); topo_mod_strfree(mod, (char *)part); topo_mod_strfree(mod, (char *)rev); + } else { + char *serial = NULL; + + if (nvlist_lookup_string(cpu, FM_PHYSCPU_INFO_CHIP_IDENTSTR, + &serial) == 0) { + if (nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, + serial) != 0) { + whinge(mod, NULL, + "create_node: nvlist_add_string failed\n"); + } + } } cnode = topo_node_bind(mod, pnode, name, inst, fmri); @@ -218,7 +233,7 @@ } if ((strand = create_node(mod, pnode, auth, STRAND_NODE_NAME, - strandid, chip_smbiosid)) == NULL) + strandid, cpu, chip_smbiosid)) == NULL) return (-1); /* @@ -339,7 +354,7 @@ } if ((core = topo_node_lookup(pnode, CORE_NODE_NAME, coreid)) == NULL) { if ((core = create_node(mod, pnode, auth, CORE_NODE_NAME, - coreid, chip_smbiosid)) == NULL) + coreid, cpu, chip_smbiosid)) == NULL) return (-1); /* @@ -508,7 +523,7 @@ if ((chip = topo_node_lookup(pnode, CHIP_NODE_NAME, chipid)) == NULL) { if ((chip = create_node(mod, pnode, auth, CHIP_NODE_NAME, - chipid, smbios_id)) == NULL) + chipid, cpu, smbios_id)) == NULL) return (-1); /* * Do not register XML map methods if SMBIOS can provide
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h Sun May 19 11:36:48 2019 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _CHIP_H @@ -182,6 +183,8 @@ nvlist_t *, nvlist_t **); extern int ntv_page_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); +extern int chip_fmri_replaced(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); extern int mem_asru_create(topo_mod_t *, nvlist_t *, nvlist_t **);
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_subr.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_subr.c Sun May 19 11:36:48 2019 -0400 @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ /* @@ -812,3 +813,54 @@ return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc == FMD_AGENT_RETIRE_DONE ? 1 : 0)); } + +/* + * Determine whether or not we believe a chip has been replaced. While it's + * tempting to just do a straight up comparison of the FMRI and its serial + * number, things are not that straightforward. + * + * The presence of a serial number on the CPU is not always guaranteed. It is + * possible that systems firmware can hide the information required to generate + * a synthesized serial number or that it is strictly not present. As such, we + * will only declare something replaced when both the old and current resource + * have a serial number present. If it is missing for whatever reason, then we + * cannot assume anything about a replacement having occurred. + * + * This logic applies regardless of whether or not we have an FM-aware SMBIOS. + */ +int +chip_fmri_replaced(topo_mod_t *mod, tnode_t *node, topo_version_t version, + nvlist_t *in, nvlist_t **out) +{ + nvlist_t *rsrc = NULL; + int err, ret; + char *old_serial, *new_serial; + + if (version > TOPO_METH_REPLACED_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_node_resource(node, &rsrc, &err) == -1) { + return (topo_mod_seterrno(mod, err)); + } + + if (nvlist_lookup_string(rsrc, FM_FMRI_HC_SERIAL_ID, + &new_serial) != 0) { + ret = FMD_OBJ_STATE_UNKNOWN; + goto out; + } + + if (nvlist_lookup_string(in, FM_FMRI_HC_SERIAL_ID, &old_serial) != 0) { + ret = FMD_OBJ_STATE_UNKNOWN; + goto out; + } + + if (strcmp(old_serial, new_serial) == 0) { + ret = FMD_OBJ_STATE_STILL_PRESENT; + } else { + ret = FMD_OBJ_STATE_REPLACED; + } + +out: + nvlist_free(rsrc); + return (set_retnvl(mod, out, TOPO_METH_REPLACED_RET, ret)); +}
--- a/usr/src/lib/libc/port/gen/strndup.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/libc/port/gen/strndup.c Sun May 19 11:36:48 2019 -0400 @@ -21,10 +21,12 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include "lint.h" #include <string.h> +#include <strings.h> #include <stdlib.h> #include <sys/types.h> @@ -38,7 +40,10 @@ char *s2; n = strnlen(s1, n); - if ((s2 = malloc(n + 1)) != NULL) - (void) strlcpy(s2, s1, n + 1); + if ((s2 = malloc(n + 1)) != NULL) { + bcopy(s1, s2, n); + s2[n] = '\0'; + } + return (s2); }
--- a/usr/src/lib/scsi/libscsi/common/libscsi.h Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/scsi/libscsi/common/libscsi.h Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #ifndef _LIBSCSI_H @@ -125,8 +126,11 @@ extern libscsi_action_t *libscsi_action_alloc(libscsi_hdl_t *, spc3_cmd_t, uint_t, void *, size_t); +extern libscsi_action_t *libscsi_action_alloc_vendor(libscsi_hdl_t *, + spc3_cmd_t, size_t, uint_t, void *, size_t); extern sam4_status_t libscsi_action_get_status(const libscsi_action_t *); extern void libscsi_action_set_timeout(libscsi_action_t *, uint32_t); +extern size_t libscsi_action_get_cdblen(const libscsi_action_t *); extern uint32_t libscsi_action_get_timeout(const libscsi_action_t *); extern uint_t libscsi_action_get_flags(const libscsi_action_t *); extern uint8_t *libscsi_action_get_cdb(const libscsi_action_t *);
--- a/usr/src/lib/scsi/libscsi/common/scsi_engine.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/scsi/libscsi/common/scsi_engine.c Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #include <sys/types.h> @@ -265,6 +266,18 @@ } /* + * Return the length of the CDB buffer associated with this action. Never + * fails. + */ +size_t +libscsi_action_get_cdblen(const libscsi_action_t *ap) +{ + const libscsi_action_impl_t *aip = (const libscsi_action_impl_t *)ap; + + return (aip->lsai_cdb_len); +} + +/* * Returns the address of the action's CDB. The CDB buffer is guaranteed to * be large enough to hold the complete CDB for the command specified when the * action was allocated. Therefore, changing the command/opcode portion of @@ -469,11 +482,11 @@ * If cmd is SPC3_CMD_REQUEST_SENSE, this flag must be clear. */ libscsi_action_t * -libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, - void *buf, size_t buflen) +libscsi_action_alloc_vendor(libscsi_hdl_t *hp, spc3_cmd_t cmd, size_t cdbsz, + uint_t flags, void *buf, size_t buflen) { libscsi_action_impl_t *aip; - size_t cdbsz, sz; + size_t sz; ptrdiff_t off; /* @@ -492,14 +505,14 @@ "in order to use a buffer"); return (NULL); } - if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { - (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " - "flag not allowed for request sense command"); + + if (cdbsz == 0) { + (void) libscsi_error(hp, ESCSI_BADLENGTH, "the supplied CDB " + "buffer size has an invalid length, it must be non-zero."); return (NULL); } - if ((sz = cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) - return (NULL); + sz = cdbsz; /* * If the caller has asked for a buffer but has not provided one, we @@ -549,6 +562,25 @@ return ((libscsi_action_t *)aip); } +libscsi_action_t * +libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, + void *buf, size_t buflen) +{ + size_t cdbsz; + + if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { + (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " + "flag not allowed for request sense command"); + return (NULL); + } + + if ((cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) + return (NULL); + + return (libscsi_action_alloc_vendor(hp, cmd, cdbsz, flags, buf, + buflen)); +} + void libscsi_action_free(libscsi_action_t *ap) {
--- a/usr/src/lib/scsi/libscsi/libscsi_api.map Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/scsi/libscsi/libscsi_api.map Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # $mapfile_version 2 @@ -40,6 +41,7 @@ libscsi_action_get_timeout { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_flags { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_cdb { TYPE = FUNCTION; FLAGS = extern }; + libscsi_action_get_cdblen { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_buffer { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_sense { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_set_status { TYPE = FUNCTION; FLAGS = extern };
--- a/usr/src/lib/scsi/libscsi/mapfile-vers Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/scsi/libscsi/mapfile-vers Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # # @@ -46,11 +47,13 @@ libscsi_open; libscsi_close; libscsi_action_alloc; + libscsi_action_alloc_vendor; libscsi_action_get_status; libscsi_action_set_status; libscsi_action_get_timeout; libscsi_action_set_timeout; libscsi_action_get_cdb; + libscsi_action_get_cdblen; libscsi_action_get_flags; libscsi_action_get_buffer; libscsi_action_get_sense;
--- a/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c Sun May 19 11:36:48 2019 -0400 @@ -22,10 +22,10 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2017, Joyent, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/scsi/impl/uscsi.h> #include <sys/scsi/generic/commands.h> @@ -150,7 +150,7 @@ cmd.uscsi_timeout = (short)libscsi_action_get_timeout(ap); cmd.uscsi_cdb = (caddr_t)cp; - cmd.uscsi_cdblen = libscsi_cmd_cdblen(hp, *cp); + cmd.uscsi_cdblen = libscsi_action_get_cdblen(ap); if (cmd.uscsi_cdblen == 0) return (-1);
--- a/usr/src/uts/i86pc/cpu/generic_cpu/gcpu.h Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/uts/i86pc/cpu/generic_cpu/gcpu.h Sun May 19 11:36:48 2019 -0400 @@ -190,6 +190,7 @@ kmutex_t gcpus_poll_lock; /* serialize pollers on the same chip */ uint32_t gcpus_actv_banks; /* MCA bank numbers active on chip */ volatile uint32_t gcpus_actv_cnt; /* active cpu count in this chip */ + char *gcpus_ident; /* ident string, if available */ }; struct gcpu_data {
--- a/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_main.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_main.c Sun May 19 11:36:48 2019 -0400 @@ -42,6 +42,7 @@ #include <sys/kmem.h> #include <sys/modctl.h> #include <sys/pghw.h> +#include <sys/x86_archext.h> #include "gcpu.h" @@ -52,6 +53,111 @@ #define GCPU_MAX_CHIPID 32 static struct gcpu_chipshared *gcpu_shared[GCPU_MAX_CHIPID]; +#ifdef DEBUG +int gcpu_id_disable = 0; +static const char *gcpu_id_override[GCPU_MAX_CHIPID] = { NULL }; +#endif + +/* + * This should probably be delegated to a CPU specific module. However, as those + * haven't been developed as actively for recent CPUs, we should revisit this + * when we do have it and move this out of gcpu. + * + * This method is only supported on Intel Xeon platforms. It relies on a + * combination of the PPIN and the cpuid signature. Both are required to form + * the synthetic ID. This ID is preceded with iv0-INTC to represent that this is + * an Intel synthetic ID. The iv0 is the illumos version zero of the ID for + * Intel. If we have a new scheme for a new generation of processors, then that + * should rev the version field, otherwise for a given processor, this synthetic + * ID should not change. For more information on PPIN and these MSRS, see the + * relevant processor external design specification. + */ +static char * +gcpu_init_ident_intc(cmi_hdl_t hdl) +{ + uint64_t msr; + + /* + * This list should be extended as new Intel Xeon family processors come + * out. + */ + switch (cmi_hdl_model(hdl)) { + case INTC_MODEL_IVYBRIDGE_XEON: + case INTC_MODEL_HASWELL_XEON: + case INTC_MODEL_BROADWELL_XEON: + case INTC_MODEL_BROADWELL_XEON_D: + case INTC_MODEL_SKYLAKE_XEON: + break; + default: + return (NULL); + } + + if (cmi_hdl_rdmsr(hdl, MSR_PLATFORM_INFO, &msr) != CMI_SUCCESS) { + return (NULL); + } + + if ((msr & MSR_PLATFORM_INFO_PPIN) == 0) { + return (NULL); + } + + if (cmi_hdl_rdmsr(hdl, MSR_PPIN_CTL, &msr) != CMI_SUCCESS) { + return (NULL); + } + + if ((msr & MSR_PPIN_CTL_ENABLED) == 0) { + if ((msr & MSR_PPIN_CTL_LOCKED) != 0) { + return (NULL); + } + + if (cmi_hdl_wrmsr(hdl, MSR_PPIN_CTL, MSR_PPIN_CTL_ENABLED) != + CMI_SUCCESS) { + return (NULL); + } + } + + if (cmi_hdl_rdmsr(hdl, MSR_PPIN, &msr) != CMI_SUCCESS) { + return (NULL); + } + + /* + * Now that we've read data, lock the PPIN. Don't worry about success or + * failure of this part, as we will have gotten everything that we need. + * It is possible that it locked open, for example. + */ + (void) cmi_hdl_wrmsr(hdl, MSR_PPIN_CTL, MSR_PPIN_CTL_LOCKED); + + return (kmem_asprintf("iv0-INTC-%x-%llx", cmi_hdl_chipsig(hdl), msr)); +} + +static void +gcpu_init_ident(cmi_hdl_t hdl, struct gcpu_chipshared *sp) +{ +#ifdef DEBUG + uint_t chipid; + + /* + * On debug, allow a developer to override the string to more + * easily test CPU autoreplace without needing to physically + * replace a CPU. + */ + if (gcpu_id_disable != 0) { + return; + } + + chipid = cmi_hdl_chipid(hdl); + if (gcpu_id_override[chipid] != NULL) { + sp->gcpus_ident = strdup(gcpu_id_override[chipid]); + return; + } +#endif + + switch (cmi_hdl_vendor(hdl)) { + case X86_VENDOR_Intel: + sp->gcpus_ident = gcpu_init_ident_intc(hdl); + default: + break; + } +} /* * Our cmi_init entry point, called during startup of each cpu instance. @@ -90,6 +196,8 @@ mutex_destroy(&sp->gcpus_poll_lock); kmem_free(sp, sizeof (struct gcpu_chipshared)); sp = osp; + } else { + gcpu_init_ident(hdl, sp); } } @@ -155,6 +263,26 @@ gcpu_mca_poll_start(hdl); } +const char * +gcpu_ident(cmi_hdl_t hdl) +{ + uint_t chipid; + struct gcpu_chipshared *sp; + + if (gcpu_disable) + return (NULL); + + chipid = cmi_hdl_chipid(hdl); + if (chipid >= GCPU_MAX_CHIPID) + return (NULL); + + if (cmi_hdl_getcmidata(hdl) == NULL) + return (NULL); + + sp = gcpu_shared[cmi_hdl_chipid(hdl)]; + return (sp->gcpus_ident); +} + #define GCPU_OP(ntvop, xpvop) ntvop cmi_api_ver_t _cmi_api_version = CMI_API_VERSION_3; @@ -172,6 +300,7 @@ GCPU_OP(gcpu_hdl_poke, NULL), /* cmi_hdl_poke */ gcpu_fini, /* cmi_fini */ GCPU_OP(NULL, gcpu_xpv_panic_callback), /* cmi_panic_callback */ + gcpu_ident /* cmi_ident */ }; static struct modlcpu modlcpu = {
--- a/usr/src/uts/intel/io/devfm_machdep.c Sun May 05 16:25:23 2019 -0400 +++ b/usr/src/uts/intel/io/devfm_machdep.c Sun May 19 11:36:48 2019 -0400 @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2018, Joyent, Inc. */ #include <sys/stat.h> @@ -150,6 +151,7 @@ { uint_t fm_chipid; uint16_t smbios_id; + const char *idstr; (void) nvlist_alloc(nvlp, NV_UNIQUE_NAME, KM_SLEEP); @@ -203,6 +205,16 @@ FM_PHYSCPU_INFO_CPU_ID, DATA_TYPE_INT32, (int32_t)cmi_hdl_logical_id(hdl), NULL); + + /* + * Do this separately so that way if there is no ident string we do not + * trigger an error. + */ + if ((idstr = cmi_hdl_chipident(hdl)) != NULL) { + fm_payload_set(*nvlp, + FM_PHYSCPU_INFO_CHIP_IDENTSTR, DATA_TYPE_STRING, idstr, + NULL); + } } /*ARGSUSED*/