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
2a4727a472
commit
a2d16bc541
@ -262,8 +262,28 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, u_int flags)
|
|||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
|
|
||||||
pcb = td->td_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,
|
KASSERT(ctx == NULL || (ctx->flags & FPU_KERN_CTX_INUSE) == 0,
|
||||||
("using inuse ctx"));
|
("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)) {
|
if ((flags & FPU_KERN_KTHR) != 0 && is_fpu_kern_thread(0)) {
|
||||||
ctx->flags = FPU_KERN_CTX_DUMMY | FPU_KERN_CTX_INUSE;
|
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;
|
pcb = td->td_pcb;
|
||||||
|
|
||||||
KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0,
|
if ((pcb->pcb_fpflags & PCB_FP_NOSAVE) != 0) {
|
||||||
("FPU context not inuse"));
|
KASSERT(ctx == NULL, ("non-null ctx after FPU_KERN_NOCTX"));
|
||||||
ctx->flags &= ~FPU_KERN_CTX_INUSE;
|
KASSERT(PCPU_GET(fpcurthread) == NULL,
|
||||||
|
("non-NULL fpcurthread for PCB_FP_NOSAVE"));
|
||||||
|
CRITICAL_ASSERT(td);
|
||||||
|
|
||||||
if (is_fpu_kern_thread(0) &&
|
vfp_disable();
|
||||||
(ctx->flags & FPU_KERN_CTX_DUMMY) != 0)
|
pcb->pcb_fpflags &= ~(PCB_FP_NOSAVE | PCB_FP_STARTED);
|
||||||
return (0);
|
critical_exit();
|
||||||
KASSERT((ctx->flags & FPU_KERN_CTX_DUMMY) == 0, ("dummy ctx"));
|
} else {
|
||||||
critical_enter();
|
KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0,
|
||||||
vfp_discard(td);
|
("FPU context not inuse"));
|
||||||
critical_exit();
|
ctx->flags &= ~FPU_KERN_CTX_INUSE;
|
||||||
pcb->pcb_fpflags &= ~PCB_FP_STARTED;
|
|
||||||
pcb->pcb_fpusaved = ctx->prev;
|
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) {
|
if (pcb->pcb_fpusaved == &pcb->pcb_fpustate) {
|
||||||
pcb->pcb_fpflags &= ~PCB_FP_KERN;
|
pcb->pcb_fpflags &= ~PCB_FP_KERN;
|
||||||
|
@ -56,6 +56,7 @@ struct pcb {
|
|||||||
int pcb_fpflags;
|
int pcb_fpflags;
|
||||||
#define PCB_FP_STARTED 0x01
|
#define PCB_FP_STARTED 0x01
|
||||||
#define PCB_FP_KERN 0x02
|
#define PCB_FP_KERN 0x02
|
||||||
|
#define PCB_FP_NOSAVE 0x04
|
||||||
/* The bits passed to userspace in get_fpcontext */
|
/* The bits passed to userspace in get_fpcontext */
|
||||||
#define PCB_FP_USERMASK (PCB_FP_STARTED)
|
#define PCB_FP_USERMASK (PCB_FP_STARTED)
|
||||||
u_int pcb_vfpcpu; /* Last cpu this thread ran VFP code */
|
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_NORMAL 0x0000
|
||||||
#define FPU_KERN_NOWAIT 0x0001
|
#define FPU_KERN_NOWAIT 0x0001
|
||||||
#define FPU_KERN_KTHR 0x0002
|
#define FPU_KERN_KTHR 0x0002
|
||||||
|
#define FPU_KERN_NOCTX 0x0004
|
||||||
|
|
||||||
struct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int);
|
struct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int);
|
||||||
void fpu_kern_free_ctx(struct fpu_kern_ctx *);
|
void fpu_kern_free_ctx(struct fpu_kern_ctx *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user