git: 01ff0fa77d33 - main - arm64: Support some per-thread sctlr_el1 fields
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Apr 2026 11:40:15 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=01ff0fa77d33dde6b6f6a0ff83b0028f76243796
commit 01ff0fa77d33dde6b6f6a0ff83b0028f76243796
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-04-29 11:34:39 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-04-29 11:34:39 +0000
arm64: Support some per-thread sctlr_el1 fields
This will be used to enable MTE from userspace.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D55950
---
sys/arm64/arm64/exec_machdep.c | 1 +
sys/arm64/arm64/pmap.c | 11 +++++++++++
sys/arm64/arm64/vm_machdep.c | 4 ++++
sys/arm64/include/armreg.h | 1 +
sys/arm64/include/proc.h | 3 ++-
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c
index 9f9b74e6a0e5..a2e1e42249b4 100644
--- a/sys/arm64/arm64/exec_machdep.c
+++ b/sys/arm64/arm64/exec_machdep.c
@@ -445,6 +445,7 @@ exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack)
else
new_tcr = 0;
td->td_proc->p_md.md_tcr = new_tcr;
+ td->td_md.md_sctlr = 0;
/* TODO: should create a pmap function for this... */
tcr = READ_SPECIALREG(tcr_el1);
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 4ba2fb6f6678..595fba2da411 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -9325,6 +9325,7 @@ pmap_switch(struct thread *new)
{
pcpu_bp_harden bp_harden;
struct pcb *pcb;
+ uint64_t sctlr;
/* Store the new curthread */
PCPU_SET(curthread, new);
@@ -9333,6 +9334,16 @@ pmap_switch(struct thread *new)
pcb = new->td_pcb;
PCPU_SET(curpcb, pcb);
+ if ((new->td_proc->p_flag & P_KPROC) == 0) {
+ sctlr = READ_SPECIALREG(sctlr_el1);
+ if ((sctlr & SCTLR_USER_MASK) != new->td_md.md_sctlr) {
+ sctlr &= ~SCTLR_USER_MASK;
+ sctlr |= new->td_md.md_sctlr;
+ WRITE_SPECIALREG(sctlr_el1, sctlr);
+ isb();
+ }
+ }
+
/*
* TODO: We may need to flush the cache here if switching
* to a user process.
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
index b46cb8793409..4cb87ca9856e 100644
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -123,6 +123,8 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
/* Copy the TCR_EL1 value */
td2->td_proc->p_md.md_tcr = td1->td_proc->p_md.md_tcr;
+ td2->td_md.md_sctlr = td1->td_md.md_sctlr;
+
#if defined(PERTHREAD_SSP)
/* Set the new canary */
arc4random_buf(&td2->td_md.md_canary, sizeof(td2->td_md.md_canary));
@@ -192,6 +194,8 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_daif = PSR_DAIF_DEFAULT;
+ td->td_md.md_sctlr = td0->td_md.md_sctlr;
+
#if defined(PERTHREAD_SSP)
/* Set the new canary */
arc4random_buf(&td->td_md.md_canary, sizeof(td->td_md.md_canary));
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index 6447f0064d33..4233a01d143c 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -2803,6 +2803,7 @@
SCTLR_SA | \
SCTLR_C | \
SCTLR_M)
+#define SCTLR_USER_MASK (SCTLR_ATA0 | SCTLR_TCF0_MASK)
/* SCTLR_EL12 */
#define SCTLR_EL12_REG MRS_REG_ALT_NAME(SCTLR_EL12)
diff --git a/sys/arm64/include/proc.h b/sys/arm64/include/proc.h
index b40990e89385..d5879a794269 100644
--- a/sys/arm64/include/proc.h
+++ b/sys/arm64/include/proc.h
@@ -70,7 +70,8 @@ struct mdthread {
int md_efirt_dis_pf;
int md_reserved0;
- uint64_t md_reserved[2];
+ uint64_t md_sctlr;
+ uint64_t md_reserved1;
};
struct mdproc {