diff options
author | John Levon <john.levon@joyent.com> | 2019-03-27 09:43:53 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2019-03-27 09:44:19 +0000 |
commit | dc238736b55afd3a593354a3a7233204ca25b27c (patch) | |
tree | 04204895aae0eb6d7e95288427a73141028b745a | |
parent | 5ffb784f5a3c76e1a0dfe2349748d3a9a8f33082 (diff) | |
download | illumos-joyent-dc238736b55afd3a593354a3a7233204ca25b27c.tar.gz |
OS-7675 would like a way to set NMI behavior at boot
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/uts/i86pc/io/pcplusmp/apic_common.c | 41 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/fakebop.c | 18 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mlsetup.c | 20 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/apic_common.h | 10 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/bootconf.h | 4 |
5 files changed, 78 insertions, 15 deletions
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic_common.c b/usr/src/uts/i86pc/io/pcplusmp/apic_common.c index 30644ad12a..b1a0b9c3d0 100644 --- a/usr/src/uts/i86pc/io/pcplusmp/apic_common.c +++ b/usr/src/uts/i86pc/io/pcplusmp/apic_common.c @@ -23,7 +23,7 @@ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2018 Joyent, Inc. + * Copyright 2019, Joyent, Inc. * Copyright (c) 2016, 2017 by Delphix. All rights reserved. */ @@ -808,6 +808,8 @@ gethrtime_again: void apic_nmi_intr(caddr_t arg, struct regs *rp) { + int action = nmi_action; + if (apic_shutdown_processors) { apic_disable_local_apic(); return; @@ -819,18 +821,41 @@ apic_nmi_intr(caddr_t arg, struct regs *rp) return; apic_num_nmis++; - if (apic_kmdb_on_nmi && psm_debugger()) { - debug_enter("NMI received: entering kmdb\n"); - } else if (apic_panic_on_nmi) { - /* Keep panic from entering kmdb. */ - nopanicdebug = 1; - panic("NMI received\n"); - } else { + /* + * "nmi_action" always over-rides the older way of doing this, unless we + * can't actually drop into kmdb when requested. + */ + if (action == NMI_ACTION_KMDB && !psm_debugger()) + action = NMI_ACTION_UNSET; + + if (action == NMI_ACTION_UNSET) { + if (apic_kmdb_on_nmi && psm_debugger()) + action = NMI_ACTION_KMDB; + else if (apic_panic_on_nmi) + action = NMI_ACTION_PANIC; + else + action = NMI_ACTION_IGNORE; + } + + switch (action) { + case NMI_ACTION_IGNORE: /* * prom_printf is the best shot we have of something which is * problem free from high level/NMI type of interrupts */ prom_printf("NMI received\n"); + break; + + case NMI_ACTION_PANIC: + /* Keep panic from entering kmdb. */ + nopanicdebug = 1; + panic("NMI received\n"); + break; + + case NMI_ACTION_KMDB: + default: + debug_enter("NMI received: entering kmdb\n"); + break; } lock_clear(&apic_nmi_lock); diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c index 7bbd6b369f..8ba2e74681 100644 --- a/usr/src/uts/i86pc/os/fakebop.c +++ b/usr/src/uts/i86pc/os/fakebop.c @@ -2915,10 +2915,8 @@ boot_compinfo(int fd, struct compinfo *cbp) return (0); } -#define BP_MAX_STRLEN 32 - /* - * Get value for given boot property + * Get an integer value for given boot property */ int bootprop_getval(const char *prop_name, u_longlong_t *prop_value) @@ -2928,7 +2926,7 @@ bootprop_getval(const char *prop_name, u_longlong_t *prop_value) u_longlong_t value; boot_prop_len = BOP_GETPROPLEN(bootops, prop_name); - if (boot_prop_len < 0 || boot_prop_len > sizeof (str) || + if (boot_prop_len < 0 || boot_prop_len >= sizeof (str) || BOP_GETPROP(bootops, prop_name, str) < 0 || kobj_getvalue(str, &value) == -1) return (-1); @@ -2938,3 +2936,15 @@ bootprop_getval(const char *prop_name, u_longlong_t *prop_value) return (0); } + +int +bootprop_getstr(const char *prop_name, char *buf, size_t buflen) +{ + int boot_prop_len = BOP_GETPROPLEN(bootops, prop_name); + + if (boot_prop_len < 0 || boot_prop_len >= buflen || + BOP_GETPROP(bootops, prop_name, buf) < 0) + return (-1); + + return (0); +} diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c index 7c17aab541..94d4695141 100644 --- a/usr/src/uts/i86pc/os/mlsetup.c +++ b/usr/src/uts/i86pc/os/mlsetup.c @@ -23,7 +23,7 @@ * * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 by Delphix. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2019, Joyent, Inc. */ /* * Copyright (c) 2010, Intel Corporation. @@ -61,6 +61,8 @@ #include <sys/archsystm.h> #include <sys/promif.h> #include <sys/pci_cfgspace.h> +#include <sys/apic.h> +#include <sys/apic_common.h> #include <sys/bootvfs.h> #include <sys/tsc.h> #ifdef __xpv @@ -79,6 +81,8 @@ extern uint32_t cpuid_feature_ecx_exclude; extern uint32_t cpuid_feature_edx_include; extern uint32_t cpuid_feature_edx_exclude; +int nmi_action = NMI_ACTION_UNSET; + /* * Set console mode */ @@ -103,6 +107,7 @@ void mlsetup(struct regs *rp) { u_longlong_t prop_value; + char prop_str[BP_MAX_STRLEN]; extern struct classfuncs sys_classfuncs; extern disp_t cpu0_disp; extern char t0stack[]; @@ -149,6 +154,19 @@ mlsetup(struct regs *rp) cpuid_feature_edx_exclude = (uint32_t)prop_value; #if !defined(__xpv) + if (bootprop_getstr("nmi", prop_str, sizeof (prop_str)) == 0) { + if (strcmp(prop_str, "ignore") == 0) { + nmi_action = NMI_ACTION_IGNORE; + } else if (strcmp(prop_str, "panic") == 0) { + nmi_action = NMI_ACTION_PANIC; + } else if (strcmp(prop_str, "kmdb") == 0) { + nmi_action = NMI_ACTION_KMDB; + } else { + prom_printf("unix: ignoring unknown nmi=%s\n", + prop_str); + } + } + /* * Check to see if KPTI has been explicitly enabled or disabled. * We have to check this before init_desctbls(). diff --git a/usr/src/uts/i86pc/sys/apic_common.h b/usr/src/uts/i86pc/sys/apic_common.h index 03e851a4dc..58b9bb93a6 100644 --- a/usr/src/uts/i86pc/sys/apic_common.h +++ b/usr/src/uts/i86pc/sys/apic_common.h @@ -23,7 +23,7 @@ * Copyright (c) 2017 by Delphix. All rights reserved. */ /* - * Copyright 2018 Joyent, Inc. + * Copyright 2019, Joyent, Inc. */ #ifndef _SYS_APIC_COMMON_H @@ -155,7 +155,6 @@ extern lock_t apic_nmi_lock; extern lock_t apic_error_lock; /* Patchable global variables. */ -extern int apic_kmdb_on_nmi; /* 0 - no, 1 - yes enter kmdb */ extern uint32_t apic_divide_reg_init; /* 0 - divide by 2 */ extern apic_intrmap_ops_t *apic_vt_ops; @@ -202,6 +201,13 @@ extern int apic_msix_enable; extern uint32_t apic_get_localapicid(uint32_t cpuid); extern uchar_t apic_get_ioapicid(uchar_t ioapicindex); +#define NMI_ACTION_UNSET (0) +#define NMI_ACTION_PANIC (1) +#define NMI_ACTION_IGNORE (2) +#define NMI_ACTION_KMDB (3) + +extern int nmi_action; + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/intel/sys/bootconf.h b/usr/src/uts/intel/sys/bootconf.h index 27a89206cf..f0ade9d94d 100644 --- a/usr/src/uts/intel/sys/bootconf.h +++ b/usr/src/uts/intel/sys/bootconf.h @@ -23,6 +23,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2016 Nexenta Systems, Inc. + * Copyright 2019, Joyent, Inc. */ #ifndef _SYS_BOOTCONF_H @@ -46,6 +47,8 @@ extern "C" { #endif +#define BP_MAX_STRLEN 32 + /* * Boot property names */ @@ -243,6 +246,7 @@ extern void bop_panic(const char *, ...) extern void boot_prop_finish(void); extern int bootprop_getval(const char *, u_longlong_t *); +extern int bootprop_getstr(const char *, char *, size_t); /* * Back door to fakebop.c to get physical memory allocated. |