Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/test/os-tests/tests/xsave/signal_restore.c
+++ new/usr/src/test/os-tests/tests/xsave/signal_restore.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 Comptuer Company
14 14 */
15 15
16 16 /*
17 17 * Verify that the FPU contents are correctly restored after taking a signal. We
18 18 * do this by going through and setting up a signal handler for SIGINFO and then
19 19 * we do the following as tightly as possible: overwriting the FPU contents and
20 20 * then calling thr_kill(). As part of the regression for #15254, we also
21 21 * purposefully go off CPU in the signal handler to try to wreak havoc.
22 22 */
23 23
24 24 #include <err.h>
25 25 #include <stdlib.h>
26 26 #include <ucontext.h>
27 27 #include <limits.h>
28 28 #include <signal.h>
29 29 #include <thread.h>
30 30 #include <string.h>
31 31 #include <time.h>
32 32 #include <unistd.h>
33 33
34 34 #include "xsave_util.h"
35 35
36 36 static xsu_fpu_t init_vals, signal_vals, found;
37 37 static volatile int exit_status = EXIT_SUCCESS;
38 38 static volatile int took_sig = 0;
39 39 static uint32_t sr_hwsup;
40 40
41 41 static void
42 42 signal_restore_siginfo(int sig, siginfo_t *sip, void *ucp)
43 43 {
44 44 struct timespec ts;
45 45 took_sig = 1;
46 46
47 47 ts.tv_sec = 0;
48 48 ts.tv_nsec = 10 * MILLISEC;
49 49
50 50 /*
51 51 * yield doesn't guarantee that we go off CPU, but try a few anyways.
52 52 * There's a slight chance that nanosleep will modify the FPU state, but
53 53 * we can hope we're lucky and that the libc function won'.
54 54 */
55 55 xsu_setfpu(&signal_vals, sr_hwsup);
56 56 yield();
57 57 yield();
58 58 (void) nanosleep(&ts, NULL);
59 59 xsu_getfpu(&found, sr_hwsup);
60 60
61 61 if (xsu_same(&signal_vals, &found, sr_hwsup)) {
62 62 (void) printf("TEST PASSED: FPU contents didn't change in "
63 63 "signal handler\n");
64 64 } else {
65 65 warnx("TEST FAILED: FPU contents changed in signal handler!");
66 66 exit_status = EXIT_FAILURE;
67 67 }
68 68
69 69 }
70 70
71 71 int
72 72 main(void)
73 73 {
74 74 int ret;
75 75 thread_t self = thr_self();
76 76 uint32_t start = arc4random();
77 77 uint32_t hwsup = xsu_hwsupport();
78 78 struct sigaction sa;
79 79
80 80 sr_hwsup = hwsup;
81 81 sa.sa_sigaction = signal_restore_siginfo;
82 82 sa.sa_flags = SA_RESETHAND;
83 83
84 84 if (sigaction(SIGINFO, &sa, NULL) != 0) {
85 85 errx(EXIT_FAILURE, "TEST FAILED: failed to set up signal "
86 86 "handler");
87 87 }
88 88
89 89 (void) printf("filling starting at 0x%x\n", start);
90 90 xsu_fill(&init_vals, hwsup, start);
91 91 xsu_fill(&signal_vals, hwsup, start + INT_MAX);
92 92
93 93 (void) memset(&sa, 0, sizeof (struct sigaction));
94 94
95 95 xsu_setfpu(&init_vals, hwsup);
96 96 ret = thr_kill(self, SIGINFO);
97 97 xsu_getfpu(&found, hwsup);
98 98
99 99 if (ret != 0) {
100 100 errc(EXIT_FAILURE, ret, "TEST FAILED: failed to deliver "
101 101 "signal");
102 102 }
103 103
104 104 if (took_sig == 0) {
105 105 errx(EXIT_FAILURE, "TEST FAILED: signal handler did not run");
106 106 }
107 107
108 108 (void) printf("TEST PASSED: SIGINFO successfully delivered\n");
109 109
110 110 if (xsu_same(&init_vals, &found, hwsup)) {
111 111 (void) printf("TEST PASSED: FPU contents successfully "
112 112 "restored\n");
113 113 } else {
114 114 warnx("TEST FAILED: FPU contents were not restored!");
115 115 exit_status = EXIT_FAILURE;
116 116 }
117 117
118 118 return (exit_status);
119 119 }
|
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX