/*===========================================================================* * do_update * *===========================================================================*/ PUBLIC int do_update(struct proc * caller, message * m_ptr) { /* Handle sys_update(). Update a process into another by swapping their process * slots. */ endpoint_t src_e, dst_e; int src_p, dst_p; struct proc *src_rp, *dst_rp; struct priv *src_privp, *dst_privp; struct proc orig_src_proc; struct proc orig_dst_proc; struct priv orig_src_priv; struct priv orig_dst_priv; /* Lookup slots for source and destination process. */ src_e = m_ptr->SYS_UPD_SRC_ENDPT; if(!isokendpt(src_e, &src_p)) { return EINVAL; } src_rp = proc_addr(src_p); src_privp = priv(src_rp); if(!(src_privp->s_flags & SYS_PROC)) { return EPERM; } dst_e = m_ptr->SYS_UPD_DST_ENDPT; if(!isokendpt(dst_e, &dst_p)) { return EINVAL; } dst_rp = proc_addr(dst_p); dst_privp = priv(dst_rp); if(!(dst_privp->s_flags & SYS_PROC)) { return EPERM; } /* Check if processes are updatable. */ if(!proc_is_updatable(src_rp) || !proc_is_updatable(dst_rp)) { return EBUSY; } #if DEBUG printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", ptproc->p_endpoint); #endif /* Save existing data. */ orig_src_proc = *src_rp; orig_src_priv = *(priv(src_rp)); orig_dst_proc = *dst_rp; orig_dst_priv = *(priv(dst_rp)); /* Swap slots. */ *src_rp = orig_dst_proc; *src_privp = orig_dst_priv; *dst_rp = orig_src_proc; *dst_privp = orig_src_priv; /* Adjust process slots. */ adjust_proc_slot(src_rp, &orig_src_proc); adjust_proc_slot(dst_rp, &orig_dst_proc); /* Adjust privilege slots. */ adjust_priv_slot(priv(src_rp), &orig_src_priv); adjust_priv_slot(priv(dst_rp), &orig_dst_priv); /* Swap global process slot addresses. */ swap_proc_slot_pointer(&ptproc, src_rp, dst_rp); /* Fix segments. */ alloc_segments(src_rp); alloc_segments(dst_rp); prot_init(); #if DEBUG printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", ptproc->p_endpoint); #endif return OK; }
/*===========================================================================* * do_update * *===========================================================================*/ int do_update(struct proc * caller, message * m_ptr) { /* Handle sys_update(). Update a process into another by swapping their process * slots. */ endpoint_t src_e, dst_e; int src_p, dst_p; struct proc *src_rp, *dst_rp; struct priv *src_privp, *dst_privp; struct proc orig_src_proc; struct proc orig_dst_proc; struct priv orig_src_priv; struct priv orig_dst_priv; int i; /* Lookup slots for source and destination process. */ src_e = m_ptr->SYS_UPD_SRC_ENDPT; if(!isokendpt(src_e, &src_p)) { return EINVAL; } src_rp = proc_addr(src_p); src_privp = priv(src_rp); if(!(src_privp->s_flags & SYS_PROC)) { return EPERM; } dst_e = m_ptr->SYS_UPD_DST_ENDPT; if(!isokendpt(dst_e, &dst_p)) { return EINVAL; } dst_rp = proc_addr(dst_p); dst_privp = priv(dst_rp); if(!(dst_privp->s_flags & SYS_PROC)) { return EPERM; } assert(!proc_is_runnable(src_rp) && !proc_is_runnable(dst_rp)); /* Check if processes are updatable. */ if(!proc_is_updatable(src_rp) || !proc_is_updatable(dst_rp)) { return EBUSY; } #if DEBUG printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint); #endif /* Let destination inherit the target mask from source. */ for (i=0; i < NR_SYS_PROCS; i++) { if (get_sys_bit(priv(src_rp)->s_ipc_to, i)) { set_sendto_bit(dst_rp, i); } } /* Save existing data. */ orig_src_proc = *src_rp; orig_src_priv = *(priv(src_rp)); orig_dst_proc = *dst_rp; orig_dst_priv = *(priv(dst_rp)); /* Swap slots. */ *src_rp = orig_dst_proc; *src_privp = orig_dst_priv; *dst_rp = orig_src_proc; *dst_privp = orig_src_priv; /* Adjust process slots. */ adjust_proc_slot(src_rp, &orig_src_proc); adjust_proc_slot(dst_rp, &orig_dst_proc); /* Adjust privilege slots. */ adjust_priv_slot(priv(src_rp), &orig_src_priv); adjust_priv_slot(priv(dst_rp), &orig_dst_priv); /* Swap global process slot addresses. */ swap_proc_slot_pointer(get_cpulocal_var_ptr(ptproc), src_rp, dst_rp); #if DEBUG printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint); #endif #ifdef CONFIG_SMP bits_fill(src_rp->p_stale_tlb, CONFIG_MAX_CPUS); bits_fill(dst_rp->p_stale_tlb, CONFIG_MAX_CPUS); #endif return OK; }
/*===========================================================================* * do_update * *===========================================================================*/ int do_update(struct proc * caller, message * m_ptr) { /* Handle sys_update(). Update a process into another by swapping their process * slots. */ endpoint_t src_e, dst_e; int src_p, dst_p, flags; struct proc *src_rp, *dst_rp; struct priv *src_privp, *dst_privp; struct proc orig_src_proc; struct proc orig_dst_proc; struct priv orig_src_priv; struct priv orig_dst_priv; int i, r; /* Lookup slots for source and destination process. */ flags = m_ptr->SYS_UPD_FLAGS; src_e = m_ptr->SYS_UPD_SRC_ENDPT; if(!isokendpt(src_e, &src_p)) { return EINVAL; } src_rp = proc_addr(src_p); src_privp = priv(src_rp); if(!(src_privp->s_flags & SYS_PROC)) { return EPERM; } dst_e = m_ptr->SYS_UPD_DST_ENDPT; if(!isokendpt(dst_e, &dst_p)) { return EINVAL; } dst_rp = proc_addr(dst_p); dst_privp = priv(dst_rp); if(!(dst_privp->s_flags & SYS_PROC)) { return EPERM; } assert(!proc_is_runnable(src_rp) && !proc_is_runnable(dst_rp)); /* Check if processes are updatable. */ if(!proc_is_updatable(src_rp) || !proc_is_updatable(dst_rp)) { return EBUSY; } #if DEBUG printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint); 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); 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); #endif /* Let destination inherit allowed IRQ, I/O ranges, and memory ranges. */ r = inherit_priv_irq(src_rp, dst_rp); if(r != OK) { return r; } r = inherit_priv_io(src_rp, dst_rp); if(r != OK) { return r; } r = inherit_priv_mem(src_rp, dst_rp); if(r != OK) { return r; } /* Let destination inherit the target mask from source. */ for (i=0; i < NR_SYS_PROCS; i++) { if (get_sys_bit(priv(src_rp)->s_ipc_to, i)) { set_sendto_bit(dst_rp, i); } } /* Save existing data. */ orig_src_proc = *src_rp; orig_src_priv = *(priv(src_rp)); orig_dst_proc = *dst_rp; orig_dst_priv = *(priv(dst_rp)); /* Adjust asyn tables. */ adjust_asyn_table(priv(src_rp), priv(dst_rp)); adjust_asyn_table(priv(dst_rp), priv(src_rp)); /* Abort any pending send() on rollback. */ if(flags & SYS_UPD_ROLLBACK) { abort_proc_ipc_send(src_rp); } /* Swap slots. */ *src_rp = orig_dst_proc; *src_privp = orig_dst_priv; *dst_rp = orig_src_proc; *dst_privp = orig_src_priv; /* Adjust process slots. */ adjust_proc_slot(src_rp, &orig_src_proc); adjust_proc_slot(dst_rp, &orig_dst_proc); /* Adjust privilege slots. */ adjust_priv_slot(priv(src_rp), &orig_src_priv); adjust_priv_slot(priv(dst_rp), &orig_dst_priv); /* Swap global process slot addresses. */ swap_proc_slot_pointer(get_cpulocal_var_ptr(ptproc), src_rp, dst_rp); /* Swap VM request entries. */ swap_memreq(src_rp, dst_rp); #if DEBUG printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n", src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr, dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr); proc_stacktrace(src_rp); proc_stacktrace(dst_rp); printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint); 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); 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); #endif #ifdef CONFIG_SMP bits_fill(src_rp->p_stale_tlb, CONFIG_MAX_CPUS); bits_fill(dst_rp->p_stale_tlb, CONFIG_MAX_CPUS); #endif return OK; }