Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/test/os-tests/tests/xsave/fpregs_xbv.c
+++ new/usr/src/test/os-tests/tests/xsave/fpregs_xbv.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2023 Oxide Computer Company
14 14 */
15 15
16 16 /*
17 17 * In illumos#15367 we noted that on some CPUs it was possible to get the xsave
18 18 * state into a place where it has not set components that are used for the x87
19 19 * and XMM state. This test attempts to create those situations and then get a
20 20 * ucontext_t to see that we actually have cleared it out. Because this behavior
21 21 * varies from CPU to CPU (e.g. in the original case we only saw this on AMD and
22 22 * not Intel), it can be tricky to guarantee we've recreated this.
23 23 */
24 24
25 25 #include <err.h>
26 26 #include <stdio.h>
27 27 #include <sys/types.h>
28 28 #include <ucontext.h>
29 29 #include <stdlib.h>
30 30
31 31 int
32 32 main(void)
33 33 {
34 34 ucontext_t ctx;
35 35 upad128_t u, *up;
36 36
37 37 u._l[0] = 0x1;
38 38 u._l[1] = 0x2;
39 39 u._l[2] = 0x3;
40 40 u._l[3] = 0x4;
41 41
42 42 /*
43 43 * Load %xmm0 and then lock in the data into the pcb with a call to
44 44 * getcontext(2) which will force an FPU save.
45 45 */
46 46 /* BEGIN CSTYLED */
47 47 __asm__ __volatile__ ("movdqu %0, %%xmm0" : : "m" (u));
48 48 __asm__ __volatile__ ("fldl %0" : : "m" (u));
49 49 /* END CSTYLED */
50 50 if (getcontext(&ctx) != 0) {
51 51 errx(EXIT_FAILURE, "TEST_FAILED: failed to get initial "
52 52 "ucontext");
53 53 }
54 54
55 55 /*
56 56 * Attempt to reset the FPU at this point and then call getcontext. The
57 57 * fninit is for the x87 part. The vzeroall covers all the higher
58 58 * registers and this combined should reset the x87 and xmm regions back
59 59 * to 0. It appears that on some Intel processors, the vzeroall is
60 60 * required to get the XMM set to not be written out as opposed to just
61 61 * doing a pxor or similar.
62 62 */
63 63 /* BEGIN CSTYLED */
64 64 __asm__ __volatile__ ("fninit" : : :);
65 65 __asm__ __volatile__ ("vzeroall" : : :);
66 66 /* END CSTYLED */
67 67 if (getcontext(&ctx) != 0) {
68 68 errx(EXIT_FAILURE, "TEST_FAILED: failed to get second "
69 69 "ucontext");
70 70 }
71 71 up = &ctx.uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[0];
72 72 if (up->_l[0] != 0 || up->_l[1] != 0 || up->_l[2] != 0 ||
73 73 up->_l[3] != 0) {
74 74 errx(EXIT_FAILURE, "TEST FAILED: %%xmm0 was not zero, found: "
75 75 "0x%x 0x%x 0x%x 0x%x", up->_l[3], up->_l[2],
76 76 up->_l[1], up->_l[0]);
77 77 }
78 78
79 79 (void) printf("TEST PASSED: successfully got zeored %%xmm0\n");
80 80 return (EXIT_SUCCESS);
81 81 }
|
↓ open down ↓ |
81 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX