brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · 1f9969b Raw
113 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#include <linux/wait.h>4 5#define THIS_PROGRAM "./vstate_exec_nolibc"6 7int main(int argc, char **argv)8{9	int rc, pid, status, test_inherit = 0;10	long ctrl, ctrl_c;11	char *exec_argv[2], *exec_envp[2];12 13	if (argc > 1)14		test_inherit = 1;15 16	ctrl = my_syscall1(__NR_prctl, PR_RISCV_V_GET_CONTROL);17	if (ctrl < 0) {18		puts("PR_RISCV_V_GET_CONTROL is not supported\n");19		return ctrl;20	}21 22	if (test_inherit) {23		pid = fork();24		if (pid == -1) {25			puts("fork failed\n");26			exit(-1);27		}28 29		/* child  */30		if (!pid) {31			exec_argv[0] = THIS_PROGRAM;32			exec_argv[1] = NULL;33			exec_envp[0] = NULL;34			exec_envp[1] = NULL;35			/* launch the program again to check inherit */36			rc = execve(THIS_PROGRAM, exec_argv, exec_envp);37			if (rc) {38				puts("child execve failed\n");39				exit(-1);40			}41		}42 43	} else {44		pid = fork();45		if (pid == -1) {46			puts("fork failed\n");47			exit(-1);48		}49 50		if (!pid) {51			rc = my_syscall1(__NR_prctl, PR_RISCV_V_GET_CONTROL);52			if (rc != ctrl) {53				puts("child's vstate_ctrl not equal to parent's\n");54				exit(-1);55			}56			asm volatile (".option push\n\t"57				      ".option arch, +v\n\t"58				      "vsetvli x0, x0, e32, m8, ta, ma\n\t"59				      ".option pop\n\t"60				      );61			exit(ctrl);62		}63	}64 65	rc = waitpid(-1, &status, 0);66 67	if (WIFEXITED(status) && WEXITSTATUS(status) == -1) {68		puts("child exited abnormally\n");69		exit(-1);70	}71 72	if (WIFSIGNALED(status)) {73		if (WTERMSIG(status) != SIGILL) {74			puts("child was terminated by unexpected signal\n");75			exit(-1);76		}77 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");80			exit(-1);81		}82 83		/* child terminated, and its vstate_ctrl is off */84		exit(ctrl);85	}86 87	ctrl_c = WEXITSTATUS(status);88	if (test_inherit) {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");92				exit(-1);93			}94		}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");99				exit(-1);100			}101 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");106					exit(-1);107				}108			}109		}110	}111	return ctrl;112}113