99#include <asm/kvm.h>
1010#include <asm/kvm_para.h>
1111
12+ #include <arm64/gic_v3.h>
13+
1214#include "test_util.h"
1315#include "kvm_util.h"
1416#include "processor.h"
1820
1921#define REG_OFFSET (vcpu , offset ) (((uint64_t)vcpu << 32) | offset)
2022
21- #define GICR_TYPER 0x8
22-
2323#define VGIC_DEV_IS_V2 (_d ) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V2)
2424#define VGIC_DEV_IS_V3 (_d ) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V3)
2525
@@ -715,6 +715,220 @@ int test_kvm_device(uint32_t gic_dev_type)
715715 return 0 ;
716716}
717717
718+ struct sr_def {
719+ const char * name ;
720+ u32 encoding ;
721+ };
722+
723+ #define PACK_SR (r ) \
724+ ((sys_reg_Op0(r) << 14) | \
725+ (sys_reg_Op1(r) << 11) | \
726+ (sys_reg_CRn(r) << 7) | \
727+ (sys_reg_CRm(r) << 3) | \
728+ (sys_reg_Op2(r)))
729+
730+ #define SR (r ) \
731+ { \
732+ .name = #r, \
733+ .encoding = r, \
734+ }
735+
736+ static const struct sr_def sysregs_el1 [] = {
737+ SR (SYS_ICC_PMR_EL1 ),
738+ SR (SYS_ICC_BPR0_EL1 ),
739+ SR (SYS_ICC_AP0R0_EL1 ),
740+ SR (SYS_ICC_AP0R1_EL1 ),
741+ SR (SYS_ICC_AP0R2_EL1 ),
742+ SR (SYS_ICC_AP0R3_EL1 ),
743+ SR (SYS_ICC_AP1R0_EL1 ),
744+ SR (SYS_ICC_AP1R1_EL1 ),
745+ SR (SYS_ICC_AP1R2_EL1 ),
746+ SR (SYS_ICC_AP1R3_EL1 ),
747+ SR (SYS_ICC_BPR1_EL1 ),
748+ SR (SYS_ICC_CTLR_EL1 ),
749+ SR (SYS_ICC_SRE_EL1 ),
750+ SR (SYS_ICC_IGRPEN0_EL1 ),
751+ SR (SYS_ICC_IGRPEN1_EL1 ),
752+ };
753+
754+ static const struct sr_def sysregs_el2 [] = {
755+ SR (SYS_ICH_AP0R0_EL2 ),
756+ SR (SYS_ICH_AP0R1_EL2 ),
757+ SR (SYS_ICH_AP0R2_EL2 ),
758+ SR (SYS_ICH_AP0R3_EL2 ),
759+ SR (SYS_ICH_AP1R0_EL2 ),
760+ SR (SYS_ICH_AP1R1_EL2 ),
761+ SR (SYS_ICH_AP1R2_EL2 ),
762+ SR (SYS_ICH_AP1R3_EL2 ),
763+ SR (SYS_ICH_HCR_EL2 ),
764+ SR (SYS_ICC_SRE_EL2 ),
765+ SR (SYS_ICH_VTR_EL2 ),
766+ SR (SYS_ICH_VMCR_EL2 ),
767+ SR (SYS_ICH_LR0_EL2 ),
768+ SR (SYS_ICH_LR1_EL2 ),
769+ SR (SYS_ICH_LR2_EL2 ),
770+ SR (SYS_ICH_LR3_EL2 ),
771+ SR (SYS_ICH_LR4_EL2 ),
772+ SR (SYS_ICH_LR5_EL2 ),
773+ SR (SYS_ICH_LR6_EL2 ),
774+ SR (SYS_ICH_LR7_EL2 ),
775+ SR (SYS_ICH_LR8_EL2 ),
776+ SR (SYS_ICH_LR9_EL2 ),
777+ SR (SYS_ICH_LR10_EL2 ),
778+ SR (SYS_ICH_LR11_EL2 ),
779+ SR (SYS_ICH_LR12_EL2 ),
780+ SR (SYS_ICH_LR13_EL2 ),
781+ SR (SYS_ICH_LR14_EL2 ),
782+ SR (SYS_ICH_LR15_EL2 ),
783+ };
784+
785+ static void test_sysreg_array (int gic , const struct sr_def * sr , int nr ,
786+ int (* check )(int , const struct sr_def * , const char * ))
787+ {
788+ for (int i = 0 ; i < nr ; i ++ ) {
789+ u64 val ;
790+ u64 attr ;
791+ int ret ;
792+
793+ /* Assume MPIDR_EL1.Aff*=0 */
794+ attr = PACK_SR (sr [i ].encoding );
795+
796+ /*
797+ * The API is braindead. A register can be advertised as
798+ * available, and yet not be readable or writable.
799+ * ICC_APnR{1,2,3}_EL1 are examples of such non-sense, and
800+ * ICH_APnR{1,2,3}_EL2 do follow suit for consistency.
801+ *
802+ * On the bright side, no known HW is implementing more than
803+ * 5 bits of priority, so we're safe. Sort of...
804+ */
805+ ret = __kvm_has_device_attr (gic , KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS ,
806+ attr );
807+ TEST_ASSERT (ret == 0 , "%s unavailable" , sr [i ].name );
808+
809+ /* Check that we can write back what we read */
810+ ret = __kvm_device_attr_get (gic , KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS ,
811+ attr , & val );
812+ TEST_ASSERT (ret == 0 || !check (gic , & sr [i ], "read" ), "%s unreadable" , sr [i ].name );
813+ ret = __kvm_device_attr_set (gic , KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS ,
814+ attr , & val );
815+ TEST_ASSERT (ret == 0 || !check (gic , & sr [i ], "write" ), "%s unwritable" , sr [i ].name );
816+ }
817+ }
818+
819+ static u8 get_ctlr_pribits (int gic )
820+ {
821+ int ret ;
822+ u64 val ;
823+ u8 pri ;
824+
825+ ret = __kvm_device_attr_get (gic , KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS ,
826+ PACK_SR (SYS_ICC_CTLR_EL1 ), & val );
827+ TEST_ASSERT (ret == 0 , "ICC_CTLR_EL1 unreadable" );
828+
829+ pri = FIELD_GET (ICC_CTLR_EL1_PRI_BITS_MASK , val ) + 1 ;
830+ TEST_ASSERT (pri >= 5 && pri <= 7 , "Bad pribits %d" , pri );
831+
832+ return pri ;
833+ }
834+
835+ static int check_unaccessible_el1_regs (int gic , const struct sr_def * sr , const char * what )
836+ {
837+ switch (sr -> encoding ) {
838+ case SYS_ICC_AP0R1_EL1 :
839+ case SYS_ICC_AP1R1_EL1 :
840+ if (get_ctlr_pribits (gic ) >= 6 )
841+ return - EINVAL ;
842+ break ;
843+ case SYS_ICC_AP0R2_EL1 :
844+ case SYS_ICC_AP0R3_EL1 :
845+ case SYS_ICC_AP1R2_EL1 :
846+ case SYS_ICC_AP1R3_EL1 :
847+ if (get_ctlr_pribits (gic ) == 7 )
848+ return 0 ;
849+ break ;
850+ default :
851+ return - EINVAL ;
852+ }
853+
854+ pr_info ("SKIP %s for %s\n" , sr -> name , what );
855+ return 0 ;
856+ }
857+
858+ static u8 get_vtr_pribits (int gic )
859+ {
860+ int ret ;
861+ u64 val ;
862+ u8 pri ;
863+
864+ ret = __kvm_device_attr_get (gic , KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS ,
865+ PACK_SR (SYS_ICH_VTR_EL2 ), & val );
866+ TEST_ASSERT (ret == 0 , "ICH_VTR_EL2 unreadable" );
867+
868+ pri = FIELD_GET (ICH_VTR_EL2_PRIbits , val ) + 1 ;
869+ TEST_ASSERT (pri >= 5 && pri <= 7 , "Bad pribits %d" , pri );
870+
871+ return pri ;
872+ }
873+
874+ static int check_unaccessible_el2_regs (int gic , const struct sr_def * sr , const char * what )
875+ {
876+ switch (sr -> encoding ) {
877+ case SYS_ICH_AP0R1_EL2 :
878+ case SYS_ICH_AP1R1_EL2 :
879+ if (get_vtr_pribits (gic ) >= 6 )
880+ return - EINVAL ;
881+ break ;
882+ case SYS_ICH_AP0R2_EL2 :
883+ case SYS_ICH_AP0R3_EL2 :
884+ case SYS_ICH_AP1R2_EL2 :
885+ case SYS_ICH_AP1R3_EL2 :
886+ if (get_vtr_pribits (gic ) == 7 )
887+ return - EINVAL ;
888+ break ;
889+ default :
890+ return - EINVAL ;
891+ }
892+
893+ pr_info ("SKIP %s for %s\n" , sr -> name , what );
894+ return 0 ;
895+ }
896+
897+ static void test_v3_sysregs (void )
898+ {
899+ struct kvm_vcpu_init init = {};
900+ struct kvm_vcpu * vcpu ;
901+ struct kvm_vm * vm ;
902+ u32 feat = 0 ;
903+ int gic ;
904+
905+ if (kvm_check_cap (KVM_CAP_ARM_EL2 ))
906+ feat |= BIT (KVM_ARM_VCPU_HAS_EL2 );
907+
908+ vm = vm_create (1 );
909+
910+ vm_ioctl (vm , KVM_ARM_PREFERRED_TARGET , & init );
911+ init .features [0 ] |= feat ;
912+
913+ vcpu = aarch64_vcpu_add (vm , 0 , & init , NULL );
914+ TEST_ASSERT (vcpu , "Can't create a vcpu?" );
915+
916+ gic = kvm_create_device (vm , KVM_DEV_TYPE_ARM_VGIC_V3 );
917+ TEST_ASSERT (gic >= 0 , "No GIC???" );
918+
919+ kvm_device_attr_set (gic , KVM_DEV_ARM_VGIC_GRP_CTRL ,
920+ KVM_DEV_ARM_VGIC_CTRL_INIT , NULL );
921+
922+ test_sysreg_array (gic , sysregs_el1 , ARRAY_SIZE (sysregs_el1 ), check_unaccessible_el1_regs );
923+ if (feat )
924+ test_sysreg_array (gic , sysregs_el2 , ARRAY_SIZE (sysregs_el2 ), check_unaccessible_el2_regs );
925+ else
926+ pr_info ("SKIP EL2 registers, not available\n" );
927+
928+ close (gic );
929+ kvm_vm_free (vm );
930+ }
931+
718932void run_tests (uint32_t gic_dev_type )
719933{
720934 test_vcpus_then_vgic (gic_dev_type );
@@ -730,6 +944,7 @@ void run_tests(uint32_t gic_dev_type)
730944 test_v3_last_bit_single_rdist ();
731945 test_v3_redist_ipa_range_check_at_vcpu_run ();
732946 test_v3_its_region ();
947+ test_v3_sysregs ();
733948 }
734949}
735950
0 commit comments