Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 292511
b: refs/heads/master
c: 7230c56
h: refs/heads/master
i:
  292509: 63cba9b
  292507: 893d533
  292503: 46aa238
  292495: 9566ebe
  292479: 5c02d20
v: v3
  • Loading branch information
Benjamin Herrenschmidt committed Mar 9, 2012
1 parent 4d4a056 commit 6c5594a
Show file tree
Hide file tree
Showing 20 changed files with 648 additions and 343 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d9ada91ae2969ae6b6dc3574fd08a6ebda5df766
refs/heads/master: 7230c5644188cd9e3fb380cc97dde00c464a3ba7
34 changes: 13 additions & 21 deletions trunk/arch/powerpc/include/asm/exception-64s.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,23 +232,30 @@ label##_hv: \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
EXC_HV, KVMTEST, vec)

#define __SOFTEN_TEST(h) \
/* This associate vector numbers with bits in paca->irq_happened */
#define SOFTEN_VALUE_0x500 PACA_IRQ_EE
#define SOFTEN_VALUE_0x502 PACA_IRQ_EE
#define SOFTEN_VALUE_0x900 PACA_IRQ_DEC
#define SOFTEN_VALUE_0x982 PACA_IRQ_DEC

#define __SOFTEN_TEST(h, vec) \
lbz r10,PACASOFTIRQEN(r13); \
cmpwi r10,0; \
li r10,SOFTEN_VALUE_##vec; \
beq masked_##h##interrupt
#define _SOFTEN_TEST(h) __SOFTEN_TEST(h)
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)

#define SOFTEN_TEST_PR(vec) \
KVMTEST_PR(vec); \
_SOFTEN_TEST(EXC_STD)
_SOFTEN_TEST(EXC_STD, vec)

#define SOFTEN_TEST_HV(vec) \
KVMTEST(vec); \
_SOFTEN_TEST(EXC_HV)
_SOFTEN_TEST(EXC_HV, vec)

#define SOFTEN_TEST_HV_201(vec) \
KVMTEST(vec); \
_SOFTEN_TEST(EXC_STD)
_SOFTEN_TEST(EXC_STD, vec)

#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
HMT_MEDIUM; \
Expand Down Expand Up @@ -279,22 +286,7 @@ label##_hv: \
*/

/* Exception addition: Hard disable interrupts */
#ifdef CONFIG_TRACE_IRQFLAGS
#define DISABLE_INTS \
lbz r10,PACASOFTIRQEN(r13); \
li r11,0; \
cmpwi cr0,r10,0; \
stb r11,PACAHARDIRQEN(r13); \
beq 44f; \
stb r11,PACASOFTIRQEN(r13); \
TRACE_DISABLE_INTS; \
44:
#else
#define DISABLE_INTS \
li r11,0; \
stb r11,PACASOFTIRQEN(r13); \
stb r11,PACAHARDIRQEN(r13)
#endif /* CONFIG_TRACE_IRQFLAGS */
#define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11)

/* Exception addition: Keep interrupt state */
#define ENABLE_INTS \
Expand Down
49 changes: 42 additions & 7 deletions trunk/arch/powerpc/include/asm/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@
#include <asm/ptrace.h>
#include <asm/processor.h>

#ifdef CONFIG_PPC64

/*
* PACA flags in paca->irq_happened.
*
* This bits are set when interrupts occur while soft-disabled
* and allow a proper replay. Additionally, PACA_IRQ_HARD_DIS
* is set whenever we manually hard disable.
*/
#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_EE_EDGE 0x10 /* BookE only */

#endif /* CONFIG_PPC64 */

#ifndef __ASSEMBLY__

extern void __replay_interrupt(unsigned int vector);

extern void timer_interrupt(struct pt_regs *);

#ifdef CONFIG_PPC64
Expand Down Expand Up @@ -42,7 +63,6 @@ static inline unsigned long arch_local_irq_disable(void)
}

extern void arch_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);

static inline void arch_local_irq_enable(void)
{
Expand Down Expand Up @@ -72,12 +92,24 @@ static inline bool arch_irqs_disabled(void)
#define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1)
#endif

#define hard_irq_disable() \
do { \
__hard_irq_disable(); \
get_paca()->soft_enabled = 0; \
get_paca()->hard_enabled = 0; \
} while(0)
static inline void hard_irq_disable(void)
{
__hard_irq_disable();
get_paca()->soft_enabled = 0;
get_paca()->irq_happened |= PACA_IRQ_HARD_DIS;
}

/*
* This is called by asynchronous interrupts to conditionally
* re-enable hard interrupts when soft-disabled after having
* cleared the source of the interrupt
*/
static inline void may_hard_irq_enable(void)
{
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
if (!(get_paca()->irq_happened & PACA_IRQ_EE))
__hard_irq_enable();
}

static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
Expand Down Expand Up @@ -149,6 +181,8 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
return !(regs->msr & MSR_EE);
}

static inline void may_hard_irq_enable(void) { }

#endif /* CONFIG_PPC64 */

#define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST
Expand All @@ -159,5 +193,6 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
*/
struct irq_chip;

#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */
37 changes: 22 additions & 15 deletions trunk/arch/powerpc/include/asm/irqflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,31 @@
#define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on)
#define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off)

#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
cmpdi en,0; \
bne 95f; \
stb en,PACASOFTIRQEN(r13); \
TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off) \
b skip; \
95: TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on) \
li en,1;
#define TRACE_AND_RESTORE_IRQ(en) \
TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \
stb en,PACASOFTIRQEN(r13); \
96:
/*
* This is used by assembly code to soft-disable interrupts
*/
#define SOFT_DISABLE_INTS(__rA, __rB) \
lbz __rA,PACASOFTIRQEN(r13); \
lbz __rB,PACAIRQHAPPENED(r13); \
cmpwi cr0,__rA,0; \
li __rA,0; \
ori __rB,__rB,PACA_IRQ_HARD_DIS; \
stb __rB,PACAIRQHAPPENED(r13); \
beq 44f; \
stb __rA,PACASOFTIRQEN(r13); \
TRACE_DISABLE_INTS; \
44:

#else
#define TRACE_ENABLE_INTS
#define TRACE_DISABLE_INTS
#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip)
#define TRACE_AND_RESTORE_IRQ(en) \
stb en,PACASOFTIRQEN(r13)

#define SOFT_DISABLE_INTS(__rA, __rB) \
lbz __rA,PACAIRQHAPPENED(r13); \
li __rB,0; \
ori __rA,__rA,PACA_IRQ_HARD_DIS; \
stb __rB,PACASOFTIRQEN(r13); \
stb __rA,PACAIRQHAPPENED(r13)
#endif
#endif

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/include/asm/paca.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct paca_struct {
u64 saved_msr; /* MSR saved here by enter_rtas */
u16 trap_save; /* Used when bad stack is encountered */
u8 soft_enabled; /* irq soft-enable flag */
u8 hard_enabled; /* set if irqs are enabled in MSR */
u8 irq_happened; /* irq happened while soft-disabled */
u8 io_sync; /* writel() needs spin_unlock sync */
u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
u8 nap_state_lost; /* NV GPR values lost in power7_idle */
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int main(void)
DEFINE(PACAKBASE, offsetof(struct paca_struct, kernelbase));
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
#ifdef CONFIG_PPC_MM_SLICES
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/kernel/dbell.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ void doorbell_exception(struct pt_regs *regs)

irq_enter();

may_hard_irq_enable();

smp_ipi_demux();

irq_exit();
Expand Down
Loading

0 comments on commit 6c5594a

Please sign in to comment.