pseries: Fix semantics of RTAS int-on, int-off and set-xive functions
Currently the ibm,int-on and ibm,int-off RTAS functions are implemented as no-ops. This is because when implemented as specified in PAPR they caused Linux (which calls both int-on/off and set-xive) to end up with interrupts masked when they should not be. Since Linux's set-xive calls make the int-on/off calls redundant, making them nops worked around the problem. In fact, the problem was caused because there was a subtle bug in set-xive, PAPR specifies that as well as updating the current priority, it also needs to update the saved priority used by int-on/off. With this bug fixed the problem goes away. This patch implements this more correct fix. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
53724ee565
commit
3fe719f467
25
hw/xics.c
25
hw/xics.c
@ -270,13 +270,14 @@ static void write_xive_lsi(struct ics_state *ics, int srcno)
|
||||
}
|
||||
|
||||
static void ics_write_xive(struct ics_state *ics, int nr, int server,
|
||||
uint8_t priority)
|
||||
uint8_t priority, uint8_t saved_priority)
|
||||
{
|
||||
int srcno = nr - ics->offset;
|
||||
struct ics_irq_state *irq = ics->irqs + srcno;
|
||||
|
||||
irq->server = server;
|
||||
irq->priority = priority;
|
||||
irq->saved_priority = saved_priority;
|
||||
|
||||
if (irq->lsi) {
|
||||
write_xive_lsi(ics, srcno);
|
||||
@ -405,7 +406,7 @@ static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
|
||||
return;
|
||||
}
|
||||
|
||||
ics_write_xive(ics, nr, server, priority);
|
||||
ics_write_xive(ics, nr, server, priority, priority);
|
||||
|
||||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
@ -453,14 +454,8 @@ static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is a NOP for now, since the described PAPR semantics don't
|
||||
* seem to gel with what Linux does */
|
||||
#if 0
|
||||
struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
|
||||
|
||||
irq->saved_priority = irq->priority;
|
||||
ics_write_xive_msi(xics, nr, irq->server, 0xff);
|
||||
#endif
|
||||
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
|
||||
ics->irqs[nr - ics->offset].priority);
|
||||
|
||||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
@ -484,13 +479,9 @@ static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is a NOP for now, since the described PAPR semantics don't
|
||||
* seem to gel with what Linux does */
|
||||
#if 0
|
||||
struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
|
||||
|
||||
ics_write_xive_msi(xics, nr, irq->server, irq->saved_priority);
|
||||
#endif
|
||||
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
|
||||
ics->irqs[nr - ics->offset].saved_priority,
|
||||
ics->irqs[nr - ics->offset].saved_priority);
|
||||
|
||||
rtas_st(rets, 0, 0); /* Success */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user