From nobody Thu Oct 9 13:21:57 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 19B66285043 for ; Wed, 18 Jun 2025 09:30:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750239029; cv=none; b=co3b8LO3RWnx8Zz+qaiXOZOiDuidpVmEovamcCzgL/8KLBfSB1XCFaYtFUT1So6dmYtK+OQzGgFI18WdxwRZ5SOgv2NYfNkXHMJPsB19kXrlKC2woJtM3dUGbloKVUet49I9WTC2jq/QuKhVDKTp5KfLoEAKxB6MufeDIjLsHkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750239029; c=relaxed/simple; bh=sUJgID6wiHDWZzlQnWjqNCHUlK2uzTjuGEe7nZnYh1A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Xz3ScdCqjPV3P86rww+nUh7Q4/JkTwDn5HJt/e4jsXEzKh6637Y8KnWSwG8INZjZTGX1tAO4FcexWa7ktsC6HGGV4oQWcJHX0myExFaAmCT/eagFlu+CXhxTIjKLR4/YKI5egnRJ3XEarF0adVE5Z4GBOpo0mejpyj9WXXdPwXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C5A641BC0; Wed, 18 Jun 2025 02:30:06 -0700 (PDT) Received: from e129823.cambridge.arm.com (e129823.arm.com [10.1.197.6]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 252493F58B; Wed, 18 Jun 2025 02:30:24 -0700 (PDT) From: Yeoreum Yun To: catalin.marinas@arm.com, pcc@google.com, will@kernel.org, broonie@kernel.org, anshuman.khandual@arm.com, joey.gouly@arm.com, maz@kernel.org, oliver.upton@linux.dev, frederic@kernel.org, hardevsinh.palaniya@siliconsignals.io, samuel.holland@sifive.com, palmer@rivosinc.com, charlie@rivosinc.com, thiago.bauermann@linaro.org, bgray@linux.ibm.com, tglx@linutronix.de, puranjay@kernel.org, david@redhat.com, yang@os.amperecomputing.com, mbenes@suse.cz, joel.granados@kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Yeoreum Yun Subject: [PATCH v7 7/8] kselftest/arm64/mte: preparation for mte store only test Date: Wed, 18 Jun 2025 10:29:56 +0100 Message-Id: <20250618092957.2069907-8-yeoreum.yun@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250618092957.2069907-1-yeoreum.yun@arm.com> References: <20250618092957.2069907-1-yeoreum.yun@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Mark Brown --- .../selftests/arm64/mte/check_buffer_fill.c | 10 +++++----- .../selftests/arm64/mte/check_child_memory.c | 4 ++-- .../selftests/arm64/mte/check_hugetlb_options.c | 6 +++--- .../selftests/arm64/mte/check_ksm_options.c | 2 +- .../selftests/arm64/mte/check_mmap_options.c | 6 +++--- .../selftests/arm64/mte/check_tags_inclusion.c | 8 ++++---- tools/testing/selftests/arm64/mte/check_user_mem.c | 2 +- .../testing/selftests/arm64/mte/mte_common_util.c | 14 ++++++++++++-- .../testing/selftests/arm64/mte/mte_common_util.h | 3 ++- 9 files changed, 33 insertions(+), 22 deletions(-) diff --git a/tools/testing/selftests/arm64/mte/check_buffer_fill.c b/tools/= testing/selftests/arm64/mte/check_buffer_fill.c index 5248b5265aa4..ff4e07503349 100644 --- a/tools/testing/selftests/arm64/mte/check_buffer_fill.c +++ b/tools/testing/selftests/arm64/mte/check_buffer_fill.c @@ -31,7 +31,7 @@ static int check_buffer_by_byte(int mem_type, int mode) int i, j, item; bool err; =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); item =3D ARRAY_SIZE(sizes); =20 for (i =3D 0; i < item; i++) { @@ -68,7 +68,7 @@ static int check_buffer_underflow_by_byte(int mem_type, i= nt mode, bool err; char *und_ptr =3D NULL; =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); item =3D ARRAY_SIZE(sizes); for (i =3D 0; i < item; i++) { ptr =3D (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 =3D NULL; =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); item =3D ARRAY_SIZE(sizes); for (i =3D 0; i < item; i++) { ptr =3D (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 =3D KSFT_PASS; =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); item =3D ARRAY_SIZE(sizes); cur_mte_cxt.fault_valid =3D false; for (i =3D 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 =3D ARRAY_SIZE(sizes); =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); for (run =3D 0; run < total; run++) { /* check initial tags for anonymous mmap */ ptr =3D (char *)mte_allocate_memory(sizes[run], mem_type, mapping, false= ); diff --git a/tools/testing/selftests/arm64/mte/check_child_memory.c b/tools= /testing/selftests/arm64/mte/check_child_memory.c index b97ea3981c21..5e97ee792e4d 100644 --- a/tools/testing/selftests/arm64/mte/check_child_memory.c +++ b/tools/testing/selftests/arm64/mte/check_child_memory.c @@ -88,7 +88,7 @@ static int check_child_memory_mapping(int mem_type, int m= ode, int mapping) int item =3D ARRAY_SIZE(sizes); =20 item =3D ARRAY_SIZE(sizes); - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); for (run =3D 0; run < item; run++) { ptr =3D (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapp= ing, UNDERFLOW, OVERFLOW); @@ -109,7 +109,7 @@ static int check_child_file_mapping(int mem_type, int m= ode, int mapping) int run, fd, map_size, result =3D KSFT_PASS; int total =3D ARRAY_SIZE(sizes); =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); for (run =3D 0; run < total; run++) { fd =3D create_temp_file(); if (fd =3D=3D -1) diff --git a/tools/testing/selftests/arm64/mte/check_hugetlb_options.c b/to= ols/testing/selftests/arm64/mte/check_hugetlb_options.c index 4e644a606394..aad1234c7e0f 100644 --- a/tools/testing/selftests/arm64/mte/check_hugetlb_options.c +++ b/tools/testing/selftests/arm64/mte/check_hugetlb_options.c @@ -151,7 +151,7 @@ static int check_hugetlb_memory_mapping(int mem_type, i= nt mode, int mapping, int =20 map_size =3D default_huge_page_size(); =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); map_ptr =3D (char *)mte_allocate_memory(map_size, mem_type, mapping, fals= e); if (check_allocated_memory(map_ptr, map_size, mem_type, false) !=3D 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; =20 prot_flag =3D 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 =3D default_huge_page_size(); map_ptr =3D (char *)mte_allocate_memory_tag_range(map_size, mem_type, map= ping, 0, 0); @@ -210,7 +210,7 @@ static int check_child_hugetlb_memory_mapping(int mem_t= ype, int mode, int mappin =20 map_size =3D default_huge_page_size(); =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); ptr =3D (char *)mte_allocate_memory_tag_range(map_size, mem_type, mapping, 0, 0); if (check_allocated_memory_range(ptr, map_size, mem_type, diff --git a/tools/testing/selftests/arm64/mte/check_ksm_options.c b/tools/= testing/selftests/arm64/mte/check_ksm_options.c index afea4e381862..0cf5faef1724 100644 --- a/tools/testing/selftests/arm64/mte/check_ksm_options.c +++ b/tools/testing/selftests/arm64/mte/check_ksm_options.c @@ -106,7 +106,7 @@ static int check_madvise_options(int mem_type, int mode= , int mapping) return err; } =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); ptr =3D mte_allocate_memory(TEST_UNIT * page_sz, mem_type, mapping, true); if (check_allocated_memory(ptr, TEST_UNIT * page_sz, mem_type, false) != =3D KSFT_PASS) return KSFT_FAIL; diff --git a/tools/testing/selftests/arm64/mte/check_mmap_options.c b/tools= /testing/selftests/arm64/mte/check_mmap_options.c index 91a81b4a9bfa..447c0ef25f71 100644 --- a/tools/testing/selftests/arm64/mte/check_mmap_options.c +++ b/tools/testing/selftests/arm64/mte/check_mmap_options.c @@ -90,7 +90,7 @@ static int check_anonymous_memory_mapping(int mem_type, i= nt mode, int mapping, i int run, result, map_size; int item =3D ARRAY_SIZE(sizes); =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); for (run =3D 0; run < item; run++) { map_size =3D sizes[run] + OVERFLOW + UNDERFLOW; map_ptr =3D (char *)mte_allocate_memory(map_size, mem_type, mapping, fal= se); @@ -122,7 +122,7 @@ static int check_file_memory_mapping(int mem_type, int = mode, int mapping, int ta int total =3D ARRAY_SIZE(sizes); int result =3D KSFT_PASS; =20 - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); for (run =3D 0; run < total; run++) { fd =3D create_temp_file(); if (fd =3D=3D -1) @@ -161,7 +161,7 @@ static int check_clear_prot_mte_flag(int mem_type, int = mode, int mapping, int at int total =3D ARRAY_SIZE(sizes); =20 prot_flag =3D 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 =3D 0; run < total; run++) { map_size =3D sizes[run] + OVERFLOW + UNDERFLOW; ptr =3D (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapp= ing, diff --git a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c b/too= ls/testing/selftests/arm64/mte/check_tags_inclusion.c index b96296ab9870..4b764f2a8185 100644 --- a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c +++ b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c @@ -57,7 +57,7 @@ static int check_single_included_tags(int mem_type, int m= ode) return KSFT_FAIL; =20 for (tag =3D 0; (tag < MT_TAG_COUNT) && (result =3D=3D KSFT_PASS); tag++)= { - ret =3D mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag)); + ret =3D mte_switch_mode(mode, MT_INCLUDE_VALID_TAG(tag), false); if (ret !=3D 0) result =3D 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) =20 for (tag =3D 0; (tag < MT_TAG_COUNT - 1) && (result =3D=3D KSFT_PASS); ta= g++) { excl_mask |=3D 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 =3D 0; (run < RUNS) && (result =3D=3D KSFT_PASS); run++) { ptr =3D mte_insert_tags(ptr, BUFFER_SIZE); @@ -120,7 +120,7 @@ static int check_all_included_tags(int mem_type, int mo= de) mem_type, false) !=3D KSFT_PASS) return KSFT_FAIL; =20 - ret =3D mte_switch_mode(mode, MT_INCLUDE_TAG_MASK); + ret =3D mte_switch_mode(mode, MT_INCLUDE_TAG_MASK, false); if (ret !=3D 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 m= ode) if (check_allocated_memory(ptr, BUFFER_SIZE, mem_type, false) !=3D KSFT_P= ASS) return KSFT_FAIL; =20 - ret =3D mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK); + ret =3D mte_switch_mode(mode, MT_EXCLUDE_TAG_MASK, false); if (ret !=3D 0) return KSFT_FAIL; /* Try to catch a excluded tag by a number of tries. */ diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/tes= ting/selftests/arm64/mte/check_user_mem.c index d1d14aaaba16..fb7936c4e097 100644 --- a/tools/testing/selftests/arm64/mte/check_user_mem.c +++ b/tools/testing/selftests/arm64/mte/check_user_mem.c @@ -44,7 +44,7 @@ static int check_usermem_access_fault(int mem_type, int m= ode, int mapping, =20 err =3D KSFT_PASS; len =3D 2 * page_sz; - mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); + mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); fd =3D create_temp_file(); if (fd =3D=3D -1) return KSFT_FAIL; diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/te= sting/selftests/arm64/mte/mte_common_util.c index 10dcbc37e379..397e57dd946a 100644 --- a/tools/testing/selftests/arm64/mte/mte_common_util.c +++ b/tools/testing/selftests/arm64/mte/mte_common_util.c @@ -28,8 +28,10 @@ =20 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; =20 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 =3D 0; } =20 -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 =3D 0; =20 @@ -346,6 +348,9 @@ int mte_switch_mode(int mte_option, unsigned long incl_= mask) break; } =20 + if (mtestonly_support && stonly) + en |=3D PR_MTE_STORE_ONLY; + en |=3D (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) !=3D 0) { @@ -370,6 +375,9 @@ int mte_default_setup(void) =20 mtefar_support =3D !!(hwcaps3 & HWCAP3_MTE_FAR); =20 + if (hwcaps3 & HWCAP3_MTE_STORE_ONLY) + mtestonly_support =3D true; + /* Get current mte mode */ ret =3D 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 =3D MTE_NONE_ERR; =20 + mte_cur_stonly =3D (ret & PR_MTE_STORE_ONLY) ? true : false; + mte_cur_pstate_tco =3D mte_get_pstate_tco(); /* Disable PSTATE.TCO */ mte_disable_pstate_tco(); @@ -391,7 +401,7 @@ int mte_default_setup(void) =20 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 =3D=3D MT_PSTATE_TCO_EN) mte_enable_pstate_tco(); else if (mte_cur_pstate_tco =3D=3D MT_PSTATE_TCO_DIS) diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.h b/tools/te= sting/selftests/arm64/mte/mte_common_util.h index 045e4ad2f018..250d671329a5 100644 --- a/tools/testing/selftests/arm64/mte/mte_common_util.h +++ b/tools/testing/selftests/arm64/mte/mte_common_util.h @@ -38,6 +38,7 @@ struct mte_fault_cxt { =20 extern struct mte_fault_cxt cur_mte_cxt; extern bool mtefar_support; +extern bool mtestonly_support; =20 /* 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= ); =20 /* Common utility functions */ --=20 LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}