Commit 64a64e5d authored by Yeoreum Yun's avatar Yeoreum Yun Committed by Catalin Marinas
Browse files

kselftest/arm64/mte: Refactor check_mmap_option test



Before add mtefar testcase on check_mmap_option.c,
refactor check_mmap_option:
  - make testcase suite array with test options (mem_type, mte_sync type and etc)
    to use general testcase pattern

  - generate each test case name acoording to test options.

Signed-off-by: default avatarYeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20250618084513.1761345-10-yeoreum.yun@arm.com


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 49cee364
Loading
Loading
Loading
Loading
+313 −54
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#define _GNU_SOURCE

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@@ -24,6 +25,23 @@
#define TAG_CHECK_ON		0
#define TAG_CHECK_OFF		1

#define TEST_NAME_MAX		256

enum mte_mem_check_type {
	CHECK_ANON_MEM = 0,
	CHECK_FILE_MEM = 1,
	CHECK_CLEAR_PROT_MTE = 2,
};

struct check_mmap_testcase {
	int check_type;
	int mem_type;
	int mte_sync;
	int mapping;
	int tag_check;
	bool enable_tco;
};

static size_t page_size;
static int sizes[] = {
	1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,
@@ -183,10 +201,271 @@ static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)
	return KSFT_PASS;
}

const char *format_test_name(struct check_mmap_testcase *tc)
{
	static char test_name[TEST_NAME_MAX];
	const char *check_type_str;
	const char *mem_type_str;
	const char *sync_str;
	const char *mapping_str;
	const char *tag_check_str;

	switch (tc->check_type) {
	case CHECK_ANON_MEM:
		check_type_str = "anonymous memory";
		break;
	case CHECK_FILE_MEM:
		check_type_str = "file memory";
		break;
	case CHECK_CLEAR_PROT_MTE:
		check_type_str = "clear PROT_MTE flags";
		break;
	default:
		assert(0);
		break;
	}

	switch (tc->mem_type) {
	case USE_MMAP:
		mem_type_str = "mmap";
		break;
	case USE_MPROTECT:
		mem_type_str = "mmap/mprotect";
		break;
	default:
		assert(0);
		break;
	}

	switch (tc->mte_sync) {
	case MTE_NONE_ERR:
		sync_str = "no error";
		break;
	case MTE_SYNC_ERR:
		sync_str = "sync error";
		break;
	case MTE_ASYNC_ERR:
		sync_str = "async error";
		break;
	default:
		assert(0);
		break;
	}

	switch (tc->mapping) {
	case MAP_SHARED:
		mapping_str = "shared";
		break;
	case MAP_PRIVATE:
		mapping_str = "private";
		break;
	default:
		assert(0);
		break;
	}

	switch (tc->tag_check) {
	case TAG_CHECK_ON:
		tag_check_str = "tag check on";
		break;
	case TAG_CHECK_OFF:
		tag_check_str = "tag check off";
		break;
	default:
		assert(0);
		break;
	}

	snprintf(test_name, sizeof(test_name),
	         "Check %s with %s mapping, %s mode, %s memory and %s\n",
	         check_type_str, mapping_str, sync_str, mem_type_str,
	         tag_check_str);

	return test_name;
}

int main(int argc, char *argv[])
{
	int err;
	int err, i;
	int item = ARRAY_SIZE(sizes);
	struct check_mmap_testcase test_cases[]= {
		{
			.check_type = CHECK_ANON_MEM,
			.mem_type = USE_MMAP,
			.mte_sync = MTE_SYNC_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_OFF,
			.enable_tco = true,
		},
		{
			.check_type = CHECK_FILE_MEM,
			.mem_type = USE_MPROTECT,
			.mte_sync = MTE_SYNC_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_OFF,
			.enable_tco = true,
		},
		{
			.check_type = CHECK_ANON_MEM,
			.mem_type = USE_MMAP,
			.mte_sync = MTE_NONE_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_OFF,
			.enable_tco = false,
		},
		{
			.check_type = CHECK_FILE_MEM,
			.mem_type = USE_MPROTECT,
			.mte_sync = MTE_NONE_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_OFF,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.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,
			.enable_tco = false,
		},
		{
			.check_type = CHECK_CLEAR_PROT_MTE,
			.mem_type = USE_MMAP,
			.mte_sync = MTE_SYNC_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_ON,
			.enable_tco = false,
		},
		{
			.check_type = CHECK_CLEAR_PROT_MTE,
			.mem_type = USE_MPROTECT,
			.mte_sync = MTE_SYNC_ERR,
			.mapping = MAP_PRIVATE,
			.tag_check = TAG_CHECK_ON,
			.enable_tco = false,
		},
	};

	err = mte_default_setup();
	if (err)
@@ -205,59 +484,39 @@ int main(int argc, char *argv[])
	mte_register_signal(SIGSEGV, mte_default_handler, false);

	/* Set test plan */
	ksft_set_plan(22);
	ksft_set_plan(ARRAY_SIZE(test_cases));

	for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) {
		if (test_cases[i].enable_tco)
			mte_enable_pstate_tco();

	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
	"Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
	"Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check off\n");

		else
			mte_disable_pstate_tco();
	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
	"Check anonymous memory with private mapping, no error mode, mmap memory and tag check off\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),
	"Check file memory with private mapping, no error mode, mmap/mprotect memory and tag check off\n");

	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check anonymous memory with private mapping, sync error mode, mmap memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check anonymous memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check anonymous memory with shared mapping, sync error mode, mmap memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check anonymous memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check anonymous memory with private mapping, async error mode, mmap memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check anonymous memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check anonymous memory with shared mapping, async error mode, mmap memory and tag check on\n");
	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check anonymous memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");

	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check file memory with private mapping, sync error mode, mmap memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check file memory with shared mapping, sync error mode, mmap memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check file memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check file memory with private mapping, async error mode, mmap memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),
	"Check file memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check file memory with shared mapping, async error mode, mmap memory and tag check on\n");
	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),
	"Check file memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");

	evaluate_test(check_clear_prot_mte_flag(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
	"Check clear PROT_MTE flags with private mapping, sync error mode and mmap memory\n");
	evaluate_test(check_clear_prot_mte_flag(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),
	"Check clear PROT_MTE flags with private mapping and sync error mode and mmap/mprotect memory\n");

		switch (test_cases[i].check_type) {
		case CHECK_ANON_MEM:
			evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type,
								     test_cases[i].mte_sync,
								     test_cases[i].mapping,
								     test_cases[i].tag_check),
				      format_test_name(&test_cases[i]));
			break;
		case CHECK_FILE_MEM:
			evaluate_test(check_file_memory_mapping(test_cases[i].mem_type,
							        test_cases[i].mte_sync,
							        test_cases[i].mapping,
							        test_cases[i].tag_check),
				      format_test_name(&test_cases[i]));
			break;
		case CHECK_CLEAR_PROT_MTE:
			evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type,
							        test_cases[i].mte_sync,
							        test_cases[i].mapping),
				      format_test_name(&test_cases[i]));
			break;
		default:
			exit(KSFT_FAIL);
		}
	}

	mte_restore_setup();
	ksft_print_cnts();