1 /* The kernel call implemented in this file:
4 * The parameters for this kernel call are:
5 * m2_i1: SYS_UPD_SRC_ENDPT (source process endpoint)
6 * m2_i2: SYS_UPD_DST_ENDPT (destination process endpoint)
9 #include "kernel/system.h"
10 #include "kernel/ipc.h"
18 #define proc_is_updatable(p) \
19 (RTS_ISSET(p, RTS_NO_PRIV) || RTS_ISSET(p, RTS_SIG_PENDING) \
20 || (RTS_ISSET(p, RTS_RECEIVING) && !RTS_ISSET(p, RTS_SENDING)))
22 static void adjust_proc_slot(struct proc
*rp
, struct proc
*from_rp
);
23 static void adjust_priv_slot(struct priv
*privp
, struct priv
25 static void swap_proc_slot_pointer(struct proc
**rpp
, struct proc
26 *src_rp
, struct proc
*dst_rp
);
28 /*===========================================================================*
30 *===========================================================================*/
31 int do_update(struct proc
* caller
, message
* m_ptr
)
33 /* Handle sys_update(). Update a process into another by swapping their process
36 endpoint_t src_e
, dst_e
;
38 struct proc
*src_rp
, *dst_rp
;
39 struct priv
*src_privp
, *dst_privp
;
40 struct proc orig_src_proc
;
41 struct proc orig_dst_proc
;
42 struct priv orig_src_priv
;
43 struct priv orig_dst_priv
;
46 /* Lookup slots for source and destination process. */
47 src_e
= m_ptr
->SYS_UPD_SRC_ENDPT
;
48 if(!isokendpt(src_e
, &src_p
)) {
51 src_rp
= proc_addr(src_p
);
52 src_privp
= priv(src_rp
);
53 if(!(src_privp
->s_flags
& SYS_PROC
)) {
57 dst_e
= m_ptr
->SYS_UPD_DST_ENDPT
;
58 if(!isokendpt(dst_e
, &dst_p
)) {
61 dst_rp
= proc_addr(dst_p
);
62 dst_privp
= priv(dst_rp
);
63 if(!(dst_privp
->s_flags
& SYS_PROC
)) {
67 assert(!proc_is_runnable(src_rp
) && !proc_is_runnable(dst_rp
));
69 /* Check if processes are updatable. */
70 if(!proc_is_updatable(src_rp
) || !proc_is_updatable(dst_rp
)) {
75 printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n",
76 src_rp
->p_endpoint
, src_rp
->p_name
, src_rp
->p_nr
, priv(src_rp
)->s_proc_nr
,
77 dst_rp
->p_endpoint
, dst_rp
->p_name
, dst_rp
->p_nr
, priv(dst_rp
)->s_proc_nr
);
79 proc_stacktrace(src_rp
);
80 proc_stacktrace(dst_rp
);
81 printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc
)->p_endpoint
);
84 /* Let destination inherit the target mask from source. */
85 for (i
=0; i
< NR_SYS_PROCS
; i
++) {
86 if (get_sys_bit(priv(src_rp
)->s_ipc_to
, i
)) {
87 set_sendto_bit(dst_rp
, i
);
91 /* Save existing data. */
92 orig_src_proc
= *src_rp
;
93 orig_src_priv
= *(priv(src_rp
));
94 orig_dst_proc
= *dst_rp
;
95 orig_dst_priv
= *(priv(dst_rp
));
98 *src_rp
= orig_dst_proc
;
99 *src_privp
= orig_dst_priv
;
100 *dst_rp
= orig_src_proc
;
101 *dst_privp
= orig_src_priv
;
103 /* Adjust process slots. */
104 adjust_proc_slot(src_rp
, &orig_src_proc
);
105 adjust_proc_slot(dst_rp
, &orig_dst_proc
);
107 /* Adjust privilege slots. */
108 adjust_priv_slot(priv(src_rp
), &orig_src_priv
);
109 adjust_priv_slot(priv(dst_rp
), &orig_dst_priv
);
111 /* Swap global process slot addresses. */
112 swap_proc_slot_pointer(get_cpulocal_var_ptr(ptproc
), src_rp
, dst_rp
);
115 printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n",
116 src_rp
->p_endpoint
, src_rp
->p_name
, src_rp
->p_nr
, priv(src_rp
)->s_proc_nr
,
117 dst_rp
->p_endpoint
, dst_rp
->p_name
, dst_rp
->p_nr
, priv(dst_rp
)->s_proc_nr
);
119 proc_stacktrace(src_rp
);
120 proc_stacktrace(dst_rp
);
121 printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc
)->p_endpoint
);
125 bits_fill(src_rp
->p_stale_tlb
, CONFIG_MAX_CPUS
);
126 bits_fill(dst_rp
->p_stale_tlb
, CONFIG_MAX_CPUS
);
132 /*===========================================================================*
134 *===========================================================================*/
135 static void adjust_proc_slot(struct proc
*rp
, struct proc
*from_rp
)
137 /* Preserve endpoints, slot numbers, priv structure, and IPC. */
138 rp
->p_endpoint
= from_rp
->p_endpoint
;
139 rp
->p_nr
= from_rp
->p_nr
;
140 rp
->p_priv
= from_rp
->p_priv
;
141 priv(rp
)->s_proc_nr
= from_rp
->p_nr
;
142 rp
->p_caller_q
= from_rp
->p_caller_q
;
144 /* preserve scheduling */
145 rp
->p_scheduler
= from_rp
->p_scheduler
;
147 rp
->p_cpu
= from_rp
->p_cpu
;
148 memcpy(rp
->p_cpu_mask
, from_rp
->p_cpu_mask
,
149 sizeof(bitchunk_t
) * BITMAP_CHUNKS(CONFIG_MAX_CPUS
));
153 /*===========================================================================*
155 *===========================================================================*/
156 static void adjust_priv_slot(struct priv
*privp
, struct priv
*from_privp
)
158 /* Preserve privilege ids and non-privilege stuff in the priv structure. */
159 privp
->s_id
= from_privp
->s_id
;
160 privp
->s_notify_pending
= from_privp
->s_notify_pending
;
161 privp
->s_int_pending
= from_privp
->s_int_pending
;
162 privp
->s_sig_pending
= from_privp
->s_sig_pending
;
163 privp
->s_alarm_timer
= from_privp
->s_alarm_timer
;
166 /*===========================================================================*
167 * swap_proc_slot_pointer *
168 *===========================================================================*/
169 static void swap_proc_slot_pointer(struct proc
**rpp
, struct proc
*src_rp
,
175 else if(*rpp
== dst_rp
) {
180 #endif /* USE_UPDATE */