1433d6423SLionel Sambuc /* The kernel call implemented in this file:
2433d6423SLionel Sambuc * m_type: SYS_UPDATE
3433d6423SLionel Sambuc *
4433d6423SLionel Sambuc * The parameters for this kernel call are:
5433d6423SLionel Sambuc * m2_i1: SYS_UPD_SRC_ENDPT (source process endpoint)
6433d6423SLionel Sambuc * m2_i2: SYS_UPD_DST_ENDPT (destination process endpoint)
7a1760b57SCristiano Giuffrida * m2_i3: SYS_UPD_FLAGS (update flags)
8433d6423SLionel Sambuc */
9433d6423SLionel Sambuc
10433d6423SLionel Sambuc #include "kernel/system.h"
11433d6423SLionel Sambuc #include <string.h>
12433d6423SLionel Sambuc #include <assert.h>
13433d6423SLionel Sambuc
14433d6423SLionel Sambuc #if USE_UPDATE
15433d6423SLionel Sambuc
16433d6423SLionel Sambuc #define DEBUG 0
17433d6423SLionel Sambuc
18433d6423SLionel Sambuc #define proc_is_updatable(p) \
19433d6423SLionel Sambuc (RTS_ISSET(p, RTS_NO_PRIV) || RTS_ISSET(p, RTS_SIG_PENDING) \
20433d6423SLionel Sambuc || (RTS_ISSET(p, RTS_RECEIVING) && !RTS_ISSET(p, RTS_SENDING)))
21433d6423SLionel Sambuc
2256e56d2aSCristiano Giuffrida static int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp);
2356e56d2aSCristiano Giuffrida static int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp);
2456e56d2aSCristiano Giuffrida static int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp);
25062400c0SCristiano Giuffrida static void abort_proc_ipc_send(struct proc *rp);
26433d6423SLionel Sambuc static void adjust_proc_slot(struct proc *rp, struct proc *from_rp);
27433d6423SLionel Sambuc static void adjust_priv_slot(struct priv *privp, struct priv
28433d6423SLionel Sambuc *from_privp);
29062400c0SCristiano Giuffrida static void adjust_asyn_table(struct priv *src_privp, struct priv *dst_privp);
30433d6423SLionel Sambuc static void swap_proc_slot_pointer(struct proc **rpp, struct proc
31433d6423SLionel Sambuc *src_rp, struct proc *dst_rp);
323779ed93SDavid van Moolenbroek static void swap_memreq(struct proc *src_rp, struct proc *dst_rp);
33433d6423SLionel Sambuc
34433d6423SLionel Sambuc /*===========================================================================*
35433d6423SLionel Sambuc * do_update *
36433d6423SLionel Sambuc *===========================================================================*/
do_update(struct proc * caller,message * m_ptr)37433d6423SLionel Sambuc int do_update(struct proc * caller, message * m_ptr)
38433d6423SLionel Sambuc {
39433d6423SLionel Sambuc /* Handle sys_update(). Update a process into another by swapping their process
40433d6423SLionel Sambuc * slots.
41433d6423SLionel Sambuc */
42433d6423SLionel Sambuc endpoint_t src_e, dst_e;
43062400c0SCristiano Giuffrida int src_p, dst_p, flags;
44433d6423SLionel Sambuc struct proc *src_rp, *dst_rp;
45433d6423SLionel Sambuc struct priv *src_privp, *dst_privp;
46433d6423SLionel Sambuc struct proc orig_src_proc;
47433d6423SLionel Sambuc struct proc orig_dst_proc;
48433d6423SLionel Sambuc struct priv orig_src_priv;
49433d6423SLionel Sambuc struct priv orig_dst_priv;
5056e56d2aSCristiano Giuffrida int i, r;
51433d6423SLionel Sambuc
52433d6423SLionel Sambuc /* Lookup slots for source and destination process. */
53062400c0SCristiano Giuffrida flags = m_ptr->SYS_UPD_FLAGS;
54433d6423SLionel Sambuc src_e = m_ptr->SYS_UPD_SRC_ENDPT;
55433d6423SLionel Sambuc if(!isokendpt(src_e, &src_p)) {
56433d6423SLionel Sambuc return EINVAL;
57433d6423SLionel Sambuc }
58433d6423SLionel Sambuc src_rp = proc_addr(src_p);
59433d6423SLionel Sambuc src_privp = priv(src_rp);
60433d6423SLionel Sambuc if(!(src_privp->s_flags & SYS_PROC)) {
61433d6423SLionel Sambuc return EPERM;
62433d6423SLionel Sambuc }
63433d6423SLionel Sambuc
64433d6423SLionel Sambuc dst_e = m_ptr->SYS_UPD_DST_ENDPT;
65433d6423SLionel Sambuc if(!isokendpt(dst_e, &dst_p)) {
66433d6423SLionel Sambuc return EINVAL;
67433d6423SLionel Sambuc }
68433d6423SLionel Sambuc dst_rp = proc_addr(dst_p);
69433d6423SLionel Sambuc dst_privp = priv(dst_rp);
70433d6423SLionel Sambuc if(!(dst_privp->s_flags & SYS_PROC)) {
71433d6423SLionel Sambuc return EPERM;
72433d6423SLionel Sambuc }
73433d6423SLionel Sambuc
74433d6423SLionel Sambuc assert(!proc_is_runnable(src_rp) && !proc_is_runnable(dst_rp));
75433d6423SLionel Sambuc
76433d6423SLionel Sambuc /* Check if processes are updatable. */
77433d6423SLionel Sambuc if(!proc_is_updatable(src_rp) || !proc_is_updatable(dst_rp)) {
78433d6423SLionel Sambuc return EBUSY;
79433d6423SLionel Sambuc }
80433d6423SLionel Sambuc
81433d6423SLionel Sambuc #if DEBUG
82433d6423SLionel Sambuc printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n",
83433d6423SLionel Sambuc src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr,
84433d6423SLionel Sambuc dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr);
85433d6423SLionel Sambuc
86433d6423SLionel Sambuc proc_stacktrace(src_rp);
87433d6423SLionel Sambuc proc_stacktrace(dst_rp);
88433d6423SLionel Sambuc printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint);
8901c875ceSCristiano Giuffrida printf("do_update: endpoint %d rts flags %x asyn tab %08x asyn endpoint %d grant tab %08x grant endpoint %d\n", src_rp->p_endpoint, src_rp->p_rts_flags, priv(src_rp)->s_asyntab, priv(src_rp)->s_asynendpoint, priv(src_rp)->s_grant_table, priv(src_rp)->s_grant_endpoint);
9001c875ceSCristiano Giuffrida printf("do_update: endpoint %d rts flags %x asyn tab %08x asyn endpoint %d grant tab %08x grant endpoint %d\n", dst_rp->p_endpoint, dst_rp->p_rts_flags, priv(dst_rp)->s_asyntab, priv(dst_rp)->s_asynendpoint, priv(dst_rp)->s_grant_table, priv(dst_rp)->s_grant_endpoint);
91433d6423SLionel Sambuc #endif
92433d6423SLionel Sambuc
9356e56d2aSCristiano Giuffrida /* Let destination inherit allowed IRQ, I/O ranges, and memory ranges. */
9456e56d2aSCristiano Giuffrida r = inherit_priv_irq(src_rp, dst_rp);
9556e56d2aSCristiano Giuffrida if(r != OK) {
9656e56d2aSCristiano Giuffrida return r;
9756e56d2aSCristiano Giuffrida }
9856e56d2aSCristiano Giuffrida r = inherit_priv_io(src_rp, dst_rp);
9956e56d2aSCristiano Giuffrida if(r != OK) {
10056e56d2aSCristiano Giuffrida return r;
10156e56d2aSCristiano Giuffrida }
10256e56d2aSCristiano Giuffrida r = inherit_priv_mem(src_rp, dst_rp);
10356e56d2aSCristiano Giuffrida if(r != OK) {
10456e56d2aSCristiano Giuffrida return r;
10556e56d2aSCristiano Giuffrida }
10656e56d2aSCristiano Giuffrida
107433d6423SLionel Sambuc /* Let destination inherit the target mask from source. */
108433d6423SLionel Sambuc for (i=0; i < NR_SYS_PROCS; i++) {
109433d6423SLionel Sambuc if (get_sys_bit(priv(src_rp)->s_ipc_to, i)) {
110433d6423SLionel Sambuc set_sendto_bit(dst_rp, i);
111433d6423SLionel Sambuc }
112433d6423SLionel Sambuc }
113433d6423SLionel Sambuc
114433d6423SLionel Sambuc /* Save existing data. */
115433d6423SLionel Sambuc orig_src_proc = *src_rp;
116433d6423SLionel Sambuc orig_src_priv = *(priv(src_rp));
117433d6423SLionel Sambuc orig_dst_proc = *dst_rp;
118433d6423SLionel Sambuc orig_dst_priv = *(priv(dst_rp));
119433d6423SLionel Sambuc
120062400c0SCristiano Giuffrida /* Adjust asyn tables. */
121062400c0SCristiano Giuffrida adjust_asyn_table(priv(src_rp), priv(dst_rp));
122062400c0SCristiano Giuffrida adjust_asyn_table(priv(dst_rp), priv(src_rp));
123062400c0SCristiano Giuffrida
124062400c0SCristiano Giuffrida /* Abort any pending send() on rollback. */
125062400c0SCristiano Giuffrida if(flags & SYS_UPD_ROLLBACK) {
126062400c0SCristiano Giuffrida abort_proc_ipc_send(src_rp);
127062400c0SCristiano Giuffrida }
128062400c0SCristiano Giuffrida
129433d6423SLionel Sambuc /* Swap slots. */
130433d6423SLionel Sambuc *src_rp = orig_dst_proc;
131433d6423SLionel Sambuc *src_privp = orig_dst_priv;
132433d6423SLionel Sambuc *dst_rp = orig_src_proc;
133433d6423SLionel Sambuc *dst_privp = orig_src_priv;
134433d6423SLionel Sambuc
135433d6423SLionel Sambuc /* Adjust process slots. */
136433d6423SLionel Sambuc adjust_proc_slot(src_rp, &orig_src_proc);
137433d6423SLionel Sambuc adjust_proc_slot(dst_rp, &orig_dst_proc);
138433d6423SLionel Sambuc
139433d6423SLionel Sambuc /* Adjust privilege slots. */
140433d6423SLionel Sambuc adjust_priv_slot(priv(src_rp), &orig_src_priv);
141433d6423SLionel Sambuc adjust_priv_slot(priv(dst_rp), &orig_dst_priv);
142433d6423SLionel Sambuc
143433d6423SLionel Sambuc /* Swap global process slot addresses. */
144433d6423SLionel Sambuc swap_proc_slot_pointer(get_cpulocal_var_ptr(ptproc), src_rp, dst_rp);
145433d6423SLionel Sambuc
1463779ed93SDavid van Moolenbroek /* Swap VM request entries. */
1473779ed93SDavid van Moolenbroek swap_memreq(src_rp, dst_rp);
1483779ed93SDavid van Moolenbroek
149433d6423SLionel Sambuc #if DEBUG
150433d6423SLionel Sambuc printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n",
151433d6423SLionel Sambuc src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr,
152433d6423SLionel Sambuc dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr);
153433d6423SLionel Sambuc
154433d6423SLionel Sambuc proc_stacktrace(src_rp);
155433d6423SLionel Sambuc proc_stacktrace(dst_rp);
156433d6423SLionel Sambuc printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint);
15701c875ceSCristiano Giuffrida printf("do_update: endpoint %d rts flags %x asyn tab %08x asyn endpoint %d grant tab %08x grant endpoint %d\n", src_rp->p_endpoint, src_rp->p_rts_flags, priv(src_rp)->s_asyntab, priv(src_rp)->s_asynendpoint, priv(src_rp)->s_grant_table, priv(src_rp)->s_grant_endpoint);
15801c875ceSCristiano Giuffrida printf("do_update: endpoint %d rts flags %x asyn tab %08x asyn endpoint %d grant tab %08x grant endpoint %d\n", dst_rp->p_endpoint, dst_rp->p_rts_flags, priv(dst_rp)->s_asyntab, priv(dst_rp)->s_asynendpoint, priv(dst_rp)->s_grant_table, priv(dst_rp)->s_grant_endpoint);
159433d6423SLionel Sambuc #endif
160433d6423SLionel Sambuc
161433d6423SLionel Sambuc #ifdef CONFIG_SMP
162433d6423SLionel Sambuc bits_fill(src_rp->p_stale_tlb, CONFIG_MAX_CPUS);
163433d6423SLionel Sambuc bits_fill(dst_rp->p_stale_tlb, CONFIG_MAX_CPUS);
164433d6423SLionel Sambuc #endif
165433d6423SLionel Sambuc
166433d6423SLionel Sambuc return OK;
167433d6423SLionel Sambuc }
168433d6423SLionel Sambuc
169433d6423SLionel Sambuc /*===========================================================================*
17056e56d2aSCristiano Giuffrida * inherit_priv_irq *
17156e56d2aSCristiano Giuffrida *===========================================================================*/
inherit_priv_irq(struct proc * src_rp,struct proc * dst_rp)17256e56d2aSCristiano Giuffrida int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp)
17356e56d2aSCristiano Giuffrida {
17456e56d2aSCristiano Giuffrida int i, r;
17556e56d2aSCristiano Giuffrida for (i= 0; i<priv(src_rp)->s_nr_irq; i++) {
17656e56d2aSCristiano Giuffrida r = priv_add_irq(dst_rp, priv(src_rp)->s_irq_tab[i]);
17756e56d2aSCristiano Giuffrida if(r != OK) {
17856e56d2aSCristiano Giuffrida return r;
17956e56d2aSCristiano Giuffrida }
18056e56d2aSCristiano Giuffrida }
18156e56d2aSCristiano Giuffrida
18256e56d2aSCristiano Giuffrida return OK;
18356e56d2aSCristiano Giuffrida }
18456e56d2aSCristiano Giuffrida
18556e56d2aSCristiano Giuffrida /*===========================================================================*
18656e56d2aSCristiano Giuffrida * inherit_priv_io *
18756e56d2aSCristiano Giuffrida *===========================================================================*/
inherit_priv_io(struct proc * src_rp,struct proc * dst_rp)18856e56d2aSCristiano Giuffrida int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp)
18956e56d2aSCristiano Giuffrida {
19056e56d2aSCristiano Giuffrida int i, r;
19156e56d2aSCristiano Giuffrida for (i= 0; i<priv(src_rp)->s_nr_io_range; i++) {
19256e56d2aSCristiano Giuffrida r = priv_add_io(dst_rp, &(priv(src_rp)->s_io_tab[i]));
19356e56d2aSCristiano Giuffrida if(r != OK) {
19456e56d2aSCristiano Giuffrida return r;
19556e56d2aSCristiano Giuffrida }
19656e56d2aSCristiano Giuffrida }
19756e56d2aSCristiano Giuffrida
19856e56d2aSCristiano Giuffrida return OK;
19956e56d2aSCristiano Giuffrida }
20056e56d2aSCristiano Giuffrida
20156e56d2aSCristiano Giuffrida /*===========================================================================*
20256e56d2aSCristiano Giuffrida * inherit_priv_mem *
20356e56d2aSCristiano Giuffrida *===========================================================================*/
inherit_priv_mem(struct proc * src_rp,struct proc * dst_rp)20456e56d2aSCristiano Giuffrida int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp)
20556e56d2aSCristiano Giuffrida {
20656e56d2aSCristiano Giuffrida int i, r;
20756e56d2aSCristiano Giuffrida for (i= 0; i<priv(src_rp)->s_nr_mem_range; i++) {
20856e56d2aSCristiano Giuffrida r = priv_add_mem(dst_rp, &(priv(src_rp)->s_mem_tab[i]));
20956e56d2aSCristiano Giuffrida if(r != OK) {
21056e56d2aSCristiano Giuffrida return r;
21156e56d2aSCristiano Giuffrida }
21256e56d2aSCristiano Giuffrida }
21356e56d2aSCristiano Giuffrida
21456e56d2aSCristiano Giuffrida return OK;
21556e56d2aSCristiano Giuffrida }
21656e56d2aSCristiano Giuffrida
21756e56d2aSCristiano Giuffrida /*===========================================================================*
218062400c0SCristiano Giuffrida * abort_proc_ipc_send *
219062400c0SCristiano Giuffrida *===========================================================================*/
abort_proc_ipc_send(struct proc * rp)220062400c0SCristiano Giuffrida void abort_proc_ipc_send(struct proc *rp)
221062400c0SCristiano Giuffrida {
222062400c0SCristiano Giuffrida if(RTS_ISSET(rp, RTS_SENDING)) {
223062400c0SCristiano Giuffrida struct proc **xpp;
224062400c0SCristiano Giuffrida RTS_UNSET(rp, RTS_SENDING);
225062400c0SCristiano Giuffrida rp->p_misc_flags &= ~MF_SENDING_FROM_KERNEL;
226062400c0SCristiano Giuffrida xpp = &(proc_addr(_ENDPOINT_P(rp->p_sendto_e))->p_caller_q);
227062400c0SCristiano Giuffrida while (*xpp) {
228062400c0SCristiano Giuffrida if(*xpp == rp) {
229062400c0SCristiano Giuffrida *xpp = rp->p_q_link;
230062400c0SCristiano Giuffrida rp->p_q_link = NULL;
231062400c0SCristiano Giuffrida break;
232062400c0SCristiano Giuffrida }
233062400c0SCristiano Giuffrida xpp = &(*xpp)->p_q_link;
234062400c0SCristiano Giuffrida }
235062400c0SCristiano Giuffrida }
236062400c0SCristiano Giuffrida }
237062400c0SCristiano Giuffrida
238062400c0SCristiano Giuffrida /*===========================================================================*
239433d6423SLionel Sambuc * adjust_proc_slot *
240433d6423SLionel Sambuc *===========================================================================*/
adjust_proc_slot(struct proc * rp,struct proc * from_rp)241433d6423SLionel Sambuc static void adjust_proc_slot(struct proc *rp, struct proc *from_rp)
242433d6423SLionel Sambuc {
243433d6423SLionel Sambuc /* Preserve endpoints, slot numbers, priv structure, and IPC. */
244433d6423SLionel Sambuc rp->p_endpoint = from_rp->p_endpoint;
245433d6423SLionel Sambuc rp->p_nr = from_rp->p_nr;
246433d6423SLionel Sambuc rp->p_priv = from_rp->p_priv;
247433d6423SLionel Sambuc priv(rp)->s_proc_nr = from_rp->p_nr;
248062400c0SCristiano Giuffrida
249433d6423SLionel Sambuc rp->p_caller_q = from_rp->p_caller_q;
250433d6423SLionel Sambuc
251433d6423SLionel Sambuc /* preserve scheduling */
252433d6423SLionel Sambuc rp->p_scheduler = from_rp->p_scheduler;
253433d6423SLionel Sambuc #ifdef CONFIG_SMP
254433d6423SLionel Sambuc rp->p_cpu = from_rp->p_cpu;
255433d6423SLionel Sambuc memcpy(rp->p_cpu_mask, from_rp->p_cpu_mask,
256433d6423SLionel Sambuc sizeof(bitchunk_t) * BITMAP_CHUNKS(CONFIG_MAX_CPUS));
257433d6423SLionel Sambuc #endif
258433d6423SLionel Sambuc }
259433d6423SLionel Sambuc
260433d6423SLionel Sambuc /*===========================================================================*
261062400c0SCristiano Giuffrida * adjust_asyn_table *
262062400c0SCristiano Giuffrida *===========================================================================*/
adjust_asyn_table(struct priv * src_privp,struct priv * dst_privp)263062400c0SCristiano Giuffrida static void adjust_asyn_table(struct priv *src_privp, struct priv *dst_privp)
264062400c0SCristiano Giuffrida {
265062400c0SCristiano Giuffrida /* Transfer the asyn table if source's table belongs to the destination. */
266062400c0SCristiano Giuffrida endpoint_t src_e = proc_addr(src_privp->s_proc_nr)->p_endpoint;
267062400c0SCristiano Giuffrida endpoint_t dst_e = proc_addr(dst_privp->s_proc_nr)->p_endpoint;
268062400c0SCristiano Giuffrida
269062400c0SCristiano Giuffrida if(src_privp->s_asynsize > 0 && dst_privp->s_asynsize > 0 && src_privp->s_asynendpoint == dst_e) {
270062400c0SCristiano Giuffrida if(data_copy(src_e, src_privp->s_asyntab, dst_e, dst_privp->s_asyntab,
271062400c0SCristiano Giuffrida src_privp->s_asynsize*sizeof(asynmsg_t)) != OK) {
272062400c0SCristiano Giuffrida printf("Warning: unable to transfer asyn table from ep %d to ep %d\n",
273062400c0SCristiano Giuffrida src_e, dst_e);
274062400c0SCristiano Giuffrida }
275062400c0SCristiano Giuffrida else {
276062400c0SCristiano Giuffrida dst_privp->s_asynsize = src_privp->s_asynsize;
277062400c0SCristiano Giuffrida }
278062400c0SCristiano Giuffrida }
279062400c0SCristiano Giuffrida }
280062400c0SCristiano Giuffrida
281062400c0SCristiano Giuffrida /*===========================================================================*
282433d6423SLionel Sambuc * adjust_priv_slot *
283433d6423SLionel Sambuc *===========================================================================*/
adjust_priv_slot(struct priv * privp,struct priv * from_privp)284433d6423SLionel Sambuc static void adjust_priv_slot(struct priv *privp, struct priv *from_privp)
285433d6423SLionel Sambuc {
286433d6423SLionel Sambuc /* Preserve privilege ids and non-privilege stuff in the priv structure. */
287433d6423SLionel Sambuc privp->s_id = from_privp->s_id;
288*7f79fb88SDavid van Moolenbroek privp->s_asyn_pending = from_privp->s_asyn_pending;
289433d6423SLionel Sambuc privp->s_notify_pending = from_privp->s_notify_pending;
290433d6423SLionel Sambuc privp->s_int_pending = from_privp->s_int_pending;
291433d6423SLionel Sambuc privp->s_sig_pending = from_privp->s_sig_pending;
292433d6423SLionel Sambuc privp->s_alarm_timer = from_privp->s_alarm_timer;
293433d6423SLionel Sambuc privp->s_diag_sig = from_privp->s_diag_sig;
294433d6423SLionel Sambuc }
295433d6423SLionel Sambuc
296433d6423SLionel Sambuc /*===========================================================================*
297433d6423SLionel Sambuc * swap_proc_slot_pointer *
298433d6423SLionel Sambuc *===========================================================================*/
swap_proc_slot_pointer(struct proc ** rpp,struct proc * src_rp,struct proc * dst_rp)299433d6423SLionel Sambuc static void swap_proc_slot_pointer(struct proc **rpp, struct proc *src_rp,
300433d6423SLionel Sambuc struct proc *dst_rp)
301433d6423SLionel Sambuc {
302433d6423SLionel Sambuc if(*rpp == src_rp) {
303433d6423SLionel Sambuc *rpp = dst_rp;
304433d6423SLionel Sambuc }
305433d6423SLionel Sambuc else if(*rpp == dst_rp) {
306433d6423SLionel Sambuc *rpp = src_rp;
307433d6423SLionel Sambuc }
308433d6423SLionel Sambuc }
309433d6423SLionel Sambuc
3103779ed93SDavid van Moolenbroek /*===========================================================================*
3113779ed93SDavid van Moolenbroek * swap_memreq *
3123779ed93SDavid van Moolenbroek *===========================================================================*/
swap_memreq(struct proc * src_rp,struct proc * dst_rp)3133779ed93SDavid van Moolenbroek static void swap_memreq(struct proc *src_rp, struct proc *dst_rp)
3143779ed93SDavid van Moolenbroek {
3153779ed93SDavid van Moolenbroek /* If either the source or the destination process is part of the VM request
3163779ed93SDavid van Moolenbroek * chain, but not both, then swap the process pointers in the chain.
3173779ed93SDavid van Moolenbroek */
3183779ed93SDavid van Moolenbroek struct proc **rpp;
3193779ed93SDavid van Moolenbroek
3203779ed93SDavid van Moolenbroek if (RTS_ISSET(src_rp, RTS_VMREQUEST) == RTS_ISSET(dst_rp, RTS_VMREQUEST))
3213779ed93SDavid van Moolenbroek return; /* nothing to do */
3223779ed93SDavid van Moolenbroek
3233779ed93SDavid van Moolenbroek for (rpp = &vmrequest; *rpp != NULL;
3243779ed93SDavid van Moolenbroek rpp = &(*rpp)->p_vmrequest.nextrequestor) {
3253779ed93SDavid van Moolenbroek if (*rpp == src_rp) {
3263779ed93SDavid van Moolenbroek dst_rp->p_vmrequest.nextrequestor =
3273779ed93SDavid van Moolenbroek src_rp->p_vmrequest.nextrequestor;
3283779ed93SDavid van Moolenbroek *rpp = dst_rp;
3293779ed93SDavid van Moolenbroek break;
3303779ed93SDavid van Moolenbroek } else if (*rpp == dst_rp) {
3313779ed93SDavid van Moolenbroek src_rp->p_vmrequest.nextrequestor =
3323779ed93SDavid van Moolenbroek dst_rp->p_vmrequest.nextrequestor;
3333779ed93SDavid van Moolenbroek *rpp = src_rp;
3343779ed93SDavid van Moolenbroek break;
3353779ed93SDavid van Moolenbroek }
3363779ed93SDavid van Moolenbroek }
3373779ed93SDavid van Moolenbroek }
3383779ed93SDavid van Moolenbroek
339433d6423SLionel Sambuc #endif /* USE_UPDATE */
340433d6423SLionel Sambuc
341