powerpc/64s: Fix may_hard_irq_enable() for PMI soft masking
The soft IRQ masking code has to hard-disable interrupts in cases where the exception is not cleared by the masked handler. External interrupts used this approach for soft masking. Now recently PMU interrupts do the same thing. The soft IRQ masking code additionally allowed for interrupt handlers to hard-enable interrupts after soft-disabling them. The idea is to allow PMU interrupts through to profile interrupt handlers. So when interrupts are being replayed when there is a pending interrupt that requires hard-disabling, there is a test to prevent those handlers from hard-enabling them if there is a pending external interrupt. may_hard_irq_enable() handles this. Afterf442d00480
("powerpc/64s: Add support to mask perf interrupts and replay them"), may_hard_irq_enable() could prematurely enable MSR[EE] when a PMU exception exists, which would result in the interrupt firing again while masked, and MSR[EE] being disabled again. I haven't seen that this could cause a serious problem, but it's more consistent to handle these soft-masked interrupts in the same way. So introduce a define for all types of interrupts that require MSR[EE] masking in their soft-disable handlers, and use that in may_hard_irq_enable(). Fixes:f442d00480
("powerpc/64s: Add support to mask perf interrupts and replay them") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:

committed by
Michael Ellerman

parent
5c11d1e52d
commit
6cc3f91bf6
@@ -29,6 +29,16 @@
|
||||
#define PACA_IRQ_HMI 0x20
|
||||
#define PACA_IRQ_PMI 0x40
|
||||
|
||||
/*
|
||||
* Some soft-masked interrupts must be hard masked until they are replayed
|
||||
* (e.g., because the soft-masked handler does not clear the exception).
|
||||
*/
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_PMI)
|
||||
#else
|
||||
#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flags for paca->irq_soft_mask
|
||||
*/
|
||||
@@ -244,7 +254,7 @@ static inline bool lazy_irq_pending(void)
|
||||
static inline void may_hard_irq_enable(void)
|
||||
{
|
||||
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
|
||||
if (!(get_paca()->irq_happened & PACA_IRQ_EE))
|
||||
if (!(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK))
|
||||
__hard_irq_enable();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user