summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2003-07-11 12:06:10 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2003-07-11 12:06:10 -0700
commit5576c776b8034a5f83ce5c377b486f535ccf7e4f (patch)
tree3b9572d94c61fd8ab3acdff7ab2c2de8c8072dc7
parent4be5bd8588bc7ec29813e4fe319420e7e4d9a4d4 (diff)
[SPARC64]: Implement force_successful_syscall().
-rw-r--r--arch/sparc64/kernel/entry.S14
-rw-r--r--include/asm-sparc64/ptrace.h2
-rw-r--r--include/asm-sparc64/thread_info.h8
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 | \