* [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature
@ 2025-06-11 9:40 Yeoreum Yun
2025-06-11 9:40 ` [PATCH v6 1/9] arm64/cpufeature: add " Yeoreum Yun
` (8 more replies)
0 siblings, 9 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:40 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
The FEAT_MTE_TAGGED_FAR feature provides support for
reporting all non-address bits during a synchronous MTE tag check fault.
This patchset extends the reporting tag to include
not only the memory tag (logical tag) but also the address tag via
si_addr when FEAT_MTE_TAGGED_FAR feature is supported.
Patch Sequences
================
Patch #1 adds cpufeature FEAT_MTE_TAGGED_FAR
Patch #2 adds MTE_FAR hwcaps and export address tag when it supports
Patch #3 adds mtefar hwcap test
Patch #4 to #7 prepares to add mtefar testcase
Patch #8 refactor check_mmap_option using general testcase pattern
Patch #9 adds mtefar test cases corresponding to
each testcase of check_mmap_options
Patch History
================
v5 to v6:
- split Patch #4.
- refactor check_mmap_option using general testcase pattern
- https://lore.kernel.org/linux-arm-kernel/20250610150144.2523945-1-yeoreum.yun@arm.com/
v4 to v5:
- rebased on v6.16-rc1
- https://lore.kernel.org/linux-arm-kernel/20250507095757.1663684-1-yeoreum.yun@arm.com/
v3 to v4:
- fix hwcap string for FEAT_MTE_TAGGED_FAR
- split cpufeature and hwcap modification and merge hwcap's
modification with exporting address tag patch
- add mtefar testcase on check_mmap_options
- https://lore.kernel.org/all/20250410074721.947380-1-yeoreum.yun@arm.com/
v2 to v3:
- Rebase to 6.15-rc1
- https://lore.kernel.org/all/20250403172758.67106-1-yeoreum.yun@arm.com/
v1 to v2:
- add hwcap test for MTE_FAR feature.
- add MTE_FAR doc into elf_hwcap.rst
- https://lore.kernel.org/all/20250403142707.26397-1-yeoreum.yun@arm.com/
Yeoreum Yun (9):
arm64/cpufeature: add FEAT_MTE_TAGGED_FAR feature
arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
tools/kselftest: add MTE_FAR hwcap test
kselftest/arm64/mte: register mte signal handler with
SA_EXPOSE_TAGBITS
kselftest/arm64/mte: check MTE_FAR feature is supported
kselftest/arm64/mte: add address tag related macro and function
kselftest/arm64/mte: add verification for address tag in signal
handler
kselftest/arm64/mte: refactor check_mmap_option test
kselftest/arm64/mte: add mtefar tests on check_mmap_options
Documentation/arch/arm64/elf_hwcaps.rst | 3 +
Documentation/arch/arm64/tagged-pointers.rst | 11 +-
arch/arm64/include/asm/hwcap.h | 1 +
arch/arm64/include/uapi/asm/hwcap.h | 1 +
arch/arm64/kernel/cpufeature.c | 9 +
arch/arm64/kernel/cpuinfo.c | 1 +
arch/arm64/mm/fault.c | 7 +-
arch/arm64/tools/cpucaps | 1 +
tools/testing/selftests/arm64/abi/hwcap.c | 6 +
.../selftests/arm64/mte/check_buffer_fill.c | 2 +-
.../selftests/arm64/mte/check_child_memory.c | 4 +-
.../arm64/mte/check_hugetlb_options.c | 4 +-
.../selftests/arm64/mte/check_ksm_options.c | 4 +-
.../selftests/arm64/mte/check_mmap_options.c | 543 +++++++++++++++---
.../arm64/mte/check_tags_inclusion.c | 2 +-
.../selftests/arm64/mte/check_user_mem.c | 2 +-
.../selftests/arm64/mte/mte_common_util.c | 70 ++-
.../selftests/arm64/mte/mte_common_util.h | 6 +-
tools/testing/selftests/arm64/mte/mte_def.h | 8 +
19 files changed, 589 insertions(+), 96 deletions(-)
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v6 1/9] arm64/cpufeature: add FEAT_MTE_TAGGED_FAR feature
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
@ 2025-06-11 9:40 ` Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported Yeoreum Yun
` (7 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:40 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
Add FEAT_MTE_TAGGED_FAR cpucap which makes FAR_ELx report
all non-address bits on a synchronous MTE tag check fault since Armv8.9
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Acked-by: Yury Khrustalev <yury.khrustalev@arm.com>
---
arch/arm64/kernel/cpufeature.c | 8 ++++++++
arch/arm64/tools/cpucaps | 1 +
2 files changed, 9 insertions(+)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b34044e20128..af6a6924a3e8 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -320,6 +320,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTEFAR_SHIFT, 4, ID_AA64PFR2_EL1_MTEFAR_NI),
ARM64_FTR_END,
};
@@ -2874,6 +2875,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, MTE, MTE3)
},
+ {
+ .desc = "FAR on MTE Tag Check Fault",
+ .capability = ARM64_MTE_FAR,
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .matches = has_cpuid_feature,
+ ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTEFAR, IMP)
+ },
#endif /* CONFIG_ARM64_MTE */
{
.desc = "RCpc load-acquire (LDAPR)",
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 10effd4cff6b..fe8f4f8ce95c 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -68,6 +68,7 @@ MPAM
MPAM_HCR
MTE
MTE_ASYMM
+MTE_FAR
SME
SME_FA64
SME2
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
2025-06-11 9:40 ` [PATCH v6 1/9] arm64/cpufeature: add " Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 11:43 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 3/9] tools/kselftest: add MTE_FAR hwcap test Yeoreum Yun
` (6 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address
are preserved in response to synchronous tag check faults (SEGV_MTESERR).
This patch modifies below to support this feature:
- Use the original FAR_EL1 value when an MTE tag check fault occurs,
if ARM64_MTE_FAR is supported so that not only logical tag
(bits 59:56) but also address tag (bits 63:60] being reported too.
- Add HWCAP for mtefar to let user know bits 63:60 includes
address tag information when when FEAT_MTE_TAGGED_FAR is supported.
Applications that require this information should install
a signal handler with the SA_EXPOSE_TAGBITS flag.
While this introduces a minor ABI change,
most applications do not set this flag and therefore will not be affected.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
Documentation/arch/arm64/elf_hwcaps.rst | 3 +++
Documentation/arch/arm64/tagged-pointers.rst | 11 ++++++-----
arch/arm64/include/asm/hwcap.h | 1 +
arch/arm64/include/uapi/asm/hwcap.h | 1 +
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kernel/cpuinfo.c | 1 +
arch/arm64/mm/fault.c | 7 +++++--
7 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index 69d7afe56853..358f5af035ff 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -435,6 +435,9 @@ HWCAP2_SME_SF8DP4
HWCAP2_POE
Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
+HWCAP3_MTE_FAR
+ Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
+
4. Unused AT_HWCAP bits
-----------------------
diff --git a/Documentation/arch/arm64/tagged-pointers.rst b/Documentation/arch/arm64/tagged-pointers.rst
index 81b6c2a770dd..73c59a9c7a63 100644
--- a/Documentation/arch/arm64/tagged-pointers.rst
+++ b/Documentation/arch/arm64/tagged-pointers.rst
@@ -60,11 +60,12 @@ that signal handlers in applications making use of tags cannot rely
on the tag information for user virtual addresses being maintained
in these fields unless the flag was set.
-Due to architecture limitations, bits 63:60 of the fault address
-are not preserved in response to synchronous tag check faults
-(SEGV_MTESERR) even if SA_EXPOSE_TAGBITS was set. Applications should
-treat the values of these bits as undefined in order to accommodate
-future architecture revisions which may preserve the bits.
+If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address
+are preserved in response to synchronous tag check faults (SEGV_MTESERR)
+otherwise not preserved even if SA_EXPOSE_TAGBITS was set.
+Applications should interpret the values of these bits based on
+the support for the 'mte_far' hwcap. If the support is not present,
+the values of these bits should be considered as undefined otherwise valid.
For signals raised in response to watchpoint debug exceptions, the
tag information will be preserved regardless of the SA_EXPOSE_TAGBITS
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 1c3f9617d54f..28dd1ac29ecc 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -176,6 +176,7 @@
#define KERNEL_HWCAP_POE __khwcap2_feature(POE)
#define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128)
+#define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR)
/*
* This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 705a7afa8e58..7d22527a7975 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -143,5 +143,6 @@
/*
* HWCAP3 flags - for AT_HWCAP3
*/
+#define HWCAP3_MTE_FAR (1UL << 0)
#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index af6a6924a3e8..8a5284c733b7 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3219,6 +3219,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
#ifdef CONFIG_ARM64_MTE
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE),
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3),
+ HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR),
#endif /* CONFIG_ARM64_MTE */
HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index c1f2b6b04b41..e552cb305641 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -160,6 +160,7 @@ static const char *const hwcap_str[] = {
[KERNEL_HWCAP_SME_SFEXPA] = "smesfexpa",
[KERNEL_HWCAP_SME_STMOP] = "smestmop",
[KERNEL_HWCAP_SME_SMOP4] = "smesmop4",
+ [KERNEL_HWCAP_MTE_FAR] = "mtefar",
};
#ifdef CONFIG_COMPAT
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ec0a337891dd..f21d972f99b1 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -837,9 +837,12 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
/*
* The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
* for tag check faults. Set them to corresponding bits in the untagged
- * address.
+ * address if ARM64_MTE_FAR isn't supported.
+ * Otherwise, bits 63:60 of FAR_EL1 are KNOWN.
*/
- far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
+ if (!cpus_have_cap(ARM64_MTE_FAR))
+ far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
+
do_bad_area(far, esr, regs);
return 0;
}
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 3/9] tools/kselftest: add MTE_FAR hwcap test
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
2025-06-11 9:40 ` [PATCH v6 1/9] arm64/cpufeature: add " Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS Yeoreum Yun
` (5 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
add MTE_FAR hwcap test on kselftest.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
---
tools/testing/selftests/arm64/abi/hwcap.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index 35f521e5f41c..e60bfb798ba2 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -1098,6 +1098,12 @@ static const struct hwcap_data {
.sigill_fn = hbc_sigill,
.sigill_reliable = true,
},
+ {
+ .name = "MTE_FAR",
+ .at_hwcap = AT_HWCAP3,
+ .hwcap_bit = HWCAP3_MTE_FAR,
+ .cpuinfo = "mtefar",
+ },
};
typedef void (*sighandler_fn)(int, siginfo_t *, void *);
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (2 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 3/9] tools/kselftest: add MTE_FAR hwcap test Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 11:45 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported Yeoreum Yun
` (4 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
To test address tag[63:60] and memory tag[59:56] is preserved
when memory tag fault happen, Let mte_register_signal() to register
signal handler with SA_EXPOSE_TAGBITS.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
tools/testing/selftests/arm64/mte/check_buffer_fill.c | 2 +-
.../testing/selftests/arm64/mte/check_child_memory.c | 4 ++--
.../selftests/arm64/mte/check_hugetlb_options.c | 4 ++--
tools/testing/selftests/arm64/mte/check_ksm_options.c | 4 ++--
.../testing/selftests/arm64/mte/check_mmap_options.c | 4 ++--
.../selftests/arm64/mte/check_tags_inclusion.c | 2 +-
tools/testing/selftests/arm64/mte/check_user_mem.c | 2 +-
tools/testing/selftests/arm64/mte/mte_common_util.c | 11 ++++++++++-
tools/testing/selftests/arm64/mte/mte_common_util.h | 3 ++-
9 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/check_buffer_fill.c b/tools/testing/selftests/arm64/mte/check_buffer_fill.c
index 2ee7f114d7fa..5248b5265aa4 100644
--- a/tools/testing/selftests/arm64/mte/check_buffer_fill.c
+++ b/tools/testing/selftests/arm64/mte/check_buffer_fill.c
@@ -415,7 +415,7 @@ int main(int argc, char *argv[])
return err;
/* Register SIGSEGV handler */
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(20);
diff --git a/tools/testing/selftests/arm64/mte/check_child_memory.c b/tools/testing/selftests/arm64/mte/check_child_memory.c
index 7597fc632cad..b97ea3981c21 100644
--- a/tools/testing/selftests/arm64/mte/check_child_memory.c
+++ b/tools/testing/selftests/arm64/mte/check_child_memory.c
@@ -160,8 +160,8 @@ int main(int argc, char *argv[])
return err;
/* Register SIGSEGV handler */
- mte_register_signal(SIGSEGV, mte_default_handler);
- mte_register_signal(SIGBUS, mte_default_handler);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
+ mte_register_signal(SIGBUS, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(12);
diff --git a/tools/testing/selftests/arm64/mte/check_hugetlb_options.c b/tools/testing/selftests/arm64/mte/check_hugetlb_options.c
index 3bfcd3848432..4e644a606394 100644
--- a/tools/testing/selftests/arm64/mte/check_hugetlb_options.c
+++ b/tools/testing/selftests/arm64/mte/check_hugetlb_options.c
@@ -235,8 +235,8 @@ int main(int argc, char *argv[])
return err;
/* Register signal handlers */
- mte_register_signal(SIGBUS, mte_default_handler);
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGBUS, mte_default_handler, false);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
allocate_hugetlb();
diff --git a/tools/testing/selftests/arm64/mte/check_ksm_options.c b/tools/testing/selftests/arm64/mte/check_ksm_options.c
index 88c74bc46d4f..afea4e381862 100644
--- a/tools/testing/selftests/arm64/mte/check_ksm_options.c
+++ b/tools/testing/selftests/arm64/mte/check_ksm_options.c
@@ -141,8 +141,8 @@ int main(int argc, char *argv[])
return KSFT_FAIL;
}
/* Register signal handlers */
- mte_register_signal(SIGBUS, mte_default_handler);
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGBUS, mte_default_handler, false);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(4);
diff --git a/tools/testing/selftests/arm64/mte/check_mmap_options.c b/tools/testing/selftests/arm64/mte/check_mmap_options.c
index 17694caaff53..b37bf481c9f9 100644
--- a/tools/testing/selftests/arm64/mte/check_mmap_options.c
+++ b/tools/testing/selftests/arm64/mte/check_mmap_options.c
@@ -201,8 +201,8 @@ int main(int argc, char *argv[])
sizes[item - 1] = page_size + 1;
/* Register signal handlers */
- mte_register_signal(SIGBUS, mte_default_handler);
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGBUS, mte_default_handler, false);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(22);
diff --git a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
index a3d1e23fe02a..b96296ab9870 100644
--- a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
+++ b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
@@ -180,7 +180,7 @@ int main(int argc, char *argv[])
return err;
/* Register SIGSEGV handler */
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(4);
diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index f4ae5f87a3b7..d1d14aaaba16 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -211,7 +211,7 @@ int main(int argc, char *argv[])
return err;
/* Register signal handlers */
- mte_register_signal(SIGSEGV, mte_default_handler);
+ mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
ksft_set_plan(64);
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
index a1dc2fe5285b..83240b980f9c 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
@@ -19,6 +19,10 @@
#include "mte_common_util.h"
#include "mte_def.h"
+#ifndef SA_EXPOSE_TAGBITS
+#define SA_EXPOSE_TAGBITS 0x00000800
+#endif
+
#define INIT_BUFFER_SIZE 256
struct mte_fault_cxt cur_mte_cxt;
@@ -79,12 +83,17 @@ void mte_default_handler(int signum, siginfo_t *si, void *uc)
}
}
-void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *))
+void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *),
+ bool export_tags)
{
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
+
+ if (export_tags && signal == SIGSEGV)
+ sa.sa_flags |= SA_EXPOSE_TAGBITS;
+
sigemptyset(&sa.sa_mask);
sigaction(signal, &sa, NULL);
}
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.h b/tools/testing/selftests/arm64/mte/mte_common_util.h
index a0017a303beb..6b109e84fa39 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.h
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.h
@@ -40,7 +40,8 @@ extern struct mte_fault_cxt cur_mte_cxt;
/* MTE utility functions */
void mte_default_handler(int signum, siginfo_t *si, void *uc);
-void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *));
+void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *),
+ bool export_tags);
void mte_wait_after_trig(void);
void *mte_allocate_memory(size_t size, int mem_type, int mapping, bool tags);
void *mte_allocate_memory_tag_range(size_t size, int mem_type, int mapping,
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (3 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 11:52 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function Yeoreum Yun
` (3 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
To run the MTE_FAR test when cpu supports MTE_FAR feature,
check the MTE_FAR_ feature is supported in mte test.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
tools/testing/selftests/arm64/mte/mte_common_util.c | 7 +++++++
tools/testing/selftests/arm64/mte/mte_common_util.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
index 83240b980f9c..048b8a507b70 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
@@ -6,6 +6,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
#include <linux/auxvec.h>
@@ -26,6 +27,7 @@
#define INIT_BUFFER_SIZE 256
struct mte_fault_cxt cur_mte_cxt;
+bool mtefar_support;
static unsigned int mte_cur_mode;
static unsigned int mte_cur_pstate_tco;
@@ -273,6 +275,7 @@ void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range)
cur_mte_cxt.fault_valid = false;
cur_mte_cxt.trig_addr = ptr;
cur_mte_cxt.trig_range = range;
+
if (mode == MTE_SYNC_ERR)
cur_mte_cxt.trig_si_code = SEGV_MTESERR;
else if (mode == MTE_ASYNC_ERR)
@@ -325,12 +328,16 @@ int mte_switch_mode(int mte_option, unsigned long incl_mask)
int mte_default_setup(void)
{
unsigned long hwcaps2 = getauxval(AT_HWCAP2);
+ unsigned long hwcaps3 = getauxval(AT_HWCAP3);
unsigned long en = 0;
int ret;
if (!(hwcaps2 & HWCAP2_MTE))
ksft_exit_skip("MTE features unavailable\n");
+ if (hwcaps3 & HWCAP3_MTE_FAR)
+ mtefar_support = true;
+
/* Get current mte mode */
ret = prctl(PR_GET_TAGGED_ADDR_CTRL, en, 0, 0, 0);
if (ret < 0) {
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.h b/tools/testing/selftests/arm64/mte/mte_common_util.h
index 6b109e84fa39..4e1dd959df9b 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.h
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.h
@@ -37,6 +37,7 @@ struct mte_fault_cxt {
};
extern struct mte_fault_cxt cur_mte_cxt;
+extern bool mtefar_support;
/* MTE utility functions */
void mte_default_handler(int signum, siginfo_t *si, void *uc);
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (4 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 11:58 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler Yeoreum Yun
` (2 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
Add address tag related macro and function to test MTE_FAR feature.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
.../testing/selftests/arm64/mte/mte_common_util.c | 14 ++++++++++++++
.../testing/selftests/arm64/mte/mte_common_util.h | 2 ++
tools/testing/selftests/arm64/mte/mte_def.h | 8 ++++++++
3 files changed, 24 insertions(+)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
index 048b8a507b70..c21f86143a6f 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
@@ -131,6 +131,20 @@ void mte_clear_tags(void *ptr, size_t size)
mte_clear_tag_address_range(ptr, size);
}
+void *mte_insert_atag(void *ptr)
+{
+ unsigned char atag;
+
+ srandom(time(NULL));
+ atag = mtefar_support ? (random() % MT_ATAG_MASK) + 1 : 0;
+ return (void *)MT_SET_ATAG((unsigned long)ptr, atag);
+}
+
+void *mte_clear_atag(void *ptr)
+{
+ return (void *)MT_CLEAR_ATAG((unsigned long)ptr);
+}
+
static void *__mte_allocate_memory_range(size_t size, int mem_type, int mapping,
size_t range_before, size_t range_after,
bool tags, int fd)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.h b/tools/testing/selftests/arm64/mte/mte_common_util.h
index 4e1dd959df9b..045e4ad2f018 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.h
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.h
@@ -56,6 +56,8 @@ void mte_free_memory_tag_range(void *ptr, size_t size, int mem_type,
size_t range_before, size_t range_after);
void *mte_insert_tags(void *ptr, size_t size);
void mte_clear_tags(void *ptr, size_t size);
+void *mte_insert_atag(void *ptr);
+void *mte_clear_atag(void *ptr);
int mte_default_setup(void);
void mte_restore_setup(void);
int mte_switch_mode(int mte_option, unsigned long incl_mask);
diff --git a/tools/testing/selftests/arm64/mte/mte_def.h b/tools/testing/selftests/arm64/mte/mte_def.h
index 9b188254b61a..6ad22f07c9b8 100644
--- a/tools/testing/selftests/arm64/mte/mte_def.h
+++ b/tools/testing/selftests/arm64/mte/mte_def.h
@@ -42,6 +42,8 @@
#define MT_TAG_COUNT 16
#define MT_INCLUDE_TAG_MASK 0xFFFF
#define MT_EXCLUDE_TAG_MASK 0x0
+#define MT_ATAG_SHIFT 60
+#define MT_ATAG_MASK 0xFUL
#define MT_ALIGN_GRANULE (MT_GRANULE_SIZE - 1)
#define MT_CLEAR_TAG(x) ((x) & ~(MT_TAG_MASK << MT_TAG_SHIFT))
@@ -49,6 +51,12 @@
#define MT_FETCH_TAG(x) ((x >> MT_TAG_SHIFT) & (MT_TAG_MASK))
#define MT_ALIGN_UP(x) ((x + MT_ALIGN_GRANULE) & ~(MT_ALIGN_GRANULE))
+#define MT_CLEAR_ATAG(x) ((x) & ~(MT_TAG_MASK << MT_ATAG_SHIFT))
+#define MT_SET_ATAG(x, y) ((x) | (((y) & MT_ATAG_MASK) << MT_ATAG_SHIFT))
+#define MT_FETCH_ATAG(x) ((x >> MT_ATAG_SHIFT) & (MT_ATAG_MASK))
+
+#define MT_CLEAR_TAGS(x) (MT_CLEAR_ATAG(MT_CLEAR_TAG(x)))
+
#define MT_PSTATE_TCO_SHIFT 25
#define MT_PSTATE_TCO_MASK ~(0x1 << MT_PSTATE_TCO_SHIFT)
#define MT_PSTATE_TCO_EN 1
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (5 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 12:12 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options Yeoreum Yun
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
Add the address tag [63:60] verification when synchronous mte fault is happen.
when signal handler is registered with SA_EXPOSE_TAGBITS,
address includes not only memory tag [59:56] but also address tag.
Therefore, when verify fault address location, remove both tags
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
.../selftests/arm64/mte/mte_common_util.c | 38 ++++++++++++++-----
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
index c21f86143a6f..ca5bb9e6472b 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
@@ -33,12 +33,25 @@ static unsigned int mte_cur_pstate_tco;
void mte_default_handler(int signum, siginfo_t *si, void *uc)
{
+ struct sigaction sa;
unsigned long addr = (unsigned long)si->si_addr;
+ unsigned char si_tag, si_atag;
+
+ sigaction(signum, NULL, &sa);
+
+ if (sa.sa_flags & SA_EXPOSE_TAGBITS) {
+ si_tag = MT_FETCH_TAG(addr);
+ si_atag = MT_FETCH_ATAG(addr);
+ addr = MT_CLEAR_TAGS(addr);
+ } else {
+ si_tag = 0;
+ si_atag = 0;
+ }
if (signum == SIGSEGV) {
#ifdef DEBUG
- ksft_print_msg("INFO: SIGSEGV signal at pc=%lx, fault addr=%lx, si_code=%lx\n",
- ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code);
+ ksft_print_msg("INFO: SIGSEGV signal at pc=%lx, fault addr=%lx, si_code=%lx, si_tag=%x, si_atag=%x\n",
+ ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code, si_tag, si_atag);
#endif
if (si->si_code == SEGV_MTEAERR) {
if (cur_mte_cxt.trig_si_code == si->si_code)
@@ -51,13 +64,18 @@ void mte_default_handler(int signum, siginfo_t *si, void *uc)
}
/* Compare the context for precise error */
else if (si->si_code == SEGV_MTESERR) {
+ if ((!mtefar_support && si_atag) || (si_atag != MT_FETCH_ATAG(cur_mte_cxt.trig_addr))) {
+ ksft_print_msg("Invalid MTE synchronous exception caught for address tag! si_tag=%x, si_atag: %x\n", si_tag, si_atag);
+ exit(KSFT_FAIL);
+ }
+
if (cur_mte_cxt.trig_si_code == si->si_code &&
((cur_mte_cxt.trig_range >= 0 &&
- addr >= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) &&
- addr <= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
+ addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
+ addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
(cur_mte_cxt.trig_range < 0 &&
- addr <= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) &&
- addr >= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)))) {
+ addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
+ addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)))) {
cur_mte_cxt.fault_valid = true;
/* Adjust the pc by 4 */
((ucontext_t *)uc)->uc_mcontext.pc += 4;
@@ -73,11 +91,11 @@ void mte_default_handler(int signum, siginfo_t *si, void *uc)
ksft_print_msg("INFO: SIGBUS signal at pc=%llx, fault addr=%lx, si_code=%x\n",
((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code);
if ((cur_mte_cxt.trig_range >= 0 &&
- addr >= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) &&
- addr <= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
+ addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
+ addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
(cur_mte_cxt.trig_range < 0 &&
- addr <= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) &&
- addr >= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range))) {
+ addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
+ addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range))) {
cur_mte_cxt.fault_valid = true;
/* Adjust the pc by 4 */
((ucontext_t *)uc)->uc_mcontext.pc += 4;
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (6 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 12:27 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options Yeoreum Yun
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
Before add mtefar testcase on check_mmap_option.c,
refactor check_mmap_option:
- make testcase suite array with test options (mem_type, mte_sync type and etc)
to use general testcase pattern
- generate each test case name acoording to test options.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
.../selftests/arm64/mte/check_mmap_options.c | 367 +++++++++++++++---
1 file changed, 313 insertions(+), 54 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/check_mmap_options.c b/tools/testing/selftests/arm64/mte/check_mmap_options.c
index b37bf481c9f9..0df7ce532465 100644
--- a/tools/testing/selftests/arm64/mte/check_mmap_options.c
+++ b/tools/testing/selftests/arm64/mte/check_mmap_options.c
@@ -3,6 +3,7 @@
#define _GNU_SOURCE
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@@ -24,6 +25,23 @@
#define TAG_CHECK_ON 0
#define TAG_CHECK_OFF 1
+#define TEST_NAME_MAX 256
+
+enum mte_mem_check_type {
+ CHECK_ANON_MEM = 0,
+ CHECK_FILE_MEM = 1,
+ CHECK_CLEAR_PROT_MTE = 2,
+};
+
+struct check_mmap_testcase {
+ int check_type;
+ int mem_type;
+ int mte_sync;
+ int mapping;
+ int tag_check;
+ bool enable_tco;
+};
+
static size_t page_size;
static int sizes[] = {
1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,
@@ -183,10 +201,271 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
return KSFT_PASS;
}
+const char *format_test_name(struct check_mmap_testcase *tc)
+{
+ static char test_name[TEST_NAME_MAX];
+ const char *check_type_str;
+ const char *mem_type_str;
+ const char *sync_str;
+ const char *mapping_str;
+ const char *tag_check_str;
+
+ switch (tc->check_type) {
+ case CHECK_ANON_MEM:
+ check_type_str = "anonymous memory";
+ break;
+ case CHECK_FILE_MEM:
+ check_type_str = "file memory";
+ break;
+ case CHECK_CLEAR_PROT_MTE:
+ check_type_str = "clear PROT_MTE flags";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch (tc->mem_type) {
+ case USE_MMAP:
+ mem_type_str = "mmap";
+ break;
+ case USE_MPROTECT:
+ mem_type_str = "mmap/mprotect";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch (tc->mte_sync) {
+ case MTE_NONE_ERR:
+ sync_str = "no error";
+ break;
+ case MTE_SYNC_ERR:
+ sync_str = "sync error";
+ break;
+ case MTE_ASYNC_ERR:
+ sync_str = "async error";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch (tc->mapping) {
+ case MAP_SHARED:
+ mapping_str = "shared";
+ break;
+ case MAP_PRIVATE:
+ mapping_str = "private";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch (tc->tag_check) {
+ case TAG_CHECK_ON:
+ tag_check_str = "tag check on";
+ break;
+ case TAG_CHECK_OFF:
+ tag_check_str = "tag check off";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ snprintf(test_name, sizeof(test_name),
+ "Check %s with %s mapping, %s mode, %s memory and %s\n",
+ check_type_str, mapping_str, sync_str, mem_type_str,
+ tag_check_str);
+
+ return test_name;
+}
+
int main(int argc, char *argv[])
{
- int err;
+ int err, i;
int item = ARRAY_SIZE(sizes);
+ struct check_mmap_testcase test_cases[]= {
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_OFF,
+ .enable_tco = true,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_OFF,
+ .enable_tco = true,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_NONE_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_OFF,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_NONE_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_OFF,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_CLEAR_PROT_MTE,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_CLEAR_PROT_MTE,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ };
err = mte_default_setup();
if (err)
@@ -205,59 +484,39 @@ int main(int argc, char *argv[])
mte_register_signal(SIGSEGV, mte_default_handler, false);
/* Set test plan */
- ksft_set_plan(22);
-
- mte_enable_pstate_tco();
-
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
- "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
- "Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check off\n");
-
- mte_disable_pstate_tco();
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
- "Check anonymous memory with private mapping, no error mode, mmap memory and tag check off\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
- "Check file memory with private mapping, no error mode, mmap/mprotect memory and tag check off\n");
-
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check anonymous memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check anonymous memory with shared mapping, sync error mode, mmap memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check anonymous memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check anonymous memory with private mapping, async error mode, mmap memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check anonymous memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check anonymous memory with shared mapping, async error mode, mmap memory and tag check on\n");
- evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check anonymous memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");
-
- evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check file memory with private mapping, sync error mode, mmap memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check file memory with shared mapping, sync error mode, mmap memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check file memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check file memory with private mapping, async error mode, mmap memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
- "Check file memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check file memory with shared mapping, async error mode, mmap memory and tag check on\n");
- evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
- "Check file memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");
-
- evaluate_test(check_clear_prot_mte_flag(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
- "Check clear PROT_MTE flags with private mapping, sync error mode and mmap memory\n");
- evaluate_test(check_clear_prot_mte_flag(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),
- "Check clear PROT_MTE flags with private mapping and sync error mode and mmap/mprotect memory\n");
+ ksft_set_plan(ARRAY_SIZE(test_cases));
+
+ for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) {
+ if (test_cases[i].enable_tco)
+ mte_enable_pstate_tco();
+ else
+ mte_disable_pstate_tco();
+
+ switch (test_cases[i].check_type) {
+ case CHECK_ANON_MEM:
+ evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type,
+ test_cases[i].mte_sync,
+ test_cases[i].mapping,
+ test_cases[i].tag_check),
+ format_test_name(&test_cases[i]));
+ break;
+ case CHECK_FILE_MEM:
+ evaluate_test(check_file_memory_mapping(test_cases[i].mem_type,
+ test_cases[i].mte_sync,
+ test_cases[i].mapping,
+ test_cases[i].tag_check),
+ format_test_name(&test_cases[i]));
+ break;
+ case CHECK_CLEAR_PROT_MTE:
+ evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type,
+ test_cases[i].mte_sync,
+ test_cases[i].mapping),
+ format_test_name(&test_cases[i]));
+ break;
+ default:
+ exit(KSFT_FAIL);
+ }
+ }
mte_restore_setup();
ksft_print_cnts();
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
` (7 preceding siblings ...)
2025-06-11 9:41 ` [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test Yeoreum Yun
@ 2025-06-11 9:41 ` Yeoreum Yun
2025-06-11 12:25 ` Mark Brown
8 siblings, 1 reply; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 9:41 UTC (permalink / raw)
To: catalin.marinas, pcc, will, broonie, anshuman.khandual,
joey.gouly, yury.khrustalev, maz, oliver.upton, frederic, akpm,
surenb
Cc: linux-arm-kernel, linux-kernel, linux-doc, Yeoreum Yun
If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address
are preserved in response to synchronous tag check faults (SEGV_MTESERR).
This patch adds new test cases using address tags (bits 63:60),
corresponding to each existing test in check_mmap_option.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
.../selftests/arm64/mte/check_mmap_options.c | 186 ++++++++++++++++--
1 file changed, 167 insertions(+), 19 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/check_mmap_options.c b/tools/testing/selftests/arm64/mte/check_mmap_options.c
index 0df7ce532465..046fa909de86 100644
--- a/tools/testing/selftests/arm64/mte/check_mmap_options.c
+++ b/tools/testing/selftests/arm64/mte/check_mmap_options.c
@@ -24,6 +24,8 @@
#define OVERFLOW MT_GRANULE_SIZE
#define TAG_CHECK_ON 0
#define TAG_CHECK_OFF 1
+#define ATAG_CHECK_ON 1
+#define ATAG_CHECK_OFF 0
#define TEST_NAME_MAX 256
@@ -39,6 +41,7 @@ struct check_mmap_testcase {
int mte_sync;
int mapping;
int tag_check;
+ int atag_check;
bool enable_tco;
};
@@ -48,8 +51,14 @@ static int sizes[] = {
/* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0
};
-static int check_mte_memory(char *ptr, int size, int mode, int tag_check)
+static int check_mte_memory(char *ptr, int size, int mode, int tag_check, int atag_check)
{
+ if (!mtefar_support && atag_check == ATAG_CHECK_ON)
+ return KSFT_SKIP;
+
+ if (atag_check == ATAG_CHECK_ON)
+ ptr = mte_insert_atag(ptr);
+
mte_initialize_current_context(mode, (uintptr_t)ptr, size);
memset(ptr, '1', size);
mte_wait_after_trig();
@@ -75,7 +84,7 @@ static int check_mte_memory(char *ptr, int size, int mode, int tag_check)
return KSFT_PASS;
}
-static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check)
+static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
{
char *ptr, *map_ptr;
int run, result, map_size;
@@ -97,16 +106,16 @@ static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, i
munmap((void *)map_ptr, map_size);
return KSFT_FAIL;
}
- result = check_mte_memory(ptr, sizes[run], mode, tag_check);
+ result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check);
mte_clear_tags((void *)ptr, sizes[run]);
mte_free_memory((void *)map_ptr, map_size, mem_type, false);
- if (result == KSFT_FAIL)
- return KSFT_FAIL;
+ if (result != KSFT_SKIP)
+ return result;
}
return KSFT_PASS;
}
-static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check)
+static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
{
char *ptr, *map_ptr;
int run, fd, map_size;
@@ -135,7 +144,7 @@ static int check_file_memory_mapping(int mem_type, int mode, int mapping, int ta
close(fd);
return KSFT_FAIL;
}
- result = check_mte_memory(ptr, sizes[run], mode, tag_check);
+ result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check);
mte_clear_tags((void *)ptr, sizes[run]);
munmap((void *)map_ptr, map_size);
close(fd);
@@ -145,7 +154,7 @@ static int check_file_memory_mapping(int mem_type, int mode, int mapping, int ta
return result;
}
-static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
+static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int atag_check)
{
char *ptr, *map_ptr;
int run, prot_flag, result, fd, map_size;
@@ -168,7 +177,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n");
return KSFT_FAIL;
}
- result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON);
+ result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check);
mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
if (result != KSFT_PASS)
return KSFT_FAIL;
@@ -192,7 +201,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
close(fd);
return KSFT_FAIL;
}
- result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON);
+ result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check);
mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
close(fd);
if (result != KSFT_PASS)
@@ -209,6 +218,7 @@ const char *format_test_name(struct check_mmap_testcase *tc)
const char *sync_str;
const char *mapping_str;
const char *tag_check_str;
+ const char *atag_check_str;
switch (tc->check_type) {
case CHECK_ANON_MEM:
@@ -276,10 +286,22 @@ const char *format_test_name(struct check_mmap_testcase *tc)
break;
}
+ switch (tc->atag_check) {
+ case ATAG_CHECK_ON:
+ atag_check_str = "with address tag [63:60]";
+ break;
+ case ATAG_CHECK_OFF:
+ atag_check_str = "without address tag [63:60]";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
snprintf(test_name, sizeof(test_name),
- "Check %s with %s mapping, %s mode, %s memory and %s\n",
+ "Check %s with %s mapping, %s mode, %s memory and %s (%s)\n",
check_type_str, mapping_str, sync_str, mem_type_str,
- tag_check_str);
+ tag_check_str, atag_check_str);
return test_name;
}
@@ -295,6 +317,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_OFF,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = true,
},
{
@@ -303,6 +326,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_OFF,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = true,
},
{
@@ -311,6 +335,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_NONE_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_OFF,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -319,6 +344,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_NONE_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_OFF,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -327,6 +353,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -335,6 +362,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -343,6 +371,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -351,6 +380,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -359,6 +389,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -367,6 +398,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -375,6 +407,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -383,6 +416,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -391,6 +425,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -399,6 +434,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -407,6 +443,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -415,6 +452,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -423,6 +461,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -431,6 +470,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -439,6 +479,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
.enable_tco = false,
},
{
@@ -447,6 +488,106 @@ int main(int argc, char *argv[])
.mte_sync = MTE_ASYNC_ERR,
.mapping = MAP_SHARED,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_CLEAR_PROT_MTE,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_CLEAR_PROT_MTE,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_OFF,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_ANON_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MPROTECT,
+ .mte_sync = MTE_SYNC_ERR,
+ .mapping = MAP_SHARED,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
+ .enable_tco = false,
+ },
+ {
+ .check_type = CHECK_FILE_MEM,
+ .mem_type = USE_MMAP,
+ .mte_sync = MTE_ASYNC_ERR,
+ .mapping = MAP_PRIVATE,
+ .tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
.enable_tco = false,
},
{
@@ -455,6 +596,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
.enable_tco = false,
},
{
@@ -463,6 +605,7 @@ int main(int argc, char *argv[])
.mte_sync = MTE_SYNC_ERR,
.mapping = MAP_PRIVATE,
.tag_check = TAG_CHECK_ON,
+ .atag_check = ATAG_CHECK_ON,
.enable_tco = false,
},
};
@@ -479,14 +622,16 @@ int main(int argc, char *argv[])
sizes[item - 2] = page_size;
sizes[item - 1] = page_size + 1;
- /* Register signal handlers */
- mte_register_signal(SIGBUS, mte_default_handler, false);
- mte_register_signal(SIGSEGV, mte_default_handler, false);
-
/* Set test plan */
ksft_set_plan(ARRAY_SIZE(test_cases));
for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) {
+ /* Register signal handlers */
+ mte_register_signal(SIGBUS, mte_default_handler,
+ test_cases[i].atag_check == ATAG_CHECK_ON);
+ mte_register_signal(SIGSEGV, mte_default_handler,
+ test_cases[i].atag_check == ATAG_CHECK_ON);
+
if (test_cases[i].enable_tco)
mte_enable_pstate_tco();
else
@@ -497,20 +642,23 @@ int main(int argc, char *argv[])
evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type,
test_cases[i].mte_sync,
test_cases[i].mapping,
- test_cases[i].tag_check),
+ test_cases[i].tag_check,
+ test_cases[i].atag_check),
format_test_name(&test_cases[i]));
break;
case CHECK_FILE_MEM:
evaluate_test(check_file_memory_mapping(test_cases[i].mem_type,
test_cases[i].mte_sync,
test_cases[i].mapping,
- test_cases[i].tag_check),
+ test_cases[i].tag_check,
+ test_cases[i].atag_check),
format_test_name(&test_cases[i]));
break;
case CHECK_CLEAR_PROT_MTE:
evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type,
test_cases[i].mte_sync,
- test_cases[i].mapping),
+ test_cases[i].mapping,
+ test_cases[i].atag_check),
format_test_name(&test_cases[i]));
break;
default:
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
2025-06-11 9:41 ` [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported Yeoreum Yun
@ 2025-06-11 11:43 ` Mark Brown
2025-06-11 12:19 ` Yeo Reum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 11:43 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 871 bytes --]
On Wed, Jun 11, 2025 at 10:41:00AM +0100, Yeoreum Yun wrote:
> +HWCAP3_MTE_FAR
> + Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
> +Applications should interpret the values of these bits based on
> +the support for the 'mte_far' hwcap. If the support is not present,
> +the values of these bits should be considered as undefined otherwise valid.
The constant is HWCAP3_MTE_FAR and the cpuinfo is mtefar:
> + [KERNEL_HWCAP_MTE_FAR] = "mtefar",
The reference to the hwcap should probably be one of these, I'd go for
HWCAP3_MTE_FAR since it says hwcap.
> /*
> * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
> * for tag check faults. Set them to corresponding bits in the untagged
> - * address.
> + * address if ARM64_MTE_FAR isn't supported.
> + * Otherwise, bits 63:60 of FAR_EL1 are KNOWN.
Should this say UNKNOWN?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS
2025-06-11 9:41 ` [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS Yeoreum Yun
@ 2025-06-11 11:45 ` Mark Brown
0 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2025-06-11 11:45 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 282 bytes --]
On Wed, Jun 11, 2025 at 10:41:02AM +0100, Yeoreum Yun wrote:
> To test address tag[63:60] and memory tag[59:56] is preserved
> when memory tag fault happen, Let mte_register_signal() to register
> signal handler with SA_EXPOSE_TAGBITS.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported
2025-06-11 9:41 ` [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported Yeoreum Yun
@ 2025-06-11 11:52 ` Mark Brown
2025-06-11 12:23 ` Yeo Reum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 11:52 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]
On Wed, Jun 11, 2025 at 10:41:03AM +0100, Yeoreum Yun wrote:
> --- a/tools/testing/selftests/arm64/mte/mte_common_util.c
> +++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
> @@ -6,6 +6,7 @@
> #include <signal.h>
> #include <stdio.h>
> #include <stdlib.h>
> +#include <time.h>
> #include <unistd.h>
Not sure why we'd be including time.h here?
>
> #include <linux/auxvec.h>
> @@ -26,6 +27,7 @@
> #define INIT_BUFFER_SIZE 256
>
> struct mte_fault_cxt cur_mte_cxt;
> +bool mtefar_support;
This is a non-static variable so won't have a defined default value...
> @@ -273,6 +275,7 @@ void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range)
> cur_mte_cxt.fault_valid = false;
> cur_mte_cxt.trig_addr = ptr;
> cur_mte_cxt.trig_range = range;
> +
> if (mode == MTE_SYNC_ERR)
> cur_mte_cxt.trig_si_code = SEGV_MTESERR;
> else if (mode == MTE_ASYNC_ERR)
Unrelated whitespace change.
> if (!(hwcaps2 & HWCAP2_MTE))
> ksft_exit_skip("MTE features unavailable\n");
>
> + if (hwcaps3 & HWCAP3_MTE_FAR)
> + mtefar_support = true;
> +
...this will only set mtefar_support if the hwcap is present, leaving it
undefined if not. If you just make this
mtefar_support = hwcap3 & HWCAP3_MTE_FAR
that should avoid the issue.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function
2025-06-11 9:41 ` [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function Yeoreum Yun
@ 2025-06-11 11:58 ` Mark Brown
2025-06-11 12:25 ` Yeo Reum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 11:58 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 799 bytes --]
On Wed, Jun 11, 2025 at 10:41:04AM +0100, Yeoreum Yun wrote:
> Add address tag related macro and function to test MTE_FAR feature.
> +void *mte_insert_atag(void *ptr)
> +{
> + unsigned char atag;
> +
> + srandom(time(NULL));
> + atag = mtefar_support ? (random() % MT_ATAG_MASK) + 1 : 0;
> + return (void *)MT_SET_ATAG((unsigned long)ptr, atag);
> +}
Ah, this is where the time.h inclusion came from - it just got split
into the wrong patch. I would move that srandom() into the main()
function, we don't need to reset the RNG every time we generate a tag
and since time() has a resolution of a second depending on how fast the
machine is we might manage to end up setting exactly the same value for
every tag insertion the program does which would seem to defeat the
point of using a RNG here.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler
2025-06-11 9:41 ` [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler Yeoreum Yun
@ 2025-06-11 12:12 ` Mark Brown
2025-06-11 13:26 ` Yeoreum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 12:12 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 883 bytes --]
On Wed, Jun 11, 2025 at 10:41:05AM +0100, Yeoreum Yun wrote:
> Add the address tag [63:60] verification when synchronous mte fault is happen.
> when signal handler is registered with SA_EXPOSE_TAGBITS,
> address includes not only memory tag [59:56] but also address tag.
> Therefore, when verify fault address location, remove both tags
Reviewed-by: Mark Brown <broonie@kernel.org>
though if you're doing a new version there's minor stylistic stuff:
> /* Compare the context for precise error */
> else if (si->si_code == SEGV_MTESERR) {
> + if ((!mtefar_support && si_atag) || (si_atag != MT_FETCH_ATAG(cur_mte_cxt.trig_addr))) {
> + ksft_print_msg("Invalid MTE synchronous exception caught for address tag! si_tag=%x, si_atag: %x\n", si_tag, si_atag);
> + exit(KSFT_FAIL);
> + }
Indentation seems off, also there's ksft_exit_fail_msg() but either way
works.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
2025-06-11 11:43 ` Mark Brown
@ 2025-06-11 12:19 ` Yeo Reum Yun
2025-06-11 12:35 ` Mark Brown
0 siblings, 1 reply; 26+ messages in thread
From: Yeo Reum Yun @ 2025-06-11 12:19 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
Hi Mark,
> > +HWCAP3_MTE_FAR
>
> > + Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
> > +Applications should interpret the values of these bits based on
> > +the support for the 'mte_far' hwcap. If the support is not present,
> > +the values of these bits should be considered as undefined otherwise valid.
>
> The constant is HWCAP3_MTE_FAR and the cpuinfo is mtefar:
>
> + [KERNEL_HWCAP_MTE_FAR] = "mtefar",
>
> The reference to the hwcap should probably be one of these, I'd go for
> HWCAP3_MTE_FAR since it says hwcap.
Just for confirmation. so change to "mtefar" -> "mte_far"
Am I missing?
--
Sincerely,
Yeoreum Yun
________________________________________
From: Mark Brown
Sent: Wednesday, June 11, 2025 12:43
To: Yeo Reum Yun
Cc: Catalin Marinas; pcc@google.com; will@kernel.org; Anshuman Khandual; Joey Gouly; Yury Khrustalev; maz@kernel.org; oliver.upton@linux.dev; frederic@kernel.org; akpm@linux-foundation.org; surenb@google.com; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-doc@vger.kernel.org
Subject: Re: [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
On Wed, Jun 11, 2025 at 10:41:00AM +0100, Yeoreum Yun wrote:
> +HWCAP3_MTE_FAR
> + Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
> +Applications should interpret the values of these bits based on
> +the support for the 'mte_far' hwcap. If the support is not present,
> +the values of these bits should be considered as undefined otherwise valid.
The constant is HWCAP3_MTE_FAR and the cpuinfo is mtefar:
> + [KERNEL_HWCAP_MTE_FAR] = "mtefar",
The reference to the hwcap should probably be one of these, I'd go for
HWCAP3_MTE_FAR since it says hwcap.
> > /*
> > * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
> > * for tag check faults. Set them to corresponding bits in the untagged
> > - * address.
> > + * address if ARM64_MTE_FAR isn't supported.
> > + * Otherwise, bits 63:60 of FAR_EL1 are KNOWN.
> >
> > Should this say UNKNOWN?
I think KNOWN is corret since this is Otherwise case (when MET_FAR is supported).
Thanks.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported
2025-06-11 11:52 ` Mark Brown
@ 2025-06-11 12:23 ` Yeo Reum Yun
0 siblings, 0 replies; 26+ messages in thread
From: Yeo Reum Yun @ 2025-06-11 12:23 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
Hi Mark,
> > #include <unistd.h>
>
> Not sure why we'd be including time.h here?
As you mention, This is my bad for wrong plcae .. Sorry
> > +bool mtefar_support;
>
> This is a non-static variable so won't have a defined default value...
Right, at the first write, I declare this with static.
But forgetting when changing more....
> > +
> > if (mode == MTE_SYNC_ERR)
> > cur_mte_cxt.trig_si_code = SEGV_MTESERR;
> > else if (mode == MTE_ASYNC_ERR)
>
> Unrelated whitespace change.
Thanks.
> ...this will only set mtefar_support if the hwcap is present, leaving it
>
> undefined if not. If you just make this
>
> mtefar_support = hwcap3 & HWCAP3_MTE_FAR
> that should avoid the issue.
Thanks for catching this.
I'll change.
--
Sincerely,
Yeoreum Yun
________________________________________
From: Mark Brown
Sent: Wednesday, June 11, 2025 12:52
To: Yeo Reum Yun
Cc: Catalin Marinas; pcc@google.com; will@kernel.org; Anshuman Khandual; Joey Gouly; Yury Khrustalev; maz@kernel.org; oliver.upton@linux.dev; frederic@kernel.org; akpm@linux-foundation.org; surenb@google.com; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-doc@vger.kernel.org
Subject: Re: [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported
On Wed, Jun 11, 2025 at 10:41:03AM +0100, Yeoreum Yun wrote:
> --- a/tools/testing/selftests/arm64/mte/mte_common_util.c
> +++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
> @@ -6,6 +6,7 @@
> #include <signal.h>
> #include <stdio.h>
> #include <stdlib.h>
> +#include <time.h>
> #include <unistd.h>
Not sure why we'd be including time.h here?
>
> #include <linux/auxvec.h>
> @@ -26,6 +27,7 @@
> #define INIT_BUFFER_SIZE 256
>
> struct mte_fault_cxt cur_mte_cxt;
> +bool mtefar_support;
This is a non-static variable so won't have a defined default value...
> @@ -273,6 +275,7 @@ void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range)
> cur_mte_cxt.fault_valid = false;
> cur_mte_cxt.trig_addr = ptr;
> cur_mte_cxt.trig_range = range;
> +
> if (mode == MTE_SYNC_ERR)
> cur_mte_cxt.trig_si_code = SEGV_MTESERR;
> else if (mode == MTE_ASYNC_ERR)
Unrelated whitespace change.
> if (!(hwcaps2 & HWCAP2_MTE))
> ksft_exit_skip("MTE features unavailable\n");
>
> + if (hwcaps3 & HWCAP3_MTE_FAR)
> + mtefar_support = true;
> +
...this will only set mtefar_support if the hwcap is present, leaving it
undefined if not. If you just make this
mtefar_support = hwcap3 & HWCAP3_MTE_FAR
that should avoid the issue.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options
2025-06-11 9:41 ` [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options Yeoreum Yun
@ 2025-06-11 12:25 ` Mark Brown
2025-06-11 13:34 ` Yeoreum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 12:25 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 1401 bytes --]
On Wed, Jun 11, 2025 at 10:41:07AM +0100, Yeoreum Yun wrote:
> +static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
> {
> char *ptr, *map_ptr;
> int run, result, map_size;
> @@ -97,16 +106,16 @@ static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, i
> munmap((void *)map_ptr, map_size);
> return KSFT_FAIL;
> }
> - result = check_mte_memory(ptr, sizes[run], mode, tag_check);
> + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check);
> mte_clear_tags((void *)ptr, sizes[run]);
> mte_free_memory((void *)map_ptr, map_size, mem_type, false);
> - if (result == KSFT_FAIL)
> - return KSFT_FAIL;
> + if (result != KSFT_SKIP)
> + return result;
> }
This changes the logic to exit the loop immediately if the check passes
which doesn't seem like what we want, should we instead change the test
to be:
if (result != KSFT_PASS)
which I think is more the intent?
> + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check);
> mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
> if (result != KSFT_PASS)
> return KSFT_FAIL;
> @@ -192,7 +201,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
> close(fd);
> return KSFT_FAIL;
> }
Won't this upgrade any skips to fails?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function
2025-06-11 11:58 ` Mark Brown
@ 2025-06-11 12:25 ` Yeo Reum Yun
2025-06-11 12:37 ` Mark Brown
0 siblings, 1 reply; 26+ messages in thread
From: Yeo Reum Yun @ 2025-06-11 12:25 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
Hi Mark,
> Ah, this is where the time.h inclusion came from - it just got split
> into the wrong patch. I would move that srandom() into the main()
> function, we don't need to reset the RNG every time we generate a tag
> and since time() has a resolution of a second depending on how fast the
> machine is we might manage to end up setting exactly the same value for
> every tag insertion the program does which would seem to defeat the
> point of using a RNG here.
You're right. but what I calling the every main() with srandom()
seems weird for me.
I think it would be better to call srandom() in mte_default_setup()
which is called only one time in testcase...
--
Sincerely,
Yeoreum Yun
________________________________________
From: Mark Brown
Sent: Wednesday, June 11, 2025 12:58
To: Yeo Reum Yun
Cc: Catalin Marinas; pcc@google.com; will@kernel.org; Anshuman Khandual; Joey Gouly; Yury Khrustalev; maz@kernel.org; oliver.upton@linux.dev; frederic@kernel.org; akpm@linux-foundation.org; surenb@google.com; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-doc@vger.kernel.org
Subject: Re: [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function
On Wed, Jun 11, 2025 at 10:41:04AM +0100, Yeoreum Yun wrote:
> Add address tag related macro and function to test MTE_FAR feature.
> +void *mte_insert_atag(void *ptr)
> +{
> + unsigned char atag;
> +
> + srandom(time(NULL));
> + atag = mtefar_support ? (random() % MT_ATAG_MASK) + 1 : 0;
> + return (void *)MT_SET_ATAG((unsigned long)ptr, atag);
> +}
Ah, this is where the time.h inclusion came from - it just got split
into the wrong patch. I would move that srandom() into the main()
function, we don't need to reset the RNG every time we generate a tag
and since time() has a resolution of a second depending on how fast the
machine is we might manage to end up setting exactly the same value for
every tag insertion the program does which would seem to defeat the
point of using a RNG here.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test
2025-06-11 9:41 ` [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test Yeoreum Yun
@ 2025-06-11 12:27 ` Mark Brown
2025-06-11 13:28 ` Yeoreum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 12:27 UTC (permalink / raw)
To: Yeoreum Yun
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
[-- Attachment #1: Type: text/plain, Size: 473 bytes --]
On Wed, Jun 11, 2025 at 10:41:06AM +0100, Yeoreum Yun wrote:
> Before add mtefar testcase on check_mmap_option.c,
> refactor check_mmap_option:
> - make testcase suite array with test options (mem_type, mte_sync type and etc)
> to use general testcase pattern
>
> - generate each test case name acoording to test options.
I didn't specifically check that all the tests are the same but assuming
they are:
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
2025-06-11 12:19 ` Yeo Reum Yun
@ 2025-06-11 12:35 ` Mark Brown
2025-06-11 13:16 ` Yeoreum Yun
0 siblings, 1 reply; 26+ messages in thread
From: Mark Brown @ 2025-06-11 12:35 UTC (permalink / raw)
To: Yeo Reum Yun
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 818 bytes --]
On Wed, Jun 11, 2025 at 12:19:57PM +0000, Yeo Reum Yun wrote:
> Hi Mark,
>
> > > +HWCAP3_MTE_FAR
> >
> > > + Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
> > > +Applications should interpret the values of these bits based on
> > > +the support for the 'mte_far' hwcap. If the support is not present,
> > > +the values of these bits should be considered as undefined otherwise valid.
> >
> > The constant is HWCAP3_MTE_FAR and the cpuinfo is mtefar:
> >
> > + [KERNEL_HWCAP_MTE_FAR] = "mtefar",
> >
> > The reference to the hwcap should probably be one of these, I'd go for
> > HWCAP3_MTE_FAR since it says hwcap.
> Just for confirmation. so change to "mtefar" -> "mte_far"
> Am I missing?
I'd write it as HWCAP3_MTE_FAR since that's the thing you're
referencing.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function
2025-06-11 12:25 ` Yeo Reum Yun
@ 2025-06-11 12:37 ` Mark Brown
0 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2025-06-11 12:37 UTC (permalink / raw)
To: Yeo Reum Yun
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 364 bytes --]
On Wed, Jun 11, 2025 at 12:25:50PM +0000, Yeo Reum Yun wrote:
> You're right. but what I calling the every main() with srandom()
> seems weird for me.
> I think it would be better to call srandom() in mte_default_setup()
> which is called only one time in testcase...
That also works, just something that's called only once during setup
rather than repeatedly.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported
2025-06-11 12:35 ` Mark Brown
@ 2025-06-11 13:16 ` Yeoreum Yun
0 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 13:16 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, pcc@google.com, will@kernel.org,
Anshuman Khandual, Joey Gouly, Yury Khrustalev, maz@kernel.org,
oliver.upton@linux.dev, frederic@kernel.org,
akpm@linux-foundation.org, surenb@google.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
Hi Mark,
> >
> > > > +HWCAP3_MTE_FAR
> > >
> > > > +��� Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
> > > > +Applications should interpret the values of these bits based on
> > > > +the support for the 'mte_far' hwcap. If the support is not present,
> > > > +the values of these bits should be considered as undefined otherwise valid.
> > >
> > > The constant is HWCAP3_MTE_FAR and the cpuinfo is mtefar:
> > >
> > > +���� [KERNEL_HWCAP_MTE_FAR]��������� = "mtefar",
> > >
> > > The reference to the hwcap should probably be one of these, I'd go for
> > > HWCAP3_MTE_FAR since it says hwcap.
>
> > Just for confirmation. so change to "mtefar" -> "mte_far"
> > Am I missing?
>
> I'd write it as HWCAP3_MTE_FAR since that's the thing you're
> referencing.
Ah I see for documents. Thanks!
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler
2025-06-11 12:12 ` Mark Brown
@ 2025-06-11 13:26 ` Yeoreum Yun
0 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 13:26 UTC (permalink / raw)
To: Mark Brown
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
Hi Mark,
> On Wed, Jun 11, 2025 at 10:41:05AM +0100, Yeoreum Yun wrote:
> > Add the address tag [63:60] verification when synchronous mte fault is happen.
> > when signal handler is registered with SA_EXPOSE_TAGBITS,
> > address includes not only memory tag [59:56] but also address tag.
> > Therefore, when verify fault address location, remove both tags
>
> Reviewed-by: Mark Brown <broonie@kernel.org>
Thanks :D
> though if you're doing a new version there's minor stylistic stuff:
>
> > /* Compare the context for precise error */
> > else if (si->si_code == SEGV_MTESERR) {
> > + if ((!mtefar_support && si_atag) || (si_atag != MT_FETCH_ATAG(cur_mte_cxt.trig_addr))) {
> > + ksft_print_msg("Invalid MTE synchronous exception caught for address tag! si_tag=%x, si_atag: %x\n", si_tag, si_atag);
> > + exit(KSFT_FAIL);
> > + }
>
> Indentation seems off, also there's ksft_exit_fail_msg() but either way
> works.
I'll fix the indentation next round. Thanks to let me know.
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test
2025-06-11 12:27 ` Mark Brown
@ 2025-06-11 13:28 ` Yeoreum Yun
0 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 13:28 UTC (permalink / raw)
To: Mark Brown
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
Hi Mask,
> > Before add mtefar testcase on check_mmap_option.c,
> > refactor check_mmap_option:
> > - make testcase suite array with test options (mem_type, mte_sync type and etc)
> > to use general testcase pattern
> >
> > - generate each test case name acoording to test options.
>
> I didn't specifically check that all the tests are the same but assuming
> they are:
>
> Reviewed-by: Mark Brown <broonie@kernel.org>
Yes. It doesn't change the all tests.
Thanks!
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options
2025-06-11 12:25 ` Mark Brown
@ 2025-06-11 13:34 ` Yeoreum Yun
0 siblings, 0 replies; 26+ messages in thread
From: Yeoreum Yun @ 2025-06-11 13:34 UTC (permalink / raw)
To: Mark Brown
Cc: catalin.marinas, pcc, will, anshuman.khandual, joey.gouly,
yury.khrustalev, maz, oliver.upton, frederic, akpm, surenb,
linux-arm-kernel, linux-kernel, linux-doc
Hi Mark,
> On Wed, Jun 11, 2025 at 10:41:07AM +0100, Yeoreum Yun wrote:
>
> > +static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
> > {
> > char *ptr, *map_ptr;
> > int run, result, map_size;
> > @@ -97,16 +106,16 @@ static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, i
> > munmap((void *)map_ptr, map_size);
> > return KSFT_FAIL;
> > }
> > - result = check_mte_memory(ptr, sizes[run], mode, tag_check);
> > + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check);
> > mte_clear_tags((void *)ptr, sizes[run]);
> > mte_free_memory((void *)map_ptr, map_size, mem_type, false);
> > - if (result == KSFT_FAIL)
> > - return KSFT_FAIL;
> > + if (result != KSFT_SKIP)
> > + return result;
> > }
>
> This changes the logic to exit the loop immediately if the check passes
> which doesn't seem like what we want, should we instead change the test
> to be:
>
> if (result != KSFT_PASS)
>
> which I think is more the intent?
Well, at the time of write, when the check_mte_memory return the "SKIP"
intent is to iterating the next item. But, yes this is meandingless.
I'll change with your suggestion.
>
> > + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check);
> > mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
> > if (result != KSFT_PASS)
> > return KSFT_FAIL;
> > @@ -192,7 +201,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
> > close(fd);
> > return KSFT_FAIL;
> > }
>
> Won't this upgrade any skips to fails?
Right. I'll change this.
Thanks!
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2025-06-11 13:35 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-11 9:40 [PATCH v6 0/9] support FEAT_MTE_TAGGED_FAR feature Yeoreum Yun
2025-06-11 9:40 ` [PATCH v6 1/9] arm64/cpufeature: add " Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 2/9] arm64: report address tag when FEAT_MTE_TAGGED_FAR is supported Yeoreum Yun
2025-06-11 11:43 ` Mark Brown
2025-06-11 12:19 ` Yeo Reum Yun
2025-06-11 12:35 ` Mark Brown
2025-06-11 13:16 ` Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 3/9] tools/kselftest: add MTE_FAR hwcap test Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 4/9] kselftest/arm64/mte: register mte signal handler with SA_EXPOSE_TAGBITS Yeoreum Yun
2025-06-11 11:45 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 5/9] kselftest/arm64/mte: check MTE_FAR feature is supported Yeoreum Yun
2025-06-11 11:52 ` Mark Brown
2025-06-11 12:23 ` Yeo Reum Yun
2025-06-11 9:41 ` [PATCH v6 6/9] kselftest/arm64/mte: add address tag related macro and function Yeoreum Yun
2025-06-11 11:58 ` Mark Brown
2025-06-11 12:25 ` Yeo Reum Yun
2025-06-11 12:37 ` Mark Brown
2025-06-11 9:41 ` [PATCH v6 7/9] kselftest/arm64/mte: add verification for address tag in signal handler Yeoreum Yun
2025-06-11 12:12 ` Mark Brown
2025-06-11 13:26 ` Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 8/9] kselftest/arm64/mte: refactor check_mmap_option test Yeoreum Yun
2025-06-11 12:27 ` Mark Brown
2025-06-11 13:28 ` Yeoreum Yun
2025-06-11 9:41 ` [PATCH v6 9/9] kselftest/arm64/mte: add mtefar tests on check_mmap_options Yeoreum Yun
2025-06-11 12:25 ` Mark Brown
2025-06-11 13:34 ` Yeoreum Yun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).