Commit b6ef5bb3 authored by Martin Schwidefsky's avatar Martin Schwidefsky

[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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ccf45caf
...@@ -26,7 +26,8 @@ extern const unsigned int sys_call_table[]; ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -342,7 +342,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
return err; return err;
restore_fp_regs(&current->thread.fp_regs); restore_fp_regs(&current->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 ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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 ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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(&current->thread.fp_regs); restore_fp_regs(&current->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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment