This one doesn't break 32-bit build by simply disabling irqtrace for 32-bit.
--- arch/powerpc/Kconfig | 9 ++++++ arch/powerpc/kernel/Makefile | 1 arch/powerpc/kernel/entry_64.S | 24 +++++++++++++++++ arch/powerpc/kernel/head_64.S | 54 ++++++++++++++++++++++++++++++++-------- arch/powerpc/kernel/irq.c | 2 - arch/powerpc/kernel/irqtrace.S | 47 ++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/ppc_ksyms.c | 2 - arch/powerpc/kernel/setup_64.c | 6 ++++ include/asm-powerpc/hw_irq.h | 14 +++++----- include/asm-powerpc/irqflags.h | 13 --------- include/asm-powerpc/rwsem.h | 34 +++++++++++++++++++------ include/asm-powerpc/spinlock.h | 1 12 files changed, 167 insertions(+), 40 deletions(-) --- linux-2.6-git32.orig/arch/powerpc/Kconfig 2007-06-28 14:53:58.603430447 +0200 +++ linux-2.6-git32/arch/powerpc/Kconfig 2007-06-28 14:58:02.683430447 +0200 @@ -38,6 +38,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 --- linux-2.6-git32.orig/arch/powerpc/kernel/irq.c 2007-06-28 14:53:58.604430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/irq.c 2007-06-28 14:48:38.709430447 +0200 @@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi : : "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; --- linux-2.6-git32.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-06-28 14:53:58.678430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/ppc_ksyms.c 2007-06-28 14:49:24.887430447 +0200 @@ -50,7 +50,7 @@ #endif #ifdef CONFIG_PPC64 -EXPORT_SYMBOL(local_irq_restore); +EXPORT_SYMBOL(raw_local_irq_restore); #endif #ifdef CONFIG_PPC32 --- linux-2.6-git32.orig/include/asm-powerpc/hw_irq.h 2007-06-28 14:53:58.730430447 +0200 +++ linux-2.6-git32/include/asm-powerpc/hw_irq.h 2007-06-28 14:58:41.508430447 +0200 @@ -27,7 +27,7 @@ static inline unsigned long local_get_fl return flags; } -static inline unsigned long local_irq_disable(void) +static inline unsigned long raw_local_irq_disable(void) { unsigned long flags, zero; @@ -39,14 +39,15 @@ static inline unsigned long local_irq_di return flags; } -extern void local_irq_restore(unsigned long); +extern void raw_local_irq_restore(unsigned long); extern void iseries_handle_interrupts(void); -#define local_irq_enable() local_irq_restore(1) -#define local_save_flags(flags) ((flags) = local_get_flags()) -#define local_irq_save(flags) ((flags) = local_irq_disable()) +#define raw_local_irq_enable() raw_local_irq_restore(1) +#define raw_local_save_flags(flags) ((flags) = local_get_flags()) +#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable()) -#define irqs_disabled() (local_get_flags() == 0) +#define raw_irqs_disabled() (local_get_flags() == 0) +#define raw_irqs_disabled_flags(flags) ((flags) == 0) #define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1) #define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1) @@ -108,6 +109,7 @@ static inline void local_irq_save_ptr(un #define local_save_flags(flags) ((flags) = mfmsr()) #define local_irq_save(flags) local_irq_save_ptr(&flags) #define irqs_disabled() ((mfmsr() & MSR_EE) == 0) +#define irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0) #define hard_irq_enable() local_irq_enable() #define hard_irq_disable() local_irq_disable() --- linux-2.6-git32.orig/include/asm-powerpc/irqflags.h 2007-06-28 14:53:58.779430447 +0200 +++ linux-2.6-git32/include/asm-powerpc/irqflags.h 2007-06-28 14:52:51.821430447 +0200 @@ -15,17 +15,4 @@ */ #include <asm-powerpc/hw_irq.h> -/* - * Do the CPU's IRQ-state tracing from assembly code. We call a - * C function, so save all the C-clobbered registers: - */ -#ifdef CONFIG_TRACE_IRQFLAGS - -#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS - -#else -# define TRACE_IRQS_ON -# define TRACE_IRQS_OFF -#endif - #endif --- linux-2.6-git32.orig/include/asm-powerpc/rwsem.h 2007-06-28 14:53:58.779430447 +0200 +++ linux-2.6-git32/include/asm-powerpc/rwsem.h 2007-06-28 14:52:51.588430447 +0200 @@ -28,11 +28,21 @@ struct rw_semaphore { #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) spinlock_t wait_lock; struct list_head wait_list; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif }; +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } +#else +# define __RWSEM_DEP_MAP_INIT(lockname) +#endif + #define __RWSEM_INITIALIZER(name) \ { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ - LIST_HEAD_INIT((name).wait_list) } + LIST_HEAD_INIT((name).wait_list) \ + __RWSEM_DEP_MAP_INIT(name) } #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) @@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); -static inline void init_rwsem(struct rw_semaphore *sem) -{ - sem->count = RWSEM_UNLOCKED_VALUE; - spin_lock_init(&sem->wait_lock); - INIT_LIST_HEAD(&sem->wait_list); -} +extern void __init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key); + +#define init_rwsem(sem) \ + do { \ + static struct lock_class_key __key; \ + \ + __init_rwsem((sem), #sem, &__key); \ + } while (0) /* * lock for reading @@ -74,7 +87,7 @@ static inline int __down_read_trylock(st /* * lock for writing */ -static inline void __down_write(struct rw_semaphore *sem) +static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) { int tmp; @@ -84,6 +97,11 @@ static inline void __down_write(struct r rwsem_down_write_failed(sem); } +static inline void __down_write(struct rw_semaphore *sem) +{ + __down_write_nested(sem, 0); +} + static inline int __down_write_trylock(struct rw_semaphore *sem) { int tmp; --- linux-2.6-git32.orig/include/asm-powerpc/spinlock.h 2007-06-28 14:53:58.780430447 +0200 +++ linux-2.6-git32/include/asm-powerpc/spinlock.h 2007-06-28 14:52:51.641430447 +0200 @@ -19,6 +19,7 @@ * * (the type definitions are in asm/spinlock_types.h) */ +#include <linux/irqflags.h> #ifdef CONFIG_PPC64 #include <asm/paca.h> #include <asm/hvcall.h> --- linux-2.6-git32.orig/arch/powerpc/kernel/head_64.S 2007-06-28 14:53:58.679430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/head_64.S 2007-06-28 14:48:33.858430447 +0200 @@ -394,6 +394,12 @@ label##_iSeries: \ EXCEPTION_PROLOG_ISERIES_2; \ b label##_common; \ +#ifdef CONFIG_TRACE_IRQFLAGS +#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off +#else +#define TRACE_DISABLE_INTS +#endif + #ifdef CONFIG_PPC_ISERIES #define DISABLE_INTS \ li r11,0; \ @@ -405,14 +411,15 @@ BEGIN_FW_FTR_SECTION; \ mfmsr r10; \ ori r10,r10,MSR_EE; \ mtmsrd r10,1; \ -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \ + TRACE_DISABLE_INTS #else #define DISABLE_INTS \ li r11,0; \ stb r11,PACASOFTIRQEN(r13); \ - stb r11,PACAHARDIRQEN(r13) - + stb r11,PACAHARDIRQEN(r13); \ + TRACE_DISABLE_INTS #endif /* CONFIG_PPC_ISERIES */ #define ENABLE_INTS \ @@ -965,24 +972,38 @@ bad_stack: */ fast_exc_return_irq: /* restores irq state too */ ld r3,SOFTE(r1) - ld r12,_MSR(r1) +#ifdef CONFIG_TRACE_IRQFLAGS + cmpdi r3,0 + beq 1f + bl .trace_hardirqs_on + ld r3,SOFTE(r1) +1: stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */ + cmpdi r3,0 + bne 2f + bl .trace_hardirqs_off + ld r3,SOFTE(r1) +2: +#else + stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */ +#endif + ld r12,_MSR(r1) rldicl r4,r12,49,63 /* get MSR_EE to LSB */ stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ - b 1f + b 3f .globl fast_exception_return fast_exception_return: ld r12,_MSR(r1) -1: ld r11,_NIP(r1) +3: ld r11,_NIP(r1) andi. r3,r12,MSR_RI /* check if RI is set */ beq- unrecov_fer #ifdef CONFIG_VIRT_CPU_ACCOUNTING andi. r3,r12,MSR_PR - beq 2f + beq 4f ACCOUNT_CPU_USER_EXIT(r3, r4) -2: +4: #endif ld r3,_CCR(r1) @@ -1387,11 +1408,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER /* * 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 +#ifdef CONFIG_TRACE_IRQFLAGS + cmpdi r3,0 + beq 14f + bl .trace_hardirqs_on + ld r3,SOFTE(r1) +14: + bl .raw_local_irq_restore + cmpdi r3,0 + bne 15f + bl .trace_hardirqs_off +15: +#else + bl .raw_local_irq_restore +#endif b 11f /* Here we have a page fault that hash_page can't handle. */ --- linux-2.6-git32.orig/arch/powerpc/kernel/setup_64.c 2007-06-28 14:53:58.729430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/setup_64.c 2007-06-28 14:49:08.305430447 +0200 @@ -33,6 +33,7 @@ #include <linux/serial_8250.h> #include <linux/bootmem.h> #include <linux/pci.h> +#include <linux/lockdep.h> #include <asm/io.h> #include <asm/kdump.h> #include <asm/prom.h> @@ -359,6 +360,11 @@ void __init setup_system(void) &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); /* + * start lockdep + */ + lockdep_init(); + + /* * Unflatten the device-tree passed by prom_init or kexec */ unflatten_device_tree(); --- linux-2.6-git32.orig/arch/powerpc/kernel/entry_64.S 2007-06-28 14:53:58.729430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/entry_64.S 2007-06-28 14:49:13.125430447 +0200 @@ -91,6 +91,13 @@ system_call_common: li r10,1 stb r10,PACASOFTIRQEN(r13) stb r10,PACAHARDIRQEN(r13) +#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 +#endif std r10,SOFTE(r1) #ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION @@ -491,8 +498,20 @@ BEGIN_FW_FTR_SECTION 4: END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif +#ifdef CONFIG_TRACE_IRQFLAGS + cmpdi r5,0 + beq 5f + bl .trace_hardirqs_on + ld r5,SOFTE(r1) stb r5,PACASOFTIRQEN(r13) - + b 6f +5: + stb r5,PACASOFTIRQEN(r13) + bl .trace_hardirqs_off +6: +#else + stb r5,PACASOFTIRQEN(r13) +#endif /* extract EE bit and use it to restore paca->hard_enabled */ ld r3,_MSR(r1) rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ @@ -560,6 +579,9 @@ do_work: bne restore /* here we are preempting the current task */ 1: +#ifdef CONFIG_TRACE_IRQFLAGS + bl .powerpc_trace_hardirqs_on +#endif li r0,1 stb r0,PACASOFTIRQEN(r13) stb r0,PACAHARDIRQEN(r13) --- linux-2.6-git32.orig/arch/powerpc/kernel/Makefile 2007-06-28 14:53:58.729430447 +0200 +++ linux-2.6-git32/arch/powerpc/kernel/Makefile 2007-06-28 14:48:41.691430447 +0200 @@ -62,6 +62,7 @@ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_TRACE_IRQFLAGS) += irqtrace.o module-$(CONFIG_PPC64) += module_64.o obj-$(CONFIG_MODULES) += $(module-y) --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-git32/arch/powerpc/kernel/irqtrace.S 2007-06-28 14:49:25.754430447 +0200 @@ -0,0 +1,47 @@ +/* + * crappy helper for irq-trace + */ + +#include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> + +#define STACKSPACE GPR0 + 16*8 + +#ifdef __powerpc64__ +#define ST std +#define L ld +#else +#define ST stw +#define L lw +#endif + +#define PRE \ + subi r1,r1,STACKSPACE ; \ + SAVE_GPR(0, r1) ; \ + SAVE_8GPRS(2, r1) ; \ + SAVE_4GPRS(10, r1) ; \ + mfcr r0 ; \ + ST r0, (14*8)(r1) ; \ + mflr r0 ; \ + ST r0, (15*8)(r1) + +#define POST \ + REST_8GPRS(2, r1) ; \ + REST_4GPRS(10, r1) ; \ + L r0, (14*8)(r1) ; \ + mtcr r0 ; \ + L r0, (15*8)(r1) ; \ + mtlr r0 ; \ + REST_GPR(0, r1) ; \ + addi r1,r1,STACKSPACE + +_GLOBAL(powerpc_trace_hardirqs_off) + PRE + bl .trace_hardirqs_off + POST + blr +_GLOBAL(powerpc_trace_hardirqs_on) + PRE + bl .trace_hardirqs_on + POST + blr _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev