diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-27 21:37:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-27 21:37:56 -0400 |
commit | c9a606660e7bb5ba9169d279346417dab72b157d (patch) | |
tree | f9bf6e3227c89d0d1be1006075a82fbe8d9987e7 /arch/mips/kernel/signal.c | |
parent | 1857a5b65c52be3e8837cc68d0ee3f4741c5c45f (diff) | |
parent | 16f0bbbc1fbe0d09cda5b5b2dbbd6716026dfa7b (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS fixes from Ralf Baechle:
"This is dominated by a large number of changes necessary for the MIPS
BPF code. code. Aside of that there are
- a fix for the MSC system controller support code.
- a Turbochannel fix.
- a recordmcount fix that's MIPS-specific.
- barrier fixes to smp-cps / pm-cps after unrelated changes elsewhere
in the kernel.
- revert support for MSA registers in the signal frames. The
reverted patch did modify the signal stack frame which of course is
inacceptable.
- fix math-emu build breakage with older compilers.
- some related cleanup.
- fix Lasat build error if CONFIG_CRC32 isn't set to y by the user"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (27 commits)
MIPS: Lasat: Fix build error if CRC32 is not enabled.
TC: Handle device_register() errors.
MIPS: MSC: Prevent out-of-bounds writes to MIPS SC ioremap'd region
MIPS: bpf: Fix stack space allocation for BPF memwords on MIPS64
MIPS: BPF: Use 32 or 64-bit load instruction to load an address to register
MIPS: bpf: Fix PKT_TYPE case for big-endian cores
MIPS: BPF: Prevent kernel fall over for >=32bit shifts
MIPS: bpf: Drop update_on_xread and always initialize the X register
MIPS: bpf: Fix is_range() semantics
MIPS: bpf: Use pr_debug instead of pr_warn for unhandled opcodes
MIPS: bpf: Fix return values for VLAN_TAG_PRESENT case
MIPS: bpf: Use correct mask for VLAN_TAG case
MIPS: bpf: Fix branch conditional for BPF_J{GT/GE} cases
MIPS: bpf: Add SEEN_SKB to flags when looking for the PKT_TYPE
MIPS: bpf: Use 'andi' instead of 'and' for the VLAN cases
MIPS: bpf: Return error code if the offset is a negative number
MIPS: bpf: Use the LO register to get division's quotient
MIPS: mm: uasm: Fix lh micro-assembler instruction
MIPS: uasm: Add SLT uasm instruction
MIPS: uasm: Add s3s1s2 instruction builder
...
Diffstat (limited to 'arch/mips/kernel/signal.c')
-rw-r--r-- | arch/mips/kernel/signal.c | 79 |
1 files changed, 8 insertions, 71 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 33133d3df3e5..9e60d117e41e 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
32 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
33 | #include <asm/fpu.h> | 33 | #include <asm/fpu.h> |
34 | #include <asm/msa.h> | ||
35 | #include <asm/sim.h> | 34 | #include <asm/sim.h> |
36 | #include <asm/ucontext.h> | 35 | #include <asm/ucontext.h> |
37 | #include <asm/cpu-features.h> | 36 | #include <asm/cpu-features.h> |
@@ -48,9 +47,6 @@ static int (*restore_fp_context)(struct sigcontext __user *sc); | |||
48 | extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); | 47 | extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); |
49 | extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); | 48 | extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); |
50 | 49 | ||
51 | extern asmlinkage int _save_msa_context(struct sigcontext __user *sc); | ||
52 | extern asmlinkage int _restore_msa_context(struct sigcontext __user *sc); | ||
53 | |||
54 | struct sigframe { | 50 | struct sigframe { |
55 | u32 sf_ass[4]; /* argument save space for o32 */ | 51 | u32 sf_ass[4]; /* argument save space for o32 */ |
56 | u32 sf_pad[2]; /* Was: signal trampoline */ | 52 | u32 sf_pad[2]; /* Was: signal trampoline */ |
@@ -100,60 +96,20 @@ static int copy_fp_from_sigcontext(struct sigcontext __user *sc) | |||
100 | } | 96 | } |
101 | 97 | ||
102 | /* | 98 | /* |
103 | * These functions will save only the upper 64 bits of the vector registers, | ||
104 | * since the lower 64 bits have already been saved as the scalar FP context. | ||
105 | */ | ||
106 | static int copy_msa_to_sigcontext(struct sigcontext __user *sc) | ||
107 | { | ||
108 | int i; | ||
109 | int err = 0; | ||
110 | |||
111 | for (i = 0; i < NUM_FPU_REGS; i++) { | ||
112 | err |= | ||
113 | __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 1), | ||
114 | &sc->sc_msaregs[i]); | ||
115 | } | ||
116 | err |= __put_user(current->thread.fpu.msacsr, &sc->sc_msa_csr); | ||
117 | |||
118 | return err; | ||
119 | } | ||
120 | |||
121 | static int copy_msa_from_sigcontext(struct sigcontext __user *sc) | ||
122 | { | ||
123 | int i; | ||
124 | int err = 0; | ||
125 | u64 val; | ||
126 | |||
127 | for (i = 0; i < NUM_FPU_REGS; i++) { | ||
128 | err |= __get_user(val, &sc->sc_msaregs[i]); | ||
129 | set_fpr64(¤t->thread.fpu.fpr[i], 1, val); | ||
130 | } | ||
131 | err |= __get_user(current->thread.fpu.msacsr, &sc->sc_msa_csr); | ||
132 | |||
133 | return err; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Helper routines | 99 | * Helper routines |
138 | */ | 100 | */ |
139 | static int protected_save_fp_context(struct sigcontext __user *sc, | 101 | static int protected_save_fp_context(struct sigcontext __user *sc) |
140 | unsigned used_math) | ||
141 | { | 102 | { |
142 | int err; | 103 | int err; |
143 | bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA); | ||
144 | #ifndef CONFIG_EVA | 104 | #ifndef CONFIG_EVA |
145 | while (1) { | 105 | while (1) { |
146 | lock_fpu_owner(); | 106 | lock_fpu_owner(); |
147 | if (is_fpu_owner()) { | 107 | if (is_fpu_owner()) { |
148 | err = save_fp_context(sc); | 108 | err = save_fp_context(sc); |
149 | if (save_msa && !err) | ||
150 | err = _save_msa_context(sc); | ||
151 | unlock_fpu_owner(); | 109 | unlock_fpu_owner(); |
152 | } else { | 110 | } else { |
153 | unlock_fpu_owner(); | 111 | unlock_fpu_owner(); |
154 | err = copy_fp_to_sigcontext(sc); | 112 | err = copy_fp_to_sigcontext(sc); |
155 | if (save_msa && !err) | ||
156 | err = copy_msa_to_sigcontext(sc); | ||
157 | } | 113 | } |
158 | if (likely(!err)) | 114 | if (likely(!err)) |
159 | break; | 115 | break; |
@@ -169,38 +125,24 @@ static int protected_save_fp_context(struct sigcontext __user *sc, | |||
169 | * EVA does not have FPU EVA instructions so saving fpu context directly | 125 | * EVA does not have FPU EVA instructions so saving fpu context directly |
170 | * does not work. | 126 | * does not work. |
171 | */ | 127 | */ |
172 | disable_msa(); | ||
173 | lose_fpu(1); | 128 | lose_fpu(1); |
174 | err = save_fp_context(sc); /* this might fail */ | 129 | err = save_fp_context(sc); /* this might fail */ |
175 | if (save_msa && !err) | ||
176 | err = copy_msa_to_sigcontext(sc); | ||
177 | #endif | 130 | #endif |
178 | return err; | 131 | return err; |
179 | } | 132 | } |
180 | 133 | ||
181 | static int protected_restore_fp_context(struct sigcontext __user *sc, | 134 | static int protected_restore_fp_context(struct sigcontext __user *sc) |
182 | unsigned used_math) | ||
183 | { | 135 | { |
184 | int err, tmp __maybe_unused; | 136 | int err, tmp __maybe_unused; |
185 | bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA); | ||
186 | #ifndef CONFIG_EVA | 137 | #ifndef CONFIG_EVA |
187 | while (1) { | 138 | while (1) { |
188 | lock_fpu_owner(); | 139 | lock_fpu_owner(); |
189 | if (is_fpu_owner()) { | 140 | if (is_fpu_owner()) { |
190 | err = restore_fp_context(sc); | 141 | err = restore_fp_context(sc); |
191 | if (restore_msa && !err) { | ||
192 | enable_msa(); | ||
193 | err = _restore_msa_context(sc); | ||
194 | } else { | ||
195 | /* signal handler may have used MSA */ | ||
196 | disable_msa(); | ||
197 | } | ||
198 | unlock_fpu_owner(); | 142 | unlock_fpu_owner(); |
199 | } else { | 143 | } else { |
200 | unlock_fpu_owner(); | 144 | unlock_fpu_owner(); |
201 | err = copy_fp_from_sigcontext(sc); | 145 | err = copy_fp_from_sigcontext(sc); |
202 | if (!err && (used_math & USEDMATH_MSA)) | ||
203 | err = copy_msa_from_sigcontext(sc); | ||
204 | } | 146 | } |
205 | if (likely(!err)) | 147 | if (likely(!err)) |
206 | break; | 148 | break; |
@@ -216,11 +158,8 @@ static int protected_restore_fp_context(struct sigcontext __user *sc, | |||
216 | * EVA does not have FPU EVA instructions so restoring fpu context | 158 | * EVA does not have FPU EVA instructions so restoring fpu context |
217 | * directly does not work. | 159 | * directly does not work. |
218 | */ | 160 | */ |
219 | enable_msa(); | ||
220 | lose_fpu(0); | 161 | lose_fpu(0); |
221 | err = restore_fp_context(sc); /* this might fail */ | 162 | err = restore_fp_context(sc); /* this might fail */ |
222 | if (restore_msa && !err) | ||
223 | err = copy_msa_from_sigcontext(sc); | ||
224 | #endif | 163 | #endif |
225 | return err; | 164 | return err; |
226 | } | 165 | } |
@@ -252,8 +191,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
252 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | 191 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); |
253 | } | 192 | } |
254 | 193 | ||
255 | used_math = used_math() ? USEDMATH_FP : 0; | 194 | used_math = !!used_math(); |
256 | used_math |= thread_msa_context_live() ? USEDMATH_MSA : 0; | ||
257 | err |= __put_user(used_math, &sc->sc_used_math); | 195 | err |= __put_user(used_math, &sc->sc_used_math); |
258 | 196 | ||
259 | if (used_math) { | 197 | if (used_math) { |
@@ -261,7 +199,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
261 | * Save FPU state to signal context. Signal handler | 199 | * Save FPU state to signal context. Signal handler |
262 | * will "inherit" current FPU state. | 200 | * will "inherit" current FPU state. |
263 | */ | 201 | */ |
264 | err |= protected_save_fp_context(sc, used_math); | 202 | err |= protected_save_fp_context(sc); |
265 | } | 203 | } |
266 | return err; | 204 | return err; |
267 | } | 205 | } |
@@ -286,14 +224,14 @@ int fpcsr_pending(unsigned int __user *fpcsr) | |||
286 | } | 224 | } |
287 | 225 | ||
288 | static int | 226 | static int |
289 | check_and_restore_fp_context(struct sigcontext __user *sc, unsigned used_math) | 227 | check_and_restore_fp_context(struct sigcontext __user *sc) |
290 | { | 228 | { |
291 | int err, sig; | 229 | int err, sig; |
292 | 230 | ||
293 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); | 231 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); |
294 | if (err > 0) | 232 | if (err > 0) |
295 | err = 0; | 233 | err = 0; |
296 | err |= protected_restore_fp_context(sc, used_math); | 234 | err |= protected_restore_fp_context(sc); |
297 | return err ?: sig; | 235 | return err ?: sig; |
298 | } | 236 | } |
299 | 237 | ||
@@ -333,10 +271,9 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
333 | if (used_math) { | 271 | if (used_math) { |
334 | /* restore fpu context if we have used it before */ | 272 | /* restore fpu context if we have used it before */ |
335 | if (!err) | 273 | if (!err) |
336 | err = check_and_restore_fp_context(sc, used_math); | 274 | err = check_and_restore_fp_context(sc); |
337 | } else { | 275 | } else { |
338 | /* signal handler may have used FPU or MSA. Disable them. */ | 276 | /* signal handler may have used FPU. Give it up. */ |
339 | disable_msa(); | ||
340 | lose_fpu(0); | 277 | lose_fpu(0); |
341 | } | 278 | } |
342 | 279 | ||