Skip to content

Commit 4d51ff5

Browse files
LeviYeoReumctmarinas
authored andcommitted
arm64/kernel: Support store-only mte tag check
Introduce new flag -- MTE_CTRL_STORE_ONLY used to set store-only tag check. This flag isn't overridden by prefered tcf flag setting but set together with prefered setting of way to report tag check fault. Signed-off-by: Yeoreum Yun <[email protected]> Reviewed-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent b1fabef commit 4d51ff5

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

arch/arm64/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#define MTE_CTRL_TCF_ASYNC (1UL << 17)
2424
#define MTE_CTRL_TCF_ASYMM (1UL << 18)
2525

26+
#define MTE_CTRL_STORE_ONLY (1UL << 19)
27+
2628
#ifndef __ASSEMBLY__
2729

2830
#include <linux/build_bug.h>

arch/arm64/kernel/mte.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static void mte_update_sctlr_user(struct task_struct *task)
200200
* program requested values go with what was requested.
201201
*/
202202
resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
203-
sctlr &= ~SCTLR_EL1_TCF0_MASK;
203+
sctlr &= ~(SCTLR_EL1_TCF0_MASK | SCTLR_EL1_TCSO0_MASK);
204204
/*
205205
* Pick an actual setting. The order in which we check for
206206
* set bits and map into register values determines our
@@ -212,6 +212,10 @@ static void mte_update_sctlr_user(struct task_struct *task)
212212
sctlr |= SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF0, ASYNC);
213213
else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
214214
sctlr |= SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF0, SYNC);
215+
216+
if (mte_ctrl & MTE_CTRL_STORE_ONLY)
217+
sctlr |= SYS_FIELD_PREP(SCTLR_EL1, TCSO0, 1);
218+
215219
task->thread.sctlr_user = sctlr;
216220
}
217221

@@ -371,6 +375,9 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
371375
(arg & PR_MTE_TCF_SYNC))
372376
mte_ctrl |= MTE_CTRL_TCF_ASYMM;
373377

378+
if (arg & PR_MTE_STORE_ONLY)
379+
mte_ctrl |= MTE_CTRL_STORE_ONLY;
380+
374381
task->thread.mte_ctrl = mte_ctrl;
375382
if (task == current) {
376383
preempt_disable();
@@ -398,6 +405,8 @@ long get_mte_ctrl(struct task_struct *task)
398405
ret |= PR_MTE_TCF_ASYNC;
399406
if (mte_ctrl & MTE_CTRL_TCF_SYNC)
400407
ret |= PR_MTE_TCF_SYNC;
408+
if (mte_ctrl & MTE_CTRL_STORE_ONLY)
409+
ret |= PR_MTE_STORE_ONLY;
401410

402411
return ret;
403412
}

arch/arm64/kernel/process.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,10 +849,14 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
849849
if (is_compat_thread(ti))
850850
return -EINVAL;
851851

852-
if (system_supports_mte())
852+
if (system_supports_mte()) {
853853
valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
854854
| PR_MTE_TAG_MASK;
855855

856+
if (cpus_have_cap(ARM64_MTE_STORE_ONLY))
857+
valid_mask |= PR_MTE_STORE_ONLY;
858+
}
859+
856860
if (arg & ~valid_mask)
857861
return -EINVAL;
858862

0 commit comments

Comments
 (0)