diff options
author | Anton Blanchard <anton@samba.org> | 2011-11-24 14:39:36 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-11-27 19:42:09 -0500 |
commit | 3ce21cdfe93efffa4ffba9cf3ca2576d3d60d6dc (patch) | |
tree | 463576e41c593246365e7e41cfcd3c0197718967 | |
parent | 3bfd0c9c8f9cd2c09cf3e5376c7113eec3370ebd (diff) |
powerpc/xics: Harden xics hypervisor backend
During kdump stress testing I sometimes see the kdump kernel panic
with:
Interrupt 0x306 (real) is invalid, disabling it.
Kernel panic - not syncing: bad return code EOI - rc = -4, value=ff000306
Instead of panicing print the error message, dump the stack the first
time it happens and continue on. Add some more information to the
debug messages as well.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/sysdev/xics/icp-hv.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c index 9518d367a64f..784b3fc6f071 100644 --- a/arch/powerpc/sysdev/xics/icp-hv.c +++ b/arch/powerpc/sysdev/xics/icp-hv.c | |||
@@ -27,33 +27,49 @@ static inline unsigned int icp_hv_get_xirr(unsigned char cppr) | |||
27 | { | 27 | { |
28 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | 28 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
29 | long rc; | 29 | long rc; |
30 | unsigned int ret = XICS_IRQ_SPURIOUS; | ||
30 | 31 | ||
31 | rc = plpar_hcall(H_XIRR, retbuf, cppr); | 32 | rc = plpar_hcall(H_XIRR, retbuf, cppr); |
32 | if (rc != H_SUCCESS) | 33 | if (rc == H_SUCCESS) { |
33 | panic(" bad return code xirr - rc = %lx\n", rc); | 34 | ret = (unsigned int)retbuf[0]; |
34 | return (unsigned int)retbuf[0]; | 35 | } else { |
36 | pr_err("%s: bad return code xirr cppr=0x%x returned %ld\n", | ||
37 | __func__, cppr, rc); | ||
38 | WARN_ON_ONCE(1); | ||
39 | } | ||
40 | |||
41 | return ret; | ||
35 | } | 42 | } |
36 | 43 | ||
37 | static inline void icp_hv_set_xirr(unsigned int value) | 44 | static inline void icp_hv_set_xirr(unsigned int value) |
38 | { | 45 | { |
39 | long rc = plpar_hcall_norets(H_EOI, value); | 46 | long rc = plpar_hcall_norets(H_EOI, value); |
40 | if (rc != H_SUCCESS) | 47 | if (rc != H_SUCCESS) { |
41 | panic("bad return code EOI - rc = %ld, value=%x\n", rc, value); | 48 | pr_err("%s: bad return code eoi xirr=0x%x returned %ld\n", |
49 | __func__, value, rc); | ||
50 | WARN_ON_ONCE(1); | ||
51 | } | ||
42 | } | 52 | } |
43 | 53 | ||
44 | static inline void icp_hv_set_cppr(u8 value) | 54 | static inline void icp_hv_set_cppr(u8 value) |
45 | { | 55 | { |
46 | long rc = plpar_hcall_norets(H_CPPR, value); | 56 | long rc = plpar_hcall_norets(H_CPPR, value); |
47 | if (rc != H_SUCCESS) | 57 | if (rc != H_SUCCESS) { |
48 | panic("bad return code cppr - rc = %lx\n", rc); | 58 | pr_err("%s: bad return code cppr cppr=0x%x returned %ld\n", |
59 | __func__, value, rc); | ||
60 | WARN_ON_ONCE(1); | ||
61 | } | ||
49 | } | 62 | } |
50 | 63 | ||
51 | static inline void icp_hv_set_qirr(int n_cpu , u8 value) | 64 | static inline void icp_hv_set_qirr(int n_cpu , u8 value) |
52 | { | 65 | { |
53 | long rc = plpar_hcall_norets(H_IPI, get_hard_smp_processor_id(n_cpu), | 66 | int hw_cpu = get_hard_smp_processor_id(n_cpu); |
54 | value); | 67 | long rc = plpar_hcall_norets(H_IPI, hw_cpu, value); |
55 | if (rc != H_SUCCESS) | 68 | if (rc != H_SUCCESS) { |
56 | panic("bad return code qirr - rc = %lx\n", rc); | 69 | pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x " |
70 | "returned %ld\n", __func__, n_cpu, hw_cpu, value, rc); | ||
71 | WARN_ON_ONCE(1); | ||
72 | } | ||
57 | } | 73 | } |
58 | 74 | ||
59 | static void icp_hv_eoi(struct irq_data *d) | 75 | static void icp_hv_eoi(struct irq_data *d) |