summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuad Tabba <tabba@google.com>2026-02-02 08:57:21 +0000
committerMarc Zyngier <maz@kernel.org>2026-02-02 10:59:25 +0000
commitfb21cb08566ebed91d5c876db5c013cc8af83b89 (patch)
tree70dc12b4ff4767bf27a0949d2d05c05b8c8f0c83
parent5ab24969705a9adadbc1d3cff4c1c15df174eafb (diff)
KVM: arm64: Use standard seq_file iterator for vgic-debug debugfs
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>
-rw-r--r--arch/arm64/kvm/vgic/vgic-debug.c40
-rw-r--r--include/kvm/arm_vgic.h3
2 files changed, 12 insertions, 31 deletions
diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
index ec3d0c1fe703..2c6776a1779b 100644
--- a/arch/arm64/kvm/vgic/vgic-debug.c
+++ b/arch/arm64/kvm/vgic/vgic-debug.c
@@ -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,
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index d32fafbd2907..f2eafc65bbf4 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -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