svn commit: r276634 - in head/sys/powerpc: include powerpc

Justin Hibbits jhibbits at FreeBSD.org
Sat Jan 3 21:06:09 UTC 2015


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;
 }
 
 


More information about the svn-src-head mailing list