Skip to content

Commit 930914b

Browse files
legoatermpe
authored andcommitted
powerpc/xive: Add a debugfs file to dump internal XIVE state
As does XMON, the debugfs file /sys/kernel/debug/powerpc/xive exposes the XIVE internal state of the machine CPUs and interrupts. Available on the PowerNV and sPAPR platforms. Signed-off-by: Cédric Le Goater <[email protected]> [mpe: Make the debugfs file 0400] Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5191e0b commit 930914b

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

arch/powerpc/sysdev/xive/common.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/spinlock.h>
2121
#include <linux/msi.h>
2222

23+
#include <asm/debugfs.h>
2324
#include <asm/prom.h>
2425
#include <asm/io.h>
2526
#include <asm/smp.h>
@@ -1555,3 +1556,107 @@ static int __init xive_off(char *arg)
15551556
return 0;
15561557
}
15571558
__setup("xive=off", xive_off);
1559+
1560+
void xive_debug_show_cpu(struct seq_file *m, int cpu)
1561+
{
1562+
struct xive_cpu *xc = per_cpu(xive_cpu, cpu);
1563+
1564+
seq_printf(m, "CPU %d:", cpu);
1565+
if (xc) {
1566+
seq_printf(m, "pp=%02x CPPR=%02x ", xc->pending_prio, xc->cppr);
1567+
1568+
#ifdef CONFIG_SMP
1569+
{
1570+
u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET);
1571+
1572+
seq_printf(m, "IPI=0x%08x PQ=%c%c ", xc->hw_ipi,
1573+
val & XIVE_ESB_VAL_P ? 'P' : '-',
1574+
val & XIVE_ESB_VAL_Q ? 'Q' : '-');
1575+
}
1576+
#endif
1577+
{
1578+
struct xive_q *q = &xc->queue[xive_irq_priority];
1579+
u32 i0, i1, idx;
1580+
1581+
if (q->qpage) {
1582+
idx = q->idx;
1583+
i0 = be32_to_cpup(q->qpage + idx);
1584+
idx = (idx + 1) & q->msk;
1585+
i1 = be32_to_cpup(q->qpage + idx);
1586+
seq_printf(m, "EQ idx=%d T=%d %08x %08x ...",
1587+
q->idx, q->toggle, i0, i1);
1588+
}
1589+
}
1590+
}
1591+
seq_puts(m, "\n");
1592+
}
1593+
1594+
void xive_debug_show_irq(struct seq_file *m, u32 hw_irq, struct irq_data *d)
1595+
{
1596+
struct irq_chip *chip = irq_data_get_irq_chip(d);
1597+
int rc;
1598+
u32 target;
1599+
u8 prio;
1600+
u32 lirq;
1601+
1602+
if (!is_xive_irq(chip))
1603+
return;
1604+
1605+
rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq);
1606+
if (rc) {
1607+
seq_printf(m, "IRQ 0x%08x : no config rc=%d\n", hw_irq, rc);
1608+
return;
1609+
}
1610+
1611+
seq_printf(m, "IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ",
1612+
hw_irq, target, prio, lirq);
1613+
1614+
if (d) {
1615+
struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
1616+
u64 val = xive_esb_read(xd, XIVE_ESB_GET);
1617+
1618+
seq_printf(m, "flags=%c%c%c PQ=%c%c",
1619+
xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ',
1620+
xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ',
1621+
xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ',
1622+
val & XIVE_ESB_VAL_P ? 'P' : '-',
1623+
val & XIVE_ESB_VAL_Q ? 'Q' : '-');
1624+
}
1625+
seq_puts(m, "\n");
1626+
}
1627+
1628+
static int xive_core_debug_show(struct seq_file *m, void *private)
1629+
{
1630+
unsigned int i;
1631+
struct irq_desc *desc;
1632+
int cpu;
1633+
1634+
if (xive_ops->debug_show)
1635+
xive_ops->debug_show(m, private);
1636+
1637+
for_each_possible_cpu(cpu)
1638+
xive_debug_show_cpu(m, cpu);
1639+
1640+
for_each_irq_desc(i, desc) {
1641+
struct irq_data *d = irq_desc_get_irq_data(desc);
1642+
unsigned int hw_irq;
1643+
1644+
if (!d)
1645+
continue;
1646+
1647+
hw_irq = (unsigned int)irqd_to_hwirq(d);
1648+
1649+
/* IPIs are special (HW number 0) */
1650+
if (hw_irq)
1651+
xive_debug_show_irq(m, hw_irq, d);
1652+
}
1653+
return 0;
1654+
}
1655+
DEFINE_SHOW_ATTRIBUTE(xive_core_debug);
1656+
1657+
int xive_core_debug_init(void)
1658+
{
1659+
debugfs_create_file("xive", 0400, powerpc_debugfs_root,
1660+
NULL, &xive_core_debug_fops);
1661+
return 0;
1662+
}

arch/powerpc/sysdev/xive/native.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/cpumask.h>
2020
#include <linux/mm.h>
2121

22+
#include <asm/machdep.h>
2223
#include <asm/prom.h>
2324
#include <asm/io.h>
2425
#include <asm/smp.h>
@@ -850,3 +851,5 @@ int xive_native_get_vp_state(u32 vp_id, u64 *out_state)
850851
return 0;
851852
}
852853
EXPORT_SYMBOL_GPL(xive_native_get_vp_state);
854+
855+
machine_arch_initcall(powernv, xive_core_debug_init);

arch/powerpc/sysdev/xive/spapr.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/delay.h>
1919
#include <linux/libfdt.h>
2020

21+
#include <asm/machdep.h>
2122
#include <asm/prom.h>
2223
#include <asm/io.h>
2324
#include <asm/smp.h>
@@ -645,6 +646,21 @@ static void xive_spapr_sync_source(u32 hw_irq)
645646
plpar_int_sync(0, hw_irq);
646647
}
647648

649+
static int xive_spapr_debug_show(struct seq_file *m, void *private)
650+
{
651+
struct xive_irq_bitmap *xibm;
652+
char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
653+
654+
list_for_each_entry(xibm, &xive_irq_bitmaps, list) {
655+
memset(buf, 0, PAGE_SIZE);
656+
bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count);
657+
seq_printf(m, "bitmap #%d: %s", xibm->count, buf);
658+
}
659+
kfree(buf);
660+
661+
return 0;
662+
}
663+
648664
static const struct xive_ops xive_spapr_ops = {
649665
.populate_irq_data = xive_spapr_populate_irq_data,
650666
.configure_irq = xive_spapr_configure_irq,
@@ -662,6 +678,7 @@ static const struct xive_ops xive_spapr_ops = {
662678
#ifdef CONFIG_SMP
663679
.get_ipi = xive_spapr_get_ipi,
664680
.put_ipi = xive_spapr_put_ipi,
681+
.debug_show = xive_spapr_debug_show,
665682
#endif /* CONFIG_SMP */
666683
.name = "spapr",
667684
};
@@ -839,3 +856,5 @@ bool __init xive_spapr_init(void)
839856
pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
840857
return true;
841858
}
859+
860+
machine_arch_initcall(pseries, xive_core_debug_init);

arch/powerpc/sysdev/xive/xive-internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ struct xive_ops {
5757
int (*get_ipi)(unsigned int cpu, struct xive_cpu *xc);
5858
void (*put_ipi)(unsigned int cpu, struct xive_cpu *xc);
5959
#endif
60+
int (*debug_show)(struct seq_file *m, void *private);
6061
const char *name;
6162
};
6263

6364
bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset,
6465
u8 max_prio);
6566
__be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift);
67+
int xive_core_debug_init(void);
6668

6769
static inline u32 xive_alloc_order(u32 queue_shift)
6870
{

0 commit comments

Comments
 (0)