Skip to content

Commit

Permalink
[S390] add TIF_SYSCALL thread flag
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Martin Schwidefsky committed Oct 30, 2011
1 parent ccf45ca commit b6ef5bb
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 94 deletions.
3 changes: 2 additions & 1 deletion arch/s390/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ extern const unsigned int sys_call_table[];
static inline long syscall_get_nr(struct task_struct *task,
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,
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ static inline struct thread_info *current_thread_info(void)
/*
* 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_SIGPENDING 2 /* signal pending */
#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_MCCK_PENDING 7 /* machine check handling is pending */
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
Expand All @@ -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_FREEZE 21 /* thread is freezing for suspend */

#define _TIF_SYSCALL (1<<TIF_SYSCALL)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#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_MCCK_PENDING (1<<TIF_MCCK_PENDING)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
return err;

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;
}

Expand Down
66 changes: 25 additions & 41 deletions arch/s390/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE

_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_MCCK_PENDING)
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
_TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT)

STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT
Expand Down Expand Up @@ -227,9 +227,10 @@ ENTRY(system_call)
sysc_saveall:
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__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_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:
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
Expand All @@ -248,7 +249,7 @@ sysc_do_svc:
sysc_nr_ok:
sll %r7,2 # svc number *4
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)
l %r8,0(%r7,%r10) # get system call addr.
bnz BASED(sysc_tracesys)
Expand All @@ -258,23 +259,19 @@ sysc_nr_ok:
sysc_return:
LOCKDEP_SYS_EXIT
sysc_tif:
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_restore)
tm __TI_flags+3(%r12),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
ni __TI_flags+3(%r12),255-_TIF_SYSCALL
sysc_restore:
RESTORE_ALL __LC_RETURN_PSW,1
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.
#
sysc_work_tif:
sysc_work:
tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
bo BASED(sysc_mcck_pending)
tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
Expand All @@ -283,8 +280,6 @@ sysc_work_tif:
bo BASED(sysc_sigpending)
tm __TI_flags+3(%r12),_TIF_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
bo BASED(sysc_singlestep)
b BASED(sysc_return) # beware of critical section cleanup
Expand Down Expand Up @@ -313,11 +308,14 @@ sysc_sigpending:
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
tm __TI_flags+3(%r12),_TIF_RESTART_SVC
bo BASED(sysc_restart)
tm __TI_flags+3(%r12),_TIF_PER_TRAP
bo BASED(sysc_singlestep)
b BASED(sysc_return)
tm __TI_flags+3(%r12),_TIF_SYSCALL
bno BASED(sysc_return)
lm %r2,%r6,SP_R2(%r15) # load svc arguments
xr %r7,%r7 # svc 0 returns -ENOSYS
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
Expand All @@ -328,25 +326,11 @@ sysc_notify_resume:
la %r14,BASED(sysc_return)
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
#
sysc_singlestep:
ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc code
ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_return) # load adr. of system return
Expand Down Expand Up @@ -376,7 +360,7 @@ sysc_tracego:
basr %r14,%r8 # call sys_xxx
st %r2,SP_R2(%r15) # store return value
sysc_tracenogo:
tm __TI_flags+2(%r12),_TIF_SYSCALL
tm __TI_flags+2(%r12),_TIF_TRACE >> 8
bz BASED(sysc_return)
l %r1,BASED(.Ltrace_exit)
la %r2,SP_PTREGS(%r15) # load pt_regs
Expand Down Expand Up @@ -454,7 +438,6 @@ ENTRY(pgm_check_handler)
bnz BASED(pgm_per) # got per exception -> special case
SAVE_ALL_PGM __LC_PGM_OLD_PSW,__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
l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
Expand Down Expand Up @@ -530,17 +513,17 @@ pgm_exit2:
pgm_svcper:
SAVE_ALL_PGM __LC_SVC_OLD_PSW,__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_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_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
l %r8,__TI_task(%r12)
mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
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
lm %r2,%r6,SP_R2(%r15) # load svc arguments
b BASED(sysc_do_svc)
Expand All @@ -550,7 +533,6 @@ pgm_svcper:
#
kernel_per:
REENABLE_IRQS
xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15)
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
basr %r14,%r1 # branch to do_single_step
Expand Down Expand Up @@ -965,9 +947,11 @@ cleanup_system_call:
s %r15,BASED(.Lc_spsize) # make room for registers & psw
st %r15,12(%r12)
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_SVC_CODE(4,%r15),__LC_SVC_ILC
mvc 0(4,%r12),__LC_THREAD_INFO
oi __TI_flags+3(%r12),_TIF_SYSCALL
cleanup_vtime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
bhe BASED(cleanup_stime)
Expand Down
Loading

0 comments on commit b6ef5bb

Please sign in to comment.