xref: /openbmc/qemu/linux-user/i386/signal.c (revision feb58e3b)
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 {
299     struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
300 
301     cpu_x86_fxsave(env, fxstate, sizeof(*fxstate));
302     __put_user(0, &sw->magic1);
303 }
304 
305 static void xsave_sigcontext(CPUX86State *env,
306                              X86LegacyXSaveArea *fxstate,
307                              abi_ptr fpstate_addr,
308                              abi_ptr xstate_addr,
309                              abi_ptr fpend_addr)
310 {
311     struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
312     /*
313      * extended_size is the offset from fpstate_addr to right after
314      * the end of the extended save states.  On 32-bit that includes
315      * the legacy FSAVE area.
316      */
317     uint32_t extended_size = fpend_addr - fpstate_addr;
318     /* Recover xstate_size by removing magic2. */
319     uint32_t xstate_size = (fpend_addr - xstate_addr
320                             - TARGET_FP_XSTATE_MAGIC2_SIZE);
321     /* magic2 goes just after xstate. */
322     uint32_t *magic2 = (void *)fxstate + xstate_size;
323 
324     /* xstate_addr must be 64 byte aligned for xsave */
325     assert(!(xstate_addr & 0x3f));
326 
327     /* Zero the header, XSAVE *adds* features to an existing save state.  */
328     memset(fxstate + 1, 0, sizeof(X86XSaveHeader));
329     cpu_x86_xsave(env, fxstate, fpend_addr - xstate_addr, env->xcr0);
330 
331     __put_user(TARGET_FP_XSTATE_MAGIC1, &sw->magic1);
332     __put_user(extended_size, &sw->extended_size);
333     __put_user(env->xcr0, &sw->xfeatures);
334     __put_user(xstate_size, &sw->xstate_size);
335     __put_user(TARGET_FP_XSTATE_MAGIC2, magic2);
336 }
337 
338 static void setup_sigcontext(CPUX86State *env,
339                              struct target_sigcontext *sc,
340                              abi_ulong mask, FPStateKind fpkind,
341                              struct target_fregs_state *fpstate,
342                              abi_ptr fpstate_addr,
343                              X86LegacyXSaveArea *fxstate,
344                              abi_ptr fxstate_addr,
345                              abi_ptr fpend_addr)
346 {
347     CPUState *cs = env_cpu(env);
348 
349 #ifndef TARGET_X86_64
350     uint16_t magic;
351 
352     /* already locked in setup_frame() */
353     __put_user(env->segs[R_GS].selector, (uint32_t *)&sc->gs);
354     __put_user(env->segs[R_FS].selector, (uint32_t *)&sc->fs);
355     __put_user(env->segs[R_ES].selector, (uint32_t *)&sc->es);
356     __put_user(env->segs[R_DS].selector, (uint32_t *)&sc->ds);
357     __put_user(env->regs[R_EDI], &sc->edi);
358     __put_user(env->regs[R_ESI], &sc->esi);
359     __put_user(env->regs[R_EBP], &sc->ebp);
360     __put_user(env->regs[R_ESP], &sc->esp);
361     __put_user(env->regs[R_EBX], &sc->ebx);
362     __put_user(env->regs[R_EDX], &sc->edx);
363     __put_user(env->regs[R_ECX], &sc->ecx);
364     __put_user(env->regs[R_EAX], &sc->eax);
365     __put_user(cs->exception_index, &sc->trapno);
366     __put_user(env->error_code, &sc->err);
367     __put_user(env->eip, &sc->eip);
368     __put_user(env->segs[R_CS].selector, (uint32_t *)&sc->cs);
369     __put_user(env->eflags, &sc->eflags);
370     __put_user(env->regs[R_ESP], &sc->esp_at_signal);
371     __put_user(env->segs[R_SS].selector, (uint32_t *)&sc->ss);
372 
373     cpu_x86_fsave(env, fpstate, sizeof(*fpstate));
374     fpstate->status = fpstate->swd;
375     magic = (fpkind == FPSTATE_FSAVE ? 0 : 0xffff);
376     __put_user(magic, &fpstate->magic);
377 #else
378     __put_user(env->regs[R_EDI], &sc->rdi);
379     __put_user(env->regs[R_ESI], &sc->rsi);
380     __put_user(env->regs[R_EBP], &sc->rbp);
381     __put_user(env->regs[R_ESP], &sc->rsp);
382     __put_user(env->regs[R_EBX], &sc->rbx);
383     __put_user(env->regs[R_EDX], &sc->rdx);
384     __put_user(env->regs[R_ECX], &sc->rcx);
385     __put_user(env->regs[R_EAX], &sc->rax);
386 
387     __put_user(env->regs[8], &sc->r8);
388     __put_user(env->regs[9], &sc->r9);
389     __put_user(env->regs[10], &sc->r10);
390     __put_user(env->regs[11], &sc->r11);
391     __put_user(env->regs[12], &sc->r12);
392     __put_user(env->regs[13], &sc->r13);
393     __put_user(env->regs[14], &sc->r14);
394     __put_user(env->regs[15], &sc->r15);
395 
396     __put_user(cs->exception_index, &sc->trapno);
397     __put_user(env->error_code, &sc->err);
398     __put_user(env->eip, &sc->rip);
399 
400     __put_user(env->eflags, &sc->eflags);
401     __put_user(env->segs[R_CS].selector, &sc->cs);
402     __put_user((uint16_t)0, &sc->gs);
403     __put_user((uint16_t)0, &sc->fs);
404     __put_user(env->segs[R_SS].selector, &sc->ss);
405 #endif
406 
407     switch (fpkind) {
408     case FPSTATE_XSAVE:
409         xsave_sigcontext(env, fxstate, fpstate_addr, fxstate_addr, fpend_addr);
410         break;
411     case FPSTATE_FXSAVE:
412         fxsave_sigcontext(env, fxstate);
413         break;
414     default:
415         break;
416     }
417 
418     __put_user(fpstate_addr, &sc->fpstate);
419     /* non-iBCS2 extensions.. */
420     __put_user(mask, &sc->oldmask);
421     __put_user(env->cr[2], &sc->cr2);
422 }
423 
424 #ifndef TARGET_X86_64
425 static void install_sigtramp(void *tramp)
426 {
427     /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */
428     __put_user(0xb858, (uint16_t *)(tramp + 0));
429     __put_user(TARGET_NR_sigreturn, (int32_t *)(tramp + 2));
430     __put_user(0x80cd, (uint16_t *)(tramp + 6));
431 }
432 
433 static void install_rt_sigtramp(void *tramp)
434 {
435     /* This is movl $syscall,%eax ; int $0x80 */
436     __put_user(0xb8, (uint8_t *)(tramp + 0));
437     __put_user(TARGET_NR_rt_sigreturn, (int32_t *)(tramp + 1));
438     __put_user(0x80cd, (uint16_t *)(tramp + 5));
439 }
440 
441 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
442 void setup_frame(int sig, struct target_sigaction *ka,
443                  target_sigset_t *set, CPUX86State *env)
444 {
445     abi_ptr frame_addr, fpstate_addr, fxstate_addr, fpend_addr;
446     struct sigframe *frame;
447     struct target_fregs_state *fpstate;
448     X86LegacyXSaveArea *fxstate;
449     unsigned total_size;
450     FPStateKind fpkind;
451 
452     fpkind = get_fpstate_kind(env);
453     frame_addr = get_sigframe(ka, env, sizeof(struct sigframe), fpkind,
454                               &fpstate_addr, &fxstate_addr, &fpend_addr);
455     trace_user_setup_frame(env, frame_addr);
456 
457     total_size = fpend_addr - frame_addr;
458     frame = lock_user(VERIFY_WRITE, frame_addr, total_size, 0);
459     if (!frame) {
460         force_sigsegv(sig);
461         return;
462     }
463 
464     fxstate = (void *)frame + (fxstate_addr - frame_addr);
465 #ifdef TARGET_X86_64
466     fpstate = NULL;
467 #else
468     fpstate = (void *)frame + (fpstate_addr - frame_addr);
469 #endif
470 
471     setup_sigcontext(env, &frame->sc, set->sig[0], fpkind,
472                      fpstate, fpstate_addr, fxstate, fxstate_addr, fpend_addr);
473 
474     for (int i = 1; i < TARGET_NSIG_WORDS; i++) {
475         __put_user(set->sig[i], &frame->extramask[i - 1]);
476     }
477 
478     /* Set up to return from userspace.  If provided, use a stub
479        already in userspace.  */
480     if (ka->sa_flags & TARGET_SA_RESTORER) {
481         __put_user(ka->sa_restorer, &frame->pretcode);
482     } else {
483         /* This is no longer used, but is retained for ABI compatibility. */
484         install_sigtramp(frame->retcode);
485         __put_user(default_sigreturn, &frame->pretcode);
486     }
487     unlock_user(frame, frame_addr, total_size);
488 
489     /* Set up registers for signal handler */
490     env->regs[R_ESP] = frame_addr;
491     env->eip = ka->_sa_handler;
492 
493     /* Store argument for both -mregparm=3 and standard. */
494     env->regs[R_EAX] = sig;
495     __put_user(sig, &frame->sig);
496     /* The kernel clears EDX and ECX even though there is only one arg. */
497     env->regs[R_EDX] = 0;
498     env->regs[R_ECX] = 0;
499 
500     cpu_x86_load_seg(env, R_DS, __USER_DS);
501     cpu_x86_load_seg(env, R_ES, __USER_DS);
502     cpu_x86_load_seg(env, R_SS, __USER_DS);
503     cpu_x86_load_seg(env, R_CS, __USER_CS);
504     env->eflags &= ~TF_MASK;
505 }
506 #endif
507 
508 /* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */
509 void setup_rt_frame(int sig, struct target_sigaction *ka,
510                     target_siginfo_t *info,
511                     target_sigset_t *set, CPUX86State *env)
512 {
513     abi_ptr frame_addr, fpstate_addr, fxstate_addr, fpend_addr;
514     struct rt_sigframe *frame;
515     X86LegacyXSaveArea *fxstate;
516     struct target_fregs_state *fpstate;
517     unsigned total_size;
518     FPStateKind fpkind;
519 
520     fpkind = get_fpstate_kind(env);
521     frame_addr = get_sigframe(ka, env, sizeof(struct rt_sigframe), fpkind,
522                               &fpstate_addr, &fxstate_addr, &fpend_addr);
523     trace_user_setup_rt_frame(env, frame_addr);
524 
525     total_size = fpend_addr - frame_addr;
526     frame = lock_user(VERIFY_WRITE, frame_addr, total_size, 0);
527     if (!frame) {
528         goto give_sigsegv;
529     }
530 
531     if (ka->sa_flags & TARGET_SA_SIGINFO) {
532         frame->info = *info;
533     }
534 
535     /* Create the ucontext.  */
536     __put_user(fpkind == FPSTATE_XSAVE, &frame->uc.tuc_flags);
537     __put_user(0, &frame->uc.tuc_link);
538     target_save_altstack(&frame->uc.tuc_stack, env);
539 
540     fxstate = (void *)frame + (fxstate_addr - frame_addr);
541 #ifdef TARGET_X86_64
542     fpstate = NULL;
543 #else
544     fpstate = (void *)frame + (fpstate_addr - frame_addr);
545 #endif
546 
547     setup_sigcontext(env, &frame->uc.tuc_mcontext, set->sig[0], fpkind,
548                      fpstate, fpstate_addr, fxstate, fxstate_addr, fpend_addr);
549 
550     for (int i = 0; i < TARGET_NSIG_WORDS; i++) {
551         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
552     }
553 
554     /*
555      * Set up to return from userspace.  If provided, use a stub
556      * already in userspace.
557      */
558     if (ka->sa_flags & TARGET_SA_RESTORER) {
559         __put_user(ka->sa_restorer, &frame->pretcode);
560     } else {
561 #ifdef TARGET_X86_64
562         /* For x86_64, SA_RESTORER is required ABI.  */
563         goto give_sigsegv;
564 #else
565         /* This is no longer used, but is retained for ABI compatibility. */
566         install_rt_sigtramp(frame->retcode);
567         __put_user(default_rt_sigreturn, &frame->pretcode);
568 #endif
569     }
570 
571     /* Set up registers for signal handler */
572     env->regs[R_ESP] = frame_addr;
573     env->eip = ka->_sa_handler;
574 
575 #ifndef TARGET_X86_64
576     /* Store arguments for both -mregparm=3 and standard. */
577     env->regs[R_EAX] = sig;
578     __put_user(sig, &frame->sig);
579     env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, info);
580     __put_user(env->regs[R_EDX], &frame->pinfo);
581     env->regs[R_ECX] = frame_addr + offsetof(struct rt_sigframe, uc);
582     __put_user(env->regs[R_ECX], &frame->puc);
583 #else
584     env->regs[R_EAX] = 0;
585     env->regs[R_EDI] = sig;
586     env->regs[R_ESI] = frame_addr + offsetof(struct rt_sigframe, info);
587     env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, uc);
588 #endif
589     unlock_user(frame, frame_addr, total_size);
590 
591     cpu_x86_load_seg(env, R_DS, __USER_DS);
592     cpu_x86_load_seg(env, R_ES, __USER_DS);
593     cpu_x86_load_seg(env, R_CS, __USER_CS);
594     cpu_x86_load_seg(env, R_SS, __USER_DS);
595     env->eflags &= ~TF_MASK;
596     return;
597 
598 give_sigsegv:
599     force_sigsegv(sig);
600 }
601 
602 /*
603  * Restore a signal frame.
604  */
605 
606 static bool xrstor_sigcontext(CPUX86State *env, FPStateKind fpkind,
607                               X86LegacyXSaveArea *fxstate,
608                               abi_ptr fxstate_addr)
609 {
610     struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved;
611     uint32_t magic1, magic2;
612     uint32_t extended_size, xstate_size, min_size, max_size;
613     uint64_t xfeatures;
614     void *xstate;
615     bool ok;
616 
617     switch (fpkind) {
618     case FPSTATE_XSAVE:
619         magic1 = tswap32(sw->magic1);
620         extended_size = tswap32(sw->extended_size);
621         xstate_size = tswap32(sw->xstate_size);
622         min_size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader);
623         max_size = xsave_area_size(env->xcr0, false);
624 
625         /* Check for the first magic field and other error scenarios. */
626         if (magic1 != TARGET_FP_XSTATE_MAGIC1 ||
627             xstate_size < min_size ||
628             xstate_size > max_size ||
629             xstate_size > extended_size) {
630             break;
631         }
632 
633         /*
634          * Restore the features indicated in the frame, masked by
635          * those currently enabled.  Re-check the frame size.
636          * ??? It is not clear where the kernel does this, but it
637          * is not in check_xstate_in_sigframe, and so (probably)
638          * does not fall back to fxrstor.
639          */
640         xfeatures = tswap64(sw->xfeatures) & env->xcr0;
641         min_size = xsave_area_size(xfeatures, false);
642         if (xstate_size < min_size) {
643             return false;
644         }
645 
646         /* Re-lock the entire xstate area, with the extensions and magic. */
647         xstate = lock_user(VERIFY_READ, fxstate_addr,
648                            xstate_size + TARGET_FP_XSTATE_MAGIC2_SIZE, 1);
649         if (!xstate) {
650             return false;
651         }
652 
653         /*
654          * Check for the presence of second magic word at the end of memory
655          * layout. This detects the case where the user just copied the legacy
656          * fpstate layout with out copying the extended state information
657          * in the memory layout.
658          */
659         magic2 = tswap32(*(uint32_t *)(xstate + xstate_size));
660         if (magic2 != TARGET_FP_XSTATE_MAGIC2) {
661             unlock_user(xstate, fxstate_addr, 0);
662             break;
663         }
664 
665         ok = cpu_x86_xrstor(env, xstate, xstate_size, xfeatures);
666         unlock_user(xstate, fxstate_addr, 0);
667         return ok;
668 
669     default:
670         break;
671     }
672 
673     cpu_x86_fxrstor(env, fxstate, sizeof(*fxstate));
674     return true;
675 }
676 
677 #ifndef TARGET_X86_64
678 static bool frstor_sigcontext(CPUX86State *env, FPStateKind fpkind,
679                               struct target_fregs_state *fpstate,
680                               abi_ptr fpstate_addr,
681                               X86LegacyXSaveArea *fxstate,
682                               abi_ptr fxstate_addr)
683 {
684     switch (fpkind) {
685     case FPSTATE_XSAVE:
686         if (!xrstor_sigcontext(env, fpkind, fxstate, fxstate_addr)) {
687             return false;
688         }
689         break;
690     case FPSTATE_FXSAVE:
691         cpu_x86_fxrstor(env, fxstate, sizeof(*fxstate));
692         break;
693     case FPSTATE_FSAVE:
694         break;
695     default:
696         g_assert_not_reached();
697     }
698 
699     /*
700      * Copy the legacy state because the FP portion of the FX frame has
701      * to be ignored for histerical raisins.  The kernel folds the two
702      * states together and then performs a single load; here we perform
703      * the merge within ENV by loading XSTATE/FXSTATE first, then
704      * overriding with the FSTATE afterward.
705      */
706     cpu_x86_frstor(env, fpstate, sizeof(*fpstate));
707     return true;
708 }
709 #endif
710 
711 static bool restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc)
712 {
713     abi_ptr fpstate_addr;
714     unsigned tmpflags, math_size;
715     FPStateKind fpkind;
716     void *fpstate;
717     bool ok;
718 
719 #ifndef TARGET_X86_64
720     cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
721     cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
722     cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
723     cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
724 
725     env->regs[R_EDI] = tswapl(sc->edi);
726     env->regs[R_ESI] = tswapl(sc->esi);
727     env->regs[R_EBP] = tswapl(sc->ebp);
728     env->regs[R_ESP] = tswapl(sc->esp);
729     env->regs[R_EBX] = tswapl(sc->ebx);
730     env->regs[R_EDX] = tswapl(sc->edx);
731     env->regs[R_ECX] = tswapl(sc->ecx);
732     env->regs[R_EAX] = tswapl(sc->eax);
733 
734     env->eip = tswapl(sc->eip);
735 #else
736     env->regs[8] = tswapl(sc->r8);
737     env->regs[9] = tswapl(sc->r9);
738     env->regs[10] = tswapl(sc->r10);
739     env->regs[11] = tswapl(sc->r11);
740     env->regs[12] = tswapl(sc->r12);
741     env->regs[13] = tswapl(sc->r13);
742     env->regs[14] = tswapl(sc->r14);
743     env->regs[15] = tswapl(sc->r15);
744 
745     env->regs[R_EDI] = tswapl(sc->rdi);
746     env->regs[R_ESI] = tswapl(sc->rsi);
747     env->regs[R_EBP] = tswapl(sc->rbp);
748     env->regs[R_EBX] = tswapl(sc->rbx);
749     env->regs[R_EDX] = tswapl(sc->rdx);
750     env->regs[R_EAX] = tswapl(sc->rax);
751     env->regs[R_ECX] = tswapl(sc->rcx);
752     env->regs[R_ESP] = tswapl(sc->rsp);
753 
754     env->eip = tswapl(sc->rip);
755 #endif
756 
757     cpu_x86_load_seg(env, R_CS, lduw_le_p(&sc->cs) | 3);
758     cpu_x86_load_seg(env, R_SS, lduw_le_p(&sc->ss) | 3);
759 
760     tmpflags = tswapl(sc->eflags);
761     env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
762 
763     fpstate_addr = tswapl(sc->fpstate);
764     if (fpstate_addr == 0) {
765         return true;
766     }
767 
768     fpkind = get_fpstate_kind(env);
769     math_size = get_fpstate_size(env, fpkind);
770 #ifndef TARGET_X86_64
771     if (fpkind != FPSTATE_FSAVE) {
772         math_size += sizeof(struct target_fregs_state);
773     }
774 #endif
775     fpstate = lock_user(VERIFY_READ, fpstate_addr, math_size, 1);
776     if (!fpstate) {
777         return false;
778     }
779 
780 #ifdef TARGET_X86_64
781     ok = xrstor_sigcontext(env, fpkind, fpstate, fpstate_addr);
782 #else
783     ok = frstor_sigcontext(env, fpkind, fpstate, fpstate_addr,
784                            fpstate + sizeof(struct target_fregs_state),
785                            fpstate_addr + sizeof(struct target_fregs_state));
786 #endif
787 
788     unlock_user(fpstate, fpstate_addr, 0);
789     return ok;
790 }
791 
792 /* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */
793 #ifndef TARGET_X86_64
794 long do_sigreturn(CPUX86State *env)
795 {
796     struct sigframe *frame;
797     abi_ulong frame_addr = env->regs[R_ESP] - 8;
798     target_sigset_t target_set;
799     sigset_t set;
800 
801     trace_user_do_sigreturn(env, frame_addr);
802     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
803         force_sig(TARGET_SIGSEGV);
804         return -QEMU_ESIGRETURN;
805     }
806 
807     /* Set blocked signals. */
808     __get_user(target_set.sig[0], &frame->sc.oldmask);
809     for (int i = 1; i < TARGET_NSIG_WORDS; i++) {
810         __get_user(target_set.sig[i], &frame->extramask[i - 1]);
811     }
812     target_to_host_sigset_internal(&set, &target_set);
813     set_sigmask(&set);
814 
815     /* Restore registers */
816     if (!restore_sigcontext(env, &frame->sc)) {
817         force_sig(TARGET_SIGSEGV);
818     }
819 
820     unlock_user_struct(frame, frame_addr, 0);
821     return -QEMU_ESIGRETURN;
822 }
823 #endif
824 
825 long do_rt_sigreturn(CPUX86State *env)
826 {
827     abi_ulong frame_addr;
828     struct rt_sigframe *frame;
829     sigset_t set;
830 
831     frame_addr = env->regs[R_ESP] - sizeof(abi_ulong);
832     trace_user_do_rt_sigreturn(env, frame_addr);
833     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
834         goto badframe;
835     target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
836     set_sigmask(&set);
837 
838     if (!restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
839         goto badframe;
840     }
841 
842     target_restore_altstack(&frame->uc.tuc_stack, env);
843 
844     unlock_user_struct(frame, frame_addr, 0);
845     return -QEMU_ESIGRETURN;
846 
847 badframe:
848     unlock_user_struct(frame, frame_addr, 0);
849     force_sig(TARGET_SIGSEGV);
850     return -QEMU_ESIGRETURN;
851 }
852 
853 #ifndef TARGET_X86_64
854 void setup_sigtramp(abi_ulong sigtramp_page)
855 {
856     uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
857     assert(tramp != NULL);
858 
859     default_sigreturn = sigtramp_page;
860     install_sigtramp(tramp);
861 
862     default_rt_sigreturn = sigtramp_page + 8;
863     install_rt_sigtramp(tramp + 8);
864 
865     unlock_user(tramp, sigtramp_page, 2 * 8);
866 }
867 #endif
868