[S390] add TIF_SYSCALL thread flag
Add an explicit TIF_SYSCALL bit that indicates if a task is inside a system call. The svc_code in the pt_regs structure is now only valid if TIF_SYSCALL is set. With this definition TIF_RESTART_SVC can be replaced with TIF_SYSCALL. Overall do_signal is a bit more readable and it saves a few lines of code. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
@@ -26,7 +26,8 @@ extern const unsigned int sys_call_table[];
|
|||||||
static inline long syscall_get_nr(struct task_struct *task,
|
static inline long syscall_get_nr(struct task_struct *task,
|
||||||
struct pt_regs *regs)
|
struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
return regs->svc_code ? (regs->svc_code & 0xffff) : -1;
|
return test_tsk_thread_flag(task, TIF_SYSCALL) ?
|
||||||
|
(regs->svc_code & 0xffff) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void syscall_rollback(struct task_struct *task,
|
static inline void syscall_rollback(struct task_struct *task,
|
||||||
|
@@ -85,10 +85,10 @@ static inline struct thread_info *current_thread_info(void)
|
|||||||
/*
|
/*
|
||||||
* thread information flags bit numbers
|
* thread information flags bit numbers
|
||||||
*/
|
*/
|
||||||
|
#define TIF_SYSCALL 0 /* inside a system call */
|
||||||
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
|
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
|
||||||
#define TIF_SIGPENDING 2 /* signal pending */
|
#define TIF_SIGPENDING 2 /* signal pending */
|
||||||
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
||||||
#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
|
|
||||||
#define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */
|
#define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */
|
||||||
#define TIF_MCCK_PENDING 7 /* machine check handling is pending */
|
#define TIF_MCCK_PENDING 7 /* machine check handling is pending */
|
||||||
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
|
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
|
||||||
@@ -104,11 +104,11 @@ static inline struct thread_info *current_thread_info(void)
|
|||||||
#define TIF_SINGLE_STEP 20 /* This task is single stepped */
|
#define TIF_SINGLE_STEP 20 /* This task is single stepped */
|
||||||
#define TIF_FREEZE 21 /* thread is freezing for suspend */
|
#define TIF_FREEZE 21 /* thread is freezing for suspend */
|
||||||
|
|
||||||
|
#define _TIF_SYSCALL (1<<TIF_SYSCALL)
|
||||||
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
|
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
|
||||||
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
|
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
|
||||||
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
||||||
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
||||||
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
|
|
||||||
#define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
|
#define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
|
||||||
#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
|
#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
|
||||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||||
|
@@ -342,7 +342,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
restore_fp_regs(¤t->thread.fp_regs);
|
restore_fp_regs(¤t->thread.fp_regs);
|
||||||
regs->svc_code = 0; /* disable syscall checks */
|
clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,11 +47,11 @@ SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
|
|||||||
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
|
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
|
||||||
|
|
||||||
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
||||||
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP )
|
_TIF_MCCK_PENDING | _TIF_PER_TRAP )
|
||||||
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
||||||
_TIF_MCCK_PENDING)
|
_TIF_MCCK_PENDING)
|
||||||
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
|
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
|
||||||
_TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
|
_TIF_SYSCALL_TRACEPOINT)
|
||||||
|
|
||||||
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
|
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
|
||||||
STACK_SIZE = 1 << STACK_SHIFT
|
STACK_SIZE = 1 << STACK_SHIFT
|
||||||
@@ -227,9 +227,10 @@ ENTRY(system_call)
|
|||||||
sysc_saveall:
|
sysc_saveall:
|
||||||
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
oi __TI_flags+3(%r12),_TIF_SYSCALL
|
||||||
sysc_vtime:
|
sysc_vtime:
|
||||||
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
||||||
sysc_stime:
|
sysc_stime:
|
||||||
@@ -248,7 +249,7 @@ sysc_do_svc:
|
|||||||
sysc_nr_ok:
|
sysc_nr_ok:
|
||||||
sll %r7,2 # svc number *4
|
sll %r7,2 # svc number *4
|
||||||
l %r10,BASED(.Lsysc_table)
|
l %r10,BASED(.Lsysc_table)
|
||||||
tm __TI_flags+2(%r12),_TIF_SYSCALL
|
tm __TI_flags+2(%r12),_TIF_TRACE >> 8
|
||||||
mvc SP_ARGS(4,%r15),SP_R7(%r15)
|
mvc SP_ARGS(4,%r15),SP_R7(%r15)
|
||||||
l %r8,0(%r7,%r10) # get system call addr.
|
l %r8,0(%r7,%r10) # get system call addr.
|
||||||
bnz BASED(sysc_tracesys)
|
bnz BASED(sysc_tracesys)
|
||||||
@@ -258,23 +259,19 @@ sysc_nr_ok:
|
|||||||
sysc_return:
|
sysc_return:
|
||||||
LOCKDEP_SYS_EXIT
|
LOCKDEP_SYS_EXIT
|
||||||
sysc_tif:
|
sysc_tif:
|
||||||
|
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||||
|
bno BASED(sysc_restore)
|
||||||
tm __TI_flags+3(%r12),_TIF_WORK_SVC
|
tm __TI_flags+3(%r12),_TIF_WORK_SVC
|
||||||
bnz BASED(sysc_work) # there is work to do (signals etc.)
|
bnz BASED(sysc_work) # there is work to do (signals etc.)
|
||||||
|
ni __TI_flags+3(%r12),255-_TIF_SYSCALL
|
||||||
sysc_restore:
|
sysc_restore:
|
||||||
RESTORE_ALL __LC_RETURN_PSW,1
|
RESTORE_ALL __LC_RETURN_PSW,1
|
||||||
sysc_done:
|
sysc_done:
|
||||||
|
|
||||||
#
|
|
||||||
# There is work to do, but first we need to check if we return to userspace.
|
|
||||||
#
|
|
||||||
sysc_work:
|
|
||||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
|
||||||
bno BASED(sysc_restore)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# One of the work bits is on. Find out which one.
|
# One of the work bits is on. Find out which one.
|
||||||
#
|
#
|
||||||
sysc_work_tif:
|
sysc_work:
|
||||||
tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
|
tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
|
||||||
bo BASED(sysc_mcck_pending)
|
bo BASED(sysc_mcck_pending)
|
||||||
tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
|
tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
|
||||||
@@ -283,8 +280,6 @@ sysc_work_tif:
|
|||||||
bo BASED(sysc_sigpending)
|
bo BASED(sysc_sigpending)
|
||||||
tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
|
tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
|
||||||
bo BASED(sysc_notify_resume)
|
bo BASED(sysc_notify_resume)
|
||||||
tm __TI_flags+3(%r12),_TIF_RESTART_SVC
|
|
||||||
bo BASED(sysc_restart)
|
|
||||||
tm __TI_flags+3(%r12),_TIF_PER_TRAP
|
tm __TI_flags+3(%r12),_TIF_PER_TRAP
|
||||||
bo BASED(sysc_singlestep)
|
bo BASED(sysc_singlestep)
|
||||||
b BASED(sysc_return) # beware of critical section cleanup
|
b BASED(sysc_return) # beware of critical section cleanup
|
||||||
@@ -313,11 +308,14 @@ sysc_sigpending:
|
|||||||
la %r2,SP_PTREGS(%r15) # load pt_regs
|
la %r2,SP_PTREGS(%r15) # load pt_regs
|
||||||
l %r1,BASED(.Ldo_signal)
|
l %r1,BASED(.Ldo_signal)
|
||||||
basr %r14,%r1 # call do_signal
|
basr %r14,%r1 # call do_signal
|
||||||
tm __TI_flags+3(%r12),_TIF_RESTART_SVC
|
tm __TI_flags+3(%r12),_TIF_SYSCALL
|
||||||
bo BASED(sysc_restart)
|
bno BASED(sysc_return)
|
||||||
tm __TI_flags+3(%r12),_TIF_PER_TRAP
|
lm %r2,%r6,SP_R2(%r15) # load svc arguments
|
||||||
bo BASED(sysc_singlestep)
|
xr %r7,%r7 # svc 0 returns -ENOSYS
|
||||||
b BASED(sysc_return)
|
clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2)
|
||||||
|
bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0
|
||||||
|
icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number
|
||||||
|
b BASED(sysc_nr_ok) # restart svc
|
||||||
|
|
||||||
#
|
#
|
||||||
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
|
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
|
||||||
@@ -328,25 +326,11 @@ sysc_notify_resume:
|
|||||||
la %r14,BASED(sysc_return)
|
la %r14,BASED(sysc_return)
|
||||||
br %r1 # call do_notify_resume
|
br %r1 # call do_notify_resume
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# _TIF_RESTART_SVC is set, set up registers and restart svc
|
|
||||||
#
|
|
||||||
sysc_restart:
|
|
||||||
ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
|
|
||||||
lm %r2,%r6,SP_R2(%r15) # load svc arguments
|
|
||||||
xr %r7,%r7 # svc 0 returns -ENOSYS
|
|
||||||
clc SP_SVC_CODE+2(%r15),BASED(.Lnr_syscalls+2)
|
|
||||||
bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0
|
|
||||||
icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number
|
|
||||||
b BASED(sysc_nr_ok) # restart svc
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# _TIF_PER_TRAP is set, call do_per_trap
|
# _TIF_PER_TRAP is set, call do_per_trap
|
||||||
#
|
#
|
||||||
sysc_singlestep:
|
sysc_singlestep:
|
||||||
ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
|
ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc code
|
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
l %r1,BASED(.Lhandle_per) # load adr. of per handler
|
l %r1,BASED(.Lhandle_per) # load adr. of per handler
|
||||||
la %r14,BASED(sysc_return) # load adr. of system return
|
la %r14,BASED(sysc_return) # load adr. of system return
|
||||||
@@ -376,7 +360,7 @@ sysc_tracego:
|
|||||||
basr %r14,%r8 # call sys_xxx
|
basr %r14,%r8 # call sys_xxx
|
||||||
st %r2,SP_R2(%r15) # store return value
|
st %r2,SP_R2(%r15) # store return value
|
||||||
sysc_tracenogo:
|
sysc_tracenogo:
|
||||||
tm __TI_flags+2(%r12),_TIF_SYSCALL
|
tm __TI_flags+2(%r12),_TIF_TRACE >> 8
|
||||||
bz BASED(sysc_return)
|
bz BASED(sysc_return)
|
||||||
l %r1,BASED(.Ltrace_exit)
|
l %r1,BASED(.Ltrace_exit)
|
||||||
la %r2,SP_PTREGS(%r15) # load pt_regs
|
la %r2,SP_PTREGS(%r15) # load pt_regs
|
||||||
@@ -454,7 +438,6 @@ ENTRY(pgm_check_handler)
|
|||||||
bnz BASED(pgm_per) # got per exception -> special case
|
bnz BASED(pgm_per) # got per exception -> special case
|
||||||
SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15)
|
|
||||||
mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
|
mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
|
||||||
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
|
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
|
||||||
@@ -530,9 +513,10 @@ pgm_exit2:
|
|||||||
pgm_svcper:
|
pgm_svcper:
|
||||||
SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
|
||||||
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
||||||
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
|
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
|
||||||
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
||||||
@@ -540,7 +524,6 @@ pgm_svcper:
|
|||||||
mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
|
mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
|
||||||
mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
|
mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
|
mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
|
||||||
oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
|
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
lm %r2,%r6,SP_R2(%r15) # load svc arguments
|
lm %r2,%r6,SP_R2(%r15) # load svc arguments
|
||||||
b BASED(sysc_do_svc)
|
b BASED(sysc_do_svc)
|
||||||
@@ -550,7 +533,6 @@ pgm_svcper:
|
|||||||
#
|
#
|
||||||
kernel_per:
|
kernel_per:
|
||||||
REENABLE_IRQS
|
REENABLE_IRQS
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15)
|
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
l %r1,BASED(.Lhandle_per) # load adr. of per handler
|
l %r1,BASED(.Lhandle_per) # load adr. of per handler
|
||||||
basr %r14,%r1 # branch to do_single_step
|
basr %r14,%r1 # branch to do_single_step
|
||||||
@@ -965,9 +947,11 @@ cleanup_system_call:
|
|||||||
s %r15,BASED(.Lc_spsize) # make room for registers & psw
|
s %r15,BASED(.Lc_spsize) # make room for registers & psw
|
||||||
st %r15,12(%r12)
|
st %r15,12(%r12)
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
mvc 0(4,%r12),__LC_THREAD_INFO
|
||||||
|
l %r12,__LC_THREAD_INFO
|
||||||
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
mvc 0(4,%r12),__LC_THREAD_INFO
|
oi __TI_flags+3(%r12),_TIF_SYSCALL
|
||||||
cleanup_vtime:
|
cleanup_vtime:
|
||||||
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
|
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
|
||||||
bhe BASED(cleanup_stime)
|
bhe BASED(cleanup_stime)
|
||||||
|
@@ -50,11 +50,11 @@ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
|
|||||||
STACK_SIZE = 1 << STACK_SHIFT
|
STACK_SIZE = 1 << STACK_SHIFT
|
||||||
|
|
||||||
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
||||||
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP )
|
_TIF_MCCK_PENDING | _TIF_PER_TRAP )
|
||||||
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
||||||
_TIF_MCCK_PENDING)
|
_TIF_MCCK_PENDING)
|
||||||
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
|
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
|
||||||
_TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
|
_TIF_SYSCALL_TRACEPOINT)
|
||||||
_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
|
_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
|
||||||
|
|
||||||
#define BASED(name) name-system_call(%r13)
|
#define BASED(name) name-system_call(%r13)
|
||||||
@@ -248,9 +248,10 @@ ENTRY(system_call)
|
|||||||
sysc_saveall:
|
sysc_saveall:
|
||||||
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
oi __TI_flags+7(%r12),_TIF_SYSCALL
|
||||||
sysc_vtime:
|
sysc_vtime:
|
||||||
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
||||||
sysc_stime:
|
sysc_stime:
|
||||||
@@ -276,7 +277,7 @@ sysc_nr_ok:
|
|||||||
larl %r10,sys_call_table_emu # use 31 bit emulation system calls
|
larl %r10,sys_call_table_emu # use 31 bit emulation system calls
|
||||||
sysc_noemu:
|
sysc_noemu:
|
||||||
#endif
|
#endif
|
||||||
tm __TI_flags+6(%r12),_TIF_SYSCALL
|
tm __TI_flags+6(%r12),_TIF_TRACE >> 8
|
||||||
mvc SP_ARGS(8,%r15),SP_R7(%r15)
|
mvc SP_ARGS(8,%r15),SP_R7(%r15)
|
||||||
lgf %r8,0(%r7,%r10) # load address of system call routine
|
lgf %r8,0(%r7,%r10) # load address of system call routine
|
||||||
jnz sysc_tracesys
|
jnz sysc_tracesys
|
||||||
@@ -286,23 +287,19 @@ sysc_noemu:
|
|||||||
sysc_return:
|
sysc_return:
|
||||||
LOCKDEP_SYS_EXIT
|
LOCKDEP_SYS_EXIT
|
||||||
sysc_tif:
|
sysc_tif:
|
||||||
|
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
||||||
|
jno sysc_restore
|
||||||
tm __TI_flags+7(%r12),_TIF_WORK_SVC
|
tm __TI_flags+7(%r12),_TIF_WORK_SVC
|
||||||
jnz sysc_work # there is work to do (signals etc.)
|
jnz sysc_work # there is work to do (signals etc.)
|
||||||
|
ni __TI_flags+7(%r12),255-_TIF_SYSCALL
|
||||||
sysc_restore:
|
sysc_restore:
|
||||||
RESTORE_ALL __LC_RETURN_PSW,1
|
RESTORE_ALL __LC_RETURN_PSW,1
|
||||||
sysc_done:
|
sysc_done:
|
||||||
|
|
||||||
#
|
|
||||||
# There is work to do, but first we need to check if we return to userspace.
|
|
||||||
#
|
|
||||||
sysc_work:
|
|
||||||
tm SP_PSW+1(%r15),0x01 # returning to user ?
|
|
||||||
jno sysc_restore
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# One of the work bits is on. Find out which one.
|
# One of the work bits is on. Find out which one.
|
||||||
#
|
#
|
||||||
sysc_work_tif:
|
sysc_work:
|
||||||
tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
|
tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
|
||||||
jo sysc_mcck_pending
|
jo sysc_mcck_pending
|
||||||
tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
|
tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
|
||||||
@@ -311,8 +308,6 @@ sysc_work_tif:
|
|||||||
jo sysc_sigpending
|
jo sysc_sigpending
|
||||||
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
|
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
|
||||||
jo sysc_notify_resume
|
jo sysc_notify_resume
|
||||||
tm __TI_flags+7(%r12),_TIF_RESTART_SVC
|
|
||||||
jo sysc_restart
|
|
||||||
tm __TI_flags+7(%r12),_TIF_PER_TRAP
|
tm __TI_flags+7(%r12),_TIF_PER_TRAP
|
||||||
jo sysc_singlestep
|
jo sysc_singlestep
|
||||||
j sysc_return # beware of critical section cleanup
|
j sysc_return # beware of critical section cleanup
|
||||||
@@ -338,11 +333,15 @@ sysc_sigpending:
|
|||||||
ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
|
ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
|
||||||
la %r2,SP_PTREGS(%r15) # load pt_regs
|
la %r2,SP_PTREGS(%r15) # load pt_regs
|
||||||
brasl %r14,do_signal # call do_signal
|
brasl %r14,do_signal # call do_signal
|
||||||
tm __TI_flags+7(%r12),_TIF_RESTART_SVC
|
tm __TI_flags+7(%r12),_TIF_SYSCALL
|
||||||
jo sysc_restart
|
jno sysc_return
|
||||||
tm __TI_flags+7(%r12),_TIF_PER_TRAP
|
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
|
||||||
jo sysc_singlestep
|
lghi %r7,0 # svc 0 returns -ENOSYS
|
||||||
j sysc_return
|
lh %r1,SP_SVC_CODE+2(%r15) # load new svc number
|
||||||
|
cghi %r1,NR_syscalls
|
||||||
|
jnl sysc_nr_ok # invalid svc number -> do svc 0
|
||||||
|
slag %r7,%r1,2
|
||||||
|
j sysc_nr_ok # restart svc
|
||||||
|
|
||||||
#
|
#
|
||||||
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
|
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
|
||||||
@@ -352,25 +351,11 @@ sysc_notify_resume:
|
|||||||
larl %r14,sysc_return
|
larl %r14,sysc_return
|
||||||
jg do_notify_resume # call do_notify_resume
|
jg do_notify_resume # call do_notify_resume
|
||||||
|
|
||||||
#
|
|
||||||
# _TIF_RESTART_SVC is set, set up registers and restart svc
|
|
||||||
#
|
|
||||||
sysc_restart:
|
|
||||||
ni __TI_flags+7(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
|
|
||||||
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
|
|
||||||
lghi %r7,0 # svc 0 returns -ENOSYS
|
|
||||||
lh %r1,SP_SVC_CODE+2(%r15) # load new svc number
|
|
||||||
cghi %r1,NR_syscalls
|
|
||||||
jnl sysc_nr_ok # invalid svc number -> do svc 0
|
|
||||||
slag %r7,%r1,2
|
|
||||||
j sysc_nr_ok # restart svc
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# _TIF_PER_TRAP is set, call do_per_trap
|
# _TIF_PER_TRAP is set, call do_per_trap
|
||||||
#
|
#
|
||||||
sysc_singlestep:
|
sysc_singlestep:
|
||||||
ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
|
ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc code
|
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
larl %r14,sysc_return # load adr. of system return
|
larl %r14,sysc_return # load adr. of system return
|
||||||
jg do_per_trap
|
jg do_per_trap
|
||||||
@@ -397,7 +382,7 @@ sysc_tracego:
|
|||||||
basr %r14,%r8 # call sys_xxx
|
basr %r14,%r8 # call sys_xxx
|
||||||
stg %r2,SP_R2(%r15) # store return value
|
stg %r2,SP_R2(%r15) # store return value
|
||||||
sysc_tracenogo:
|
sysc_tracenogo:
|
||||||
tm __TI_flags+6(%r12),_TIF_SYSCALL
|
tm __TI_flags+6(%r12),_TIF_TRACE >> 8
|
||||||
jz sysc_return
|
jz sysc_return
|
||||||
la %r2,SP_PTREGS(%r15) # load pt_regs
|
la %r2,SP_PTREGS(%r15) # load pt_regs
|
||||||
larl %r14,sysc_return # return point is sysc_return
|
larl %r14,sysc_return # return point is sysc_return
|
||||||
@@ -470,7 +455,6 @@ ENTRY(pgm_check_handler)
|
|||||||
jnz pgm_per # got per exception -> special case
|
jnz pgm_per # got per exception -> special case
|
||||||
SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15)
|
|
||||||
mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
|
mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
|
||||||
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
HANDLE_SIE_INTERCEPT
|
HANDLE_SIE_INTERCEPT
|
||||||
@@ -550,9 +534,10 @@ pgm_exit2:
|
|||||||
pgm_svcper:
|
pgm_svcper:
|
||||||
SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
|
oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
|
||||||
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
|
||||||
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
|
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
|
||||||
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
||||||
@@ -561,7 +546,6 @@ pgm_svcper:
|
|||||||
mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
|
mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
|
||||||
mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
|
mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
|
mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
|
||||||
oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
|
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
|
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
|
||||||
j sysc_do_svc
|
j sysc_do_svc
|
||||||
@@ -571,7 +555,6 @@ pgm_svcper:
|
|||||||
#
|
#
|
||||||
kernel_per:
|
kernel_per:
|
||||||
REENABLE_IRQS
|
REENABLE_IRQS
|
||||||
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc number
|
|
||||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||||
brasl %r14,do_per_trap
|
brasl %r14,do_per_trap
|
||||||
j pgm_exit
|
j pgm_exit
|
||||||
@@ -972,9 +955,11 @@ cleanup_system_call:
|
|||||||
stg %r15,32(%r12)
|
stg %r15,32(%r12)
|
||||||
stg %r11,0(%r12)
|
stg %r11,0(%r12)
|
||||||
CREATE_STACK_FRAME __LC_SAVE_AREA
|
CREATE_STACK_FRAME __LC_SAVE_AREA
|
||||||
|
mvc 8(8,%r12),__LC_THREAD_INFO
|
||||||
|
lg %r12,__LC_THREAD_INFO
|
||||||
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
|
||||||
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC
|
||||||
mvc 8(8,%r12),__LC_THREAD_INFO
|
oi __TI_flags+7(%r12),_TIF_SYSCALL
|
||||||
cleanup_vtime:
|
cleanup_vtime:
|
||||||
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
|
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
|
||||||
jhe cleanup_stime
|
jhe cleanup_stime
|
||||||
|
@@ -750,7 +750,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
|||||||
* debugger stored an invalid system call number. Skip
|
* debugger stored an invalid system call number. Skip
|
||||||
* the system call and the system call restart handling.
|
* the system call and the system call restart handling.
|
||||||
*/
|
*/
|
||||||
regs->svc_code = 0;
|
clear_thread_flag(TIF_SYSCALL);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -157,7 +157,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
|||||||
current->thread.fp_regs.fpc &= FPC_VALID_MASK;
|
current->thread.fp_regs.fpc &= FPC_VALID_MASK;
|
||||||
|
|
||||||
restore_fp_regs(¤t->thread.fp_regs);
|
restore_fp_regs(¤t->thread.fp_regs);
|
||||||
regs->svc_code = 0; /* disable syscall checks */
|
clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,13 +426,14 @@ void do_signal(struct pt_regs *regs)
|
|||||||
* the debugger may change all our registers, including the system
|
* the debugger may change all our registers, including the system
|
||||||
* call information.
|
* call information.
|
||||||
*/
|
*/
|
||||||
current_thread_info()->system_call = regs->svc_code;
|
current_thread_info()->system_call =
|
||||||
|
test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0;
|
||||||
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||||
regs->svc_code = current_thread_info()->system_call;
|
|
||||||
|
|
||||||
if (signr > 0) {
|
if (signr > 0) {
|
||||||
/* Whee! Actually deliver the signal. */
|
/* Whee! Actually deliver the signal. */
|
||||||
if (regs->svc_code > 0) {
|
if (current_thread_info()->system_call) {
|
||||||
|
regs->svc_code = current_thread_info()->system_call;
|
||||||
/* Check for system call restarting. */
|
/* Check for system call restarting. */
|
||||||
switch (regs->gprs[2]) {
|
switch (regs->gprs[2]) {
|
||||||
case -ERESTART_RESTARTBLOCK:
|
case -ERESTART_RESTARTBLOCK:
|
||||||
@@ -453,7 +454,7 @@ void do_signal(struct pt_regs *regs)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* No longer in a system call */
|
/* No longer in a system call */
|
||||||
regs->svc_code = 0;
|
clear_thread_flag(TIF_SYSCALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((is_compat_task() ?
|
if ((is_compat_task() ?
|
||||||
@@ -478,7 +479,8 @@ void do_signal(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* No handlers present - check for system call restart */
|
/* No handlers present - check for system call restart */
|
||||||
if (regs->svc_code > 0) {
|
if (current_thread_info()->system_call) {
|
||||||
|
regs->svc_code = current_thread_info()->system_call;
|
||||||
switch (regs->gprs[2]) {
|
switch (regs->gprs[2]) {
|
||||||
case -ERESTART_RESTARTBLOCK:
|
case -ERESTART_RESTARTBLOCK:
|
||||||
/* Restart with sys_restart_syscall */
|
/* Restart with sys_restart_syscall */
|
||||||
@@ -489,7 +491,10 @@ void do_signal(struct pt_regs *regs)
|
|||||||
case -ERESTARTNOINTR:
|
case -ERESTARTNOINTR:
|
||||||
/* Restart system call with magic TIF bit. */
|
/* Restart system call with magic TIF bit. */
|
||||||
regs->gprs[2] = regs->orig_gpr2;
|
regs->gprs[2] = regs->orig_gpr2;
|
||||||
set_thread_flag(TIF_RESTART_SVC);
|
set_thread_flag(TIF_SYSCALL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
clear_thread_flag(TIF_SYSCALL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user