diff options
| author | David S. Miller <davem@nuts.ninka.net> | 2003-07-11 12:06:10 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2003-07-11 12:06:10 -0700 |
| commit | 5576c776b8034a5f83ce5c377b486f535ccf7e4f (patch) | |
| tree | 3b9572d94c61fd8ab3acdff7ab2c2de8c8072dc7 | |
| parent | 4be5bd8588bc7ec29813e4fe319420e7e4d9a4d4 (diff) | |
[SPARC64]: Implement force_successful_syscall().
| -rw-r--r-- | arch/sparc64/kernel/entry.S | 14 | ||||
| -rw-r--r-- | include/asm-sparc64/ptrace.h | 2 | ||||
| -rw-r--r-- | include/asm-sparc64/thread_info.h | 8 |
3 files changed, 22 insertions, 2 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 2678db1ea4b9..df3ff3d09a6b 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1749,8 +1749,8 @@ ret_sys_call: cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 bgeu,pn %xcc, 1f - andcc %l0, _TIF_SYSCALL_TRACE, %l6 +80: andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 @@ -1760,9 +1760,21 @@ ret_sys_call: stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: + /* Really a failure? Check if force_successful_syscall_return() + * was invoked. + */ + ldx [%curptr + TI_FLAGS], %l0 ! Load + andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 + be,pt %icc, 1f + andcc %l0, _TIF_SYSCALL_TRACE, %l6 + andn %l0, _TIF_SYSCALL_SUCCESS, %l0 + ba,pt %xcc, 80b + stx %l0, [%curptr + TI_FLAGS] + /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ +1: sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index ec7698b8467f..c679d2c213aa 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -94,6 +94,8 @@ struct sparc_trapf { #define STACKFRAME32_SZ sizeof(struct sparc_stackf32) #ifdef __KERNEL__ +#define force_successful_syscall_return() \ + set_thread_flag(TIF_SYSCALL_SUCCESS) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define instruction_pointer(regs) ((regs)->tpc) extern void show_regs(struct pt_regs *); diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 88dd8b32345a..85e013d40ccb 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -205,7 +205,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TIF_BLKCOMMIT 9 /* use ASI_BLK_COMMIT_* in copy_user_page */ #define TIF_POLLING_NRFLAG 10 -#define TIF_ABI_PENDING 11 +#define TIF_SYSCALL_SUCCESS 11 +/* NOTE: Thread flags >= 12 should be ones we have no interest + * in using in assembly, else we can't use the mask as + * an immediate value in instructions such as andcc. + */ +#define TIF_ABI_PENDING 12 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) @@ -219,6 +224,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_BLKCOMMIT (1<<TIF_BLKCOMMIT) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) +#define _TIF_SYSCALL_SUCCESS (1<<TIF_SYSCALL_SUCCESS) #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ |
