Commit 4043848c authored by Paul Mackerras's avatar Paul Mackerras

PPC32: Implement force_successful_syscall_return.

We use a bit in the thread_info flags for this.  The bit is cleared on syscall
entry and set by force_successful_syscall_return.  If the bit is set on syscall
exit, the normal check whether the value from the syscall function is an
error code is disabled and the value is just returned to userspace.
parent aae1760a
...@@ -173,8 +173,10 @@ _GLOBAL(DoSyscall) ...@@ -173,8 +173,10 @@ _GLOBAL(DoSyscall)
cmpli 0,r0,NR_syscalls cmpli 0,r0,NR_syscalls
bge- 66f bge- 66f
rlwinm r10,r1,0,0,18 /* current_thread_info() */ rlwinm r10,r1,0,0,18 /* current_thread_info() */
lwz r10,TI_FLAGS(r10) lwz r11,TI_FLAGS(r10)
andi. r10,r10,_TIF_SYSCALL_TRACE rlwinm r11,r11,0,~_TIF_FORCE_NOERROR
stw r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_TRACE
bne- syscall_dotrace bne- syscall_dotrace
syscall_dotrace_cont: syscall_dotrace_cont:
lis r10,sys_call_table@h lis r10,sys_call_table@h
...@@ -192,7 +194,11 @@ ret_from_syscall: ...@@ -192,7 +194,11 @@ ret_from_syscall:
mr r6,r3 mr r6,r3
li r11,-_LAST_ERRNO li r11,-_LAST_ERRNO
cmpl 0,r3,r11 cmpl 0,r3,r11
rlwinm r12,r1,0,0,18 /* current_thread_info() */
blt+ 30f blt+ 30f
lwz r11,TI_FLAGS(r12)
andi. r11,r11,_TIF_FORCE_NOERROR
bne 30f
neg r3,r3 neg r3,r3
cmpi 0,r3,ERESTARTNOHAND cmpi 0,r3,ERESTARTNOHAND
bne 22f bne 22f
...@@ -205,7 +211,6 @@ ret_from_syscall: ...@@ -205,7 +211,6 @@ ret_from_syscall:
30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
SYNC SYNC
MTMSRD(r10) MTMSRD(r10)
rlwinm r12,r1,0,0,18 /* current_thread_info() */
lwz r9,TI_FLAGS(r12) lwz r9,TI_FLAGS(r12)
andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED) andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
bne- syscall_exit_work bne- syscall_exit_work
......
...@@ -49,6 +49,8 @@ struct pt_regs { ...@@ -49,6 +49,8 @@ struct pt_regs {
#define instruction_pointer(regs) ((regs)->nip) #define instruction_pointer(regs) ((regs)->nip)
#define user_mode(regs) (((regs)->msr & MSR_PR) != 0) #define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
#define force_successful_syscall_return() set_thread_flag(TIF_FORCE_NOERROR)
/* /*
* We use the least-significant bit of the trap field to indicate * We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a * whether we have saved the full set of registers, or only a
......
...@@ -86,6 +86,8 @@ static inline struct thread_info *current_thread_info(void) ...@@ -86,6 +86,8 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
TIF_NEED_RESCHED */ TIF_NEED_RESCHED */
#define TIF_FORCE_NOERROR 5 /* don't return error from current
syscall even if result < 0 */
/* as above, but as bit values */ /* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
...@@ -93,6 +95,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -93,6 +95,7 @@ static inline struct thread_info *current_thread_info(void)
#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_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FORCE_NOERROR (1<<TIF_FORCE_NOERROR)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
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