@@ -457,6 +457,53 @@ static void test_guest_reg_read(struct kvm_vcpu *vcpu)
457
457
}
458
458
}
459
459
460
+ /* Politely lifted from arch/arm64/include/asm/cache.h */
461
+ /* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
462
+ #define CLIDR_CTYPE_SHIFT (level ) (3 * (level - 1))
463
+ #define CLIDR_CTYPE_MASK (level ) (7 << CLIDR_CTYPE_SHIFT(level))
464
+ #define CLIDR_CTYPE (clidr , level ) \
465
+ (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level))
466
+
467
+ static void test_clidr (struct kvm_vcpu * vcpu )
468
+ {
469
+ uint64_t clidr ;
470
+ int level ;
471
+
472
+ vcpu_get_reg (vcpu , KVM_ARM64_SYS_REG (SYS_CLIDR_EL1 ), & clidr );
473
+
474
+ /* find the first empty level in the cache hierarchy */
475
+ for (level = 1 ; level < 7 ; level ++ ) {
476
+ if (!CLIDR_CTYPE (clidr , level ))
477
+ break ;
478
+ }
479
+
480
+ /*
481
+ * If you have a mind-boggling 7 levels of cache, congratulations, you
482
+ * get to fix this.
483
+ */
484
+ TEST_ASSERT (level <= 7 , "can't find an empty level in cache hierarchy" );
485
+
486
+ /* stick in a unified cache level */
487
+ clidr |= BIT (2 ) << CLIDR_CTYPE_SHIFT (level );
488
+
489
+ vcpu_set_reg (vcpu , KVM_ARM64_SYS_REG (SYS_CLIDR_EL1 ), clidr );
490
+ test_reg_vals [encoding_to_range_idx (SYS_CLIDR_EL1 )] = clidr ;
491
+ }
492
+
493
+ static void test_vcpu_ftr_id_regs (struct kvm_vcpu * vcpu )
494
+ {
495
+ u64 val ;
496
+
497
+ test_clidr (vcpu );
498
+
499
+ vcpu_get_reg (vcpu , KVM_ARM64_SYS_REG (SYS_MPIDR_EL1 ), & val );
500
+ val ++ ;
501
+ vcpu_set_reg (vcpu , KVM_ARM64_SYS_REG (SYS_MPIDR_EL1 ), val );
502
+
503
+ test_reg_vals [encoding_to_range_idx (SYS_MPIDR_EL1 )] = val ;
504
+ ksft_test_result_pass ("%s\n" , __func__ );
505
+ }
506
+
460
507
static void test_assert_id_reg_unchanged (struct kvm_vcpu * vcpu , uint32_t encoding )
461
508
{
462
509
size_t idx = encoding_to_range_idx (encoding );
@@ -477,6 +524,8 @@ static void test_reset_preserves_id_regs(struct kvm_vcpu *vcpu)
477
524
for (int i = 0 ; i < ARRAY_SIZE (test_regs ); i ++ )
478
525
test_assert_id_reg_unchanged (vcpu , test_regs [i ].reg );
479
526
527
+ test_assert_id_reg_unchanged (vcpu , SYS_CLIDR_EL1 );
528
+
480
529
ksft_test_result_pass ("%s\n" , __func__ );
481
530
}
482
531
@@ -504,11 +553,13 @@ int main(void)
504
553
ARRAY_SIZE (ftr_id_aa64isar2_el1 ) + ARRAY_SIZE (ftr_id_aa64pfr0_el1 ) +
505
554
ARRAY_SIZE (ftr_id_aa64mmfr0_el1 ) + ARRAY_SIZE (ftr_id_aa64mmfr1_el1 ) +
506
555
ARRAY_SIZE (ftr_id_aa64mmfr2_el1 ) + ARRAY_SIZE (ftr_id_aa64zfr0_el1 ) -
507
- ARRAY_SIZE (test_regs ) + 1 ;
556
+ ARRAY_SIZE (test_regs ) + 2 ;
508
557
509
558
ksft_set_plan (test_cnt );
510
559
511
560
test_vm_ftr_id_regs (vcpu , aarch64_only );
561
+ test_vcpu_ftr_id_regs (vcpu );
562
+
512
563
test_guest_reg_read (vcpu );
513
564
514
565
test_reset_preserves_id_regs (vcpu );
0 commit comments