hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/x86/platform/uv/uv_nmi.c
....@@ -1,22 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * SGI NMI support routines
34 *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
- *
18
- * Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved.
19
- * Copyright (c) Mike Travis
5
+ * (C) Copyright 2020 Hewlett Packard Enterprise Development LP
6
+ * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved.
7
+ * Copyright (c) Mike Travis
208 */
219
2210 #include <linux/cpu.h>
....@@ -66,6 +54,19 @@
6654 static struct uv_hub_nmi_s **uv_hub_nmi_list;
6755
6856 DEFINE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi);
57
+
58
+/* Newer SMM NMI handler, not present in all systems */
59
+static unsigned long uvh_nmi_mmrx; /* UVH_EVENT_OCCURRED0/1 */
60
+static unsigned long uvh_nmi_mmrx_clear; /* UVH_EVENT_OCCURRED0/1_ALIAS */
61
+static int uvh_nmi_mmrx_shift; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_SHFT */
62
+static char *uvh_nmi_mmrx_type; /* "EXTIO_INT0" */
63
+
64
+/* Non-zero indicates newer SMM NMI handler present */
65
+static unsigned long uvh_nmi_mmrx_supported; /* UVH_EXTIO_INT0_BROADCAST */
66
+
67
+/* Indicates to BIOS that we want to use the newer SMM NMI handler */
68
+static unsigned long uvh_nmi_mmrx_req; /* UVH_BIOS_KERNEL_MMR_ALIAS_2 */
69
+static int uvh_nmi_mmrx_req_shift; /* 62 */
6970
7071 /* UV hubless values */
7172 #define NMI_CONTROL_PORT 0x70
....@@ -240,13 +241,41 @@
240241 /* Setup which NMI support is present in system */
241242 static void uv_nmi_setup_mmrs(void)
242243 {
243
- if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) {
244
- uv_write_local_mmr(UVH_NMI_MMRX_REQ,
245
- 1UL << UVH_NMI_MMRX_REQ_SHIFT);
246
- nmi_mmr = UVH_NMI_MMRX;
247
- nmi_mmr_clear = UVH_NMI_MMRX_CLEAR;
248
- nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT;
249
- pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE);
244
+ /* First determine arch specific MMRs to handshake with BIOS */
245
+ if (UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK) {
246
+ uvh_nmi_mmrx = UVH_EVENT_OCCURRED0;
247
+ uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED0_ALIAS;
248
+ uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT;
249
+ uvh_nmi_mmrx_type = "OCRD0-EXTIO_INT0";
250
+
251
+ uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
252
+ uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
253
+ uvh_nmi_mmrx_req_shift = 62;
254
+
255
+ } else if (UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK) {
256
+ uvh_nmi_mmrx = UVH_EVENT_OCCURRED1;
257
+ uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED1_ALIAS;
258
+ uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT;
259
+ uvh_nmi_mmrx_type = "OCRD1-EXTIO_INT0";
260
+
261
+ uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
262
+ uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
263
+ uvh_nmi_mmrx_req_shift = 62;
264
+
265
+ } else {
266
+ pr_err("UV:%s:cannot find EVENT_OCCURRED*_EXTIO_INT0\n",
267
+ __func__);
268
+ return;
269
+ }
270
+
271
+ /* Then find out if new NMI is supported */
272
+ if (likely(uv_read_local_mmr(uvh_nmi_mmrx_supported))) {
273
+ uv_write_local_mmr(uvh_nmi_mmrx_req,
274
+ 1UL << uvh_nmi_mmrx_req_shift);
275
+ nmi_mmr = uvh_nmi_mmrx;
276
+ nmi_mmr_clear = uvh_nmi_mmrx_clear;
277
+ nmi_mmr_pending = 1UL << uvh_nmi_mmrx_shift;
278
+ pr_info("UV: SMI NMI support: %s\n", uvh_nmi_mmrx_type);
250279 } else {
251280 nmi_mmr = UVH_NMI_MMR;
252281 nmi_mmr_clear = UVH_NMI_MMR_CLEAR;
....@@ -560,7 +589,7 @@
560589 }
561590 }
562591
563
-/* Ping non-responding CPU's attemping to force them into the NMI handler */
592
+/* Ping non-responding CPU's attempting to force them into the NMI handler */
564593 static void uv_nmi_nr_cpus_ping(void)
565594 {
566595 int cpu;
....@@ -1062,5 +1091,5 @@
10621091 /* Ensure NMI enabled in Processor Interface Reg: */
10631092 uv_reassert_nmi();
10641093 uv_register_nmi_notifier();
1065
- pr_info("UV: Hubless NMI enabled\n");
1094
+ pr_info("UV: PCH NMI enabled\n");
10661095 }