Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 May 2025 12:50:21 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f68ca1421a1d - main - arm64: Remove kernel undef instruction support
Message-ID:  <202505121250.54CCoLqi082853@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=f68ca1421a1d54b29b2d2059b77459e00e86bba0

commit f68ca1421a1d54b29b2d2059b77459e00e86bba0
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-05-12 11:06:08 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-05-12 11:06:08 +0000

    arm64: Remove kernel undef instruction support
    
    Now we don't handle any undefined instructions in the kernel remove
    the support to handle them. The kernel should only ever execute valid
    instructions. The only case it needed to handle was an old emulator
    that is now well out of support, and the handler for this has been
    removed.
    
    Reviewed by:    harry.moulton_arm.com
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D50205
---
 sys/arm/arm/generic_timer.c   |  2 +-
 sys/arm64/arm64/identcpu.c    |  4 ++--
 sys/arm64/arm64/trap.c        |  6 ++----
 sys/arm64/arm64/undefined.c   | 37 ++++++++++++++-----------------------
 sys/arm64/include/undefined.h |  4 ++--
 5 files changed, 21 insertions(+), 32 deletions(-)

diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 685398117396..a82f8756b806 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -332,7 +332,7 @@ tmr_setup_user_access(void *arg __unused)
 #ifdef __aarch64__
 		if (TUNABLE_INT_FETCH("hw.emulate_phys_counter", &emulate) &&
 		    emulate != 0) {
-			install_undef_handler(true, cntpct_handler);
+			install_undef_handler(cntpct_handler);
 		}
 #endif
 	}
diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index 654a1b63d165..663c1a335114 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -2792,8 +2792,8 @@ identify_cpu_sysinit(void *dummy __unused)
 		panic("CPU does not support LSE atomic instructions");
 #endif
 
-	install_undef_handler(true, user_ctr_handler);
-	install_undef_handler(true, user_mrs_handler);
+	install_undef_handler(user_ctr_handler);
+	install_undef_handler(user_mrs_handler);
 }
 SYSINIT(identify_cpu, SI_SUB_CPU, SI_ORDER_MIDDLE, identify_cpu_sysinit, NULL);
 
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index fdcc38cd9a31..bed58095201a 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -578,8 +578,6 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
 		panic("FPAC kernel exception");
 		break;
 	case EXCP_UNKNOWN:
-		if (undef_insn(1, frame))
-			break;
 		print_registers(frame);
 		print_gp_register("far", far);
 		panic("Undefined instruction: %08x",
@@ -676,7 +674,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
 		}
 		break;
 	case EXCP_UNKNOWN:
-		if (!undef_insn(0, frame))
+		if (!undef_insn(frame))
 			call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far,
 			    exception);
 		userret(td, frame);
@@ -716,7 +714,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
 		 * instruction to access a special register userspace doesn't
 		 * have access to.
 		 */
-		if (!undef_insn(0, frame))
+		if (!undef_insn(frame))
 			call_trapsignal(td, SIGILL, ILL_PRVOPC,
 			    (void *)frame->tf_elr, exception);
 		userret(td, frame);
diff --git a/sys/arm64/arm64/undefined.c b/sys/arm64/arm64/undefined.c
index 1f44114af544..71c9b689aa78 100644
--- a/sys/arm64/arm64/undefined.c
+++ b/sys/arm64/arm64/undefined.c
@@ -83,10 +83,11 @@ struct undef_handler {
 };
 
 /*
- * Create two undefined instruction handler lists, one for userspace, one for
- * the kernel. This allows us to handle instructions that will trap
+ * Create the undefined instruction handler lists.
+ * This allows us to handle instructions that will trap.
  */
-LIST_HEAD(, undef_handler) undef_handlers[2];
+LIST_HEAD(, undef_handler) undef_handlers =
+    LIST_HEAD_INITIALIZER(undef_handlers);
 
 static bool
 arm_cond_match(uint32_t insn, struct trapframe *frame)
@@ -248,24 +249,20 @@ fault:
 void
 undef_init(void)
 {
-
-	LIST_INIT(&undef_handlers[0]);
-	LIST_INIT(&undef_handlers[1]);
-
 #ifdef COMPAT_FREEBSD32
-	install_undef_handler(true, gdb_trapper);
-	install_undef_handler(true, swp_emulate);
+	install_undef_handler(gdb_trapper);
+	install_undef_handler(swp_emulate);
 #endif
 }
 
 void *
-install_undef_handler(bool user, undef_handler_t func)
+install_undef_handler(undef_handler_t func)
 {
 	struct undef_handler *uh;
 
 	uh = malloc(sizeof(*uh), M_UNDEF, M_WAITOK);
 	uh->uh_handler = func;
-	LIST_INSERT_HEAD(&undef_handlers[user ? 0 : 1], uh, uh_link);
+	LIST_INSERT_HEAD(&undef_handlers, uh, uh_link);
 
 	return (uh);
 }
@@ -281,24 +278,18 @@ remove_undef_handler(void *handle)
 }
 
 int
-undef_insn(u_int el, struct trapframe *frame)
+undef_insn(struct trapframe *frame)
 {
 	struct undef_handler *uh;
 	uint32_t insn;
 	int ret;
 
-	KASSERT(el < 2, ("Invalid exception level %u", el));
-
-	if (el == 0) {
-		ret = fueword32((uint32_t *)frame->tf_elr, &insn);
-		/* Raise a SIGILL if we are unable to read the instruction */
-		if (ret != 0)
-			return (0);
-	} else {
-		insn = *(uint32_t *)frame->tf_elr;
-	}
+	ret = fueword32((uint32_t *)frame->tf_elr, &insn);
+	/* Raise a SIGILL if we are unable to read the instruction */
+	if (ret != 0)
+		return (0);
 
-	LIST_FOREACH(uh, &undef_handlers[el], uh_link) {
+	LIST_FOREACH(uh, &undef_handlers, uh_link) {
 		ret = uh->uh_handler(frame->tf_elr, insn, frame, frame->tf_esr);
 		if (ret)
 			return (1);
diff --git a/sys/arm64/include/undefined.h b/sys/arm64/include/undefined.h
index db5d0523e711..1370a648b17c 100644
--- a/sys/arm64/include/undefined.h
+++ b/sys/arm64/include/undefined.h
@@ -57,9 +57,9 @@ MRS_GET(CRm)
 MRS_GET(Op2)
 
 void undef_init(void);
-void *install_undef_handler(bool, undef_handler_t);
+void *install_undef_handler(undef_handler_t);
 void remove_undef_handler(void *);
-int undef_insn(u_int, struct trapframe *);
+int undef_insn(struct trapframe *);
 
 #endif /* _KERNEL */
 



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