Author: jhibbits
Date: Sat Jan  3 21:06:06 2015
New Revision: 276634
URL: https://svnweb.freebsd.org/changeset/base/276634

Log:
  Dump VMX registers into the userland coredump.
  
  Reviewed by:  nwhitehorn
  MFC after:    2 weeks

Modified:
  head/sys/powerpc/include/altivec.h
  head/sys/powerpc/powerpc/altivec.c
  head/sys/powerpc/powerpc/elf32_machdep.c
  head/sys/powerpc/powerpc/elf64_machdep.c

Modified: head/sys/powerpc/include/altivec.h
==============================================================================
--- head/sys/powerpc/include/altivec.h  Sat Jan  3 20:29:47 2015        
(r276633)
+++ head/sys/powerpc/include/altivec.h  Sat Jan  3 21:06:06 2015        
(r276634)
@@ -34,6 +34,7 @@
 
 void    enable_vec(struct thread *);
 void    save_vec(struct thread *);
+void    save_vec_nodrop(struct thread *);
 
 #endif /* _MACHINE_ALTIVEC_H_ */
 

Modified: head/sys/powerpc/powerpc/altivec.c
==============================================================================
--- head/sys/powerpc/powerpc/altivec.c  Sat Jan  3 20:29:47 2015        
(r276633)
+++ head/sys/powerpc/powerpc/altivec.c  Sat Jan  3 21:06:06 2015        
(r276634)
@@ -43,6 +43,46 @@ __FBSDID("$FreeBSD$");
 #include <machine/pcb.h>
 #include <machine/psl.h>
 
+static void
+save_vec_int(struct thread *td)
+{
+       int     msr;
+       struct  pcb *pcb;
+
+       pcb = td->td_pcb;
+
+       /*
+        * Temporarily re-enable the vector unit during the save
+        */
+       msr = mfmsr();
+       mtmsr(msr | PSL_VEC);
+       isync();
+
+       /*
+        * Save the vector registers and VSCR to the PCB
+        */
+#define STVX(n)   __asm ("stvx %1,0,%0" \
+               :: "b"(pcb->pcb_vec.vr[n]), "n"(n));
+       STVX(0);        STVX(1);        STVX(2);        STVX(3);
+       STVX(4);        STVX(5);        STVX(6);        STVX(7);
+       STVX(8);        STVX(9);        STVX(10);       STVX(11);
+       STVX(12);       STVX(13);       STVX(14);       STVX(15);
+       STVX(16);       STVX(17);       STVX(18);       STVX(19);
+       STVX(20);       STVX(21);       STVX(22);       STVX(23);
+       STVX(24);       STVX(25);       STVX(26);       STVX(27);
+       STVX(28);       STVX(29);       STVX(30);       STVX(31);
+#undef STVX
+
+       __asm __volatile("mfvscr 0; stvewx 0,0,%0" :: "b"(&pcb->pcb_vec.vscr));
+
+       /*
+        * Disable vector unit again
+        */
+       isync();
+       mtmsr(msr);
+
+}
+
 void
 enable_vec(struct thread *td)
 {
@@ -107,40 +147,11 @@ enable_vec(struct thread *td)
 void
 save_vec(struct thread *td)
 {
-       int     msr;
-       struct  pcb *pcb;
+       struct pcb *pcb;
 
        pcb = td->td_pcb;
 
-       /*
-        * Temporarily re-enable the vector unit during the save
-        */
-       msr = mfmsr();
-       mtmsr(msr | PSL_VEC);
-       isync();
-
-       /*
-        * Save the vector registers and VSCR to the PCB
-        */
-#define STVX(n)   __asm ("stvx %1,0,%0" \
-               :: "b"(pcb->pcb_vec.vr[n]), "n"(n));
-       STVX(0);        STVX(1);        STVX(2);        STVX(3);
-       STVX(4);        STVX(5);        STVX(6);        STVX(7);
-       STVX(8);        STVX(9);        STVX(10);       STVX(11);
-       STVX(12);       STVX(13);       STVX(14);       STVX(15);
-       STVX(16);       STVX(17);       STVX(18);       STVX(19);
-       STVX(20);       STVX(21);       STVX(22);       STVX(23);
-       STVX(24);       STVX(25);       STVX(26);       STVX(27);
-       STVX(28);       STVX(29);       STVX(30);       STVX(31);
-#undef STVX
-
-       __asm __volatile("mfvscr 0; stvewx 0,0,%0" :: "b"(&pcb->pcb_vec.vscr));
-
-       /*
-        * Disable vector unit again
-        */
-       isync();
-       mtmsr(msr);
+       save_vec_int(td);
 
        /*
         * Clear the current vec thread and pcb's CPU id
@@ -150,3 +161,19 @@ save_vec(struct thread *td)
        PCPU_SET(vecthread, NULL);
 }
 
+/*
+ * Save altivec state without dropping ownership.  This will only save state if
+ * the current vector-thread is `td'.
+ */
+void
+save_vec_nodrop(struct thread *td)
+{
+       struct thread *vtd;
+
+       vtd = PCPU_GET(vecthread);
+       if (td != vtd) {
+               return;
+       }
+
+       save_vec_int(td);
+}

Modified: head/sys/powerpc/powerpc/elf32_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf32_machdep.c    Sat Jan  3 20:29:47 2015        
(r276633)
+++ head/sys/powerpc/powerpc/elf32_machdep.c    Sat Jan  3 21:06:06 2015        
(r276634)
@@ -47,6 +47,7 @@
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 
+#include <machine/altivec.h>
 #include <machine/cpu.h>
 #include <machine/elf.h>
 #include <machine/reg.h>
@@ -147,9 +148,24 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_AN
        &freebsd_brand_oinfo);
 
 void
-elf32_dump_thread(struct thread *td __unused, void *dst __unused,
-    size_t *off __unused)
+elf32_dump_thread(struct thread *td, void *dst, size_t *off)
 {
+       size_t len;
+       struct pcb *pcb;
+
+       len = 0;
+       pcb = td->td_pcb;
+       if (pcb->pcb_flags & PCB_VEC) {
+               save_vec_nodrop(td);
+               if (dst != NULL) {
+                       len += elf32_populate_note(NT_PPC_VMX,
+                           &pcb->pcb_vec, dst,
+                           sizeof(pcb->pcb_vec), NULL);
+               } else
+                       len += elf32_populate_note(NT_PPC_VMX, NULL, NULL,
+                           sizeof(pcb->pcb_vec), NULL);
+       }
+       *off = len;
 }
 
 #ifndef __powerpc64__

Modified: head/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf64_machdep.c    Sat Jan  3 20:29:47 2015        
(r276633)
+++ head/sys/powerpc/powerpc/elf64_machdep.c    Sat Jan  3 21:06:06 2015        
(r276634)
@@ -44,6 +44,7 @@
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 
+#include <machine/altivec.h>
 #include <machine/cpu.h>
 #include <machine/elf.h>
 #include <machine/md_var.h>
@@ -119,9 +120,24 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_AN
        &freebsd_brand_oinfo);
 
 void
-elf64_dump_thread(struct thread *td __unused, void *dst __unused,
-    size_t *off __unused)
+elf64_dump_thread(struct thread *td, void *dst, size_t *off)
 {
+       size_t len;
+       struct pcb *pcb;
+
+       len = 0;
+       pcb = td->td_pcb;
+       if (pcb->pcb_flags & PCB_VEC) {
+               save_vec_nodrop(td);
+               if (dst != NULL) {
+                       len += elf64_populate_note(NT_PPC_VMX,
+                           &pcb->pcb_vec, dst,
+                           sizeof(pcb->pcb_vec), NULL);
+               } else
+                       len += elf64_populate_note(NT_PPC_VMX, NULL, NULL,
+                           sizeof(pcb->pcb_vec), NULL);
+       }
+       *off = len;
 }
 
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to