xref: /linux/arch/arm64/kvm/vgic/vgic-debug.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
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 dist_id;
29 	int vcpu_id;
30 	unsigned long intid;
31 };
32 
iter_next(struct kvm * kvm,struct vgic_state_iter * iter)33 static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter)
34 {
35 	struct vgic_dist *dist = &kvm->arch.vgic;
36 
37 	if (iter->dist_id == 0) {
38 		iter->dist_id++;
39 		return;
40 	}
41 
42 	/*
43 	 * Let the xarray drive the iterator after the last SPI, as the iterator
44 	 * has exhausted the sequentially-allocated INTID space.
45 	 */
46 	if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS - 1)) {
47 		if (iter->intid == VGIC_LPI_MAX_INTID + 1)
48 			return;
49 
50 		rcu_read_lock();
51 		if (!xa_find_after(&dist->lpi_xa, &iter->intid,
52 				   VGIC_LPI_MAX_INTID, XA_PRESENT))
53 			iter->intid = VGIC_LPI_MAX_INTID + 1;
54 		rcu_read_unlock();
55 		return;
56 	}
57 
58 	iter->intid++;
59 	if (iter->intid == VGIC_NR_PRIVATE_IRQS &&
60 	    ++iter->vcpu_id < iter->nr_cpus)
61 		iter->intid = 0;
62 }
63 
vgic_count_lpis(struct kvm * kvm)64 static int vgic_count_lpis(struct kvm *kvm)
65 {
66 	struct vgic_dist *dist = &kvm->arch.vgic;
67 	struct vgic_irq *irq;
68 	unsigned long intid;
69 	int nr_lpis = 0;
70 
71 	rcu_read_lock();
72 	xa_for_each(&dist->lpi_xa, intid, irq)
73 		nr_lpis++;
74 	rcu_read_unlock();
75 
76 	return nr_lpis;
77 }
78 
iter_init(struct kvm * kvm,struct vgic_state_iter * iter,loff_t pos)79 static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter,
80 		      loff_t pos)
81 {
82 	int nr_cpus = atomic_read(&kvm->online_vcpus);
83 
84 	memset(iter, 0, sizeof(*iter));
85 
86 	iter->nr_cpus = nr_cpus;
87 	iter->nr_spis = kvm->arch.vgic.nr_spis;
88 
89 	/* Fast forward to the right position if needed */
90 	while (pos--)
91 		iter_next(kvm, iter);
92 }
93 
end_of_vgic(struct vgic_state_iter * iter)94 static bool end_of_vgic(struct vgic_state_iter *iter)
95 {
96 	return iter->dist_id > 0 &&
97 		iter->vcpu_id == iter->nr_cpus &&
98 		iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS) &&
99 		iter->intid > VGIC_LPI_MAX_INTID;
100 }
101 
vgic_debug_start(struct seq_file * s,loff_t * pos)102 static void *vgic_debug_start(struct seq_file *s, loff_t *pos)
103 {
104 	struct kvm *kvm = s->private;
105 	struct vgic_state_iter *iter;
106 
107 	iter = kmalloc_obj(*iter);
108 	if (!iter)
109 		return ERR_PTR(-ENOMEM);
110 
111 	iter_init(kvm, iter, *pos);
112 
113 	if (end_of_vgic(iter)) {
114 		kfree(iter);
115 		iter = NULL;
116 	}
117 
118 	return iter;
119 }
120 
vgic_debug_next(struct seq_file * s,void * v,loff_t * pos)121 static void *vgic_debug_next(struct seq_file *s, void *v, loff_t *pos)
122 {
123 	struct kvm *kvm = s->private;
124 	struct vgic_state_iter *iter = v;
125 
126 	++*pos;
127 	iter_next(kvm, iter);
128 	if (end_of_vgic(iter)) {
129 		kfree(iter);
130 		iter = NULL;
131 	}
132 	return iter;
133 }
134 
vgic_debug_stop(struct seq_file * s,void * v)135 static void vgic_debug_stop(struct seq_file *s, void *v)
136 {
137 	struct vgic_state_iter *iter = v;
138 
139 	if (IS_ERR_OR_NULL(v))
140 		return;
141 
142 	kfree(iter);
143 }
144 
print_dist_state(struct seq_file * s,struct vgic_dist * dist,struct vgic_state_iter * iter)145 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist,
146 			     struct vgic_state_iter *iter)
147 {
148 	bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3;
149 	struct kvm *kvm = s->private;
150 
151 	seq_printf(s, "Distributor\n");
152 	seq_printf(s, "===========\n");
153 	seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2");
154 	seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis);
155 	if (v3)
156 		seq_printf(s, "nr_lpis:\t%d\n", vgic_count_lpis(kvm));
157 	seq_printf(s, "enabled:\t%d\n", dist->enabled);
158 	seq_printf(s, "\n");
159 
160 	seq_printf(s, "P=pending_latch, L=line_level, A=active\n");
161 	seq_printf(s, "E=enabled, H=hw, C=config (level=1, edge=0)\n");
162 	seq_printf(s, "G=group\n");
163 }
164 
print_header(struct seq_file * s,struct vgic_irq * irq,struct kvm_vcpu * vcpu)165 static void print_header(struct seq_file *s, struct vgic_irq *irq,
166 			 struct kvm_vcpu *vcpu)
167 {
168 	int id = 0;
169 	char *hdr = "SPI ";
170 
171 	if (vcpu) {
172 		hdr = "VCPU";
173 		id = vcpu->vcpu_idx;
174 	}
175 
176 	seq_printf(s, "\n");
177 	seq_printf(s, "%s%2d TYP   ID TGT_ID PLAEHCG     HWID   TARGET SRC PRI VCPU_ID\n", hdr, id);
178 	seq_printf(s, "----------------------------------------------------------------\n");
179 }
180 
print_irq_state(struct seq_file * s,struct vgic_irq * irq,struct kvm_vcpu * vcpu)181 static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
182 			    struct kvm_vcpu *vcpu)
183 {
184 	char *type;
185 	bool pending;
186 
187 	if (irq->intid < VGIC_NR_SGIS)
188 		type = "SGI";
189 	else if (irq->intid < VGIC_NR_PRIVATE_IRQS)
190 		type = "PPI";
191 	else if (irq->intid < VGIC_MAX_SPI)
192 		type = "SPI";
193 	else
194 		type = "LPI";
195 
196 	if (irq->intid ==0 || irq->intid == VGIC_NR_PRIVATE_IRQS)
197 		print_header(s, irq, vcpu);
198 
199 	pending = irq->pending_latch;
200 	if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
201 		int err;
202 
203 		err = irq_get_irqchip_state(irq->host_irq,
204 					    IRQCHIP_STATE_PENDING,
205 					    &pending);
206 		WARN_ON_ONCE(err);
207 	}
208 
209 	seq_printf(s, "       %s %4d "
210 		      "    %2d "
211 		      "%d%d%d%d%d%d%d "
212 		      "%8d "
213 		      "%8x "
214 		      " %2x "
215 		      "%3d "
216 		      "     %2d "
217 		      "\n",
218 			type, irq->intid,
219 			(irq->target_vcpu) ? irq->target_vcpu->vcpu_idx : -1,
220 			pending,
221 			irq->line_level,
222 			irq->active,
223 			irq->enabled,
224 			irq->hw,
225 			irq->config == VGIC_CONFIG_LEVEL,
226 			irq->group,
227 			irq->hwintid,
228 			irq->mpidr,
229 			irq->source,
230 			irq->priority,
231 			(irq->vcpu) ? irq->vcpu->vcpu_idx : -1);
232 }
233 
vgic_debug_show(struct seq_file * s,void * v)234 static int vgic_debug_show(struct seq_file *s, void *v)
235 {
236 	struct kvm *kvm = s->private;
237 	struct vgic_state_iter *iter = v;
238 	struct vgic_irq *irq;
239 	struct kvm_vcpu *vcpu = NULL;
240 	unsigned long flags;
241 
242 	if (iter->dist_id == 0) {
243 		print_dist_state(s, &kvm->arch.vgic, iter);
244 		return 0;
245 	}
246 
247 	if (!kvm->arch.vgic.initialized)
248 		return 0;
249 
250 	if (iter->vcpu_id < iter->nr_cpus)
251 		vcpu = kvm_get_vcpu(kvm, iter->vcpu_id);
252 
253 	if (iter->intid < VGIC_NR_PRIVATE_IRQS)
254 		irq = vgic_get_vcpu_irq(vcpu, iter->intid);
255 	else
256 		irq = vgic_get_irq(kvm, iter->intid);
257 
258 	if (!irq)
259 		return 0;
260 
261 	raw_spin_lock_irqsave(&irq->irq_lock, flags);
262 	print_irq_state(s, irq, vcpu);
263 	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
264 
265 	vgic_put_irq(kvm, irq);
266 	return 0;
267 }
268 
269 static const struct seq_operations vgic_debug_sops = {
270 	.start = vgic_debug_start,
271 	.next  = vgic_debug_next,
272 	.stop  = vgic_debug_stop,
273 	.show  = vgic_debug_show
274 };
275 
276 DEFINE_SEQ_ATTRIBUTE(vgic_debug);
277 
vgic_debug_init(struct kvm * kvm)278 void vgic_debug_init(struct kvm *kvm)
279 {
280 	debugfs_create_file("vgic-state", 0444, kvm->debugfs_dentry, kvm,
281 			    &vgic_debug_fops);
282 }
283 
vgic_debug_destroy(struct kvm * kvm)284 void vgic_debug_destroy(struct kvm *kvm)
285 {
286 }
287 
288 /**
289  * struct vgic_its_iter - Iterator for traversing VGIC ITS device tables.
290  * @dev: Pointer to the current its_device being processed.
291  * @ite: Pointer to the current its_ite within the device being processed.
292  *
293  * This structure is used to maintain the current position during iteration
294  * over the ITS device tables. It holds pointers to both the current device
295  * and the current ITE within that device.
296  */
297 struct vgic_its_iter {
298 	struct its_device *dev;
299 	struct its_ite *ite;
300 };
301 
302 /**
303  * end_of_iter - Checks if the iterator has reached the end.
304  * @iter: The iterator to check.
305  *
306  * When the iterator completed processing the final ITE in the last device
307  * table, it was marked to indicate the end of iteration by setting its
308  * device and ITE pointers to NULL.
309  * This function checks whether the iterator was marked as end.
310  *
311  * Return: True if the iterator is marked as end, false otherwise.
312  */
end_of_iter(struct vgic_its_iter * iter)313 static inline bool end_of_iter(struct vgic_its_iter *iter)
314 {
315 	return !iter->dev && !iter->ite;
316 }
317 
318 /**
319  * vgic_its_iter_next - Advances the iterator to the next entry in the ITS tables.
320  * @its: The VGIC ITS structure.
321  * @iter: The iterator to advance.
322  *
323  * This function moves the iterator to the next ITE within the current device,
324  * or to the first ITE of the next device if the current ITE is the last in
325  * the device. If the current device is the last device, the iterator is set
326  * to indicate the end of iteration.
327  */
vgic_its_iter_next(struct vgic_its * its,struct vgic_its_iter * iter)328 static void vgic_its_iter_next(struct vgic_its *its, struct vgic_its_iter *iter)
329 {
330 	struct its_device *dev = iter->dev;
331 	struct its_ite *ite = iter->ite;
332 
333 	if (!ite || list_is_last(&ite->ite_list, &dev->itt_head)) {
334 		if (list_is_last(&dev->dev_list, &its->device_list)) {
335 			dev = NULL;
336 			ite = NULL;
337 		} else {
338 			dev = list_next_entry(dev, dev_list);
339 			ite = list_first_entry_or_null(&dev->itt_head,
340 						       struct its_ite,
341 						       ite_list);
342 		}
343 	} else {
344 		ite = list_next_entry(ite, ite_list);
345 	}
346 
347 	iter->dev = dev;
348 	iter->ite = ite;
349 }
350 
351 /**
352  * vgic_its_debug_start - Start function for the seq_file interface.
353  * @s: The seq_file structure.
354  * @pos: The starting position (offset).
355  *
356  * This function initializes the iterator to the beginning of the ITS tables
357  * and advances it to the specified position. It acquires the its_lock mutex
358  * to protect shared data.
359  *
360  * Return: An iterator pointer on success, NULL if no devices are found or
361  *         the end of the list is reached, or ERR_PTR(-ENOMEM) on memory
362  *         allocation failure.
363  */
vgic_its_debug_start(struct seq_file * s,loff_t * pos)364 static void *vgic_its_debug_start(struct seq_file *s, loff_t *pos)
365 {
366 	struct vgic_its *its = s->private;
367 	struct vgic_its_iter *iter;
368 	struct its_device *dev;
369 	loff_t offset = *pos;
370 
371 	mutex_lock(&its->its_lock);
372 
373 	dev = list_first_entry_or_null(&its->device_list,
374 				       struct its_device, dev_list);
375 	if (!dev)
376 		return NULL;
377 
378 	iter = kmalloc_obj(*iter);
379 	if (!iter)
380 		return ERR_PTR(-ENOMEM);
381 
382 	iter->dev = dev;
383 	iter->ite = list_first_entry_or_null(&dev->itt_head,
384 					     struct its_ite, ite_list);
385 
386 	while (!end_of_iter(iter) && offset--)
387 		vgic_its_iter_next(its, iter);
388 
389 	if (end_of_iter(iter)) {
390 		kfree(iter);
391 		return NULL;
392 	}
393 
394 	return iter;
395 }
396 
397 /**
398  * vgic_its_debug_next - Next function for the seq_file interface.
399  * @s: The seq_file structure.
400  * @v: The current iterator.
401  * @pos: The current position (offset).
402  *
403  * This function advances the iterator to the next entry and increments the
404  * position.
405  *
406  * Return: An iterator pointer on success, or NULL if the end of the list is
407  *         reached.
408  */
vgic_its_debug_next(struct seq_file * s,void * v,loff_t * pos)409 static void *vgic_its_debug_next(struct seq_file *s, void *v, loff_t *pos)
410 {
411 	struct vgic_its *its = s->private;
412 	struct vgic_its_iter *iter = v;
413 
414 	++*pos;
415 	vgic_its_iter_next(its, iter);
416 
417 	if (end_of_iter(iter)) {
418 		kfree(iter);
419 		return NULL;
420 	}
421 	return iter;
422 }
423 
424 /**
425  * vgic_its_debug_stop - Stop function for the seq_file interface.
426  * @s: The seq_file structure.
427  * @v: The current iterator.
428  *
429  * This function frees the iterator and releases the its_lock mutex.
430  */
vgic_its_debug_stop(struct seq_file * s,void * v)431 static void vgic_its_debug_stop(struct seq_file *s, void *v)
432 {
433 	struct vgic_its *its = s->private;
434 	struct vgic_its_iter *iter = v;
435 
436 	if (!IS_ERR_OR_NULL(iter))
437 		kfree(iter);
438 	mutex_unlock(&its->its_lock);
439 }
440 
441 /**
442  * vgic_its_debug_show - Show function for the seq_file interface.
443  * @s: The seq_file structure.
444  * @v: The current iterator.
445  *
446  * This function formats and prints the ITS table entry information to the
447  * seq_file output.
448  *
449  * Return: 0 on success.
450  */
vgic_its_debug_show(struct seq_file * s,void * v)451 static int vgic_its_debug_show(struct seq_file *s, void *v)
452 {
453 	struct vgic_its_iter *iter = v;
454 	struct its_device *dev = iter->dev;
455 	struct its_ite *ite = iter->ite;
456 
457 	if (!ite)
458 		return 0;
459 
460 	if (list_is_first(&ite->ite_list, &dev->itt_head)) {
461 		seq_printf(s, "\n");
462 		seq_printf(s, "Device ID: 0x%x, Event ID Range: [0 - %llu]\n",
463 			   dev->device_id, BIT_ULL(dev->num_eventid_bits) - 1);
464 		seq_printf(s, "EVENT_ID    INTID  HWINTID   TARGET   COL_ID HW\n");
465 		seq_printf(s, "-----------------------------------------------\n");
466 	}
467 
468 	if (ite->irq && ite->collection) {
469 		seq_printf(s, "%8u %8u %8u %8u %8u %2d\n",
470 			   ite->event_id, ite->irq->intid, ite->irq->hwintid,
471 			   ite->collection->target_addr,
472 			   ite->collection->collection_id, ite->irq->hw);
473 	}
474 
475 	return 0;
476 }
477 
478 static const struct seq_operations vgic_its_debug_sops = {
479 	.start = vgic_its_debug_start,
480 	.next  = vgic_its_debug_next,
481 	.stop  = vgic_its_debug_stop,
482 	.show  = vgic_its_debug_show
483 };
484 
485 DEFINE_SEQ_ATTRIBUTE(vgic_its_debug);
486 
487 /**
488  * vgic_its_debug_init - Initializes the debugfs interface for VGIC ITS.
489  * @dev: The KVM device structure.
490  *
491  * This function creates a debugfs file named "vgic-its-state@%its_base"
492  * to expose the ITS table information.
493  *
494  * Return: 0 on success.
495  */
vgic_its_debug_init(struct kvm_device * dev)496 int vgic_its_debug_init(struct kvm_device *dev)
497 {
498 	struct vgic_its *its = dev->private;
499 	char *name;
500 
501 	name = kasprintf(GFP_KERNEL, "vgic-its-state@%llx", (u64)its->vgic_its_base);
502 	if (!name)
503 		return -ENOMEM;
504 
505 	debugfs_create_file(name, 0444, dev->kvm->debugfs_dentry, its, &vgic_its_debug_fops);
506 
507 	kfree(name);
508 	return 0;
509 }
510 
vgic_its_debug_destroy(struct kvm_device * dev)511 void vgic_its_debug_destroy(struct kvm_device *dev)
512 {
513 }
514