Page MenuHomeFreeBSD

D15458.diff
No OneTemporary

D15458.diff

Index: head/lib/libc/sys/ptrace.2
===================================================================
--- head/lib/libc/sys/ptrace.2
+++ head/lib/libc/sys/ptrace.2
@@ -2,7 +2,7 @@
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
-.Dd May 22, 2018
+.Dd June 2, 2018
.Dt PTRACE 2
.Os
.Sh NAME
@@ -934,6 +934,24 @@
Set the thread's
.Dv ALTIVEC
machine state from the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_GETVSRREGS
+Return doubleword 1 of the thread's
+.Dv VSX
+registers VSR0-VSR31 in the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETVSRREGS
+Set doubleword 1 of the thread's
+.Dv VSX
+registers VSR0-VSR31 from the buffer pointed to by
.Fa addr .
.Pp
The
Index: head/sys/powerpc/include/fpu.h
===================================================================
--- head/sys/powerpc/include/fpu.h
+++ head/sys/powerpc/include/fpu.h
@@ -74,6 +74,7 @@
void enable_fpu(struct thread *);
void save_fpu(struct thread *);
+void save_fpu_nodrop(struct thread *);
#endif /* _KERNEL */
Index: head/sys/powerpc/include/ptrace.h
===================================================================
--- head/sys/powerpc/include/ptrace.h
+++ head/sys/powerpc/include/ptrace.h
@@ -39,5 +39,7 @@
#define PT_GETVRREGS (PT_FIRSTMACH + 0)
#define PT_SETVRREGS (PT_FIRSTMACH + 1)
+#define PT_GETVSRREGS (PT_FIRSTMACH + 2)
+#define PT_SETVSRREGS (PT_FIRSTMACH + 3)
#endif
Index: head/sys/powerpc/powerpc/fpu.c
===================================================================
--- head/sys/powerpc/powerpc/fpu.c
+++ head/sys/powerpc/powerpc/fpu.c
@@ -45,6 +45,60 @@
#include <machine/pcb.h>
#include <machine/psl.h>
+static void
+save_fpu_int(struct thread *td)
+{
+ int msr;
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+
+ /*
+ * Temporarily re-enable floating-point during the save
+ */
+ msr = mfmsr();
+ if (pcb->pcb_flags & PCB_VSX)
+ mtmsr(msr | PSL_FP | PSL_VSX);
+ else
+ mtmsr(msr | PSL_FP);
+
+ /*
+ * Save the floating-point registers and FPSCR to the PCB
+ */
+ if (pcb->pcb_flags & PCB_VSX) {
+ #define SFP(n) __asm ("stxvw4x " #n ", 0,%0" \
+ :: "b"(&pcb->pcb_fpu.fpr[n]));
+ SFP(0); SFP(1); SFP(2); SFP(3);
+ SFP(4); SFP(5); SFP(6); SFP(7);
+ SFP(8); SFP(9); SFP(10); SFP(11);
+ SFP(12); SFP(13); SFP(14); SFP(15);
+ SFP(16); SFP(17); SFP(18); SFP(19);
+ SFP(20); SFP(21); SFP(22); SFP(23);
+ SFP(24); SFP(25); SFP(26); SFP(27);
+ SFP(28); SFP(29); SFP(30); SFP(31);
+ #undef SFP
+ } else {
+ #define SFP(n) __asm ("stfd " #n ", 0(%0)" \
+ :: "b"(&pcb->pcb_fpu.fpr[n]));
+ SFP(0); SFP(1); SFP(2); SFP(3);
+ SFP(4); SFP(5); SFP(6); SFP(7);
+ SFP(8); SFP(9); SFP(10); SFP(11);
+ SFP(12); SFP(13); SFP(14); SFP(15);
+ SFP(16); SFP(17); SFP(18); SFP(19);
+ SFP(20); SFP(21); SFP(22); SFP(23);
+ SFP(24); SFP(25); SFP(26); SFP(27);
+ SFP(28); SFP(29); SFP(30); SFP(31);
+ #undef SFP
+ }
+ __asm __volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpscr));
+
+ /*
+ * Disable floating-point again
+ */
+ isync();
+ mtmsr(msr);
+}
+
void
enable_fpu(struct thread *td)
{
@@ -129,57 +183,13 @@
void
save_fpu(struct thread *td)
{
- int msr;
struct pcb *pcb;
pcb = td->td_pcb;
- /*
- * Temporarily re-enable floating-point during the save
- */
- msr = mfmsr();
- if (pcb->pcb_flags & PCB_VSX)
- mtmsr(msr | PSL_FP | PSL_VSX);
- else
- mtmsr(msr | PSL_FP);
+ save_fpu_int(td);
/*
- * Save the floating-point registers and FPSCR to the PCB
- */
- if (pcb->pcb_flags & PCB_VSX) {
- #define SFP(n) __asm ("stxvw4x " #n ", 0,%0" \
- :: "b"(&pcb->pcb_fpu.fpr[n]));
- SFP(0); SFP(1); SFP(2); SFP(3);
- SFP(4); SFP(5); SFP(6); SFP(7);
- SFP(8); SFP(9); SFP(10); SFP(11);
- SFP(12); SFP(13); SFP(14); SFP(15);
- SFP(16); SFP(17); SFP(18); SFP(19);
- SFP(20); SFP(21); SFP(22); SFP(23);
- SFP(24); SFP(25); SFP(26); SFP(27);
- SFP(28); SFP(29); SFP(30); SFP(31);
- #undef SFP
- } else {
- #define SFP(n) __asm ("stfd " #n ", 0(%0)" \
- :: "b"(&pcb->pcb_fpu.fpr[n]));
- SFP(0); SFP(1); SFP(2); SFP(3);
- SFP(4); SFP(5); SFP(6); SFP(7);
- SFP(8); SFP(9); SFP(10); SFP(11);
- SFP(12); SFP(13); SFP(14); SFP(15);
- SFP(16); SFP(17); SFP(18); SFP(19);
- SFP(20); SFP(21); SFP(22); SFP(23);
- SFP(24); SFP(25); SFP(26); SFP(27);
- SFP(28); SFP(29); SFP(30); SFP(31);
- #undef SFP
- }
- __asm __volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpscr));
-
- /*
- * Disable floating-point again
- */
- isync();
- mtmsr(msr);
-
- /*
* Clear the current fp thread and pcb's CPU id
* XXX should this be left clear to allow lazy save/restore ?
*/
@@ -187,3 +197,19 @@
PCPU_SET(fputhread, NULL);
}
+/*
+ * Save fpu state without dropping ownership. This will only save state if
+ * the current fpu thread is `td'.
+ */
+void
+save_fpu_nodrop(struct thread *td)
+{
+ struct thread *ftd;
+
+ ftd = PCPU_GET(fputhread);
+ if (td != ftd) {
+ return;
+ }
+
+ save_fpu_int(td);
+}
Index: head/sys/powerpc/powerpc/ptrace_machdep.c
===================================================================
--- head/sys/powerpc/powerpc/ptrace_machdep.c
+++ head/sys/powerpc/powerpc/ptrace_machdep.c
@@ -35,6 +35,7 @@
#include <sys/ptrace.h>
#include <sys/sysent.h>
#include <machine/altivec.h>
+#include <machine/fpu.h>
#include <machine/cpu.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
@@ -45,10 +46,14 @@
int error;
struct pcb *pcb;
struct vec vec;
+ uint64_t vsr[32];
+ uint64_t *vsr_dw1;
+ int vsr_idx;
pcb = td->td_pcb;
bzero(&vec, sizeof(vec));
+ bzero(vsr, sizeof(vsr));
error = EINVAL;
switch (req) {
@@ -69,6 +74,43 @@
if (error == 0) {
pcb->pcb_flags |= PCB_VEC;
memcpy(&pcb->pcb_vec, &vec, sizeof(vec));
+ }
+ break;
+ case PT_GETVSRREGS:
+ if (!(cpu_features & PPC_FEATURE_HAS_VSX))
+ break;
+
+ if (pcb->pcb_flags & PCB_VSX) {
+ save_fpu_nodrop(td);
+
+ /*
+ * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
+ * VSR32-VSR63 overlap with VR0-VR31, so we only copy
+ * the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
+ */
+ for (vsr_idx = 0; vsr_idx < nitems(vsr); vsr_idx++) {
+ vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
+ vsr[vsr_idx] = *vsr_dw1;
+ }
+ }
+ error = copyout(&vsr, addr, sizeof(vsr));
+ break;
+ case PT_SETVSRREGS:
+ if (!(cpu_features & PPC_FEATURE_HAS_VSX))
+ break;
+ error = copyin(addr, &vsr, sizeof(vsr));
+ if (error == 0) {
+ pcb->pcb_flags |= PCB_VSX;
+
+ /*
+ * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
+ * VSR32-VSR63 overlap with VR0-VR31, so we only copy
+ * the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
+ */
+ for (vsr_idx = 0; vsr_idx < nitems(vsr); vsr_idx++) {
+ vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
+ *vsr_dw1 = vsr[vsr_idx];
+ }
}
break;

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 18, 6:17 PM (13 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27714577
Default Alt Text
D15458.diff (6 KB)

Event Timeline