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-all
mailing list