Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+443 -44
+3
Documentation/arch/arm64/elf_hwcaps.rst
··· 438 438 HWCAP3_MTE_FAR 439 439 Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001. 440 440 441 + HWCAP3_MTE_STORE_ONLY 442 + Functionality implied by ID_AA64PFR2_EL1.MTESTOREONLY == 0b0001. 443 + 441 444 4. Unused AT_HWCAP bits 442 445 ----------------------- 443 446
+1
arch/arm64/include/asm/hwcap.h
··· 177 177 178 178 #define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128) 179 179 #define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR) 180 + #define KERNEL_HWCAP_MTE_STORE_ONLY __khwcap3_feature(MTE_STORE_ONLY) 180 181 181 182 /* 182 183 * This yields a mask that user programs can use to figure out what
+2
arch/arm64/include/asm/processor.h
··· 23 23 #define MTE_CTRL_TCF_ASYNC (1UL << 17) 24 24 #define MTE_CTRL_TCF_ASYMM (1UL << 18) 25 25 26 + #define MTE_CTRL_STORE_ONLY (1UL << 19) 27 + 26 28 #ifndef __ASSEMBLY__ 27 29 28 30 #include <linux/build_bug.h>
+1
arch/arm64/include/uapi/asm/hwcap.h
··· 144 144 * HWCAP3 flags - for AT_HWCAP3 145 145 */ 146 146 #define HWCAP3_MTE_FAR (1UL << 0) 147 + #define HWCAP3_MTE_STORE_ONLY (1UL << 1) 147 148 148 149 #endif /* _UAPI__ASM_HWCAP_H */
+9
arch/arm64/kernel/cpufeature.c
··· 321 321 static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = { 322 322 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0), 323 323 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), 324 325 ARM64_FTR_END, 325 326 }; 326 327 ··· 2915 2914 .matches = has_cpuid_feature, 2916 2915 ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTEFAR, IMP) 2917 2916 }, 2917 + { 2918 + .desc = "Store Only MTE Tag Check", 2919 + .capability = ARM64_MTE_STORE_ONLY, 2920 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 2921 + .matches = has_cpuid_feature, 2922 + ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTESTOREONLY, IMP) 2923 + }, 2918 2924 #endif /* CONFIG_ARM64_MTE */ 2919 2925 { 2920 2926 .desc = "RCpc load-acquire (LDAPR)", ··· 3266 3258 HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE), 3267 3259 HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3), 3268 3260 HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR), 3261 + HWCAP_CAP(ID_AA64PFR2_EL1, MTESTOREONLY, IMP, CAP_HWCAP , KERNEL_HWCAP_MTE_STORE_ONLY), 3269 3262 #endif /* CONFIG_ARM64_MTE */ 3270 3263 HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV), 3271 3264 HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),
+1
arch/arm64/kernel/cpuinfo.c
··· 161 161 [KERNEL_HWCAP_SME_STMOP] = "smestmop", 162 162 [KERNEL_HWCAP_SME_SMOP4] = "smesmop4", 163 163 [KERNEL_HWCAP_MTE_FAR] = "mtefar", 164 + [KERNEL_HWCAP_MTE_STORE_ONLY] = "mtestoreonly", 164 165 }; 165 166 166 167 #ifdef CONFIG_COMPAT
+10 -1
arch/arm64/kernel/mte.c
··· 200 200 * program requested values go with what was requested. 201 201 */ 202 202 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); 204 204 /* 205 205 * Pick an actual setting. The order in which we check for 206 206 * set bits and map into register values determines our ··· 212 212 sctlr |= SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF0, ASYNC); 213 213 else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC) 214 214 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 + 215 219 task->thread.sctlr_user = sctlr; 216 220 } 217 221 ··· 375 371 (arg & PR_MTE_TCF_SYNC)) 376 372 mte_ctrl |= MTE_CTRL_TCF_ASYMM; 377 373 374 + if (arg & PR_MTE_STORE_ONLY) 375 + mte_ctrl |= MTE_CTRL_STORE_ONLY; 376 + 378 377 task->thread.mte_ctrl = mte_ctrl; 379 378 if (task == current) { 380 379 preempt_disable(); ··· 405 398 ret |= PR_MTE_TCF_ASYNC; 406 399 if (mte_ctrl & MTE_CTRL_TCF_SYNC) 407 400 ret |= PR_MTE_TCF_SYNC; 401 + if (mte_ctrl & MTE_CTRL_STORE_ONLY) 402 + ret |= PR_MTE_STORE_ONLY; 408 403 409 404 return ret; 410 405 }
+5 -1
arch/arm64/kernel/process.c
··· 850 850 if (is_compat_thread(ti)) 851 851 return -EINVAL; 852 852 853 - if (system_supports_mte()) 853 + if (system_supports_mte()) { 854 854 valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \ 855 855 | PR_MTE_TAG_MASK; 856 + 857 + if (cpus_have_cap(ARM64_MTE_STORE_ONLY)) 858 + valid_mask |= PR_MTE_STORE_ONLY; 859 + } 856 860 857 861 if (arg & ~valid_mask) 858 862 return -EINVAL;
+5 -2
arch/arm64/kvm/sys_regs.c
··· 1618 1618 break; 1619 1619 case SYS_ID_AA64PFR2_EL1: 1620 1620 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); 1622 1624 break; 1623 1625 case SYS_ID_AA64ISAR1_EL1: 1624 1626 if (!vcpu_has_ptrauth(vcpu)) ··· 2880 2878 ID_AA64PFR1_EL1_MTE)), 2881 2879 ID_WRITABLE(ID_AA64PFR2_EL1, 2882 2880 ID_AA64PFR2_EL1_FPMR | 2883 - ID_AA64PFR2_EL1_MTEFAR), 2881 + ID_AA64PFR2_EL1_MTEFAR | 2882 + ID_AA64PFR2_EL1_MTESTOREONLY), 2884 2883 ID_UNALLOCATED(4,3), 2885 2884 ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), 2886 2885 ID_HIDDEN(ID_AA64SMFR0_EL1),
+1
arch/arm64/tools/cpucaps
··· 70 70 MTE 71 71 MTE_ASYMM 72 72 MTE_FAR 73 + MTE_STORE_ONLY 73 74 SME 74 75 SME_FA64 75 76 SME2
+2
include/uapi/linux/prctl.h
··· 244 244 # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) 245 245 /* Unused; kept only for source compatibility */ 246 246 # define PR_MTE_TCF_SHIFT 1 247 + /* MTE tag check store only */ 248 + # define PR_MTE_STORE_ONLY (1UL << 19) 247 249 /* RISC-V pointer masking tag length */ 248 250 # define PR_PMLEN_SHIFT 24 249 251 # define PR_PMLEN_MASK (0x7fUL << PR_PMLEN_SHIFT)
+6
tools/testing/selftests/arm64/abi/hwcap.c
··· 1108 1108 .hwcap_bit = HWCAP3_MTE_FAR, 1109 1109 .cpuinfo = "mtefar", 1110 1110 }, 1111 + { 1112 + .name = "MTE_STOREONLY", 1113 + .at_hwcap = AT_HWCAP3, 1114 + .hwcap_bit = HWCAP3_MTE_STORE_ONLY, 1115 + .cpuinfo = "mtestoreonly", 1116 + }, 1111 1117 }; 1112 1118 1113 1119 typedef void (*sighandler_fn)(int, siginfo_t *, void *);
+5 -5
tools/testing/selftests/arm64/mte/check_buffer_fill.c
··· 31 31 int i, j, item; 32 32 bool err; 33 33 34 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 34 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 35 35 item = ARRAY_SIZE(sizes); 36 36 37 37 for (i = 0; i < item; i++) { ··· 68 68 bool err; 69 69 char *und_ptr = NULL; 70 70 71 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 71 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 72 72 item = ARRAY_SIZE(sizes); 73 73 for (i = 0; i < item; i++) { 74 74 ptr = (char *)mte_allocate_memory_tag_range(sizes[i], mem_type, 0, ··· 164 164 size_t tagged_size, overflow_size; 165 165 char *over_ptr = NULL; 166 166 167 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 167 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 168 168 item = ARRAY_SIZE(sizes); 169 169 for (i = 0; i < item; i++) { 170 170 ptr = (char *)mte_allocate_memory_tag_range(sizes[i], mem_type, 0, ··· 337 337 { 338 338 int i, item, result = KSFT_PASS; 339 339 340 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 340 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 341 341 item = ARRAY_SIZE(sizes); 342 342 cur_mte_cxt.fault_valid = false; 343 343 for (i = 0; i < item; i++) { ··· 368 368 int run, fd; 369 369 int total = ARRAY_SIZE(sizes); 370 370 371 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 371 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 372 372 for (run = 0; run < total; run++) { 373 373 /* check initial tags for anonymous mmap */ 374 374 ptr = (char *)mte_allocate_memory(sizes[run], mem_type, mapping, false);
+2 -2
tools/testing/selftests/arm64/mte/check_child_memory.c
··· 88 88 int item = ARRAY_SIZE(sizes); 89 89 90 90 item = ARRAY_SIZE(sizes); 91 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 91 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 92 92 for (run = 0; run < item; run++) { 93 93 ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping, 94 94 UNDERFLOW, OVERFLOW); ··· 109 109 int run, fd, map_size, result = KSFT_PASS; 110 110 int total = ARRAY_SIZE(sizes); 111 111 112 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 112 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 113 113 for (run = 0; run < total; run++) { 114 114 fd = create_temp_file(); 115 115 if (fd == -1)
+3 -3
tools/testing/selftests/arm64/mte/check_hugetlb_options.c
··· 151 151 152 152 map_size = default_huge_page_size(); 153 153 154 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 154 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 155 155 map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false); 156 156 if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) 157 157 return KSFT_FAIL; ··· 180 180 unsigned long map_size; 181 181 182 182 prot_flag = PROT_READ | PROT_WRITE; 183 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 183 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 184 184 map_size = default_huge_page_size(); 185 185 map_ptr = (char *)mte_allocate_memory_tag_range(map_size, mem_type, mapping, 186 186 0, 0); ··· 210 210 211 211 map_size = default_huge_page_size(); 212 212 213 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 213 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 214 214 ptr = (char *)mte_allocate_memory_tag_range(map_size, mem_type, mapping, 215 215 0, 0); 216 216 if (check_allocated_memory_range(ptr, map_size, mem_type,
+1 -1
tools/testing/selftests/arm64/mte/check_ksm_options.c
··· 106 106 return err; 107 107 } 108 108 109 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 109 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 110 110 ptr = mte_allocate_memory(TEST_UNIT * page_sz, mem_type, mapping, true); 111 111 if (check_allocated_memory(ptr, TEST_UNIT * page_sz, mem_type, false) != KSFT_PASS) 112 112 return KSFT_FAIL;
+350 -13
tools/testing/selftests/arm64/mte/check_mmap_options.c
··· 35 35 CHECK_CLEAR_PROT_MTE = 2, 36 36 }; 37 37 38 + enum mte_tag_op_type { 39 + TAG_OP_ALL = 0, 40 + TAG_OP_STONLY = 1, 41 + }; 42 + 38 43 struct check_mmap_testcase { 39 44 int check_type; 40 45 int mem_type; ··· 47 42 int mapping; 48 43 int tag_check; 49 44 int atag_check; 45 + int tag_op; 50 46 bool enable_tco; 51 47 }; 48 + 49 + #define TAG_OP_ALL 0 50 + #define TAG_OP_STONLY 1 52 51 53 52 static size_t page_size; 54 53 static int sizes[] = { ··· 60 51 /* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0 61 52 }; 62 53 63 - static int check_mte_memory(char *ptr, int size, int mode, int tag_check, int atag_check) 54 + static int check_mte_memory(char *ptr, int size, int mode, 55 + int tag_check,int atag_check, int tag_op) 64 56 { 57 + char buf[MT_GRANULE_SIZE]; 58 + 65 59 if (!mtefar_support && atag_check == ATAG_CHECK_ON) 66 60 return KSFT_SKIP; 67 61 ··· 93 81 if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF) 94 82 return KSFT_FAIL; 95 83 84 + if (tag_op == TAG_OP_STONLY) { 85 + mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW); 86 + memcpy(buf, ptr - UNDERFLOW, MT_GRANULE_SIZE); 87 + mte_wait_after_trig(); 88 + if (cur_mte_cxt.fault_valid == true) 89 + return KSFT_FAIL; 90 + 91 + mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW); 92 + memcpy(buf, ptr + size, MT_GRANULE_SIZE); 93 + mte_wait_after_trig(); 94 + if (cur_mte_cxt.fault_valid == true) 95 + return KSFT_FAIL; 96 + } 97 + 96 98 return KSFT_PASS; 97 99 } 98 100 99 - static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 101 + static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, 102 + int tag_check, int atag_check, int tag_op) 100 103 { 101 104 char *ptr, *map_ptr; 102 105 int run, result, map_size; 103 106 int item = ARRAY_SIZE(sizes); 104 107 105 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 108 + if (tag_op == TAG_OP_STONLY && !mtestonly_support) 109 + return KSFT_SKIP; 110 + 111 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op); 106 112 for (run = 0; run < item; run++) { 107 113 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 108 114 map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false); ··· 136 106 munmap((void *)map_ptr, map_size); 137 107 return KSFT_FAIL; 138 108 } 139 - result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 109 + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op); 140 110 mte_clear_tags((void *)ptr, sizes[run]); 141 111 mte_free_memory((void *)map_ptr, map_size, mem_type, false); 142 112 if (result != KSFT_PASS) ··· 145 115 return KSFT_PASS; 146 116 } 147 117 148 - static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 118 + static int check_file_memory_mapping(int mem_type, int mode, int mapping, 119 + int tag_check, int atag_check, int tag_op) 149 120 { 150 121 char *ptr, *map_ptr; 151 122 int run, fd, map_size; 152 123 int total = ARRAY_SIZE(sizes); 153 124 int result = KSFT_PASS; 154 125 155 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 126 + if (tag_op == TAG_OP_STONLY && !mtestonly_support) 127 + return KSFT_SKIP; 128 + 129 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op); 156 130 for (run = 0; run < total; run++) { 157 131 fd = create_temp_file(); 158 132 if (fd == -1) ··· 178 144 close(fd); 179 145 return KSFT_FAIL; 180 146 } 181 - result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 147 + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op); 182 148 mte_clear_tags((void *)ptr, sizes[run]); 183 149 munmap((void *)map_ptr, map_size); 184 150 close(fd); ··· 195 161 int total = ARRAY_SIZE(sizes); 196 162 197 163 prot_flag = PROT_READ | PROT_WRITE; 198 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 164 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 199 165 for (run = 0; run < total; run++) { 200 166 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 201 167 ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping, ··· 211 177 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 212 178 return KSFT_FAIL; 213 179 } 214 - result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 180 + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL); 215 181 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 216 182 if (result != KSFT_PASS) 217 - return KSFT_FAIL; 183 + return result; 218 184 219 185 fd = create_temp_file(); 220 186 if (fd == -1) ··· 235 201 close(fd); 236 202 return KSFT_FAIL; 237 203 } 238 - result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 204 + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL); 239 205 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 240 206 close(fd); 241 207 if (result != KSFT_PASS) ··· 253 219 const char *mapping_str; 254 220 const char *tag_check_str; 255 221 const char *atag_check_str; 222 + const char *tag_op_str; 256 223 257 224 switch (tc->check_type) { 258 225 case CHECK_ANON_MEM: ··· 338 303 check_type_str, mapping_str, sync_str, mem_type_str, 339 304 tag_check_str, atag_check_str); 340 305 306 + switch (tc->tag_op) { 307 + case TAG_OP_ALL: 308 + tag_op_str = ""; 309 + break; 310 + case TAG_OP_STONLY: 311 + tag_op_str = " / store-only"; 312 + break; 313 + default: 314 + assert(0); 315 + break; 316 + } 317 + 318 + snprintf(test_name, TEST_NAME_MAX, 319 + "Check %s with %s mapping, %s mode, %s memory and %s (%s%s)\n", 320 + check_type_str, mapping_str, sync_str, mem_type_str, 321 + tag_check_str, atag_check_str, tag_op_str); 322 + 341 323 return test_name; 342 324 } 343 325 ··· 370 318 .mapping = MAP_PRIVATE, 371 319 .tag_check = TAG_CHECK_OFF, 372 320 .atag_check = ATAG_CHECK_OFF, 321 + .tag_op = TAG_OP_ALL, 373 322 .enable_tco = true, 374 323 }, 375 324 { ··· 380 327 .mapping = MAP_PRIVATE, 381 328 .tag_check = TAG_CHECK_OFF, 382 329 .atag_check = ATAG_CHECK_OFF, 330 + .tag_op = TAG_OP_ALL, 383 331 .enable_tco = true, 384 332 }, 385 333 { ··· 390 336 .mapping = MAP_PRIVATE, 391 337 .tag_check = TAG_CHECK_OFF, 392 338 .atag_check = ATAG_CHECK_OFF, 339 + .tag_op = TAG_OP_ALL, 393 340 .enable_tco = false, 394 341 }, 395 342 { ··· 400 345 .mapping = MAP_PRIVATE, 401 346 .tag_check = TAG_CHECK_OFF, 402 347 .atag_check = ATAG_CHECK_OFF, 348 + .tag_op = TAG_OP_ALL, 403 349 .enable_tco = false, 404 350 }, 405 351 { ··· 410 354 .mapping = MAP_PRIVATE, 411 355 .tag_check = TAG_CHECK_ON, 412 356 .atag_check = ATAG_CHECK_OFF, 357 + .tag_op = TAG_OP_ALL, 413 358 .enable_tco = false, 414 359 }, 415 360 { ··· 420 363 .mapping = MAP_PRIVATE, 421 364 .tag_check = TAG_CHECK_ON, 422 365 .atag_check = ATAG_CHECK_OFF, 366 + .tag_op = TAG_OP_ALL, 423 367 .enable_tco = false, 424 368 }, 425 369 { ··· 430 372 .mapping = MAP_SHARED, 431 373 .tag_check = TAG_CHECK_ON, 432 374 .atag_check = ATAG_CHECK_OFF, 375 + .tag_op = TAG_OP_ALL, 433 376 .enable_tco = false, 434 377 }, 435 378 { ··· 440 381 .mapping = MAP_SHARED, 441 382 .tag_check = TAG_CHECK_ON, 442 383 .atag_check = ATAG_CHECK_OFF, 384 + .tag_op = TAG_OP_ALL, 443 385 .enable_tco = false, 444 386 }, 445 387 { ··· 450 390 .mapping = MAP_PRIVATE, 451 391 .tag_check = TAG_CHECK_ON, 452 392 .atag_check = ATAG_CHECK_OFF, 393 + .tag_op = TAG_OP_ALL, 453 394 .enable_tco = false, 454 395 }, 455 396 { ··· 460 399 .mapping = MAP_PRIVATE, 461 400 .tag_check = TAG_CHECK_ON, 462 401 .atag_check = ATAG_CHECK_OFF, 402 + .tag_op = TAG_OP_ALL, 463 403 .enable_tco = false, 464 404 }, 465 405 { ··· 470 408 .mapping = MAP_SHARED, 471 409 .tag_check = TAG_CHECK_ON, 472 410 .atag_check = ATAG_CHECK_OFF, 411 + .tag_op = TAG_OP_ALL, 473 412 .enable_tco = false, 474 413 }, 475 414 { ··· 480 417 .mapping = MAP_SHARED, 481 418 .tag_check = TAG_CHECK_ON, 482 419 .atag_check = ATAG_CHECK_OFF, 420 + .tag_op = TAG_OP_ALL, 483 421 .enable_tco = false, 484 422 }, 485 423 { ··· 490 426 .mapping = MAP_PRIVATE, 491 427 .tag_check = TAG_CHECK_ON, 492 428 .atag_check = ATAG_CHECK_OFF, 429 + .tag_op = TAG_OP_ALL, 493 430 .enable_tco = false, 494 431 }, 495 432 { ··· 500 435 .mapping = MAP_PRIVATE, 501 436 .tag_check = TAG_CHECK_ON, 502 437 .atag_check = ATAG_CHECK_OFF, 438 + .tag_op = TAG_OP_ALL, 503 439 .enable_tco = false, 504 440 }, 505 441 { ··· 510 444 .mapping = MAP_SHARED, 511 445 .tag_check = TAG_CHECK_ON, 512 446 .atag_check = ATAG_CHECK_OFF, 447 + .tag_op = TAG_OP_ALL, 513 448 .enable_tco = false, 514 449 }, 515 450 { ··· 520 453 .mapping = MAP_SHARED, 521 454 .tag_check = TAG_CHECK_ON, 522 455 .atag_check = ATAG_CHECK_OFF, 456 + .tag_op = TAG_OP_ALL, 523 457 .enable_tco = false, 524 458 }, 525 459 { ··· 530 462 .mapping = MAP_PRIVATE, 531 463 .tag_check = TAG_CHECK_ON, 532 464 .atag_check = ATAG_CHECK_OFF, 465 + .tag_op = TAG_OP_ALL, 533 466 .enable_tco = false, 534 467 }, 535 468 { ··· 540 471 .mapping = MAP_PRIVATE, 541 472 .tag_check = TAG_CHECK_ON, 542 473 .atag_check = ATAG_CHECK_OFF, 474 + .tag_op = TAG_OP_ALL, 543 475 .enable_tco = false, 544 476 }, 545 477 { ··· 550 480 .mapping = MAP_SHARED, 551 481 .tag_check = TAG_CHECK_ON, 552 482 .atag_check = ATAG_CHECK_OFF, 483 + .tag_op = TAG_OP_ALL, 553 484 .enable_tco = false, 554 485 }, 555 486 { ··· 560 489 .mapping = MAP_SHARED, 561 490 .tag_check = TAG_CHECK_ON, 562 491 .atag_check = ATAG_CHECK_OFF, 492 + .tag_op = TAG_OP_ALL, 563 493 .enable_tco = false, 564 494 }, 565 495 { ··· 570 498 .mapping = MAP_PRIVATE, 571 499 .tag_check = TAG_CHECK_ON, 572 500 .atag_check = ATAG_CHECK_OFF, 501 + .tag_op = TAG_OP_ALL, 573 502 .enable_tco = false, 574 503 }, 575 504 { ··· 580 507 .mapping = MAP_PRIVATE, 581 508 .tag_check = TAG_CHECK_ON, 582 509 .atag_check = ATAG_CHECK_OFF, 510 + .tag_op = TAG_OP_ALL, 583 511 .enable_tco = false, 584 512 }, 585 513 { ··· 590 516 .mapping = MAP_PRIVATE, 591 517 .tag_check = TAG_CHECK_ON, 592 518 .atag_check = ATAG_CHECK_ON, 519 + .tag_op = TAG_OP_ALL, 593 520 .enable_tco = false, 594 521 }, 595 522 { ··· 600 525 .mapping = MAP_PRIVATE, 601 526 .tag_check = TAG_CHECK_ON, 602 527 .atag_check = ATAG_CHECK_ON, 528 + .tag_op = TAG_OP_ALL, 603 529 .enable_tco = false, 604 530 }, 605 531 { ··· 610 534 .mapping = MAP_SHARED, 611 535 .tag_check = TAG_CHECK_ON, 612 536 .atag_check = ATAG_CHECK_ON, 537 + .tag_op = TAG_OP_ALL, 613 538 .enable_tco = false, 614 539 }, 615 540 { ··· 620 543 .mapping = MAP_SHARED, 621 544 .tag_check = TAG_CHECK_ON, 622 545 .atag_check = ATAG_CHECK_ON, 546 + .tag_op = TAG_OP_ALL, 623 547 .enable_tco = false, 624 548 }, 625 549 { ··· 630 552 .mapping = MAP_PRIVATE, 631 553 .tag_check = TAG_CHECK_ON, 632 554 .atag_check = ATAG_CHECK_ON, 555 + .tag_op = TAG_OP_ALL, 633 556 .enable_tco = false, 634 557 }, 635 558 { ··· 640 561 .mapping = MAP_PRIVATE, 641 562 .tag_check = TAG_CHECK_ON, 642 563 .atag_check = ATAG_CHECK_ON, 564 + .tag_op = TAG_OP_ALL, 643 565 .enable_tco = false, 644 566 }, 645 567 { ··· 650 570 .mapping = MAP_SHARED, 651 571 .tag_check = TAG_CHECK_ON, 652 572 .atag_check = ATAG_CHECK_ON, 573 + .tag_op = TAG_OP_ALL, 653 574 .enable_tco = false, 654 575 }, 655 576 { ··· 660 579 .mapping = MAP_SHARED, 661 580 .tag_check = TAG_CHECK_ON, 662 581 .atag_check = ATAG_CHECK_ON, 582 + .tag_op = TAG_OP_ALL, 663 583 .enable_tco = false, 664 584 }, 665 585 { ··· 670 588 .mapping = MAP_PRIVATE, 671 589 .tag_check = TAG_CHECK_ON, 672 590 .atag_check = ATAG_CHECK_ON, 591 + .tag_op = TAG_OP_ALL, 592 + .enable_tco = false, 593 + }, 594 + { 595 + .check_type = CHECK_ANON_MEM, 596 + .mem_type = USE_MMAP, 597 + .mte_sync = MTE_SYNC_ERR, 598 + .mapping = MAP_PRIVATE, 599 + .tag_check = TAG_CHECK_ON, 600 + .atag_check = ATAG_CHECK_OFF, 601 + .tag_op = TAG_OP_STONLY, 602 + .enable_tco = false, 603 + }, 604 + { 605 + .check_type = CHECK_ANON_MEM, 606 + .mem_type = USE_MPROTECT, 607 + .mte_sync = MTE_SYNC_ERR, 608 + .mapping = MAP_PRIVATE, 609 + .tag_check = TAG_CHECK_ON, 610 + .atag_check = ATAG_CHECK_OFF, 611 + .tag_op = TAG_OP_STONLY, 612 + .enable_tco = false, 613 + }, 614 + { 615 + .check_type = CHECK_ANON_MEM, 616 + .mem_type = USE_MMAP, 617 + .mte_sync = MTE_SYNC_ERR, 618 + .mapping = MAP_SHARED, 619 + .tag_check = TAG_CHECK_ON, 620 + .atag_check = ATAG_CHECK_OFF, 621 + .tag_op = TAG_OP_STONLY, 622 + .enable_tco = false, 623 + }, 624 + { 625 + .check_type = CHECK_ANON_MEM, 626 + .mem_type = USE_MPROTECT, 627 + .mte_sync = MTE_SYNC_ERR, 628 + .mapping = MAP_SHARED, 629 + .tag_check = TAG_CHECK_ON, 630 + .atag_check = ATAG_CHECK_OFF, 631 + .tag_op = TAG_OP_STONLY, 632 + .enable_tco = false, 633 + }, 634 + { 635 + .check_type = CHECK_ANON_MEM, 636 + .mem_type = USE_MMAP, 637 + .mte_sync = MTE_ASYNC_ERR, 638 + .mapping = MAP_PRIVATE, 639 + .tag_check = TAG_CHECK_ON, 640 + .atag_check = ATAG_CHECK_OFF, 641 + .tag_op = TAG_OP_STONLY, 642 + .enable_tco = false, 643 + }, 644 + { 645 + .check_type = CHECK_ANON_MEM, 646 + .mem_type = USE_MPROTECT, 647 + .mte_sync = MTE_ASYNC_ERR, 648 + .mapping = MAP_PRIVATE, 649 + .tag_check = TAG_CHECK_ON, 650 + .atag_check = ATAG_CHECK_OFF, 651 + .tag_op = TAG_OP_STONLY, 652 + .enable_tco = false, 653 + }, 654 + { 655 + .check_type = CHECK_ANON_MEM, 656 + .mem_type = USE_MMAP, 657 + .mte_sync = MTE_ASYNC_ERR, 658 + .mapping = MAP_SHARED, 659 + .tag_check = TAG_CHECK_ON, 660 + .atag_check = ATAG_CHECK_OFF, 661 + .tag_op = TAG_OP_STONLY, 662 + .enable_tco = false, 663 + }, 664 + { 665 + .check_type = CHECK_ANON_MEM, 666 + .mem_type = USE_MPROTECT, 667 + .mte_sync = MTE_ASYNC_ERR, 668 + .mapping = MAP_SHARED, 669 + .tag_check = TAG_CHECK_ON, 670 + .atag_check = ATAG_CHECK_OFF, 671 + .tag_op = TAG_OP_STONLY, 672 + .enable_tco = false, 673 + }, 674 + { 675 + .check_type = CHECK_FILE_MEM, 676 + .mem_type = USE_MMAP, 677 + .mte_sync = MTE_SYNC_ERR, 678 + .mapping = MAP_PRIVATE, 679 + .tag_check = TAG_CHECK_ON, 680 + .atag_check = ATAG_CHECK_OFF, 681 + .tag_op = TAG_OP_STONLY, 682 + .enable_tco = false, 683 + }, 684 + { 685 + .check_type = CHECK_FILE_MEM, 686 + .mem_type = USE_MPROTECT, 687 + .mte_sync = MTE_SYNC_ERR, 688 + .mapping = MAP_PRIVATE, 689 + .tag_check = TAG_CHECK_ON, 690 + .atag_check = ATAG_CHECK_OFF, 691 + .tag_op = TAG_OP_STONLY, 692 + .enable_tco = false, 693 + }, 694 + { 695 + .check_type = CHECK_FILE_MEM, 696 + .mem_type = USE_MMAP, 697 + .mte_sync = MTE_SYNC_ERR, 698 + .mapping = MAP_SHARED, 699 + .tag_check = TAG_CHECK_ON, 700 + .atag_check = ATAG_CHECK_OFF, 701 + .tag_op = TAG_OP_STONLY, 702 + .enable_tco = false, 703 + }, 704 + { 705 + .check_type = CHECK_FILE_MEM, 706 + .mem_type = USE_MPROTECT, 707 + .mte_sync = MTE_SYNC_ERR, 708 + .mapping = MAP_SHARED, 709 + .tag_check = TAG_CHECK_ON, 710 + .atag_check = ATAG_CHECK_OFF, 711 + .tag_op = TAG_OP_STONLY, 712 + .enable_tco = false, 713 + }, 714 + { 715 + .check_type = CHECK_FILE_MEM, 716 + .mem_type = USE_MMAP, 717 + .mte_sync = MTE_ASYNC_ERR, 718 + .mapping = MAP_PRIVATE, 719 + .tag_check = TAG_CHECK_ON, 720 + .atag_check = ATAG_CHECK_OFF, 721 + .tag_op = TAG_OP_STONLY, 722 + .enable_tco = false, 723 + }, 724 + { 725 + .check_type = CHECK_FILE_MEM, 726 + .mem_type = USE_MPROTECT, 727 + .mte_sync = MTE_ASYNC_ERR, 728 + .mapping = MAP_PRIVATE, 729 + .tag_check = TAG_CHECK_ON, 730 + .atag_check = ATAG_CHECK_OFF, 731 + .tag_op = TAG_OP_STONLY, 732 + .enable_tco = false, 733 + }, 734 + { 735 + .check_type = CHECK_FILE_MEM, 736 + .mem_type = USE_MMAP, 737 + .mte_sync = MTE_ASYNC_ERR, 738 + .mapping = MAP_SHARED, 739 + .tag_check = TAG_CHECK_ON, 740 + .atag_check = ATAG_CHECK_OFF, 741 + .tag_op = TAG_OP_STONLY, 742 + .enable_tco = false, 743 + }, 744 + { 745 + .check_type = CHECK_FILE_MEM, 746 + .mem_type = USE_MPROTECT, 747 + .mte_sync = MTE_ASYNC_ERR, 748 + .mapping = MAP_SHARED, 749 + .tag_check = TAG_CHECK_ON, 750 + .atag_check = ATAG_CHECK_OFF, 751 + .tag_op = TAG_OP_STONLY, 752 + .enable_tco = false, 753 + }, 754 + { 755 + .check_type = CHECK_ANON_MEM, 756 + .mem_type = USE_MMAP, 757 + .mte_sync = MTE_SYNC_ERR, 758 + .mapping = MAP_PRIVATE, 759 + .tag_check = TAG_CHECK_ON, 760 + .atag_check = ATAG_CHECK_ON, 761 + .tag_op = TAG_OP_STONLY, 762 + .enable_tco = false, 763 + }, 764 + { 765 + .check_type = CHECK_ANON_MEM, 766 + .mem_type = USE_MPROTECT, 767 + .mte_sync = MTE_SYNC_ERR, 768 + .mapping = MAP_PRIVATE, 769 + .tag_check = TAG_CHECK_ON, 770 + .atag_check = ATAG_CHECK_ON, 771 + .tag_op = TAG_OP_STONLY, 772 + .enable_tco = false, 773 + }, 774 + { 775 + .check_type = CHECK_ANON_MEM, 776 + .mem_type = USE_MMAP, 777 + .mte_sync = MTE_SYNC_ERR, 778 + .mapping = MAP_SHARED, 779 + .tag_check = TAG_CHECK_ON, 780 + .atag_check = ATAG_CHECK_ON, 781 + .tag_op = TAG_OP_STONLY, 782 + .enable_tco = false, 783 + }, 784 + { 785 + .check_type = CHECK_ANON_MEM, 786 + .mem_type = USE_MPROTECT, 787 + .mte_sync = MTE_SYNC_ERR, 788 + .mapping = MAP_SHARED, 789 + .tag_check = TAG_CHECK_ON, 790 + .atag_check = ATAG_CHECK_ON, 791 + .tag_op = TAG_OP_STONLY, 792 + .enable_tco = false, 793 + }, 794 + { 795 + .check_type = CHECK_FILE_MEM, 796 + .mem_type = USE_MMAP, 797 + .mte_sync = MTE_SYNC_ERR, 798 + .mapping = MAP_PRIVATE, 799 + .tag_check = TAG_CHECK_ON, 800 + .atag_check = ATAG_CHECK_ON, 801 + .tag_op = TAG_OP_STONLY, 802 + .enable_tco = false, 803 + }, 804 + { 805 + .check_type = CHECK_FILE_MEM, 806 + .mem_type = USE_MPROTECT, 807 + .mte_sync = MTE_SYNC_ERR, 808 + .mapping = MAP_PRIVATE, 809 + .tag_check = TAG_CHECK_ON, 810 + .atag_check = ATAG_CHECK_ON, 811 + .tag_op = TAG_OP_STONLY, 812 + .enable_tco = false, 813 + }, 814 + { 815 + .check_type = CHECK_FILE_MEM, 816 + .mem_type = USE_MMAP, 817 + .mte_sync = MTE_SYNC_ERR, 818 + .mapping = MAP_SHARED, 819 + .tag_check = TAG_CHECK_ON, 820 + .atag_check = ATAG_CHECK_ON, 821 + .tag_op = TAG_OP_STONLY, 822 + .enable_tco = false, 823 + }, 824 + { 825 + .check_type = CHECK_FILE_MEM, 826 + .mem_type = USE_MPROTECT, 827 + .mte_sync = MTE_SYNC_ERR, 828 + .mapping = MAP_SHARED, 829 + .tag_check = TAG_CHECK_ON, 830 + .atag_check = ATAG_CHECK_ON, 831 + .tag_op = TAG_OP_STONLY, 832 + .enable_tco = false, 833 + }, 834 + { 835 + .check_type = CHECK_FILE_MEM, 836 + .mem_type = USE_MMAP, 837 + .mte_sync = MTE_ASYNC_ERR, 838 + .mapping = MAP_PRIVATE, 839 + .tag_check = TAG_CHECK_ON, 840 + .atag_check = ATAG_CHECK_ON, 841 + .tag_op = TAG_OP_STONLY, 673 842 .enable_tco = false, 674 843 }, 675 844 { ··· 930 597 .mapping = MAP_PRIVATE, 931 598 .tag_check = TAG_CHECK_ON, 932 599 .atag_check = ATAG_CHECK_ON, 600 + .tag_op = TAG_OP_ALL, 933 601 .enable_tco = false, 934 602 }, 935 603 { ··· 940 606 .mapping = MAP_PRIVATE, 941 607 .tag_check = TAG_CHECK_ON, 942 608 .atag_check = ATAG_CHECK_ON, 609 + .tag_op = TAG_OP_ALL, 943 610 .enable_tco = false, 944 611 }, 945 612 }; ··· 978 643 test_cases[i].mte_sync, 979 644 test_cases[i].mapping, 980 645 test_cases[i].tag_check, 981 - test_cases[i].atag_check), 646 + test_cases[i].atag_check, 647 + test_cases[i].tag_op), 982 648 format_test_name(&test_cases[i])); 983 649 break; 984 650 case CHECK_FILE_MEM: ··· 987 651 test_cases[i].mte_sync, 988 652 test_cases[i].mapping, 989 653 test_cases[i].tag_check, 990 - test_cases[i].atag_check), 654 + test_cases[i].atag_check, 655 + test_cases[i].tag_op), 991 656 format_test_name(&test_cases[i])); 992 657 break; 993 658 case CHECK_CLEAR_PROT_MTE:
+17 -8
tools/testing/selftests/arm64/mte/check_prctl.c
··· 64 64 /* 65 65 * Attempt to set a specified combination of modes. 66 66 */ 67 - void set_mode_test(const char *name, int hwcap2, int mask) 67 + void set_mode_test(const char *name, int hwcap2, int hwcap3, int mask) 68 68 { 69 69 int ret; 70 70 71 71 if ((getauxval(AT_HWCAP2) & hwcap2) != hwcap2) { 72 + ksft_test_result_skip("%s\n", name); 73 + return; 74 + } 75 + 76 + if ((getauxval(AT_HWCAP3) & hwcap3) != hwcap3) { 72 77 ksft_test_result_skip("%s\n", name); 73 78 return; 74 79 } ··· 90 85 return; 91 86 } 92 87 93 - if ((ret & PR_MTE_TCF_MASK) == mask) { 88 + if ((ret & (PR_MTE_TCF_MASK | PR_MTE_STORE_ONLY)) == mask) { 94 89 ksft_test_result_pass("%s\n", name); 95 90 } else { 96 91 ksft_print_msg("Got %x, expected %x\n", ··· 102 97 struct mte_mode { 103 98 int mask; 104 99 int hwcap2; 100 + int hwcap3; 105 101 const char *name; 106 102 } mte_modes[] = { 107 - { PR_MTE_TCF_NONE, 0, "NONE" }, 108 - { PR_MTE_TCF_SYNC, HWCAP2_MTE, "SYNC" }, 109 - { PR_MTE_TCF_ASYNC, HWCAP2_MTE, "ASYNC" }, 110 - { PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC, HWCAP2_MTE, "SYNC+ASYNC" }, 103 + { PR_MTE_TCF_NONE, 0, 0, "NONE" }, 104 + { PR_MTE_TCF_SYNC, HWCAP2_MTE, 0, "SYNC" }, 105 + { PR_MTE_TCF_ASYNC, HWCAP2_MTE, 0, "ASYNC" }, 106 + { PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC, HWCAP2_MTE, 0, "SYNC+ASYNC" }, 107 + { PR_MTE_TCF_SYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "SYNC+STONLY" }, 108 + { PR_MTE_TCF_ASYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "ASYNC+STONLY" }, 109 + { PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "SYNC+ASYNC+STONLY" }, 111 110 }; 112 111 113 112 int main(void) ··· 119 110 int i; 120 111 121 112 ksft_print_header(); 122 - ksft_set_plan(5); 113 + ksft_set_plan(ARRAY_SIZE(mte_modes)); 123 114 124 115 check_basic_read(); 125 116 for (i = 0; i < ARRAY_SIZE(mte_modes); i++) 126 - set_mode_test(mte_modes[i].name, mte_modes[i].hwcap2, 117 + set_mode_test(mte_modes[i].name, mte_modes[i].hwcap2, mte_modes[i].hwcap3, 127 118 mte_modes[i].mask); 128 119 129 120 ksft_print_cnts();
+4 -4
tools/testing/selftests/arm64/mte/check_tags_inclusion.c
··· 57 57 return KSFT_FAIL; 58 58 59 59 for (tag = 0; (tag < MT_TAG_COUNT) && (result == KSFT_PASS); tag++) { 60 - ret = mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag)); 60 + ret = mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag), false); 61 61 if (ret != 0) 62 62 result = KSFT_FAIL; 63 63 /* Try to catch a excluded tag by a number of tries. */ ··· 91 91 92 92 for (tag = 0; (tag < MT_TAG_COUNT - 1) && (result == KSFT_PASS); tag++) { 93 93 excl_mask |= 1 << tag; 94 - mte_switch_mode(mode, MT_INCLUDE_VALID_TAGS(excl_mask)); 94 + mte_switch_mode(mode, MT_INCLUDE_VALID_TAGS(excl_mask), false); 95 95 /* Try to catch a excluded tag by a number of tries. */ 96 96 for (run = 0; (run < RUNS) && (result == KSFT_PASS); run++) { 97 97 ptr = mte_insert_tags(ptr, BUFFER_SIZE); ··· 120 120 mem_type, false) != KSFT_PASS) 121 121 return KSFT_FAIL; 122 122 123 - ret = mte_switch_mode(mode, MT_INCLUDE_TAG_MASK); 123 + ret = mte_switch_mode(mode, MT_INCLUDE_TAG_MASK, false); 124 124 if (ret != 0) 125 125 return KSFT_FAIL; 126 126 /* Try to catch a excluded tag by a number of tries. */ ··· 145 145 if (check_allocated_memory(ptr, BUFFER_SIZE, mem_type, false) != KSFT_PASS) 146 146 return KSFT_FAIL; 147 147 148 - ret = mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK); 148 + ret = mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK, false); 149 149 if (ret != 0) 150 150 return KSFT_FAIL; 151 151 /* Try to catch a excluded tag by a number of tries. */
+1 -1
tools/testing/selftests/arm64/mte/check_user_mem.c
··· 44 44 45 45 err = KSFT_PASS; 46 46 len = 2 * page_sz; 47 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 47 + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 48 48 fd = create_temp_file(); 49 49 if (fd == -1) 50 50 return KSFT_FAIL;
+12 -2
tools/testing/selftests/arm64/mte/mte_common_util.c
··· 28 28 29 29 struct mte_fault_cxt cur_mte_cxt; 30 30 bool mtefar_support; 31 + bool mtestonly_support; 31 32 static unsigned int mte_cur_mode; 32 33 static unsigned int mte_cur_pstate_tco; 34 + static bool mte_cur_stonly; 33 35 34 36 void mte_default_handler(int signum, siginfo_t *si, void *uc) 35 37 { ··· 316 314 cur_mte_cxt.trig_si_code = 0; 317 315 } 318 316 319 - int mte_switch_mode(int mte_option, unsigned long incl_mask) 317 + int mte_switch_mode(int mte_option, unsigned long incl_mask, bool stonly) 320 318 { 321 319 unsigned long en = 0; 322 320 ··· 348 346 break; 349 347 } 350 348 349 + if (mtestonly_support && stonly) 350 + en |= PR_MTE_STORE_ONLY; 351 + 351 352 en |= (incl_mask << PR_MTE_TAG_SHIFT); 352 353 /* Enable address tagging ABI, mte error reporting mode and tag inclusion mask. */ 353 354 if (prctl(PR_SET_TAGGED_ADDR_CTRL, en, 0, 0, 0) != 0) { ··· 375 370 376 371 mtefar_support = !!(hwcaps3 & HWCAP3_MTE_FAR); 377 372 373 + if (hwcaps3 & HWCAP3_MTE_STORE_ONLY) 374 + mtestonly_support = true; 375 + 378 376 /* Get current mte mode */ 379 377 ret = prctl(PR_GET_TAGGED_ADDR_CTRL, en, 0, 0, 0); 380 378 if (ret < 0) { ··· 391 383 else if (ret & PR_MTE_TCF_NONE) 392 384 mte_cur_mode = MTE_NONE_ERR; 393 385 386 + mte_cur_stonly = (ret & PR_MTE_STORE_ONLY) ? true : false; 387 + 394 388 mte_cur_pstate_tco = mte_get_pstate_tco(); 395 389 /* Disable PSTATE.TCO */ 396 390 mte_disable_pstate_tco(); ··· 401 391 402 392 void mte_restore_setup(void) 403 393 { 404 - mte_switch_mode(mte_cur_mode, MTE_ALLOW_NON_ZERO_TAG); 394 + mte_switch_mode(mte_cur_mode, MTE_ALLOW_NON_ZERO_TAG, mte_cur_stonly); 405 395 if (mte_cur_pstate_tco == MT_PSTATE_TCO_EN) 406 396 mte_enable_pstate_tco(); 407 397 else if (mte_cur_pstate_tco == MT_PSTATE_TCO_DIS)
+2 -1
tools/testing/selftests/arm64/mte/mte_common_util.h
··· 38 38 39 39 extern struct mte_fault_cxt cur_mte_cxt; 40 40 extern bool mtefar_support; 41 + extern bool mtestonly_support; 41 42 42 43 /* MTE utility functions */ 43 44 void mte_default_handler(int signum, siginfo_t *si, void *uc); ··· 61 60 void *mte_clear_atag(void *ptr); 62 61 int mte_default_setup(void); 63 62 void mte_restore_setup(void); 64 - int mte_switch_mode(int mte_option, unsigned long incl_mask); 63 + int mte_switch_mode(int mte_option, unsigned long incl_mask, bool stonly); 65 64 void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range); 66 65 67 66 /* Common utility functions */