Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174548524
D55959.id173929.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D55959.id173929.diff
View Options
diff --git a/sys/arm64/arm64/mte.c b/sys/arm64/arm64/mte.c
--- a/sys/arm64/arm64/mte.c
+++ b/sys/arm64/arm64/mte.c
@@ -246,6 +246,38 @@
dstpage->md.pv_flags |= PV_MTE_TAGGED;
}
+bool
+mte_check_async(struct thread *td, struct trapframe *frame, bool syscall)
+{
+ ksiginfo_t ksi;
+
+ if (!MTE_HAS_TAG_CHECK)
+ return (false);
+
+ if ((mte_flags & MTE_HAS_ASYNC) == 0)
+ return (false);
+
+ if (atomic_testandclear_32(&td->td_md.md_flags,
+ MD_FLAG_MTE_ASYNC_FAULT_SHIFT)) {
+ /*
+ * If we are in a syscall adjust elr so the faulting
+ * instruction is the svc that entered the kernel.
+ */
+ if (syscall)
+ frame->tf_elr -= 4;
+
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGSEGV;
+ ksi.ksi_code = SEGV_MTEAERR;
+ ksi.ksi_addr = 0;
+ ksi.ksi_trapno = ESR_ELx_EXCEPTION(frame->tf_esr);
+ trapsignal(td, &ksi);
+ return (true);
+ }
+
+ return (false);
+}
+
void
mte_fork(struct thread *new_td, struct thread *orig_td)
{
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
@@ -88,7 +88,7 @@
u_long cnt_efirt_faults;
int print_efirt_faults;
-typedef void (abort_handler)(struct thread *, struct trapframe *, uint64_t,
+typedef bool (abort_handler)(struct thread *, struct trapframe *, uint64_t,
uint64_t, int);
static abort_handler align_abort;
@@ -198,20 +198,25 @@
static bool
svc_handler(struct thread *td, struct trapframe *frame)
{
+ /* TODO: This could cause issues for sigreturn? */
+ if (mte_check_async(td, frame, true)) {
+ userret(td, frame);
+ return (true);
+ }
if ((frame->tf_esr & ESR_ELx_ISS_MASK) == 0) {
syscallenter(td);
syscallret(td);
/* Skip userret as syscallret already called it */
return (true);
- } else {
- call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr,
- ESR_ELx_EXCEPTION(frame->tf_esr));
- return (false);
}
+
+ call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr,
+ ESR_ELx_EXCEPTION(frame->tf_esr));
+ return (false);
}
-static void
+static bool
align_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
uint64_t far, int lower)
{
@@ -224,17 +229,18 @@
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr,
ESR_ELx_EXCEPTION(frame->tf_esr));
+ return (true);
}
-static void
+static bool
external_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
uint64_t far, int lower)
{
if (lower) {
call_trapsignal(td, SIGBUS, BUS_OBJERR, (void *)far,
ESR_ELx_EXCEPTION(frame->tf_esr));
- return;
+ return (true);
}
/*
@@ -243,7 +249,7 @@
*/
if (test_bs_fault((void *)frame->tf_elr)) {
frame->tf_elr = (uint64_t)generic_bs_fault;
- return;
+ return (false);
}
print_registers(frame);
@@ -252,7 +258,7 @@
panic("Unhandled external data abort");
}
-static void
+static bool
tag_check_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
uint64_t far, int lower)
{
@@ -269,7 +275,7 @@
call_trapsignal(td, SIGSEGV, SEGV_MTESERR, (void *)far,
ESR_ELx_EXCEPTION(frame->tf_esr));
- userret(td, frame);
+ return (true);
}
/*
@@ -278,7 +284,7 @@
* Thus, stack-smashing detection with per-thread canaries must be disabled in
* this function.
*/
-static void NO_PERTHREAD_SSP
+static bool NO_PERTHREAD_SSP
data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
uint64_t far, int lower)
{
@@ -301,7 +307,7 @@
#ifdef KDB
if (kdb_active) {
kdb_reenter();
- return;
+ return (false);
}
#endif
@@ -334,7 +340,7 @@
case ISS_DATA_DFSC_TF_L2:
case ISS_DATA_DFSC_TF_L3:
if (pmap_klookup(far, NULL))
- return;
+ return (false);
break;
}
}
@@ -365,7 +371,7 @@
*/
if ((lower || map == kernel_map || pcb->pcb_onfault != 0) &&
pmap_fault(map->pmap, esr, fault_va) == KERN_SUCCESS)
- return;
+ return (false);
#ifdef INVARIANTS
if (td->td_md.md_spinlock_count != 0) {
@@ -411,12 +417,13 @@
if (lower) {
call_trapsignal(td, sig, ucode, (void *)far,
ESR_ELx_EXCEPTION(esr));
+ return (true);
} else {
bad_far:
if (td->td_intr_nesting_level == 0 &&
pcb->pcb_onfault != 0) {
frame->tf_elr = pcb->pcb_onfault;
- return;
+ return (false);
}
printf("Fatal data abort:\n");
@@ -431,13 +438,14 @@
frame);
kdb_why = KDB_WHY_UNSET;
if (handled)
- return;
+ return (false);
}
#endif
panic("vm_fault failed: 0x%lx error %d",
frame->tf_elr, error);
}
}
+ return (false);
}
static void
@@ -691,7 +699,7 @@
uint32_t exception;
uint64_t esr, far;
int dfsc;
- bool skip_userret;
+ bool has_sig, skip_userret;
/* Check we have a sane environment when entering from userland */
KASSERT((uintptr_t)get_pcpu() >= VM_MIN_KERNEL_ADDRESS,
@@ -720,6 +728,7 @@
__func__, exception, frame->tf_elr, esr);
skip_userret = false;
+ has_sig = false;
switch (exception) {
case EXCP_FP_SIMD:
#ifdef VFP
@@ -731,52 +740,58 @@
case EXCP_TRAP_FP:
#ifdef VFP
fpe_trap(td, (void *)frame->tf_elr, esr);
+ has_sig = true;
#else
panic("VFP exception in userland");
#endif
break;
case EXCP_SVE:
/* Returns true if this thread can use SVE */
- if (!sve_restore_state(td))
+ if (!sve_restore_state(td)) {
call_trapsignal(td, SIGILL, ILL_ILLTRP,
(void *)frame->tf_elr, exception);
+ has_sig = true;
+ }
break;
case EXCP_SVC32:
case EXCP_SVC64:
skip_userret = svc_handler(td, frame);
+ has_sig = true;
break;
case EXCP_INSN_ABORT_L:
case EXCP_DATA_ABORT_L:
case EXCP_DATA_ABORT:
dfsc = esr & ISS_DATA_DFSC_MASK;
if (dfsc < nitems(abort_handlers) &&
- abort_handlers[dfsc] != NULL)
- abort_handlers[dfsc](td, frame, esr, far, 1);
- else {
- print_registers(frame);
- print_gp_register("far", far);
- printf(" esr: 0x%.16lx\n", esr);
- panic("Unhandled EL0 %s abort: 0x%x",
- exception == EXCP_INSN_ABORT_L ? "instruction" :
- "data", dfsc);
+ abort_handlers[dfsc] != NULL) {
+ has_sig = abort_handlers[dfsc](td, frame, esr, far, 1);
+ } else {
+ call_trapsignal(td, SIGBUS, BUS_OBJERR,
+ (void *)frame->tf_elr, exception);
+ has_sig = true;
}
break;
case EXCP_UNKNOWN:
- if (!undef_insn(frame))
+ if (!undef_insn(frame)) {
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far,
exception);
+ has_sig = true;
+ }
break;
case EXCP_FPAC:
call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr,
exception);
+ has_sig = true;
break;
case EXCP_SP_ALIGN:
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp,
exception);
+ has_sig = true;
break;
case EXCP_PC_ALIGN:
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr,
exception);
+ has_sig = true;
break;
case EXCP_BRKPT_EL0:
case EXCP_BRK:
@@ -785,10 +800,12 @@
#endif /* COMPAT_FREEBSD32 */
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr,
exception);
+ has_sig = true;
break;
case EXCP_WATCHPT_EL0:
call_trapsignal(td, SIGTRAP, TRAP_TRACE, (void *)far,
exception);
+ has_sig = true;
break;
case EXCP_MSR:
/*
@@ -796,9 +813,11 @@
* instruction to access a special register userspace doesn't
* have access to.
*/
- if (!undef_insn(frame))
+ if (!undef_insn(frame)) {
call_trapsignal(td, SIGILL, ILL_PRVOPC,
(void *)frame->tf_elr, exception);
+ has_sig = true;
+ }
break;
case EXCP_SOFTSTP_EL0:
PROC_LOCK(td->td_proc);
@@ -811,10 +830,12 @@
PROC_UNLOCK(td->td_proc);
call_trapsignal(td, SIGTRAP, TRAP_TRACE,
(void *)frame->tf_elr, exception);
+ has_sig = true;
break;
case EXCP_BTI:
call_trapsignal(td, SIGILL, ILL_ILLOPC, (void *)frame->tf_elr,
exception);
+ has_sig = true;
break;
case EXCP_MOE:
handle_moe(td, frame, esr);
@@ -822,9 +843,12 @@
default:
call_trapsignal(td, SIGBUS, BUS_OBJERR, (void *)frame->tf_elr,
exception);
+ has_sig = true;
break;
}
+ if (!has_sig)
+ mte_check_async(td, frame, false);
if (!skip_userret)
userret(td, frame);
KASSERT(
diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h
--- a/sys/arm64/include/cpu.h
+++ b/sys/arm64/include/cpu.h
@@ -292,6 +292,7 @@
void mte_save_tags(vm_page_t, void *);
void mte_load_tags(vm_page_t, const void *);
void mte_copy_tags(vm_page_t, vm_page_t, vm_offset_t, vm_offset_t);
+bool mte_check_async(struct thread *, struct trapframe *, bool);
int mte_sysarch_ctrl(struct thread *, uint64_t);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 5, 2:25 AM (10 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40221992
Default Alt Text
D55959.id173929.diff (8 KB)
Attached To
Mode
D55959: arm64: Support async MTE
Attached
Detach File
Event Timeline
Log In to Comment