Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: riscv: Support xtheadvector in vector tests

Extend existing vector tests to be compatible with the xtheadvector
instructions.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Tested-by: Yangyu Chen <cyy@cyyself.name>
Link: https://lore.kernel.org/r/20241113-xtheadvector-v11-13-236c22791ef9@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Charlie Jenkins and committed by
Palmer Dabbelt
c384c5d4 57d7713a

+113 -52
+16 -7
tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
··· 18 18 unsigned long vl; 19 19 int first = 1; 20 20 21 - asm volatile ( 22 - ".option push\n\t" 23 - ".option arch, +v\n\t" 24 - "vsetvli %[vl], x0, e8, m1, ta, ma\n\t" 25 - ".option pop\n\t" 26 - : [vl] "=r" (vl) 27 - ); 21 + if (argc > 2 && strcmp(argv[2], "x")) 22 + asm volatile ( 23 + // 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli 24 + // vsetvli t4, x0, e8, m1, d1 25 + ".4byte 0b00000000000000000111111011010111\n\t" 26 + "mv %[vl], t4\n\t" 27 + : [vl] "=r" (vl) : : "t4" 28 + ); 29 + else 30 + asm volatile ( 31 + ".option push\n\t" 32 + ".option arch, +v\n\t" 33 + "vsetvli %[vl], x0, e8, m1, ta, ma\n\t" 34 + ".option pop\n\t" 35 + : [vl] "=r" (vl) 36 + ); 28 37 29 38 #define CHECK_VECTOR_REGISTER(register) ({ \ 30 39 for (int i = 0; i < vl; i++) { \
+14 -3
tools/testing/selftests/riscv/vector/v_helpers.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 #include "../hwprobe/hwprobe.h" 4 + #include <asm/vendor/thead.h> 4 5 #include <stdbool.h> 5 6 #include <stdlib.h> 6 7 #include <stdio.h> 7 8 #include <unistd.h> 8 9 #include <sys/wait.h> 10 + 11 + bool is_xtheadvector_supported(void) 12 + { 13 + struct riscv_hwprobe pair; 14 + 15 + pair.key = RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0; 16 + riscv_hwprobe(&pair, 1, 0, NULL, 0); 17 + return pair.value & RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR; 18 + } 9 19 10 20 bool is_vector_supported(void) 11 21 { ··· 26 16 return pair.value & RISCV_HWPROBE_EXT_ZVE32X; 27 17 } 28 18 29 - int launch_test(char *next_program, int test_inherit) 19 + int launch_test(char *next_program, int test_inherit, int xtheadvector) 30 20 { 31 - char *exec_argv[3], *exec_envp[1]; 21 + char *exec_argv[4], *exec_envp[1]; 32 22 int rc, pid, status; 33 23 34 24 pid = fork(); ··· 40 30 if (!pid) { 41 31 exec_argv[0] = next_program; 42 32 exec_argv[1] = test_inherit != 0 ? "x" : NULL; 43 - exec_argv[2] = NULL; 33 + exec_argv[2] = xtheadvector != 0 ? "x" : NULL; 34 + exec_argv[3] = NULL; 44 35 exec_envp[0] = NULL; 45 36 /* launch the program again to check inherit */ 46 37 rc = execve(next_program, exec_argv, exec_envp);
+3 -1
tools/testing/selftests/riscv/vector/v_helpers.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 #include <stdbool.h> 3 3 4 + bool is_xtheadvector_supported(void); 5 + 4 6 bool is_vector_supported(void); 5 7 6 - int launch_test(char *next_program, int test_inherit); 8 + int launch_test(char *next_program, int test_inherit, int xtheadvector);
+9 -3
tools/testing/selftests/riscv/vector/v_initval.c
··· 7 7 8 8 TEST(v_initval) 9 9 { 10 - if (!is_vector_supported()) 11 - SKIP(return, "Vector not supported"); 10 + int xtheadvector = 0; 12 11 13 - ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0)); 12 + if (!is_vector_supported()) { 13 + if (is_xtheadvector_supported()) 14 + xtheadvector = 1; 15 + else 16 + SKIP(return, "Vector not supported"); 17 + } 18 + 19 + ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0, xtheadvector)); 14 20 } 15 21 16 22 TEST_HARNESS_MAIN
+13 -7
tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
··· 6 6 7 7 int main(int argc, char **argv) 8 8 { 9 - int rc, pid, status, test_inherit = 0; 9 + int rc, pid, status, test_inherit = 0, xtheadvector = 0; 10 10 long ctrl, ctrl_c; 11 11 char *exec_argv[2], *exec_envp[2]; 12 12 13 - if (argc > 1) 13 + if (argc > 1 && strcmp(argv[1], "x")) 14 14 test_inherit = 1; 15 + 16 + if (argc > 2 && strcmp(argv[2], "x")) 17 + xtheadvector = 1; 15 18 16 19 ctrl = my_syscall1(__NR_prctl, PR_RISCV_V_GET_CONTROL); 17 20 if (ctrl < 0) { ··· 56 53 puts("child's vstate_ctrl not equal to parent's\n"); 57 54 exit(-1); 58 55 } 59 - asm volatile (".option push\n\t" 60 - ".option arch, +v\n\t" 61 - "vsetvli x0, x0, e32, m8, ta, ma\n\t" 62 - ".option pop\n\t" 63 - ); 56 + if (xtheadvector) 57 + asm volatile (".4byte 0x00007ed7"); 58 + else 59 + asm volatile (".option push\n\t" 60 + ".option arch, +v\n\t" 61 + "vsetvli x0, x0, e32, m8, ta, ma\n\t" 62 + ".option pop\n\t" 63 + ); 64 64 exit(ctrl); 65 65 } 66 66 }
+58 -31
tools/testing/selftests/riscv/vector/vstate_prctl.c
··· 11 11 12 12 #define NEXT_PROGRAM "./vstate_exec_nolibc" 13 13 14 - int test_and_compare_child(long provided, long expected, int inherit) 14 + int test_and_compare_child(long provided, long expected, int inherit, int xtheadvector) 15 15 { 16 16 int rc; 17 17 ··· 21 21 provided, rc); 22 22 return -1; 23 23 } 24 - rc = launch_test(NEXT_PROGRAM, inherit); 24 + rc = launch_test(NEXT_PROGRAM, inherit, xtheadvector); 25 25 if (rc != expected) { 26 26 printf("Test failed, check %d != %ld\n", rc, expected); 27 27 return -2; ··· 36 36 { 37 37 long rc; 38 38 39 - if (is_vector_supported()) 39 + if (is_vector_supported() || is_xtheadvector_supported()) 40 40 SKIP(return, "Test expects vector to be not supported"); 41 41 42 42 rc = prctl(PR_RISCV_V_GET_CONTROL); ··· 50 50 { 51 51 long rc; 52 52 53 - if (is_vector_supported()) 53 + if (is_vector_supported() || is_xtheadvector_supported()) 54 54 SKIP(return, "Test expects vector to be not supported"); 55 55 56 56 rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON); ··· 65 65 long flag; 66 66 long rc; 67 67 68 - if (!is_vector_supported()) 68 + if (!is_vector_supported() && !is_xtheadvector_supported()) 69 69 SKIP(return, "Vector not supported"); 70 70 71 71 flag = PR_RISCV_V_VSTATE_CTRL_ON; 72 72 rc = prctl(PR_RISCV_V_SET_CONTROL, flag); 73 - EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always success"); 73 + EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always succeed"); 74 74 } 75 75 76 76 TEST(vstate_off_eperm) ··· 78 78 long flag; 79 79 long rc; 80 80 81 - if (!is_vector_supported()) 81 + if (!is_vector_supported() && !is_xtheadvector_supported()) 82 82 SKIP(return, "Vector not supported"); 83 83 84 84 flag = PR_RISCV_V_VSTATE_CTRL_OFF; ··· 92 92 TEST(vstate_on_no_nesting) 93 93 { 94 94 long flag; 95 + int xtheadvector = 0; 95 96 96 - if (!is_vector_supported()) 97 - SKIP(return, "Vector not supported"); 97 + if (!is_vector_supported()) { 98 + if (is_xtheadvector_supported()) 99 + xtheadvector = 1; 100 + else 101 + SKIP(return, "Vector not supported"); 102 + } 98 103 99 104 /* Turn on next's vector explicitly and test */ 100 105 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 101 106 102 - EXPECT_EQ(0, 103 - test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0)); 107 + EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0, xtheadvector)); 104 108 } 105 109 106 110 TEST(vstate_off_nesting) 107 111 { 108 112 long flag; 113 + int xtheadvector = 0; 109 114 110 - if (!is_vector_supported()) 111 - SKIP(return, "Vector not supported"); 115 + if (!is_vector_supported()) { 116 + if (is_xtheadvector_supported()) 117 + xtheadvector = 1; 118 + else 119 + SKIP(return, "Vector not supported"); 120 + } 112 121 113 122 /* Turn off next's vector explicitly and test */ 114 123 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 115 124 116 - EXPECT_EQ(0, 117 - test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1)); 125 + EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1, xtheadvector)); 118 126 } 119 127 120 128 TEST(vstate_on_inherit_no_nesting) 121 129 { 122 130 long flag, expected; 131 + int xtheadvector = 0; 123 132 124 - if (!is_vector_supported()) 125 - SKIP(return, "Vector not supported"); 133 + if (!is_vector_supported()) { 134 + if (is_xtheadvector_supported()) 135 + xtheadvector = 1; 136 + else 137 + SKIP(return, "Vector not supported"); 138 + } 126 139 127 140 /* Turn on next's vector explicitly and test no inherit */ 128 141 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 129 142 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 130 143 expected = flag | PR_RISCV_V_VSTATE_CTRL_ON; 131 144 132 - EXPECT_EQ(0, test_and_compare_child(flag, expected, 0)); 145 + EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector)); 133 146 } 134 147 135 148 TEST(vstate_on_inherit) 136 149 { 137 150 long flag, expected; 151 + int xtheadvector = 0; 138 152 139 - if (!is_vector_supported()) 140 - SKIP(return, "Vector not supported"); 153 + if (!is_vector_supported()) { 154 + if (is_xtheadvector_supported()) 155 + xtheadvector = 1; 156 + else 157 + SKIP(return, "Vector not supported"); 158 + } 141 159 142 160 /* Turn on next's vector explicitly and test inherit */ 143 161 flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 144 162 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 145 163 expected = flag | PR_RISCV_V_VSTATE_CTRL_ON; 146 164 147 - EXPECT_EQ(0, test_and_compare_child(flag, expected, 1)); 165 + EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector)); 148 166 } 149 167 150 168 TEST(vstate_off_inherit_no_nesting) 151 169 { 152 170 long flag, expected; 171 + int xtheadvector = 0; 153 172 154 - if (!is_vector_supported()) 155 - SKIP(return, "Vector not supported"); 156 - 173 + if (!is_vector_supported()) { 174 + if (is_xtheadvector_supported()) 175 + xtheadvector = 1; 176 + else 177 + SKIP(return, "Vector not supported"); 178 + } 157 179 /* Turn off next's vector explicitly and test no inherit */ 158 180 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 159 181 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 160 182 expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF; 161 183 162 - EXPECT_EQ(0, test_and_compare_child(flag, expected, 0)); 184 + EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector)); 163 185 } 164 186 165 187 TEST(vstate_off_inherit) 166 188 { 167 189 long flag, expected; 190 + int xtheadvector = 0; 168 191 169 - if (!is_vector_supported()) 170 - SKIP(return, "Vector not supported"); 192 + if (!is_vector_supported()) { 193 + if (is_xtheadvector_supported()) 194 + xtheadvector = 1; 195 + else 196 + SKIP(return, "Vector not supported"); 197 + } 171 198 172 199 /* Turn off next's vector explicitly and test inherit */ 173 200 flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; 174 201 flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 175 202 expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF; 176 203 177 - EXPECT_EQ(0, test_and_compare_child(flag, expected, 1)); 204 + EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector)); 178 205 } 179 206 180 207 /* arguments should fail with EINVAL */ ··· 209 182 { 210 183 int rc; 211 184 212 - if (!is_vector_supported()) 185 + if (!is_vector_supported() && !is_xtheadvector_supported()) 213 186 SKIP(return, "Vector not supported"); 214 187 215 188 rc = prctl(PR_RISCV_V_SET_CONTROL, 0xff0); ··· 222 195 { 223 196 int rc; 224 197 225 - if (!is_vector_supported()) 198 + if (!is_vector_supported() && !is_xtheadvector_supported()) 226 199 SKIP(return, "Vector not supported"); 227 200 228 201 rc = prctl(PR_RISCV_V_SET_CONTROL, 0x3); ··· 235 208 { 236 209 int rc; 237 210 238 - if (!is_vector_supported()) 211 + if (!is_vector_supported() && !is_xtheadvector_supported()) 239 212 SKIP(return, "Vector not supported"); 240 213 241 214 rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);