diff options
Diffstat (limited to 'arch/sparc/include')
-rw-r--r-- | arch/sparc/include/asm/atomic_64.h | 4 | ||||
-rw-r--r-- | arch/sparc/include/asm/backoff.h | 69 | ||||
-rw-r--r-- | arch/sparc/include/asm/compat.h | 5 | ||||
-rw-r--r-- | arch/sparc/include/asm/processor_32.h | 1 | ||||
-rw-r--r-- | arch/sparc/include/asm/processor_64.h | 28 | ||||
-rw-r--r-- | arch/sparc/include/asm/prom.h | 8 | ||||
-rw-r--r-- | arch/sparc/include/asm/ptrace.h | 23 | ||||
-rw-r--r-- | arch/sparc/include/asm/smp_64.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/asm/switch_to_64.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/asm/syscalls.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/asm/thread_info_64.h | 30 | ||||
-rw-r--r-- | arch/sparc/include/asm/ttable.h | 24 | ||||
-rw-r--r-- | arch/sparc/include/asm/uaccess_64.h | 4 | ||||
-rw-r--r-- | arch/sparc/include/asm/unistd.h | 1 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/sigcontext.h | 4 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/unistd.h | 7 |
16 files changed, 166 insertions, 48 deletions
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index ce35a1cf1a20..be56a244c9cf 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* atomic.h: Thankfully the V9 is at least reasonable for this | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
2 | * stuff. | 2 | * stuff. |
3 | * | 3 | * |
4 | * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __ARCH_SPARC64_ATOMIC__ | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
@@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) | |||
106 | 106 | ||
107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
108 | 108 | ||
109 | extern long atomic64_dec_if_positive(atomic64_t *v); | ||
110 | |||
109 | /* Atomic operations are already serializing */ | 111 | /* Atomic operations are already serializing */ |
110 | #define smp_mb__before_atomic_dec() barrier() | 112 | #define smp_mb__before_atomic_dec() barrier() |
111 | #define smp_mb__after_atomic_dec() barrier() | 113 | #define smp_mb__after_atomic_dec() barrier() |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index db3af0d30fb1..4e02086b839c 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -1,6 +1,46 @@ | |||
1 | #ifndef _SPARC64_BACKOFF_H | 1 | #ifndef _SPARC64_BACKOFF_H |
2 | #define _SPARC64_BACKOFF_H | 2 | #define _SPARC64_BACKOFF_H |
3 | 3 | ||
4 | /* The macros in this file implement an exponential backoff facility | ||
5 | * for atomic operations. | ||
6 | * | ||
7 | * When multiple threads compete on an atomic operation, it is | ||
8 | * possible for one thread to be continually denied a successful | ||
9 | * completion of the compare-and-swap instruction. Heavily | ||
10 | * threaded cpu implementations like Niagara can compound this | ||
11 | * problem even further. | ||
12 | * | ||
13 | * When an atomic operation fails and needs to be retried, we spin a | ||
14 | * certain number of times. At each subsequent failure of the same | ||
15 | * operation we double the spin count, realizing an exponential | ||
16 | * backoff. | ||
17 | * | ||
18 | * When we spin, we try to use an operation that will cause the | ||
19 | * current cpu strand to block, and therefore make the core fully | ||
20 | * available to any other other runnable strands. There are two | ||
21 | * options, based upon cpu capabilities. | ||
22 | * | ||
23 | * On all cpus prior to SPARC-T4 we do three dummy reads of the | ||
24 | * condition code register. Each read blocks the strand for something | ||
25 | * between 40 and 50 cpu cycles. | ||
26 | * | ||
27 | * For SPARC-T4 and later we have a special "pause" instruction | ||
28 | * available. This is implemented using writes to register %asr27. | ||
29 | * The cpu will block the number of cycles written into the register, | ||
30 | * unless a disrupting trap happens first. SPARC-T4 specifically | ||
31 | * implements pause with a granularity of 8 cycles. Each strand has | ||
32 | * an internal pause counter which decrements every 8 cycles. So the | ||
33 | * chip shifts the %asr27 value down by 3 bits, and writes the result | ||
34 | * into the pause counter. If a value smaller than 8 is written, the | ||
35 | * chip blocks for 1 cycle. | ||
36 | * | ||
37 | * To achieve the same amount of backoff as the three %ccr reads give | ||
38 | * on earlier chips, we shift the backoff value up by 7 bits. (Three | ||
39 | * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | ||
40 | * whole amount we want to block into the pause register, rather than | ||
41 | * loop writing 128 each time. | ||
42 | */ | ||
43 | |||
4 | #define BACKOFF_LIMIT (4 * 1024) | 44 | #define BACKOFF_LIMIT (4 * 1024) |
5 | 45 | ||
6 | #ifdef CONFIG_SMP | 46 | #ifdef CONFIG_SMP |
@@ -11,16 +51,25 @@ | |||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
12 | spin_label | 52 | spin_label |
13 | 53 | ||
14 | #define BACKOFF_SPIN(reg, tmp, label) \ | 54 | #define BACKOFF_SPIN(reg, tmp, label) \ |
15 | mov reg, tmp; \ | 55 | mov reg, tmp; \ |
16 | 88: brnz,pt tmp, 88b; \ | 56 | 88: rd %ccr, %g0; \ |
17 | sub tmp, 1, tmp; \ | 57 | rd %ccr, %g0; \ |
18 | set BACKOFF_LIMIT, tmp; \ | 58 | rd %ccr, %g0; \ |
19 | cmp reg, tmp; \ | 59 | .section .pause_3insn_patch,"ax";\ |
20 | bg,pn %xcc, label; \ | 60 | .word 88b; \ |
21 | nop; \ | 61 | sllx tmp, 7, tmp; \ |
22 | ba,pt %xcc, label; \ | 62 | wr tmp, 0, %asr27; \ |
23 | sllx reg, 1, reg; | 63 | clr tmp; \ |
64 | .previous; \ | ||
65 | brnz,pt tmp, 88b; \ | ||
66 | sub tmp, 1, tmp; \ | ||
67 | set BACKOFF_LIMIT, tmp; \ | ||
68 | cmp reg, tmp; \ | ||
69 | bg,pn %xcc, label; \ | ||
70 | nop; \ | ||
71 | ba,pt %xcc, label; \ | ||
72 | sllx reg, 1, reg; | ||
24 | 73 | ||
25 | #else | 74 | #else |
26 | 75 | ||
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index cef99fbc0a21..830502fe62b4 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h | |||
@@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
232 | struct pt_regs *regs = current_thread_info()->kregs; | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
233 | unsigned long usp = regs->u_regs[UREG_I6]; | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
234 | 234 | ||
235 | if (!(test_thread_flag(TIF_32BIT))) | 235 | if (test_thread_64bit_stack(usp)) |
236 | usp += STACK_BIAS; | 236 | usp += STACK_BIAS; |
237 | else | 237 | |
238 | if (test_thread_flag(TIF_32BIT)) | ||
238 | usp &= 0xffffffffUL; | 239 | usp &= 0xffffffffUL; |
239 | 240 | ||
240 | usp -= len; | 241 | usp -= len; |
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index f74ac9ee33a8..c1e01914fd98 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h | |||
@@ -106,7 +106,6 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc, | |||
106 | 106 | ||
107 | /* Free all resources held by a thread. */ | 107 | /* Free all resources held by a thread. */ |
108 | #define release_thread(tsk) do { } while(0) | 108 | #define release_thread(tsk) do { } while(0) |
109 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
110 | 109 | ||
111 | extern unsigned long get_wchan(struct task_struct *); | 110 | extern unsigned long get_wchan(struct task_struct *); |
112 | 111 | ||
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 4e5a483122a0..cce72ce4c334 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h | |||
@@ -94,6 +94,7 @@ struct thread_struct { | |||
94 | #ifndef __ASSEMBLY__ | 94 | #ifndef __ASSEMBLY__ |
95 | 95 | ||
96 | #include <linux/types.h> | 96 | #include <linux/types.h> |
97 | #include <asm/fpumacro.h> | ||
97 | 98 | ||
98 | /* Return saved PC of a blocked thread. */ | 99 | /* Return saved PC of a blocked thread. */ |
99 | struct task_struct; | 100 | struct task_struct; |
@@ -143,6 +144,10 @@ do { \ | |||
143 | : \ | 144 | : \ |
144 | : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ | 145 | : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ |
145 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ | 146 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ |
147 | fprs_write(0); \ | ||
148 | current_thread_info()->xfsr[0] = 0; \ | ||
149 | current_thread_info()->fpsaved[0] = 0; \ | ||
150 | regs->tstate &= ~TSTATE_PEF; \ | ||
146 | } while (0) | 151 | } while (0) |
147 | 152 | ||
148 | #define start_thread32(regs, pc, sp) \ | 153 | #define start_thread32(regs, pc, sp) \ |
@@ -183,20 +188,37 @@ do { \ | |||
183 | : \ | 188 | : \ |
184 | : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ | 189 | : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ |
185 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ | 190 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ |
191 | fprs_write(0); \ | ||
192 | current_thread_info()->xfsr[0] = 0; \ | ||
193 | current_thread_info()->fpsaved[0] = 0; \ | ||
194 | regs->tstate &= ~TSTATE_PEF; \ | ||
186 | } while (0) | 195 | } while (0) |
187 | 196 | ||
188 | /* Free all resources held by a thread. */ | 197 | /* Free all resources held by a thread. */ |
189 | #define release_thread(tsk) do { } while (0) | 198 | #define release_thread(tsk) do { } while (0) |
190 | 199 | ||
191 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
192 | |||
193 | extern unsigned long get_wchan(struct task_struct *task); | 200 | extern unsigned long get_wchan(struct task_struct *task); |
194 | 201 | ||
195 | #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs) | 202 | #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs) |
196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) | 203 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) | 204 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
198 | 205 | ||
199 | #define cpu_relax() barrier() | 206 | /* Please see the commentary in asm/backoff.h for a description of |
207 | * what these instructions are doing and how they have been choosen. | ||
208 | * To make a long story short, we are trying to yield the current cpu | ||
209 | * strand during busy loops. | ||
210 | */ | ||
211 | #define cpu_relax() asm volatile("\n99:\n\t" \ | ||
212 | "rd %%ccr, %%g0\n\t" \ | ||
213 | "rd %%ccr, %%g0\n\t" \ | ||
214 | "rd %%ccr, %%g0\n\t" \ | ||
215 | ".section .pause_3insn_patch,\"ax\"\n\t"\ | ||
216 | ".word 99b\n\t" \ | ||
217 | "wr %%g0, 128, %%asr27\n\t" \ | ||
218 | "nop\n\t" \ | ||
219 | "nop\n\t" \ | ||
220 | ".previous" \ | ||
221 | ::: "memory") | ||
200 | 222 | ||
201 | /* Prefetch support. This is tuned for UltraSPARC-III and later. | 223 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
202 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has | 224 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c28765110706..67c62578d170 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
@@ -63,5 +63,13 @@ extern char *of_console_options; | |||
63 | extern void irq_trans_init(struct device_node *dp); | 63 | extern void irq_trans_init(struct device_node *dp); |
64 | extern char *build_path_component(struct device_node *dp); | 64 | extern char *build_path_component(struct device_node *dp); |
65 | 65 | ||
66 | /* SPARC has local implementations */ | ||
67 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
68 | struct resource *r); | ||
69 | #define of_address_to_resource of_address_to_resource | ||
70 | |||
71 | void __iomem *of_iomap(struct device_node *node, int index); | ||
72 | #define of_iomap of_iomap | ||
73 | |||
66 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
67 | #endif /* _SPARC_PROM_H */ | 75 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index 0c6f6b068289..bdfafd7af46f 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h | |||
@@ -32,6 +32,9 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | |||
32 | #define arch_ptrace_stop(exit_code, info) \ | 32 | #define arch_ptrace_stop(exit_code, info) \ |
33 | synchronize_user_stack() | 33 | synchronize_user_stack() |
34 | 34 | ||
35 | #define current_pt_regs() \ | ||
36 | ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) | ||
37 | |||
35 | struct global_reg_snapshot { | 38 | struct global_reg_snapshot { |
36 | unsigned long tstate; | 39 | unsigned long tstate; |
37 | unsigned long tpc; | 40 | unsigned long tpc; |
@@ -42,11 +45,20 @@ struct global_reg_snapshot { | |||
42 | struct thread_info *thread; | 45 | struct thread_info *thread; |
43 | unsigned long pad1; | 46 | unsigned long pad1; |
44 | }; | 47 | }; |
45 | extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; | ||
46 | 48 | ||
47 | #define force_successful_syscall_return() \ | 49 | struct global_pmu_snapshot { |
48 | do { current_thread_info()->syscall_noerror = 1; \ | 50 | unsigned long pcr[4]; |
49 | } while (0) | 51 | unsigned long pic[4]; |
52 | }; | ||
53 | |||
54 | union global_cpu_snapshot { | ||
55 | struct global_reg_snapshot reg; | ||
56 | struct global_pmu_snapshot pmu; | ||
57 | }; | ||
58 | |||
59 | extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS]; | ||
60 | |||
61 | #define force_successful_syscall_return() set_thread_noerror(1) | ||
50 | #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) | 62 | #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) |
51 | #define instruction_pointer(regs) ((regs)->tpc) | 63 | #define instruction_pointer(regs) ((regs)->tpc) |
52 | #define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) | 64 | #define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) |
@@ -89,6 +101,9 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | |||
89 | #define arch_ptrace_stop(exit_code, info) \ | 101 | #define arch_ptrace_stop(exit_code, info) \ |
90 | synchronize_user_stack() | 102 | synchronize_user_stack() |
91 | 103 | ||
104 | #define current_pt_regs() \ | ||
105 | ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) | ||
106 | |||
92 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) | 107 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) |
93 | #define instruction_pointer(regs) ((regs)->pc) | 108 | #define instruction_pointer(regs) ((regs)->pc) |
94 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) | 109 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) |
diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index 29862a9e9065..dd3bef4b9896 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h | |||
@@ -48,6 +48,7 @@ extern void smp_fill_in_sib_core_maps(void); | |||
48 | extern void cpu_play_dead(void); | 48 | extern void cpu_play_dead(void); |
49 | 49 | ||
50 | extern void smp_fetch_global_regs(void); | 50 | extern void smp_fetch_global_regs(void); |
51 | extern void smp_fetch_global_pmu(void); | ||
51 | 52 | ||
52 | struct seq_file; | 53 | struct seq_file; |
53 | void smp_bogo(struct seq_file *); | 54 | void smp_bogo(struct seq_file *); |
@@ -65,6 +66,7 @@ extern void __cpu_die(unsigned int cpu); | |||
65 | #define hard_smp_processor_id() 0 | 66 | #define hard_smp_processor_id() 0 |
66 | #define smp_fill_in_sib_core_maps() do { } while (0) | 67 | #define smp_fill_in_sib_core_maps() do { } while (0) |
67 | #define smp_fetch_global_regs() do { } while (0) | 68 | #define smp_fetch_global_regs() do { } while (0) |
69 | #define smp_fetch_global_pmu() do { } while (0) | ||
68 | 70 | ||
69 | #endif /* !(CONFIG_SMP) */ | 71 | #endif /* !(CONFIG_SMP) */ |
70 | 72 | ||
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index 7923c4a2be38..cad36f56fa03 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h | |||
@@ -23,7 +23,7 @@ do { flush_tlb_pending(); \ | |||
23 | /* If you are tempted to conditionalize the following */ \ | 23 | /* If you are tempted to conditionalize the following */ \ |
24 | /* so that ASI is only written if it changes, think again. */ \ | 24 | /* so that ASI is only written if it changes, think again. */ \ |
25 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ | 25 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ |
26 | : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ | 26 | : : "r" (task_thread_info(next)->current_ds));\ |
27 | trap_block[current_thread_info()->cpu].thread = \ | 27 | trap_block[current_thread_info()->cpu].thread = \ |
28 | task_thread_info(next); \ | 28 | task_thread_info(next); \ |
29 | __asm__ __volatile__( \ | 29 | __asm__ __volatile__( \ |
diff --git a/arch/sparc/include/asm/syscalls.h b/arch/sparc/include/asm/syscalls.h index 45a43f637a14..bf8972adea17 100644 --- a/arch/sparc/include/asm/syscalls.h +++ b/arch/sparc/include/asm/syscalls.h | |||
@@ -8,6 +8,4 @@ extern asmlinkage long sparc_do_fork(unsigned long clone_flags, | |||
8 | struct pt_regs *regs, | 8 | struct pt_regs *regs, |
9 | unsigned long stack_size); | 9 | unsigned long stack_size); |
10 | 10 | ||
11 | extern asmlinkage int sparc_execve(struct pt_regs *regs); | ||
12 | |||
13 | #endif /* _SPARC64_SYSCALLS_H */ | 11 | #endif /* _SPARC64_SYSCALLS_H */ |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 4e2276631081..269bd92313df 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
@@ -14,12 +14,12 @@ | |||
14 | #define TI_FLAG_FAULT_CODE_SHIFT 56 | 14 | #define TI_FLAG_FAULT_CODE_SHIFT 56 |
15 | #define TI_FLAG_BYTE_WSTATE 1 | 15 | #define TI_FLAG_BYTE_WSTATE 1 |
16 | #define TI_FLAG_WSTATE_SHIFT 48 | 16 | #define TI_FLAG_WSTATE_SHIFT 48 |
17 | #define TI_FLAG_BYTE_CWP 2 | 17 | #define TI_FLAG_BYTE_NOERROR 2 |
18 | #define TI_FLAG_CWP_SHIFT 40 | 18 | #define TI_FLAG_BYTE_NOERROR_SHIFT 40 |
19 | #define TI_FLAG_BYTE_CURRENT_DS 3 | 19 | #define TI_FLAG_BYTE_FPDEPTH 3 |
20 | #define TI_FLAG_CURRENT_DS_SHIFT 32 | 20 | #define TI_FLAG_FPDEPTH_SHIFT 32 |
21 | #define TI_FLAG_BYTE_FPDEPTH 4 | 21 | #define TI_FLAG_BYTE_CWP 4 |
22 | #define TI_FLAG_FPDEPTH_SHIFT 24 | 22 | #define TI_FLAG_CWP_SHIFT 24 |
23 | #define TI_FLAG_BYTE_WSAVED 5 | 23 | #define TI_FLAG_BYTE_WSAVED 5 |
24 | #define TI_FLAG_WSAVED_SHIFT 16 | 24 | #define TI_FLAG_WSAVED_SHIFT 16 |
25 | 25 | ||
@@ -47,7 +47,7 @@ struct thread_info { | |||
47 | struct exec_domain *exec_domain; | 47 | struct exec_domain *exec_domain; |
48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
49 | __u8 new_child; | 49 | __u8 new_child; |
50 | __u8 syscall_noerror; | 50 | __u8 current_ds; |
51 | __u16 cpu; | 51 | __u16 cpu; |
52 | 52 | ||
53 | unsigned long *utraps; | 53 | unsigned long *utraps; |
@@ -74,9 +74,9 @@ struct thread_info { | |||
74 | #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) | 74 | #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) |
75 | #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) | 75 | #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) |
76 | #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) | 76 | #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) |
77 | #define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS) | ||
78 | #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) | 77 | #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) |
79 | #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) | 78 | #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) |
79 | #define TI_SYS_NOERROR (TI_FLAGS + TI_FLAG_BYTE_NOERROR) | ||
80 | #define TI_FPSAVED 0x00000010 | 80 | #define TI_FPSAVED 0x00000010 |
81 | #define TI_KSP 0x00000018 | 81 | #define TI_KSP 0x00000018 |
82 | #define TI_FAULT_ADDR 0x00000020 | 82 | #define TI_FAULT_ADDR 0x00000020 |
@@ -84,7 +84,7 @@ struct thread_info { | |||
84 | #define TI_EXEC_DOMAIN 0x00000030 | 84 | #define TI_EXEC_DOMAIN 0x00000030 |
85 | #define TI_PRE_COUNT 0x00000038 | 85 | #define TI_PRE_COUNT 0x00000038 |
86 | #define TI_NEW_CHILD 0x0000003c | 86 | #define TI_NEW_CHILD 0x0000003c |
87 | #define TI_SYS_NOERROR 0x0000003d | 87 | #define TI_CURRENT_DS 0x0000003d |
88 | #define TI_CPU 0x0000003e | 88 | #define TI_CPU 0x0000003e |
89 | #define TI_UTRAPS 0x00000040 | 89 | #define TI_UTRAPS 0x00000040 |
90 | #define TI_REG_WINDOW 0x00000048 | 90 | #define TI_REG_WINDOW 0x00000048 |
@@ -121,7 +121,7 @@ struct thread_info { | |||
121 | #define INIT_THREAD_INFO(tsk) \ | 121 | #define INIT_THREAD_INFO(tsk) \ |
122 | { \ | 122 | { \ |
123 | .task = &tsk, \ | 123 | .task = &tsk, \ |
124 | .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ | 124 | .current_ds = ASI_P, \ |
125 | .exec_domain = &default_exec_domain, \ | 125 | .exec_domain = &default_exec_domain, \ |
126 | .preempt_count = INIT_PREEMPT_COUNT, \ | 126 | .preempt_count = INIT_PREEMPT_COUNT, \ |
127 | .restart_block = { \ | 127 | .restart_block = { \ |
@@ -153,13 +153,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
153 | #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) | 153 | #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) |
154 | #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) | 154 | #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) |
155 | #define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) | 155 | #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]) | 156 | #define get_thread_noerror() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR]) |
157 | #define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) | 157 | #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]) | 158 | #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)) | 159 | #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]) | 160 | #define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) |
161 | #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) | 161 | #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) |
162 | |||
163 | #endif /* !(__ASSEMBLY__) */ | 162 | #endif /* !(__ASSEMBLY__) */ |
164 | 163 | ||
165 | /* | 164 | /* |
@@ -259,6 +258,11 @@ static inline bool test_and_clear_restore_sigmask(void) | |||
259 | 258 | ||
260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) | 259 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) |
261 | 260 | ||
261 | #define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) | ||
262 | #define test_thread_64bit_stack(__SP) \ | ||
263 | ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ | ||
264 | false : true) | ||
265 | |||
262 | #endif /* !__ASSEMBLY__ */ | 266 | #endif /* !__ASSEMBLY__ */ |
263 | 267 | ||
264 | #endif /* __KERNEL__ */ | 268 | #endif /* __KERNEL__ */ |
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 48f2807d3265..71b5a67522ab 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h | |||
@@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ | |||
372 | 372 | ||
373 | /* Normal 32bit spill */ | 373 | /* Normal 32bit spill */ |
374 | #define SPILL_2_GENERIC(ASI) \ | 374 | #define SPILL_2_GENERIC(ASI) \ |
375 | srl %sp, 0, %sp; \ | 375 | and %sp, 1, %g3; \ |
376 | brnz,pn %g3, (. - (128 + 4)); \ | ||
377 | srl %sp, 0, %sp; \ | ||
376 | stwa %l0, [%sp + %g0] ASI; \ | 378 | stwa %l0, [%sp + %g0] ASI; \ |
377 | mov 0x04, %g3; \ | 379 | mov 0x04, %g3; \ |
378 | stwa %l1, [%sp + %g3] ASI; \ | 380 | stwa %l1, [%sp + %g3] ASI; \ |
@@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ | |||
398 | stwa %i6, [%g1 + %g0] ASI; \ | 400 | stwa %i6, [%g1 + %g0] ASI; \ |
399 | stwa %i7, [%g1 + %g3] ASI; \ | 401 | stwa %i7, [%g1 + %g3] ASI; \ |
400 | saved; \ | 402 | saved; \ |
401 | retry; nop; nop; \ | 403 | retry; \ |
402 | b,a,pt %xcc, spill_fixup_dax; \ | 404 | b,a,pt %xcc, spill_fixup_dax; \ |
403 | b,a,pt %xcc, spill_fixup_mna; \ | 405 | b,a,pt %xcc, spill_fixup_mna; \ |
404 | b,a,pt %xcc, spill_fixup; | 406 | b,a,pt %xcc, spill_fixup; |
405 | 407 | ||
406 | #define SPILL_2_GENERIC_ETRAP \ | 408 | #define SPILL_2_GENERIC_ETRAP \ |
407 | etrap_user_spill_32bit: \ | 409 | etrap_user_spill_32bit: \ |
408 | srl %sp, 0, %sp; \ | 410 | and %sp, 1, %g3; \ |
411 | brnz,pn %g3, etrap_user_spill_64bit; \ | ||
412 | srl %sp, 0, %sp; \ | ||
409 | stwa %l0, [%sp + 0x00] %asi; \ | 413 | stwa %l0, [%sp + 0x00] %asi; \ |
410 | stwa %l1, [%sp + 0x04] %asi; \ | 414 | stwa %l1, [%sp + 0x04] %asi; \ |
411 | stwa %l2, [%sp + 0x08] %asi; \ | 415 | stwa %l2, [%sp + 0x08] %asi; \ |
@@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ | |||
427 | ba,pt %xcc, etrap_save; \ | 431 | ba,pt %xcc, etrap_save; \ |
428 | wrpr %g1, %cwp; \ | 432 | wrpr %g1, %cwp; \ |
429 | nop; nop; nop; nop; \ | 433 | nop; nop; nop; nop; \ |
430 | nop; nop; nop; nop; \ | 434 | nop; nop; \ |
431 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 435 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
432 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 436 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
433 | ba,a,pt %xcc, etrap_spill_fixup_32bit; | 437 | ba,a,pt %xcc, etrap_spill_fixup_32bit; |
@@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ | |||
592 | 596 | ||
593 | /* Normal 32bit fill */ | 597 | /* Normal 32bit fill */ |
594 | #define FILL_2_GENERIC(ASI) \ | 598 | #define FILL_2_GENERIC(ASI) \ |
595 | srl %sp, 0, %sp; \ | 599 | and %sp, 1, %g3; \ |
600 | brnz,pn %g3, (. - (128 + 4)); \ | ||
601 | srl %sp, 0, %sp; \ | ||
596 | lduwa [%sp + %g0] ASI, %l0; \ | 602 | lduwa [%sp + %g0] ASI, %l0; \ |
597 | mov 0x04, %g2; \ | 603 | mov 0x04, %g2; \ |
598 | mov 0x08, %g3; \ | 604 | mov 0x08, %g3; \ |
@@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ | |||
616 | lduwa [%g1 + %g3] ASI, %i6; \ | 622 | lduwa [%g1 + %g3] ASI, %i6; \ |
617 | lduwa [%g1 + %g5] ASI, %i7; \ | 623 | lduwa [%g1 + %g5] ASI, %i7; \ |
618 | restored; \ | 624 | restored; \ |
619 | retry; nop; nop; nop; nop; \ | 625 | retry; nop; nop; \ |
620 | b,a,pt %xcc, fill_fixup_dax; \ | 626 | b,a,pt %xcc, fill_fixup_dax; \ |
621 | b,a,pt %xcc, fill_fixup_mna; \ | 627 | b,a,pt %xcc, fill_fixup_mna; \ |
622 | b,a,pt %xcc, fill_fixup; | 628 | b,a,pt %xcc, fill_fixup; |
623 | 629 | ||
624 | #define FILL_2_GENERIC_RTRAP \ | 630 | #define FILL_2_GENERIC_RTRAP \ |
625 | user_rtt_fill_32bit: \ | 631 | user_rtt_fill_32bit: \ |
626 | srl %sp, 0, %sp; \ | 632 | and %sp, 1, %g3; \ |
633 | brnz,pn %g3, user_rtt_fill_64bit; \ | ||
634 | srl %sp, 0, %sp; \ | ||
627 | lduwa [%sp + 0x00] %asi, %l0; \ | 635 | lduwa [%sp + 0x00] %asi, %l0; \ |
628 | lduwa [%sp + 0x04] %asi, %l1; \ | 636 | lduwa [%sp + 0x04] %asi, %l1; \ |
629 | lduwa [%sp + 0x08] %asi, %l2; \ | 637 | lduwa [%sp + 0x08] %asi, %l2; \ |
@@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ | |||
643 | ba,pt %xcc, user_rtt_pre_restore; \ | 651 | ba,pt %xcc, user_rtt_pre_restore; \ |
644 | restored; \ | 652 | restored; \ |
645 | nop; nop; nop; nop; nop; \ | 653 | nop; nop; nop; nop; nop; \ |
646 | nop; nop; nop; nop; nop; \ | 654 | nop; nop; nop; \ |
647 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 655 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
648 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 656 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
649 | ba,a,pt %xcc, user_rtt_fill_fixup; | 657 | ba,a,pt %xcc, user_rtt_fill_fixup; |
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 73083e1d38d9..e562d3caee57 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
@@ -38,14 +38,14 @@ | |||
38 | #define VERIFY_READ 0 | 38 | #define VERIFY_READ 0 |
39 | #define VERIFY_WRITE 1 | 39 | #define VERIFY_WRITE 1 |
40 | 40 | ||
41 | #define get_fs() ((mm_segment_t) { get_thread_current_ds() }) | 41 | #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) |
42 | #define get_ds() (KERNEL_DS) | 42 | #define get_ds() (KERNEL_DS) |
43 | 43 | ||
44 | #define segment_eq(a,b) ((a).seg == (b).seg) | 44 | #define segment_eq(a,b) ((a).seg == (b).seg) |
45 | 45 | ||
46 | #define set_fs(val) \ | 46 | #define set_fs(val) \ |
47 | do { \ | 47 | do { \ |
48 | set_thread_current_ds((val).seg); \ | 48 | current_thread_info()->current_ds =(val).seg; \ |
49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ | 49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ |
50 | } while(0) | 50 | } while(0) |
51 | 51 | ||
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 0ecea6ed943e..c3e5d8b64171 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | 46 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND |
47 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | 47 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE |
48 | #endif | 48 | #endif |
49 | #define __ARCH_WANT_SYS_EXECVE | ||
49 | 50 | ||
50 | /* | 51 | /* |
51 | * "Conditional" syscalls | 52 | * "Conditional" syscalls |
diff --git a/arch/sparc/include/uapi/asm/sigcontext.h b/arch/sparc/include/uapi/asm/sigcontext.h index e69de29bb2d1..ae5704fa77ad 100644 --- a/arch/sparc/include/uapi/asm/sigcontext.h +++ b/arch/sparc/include/uapi/asm/sigcontext.h | |||
@@ -0,0 +1,4 @@ | |||
1 | /* | ||
2 | * There isn't anything here anymore, but the file must not be empty or patch | ||
3 | * will delete it. | ||
4 | */ | ||
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 8974ef7ae920..cac719d1bc5c 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h | |||
@@ -405,8 +405,13 @@ | |||
405 | #define __NR_setns 337 | 405 | #define __NR_setns 337 |
406 | #define __NR_process_vm_readv 338 | 406 | #define __NR_process_vm_readv 338 |
407 | #define __NR_process_vm_writev 339 | 407 | #define __NR_process_vm_writev 339 |
408 | #define __NR_kern_features 340 | ||
409 | #define __NR_kcmp 341 | ||
408 | 410 | ||
409 | #define NR_syscalls 340 | 411 | #define NR_syscalls 342 |
412 | |||
413 | /* Bitmask values returned from kern_features system call. */ | ||
414 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | ||
410 | 415 | ||
411 | #ifdef __32bit_syscall_numbers__ | 416 | #ifdef __32bit_syscall_numbers__ |
412 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 417 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |