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

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

File Facts

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

// SPDX-License-Identifier: GPL-2.0-only
#include <sys/prctl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>

#include "kselftest_harness.h"
#include "v_helpers.h"

#define NEXT_PROGRAM "./vstate_exec_nolibc"

int test_and_compare_child(long provided, long expected, int inherit, int xtheadvector)
{
	int rc;

	rc = prctl(PR_RISCV_V_SET_CONTROL, provided);
	if (rc != 0) {
		printf("prctl with provided arg %lx failed with code %d\n",
		       provided, rc);
		return -1;
	}
	rc = launch_test(NEXT_PROGRAM, inherit, xtheadvector);
	if (rc != expected) {
		printf("Test failed, check %d != %ld\n", rc, expected);
		return -2;
	}
	return 0;
}

#define PR_RISCV_V_VSTATE_CTRL_CUR_SHIFT 0
#define PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT 2

TEST(get_control_no_v)
{
	long rc;

	if (is_vector_supported() || is_xtheadvector_supported())
		SKIP(return, "Test expects vector to be not supported");

	rc = prctl(PR_RISCV_V_GET_CONTROL);
	EXPECT_EQ(-1, rc)
	TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
	EXPECT_EQ(EINVAL, errno)
	TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
}

TEST(set_control_no_v)
{
	long rc;

	if (is_vector_supported() || is_xtheadvector_supported())
		SKIP(return, "Test expects vector to be not supported");

	rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
	EXPECT_EQ(-1, rc)
	TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
	EXPECT_EQ(EINVAL, errno)
	TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
}

TEST(vstate_on_current)
{
	long flag;
	long rc;

	if (!is_vector_supported() && !is_xtheadvector_supported())
		SKIP(return, "Vector not supported");

	flag = PR_RISCV_V_VSTATE_CTRL_ON;
	rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
	EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always succeed");
}

TEST(vstate_off_eperm)
{
	long flag;
	long rc;

	if (!is_vector_supported() && !is_xtheadvector_supported())
		SKIP(return, "Vector not supported");

	flag = PR_RISCV_V_VSTATE_CTRL_OFF;
	rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
	EXPECT_EQ(EPERM, errno)
	TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
	EXPECT_EQ(-1, rc)
	TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
}

Annotation

Implementation Notes