git: 6f9e9eba984f - main - arm64: mte: handle synchronous tag check faults
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 16 Apr 2026 14:23:05 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=6f9e9eba984f5c8d8a022c0ec99f844a911687fe
commit 6f9e9eba984f5c8d8a022c0ec99f844a911687fe
Author: Harry Moulton <harry.moulton@arm.com>
AuthorDate: 2026-04-16 13:29:14 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-04-16 14:22:24 +0000
arm64: mte: handle synchronous tag check faults
The Memory Tagging Extension supports both Synchronous and Asynchronous
faults, called Tag Check Faults, which are configurable via
SCTLR_EL1.TCF0 for userspace and SCTLR_EL1.TCF for the kernel.
This commit adds support for handling synchronous tag check faults at
EL0 and EL1, although these are only enabled on a per-process basis in
userspace, kernel space does not enable tag check faults. A TCF in the
kernel will cause a kernel panic like any other virtual memory fault,
and a TCF in userspace will result in a SIGSEGV
Reviewed by: kib
Sponsored by: Arm Ltd
Signed-off-by: Harry Moulton <harry.moulton@arm.com>
Differential Revision: https://reviews.freebsd.org/D55947
---
sys/arm64/arm64/trap.c | 22 ++++++++++++++++++++++
sys/sys/signal.h | 2 ++
2 files changed, 24 insertions(+)
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index ad461aa1bffc..1178817108e5 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -94,6 +94,7 @@ typedef void (abort_handler)(struct thread *, struct trapframe *, uint64_t,
static abort_handler align_abort;
static abort_handler data_abort;
static abort_handler external_abort;
+static abort_handler tag_check_abort;
static abort_handler *abort_handlers[] = {
[ISS_DATA_DFSC_TF_L0] = data_abort,
@@ -106,6 +107,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_TAG] = tag_check_abort,
[ISS_DATA_DFSC_ALIGN] = align_abort,
[ISS_DATA_DFSC_EXT] = external_abort,
[ISS_DATA_DFSC_EXT_L0] = external_abort,
@@ -250,6 +252,26 @@ external_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
panic("Unhandled external data abort");
}
+static void
+tag_check_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
+ uint64_t far, int lower)
+{
+ /*
+ * A Tag Check Fault should be handled as a SIGSEGV if it occurs
+ * at EL0 and a kernel panic if at EL1.
+ */
+ if (!lower) {
+ print_registers(frame);
+ print_gp_register("far", far);
+ printf(" esr: 0x%.16lx\n", esr);
+ panic("Tag Check Fault");
+ }
+
+ call_trapsignal(td, SIGSEGV, SEGV_MTESERR, (void *)far,
+ ESR_ELx_EXCEPTION(frame->tf_esr));
+ userret(td, frame);
+}
+
/*
* It is unsafe to access the stack canary value stored in "td" until
* kernel map translation faults are handled, see the pmap_klookup() call below.
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index c0b65c0c9ef0..863b981c2b7a 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -307,6 +307,8 @@ struct __siginfo32 {
#define SEGV_ACCERR 2 /* Invalid permissions for mapped */
/* object. */
#define SEGV_PKUERR 100 /* x86: PKU violation */
+#define SEGV_MTEAERR 100 /* arm64: Asynchronous Arm MTE error */
+#define SEGV_MTESERR 101 /* arm64: Synchronous Arm MTE error */
/* codes for SIGFPE */
#define FPE_INTOVF 1 /* Integer overflow. */