mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 07:03:28 -04:00
kselftest/arm64/mte: Add MTE_STORE_ONLY testcases
Since ARMv8.9, FEAT_MTE_STORE_ONLY can be used to restrict raise of tag check fault on store operation only. Adds new test cases using MTE_STORE_ONLY feature. Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20250618092957.2069907-9-yeoreum.yun@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
committed by
Catalin Marinas
parent
391ca7c81b
commit
1f488fb913
@@ -35,6 +35,11 @@ enum mte_mem_check_type {
|
||||
CHECK_CLEAR_PROT_MTE = 2,
|
||||
};
|
||||
|
||||
enum mte_tag_op_type {
|
||||
TAG_OP_ALL = 0,
|
||||
TAG_OP_STONLY = 1,
|
||||
};
|
||||
|
||||
struct check_mmap_testcase {
|
||||
int check_type;
|
||||
int mem_type;
|
||||
@@ -42,17 +47,24 @@ struct check_mmap_testcase {
|
||||
int mapping;
|
||||
int tag_check;
|
||||
int atag_check;
|
||||
int tag_op;
|
||||
bool enable_tco;
|
||||
};
|
||||
|
||||
#define TAG_OP_ALL 0
|
||||
#define TAG_OP_STONLY 1
|
||||
|
||||
static size_t page_size;
|
||||
static int sizes[] = {
|
||||
1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,
|
||||
/* 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, int atag_check)
|
||||
static int check_mte_memory(char *ptr, int size, int mode,
|
||||
int tag_check,int atag_check, int tag_op)
|
||||
{
|
||||
char buf[MT_GRANULE_SIZE];
|
||||
|
||||
if (!mtefar_support && atag_check == ATAG_CHECK_ON)
|
||||
return KSFT_SKIP;
|
||||
|
||||
@@ -81,16 +93,34 @@ static int check_mte_memory(char *ptr, int size, int mode, int tag_check, int at
|
||||
if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF)
|
||||
return KSFT_FAIL;
|
||||
|
||||
if (tag_op == TAG_OP_STONLY) {
|
||||
mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW);
|
||||
memcpy(buf, ptr - UNDERFLOW, MT_GRANULE_SIZE);
|
||||
mte_wait_after_trig();
|
||||
if (cur_mte_cxt.fault_valid == true)
|
||||
return KSFT_FAIL;
|
||||
|
||||
mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW);
|
||||
memcpy(buf, ptr + size, MT_GRANULE_SIZE);
|
||||
mte_wait_after_trig();
|
||||
if (cur_mte_cxt.fault_valid == true)
|
||||
return KSFT_FAIL;
|
||||
}
|
||||
|
||||
return KSFT_PASS;
|
||||
}
|
||||
|
||||
static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
|
||||
static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping,
|
||||
int tag_check, int atag_check, int tag_op)
|
||||
{
|
||||
char *ptr, *map_ptr;
|
||||
int run, result, map_size;
|
||||
int item = ARRAY_SIZE(sizes);
|
||||
|
||||
mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
|
||||
if (tag_op == TAG_OP_STONLY && !mtestonly_support)
|
||||
return KSFT_SKIP;
|
||||
|
||||
mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op);
|
||||
for (run = 0; run < item; run++) {
|
||||
map_size = sizes[run] + OVERFLOW + UNDERFLOW;
|
||||
map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false);
|
||||
@@ -106,7 +136,7 @@ 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, atag_check);
|
||||
result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op);
|
||||
mte_clear_tags((void *)ptr, sizes[run]);
|
||||
mte_free_memory((void *)map_ptr, map_size, mem_type, false);
|
||||
if (result != KSFT_PASS)
|
||||
@@ -115,14 +145,18 @@ static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, i
|
||||
return KSFT_PASS;
|
||||
}
|
||||
|
||||
static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check)
|
||||
static int check_file_memory_mapping(int mem_type, int mode, int mapping,
|
||||
int tag_check, int atag_check, int tag_op)
|
||||
{
|
||||
char *ptr, *map_ptr;
|
||||
int run, fd, map_size;
|
||||
int total = ARRAY_SIZE(sizes);
|
||||
int result = KSFT_PASS;
|
||||
|
||||
mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false);
|
||||
if (tag_op == TAG_OP_STONLY && !mtestonly_support)
|
||||
return KSFT_SKIP;
|
||||
|
||||
mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op);
|
||||
for (run = 0; run < total; run++) {
|
||||
fd = create_temp_file();
|
||||
if (fd == -1)
|
||||
@@ -144,7 +178,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, atag_check);
|
||||
result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op);
|
||||
mte_clear_tags((void *)ptr, sizes[run]);
|
||||
munmap((void *)map_ptr, map_size);
|
||||
close(fd);
|
||||
@@ -177,10 +211,10 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int at
|
||||
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, atag_check);
|
||||
result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL);
|
||||
mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
|
||||
if (result != KSFT_PASS)
|
||||
return KSFT_FAIL;
|
||||
return result;
|
||||
|
||||
fd = create_temp_file();
|
||||
if (fd == -1)
|
||||
@@ -201,7 +235,7 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int at
|
||||
close(fd);
|
||||
return KSFT_FAIL;
|
||||
}
|
||||
result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check);
|
||||
result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL);
|
||||
mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
|
||||
close(fd);
|
||||
if (result != KSFT_PASS)
|
||||
@@ -219,6 +253,7 @@ const char *format_test_name(struct check_mmap_testcase *tc)
|
||||
const char *mapping_str;
|
||||
const char *tag_check_str;
|
||||
const char *atag_check_str;
|
||||
const char *tag_op_str;
|
||||
|
||||
switch (tc->check_type) {
|
||||
case CHECK_ANON_MEM:
|
||||
@@ -303,6 +338,23 @@ const char *format_test_name(struct check_mmap_testcase *tc)
|
||||
check_type_str, mapping_str, sync_str, mem_type_str,
|
||||
tag_check_str, atag_check_str);
|
||||
|
||||
switch (tc->tag_op) {
|
||||
case TAG_OP_ALL:
|
||||
tag_op_str = "";
|
||||
break;
|
||||
case TAG_OP_STONLY:
|
||||
tag_op_str = " / store-only";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(test_name, TEST_NAME_MAX,
|
||||
"Check %s with %s mapping, %s mode, %s memory and %s (%s%s)\n",
|
||||
check_type_str, mapping_str, sync_str, mem_type_str,
|
||||
tag_check_str, atag_check_str, tag_op_str);
|
||||
|
||||
return test_name;
|
||||
}
|
||||
|
||||
@@ -318,6 +370,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_OFF,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = true,
|
||||
},
|
||||
{
|
||||
@@ -327,6 +380,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_OFF,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = true,
|
||||
},
|
||||
{
|
||||
@@ -336,6 +390,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_OFF,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -345,6 +400,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_OFF,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -354,6 +410,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -363,6 +420,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -372,6 +430,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -381,6 +440,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -390,6 +450,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -399,6 +460,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -408,6 +470,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -417,6 +480,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -426,6 +490,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -435,6 +500,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -444,6 +510,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -453,6 +520,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -462,6 +530,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -471,6 +540,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -480,6 +550,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -489,6 +560,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -498,6 +570,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -507,6 +580,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -516,6 +590,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -525,6 +600,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -534,6 +610,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -543,6 +620,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -552,6 +630,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -561,6 +640,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -570,6 +650,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -579,6 +660,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_SHARED,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -588,6 +670,257 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.atag_check = ATAG_CHECK_OFF,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.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,
|
||||
.tag_op = TAG_OP_STONLY,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -597,6 +930,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
{
|
||||
@@ -606,6 +940,7 @@ int main(int argc, char *argv[])
|
||||
.mapping = MAP_PRIVATE,
|
||||
.tag_check = TAG_CHECK_ON,
|
||||
.atag_check = ATAG_CHECK_ON,
|
||||
.tag_op = TAG_OP_ALL,
|
||||
.enable_tco = false,
|
||||
},
|
||||
};
|
||||
@@ -643,7 +978,8 @@ int main(int argc, char *argv[])
|
||||
test_cases[i].mte_sync,
|
||||
test_cases[i].mapping,
|
||||
test_cases[i].tag_check,
|
||||
test_cases[i].atag_check),
|
||||
test_cases[i].atag_check,
|
||||
test_cases[i].tag_op),
|
||||
format_test_name(&test_cases[i]));
|
||||
break;
|
||||
case CHECK_FILE_MEM:
|
||||
@@ -651,7 +987,8 @@ int main(int argc, char *argv[])
|
||||
test_cases[i].mte_sync,
|
||||
test_cases[i].mapping,
|
||||
test_cases[i].tag_check,
|
||||
test_cases[i].atag_check),
|
||||
test_cases[i].atag_check,
|
||||
test_cases[i].tag_op),
|
||||
format_test_name(&test_cases[i]));
|
||||
break;
|
||||
case CHECK_CLEAR_PROT_MTE:
|
||||
|
||||
@@ -60,7 +60,7 @@ void check_basic_read(void)
|
||||
/*
|
||||
* Attempt to set a specified combination of modes.
|
||||
*/
|
||||
void set_mode_test(const char *name, int hwcap2, int mask)
|
||||
void set_mode_test(const char *name, int hwcap2, int hwcap3, int mask)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -69,6 +69,11 @@ void set_mode_test(const char *name, int hwcap2, int mask)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((getauxval(AT_HWCAP3) & hwcap3) != hwcap3) {
|
||||
ksft_test_result_skip("%s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = set_tagged_addr_ctrl(mask);
|
||||
if (ret < 0) {
|
||||
ksft_test_result_fail("%s\n", name);
|
||||
@@ -81,7 +86,7 @@ void set_mode_test(const char *name, int hwcap2, int mask)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret & PR_MTE_TCF_MASK) == mask) {
|
||||
if ((ret & (PR_MTE_TCF_MASK | PR_MTE_STORE_ONLY)) == mask) {
|
||||
ksft_test_result_pass("%s\n", name);
|
||||
} else {
|
||||
ksft_print_msg("Got %x, expected %x\n",
|
||||
@@ -93,12 +98,16 @@ void set_mode_test(const char *name, int hwcap2, int mask)
|
||||
struct mte_mode {
|
||||
int mask;
|
||||
int hwcap2;
|
||||
int hwcap3;
|
||||
const char *name;
|
||||
} mte_modes[] = {
|
||||
{ PR_MTE_TCF_NONE, 0, "NONE" },
|
||||
{ PR_MTE_TCF_SYNC, HWCAP2_MTE, "SYNC" },
|
||||
{ PR_MTE_TCF_ASYNC, HWCAP2_MTE, "ASYNC" },
|
||||
{ PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC, HWCAP2_MTE, "SYNC+ASYNC" },
|
||||
{ PR_MTE_TCF_NONE, 0, 0, "NONE" },
|
||||
{ PR_MTE_TCF_SYNC, HWCAP2_MTE, 0, "SYNC" },
|
||||
{ PR_MTE_TCF_ASYNC, HWCAP2_MTE, 0, "ASYNC" },
|
||||
{ PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC, HWCAP2_MTE, 0, "SYNC+ASYNC" },
|
||||
{ PR_MTE_TCF_SYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "SYNC+STONLY" },
|
||||
{ PR_MTE_TCF_ASYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "ASYNC+STONLY" },
|
||||
{ PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | PR_MTE_STORE_ONLY, HWCAP2_MTE, HWCAP3_MTE_STORE_ONLY, "SYNC+ASYNC+STONLY" },
|
||||
};
|
||||
|
||||
int main(void)
|
||||
@@ -106,11 +115,11 @@ int main(void)
|
||||
int i;
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(5);
|
||||
ksft_set_plan(ARRAY_SIZE(mte_modes));
|
||||
|
||||
check_basic_read();
|
||||
for (i = 0; i < ARRAY_SIZE(mte_modes); i++)
|
||||
set_mode_test(mte_modes[i].name, mte_modes[i].hwcap2,
|
||||
set_mode_test(mte_modes[i].name, mte_modes[i].hwcap2, mte_modes[i].hwcap3,
|
||||
mte_modes[i].mask);
|
||||
|
||||
ksft_print_cnts();
|
||||
|
||||
Reference in New Issue
Block a user