aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2008-06-25 00:07:18 -0400
committerPaul Mackerras <paulus@samba.org>2008-06-30 21:28:50 -0400
commitce48b2100785e5ca629fb3aa8e3b50aca808f692 (patch)
tree63532ff7cc68b18ca4902bd10e03fcbaaf01cade /arch/powerpc/kernel/ptrace.c
parent72ffff5b1792b0fa4d40a8e2f3276fff999820ec (diff)
powerpc: Add VSX context save/restore, ptrace and signal support
This patch extends the floating point save and restore code to use the VSX load/stores when VSX is available. This will make FP context save/restore marginally slower on FP only code, when VSX is available, as it has to load/store 128bits rather than just 64bits. Mixing FP, VMX and VSX code will get constant architected state. The signals interface is extended to enable access to VSR 0-31 doubleword 1 after discussions with tool chain maintainers. Backward compatibility is maintained. The ptrace interface is also extended to allow access to VSR 0-31 full registers. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 70fbde84b83f..4e203a89e189 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -350,6 +350,51 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
350} 350}
351#endif /* CONFIG_ALTIVEC */ 351#endif /* CONFIG_ALTIVEC */
352 352
353#ifdef CONFIG_VSX
354/*
355 * Currently to set and and get all the vsx state, you need to call
356 * the fp and VMX calls aswell. This only get/sets the lower 32
357 * 128bit VSX registers.
358 */
359
360static int vsr_active(struct task_struct *target,
361 const struct user_regset *regset)
362{
363 flush_vsx_to_thread(target);
364 return target->thread.used_vsr ? regset->n : 0;
365}
366
367static int vsr_get(struct task_struct *target, const struct user_regset *regset,
368 unsigned int pos, unsigned int count,
369 void *kbuf, void __user *ubuf)
370{
371 int ret;
372
373 flush_vsx_to_thread(target);
374
375 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
376 target->thread.fpr, 0,
377 32 * sizeof(vector128));
378
379 return ret;
380}
381
382static int vsr_set(struct task_struct *target, const struct user_regset *regset,
383 unsigned int pos, unsigned int count,
384 const void *kbuf, const void __user *ubuf)
385{
386 int ret;
387
388 flush_vsx_to_thread(target);
389
390 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
391 target->thread.fpr, 0,
392 32 * sizeof(vector128));
393
394 return ret;
395}
396#endif /* CONFIG_VSX */
397
353#ifdef CONFIG_SPE 398#ifdef CONFIG_SPE
354 399
355/* 400/*
@@ -426,6 +471,9 @@ enum powerpc_regset {
426#ifdef CONFIG_ALTIVEC 471#ifdef CONFIG_ALTIVEC
427 REGSET_VMX, 472 REGSET_VMX,
428#endif 473#endif
474#ifdef CONFIG_VSX
475 REGSET_VSX,
476#endif
429#ifdef CONFIG_SPE 477#ifdef CONFIG_SPE
430 REGSET_SPE, 478 REGSET_SPE,
431#endif 479#endif
@@ -449,6 +497,13 @@ static const struct user_regset native_regsets[] = {
449 .active = vr_active, .get = vr_get, .set = vr_set 497 .active = vr_active, .get = vr_get, .set = vr_set
450 }, 498 },
451#endif 499#endif
500#ifdef CONFIG_VSX
501 [REGSET_VSX] = {
502 .n = 32,
503 .size = sizeof(vector128), .align = sizeof(vector128),
504 .active = vsr_active, .get = vsr_get, .set = vsr_set
505 },
506#endif
452#ifdef CONFIG_SPE 507#ifdef CONFIG_SPE
453 [REGSET_SPE] = { 508 [REGSET_SPE] = {
454 .n = 35, 509 .n = 35,
@@ -849,6 +904,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
849 sizeof(u32)), 904 sizeof(u32)),
850 (const void __user *) data); 905 (const void __user *) data);
851#endif 906#endif
907#ifdef CONFIG_VSX
908 case PTRACE_GETVSRREGS:
909 return copy_regset_to_user(child, &user_ppc_native_view,
910 REGSET_VSX,
911 0, (32 * sizeof(vector128) +
912 sizeof(u32)),
913 (void __user *) data);
914
915 case PTRACE_SETVSRREGS:
916 return copy_regset_from_user(child, &user_ppc_native_view,
917 REGSET_VSX,
918 0, (32 * sizeof(vector128) +
919 sizeof(u32)),
920 (const void __user *) data);
921#endif
852#ifdef CONFIG_SPE 922#ifdef CONFIG_SPE
853 case PTRACE_GETEVRREGS: 923 case PTRACE_GETEVRREGS:
854 /* Get the child spe register state. */ 924 /* Get the child spe register state. */