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