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


1364                             "another thread already is using", kfpu);
1365 
1366                 if ((kfpu->kfpu_flags & KFPU_F_INITIALIZED) == 0)
1367                         kernel_fpu_fpstate_init(kfpu);
1368 
1369                 kfpu->kfpu_curthread = curthread;
1370         }
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




1364                             "another thread already is using", kfpu);
1365 
1366                 if ((kfpu->kfpu_flags & KFPU_F_INITIALIZED) == 0)
1367                         kernel_fpu_fpstate_init(kfpu);
1368 
1369                 kfpu->kfpu_curthread = curthread;
1370         }
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                 fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
1385 
1386                 kpreempt_disable();
1387                 if ((flags & KFPU_USE_LWP) == 0) {
1388                         fp_save(pf);
1389                 } else {
1390                         /*
1391                          * For pure kernel threads with an LWP, we can use the
1392                          * LWP's pcb_fpu to save/restore context.
1393                          */
1394                         VERIFY(curthread->t_procp->p_flag & SSYS);
1395                         VERIFY(kfpu == NULL);
1396                         ASSERT((pf->fpu_flags & FPU_EN) == 0);
1397 
1398                         /* Always restore the fpu to the initial state. */
1399                         if (fp_save_mech == FP_XSAVE)
1400                                 pf->fpu_xsave_mask = XFEATURE_FP_ALL;
1401                         fpinit();
1402                         pf->fpu_flags = FPU_EN;
1403                 }
1404                 pf->fpu_flags |= FPU_KERNEL;
1405                 kpreempt_enable();
1406         }
1407 
1408         /*
1409          * Set the context operations for kernel FPU usage. Note that this
1410          * cannot be done with pre-emption and interrupts disabled, since
1411          * installctx does a sleeping allocation. We haven't finished
1412          * initializing our kernel FPU state yet, but in the rare case that we
1413          * happen to save/restore before that, no harm is done.
1414          */
1415         installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
1416             NULL, NULL, NULL, NULL);
1417 
1418         curthread->t_flag |= T_KFPU;
1419 
1420         if ((flags & KFPU_USE_LWP) == 0) {
















1421                 /* initialize the kfpu state */
1422                 kernel_fpu_ctx_restore(kfpu);
1423         }
1424 }
1425 
1426 void
1427 kernel_fpu_end(kfpu_state_t *kfpu, uint_t flags)
1428 {
1429         ulong_t iflags;
1430 
1431         if ((curthread->t_flag & T_KFPU) == 0) {
1432                 panic("curthread attempting to clear kernel FPU state "
1433                     "without using it");
1434         }
1435 
1436         /*
1437          * General comments on why the rest of this function is structured the
1438          * way it is. Be aware that there is a lot of subtlety here.
1439          *
1440          * If a user-level thread ever uses the fpu while in the kernel, then