Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Aug 2015 13:21:00 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286721 - head/sys/arm64/arm64
Message-ID:  <201508131321.t7DDL0eh035844@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Thu Aug 13 13:21:00 2015
New Revision: 286721
URL: https://svnweb.freebsd.org/changeset/base/286721

Log:
  arm64: turn unknown el0 exception into a SIGILL
  
  It seems we get EXCP_UNKNOWN from QEMU when executing zeroed memory.
  Print a register dump here and signal illegal instruction. Also print
  a register dump for other invalid exceptions, before panic.
  
  Reviewed by:	andrew
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D3370

Modified:
  head/sys/arm64/arm64/trap.c

Modified: head/sys/arm64/arm64/trap.c
==============================================================================
--- head/sys/arm64/arm64/trap.c	Thu Aug 13 13:20:29 2015	(r286720)
+++ head/sys/arm64/arm64/trap.c	Thu Aug 13 13:21:00 2015	(r286721)
@@ -229,6 +229,21 @@ data_abort(struct trapframe *frame, uint
 		userret(td, frame);
 }
 
+static void
+print_registers(struct trapframe *frame)
+{
+	u_int reg;
+
+	for (reg = 0; reg < 31; reg++) {
+		printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg,
+		    frame->tf_x[reg]);
+	}
+	printf("  sp: %16lx\n", frame->tf_sp);
+	printf("  lr: %16lx\n", frame->tf_lr);
+	printf(" elr: %16lx\n", frame->tf_elr);
+	printf("spsr: %16lx\n", frame->tf_spsr);
+}
+
 void
 do_el1h_sync(struct trapframe *frame)
 {
@@ -265,6 +280,7 @@ do_el1h_sync(struct trapframe *frame)
 	switch(exception) {
 	case EXCP_FP_SIMD:
 	case EXCP_TRAP_FP:
+		print_registers(frame);
 		panic("VFP exception in the kernel");
 	case EXCP_DATA_ABORT:
 		data_abort(frame, esr, 0);
@@ -286,11 +302,30 @@ do_el1h_sync(struct trapframe *frame)
 #endif
 		break;
 	default:
+		print_registers(frame);
 		panic("Unknown kernel exception %x esr_el1 %lx\n", exception,
 		    esr);
 	}
 }
 
+/*
+ * We get EXCP_UNKNOWN from QEMU when executing zeroed memory. For now turn
+ * this into a SIGILL.
+ */
+static void
+el0_excp_unknown(struct trapframe *frame)
+{
+	struct thread *td;
+	uint64_t far;
+
+	td = curthread;
+	far = READ_SPECIALREG(far_el1);
+	printf("el0 EXCP_UNKNOWN exception\n");
+	print_registers(frame);
+	call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far);
+	userret(td, frame);
+}
+
 void
 do_el0_sync(struct trapframe *frame)
 {
@@ -332,7 +367,11 @@ do_el0_sync(struct trapframe *frame)
 	case EXCP_DATA_ABORT:
 		data_abort(frame, esr, 1);
 		break;
+	case EXCP_UNKNOWN:
+		el0_excp_unknown(frame);
+		break;
 	default:
+		print_registers(frame);
 		panic("Unknown userland exception %x esr_el1 %lx\n", exception,
 		    esr);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508131321.t7DDL0eh035844>