Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kselftest/arm64: mte: user_mem: test a wider range of values

Instead of hard coding a small amount of tests, generate a wider
range of tests to try catch any corner cases that could show up.

These new tests test different MTE tag lengths and offsets, which
previously would have caused infinite loops in the kernel. This was
fixed by 295cf156231c ("arm64: Avoid premature usercopy failure"),
so these are regressions tests for that corner case.

Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20220209152240.52788-7-joey.gouly@arm.com
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Joey Gouly and committed by
Will Deacon
0a775ccb e8d3974f

+82 -10
+82 -10
tools/testing/selftests/arm64/mte/check_user_mem.c
··· 3 3 4 4 #define _GNU_SOURCE 5 5 6 + #include <assert.h> 6 7 #include <errno.h> 7 8 #include <fcntl.h> 8 9 #include <signal.h> ··· 20 19 #include "mte_def.h" 21 20 22 21 static size_t page_sz; 22 + 23 + #define TEST_NAME_MAX 100 23 24 24 25 enum test_type { 25 26 READ_TEST, ··· 139 136 return err; 140 137 } 141 138 139 + void format_test_name(char* name, int name_len, int type, int sync, int map, int len, int offset) { 140 + const char* test_type; 141 + const char* mte_type; 142 + const char* map_type; 143 + 144 + switch (type) { 145 + case READ_TEST: 146 + test_type = "read"; 147 + break; 148 + case WRITE_TEST: 149 + test_type = "write"; 150 + break; 151 + case READV_TEST: 152 + test_type = "readv"; 153 + break; 154 + case WRITEV_TEST: 155 + test_type = "writev"; 156 + break; 157 + default: 158 + assert(0); 159 + break; 160 + } 161 + 162 + switch (sync) { 163 + case MTE_SYNC_ERR: 164 + mte_type = "MTE_SYNC_ERR"; 165 + break; 166 + case MTE_ASYNC_ERR: 167 + mte_type = "MTE_ASYNC_ERR"; 168 + break; 169 + default: 170 + assert(0); 171 + break; 172 + } 173 + 174 + switch (map) { 175 + case MAP_SHARED: 176 + map_type = "MAP_SHARED"; 177 + break; 178 + case MAP_PRIVATE: 179 + map_type = "MAP_PRIVATE"; 180 + break; 181 + default: 182 + assert(0); 183 + break; 184 + } 185 + 186 + snprintf(name, name_len, 187 + "test type: %s, %s, %s, tag len: %d, tag offset: %d\n", 188 + test_type, mte_type, map_type, len, offset); 189 + } 190 + 142 191 int main(int argc, char *argv[]) 143 192 { 144 193 int err; 194 + int t, s, m, l, o; 195 + int mte_sync[] = {MTE_SYNC_ERR, MTE_ASYNC_ERR}; 196 + int maps[] = {MAP_SHARED, MAP_PRIVATE}; 197 + int tag_lens[] = {0, MT_GRANULE_SIZE}; 198 + int tag_offsets[] = {page_sz, MT_GRANULE_SIZE}; 199 + char test_name[TEST_NAME_MAX]; 145 200 146 201 page_sz = getpagesize(); 147 202 if (!page_sz) { ··· 214 153 mte_register_signal(SIGSEGV, mte_default_handler); 215 154 216 155 /* Set test plan */ 217 - ksft_set_plan(4); 156 + ksft_set_plan(64); 218 157 219 - evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz, 0, READ_TEST), 220 - "Check memory access from kernel in sync mode, private mapping and mmap memory\n"); 221 - evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, page_sz, 0, READ_TEST), 222 - "Check memory access from kernel in sync mode, shared mapping and mmap memory\n"); 223 - 224 - evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, page_sz, 0, READ_TEST), 225 - "Check memory access from kernel in async mode, private mapping and mmap memory\n"); 226 - evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, page_sz, 0, READ_TEST), 227 - "Check memory access from kernel in async mode, shared mapping and mmap memory\n"); 158 + for (t = 0; t < LAST_TEST; t++) { 159 + for (s = 0; s < ARRAY_SIZE(mte_sync); s++) { 160 + for (m = 0; m < ARRAY_SIZE(maps); m++) { 161 + for (l = 0; l < ARRAY_SIZE(tag_lens); l++) { 162 + for (o = 0; o < ARRAY_SIZE(tag_offsets); o++) { 163 + int sync = mte_sync[s]; 164 + int map = maps[m]; 165 + int offset = tag_offsets[o]; 166 + int tag_len = tag_lens[l]; 167 + int res = check_usermem_access_fault(USE_MMAP, sync, 168 + map, offset, 169 + tag_len, t); 170 + format_test_name(test_name, TEST_NAME_MAX, 171 + t, sync, map, tag_len, offset); 172 + evaluate_test(res, test_name); 173 + } 174 + } 175 + } 176 + } 177 + } 228 178 229 179 mte_restore_setup(); 230 180 ksft_print_cnts();