KVM: arm64: selftests: Add tests for GIC redist/cpuif partially above IPA range

Add tests for checking that KVM returns the right error when trying to
set GICv2 CPU interfaces or GICv3 Redistributors partially above the
addressable IPA range. Also tighten the IPA range by replacing
KVM_CAP_ARM_VM_IPA_SIZE with the IPA range currently configured for the
guest (i.e., the default).

The check for the GICv3 redistributor created using the REDIST legacy
API is not sufficient as this new test only checks the check done using
vcpus already created when setting the base. The next commit will add
the missing test which verifies that the KVM check is done at first vcpu
run.

Signed-off-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20211005011921.437353-10-ricarkol@google.com
This commit is contained in:
Ricardo Koller 2021-10-04 18:19:19 -07:00 committed by Marc Zyngier
parent c44df5f9ff
commit 2dcd9aa1c3

View File

@ -31,7 +31,7 @@ struct vm_gic {
uint32_t gic_dev_type;
};
static int max_ipa_bits;
static uint64_t max_phys_size;
/* helper to access a redistributor register */
static int access_v3_redist_reg(int gicv3_fd, int vcpu, int offset,
@ -152,16 +152,21 @@ static void subtest_dist_rdist(struct vm_gic *v)
TEST_ASSERT(ret && errno == EINVAL, "GIC redist/cpu base not aligned");
/* out of range address */
if (max_ipa_bits) {
addr = 1ULL << max_ipa_bits;
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
dist.attr, &addr, true);
TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
addr = max_phys_size;
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
dist.attr, &addr, true);
TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
rdist.attr, &addr, true);
TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
}
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
rdist.attr, &addr, true);
TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
/* Space for half a rdist (a rdist is: 2 * rdist.alignment). */
addr = max_phys_size - dist.alignment;
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
rdist.attr, &addr, true);
TEST_ASSERT(ret && errno == E2BIG,
"half of the redist is beyond IPA limit");
/* set REDIST base address @0x0*/
addr = 0x00000;
@ -250,12 +255,19 @@ static void subtest_v3_redist_regions(struct vm_gic *v)
kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
addr = REDIST_REGION_ATTR_ADDR(1, 1ULL << max_ipa_bits, 0, 2);
addr = REDIST_REGION_ATTR_ADDR(1, max_phys_size, 0, 2);
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
TEST_ASSERT(ret && errno == E2BIG,
"register redist region with base address beyond IPA range");
/* The last redist is above the pa range. */
addr = REDIST_REGION_ATTR_ADDR(2, max_phys_size - 0x30000, 0, 2);
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
TEST_ASSERT(ret && errno == E2BIG,
"register redist region with top address beyond IPA range");
addr = 0x260000;
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
@ -610,8 +622,10 @@ void run_tests(uint32_t gic_dev_type)
int main(int ac, char **av)
{
int ret;
int pa_bits;
max_ipa_bits = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
pa_bits = vm_guest_mode_params[VM_MODE_DEFAULT].pa_bits;
max_phys_size = 1ULL << pa_bits;
ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V3);
if (!ret) {