/* * PACA flags in paca->irq_happened. * * This bits are set when interrupts occur while soft-disabled * and allow a proper replay. * * The PACA_IRQ_HARD_DIS is set whenever we hard disable. It is almost * always in synch with the MSR[EE] state, except: * - A window in interrupt entry, where hardware disables MSR[EE] and that * must be "reconciled" with the soft mask state. * - NMI interrupts that hit in awkward places, until they fix the state. * - When local irqs are being enabled and state is being fixed up. * - When returning from an interrupt there are some windows where this * can become out of synch, but gets fixed before the RFI or before * executing the next user instruction (see arch/powerpc/kernel/interrupt.c).
*/ #define PACA_IRQ_HARD_DIS 0x01 #define PACA_IRQ_DBELL 0x02 #define PACA_IRQ_EE 0x04 #define PACA_IRQ_DEC 0x08 /* Or FIT */ #define PACA_IRQ_HMI 0x10 #define PACA_IRQ_PMI 0x20 #define PACA_IRQ_REPLAYING 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). * Interrupt replay itself must remain hard masked too.
*/ #ifdef CONFIG_PPC_BOOK3S #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_PMI|PACA_IRQ_REPLAYING) #else #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_REPLAYING) #endif
/* * The "memory" clobber acts as both a compiler barrier * for the critical section and as a clobber because * we changed paca->irq_soft_mask
*/ staticinline notrace void irq_soft_mask_set(unsignedlong mask)
{ /* * The irq mask must always include the STD bit if any are set. * * and interrupts don't get replayed until the standard * interrupt (local_irq_disable()) is unmasked. * * Other masks must only provide additional masking beyond * the standard, and they are also not replayed until the * standard interrupt becomes unmasked. * * This could be changed, but it will require partial * unmasks to be replayed, among other things. For now, take * the simple approach.
*/ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
WARN_ON(mask && !(mask & IRQS_DISABLED));
staticinlinevoid set_pmi_irq_pending(void)
{ /* * Invoked from PMU callback functions to set PMI bit in the paca. * This has to be called with irq's disabled (via hard_irq_disable()).
*/ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
WARN_ON_ONCE(mfmsr() & MSR_EE);
get_paca()->irq_happened |= PACA_IRQ_PMI;
}
staticinlinevoid clear_pmi_irq_pending(void)
{ /* * Invoked from PMU callback functions to clear the pending PMI bit * in the paca.
*/ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
WARN_ON_ONCE(mfmsr() & MSR_EE);
get_paca()->irq_happened &= ~PACA_IRQ_PMI;
}
staticinlinebool pmi_irq_pending(void)
{ /* * Invoked from PMU callback functions to check if there is a pending * PMI bit in the paca.
*/ if (get_paca()->irq_happened & PACA_IRQ_PMI) returntrue;
returnfalse;
}
#ifdef CONFIG_PPC_BOOK3S /* * To support disabling and enabling of irq with PMI, set of * new powerpc_local_irq_pmu_save() and powerpc_local_irq_restore() * functions are added. These macros are implemented using generic * linux local_irq_* code from include/linux/irqflags.h.
*/ #define raw_local_irq_pmu_save(flags) \ do { \
typecheck(unsignedlong, flags); \
flags = irq_soft_mask_or_return(IRQS_DISABLED | \
IRQS_PMI_DISABLED); \
} while(0)
/* * Check if a lazy IRQ is pending. Should be called with IRQs hard disabled.
*/ staticinlinebool lazy_irq_pending(void)
{ return __lazy_irq_pending(get_paca()->irq_happened);
}
/* * Check if a lazy IRQ is pending, with no debugging checks. * Should be called with IRQs hard disabled. * For use in RI disabled code or other constrained situations.
*/ staticinlinebool lazy_irq_pending_nocheck(void)
{ return __lazy_irq_pending(local_paca->irq_happened);
}
bool power_pmu_wants_prompt_pmi(void);
/* * This is called by asynchronous interrupts to check whether to * conditionally re-enable hard interrupts after having cleared * the source of the interrupt. They are kept disabled if there * is a different soft-masked interrupt pending that requires hard * masking.
*/ staticinlinebool should_hard_irq_enable(struct pt_regs *regs)
{ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) {
WARN_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
WARN_ON(!(get_paca()->irq_happened & PACA_IRQ_HARD_DIS));
WARN_ON(mfmsr() & MSR_EE);
}
if (!IS_ENABLED(CONFIG_PERF_EVENTS)) returnfalse; /* * If the PMU is not running, there is not much reason to enable * MSR[EE] in irq handlers because any interrupts would just be * soft-masked. * * TODO: Add test for 64e
*/ if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) { if (!power_pmu_wants_prompt_pmi()) returnfalse; /* * If PMIs are disabled then IRQs should be disabled as well, * so we shouldn't see this condition, check for it just in * case because we are about to enable PMIs.
*/ if (WARN_ON_ONCE(regs->softe & IRQS_PMI_DISABLED)) returnfalse;
}
if (get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK) returnfalse;
returntrue;
}
/* * Do the hard enabling, only call this if should_hard_irq_enable is true. * This allows PMI interrupts to profile irq handlers.
*/ staticinlinevoid do_hard_irq_enable(void)
{ /* * Asynch interrupts come in with IRQS_ALL_DISABLED, * PACA_IRQ_HARD_DIS, and MSR[EE]=0.
*/ if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
irq_soft_mask_andc_return(IRQS_PMI_DISABLED);
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
__hard_irq_enable();
}
staticinlineunsignedlong mtmsr_isync_irqsafe(unsignedlong msr)
{ #ifdef CONFIG_PPC64 if (arch_irqs_disabled()) { /* * With soft-masking, MSR[EE] can change from 1 to 0 * asynchronously when irqs are disabled, and we don't want to * set MSR[EE] back to 1 here if that has happened. A race-free * way to do this is ensure EE is already 0. Another way it * could be done is with a RESTART_TABLE handler, but that's * probably overkill here.
*/
msr &= ~MSR_EE;
mtmsr_isync(msr);
irq_soft_mask_set(IRQS_ALL_DISABLED);
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
} else #endif
mtmsr_isync(msr);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.