diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-05-07 05:27:54 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-05-07 05:27:54 -0400 |
commit | 48652ced1533c3372f996a0d83b6e73b1f1c9381 (patch) | |
tree | 5e17729cfcdc97bf798a17b57cdb888b4ded65b0 /arch/arm/kernel | |
parent | 99bd5e2f245d8cd17d040c82d40becdb3efd9b69 (diff) | |
parent | 66f41d4c5c8a5deed66fdcc84509376c9a0bf9d8 (diff) |
Merge commit 'v2.6.34-rc6' into sched/core
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 10 | ||||
-rw-r--r-- | arch/arm/kernel/ftrace.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 93 |
4 files changed, 102 insertions, 17 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 6c5cf369183b..e6a0fb0f392e 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -523,16 +523,16 @@ ENDPROC(__und_usr) | |||
523 | /* | 523 | /* |
524 | * The out of line fixup for the ldrt above. | 524 | * The out of line fixup for the ldrt above. |
525 | */ | 525 | */ |
526 | .section .fixup, "ax" | 526 | .pushsection .fixup, "ax" |
527 | 4: mov pc, r9 | 527 | 4: mov pc, r9 |
528 | .previous | 528 | .popsection |
529 | .section __ex_table,"a" | 529 | .pushsection __ex_table,"a" |
530 | .long 1b, 4b | 530 | .long 1b, 4b |
531 | #if __LINUX_ARM_ARCH__ >= 7 | 531 | #if __LINUX_ARM_ARCH__ >= 7 |
532 | .long 2b, 4b | 532 | .long 2b, 4b |
533 | .long 3b, 4b | 533 | .long 3b, 4b |
534 | #endif | 534 | #endif |
535 | .previous | 535 | .popsection |
536 | 536 | ||
537 | /* | 537 | /* |
538 | * Check whether the instruction is a co-processor instruction. | 538 | * Check whether the instruction is a co-processor instruction. |
@@ -679,7 +679,7 @@ do_fpe: | |||
679 | .data | 679 | .data |
680 | ENTRY(fp_enter) | 680 | ENTRY(fp_enter) |
681 | .word no_fp | 681 | .word no_fp |
682 | .previous | 682 | .text |
683 | 683 | ||
684 | ENTRY(no_fp) | 684 | ENTRY(no_fp) |
685 | mov pc, lr | 685 | mov pc, lr |
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index c63842766229..0298286ad4ad 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -62,15 +62,15 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code, | |||
62 | " movne %0, #2 \n" | 62 | " movne %0, #2 \n" |
63 | "3:\n" | 63 | "3:\n" |
64 | 64 | ||
65 | ".section .fixup, \"ax\"\n" | 65 | ".pushsection .fixup, \"ax\"\n" |
66 | "4: mov %0, #1 \n" | 66 | "4: mov %0, #1 \n" |
67 | " b 3b \n" | 67 | " b 3b \n" |
68 | ".previous\n" | 68 | ".popsection\n" |
69 | 69 | ||
70 | ".section __ex_table, \"a\"\n" | 70 | ".pushsection __ex_table, \"a\"\n" |
71 | " .long 1b, 4b \n" | 71 | " .long 1b, 4b \n" |
72 | " .long 2b, 4b \n" | 72 | " .long 2b, 4b \n" |
73 | ".previous\n" | 73 | ".popsection\n" |
74 | 74 | ||
75 | : "=r"(err), "=r"(replaced) | 75 | : "=r"(err), "=r"(replaced) |
76 | : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced) | 76 | : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced) |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 0e12e0acbf26..acf5e6fdb6dc 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -355,7 +355,7 @@ EXPORT_SYMBOL(dump_fpu); | |||
355 | * the thread function, and r3 points to the exit function. | 355 | * the thread function, and r3 points to the exit function. |
356 | */ | 356 | */ |
357 | extern void kernel_thread_helper(void); | 357 | extern void kernel_thread_helper(void); |
358 | asm( ".section .text\n" | 358 | asm( ".pushsection .text\n" |
359 | " .align\n" | 359 | " .align\n" |
360 | " .type kernel_thread_helper, #function\n" | 360 | " .type kernel_thread_helper, #function\n" |
361 | "kernel_thread_helper:\n" | 361 | "kernel_thread_helper:\n" |
@@ -363,11 +363,11 @@ asm( ".section .text\n" | |||
363 | " mov lr, r3\n" | 363 | " mov lr, r3\n" |
364 | " mov pc, r2\n" | 364 | " mov pc, r2\n" |
365 | " .size kernel_thread_helper, . - kernel_thread_helper\n" | 365 | " .size kernel_thread_helper, . - kernel_thread_helper\n" |
366 | " .previous"); | 366 | " .popsection"); |
367 | 367 | ||
368 | #ifdef CONFIG_ARM_UNWIND | 368 | #ifdef CONFIG_ARM_UNWIND |
369 | extern void kernel_thread_exit(long code); | 369 | extern void kernel_thread_exit(long code); |
370 | asm( ".section .text\n" | 370 | asm( ".pushsection .text\n" |
371 | " .align\n" | 371 | " .align\n" |
372 | " .type kernel_thread_exit, #function\n" | 372 | " .type kernel_thread_exit, #function\n" |
373 | "kernel_thread_exit:\n" | 373 | "kernel_thread_exit:\n" |
@@ -377,7 +377,7 @@ asm( ".section .text\n" | |||
377 | " nop\n" | 377 | " nop\n" |
378 | " .fnend\n" | 378 | " .fnend\n" |
379 | " .size kernel_thread_exit, . - kernel_thread_exit\n" | 379 | " .size kernel_thread_exit, . - kernel_thread_exit\n" |
380 | " .previous"); | 380 | " .popsection"); |
381 | #else | 381 | #else |
382 | #define kernel_thread_exit do_exit | 382 | #define kernel_thread_exit do_exit |
383 | #endif | 383 | #endif |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index e7714f367eb8..907d5a620bca 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
19 | #include <asm/ucontext.h> | 19 | #include <asm/ucontext.h> |
20 | #include <asm/unistd.h> | 20 | #include <asm/unistd.h> |
21 | #include <asm/vfp.h> | ||
21 | 22 | ||
22 | #include "ptrace.h" | 23 | #include "ptrace.h" |
23 | #include "signal.h" | 24 | #include "signal.h" |
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) | |||
175 | 176 | ||
176 | #endif | 177 | #endif |
177 | 178 | ||
179 | #ifdef CONFIG_VFP | ||
180 | |||
181 | static int preserve_vfp_context(struct vfp_sigframe __user *frame) | ||
182 | { | ||
183 | struct thread_info *thread = current_thread_info(); | ||
184 | struct vfp_hard_struct *h = &thread->vfpstate.hard; | ||
185 | const unsigned long magic = VFP_MAGIC; | ||
186 | const unsigned long size = VFP_STORAGE_SIZE; | ||
187 | int err = 0; | ||
188 | |||
189 | vfp_sync_hwstate(thread); | ||
190 | __put_user_error(magic, &frame->magic, err); | ||
191 | __put_user_error(size, &frame->size, err); | ||
192 | |||
193 | /* | ||
194 | * Copy the floating point registers. There can be unused | ||
195 | * registers see asm/hwcap.h for details. | ||
196 | */ | ||
197 | err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, | ||
198 | sizeof(h->fpregs)); | ||
199 | /* | ||
200 | * Copy the status and control register. | ||
201 | */ | ||
202 | __put_user_error(h->fpscr, &frame->ufp.fpscr, err); | ||
203 | |||
204 | /* | ||
205 | * Copy the exception registers. | ||
206 | */ | ||
207 | __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); | ||
208 | __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); | ||
209 | __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); | ||
210 | |||
211 | return err ? -EFAULT : 0; | ||
212 | } | ||
213 | |||
214 | static int restore_vfp_context(struct vfp_sigframe __user *frame) | ||
215 | { | ||
216 | struct thread_info *thread = current_thread_info(); | ||
217 | struct vfp_hard_struct *h = &thread->vfpstate.hard; | ||
218 | unsigned long magic; | ||
219 | unsigned long size; | ||
220 | unsigned long fpexc; | ||
221 | int err = 0; | ||
222 | |||
223 | __get_user_error(magic, &frame->magic, err); | ||
224 | __get_user_error(size, &frame->size, err); | ||
225 | |||
226 | if (err) | ||
227 | return -EFAULT; | ||
228 | if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) | ||
229 | return -EINVAL; | ||
230 | |||
231 | /* | ||
232 | * Copy the floating point registers. There can be unused | ||
233 | * registers see asm/hwcap.h for details. | ||
234 | */ | ||
235 | err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, | ||
236 | sizeof(h->fpregs)); | ||
237 | /* | ||
238 | * Copy the status and control register. | ||
239 | */ | ||
240 | __get_user_error(h->fpscr, &frame->ufp.fpscr, err); | ||
241 | |||
242 | /* | ||
243 | * Sanitise and restore the exception registers. | ||
244 | */ | ||
245 | __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); | ||
246 | /* Ensure the VFP is enabled. */ | ||
247 | fpexc |= FPEXC_EN; | ||
248 | /* Ensure FPINST2 is invalid and the exception flag is cleared. */ | ||
249 | fpexc &= ~(FPEXC_EX | FPEXC_FP2V); | ||
250 | h->fpexc = fpexc; | ||
251 | |||
252 | __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); | ||
253 | __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); | ||
254 | |||
255 | if (!err) | ||
256 | vfp_flush_hwstate(thread); | ||
257 | |||
258 | return err ? -EFAULT : 0; | ||
259 | } | ||
260 | |||
261 | #endif | ||
262 | |||
178 | /* | 263 | /* |
179 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. | 264 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. |
180 | */ | 265 | */ |
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) | |||
233 | err |= restore_iwmmxt_context(&aux->iwmmxt); | 318 | err |= restore_iwmmxt_context(&aux->iwmmxt); |
234 | #endif | 319 | #endif |
235 | #ifdef CONFIG_VFP | 320 | #ifdef CONFIG_VFP |
236 | // if (err == 0) | 321 | if (err == 0) |
237 | // err |= vfp_restore_state(&sf->aux.vfp); | 322 | err |= restore_vfp_context(&aux->vfp); |
238 | #endif | 323 | #endif |
239 | 324 | ||
240 | return err; | 325 | return err; |
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) | |||
348 | err |= preserve_iwmmxt_context(&aux->iwmmxt); | 433 | err |= preserve_iwmmxt_context(&aux->iwmmxt); |
349 | #endif | 434 | #endif |
350 | #ifdef CONFIG_VFP | 435 | #ifdef CONFIG_VFP |
351 | // if (err == 0) | 436 | if (err == 0) |
352 | // err |= vfp_save_state(&sf->aux.vfp); | 437 | err |= preserve_vfp_context(&aux->vfp); |
353 | #endif | 438 | #endif |
354 | __put_user_error(0, &aux->end_magic, err); | 439 | __put_user_error(0, &aux->end_magic, err); |
355 | 440 | ||