blob: 7387161886f76b07e33ed30b2ea54a1f57c96e45 [file] [log] [blame]
mardyk01f5b46352023-10-24 16:23:23 -05001/*
mardyk017b51dbe2024-01-17 15:25:36 -06002 * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
mardyk01f5b46352023-10-24 16:23:23 -05003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Alex Liang0fa7d212024-06-18 11:17:01 -05007#include <stdio.h>
8#include <stdlib.h>
9#include <time.h>
10
Mark Dykes50297972024-03-15 12:49:22 -050011#include <arg_struct_def.h>
12#include "constraint.h"
mardyk017b51dbe2024-01-17 15:25:36 -060013#include <fuzz_names.h>
mardyk01f5b46352023-10-24 16:23:23 -050014#include <sdei_fuzz_helper.h>
15
Mark Dykes2b6c1402025-03-06 10:01:19 -060016#ifdef SDEI_INCLUDE
17
Mark Dykes50297972024-03-15 12:49:22 -050018int stbev = 0;
19
Alex Liang0fa7d212024-06-18 11:17:01 -050020#define MIN_PPI_ID U(16)
21#define MAX_PPI_ID U(31)
22#define MIN_SPI_ID U(32)
23#define MAX_SPI_ID U(255)
24#define EV_COOKIE 0xDEADBEEF
25#define PPI_RANGE ((uint64_t[2]) {MIN_PPI_ID, MAX_PPI_ID})
26#define SPI_RANGE ((uint64_t[2]) {MIN_SPI_ID, MAX_SPI_ID})
27#define BIND_SLOTS_MASK 0xffffU
28#define FEATURES_SHARED_SLOTS_SHIFT 16U
29#define FEATURES_PRIVATE_SLOTS_SHIFT 0U
30
31extern sdei_handler_t sdei_entrypoint;
32extern sdei_handler_t sdei_entrypoint_resume;
33
34#define HANDLER_SVALUE ((uint64_t[1]) { (uint64_t)(uintptr_t)sdei_entrypoint_resume })
35#define PE_SVALUE ((uint64_t[1]) { read_mpidr_el1() })
36#define ZERO_EVENT_SVALUE ((uint64_t[1]) { 0 })
37#define EV_COOKIE_SVALUE ((uint64_t[1]) { 0xDEADBEEF })
38#define VENDOR_EVENTS_RANGE ((uint64_t[2]) { 0x40000000, 0x40FFFFFF })
39#define STD_EVENTS_RANGE ((uint64_t[2]) { 0x00000001, 0x00FFFFFF })
40#define ANY_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_ANY })
41#define PE_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_PE })
42#define ROUTING_MODES ((uint64_t[2]) { SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE })
43#define OUT_OF_RESOURCE_ERR -10
44#define MAX_BIND_SLOTS (1 << 16)
45
46#define register_handler() setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, \
47SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE)
48
49char *return_str(int64_t return_val)
50{
51 switch (return_val) {
52 case -1:
53 return "NOT_SUPPORTED";
54 case -2:
55 return "INVALID_PARAMETERS";
56 case -3:
57 return "DENIED";
58 case -5:
59 return "PENDING";
60 case -10:
61 return "OUT_OF_RESOURCE";
62 default:
63 return "UNKNOWN ERROR CODE";
64 }
65}
66
67void print_return(char *funcstr, int64_t ret)
68{
69 if (ret < 0) {
70 printf("%s failed: 0x%llx. %s\n", funcstr, ret, return_str(ret));
71 } else {
72 printf("%s successful return: %llx\n", funcstr, ret);
73 }
74}
75
76void set_event_constraints(int sdei_arg_name, struct memmod *mmod)
77{
78 setconstraint(FUZZER_CONSTRAINT_SVALUE, ZERO_EVENT_SVALUE, 1, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
79 setconstraint(FUZZER_CONSTRAINT_SVALUE, STD_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
80 setconstraint(FUZZER_CONSTRAINT_SVALUE, VENDOR_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
81}
82
mardyk017b51dbe2024-01-17 15:25:36 -060083/*
84 * SDEI function that has no arguments
85 */
Alex Liang0fa7d212024-06-18 11:17:01 -050086int64_t tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr)
mardyk01f5b46352023-10-24 16:23:23 -050087{
88 int64_t ret = (*sdei_func)();
89
90 if (ret < 0) {
91 tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
92 }
Alex Liang0fa7d212024-06-18 11:17:01 -050093
94 printf("%s return: %llx\n", funcstr, ret);
95
96 return ret;
mardyk01f5b46352023-10-24 16:23:23 -050097}
98
mardyk017b51dbe2024-01-17 15:25:36 -060099/*
100 * SDEI function that has single argument
101 */
mardyk01f5b46352023-10-24 16:23:23 -0500102void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr)
103{
Mark Dykes50297972024-03-15 12:49:22 -0500104 struct sdei_intr_ctx intr_ctx;
105 int bev;
106
107 bev = sdei_interrupt_bind(tftf_get_timer_irq(), &intr_ctx);
108 int64_t ret = (*sdei_func)(bev);
mardyk01f5b46352023-10-24 16:23:23 -0500109
110 if (ret < 0) {
111 tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
112 }
113}
114
Alex Liang0fa7d212024-06-18 11:17:01 -0500115uint64_t *bound_shared_inums;
116uint64_t *bound_private_inums;
117uint64_t *bound_shared_evnums;
118uint64_t *bound_private_evnums;
119int64_t private_slots_count;
120int64_t shared_slots_count;
121static int64_t private_slots_len;
122static int64_t shared_slots_len;
123
124
125void bound_event_constraints(int fieldname, struct memmod *mmod)
126{
127 setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_shared_evnums, shared_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
128 setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_private_evnums, private_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
129}
130
131void release_shared_slots(struct memmod *mmod, int slots, bool release)
132{
133
134 if ((slots < 0) || (slots > shared_slots_len)) {
135 return;
136 }
137
138 struct inputparameters inp;
139 int64_t ret;
140 struct sdei_intr_ctx intr_ctx;
141
142 if (release) {
143 for (int k = 0; k < slots; k++) {
144 uint64_t release_enum[1] = {bound_shared_evnums[shared_slots_len - 1 - k]};
145
146
147 setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
148 inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
149 ret = sdei_event_unregister(inp.x1);
150 print_return("unregister", ret);
151
152
153 setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
154 inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
155 ret = sdei_interrupt_release(inp.x1, &intr_ctx);
156 print_return("release", ret);
157 }
158 }
159
160 for (int i = shared_slots_len; i > 0; i--) {
161 bound_shared_inums[i] = bound_shared_inums[i-slots];
162 }
163 for (int i = 0; i < slots; i++) {
164 bound_shared_inums[i] = 0;
165 }
166
167 for (int i = shared_slots_len; i > 0; i--) {
168 bound_shared_evnums[i] = bound_shared_evnums[i-slots];
169 }
170 for (int i = 0; i < slots; i++) {
171 bound_shared_evnums[i] = 0;
172 }
173 shared_slots_count = (shared_slots_count + slots < shared_slots_len ? shared_slots_count + slots : shared_slots_len);
174}
175
176void release_private_slots(struct memmod *mmod, int slots, bool release)
177{
178 if ((slots < 0) || (slots > private_slots_len)) {
179 return;
180 }
181
182 struct inputparameters inp;
183 int64_t ret;
184 struct sdei_intr_ctx intr_ctx;
185
186 if (release) {
187 for (int k = 0; k < slots; k++) {
188 uint64_t release_enum[1] = {bound_private_evnums[private_slots_len-1-k]};
189
190 setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
191 inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
192 ret = sdei_event_unregister(inp.x1);
193 print_return("unregister", ret);
194
195 setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
196 inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
197 ret = sdei_interrupt_release(inp.x1, &intr_ctx);
198 print_return("release", ret);
199 }
200 }
201
202 for (int i = private_slots_len; i > 0; i--) {
203 bound_private_inums[i] = bound_private_inums[i-slots];
204 }
205 for (int i = 0; i < slots; i++) {
206 bound_private_inums[i] = 0;
207 }
208
209 for (int i = private_slots_len; i > 0; i--) {
210 bound_private_evnums[i] = bound_private_evnums[i-slots];
211 }
212 for (int i = 0; i < slots; i++) {
213 bound_private_evnums[i] = 0;
214 }
215
216 private_slots_count = (private_slots_count + slots < private_slots_len ? private_slots_count + slots : private_slots_len);
217}
218
219void initalize_interrupt_slots(struct memmod *mmod)
220{
221 uint64_t bind_slots[1] = {0};
222
223 setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
224 struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
225 int64_t slots = sdei_features(inp.x1);
226
227 shared_slots_count = slots & 0xffffU;
228 private_slots_count = (slots >> 16U) & 0xfffU;
229 shared_slots_len = shared_slots_count;
230 private_slots_len = private_slots_count;
231 static uint64_t tmp[MAX_BIND_SLOTS];
232 static uint64_t tmp1[MAX_BIND_SLOTS];
233 static uint64_t tmp2[MAX_BIND_SLOTS];
234 static uint64_t tmp3[MAX_BIND_SLOTS];
235
236 bound_shared_inums = tmp;
237 bound_shared_evnums = tmp1;
238
239 bound_private_inums = tmp2;
240 bound_private_evnums = tmp3;
241 for (int i = 0; i < shared_slots_count; i++) {
242 bound_shared_inums[i] = 0;
243 bound_shared_evnums[i] = 0;
244 }
245 for (int i = 0; i < private_slots_count; i++) {
246 bound_private_inums[i] = 0;
247 bound_private_evnums[i] = 0;
248 }
249}
250
251void release_full_slots(struct inputparameters inp, struct memmod *mmod)
252{
253 if ((!shared_slots_count)) {
254 if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
255 release_shared_slots(mmod, 1, true);
256 }
257 }
258
259 if ((!private_slots_count)) {
260 if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
261 release_private_slots(mmod, 1, true);
262 }
263 }
264}
265
mardyk017b51dbe2024-01-17 15:25:36 -0600266/*
267 * SDEI function called from fuzzer
268 */
Alex Liang0fa7d212024-06-18 11:17:01 -0500269void run_sdei_fuzz(int funcid, struct memmod *mmod, bool inrange, int cntid)
mardyk01f5b46352023-10-24 16:23:23 -0500270{
Alex Liang0fa7d212024-06-18 11:17:01 -0500271 #ifdef SMC_FUZZER_DEBUG
272 if (inrange) {
273 printf("%d\n", cntid);
274 }
275 #endif
mardyk01f5b46352023-10-24 16:23:23 -0500276
Alex Liang0fa7d212024-06-18 11:17:01 -0500277 if (cntid == 0 && CONSTRAIN_EVENTS) {
278 initalize_interrupt_slots(mmod);
279 }
280
281 #ifdef SMC_FUZZER_DEBUG
282 if (CONSTRAIN_EVENTS) {
283 printf("Bound priv inums: %llu, %llu, %llu\n", bound_private_inums[0], bound_private_inums[1], bound_private_inums[2]);
284 printf("Bound priv evnums: %llu, %llu, %llu\n", bound_private_evnums[0], bound_private_evnums[1], bound_private_evnums[2]);
285 printf("Bound shared inums: %llu, %llu, %llu\n", bound_shared_inums[0], bound_shared_inums[1], bound_shared_inums[2]);
286 printf("Bound shared evnums: %llu, %llu, %llu\n", bound_shared_evnums[0], bound_shared_evnums[1], bound_shared_evnums[2]);
287 printf("Shared slots left: %lld\n", shared_slots_count);
288 printf("Private slots left: %lld\n\n", private_slots_count);
289 }
290 #endif
291 if (funcid == sdei_version_funcid) {
292 long long ret;
293
294 if (inrange) {
295 ret = sdei_version();
296
297 if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
298 tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n", ret);
299 }
mardyk01f5b46352023-10-24 16:23:23 -0500300 }
mardyk017b51dbe2024-01-17 15:25:36 -0600301 } else if (funcid == sdei_pe_unmask_funcid) {
Alex Liang0fa7d212024-06-18 11:17:01 -0500302 if (inrange) {
303 tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmask");
304 }
mardyk017b51dbe2024-01-17 15:25:36 -0600305 } else if (funcid == sdei_pe_mask_funcid) {
Alex Liang0fa7d212024-06-18 11:17:01 -0500306 if (inrange) {
307 tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
308 }
Mark Dykes50297972024-03-15 12:49:22 -0500309 } else if (funcid == sdei_interrupt_bind_funcid) {
310 struct sdei_intr_ctx intr_ctx;
Mark Dykes50297972024-03-15 12:49:22 -0500311
Alex Liang0fa7d212024-06-18 11:17:01 -0500312 setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
313 SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
Mark Dykes50297972024-03-15 12:49:22 -0500314
Alex Liang0fa7d212024-06-18 11:17:01 -0500315 if (INTR_ASSERT) {
316 setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
317 SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
318 }
Mark Dykes50297972024-03-15 12:49:22 -0500319
Alex Liang0fa7d212024-06-18 11:17:01 -0500320 struct inputparameters inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
Mark Dykes50297972024-03-15 12:49:22 -0500321
Alex Liang0fa7d212024-06-18 11:17:01 -0500322 release_full_slots(inp, mmod);
323
324 if (inrange) {
325 stbev = sdei_interrupt_bind(inp.x1, &intr_ctx);
326 if (stbev < 0) {
327 tftf_testcase_printf("sdei_interrupt_bind failed: 0x%llx %d\n", inp.x1, stbev);
328 } else if (CONSTRAIN_EVENTS) {
329 bool duplicate = false;
330
331 if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
332
333 for (int i = 0; i < shared_slots_len; i++) {
334 if (bound_shared_inums[i] == inp.x1) {
335 duplicate = true;
336 }
337 }
338 if (!duplicate) {
339 shared_slots_count--;
340 bound_shared_inums[shared_slots_count] = inp.x1;
341 bound_shared_evnums[shared_slots_count] = stbev;
342 }
343
344 } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
345 for (int i = 0; i < private_slots_len; i++) {
346 if (bound_private_inums[i] == inp.x1) {
347 duplicate = true;
348 }
349 }
350 if (!duplicate) {
351 private_slots_count--;
352 bound_private_inums[private_slots_count] = inp.x1;
353 bound_private_evnums[private_slots_count] = stbev;
354 }
355 }
356 }
357
358 #ifdef SMC_FUZZER_DEBUG
359 printf("stbev is %d and interrupt number is %lld\n", stbev, inp.x1);
360 #endif
361 }
mardyk017b51dbe2024-01-17 15:25:36 -0600362 } else if (funcid == sdei_event_status_funcid) {
Alex Liang0fa7d212024-06-18 11:17:01 -0500363 struct inputparameters inp;
Mark Dykes50297972024-03-15 12:49:22 -0500364
Alex Liang0fa7d212024-06-18 11:17:01 -0500365 if (CONSTRAIN_EVENTS) {
366 bound_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
367 set_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
368 }
369 inp = generate_args(SDEI_EVENT_STATUS_CALL, SMC_FUZZ_SANITY_LEVEL);
370 int64_t ret;
371
372 if (inrange) {
373 ret = sdei_event_status(inp.x1);
374 if (ret < 0) {
375
376 tftf_testcase_printf("sdei_event_status failed: 0x%llx %d\n", ret, stbev);
377 } else {
378
379 }
Mark Dykes50297972024-03-15 12:49:22 -0500380 }
381
mardyk017b51dbe2024-01-17 15:25:36 -0600382 } else if (funcid == sdei_event_signal_funcid) {
Mark Dykes50297972024-03-15 12:49:22 -0500383
Alex Liang0fa7d212024-06-18 11:17:01 -0500384 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1,
385 SDEI_EVENT_SIGNAL_CALL_ARG2_PE, mmod, FUZZER_CONSTRAINT_ACCMODE);
386 struct inputparameters inp = generate_args(SDEI_EVENT_SIGNAL_CALL, SMC_FUZZ_SANITY_LEVEL);
387 int64_t ret;
388
389 if (inrange) {
390 ret = sdei_event_signal(inp.x2);
391 if (ret < 0) {
392 tftf_testcase_printf("sdei_event_signal failed: %lld\n", ret);
393 }
394 }
395 } else if (funcid == sdei_private_reset_funcid) {
396 if (inrange) {
397 tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");
398 }
399 } else if (funcid == sdei_shared_reset_funcid) {
400 int64_t ret = -1;
401
402 if (inrange) {
403 ret = tftf_test_sdei_noarg(sdei_shared_reset, "sdei_shared_reset");
404 }
405 if (ret == 0) {
406 release_shared_slots(mmod, private_slots_len, false);
407 release_private_slots(mmod, shared_slots_len, false);
Mark Dykes50297972024-03-15 12:49:22 -0500408 }
409
Alex Liang0fa7d212024-06-18 11:17:01 -0500410 } else if (funcid == sdei_event_register_funcid) {
411
412 if (CONSTRAIN_EVENTS) {
413 set_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
414 bound_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
415 }
416
417 register_handler();
418
419 uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
420
421 setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
422 setconstraint(FUZZER_CONSTRAINT_SVALUE, EV_COOKIE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG3_ARG, mmod, FUZZER_CONSTRAINT_EXCMODE);
423 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
424
425 struct inputparameters inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
426
427 int64_t ret;
428
429 if (inrange) {
430 ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
431 if (ret < 0) {
432 tftf_testcase_printf("sdei_event_register failed: 0x%llx\n", ret);
433 }
434 }
435
436
437 } else if (funcid == sdei_event_enable_funcid) {
438 struct inputparameters inp;
439
440
441 if (CONSTRAIN_EVENTS) {
442 set_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
443 bound_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
444 }
445
446 inp = generate_args(SDEI_EVENT_ENABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
447 int64_t ret;
448
449 if (inrange) {
450 ret = sdei_event_enable(inp.x1);
451 if (ret < 0) {
452 tftf_testcase_printf("sdei_event_enable failed: 0x%llx\n", ret);
453 }
454 }
455
456 } else if (funcid == sdei_event_disable_funcid) {
457 struct inputparameters inp;
458
459 if (CONSTRAIN_EVENTS) {
460 set_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
461 bound_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
462 }
463
464 inp = generate_args(SDEI_EVENT_DISABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
465
466 int64_t ret;
467
468 if (inrange) {
469 ret = sdei_event_disable(inp.x1);
470 if (ret < 0) {
471 tftf_testcase_printf("sdei_event_disable failed: 0x%llx\n", ret);
472 }
473 }
474
475 } else if (funcid == sdei_features_funcid) {
476 uint64_t feature_values[2] = {0, 1};
477
478 setconstraint(FUZZER_CONSTRAINT_RANGE, feature_values, 2, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
479 struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SANITY_LEVEL_3);
480
481 int64_t ret;
482
483 if (inrange) {
484 ret = sdei_features(inp.x1);
485 if (ret < 0) {
486 tftf_testcase_printf("sdei_features failed: 0x%llx\n", ret);
487 } else if ((ret >> 32) == 0) {
488 #ifdef SMC_FUZZER_DEBUG
489 printf("SUCCESS: sdei_features expected [63:32]\n");
490 printf("private event slots: %llx\n", (ret & 0xffffU));
491 printf("shared event slots: %llx\n", ((ret >> 16U) & 0xfffU));
492 #endif
493 }
494 }
495 } else if (funcid == sdei_event_unregister_funcid) {
496 struct inputparameters inp;
497
498 if (CONSTRAIN_EVENTS) {
499 set_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
500 bound_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
501 }
502
503 inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
504
505 int64_t ret;
506
507 if (inrange) {
508 ret = sdei_event_unregister(inp.x1);
509
510 if (ret < 0) {
511 tftf_testcase_printf("sdei_event_unregister failed: 0x%llx\n", ret);
512 }
513 }
514
515 } else if (funcid == sdei_event_context_funcid) {
516
517 uint64_t register_range[2] = {0, 17};
518
519 setconstraint(FUZZER_CONSTRAINT_RANGE, register_range, 2, SDEI_EVENT_CONTEXT_CALL_ARG1_PARAM, mmod, FUZZER_CONSTRAINT_ACCMODE);
520 struct inputparameters inp = generate_args(SDEI_EVENT_CONTEXT_CALL, SMC_FUZZ_SANITY_LEVEL);
521
522 int64_t ret;
523
524 if (inrange) {
525 ret = sdei_event_context(inp.x1);
526 if (ret < 0) {
527 tftf_testcase_printf("sdei_event_context failed: 0x%llx\n", ret);
528 }
529 }
530
531 } else if (funcid == sdei_event_complete_funcid) {
532
533 uint64_t status_codes[2] = {0, 1};
534
535 setconstraint(FUZZER_CONSTRAINT_RANGE, status_codes, 2, SDEI_EVENT_COMPLETE_CALL_ARG1_STAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
536
537 struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_CALL, SMC_FUZZ_SANITY_LEVEL);
538
539 int64_t ret;
540
541 if (inrange) {
542 ret = sdei_event_complete(inp.x1);
543 if (ret < 0) {
544 tftf_testcase_printf("sdei_event_complete failed: 0x%llx\n", ret);
545 }
546 }
547
548 } else if (funcid == sdei_event_complete_and_resume_funcid) {
549 struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_AND_RESUME_CALL, SMC_FUZZ_SANITY_LEVEL);
550
551 int64_t ret;
552
553 if (inrange) {
554 ret = sdei_event_complete_and_resume(inp.x1);
555 if (ret < 0) {
556 tftf_testcase_printf("sdei_event_complete_and_resume failed: 0x%llx\n", ret);
557 }
558 }
559
560 } else if (funcid == sdei_event_get_info_funcid) {
561 struct inputparameters inp;
562 uint64_t info_values[2] = {0, 4};
563
564 setconstraint(FUZZER_CONSTRAINT_RANGE, info_values, 2, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
565
566
567 if (CONSTRAIN_EVENTS) {
568 set_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
569 bound_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
570 }
571
572 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
573
574 int64_t ret;
575
576 if (inrange) {
577 ret = sdei_event_get_info(inp.x1, inp.x2);
578 if (ret < 0) {
579 tftf_testcase_printf("sdei_event_get_info failed: 0x%llx\n", ret);
580 }
581 }
582 } else if (funcid == sdei_event_routing_set_funcid) {
583 uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
584
Alex Liang1d40d722024-07-23 16:42:16 -0500585 setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_ROUTING_SET_CALL_ARG2_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
586 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG3_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
Alex Liang0fa7d212024-06-18 11:17:01 -0500587 struct inputparameters inp;
588
589 if (CONSTRAIN_EVENTS) {
590 set_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
591 bound_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
592 }
593
594 inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
595
596 int64_t ret;
597
598 if (inrange) {
599 ret = sdei_event_routing_set(inp.x1, inp.x2);
600 if (ret < 0) {
601 tftf_testcase_printf("sdei_event_routing_set failed: 0x%llx\n", ret);
602 }
603 }
604
605 } else if (funcid == sdei_interrupt_release_funcid) {
606 struct sdei_intr_ctx intr_ctx;
607
608 setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
609 SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
610 setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
611 SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
612
613 struct inputparameters inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
614
615 int64_t ret;
616
617 if (inrange) {
618 ret = sdei_interrupt_release(inp.x1, &intr_ctx);
619 if (ret < 0) {
620
621 tftf_testcase_printf("sdei_interrupt_release failed: 0x%llx\n", ret);
622 } else {
623 if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
624 release_shared_slots(mmod, 1, false);
625 } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
626 release_private_slots(mmod, 1, false);
627 }
628 }
629 }
630
631 } else if (funcid == sdei_routing_set_coverage_funcid) {
632 int64_t ret;
633 struct inputparameters inp;
634
635 uint64_t bind_slots[1] = {0};
636
637 setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
638 inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
639 int64_t slots = sdei_features(inp.x1);
640
641 print_return("features", slots);
642
643 // bind shared interrupt to create shared event
644 struct sdei_intr_ctx intr_ctx;
645 uint64_t inum_range[2] = { MIN_SPI_ID, U(255) };
646
647 setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
648 inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
649
650 release_full_slots(inp, mmod);
651
652
653 ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
654 if (ret < 0) {
655 return;
656 }
657
658 // register shared event
659 uint64_t evnum[1] = {ret};
660
661 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
662 setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
663 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
664 setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
665 inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
666 ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
667 print_return("register", ret);
668
669 uint64_t signal_info[1] = {0};
670
671 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
672 setconstraint(FUZZER_CONSTRAINT_SVALUE, signal_info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
673 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
674 ret = sdei_event_get_info(inp.x1, inp.x2);
675 print_return("get_info", ret);
676
677
678 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
Alex Liang1d40d722024-07-23 16:42:16 -0500679 setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG2_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
680 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG3_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
Alex Liang0fa7d212024-06-18 11:17:01 -0500681 inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
682 ret = sdei_event_routing_set(inp.x1, inp.x2);
683 print_return("routing_set", ret);
684
685 // unregister
686 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
687 inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
688 ret = sdei_event_unregister(inp.x1);
689 print_return("unregister", ret);
690
691 // release
692 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
693 inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
694 sdei_interrupt_release(inp.x1, &intr_ctx);
695 print_return("release", ret);
696
697 if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
698 release_shared_slots(mmod, 1, false);
699 } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
700 release_private_slots(mmod, 1, false);
701 }
702
703 } else if (funcid == sdei_event_get_info_coverage_funcid) {
704 int64_t ret;
705 struct inputparameters inp;
706 uint64_t info[1];
707
708 // bind shared interrupt to create shared event
709 struct sdei_intr_ctx intr_ctx;
710 uint64_t inum_range[2] = { MIN_SPI_ID, U(255)};
711
712 setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
713 inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
714
715 release_full_slots(inp, mmod);
716
717 ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
718
719 if (ret < 0) {
720 return;
721 }
722
723 uint64_t evnum[1] = {ret};
724
725 // event type
726 info[0] = 0;
727 setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
728 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
729 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
730 ret = sdei_event_get_info(inp.x1, inp.x2);
731 print_return("get info", ret);
732
733 // event signalable
734 info[0] = 1;
735 setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
736 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
737 ret = sdei_event_get_info(inp.x1, inp.x2);
738 print_return("get info", ret);
739
740 // event priority
741 printf("priority\n");
742 info[0] = 2;
743 setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
744 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
745 ret = sdei_event_get_info(inp.x1, inp.x2);
746 print_return("get info", ret);
747
748 // register event
749 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
750 setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
751 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
752 setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
753 inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
754 ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
755 print_return("register", ret);
756
757 // event routing mode
758 info[0] = 3;
759 setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
760 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
761 ret = sdei_event_get_info(inp.x1, inp.x2);
762 print_return("get info", ret);
763
764 // event affinity
765 info[0] = 4;
766 setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
767 inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
768 ret = sdei_event_get_info(inp.x1, inp.x2);
769 print_return("get info", ret);
770
771 // unregister
772 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
773 inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
774 ret = sdei_event_unregister(inp.x1);
775 print_return("unregister", ret);
776
777 // release
778 setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
779 inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
780 ret = sdei_interrupt_release(inp.x1, &intr_ctx);
781 print_return("release", ret);
782
783 if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
784 release_shared_slots(mmod, 1, false);
785 } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
786 release_private_slots(mmod, 1, false);
787 }
mardyk01f5b46352023-10-24 16:23:23 -0500788 }
789}
Mark Dykes2b6c1402025-03-06 10:01:19 -0600790
791#endif