diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -94,6 +94,7 @@ 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 @@ [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 @@ 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 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -307,6 +307,8 @@ #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. */