tools/testing/selftests/riscv/vector/vstate_ptrace.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/riscv/vector/vstate_ptrace.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/riscv/vector/vstate_ptrace.c
Extension
.c
Size
3003 bytes
Lines
135
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

if (WIFEXITED(status)) {
			ksft_test_result(WEXITSTATUS(status) == 0, "SETREGSET vector\n");
			goto out;
		} else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) {
			size_t size;
			void *data, *v31;
			struct __riscv_v_regset_state *v_regset_hdr;
			struct user_regs_struct *gpreg;

			size = sizeof(*v_regset_hdr);
			data = malloc(size);
			if (!data)
				goto out;
			v_regset_hdr = (struct __riscv_v_regset_state *)data;

			if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
				goto out;

			ksft_print_msg("vlenb %ld\n", v_regset_hdr->vlenb);
			data = realloc(data, size + v_regset_hdr->vlenb * 32);
			if (!data)
				goto out;
			v_regset_hdr = (struct __riscv_v_regset_state *)data;
			v31 = (void *)(data + size + v_regset_hdr->vlenb * 31);
			size += v_regset_hdr->vlenb * 32;

			if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
				goto out;

			ksft_test_result(*(int *)v31 == child_set_val, "GETREGSET vector\n");

			*(int *)v31 = parent_set_val;
			if (do_ptrace(PTRACE_SETREGSET, child, NT_RISCV_VECTOR, size, data))
				goto out;

			/* move the pc forward */
			size = sizeof(*gpreg);
			data = realloc(data, size);
			gpreg = (struct user_regs_struct *)data;

			if (do_ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, size, data))
				goto out;

			gpreg->pc += 4;
			if (do_ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, size, data))
				goto out;
		}

		ptrace(PTRACE_CONT, child, NULL, NULL);
	}

out:
	free(data);
}

int main(void)
{
	pid_t child;

	ksft_set_plan(2);
	if (!is_vector_supported() && !is_xtheadvector_supported())
		ksft_exit_skip("Vector not supported\n");

	srandom(getpid());
	parent_set_val = rand();
	child_set_val = rand();

	child = fork();
	if (child < 0)
		ksft_exit_fail_msg("Fork failed %d\n", child);

	if (!child)
		return do_child();

	do_parent(child);

	ksft_finished();
}

Annotation

Implementation Notes