svn commit: r286225 - in head/sys/arm64: arm64 include

Andrew Turner andrew at FreeBSD.org
Mon Aug 3 11:05:05 UTC 2015


Author: andrew
Date: Mon Aug  3 11:05:02 2015
New Revision: 286225
URL: https://svnweb.freebsd.org/changeset/base/286225

Log:
  Pass the pcb to store the vfp state in to vfp_save_state. This fixes a bug
  in savectx where it will be used to store the current state however will
  pass in a pcb when vfp_save_state expected a thread pointer.
  
  Obtained from:	ABT Systems Ltd
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/arm64/arm64/machdep.c
  head/sys/arm64/arm64/swtch.S
  head/sys/arm64/arm64/vfp.c
  head/sys/arm64/arm64/vm_machdep.c
  head/sys/arm64/include/vfp.h

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c	Mon Aug  3 10:10:49 2015	(r286224)
+++ head/sys/arm64/arm64/machdep.c	Mon Aug  3 11:05:02 2015	(r286225)
@@ -180,7 +180,7 @@ fill_fpregs(struct thread *td, struct fp
 		 * If we have just been running VFP instructions we will
 		 * need to save the state to memcpy it below.
 		 */
-		vfp_save_state(td);
+		vfp_save_state(td, pcb);
 
 		memcpy(regs->fp_q, pcb->pcb_vfp, sizeof(regs->fp_q));
 		regs->fp_cr = pcb->pcb_fpcr;
@@ -314,7 +314,7 @@ get_fpcontext(struct thread *td, mcontex
 		 * If we have just been running VFP instructions we will
 		 * need to save the state to memcpy it below.
 		 */
-		vfp_save_state(td);
+		vfp_save_state(td, curpcb);
 
 		memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_vfp,
 		    sizeof(mcp->mc_fpregs));

Modified: head/sys/arm64/arm64/swtch.S
==============================================================================
--- head/sys/arm64/arm64/swtch.S	Mon Aug  3 10:10:49 2015	(r286224)
+++ head/sys/arm64/arm64/swtch.S	Mon Aug  3 11:05:02 2015	(r286225)
@@ -131,6 +131,8 @@ ENTRY(cpu_switch)
 	mov	x19, x0
 	mov	x20, x1
 	mov	x21, x2
+	/* Load the pcb address */
+	mov	x1, x4
 	bl	vfp_save_state
 	mov	x2, x21
 	mov	x1, x20
@@ -268,9 +270,11 @@ ENTRY(savectx)
 
 	/* Store the VFP registers */
 #ifdef VFP
-	mov	x29, lr
+	mov	x28, lr
+	mov	x1, x0			/* move pcb to the correct register */
+	mov	x0, xzr			/* td = NULL */
 	bl	vfp_save_state
-	mov	lr, x29
+	mov	lr, x28
 #endif
 
 	ret

Modified: head/sys/arm64/arm64/vfp.c
==============================================================================
--- head/sys/arm64/arm64/vfp.c	Mon Aug  3 10:10:49 2015	(r286224)
+++ head/sys/arm64/arm64/vfp.c	Mon Aug  3 11:05:02 2015	(r286225)
@@ -82,12 +82,18 @@ vfp_discard(struct thread *td)
 }
 
 void
-vfp_save_state(struct thread *td)
+vfp_save_state(struct thread *td, struct pcb *pcb)
 {
 	__int128_t *vfp_state;
 	uint64_t fpcr, fpsr;
 	uint32_t cpacr;
 
+	KASSERT(pcb != NULL, ("NULL vfp pcb"));
+	KASSERT(td == NULL || td->td_pcb == pcb, ("Invalid vfp pcb"));
+
+	if (td == NULL)
+		td = curthread;
+
 	critical_enter();
 	/*
 	 * Only store the registers if the VFP is enabled,
@@ -98,7 +104,7 @@ vfp_save_state(struct thread *td)
 		KASSERT(PCPU_GET(fpcurthread) == td,
 		    ("Storing an invalid VFP state"));
 
-		vfp_state = td->td_pcb->pcb_vfp;
+		vfp_state = pcb->pcb_vfp;
 		__asm __volatile(
 		    "mrs	%0, fpcr		\n"
 		    "mrs	%1, fpsr		\n"
@@ -120,8 +126,8 @@ vfp_save_state(struct thread *td)
 		    "stp	q30, q31, [%2, #16 * 30]\n"
 		    : "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state));
 
-		td->td_pcb->pcb_fpcr = fpcr;
-		td->td_pcb->pcb_fpsr = fpsr;
+		pcb->pcb_fpcr = fpcr;
+		pcb->pcb_fpsr = fpsr;
 
 		dsb(ish);
 		vfp_disable();

Modified: head/sys/arm64/arm64/vm_machdep.c
==============================================================================
--- head/sys/arm64/arm64/vm_machdep.c	Mon Aug  3 10:10:49 2015	(r286224)
+++ head/sys/arm64/arm64/vm_machdep.c	Mon Aug  3 11:05:02 2015	(r286225)
@@ -74,7 +74,7 @@ cpu_fork(struct thread *td1, struct proc
 		td1->td_pcb->pcb_tpidr_el0 = READ_SPECIALREG(tpidr_el0);
 #ifdef VFP
 		if ((td1->td_pcb->pcb_fpflags & PCB_FP_STARTED) != 0)
-			vfp_save_state(td1);
+			vfp_save_state(td1, td1->td_pcb);
 #endif
 	}
 

Modified: head/sys/arm64/include/vfp.h
==============================================================================
--- head/sys/arm64/include/vfp.h	Mon Aug  3 10:10:49 2015	(r286224)
+++ head/sys/arm64/include/vfp.h	Mon Aug  3 11:05:02 2015	(r286225)
@@ -38,7 +38,7 @@
 void	vfp_init(void);
 void	vfp_discard(struct thread *);
 void	vfp_restore_state(void);
-void	vfp_save_state(struct thread *);
+void	vfp_save_state(struct thread *, struct pcb *);
 #endif
 
 #endif


More information about the svn-src-all mailing list