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.

Merge branch kvm-arm64/debugfs-fixes into kvmarm-master/next

* kvm-arm64/debugfs-fixes:
: .
: Cleanup of the debugfs iterator, which are way more complicated
: than they ought to be, courtesy of Fuad Tabba. From the cover letter:
:
: "This series refactors the debugfs implementations for `idregs` and
: `vgic-state` to use standard `seq_file` iterator patterns.
:
: The existing implementations relied on storing iterator state within
: global VM structures (`kvm_arch` and `vgic_dist`). This approach
: prevented concurrent reads of the debugfs files (returning -EBUSY) and
: created improper dependencies between transient file operations and
: long-lived VM state."
: .
KVM: arm64: Use standard seq_file iterator for vgic-debug debugfs
KVM: arm64: Reimplement vgic-debug XArray iteration
KVM: arm64: Use standard seq_file iterator for idregs debugfs

Signed-off-by: Marc Zyngier <maz@kernel.org>

+40 -125
-3
arch/arm64/include/asm/kvm_host.h
··· 373 373 /* Maximum number of counters for the guest */ 374 374 u8 nr_pmu_counters; 375 375 376 - /* Iterator for idreg debugfs */ 377 - u8 idreg_debugfs_iter; 378 - 379 376 /* Hypercall features firmware registers' descriptor */ 380 377 struct kvm_smccc_features smccc_feat; 381 378 struct maple_tree smccc_filter;
+8 -42
arch/arm64/kvm/sys_regs.c
··· 4993 4993 return false; 4994 4994 } 4995 4995 4996 - static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, u8 pos) 4996 + static const struct sys_reg_desc *idregs_debug_find(struct kvm *kvm, loff_t pos) 4997 4997 { 4998 4998 unsigned long i, idreg_idx = 0; 4999 4999 ··· 5003 5003 if (!is_vm_ftr_id_reg(reg_to_encoding(r))) 5004 5004 continue; 5005 5005 5006 - if (idreg_idx == pos) 5006 + if (idreg_idx++ == pos) 5007 5007 return r; 5008 - 5009 - idreg_idx++; 5010 5008 } 5011 5009 5012 5010 return NULL; ··· 5013 5015 static void *idregs_debug_start(struct seq_file *s, loff_t *pos) 5014 5016 { 5015 5017 struct kvm *kvm = s->private; 5016 - u8 *iter; 5017 5018 5018 - mutex_lock(&kvm->arch.config_lock); 5019 + if (!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)) 5020 + return NULL; 5019 5021 5020 - iter = &kvm->arch.idreg_debugfs_iter; 5021 - if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags) && 5022 - *iter == (u8)~0) { 5023 - *iter = *pos; 5024 - if (!idregs_debug_find(kvm, *iter)) 5025 - iter = NULL; 5026 - } else { 5027 - iter = ERR_PTR(-EBUSY); 5028 - } 5029 - 5030 - mutex_unlock(&kvm->arch.config_lock); 5031 - 5032 - return iter; 5022 + return (void *)idregs_debug_find(kvm, *pos); 5033 5023 } 5034 5024 5035 5025 static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos) ··· 5026 5040 5027 5041 (*pos)++; 5028 5042 5029 - if (idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter + 1)) { 5030 - kvm->arch.idreg_debugfs_iter++; 5031 - 5032 - return &kvm->arch.idreg_debugfs_iter; 5033 - } 5034 - 5035 - return NULL; 5043 + return (void *)idregs_debug_find(kvm, *pos); 5036 5044 } 5037 5045 5038 5046 static void idregs_debug_stop(struct seq_file *s, void *v) 5039 5047 { 5040 - struct kvm *kvm = s->private; 5041 - 5042 - if (IS_ERR(v)) 5043 - return; 5044 - 5045 - mutex_lock(&kvm->arch.config_lock); 5046 - 5047 - kvm->arch.idreg_debugfs_iter = ~0; 5048 - 5049 - mutex_unlock(&kvm->arch.config_lock); 5050 5048 } 5051 5049 5052 5050 static int idregs_debug_show(struct seq_file *s, void *v) 5053 5051 { 5054 - const struct sys_reg_desc *desc; 5052 + const struct sys_reg_desc *desc = v; 5055 5053 struct kvm *kvm = s->private; 5056 5054 5057 - desc = idregs_debug_find(kvm, kvm->arch.idreg_debugfs_iter); 5058 - 5059 - if (!desc->name) 5055 + if (!desc) 5060 5056 return 0; 5061 5057 5062 5058 seq_printf(s, "%20s:\t%016llx\n", ··· 5058 5090 5059 5091 void kvm_sys_regs_create_debugfs(struct kvm *kvm) 5060 5092 { 5061 - kvm->arch.idreg_debugfs_iter = ~0; 5062 - 5063 5093 debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm, 5064 5094 &idregs_debug_fops); 5065 5095 }
+32 -76
arch/arm64/kvm/vgic/vgic-debug.c
··· 25 25 struct vgic_state_iter { 26 26 int nr_cpus; 27 27 int nr_spis; 28 - int nr_lpis; 29 28 int dist_id; 30 29 int vcpu_id; 31 30 unsigned long intid; 32 - int lpi_idx; 33 31 }; 34 32 35 33 static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter) ··· 43 45 * Let the xarray drive the iterator after the last SPI, as the iterator 44 46 * has exhausted the sequentially-allocated INTID space. 45 47 */ 46 - if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS - 1) && 47 - iter->nr_lpis) { 48 - if (iter->lpi_idx < iter->nr_lpis) 49 - xa_find_after(&dist->lpi_xa, &iter->intid, 50 - VGIC_LPI_MAX_INTID, 51 - LPI_XA_MARK_DEBUG_ITER); 52 - iter->lpi_idx++; 48 + if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS - 1)) { 49 + if (iter->intid == VGIC_LPI_MAX_INTID + 1) 50 + return; 51 + 52 + rcu_read_lock(); 53 + if (!xa_find_after(&dist->lpi_xa, &iter->intid, 54 + VGIC_LPI_MAX_INTID, XA_PRESENT)) 55 + iter->intid = VGIC_LPI_MAX_INTID + 1; 56 + rcu_read_unlock(); 53 57 return; 54 58 } 55 59 ··· 61 61 iter->intid = 0; 62 62 } 63 63 64 - static int iter_mark_lpis(struct kvm *kvm) 64 + static int vgic_count_lpis(struct kvm *kvm) 65 65 { 66 66 struct vgic_dist *dist = &kvm->arch.vgic; 67 - unsigned long intid, flags; 68 67 struct vgic_irq *irq; 68 + unsigned long intid; 69 69 int nr_lpis = 0; 70 70 71 - xa_lock_irqsave(&dist->lpi_xa, flags); 72 - 73 - xa_for_each(&dist->lpi_xa, intid, irq) { 74 - if (!vgic_try_get_irq_ref(irq)) 75 - continue; 76 - 77 - __xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); 71 + rcu_read_lock(); 72 + xa_for_each(&dist->lpi_xa, intid, irq) 78 73 nr_lpis++; 79 - } 80 - 81 - xa_unlock_irqrestore(&dist->lpi_xa, flags); 74 + rcu_read_unlock(); 82 75 83 76 return nr_lpis; 84 - } 85 - 86 - static void iter_unmark_lpis(struct kvm *kvm) 87 - { 88 - struct vgic_dist *dist = &kvm->arch.vgic; 89 - unsigned long intid, flags; 90 - struct vgic_irq *irq; 91 - 92 - xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) { 93 - xa_lock_irqsave(&dist->lpi_xa, flags); 94 - __xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); 95 - xa_unlock_irqrestore(&dist->lpi_xa, flags); 96 - 97 - /* vgic_put_irq() expects to be called outside of the xa_lock */ 98 - vgic_put_irq(kvm, irq); 99 - } 100 77 } 101 78 102 79 static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter, ··· 85 108 86 109 iter->nr_cpus = nr_cpus; 87 110 iter->nr_spis = kvm->arch.vgic.nr_spis; 88 - if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) 89 - iter->nr_lpis = iter_mark_lpis(kvm); 90 111 91 112 /* Fast forward to the right position if needed */ 92 113 while (pos--) ··· 96 121 return iter->dist_id > 0 && 97 122 iter->vcpu_id == iter->nr_cpus && 98 123 iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS) && 99 - (!iter->nr_lpis || iter->lpi_idx > iter->nr_lpis); 124 + iter->intid > VGIC_LPI_MAX_INTID; 100 125 } 101 126 102 127 static void *vgic_debug_start(struct seq_file *s, loff_t *pos) ··· 104 129 struct kvm *kvm = s->private; 105 130 struct vgic_state_iter *iter; 106 131 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 132 iter = kmalloc(sizeof(*iter), GFP_KERNEL); 115 - if (!iter) { 116 - iter = ERR_PTR(-ENOMEM); 117 - goto out; 118 - } 133 + if (!iter) 134 + return ERR_PTR(-ENOMEM); 119 135 120 136 iter_init(kvm, iter, *pos); 121 - kvm->arch.vgic.iter = iter; 122 137 123 - if (end_of_vgic(iter)) 138 + if (end_of_vgic(iter)) { 139 + kfree(iter); 124 140 iter = NULL; 125 - out: 126 - mutex_unlock(&kvm->arch.config_lock); 141 + } 142 + 127 143 return iter; 128 144 } 129 145 130 146 static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos) 131 147 { 132 148 struct kvm *kvm = s->private; 133 - struct vgic_state_iter *iter = kvm->arch.vgic.iter; 149 + struct vgic_state_iter *iter = v; 134 150 135 151 ++*pos; 136 152 iter_next(kvm, iter); 137 - if (end_of_vgic(iter)) 153 + if (end_of_vgic(iter)) { 154 + kfree(iter); 138 155 iter = NULL; 156 + } 139 157 return iter; 140 158 } 141 159 142 160 static void vgic_debug_stop(struct seq_file *s, void *v) 143 161 { 144 - struct kvm *kvm = s->private; 145 - struct vgic_state_iter *iter; 162 + struct vgic_state_iter *iter = v; 146 163 147 - /* 148 - * If the seq file wasn't properly opened, there's nothing to clearn 149 - * up. 150 - */ 151 - if (IS_ERR(v)) 164 + if (IS_ERR_OR_NULL(v)) 152 165 return; 153 166 154 - mutex_lock(&kvm->arch.config_lock); 155 - iter = kvm->arch.vgic.iter; 156 - iter_unmark_lpis(kvm); 157 167 kfree(iter); 158 - kvm->arch.vgic.iter = NULL; 159 - mutex_unlock(&kvm->arch.config_lock); 160 168 } 161 169 162 170 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist, 163 171 struct vgic_state_iter *iter) 164 172 { 165 173 bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3; 174 + struct kvm *kvm = s->private; 166 175 167 176 seq_printf(s, "Distributor\n"); 168 177 seq_printf(s, "===========\n"); 169 178 seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2"); 170 179 seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis); 171 180 if (v3) 172 - seq_printf(s, "nr_lpis:\t%d\n", iter->nr_lpis); 181 + seq_printf(s, "nr_lpis:\t%d\n", vgic_count_lpis(kvm)); 173 182 seq_printf(s, "enabled:\t%d\n", dist->enabled); 174 183 seq_printf(s, "\n"); 175 184 ··· 250 291 if (iter->vcpu_id < iter->nr_cpus) 251 292 vcpu = kvm_get_vcpu(kvm, iter->vcpu_id); 252 293 253 - /* 254 - * Expect this to succeed, as iter_mark_lpis() takes a reference on 255 - * every LPI to be visited. 256 - */ 257 294 if (iter->intid < VGIC_NR_PRIVATE_IRQS) 258 295 irq = vgic_get_vcpu_irq(vcpu, iter->intid); 259 296 else 260 297 irq = vgic_get_irq(kvm, iter->intid); 261 - if (WARN_ON_ONCE(!irq)) 262 - return -EINVAL; 298 + 299 + if (!irq) 300 + return 0; 263 301 264 302 raw_spin_lock_irqsave(&irq->irq_lock, flags); 265 303 print_irq_state(s, irq, vcpu);
-4
include/kvm/arm_vgic.h
··· 300 300 */ 301 301 u64 propbaser; 302 302 303 - #define LPI_XA_MARK_DEBUG_ITER XA_MARK_0 304 303 struct xarray lpi_xa; 305 - 306 - /* used by vgic-debug */ 307 - struct vgic_state_iter *iter; 308 304 309 305 /* 310 306 * GICv4 ITS per-VM data, containing the IRQ domain, the VPE