1 /* The kernel call that is implemented in this file:
2 * m_type: SYS_SIGRETURN
4 * The parameters for this kernel call are:
5 * m_sigcalls.endp # process returning from handler
6 * m_sigcalls.sigctx # pointer to sigcontext structure
10 #include "kernel/system.h"
12 #include <machine/cpu.h>
16 /*===========================================================================*
18 *===========================================================================*/
19 int do_sigreturn(struct proc
* caller
, message
* m_ptr
)
21 /* POSIX style signals require sys_sigreturn to put things in order before
22 * the signalled process can resume execution
25 register struct proc
*rp
;
28 if (!isokendpt(m_ptr
->m_sigcalls
.endpt
, &proc_nr
)) return EINVAL
;
29 if (iskerneln(proc_nr
)) return EPERM
;
30 rp
= proc_addr(proc_nr
);
32 /* Copy in the sigcontext structure. */
33 if ((r
= data_copy(m_ptr
->m_sigcalls
.endpt
,
34 (vir_bytes
)m_ptr
->m_sigcalls
.sigctx
, KERNEL
,
35 (vir_bytes
)&sc
, sizeof(struct sigcontext
))) != OK
)
39 /* Restore user bits of psw from sc, maintain system bits from proc. */
40 sc
.sc_eflags
= (sc
.sc_eflags
& X86_FLAGS_USER
) |
41 (rp
->p_reg
.psw
& ~X86_FLAGS_USER
);
45 /* Write back registers we allow to be restored, i.e.
46 * not the segment ones.
48 rp
->p_reg
.di
= sc
.sc_edi
;
49 rp
->p_reg
.si
= sc
.sc_esi
;
50 rp
->p_reg
.fp
= sc
.sc_ebp
;
51 rp
->p_reg
.bx
= sc
.sc_ebx
;
52 rp
->p_reg
.dx
= sc
.sc_edx
;
53 rp
->p_reg
.cx
= sc
.sc_ecx
;
54 rp
->p_reg
.retreg
= sc
.sc_eax
;
55 rp
->p_reg
.pc
= sc
.sc_eip
;
56 rp
->p_reg
.psw
= sc
.sc_eflags
;
57 rp
->p_reg
.sp
= sc
.sc_esp
;
61 rp
->p_reg
.psr
= sc
.sc_spsr
;
62 rp
->p_reg
.retreg
= sc
.sc_r0
;
63 rp
->p_reg
.r1
= sc
.sc_r1
;
64 rp
->p_reg
.r2
= sc
.sc_r2
;
65 rp
->p_reg
.r3
= sc
.sc_r3
;
66 rp
->p_reg
.r4
= sc
.sc_r4
;
67 rp
->p_reg
.r5
= sc
.sc_r5
;
68 rp
->p_reg
.r6
= sc
.sc_r6
;
69 rp
->p_reg
.r7
= sc
.sc_r7
;
70 rp
->p_reg
.r8
= sc
.sc_r8
;
71 rp
->p_reg
.r9
= sc
.sc_r9
;
72 rp
->p_reg
.r10
= sc
.sc_r10
;
73 rp
->p_reg
.fp
= sc
.sc_r11
;
74 rp
->p_reg
.r12
= sc
.sc_r12
;
75 rp
->p_reg
.sp
= sc
.sc_usr_sp
;
76 rp
->p_reg
.lr
= sc
.sc_usr_lr
;
77 rp
->p_reg
.pc
= sc
.sc_pc
;
80 /* Restore the registers. */
81 arch_proc_setcontext(rp
, &rp
->p_reg
, 1, sc
.trap_style
);
83 if(sc
.sc_magic
!= SC_MAGIC
) { printf("kernel sigreturn: corrupt signal context\n"); }
86 if (sc
.sc_flags
& MF_FPU_INITIALIZED
)
88 memcpy(rp
->p_seg
.fpu_state
, &sc
.sc_fpu_state
, FPU_XFP_SIZE
);
89 rp
->p_misc_flags
|= MF_FPU_INITIALIZED
; /* Restore math usage flag. */
90 /* force reloading FPU */
97 #endif /* USE_SIGRETURN */