diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-07-09 18:33:59 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-07-21 15:50:52 -0700 |
commit | 7d91603476b740ff8f4c917d71ee5884ab39cb60 (patch) | |
tree | c02be81031cbbc3869a0d974925ff4dbc242ee2f | |
parent | 777a71cfc7f5d1d0c739d58698fe598f2cdb6f2d (diff) | |
download | illumos-joyent-7d91603476b740ff8f4c917d71ee5884ab39cb60.tar.gz |
12966 imc driver blew up on missing channel
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: Paul Winder <paul@winder.uk.net>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/uts/i86pc/io/imc/imc.c | 39 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/imc/imc.h | 5 |
2 files changed, 42 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/io/imc/imc.c b/usr/src/uts/i86pc/io/imc/imc.c index 25ba86061b..e1dbfbfc2e 100644 --- a/usr/src/uts/i86pc/io/imc/imc.c +++ b/usr/src/uts/i86pc/io/imc/imc.c @@ -932,6 +932,40 @@ imc_fixup_stubs(imc_t *imc) } /* + * In the wild we've hit a few odd cases where not all devices are exposed that + * we might expect by firmware. In particular we've seen and validate the + * following cases: + * + * o We don't find all of the channel devices that we expect, e.g. we have the + * stubs for channels 1-3, but not 0. That has been seen on an Intel S2600CW + * with an E5-2630v3. + */ +static boolean_t +imc_validate_stubs(imc_t *imc) +{ + for (uint_t sock = 0; sock < imc->imc_nsockets; sock++) { + imc_socket_t *socket = &imc->imc_sockets[sock]; + + for (uint_t mc = 0; mc < socket->isock_nimc; mc++) { + imc_mc_t *mcp = &socket->isock_imcs[mc]; + + for (uint_t chan = 0; chan < mcp->icn_nchannels; + chan++) { + if (mcp->icn_channels[chan].ich_desc == NULL) { + dev_err(imc->imc_dip, CE_WARN, + "!missing device for socket %u/" + "imc %u/channel %u", sock, mc, + chan); + return (B_FALSE); + } + } + } + } + + return (B_TRUE); +} + +/* * Attempt to map all of the discovered sockets to the corresponding APIC based * socket. We do these mappings by getting the node id of the socket and * adjusting it to make sure that no home agent is present in it. We use the @@ -2194,6 +2228,11 @@ imc_attach_complete(void *arg) goto done; } + if (!imc_validate_stubs(imc)) { + imc->imc_flags |= IMC_F_VALIDATE_FAILED; + goto done; + } + imc_fixup_stubs(imc); imc_map_sockets(imc); diff --git a/usr/src/uts/i86pc/io/imc/imc.h b/usr/src/uts/i86pc/io/imc/imc.h index 7d07be20af..5f3def4930 100644 --- a/usr/src/uts/i86pc/io/imc/imc.h +++ b/usr/src/uts/i86pc/io/imc/imc.h @@ -500,12 +500,13 @@ typedef enum { IMC_F_SCAN_COMPLETE = (1 << 2), IMC_F_ATTACH_DISPATCHED = (1 << 3), IMC_F_ATTACH_COMPLETE = (1 << 4), - IMC_F_MCREG_FAILED = (1 << 5) + IMC_F_MCREG_FAILED = (1 << 5), + IMC_F_VALIDATE_FAILED = (1 << 6) } imc_flags_t; #define IMC_F_ALL_FLAGS (IMC_F_UNSUP_PLATFORM | IMC_F_SCAN_DISPATCHED | \ IMC_F_SCAN_COMPLETE | IMC_F_ATTACH_DISPATCHED | IMC_F_ATTACH_COMPLETE | \ - IMC_F_MCREG_FAILED) + IMC_F_MCREG_FAILED | IMC_F_VALIDATE_FAILED) typedef enum imc_dimm_type { IMC_DIMM_UNKNOWN, |