]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: Use standard seq_file iterator for vgic-debug debugfs
authorFuad Tabba <tabba@google.com>
Mon, 2 Feb 2026 08:57:21 +0000 (08:57 +0000)
committerMarc Zyngier <maz@kernel.org>
Mon, 2 Feb 2026 10:59:25 +0000 (10:59 +0000)
The current implementation uses `vgic_state_iter` in `struct
vgic_dist` to track the sequence position. This effectively makes the
iterator shared across all open file descriptors for the VM.

This approach has significant drawbacks:
- It enforces mutual exclusion, preventing concurrent reads of the
  debugfs file (returning -EBUSY).
- It relies on storing transient iterator state in the long-lived
  VM structure (`vgic_dist`).

Refactor the implementation to use the standard `seq_file` iterator.
Instead of storing state in `kvm_arch`, rely on the `pos` argument
passed to the `start` and `next` callbacks, which tracks the logical
index specific to the file descriptor.

This change enables concurrent access and eliminates the
`vgic_state_iter` field from `struct vgic_dist`.

Signed-off-by: Fuad Tabba <tabba@google.com>
Link: https://patch.msgid.link/20260202085721.3954942-4-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/vgic/vgic-debug.c
include/kvm/arm_vgic.h

index ec3d0c1fe703348d3e5740ca8fe7189cefe16074..2c6776a1779b8fa9d0d52d7b8ec5d4d050424444 100644 (file)
@@ -104,58 +104,42 @@ static void *vgic_debug_start(struct seq_file *s, loff_t *pos)
        struct kvm *kvm = s->private;
        struct vgic_state_iter *iter;
 
-       mutex_lock(&kvm->arch.config_lock);
-       iter = kvm->arch.vgic.iter;
-       if (iter) {
-               iter = ERR_PTR(-EBUSY);
-               goto out;
-       }
-
        iter = kmalloc(sizeof(*iter), GFP_KERNEL);
-       if (!iter) {
-               iter = ERR_PTR(-ENOMEM);
-               goto out;
-       }
+       if (!iter)
+               return ERR_PTR(-ENOMEM);
 
        iter_init(kvm, iter, *pos);
-       kvm->arch.vgic.iter = iter;
 
-       if (end_of_vgic(iter))
+       if (end_of_vgic(iter)) {
+               kfree(iter);
                iter = NULL;
-out:
-       mutex_unlock(&kvm->arch.config_lock);
+       }
+
        return iter;
 }
 
 static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct kvm *kvm = s->private;
-       struct vgic_state_iter *iter = kvm->arch.vgic.iter;
+       struct vgic_state_iter *iter = v;
 
        ++*pos;
        iter_next(kvm, iter);
-       if (end_of_vgic(iter))
+       if (end_of_vgic(iter)) {
+               kfree(iter);
                iter = NULL;
+       }
        return iter;
 }
 
 static void vgic_debug_stop(struct seq_file *s, void *v)
 {
-       struct kvm *kvm = s->private;
-       struct vgic_state_iter *iter;
+       struct vgic_state_iter *iter = v;
 
-       /*
-        * If the seq file wasn't properly opened, there's nothing to clearn
-        * up.
-        */
-       if (IS_ERR(v))
+       if (IS_ERR_OR_NULL(v))
                return;
 
-       mutex_lock(&kvm->arch.config_lock);
-       iter = kvm->arch.vgic.iter;
        kfree(iter);
-       kvm->arch.vgic.iter = NULL;
-       mutex_unlock(&kvm->arch.config_lock);
 }
 
 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist,
index d32fafbd2907d80daeb12d8a7400b8746492e8d2..f2eafc65bbf4c1af29c4836e89a4f785dbcb3446 100644 (file)
@@ -302,9 +302,6 @@ struct vgic_dist {
 
        struct xarray           lpi_xa;
 
-       /* used by vgic-debug */
-       struct vgic_state_iter *iter;
-
        /*
         * GICv4 ITS per-VM data, containing the IRQ domain, the VPE
         * array, the property table pointer as well as allocation