Skip to content

Commit 5b1ae9d

Browse files
committed
Merge branch 'for-next/feat_mte_store_only' into for-next/core
* for-next/feat_mte_store_only: : MTE feature to restrict tag checking to store only operations kselftest/arm64/mte: Add MTE_STORE_ONLY testcases kselftest/arm64/mte: Preparation for mte store only test kselftest/arm64/abi: Add MTE_STORE_ONLY feature hwcap test KVM: arm64: Expose MTE_STORE_ONLY feature to guest arm64/hwcaps: Add MTE_STORE_ONLY hwcaps arm64/kernel: Support store-only mte tag check prctl: Introduce PR_MTE_STORE_ONLY arm64/cpufeature: Add MTE_STORE_ONLY feature
2 parents 3ae8cef + 1f488fb commit 5b1ae9d

File tree

22 files changed

+443
-44
lines changed

22 files changed

+443
-44
lines changed

Documentation/arch/arm64/elf_hwcaps.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ HWCAP2_POE
438438
HWCAP3_MTE_FAR
439439
Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
440440

441+
HWCAP3_MTE_STORE_ONLY
442+
Functionality implied by ID_AA64PFR2_EL1.MTESTOREONLY == 0b0001.
443+
441444
4. Unused AT_HWCAP bits
442445
-----------------------
443446

arch/arm64/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177

178178
#define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128)
179179
#define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR)
180+
#define KERNEL_HWCAP_MTE_STORE_ONLY __khwcap3_feature(MTE_STORE_ONLY)
180181

181182
/*
182183
* This yields a mask that user programs can use to figure out what

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/include/uapi/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,6 @@
144144
* HWCAP3 flags - for AT_HWCAP3
145145
*/
146146
#define HWCAP3_MTE_FAR (1UL << 0)
147+
#define HWCAP3_MTE_STORE_ONLY (1UL << 1)
147148

148149
#endif /* _UAPI__ASM_HWCAP_H */

arch/arm64/kernel/cpufeature.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
321321
static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
322322
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
323323
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTEFAR_SHIFT, 4, ID_AA64PFR2_EL1_MTEFAR_NI),
324+
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTESTOREONLY_SHIFT, 4, ID_AA64PFR2_EL1_MTESTOREONLY_NI),
324325
ARM64_FTR_END,
325326
};
326327

@@ -2914,6 +2915,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
29142915
.matches = has_cpuid_feature,
29152916
ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTEFAR, IMP)
29162917
},
2918+
{
2919+
.desc = "Store Only MTE Tag Check",
2920+
.capability = ARM64_MTE_STORE_ONLY,
2921+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2922+
.matches = has_cpuid_feature,
2923+
ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTESTOREONLY, IMP)
2924+
},
29172925
#endif /* CONFIG_ARM64_MTE */
29182926
{
29192927
.desc = "RCpc load-acquire (LDAPR)",
@@ -3258,6 +3266,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
32583266
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE),
32593267
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3),
32603268
HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR),
3269+
HWCAP_CAP(ID_AA64PFR2_EL1, MTESTOREONLY, IMP, CAP_HWCAP , KERNEL_HWCAP_MTE_STORE_ONLY),
32613270
#endif /* CONFIG_ARM64_MTE */
32623271
HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
32633272
HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),

arch/arm64/kernel/cpuinfo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static const char *const hwcap_str[] = {
161161
[KERNEL_HWCAP_SME_STMOP] = "smestmop",
162162
[KERNEL_HWCAP_SME_SMOP4] = "smesmop4",
163163
[KERNEL_HWCAP_MTE_FAR] = "mtefar",
164+
[KERNEL_HWCAP_MTE_STORE_ONLY] = "mtestoreonly",
164165
};
165166

166167
#ifdef CONFIG_COMPAT

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
@@ -850,10 +850,14 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
850850
if (is_compat_thread(ti))
851851
return -EINVAL;
852852

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

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

arch/arm64/kvm/sys_regs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
16181618
break;
16191619
case SYS_ID_AA64PFR2_EL1:
16201620
val &= ID_AA64PFR2_EL1_FPMR |
1621-
(kvm_has_mte(vcpu->kvm) ? ID_AA64PFR2_EL1_MTEFAR : 0);
1621+
(kvm_has_mte(vcpu->kvm) ?
1622+
ID_AA64PFR2_EL1_MTEFAR | ID_AA64PFR2_EL1_MTESTOREONLY :
1623+
0);
16221624
break;
16231625
case SYS_ID_AA64ISAR1_EL1:
16241626
if (!vcpu_has_ptrauth(vcpu))
@@ -2878,7 +2880,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
28782880
ID_AA64PFR1_EL1_MTE)),
28792881
ID_WRITABLE(ID_AA64PFR2_EL1,
28802882
ID_AA64PFR2_EL1_FPMR |
2881-
ID_AA64PFR2_EL1_MTEFAR),
2883+
ID_AA64PFR2_EL1_MTEFAR |
2884+
ID_AA64PFR2_EL1_MTESTOREONLY),
28822885
ID_UNALLOCATED(4,3),
28832886
ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
28842887
ID_HIDDEN(ID_AA64SMFR0_EL1),

arch/arm64/tools/cpucaps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ MPAM_HCR
7070
MTE
7171
MTE_ASYMM
7272
MTE_FAR
73+
MTE_STORE_ONLY
7374
SME
7475
SME_FA64
7576
SME2

0 commit comments

Comments
 (0)