| From d0ab60bfcd05fcbbe27a5cf9b0abbfe6941f89a6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 31 Mar 2021 16:45:12 +0200 |
| Subject: powerpc/xive: Fix xmon command "dxi" |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Cédric Le Goater <clg@kaod.org> |
| |
| [ Upstream commit 33e4bc5946432a4ac173fd08e8e30a13ab94d06d ] |
| |
| When under xmon, the "dxi" command dumps the state of the XIVE |
| interrupts. If an interrupt number is specified, only the state of |
| the associated XIVE interrupt is dumped. This form of the command |
| lacks an irq_data parameter which is nevertheless used by |
| xmon_xive_get_irq_config(), leading to an xmon crash. |
| |
| Fix that by doing a lookup in the system IRQ mapping to query the IRQ |
| descriptor data. Invalid interrupt numbers, or not belonging to the |
| XIVE IRQ domain, OPAL event interrupt number for instance, should be |
| caught by the previous query done at the firmware level. |
| |
| Fixes: 97ef27507793 ("powerpc/xive: Fix xmon support on the PowerNV platform") |
| Reported-by: kernel test robot <lkp@intel.com> |
| Reported-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Signed-off-by: Cédric Le Goater <clg@kaod.org> |
| Tested-by: Greg Kurz <groug@kaod.org> |
| Reviewed-by: Greg Kurz <groug@kaod.org> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Link: https://lore.kernel.org/r/20210331144514.892250-8-clg@kaod.org |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/powerpc/sysdev/xive/common.c | 14 ++++++++++---- |
| 1 file changed, 10 insertions(+), 4 deletions(-) |
| |
| diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c |
| index 6e43bba80707..5cacb632eb37 100644 |
| --- a/arch/powerpc/sysdev/xive/common.c |
| +++ b/arch/powerpc/sysdev/xive/common.c |
| @@ -253,17 +253,20 @@ notrace void xmon_xive_do_dump(int cpu) |
| xmon_printf("\n"); |
| } |
| |
| +static struct irq_data *xive_get_irq_data(u32 hw_irq) |
| +{ |
| + unsigned int irq = irq_find_mapping(xive_irq_domain, hw_irq); |
| + |
| + return irq ? irq_get_irq_data(irq) : NULL; |
| +} |
| + |
| int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) |
| { |
| - struct irq_chip *chip = irq_data_get_irq_chip(d); |
| int rc; |
| u32 target; |
| u8 prio; |
| u32 lirq; |
| |
| - if (!is_xive_irq(chip)) |
| - return -EINVAL; |
| - |
| rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq); |
| if (rc) { |
| xmon_printf("IRQ 0x%08x : no config rc=%d\n", hw_irq, rc); |
| @@ -273,6 +276,9 @@ int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) |
| xmon_printf("IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ", |
| hw_irq, target, prio, lirq); |
| |
| + if (!d) |
| + d = xive_get_irq_data(hw_irq); |
| + |
| if (d) { |
| struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); |
| u64 val = xive_esb_read(xd, XIVE_ESB_GET); |
| -- |
| 2.30.2 |
| |