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

Commit 945feb17 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras
Browse files

[POWERPC] irqtrace support for 64-bit powerpc



This adds the low level irq tracing hooks to the powerpc architecture
needed to enable full lockdep functionality.

This is partly based on Johannes Berg's initial version.  I removed
the asm trampoline that isn't needed (thus improving performance) and
modified all sorts of bits and pieces, reworking most of the assembly,
etc...

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent fd3e0bbc
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -53,6 +53,15 @@ config STACKTRACE_SUPPORT
	bool
	default y

config TRACE_IRQFLAGS_SUPPORT
	bool
	depends on PPC64
	default y

config LOCKDEP_SUPPORT
	bool
	default y

config RWSEM_GENERIC_SPINLOCK
	bool

+25 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <asm/firmware.h>
#include <asm/bug.h>
#include <asm/ptrace.h>
#include <asm/irqflags.h>

/*
 * System calls.
@@ -89,6 +90,14 @@ system_call_common:
	addi	r9,r1,STACK_FRAME_OVERHEAD
	ld	r11,exception_marker@toc(r2)
	std	r11,-16(r9)		/* "regshere" marker */
#ifdef CONFIG_TRACE_IRQFLAGS
	bl	.trace_hardirqs_on
	REST_GPR(0,r1)
	REST_4GPRS(3,r1)
	REST_2GPRS(7,r1)
	addi	r9,r1,STACK_FRAME_OVERHEAD
	ld	r12,_MSR(r1)
#endif /* CONFIG_TRACE_IRQFLAGS */
	li	r10,1
	stb	r10,PACASOFTIRQEN(r13)
	stb	r10,PACAHARDIRQEN(r13)
@@ -103,7 +112,7 @@ BEGIN_FW_FTR_SECTION
	b	hardware_interrupt_entry
2:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
#endif /* CONFIG_PPC_ISERIES */
	mfmsr	r11
	ori	r11,r11,MSR_EE
	mtmsrd	r11,1
@@ -505,6 +514,10 @@ BEGIN_FW_FTR_SECTION

	li	r3,0
	stb	r3,PACASOFTIRQEN(r13)	/* ensure we are soft-disabled */
#ifdef CONFIG_TRACE_IRQFLAGS
	bl	.trace_hardirqs_off
	mfmsr	r10
#endif
	ori	r10,r10,MSR_EE
	mtmsrd	r10			/* hard-enable again */
	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -513,7 +526,7 @@ BEGIN_FW_FTR_SECTION
4:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
	stb	r5,PACASOFTIRQEN(r13)
	TRACE_AND_RESTORE_IRQ(r5);

	/* extract EE bit and use it to restore paca->hard_enabled */
	ld	r3,_MSR(r1)
@@ -581,6 +594,16 @@ do_work:
	bne	restore
	/* here we are preempting the current task */
1:
#ifdef CONFIG_TRACE_IRQFLAGS
	bl	.trace_hardirqs_on
	/* Note: we just clobbered r10 which used to contain the previous
	 * MSR before the hard-disabling done by the caller of do_work.
	 * We don't have that value anymore, but it doesn't matter as
	 * we will hard-enable unconditionally, we can just reload the
	 * current MSR into r10
	 */
	mfmsr	r10
#endif /* CONFIG_TRACE_IRQFLAGS */
	li	r0,1
	stb	r0,PACASOFTIRQEN(r13)
	stb	r0,PACAHARDIRQEN(r13)
+32 −15
Original line number Diff line number Diff line
@@ -36,8 +36,7 @@
#include <asm/firmware.h>
#include <asm/page_64.h>
#include <asm/exception.h>

#define DO_SOFT_DISABLE
#include <asm/irqflags.h>

/*
 * We layout physical memory as follows:
@@ -450,8 +449,8 @@ bad_stack:
 */
fast_exc_return_irq:			/* restores irq state too */
	ld	r3,SOFTE(r1)
	TRACE_AND_RESTORE_IRQ(r3);
	ld	r12,_MSR(r1)
	stb	r3,PACASOFTIRQEN(r13)	/* restore paca->soft_enabled */
	rldicl	r4,r12,49,63		/* get MSR_EE to LSB */
	stb	r4,PACAHARDIRQEN(r13)	/* restore paca->hard_enabled */
	b	1f
@@ -824,7 +823,7 @@ _STATIC(load_up_altivec)
 * Hash table stuff
 */
	.align	7
_GLOBAL(do_hash_page)
_STATIC(do_hash_page)
	std	r3,_DAR(r1)
	std	r4,_DSISR(r1)

@@ -835,6 +834,27 @@ BEGIN_FTR_SECTION
	bne-	do_ste_alloc		/* If so handle it */
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)

	/*
	 * On iSeries, we soft-disable interrupts here, then
	 * hard-enable interrupts so that the hash_page code can spin on
	 * the hash_table_lock without problems on a shared processor.
	 */
	DISABLE_INTS

	/*
	 * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
	 * and will clobber volatile registers when irq tracing is enabled
	 * so we need to reload them. It may be possible to be smarter here
	 * and move the irq tracing elsewhere but let's keep it simple for
	 * now
	 */
#ifdef CONFIG_TRACE_IRQFLAGS
	ld	r3,_DAR(r1)
	ld	r4,_DSISR(r1)
	ld	r5,_TRAP(r1)
	ld	r12,_MSR(r1)
	clrrdi	r5,r5,4
#endif /* CONFIG_TRACE_IRQFLAGS */
	/*
	 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
	 * accessing a userspace segment (even from the kernel). We assume
@@ -847,13 +867,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
	ori	r4,r4,1			/* add _PAGE_PRESENT */
	rlwimi	r4,r5,22+2,31-2,31-2	/* Set _PAGE_EXEC if trap is 0x400 */

	/*
	 * On iSeries, we soft-disable interrupts here, then
	 * hard-enable interrupts so that the hash_page code can spin on
	 * the hash_table_lock without problems on a shared processor.
	 */
	DISABLE_INTS

	/*
	 * r3 contains the faulting address
	 * r4 contains the required access permissions
@@ -864,7 +877,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
	bl	.hash_page		/* build HPTE if possible */
	cmpdi	r3,0			/* see if hash_page succeeded */

#ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
	/*
	 * If we had interrupts soft-enabled at the point where the
@@ -876,7 +888,7 @@ BEGIN_FW_FTR_SECTION
	 */
	beq	13f
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif

BEGIN_FW_FTR_SECTION
	/*
	 * Here we have interrupts hard-disabled, so it is sufficient
@@ -890,11 +902,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)

	/*
	 * hash_page couldn't handle it, set soft interrupt enable back
	 * to what it was before the trap.  Note that .local_irq_restore
	 * to what it was before the trap.  Note that .raw_local_irq_restore
	 * handles any interrupts pending at this point.
	 */
	ld	r3,SOFTE(r1)
	bl	.local_irq_restore
	TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
	bl	.raw_local_irq_restore
	b	11f

/* Here we have a page fault that hash_page can't handle. */
@@ -1493,6 +1506,10 @@ _INIT_STATIC(start_here_multiplatform)
	addi	r2,r2,0x4000
	add	r2,r2,r26

	/* Set initial ptr to current */
	LOAD_REG_IMMEDIATE(r4, init_task)
	std	r4,PACACURRENT(r13)

	/* Do very early kernel initializations, including initial hash table,
	 * stab and slb setup before we turn on relocation.	*/

+2 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsigned long enable)
	: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}

void local_irq_restore(unsigned long en)
void raw_local_irq_restore(unsigned long en)
{
	/*
	 * get_paca()->soft_enabled = en;
@@ -174,6 +174,7 @@ void local_irq_restore(unsigned long en)

	__hard_irq_enable();
}
EXPORT_SYMBOL(raw_local_irq_restore);
#endif /* CONFIG_PPC64 */

int show_interrupts(struct seq_file *p, void *v)
+0 −4
Original line number Diff line number Diff line
@@ -45,10 +45,6 @@
#include <asm/signal.h>
#include <asm/dcr.h>

#ifdef CONFIG_PPC64
EXPORT_SYMBOL(local_irq_restore);
#endif

#ifdef CONFIG_PPC32
extern void transfer_to_handler(void);
extern void do_IRQ(struct pt_regs *regs);
Loading