master
c 890 lines 26.2 KB
Raw
1 /*
2 * Emulation of Linux signals
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20 #include "qemu.h"
21 #include "user-internals.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
24 #include "user/tswap-target.h"
25
26 /* from the Linux kernel - /arch/x86/include/uapi/asm/sigcontext.h */
27
28 #define TARGET_FP_XSTATE_MAGIC1 0x46505853U /* FPXS */
29 #define TARGET_FP_XSTATE_MAGIC2 0x46505845U /* FPXE */
30 #define TARGET_FP_XSTATE_MAGIC2_SIZE 4
31
32 struct target_fpreg {
33 uint16_t significand[4];
34 uint16_t exponent;
35 };
36
37 /* Legacy x87 fpu state format for FSAVE/FRESTOR. */
38 struct target_fregs_state {
39 uint32_t cwd;
40 uint32_t swd;
41 uint32_t twd;
42 uint32_t fip;
43 uint32_t fcs;
44 uint32_t foo;
45 uint32_t fos;
46 struct target_fpreg st[8];
47
48 /* Software status information [not touched by FSAVE]. */
49 uint16_t status;
50 uint16_t magic; /* 0xffff: FPU data only, 0x0000: FXSR FPU data */
51 };
52 QEMU_BUILD_BUG_ON(sizeof(struct target_fregs_state) != 32 + 80);
53
54 struct target_fpx_sw_bytes {
55 uint32_t magic1;
56 uint32_t extended_size;
57 uint64_t xfeatures;
58 uint32_t xstate_size;
59 uint32_t reserved[7];
60 };
61 QEMU_BUILD_BUG_ON(sizeof(struct target_fpx_sw_bytes) != 12*4);
62
63 struct fpxreg {
64 uint16_t significand[4];
65 uint16_t exponent;
66 uint16_t padding[3];
67 };
68
69 struct xmmreg {
70 uint32_t element[4];
71 };
72
73 /*
74 * This corresponds to the kernel's _fpstate_32. Since we
75 * only use it for the fpstate_unused padding section in
76 * the target sigcontext, it doesn't actually matter what fields
77 * we define here as long as we get the size right.
78 */
79 struct target_fpstate_32 {
80 struct target_fregs_state fpstate;
81 uint32_t fxsr_env[6];
82 uint32_t mxcsr;
83 uint32_t reserved;
84 struct fpxreg fxsr_st[8];
85 struct xmmreg xmm[8];
86 uint32_t padding1[44];
87 uint32_t padding2[12]; /* aka sw_reserved */
88 };
89 QEMU_BUILD_BUG_ON(sizeof(struct target_fpstate_32) != 32 + 80 + 512);
90
91 struct target_sigcontext_32 {
92 uint16_t gs, __gsh;
93 uint16_t fs, __fsh;
94 uint16_t es, __esh;
95 uint16_t ds, __dsh;
96 uint32_t edi;
97 uint32_t esi;
98 uint32_t ebp;
99 uint32_t esp;
100 uint32_t ebx;
101 uint32_t edx;
102 uint32_t ecx;
103 uint32_t eax;
104 uint32_t trapno;
105 uint32_t err;
106 uint32_t eip;
107 uint16_t cs, __csh;
108 uint32_t eflags;
109 uint32_t esp_at_signal;
110 uint16_t ss, __ssh;
111 uint32_t fpstate; /* pointer */
112 uint32_t oldmask;
113 uint32_t cr2;
114 };
115
116 struct target_sigcontext_64 {
117 uint64_t r8;
118 uint64_t r9;
119 uint64_t r10;
120 uint64_t r11;
121 uint64_t r12;
122 uint64_t r13;
123 uint64_t r14;
124 uint64_t r15;
125
126 uint64_t rdi;
127 uint64_t rsi;
128 uint64_t rbp;
129 uint64_t rbx;
130 uint64_t rdx;
131 uint64_t rax;
132 uint64_t rcx;
133 uint64_t rsp;
134 uint64_t rip;
135
136 uint64_t eflags;
137
138 uint16_t cs;
139 uint16_t gs;
140 uint16_t fs;
141 uint16_t ss;
142
143 uint64_t err;
144 uint64_t trapno;
145 uint64_t oldmask;
146 uint64_t cr2;
147
148 uint64_t fpstate; /* pointer */
149 uint64_t padding[8];
150 };
151
152 #ifndef TARGET_X86_64
153 # define target_sigcontext target_sigcontext_32
154 #else
155 # define target_sigcontext target_sigcontext_64
156 #endif
157
158 /* see Linux/include/uapi/asm-generic/ucontext.h */
159 struct target_ucontext {
160 abi_ulong tuc_flags;
161 abi_ulong tuc_link;
162 target_stack_t tuc_stack;
163 struct target_sigcontext tuc_mcontext;
164 target_sigset_t tuc_sigmask; /* mask last for extensibility */
165 };
166
167 #ifndef TARGET_X86_64
168 struct sigframe {
169 abi_ulong pretcode;
170 int sig;
171 struct target_sigcontext sc;
172 /*
173 * The actual fpstate is placed after retcode[] below, to make room
174 * for the variable-sized xsave data. The older unused fpstate has
175 * to be kept to avoid changing the offset of extramask[], which
176 * is part of the ABI.
177 */
178 struct target_fpstate_32 fpstate_unused;
179 abi_ulong extramask[TARGET_NSIG_WORDS-1];
180 char retcode[8];
181 /* fp state follows here */
182 };
183
184 struct rt_sigframe {
185 abi_ulong pretcode;
186 int sig;
187 abi_ulong pinfo;
188 abi_ulong puc;
189 struct target_siginfo info;
190 struct target_ucontext uc;
191 char retcode[8];
192 /* fp state follows here */
193 };
194
195 /*
196 * Verify that vdso-asmoffset.h constants match.
197 */
198 #include "i386/vdso-asmoffset.h"
199
200 QEMU_BUILD_BUG_ON(offsetof(struct sigframe, sc.eip)
201 != SIGFRAME_SIGCONTEXT_eip);
202 QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, uc.tuc_mcontext.eip)
203 != RT_SIGFRAME_SIGCONTEXT_eip);
204
205 #else
206
207 struct rt_sigframe {
208 abi_ulong pretcode;
209 struct target_ucontext uc;
210 struct target_siginfo info;
211 /* fp state follows here */
212 };
213 #endif
214
215 typedef enum {
216 #ifndef TARGET_X86_64
217 FPSTATE_FSAVE,
218 #endif
219 FPSTATE_FXSAVE,
220 FPSTATE_XSAVE
221 } FPStateKind;
222
223 static FPStateKind get_fpstate_kind(CPUX86State *env)
224 {
225 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
226 return FPSTATE_XSAVE;
227 }
228 #ifdef TARGET_X86_64
229 return FPSTATE_FXSAVE;
230 #else
231 if (env->features[FEAT_1_EDX] & CPUID_FXSR) {
232 return FPSTATE_FXSAVE;
233 }
234 return FPSTATE_FSAVE;
235 #endif
236 }
237
238 static unsigned get_fpstate_size(CPUX86State *env, FPStateKind fpkind)
239 {
240 /*
241 * Kernel:
242 * fpu__alloc_mathframe
243 * xstate_sigframe_size(current->thread.fpu.fpstate);
244 * size = fpstate->user_size
245 * use_xsave() ? size + FP_XSTATE_MAGIC2_SIZE : size
246 * where fpstate->user_size is computed at init in
247 * fpu__init_system_xstate_size_legacy and
248 * fpu__init_system_xstate.
249 *
250 * Here we have no place to pre-compute, so inline it all.
251 */
252 switch (fpkind) {
253 case FPSTATE_XSAVE:
254 return (xsave_area_size(env->xcr0, false)
255 + TARGET_FP_XSTATE_MAGIC2_SIZE);
256 case FPSTATE_FXSAVE:
257 return sizeof(X86LegacyXSaveArea);
258 #ifndef TARGET_X86_64
259 case FPSTATE_FSAVE:
260 return sizeof(struct target_fregs_state);
261 #endif
262 }
263 g_assert_not_reached();
264 }
265
266 static abi_ptr get_sigframe(struct target_sigaction *ka, CPUX86State *env,
267 unsigned frame_size, FPStateKind fpkind,
268 abi_ptr *fpstate, abi_ptr *fxstate, abi_ptr *fpend)
269 {
270 abi_ptr sp;
271 unsigned math_size;
272
273 /* Default to using normal stack */
274 sp = get_sp_from_cpustate(env);
275 #ifdef TARGET_X86_64
276 sp -= 128; /* this is the redzone */
277 #endif
278
279 /* This is the X/Open sanctioned signal stack switching. */
280 if (ka->sa_flags & TARGET_SA_ONSTACK) {
281 sp = target_sigsp(sp, ka);
282 } else {
283 #ifndef TARGET_X86_64
284 /* This is the legacy signal stack switching. */
285 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS
286 && !(ka->sa_flags & TARGET_SA_RESTORER)
287 && ka->sa_restorer) {
288 sp = ka->sa_restorer;
289 }
290 #endif
291 }
292
293 math_size = get_fpstate_size(env, fpkind);
294 sp = ROUND_DOWN(sp - math_size, 64);
295 *fpend = sp + math_size;
296 *fxstate = sp;
297 #ifndef TARGET_X86_64
298 if (fpkind != FPSTATE_FSAVE) {
299 sp -= sizeof(struct target_fregs_state);
300 }
301 #endif
302 *fpstate = sp;
303
304 sp -= frame_size;
305 /*
306 * Align the stack pointer according to the ABI, i.e. so that on
307 * function entry ((sp + sizeof(return_addr)) & 15) == 0.
308 */
309 sp += sizeof(target_ulong);
310 sp = ROUND_DOWN(sp, 16);
311 sp -= sizeof(target_ulong);
312
313 return sp;
314 }
315
316 /*
317 * Set up a signal frame.
318 */
319
320 static void fxsave_sigcontext(CPUX86State *env, X86LegacyXSaveArea *fxstate)
321 {
322 struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
323
324 cpu_x86_fxsave(env, fxstate, sizeof(*fxstate));
325 __put_user(0, &sw->magic1);
326 }
327
328 static void xsave_sigcontext(CPUX86State *env,
329 X86LegacyXSaveArea *fxstate,
330 abi_ptr fpstate_addr,
331 abi_ptr xstate_addr,
332 abi_ptr fpend_addr)
333 {
334 struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
335 /*
336 * extended_size is the offset from fpstate_addr to right after
337 * the end of the extended save states. On 32-bit that includes
338 * the legacy FSAVE area.
339 */
340 uint32_t extended_size = fpend_addr - fpstate_addr;
341 /* Recover xstate_size by removing magic2. */
342 uint32_t xstate_size = (fpend_addr - xstate_addr
343 - TARGET_FP_XSTATE_MAGIC2_SIZE);
344 /* magic2 goes just after xstate. */
345 uint32_t *magic2 = (void *)fxstate + xstate_size;
346
347 /* xstate_addr must be 64 byte aligned for xsave */
348 assert(!(xstate_addr & 0x3f));
349
350 /* Zero the header, XSAVE *adds* features to an existing save state. */
351 memset(fxstate + 1, 0, sizeof(X86XSaveHeader));
352 cpu_x86_xsave(env, fxstate, fpend_addr - xstate_addr, env->xcr0);
353
354 __put_user(TARGET_FP_XSTATE_MAGIC1, &sw->magic1);
355 __put_user(extended_size, &sw->extended_size);
356 __put_user(env->xcr0, &sw->xfeatures);
357 __put_user(xstate_size, &sw->xstate_size);
358 __put_user(TARGET_FP_XSTATE_MAGIC2, magic2);
359 }
360
361 static void setup_sigcontext(CPUX86State *env,
362 struct target_sigcontext *sc,
363 abi_ulong mask, FPStateKind fpkind,
364 struct target_fregs_state *fpstate,
365 abi_ptr fpstate_addr,
366 X86LegacyXSaveArea *fxstate,
367 abi_ptr fxstate_addr,
368 abi_ptr fpend_addr)
369 {
370 CPUState *cs = env_cpu(env);
371
372 #ifndef TARGET_X86_64
373 uint16_t magic;
374
375 /* already locked in setup_frame() */
376 __put_user(env->segs[R_GS].selector, (uint32_t *)&sc->gs);
377 __put_user(env->segs[R_FS].selector, (uint32_t *)&sc->fs);
378 __put_user(env->segs[R_ES].selector, (uint32_t *)&sc->es);
379 __put_user(env->segs[R_DS].selector, (uint32_t *)&sc->ds);
380 __put_user(env->regs[R_EDI], &sc->edi);
381 __put_user(env->regs[R_ESI], &sc->esi);
382 __put_user(env->regs[R_EBP], &sc->ebp);
383 __put_user(env->regs[R_ESP], &sc->esp);
384 __put_user(env->regs[R_EBX], &sc->ebx);
385 __put_user(env->regs[R_EDX], &sc->edx);
386 __put_user(env->regs[R_ECX], &sc->ecx);
387 __put_user(env->regs[R_EAX], &sc->eax);
388 __put_user(cs->exception_index, &sc->trapno);
389 __put_user(env->error_code, &sc->err);
390 __put_user(env->eip, &sc->eip);
391 __put_user(env->segs[R_CS].selector, (uint32_t *)&sc->cs);
392 __put_user(env->eflags, &sc->eflags);
393 __put_user(env->regs[R_ESP], &sc->esp_at_signal);
394 __put_user(env->segs[R_SS].selector, (uint32_t *)&sc->ss);
395
396 cpu_x86_fsave(env, fpstate, sizeof(*fpstate));
397 fpstate->status = fpstate->swd;
398 magic = (fpkind == FPSTATE_FSAVE ? 0 : 0xffff);
399 __put_user(magic, &fpstate->magic);
400 #else
401 __put_user(env->regs[R_EDI], &sc->rdi);
402 __put_user(env->regs[R_ESI], &sc->rsi);
403 __put_user(env->regs[R_EBP], &sc->rbp);
404 __put_user(env->regs[R_ESP], &sc->rsp);
405 __put_user(env->regs[R_EBX], &sc->rbx);
406 __put_user(env->regs[R_EDX], &sc->rdx);
407 __put_user(env->regs[R_ECX], &sc->rcx);
408 __put_user(env->regs[R_EAX], &sc->rax);
409
410 __put_user(env->regs[8], &sc->r8);
411 __put_user(env->regs[9], &sc->r9);
412 __put_user(env->regs[10], &sc->r10);
413 __put_user(env->regs[11], &sc->r11);
414 __put_user(env->regs[12], &sc->r12);
415 __put_user(env->regs[13], &sc->r13);
416 __put_user(env->regs[14], &sc->r14);
417 __put_user(env->regs[15], &sc->r15);
418
419 __put_user(cs->exception_index, &sc->trapno);
420 __put_user(env->error_code, &sc->err);
421 __put_user(env->eip, &sc->rip);
422
423 __put_user(env->eflags, &sc->eflags);
424 __put_user(env->segs[R_CS].selector, &sc->cs);
425 __put_user((uint16_t)0, &sc->gs);
426 __put_user((uint16_t)0, &sc->fs);
427 __put_user(env->segs[R_SS].selector, &sc->ss);
428 #endif
429
430 switch (fpkind) {
431 case FPSTATE_XSAVE:
432 xsave_sigcontext(env, fxstate, fpstate_addr, fxstate_addr, fpend_addr);
433 break;
434 case FPSTATE_FXSAVE:
435 fxsave_sigcontext(env, fxstate);
436 break;
437 default:
438 break;
439 }
440
441 __put_user(fpstate_addr, &sc->fpstate);
442 /* non-iBCS2 extensions.. */
443 __put_user(mask, &sc->oldmask);
444 __put_user(env->cr[2], &sc->cr2);
445 }
446
447 #ifndef TARGET_X86_64
448 static void install_sigtramp(void *tramp)
449 {
450 /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */
451 __put_user(0xb858, (uint16_t *)(tramp + 0));
452 __put_user(TARGET_NR_sigreturn, (int32_t *)(tramp + 2));
453 __put_user(0x80cd, (uint16_t *)(tramp + 6));
454 }
455
456 static void install_rt_sigtramp(void *tramp)
457 {
458 /* This is movl $syscall,%eax ; int $0x80 */
459 __put_user(0xb8, (uint8_t *)(tramp + 0));
460 __put_user(TARGET_NR_rt_sigreturn, (int32_t *)(tramp + 1));
461 __put_user(0x80cd, (uint16_t *)(tramp + 5));
462 }
463
464 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
465 void setup_frame(int sig, struct target_sigaction *ka,
466 target_sigset_t *set, CPUX86State *env)
467 {
468 abi_ptr frame_addr, fpstate_addr, fxstate_addr, fpend_addr;
469 struct sigframe *frame;
470 struct target_fregs_state *fpstate;
471 X86LegacyXSaveArea *fxstate;
472 unsigned total_size;
473 FPStateKind fpkind;
474
475 fpkind = get_fpstate_kind(env);
476 frame_addr = get_sigframe(ka, env, sizeof(struct sigframe), fpkind,
477 &fpstate_addr, &fxstate_addr, &fpend_addr);
478 trace_user_setup_frame(env, frame_addr);
479
480 total_size = fpend_addr - frame_addr;
481 frame = lock_user(VERIFY_WRITE, frame_addr, total_size, 0);
482 if (!frame) {
483 force_sigsegv(sig);
484 return;
485 }
486
487 fxstate = (void *)frame + (fxstate_addr - frame_addr);
488 #ifdef TARGET_X86_64
489 fpstate = NULL;
490 #else
491 fpstate = (void *)frame + (fpstate_addr - frame_addr);
492 #endif
493
494 setup_sigcontext(env, &frame->sc, set->sig[0], fpkind,
495 fpstate, fpstate_addr, fxstate, fxstate_addr, fpend_addr);
496
497 for (int i = 1; i < TARGET_NSIG_WORDS; i++) {
498 __put_user(set->sig[i], &frame->extramask[i - 1]);
499 }
500
501 /* Set up to return from userspace. If provided, use a stub
502 already in userspace. */
503 if (ka->sa_flags & TARGET_SA_RESTORER) {
504 __put_user(ka->sa_restorer, &frame->pretcode);
505 } else {
506 /* This is no longer used, but is retained for ABI compatibility. */
507 install_sigtramp(frame->retcode);
508 __put_user(default_sigreturn, &frame->pretcode);
509 }
510 unlock_user(frame, frame_addr, total_size);
511
512 /* Set up registers for signal handler */
513 env->regs[R_ESP] = frame_addr;
514 env->eip = ka->_sa_handler;
515
516 /* Store argument for both -mregparm=3 and standard. */
517 env->regs[R_EAX] = sig;
518 __put_user(sig, &frame->sig);
519 /* The kernel clears EDX and ECX even though there is only one arg. */
520 env->regs[R_EDX] = 0;
521 env->regs[R_ECX] = 0;
522
523 cpu_x86_load_seg(env, R_DS, __USER_DS);
524 cpu_x86_load_seg(env, R_ES, __USER_DS);
525 cpu_x86_load_seg(env, R_SS, __USER_DS);
526 cpu_x86_load_seg(env, R_CS, __USER_CS);
527 env->eflags &= ~TF_MASK;
528 }
529 #endif
530
531 /* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */
532 void setup_rt_frame(int sig, struct target_sigaction *ka,
533 target_siginfo_t *info,
534 target_sigset_t *set, CPUX86State *env)
535 {
536 abi_ptr frame_addr, fpstate_addr, fxstate_addr, fpend_addr;
537 struct rt_sigframe *frame;
538 X86LegacyXSaveArea *fxstate;
539 struct target_fregs_state *fpstate;
540 unsigned total_size;
541 FPStateKind fpkind;
542
543 fpkind = get_fpstate_kind(env);
544 frame_addr = get_sigframe(ka, env, sizeof(struct rt_sigframe), fpkind,
545 &fpstate_addr, &fxstate_addr, &fpend_addr);
546 trace_user_setup_rt_frame(env, frame_addr);
547
548 total_size = fpend_addr - frame_addr;
549 frame = lock_user(VERIFY_WRITE, frame_addr, total_size, 0);
550 if (!frame) {
551 goto give_sigsegv;
552 }
553
554 if (ka->sa_flags & TARGET_SA_SIGINFO) {
555 frame->info = *info;
556 }
557
558 /* Create the ucontext. */
559 __put_user(fpkind == FPSTATE_XSAVE, &frame->uc.tuc_flags);
560 __put_user(0, &frame->uc.tuc_link);
561 target_save_altstack(&frame->uc.tuc_stack, env);
562
563 fxstate = (void *)frame + (fxstate_addr - frame_addr);
564 #ifdef TARGET_X86_64
565 fpstate = NULL;
566 #else
567 fpstate = (void *)frame + (fpstate_addr - frame_addr);
568 #endif
569
570 setup_sigcontext(env, &frame->uc.tuc_mcontext, set->sig[0], fpkind,
571 fpstate, fpstate_addr, fxstate, fxstate_addr, fpend_addr);
572
573 for (int i = 0; i < TARGET_NSIG_WORDS; i++) {
574 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
575 }
576
577 /*
578 * Set up to return from userspace. If provided, use a stub
579 * already in userspace.
580 */
581 if (ka->sa_flags & TARGET_SA_RESTORER) {
582 __put_user(ka->sa_restorer, &frame->pretcode);
583 } else {
584 #ifdef TARGET_X86_64
585 /* For x86_64, SA_RESTORER is required ABI. */
586 goto give_sigsegv;
587 #else
588 /* This is no longer used, but is retained for ABI compatibility. */
589 install_rt_sigtramp(frame->retcode);
590 __put_user(default_rt_sigreturn, &frame->pretcode);
591 #endif
592 }
593
594 /* Set up registers for signal handler */
595 env->regs[R_ESP] = frame_addr;
596 env->eip = ka->_sa_handler;
597
598 #ifndef TARGET_X86_64
599 /* Store arguments for both -mregparm=3 and standard. */
600 env->regs[R_EAX] = sig;
601 __put_user(sig, &frame->sig);
602 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, info);
603 __put_user(env->regs[R_EDX], &frame->pinfo);
604 env->regs[R_ECX] = frame_addr + offsetof(struct rt_sigframe, uc);
605 __put_user(env->regs[R_ECX], &frame->puc);
606 #else
607 env->regs[R_EAX] = 0;
608 env->regs[R_EDI] = sig;
609 env->regs[R_ESI] = frame_addr + offsetof(struct rt_sigframe, info);
610 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, uc);
611 #endif
612 unlock_user(frame, frame_addr, total_size);
613
614 cpu_x86_load_seg(env, R_DS, __USER_DS);
615 cpu_x86_load_seg(env, R_ES, __USER_DS);
616 cpu_x86_load_seg(env, R_CS, __USER_CS);
617 cpu_x86_load_seg(env, R_SS, __USER_DS);
618 env->eflags &= ~TF_MASK;
619 return;
620
621 give_sigsegv:
622 force_sigsegv(sig);
623 }
624
625 /*
626 * Restore a signal frame.
627 */
628
629 static bool xrstor_sigcontext(CPUX86State *env, FPStateKind fpkind,
630 X86LegacyXSaveArea *fxstate,
631 abi_ptr fxstate_addr)
632 {
633 struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
634 uint32_t magic1, magic2;
635 uint32_t extended_size, xstate_size, min_size, max_size;
636 uint64_t xfeatures;
637 void *xstate;
638 bool ok;
639
640 switch (fpkind) {
641 case FPSTATE_XSAVE:
642 magic1 = tswap32(sw->magic1);
643 extended_size = tswap32(sw->extended_size);
644 xstate_size = tswap32(sw->xstate_size);
645 min_size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader);
646 max_size = xsave_area_size(env->xcr0, false);
647
648 /* Check for the first magic field and other error scenarios. */
649 if (magic1 != TARGET_FP_XSTATE_MAGIC1 ||
650 xstate_size < min_size ||
651 xstate_size > max_size ||
652 xstate_size > extended_size) {
653 break;
654 }
655
656 /*
657 * Restore the features indicated in the frame, masked by
658 * those currently enabled. Re-check the frame size.
659 * ??? It is not clear where the kernel does this, but it
660 * is not in check_xstate_in_sigframe, and so (probably)
661 * does not fall back to fxrstor.
662 */
663 xfeatures = tswap64(sw->xfeatures) & env->xcr0;
664 min_size = xsave_area_size(xfeatures, false);
665 if (xstate_size < min_size) {
666 return false;
667 }
668
669 /* Re-lock the entire xstate area, with the extensions and magic. */
670 xstate = lock_user(VERIFY_READ, fxstate_addr,
671 xstate_size + TARGET_FP_XSTATE_MAGIC2_SIZE, 1);
672 if (!xstate) {
673 return false;
674 }
675
676 /*
677 * Check for the presence of second magic word at the end of memory
678 * layout. This detects the case where the user just copied the legacy
679 * fpstate layout with out copying the extended state information
680 * in the memory layout.
681 */
682 magic2 = tswap32(*(uint32_t *)(xstate + xstate_size));
683 if (magic2 != TARGET_FP_XSTATE_MAGIC2) {
684 unlock_user(xstate, fxstate_addr, 0);
685 break;
686 }
687
688 ok = cpu_x86_xrstor(env, xstate, xstate_size, xfeatures);
689 unlock_user(xstate, fxstate_addr, 0);
690 return ok;
691
692 default:
693 break;
694 }
695
696 cpu_x86_fxrstor(env, fxstate, sizeof(*fxstate));
697 return true;
698 }
699
700 #ifndef TARGET_X86_64
701 static bool frstor_sigcontext(CPUX86State *env, FPStateKind fpkind,
702 struct target_fregs_state *fpstate,
703 abi_ptr fpstate_addr,
704 X86LegacyXSaveArea *fxstate,
705 abi_ptr fxstate_addr)
706 {
707 switch (fpkind) {
708 case FPSTATE_XSAVE:
709 if (!xrstor_sigcontext(env, fpkind, fxstate, fxstate_addr)) {
710 return false;
711 }
712 break;
713 case FPSTATE_FXSAVE:
714 cpu_x86_fxrstor(env, fxstate, sizeof(*fxstate));
715 break;
716 case FPSTATE_FSAVE:
717 break;
718 default:
719 g_assert_not_reached();
720 }
721
722 /*
723 * Copy the legacy state because the FP portion of the FX frame has
724 * to be ignored for histerical raisins. The kernel folds the two
725 * states together and then performs a single load; here we perform
726 * the merge within ENV by loading XSTATE/FXSTATE first, then
727 * overriding with the FSTATE afterward.
728 */
729 cpu_x86_frstor(env, fpstate, sizeof(*fpstate));
730 return true;
731 }
732 #endif
733
734 static bool restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc)
735 {
736 abi_ptr fpstate_addr;
737 unsigned tmpflags, math_size;
738 FPStateKind fpkind;
739 void *fpstate;
740 bool ok;
741
742 #ifndef TARGET_X86_64
743 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
744 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
745 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
746 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
747
748 env->regs[R_EDI] = tswapl(sc->edi);
749 env->regs[R_ESI] = tswapl(sc->esi);
750 env->regs[R_EBP] = tswapl(sc->ebp);
751 env->regs[R_ESP] = tswapl(sc->esp);
752 env->regs[R_EBX] = tswapl(sc->ebx);
753 env->regs[R_EDX] = tswapl(sc->edx);
754 env->regs[R_ECX] = tswapl(sc->ecx);
755 env->regs[R_EAX] = tswapl(sc->eax);
756
757 env->eip = tswapl(sc->eip);
758 #else
759 env->regs[8] = tswapl(sc->r8);
760 env->regs[9] = tswapl(sc->r9);
761 env->regs[10] = tswapl(sc->r10);
762 env->regs[11] = tswapl(sc->r11);
763 env->regs[12] = tswapl(sc->r12);
764 env->regs[13] = tswapl(sc->r13);
765 env->regs[14] = tswapl(sc->r14);
766 env->regs[15] = tswapl(sc->r15);
767
768 env->regs[R_EDI] = tswapl(sc->rdi);
769 env->regs[R_ESI] = tswapl(sc->rsi);
770 env->regs[R_EBP] = tswapl(sc->rbp);
771 env->regs[R_EBX] = tswapl(sc->rbx);
772 env->regs[R_EDX] = tswapl(sc->rdx);
773 env->regs[R_EAX] = tswapl(sc->rax);
774 env->regs[R_ECX] = tswapl(sc->rcx);
775 env->regs[R_ESP] = tswapl(sc->rsp);
776
777 env->eip = tswapl(sc->rip);
778 #endif
779
780 cpu_x86_load_seg(env, R_CS, lduw_le_p(&sc->cs) | 3);
781 cpu_x86_load_seg(env, R_SS, lduw_le_p(&sc->ss) | 3);
782
783 tmpflags = tswapl(sc->eflags);
784 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
785
786 fpstate_addr = tswapl(sc->fpstate);
787 if (fpstate_addr == 0) {
788 return true;
789 }
790
791 fpkind = get_fpstate_kind(env);
792 math_size = get_fpstate_size(env, fpkind);
793 #ifndef TARGET_X86_64
794 if (fpkind != FPSTATE_FSAVE) {
795 math_size += sizeof(struct target_fregs_state);
796 }
797 #endif
798 fpstate = lock_user(VERIFY_READ, fpstate_addr, math_size, 1);
799 if (!fpstate) {
800 return false;
801 }
802
803 #ifdef TARGET_X86_64
804 ok = xrstor_sigcontext(env, fpkind, fpstate, fpstate_addr);
805 #else
806 ok = frstor_sigcontext(env, fpkind, fpstate, fpstate_addr,
807 fpstate + sizeof(struct target_fregs_state),
808 fpstate_addr + sizeof(struct target_fregs_state));
809 #endif
810
811 unlock_user(fpstate, fpstate_addr, 0);
812 return ok;
813 }
814
815 /* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */
816 #ifndef TARGET_X86_64
817 long do_sigreturn(CPUX86State *env)
818 {
819 struct sigframe *frame;
820 abi_ulong frame_addr = env->regs[R_ESP] - 8;
821 target_sigset_t target_set;
822 sigset_t set;
823
824 trace_user_do_sigreturn(env, frame_addr);
825 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
826 force_sig(TARGET_SIGSEGV);
827 return -QEMU_ESIGRETURN;
828 }
829
830 /* Set blocked signals. */
831 __get_user(target_set.sig[0], &frame->sc.oldmask);
832 for (int i = 1; i < TARGET_NSIG_WORDS; i++) {
833 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
834 }
835 target_to_host_sigset_internal(&set, &target_set);
836 set_sigmask(&set);
837
838 /* Restore registers */
839 if (!restore_sigcontext(env, &frame->sc)) {
840 force_sig(TARGET_SIGSEGV);
841 }
842
843 unlock_user_struct(frame, frame_addr, 0);
844 return -QEMU_ESIGRETURN;
845 }
846 #endif
847
848 long do_rt_sigreturn(CPUX86State *env)
849 {
850 abi_ulong frame_addr;
851 struct rt_sigframe *frame;
852 sigset_t set;
853
854 frame_addr = env->regs[R_ESP] - sizeof(abi_ulong);
855 trace_user_do_rt_sigreturn(env, frame_addr);
856 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
857 goto badframe;
858 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
859 set_sigmask(&set);
860
861 if (!restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
862 goto badframe;
863 }
864
865 target_restore_altstack(&frame->uc.tuc_stack, env);
866
867 unlock_user_struct(frame, frame_addr, 0);
868 return -QEMU_ESIGRETURN;
869
870 badframe:
871 unlock_user_struct(frame, frame_addr, 0);
872 force_sig(TARGET_SIGSEGV);
873 return -QEMU_ESIGRETURN;
874 }
875
876 #ifndef TARGET_X86_64
877 void setup_sigtramp(abi_ulong sigtramp_page)
878 {
879 uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
880 assert(tramp != NULL);
881
882 default_sigreturn = sigtramp_page;
883 install_sigtramp(tramp);
884
885 default_rt_sigreturn = sigtramp_page + 8;
886 install_rt_sigtramp(tramp + 8);
887
888 unlock_user(tramp, sigtramp_page, 2 * 8);
889 }
890 #endif