Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v6.18 246 lines 6.0 kB view raw
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