Print this page
13902 Fix for 13717 may break 8-disk raidz2


1371 
1372         /*
1373          * Not all threads may have an active LWP. If they do and we're not
1374          * going to re-use the LWP, then we should go ahead and save the state.
1375          * We must also note that the fpu is now being used by the kernel and
1376          * therefore we do not want to manage the fpu state via the user-level
1377          * thread's context handlers.
1378          *
1379          * We might have already saved once (due to a prior use of the kernel
1380          * FPU or another code path) so FPU_VALID could be set. This is handled
1381          * by fp_save, as is the FPU_EN check.
1382          */
1383         if (pl != NULL) {
1384                 kpreempt_disable();
1385                 if ((flags & KFPU_USE_LWP) == 0)
1386                         fp_save(&pl->lwp_pcb.pcb_fpu);
1387                 pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL;
1388                 kpreempt_enable();
1389         }
1390 
1391         /*
1392          * Set the context operations for kernel FPU usage. Note that this
1393          * cannot be done with pre-emption and interrupts disabled, since
1394          * installctx does a sleeping allocation. We haven't finished
1395          * initializing our kernel FPU state yet, but in the rare case that we
1396          * happen to save/restore before that, no harm is done.
1397          */
1398         installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
1399             NULL, NULL, NULL, NULL);
1400 
1401         curthread->t_flag |= T_KFPU;
1402 
1403         if ((flags & KFPU_USE_LWP) == KFPU_USE_LWP) {
1404                 /*
1405                  * For pure kernel threads with an LWP, we can use the LWP's
1406                  * pcb_fpu to save/restore context.
1407                  */
1408                 fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
1409 
1410                 VERIFY(curthread->t_procp->p_flag & SSYS);
1411                 VERIFY(kfpu == NULL);
1412                 ASSERT((pf->fpu_flags & FPU_EN) == 0);
1413 
1414                 /* Always restore the fpu to the initial state. */
1415                 if (fp_save_mech == FP_XSAVE)
1416                         pf->fpu_xsave_mask = XFEATURE_FP_ALL;
1417                 fpinit();
1418                 pf->fpu_flags = FPU_EN | FPU_KERNEL;
1419         } else {
1420                 /* initialize the kfpu state */
1421                 kernel_fpu_ctx_restore(kfpu);
1422         }










1423 }
1424 
1425 void
1426 kernel_fpu_end(kfpu_state_t *kfpu, uint_t flags)
1427 {
1428         ulong_t iflags;
1429 
1430         if ((curthread->t_flag & T_KFPU) == 0) {
1431                 panic("curthread attempting to clear kernel FPU state "
1432                     "without using it");
1433         }
1434 
1435         /*
1436          * General comments on why the rest of this function is structured the
1437          * way it is. Be aware that there is a lot of subtlety here.
1438          *
1439          * If a user-level thread ever uses the fpu while in the kernel, then
1440          * we cannot call fpdisable since that does STTS. That will set the
1441          * ts bit in %cr0 which will cause an exception if anything touches the
1442          * fpu. However, the user-level context switch handler (fpsave_ctxt)




1371 
1372         /*
1373          * Not all threads may have an active LWP. If they do and we're not
1374          * going to re-use the LWP, then we should go ahead and save the state.
1375          * We must also note that the fpu is now being used by the kernel and
1376          * therefore we do not want to manage the fpu state via the user-level
1377          * thread's context handlers.
1378          *
1379          * We might have already saved once (due to a prior use of the kernel
1380          * FPU or another code path) so FPU_VALID could be set. This is handled
1381          * by fp_save, as is the FPU_EN check.
1382          */
1383         if (pl != NULL) {
1384                 kpreempt_disable();
1385                 if ((flags & KFPU_USE_LWP) == 0)
1386                         fp_save(&pl->lwp_pcb.pcb_fpu);
1387                 pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL;
1388                 kpreempt_enable();
1389         }
1390 










1391         curthread->t_flag |= T_KFPU;
1392 
1393         if ((flags & KFPU_USE_LWP) == KFPU_USE_LWP) {
1394                 /*
1395                  * For pure kernel threads with an LWP, we can use the LWP's
1396                  * pcb_fpu to save/restore context.
1397                  */
1398                 fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
1399 
1400                 VERIFY(curthread->t_procp->p_flag & SSYS);
1401                 VERIFY(kfpu == NULL);
1402                 ASSERT((pf->fpu_flags & FPU_EN) == 0);
1403 
1404                 /* Always restore the fpu to the initial state. */
1405                 if (fp_save_mech == FP_XSAVE)
1406                         pf->fpu_xsave_mask = XFEATURE_FP_ALL;
1407                 fpinit();
1408                 pf->fpu_flags = FPU_EN | FPU_KERNEL;
1409         } else {
1410                 /* initialize the kfpu state */
1411                 kernel_fpu_ctx_restore(kfpu);
1412         }
1413 
1414         /*
1415          * Set the context operations for kernel FPU usage. Note that this
1416          * cannot be done with pre-emption and interrupts disabled, since
1417          * installctx does a sleeping allocation. We haven't finished
1418          * initializing our kernel FPU state yet, but in the rare case that we
1419          * happen to save/restore before that, no harm is done.
1420          */
1421         installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
1422             NULL, NULL, NULL, NULL);
1423 }
1424 
1425 void
1426 kernel_fpu_end(kfpu_state_t *kfpu, uint_t flags)
1427 {
1428         ulong_t iflags;
1429 
1430         if ((curthread->t_flag & T_KFPU) == 0) {
1431                 panic("curthread attempting to clear kernel FPU state "
1432                     "without using it");
1433         }
1434 
1435         /*
1436          * General comments on why the rest of this function is structured the
1437          * way it is. Be aware that there is a lot of subtlety here.
1438          *
1439          * If a user-level thread ever uses the fpu while in the kernel, then
1440          * we cannot call fpdisable since that does STTS. That will set the
1441          * ts bit in %cr0 which will cause an exception if anything touches the
1442          * fpu. However, the user-level context switch handler (fpsave_ctxt)