@@ -457,6 +457,53 @@ static void test_guest_reg_read(struct kvm_vcpu *vcpu)
457457 }
458458}
459459
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+
460507static void test_assert_id_reg_unchanged (struct kvm_vcpu * vcpu , uint32_t encoding )
461508{
462509 size_t idx = encoding_to_range_idx (encoding );
@@ -477,6 +524,8 @@ static void test_reset_preserves_id_regs(struct kvm_vcpu *vcpu)
477524 for (int i = 0 ; i < ARRAY_SIZE (test_regs ); i ++ )
478525 test_assert_id_reg_unchanged (vcpu , test_regs [i ].reg );
479526
527+ test_assert_id_reg_unchanged (vcpu , SYS_CLIDR_EL1 );
528+
480529 ksft_test_result_pass ("%s\n" , __func__ );
481530}
482531
@@ -504,11 +553,13 @@ int main(void)
504553 ARRAY_SIZE (ftr_id_aa64isar2_el1 ) + ARRAY_SIZE (ftr_id_aa64pfr0_el1 ) +
505554 ARRAY_SIZE (ftr_id_aa64mmfr0_el1 ) + ARRAY_SIZE (ftr_id_aa64mmfr1_el1 ) +
506555 ARRAY_SIZE (ftr_id_aa64mmfr2_el1 ) + ARRAY_SIZE (ftr_id_aa64zfr0_el1 ) -
507- ARRAY_SIZE (test_regs ) + 1 ;
556+ ARRAY_SIZE (test_regs ) + 2 ;
508557
509558 ksft_set_plan (test_cnt );
510559
511560 test_vm_ftr_id_regs (vcpu , aarch64_only );
561+ test_vcpu_ftr_id_regs (vcpu );
562+
512563 test_guest_reg_read (vcpu );
513564
514565 test_reset_preserves_id_regs (vcpu );
0 commit comments