make vfs & filesystems use failable copying
[minix3.git] / kernel / system / do_mcontext.c
blobe5d74490100366a28990546eed22ffa4f4d965d0
1 /* The kernel calls that are implemented in this file:
2 * m_type: SYS_SETMCONTEXT
3 * m_type: SYS_GETMCONTEXT
5 * The parameters for these kernel calls are:
6 * m1_i1: PR_ENDPT # proc endpoint doing call
7 * m1_p1: PR_MEM_PTR # pointer to mcontext structure
9 */
11 #include "kernel/system.h"
12 #include <string.h>
13 #include <assert.h>
14 #include <machine/mcontext.h>
16 #if USE_MCONTEXT
17 /*===========================================================================*
18 * do_getmcontext *
19 *===========================================================================*/
20 int do_getmcontext(struct proc * caller, message * m_ptr)
22 /* Retrieve machine context of a process */
24 register struct proc *rp;
25 int proc_nr, r;
26 mcontext_t mc;
28 if (! isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return(EINVAL);
29 if (iskerneln(proc_nr)) return(EPERM);
30 rp = proc_addr(proc_nr);
32 #if defined(__i386__)
33 if (!proc_used_fpu(rp))
34 return(OK); /* No state to copy */
35 #endif
37 /* Get the mcontext structure into our address space. */
38 if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL,
39 (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
40 return(r);
42 mc.mc_flags = 0;
43 #if defined(__i386__)
44 /* Copy FPU state */
45 if (proc_used_fpu(rp)) {
46 /* make sure that the FPU context is saved into proc structure first */
47 save_fpu(rp);
48 mc.mc_flags = (rp->p_misc_flags & MF_FPU_INITIALIZED) ? _MC_FPU_SAVED : 0;
49 assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
50 memcpy(&(mc.__fpregs.__fp_reg_set), rp->p_seg.fpu_state, FPU_XFP_SIZE);
52 #endif
55 /* Copy the mcontext structure to the user's address space. */
56 if ((r = data_copy(KERNEL, (vir_bytes) &mc, m_ptr->PR_ENDPT,
57 (vir_bytes) m_ptr->PR_CTX_PTR,
58 (phys_bytes) sizeof(mcontext_t))) != OK)
59 return(r);
61 return(OK);
65 /*===========================================================================*
66 * do_setmcontext *
67 *===========================================================================*/
68 int do_setmcontext(struct proc * caller, message * m_ptr)
70 /* Set machine context of a process */
72 register struct proc *rp;
73 int proc_nr, r;
74 mcontext_t mc;
76 if (!isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return(EINVAL);
77 rp = proc_addr(proc_nr);
79 /* Get the mcontext structure into our address space. */
80 if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL,
81 (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
82 return(r);
84 #if defined(__i386__)
85 /* Copy FPU state */
86 if (mc.mc_flags & _MC_FPU_SAVED) {
87 rp->p_misc_flags |= MF_FPU_INITIALIZED;
88 assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
89 memcpy(rp->p_seg.fpu_state, &(mc.__fpregs.__fp_reg_set), FPU_XFP_SIZE);
90 } else
91 rp->p_misc_flags &= ~MF_FPU_INITIALIZED;
92 /* force reloading FPU in either case */
93 release_fpu(rp);
94 #endif
96 return(OK);
99 #endif