diff mbox series

[RFC,3/9] Add OPAL_REPORT_TRAP interface

Message ID 20200502113649.176329-4-npiggin@gmail.com
State New
Headers show
Series OPAL V4 | expand

Checks

Context Check Description
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (0f1937ef40fca0c3212a9dff1010b832a24fb063)

Commit Message

Nicholas Piggin May 2, 2020, 11:36 a.m. UTC
If the OS takes over OPAL's assert trap interrupts, it needs a way to
report them and get metadata. This API leaves room for a WARN type of
assertion without actually implementing one yet.

The changes behaviour of OPAL asserts when the OS is running. They don't
get put into an infinite loop, but rather try to kill the calling
process. Not sure if this is quite the best way to go yet, it's possible
we should be more recoverable like Linux BUG(), but there may be other
issues with that. There is a way to ask for a panic, but that's also not
used yet.

Again the benefit of trap over the inline assertion is (aside from the
above killing the process and attempting to continue), that a more
precise snapshot of registers can be reported, and the current stack is
not required (OS can use an alternative stack if it chooses).

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 core/utils.c       | 22 ++++++++++++++++++++++
 include/opal-api.h |  7 ++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/core/utils.c b/core/utils.c
index d53bcf374..2ec11255d 100644
--- a/core/utils.c
+++ b/core/utils.c
@@ -166,6 +166,28 @@  static int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsi
 }
 opal_call(OPAL_SYM_TO_ADDR, opal_sym_to_addr, 3);
 
+static int64_t opal_report_trap(uint64_t nip)
+{
+	struct trap_table_entry *tte;
+
+	for (tte = __trap_table_start; tte < __trap_table_end; tte++) {
+		if (tte->address == nip) {
+			prerror("< %s >\n", tte->message);
+			prerror("    .\n");
+			prerror("     .\n");
+			prerror("      .\n");
+			prerror("        OO__)\n");
+			prerror("       <\"__/\n");
+			prerror("        ^ ^\n");
+
+			return OPAL_TRAP_FATAL;
+		}
+	}
+
+	return OPAL_EMPTY;
+}
+opal_call(OPAL_REPORT_TRAP, opal_report_trap, 1);
+
 size_t snprintf_symbol(char *buf, size_t len, uint64_t addr)
 {
 	unsigned long saddr;
diff --git a/include/opal-api.h b/include/opal-api.h
index ab8fc721f..76d751c75 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -229,7 +229,8 @@ 
 #define OPAL_PHB_GET_OPTION			180
 #define OPAL_ADDR_TO_SYM			181
 #define OPAL_SYM_TO_ADDR			182
-#define OPAL_LAST				182
+#define OPAL_REPORT_TRAP			183
+#define OPAL_LAST				183
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
@@ -1257,6 +1258,10 @@  struct opal_mpipl_fadump {
 	struct	opal_mpipl_region region[];
 };
 
+#define OPAL_TRAP_FATAL	1
+#define OPAL_TRAP_WARN	2
+#define OPAL_TRAP_PANIC	3
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */