tools/testing/selftests/x86/lam.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/x86/lam.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/x86/lam.c
Extension
.c
Size
29285 bytes
Lines
1372
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 testcases {
	unsigned int later;
	int expected; /* 2: SIGSEGV Error; 1: other errors */
	unsigned long lam;
	uint64_t addr;
	uint64_t cmd;
	int (*test_func)(struct testcases *test);
	const char *msg;
};

/* Used by CQ of uring, source file handler and file's size */
struct file_io {
	int file_fd;
	off_t file_sz;
	struct iovec iovecs[];
};

struct io_uring_queue {
	unsigned int *head;
	unsigned int *tail;
	unsigned int *ring_mask;
	unsigned int *ring_entries;
	unsigned int *flags;
	unsigned int *array;
	union {
		struct io_uring_cqe *cqes;
		struct io_uring_sqe *sqes;
	} queue;
	size_t ring_sz;
};

struct io_ring {
	int ring_fd;
	struct io_uring_queue sq_ring;
	struct io_uring_queue cq_ring;
};

int tests_cnt;
jmp_buf segv_env;

static void segv_handler(int sig)
{
	ksft_print_msg("Get segmentation fault(%d).", sig);

	siglongjmp(segv_env, 1);
}

static inline int lam_is_available(void)
{
	unsigned int cpuinfo[4];
	unsigned long bits = 0;
	int ret;

	__cpuid_count(0x7, 1, cpuinfo[0], cpuinfo[1], cpuinfo[2], cpuinfo[3]);

	/* Check if cpu supports LAM */
	if (!(cpuinfo[0] & (1 << 26))) {
		ksft_print_msg("LAM is not supported!\n");
		return 0;
	}

	/* Return 0 if CONFIG_ADDRESS_MASKING is not set */
	ret = syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &bits);
	if (ret) {
		ksft_print_msg("LAM is disabled in the kernel!\n");
		return 0;
	}

	return 1;
}

static inline int la57_enabled(void)
{
	int ret;
	void *p;

	p = mmap((void *)HIGH_ADDR, PAGE_SIZE, PROT_READ | PROT_WRITE,
		 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);

	ret = p == MAP_FAILED ? 0 : 1;

	munmap(p, PAGE_SIZE);
	return ret;
}

/*
 * Set tagged address and read back untag mask.
 * check if the untagged mask is expected.
 *
 * @return:

Annotation

Implementation Notes