Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
usr/src/uts/common/fs/proc/prcontrol.c
usr/src/uts/intel/os/archdep.c
usr/src/uts/intel/sys/ucontext.h
usr/src/uts/intel/syscall/getcontext.c
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/i86pc/os/fpu_subr.c
+++ new/usr/src/uts/intel/os/fpu_subr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2018, Joyent, Inc.
25 25 */
26 26
27 27 /*
28 28 * Floating point configuration.
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/regset.h>
33 33 #include <sys/privregs.h>
34 34 #include <sys/x86_archext.h>
35 35 #include <sys/archsystm.h>
36 36 #include <sys/fp.h>
37 37 #include <sys/cmn_err.h>
38 38 #include <sys/exec.h>
39 39
40 40 #define XMM_ALIGN 16
41 41
42 42 /*
43 43 * See section 10.5.1 in the Intel 64 and IA-32 Architectures Software
44 44 * Developer’s Manual, Volume 1.
45 45 */
46 46 #define FXSAVE_ALIGN 16
47 47
48 48 /*
49 49 * See section 13.4 in the Intel 64 and IA-32 Architectures Software
50 50 * Developer’s Manual, Volume 1.
51 51 */
52 52 #define XSAVE_ALIGN 64
53 53
54 54 /*
|
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
55 55 * If fpu_exists is non-zero, fpu_probe will attempt to use any
56 56 * hardware FPU (subject to other constraints, see below). If
57 57 * fpu_exists is zero, fpu_probe will report that there is no
58 58 * FPU even if there is one.
59 59 */
60 60 int fpu_exists = 1;
61 61
62 62 int fp_kind = FP_387;
63 63
64 64 /*
65 - * The kind of FPU we advertise to rtld so it knows what to do on context
66 - * switch.
67 - */
68 -int fp_elf = AT_386_FPINFO_FXSAVE;
69 -
70 -/*
71 - * Mechanism to save FPU state.
72 - */
73 -int fp_save_mech = FP_FXSAVE;
74 -
75 -/*
76 65 * The variable fpu_ignored is provided to allow other code to
77 66 * determine whether emulation is being done because there is
78 67 * no FPU or because of an override requested via /etc/system.
79 68 */
80 69 int fpu_ignored = 0;
81 70
82 71 /*
83 72 * Used by ppcopy and ppzero to determine whether or not to use the
84 73 * SSE-based pagecopy and pagezero routines
85 74 */
86 75 int use_sse_pagecopy = 0;
87 76 int use_sse_pagezero = 0;
88 77 int use_sse_copy = 0;
89 78
90 79 #if defined(__xpv)
91 80
92 81 /*
93 82 * Use of SSE or otherwise is forcibly configured for us by the hypervisor.
94 83 */
95 84
96 85 #define ENABLE_SSE()
97 86 #define DISABLE_SSE()
98 87
99 88 #else /* __xpv */
100 89
101 90 #define ENABLE_SSE() setcr4(CR4_ENABLE_SSE_FLAGS(getcr4()))
102 91 #define DISABLE_SSE() setcr4(CR4_DISABLE_SSE_FLAGS(getcr4()))
103 92
104 93 #endif /* __xpv */
105 94
106 95 /*
107 96 * Try and figure out what kind of FP capabilities we have, and
108 97 * set up the control registers accordingly.
109 98 */
110 99 void
111 100 fpu_probe(void)
112 101 {
113 102 if (fpu_initial_probe() != 0)
114 103 goto nofpu;
115 104
116 105 if (fpu_exists == 0) {
117 106 fpu_ignored = 1;
118 107 goto nofpu;
119 108 }
120 109
121 110 #ifndef __xpv
122 111 /*
123 112 * Check and see if the fpu is present by looking
124 113 * at the "extension type" bit. (While this used to
125 114 * indicate a 387DX coprocessor in days gone by,
126 115 * it's forced on by modern implementations for
127 116 * compatibility.)
128 117 */
129 118 if ((getcr0() & CR0_ET) == 0)
130 119 goto nofpu;
131 120 #endif
132 121
133 122 /* Use the more complex exception clearing code if necessary */
134 123 if (cpuid_need_fp_excp_handling())
135 124 fpsave_ctxt = fpxsave_excp_clr_ctxt;
136 125
137 126 /*
138 127 * SSE and SSE2 are required for the 64-bit ABI.
139 128 *
140 129 * If they're not present, we can in principal run
141 130 * 32-bit userland, though 64-bit processes will be hosed.
142 131 *
143 132 * (Perhaps we should complain more about this case!)
144 133 */
145 134 if (is_x86_feature(x86_featureset, X86FSET_SSE) &&
146 135 is_x86_feature(x86_featureset, X86FSET_SSE2)) {
147 136 fp_kind |= __FP_SSE;
148 137 ENABLE_SSE();
149 138
150 139 if (is_x86_feature(x86_featureset, X86FSET_AVX)) {
151 140 ASSERT(is_x86_feature(x86_featureset, X86FSET_XSAVE));
152 141 fp_kind |= __FP_AVX;
153 142 }
154 143
155 144 if (is_x86_feature(x86_featureset, X86FSET_XSAVE)) {
156 145 fp_save_mech = FP_XSAVE;
157 146 fp_elf = AT_386_FPINFO_XSAVE;
158 147 if (is_x86_feature(x86_featureset, X86FSET_XSAVEOPT)) {
159 148 /*
160 149 * Use the more complex exception
161 150 * clearing code if necessary.
162 151 */
163 152 if (cpuid_need_fp_excp_handling()) {
164 153 fpsave_ctxt = xsaveopt_excp_clr_ctxt;
165 154 fp_elf = AT_386_FPINFO_XSAVE_AMD;
166 155 } else {
167 156 fpsave_ctxt = xsaveopt_ctxt;
168 157 }
169 158 xsavep = xsaveopt;
170 159 } else {
171 160 /*
172 161 * Use the more complex exception
173 162 * clearing code if necessary.
174 163 */
175 164 if (cpuid_need_fp_excp_handling()) {
176 165 fpsave_ctxt = xsave_excp_clr_ctxt;
177 166 fp_elf = AT_386_FPINFO_XSAVE_AMD;
178 167 } else {
179 168 fpsave_ctxt = xsave_ctxt;
180 169 }
181 170 }
182 171 fprestore_ctxt = xrestore_ctxt;
183 172 fpsave_cachep = kmem_cache_create("xsave_cache",
184 173 cpuid_get_xsave_size(), XSAVE_ALIGN,
185 174 NULL, NULL, NULL, NULL, NULL, 0);
186 175 } else {
187 176 /* fp_save_mech defaults to FP_FXSAVE */
188 177 fpsave_cachep = kmem_cache_create("fxsave_cache",
189 178 sizeof (struct fxsave_state), FXSAVE_ALIGN,
190 179 NULL, NULL, NULL, NULL, NULL, 0);
191 180 fp_elf = AT_386_FPINFO_FXSAVE;
192 181 }
193 182 }
194 183
195 184 if (is_x86_feature(x86_featureset, X86FSET_SSE2)) {
196 185 use_sse_pagecopy = use_sse_pagezero = use_sse_copy = 1;
197 186 }
198 187
199 188 if (fp_kind & __FP_SSE) {
200 189 struct fxsave_state *fx;
201 190 uint8_t fxsave_state[sizeof (struct fxsave_state) + XMM_ALIGN];
202 191
203 192 /*
204 193 * Extract the mxcsr mask from our first fxsave
205 194 */
206 195 fx = (void *)(((uintptr_t)(&fxsave_state[0]) +
207 196 XMM_ALIGN) & ~(XMM_ALIGN - 1ul));
208 197
209 198 fx->fx_mxcsr_mask = 0;
210 199 fxsave_insn(fx);
211 200 if (fx->fx_mxcsr_mask != 0) {
212 201 /*
213 202 * Override default mask initialized in fpu.c
214 203 */
215 204 sse_mxcsr_mask = fx->fx_mxcsr_mask;
216 205 }
217 206 }
218 207
219 208 setcr0(CR0_ENABLE_FPU_FLAGS(getcr0()));
|
↓ open down ↓ |
134 lines elided |
↑ open up ↑ |
220 209 return;
221 210
222 211 /*
223 212 * No FPU hardware present
224 213 */
225 214 nofpu:
226 215 setcr0(CR0_DISABLE_FPU_FLAGS(getcr0()));
227 216 DISABLE_SSE();
228 217 fp_kind = FP_NO;
229 218 fpu_exists = 0;
230 -}
231 -
232 -/*
233 - * Fill in FPU information that is required by exec.
234 - */
235 -void
236 -fpu_auxv_info(int *typep, size_t *lenp)
237 -{
238 - *typep = fp_elf;
239 - switch (fp_save_mech) {
240 - case FP_FXSAVE:
241 - *lenp = sizeof (struct fxsave_state);
242 - break;
243 - case FP_XSAVE:
244 - *lenp = cpuid_get_xsave_size();
245 - break;
246 - default:
247 - *lenp = 0;
248 - break;
249 - }
250 219 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX