1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2023 Oxide Computer Company
  14  */
  15 
  16 /*
  17  * The purpose of this program is to go through and replace all the FPU
  18  * registers in the floating point state in a ucontext_t and verify that we see
  19  * what we expected here.
  20  */
  21 
  22 #include <err.h>
  23 #include <stdlib.h>
  24 #include <ucontext.h>
  25 
  26 #include "xsave_util.h"
  27 
  28 xsu_fpu_t to_set, found;
  29 
  30 static void
  31 setcontext_replace_check(uint32_t hwsup)
  32 {
  33         xsu_getfpu(&found, hwsup);
  34         if (xsu_same(&to_set, &found, hwsup)) {
  35                 (void) printf("TEST PASSED: setcontext() correctly wrote FPU "
  36                     "contents\n");
  37                 exit(EXIT_SUCCESS);
  38         } else {
  39                 errx(EXIT_FAILURE, "TEST_FAILED: setcontext() did not write "
  40                     "full FPU state");
  41         }
  42 }
  43 
  44 int
  45 main(void)
  46 {
  47         ucontext_t *ctx;
  48         uint32_t start = arc4random();
  49         uint32_t hwsup = xsu_hwsupport();
  50 
  51         ctx = ucontext_alloc(0);
  52         if (ctx == NULL) {
  53                 err(EXIT_FAILURE, "failed to get allocate ucontext_t");
  54         }
  55         (void) printf("filling starting at 0x%x\n", start);
  56         xsu_fill(&to_set, hwsup, start);
  57         if (getcontext_extd(ctx, 0) != 0) {
  58                 err(EXIT_FAILURE, "failed to get extended context");
  59         }
  60 
  61         xsu_overwrite_uctx(ctx, &to_set, hwsup);
  62         makecontext(ctx, setcontext_replace_check, 1, hwsup);
  63         (void) setcontext(ctx);
  64 
  65         err(EXIT_FAILURE, "TEST FAILED: set context did not work!");
  66 }