diff options
Diffstat (limited to 'arch/powerpc/include/asm/irqflags.h')
| -rw-r--r-- | arch/powerpc/include/asm/irqflags.h | 62 | 
1 files changed, 45 insertions, 17 deletions
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h index b85d8ddbb66..e20eb95429a 100644 --- a/arch/powerpc/include/asm/irqflags.h +++ b/arch/powerpc/include/asm/irqflags.h @@ -12,31 +12,59 @@  #else  #ifdef CONFIG_TRACE_IRQFLAGS +#ifdef CONFIG_IRQSOFF_TRACER +/* + * Since the ftrace irqsoff latency trace checks CALLER_ADDR1, + * which is the stack frame here, we need to force a stack frame + * in case we came from user space. + */ +#define TRACE_WITH_FRAME_BUFFER(func)		\ +	mflr	r0;				\ +	stdu	r1, -STACK_FRAME_OVERHEAD(r1);	\ +	std	r0, 16(r1);			\ +	stdu	r1, -STACK_FRAME_OVERHEAD(r1);	\ +	bl func;				\ +	ld	r1, 0(r1);			\ +	ld	r1, 0(r1); +#else +#define TRACE_WITH_FRAME_BUFFER(func)		\ +	bl func; +#endif +  /*   * Most of the CPU's IRQ-state tracing is done from assembly code; we   * have to call a C function so call a wrapper that saves all the   * C-clobbered registers.   */ -#define TRACE_ENABLE_INTS	bl .trace_hardirqs_on -#define TRACE_DISABLE_INTS	bl .trace_hardirqs_off -#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip)	\ -	cmpdi	en,0;				\ -	bne	95f;				\ -	stb	en,PACASOFTIRQEN(r13);		\ -	bl	.trace_hardirqs_off;		\ -	b	skip;				\ -95:	bl	.trace_hardirqs_on;		\ -	li	en,1; -#define TRACE_AND_RESTORE_IRQ(en)		\ -	TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f);	\ -	stb	en,PACASOFTIRQEN(r13);	        \ -96: +#define TRACE_ENABLE_INTS	TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on) +#define TRACE_DISABLE_INTS	TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off) + +/* + * This is used by assembly code to soft-disable interrupts first and + * reconcile irq state. + */ +#define RECONCILE_IRQ_STATE(__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 RECONCILE_IRQ_STATE(__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  | 
