mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
[PATCH] lockdep: irqtrace subsystem, s390 support
irqtrace support for s390. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Arjan van de Ven <arjan@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
6375e2b74c
commit
1f194a4c39
9 changed files with 113 additions and 38 deletions
|
@ -1,5 +1,9 @@
|
||||||
menu "Kernel hacking"
|
menu "Kernel hacking"
|
||||||
|
|
||||||
|
config TRACE_IRQFLAGS_SUPPORT
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
source "lib/Kconfig.debug"
|
source "lib/Kconfig.debug"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -58,6 +58,21 @@ STACK_SIZE = 1 << STACK_SHIFT
|
||||||
|
|
||||||
#define BASED(name) name-system_call(%r13)
|
#define BASED(name) name-system_call(%r13)
|
||||||
|
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
.macro TRACE_IRQS_ON
|
||||||
|
l %r1,BASED(.Ltrace_irq_on)
|
||||||
|
basr %r14,%r1
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro TRACE_IRQS_OFF
|
||||||
|
l %r1,BASED(.Ltrace_irq_off)
|
||||||
|
basr %r14,%r1
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
#define TRACE_IRQS_ON
|
||||||
|
#define TRACE_IRQS_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register usage in interrupt handlers:
|
* Register usage in interrupt handlers:
|
||||||
* R9 - pointer to current task structure
|
* R9 - pointer to current task structure
|
||||||
|
@ -361,6 +376,7 @@ ret_from_fork:
|
||||||
st %r15,SP_R15(%r15) # store stack pointer for new kthread
|
st %r15,SP_R15(%r15) # store stack pointer for new kthread
|
||||||
0: l %r1,BASED(.Lschedtail)
|
0: l %r1,BASED(.Lschedtail)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
|
TRACE_IRQS_ON
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
b BASED(sysc_return)
|
b BASED(sysc_return)
|
||||||
|
|
||||||
|
@ -516,6 +532,7 @@ pgm_no_vtime3:
|
||||||
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
|
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
||||||
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||||
|
TRACE_IRQS_ON
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
b BASED(sysc_do_svc)
|
b BASED(sysc_do_svc)
|
||||||
|
|
||||||
|
@ -539,9 +556,11 @@ io_int_handler:
|
||||||
io_no_vtime:
|
io_no_vtime:
|
||||||
#endif
|
#endif
|
||||||
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
|
TRACE_IRQS_OFF
|
||||||
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
|
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
basr %r14,%r1 # branch to standard irq handler
|
basr %r14,%r1 # branch to standard irq handler
|
||||||
|
TRACE_IRQS_ON
|
||||||
|
|
||||||
io_return:
|
io_return:
|
||||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||||
|
@ -651,10 +670,12 @@ ext_int_handler:
|
||||||
ext_no_vtime:
|
ext_no_vtime:
|
||||||
#endif
|
#endif
|
||||||
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
|
TRACE_IRQS_OFF
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
lh %r3,__LC_EXT_INT_CODE # get interruption code
|
lh %r3,__LC_EXT_INT_CODE # get interruption code
|
||||||
l %r1,BASED(.Ldo_extint)
|
l %r1,BASED(.Ldo_extint)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
|
TRACE_IRQS_ON
|
||||||
b BASED(io_return)
|
b BASED(io_return)
|
||||||
|
|
||||||
__critical_end:
|
__critical_end:
|
||||||
|
@ -731,8 +752,10 @@ mcck_no_vtime:
|
||||||
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
||||||
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
|
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
|
||||||
bno BASED(mcck_return)
|
bno BASED(mcck_return)
|
||||||
|
TRACE_IRQS_OFF
|
||||||
l %r1,BASED(.Ls390_handle_mcck)
|
l %r1,BASED(.Ls390_handle_mcck)
|
||||||
basr %r14,%r1 # call machine check handler
|
basr %r14,%r1 # call machine check handler
|
||||||
|
TRACE_IRQS_ON
|
||||||
mcck_return:
|
mcck_return:
|
||||||
mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
|
mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
|
||||||
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
||||||
|
@ -1012,7 +1035,11 @@ cleanup_io_leave_insn:
|
||||||
.Lvfork: .long sys_vfork
|
.Lvfork: .long sys_vfork
|
||||||
.Lschedtail: .long schedule_tail
|
.Lschedtail: .long schedule_tail
|
||||||
.Lsysc_table: .long sys_call_table
|
.Lsysc_table: .long sys_call_table
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
.Ltrace_irq_on:.long trace_hardirqs_on
|
||||||
|
.Ltrace_irq_off:
|
||||||
|
.long trace_hardirqs_off
|
||||||
|
#endif
|
||||||
.Lcritical_start:
|
.Lcritical_start:
|
||||||
.long __critical_start + 0x80000000
|
.long __critical_start + 0x80000000
|
||||||
.Lcritical_end:
|
.Lcritical_end:
|
||||||
|
|
|
@ -58,6 +58,19 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
|
||||||
|
|
||||||
#define BASED(name) name-system_call(%r13)
|
#define BASED(name) name-system_call(%r13)
|
||||||
|
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
.macro TRACE_IRQS_ON
|
||||||
|
brasl %r14,trace_hardirqs_on
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro TRACE_IRQS_OFF
|
||||||
|
brasl %r14,trace_hardirqs_off
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
#define TRACE_IRQS_ON
|
||||||
|
#define TRACE_IRQS_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
.macro STORE_TIMER lc_offset
|
.macro STORE_TIMER lc_offset
|
||||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||||
stpt \lc_offset
|
stpt \lc_offset
|
||||||
|
@ -354,6 +367,7 @@ ret_from_fork:
|
||||||
jo 0f
|
jo 0f
|
||||||
stg %r15,SP_R15(%r15) # store stack pointer for new kthread
|
stg %r15,SP_R15(%r15) # store stack pointer for new kthread
|
||||||
0: brasl %r14,schedule_tail
|
0: brasl %r14,schedule_tail
|
||||||
|
TRACE_IRQS_ON
|
||||||
stosm 24(%r15),0x03 # reenable interrupts
|
stosm 24(%r15),0x03 # reenable interrupts
|
||||||
j sysc_return
|
j sysc_return
|
||||||
|
|
||||||
|
@ -535,6 +549,7 @@ pgm_no_vtime3:
|
||||||
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
|
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
||||||
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||||
|
TRACE_IRQS_ON
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
j sysc_do_svc
|
j sysc_do_svc
|
||||||
|
|
||||||
|
@ -557,8 +572,10 @@ io_int_handler:
|
||||||
io_no_vtime:
|
io_no_vtime:
|
||||||
#endif
|
#endif
|
||||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
|
TRACE_IRQS_OFF
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
brasl %r14,do_IRQ # call standard irq handler
|
brasl %r14,do_IRQ # call standard irq handler
|
||||||
|
TRACE_IRQS_ON
|
||||||
|
|
||||||
io_return:
|
io_return:
|
||||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||||
|
@ -665,9 +682,11 @@ ext_int_handler:
|
||||||
ext_no_vtime:
|
ext_no_vtime:
|
||||||
#endif
|
#endif
|
||||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
|
TRACE_IRQS_OFF
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
llgh %r3,__LC_EXT_INT_CODE # get interruption code
|
llgh %r3,__LC_EXT_INT_CODE # get interruption code
|
||||||
brasl %r14,do_extint
|
brasl %r14,do_extint
|
||||||
|
TRACE_IRQS_ON
|
||||||
j io_return
|
j io_return
|
||||||
|
|
||||||
__critical_end:
|
__critical_end:
|
||||||
|
@ -743,7 +762,9 @@ mcck_no_vtime:
|
||||||
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
||||||
tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
|
tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
|
||||||
jno mcck_return
|
jno mcck_return
|
||||||
|
TRACE_IRQS_OFF
|
||||||
brasl %r14,s390_handle_mcck
|
brasl %r14,s390_handle_mcck
|
||||||
|
TRACE_IRQS_ON
|
||||||
mcck_return:
|
mcck_return:
|
||||||
mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
|
mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
|
||||||
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
||||||
|
|
|
@ -97,7 +97,7 @@ asmlinkage void do_softirq(void)
|
||||||
|
|
||||||
account_system_vtime(current);
|
account_system_vtime(current);
|
||||||
|
|
||||||
__local_bh_enable();
|
_local_bh_enable();
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ static void default_idle(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_hardirqs_on();
|
||||||
/* Wait for external, I/O or machine check interrupt. */
|
/* Wait for external, I/O or machine check interrupt. */
|
||||||
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
|
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
|
||||||
PSW_MASK_IO | PSW_MASK_EXT);
|
PSW_MASK_IO | PSW_MASK_EXT);
|
||||||
|
|
|
@ -383,6 +383,7 @@ void
|
||||||
sclp_sync_wait(void)
|
sclp_sync_wait(void)
|
||||||
{
|
{
|
||||||
unsigned long psw_mask;
|
unsigned long psw_mask;
|
||||||
|
unsigned long flags;
|
||||||
unsigned long cr0, cr0_sync;
|
unsigned long cr0, cr0_sync;
|
||||||
u64 timeout;
|
u64 timeout;
|
||||||
|
|
||||||
|
@ -395,9 +396,11 @@ sclp_sync_wait(void)
|
||||||
sclp_tod_from_jiffies(sclp_request_timer.expires -
|
sclp_tod_from_jiffies(sclp_request_timer.expires -
|
||||||
jiffies);
|
jiffies);
|
||||||
}
|
}
|
||||||
|
local_irq_save(flags);
|
||||||
/* Prevent bottom half from executing once we force interrupts open */
|
/* Prevent bottom half from executing once we force interrupts open */
|
||||||
local_bh_disable();
|
local_bh_disable();
|
||||||
/* Enable service-signal interruption, disable timer interrupts */
|
/* Enable service-signal interruption, disable timer interrupts */
|
||||||
|
trace_hardirqs_on();
|
||||||
__ctl_store(cr0, 0, 0);
|
__ctl_store(cr0, 0, 0);
|
||||||
cr0_sync = cr0;
|
cr0_sync = cr0;
|
||||||
cr0_sync |= 0x00000200;
|
cr0_sync |= 0x00000200;
|
||||||
|
@ -415,11 +418,10 @@ sclp_sync_wait(void)
|
||||||
barrier();
|
barrier();
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
/* Restore interrupt settings */
|
local_irq_disable();
|
||||||
asm volatile ("SSM 0(%0)"
|
|
||||||
: : "a" (&psw_mask) : "memory");
|
|
||||||
__ctl_load(cr0, 0, 0);
|
__ctl_load(cr0, 0, 0);
|
||||||
__local_bh_enable();
|
_local_bh_enable();
|
||||||
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(sclp_sync_wait);
|
EXPORT_SYMBOL(sclp_sync_wait);
|
||||||
|
|
|
@ -147,7 +147,7 @@ cio_tpi(void)
|
||||||
sch->driver->irq(&sch->dev);
|
sch->driver->irq(&sch->dev);
|
||||||
spin_unlock(&sch->lock);
|
spin_unlock(&sch->lock);
|
||||||
irq_exit ();
|
irq_exit ();
|
||||||
__local_bh_enable();
|
_local_bh_enable();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
50
include/asm-s390/irqflags.h
Normal file
50
include/asm-s390/irqflags.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* include/asm-s390/irqflags.h
|
||||||
|
*
|
||||||
|
* Copyright (C) IBM Corp. 2006
|
||||||
|
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_IRQFLAGS_H
|
||||||
|
#define __ASM_IRQFLAGS_H
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
/* interrupt control.. */
|
||||||
|
#define raw_local_irq_enable() ({ \
|
||||||
|
unsigned long __dummy; \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"stosm 0(%1),0x03" \
|
||||||
|
: "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define raw_local_irq_disable() ({ \
|
||||||
|
unsigned long __flags; \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
|
||||||
|
__flags; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define raw_local_save_flags(x) \
|
||||||
|
__asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
|
||||||
|
|
||||||
|
#define raw_local_irq_restore(x) \
|
||||||
|
__asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory")
|
||||||
|
|
||||||
|
#define raw_irqs_disabled() \
|
||||||
|
({ \
|
||||||
|
unsigned long flags; \
|
||||||
|
local_save_flags(flags); \
|
||||||
|
!((flags >> __FLAG_SHIFT) & 3); \
|
||||||
|
})
|
||||||
|
|
||||||
|
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||||
|
{
|
||||||
|
return !((flags >> __FLAG_SHIFT) & 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For spinlocks etc */
|
||||||
|
#define raw_local_irq_save(x) ((x) = raw_local_irq_disable())
|
||||||
|
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
#endif /* __ASM_IRQFLAGS_H */
|
|
@ -301,34 +301,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||||
#define set_mb(var, value) do { var = value; mb(); } while (0)
|
#define set_mb(var, value) do { var = value; mb(); } while (0)
|
||||||
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
|
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
|
||||||
|
|
||||||
/* interrupt control.. */
|
|
||||||
#define local_irq_enable() ({ \
|
|
||||||
unsigned long __dummy; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
"stosm 0(%1),0x03" \
|
|
||||||
: "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define local_irq_disable() ({ \
|
|
||||||
unsigned long __flags; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
|
|
||||||
__flags; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define local_save_flags(x) \
|
|
||||||
__asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
|
|
||||||
|
|
||||||
#define local_irq_restore(x) \
|
|
||||||
__asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory")
|
|
||||||
|
|
||||||
#define irqs_disabled() \
|
|
||||||
({ \
|
|
||||||
unsigned long flags; \
|
|
||||||
local_save_flags(flags); \
|
|
||||||
!((flags >> __FLAG_SHIFT) & 3); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
|
|
||||||
#define __ctl_load(array, low, high) ({ \
|
#define __ctl_load(array, low, high) ({ \
|
||||||
|
@ -442,8 +414,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||||
})
|
})
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
|
||||||
/* For spinlocks etc */
|
#include <linux/irqflags.h>
|
||||||
#define local_irq_save(x) ((x) = local_irq_disable())
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use to set psw mask except for the first byte which
|
* Use to set psw mask except for the first byte which
|
||||||
|
@ -482,4 +453,3 @@ extern void (*_machine_power_off)(void);
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue