Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d928b0b authored by Uwe Kleine-König's avatar Uwe Kleine-König
Browse files

Complete irq tracing support for ARM



Before this patch enabling and disabling irqs in assembler code and by
the hardware wasn't tracked completly.

I had to transpose two instructions in arch/arm/lib/bitops.h because
restore_irqs doesn't preserve the flags with CONFIG_TRACE_IRQFLAGS=y

Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>

Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
parent 181f817e
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -74,23 +74,56 @@
 * Enable and disable interrupts
 */
#if __LINUX_ARM_ARCH__ >= 6
	.macro	disable_irq
	.macro	disable_irq_notrace
	cpsid	i
	.endm

	.macro	enable_irq
	.macro	enable_irq_notrace
	cpsie	i
	.endm
#else
	.macro	disable_irq
	.macro	disable_irq_notrace
	msr	cpsr_c, #PSR_I_BIT | SVC_MODE
	.endm

	.macro	enable_irq
	.macro	enable_irq_notrace
	msr	cpsr_c, #SVC_MODE
	.endm
#endif

	.macro asm_trace_hardirqs_off
#if defined(CONFIG_TRACE_IRQFLAGS)
	stmdb   sp!, {r0-r3, ip, lr}
	bl	trace_hardirqs_off
	ldmia	sp!, {r0-r3, ip, lr}
#endif
	.endm

	.macro asm_trace_hardirqs_on_cond, cond
#if defined(CONFIG_TRACE_IRQFLAGS)
	/*
	 * actually the registers should be pushed and pop'd conditionally, but
	 * after bl the flags are certainly clobbered
	 */
	stmdb   sp!, {r0-r3, ip, lr}
	bl\cond	trace_hardirqs_on
	ldmia	sp!, {r0-r3, ip, lr}
#endif
	.endm

	.macro asm_trace_hardirqs_on
	asm_trace_hardirqs_on_cond al
	.endm

	.macro disable_irq
	disable_irq_notrace
	asm_trace_hardirqs_off
	.endm

	.macro enable_irq
	asm_trace_hardirqs_on
	enable_irq_notrace
	.endm
/*
 * Save the current IRQ state and disable IRQs.  Note that this macro
 * assumes FIQs are enabled, and that the processor is in SVC mode.
@@ -104,10 +137,16 @@
 * Restore interrupt state previously stored in a register.  We don't
 * guarantee that this will preserve the flags.
 */
	.macro	restore_irqs, oldcpsr
	.macro	restore_irqs_notrace, oldcpsr
	msr	cpsr_c, \oldcpsr
	.endm

	.macro restore_irqs, oldcpsr
	tst	\oldcpsr, #PSR_I_BIT
	asm_trace_hardirqs_on_cond eq
	restore_irqs_notrace \oldcpsr
	.endm

#define USER(x...)				\
9999:	x;					\
	.section __ex_table,"a";		\
+4 −6
Original line number Diff line number Diff line
@@ -151,6 +151,8 @@ ENDPROC(__und_invalid)
	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
	@
	stmia	r5, {r0 - r4}

	asm_trace_hardirqs_off
	.endm

	.align	5
@@ -206,9 +208,6 @@ ENDPROC(__dabt_svc)
__irq_svc:
	svc_entry

#ifdef CONFIG_TRACE_IRQFLAGS
	bl	trace_hardirqs_off
#endif
#ifdef CONFIG_PREEMPT
	get_thread_info tsk
	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
@@ -383,6 +382,8 @@ ENDPROC(__pabt_svc)
	@ Clear FP to mark the first stack frame
	@
	zero_fp

	asm_trace_hardirqs_off
	.endm

	.macro	kuser_cmpxchg_check
@@ -437,9 +438,6 @@ __irq_usr:
	usr_entry
	kuser_cmpxchg_check

#ifdef CONFIG_TRACE_IRQFLAGS
	bl	trace_hardirqs_off
#endif
	get_thread_info tsk
#ifdef CONFIG_PREEMPT
	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
+1 −1
Original line number Diff line number Diff line
@@ -60,8 +60,8 @@
	tst	r2, r0, lsl r3
	\instr	r2, r2, r0, lsl r3
	\store	r2, [r1]
	restore_irqs ip
	moveq	r0, #0
	restore_irqs ip
	mov	pc, lr
	.endm
#endif