forked from Minki/linux
[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
@ -1,5 +1,9 @@
|
||||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
endmenu
|
||||
|
@ -58,6 +58,21 @@ STACK_SIZE = 1 << STACK_SHIFT
|
||||
|
||||
#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:
|
||||
* R9 - pointer to current task structure
|
||||
@ -361,6 +376,7 @@ ret_from_fork:
|
||||
st %r15,SP_R15(%r15) # store stack pointer for new kthread
|
||||
0: l %r1,BASED(.Lschedtail)
|
||||
basr %r14,%r1
|
||||
TRACE_IRQS_ON
|
||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||
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_access_id(1,%r1),__LC_PER_ACCESS_ID
|
||||
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||
TRACE_IRQS_ON
|
||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||
b BASED(sysc_do_svc)
|
||||
|
||||
@ -539,9 +556,11 @@ io_int_handler:
|
||||
io_no_vtime:
|
||||
#endif
|
||||
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||
TRACE_IRQS_OFF
|
||||
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
basr %r14,%r1 # branch to standard irq handler
|
||||
TRACE_IRQS_ON
|
||||
|
||||
io_return:
|
||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||
@ -651,10 +670,12 @@ ext_int_handler:
|
||||
ext_no_vtime:
|
||||
#endif
|
||||
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||
TRACE_IRQS_OFF
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
lh %r3,__LC_EXT_INT_CODE # get interruption code
|
||||
l %r1,BASED(.Ldo_extint)
|
||||
basr %r14,%r1
|
||||
TRACE_IRQS_ON
|
||||
b BASED(io_return)
|
||||
|
||||
__critical_end:
|
||||
@ -731,8 +752,10 @@ mcck_no_vtime:
|
||||
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
||||
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
|
||||
bno BASED(mcck_return)
|
||||
TRACE_IRQS_OFF
|
||||
l %r1,BASED(.Ls390_handle_mcck)
|
||||
basr %r14,%r1 # call machine check handler
|
||||
TRACE_IRQS_ON
|
||||
mcck_return:
|
||||
mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
|
||||
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
||||
@ -1012,7 +1035,11 @@ cleanup_io_leave_insn:
|
||||
.Lvfork: .long sys_vfork
|
||||
.Lschedtail: .long schedule_tail
|
||||
.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:
|
||||
.long __critical_start + 0x80000000
|
||||
.Lcritical_end:
|
||||
|
@ -58,6 +58,19 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
|
||||
|
||||
#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
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
stpt \lc_offset
|
||||
@ -354,6 +367,7 @@ ret_from_fork:
|
||||
jo 0f
|
||||
stg %r15,SP_R15(%r15) # store stack pointer for new kthread
|
||||
0: brasl %r14,schedule_tail
|
||||
TRACE_IRQS_ON
|
||||
stosm 24(%r15),0x03 # reenable interrupts
|
||||
j sysc_return
|
||||
|
||||
@ -535,6 +549,7 @@ pgm_no_vtime3:
|
||||
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
|
||||
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
||||
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||
TRACE_IRQS_ON
|
||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||
j sysc_do_svc
|
||||
|
||||
@ -557,8 +572,10 @@ io_int_handler:
|
||||
io_no_vtime:
|
||||
#endif
|
||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||
TRACE_IRQS_OFF
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
brasl %r14,do_IRQ # call standard irq handler
|
||||
TRACE_IRQS_ON
|
||||
|
||||
io_return:
|
||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||
@ -665,9 +682,11 @@ ext_int_handler:
|
||||
ext_no_vtime:
|
||||
#endif
|
||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||
TRACE_IRQS_OFF
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
llgh %r3,__LC_EXT_INT_CODE # get interruption code
|
||||
brasl %r14,do_extint
|
||||
TRACE_IRQS_ON
|
||||
j io_return
|
||||
|
||||
__critical_end:
|
||||
@ -743,7 +762,9 @@ mcck_no_vtime:
|
||||
stosm __SF_EMPTY(%r15),0x04 # turn dat on
|
||||
tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
|
||||
jno mcck_return
|
||||
TRACE_IRQS_OFF
|
||||
brasl %r14,s390_handle_mcck
|
||||
TRACE_IRQS_ON
|
||||
mcck_return:
|
||||
mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
|
||||
ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
|
||||
|
@ -97,7 +97,7 @@ asmlinkage void do_softirq(void)
|
||||
|
||||
account_system_vtime(current);
|
||||
|
||||
__local_bh_enable();
|
||||
_local_bh_enable();
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
@ -142,6 +142,7 @@ static void default_idle(void)
|
||||
return;
|
||||
}
|
||||
|
||||
trace_hardirqs_on();
|
||||
/* Wait for external, I/O or machine check interrupt. */
|
||||
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
|
||||
PSW_MASK_IO | PSW_MASK_EXT);
|
||||
|
@ -383,6 +383,7 @@ void
|
||||
sclp_sync_wait(void)
|
||||
{
|
||||
unsigned long psw_mask;
|
||||
unsigned long flags;
|
||||
unsigned long cr0, cr0_sync;
|
||||
u64 timeout;
|
||||
|
||||
@ -395,9 +396,11 @@ sclp_sync_wait(void)
|
||||
sclp_tod_from_jiffies(sclp_request_timer.expires -
|
||||
jiffies);
|
||||
}
|
||||
local_irq_save(flags);
|
||||
/* Prevent bottom half from executing once we force interrupts open */
|
||||
local_bh_disable();
|
||||
/* Enable service-signal interruption, disable timer interrupts */
|
||||
trace_hardirqs_on();
|
||||
__ctl_store(cr0, 0, 0);
|
||||
cr0_sync = cr0;
|
||||
cr0_sync |= 0x00000200;
|
||||
@ -415,11 +418,10 @@ sclp_sync_wait(void)
|
||||
barrier();
|
||||
cpu_relax();
|
||||
}
|
||||
/* Restore interrupt settings */
|
||||
asm volatile ("SSM 0(%0)"
|
||||
: : "a" (&psw_mask) : "memory");
|
||||
local_irq_disable();
|
||||
__ctl_load(cr0, 0, 0);
|
||||
__local_bh_enable();
|
||||
_local_bh_enable();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(sclp_sync_wait);
|
||||
|
@ -147,7 +147,7 @@ cio_tpi(void)
|
||||
sch->driver->irq(&sch->dev);
|
||||
spin_unlock(&sch->lock);
|
||||
irq_exit ();
|
||||
__local_bh_enable();
|
||||
_local_bh_enable();
|
||||
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_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__
|
||||
|
||||
#define __ctl_load(array, low, high) ({ \
|
||||
@ -442,8 +414,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||
})
|
||||
#endif /* __s390x__ */
|
||||
|
||||
/* For spinlocks etc */
|
||||
#define local_irq_save(x) ((x) = local_irq_disable())
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
/*
|
||||
* Use to set psw mask except for the first byte which
|
||||
@ -482,4 +453,3 @@ extern void (*_machine_power_off)(void);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user