xref: /openbmc/qemu/linux-user/sparc/signal.c (revision 11670e849227890e7ab3f1413bae28bf6a0f6707)
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 "signal-common.h"
22 #include "linux-user/trace.h"
23 
24 /* A Sparc register window */
25 struct target_reg_window {
26     abi_ulong locals[8];
27     abi_ulong ins[8];
28 };
29 
30 /* A Sparc stack frame. */
31 struct target_stackf {
32     /*
33      * Since qemu does not reference fp or callers_pc directly,
34      * it's simpler to treat fp and callers_pc as elements of ins[],
35      * and then bundle locals[] and ins[] into reg_window.
36      */
37     struct target_reg_window win;
38     /*
39      * Similarly, bundle structptr and xxargs into xargs[].
40      * This portion of the struct is part of the function call abi,
41      * and belongs to the callee for spilling argument registers.
42      */
43     abi_ulong xargs[8];
44 };
45 
46 struct target_siginfo_fpu {
47 #ifdef TARGET_SPARC64
48     uint64_t si_double_regs[32];
49     uint64_t si_fsr;
50     uint64_t si_gsr;
51     uint64_t si_fprs;
52 #else
53     /* It is more convenient for qemu to move doubles, not singles. */
54     uint64_t si_double_regs[16];
55     uint32_t si_fsr;
56     uint32_t si_fpqdepth;
57     struct {
58         uint32_t insn_addr;
59         uint32_t insn;
60     } si_fpqueue [16];
61 #endif
62 };
63 
64 struct target_signal_frame {
65     struct target_stackf ss;
66     struct target_pt_regs regs;
67     uint32_t si_mask;
68     abi_ulong fpu_save;
69     uint32_t insns[2] QEMU_ALIGNED(8);
70     abi_ulong extramask[TARGET_NSIG_WORDS - 1];
71     abi_ulong extra_size; /* Should be 0 */
72     abi_ulong rwin_save;
73 };
74 
75 static abi_ulong get_sigframe(struct target_sigaction *sa,
76                               CPUSPARCState *env,
77                               size_t framesize)
78 {
79     abi_ulong sp = get_sp_from_cpustate(env);
80 
81     /*
82      * If we are on the alternate signal stack and would overflow it, don't.
83      * Return an always-bogus address instead so we will die with SIGSEGV.
84      */
85     if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) {
86         return -1;
87     }
88 
89     /* This is the X/Open sanctioned signal stack switching.  */
90     sp = target_sigsp(sp, sa) - framesize;
91 
92     /*
93      * Always align the stack frame.  This handles two cases.  First,
94      * sigaltstack need not be mindful of platform specific stack
95      * alignment.  Second, if we took this signal because the stack
96      * is not aligned properly, we'd like to take the signal cleanly
97      * and report that.
98      */
99     sp &= ~15UL;
100 
101     return sp;
102 }
103 
104 static void save_pt_regs(struct target_pt_regs *regs, CPUSPARCState *env)
105 {
106     int i;
107 
108 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
109     __put_user(sparc64_tstate(env), &regs->tstate);
110     /* TODO: magic should contain PT_REG_MAGIC + %tt. */
111     __put_user(0, &regs->magic);
112 #else
113     __put_user(cpu_get_psr(env), &regs->psr);
114 #endif
115 
116     __put_user(env->pc, &regs->pc);
117     __put_user(env->npc, &regs->npc);
118     __put_user(env->y, &regs->y);
119 
120     for (i = 0; i < 8; i++) {
121         __put_user(env->gregs[i], &regs->u_regs[i]);
122     }
123     for (i = 0; i < 8; i++) {
124         __put_user(env->regwptr[WREG_O0 + i], &regs->u_regs[i + 8]);
125     }
126 }
127 
128 static void restore_pt_regs(struct target_pt_regs *regs, CPUSPARCState *env)
129 {
130     int i;
131 
132 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
133     /* User can only change condition codes and %asi in %tstate. */
134     uint64_t tstate;
135     __get_user(tstate, &regs->tstate);
136     cpu_put_ccr(env, tstate >> 32);
137     env->asi = extract64(tstate, 24, 8);
138 #else
139     /*
140      * User can only change condition codes and FPU enabling in %psr.
141      * But don't bother with FPU enabling, since a real kernel would
142      * just re-enable the FPU upon the next fpu trap.
143      */
144     uint32_t psr;
145     __get_user(psr, &regs->psr);
146     env->psr = (psr & PSR_ICC) | (env->psr & ~PSR_ICC);
147 #endif
148 
149     /* Note that pc and npc are handled in the caller. */
150 
151     __get_user(env->y, &regs->y);
152 
153     for (i = 0; i < 8; i++) {
154         __get_user(env->gregs[i], &regs->u_regs[i]);
155     }
156     for (i = 0; i < 8; i++) {
157         __get_user(env->regwptr[WREG_O0 + i], &regs->u_regs[i + 8]);
158     }
159 }
160 
161 static void save_reg_win(struct target_reg_window *win, CPUSPARCState *env)
162 {
163     int i;
164 
165     for (i = 0; i < 8; i++) {
166         __put_user(env->regwptr[i + WREG_L0], &win->locals[i]);
167     }
168     for (i = 0; i < 8; i++) {
169         __put_user(env->regwptr[i + WREG_I0], &win->ins[i]);
170     }
171 }
172 
173 static void save_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
174 {
175     int i;
176 
177 #ifdef TARGET_SPARC64
178     for (i = 0; i < 32; ++i) {
179         __put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
180     }
181     __put_user(env->fsr, &fpu->si_fsr);
182     __put_user(env->gsr, &fpu->si_gsr);
183     __put_user(env->fprs, &fpu->si_fprs);
184 #else
185     for (i = 0; i < 16; ++i) {
186         __put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
187     }
188     __put_user(env->fsr, &fpu->si_fsr);
189     __put_user(0, &fpu->si_fpqdepth);
190 #endif
191 }
192 
193 static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
194 {
195     int i;
196 
197 #ifdef TARGET_SPARC64
198     uint64_t fprs;
199     __get_user(fprs, &fpu->si_fprs);
200 
201     /* In case the user mucks about with FPRS, restore as directed. */
202     if (fprs & FPRS_DL) {
203         for (i = 0; i < 16; ++i) {
204             __get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
205         }
206     }
207     if (fprs & FPRS_DU) {
208         for (i = 16; i < 32; ++i) {
209             __get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
210         }
211     }
212     __get_user(env->fsr, &fpu->si_fsr);
213     __get_user(env->gsr, &fpu->si_gsr);
214     env->fprs |= fprs;
215 #else
216     for (i = 0; i < 16; ++i) {
217         __get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
218     }
219     __get_user(env->fsr, &fpu->si_fsr);
220 #endif
221 }
222 
223 void setup_frame(int sig, struct target_sigaction *ka,
224                  target_sigset_t *set, CPUSPARCState *env)
225 {
226     abi_ulong sf_addr;
227     struct target_signal_frame *sf;
228     size_t sf_size = sizeof(*sf) + sizeof(struct target_siginfo_fpu);
229     int i;
230 
231     sf_addr = get_sigframe(ka, env, sf_size);
232     trace_user_setup_frame(env, sf_addr);
233 
234     sf = lock_user(VERIFY_WRITE, sf_addr, sf_size, 0);
235     if (!sf) {
236         force_sigsegv(sig);
237         return;
238     }
239 
240     /* 2. Save the current process state */
241     save_pt_regs(&sf->regs, env);
242     __put_user(0, &sf->extra_size);
243 
244     save_fpu((struct target_siginfo_fpu *)(sf + 1), env);
245     __put_user(sf_addr + sizeof(*sf), &sf->fpu_save);
246 
247     __put_user(0, &sf->rwin_save);  /* TODO: save_rwin_state */
248 
249     __put_user(set->sig[0], &sf->si_mask);
250     for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
251         __put_user(set->sig[i + 1], &sf->extramask[i]);
252     }
253 
254     save_reg_win(&sf->ss.win, env);
255 
256     /* 3. signal handler back-trampoline and parameters */
257     env->regwptr[WREG_SP] = sf_addr;
258     env->regwptr[WREG_O0] = sig;
259     env->regwptr[WREG_O1] = sf_addr +
260             offsetof(struct target_signal_frame, regs);
261     env->regwptr[WREG_O2] = sf_addr +
262             offsetof(struct target_signal_frame, regs);
263 
264     /* 4. signal handler */
265     env->pc = ka->_sa_handler;
266     env->npc = env->pc + 4;
267 
268     /* 5. return to kernel instructions */
269     if (ka->ka_restorer) {
270         env->regwptr[WREG_O7] = ka->ka_restorer;
271     } else {
272         env->regwptr[WREG_O7] = sf_addr +
273                 offsetof(struct target_signal_frame, insns) - 2 * 4;
274 
275         /* mov __NR_sigreturn, %g1 */
276         __put_user(0x821020d8u, &sf->insns[0]);
277         /* t 0x10 */
278         __put_user(0x91d02010u, &sf->insns[1]);
279     }
280     unlock_user(sf, sf_addr, sf_size);
281 }
282 
283 void setup_rt_frame(int sig, struct target_sigaction *ka,
284                     target_siginfo_t *info,
285                     target_sigset_t *set, CPUSPARCState *env)
286 {
287     qemu_log_mask(LOG_UNIMP, "setup_rt_frame: not implemented\n");
288 }
289 
290 long do_sigreturn(CPUSPARCState *env)
291 {
292     abi_ulong sf_addr;
293     struct target_signal_frame *sf = NULL;
294     abi_ulong pc, npc, ptr;
295     target_sigset_t set;
296     sigset_t host_set;
297     int i;
298 
299     sf_addr = env->regwptr[WREG_SP];
300     trace_user_do_sigreturn(env, sf_addr);
301 
302     /* 1. Make sure we are not getting garbage from the user */
303     if ((sf_addr & 15) || !lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
304         goto segv_and_exit;
305     }
306 
307     /* Make sure stack pointer is aligned.  */
308     __get_user(ptr, &sf->regs.u_regs[14]);
309     if (ptr & 7) {
310         goto segv_and_exit;
311     }
312 
313     /* Make sure instruction pointers are aligned.  */
314     __get_user(pc, &sf->regs.pc);
315     __get_user(npc, &sf->regs.npc);
316     if ((pc | npc) & 3) {
317         goto segv_and_exit;
318     }
319 
320     /* 2. Restore the state */
321     restore_pt_regs(&sf->regs, env);
322     env->pc = pc;
323     env->npc = npc;
324 
325     __get_user(ptr, &sf->fpu_save);
326     if (ptr) {
327         struct target_siginfo_fpu *fpu;
328         if ((ptr & 3) || !lock_user_struct(VERIFY_READ, fpu, ptr, 1)) {
329             goto segv_and_exit;
330         }
331         restore_fpu(fpu, env);
332         unlock_user_struct(fpu, ptr, 0);
333     }
334 
335     __get_user(ptr, &sf->rwin_save);
336     if (ptr) {
337         goto segv_and_exit;  /* TODO: restore_rwin */
338     }
339 
340     __get_user(set.sig[0], &sf->si_mask);
341     for (i = 1; i < TARGET_NSIG_WORDS; i++) {
342         __get_user(set.sig[i], &sf->extramask[i - 1]);
343     }
344 
345     target_to_host_sigset_internal(&host_set, &set);
346     set_sigmask(&host_set);
347 
348     unlock_user_struct(sf, sf_addr, 0);
349     return -TARGET_QEMU_ESIGRETURN;
350 
351  segv_and_exit:
352     unlock_user_struct(sf, sf_addr, 0);
353     force_sig(TARGET_SIGSEGV);
354     return -TARGET_QEMU_ESIGRETURN;
355 }
356 
357 long do_rt_sigreturn(CPUSPARCState *env)
358 {
359     trace_user_do_rt_sigreturn(env, 0);
360     qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
361     return -TARGET_ENOSYS;
362 }
363 
364 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
365 #define SPARC_MC_TSTATE 0
366 #define SPARC_MC_PC 1
367 #define SPARC_MC_NPC 2
368 #define SPARC_MC_Y 3
369 #define SPARC_MC_G1 4
370 #define SPARC_MC_G2 5
371 #define SPARC_MC_G3 6
372 #define SPARC_MC_G4 7
373 #define SPARC_MC_G5 8
374 #define SPARC_MC_G6 9
375 #define SPARC_MC_G7 10
376 #define SPARC_MC_O0 11
377 #define SPARC_MC_O1 12
378 #define SPARC_MC_O2 13
379 #define SPARC_MC_O3 14
380 #define SPARC_MC_O4 15
381 #define SPARC_MC_O5 16
382 #define SPARC_MC_O6 17
383 #define SPARC_MC_O7 18
384 #define SPARC_MC_NGREG 19
385 
386 typedef abi_ulong target_mc_greg_t;
387 typedef target_mc_greg_t target_mc_gregset_t[SPARC_MC_NGREG];
388 
389 struct target_mc_fq {
390     abi_ulong mcfq_addr;
391     uint32_t mcfq_insn;
392 };
393 
394 /*
395  * Note the manual 16-alignment; the kernel gets this because it
396  * includes a "long double qregs[16]" in the mcpu_fregs union,
397  * which we can't do.
398  */
399 struct target_mc_fpu {
400     union {
401         uint32_t sregs[32];
402         uint64_t dregs[32];
403         //uint128_t qregs[16];
404     } mcfpu_fregs;
405     abi_ulong mcfpu_fsr;
406     abi_ulong mcfpu_fprs;
407     abi_ulong mcfpu_gsr;
408     abi_ulong mcfpu_fq;
409     unsigned char mcfpu_qcnt;
410     unsigned char mcfpu_qentsz;
411     unsigned char mcfpu_enab;
412 } __attribute__((aligned(16)));
413 typedef struct target_mc_fpu target_mc_fpu_t;
414 
415 typedef struct {
416     target_mc_gregset_t mc_gregs;
417     target_mc_greg_t mc_fp;
418     target_mc_greg_t mc_i7;
419     target_mc_fpu_t mc_fpregs;
420 } target_mcontext_t;
421 
422 struct target_ucontext {
423     abi_ulong tuc_link;
424     abi_ulong tuc_flags;
425     target_sigset_t tuc_sigmask;
426     target_mcontext_t tuc_mcontext;
427 };
428 
429 /* {set, get}context() needed for 64-bit SparcLinux userland. */
430 void sparc64_set_context(CPUSPARCState *env)
431 {
432     abi_ulong ucp_addr;
433     struct target_ucontext *ucp;
434     target_mc_gregset_t *grp;
435     target_mc_fpu_t *fpup;
436     abi_ulong pc, npc, tstate;
437     unsigned int i;
438     unsigned char fenab;
439 
440     ucp_addr = env->regwptr[WREG_O0];
441     if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
442         goto do_sigsegv;
443     }
444     grp  = &ucp->tuc_mcontext.mc_gregs;
445     __get_user(pc, &((*grp)[SPARC_MC_PC]));
446     __get_user(npc, &((*grp)[SPARC_MC_NPC]));
447     if ((pc | npc) & 3) {
448         goto do_sigsegv;
449     }
450     if (env->regwptr[WREG_O1]) {
451         target_sigset_t target_set;
452         sigset_t set;
453 
454         if (TARGET_NSIG_WORDS == 1) {
455             __get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]);
456         } else {
457             abi_ulong *src, *dst;
458             src = ucp->tuc_sigmask.sig;
459             dst = target_set.sig;
460             for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
461                 __get_user(*dst, src);
462             }
463         }
464         target_to_host_sigset_internal(&set, &target_set);
465         set_sigmask(&set);
466     }
467     env->pc = pc;
468     env->npc = npc;
469     __get_user(env->y, &((*grp)[SPARC_MC_Y]));
470     __get_user(tstate, &((*grp)[SPARC_MC_TSTATE]));
471     /* Honour TSTATE_ASI, TSTATE_ICC and TSTATE_XCC only */
472     env->asi = (tstate >> 24) & 0xff;
473     cpu_put_ccr(env, (tstate >> 32) & 0xff);
474     __get_user(env->gregs[1], (&(*grp)[SPARC_MC_G1]));
475     __get_user(env->gregs[2], (&(*grp)[SPARC_MC_G2]));
476     __get_user(env->gregs[3], (&(*grp)[SPARC_MC_G3]));
477     __get_user(env->gregs[4], (&(*grp)[SPARC_MC_G4]));
478     __get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
479     __get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
480     /* Skip g7 as that's the thread register in userspace */
481 
482     /*
483      * Note that unlike the kernel, we didn't need to mess with the
484      * guest register window state to save it into a pt_regs to run
485      * the kernel. So for us the guest's O regs are still in WREG_O*
486      * (unlike the kernel which has put them in UREG_I* in a pt_regs)
487      * and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
488      * need to be written back to userspace memory.
489      */
490     __get_user(env->regwptr[WREG_O0], (&(*grp)[SPARC_MC_O0]));
491     __get_user(env->regwptr[WREG_O1], (&(*grp)[SPARC_MC_O1]));
492     __get_user(env->regwptr[WREG_O2], (&(*grp)[SPARC_MC_O2]));
493     __get_user(env->regwptr[WREG_O3], (&(*grp)[SPARC_MC_O3]));
494     __get_user(env->regwptr[WREG_O4], (&(*grp)[SPARC_MC_O4]));
495     __get_user(env->regwptr[WREG_O5], (&(*grp)[SPARC_MC_O5]));
496     __get_user(env->regwptr[WREG_O6], (&(*grp)[SPARC_MC_O6]));
497     __get_user(env->regwptr[WREG_O7], (&(*grp)[SPARC_MC_O7]));
498 
499     __get_user(env->regwptr[WREG_FP], &(ucp->tuc_mcontext.mc_fp));
500     __get_user(env->regwptr[WREG_I7], &(ucp->tuc_mcontext.mc_i7));
501 
502     fpup = &ucp->tuc_mcontext.mc_fpregs;
503 
504     __get_user(fenab, &(fpup->mcfpu_enab));
505     if (fenab) {
506         abi_ulong fprs;
507 
508         /*
509          * We use the FPRS from the guest only in deciding whether
510          * to restore the upper, lower, or both banks of the FPU regs.
511          * The kernel here writes the FPU register data into the
512          * process's current_thread_info state and unconditionally
513          * clears FPRS and TSTATE_PEF: this disables the FPU so that the
514          * next FPU-disabled trap will copy the data out of
515          * current_thread_info and into the real FPU registers.
516          * QEMU doesn't need to handle lazy-FPU-state-restoring like that,
517          * so we always load the data directly into the FPU registers
518          * and leave FPRS and TSTATE_PEF alone (so the FPU stays enabled).
519          * Note that because we (and the kernel) always write zeroes for
520          * the fenab and fprs in sparc64_get_context() none of this code
521          * will execute unless the guest manually constructed or changed
522          * the context structure.
523          */
524         __get_user(fprs, &(fpup->mcfpu_fprs));
525         if (fprs & FPRS_DL) {
526             for (i = 0; i < 16; i++) {
527                 __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
528             }
529         }
530         if (fprs & FPRS_DU) {
531             for (i = 16; i < 32; i++) {
532                 __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
533             }
534         }
535         __get_user(env->fsr, &(fpup->mcfpu_fsr));
536         __get_user(env->gsr, &(fpup->mcfpu_gsr));
537     }
538     unlock_user_struct(ucp, ucp_addr, 0);
539     return;
540 do_sigsegv:
541     unlock_user_struct(ucp, ucp_addr, 0);
542     force_sig(TARGET_SIGSEGV);
543 }
544 
545 void sparc64_get_context(CPUSPARCState *env)
546 {
547     abi_ulong ucp_addr;
548     struct target_ucontext *ucp;
549     target_mc_gregset_t *grp;
550     target_mcontext_t *mcp;
551     int err;
552     unsigned int i;
553     target_sigset_t target_set;
554     sigset_t set;
555 
556     ucp_addr = env->regwptr[WREG_O0];
557     if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
558         goto do_sigsegv;
559     }
560 
561     memset(ucp, 0, sizeof(*ucp));
562 
563     mcp = &ucp->tuc_mcontext;
564     grp = &mcp->mc_gregs;
565 
566     /* Skip over the trap instruction, first. */
567     env->pc = env->npc;
568     env->npc += 4;
569 
570     /* If we're only reading the signal mask then do_sigprocmask()
571      * is guaranteed not to fail, which is important because we don't
572      * have any way to signal a failure or restart this operation since
573      * this is not a normal syscall.
574      */
575     err = do_sigprocmask(0, NULL, &set);
576     assert(err == 0);
577     host_to_target_sigset_internal(&target_set, &set);
578     if (TARGET_NSIG_WORDS == 1) {
579         __put_user(target_set.sig[0],
580                    (abi_ulong *)&ucp->tuc_sigmask);
581     } else {
582         abi_ulong *src, *dst;
583         src = target_set.sig;
584         dst = ucp->tuc_sigmask.sig;
585         for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
586             __put_user(*src, dst);
587         }
588     }
589 
590     __put_user(sparc64_tstate(env), &((*grp)[SPARC_MC_TSTATE]));
591     __put_user(env->pc, &((*grp)[SPARC_MC_PC]));
592     __put_user(env->npc, &((*grp)[SPARC_MC_NPC]));
593     __put_user(env->y, &((*grp)[SPARC_MC_Y]));
594     __put_user(env->gregs[1], &((*grp)[SPARC_MC_G1]));
595     __put_user(env->gregs[2], &((*grp)[SPARC_MC_G2]));
596     __put_user(env->gregs[3], &((*grp)[SPARC_MC_G3]));
597     __put_user(env->gregs[4], &((*grp)[SPARC_MC_G4]));
598     __put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
599     __put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
600     __put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
601 
602     /*
603      * Note that unlike the kernel, we didn't need to mess with the
604      * guest register window state to save it into a pt_regs to run
605      * the kernel. So for us the guest's O regs are still in WREG_O*
606      * (unlike the kernel which has put them in UREG_I* in a pt_regs)
607      * and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
608      * need to be fished out of userspace memory.
609      */
610     __put_user(env->regwptr[WREG_O0], &((*grp)[SPARC_MC_O0]));
611     __put_user(env->regwptr[WREG_O1], &((*grp)[SPARC_MC_O1]));
612     __put_user(env->regwptr[WREG_O2], &((*grp)[SPARC_MC_O2]));
613     __put_user(env->regwptr[WREG_O3], &((*grp)[SPARC_MC_O3]));
614     __put_user(env->regwptr[WREG_O4], &((*grp)[SPARC_MC_O4]));
615     __put_user(env->regwptr[WREG_O5], &((*grp)[SPARC_MC_O5]));
616     __put_user(env->regwptr[WREG_O6], &((*grp)[SPARC_MC_O6]));
617     __put_user(env->regwptr[WREG_O7], &((*grp)[SPARC_MC_O7]));
618 
619     __put_user(env->regwptr[WREG_FP], &(mcp->mc_fp));
620     __put_user(env->regwptr[WREG_I7], &(mcp->mc_i7));
621 
622     /*
623      * We don't write out the FPU state. This matches the kernel's
624      * implementation (which has the code for doing this but
625      * hidden behind an "if (fenab)" where fenab is always 0).
626      */
627 
628     unlock_user_struct(ucp, ucp_addr, 1);
629     return;
630 do_sigsegv:
631     unlock_user_struct(ucp, ucp_addr, 1);
632     force_sig(TARGET_SIGSEGV);
633 }
634 #endif
635