svn commit: r347495 - in stable/12/sys: conf powerpc/include powerpc/powernv powerpc/powerpc

Justin Hibbits jhibbits at FreeBSD.org
Sat May 11 18:25:17 UTC 2019


Author: jhibbits
Date: Sat May 11 18:25:15 2019
New Revision: 347495
URL: https://svnweb.freebsd.org/changeset/base/347495

Log:
  MFC r345435:
  
  powernv: Add Hypervisor Maintenance Interrupt handler
  
  Attempting to build www/firefox on POWER9 resulted in a HMI exception being
  thrown, a fatal trap currently.  This is typically caused by timer facility
  errors, but examination of the Hypervisor Maintenance Exception Register
  (HMER) yielded only that an exception had recovered, with no information of
  the actual exception cause.
  
  When an HMI occurs, OPAL_HANDLE_HMI or OPAL_HANDLE_HMI2 must be called to
  handle the exception at the firmware level.  If the exception is handled, we
  can continue.
  
  This adds only the preliminary handler, enough to prevent package building
  from panicking.  An enhancement in the future is to use the flags returned
  by OPAL_HANDLE_HMI2 to print more useful error messages, and log maintenance
  events.

Added:
  stable/12/sys/powerpc/powernv/opal_hmi.c
     - copied unchanged from r345435, head/sys/powerpc/powernv/opal_hmi.c
Modified:
  stable/12/sys/conf/files.powerpc
  stable/12/sys/powerpc/include/spr.h
  stable/12/sys/powerpc/include/trap.h
  stable/12/sys/powerpc/powernv/opal.h
  stable/12/sys/powerpc/powerpc/interrupt.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/conf/files.powerpc
==============================================================================
--- stable/12/sys/conf/files.powerpc	Sat May 11 17:59:13 2019	(r347494)
+++ stable/12/sys/conf/files.powerpc	Sat May 11 18:25:15 2019	(r347495)
@@ -193,6 +193,7 @@ powerpc/powermac/vcoregpio.c	optional	powermac 
 powerpc/powernv/opal.c		optional	powernv
 powerpc/powernv/opal_console.c	optional	powernv
 powerpc/powernv/opal_dev.c	optional	powernv
+powerpc/powernv/opal_hmi.c	optional	powernv
 powerpc/powernv/opal_i2c.c	optional	iicbus fdt powernv
 powerpc/powernv/opal_i2cm.c	optional	iicbus fdt powernv
 powerpc/powernv/opal_pci.c	optional	powernv pci

Modified: stable/12/sys/powerpc/include/spr.h
==============================================================================
--- stable/12/sys/powerpc/include/spr.h	Sat May 11 17:59:13 2019	(r347494)
+++ stable/12/sys/powerpc/include/spr.h	Sat May 11 18:25:15 2019	(r347495)
@@ -242,6 +242,8 @@
 #define	  LPCR_PECE_ME            (1ULL << 12) /* Machine Check and Hypervisor */
                                                /* Maintenance exceptions */
 #define	SPR_LPID		0x13f	/* Logical Partitioning Control */
+#define	SPR_HMER		0x150	/* Hypervisor Maintenance Exception Register */
+#define	SPR_HMEER		0x151	/* Hypervisor Maintenance Exception Enable Register */
 
 #define	SPR_PTCR		0x1d0	/* Partition Table Control Register */
 #define	SPR_SPEFSCR		0x200	/* ..8 Signal Processing Engine FSCR. */

Modified: stable/12/sys/powerpc/include/trap.h
==============================================================================
--- stable/12/sys/powerpc/include/trap.h	Sat May 11 17:59:13 2019	(r347494)
+++ stable/12/sys/powerpc/include/trap.h	Sat May 11 18:25:15 2019	(r347495)
@@ -150,6 +150,7 @@
 #ifndef LOCORE
 struct	trapframe;
 struct	pcb;
+extern int	(*hmi_handler)(struct trapframe *);
 void    trap(struct trapframe *);
 int	ppc_instr_emulate(struct trapframe *, struct pcb *);
 #endif

Modified: stable/12/sys/powerpc/powernv/opal.h
==============================================================================
--- stable/12/sys/powerpc/powernv/opal.h	Sat May 11 17:59:13 2019	(r347494)
+++ stable/12/sys/powerpc/powernv/opal.h	Sat May 11 18:25:15 2019	(r347495)
@@ -71,8 +71,10 @@ int opal_call(uint64_t token, ...);
 #define	OPAL_PCI_MAP_PE_DMA_WINDOW_REAL	45
 #define	OPAL_RETURN_CPU			69
 #define	OPAL_REINIT_CPUS		70
+#define	OPAL_CHECK_TOKEN		80
 #define	OPAL_CHECK_ASYNC_COMPLETION	86
 #define	OPAL_SENSOR_READ		88
+#define	OPAL_HANDLE_HMI			98
 #define	OPAL_IPMI_SEND			107
 #define	OPAL_IPMI_RECV			108
 #define	OPAL_I2C_REQUEST		109
@@ -85,6 +87,7 @@ int opal_call(uint64_t token, ...);
 #define	OPAL_SENSOR_GROUP_CLEAR		156
 #define	OPAL_SENSOR_READ_U64		162
 #define	OPAL_SENSOR_GROUP_ENABLE	163
+#define	OPAL_HANDLE_HMI2		166
 
 /* For OPAL_PCI_SET_PE */
 #define	OPAL_UNMAP_PE			0
@@ -114,6 +117,15 @@ int opal_call(uint64_t token, ...);
 #define	OPAL_BUSY_EVENT			-12
 #define	OPAL_ASYNC_COMPLETION		-15
 #define	OPAL_EMPTY			-16
+
+#define	OPAL_TOKEN_ABSENT		0
+#define	OPAL_TOKEN_PRESENT		1
+
+#define	OPAL_HMI_FLAGS_TB_RESYNC	(1ull << 0)
+#define	OPAL_HMI_FLAGS_DEC_LOST		(1ull << 1)
+#define	OPAL_HMI_FLAGS_HDEC_LOST	(1ull << 2)
+#define	OPAL_HMI_FLAGS_TOD_TB_FAIL	(1ull << 3)
+#define	OPAL_HMI_FLAGS_NEW_EVENT	(1ull << 63)
 
 struct opal_msg {
 	uint32_t msg_type;

Copied: stable/12/sys/powerpc/powernv/opal_hmi.c (from r345435, head/sys/powerpc/powernv/opal_hmi.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/sys/powerpc/powernv/opal_hmi.c	Sat May 11 18:25:15 2019	(r347495, copy of r345435, head/sys/powerpc/powernv/opal_hmi.c)
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2019 Justin Hibbits
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/spr.h>
+#include <machine/trap.h>
+#include "opal.h"
+
+static int
+opal_hmi_handler2(struct trapframe *frame)
+{
+	int64_t flags;
+	int err;
+
+	err = opal_call(OPAL_HANDLE_HMI2, vtophys(&flags));
+
+	/* XXX: At some point, handle the flags outvar. */
+	if (err == OPAL_SUCCESS) {
+		mtspr(SPR_HMER, 0);
+		return (0);
+	}
+
+	printf("HMI handler failed!  OPAL error code: %d\n", err);
+
+	return (-1);
+}
+
+static int
+opal_hmi_handler(struct trapframe *frame)
+{
+	int err;
+
+	err = opal_call(OPAL_HANDLE_HMI);
+
+	if (err == OPAL_SUCCESS) {
+		mtspr(SPR_HMER, 0);
+		return (0);
+	}
+
+	printf("HMI handler failed!  OPAL error code: %d\n", err);
+
+	return (-1);
+}
+
+static void
+opal_setup_hmi(void *data)
+{
+	/* This only works for OPAL, so first make sure we have it. */
+	if (opal_check() != 0)
+		return;
+
+	if (opal_call(OPAL_CHECK_TOKEN, OPAL_HANDLE_HMI2) == OPAL_TOKEN_PRESENT)
+		hmi_handler = opal_hmi_handler2;
+	else if (opal_call(OPAL_CHECK_TOKEN, OPAL_HANDLE_HMI) == OPAL_TOKEN_PRESENT)
+		hmi_handler = opal_hmi_handler;
+	else {
+		printf("Warning: No OPAL HMI handler found.\n");
+		return;
+	}
+
+	if (bootverbose)
+		printf("Installed OPAL HMI handler.\n");
+}
+
+SYSINIT(opal_setup_hmi, SI_SUB_HYPERVISOR, SI_ORDER_ANY, opal_setup_hmi, NULL);

Modified: stable/12/sys/powerpc/powerpc/interrupt.c
==============================================================================
--- stable/12/sys/powerpc/powerpc/interrupt.c	Sat May 11 17:59:13 2019	(r347494)
+++ stable/12/sys/powerpc/powerpc/interrupt.c	Sat May 11 18:25:15 2019	(r347495)
@@ -32,6 +32,7 @@
  */
 
 #include "opt_hwpmc_hooks.h"
+#include "opt_platform.h"
 
 #include <sys/cdefs.h>                  /* RCS ID & Copyright macro defns */
 
@@ -68,6 +69,10 @@
 
 #include "pic_if.h"
 
+#ifdef POWERNV
+int (*hmi_handler)(struct trapframe *);
+#endif
+
 /*
  * A very short dispatch, to try and maximise assembler code use
  * between all exception types. Maybe 'true' interrupts should go
@@ -117,6 +122,13 @@ powerpc_interrupt(struct trapframe *framep)
 			pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, framep);
 		critical_exit();
 		break;
+#endif
+
+#ifdef POWERNV
+	case EXC_HMI:
+		if (hmi_handler != 0 && hmi_handler(framep) == 0)
+			break;
+		/* If no handler, or failure to handle, just drop to trap. */
 #endif
 
 	default:


More information about the svn-src-all mailing list