1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2016 Linaro 4 * Author: Christoffer Dall <christoffer.dall@linaro.org> 5 */ 6 7 #include <linux/cpu.h> 8 #include <linux/debugfs.h> 9 #include <linux/interrupt.h> 10 #include <linux/kvm_host.h> 11 #include <linux/seq_file.h> 12 #include <kvm/arm_vgic.h> 13 #include <asm/kvm_mmu.h> 14 #include "vgic.h" 15 16 /* 17 * Structure to control looping through the entire vgic state. We start at 18 * zero for each field and move upwards. So, if dist_id is 0 we print the 19 * distributor info. When dist_id is 1, we have already printed it and move 20 * on. 21 * 22 * When vcpu_id < nr_cpus we print the vcpu info until vcpu_id == nr_cpus and 23 * so on. 24 */ 25 struct vgic_state_iter { 26 int nr_cpus; 27 int nr_spis; 28 int nr_lpis; 29 int dist_id; 30 int vcpu_id; 31 unsigned long intid; 32 int lpi_idx; 33 }; 34 35 static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter) 36 { 37 struct vgic_dist *dist = &kvm->arch.vgic; 38 39 if (iter->dist_id == 0) { 40 iter->dist_id++; 41 return; 42 } 43 44 /* 45 * Let the xarray drive the iterator after the last SPI, as the iterator 46 * has exhausted the sequentially-allocated INTID space. 47 */ 48 if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS - 1)) { 49 if (iter->lpi_idx < iter->nr_lpis) 50 xa_find_after(&dist->lpi_xa, &iter->intid, 51 VGIC_LPI_MAX_INTID, 52 LPI_XA_MARK_DEBUG_ITER); 53 iter->lpi_idx++; 54 return; 55 } 56 57 iter->intid++; 58 if (iter->intid == VGIC_NR_PRIVATE_IRQS && 59 ++iter->vcpu_id < iter->nr_cpus) 60 iter->intid = 0; 61 } 62 63 static int iter_mark_lpis(struct kvm *kvm) 64 { 65 struct vgic_dist *dist = &kvm->arch.vgic; 66 struct vgic_irq *irq; 67 unsigned long intid; 68 int nr_lpis = 0; 69 70 xa_for_each(&dist->lpi_xa, intid, irq) { 71 if (!vgic_try_get_irq_kref(irq)) 72 continue; 73 74 xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); 75 nr_lpis++; 76 } 77 78 return nr_lpis; 79 } 80 81 static void iter_unmark_lpis(struct kvm *kvm) 82 { 83 struct vgic_dist *dist = &kvm->arch.vgic; 84 struct vgic_irq *irq; 85 unsigned long intid; 86 87 xa_for_each(&dist->lpi_xa, intid, irq) { 88 xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); 89 vgic_put_irq(kvm, irq); 90 } 91 } 92 93 static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter, 94 loff_t pos) 95 { 96 int nr_cpus = atomic_read(&kvm->online_vcpus); 97 98 memset(iter, 0, sizeof(*iter)); 99 100 iter->nr_cpus = nr_cpus; 101 iter->nr_spis = kvm->arch.vgic.nr_spis; 102 if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) 103 iter->nr_lpis = iter_mark_lpis(kvm); 104 105 /* Fast forward to the right position if needed */ 106 while (pos--) 107 iter_next(kvm, iter); 108 } 109 110 static bool end_of_vgic(struct vgic_state_iter *iter) 111 { 112 return iter->dist_id > 0 && 113 iter->vcpu_id == iter->nr_cpus && 114 iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS) && 115 iter->lpi_idx > iter->nr_lpis; 116 } 117 118 static void *vgic_debug_start(struct seq_file *s, loff_t *pos) 119 { 120 struct kvm *kvm = s->private; 121 struct vgic_state_iter *iter; 122 123 mutex_lock(&kvm->arch.config_lock); 124 iter = kvm->arch.vgic.iter; 125 if (iter) { 126 iter = ERR_PTR(-EBUSY); 127 goto out; 128 } 129 130 iter = kmalloc(sizeof(*iter), GFP_KERNEL); 131 if (!iter) { 132 iter = ERR_PTR(-ENOMEM); 133 goto out; 134 } 135 136 iter_init(kvm, iter, *pos); 137 kvm->arch.vgic.iter = iter; 138 139 if (end_of_vgic(iter)) 140 iter = NULL; 141 out: 142 mutex_unlock(&kvm->arch.config_lock); 143 return iter; 144 } 145 146 static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos) 147 { 148 struct kvm *kvm = s->private; 149 struct vgic_state_iter *iter = kvm->arch.vgic.iter; 150 151 ++*pos; 152 iter_next(kvm, iter); 153 if (end_of_vgic(iter)) 154 iter = NULL; 155 return iter; 156 } 157 158 static void vgic_debug_stop(struct seq_file *s, void *v) 159 { 160 struct kvm *kvm = s->private; 161 struct vgic_state_iter *iter; 162 163 /* 164 * If the seq file wasn't properly opened, there's nothing to clearn 165 * up. 166 */ 167 if (IS_ERR(v)) 168 return; 169 170 mutex_lock(&kvm->arch.config_lock); 171 iter = kvm->arch.vgic.iter; 172 iter_unmark_lpis(kvm); 173 kfree(iter); 174 kvm->arch.vgic.iter = NULL; 175 mutex_unlock(&kvm->arch.config_lock); 176 } 177 178 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist, 179 struct vgic_state_iter *iter) 180 { 181 bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3; 182 183 seq_printf(s, "Distributor\n"); 184 seq_printf(s, "===========\n"); 185 seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2"); 186 seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis); 187 if (v3) 188 seq_printf(s, "nr_lpis:\t%d\n", iter->nr_lpis); 189 seq_printf(s, "enabled:\t%d\n", dist->enabled); 190 seq_printf(s, "\n"); 191 192 seq_printf(s, "P=pending_latch, L=line_level, A=active\n"); 193 seq_printf(s, "E=enabled, H=hw, C=config (level=1, edge=0)\n"); 194 seq_printf(s, "G=group\n"); 195 } 196 197 static void print_header(struct seq_file *s, struct vgic_irq *irq, 198 struct kvm_vcpu *vcpu) 199 { 200 int id = 0; 201 char *hdr = "SPI "; 202 203 if (vcpu) { 204 hdr = "VCPU"; 205 id = vcpu->vcpu_idx; 206 } 207 208 seq_printf(s, "\n"); 209 seq_printf(s, "%s%2d TYP ID TGT_ID PLAEHCG HWID TARGET SRC PRI VCPU_ID\n", hdr, id); 210 seq_printf(s, "----------------------------------------------------------------\n"); 211 } 212 213 static void print_irq_state(struct seq_file *s, struct vgic_irq *irq, 214 struct kvm_vcpu *vcpu) 215 { 216 char *type; 217 bool pending; 218 219 if (irq->intid < VGIC_NR_SGIS) 220 type = "SGI"; 221 else if (irq->intid < VGIC_NR_PRIVATE_IRQS) 222 type = "PPI"; 223 else if (irq->intid < VGIC_MAX_SPI) 224 type = "SPI"; 225 else 226 type = "LPI"; 227 228 if (irq->intid ==0 || irq->intid == VGIC_NR_PRIVATE_IRQS) 229 print_header(s, irq, vcpu); 230 231 pending = irq->pending_latch; 232 if (irq->hw && vgic_irq_is_sgi(irq->intid)) { 233 int err; 234 235 err = irq_get_irqchip_state(irq->host_irq, 236 IRQCHIP_STATE_PENDING, 237 &pending); 238 WARN_ON_ONCE(err); 239 } 240 241 seq_printf(s, " %s %4d " 242 " %2d " 243 "%d%d%d%d%d%d%d " 244 "%8d " 245 "%8x " 246 " %2x " 247 "%3d " 248 " %2d " 249 "\n", 250 type, irq->intid, 251 (irq->target_vcpu) ? irq->target_vcpu->vcpu_idx : -1, 252 pending, 253 irq->line_level, 254 irq->active, 255 irq->enabled, 256 irq->hw, 257 irq->config == VGIC_CONFIG_LEVEL, 258 irq->group, 259 irq->hwintid, 260 irq->mpidr, 261 irq->source, 262 irq->priority, 263 (irq->vcpu) ? irq->vcpu->vcpu_idx : -1); 264 } 265 266 static int vgic_debug_show(struct seq_file *s, void *v) 267 { 268 struct kvm *kvm = s->private; 269 struct vgic_state_iter *iter = v; 270 struct vgic_irq *irq; 271 struct kvm_vcpu *vcpu = NULL; 272 unsigned long flags; 273 274 if (iter->dist_id == 0) { 275 print_dist_state(s, &kvm->arch.vgic, iter); 276 return 0; 277 } 278 279 if (!kvm->arch.vgic.initialized) 280 return 0; 281 282 if (iter->vcpu_id < iter->nr_cpus) 283 vcpu = kvm_get_vcpu(kvm, iter->vcpu_id); 284 285 /* 286 * Expect this to succeed, as iter_mark_lpis() takes a reference on 287 * every LPI to be visited. 288 */ 289 irq = vgic_get_irq(kvm, vcpu, iter->intid); 290 if (WARN_ON_ONCE(!irq)) 291 return -EINVAL; 292 293 raw_spin_lock_irqsave(&irq->irq_lock, flags); 294 print_irq_state(s, irq, vcpu); 295 raw_spin_unlock_irqrestore(&irq->irq_lock, flags); 296 297 vgic_put_irq(kvm, irq); 298 return 0; 299 } 300 301 static const struct seq_operations vgic_debug_sops = { 302 .start = vgic_debug_start, 303 .next = vgic_debug_next, 304 .stop = vgic_debug_stop, 305 .show = vgic_debug_show 306 }; 307 308 DEFINE_SEQ_ATTRIBUTE(vgic_debug); 309 310 void vgic_debug_init(struct kvm *kvm) 311 { 312 debugfs_create_file("vgic-state", 0444, kvm->debugfs_dentry, kvm, 313 &vgic_debug_fops); 314 } 315 316 void vgic_debug_destroy(struct kvm *kvm) 317 { 318 } 319