Skip to content

Commit 3435bd7

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: selftest: vgic-v3: Add basic GICv3 sysreg userspace access test
We have a lot of more or less useful vgic tests, but none of them tracks the availability of GICv3 system registers, which is a bit annoying. Add one such test, which covers both EL1 and EL2 registers. Signed-off-by: Marc Zyngier <[email protected]> Tested-by: Itaru Kitayama <[email protected]> Reviewed-by: Sebastian Ott <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 8af3e8a commit 3435bd7

File tree

1 file changed

+217
-2
lines changed

1 file changed

+217
-2
lines changed

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

Lines changed: 217 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
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"
@@ -18,8 +20,6 @@
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+
718932
void 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

Comments
 (0)