tools/testing/selftests/arm64/fp/sve-ptrace.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/fp/sve-ptrace.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/arm64/fp/sve-ptrace.c
Extension
.c
Size
22921 bytes
Lines
920
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 vec_type {
	const char *name;
	unsigned long hwcap_type;
	unsigned long hwcap;
	int regset;
	int prctl_set;
};

static const struct vec_type vec_types[] = {
	{
		.name = "SVE",
		.hwcap_type = AT_HWCAP,
		.hwcap = HWCAP_SVE,
		.regset = NT_ARM_SVE,
		.prctl_set = PR_SVE_SET_VL,
	},
	{
		.name = "Streaming SVE",
		.hwcap_type = AT_HWCAP2,
		.hwcap = HWCAP2_SME,
		.regset = NT_ARM_SSVE,
		.prctl_set = PR_SME_SET_VL,
	},
};

#define VL_TESTS (((TEST_VQ_MAX - SVE_VQ_MIN) + 1) * 4)
#define FLAG_TESTS 4
#define FPSIMD_TESTS 2

#define EXPECTED_TESTS ((VL_TESTS + FLAG_TESTS + FPSIMD_TESTS) * ARRAY_SIZE(vec_types))

static void fill_buf(char *buf, size_t size)
{
	int i;

	for (i = 0; i < size; i++)
		buf[i] = random();
}

static int do_child(void)
{
	if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
		ksft_exit_fail_msg("ptrace(PTRACE_TRACEME) failed: %s (%d)\n",
				   strerror(errno), errno);

	if (raise(SIGSTOP))
		ksft_exit_fail_msg("raise(SIGSTOP) failed: %s (%d)\n",
				   strerror(errno), errno);

	return EXIT_SUCCESS;
}

static int get_fpsimd(pid_t pid, struct user_fpsimd_state *fpsimd)
{
	struct iovec iov;
	int ret;

	iov.iov_base = fpsimd;
	iov.iov_len = sizeof(*fpsimd);
	ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov);
	if (ret == -1)
		ksft_perror("ptrace(PTRACE_GETREGSET)");
	return ret;
}

static int set_fpsimd(pid_t pid, struct user_fpsimd_state *fpsimd)
{
	struct iovec iov;
	int ret;

	iov.iov_base = fpsimd;
	iov.iov_len = sizeof(*fpsimd);
	ret = ptrace(PTRACE_SETREGSET, pid, NT_PRFPREG, &iov);
	if (ret == -1)
		ksft_perror("ptrace(PTRACE_SETREGSET)");
	return ret;
}

static struct user_sve_header *get_sve(pid_t pid, const struct vec_type *type,
				       void **buf, size_t *size)
{
	struct user_sve_header *sve;
	void *p;
	size_t sz = sizeof(*sve);
	struct iovec iov;
	int ret;

	while (1) {
		if (*size < sz) {
			p = realloc(*buf, sz);

Annotation

Implementation Notes