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
This commit is contained in:
parent
95bf54ddfc
commit
44e79a530d
@ -262,8 +262,28 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, u_int flags)
|
||||
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;
|
||||
@ -293,19 +313,30 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *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;
|
||||
|
@ -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 */
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user