svn commit: r286721 - head/sys/arm64/arm64

Ed Maste emaste at FreeBSD.org
Thu Aug 13 13:21:01 UTC 2015


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


More information about the svn-src-head mailing list