Skip to content

Commit dcd79ed

Browse files
Fuad TabbaMarc Zyngier
authored andcommitted
KVM: arm64: Use standard seq_file iterator for idregs debugfs
The current implementation uses `idreg_debugfs_iter` in `struct kvm_arch` 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 (`kvm_arch`). - The use of `u8` for the iterator index imposes an implicit limit of 255 registers. While not currently exceeded, this is fragile against future architectural growth. Switching to `loff_t` eliminates this overflow risk. 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 `idreg_debugfs_iter` field from `struct kvm_arch`. Signed-off-by: Fuad Tabba <tabba@google.com> Link: https://patch.msgid.link/20260202085721.3954942-2-tabba@google.com Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 9ace475 commit dcd79ed

2 files changed

Lines changed: 8 additions & 45 deletions

File tree

arch/arm64/include/asm/kvm_host.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,6 @@ struct kvm_arch {
373373
/* Maximum number of counters for the guest */
374374
u8 nr_pmu_counters;
375375

376-
/* Iterator for idreg debugfs */
377-
u8 idreg_debugfs_iter;
378-
379376
/* Hypercall features firmware registers' descriptor */
380377
struct kvm_smccc_features smccc_feat;
381378
struct maple_tree smccc_filter;

arch/arm64/kvm/sys_regs.c

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4992,7 +4992,7 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
49924992
return false;
49934993
}
49944994

4995-
static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, u8 pos)
4995+
static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, loff_t pos)
49964996
{
49974997
unsigned long i, idreg_idx = 0;
49984998

@@ -5002,10 +5002,8 @@ static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, u8 pos)
50025002
if (!is_vm_ftr_id_reg(reg_to_encoding(r)))
50035003
continue;
50045004

5005-
if (idreg_idx == pos)
5005+
if (idreg_idx++ == pos)
50065006
return r;
5007-
5008-
idreg_idx++;
50095007
}
50105008

50115009
return NULL;
@@ -5014,23 +5012,11 @@ static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, u8 pos)
50145012
static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
50155013
{
50165014
struct kvm *kvm = s->private;
5017-
u8 *iter;
5018-
5019-
mutex_lock(&kvm->arch.config_lock);
5020-
5021-
iter = &kvm->arch.idreg_debugfs_iter;
5022-
if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags) &&
5023-
*iter == (u8)~0) {
5024-
*iter = *pos;
5025-
if (!idregs_debug_find(kvm, *iter))
5026-
iter = NULL;
5027-
} else {
5028-
iter = ERR_PTR(-EBUSY);
5029-
}
50305015

5031-
mutex_unlock(&kvm->arch.config_lock);
5016+
if (!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
5017+
return NULL;
50325018

5033-
return iter;
5019+
return (void *)idregs_debug_find(kvm, *pos);
50345020
}
50355021

50365022
static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
@@ -5039,37 +5025,19 @@ static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
50395025

50405026
(*pos)++;
50415027

5042-
if (idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter + 1)) {
5043-
kvm->arch.idreg_debugfs_iter++;
5044-
5045-
return &kvm->arch.idreg_debugfs_iter;
5046-
}
5047-
5048-
return NULL;
5028+
return (void *)idregs_debug_find(kvm, *pos);
50495029
}
50505030

50515031
static void idregs_debug_stop(struct seq_file *s, void *v)
50525032
{
5053-
struct kvm *kvm = s->private;
5054-
5055-
if (IS_ERR(v))
5056-
return;
5057-
5058-
mutex_lock(&kvm->arch.config_lock);
5059-
5060-
kvm->arch.idreg_debugfs_iter = ~0;
5061-
5062-
mutex_unlock(&kvm->arch.config_lock);
50635033
}
50645034

50655035
static int idregs_debug_show(struct seq_file *s, void *v)
50665036
{
5067-
const struct sys_reg_desc *desc;
5037+
const struct sys_reg_desc *desc = v;
50685038
struct kvm *kvm = s->private;
50695039

5070-
desc = idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter);
5071-
5072-
if (!desc->name)
5040+
if (!desc)
50735041
return 0;
50745042

50755043
seq_printf(s, "%20s:\t%016llx\n",
@@ -5089,8 +5057,6 @@ DEFINE_SEQ_ATTRIBUTE(idregs_debug);
50895057

50905058
void kvm_sys_regs_create_debugfs(struct kvm *kvm)
50915059
{
5092-
kvm->arch.idreg_debugfs_iter = ~0;
5093-
50945060
debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
50955061
&idregs_debug_fops);
50965062
}

0 commit comments

Comments
 (0)