1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/wait.h>
5 #define THIS_PROGRAM "./vstate_exec_nolibc"
7 int main(int argc
, char **argv
)
9 int rc
, pid
, status
, test_inherit
= 0;
11 char *exec_argv
[2], *exec_envp
[2];
16 ctrl
= my_syscall1(__NR_prctl
, PR_RISCV_V_GET_CONTROL
);
18 puts("PR_RISCV_V_GET_CONTROL is not supported\n");
25 puts("fork failed\n");
31 exec_argv
[0] = THIS_PROGRAM
;
35 /* launch the program again to check inherit */
36 rc
= execve(THIS_PROGRAM
, exec_argv
, exec_envp
);
38 puts("child execve failed\n");
46 puts("fork failed\n");
51 rc
= my_syscall1(__NR_prctl
, PR_RISCV_V_GET_CONTROL
);
53 puts("child's vstate_ctrl not equal to parent's\n");
56 asm volatile (".option push\n\t"
57 ".option arch, +v\n\t"
58 "vsetvli x0, x0, e32, m8, ta, ma\n\t"
65 rc
= waitpid(-1, &status
, 0);
67 if (WIFEXITED(status
) && WEXITSTATUS(status
) == -1) {
68 puts("child exited abnormally\n");
72 if (WIFSIGNALED(status
)) {
73 if (WTERMSIG(status
) != SIGILL
) {
74 puts("child was terminated by unexpected signal\n");
78 if ((ctrl
& PR_RISCV_V_VSTATE_CTRL_CUR_MASK
) != PR_RISCV_V_VSTATE_CTRL_OFF
) {
79 puts("child signaled by illegal V access but vstate_ctrl is not off\n");
83 /* child terminated, and its vstate_ctrl is off */
87 ctrl_c
= WEXITSTATUS(status
);
89 if (ctrl
& PR_RISCV_V_VSTATE_CTRL_INHERIT
) {
90 if (!(ctrl_c
& PR_RISCV_V_VSTATE_CTRL_INHERIT
)) {
91 puts("parent has inherit bit, but child has not\n");
95 rc
= (ctrl
& PR_RISCV_V_VSTATE_CTRL_NEXT_MASK
) >> 2;
96 if (rc
!= PR_RISCV_V_VSTATE_CTRL_DEFAULT
) {
97 if (rc
!= (ctrl_c
& PR_RISCV_V_VSTATE_CTRL_CUR_MASK
)) {
98 puts("parent's next setting does not equal to child's\n");
102 if (!(ctrl
& PR_RISCV_V_VSTATE_CTRL_INHERIT
)) {
103 if ((ctrl_c
& PR_RISCV_V_VSTATE_CTRL_NEXT_MASK
) !=
104 PR_RISCV_V_VSTATE_CTRL_DEFAULT
) {
105 puts("must clear child's next vstate_ctrl if !inherit\n");