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