提交 4f1fc48a 编写于 作者: M Milton Miller 提交者: Benjamin Herrenschmidt

powerpc/xics: Fix numberspace mismatch from irq_desc conversion

commit 79f26c26 (powerpc:
platforms/pseries irq_data conversion) pushed irq_desc down into many
functions, dererencing the descriptor irq field as late as possible.

But it incorrectly passed a linix virtural irq number to RTAS,
resulting in the interrupt not being disabled and possibly
other bad things, such as another interrupt being disabled and/or
a checkstop.

In addition this missed the point of xics_mask_unknown_vec and
the seperation of xics_mask_real_irq from xics_mask_irq.  When
xics_mask_unknown_vec is called it's because the hardware delivered an
irq source for which we have no linux irq allocated, and thefore we can
not have an irq_desc allocated.

Revert xics_mask_real_irq to its prior version, naming the argument
hwirq to highlight the difference.
Signed-off-by: NMilton Miller <miltonm@bga.com>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 834796a8
...@@ -250,26 +250,26 @@ static unsigned int xics_startup(struct irq_data *d) ...@@ -250,26 +250,26 @@ static unsigned int xics_startup(struct irq_data *d)
return 0; return 0;
} }
static void xics_mask_real_irq(struct irq_data *d) static void xics_mask_real_irq(unsigned int hwirq)
{ {
int call_status; int call_status;
if (d->irq == XICS_IPI) if (hwirq == XICS_IPI)
return; return;
call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq); call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq);
if (call_status != 0) { if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
__func__, d->irq, call_status); __func__, hwirq, call_status);
return; return;
} }
/* Have to set XIVE to 0xff to be able to remove a slot */ /* Have to set XIVE to 0xff to be able to remove a slot */
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq, call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq,
default_server, 0xff); default_server, 0xff);
if (call_status != 0) { if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
__func__, d->irq, call_status); __func__, hwirq, call_status);
return; return;
} }
} }
...@@ -283,13 +283,13 @@ static void xics_mask_irq(struct irq_data *d) ...@@ -283,13 +283,13 @@ static void xics_mask_irq(struct irq_data *d)
irq = (unsigned int)irq_map[d->irq].hwirq; irq = (unsigned int)irq_map[d->irq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return; return;
xics_mask_real_irq(d); xics_mask_real_irq(irq);
} }
static void xics_mask_unknown_vec(unsigned int vec) static void xics_mask_unknown_vec(unsigned int vec)
{ {
printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec); printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
xics_mask_real_irq(irq_get_irq_data(vec)); xics_mask_real_irq(vec);
} }
static inline unsigned int xics_xirr_vector(unsigned int xirr) static inline unsigned int xics_xirr_vector(unsigned int xirr)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册