Commit dff933da authored by Al Viro's avatar Al Viro

sparc64: clear syscall_noerror on the entry to syscall, not on the exit

Move that sucker to just before TI_FPDEPTH and replace stb with sth in
etrap_save().  Take current_ds to its old place, so that we don't push
wsaved into TI_... flags.  That allows to lose clearing syscall_noerror
on return from syscall.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ddffeb8c
...@@ -44,9 +44,7 @@ struct global_reg_snapshot { ...@@ -44,9 +44,7 @@ struct global_reg_snapshot {
}; };
extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
#define force_successful_syscall_return() \ #define force_successful_syscall_return() set_thread_noerror(1)
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
#define instruction_pointer(regs) ((regs)->tpc) #define instruction_pointer(regs) ((regs)->tpc)
#define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) #define instruction_pointer_set(regs, val) ((regs)->tpc = (val))
......
...@@ -23,7 +23,7 @@ do { flush_tlb_pending(); \ ...@@ -23,7 +23,7 @@ do { flush_tlb_pending(); \
/* If you are tempted to conditionalize the following */ \ /* If you are tempted to conditionalize the following */ \
/* so that ASI is only written if it changes, think again. */ \ /* so that ASI is only written if it changes, think again. */ \
__asm__ __volatile__("wr %%g0, %0, %%asi" \ __asm__ __volatile__("wr %%g0, %0, %%asi" \
: : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ : : "r" (task_thread_info(next)->current_ds));\
trap_block[current_thread_info()->cpu].thread = \ trap_block[current_thread_info()->cpu].thread = \
task_thread_info(next); \ task_thread_info(next); \
__asm__ __volatile__( \ __asm__ __volatile__( \
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
#define TI_FLAG_FAULT_CODE_SHIFT 56 #define TI_FLAG_FAULT_CODE_SHIFT 56
#define TI_FLAG_BYTE_WSTATE 1 #define TI_FLAG_BYTE_WSTATE 1
#define TI_FLAG_WSTATE_SHIFT 48 #define TI_FLAG_WSTATE_SHIFT 48
#define TI_FLAG_BYTE_CWP 2 #define TI_FLAG_BYTE_NOERROR 2
#define TI_FLAG_CWP_SHIFT 40 #define TI_FLAG_BYTE_NOERROR_SHIFT 40
#define TI_FLAG_BYTE_CURRENT_DS 3 #define TI_FLAG_BYTE_FPDEPTH 3
#define TI_FLAG_CURRENT_DS_SHIFT 32 #define TI_FLAG_FPDEPTH_SHIFT 32
#define TI_FLAG_BYTE_FPDEPTH 4 #define TI_FLAG_BYTE_CWP 4
#define TI_FLAG_FPDEPTH_SHIFT 24 #define TI_FLAG_CWP_SHIFT 24
#define TI_FLAG_BYTE_WSAVED 5 #define TI_FLAG_BYTE_WSAVED 5
#define TI_FLAG_WSAVED_SHIFT 16 #define TI_FLAG_WSAVED_SHIFT 16
...@@ -47,7 +47,7 @@ struct thread_info { ...@@ -47,7 +47,7 @@ struct thread_info {
struct exec_domain *exec_domain; struct exec_domain *exec_domain;
int preempt_count; /* 0 => preemptable, <0 => BUG */ int preempt_count; /* 0 => preemptable, <0 => BUG */
__u8 new_child; __u8 new_child;
__u8 syscall_noerror; __u8 current_ds;
__u16 cpu; __u16 cpu;
unsigned long *utraps; unsigned long *utraps;
...@@ -74,9 +74,9 @@ struct thread_info { ...@@ -74,9 +74,9 @@ struct thread_info {
#define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE)
#define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE)
#define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP)
#define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
#define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
#define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED)
#define TI_SYS_NOERROR (TI_FLAGS + TI_FLAG_BYTE_NOERROR)
#define TI_FPSAVED 0x00000010 #define TI_FPSAVED 0x00000010
#define TI_KSP 0x00000018 #define TI_KSP 0x00000018
#define TI_FAULT_ADDR 0x00000020 #define TI_FAULT_ADDR 0x00000020
...@@ -84,7 +84,7 @@ struct thread_info { ...@@ -84,7 +84,7 @@ struct thread_info {
#define TI_EXEC_DOMAIN 0x00000030 #define TI_EXEC_DOMAIN 0x00000030
#define TI_PRE_COUNT 0x00000038 #define TI_PRE_COUNT 0x00000038
#define TI_NEW_CHILD 0x0000003c #define TI_NEW_CHILD 0x0000003c
#define TI_SYS_NOERROR 0x0000003d #define TI_CURRENT_DS 0x0000003d
#define TI_CPU 0x0000003e #define TI_CPU 0x0000003e
#define TI_UTRAPS 0x00000040 #define TI_UTRAPS 0x00000040
#define TI_REG_WINDOW 0x00000048 #define TI_REG_WINDOW 0x00000048
...@@ -121,7 +121,7 @@ struct thread_info { ...@@ -121,7 +121,7 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
.task = &tsk, \ .task = &tsk, \
.flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ .current_ds = ASI_P, \
.exec_domain = &default_exec_domain, \ .exec_domain = &default_exec_domain, \
.preempt_count = INIT_PREEMPT_COUNT, \ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \ .restart_block = { \
...@@ -153,13 +153,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); ...@@ -153,13 +153,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val))
#define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP])
#define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) #define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val))
#define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS]) #define get_thread_noerror() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR])
#define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) #define set_thread_noerror(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR] = (val))
#define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) #define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH])
#define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) #define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val))
#define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) #define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED])
#define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val))
#endif /* !(__ASSEMBLY__) */ #endif /* !(__ASSEMBLY__) */
/* /*
......
...@@ -38,14 +38,14 @@ ...@@ -38,14 +38,14 @@
#define VERIFY_READ 0 #define VERIFY_READ 0
#define VERIFY_WRITE 1 #define VERIFY_WRITE 1
#define get_fs() ((mm_segment_t) { get_thread_current_ds() }) #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)})
#define get_ds() (KERNEL_DS) #define get_ds() (KERNEL_DS)
#define segment_eq(a,b) ((a).seg == (b).seg) #define segment_eq(a,b) ((a).seg == (b).seg)
#define set_fs(val) \ #define set_fs(val) \
do { \ do { \
set_thread_current_ds((val).seg); \ current_thread_info()->current_ds =(val).seg; \
__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \
} while(0) } while(0)
......
...@@ -92,8 +92,10 @@ etrap_save: save %g2, -STACK_BIAS, %sp ...@@ -92,8 +92,10 @@ etrap_save: save %g2, -STACK_BIAS, %sp
rdpr %wstate, %g2 rdpr %wstate, %g2
wrpr %g0, 0, %canrestore wrpr %g0, 0, %canrestore
sll %g2, 3, %g2 sll %g2, 3, %g2
/* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */
mov 1, %l5 mov 1, %l5
stb %l5, [%l6 + TI_FPDEPTH] sth %l5, [%l6 + TI_SYS_NOERROR]
wrpr %g3, 0, %otherwin wrpr %g3, 0, %otherwin
wrpr %g2, 0, %wstate wrpr %g2, 0, %wstate
...@@ -152,7 +154,9 @@ etrap_save: save %g2, -STACK_BIAS, %sp ...@@ -152,7 +154,9 @@ etrap_save: save %g2, -STACK_BIAS, %sp
add %l6, TI_FPSAVED + 1, %l4 add %l6, TI_FPSAVED + 1, %l4
srl %l5, 1, %l3 srl %l5, 1, %l3
add %l5, 2, %l5 add %l5, 2, %l5
stb %l5, [%l6 + TI_FPDEPTH]
/* Set TI_SYS_FPDEPTH to %l5 and clear TI_SYS_NOERROR. */
sth %l5, [%l6 + TI_SYS_NOERROR]
ba,pt %xcc, 2b ba,pt %xcc, 2b
stb %g0, [%l4 + %l3] stb %g0, [%l4 + %l3]
nop nop
......
...@@ -557,9 +557,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, ...@@ -557,9 +557,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
(THREAD_SIZE - child_stack_sz)); (THREAD_SIZE - child_stack_sz));
memcpy(child_trap_frame, parent_sf, child_stack_sz); memcpy(child_trap_frame, parent_sf, child_stack_sz);
t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | (regs->tstate + 1) & TSTATE_CWP;
(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
t->new_child = 1; t->new_child = 1;
t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
t->kregs = (struct pt_regs *) (child_trap_frame + t->kregs = (struct pt_regs *) (child_trap_frame +
...@@ -575,7 +574,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, ...@@ -575,7 +574,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
t->kregs->u_regs[UREG_FP] = t->kregs->u_regs[UREG_FP] =
((unsigned long) child_sf) - STACK_BIAS; ((unsigned long) child_sf) - STACK_BIAS;
t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); t->current_ds = ASI_P;
t->kregs->u_regs[UREG_G6] = (unsigned long) t; t->kregs->u_regs[UREG_G6] = (unsigned long) t;
t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; t->kregs->u_regs[UREG_G4] = (unsigned long) t->task;
} else { } else {
...@@ -584,7 +583,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, ...@@ -584,7 +583,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
} }
t->kregs->u_regs[UREG_FP] = sp; t->kregs->u_regs[UREG_FP] = sp;
t->flags |= ((long)ASI_AIUS << TI_FLAG_CURRENT_DS_SHIFT); t->current_ds = ASI_AIUS;
if (sp != regs->u_regs[UREG_FP]) { if (sp != regs->u_regs[UREG_FP]) {
unsigned long csp; unsigned long csp;
......
...@@ -222,7 +222,6 @@ ret_sys_call: ...@@ -222,7 +222,6 @@ ret_sys_call:
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
2: 2:
stb %g0, [%g6 + TI_SYS_NOERROR]
/* System call success, clear Carry condition code. */ /* System call success, clear Carry condition code. */
andn %g3, %g2, %g3 andn %g3, %g2, %g3
3: 3:
......
...@@ -2688,8 +2688,8 @@ void __init trap_init(void) ...@@ -2688,8 +2688,8 @@ void __init trap_init(void)
TI_PRE_COUNT != offsetof(struct thread_info, TI_PRE_COUNT != offsetof(struct thread_info,
preempt_count) || preempt_count) ||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) || TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
TI_SYS_NOERROR != offsetof(struct thread_info, TI_CURRENT_DS != offsetof(struct thread_info,
syscall_noerror) || current_ds) ||
TI_RESTART_BLOCK != offsetof(struct thread_info, TI_RESTART_BLOCK != offsetof(struct thread_info,
restart_block) || restart_block) ||
TI_KUNA_REGS != offsetof(struct thread_info, TI_KUNA_REGS != offsetof(struct thread_info,
......
...@@ -624,7 +624,7 @@ static void __init inherit_prom_mappings(void) ...@@ -624,7 +624,7 @@ static void __init inherit_prom_mappings(void)
void prom_world(int enter) void prom_world(int enter)
{ {
if (!enter) if (!enter)
set_fs((mm_segment_t) { get_thread_current_ds() }); set_fs(get_fs());
__asm__ __volatile__("flushw"); __asm__ __volatile__("flushw");
} }
......
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