diff options
| author | Andrew Turner <andrew@FreeBSD.org> | 2026-03-05 14:27:37 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2026-03-05 15:13:30 +0000 |
| commit | 570b8b25753c2be7657f0e906cb5a89c7f35b56e (patch) | |
| tree | 18870b76bbdb492c49c4dbef0b19f39c2de78fb4 | |
| parent | 5d757312ad591aae26b39943f113ebf3819718da (diff) | |
arm64: Use a canonical address when TBI is enabled
When Top Byte Ignore (TBI) is enabled in a processor we need to pass
a canonical address to the vm subsystem.
Reviewed by: alc, kib
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D55619
| -rw-r--r-- | sys/arm64/arm64/trap.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index b3c68fa4826f..3ce0b29f0b82 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -262,6 +262,7 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, { struct vm_map *map; struct pcb *pcb; + vm_offset_t fault_va; vm_prot_t ftype; int error, sig, ucode; #ifdef KDB @@ -282,8 +283,11 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, } #endif + fault_va = far; if (lower) { map = &td->td_proc->p_vmspace->vm_map; + if ((td->td_proc->p_md.md_tcr & TCR_TBI0) != 0) + fault_va = ADDR_MAKE_CANONICAL(far); } else if (!ADDR_IS_CANONICAL(far)) { /* We received a TBI/PAC/etc. fault from the kernel */ error = KERN_INVALID_ADDRESS; @@ -338,7 +342,7 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, * or pmap_fault() will recurse on that lock. */ if ((lower || map == kernel_map || pcb->pcb_onfault != 0) && - pmap_fault(map->pmap, esr, far) == KERN_SUCCESS) + pmap_fault(map->pmap, esr, fault_va) == KERN_SUCCESS) return; #ifdef INVARIANTS @@ -379,7 +383,8 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, } /* Fault in the page. */ - error = vm_fault_trap(map, far, ftype, VM_FAULT_NORMAL, &sig, &ucode); + error = vm_fault_trap(map, fault_va, ftype, VM_FAULT_NORMAL, &sig, + &ucode); if (error != KERN_SUCCESS) { if (lower) { call_trapsignal(td, sig, ucode, (void *)far, |
