22
22
23
23
#define GICR_TYPER 0x8
24
24
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
+
25
28
struct vm_gic {
26
29
struct kvm_vm * vm ;
27
30
int gic_fd ;
@@ -30,8 +33,8 @@ struct vm_gic {
30
33
static int max_ipa_bits ;
31
34
32
35
/* 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 )
35
38
{
36
39
uint64_t attr = REG_OFFSET (vcpu , offset );
37
40
@@ -58,7 +61,7 @@ static int run_vcpu(struct kvm_vm *vm, uint32_t vcpuid)
58
61
return 0 ;
59
62
}
60
63
61
- static struct vm_gic vm_gic_create (void )
64
+ static struct vm_gic vm_gic_v3_create (void )
62
65
{
63
66
struct vm_gic v ;
64
67
@@ -80,7 +83,7 @@ static void vm_gic_destroy(struct vm_gic *v)
80
83
* device gets created, a legacy RDIST region is set at @0x0
81
84
* and a DIST region is set @0x60000
82
85
*/
83
- static void subtest_dist_rdist (struct vm_gic * v )
86
+ static void subtest_v3_dist_rdist (struct vm_gic * v )
84
87
{
85
88
int ret ;
86
89
uint64_t addr ;
@@ -145,7 +148,7 @@ static void subtest_dist_rdist(struct vm_gic *v)
145
148
}
146
149
147
150
/* 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 )
149
152
{
150
153
uint64_t addr , expected_addr ;
151
154
int ret ;
@@ -249,15 +252,15 @@ static void subtest_redist_regions(struct vm_gic *v)
249
252
* VGIC KVM device is created and initialized before the secondary CPUs
250
253
* get created
251
254
*/
252
- static void test_vgic_then_vcpus ( void )
255
+ static void test_v3_vgic_then_vcpus ( uint32_t gic_dev_type )
253
256
{
254
257
struct vm_gic v ;
255
258
int ret , i ;
256
259
257
260
v .vm = vm_create_default (0 , 0 , guest_code );
258
261
v .gic_fd = kvm_create_device (v .vm , KVM_DEV_TYPE_ARM_VGIC_V3 , false);
259
262
260
- subtest_dist_rdist (& v );
263
+ subtest_v3_dist_rdist (& v );
261
264
262
265
/* Add the rest of the VCPUs */
263
266
for (i = 1 ; i < NR_VCPUS ; ++ i )
@@ -270,30 +273,30 @@ static void test_vgic_then_vcpus(void)
270
273
}
271
274
272
275
/* 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 )
274
277
{
275
278
struct vm_gic v ;
276
279
int ret ;
277
280
278
- v = vm_gic_create ();
281
+ v = vm_gic_v3_create ();
279
282
280
- subtest_dist_rdist (& v );
283
+ subtest_v3_dist_rdist (& v );
281
284
282
285
ret = run_vcpu (v .vm , 3 );
283
286
TEST_ASSERT (ret == - EINVAL , "dist/rdist overlap detected on 1st vcpu run" );
284
287
285
288
vm_gic_destroy (& v );
286
289
}
287
290
288
- static void test_new_redist_regions (void )
291
+ static void test_v3_new_redist_regions (void )
289
292
{
290
293
void * dummy = NULL ;
291
294
struct vm_gic v ;
292
295
uint64_t addr ;
293
296
int ret ;
294
297
295
- v = vm_gic_create ();
296
- subtest_redist_regions (& v );
298
+ v = vm_gic_v3_create ();
299
+ subtest_v3_redist_regions (& v );
297
300
kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_CTRL ,
298
301
KVM_DEV_ARM_VGIC_CTRL_INIT , NULL , true);
299
302
@@ -303,8 +306,8 @@ static void test_new_redist_regions(void)
303
306
304
307
/* step2 */
305
308
306
- v = vm_gic_create ();
307
- subtest_redist_regions (& v );
309
+ v = vm_gic_v3_create ();
310
+ subtest_v3_redist_regions (& v );
308
311
309
312
addr = REDIST_REGION_ATTR_ADDR (1 , 0x280000 , 0 , 2 );
310
313
kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
@@ -317,8 +320,8 @@ static void test_new_redist_regions(void)
317
320
318
321
/* step 3 */
319
322
320
- v = vm_gic_create ();
321
- subtest_redist_regions (& v );
323
+ v = vm_gic_v3_create ();
324
+ subtest_v3_redist_regions (& v );
322
325
323
326
_kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
324
327
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION , dummy , true);
@@ -338,7 +341,7 @@ static void test_new_redist_regions(void)
338
341
vm_gic_destroy (& v );
339
342
}
340
343
341
- static void test_typer_accesses (void )
344
+ static void test_v3_typer_accesses (void )
342
345
{
343
346
struct vm_gic v ;
344
347
uint64_t addr ;
@@ -351,12 +354,12 @@ static void test_typer_accesses(void)
351
354
352
355
vm_vcpu_add_default (v .vm , 3 , guest_code );
353
356
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);
355
358
TEST_ASSERT (ret && errno == EINVAL , "attempting to read GICR_TYPER of non created vcpu" );
356
359
357
360
vm_vcpu_add_default (v .vm , 1 , guest_code );
358
361
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);
360
363
TEST_ASSERT (ret && errno == EBUSY , "read GICR_TYPER before GIC initialized" );
361
364
362
365
vm_vcpu_add_default (v .vm , 2 , guest_code );
@@ -365,7 +368,7 @@ static void test_typer_accesses(void)
365
368
KVM_DEV_ARM_VGIC_CTRL_INIT , NULL , true);
366
369
367
370
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);
369
372
TEST_ASSERT (!ret && !val , "read GICR_TYPER before rdist region setting" );
370
373
}
371
374
@@ -374,33 +377,33 @@ static void test_typer_accesses(void)
374
377
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION , & addr , true);
375
378
376
379
/* 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);
378
381
TEST_ASSERT (!ret && !val , "read typer of rdist #0" );
379
382
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);
381
384
TEST_ASSERT (!ret && val == 0x310 , "read typer of rdist #1" );
382
385
383
386
addr = REDIST_REGION_ATTR_ADDR (10 , 0x100000 , 0 , 1 );
384
387
ret = _kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
385
388
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION , & addr , true);
386
389
TEST_ASSERT (ret && errno == EINVAL , "collision with previous rdist region" );
387
390
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);
389
392
TEST_ASSERT (!ret && val == 0x100 ,
390
393
"no redist region attached to vcpu #1 yet, last cannot be returned" );
391
394
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);
393
396
TEST_ASSERT (!ret && val == 0x200 ,
394
397
"no redist region attached to vcpu #2, last cannot be returned" );
395
398
396
399
addr = REDIST_REGION_ATTR_ADDR (10 , 0x20000 , 0 , 1 );
397
400
kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
398
401
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION , & addr , true);
399
402
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);
401
404
TEST_ASSERT (!ret && val == 0x100 , "read typer of rdist #1" );
402
405
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);
404
407
TEST_ASSERT (!ret && val == 0x210 ,
405
408
"read typer of rdist #1, last properly returned" );
406
409
@@ -417,7 +420,7 @@ static void test_typer_accesses(void)
417
420
* rdist region #2 @0x200000 2 rdist capacity
418
421
* rdists: 1, 2
419
422
*/
420
- static void test_last_bit_redist_regions (void )
423
+ static void test_v3_last_bit_redist_regions (void )
421
424
{
422
425
uint32_t vcpuids [] = { 0 , 3 , 5 , 4 , 1 , 2 };
423
426
struct vm_gic v ;
@@ -444,29 +447,29 @@ static void test_last_bit_redist_regions(void)
444
447
kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
445
448
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION , & addr , true);
446
449
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);
448
451
TEST_ASSERT (!ret && val == 0x000 , "read typer of rdist #0" );
449
452
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);
451
454
TEST_ASSERT (!ret && val == 0x100 , "read typer of rdist #1" );
452
455
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);
454
457
TEST_ASSERT (!ret && val == 0x200 , "read typer of rdist #2" );
455
458
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);
457
460
TEST_ASSERT (!ret && val == 0x310 , "read typer of rdist #3" );
458
461
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);
460
463
TEST_ASSERT (!ret && val == 0x500 , "read typer of rdist #5" );
461
464
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);
463
466
TEST_ASSERT (!ret && val == 0x410 , "read typer of rdist #4" );
464
467
465
468
vm_gic_destroy (& v );
466
469
}
467
470
468
471
/* 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 )
470
473
{
471
474
uint32_t vcpuids [] = { 0 , 3 , 5 , 4 , 1 , 2 };
472
475
struct vm_gic v ;
@@ -485,67 +488,98 @@ static void test_last_bit_single_rdist(void)
485
488
kvm_device_access (v .gic_fd , KVM_DEV_ARM_VGIC_GRP_ADDR ,
486
489
KVM_VGIC_V3_ADDR_TYPE_REDIST , & addr , true);
487
490
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);
489
492
TEST_ASSERT (!ret && val == 0x000 , "read typer of rdist #0" );
490
493
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);
492
495
TEST_ASSERT (!ret && val == 0x300 , "read typer of rdist #1" );
493
496
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);
495
498
TEST_ASSERT (!ret && val == 0x500 , "read typer of rdist #2" );
496
499
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);
498
501
TEST_ASSERT (!ret && val == 0x100 , "read typer of rdist #3" );
499
502
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);
501
504
TEST_ASSERT (!ret && val == 0x210 , "read typer of rdist #3" );
502
505
503
506
vm_gic_destroy (& v );
504
507
}
505
508
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 )
507
513
{
508
514
struct vm_gic v ;
509
515
int ret , fd ;
516
+ uint32_t other ;
510
517
511
518
v .vm = vm_create_default_with_vcpus (NR_VCPUS , 0 , 0 , guest_code , NULL );
512
519
513
520
/* try to create a non existing KVM device */
514
521
ret = _kvm_create_device (v .vm , 0 , true, & fd );
515
522
TEST_ASSERT (ret && errno == ENODEV , "unsupported device" );
516
523
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" );
524
532
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);
527
534
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 ;
529
538
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" );
533
543
}
534
544
535
545
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
+ }
536
560
}
537
561
538
562
int main (int ac , char * * av )
539
563
{
564
+ int ret ;
565
+
540
566
max_ipa_bits = kvm_check_cap (KVM_CAP_ARM_VM_IPA_SIZE );
541
567
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
+ }
549
581
582
+ print_skip ("No GICv2 nor GICv3 support" );
583
+ exit (KSFT_SKIP );
550
584
return 0 ;
551
585
}
0 commit comments