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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/ia32/os/fpu.c
          +++ new/usr/src/uts/intel/ia32/os/fpu.c
↓ open down ↓ 1373 lines elided ↑ open up ↑
1374 1374           * going to re-use the LWP, then we should go ahead and save the state.
1375 1375           * We must also note that the fpu is now being used by the kernel and
1376 1376           * therefore we do not want to manage the fpu state via the user-level
1377 1377           * thread's context handlers.
1378 1378           *
1379 1379           * We might have already saved once (due to a prior use of the kernel
1380 1380           * FPU or another code path) so FPU_VALID could be set. This is handled
1381 1381           * by fp_save, as is the FPU_EN check.
1382 1382           */
1383 1383          if (pl != NULL) {
     1384 +                fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
     1385 +
1384 1386                  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;
     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;
1388 1405                  kpreempt_enable();
1389 1406          }
1390 1407  
1391 1408          /*
1392 1409           * Set the context operations for kernel FPU usage. Note that this
1393 1410           * cannot be done with pre-emption and interrupts disabled, since
1394 1411           * installctx does a sleeping allocation. We haven't finished
1395 1412           * initializing our kernel FPU state yet, but in the rare case that we
1396 1413           * happen to save/restore before that, no harm is done.
1397 1414           */
1398 1415          installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
1399 1416              NULL, NULL, NULL, NULL);
1400 1417  
1401 1418          curthread->t_flag |= T_KFPU;
1402 1419  
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 +        if ((flags & KFPU_USE_LWP) == 0) {
1420 1421                  /* initialize the kfpu state */
1421 1422                  kernel_fpu_ctx_restore(kfpu);
1422 1423          }
1423 1424  }
1424 1425  
1425 1426  void
1426 1427  kernel_fpu_end(kfpu_state_t *kfpu, uint_t flags)
1427 1428  {
1428 1429          ulong_t iflags;
1429 1430  
↓ open down ↓ 90 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX