From fc327e268fbef08e129ad51aa3a7113ee9bc6ba5 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Sat, 28 Apr 2012 18:51:43 -0400 Subject: arch/tile: fix up some issues in calling do_work_pending() First, we were at risk of handling thread-info flags, in particular do_signal(), when returning from kernel space. This could happen after a failed kernel_execve(), or when forking a kernel thread. The fix is to test in do_work_pending() for user_mode() and return immediately if so; we already had this test for one of the flags, so I just hoisted it to the top of the function. Second, if a ptraced process updated the callee-saved registers in the ptregs struct and then processed another thread-info flag, we would overwrite the modifications with the original callee-saved registers. To fix this, we add a register to note if we've already saved the registers once, and skip doing it on additional passes through the loop. To avoid a performance hit from the couple of extra instructions involved, I modified the GET_THREAD_INFO() macro to be guaranteed to be one instruction, then bundled it with adjacent instructions, yielding an overall net savings. Reported-By: Al Viro Signed-off-by: Chris Metcalf --- arch/tile/include/asm/thread_info.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/tile/include') diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index bc4f562bd459..7594764d8a69 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h @@ -100,9 +100,14 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti, #else /* __ASSEMBLY__ */ -/* how to get the thread information struct from ASM */ +/* + * How to get the thread information struct from assembly. + * Note that we use different macros since different architectures + * have different semantics in their "mm" instruction and we would + * like to guarantee that the macro expands to exactly one instruction. + */ #ifdef __tilegx__ -#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63 +#define EXTRACT_THREAD_INFO(reg) mm reg, zero, LOG2_THREAD_SIZE, 63 #else #define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31 #endif -- cgit v1.2.1