| 1145 | } |
| 1146 | |
| 1147 | void |
| 1148 | fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx, u_int flags) |
| 1149 | { |
| 1150 | struct pcb *pcb; |
| 1151 | |
| 1152 | pcb = td->td_pcb; |
| 1153 | KASSERT((flags & FPU_KERN_NOCTX) != 0 || ctx != NULL, |
| 1154 | ("ctx is required when !FPU_KERN_NOCTX")); |
| 1155 | KASSERT(ctx == NULL || (ctx->flags & FPU_KERN_CTX_INUSE) == 0, |
| 1156 | ("using inuse ctx")); |
| 1157 | KASSERT((pcb->pcb_flags & PCB_FPUNOSAVE) == 0, |
| 1158 | ("recursive fpu_kern_enter while in PCB_FPUNOSAVE state")); |
| 1159 | |
| 1160 | if ((flags & FPU_KERN_NOCTX) != 0) { |
| 1161 | critical_enter(); |
| 1162 | stop_emulating(); |
| 1163 | if (curthread == PCPU_GET(fpcurthread)) { |
| 1164 | fpusave(curpcb->pcb_save); |
| 1165 | PCPU_SET(fpcurthread, NULL); |
| 1166 | } else { |
| 1167 | KASSERT(PCPU_GET(fpcurthread) == NULL, |
| 1168 | ("invalid fpcurthread")); |
| 1169 | } |
| 1170 | |
| 1171 | /* |
| 1172 | * This breaks XSAVEOPT tracker, but |
| 1173 | * PCB_FPUNOSAVE state is supposed to never need to |
| 1174 | * save FPU context at all. |
| 1175 | */ |
| 1176 | fpurestore(fpu_initialstate); |
| 1177 | set_pcb_flags(pcb, PCB_KERNFPU | PCB_FPUNOSAVE | |
| 1178 | PCB_FPUINITDONE); |
| 1179 | return; |
| 1180 | } |
| 1181 | if ((flags & FPU_KERN_KTHR) != 0 && is_fpu_kern_thread(0)) { |
| 1182 | ctx->flags = FPU_KERN_CTX_DUMMY | FPU_KERN_CTX_INUSE; |
| 1183 | return; |
| 1184 | } |
| 1185 | critical_enter(); |
| 1186 | KASSERT(!PCB_USER_FPU(pcb) || pcb->pcb_save == |
| 1187 | get_pcb_user_save_pcb(pcb), ("mangled pcb_save")); |
| 1188 | ctx->flags = FPU_KERN_CTX_INUSE; |
| 1189 | if ((pcb->pcb_flags & PCB_FPUINITDONE) != 0) |
| 1190 | ctx->flags |= FPU_KERN_CTX_FPUINITDONE; |
| 1191 | fpuexit(td); |
| 1192 | ctx->prev = pcb->pcb_save; |
| 1193 | pcb->pcb_save = fpu_kern_ctx_savefpu(ctx); |
| 1194 | set_pcb_flags(pcb, PCB_KERNFPU); |
| 1195 | clear_pcb_flags(pcb, PCB_FPUINITDONE); |
| 1196 | critical_exit(); |
| 1197 | } |
| 1198 | |
| 1199 | int |
| 1200 | fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx) |
nothing calls this directly
no test coverage detected