@@ -66,7 +66,7 @@ static const struct vec_type vec_types[] = {
6666};
6767
6868#define VL_TESTS (((TEST_VQ_MAX - SVE_VQ_MIN) + 1) * 4)
69- #define FLAG_TESTS 2
69+ #define FLAG_TESTS 4
7070#define FPSIMD_TESTS 2
7171
7272#define EXPECTED_TESTS ((VL_TESTS + FLAG_TESTS + FPSIMD_TESTS) * ARRAY_SIZE(vec_types))
@@ -95,28 +95,37 @@ static int do_child(void)
9595static int get_fpsimd (pid_t pid , struct user_fpsimd_state * fpsimd )
9696{
9797 struct iovec iov ;
98+ int ret ;
9899
99100 iov .iov_base = fpsimd ;
100101 iov .iov_len = sizeof (* fpsimd );
101- return ptrace (PTRACE_GETREGSET , pid , NT_PRFPREG , & iov );
102+ ret = ptrace (PTRACE_GETREGSET , pid , NT_PRFPREG , & iov );
103+ if (ret == -1 )
104+ ksft_perror ("ptrace(PTRACE_GETREGSET)" );
105+ return ret ;
102106}
103107
104108static int set_fpsimd (pid_t pid , struct user_fpsimd_state * fpsimd )
105109{
106110 struct iovec iov ;
111+ int ret ;
107112
108113 iov .iov_base = fpsimd ;
109114 iov .iov_len = sizeof (* fpsimd );
110- return ptrace (PTRACE_SETREGSET , pid , NT_PRFPREG , & iov );
115+ ret = ptrace (PTRACE_SETREGSET , pid , NT_PRFPREG , & iov );
116+ if (ret == -1 )
117+ ksft_perror ("ptrace(PTRACE_SETREGSET)" );
118+ return ret ;
111119}
112120
113121static struct user_sve_header * get_sve (pid_t pid , const struct vec_type * type ,
114122 void * * buf , size_t * size )
115123{
116124 struct user_sve_header * sve ;
117125 void * p ;
118- size_t sz = sizeof * sve ;
126+ size_t sz = sizeof ( * sve ) ;
119127 struct iovec iov ;
128+ int ret ;
120129
121130 while (1 ) {
122131 if (* size < sz ) {
@@ -132,8 +141,11 @@ static struct user_sve_header *get_sve(pid_t pid, const struct vec_type *type,
132141
133142 iov .iov_base = * buf ;
134143 iov .iov_len = sz ;
135- if (ptrace (PTRACE_GETREGSET , pid , type -> regset , & iov ))
144+ ret = ptrace (PTRACE_GETREGSET , pid , type -> regset , & iov );
145+ if (ret ) {
146+ ksft_perror ("ptrace(PTRACE_GETREGSET)" );
136147 goto error ;
148+ }
137149
138150 sve = * buf ;
139151 if (sve -> size <= sz )
@@ -152,10 +164,46 @@ static int set_sve(pid_t pid, const struct vec_type *type,
152164 const struct user_sve_header * sve )
153165{
154166 struct iovec iov ;
167+ int ret ;
155168
156169 iov .iov_base = (void * )sve ;
157170 iov .iov_len = sve -> size ;
158- return ptrace (PTRACE_SETREGSET , pid , type -> regset , & iov );
171+ ret = ptrace (PTRACE_SETREGSET , pid , type -> regset , & iov );
172+ if (ret == -1 )
173+ ksft_perror ("ptrace(PTRACE_SETREGSET)" );
174+ return ret ;
175+ }
176+
177+ /* A read operation fails */
178+ static void read_fails (pid_t child , const struct vec_type * type )
179+ {
180+ struct user_sve_header * new_sve = NULL ;
181+ size_t new_sve_size = 0 ;
182+ void * ret ;
183+
184+ ret = get_sve (child , type , (void * * )& new_sve , & new_sve_size );
185+
186+ ksft_test_result (ret == NULL , "%s unsupported read fails\n" ,
187+ type -> name );
188+
189+ free (new_sve );
190+ }
191+
192+ /* A write operation fails */
193+ static void write_fails (pid_t child , const struct vec_type * type )
194+ {
195+ struct user_sve_header sve ;
196+ int ret ;
197+
198+ /* Just the header, no data */
199+ memset (& sve , 0 , sizeof (sve ));
200+ sve .size = sizeof (sve );
201+ sve .flags = SVE_PT_REGS_SVE ;
202+ sve .vl = SVE_VL_MIN ;
203+ ret = set_sve (child , type , & sve );
204+
205+ ksft_test_result (ret != 0 , "%s unsupported write fails\n" ,
206+ type -> name );
159207}
160208
161209/* Validate setting and getting the inherit flag */
@@ -270,6 +318,25 @@ static void check_u32(unsigned int vl, const char *reg,
270318 }
271319}
272320
321+ /* Set out of range VLs */
322+ static void ptrace_set_vl_ranges (pid_t child , const struct vec_type * type )
323+ {
324+ struct user_sve_header sve ;
325+ int ret ;
326+
327+ memset (& sve , 0 , sizeof (sve ));
328+ sve .flags = SVE_PT_REGS_SVE ;
329+ sve .size = sizeof (sve );
330+
331+ ret = set_sve (child , type , & sve );
332+ ksft_test_result (ret != 0 , "%s Set invalid VL 0\n" , type -> name );
333+
334+ sve .vl = SVE_VL_MAX + SVE_VQ_BYTES ;
335+ ret = set_sve (child , type , & sve );
336+ ksft_test_result (ret != 0 , "%s Set invalid VL %d\n" , type -> name ,
337+ SVE_VL_MAX + SVE_VQ_BYTES );
338+ }
339+
273340/* Access the FPSIMD registers via the SVE regset */
274341static void ptrace_sve_fpsimd (pid_t child , const struct vec_type * type )
275342{
@@ -683,6 +750,20 @@ static int do_parent(pid_t child)
683750 }
684751
685752 for (i = 0 ; i < ARRAY_SIZE (vec_types ); i ++ ) {
753+ /*
754+ * If the vector type isn't supported reads and writes
755+ * should fail.
756+ */
757+ if (!(getauxval (vec_types [i ].hwcap_type ) & vec_types [i ].hwcap )) {
758+ read_fails (child , & vec_types [i ]);
759+ write_fails (child , & vec_types [i ]);
760+ } else {
761+ ksft_test_result_skip ("%s unsupported read fails\n" ,
762+ vec_types [i ].name );
763+ ksft_test_result_skip ("%s unsupported write fails\n" ,
764+ vec_types [i ].name );
765+ }
766+
686767 /* FPSIMD via SVE regset */
687768 if (getauxval (vec_types [i ].hwcap_type ) & vec_types [i ].hwcap ) {
688769 ptrace_sve_fpsimd (child , & vec_types [i ]);
@@ -703,6 +784,17 @@ static int do_parent(pid_t child)
703784 vec_types [i ].name );
704785 }
705786
787+ /* Setting out of bounds VLs should fail */
788+ if (getauxval (vec_types [i ].hwcap_type ) & vec_types [i ].hwcap ) {
789+ ptrace_set_vl_ranges (child , & vec_types [i ]);
790+ } else {
791+ ksft_test_result_skip ("%s Set invalid VL 0\n" ,
792+ vec_types [i ].name );
793+ ksft_test_result_skip ("%s Set invalid VL %d\n" ,
794+ vec_types [i ].name ,
795+ SVE_VL_MAX + SVE_VQ_BYTES );
796+ }
797+
706798 /* Step through every possible VQ */
707799 for (vq = SVE_VQ_MIN ; vq <= TEST_VQ_MAX ; vq ++ ) {
708800 vl = sve_vl_from_vq (vq );
0 commit comments