tools/testing/selftests/arm64/mte/check_mmap_options.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/mte/check_mmap_options.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/arm64/mte/check_mmap_options.c
Extension
.c
Size
25352 bytes
Lines
1010
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct check_mmap_testcase {
	int check_type;
	int mem_type;
	int mte_sync;
	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, int tag_op)
{
	char buf[MT_GRANULE_SIZE];

	if (!mtefar_support && atag_check == ATAG_CHECK_ON)
		return KSFT_SKIP;

	if (atag_check == ATAG_CHECK_ON)
		ptr = mte_insert_atag(ptr);

	mte_initialize_current_context(mode, (uintptr_t)ptr, size);
	memset(ptr, '1', size);
	mte_wait_after_trig();
	if (cur_mte_cxt.fault_valid == true)
		return KSFT_FAIL;

	mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW);
	memset(ptr - UNDERFLOW, '2', UNDERFLOW);
	mte_wait_after_trig();
	if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON)
		return KSFT_FAIL;
	if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF)
		return KSFT_FAIL;

	mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW);
	memset(ptr + size, '3', OVERFLOW);
	mte_wait_after_trig();
	if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON)
		return KSFT_FAIL;
	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, int tag_op)
{
	char *ptr, *map_ptr;
	int run, result, map_size;
	int item = ARRAY_SIZE(sizes);

	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);
		if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS)
			return KSFT_FAIL;

		ptr = map_ptr + UNDERFLOW;
		mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]);
		/* Only mte enabled memory will allow tag insertion */

Annotation

Implementation Notes