x86/platform/uv: Update for UV5 NMI MMR changes

The UV NMI MMR addresses and fields moved between UV4 and UV5
necessitating a rewrite of the UV NMI handler.  Adjust references
to accommodate those changes.

Signed-off-by: Mike Travis <mike.travis@hpe.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Reviewed-by: Steve Wahl <steve.wahl@hpe.com>
Link: https://lkml.kernel.org/r/20201005203929.148656-13-mike.travis@hpe.com
This commit is contained in:
Mike Travis 2020-10-05 15:39:28 -05:00 committed by Borislav Petkov
parent 6a7cf55e9f
commit ae5f8ce3c2
2 changed files with 54 additions and 23 deletions

View File

@ -734,19 +734,6 @@ extern void uv_nmi_setup_hubless(void);
#define UVH_NMI_MMR_SHIFT 63
#define UVH_NMI_MMR_TYPE "SCRATCH5"
/* Newer SMM NMI handler, not present in all systems */
#define UVH_NMI_MMRX UVH_EVENT_OCCURRED0
#define UVH_NMI_MMRX_CLEAR UVH_EVENT_OCCURRED0_ALIAS
#define UVH_NMI_MMRX_SHIFT UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT
#define UVH_NMI_MMRX_TYPE "EXTIO_INT0"
/* Non-zero indicates newer SMM NMI handler present */
#define UVH_NMI_MMRX_SUPPORTED UVH_EXTIO_INT0_BROADCAST
/* Indicates to BIOS that we want to use the newer SMM NMI handler */
#define UVH_NMI_MMRX_REQ UVH_BIOS_KERNEL_MMR_ALIAS_2
#define UVH_NMI_MMRX_REQ_SHIFT 62
struct uv_hub_nmi_s {
raw_spinlock_t nmi_lock;
atomic_t in_nmi; /* flag this node in UV NMI IRQ */

View File

@ -2,8 +2,8 @@
/*
* SGI NMI support routines
*
* Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) Mike Travis
* Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved.
* Copyright (c) Mike Travis
*/
#include <linux/cpu.h>
@ -54,6 +54,20 @@ static struct uv_hub_nmi_s **uv_hub_nmi_list;
DEFINE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi);
/* Newer SMM NMI handler, not present in all systems */
static unsigned long uvh_nmi_mmrx; /* UVH_EVENT_OCCURRED0/1 */
static unsigned long uvh_nmi_mmrx_clear; /* UVH_EVENT_OCCURRED0/1_ALIAS */
static int uvh_nmi_mmrx_shift; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_SHFT */
static int uvh_nmi_mmrx_mask; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_MASK */
static char *uvh_nmi_mmrx_type; /* "EXTIO_INT0" */
/* Non-zero indicates newer SMM NMI handler present */
static unsigned long uvh_nmi_mmrx_supported; /* UVH_EXTIO_INT0_BROADCAST */
/* Indicates to BIOS that we want to use the newer SMM NMI handler */
static unsigned long uvh_nmi_mmrx_req; /* UVH_BIOS_KERNEL_MMR_ALIAS_2 */
static int uvh_nmi_mmrx_req_shift; /* 62 */
/* UV hubless values */
#define NMI_CONTROL_PORT 0x70
#define NMI_DUMMY_PORT 0x71
@ -227,13 +241,43 @@ static inline bool uv_nmi_action_is(const char *action)
/* Setup which NMI support is present in system */
static void uv_nmi_setup_mmrs(void)
{
if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) {
uv_write_local_mmr(UVH_NMI_MMRX_REQ,
1UL << UVH_NMI_MMRX_REQ_SHIFT);
nmi_mmr = UVH_NMI_MMRX;
nmi_mmr_clear = UVH_NMI_MMRX_CLEAR;
nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT;
pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE);
/* First determine arch specific MMRs to handshake with BIOS */
if (UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK) {
uvh_nmi_mmrx = UVH_EVENT_OCCURRED0;
uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED0_ALIAS;
uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT;
uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK;
uvh_nmi_mmrx_type = "OCRD0-EXTIO_INT0";
uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
uvh_nmi_mmrx_req_shift = 62;
} else if (UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK) {
uvh_nmi_mmrx = UVH_EVENT_OCCURRED1;
uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED1_ALIAS;
uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT;
uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK;
uvh_nmi_mmrx_type = "OCRD1-EXTIO_INT0";
uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
uvh_nmi_mmrx_req_shift = 62;
} else {
pr_err("UV:%s:cannot find EVENT_OCCURRED*_EXTIO_INT0\n",
__func__);
return;
}
/* Then find out if new NMI is supported */
if (likely(uv_read_local_mmr(uvh_nmi_mmrx_supported))) {
uv_write_local_mmr(uvh_nmi_mmrx_req,
1UL << uvh_nmi_mmrx_req_shift);
nmi_mmr = uvh_nmi_mmrx;
nmi_mmr_clear = uvh_nmi_mmrx_clear;
nmi_mmr_pending = 1UL << uvh_nmi_mmrx_shift;
pr_info("UV: SMI NMI support: %s\n", uvh_nmi_mmrx_type);
} else {
nmi_mmr = UVH_NMI_MMR;
nmi_mmr_clear = UVH_NMI_MMR_CLEAR;
@ -1049,5 +1093,5 @@ void __init uv_nmi_setup_hubless(void)
/* Ensure NMI enabled in Processor Interface Reg: */
uv_reassert_nmi();
uv_register_nmi_notifier();
pr_info("UV: Hubless NMI enabled\n");
pr_info("UV: PCH NMI enabled\n");
}