aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-05-07 05:27:54 -0400
committerIngo Molnar <mingo@elte.hu>2010-05-07 05:27:54 -0400
commit48652ced1533c3372f996a0d83b6e73b1f1c9381 (patch)
tree5e17729cfcdc97bf798a17b57cdb888b4ded65b0 /arch/arm/kernel
parent99bd5e2f245d8cd17d040c82d40becdb3efd9b69 (diff)
parent66f41d4c5c8a5deed66fdcc84509376c9a0bf9d8 (diff)
Merge commit 'v2.6.34-rc6' into sched/core
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/ftrace.c8
-rw-r--r--arch/arm/kernel/process.c8
-rw-r--r--arch/arm/kernel/signal.c93
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"
5274: mov pc, r9 5274: 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
680ENTRY(fp_enter) 680ENTRY(fp_enter)
681 .word no_fp 681 .word no_fp
682 .previous 682 .text
683 683
684ENTRY(no_fp) 684ENTRY(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 */
357extern void kernel_thread_helper(void); 357extern void kernel_thread_helper(void);
358asm( ".section .text\n" 358asm( ".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
369extern void kernel_thread_exit(long code); 369extern void kernel_thread_exit(long code);
370asm( ".section .text\n" 370asm( ".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
181static 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
214static 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