Commit ae5f8ce3 authored by Mike Travis's avatar Mike Travis Committed by Borislav Petkov
Browse files

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: default avatarMike Travis <mike.travis@hpe.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarDimitri Sivanich <dimitri.sivanich@hpe.com>
Reviewed-by: default avatarSteve Wahl <steve.wahl@hpe.com>
Link: https://lkml.kernel.org/r/20201005203929.148656-13-mike.travis@hpe.com
parent 6a7cf55e
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -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 */
+54 −10
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * SGI NMI support routines
 *
 *  Copyright (c) 2009-2013 Silicon Graphics, Inc.  All Rights Reserved.
 * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved.
 * Copyright (c) Mike Travis
 */

@@ -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");
}