mirror of
https://github.com/torvalds/linux.git
synced 2026-01-25 15:03:52 +08:00
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 <yeoreum.yun@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20250618092957.2069907-4-yeoreum.yun@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
committed by
Catalin Marinas
parent
b1fabef37b
commit
4d51ff5bba
@@ -23,6 +23,8 @@
|
||||
#define MTE_CTRL_TCF_ASYNC (1UL << 17)
|
||||
#define MTE_CTRL_TCF_ASYMM (1UL << 18)
|
||||
|
||||
#define MTE_CTRL_STORE_ONLY (1UL << 19)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
|
||||
@@ -200,7 +200,7 @@ static void mte_update_sctlr_user(struct task_struct *task)
|
||||
* program requested values go with what was requested.
|
||||
*/
|
||||
resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
|
||||
sctlr &= ~SCTLR_EL1_TCF0_MASK;
|
||||
sctlr &= ~(SCTLR_EL1_TCF0_MASK | SCTLR_EL1_TCSO0_MASK);
|
||||
/*
|
||||
* Pick an actual setting. The order in which we check for
|
||||
* set bits and map into register values determines our
|
||||
@@ -212,6 +212,10 @@ static void mte_update_sctlr_user(struct task_struct *task)
|
||||
sctlr |= SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF0, ASYNC);
|
||||
else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
|
||||
sctlr |= SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF0, SYNC);
|
||||
|
||||
if (mte_ctrl & MTE_CTRL_STORE_ONLY)
|
||||
sctlr |= SYS_FIELD_PREP(SCTLR_EL1, TCSO0, 1);
|
||||
|
||||
task->thread.sctlr_user = sctlr;
|
||||
}
|
||||
|
||||
@@ -371,6 +375,9 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
|
||||
(arg & PR_MTE_TCF_SYNC))
|
||||
mte_ctrl |= MTE_CTRL_TCF_ASYMM;
|
||||
|
||||
if (arg & PR_MTE_STORE_ONLY)
|
||||
mte_ctrl |= MTE_CTRL_STORE_ONLY;
|
||||
|
||||
task->thread.mte_ctrl = mte_ctrl;
|
||||
if (task == current) {
|
||||
preempt_disable();
|
||||
@@ -398,6 +405,8 @@ long get_mte_ctrl(struct task_struct *task)
|
||||
ret |= PR_MTE_TCF_ASYNC;
|
||||
if (mte_ctrl & MTE_CTRL_TCF_SYNC)
|
||||
ret |= PR_MTE_TCF_SYNC;
|
||||
if (mte_ctrl & MTE_CTRL_STORE_ONLY)
|
||||
ret |= PR_MTE_STORE_ONLY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -849,10 +849,14 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
|
||||
if (is_compat_thread(ti))
|
||||
return -EINVAL;
|
||||
|
||||
if (system_supports_mte())
|
||||
if (system_supports_mte()) {
|
||||
valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
|
||||
| PR_MTE_TAG_MASK;
|
||||
|
||||
if (cpus_have_cap(ARM64_MTE_STORE_ONLY))
|
||||
valid_mask |= PR_MTE_STORE_ONLY;
|
||||
}
|
||||
|
||||
if (arg & ~valid_mask)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user