Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Oct 2019 15:30:40 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354182 - head/sys/arm64/arm64
Message-ID:  <201910301530.x9UFUe8X091385@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Wed Oct 30 15:30:40 2019
New Revision: 354182
URL: https://svnweb.freebsd.org/changeset/base/354182

Log:
  ARM64: Treat alignment faults as bus errors
  
  Summary:
  ARM64 currently treats all data abort exceptions as page faults.  This
  can cause infinite loops on non-page fault faults, such as alignment faults.
  
  Since kernel-side alignment faults should be avoided, this adds support directly
  to the el0 fault handler, instead of the data_abort() handler.
  
  Test Plan: Tested on rpi3, with a misaligned ldm test.
  
  Reviewed by:	andrew
  Differential Revision:	https://reviews.freebsd.org/D22133

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

Modified: head/sys/arm64/arm64/trap.c
==============================================================================
--- head/sys/arm64/arm64/trap.c	Wed Oct 30 15:26:41 2019	(r354181)
+++ head/sys/arm64/arm64/trap.c	Wed Oct 30 15:30:40 2019	(r354182)
@@ -87,6 +87,7 @@ int (*dtrace_invop_jump_addr)(struct trapframe *);
 typedef void (abort_handler)(struct thread *, struct trapframe *, uint64_t,
     uint64_t, int);
 
+static abort_handler align_abort;
 static abort_handler data_abort;
 
 static abort_handler *abort_handlers[] = {
@@ -100,6 +101,7 @@ static abort_handler *abort_handlers[] = {
 	[ISS_DATA_DFSC_PF_L1] = data_abort,
 	[ISS_DATA_DFSC_PF_L2] = data_abort,
 	[ISS_DATA_DFSC_PF_L3] = data_abort,
+	[ISS_DATA_DFSC_ALIGN] = align_abort,
 };
 
 static __inline void
@@ -163,6 +165,17 @@ svc_handler(struct thread *td, struct trapframe *frame
 		call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr);
 		userret(td, frame);
 	}
+}
+
+static void
+align_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
+    uint64_t far, int lower)
+{
+	if (!lower)
+		panic("Misaligned access from kernel space!");
+
+	call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr);
+	userret(td, frame);
 }
 
 static void



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