Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Fuad Tabba and committed by
Marc Zyngier
fb21cb08 5ab24969

+12 -31
+12 -28
arch/arm64/kvm/vgic/vgic-debug.c
··· 104 104 struct kvm *kvm = s->private; 105 105 struct vgic_state_iter *iter; 106 106 107 - mutex_lock(&kvm->arch.config_lock); 108 - iter = kvm->arch.vgic.iter; 109 - if (iter) { 110 - iter = ERR_PTR(-EBUSY); 111 - goto out; 112 - } 113 - 114 107 iter = kmalloc(sizeof(*iter), GFP_KERNEL); 115 - if (!iter) { 116 - iter = ERR_PTR(-ENOMEM); 117 - goto out; 118 - } 108 + if (!iter) 109 + return ERR_PTR(-ENOMEM); 119 110 120 111 iter_init(kvm, iter, *pos); 121 - kvm->arch.vgic.iter = iter; 122 112 123 - if (end_of_vgic(iter)) 113 + if (end_of_vgic(iter)) { 114 + kfree(iter); 124 115 iter = NULL; 125 - out: 126 - mutex_unlock(&kvm->arch.config_lock); 116 + } 117 + 127 118 return iter; 128 119 } 129 120 130 121 static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos) 131 122 { 132 123 struct kvm *kvm = s->private; 133 - struct vgic_state_iter *iter = kvm->arch.vgic.iter; 124 + struct vgic_state_iter *iter = v; 134 125 135 126 ++*pos; 136 127 iter_next(kvm, iter); 137 - if (end_of_vgic(iter)) 128 + if (end_of_vgic(iter)) { 129 + kfree(iter); 138 130 iter = NULL; 131 + } 139 132 return iter; 140 133 } 141 134 142 135 static void vgic_debug_stop(struct seq_file *s, void *v) 143 136 { 144 - struct kvm *kvm = s->private; 145 - struct vgic_state_iter *iter; 137 + struct vgic_state_iter *iter = v; 146 138 147 - /* 148 - * If the seq file wasn't properly opened, there's nothing to clearn 149 - * up. 150 - */ 151 - if (IS_ERR(v)) 139 + if (IS_ERR_OR_NULL(v)) 152 140 return; 153 141 154 - mutex_lock(&kvm->arch.config_lock); 155 - iter = kvm->arch.vgic.iter; 156 142 kfree(iter); 157 - kvm->arch.vgic.iter = NULL; 158 - mutex_unlock(&kvm->arch.config_lock); 159 143 } 160 144 161 145 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist,
-3
include/kvm/arm_vgic.h
··· 302 302 303 303 struct xarray lpi_xa; 304 304 305 - /* used by vgic-debug */ 306 - struct vgic_state_iter *iter; 307 - 308 305 /* 309 306 * GICv4 ITS per-VM data, containing the IRQ domain, the VPE 310 307 * array, the property table pointer as well as allocation