powerpc fixes for 5.11 #6
One fix for a bug in our soft interrupt masking, which could lead to interrupt replaying recursing, causing spurious interrupts. Thanks to: Nicholas Piggin. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmAWjOITHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgPxED/9yFcXGg/Xr/pEYTcwz8+CBvvunfw2s Bm/S1g7uMrAYHUFViKZ4PtzHwzVyEiJPf72stIaYTGmfSwqEnyN71sV3Ij19yXoK ywxbBx18G4cfaCJFuoL2AFTNYC1ZAC2B+1Yk4KboyxGsG9sNspk8uysCxD4dInEt qIWVHjqV7e/RUgdqJv5vM/PqMGDqkriB2vjn+UBs9Cv6P27n/MmcIqJRCPwKNQ3t v2kQ4fALPJRfGL4tQku/RUTa/0dPjCt0wYpbly4257yWzLjwc4xqVqNVgQfO2bj8 4wA68mIP5KpJ+5b5Qe9Jy5i/GqopN05akfqKuP5ILA6+NuVetZIWvVi9fzo39/x8 rJY+37XtfoRMFeAbidd6sMpNjPsJRyv5bDeHRI0iZJj99+OK4AHkcngQyDb7bXag 91jfDHRPhyzDazw/eKPeQkK+DNSF2u7EFRXbvO3d8FzH/EeV558m/w/ld94DUO3c M0nzCRSzijXkas+mPX6gRX3zK/4hrL+EHGqpGhPRTeCIaFRctapYlaQCdx/6npbH Q+5dHAKK+2Rj8KbjDGkt7ue8T+a9CUgdcjZYtO+4yZ8PKckuj2CFp9tKRR5veemS jFEArK3QA/8Gz57HCaks9fz6Ki7szUF1YurIO/5oRK7CWz6lOtRxT4AO1pHYNcLO NiiJfFjq5r4X/A== =hC+4 -----END PGP SIGNATURE----- Merge tag 'powerpc-5.11-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fix from Michael Ellerman: "One fix for a bug in our soft interrupt masking, which could lead to interrupt replaying recursing, causing spurious interrupts. Thanks to Nicholas Piggin" * tag 'powerpc-5.11-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/64s: prevent recursive replay_soft_interrupts causing superfluous interrupt
This commit is contained in:
Коммит
b333a99e14
|
@ -180,14 +180,19 @@ void notrace restore_interrupts(void)
|
||||||
|
|
||||||
void replay_soft_interrupts(void)
|
void replay_soft_interrupts(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* We use local_paca rather than get_paca() to avoid all
|
|
||||||
* the debug_smp_processor_id() business in this low level
|
|
||||||
* function
|
|
||||||
*/
|
|
||||||
unsigned char happened = local_paca->irq_happened;
|
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Be careful here, calling these interrupt handlers can cause
|
||||||
|
* softirqs to be raised, which they may run when calling irq_exit,
|
||||||
|
* which will cause local_irq_enable() to be run, which can then
|
||||||
|
* recurse into this function. Don't keep any state across
|
||||||
|
* interrupt handler calls which may change underneath us.
|
||||||
|
*
|
||||||
|
* We use local_paca rather than get_paca() to avoid all the
|
||||||
|
* debug_smp_processor_id() business in this low level function.
|
||||||
|
*/
|
||||||
|
|
||||||
ppc_save_regs(®s);
|
ppc_save_regs(®s);
|
||||||
regs.softe = IRQS_ENABLED;
|
regs.softe = IRQS_ENABLED;
|
||||||
|
|
||||||
|
@ -209,7 +214,7 @@ again:
|
||||||
* This is a higher priority interrupt than the others, so
|
* This is a higher priority interrupt than the others, so
|
||||||
* replay it first.
|
* replay it first.
|
||||||
*/
|
*/
|
||||||
if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_HMI)) {
|
if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) {
|
||||||
local_paca->irq_happened &= ~PACA_IRQ_HMI;
|
local_paca->irq_happened &= ~PACA_IRQ_HMI;
|
||||||
regs.trap = 0xe60;
|
regs.trap = 0xe60;
|
||||||
handle_hmi_exception(®s);
|
handle_hmi_exception(®s);
|
||||||
|
@ -217,7 +222,7 @@ again:
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (happened & PACA_IRQ_DEC) {
|
if (local_paca->irq_happened & PACA_IRQ_DEC) {
|
||||||
local_paca->irq_happened &= ~PACA_IRQ_DEC;
|
local_paca->irq_happened &= ~PACA_IRQ_DEC;
|
||||||
regs.trap = 0x900;
|
regs.trap = 0x900;
|
||||||
timer_interrupt(®s);
|
timer_interrupt(®s);
|
||||||
|
@ -225,7 +230,7 @@ again:
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (happened & PACA_IRQ_EE) {
|
if (local_paca->irq_happened & PACA_IRQ_EE) {
|
||||||
local_paca->irq_happened &= ~PACA_IRQ_EE;
|
local_paca->irq_happened &= ~PACA_IRQ_EE;
|
||||||
regs.trap = 0x500;
|
regs.trap = 0x500;
|
||||||
do_IRQ(®s);
|
do_IRQ(®s);
|
||||||
|
@ -233,7 +238,7 @@ again:
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) {
|
if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) {
|
||||||
local_paca->irq_happened &= ~PACA_IRQ_DBELL;
|
local_paca->irq_happened &= ~PACA_IRQ_DBELL;
|
||||||
if (IS_ENABLED(CONFIG_PPC_BOOK3E))
|
if (IS_ENABLED(CONFIG_PPC_BOOK3E))
|
||||||
regs.trap = 0x280;
|
regs.trap = 0x280;
|
||||||
|
@ -245,7 +250,7 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Book3E does not support soft-masking PMI interrupts */
|
/* Book3E does not support soft-masking PMI interrupts */
|
||||||
if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_PMI)) {
|
if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) {
|
||||||
local_paca->irq_happened &= ~PACA_IRQ_PMI;
|
local_paca->irq_happened &= ~PACA_IRQ_PMI;
|
||||||
regs.trap = 0xf00;
|
regs.trap = 0xf00;
|
||||||
performance_monitor_exception(®s);
|
performance_monitor_exception(®s);
|
||||||
|
@ -253,8 +258,7 @@ again:
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
happened = local_paca->irq_happened;
|
if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) {
|
||||||
if (happened & ~PACA_IRQ_HARD_DIS) {
|
|
||||||
/*
|
/*
|
||||||
* We are responding to the next interrupt, so interrupt-off
|
* We are responding to the next interrupt, so interrupt-off
|
||||||
* latencies should be reset here.
|
* latencies should be reset here.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче