Skip to content

Commit 3f4db37

Browse files
Ricardo KollerMarc Zyngier
authored andcommitted
KVM: arm64: selftests: Make vgic_init gic version agnostic
As a preparation for the next commits which will add some tests for GICv2, make aarch64/vgic_init GIC version agnostic. Add a new generic run_tests function(gic_dev_type) that starts all applicable tests using GICv3 or GICv2. GICv2 tests are attempted if GICv3 is not available in the system. There are currently no GICv2 tests, but the test passes now in GICv2 systems. Reviewed-by: Eric Auger <[email protected]> Signed-off-by: Ricardo Koller <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 96e9038 commit 3f4db37

File tree

1 file changed

+95
-61
lines changed

1 file changed

+95
-61
lines changed

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

Lines changed: 95 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
#define GICR_TYPER 0x8
2424

25+
#define VGIC_DEV_IS_V2(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V2)
26+
#define VGIC_DEV_IS_V3(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V3)
27+
2528
struct vm_gic {
2629
struct kvm_vm *vm;
2730
int gic_fd;
@@ -30,8 +33,8 @@ struct vm_gic {
3033
static int max_ipa_bits;
3134

3235
/* helper to access a redistributor register */
33-
static int access_redist_reg(int gicv3_fd, int vcpu, int offset,
34-
uint32_t *val, bool write)
36+
static int access_v3_redist_reg(int gicv3_fd, int vcpu, int offset,
37+
uint32_t *val, bool write)
3538
{
3639
uint64_t attr = REG_OFFSET(vcpu, offset);
3740

@@ -58,7 +61,7 @@ static int run_vcpu(struct kvm_vm *vm, uint32_t vcpuid)
5861
return 0;
5962
}
6063

61-
static struct vm_gic vm_gic_create(void)
64+
static struct vm_gic vm_gic_v3_create(void)
6265
{
6366
struct vm_gic v;
6467

@@ -80,7 +83,7 @@ static void vm_gic_destroy(struct vm_gic *v)
8083
* device gets created, a legacy RDIST region is set at @0x0
8184
* and a DIST region is set @0x60000
8285
*/
83-
static void subtest_dist_rdist(struct vm_gic *v)
86+
static void subtest_v3_dist_rdist(struct vm_gic *v)
8487
{
8588
int ret;
8689
uint64_t addr;
@@ -145,7 +148,7 @@ static void subtest_dist_rdist(struct vm_gic *v)
145148
}
146149

147150
/* Test the new REDIST region API */
148-
static void subtest_redist_regions(struct vm_gic *v)
151+
static void subtest_v3_redist_regions(struct vm_gic *v)
149152
{
150153
uint64_t addr, expected_addr;
151154
int ret;
@@ -249,15 +252,15 @@ static void subtest_redist_regions(struct vm_gic *v)
249252
* VGIC KVM device is created and initialized before the secondary CPUs
250253
* get created
251254
*/
252-
static void test_vgic_then_vcpus(void)
255+
static void test_v3_vgic_then_vcpus(uint32_t gic_dev_type)
253256
{
254257
struct vm_gic v;
255258
int ret, i;
256259

257260
v.vm = vm_create_default(0, 0, guest_code);
258261
v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
259262

260-
subtest_dist_rdist(&v);
263+
subtest_v3_dist_rdist(&v);
261264

262265
/* Add the rest of the VCPUs */
263266
for (i = 1; i < NR_VCPUS; ++i)
@@ -270,30 +273,30 @@ static void test_vgic_then_vcpus(void)
270273
}
271274

272275
/* All the VCPUs are created before the VGIC KVM device gets initialized */
273-
static void test_vcpus_then_vgic(void)
276+
static void test_v3_vcpus_then_vgic(uint32_t gic_dev_type)
274277
{
275278
struct vm_gic v;
276279
int ret;
277280

278-
v = vm_gic_create();
281+
v = vm_gic_v3_create();
279282

280-
subtest_dist_rdist(&v);
283+
subtest_v3_dist_rdist(&v);
281284

282285
ret = run_vcpu(v.vm, 3);
283286
TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
284287

285288
vm_gic_destroy(&v);
286289
}
287290

288-
static void test_new_redist_regions(void)
291+
static void test_v3_new_redist_regions(void)
289292
{
290293
void *dummy = NULL;
291294
struct vm_gic v;
292295
uint64_t addr;
293296
int ret;
294297

295-
v = vm_gic_create();
296-
subtest_redist_regions(&v);
298+
v = vm_gic_v3_create();
299+
subtest_v3_redist_regions(&v);
297300
kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
298301
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
299302

@@ -303,8 +306,8 @@ static void test_new_redist_regions(void)
303306

304307
/* step2 */
305308

306-
v = vm_gic_create();
307-
subtest_redist_regions(&v);
309+
v = vm_gic_v3_create();
310+
subtest_v3_redist_regions(&v);
308311

309312
addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
310313
kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -317,8 +320,8 @@ static void test_new_redist_regions(void)
317320

318321
/* step 3 */
319322

320-
v = vm_gic_create();
321-
subtest_redist_regions(&v);
323+
v = vm_gic_v3_create();
324+
subtest_v3_redist_regions(&v);
322325

323326
_kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
324327
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, dummy, true);
@@ -338,7 +341,7 @@ static void test_new_redist_regions(void)
338341
vm_gic_destroy(&v);
339342
}
340343

341-
static void test_typer_accesses(void)
344+
static void test_v3_typer_accesses(void)
342345
{
343346
struct vm_gic v;
344347
uint64_t addr;
@@ -351,12 +354,12 @@ static void test_typer_accesses(void)
351354

352355
vm_vcpu_add_default(v.vm, 3, guest_code);
353356

354-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
357+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
355358
TEST_ASSERT(ret && errno == EINVAL, "attempting to read GICR_TYPER of non created vcpu");
356359

357360
vm_vcpu_add_default(v.vm, 1, guest_code);
358361

359-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
362+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
360363
TEST_ASSERT(ret && errno == EBUSY, "read GICR_TYPER before GIC initialized");
361364

362365
vm_vcpu_add_default(v.vm, 2, guest_code);
@@ -365,7 +368,7 @@ static void test_typer_accesses(void)
365368
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
366369

367370
for (i = 0; i < NR_VCPUS ; i++) {
368-
ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
371+
ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
369372
TEST_ASSERT(!ret && !val, "read GICR_TYPER before rdist region setting");
370373
}
371374

@@ -374,33 +377,33 @@ static void test_typer_accesses(void)
374377
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
375378

376379
/* The 2 first rdists should be put there (vcpu 0 and 3) */
377-
ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
380+
ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
378381
TEST_ASSERT(!ret && !val, "read typer of rdist #0");
379382

380-
ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
383+
ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
381384
TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #1");
382385

383386
addr = REDIST_REGION_ATTR_ADDR(10, 0x100000, 0, 1);
384387
ret = _kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
385388
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
386389
TEST_ASSERT(ret && errno == EINVAL, "collision with previous rdist region");
387390

388-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
391+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
389392
TEST_ASSERT(!ret && val == 0x100,
390393
"no redist region attached to vcpu #1 yet, last cannot be returned");
391394

392-
ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
395+
ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
393396
TEST_ASSERT(!ret && val == 0x200,
394397
"no redist region attached to vcpu #2, last cannot be returned");
395398

396399
addr = REDIST_REGION_ATTR_ADDR(10, 0x20000, 0, 1);
397400
kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
398401
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
399402

400-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
403+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
401404
TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
402405

403-
ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
406+
ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
404407
TEST_ASSERT(!ret && val == 0x210,
405408
"read typer of rdist #1, last properly returned");
406409

@@ -417,7 +420,7 @@ static void test_typer_accesses(void)
417420
* rdist region #2 @0x200000 2 rdist capacity
418421
* rdists: 1, 2
419422
*/
420-
static void test_last_bit_redist_regions(void)
423+
static void test_v3_last_bit_redist_regions(void)
421424
{
422425
uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
423426
struct vm_gic v;
@@ -444,29 +447,29 @@ static void test_last_bit_redist_regions(void)
444447
kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
445448
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
446449

447-
ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
450+
ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
448451
TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
449452

450-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
453+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
451454
TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
452455

453-
ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
456+
ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
454457
TEST_ASSERT(!ret && val == 0x200, "read typer of rdist #2");
455458

456-
ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
459+
ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
457460
TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #3");
458461

459-
ret = access_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
462+
ret = access_v3_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
460463
TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #5");
461464

462-
ret = access_redist_reg(v.gic_fd, 4, GICR_TYPER, &val, false);
465+
ret = access_v3_redist_reg(v.gic_fd, 4, GICR_TYPER, &val, false);
463466
TEST_ASSERT(!ret && val == 0x410, "read typer of rdist #4");
464467

465468
vm_gic_destroy(&v);
466469
}
467470

468471
/* Test last bit with legacy region */
469-
static void test_last_bit_single_rdist(void)
472+
static void test_v3_last_bit_single_rdist(void)
470473
{
471474
uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
472475
struct vm_gic v;
@@ -485,67 +488,98 @@ static void test_last_bit_single_rdist(void)
485488
kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
486489
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
487490

488-
ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
491+
ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
489492
TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
490493

491-
ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
494+
ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
492495
TEST_ASSERT(!ret && val == 0x300, "read typer of rdist #1");
493496

494-
ret = access_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
497+
ret = access_v3_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
495498
TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #2");
496499

497-
ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
500+
ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
498501
TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #3");
499502

500-
ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
503+
ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
501504
TEST_ASSERT(!ret && val == 0x210, "read typer of rdist #3");
502505

503506
vm_gic_destroy(&v);
504507
}
505508

506-
void test_kvm_device(void)
509+
/*
510+
* Returns 0 if it's possible to create GIC device of a given type (V2 or V3).
511+
*/
512+
int test_kvm_device(uint32_t gic_dev_type)
507513
{
508514
struct vm_gic v;
509515
int ret, fd;
516+
uint32_t other;
510517

511518
v.vm = vm_create_default_with_vcpus(NR_VCPUS, 0, 0, guest_code, NULL);
512519

513520
/* try to create a non existing KVM device */
514521
ret = _kvm_create_device(v.vm, 0, true, &fd);
515522
TEST_ASSERT(ret && errno == ENODEV, "unsupported device");
516523

517-
/* trial mode with VGIC_V3 device */
518-
ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, true, &fd);
519-
if (ret) {
520-
print_skip("GICv3 not supported");
521-
exit(KSFT_SKIP);
522-
}
523-
v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
524+
/* trial mode */
525+
ret = _kvm_create_device(v.vm, gic_dev_type, true, &fd);
526+
if (ret)
527+
return ret;
528+
v.gic_fd = kvm_create_device(v.vm, gic_dev_type, false);
529+
530+
ret = _kvm_create_device(v.vm, gic_dev_type, false, &fd);
531+
TEST_ASSERT(ret && errno == EEXIST, "create GIC device twice");
524532

525-
ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false, &fd);
526-
TEST_ASSERT(ret && errno == EEXIST, "create GICv3 device twice");
533+
kvm_create_device(v.vm, gic_dev_type, true);
527534

528-
kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
535+
/* try to create the other gic_dev_type */
536+
other = VGIC_DEV_IS_V2(gic_dev_type) ? KVM_DEV_TYPE_ARM_VGIC_V3
537+
: KVM_DEV_TYPE_ARM_VGIC_V2;
529538

530-
if (!_kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V2, true, &fd)) {
531-
ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V2, false, &fd);
532-
TEST_ASSERT(ret && errno == EINVAL, "create GICv2 while v3 exists");
539+
if (!_kvm_create_device(v.vm, other, true, &fd)) {
540+
ret = _kvm_create_device(v.vm, other, false, &fd);
541+
TEST_ASSERT(ret && errno == EINVAL,
542+
"create GIC device while other version exists");
533543
}
534544

535545
vm_gic_destroy(&v);
546+
547+
return 0;
548+
}
549+
550+
void run_tests(uint32_t gic_dev_type)
551+
{
552+
if (VGIC_DEV_IS_V3(gic_dev_type)) {
553+
test_v3_vcpus_then_vgic(gic_dev_type);
554+
test_v3_vgic_then_vcpus(gic_dev_type);
555+
test_v3_new_redist_regions();
556+
test_v3_typer_accesses();
557+
test_v3_last_bit_redist_regions();
558+
test_v3_last_bit_single_rdist();
559+
}
536560
}
537561

538562
int main(int ac, char **av)
539563
{
564+
int ret;
565+
540566
max_ipa_bits = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
541567

542-
test_kvm_device();
543-
test_vcpus_then_vgic();
544-
test_vgic_then_vcpus();
545-
test_new_redist_regions();
546-
test_typer_accesses();
547-
test_last_bit_redist_regions();
548-
test_last_bit_single_rdist();
568+
ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V3);
569+
if (!ret) {
570+
pr_info("Running GIC_v3 tests.\n");
571+
run_tests(KVM_DEV_TYPE_ARM_VGIC_V3);
572+
return 0;
573+
}
574+
575+
ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V2);
576+
if (!ret) {
577+
pr_info("Running GIC_v2 tests.\n");
578+
run_tests(KVM_DEV_TYPE_ARM_VGIC_V2);
579+
return 0;
580+
}
549581

582+
print_skip("No GICv2 nor GICv3 support");
583+
exit(KSFT_SKIP);
550584
return 0;
551585
}

0 commit comments

Comments
 (0)