aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-04 16:52:53 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-04 17:13:29 -0400
commit40138249c3b7a0762155216b963ec7fd4d09b5b4 (patch)
treebe0a2441aa7f7b3245e6de70cc4a8055031742f8 /arch
parentecefbd94b834fa32559d854646d777c56749ef1c (diff)
sparc64: Rearrange thread info to cheaply clear syscall noerror state.
After fixing a couple of brainos, it even seems to work. What's done here is move of ->syscall_noerror right before FPDEPTH byte in ->flags and using sth to [%g6 + TI_SYS_NOERROR] instead of stb to [%g6 + TI_FPDEPTH] in both branches of etrap_save. AFAICS, that ought to be solid. Again, deciding what to do with now unused delay slot of branch on ->syscall_noerror and dealing with the order of tests in ret_from_sys is a separate question, but at least that way we don't have to clean ->syscall_noerror in there at all. AFAICS, it ought to be a clear win - sth is not going to cost more than stb on etrap_64.S side of things, and we are losing write on syscalls.S one. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/include/asm/ptrace.h4
-rw-r--r--arch/sparc/include/asm/thread_info_64.h16
-rw-r--r--arch/sparc/kernel/etrap_64.S8
-rw-r--r--arch/sparc/kernel/syscalls.S4
-rw-r--r--arch/sparc/kernel/traps_64.c2
5 files changed, 19 insertions, 15 deletions
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index fd9c3f21cbf..eeed804316b 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -202,9 +202,7 @@ struct global_reg_snapshot {
202}; 202};
203extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; 203extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
204 204
205#define force_successful_syscall_return() \ 205#define force_successful_syscall_return() set_thread_noerror(1)
206do { current_thread_info()->syscall_noerror = 1; \
207} while (0)
208#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) 206#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
209#define instruction_pointer(regs) ((regs)->tpc) 207#define instruction_pointer(regs) ((regs)->tpc)
210#define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) 208#define instruction_pointer_set(regs, val) ((regs)->tpc = (val))
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index cfa8c38fb9c..8511e5fcc97 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -18,10 +18,12 @@
18#define TI_FLAG_CWP_SHIFT 40 18#define TI_FLAG_CWP_SHIFT 40
19#define TI_FLAG_BYTE_CURRENT_DS 3 19#define TI_FLAG_BYTE_CURRENT_DS 3
20#define TI_FLAG_CURRENT_DS_SHIFT 32 20#define TI_FLAG_CURRENT_DS_SHIFT 32
21#define TI_FLAG_BYTE_FPDEPTH 4 21#define TI_FLAG_BYTE_NOERROR 4
22#define TI_FLAG_FPDEPTH_SHIFT 24 22#define TI_FLAG_BYTE_NOERROR_SHIFT 24
23#define TI_FLAG_BYTE_WSAVED 5 23#define TI_FLAG_BYTE_FPDEPTH 5
24#define TI_FLAG_WSAVED_SHIFT 16 24#define TI_FLAG_FPDEPTH_SHIFT 16
25#define TI_FLAG_BYTE_WSAVED 6
26#define TI_FLAG_WSAVED_SHIFT 8
25 27
26#include <asm/page.h> 28#include <asm/page.h>
27 29
@@ -47,7 +49,7 @@ struct thread_info {
47 struct exec_domain *exec_domain; 49 struct exec_domain *exec_domain;
48 int preempt_count; /* 0 => preemptable, <0 => BUG */ 50 int preempt_count; /* 0 => preemptable, <0 => BUG */
49 __u8 new_child; 51 __u8 new_child;
50 __u8 syscall_noerror; 52 __u8 __pad;
51 __u16 cpu; 53 __u16 cpu;
52 54
53 unsigned long *utraps; 55 unsigned long *utraps;
@@ -77,6 +79,7 @@ struct thread_info {
77#define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS) 79#define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
78#define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) 80#define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
79#define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) 81#define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED)
82#define TI_SYS_NOERROR (TI_FLAGS + TI_FLAG_BYTE_NOERROR)
80#define TI_FPSAVED 0x00000010 83#define TI_FPSAVED 0x00000010
81#define TI_KSP 0x00000018 84#define TI_KSP 0x00000018
82#define TI_FAULT_ADDR 0x00000020 85#define TI_FAULT_ADDR 0x00000020
@@ -84,7 +87,6 @@ struct thread_info {
84#define TI_EXEC_DOMAIN 0x00000030 87#define TI_EXEC_DOMAIN 0x00000030
85#define TI_PRE_COUNT 0x00000038 88#define TI_PRE_COUNT 0x00000038
86#define TI_NEW_CHILD 0x0000003c 89#define TI_NEW_CHILD 0x0000003c
87#define TI_SYS_NOERROR 0x0000003d
88#define TI_CPU 0x0000003e 90#define TI_CPU 0x0000003e
89#define TI_UTRAPS 0x00000040 91#define TI_UTRAPS 0x00000040
90#define TI_REG_WINDOW 0x00000048 92#define TI_REG_WINDOW 0x00000048
@@ -155,6 +157,8 @@ register struct thread_info *current_thread_info_reg asm("g6");
155#define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) 157#define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val))
156#define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS]) 158#define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS])
157#define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) 159#define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val))
160#define get_thread_noerror() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR])
161#define set_thread_noerror(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR] = (val))
158#define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) 162#define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH])
159#define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) 163#define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val))
160#define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) 164#define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED])
diff --git a/arch/sparc/kernel/etrap_64.S b/arch/sparc/kernel/etrap_64.S
index 786b185e6e3..1276ca2567b 100644
--- a/arch/sparc/kernel/etrap_64.S
+++ b/arch/sparc/kernel/etrap_64.S
@@ -92,8 +92,10 @@ etrap_save: save %g2, -STACK_BIAS, %sp
92 rdpr %wstate, %g2 92 rdpr %wstate, %g2
93 wrpr %g0, 0, %canrestore 93 wrpr %g0, 0, %canrestore
94 sll %g2, 3, %g2 94 sll %g2, 3, %g2
95
96 /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */
95 mov 1, %l5 97 mov 1, %l5
96 stb %l5, [%l6 + TI_FPDEPTH] 98 sth %l5, [%l6 + TI_SYS_NOERROR]
97 99
98 wrpr %g3, 0, %otherwin 100 wrpr %g3, 0, %otherwin
99 wrpr %g2, 0, %wstate 101 wrpr %g2, 0, %wstate
@@ -152,7 +154,9 @@ etrap_save: save %g2, -STACK_BIAS, %sp
152 add %l6, TI_FPSAVED + 1, %l4 154 add %l6, TI_FPSAVED + 1, %l4
153 srl %l5, 1, %l3 155 srl %l5, 1, %l3
154 add %l5, 2, %l5 156 add %l5, 2, %l5
155 stb %l5, [%l6 + TI_FPDEPTH] 157
158 /* Set TI_SYS_FPDEPTH to %l5 and clear TI_SYS_NOERROR. */
159 sth %l5, [%l6 + TI_SYS_NOERROR]
156 ba,pt %xcc, 2b 160 ba,pt %xcc, 2b
157 stb %g0, [%l4 + %l3] 161 stb %g0, [%l4 + %l3]
158 nop 162 nop
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274f3f2..ed277e2fdfc 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -221,8 +221,8 @@ ret_sys_call:
221 * was invoked. 221 * was invoked.
222 */ 222 */
223 ldub [%g6 + TI_SYS_NOERROR], %l2 223 ldub [%g6 + TI_SYS_NOERROR], %l2
224 brnz,a,pn %l2, 80f 224 brnz,pn %l2, 80f
225 stb %g0, [%g6 + TI_SYS_NOERROR] 225 nop
226 226
227 cmp %o0, -ERESTART_RESTARTBLOCK 227 cmp %o0, -ERESTART_RESTARTBLOCK
228 bgeu,pn %xcc, 1f 228 bgeu,pn %xcc, 1f
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index fa1f1d375ff..82af591fe43 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2547,8 +2547,6 @@ void __init trap_init(void)
2547 TI_PRE_COUNT != offsetof(struct thread_info, 2547 TI_PRE_COUNT != offsetof(struct thread_info,
2548 preempt_count) || 2548 preempt_count) ||
2549 TI_NEW_CHILD != offsetof(struct thread_info, new_child) || 2549 TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
2550 TI_SYS_NOERROR != offsetof(struct thread_info,
2551 syscall_noerror) ||
2552 TI_RESTART_BLOCK != offsetof(struct thread_info, 2550 TI_RESTART_BLOCK != offsetof(struct thread_info,
2553 restart_block) || 2551 restart_block) ||
2554 TI_KUNA_REGS != offsetof(struct thread_info, 2552 TI_KUNA_REGS != offsetof(struct thread_info,