Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/test/os-tests/tests/xsave/xregs_roundtrip.c
+++ new/usr/src/test/os-tests/tests/xsave/xregs_roundtrip.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 * Verify that we can read the xregs of a thread and write them back intact.
18 18 * This uses libproc as a wrapper. We then start the thread running again and
19 19 * attempt to write to /proc ourselves to expect an EBUSY because the thread is
20 20 * not stopped.
21 21 */
22 22
23 23 #include <libproc.h>
24 24 #include <thread.h>
25 25 #include <stdlib.h>
26 26 #include <err.h>
27 27 #include <errno.h>
28 28 #include <string.h>
29 29 #include <sys/sysmacros.h>
30 30
31 31 #include "xsave_util.h"
32 32
33 33 int
34 34 main(void)
35 35 {
36 36 int ret, fd;
37 37 ssize_t sret;
38 38 struct ps_prochandle *P;
39 39 struct ps_lwphandle *L;
40 40 thread_t targ;
41 41 prxregset_t *prx, *prx_alt;
42 42 size_t prx_len, prx_alt_len;
43 43 struct iovec iov[2];
44 44 long cmd = PCSXREG;
45 45
46 46 P = Pgrab(getpid(), PGRAB_RDONLY, &ret);
47 47 if (P == NULL) {
48 48 errx(EXIT_FAILURE, "failed to grab ourself: %s",
49 49 Pgrab_error(ret));
50 50 }
51 51
52 52 ret = thr_create(NULL, 0, xsu_sleeper_thread, NULL, THR_DETACHED,
53 53 &targ);
54 54 if (ret != 0) {
55 55 errc(EXIT_FAILURE, ret, "failed to create sleeper thread");
56 56 }
57 57
58 58 L = Lgrab(P, targ, &ret);
59 59 if (L == NULL) {
60 60 errx(EXIT_FAILURE, "failed to grab our sleeper thread: %s",
61 61 Lgrab_error(ret));
62 62 }
63 63
64 64 ret = Lstop(L, 0);
65 65 if (ret != 0) {
66 66 err(EXIT_FAILURE, "failed to stop the sleeper thread");
67 67 }
68 68
69 69 if (Lgetxregs(L, &prx, &prx_len) != 0) {
70 70 err(EXIT_FAILURE, "failed to get xregs");
71 71 }
72 72
73 73 (void) printf("TEST PASSED: sucessfully got initial xregs\n");
74 74
75 75 if (Lsetxregs(L, prx, prx_len) != 0) {
76 76 err(EXIT_FAILURE, "failed to set xregs");
77 77 }
78 78
79 79 (void) printf("TEST PASSED: sucessfully set xregs\n");
80 80
81 81 if (Lgetxregs(L, &prx_alt, &prx_alt_len) != 0) {
82 82 err(EXIT_FAILURE, "failed to get xregs after write");
83 83 }
84 84
85 85 if (prx_len != prx_alt_len) {
86 86 errx(EXIT_FAILURE, "xreg length changed across a write: "
87 87 "originally found %zu, now %zu", prx_len, prx_alt_len);
88 88 }
89 89
90 90 if (memcmp(prx, prx_alt, prx_len) != 0) {
91 91 const uint8_t *a = (uint8_t *)prx;
92 92 const uint8_t *b = (uint8_t *)prx_alt;
93 93 for (size_t i = 0; i < prx_len; i++) {
94 94 if (a[i] != b[i]) {
95 95 (void) fprintf(stderr, "prx[0x%x] = 0x%02x, "
96 96 "prx_alt[0x%x] = 0x%02x\n", i, a[i], i,
97 97 b[i]);
98 98 }
99 99 }
100 100 errx(EXIT_FAILURE, "xregs were not the same!");
101 101 }
102 102
103 103 (void) printf("TEST PASSED: round-trip xregs\n");
104 104
105 105 if (Lsetrun(L, 0, 0) != 0) {
106 106 err(EXIT_FAILURE, "failed to start sleeper thread");
107 107 }
108 108
109 109 /*
110 110 * We write to /proc directly ourselves as a way to avoid libproc's own
111 111 * checks for the state of the thread.
112 112 */
113 113 fd = Lctlfd(L);
114 114 if (fd < 0) {
115 115 errx(EXIT_FAILURE, "failed to get sleeper thread control d");
116 116 }
117 117
118 118 iov[0].iov_base = (char *)&cmd;
119 119 iov[0].iov_len = sizeof (long);
120 120 iov[1].iov_base = (char *)prx;
121 121 iov[1].iov_len = prx_len;
122 122 sret = writev(fd, iov, ARRAY_SIZE(iov));
123 123 if (sret != -1) {
124 124 errx(EXIT_FAILURE, "writev returned %zd, but expected -1",
125 125 sret);
126 126 }
127 127
128 128 if (errno != EBUSY) {
129 129
130 130 }
131 131
132 132 (void) printf("TEST PASSED: got EBUSY with PCSXREG to running "
133 133 "thread\n");
134 134 Plwp_freexregs(P, prx, prx_len);
135 135 return (EXIT_SUCCESS);
136 136 }
|
↓ open down ↓ |
136 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX