Print this page
manifest

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/os/archdep.c
          +++ new/usr/src/uts/intel/os/archdep.c
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  
  25   25  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  26   26  /*        All Rights Reserved   */
  27   27  /*
  28   28   * Copyright (c) 2018, Joyent, Inc.
  29   29   * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  30      - * Copyright 2022 Oxide Computer Company
       30 + * Copyright 2023 Oxide Computer Company
  31   31   */
  32   32  
  33   33  #include <sys/param.h>
  34   34  #include <sys/types.h>
  35   35  #include <sys/vmparam.h>
  36   36  #include <sys/systm.h>
  37   37  #include <sys/signal.h>
  38   38  #include <sys/stack.h>
  39   39  #include <sys/regset.h>
  40   40  #include <sys/privregs.h>
↓ open down ↓ 191 lines elided ↑ open up ↑
 232  232              src->fp_reg_set.fpchip_state.xstatus;
 233  233  }
 234  234  #endif
 235  235  
 236  236  /*
 237  237   * Set floating-point registers from a native fpregset_t.
 238  238   */
 239  239  void
 240  240  setfpregs(klwp_t *lwp, fpregset_t *fp)
 241  241  {
 242      -        struct fpu_ctx *fpu = &lwp->lwp_pcb.pcb_fpu;
 243      -
 244      -        if (fpu->fpu_flags & FPU_EN) {
 245      -                if (!(fpu->fpu_flags & FPU_VALID)) {
 246      -                        /*
 247      -                         * FPU context is still active, release the
 248      -                         * ownership.
 249      -                         */
 250      -                        fp_free(fpu);
 251      -                }
 252      -        }
 253      -        /*
 254      -         * Else: if we are trying to change the FPU state of a thread which
 255      -         * hasn't yet initialized floating point, store the state in
 256      -         * the pcb and indicate that the state is valid.  When the
 257      -         * thread enables floating point, it will use this state instead
 258      -         * of the default state.
 259      -         */
 260      -
 261      -        switch (fp_save_mech) {
 262      -        case FP_FXSAVE:
 263      -                fpregset_to_fxsave(fp, fpu->fpu_regs.kfpu_u.kfpu_fx);
 264      -                fpu->fpu_regs.kfpu_xstatus =
 265      -                    fp->fp_reg_set.fpchip_state.xstatus;
 266      -                break;
 267      -
 268      -        case FP_XSAVE:
 269      -                fpregset_to_fxsave(fp,
 270      -                    &fpu->fpu_regs.kfpu_u.kfpu_xs->xs_fxsave);
 271      -                fpu->fpu_regs.kfpu_xstatus =
 272      -                    fp->fp_reg_set.fpchip_state.xstatus;
 273      -                fpu->fpu_regs.kfpu_u.kfpu_xs->xs_header.xsh_xstate_bv |=
 274      -                    (XFEATURE_LEGACY_FP | XFEATURE_SSE);
 275      -                break;
 276      -        default:
 277      -                panic("Invalid fp_save_mech");
 278      -                /*NOTREACHED*/
 279      -        }
 280      -
 281      -        fpu->fpu_regs.kfpu_status = fp->fp_reg_set.fpchip_state.status;
 282      -        fpu->fpu_flags |= FPU_VALID;
 283      -        PCB_SET_UPDATE_FPU(&lwp->lwp_pcb);
      242 +        fpu_set_fpregset(lwp, fp);
 284  243  }
 285  244  
 286  245  /*
 287  246   * Get floating-point registers into a native fpregset_t.
 288  247   */
 289  248  void
 290  249  getfpregs(klwp_t *lwp, fpregset_t *fp)
 291  250  {
 292      -        struct fpu_ctx *fpu = &lwp->lwp_pcb.pcb_fpu;
 293      -
 294      -        kpreempt_disable();
 295      -        if (fpu->fpu_flags & FPU_EN) {
 296      -                /*
 297      -                 * If we have FPU hw and the thread's pcb doesn't have
 298      -                 * a valid FPU state then get the state from the hw.
 299      -                 */
 300      -                if (fpu_exists && ttolwp(curthread) == lwp &&
 301      -                    !(fpu->fpu_flags & FPU_VALID))
 302      -                        fp_save(fpu); /* get the current FPU state */
 303      -        }
 304      -
 305      -        /*
 306      -         * There are 3 possible cases we have to be aware of here:
 307      -         *
 308      -         * 1. FPU is enabled.  FPU state is stored in the current LWP.
 309      -         *
 310      -         * 2. FPU is not enabled, and there have been no intervening /proc
 311      -         *    modifications.  Return initial FPU state.
 312      -         *
 313      -         * 3. FPU is not enabled, but a /proc consumer has modified FPU state.
 314      -         *    FPU state is stored in the current LWP.
 315      -         */
 316      -        if ((fpu->fpu_flags & FPU_EN) || (fpu->fpu_flags & FPU_VALID)) {
 317      -                /*
 318      -                 * Cases 1 and 3.
 319      -                 */
 320      -                switch (fp_save_mech) {
 321      -                case FP_FXSAVE:
 322      -                        fxsave_to_fpregset(fpu->fpu_regs.kfpu_u.kfpu_fx, fp);
 323      -                        fp->fp_reg_set.fpchip_state.xstatus =
 324      -                            fpu->fpu_regs.kfpu_xstatus;
 325      -                        break;
 326      -                case FP_XSAVE:
 327      -                        fxsave_to_fpregset(
 328      -                            &fpu->fpu_regs.kfpu_u.kfpu_xs->xs_fxsave, fp);
 329      -                        fp->fp_reg_set.fpchip_state.xstatus =
 330      -                            fpu->fpu_regs.kfpu_xstatus;
 331      -                        break;
 332      -                default:
 333      -                        panic("Invalid fp_save_mech");
 334      -                        /*NOTREACHED*/
 335      -                }
 336      -                fp->fp_reg_set.fpchip_state.status = fpu->fpu_regs.kfpu_status;
 337      -        } else {
 338      -                /*
 339      -                 * Case 2.
 340      -                 */
 341      -                switch (fp_save_mech) {
 342      -                case FP_FXSAVE:
 343      -                case FP_XSAVE:
 344      -                        /*
 345      -                         * For now, we don't have any AVX specific field in ABI.
 346      -                         * If we add any in the future, we need to initial them
 347      -                         * as well.
 348      -                         */
 349      -                        fxsave_to_fpregset(&sse_initial, fp);
 350      -                        fp->fp_reg_set.fpchip_state.xstatus =
 351      -                            fpu->fpu_regs.kfpu_xstatus;
 352      -                        break;
 353      -                default:
 354      -                        panic("Invalid fp_save_mech");
 355      -                        /*NOTREACHED*/
 356      -                }
 357      -                fp->fp_reg_set.fpchip_state.status = fpu->fpu_regs.kfpu_status;
 358      -        }
 359      -        kpreempt_enable();
      251 +        bzero(fp, sizeof (*fp));
      252 +        fpu_get_fpregset(lwp, fp);
 360  253  }
 361  254  
 362  255  #if defined(_SYSCALL32_IMPL)
 363  256  
 364  257  /*
 365  258   * Set floating-point registers from an fpregset32_t.
 366  259   */
 367  260  void
 368  261  setfpregs32(klwp_t *lwp, fpregset32_t *fp)
 369  262  {
↓ open down ↓ 151 lines elided ↑ open up ↑
 521  414          if (src->uc_flags & UC_FPU)
 522  415                  fpregset_32ton(&src->uc_mcontext.fpregs,
 523  416                      &dst->uc_mcontext.fpregs);
 524  417  
 525  418          /*
 526  419           * Copy the brand-private data:
 527  420           */
 528  421          dst->uc_brand_data[0] = (void *)(uintptr_t)src->uc_brand_data[0];
 529  422          dst->uc_brand_data[1] = (void *)(uintptr_t)src->uc_brand_data[1];
 530  423          dst->uc_brand_data[2] = (void *)(uintptr_t)src->uc_brand_data[2];
      424 +
      425 +        if (src->uc_flags & UC_XSAVE) {
      426 +                dst->uc_xsave = (long)(uint32_t)src->uc_xsave;
      427 +        } else {
      428 +                dst->uc_xsave = 0;
      429 +        }
 531  430  }
 532  431  
 533  432  #endif  /* _SYSCALL32_IMPL */
 534  433  
 535  434  /*
 536  435   * Return the user-level PC.
 537  436   * If in a system call, return the address of the syscall trap.
 538  437   */
 539  438  greg_t
 540      -getuserpc()
      439 +getuserpc(void)
 541  440  {
 542  441          greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
 543  442          uint32_t insn;
 544  443  
 545  444          if (curthread->t_sysnum == 0)
 546  445                  return (upc);
 547  446  
 548  447          /*
 549  448           * We might've gotten here from sysenter (0xf 0x34),
 550  449           * syscall (0xf 0x5) or lcall (0x9a 0 0 0 0 0x27 0).
↓ open down ↓ 720 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX