]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
kselftest/arm64/mte: Preparation for mte store only test
authorYeoreum Yun <yeoreum.yun@arm.com>
Wed, 18 Jun 2025 09:29:56 +0000 (10:29 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 2 Jul 2025 17:50:53 +0000 (18:50 +0100)
Since ARMv8.9, FEAT_MTE_STORE_ONLY can be used to restrict raise of tag
check fault on store operation only.

This patch is preparation for testing FEAT_MTE_STORE_ONLY
It shouldn't change test result.

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20250618092957.2069907-8-yeoreum.yun@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
tools/testing/selftests/arm64/mte/check_buffer_fill.c
tools/testing/selftests/arm64/mte/check_child_memory.c
tools/testing/selftests/arm64/mte/check_hugetlb_options.c
tools/testing/selftests/arm64/mte/check_ksm_options.c
tools/testing/selftests/arm64/mte/check_mmap_options.c
tools/testing/selftests/arm64/mte/check_tags_inclusion.c
tools/testing/selftests/arm64/mte/check_user_mem.c
tools/testing/selftests/arm64/mte/mte_common_util.c
tools/testing/selftests/arm64/mte/mte_common_util.h

index 5248b5265aa4bc45951a61a2eee954be1e25741d..ff4e0750334936e442f22327f89141d81cfd965d 100644 (file)
@@ -31,7 +31,7 @@ static int check_buffer_by_byte(int mem_type, int mode)
        int i, j, item;
        bool err;
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        item = ARRAY_SIZE(sizes);
 
        for (i = 0; i < item; i++) {
@@ -68,7 +68,7 @@ static int check_buffer_underflow_by_byte(int mem_type, int mode,
        bool err;
        char *und_ptr = NULL;
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        item = ARRAY_SIZE(sizes);
        for (i = 0; i < item; i++) {
                ptr = (char *)mte_allocate_memory_tag_range(sizes[i], mem_type, 0,
@@ -164,7 +164,7 @@ static int check_buffer_overflow_by_byte(int mem_type, int mode,
        size_t tagged_size, overflow_size;
        char *over_ptr = NULL;
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        item = ARRAY_SIZE(sizes);
        for (i = 0; i < item; i++) {
                ptr = (char *)mte_allocate_memory_tag_range(sizes[i], mem_type, 0,
@@ -337,7 +337,7 @@ static int check_buffer_by_block(int mem_type, int mode)
 {
        int i, item, result = KSFT_PASS;
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        item = ARRAY_SIZE(sizes);
        cur_mte_cxt.fault_valid = false;
        for (i = 0; i < item; i++) {
@@ -368,7 +368,7 @@ static int check_memory_initial_tags(int mem_type, int mode, int mapping)
        int run, fd;
        int total = ARRAY_SIZE(sizes);
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < total; run++) {
                /* check initial tags for anonymous mmap */
                ptr = (char *)mte_allocate_memory(sizes[run], mem_type, mapping, false);
index b97ea3981c21e10eb99c766257b79c97e9540d9b..5e97ee792e4d2e4110f0dd2451794239dec490f2 100644 (file)
@@ -88,7 +88,7 @@ static int check_child_memory_mapping(int mem_type, int mode, int mapping)
        int item = ARRAY_SIZE(sizes);
 
        item = ARRAY_SIZE(sizes);
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < item; run++) {
                ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping,
                                                            UNDERFLOW, OVERFLOW);
@@ -109,7 +109,7 @@ static int check_child_file_mapping(int mem_type, int mode, int mapping)
        int run, fd, map_size, result = KSFT_PASS;
        int total = ARRAY_SIZE(sizes);
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < total; run++) {
                fd = create_temp_file();
                if (fd == -1)
index 4e644a60639456b02514724787deba157d0dcb76..aad1234c7e0feb4674af40a07ace308261c30b67 100644 (file)
@@ -151,7 +151,7 @@ static int check_hugetlb_memory_mapping(int mem_type, int mode, int mapping, int
 
        map_size = default_huge_page_size();
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false);
        if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS)
                return KSFT_FAIL;
@@ -180,7 +180,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
        unsigned long map_size;
 
        prot_flag = PROT_READ | PROT_WRITE;
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        map_size = default_huge_page_size();
        map_ptr = (char *)mte_allocate_memory_tag_range(map_size, mem_type, mapping,
                                                        0, 0);
@@ -210,7 +210,7 @@ static int check_child_hugetlb_memory_mapping(int mem_type, int mode, int mappin
 
        map_size = default_huge_page_size();
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        ptr = (char *)mte_allocate_memory_tag_range(map_size, mem_type, mapping,
                                                    0, 0);
        if (check_allocated_memory_range(ptr, map_size, mem_type,
index afea4e381862c9a71031cf34fc0efb6dbcd629ac..0cf5faef172481d931e13962c131680967772a74 100644 (file)
@@ -106,7 +106,7 @@ static int check_madvise_options(int mem_type, int mode, int mapping)
                return err;
        }
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        ptr = mte_allocate_memory(TEST_UNIT * page_sz, mem_type, mapping, true);
        if (check_allocated_memory(ptr, TEST_UNIT * page_sz, mem_type, false) != KSFT_PASS)
                return KSFT_FAIL;
index 91a81b4a9bfade62eb4bf39311cbd48d1da639b0..447c0ef25f71cc8e6978a49e7553eb002c7cd975 100644 (file)
@@ -90,7 +90,7 @@ static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, i
        int run, result, map_size;
        int item = ARRAY_SIZE(sizes);
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < item; run++) {
                map_size = sizes[run] + OVERFLOW + UNDERFLOW;
                map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false);
@@ -122,7 +122,7 @@ static int check_file_memory_mapping(int mem_type, int mode, int mapping, int ta
        int total = ARRAY_SIZE(sizes);
        int result = KSFT_PASS;
 
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < total; run++) {
                fd = create_temp_file();
                if (fd == -1)
@@ -161,7 +161,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int at
        int total = ARRAY_SIZE(sizes);
 
        prot_flag = PROT_READ | PROT_WRITE;
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        for (run = 0; run < total; run++) {
                map_size = sizes[run] + OVERFLOW + UNDERFLOW;
                ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping,
index b96296ab98700e0d942ecfbec5af712b692ab99f..4b764f2a818576bd5d763096cd57c37b01763615 100644 (file)
@@ -57,7 +57,7 @@ static int check_single_included_tags(int mem_type, int mode)
                return KSFT_FAIL;
 
        for (tag = 0; (tag < MT_TAG_COUNT) && (result == KSFT_PASS); tag++) {
-               ret = mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag));
+               ret = mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag), false);
                if (ret != 0)
                        result = KSFT_FAIL;
                /* Try to catch a excluded tag by a number of tries. */
@@ -91,7 +91,7 @@ static int check_multiple_included_tags(int mem_type, int mode)
 
        for (tag = 0; (tag < MT_TAG_COUNT - 1) && (result == KSFT_PASS); tag++) {
                excl_mask |= 1 << tag;
-               mte_switch_mode(mode, MT_INCLUDE_VALID_TAGS(excl_mask));
+               mte_switch_mode(mode, MT_INCLUDE_VALID_TAGS(excl_mask), false);
                /* Try to catch a excluded tag by a number of tries. */
                for (run = 0; (run < RUNS) && (result == KSFT_PASS); run++) {
                        ptr = mte_insert_tags(ptr, BUFFER_SIZE);
@@ -120,7 +120,7 @@ static int check_all_included_tags(int mem_type, int mode)
                                   mem_type, false) != KSFT_PASS)
                return KSFT_FAIL;
 
-       ret = mte_switch_mode(mode, MT_INCLUDE_TAG_MASK);
+       ret = mte_switch_mode(mode, MT_INCLUDE_TAG_MASK, false);
        if (ret != 0)
                return KSFT_FAIL;
        /* Try to catch a excluded tag by a number of tries. */
@@ -145,7 +145,7 @@ static int check_none_included_tags(int mem_type, int mode)
        if (check_allocated_memory(ptr, BUFFER_SIZE, mem_type, false) != KSFT_PASS)
                return KSFT_FAIL;
 
-       ret = mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK);
+       ret = mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK, false);
        if (ret != 0)
                return KSFT_FAIL;
        /* Try to catch a excluded tag by a number of tries. */
index d1d14aaaba16ce0a8e679cf5da9c1aa8c1a39166..fb7936c4e09785bd30d8fa154a5c0ac47608ff3c 100644 (file)
@@ -44,7 +44,7 @@ static int check_usermem_access_fault(int mem_type, int mode, int mapping,
 
        err = KSFT_PASS;
        len = 2 * page_sz;
-       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
        fd = create_temp_file();
        if (fd == -1)
                return KSFT_FAIL;
index 10dcbc37e3792702f4f782ccd1818831bb82d194..397e57dd946a161f8298abd17855ca420d42c175 100644 (file)
 
 struct mte_fault_cxt cur_mte_cxt;
 bool mtefar_support;
+bool mtestonly_support;
 static unsigned int mte_cur_mode;
 static unsigned int mte_cur_pstate_tco;
+static bool mte_cur_stonly;
 
 void mte_default_handler(int signum, siginfo_t *si, void *uc)
 {
@@ -314,7 +316,7 @@ void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range)
                cur_mte_cxt.trig_si_code = 0;
 }
 
-int mte_switch_mode(int mte_option, unsigned long incl_mask)
+int mte_switch_mode(int mte_option, unsigned long incl_mask, bool stonly)
 {
        unsigned long en = 0;
 
@@ -346,6 +348,9 @@ int mte_switch_mode(int mte_option, unsigned long incl_mask)
                break;
        }
 
+       if (mtestonly_support && stonly)
+               en |= PR_MTE_STORE_ONLY;
+
        en |= (incl_mask << PR_MTE_TAG_SHIFT);
        /* Enable address tagging ABI, mte error reporting mode and tag inclusion mask. */
        if (prctl(PR_SET_TAGGED_ADDR_CTRL, en, 0, 0, 0) != 0) {
@@ -370,6 +375,9 @@ int mte_default_setup(void)
 
        mtefar_support = !!(hwcaps3 & HWCAP3_MTE_FAR);
 
+       if (hwcaps3 & HWCAP3_MTE_STORE_ONLY)
+               mtestonly_support = true;
+
        /* Get current mte mode */
        ret = prctl(PR_GET_TAGGED_ADDR_CTRL, en, 0, 0, 0);
        if (ret < 0) {
@@ -383,6 +391,8 @@ int mte_default_setup(void)
        else if (ret & PR_MTE_TCF_NONE)
                mte_cur_mode = MTE_NONE_ERR;
 
+       mte_cur_stonly = (ret & PR_MTE_STORE_ONLY) ? true : false;
+
        mte_cur_pstate_tco = mte_get_pstate_tco();
        /* Disable PSTATE.TCO */
        mte_disable_pstate_tco();
@@ -391,7 +401,7 @@ int mte_default_setup(void)
 
 void mte_restore_setup(void)
 {
-       mte_switch_mode(mte_cur_mode, MTE_ALLOW_NON_ZERO_TAG);
+       mte_switch_mode(mte_cur_mode, MTE_ALLOW_NON_ZERO_TAG, mte_cur_stonly);
        if (mte_cur_pstate_tco == MT_PSTATE_TCO_EN)
                mte_enable_pstate_tco();
        else if (mte_cur_pstate_tco == MT_PSTATE_TCO_DIS)
index 045e4ad2f0182faefd4b98a912b073ed38555695..250d671329a511acf63a3254518a0cae97b0cceb 100644 (file)
@@ -38,6 +38,7 @@ struct mte_fault_cxt {
 
 extern struct mte_fault_cxt cur_mte_cxt;
 extern bool mtefar_support;
+extern bool mtestonly_support;
 
 /* MTE utility functions */
 void mte_default_handler(int signum, siginfo_t *si, void *uc);
@@ -60,7 +61,7 @@ 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);
+int mte_switch_mode(int mte_option, unsigned long incl_mask, bool stonly);
 void mte_initialize_current_context(int mode, uintptr_t ptr, ssize_t range);
 
 /* Common utility functions */