kselftest/arm64/mte: Preparation for mte store only test
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>
This commit is contained in:
committed by
Catalin Marinas
parent
964a07426e
commit
391ca7c81b
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
|
||||
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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user