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

Andrew Turner andrew at FreeBSD.org
Tue Jul 18 16:36:34 UTC 2017


Author: andrew
Date: Tue Jul 18 16:36:32 2017
New Revision: 321131
URL: https://svnweb.freebsd.org/changeset/base/321131

Log:
  Add support for passing FPU_KERN_NOCTX to fpu_kern_enter on arm64. This
  will be used to call into UEFI from the kernel.
  
  Sponsored by:	DARPA, AFRL

Modified:
  head/sys/arm64/arm64/vfp.c
  head/sys/arm64/include/pcb.h
  head/sys/arm64/include/vfp.h

Modified: head/sys/arm64/arm64/vfp.c
==============================================================================
--- head/sys/arm64/arm64/vfp.c	Tue Jul 18 16:27:10 2017	(r321130)
+++ head/sys/arm64/arm64/vfp.c	Tue Jul 18 16:36:32 2017	(r321131)
@@ -262,9 +262,29 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx 
 	struct pcb *pcb;
 
 	pcb = td->td_pcb;
+	KASSERT((flags & FPU_KERN_NOCTX) != 0 || ctx != NULL,
+	    ("ctx is required when !FPU_KERN_NOCTX"));
 	KASSERT(ctx == NULL || (ctx->flags & FPU_KERN_CTX_INUSE) == 0,
 	    ("using inuse ctx"));
+	KASSERT((pcb->pcb_fpflags & PCB_FP_NOSAVE) == 0,
+	    ("recursive fpu_kern_enter while in PCB_FP_NOSAVE state"));
 
+	if ((flags & FPU_KERN_NOCTX) != 0) {
+		critical_enter();
+		if (curthread == PCPU_GET(fpcurthread)) {
+			vfp_save_state(curthread, pcb);
+			PCPU_SET(fpcurthread, NULL);
+		} else {
+			KASSERT(PCPU_GET(fpcurthread) == NULL,
+			    ("invalid fpcurthread"));
+		}
+
+		vfp_enable();
+		pcb->pcb_fpflags |= PCB_FP_KERN | PCB_FP_NOSAVE |
+		    PCB_FP_STARTED;
+		return (0);
+	}
+
 	if ((flags & FPU_KERN_KTHR) != 0 && is_fpu_kern_thread(0)) {
 		ctx->flags = FPU_KERN_CTX_DUMMY | FPU_KERN_CTX_INUSE;
 		return (0);
@@ -293,19 +313,30 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx 
 
 	pcb = td->td_pcb;
 
-	KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0,
-	    ("FPU context not inuse"));
-	ctx->flags &= ~FPU_KERN_CTX_INUSE;
+	if ((pcb->pcb_fpflags & PCB_FP_NOSAVE) != 0) {
+		KASSERT(ctx == NULL, ("non-null ctx after FPU_KERN_NOCTX"));
+		KASSERT(PCPU_GET(fpcurthread) == NULL,
+		    ("non-NULL fpcurthread for PCB_FP_NOSAVE"));
+		CRITICAL_ASSERT(td);
 
-	if (is_fpu_kern_thread(0) &&
-	    (ctx->flags & FPU_KERN_CTX_DUMMY) != 0)
-		return (0);
-	KASSERT((ctx->flags & FPU_KERN_CTX_DUMMY) == 0, ("dummy ctx"));
-	critical_enter();
-	vfp_discard(td);
-	critical_exit();
-	pcb->pcb_fpflags &= ~PCB_FP_STARTED;
-	pcb->pcb_fpusaved = ctx->prev;
+		vfp_disable();
+		pcb->pcb_fpflags &= ~(PCB_FP_NOSAVE | PCB_FP_STARTED);
+		critical_exit();
+	} else {
+		KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0,
+		    ("FPU context not inuse"));
+		ctx->flags &= ~FPU_KERN_CTX_INUSE;
+
+		if (is_fpu_kern_thread(0) &&
+		    (ctx->flags & FPU_KERN_CTX_DUMMY) != 0)
+			return (0);
+		KASSERT((ctx->flags & FPU_KERN_CTX_DUMMY) == 0, ("dummy ctx"));
+		critical_enter();
+		vfp_discard(td);
+		critical_exit();
+		pcb->pcb_fpflags &= ~PCB_FP_STARTED;
+		pcb->pcb_fpusaved = ctx->prev;
+	}
 
 	if (pcb->pcb_fpusaved == &pcb->pcb_fpustate) {
 		pcb->pcb_fpflags &= ~PCB_FP_KERN;

Modified: head/sys/arm64/include/pcb.h
==============================================================================
--- head/sys/arm64/include/pcb.h	Tue Jul 18 16:27:10 2017	(r321130)
+++ head/sys/arm64/include/pcb.h	Tue Jul 18 16:36:32 2017	(r321131)
@@ -56,6 +56,7 @@ struct pcb {
 	int		pcb_fpflags;
 #define	PCB_FP_STARTED	0x01
 #define	PCB_FP_KERN	0x02
+#define	PCB_FP_NOSAVE	0x04
 /* The bits passed to userspace in get_fpcontext */
 #define	PCB_FP_USERMASK	(PCB_FP_STARTED)
 	u_int		pcb_vfpcpu;	/* Last cpu this thread ran VFP code */

Modified: head/sys/arm64/include/vfp.h
==============================================================================
--- head/sys/arm64/include/vfp.h	Tue Jul 18 16:27:10 2017	(r321130)
+++ head/sys/arm64/include/vfp.h	Tue Jul 18 16:36:32 2017	(r321131)
@@ -56,6 +56,7 @@ struct fpu_kern_ctx;
 #define	FPU_KERN_NORMAL	0x0000
 #define	FPU_KERN_NOWAIT	0x0001
 #define	FPU_KERN_KTHR	0x0002
+#define	FPU_KERN_NOCTX	0x0004
 
 struct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int);
 void fpu_kern_free_ctx(struct fpu_kern_ctx *);


More information about the svn-src-head mailing list