mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	powerpc: Add irqtrace support for 32-bit powerpc
Based on initial work from: Dale Farnsworth <dale@farnsworth.org> Add the low level irq tracing hooks for 32-bit powerpc needed to enable full lockdep functionality. The approach taken to deal with the code in entry_32.S is that we don't trace all the transitions of MSR:EE when we just turn it off to peek at TI_FLAGS without races. Only when we are calling into C code or returning from exceptions with a state that have changed from what lockdep thinks. There's a little bugger though: If we take an exception that keeps interrupts enabled (such as an alignment exception) while interrupts are enabled, we will call trace_hardirqs_on() on the way back spurriously. Not a big deal, but to get rid of it would require remembering in pt_regs that the exception was one of the type that kept interrupts enabled which we don't know at this stage. (Well, we could test all cases for regs->trap but that sucks too much). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Tested-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
		
							parent
							
								
									04a85d1234
								
							
						
					
					
						commit
						5d38902c48
					
				
					 4 changed files with 135 additions and 15 deletions
				
			
		| 
						 | 
					@ -62,7 +62,6 @@ config HAVE_LATENCYTOP_SUPPORT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config TRACE_IRQFLAGS_SUPPORT
 | 
					config TRACE_IRQFLAGS_SUPPORT
 | 
				
			||||||
	bool
 | 
						bool
 | 
				
			||||||
	depends on PPC64
 | 
					 | 
				
			||||||
	default y
 | 
						default y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config LOCKDEP_SUPPORT
 | 
					config LOCKDEP_SUPPORT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(unsigned long flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_BOOKE)
 | 
					#if defined(CONFIG_BOOKE)
 | 
				
			||||||
#define SET_MSR_EE(x)	mtmsr(x)
 | 
					#define SET_MSR_EE(x)	mtmsr(x)
 | 
				
			||||||
#define local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
 | 
					#define raw_local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SET_MSR_EE(x)	mtmsr(x)
 | 
					#define SET_MSR_EE(x)	mtmsr(x)
 | 
				
			||||||
#define local_irq_restore(flags)	mtmsr(flags)
 | 
					#define raw_local_irq_restore(flags)	mtmsr(flags)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void local_irq_disable(void)
 | 
					static inline void raw_local_irq_disable(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_BOOKE
 | 
					#ifdef CONFIG_BOOKE
 | 
				
			||||||
	__asm__ __volatile__("wrteei 0": : :"memory");
 | 
						__asm__ __volatile__("wrteei 0": : :"memory");
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ static inline void local_irq_disable(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void local_irq_enable(void)
 | 
					static inline void raw_local_irq_enable(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_BOOKE
 | 
					#ifdef CONFIG_BOOKE
 | 
				
			||||||
	__asm__ __volatile__("wrteei 1": : :"memory");
 | 
						__asm__ __volatile__("wrteei 1": : :"memory");
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ static inline void local_irq_enable(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void local_irq_save_ptr(unsigned long *flags)
 | 
					static inline void raw_local_irq_save_ptr(unsigned long *flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long msr;
 | 
						unsigned long msr;
 | 
				
			||||||
	msr = mfmsr();
 | 
						msr = mfmsr();
 | 
				
			||||||
| 
						 | 
					@ -110,12 +110,12 @@ static inline void local_irq_save_ptr(unsigned long *flags)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define local_save_flags(flags)	((flags) = mfmsr())
 | 
					#define raw_local_save_flags(flags)	((flags) = mfmsr())
 | 
				
			||||||
#define local_irq_save(flags)	local_irq_save_ptr(&flags)
 | 
					#define raw_local_irq_save(flags)	raw_local_irq_save_ptr(&flags)
 | 
				
			||||||
#define irqs_disabled()		((mfmsr() & MSR_EE) == 0)
 | 
					#define raw_irqs_disabled()		((mfmsr() & MSR_EE) == 0)
 | 
				
			||||||
 | 
					#define raw_irqs_disabled_flags(flags)	(((flags) & MSR_EE) == 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define hard_irq_enable()	local_irq_enable()
 | 
					#define hard_irq_disable()		raw_local_irq_disable()
 | 
				
			||||||
#define hard_irq_disable()	local_irq_disable()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int irqs_disabled_flags(unsigned long flags)
 | 
					static inline int irqs_disabled_flags(unsigned long flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,11 +191,49 @@ transfer_to_handler_cont:
 | 
				
			||||||
	mflr	r9
 | 
						mflr	r9
 | 
				
			||||||
	lwz	r11,0(r9)		/* virtual address of handler */
 | 
						lwz	r11,0(r9)		/* virtual address of handler */
 | 
				
			||||||
	lwz	r9,4(r9)		/* where to go when done */
 | 
						lwz	r9,4(r9)		/* where to go when done */
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						lis	r12,reenable_mmu@h
 | 
				
			||||||
 | 
						ori	r12,r12,reenable_mmu@l
 | 
				
			||||||
 | 
						mtspr	SPRN_SRR0,r12
 | 
				
			||||||
 | 
						mtspr	SPRN_SRR1,r10
 | 
				
			||||||
 | 
						SYNC
 | 
				
			||||||
 | 
						RFI
 | 
				
			||||||
 | 
					reenable_mmu:				/* re-enable mmu so we can */
 | 
				
			||||||
 | 
						mfmsr	r10
 | 
				
			||||||
 | 
						lwz	r12,_MSR(r1)
 | 
				
			||||||
 | 
						xor	r10,r10,r12
 | 
				
			||||||
 | 
						andi.	r10,r10,MSR_EE		/* Did EE change? */
 | 
				
			||||||
 | 
						beq	1f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Save handler and return address into the 2 unused words
 | 
				
			||||||
 | 
						 * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything
 | 
				
			||||||
 | 
						 * else can be recovered from the pt_regs except r3 which for
 | 
				
			||||||
 | 
						 * normal interrupts has been set to pt_regs and for syscalls
 | 
				
			||||||
 | 
						 * is an argument, so we temporarily use ORIG_GPR3 to save it
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						stw	r9,8(r1)
 | 
				
			||||||
 | 
						stw	r11,12(r1)
 | 
				
			||||||
 | 
						stw	r3,ORIG_GPR3(r1)
 | 
				
			||||||
 | 
						bl	trace_hardirqs_off
 | 
				
			||||||
 | 
						lwz	r0,GPR0(r1)
 | 
				
			||||||
 | 
						lwz	r3,ORIG_GPR3(r1)
 | 
				
			||||||
 | 
						lwz	r4,GPR4(r1)
 | 
				
			||||||
 | 
						lwz	r5,GPR5(r1)
 | 
				
			||||||
 | 
						lwz	r6,GPR6(r1)
 | 
				
			||||||
 | 
						lwz	r7,GPR7(r1)
 | 
				
			||||||
 | 
						lwz	r8,GPR8(r1)
 | 
				
			||||||
 | 
						lwz	r9,8(r1)
 | 
				
			||||||
 | 
						lwz	r11,12(r1)
 | 
				
			||||||
 | 
					1:	mtctr	r11
 | 
				
			||||||
 | 
						mtlr	r9
 | 
				
			||||||
 | 
						bctr				/* jump to handler */
 | 
				
			||||||
 | 
					#else /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
	mtspr	SPRN_SRR0,r11
 | 
						mtspr	SPRN_SRR0,r11
 | 
				
			||||||
	mtspr	SPRN_SRR1,r10
 | 
						mtspr	SPRN_SRR1,r10
 | 
				
			||||||
	mtlr	r9
 | 
						mtlr	r9
 | 
				
			||||||
	SYNC
 | 
						SYNC
 | 
				
			||||||
	RFI				/* jump to handler, enable MMU */
 | 
						RFI				/* jump to handler, enable MMU */
 | 
				
			||||||
 | 
					#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined (CONFIG_6xx) || defined(CONFIG_E500)
 | 
					#if defined (CONFIG_6xx) || defined(CONFIG_E500)
 | 
				
			||||||
4:	rlwinm	r12,r12,0,~_TLF_NAPPING
 | 
					4:	rlwinm	r12,r12,0,~_TLF_NAPPING
 | 
				
			||||||
| 
						 | 
					@ -251,6 +289,31 @@ _GLOBAL(DoSyscall)
 | 
				
			||||||
#ifdef SHOW_SYSCALLS
 | 
					#ifdef SHOW_SYSCALLS
 | 
				
			||||||
	bl	do_show_syscall
 | 
						bl	do_show_syscall
 | 
				
			||||||
#endif /* SHOW_SYSCALLS */
 | 
					#endif /* SHOW_SYSCALLS */
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						/* Return from syscalls can (and generally will) hard enable
 | 
				
			||||||
 | 
						 * interrupts. You aren't supposed to call a syscall with
 | 
				
			||||||
 | 
						 * interrupts disabled in the first place. However, to ensure
 | 
				
			||||||
 | 
						 * that we get it right vs. lockdep if it happens, we force
 | 
				
			||||||
 | 
						 * that hard enable here with appropriate tracing if we see
 | 
				
			||||||
 | 
						 * that we have been called with interrupts off
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						mfmsr	r11
 | 
				
			||||||
 | 
						andi.	r12,r11,MSR_EE
 | 
				
			||||||
 | 
						bne+	1f
 | 
				
			||||||
 | 
						/* We came in with interrupts disabled, we enable them now */
 | 
				
			||||||
 | 
						bl	trace_hardirqs_on
 | 
				
			||||||
 | 
						mfmsr	r11
 | 
				
			||||||
 | 
						lwz	r0,GPR0(r1)
 | 
				
			||||||
 | 
						lwz	r3,GPR3(r1)
 | 
				
			||||||
 | 
						lwz	r4,GPR4(r1)
 | 
				
			||||||
 | 
						ori	r11,r11,MSR_EE
 | 
				
			||||||
 | 
						lwz	r5,GPR5(r1)
 | 
				
			||||||
 | 
						lwz	r6,GPR6(r1)
 | 
				
			||||||
 | 
						lwz	r7,GPR7(r1)
 | 
				
			||||||
 | 
						lwz	r8,GPR8(r1)
 | 
				
			||||||
 | 
						mtmsr	r11
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
 | 
					#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
 | 
						rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
 | 
				
			||||||
	lwz	r11,TI_FLAGS(r10)
 | 
						lwz	r11,TI_FLAGS(r10)
 | 
				
			||||||
	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 | 
						andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 | 
				
			||||||
| 
						 | 
					@ -275,6 +338,7 @@ ret_from_syscall:
 | 
				
			||||||
	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
 | 
						rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
 | 
				
			||||||
	/* disable interrupts so current_thread_info()->flags can't change */
 | 
						/* disable interrupts so current_thread_info()->flags can't change */
 | 
				
			||||||
	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 | 
						LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 | 
				
			||||||
 | 
						/* Note: We don't bother telling lockdep about it */
 | 
				
			||||||
	SYNC
 | 
						SYNC
 | 
				
			||||||
	MTMSRD(r10)
 | 
						MTMSRD(r10)
 | 
				
			||||||
	lwz	r9,TI_FLAGS(r12)
 | 
						lwz	r9,TI_FLAGS(r12)
 | 
				
			||||||
| 
						 | 
					@ -288,6 +352,19 @@ ret_from_syscall:
 | 
				
			||||||
	oris	r11,r11,0x1000	/* Set SO bit in CR */
 | 
						oris	r11,r11,0x1000	/* Set SO bit in CR */
 | 
				
			||||||
	stw	r11,_CCR(r1)
 | 
						stw	r11,_CCR(r1)
 | 
				
			||||||
syscall_exit_cont:
 | 
					syscall_exit_cont:
 | 
				
			||||||
 | 
						lwz	r8,_MSR(r1)
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						/* If we are going to return from the syscall with interrupts
 | 
				
			||||||
 | 
						 * off, we trace that here. It shouldn't happen though but we
 | 
				
			||||||
 | 
						 * want to catch the bugger if it does right ?
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						andi.	r10,r8,MSR_EE
 | 
				
			||||||
 | 
						bne+	1f
 | 
				
			||||||
 | 
						stw	r3,GPR3(r1)
 | 
				
			||||||
 | 
						bl      trace_hardirqs_off
 | 
				
			||||||
 | 
						lwz	r3,GPR3(r1)
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
 | 
					#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 | 
					#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 | 
				
			||||||
	/* If the process has its own DBCR0 value, load it up.  The internal
 | 
						/* If the process has its own DBCR0 value, load it up.  The internal
 | 
				
			||||||
	   debug mode bit tells us that dbcr0 should be loaded. */
 | 
						   debug mode bit tells us that dbcr0 should be loaded. */
 | 
				
			||||||
| 
						 | 
					@ -311,7 +388,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 | 
				
			||||||
	mtlr	r4
 | 
						mtlr	r4
 | 
				
			||||||
	mtcr	r5
 | 
						mtcr	r5
 | 
				
			||||||
	lwz	r7,_NIP(r1)
 | 
						lwz	r7,_NIP(r1)
 | 
				
			||||||
	lwz	r8,_MSR(r1)
 | 
					 | 
				
			||||||
	FIX_SRR1(r8, r0)
 | 
						FIX_SRR1(r8, r0)
 | 
				
			||||||
	lwz	r2,GPR2(r1)
 | 
						lwz	r2,GPR2(r1)
 | 
				
			||||||
	lwz	r1,GPR1(r1)
 | 
						lwz	r1,GPR1(r1)
 | 
				
			||||||
| 
						 | 
					@ -394,7 +470,9 @@ syscall_exit_work:
 | 
				
			||||||
	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
 | 
						andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
 | 
				
			||||||
	beq	ret_from_except
 | 
						beq	ret_from_except
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Re-enable interrupts */
 | 
						/* Re-enable interrupts. There is no need to trace that with
 | 
				
			||||||
 | 
						 * lockdep as we are supposed to have IRQs on at this point
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	ori	r10,r10,MSR_EE
 | 
						ori	r10,r10,MSR_EE
 | 
				
			||||||
	SYNC
 | 
						SYNC
 | 
				
			||||||
	MTMSRD(r10)
 | 
						MTMSRD(r10)
 | 
				
			||||||
| 
						 | 
					@ -705,6 +783,7 @@ ret_from_except:
 | 
				
			||||||
	/* Hard-disable interrupts so that current_thread_info()->flags
 | 
						/* Hard-disable interrupts so that current_thread_info()->flags
 | 
				
			||||||
	 * can't change between when we test it and when we return
 | 
						 * can't change between when we test it and when we return
 | 
				
			||||||
	 * from the interrupt. */
 | 
						 * from the interrupt. */
 | 
				
			||||||
 | 
						/* Note: We don't bother telling lockdep about it */
 | 
				
			||||||
	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 | 
						LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 | 
				
			||||||
	SYNC			/* Some chip revs have problems here... */
 | 
						SYNC			/* Some chip revs have problems here... */
 | 
				
			||||||
	MTMSRD(r10)		/* disable interrupts */
 | 
						MTMSRD(r10)		/* disable interrupts */
 | 
				
			||||||
| 
						 | 
					@ -744,11 +823,24 @@ resume_kernel:
 | 
				
			||||||
	beq+	restore
 | 
						beq+	restore
 | 
				
			||||||
	andi.	r0,r3,MSR_EE	/* interrupts off? */
 | 
						andi.	r0,r3,MSR_EE	/* interrupts off? */
 | 
				
			||||||
	beq	restore		/* don't schedule if so */
 | 
						beq	restore		/* don't schedule if so */
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						/* Lockdep thinks irqs are enabled, we need to call
 | 
				
			||||||
 | 
						 * preempt_schedule_irq with IRQs off, so we inform lockdep
 | 
				
			||||||
 | 
						 * now that we -did- turn them off already
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bl	trace_hardirqs_off
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
1:	bl	preempt_schedule_irq
 | 
					1:	bl	preempt_schedule_irq
 | 
				
			||||||
	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
 | 
						rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
 | 
				
			||||||
	lwz	r3,TI_FLAGS(r9)
 | 
						lwz	r3,TI_FLAGS(r9)
 | 
				
			||||||
	andi.	r0,r3,_TIF_NEED_RESCHED
 | 
						andi.	r0,r3,_TIF_NEED_RESCHED
 | 
				
			||||||
	bne-	1b
 | 
						bne-	1b
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						/* And now, to properly rebalance the above, we tell lockdep they
 | 
				
			||||||
 | 
						 * are being turned back on, which will happen when we return
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bl	trace_hardirqs_on
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
resume_kernel:
 | 
					resume_kernel:
 | 
				
			||||||
#endif /* CONFIG_PREEMPT */
 | 
					#endif /* CONFIG_PREEMPT */
 | 
				
			||||||
| 
						 | 
					@ -765,6 +857,28 @@ restore:
 | 
				
			||||||
	stw	r6,icache_44x_need_flush@l(r4)
 | 
						stw	r6,icache_44x_need_flush@l(r4)
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
#endif  /* CONFIG_44x */
 | 
					#endif  /* CONFIG_44x */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lwz	r9,_MSR(r1)
 | 
				
			||||||
 | 
					#ifdef CONFIG_TRACE_IRQFLAGS
 | 
				
			||||||
 | 
						/* Lockdep doesn't know about the fact that IRQs are temporarily turned
 | 
				
			||||||
 | 
						 * off in this assembly code while peeking at TI_FLAGS() and such. However
 | 
				
			||||||
 | 
						 * we need to inform it if the exception turned interrupts off, and we
 | 
				
			||||||
 | 
						 * are about to trun them back on.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * The problem here sadly is that we don't know whether the exceptions was
 | 
				
			||||||
 | 
						 * one that turned interrupts off or not. So we always tell lockdep about
 | 
				
			||||||
 | 
						 * turning them on here when we go back to wherever we came from with EE
 | 
				
			||||||
 | 
						 * on, even if that may meen some redudant calls being tracked. Maybe later
 | 
				
			||||||
 | 
						 * we could encode what the exception did somewhere or test the exception
 | 
				
			||||||
 | 
						 * type in the pt_regs but that sounds overkill
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						andi.	r10,r9,MSR_EE
 | 
				
			||||||
 | 
						beq	1f
 | 
				
			||||||
 | 
						bl	trace_hardirqs_on
 | 
				
			||||||
 | 
						lwz	r9,_MSR(r1)
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
 | 
					#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lwz	r0,GPR0(r1)
 | 
						lwz	r0,GPR0(r1)
 | 
				
			||||||
	lwz	r2,GPR2(r1)
 | 
						lwz	r2,GPR2(r1)
 | 
				
			||||||
	REST_4GPRS(3, r1)
 | 
						REST_4GPRS(3, r1)
 | 
				
			||||||
| 
						 | 
					@ -782,7 +896,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 | 
				
			||||||
	stwcx.	r0,0,r1			/* to clear the reservation */
 | 
						stwcx.	r0,0,r1			/* to clear the reservation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
 | 
					#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
 | 
				
			||||||
	lwz	r9,_MSR(r1)
 | 
					 | 
				
			||||||
	andi.	r10,r9,MSR_RI		/* check if this exception occurred */
 | 
						andi.	r10,r9,MSR_RI		/* check if this exception occurred */
 | 
				
			||||||
	beql	nonrecoverable		/* at a bad place (MSR:RI = 0) */
 | 
						beql	nonrecoverable		/* at a bad place (MSR:RI = 0) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -805,7 +918,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 | 
				
			||||||
	MTMSRD(r10)		/* clear the RI bit */
 | 
						MTMSRD(r10)		/* clear the RI bit */
 | 
				
			||||||
	.globl exc_exit_restart
 | 
						.globl exc_exit_restart
 | 
				
			||||||
exc_exit_restart:
 | 
					exc_exit_restart:
 | 
				
			||||||
	lwz	r9,_MSR(r1)
 | 
					 | 
				
			||||||
	lwz	r12,_NIP(r1)
 | 
						lwz	r12,_NIP(r1)
 | 
				
			||||||
	FIX_SRR1(r9,r10)
 | 
						FIX_SRR1(r9,r10)
 | 
				
			||||||
	mtspr	SPRN_SRR0,r12
 | 
						mtspr	SPRN_SRR0,r12
 | 
				
			||||||
| 
						 | 
					@ -1035,11 +1147,18 @@ do_work:			/* r10 contains MSR_KERNEL here */
 | 
				
			||||||
	beq	do_user_signal
 | 
						beq	do_user_signal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
do_resched:			/* r10 contains MSR_KERNEL here */
 | 
					do_resched:			/* r10 contains MSR_KERNEL here */
 | 
				
			||||||
 | 
						/* Note: We don't need to inform lockdep that we are enabling
 | 
				
			||||||
 | 
						 * interrupts here. As far as it knows, they are already enabled
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	ori	r10,r10,MSR_EE
 | 
						ori	r10,r10,MSR_EE
 | 
				
			||||||
	SYNC
 | 
						SYNC
 | 
				
			||||||
	MTMSRD(r10)		/* hard-enable interrupts */
 | 
						MTMSRD(r10)		/* hard-enable interrupts */
 | 
				
			||||||
	bl	schedule
 | 
						bl	schedule
 | 
				
			||||||
recheck:
 | 
					recheck:
 | 
				
			||||||
 | 
						/* Note: And we don't tell it we are disabling them again
 | 
				
			||||||
 | 
						 * neither. Those disable/enable cycles used to peek at
 | 
				
			||||||
 | 
						 * TI_FLAGS aren't advertised.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 | 
						LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 | 
				
			||||||
	SYNC
 | 
						SYNC
 | 
				
			||||||
	MTMSRD(r10)		/* disable interrupts */
 | 
						MTMSRD(r10)		/* disable interrupts */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,6 +119,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
notrace void __init machine_init(unsigned long dt_ptr)
 | 
					notrace void __init machine_init(unsigned long dt_ptr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						lockdep_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Enable early debugging if any specified (see udbg.h) */
 | 
						/* Enable early debugging if any specified (see udbg.h) */
 | 
				
			||||||
	udbg_early_init();
 | 
						udbg_early_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue