aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2019-08-14 11:47:53 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2019-08-18 23:20:24 -0400
commitb4868ff55d082bc66b0c287a41e4888f6d3e5f87 (patch)
tree1433205cf4e23a07497bebeacac7ec7b599822ca
parentc3e0dbd7f780a58c4695f1cd8fc8afde80376737 (diff)
powerpc/xive: Fix dump of XIVE interrupt under pseries
The xmon 'dxi' command calls OPAL to query the XIVE configuration of a interrupt. This can only be done on baremetal (PowerNV) and it will crash a pseries machine. Introduce a new XIVE get_irq_config() operation which implements a different query depending on the platform, PowerNV or pseries, and modify xmon to use a top level wrapper. Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190814154754.23682-3-clg@kaod.org
-rw-r--r--arch/powerpc/include/asm/xive.h2
-rw-r--r--arch/powerpc/sysdev/xive/common.c7
-rw-r--r--arch/powerpc/sysdev/xive/native.c15
-rw-r--r--arch/powerpc/sysdev/xive/spapr.c51
-rw-r--r--arch/powerpc/sysdev/xive/xive-internal.h2
-rw-r--r--arch/powerpc/xmon/xmon.c12
6 files changed, 83 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index efb0e597b272..967d6ab3c977 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -99,6 +99,8 @@ extern void xive_flush_interrupt(void);
99 99
100/* xmon hook */ 100/* xmon hook */
101extern void xmon_xive_do_dump(int cpu); 101extern void xmon_xive_do_dump(int cpu);
102extern int xmon_xive_get_irq_config(u32 irq, u32 *target, u8 *prio,
103 u32 *sw_irq);
102 104
103/* APIs used by KVM */ 105/* APIs used by KVM */
104extern u32 xive_native_default_eq_shift(void); 106extern u32 xive_native_default_eq_shift(void);
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index 6b973b7cdd8a..f75a660365e5 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -257,6 +257,13 @@ notrace void xmon_xive_do_dump(int cpu)
257 } 257 }
258#endif 258#endif
259} 259}
260
261int xmon_xive_get_irq_config(u32 irq, u32 *target, u8 *prio,
262 u32 *sw_irq)
263{
264 return xive_ops->get_irq_config(irq, target, prio, sw_irq);
265}
266
260#endif /* CONFIG_XMON */ 267#endif /* CONFIG_XMON */
261 268
262static unsigned int xive_get_irq(void) 269static unsigned int xive_get_irq(void)
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
index 2f26b74f6cfa..4b61e44f0171 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -111,6 +111,20 @@ int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq)
111} 111}
112EXPORT_SYMBOL_GPL(xive_native_configure_irq); 112EXPORT_SYMBOL_GPL(xive_native_configure_irq);
113 113
114static int xive_native_get_irq_config(u32 hw_irq, u32 *target, u8 *prio,
115 u32 *sw_irq)
116{
117 s64 rc;
118 __be64 vp;
119 __be32 lirq;
120
121 rc = opal_xive_get_irq_config(hw_irq, &vp, prio, &lirq);
122
123 *target = be64_to_cpu(vp);
124 *sw_irq = be32_to_cpu(lirq);
125
126 return rc == 0 ? 0 : -ENXIO;
127}
114 128
115/* This can be called multiple time to change a queue configuration */ 129/* This can be called multiple time to change a queue configuration */
116int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, 130int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
@@ -442,6 +456,7 @@ EXPORT_SYMBOL_GPL(xive_native_sync_queue);
442static const struct xive_ops xive_native_ops = { 456static const struct xive_ops xive_native_ops = {
443 .populate_irq_data = xive_native_populate_irq_data, 457 .populate_irq_data = xive_native_populate_irq_data,
444 .configure_irq = xive_native_configure_irq, 458 .configure_irq = xive_native_configure_irq,
459 .get_irq_config = xive_native_get_irq_config,
445 .setup_queue = xive_native_setup_queue, 460 .setup_queue = xive_native_setup_queue,
446 .cleanup_queue = xive_native_cleanup_queue, 461 .cleanup_queue = xive_native_cleanup_queue,
447 .match = xive_native_match, 462 .match = xive_native_match,
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index 52198131c75e..33c10749edec 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -215,6 +215,38 @@ static long plpar_int_set_source_config(unsigned long flags,
215 return 0; 215 return 0;
216} 216}
217 217
218static long plpar_int_get_source_config(unsigned long flags,
219 unsigned long lisn,
220 unsigned long *target,
221 unsigned long *prio,
222 unsigned long *sw_irq)
223{
224 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
225 long rc;
226
227 pr_devel("H_INT_GET_SOURCE_CONFIG flags=%lx lisn=%lx\n", flags, lisn);
228
229 do {
230 rc = plpar_hcall(H_INT_GET_SOURCE_CONFIG, retbuf, flags, lisn,
231 target, prio, sw_irq);
232 } while (plpar_busy_delay(rc));
233
234 if (rc) {
235 pr_err("H_INT_GET_SOURCE_CONFIG lisn=%ld failed %ld\n",
236 lisn, rc);
237 return rc;
238 }
239
240 *target = retbuf[0];
241 *prio = retbuf[1];
242 *sw_irq = retbuf[2];
243
244 pr_devel("H_INT_GET_SOURCE_CONFIG target=%lx prio=%lx sw_irq=%lx\n",
245 retbuf[0], retbuf[1], retbuf[2]);
246
247 return 0;
248}
249
218static long plpar_int_get_queue_info(unsigned long flags, 250static long plpar_int_get_queue_info(unsigned long flags,
219 unsigned long target, 251 unsigned long target,
220 unsigned long priority, 252 unsigned long priority,
@@ -398,6 +430,24 @@ static int xive_spapr_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq)
398 return rc == 0 ? 0 : -ENXIO; 430 return rc == 0 ? 0 : -ENXIO;
399} 431}
400 432
433static int xive_spapr_get_irq_config(u32 hw_irq, u32 *target, u8 *prio,
434 u32 *sw_irq)
435{
436 long rc;
437 unsigned long h_target;
438 unsigned long h_prio;
439 unsigned long h_sw_irq;
440
441 rc = plpar_int_get_source_config(0, hw_irq, &h_target, &h_prio,
442 &h_sw_irq);
443
444 *target = h_target;
445 *prio = h_prio;
446 *sw_irq = h_sw_irq;
447
448 return rc == 0 ? 0 : -ENXIO;
449}
450
401/* This can be called multiple time to change a queue configuration */ 451/* This can be called multiple time to change a queue configuration */
402static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, 452static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
403 __be32 *qpage, u32 order) 453 __be32 *qpage, u32 order)
@@ -590,6 +640,7 @@ static void xive_spapr_sync_source(u32 hw_irq)
590static const struct xive_ops xive_spapr_ops = { 640static const struct xive_ops xive_spapr_ops = {
591 .populate_irq_data = xive_spapr_populate_irq_data, 641 .populate_irq_data = xive_spapr_populate_irq_data,
592 .configure_irq = xive_spapr_configure_irq, 642 .configure_irq = xive_spapr_configure_irq,
643 .get_irq_config = xive_spapr_get_irq_config,
593 .setup_queue = xive_spapr_setup_queue, 644 .setup_queue = xive_spapr_setup_queue,
594 .cleanup_queue = xive_spapr_cleanup_queue, 645 .cleanup_queue = xive_spapr_cleanup_queue,
595 .match = xive_spapr_match, 646 .match = xive_spapr_match,
diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h
index 211725dbf364..59cd366e7933 100644
--- a/arch/powerpc/sysdev/xive/xive-internal.h
+++ b/arch/powerpc/sysdev/xive/xive-internal.h
@@ -33,6 +33,8 @@ struct xive_cpu {
33struct xive_ops { 33struct xive_ops {
34 int (*populate_irq_data)(u32 hw_irq, struct xive_irq_data *data); 34 int (*populate_irq_data)(u32 hw_irq, struct xive_irq_data *data);
35 int (*configure_irq)(u32 hw_irq, u32 target, u8 prio, u32 sw_irq); 35 int (*configure_irq)(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
36 int (*get_irq_config)(u32 hw_irq, u32 *target, u8 *prio,
37 u32 *sw_irq);
36 int (*setup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio); 38 int (*setup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio);
37 void (*cleanup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio); 39 void (*cleanup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio);
38 void (*setup_cpu)(unsigned int cpu, struct xive_cpu *xc); 40 void (*setup_cpu)(unsigned int cpu, struct xive_cpu *xc);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 25d4adccf750..4ea53e05053f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2574,14 +2574,14 @@ static void dump_all_xives(void)
2574 2574
2575static void dump_one_xive_irq(u32 num) 2575static void dump_one_xive_irq(u32 num)
2576{ 2576{
2577 s64 rc; 2577 int rc;
2578 __be64 vp; 2578 u32 target;
2579 u8 prio; 2579 u8 prio;
2580 __be32 lirq; 2580 u32 lirq;
2581 2581
2582 rc = opal_xive_get_irq_config(num, &vp, &prio, &lirq); 2582 rc = xmon_xive_get_irq_config(num, &target, &prio, &lirq);
2583 xmon_printf("IRQ 0x%x config: vp=0x%llx prio=%d lirq=0x%x (rc=%lld)\n", 2583 xmon_printf("IRQ 0x%08x : target=0x%x prio=%d lirq=0x%x (rc=%d)\n",
2584 num, be64_to_cpu(vp), prio, be32_to_cpu(lirq), rc); 2584 num, target, prio, lirq, rc);
2585} 2585}
2586 2586
2587static void dump_xives(void) 2587static void dump_xives(void)