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 14 int 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 35 TEST(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 49 TEST(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 63 TEST(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 76 TEST(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 92 TEST(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 110 TEST(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 128 TEST(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 148 TEST(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 168 TEST(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 187 TEST(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 */ 208 TEST(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 */ 221 TEST(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 */ 234 TEST(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 246 TEST_HARNESS_MAIN 247