Messages in this thread Patch in this message | | | Subject | [PATCH] ppc32: Fix racy access to TI_FLAGS | From | Benjamin Herrenschmidt <> | Date | Fri, 26 Mar 2004 14:21:37 +1100 |
| |
Hi !
The ppc32 syscall entry code could access the thread info flags in a racy way, thus potentially losing bits sets there at interrupt time or by another CPU, like NEED_RESCHED or SIGPENDING (ouch !).
This fixes it by moving the potentially racy bit to a different field (I preferred that rather than turning the access into an atomic operation for performances reasons).
Please apply, Ben.
diff -urN linux-2.5/arch/ppc/kernel/entry.S linuxppc-2.5-benh/arch/ppc/kernel/entry.S --- linux-2.5/arch/ppc/kernel/entry.S 2004-03-01 18:11:11.000000000 +1100 +++ linuxppc-2.5-benh/arch/ppc/kernel/entry.S 2004-03-25 14:10:41.000000000 +1100 @@ -171,9 +171,10 @@ bl do_show_syscall #endif /* SHOW_SYSCALLS */ rlwinm r10,r1,0,0,18 /* current_thread_info() */ + lwz r11,TI_LOCAL_FLAGS(r10) + rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR + stw r11,TI_LOCAL_FLAGS(r10) lwz r11,TI_FLAGS(r10) - rlwinm r11,r11,0,~_TIF_FORCE_NOERROR - stw r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_TRACE bne- syscall_dotrace syscall_dotrace_cont: @@ -196,8 +197,8 @@ cmpl 0,r3,r11 rlwinm r12,r1,0,0,18 /* current_thread_info() */ blt+ 30f - lwz r11,TI_FLAGS(r12) - andi. r11,r11,_TIF_FORCE_NOERROR + lwz r11,TI_LOCAL_FLAGS(r12) + andi. r11,r11,_TIFL_FORCE_NOERROR bne 30f neg r3,r3 lwz r10,_CCR(r1) /* Set SO bit in CR */ diff -urN linux-2.5/include/asm-ppc/ptrace.h linuxppc-2.5-benh/include/asm-ppc/ptrace.h --- linux-2.5/include/asm-ppc/ptrace.h 2004-03-01 18:13:06.000000000 +1100 +++ linuxppc-2.5-benh/include/asm-ppc/ptrace.h 2004-03-25 14:02:44.000000000 +1100 @@ -49,7 +49,10 @@ #define instruction_pointer(regs) ((regs)->nip) #define user_mode(regs) (((regs)->msr & MSR_PR) != 0) -#define force_successful_syscall_return() set_thread_flag(TIF_FORCE_NOERROR) +#define force_successful_syscall_return() \ + do { \ + current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \ + } while(0) /* * We use the least-significant bit of the trap field to indicate diff -urN linux-2.5/include/asm-ppc/thread_info.h linuxppc-2.5-benh/include/asm-ppc/thread_info.h --- linux-2.5/include/asm-ppc/thread_info.h 2004-03-01 18:13:06.000000000 +1100 +++ linuxppc-2.5-benh/include/asm-ppc/thread_info.h 2004-03-25 14:03:56.000000000 +1100 @@ -18,6 +18,7 @@ struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ + unsigned long local_flags; /* non-racy flags */ int cpu; /* cpu we're on */ int preempt_count; struct restart_block restart_block; @@ -28,6 +29,7 @@ .task = &tsk, \ .exec_domain = &default_exec_domain, \ .flags = 0, \ + .local_flags = 0, \ .cpu = 0, \ .preempt_count = 1, \ .restart_block = { \ @@ -69,8 +71,9 @@ #define TI_TASK 0 #define TI_EXECDOMAIN 4 #define TI_FLAGS 8 -#define TI_CPU 12 -#define TI_PREEMPT 16 +#define TI_LOCAL_FLAGS 12 +#define TI_CPU 16 +#define TI_PREEMPT 20 #define PREEMPT_ACTIVE 0x4000000 @@ -83,16 +86,22 @@ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling 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 */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) -#define _TIF_FORCE_NOERROR (1<<TIF_FORCE_NOERROR) + +/* + * Non racy (local) flags bit numbers + */ +#define TIFL_FORCE_NOERROR 0 /* don't return error from current + syscall even if result < 0 */ + +/* as above, but as bit values */ +#define _TIFL_FORCE_NOERROR (1<<TIFL_FORCE_NOERROR) + #endif /* __KERNEL__ */
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |