Skip to content

Commit 8a35b28

Browse files
Ricardo KollerMarc Zyngier
authored andcommitted
KVM: selftests: aarch64: Cmdline arg to set EOI mode in vgic_irq
Add a new cmdline arg to set the EOI mode for all vgic_irq tests. This specifies whether a write to EOIR will deactivate IRQs or not. Signed-off-by: Ricardo Koller <[email protected]> Acked-by: Andrew Jones <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e5410ee commit 8a35b28

File tree

1 file changed

+50
-8
lines changed

1 file changed

+50
-8
lines changed

tools/testing/selftests/kvm/aarch64/vgic_irq.c

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
*/
3030
struct test_args {
3131
uint32_t nr_irqs; /* number of KVM supported IRQs. */
32+
bool eoi_split; /* 1 is eoir+dir, 0 is eoir only */
3233
};
3334

3435
/*
@@ -112,7 +113,7 @@ static uint64_t gic_read_ap1r0(void)
112113
return reg;
113114
}
114115

115-
static void guest_irq_handler(struct ex_regs *regs)
116+
static void guest_irq_generic_handler(bool eoi_split)
116117
{
117118
uint32_t intid = gic_get_and_ack_irq();
118119

@@ -129,6 +130,8 @@ static void guest_irq_handler(struct ex_regs *regs)
129130

130131
gic_set_eoi(intid);
131132
GUEST_ASSERT_EQ(gic_read_ap1r0(), 0);
133+
if (eoi_split)
134+
gic_set_dir(intid);
132135

133136
GUEST_ASSERT(!gic_irq_get_active(intid));
134137
GUEST_ASSERT(!gic_irq_get_pending(intid));
@@ -151,6 +154,24 @@ do { \
151154
GUEST_ASSERT(_intid == 0 || _intid == IAR_SPURIOUS); \
152155
} while (0)
153156

157+
#define CAT_HELPER(a, b) a ## b
158+
#define CAT(a, b) CAT_HELPER(a, b)
159+
#define PREFIX guest_irq_handler_
160+
#define GUEST_IRQ_HANDLER_NAME(split) CAT(PREFIX, split)
161+
#define GENERATE_GUEST_IRQ_HANDLER(split) \
162+
static void CAT(PREFIX, split)(struct ex_regs *regs) \
163+
{ \
164+
guest_irq_generic_handler(split); \
165+
}
166+
167+
GENERATE_GUEST_IRQ_HANDLER(0);
168+
GENERATE_GUEST_IRQ_HANDLER(1);
169+
170+
static void (*guest_irq_handlers[2])(struct ex_regs *) = {
171+
GUEST_IRQ_HANDLER_NAME(0),
172+
GUEST_IRQ_HANDLER_NAME(1),
173+
};
174+
154175
static void reset_priorities(struct test_args *args)
155176
{
156177
int i;
@@ -220,6 +241,8 @@ static void guest_code(struct test_args args)
220241
for (i = 0; i < nr_irqs; i++)
221242
gic_irq_enable(i);
222243

244+
gic_set_eoi_split(args.eoi_split);
245+
223246
reset_priorities(&args);
224247
gic_set_priority_mask(CPU_PRIO_MASK);
225248

@@ -268,10 +291,11 @@ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc,
268291

269292
static void print_args(struct test_args *args)
270293
{
271-
printf("nr-irqs=%d\n", args->nr_irqs);
294+
printf("nr-irqs=%d eoi-split=%d\n",
295+
args->nr_irqs, args->eoi_split);
272296
}
273297

274-
static void test_vgic(uint32_t nr_irqs)
298+
static void test_vgic(uint32_t nr_irqs, bool eoi_split)
275299
{
276300
struct ucall uc;
277301
int gic_fd;
@@ -280,6 +304,7 @@ static void test_vgic(uint32_t nr_irqs)
280304

281305
struct test_args args = {
282306
.nr_irqs = nr_irqs,
307+
.eoi_split = eoi_split,
283308
};
284309

285310
print_args(&args);
@@ -297,7 +322,7 @@ static void test_vgic(uint32_t nr_irqs)
297322
GICD_BASE_GPA, GICR_BASE_GPA);
298323

299324
vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
300-
guest_irq_handler);
325+
guest_irq_handlers[args.eoi_split]);
301326

302327
while (1) {
303328
vcpu_run(vm, VCPU_ID);
@@ -328,35 +353,52 @@ static void help(const char *name)
328353
{
329354
printf(
330355
"\n"
331-
"usage: %s [-n num_irqs]\n", name);
332-
printf(" -n: specify the number of IRQs to configure the vgic with.\n");
356+
"usage: %s [-n num_irqs] [-e eoi_split]\n", name);
357+
printf(" -n: specify the number of IRQs to configure the vgic with. "
358+
"It has to be a multiple of 32 and between 64 and 1024.\n");
359+
printf(" -e: if 1 then EOI is split into a write to DIR on top "
360+
"of writing EOI.\n");
333361
puts("");
334362
exit(1);
335363
}
336364

337365
int main(int argc, char **argv)
338366
{
339367
uint32_t nr_irqs = 64;
368+
bool default_args = true;
340369
int opt;
370+
bool eoi_split = false;
341371

342372
/* Tell stdout not to buffer its content */
343373
setbuf(stdout, NULL);
344374

345-
while ((opt = getopt(argc, argv, "hg:n:")) != -1) {
375+
while ((opt = getopt(argc, argv, "hn:e:")) != -1) {
346376
switch (opt) {
347377
case 'n':
348378
nr_irqs = atoi(optarg);
349379
if (nr_irqs > 1024 || nr_irqs % 32)
350380
help(argv[0]);
351381
break;
382+
case 'e':
383+
eoi_split = (bool)atoi(optarg);
384+
default_args = false;
385+
break;
352386
case 'h':
353387
default:
354388
help(argv[0]);
355389
break;
356390
}
357391
}
358392

359-
test_vgic(nr_irqs);
393+
/* If the user just specified nr_irqs and/or gic_version, then run all
394+
* combinations.
395+
*/
396+
if (default_args) {
397+
test_vgic(nr_irqs, false /* eoi_split */);
398+
test_vgic(nr_irqs, true /* eoi_split */);
399+
} else {
400+
test_vgic(nr_irqs, eoi_split);
401+
}
360402

361403
return 0;
362404
}

0 commit comments

Comments
 (0)