]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: selftests: Add unsanitised helpers for VGICv3 creation
authorOliver Upton <oliver.upton@linux.dev>
Wed, 17 Sep 2025 21:20:34 +0000 (14:20 -0700)
committerMarc Zyngier <maz@kernel.org>
Wed, 24 Sep 2025 18:23:32 +0000 (19:23 +0100)
vgic_v3_setup() has a good bit of sanity checking internally to ensure
that vCPUs have actually been created and match the dimensioning of the
vgic itself. Spin off an unsanitised setup and initialization helper so
vgic initialization can be wired in around a 'default' VM's vCPU
creation.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
tools/testing/selftests/kvm/include/arm64/vgic.h
tools/testing/selftests/kvm/lib/arm64/vgic.c

index b858fa8195b4c321980f0319772d4ad4be096545..688beccc94366ce480fff5ad928890f7c6eb0a11 100644 (file)
@@ -17,6 +17,8 @@
        index)
 
 bool kvm_supports_vgic_v3(void);
+int __vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs);
+void __vgic_v3_init(int fd);
 int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs);
 
 #define VGIC_MAX_RESERVED      1023
index 661744c6532e9a66a7e08c6261e229d754846d7d..d0f7bd0984b84f6b5afb7c9e1519e60b7cfda003 100644 (file)
@@ -41,24 +41,11 @@ bool kvm_supports_vgic_v3(void)
  * redistributor regions of the guest. Since it depends on the number of
  * vCPUs for the VM, it must be called after all the vCPUs have been created.
  */
-int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs)
+int __vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs)
 {
        int gic_fd;
        uint64_t attr;
-       struct list_head *iter;
-       unsigned int nr_gic_pages, nr_vcpus_created = 0;
-
-       TEST_ASSERT(nr_vcpus, "Number of vCPUs cannot be empty");
-
-       /*
-        * Make sure that the caller is infact calling this
-        * function after all the vCPUs are added.
-        */
-       list_for_each(iter, &vm->vcpus)
-               nr_vcpus_created++;
-       TEST_ASSERT(nr_vcpus == nr_vcpus_created,
-                       "Number of vCPUs requested (%u) doesn't match with the ones created for the VM (%u)",
-                       nr_vcpus, nr_vcpus_created);
+       unsigned int nr_gic_pages;
 
        /* Distributor setup */
        gic_fd = __kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3);
@@ -81,10 +68,39 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs)
                                                KVM_VGIC_V3_REDIST_SIZE * nr_vcpus);
        virt_map(vm, GICR_BASE_GPA, GICR_BASE_GPA, nr_gic_pages);
 
-       kvm_device_attr_set(gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
+       return gic_fd;
+}
+
+void __vgic_v3_init(int fd)
+{
+       kvm_device_attr_set(fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                            KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
+}
 
-       return gic_fd;
+int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs)
+{
+       unsigned int nr_vcpus_created = 0;
+       struct list_head *iter;
+       int fd;
+
+       TEST_ASSERT(nr_vcpus, "Number of vCPUs cannot be empty");
+
+       /*
+        * Make sure that the caller is infact calling this
+        * function after all the vCPUs are added.
+        */
+       list_for_each(iter, &vm->vcpus)
+               nr_vcpus_created++;
+       TEST_ASSERT(nr_vcpus == nr_vcpus_created,
+                   "Number of vCPUs requested (%u) doesn't match with the ones created for the VM (%u)",
+                   nr_vcpus, nr_vcpus_created);
+
+       fd = __vgic_v3_setup(vm, nr_vcpus, nr_irqs);
+       if (fd < 0)
+               return fd;
+
+       __vgic_v3_init(fd);
+       return fd;
 }
 
 /* should only work for level sensitive interrupts */