Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2#include <sys/prctl.h>
3#include <unistd.h>
4#include <errno.h>
5#include <sys/wait.h>
6#include <sys/types.h>
7#include <stdlib.h>
8
9#include "../../kselftest_harness.h"
10#include "v_helpers.h"
11
12#define NEXT_PROGRAM "./vstate_exec_nolibc"
13
14int test_and_compare_child(long provided, long expected, int inherit, int xtheadvector)
15{
16 int rc;
17
18 rc = prctl(PR_RISCV_V_SET_CONTROL, provided);
19 if (rc != 0) {
20 printf("prctl with provided arg %lx failed with code %d\n",
21 provided, rc);
22 return -1;
23 }
24 rc = launch_test(NEXT_PROGRAM, inherit, xtheadvector);
25 if (rc != expected) {
26 printf("Test failed, check %d != %ld\n", rc, expected);
27 return -2;
28 }
29 return 0;
30}
31
32#define PR_RISCV_V_VSTATE_CTRL_CUR_SHIFT 0
33#define PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT 2
34
35TEST(get_control_no_v)
36{
37 long rc;
38
39 if (is_vector_supported() || is_xtheadvector_supported())
40 SKIP(return, "Test expects vector to be not supported");
41
42 rc = prctl(PR_RISCV_V_GET_CONTROL);
43 EXPECT_EQ(-1, rc)
44 TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
45 EXPECT_EQ(EINVAL, errno)
46 TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
47}
48
49TEST(set_control_no_v)
50{
51 long rc;
52
53 if (is_vector_supported() || is_xtheadvector_supported())
54 SKIP(return, "Test expects vector to be not supported");
55
56 rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
57 EXPECT_EQ(-1, rc)
58 TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
59 EXPECT_EQ(EINVAL, errno)
60 TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
61}
62
63TEST(vstate_on_current)
64{
65 long flag;
66 long rc;
67
68 if (!is_vector_supported() && !is_xtheadvector_supported())
69 SKIP(return, "Vector not supported");
70
71 flag = PR_RISCV_V_VSTATE_CTRL_ON;
72 rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
73 EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always succeed");
74}
75
76TEST(vstate_off_eperm)
77{
78 long flag;
79 long rc;
80
81 if (!is_vector_supported() && !is_xtheadvector_supported())
82 SKIP(return, "Vector not supported");
83
84 flag = PR_RISCV_V_VSTATE_CTRL_OFF;
85 rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
86 EXPECT_EQ(EPERM, errno)
87 TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
88 EXPECT_EQ(-1, rc)
89 TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
90}
91
92TEST(vstate_on_no_nesting)
93{
94 long flag;
95 int xtheadvector = 0;
96
97 if (!is_vector_supported()) {
98 if (is_xtheadvector_supported())
99 xtheadvector = 1;
100 else
101 SKIP(return, "Vector not supported");
102 }
103
104 /* Turn on next's vector explicitly and test */
105 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
106
107 EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0, xtheadvector));
108}
109
110TEST(vstate_off_nesting)
111{
112 long flag;
113 int xtheadvector = 0;
114
115 if (!is_vector_supported()) {
116 if (is_xtheadvector_supported())
117 xtheadvector = 1;
118 else
119 SKIP(return, "Vector not supported");
120 }
121
122 /* Turn off next's vector explicitly and test */
123 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
124
125 EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1, xtheadvector));
126}
127
128TEST(vstate_on_inherit_no_nesting)
129{
130 long flag, expected;
131 int xtheadvector = 0;
132
133 if (!is_vector_supported()) {
134 if (is_xtheadvector_supported())
135 xtheadvector = 1;
136 else
137 SKIP(return, "Vector not supported");
138 }
139
140 /* Turn on next's vector explicitly and test no inherit */
141 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
142 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
143 expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
144
145 EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector));
146}
147
148TEST(vstate_on_inherit)
149{
150 long flag, expected;
151 int xtheadvector = 0;
152
153 if (!is_vector_supported()) {
154 if (is_xtheadvector_supported())
155 xtheadvector = 1;
156 else
157 SKIP(return, "Vector not supported");
158 }
159
160 /* Turn on next's vector explicitly and test inherit */
161 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
162 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
163 expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
164
165 EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector));
166}
167
168TEST(vstate_off_inherit_no_nesting)
169{
170 long flag, expected;
171 int xtheadvector = 0;
172
173 if (!is_vector_supported()) {
174 if (is_xtheadvector_supported())
175 xtheadvector = 1;
176 else
177 SKIP(return, "Vector not supported");
178 }
179 /* Turn off next's vector explicitly and test no inherit */
180 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
181 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
182 expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
183
184 EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector));
185}
186
187TEST(vstate_off_inherit)
188{
189 long flag, expected;
190 int xtheadvector = 0;
191
192 if (!is_vector_supported()) {
193 if (is_xtheadvector_supported())
194 xtheadvector = 1;
195 else
196 SKIP(return, "Vector not supported");
197 }
198
199 /* Turn off next's vector explicitly and test inherit */
200 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
201 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
202 expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
203
204 EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector));
205}
206
207/* arguments should fail with EINVAL */
208TEST(inval_set_control_1)
209{
210 int rc;
211
212 if (!is_vector_supported() && !is_xtheadvector_supported())
213 SKIP(return, "Vector not supported");
214
215 rc = prctl(PR_RISCV_V_SET_CONTROL, 0xff0);
216 EXPECT_EQ(-1, rc);
217 EXPECT_EQ(EINVAL, errno);
218}
219
220/* arguments should fail with EINVAL */
221TEST(inval_set_control_2)
222{
223 int rc;
224
225 if (!is_vector_supported() && !is_xtheadvector_supported())
226 SKIP(return, "Vector not supported");
227
228 rc = prctl(PR_RISCV_V_SET_CONTROL, 0x3);
229 EXPECT_EQ(-1, rc);
230 EXPECT_EQ(EINVAL, errno);
231}
232
233/* arguments should fail with EINVAL */
234TEST(inval_set_control_3)
235{
236 int rc;
237
238 if (!is_vector_supported() && !is_xtheadvector_supported())
239 SKIP(return, "Vector not supported");
240
241 rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);
242 EXPECT_EQ(-1, rc);
243 EXPECT_EQ(EINVAL, errno);
244}
245
246TEST_HARNESS_MAIN