/*===========================================================================* * do_rs_update * *===========================================================================*/ int do_rs_update(message *m_ptr) { endpoint_t src_e, dst_e, reply_e; int src_p, dst_p; struct vmproc *src_vmp, *dst_vmp; int r; src_e = m_ptr->VM_RS_SRC_ENDPT; dst_e = m_ptr->VM_RS_DST_ENDPT; /* Lookup slots for source and destination process. */ if(vm_isokendpt(src_e, &src_p) != OK) { printf("do_rs_update: bad src endpoint %d\n", src_e); return EINVAL; } src_vmp = &vmproc[src_p]; if(vm_isokendpt(dst_e, &dst_p) != OK) { printf("do_rs_update: bad dst endpoint %d\n", dst_e); return EINVAL; } dst_vmp = &vmproc[dst_p]; /* Let the kernel do the update first. */ r = sys_update(src_e, dst_e); if(r != OK) { return r; } /* Do the update in VM now. */ r = swap_proc_slot(src_vmp, dst_vmp); if(r != OK) { return r; } r = swap_proc_dyn_data(src_vmp, dst_vmp); if(r != OK) { return r; } pt_bind(&src_vmp->vm_pt, src_vmp); pt_bind(&dst_vmp->vm_pt, dst_vmp); /* Reply, update-aware. */ reply_e = m_ptr->m_source; if(reply_e == src_e) reply_e = dst_e; else if(reply_e == dst_e) reply_e = src_e; m_ptr->m_type = OK; r = send(reply_e, m_ptr); if(r != OK) { panic("send() error"); } return SUSPEND; }
/*===========================================================================* * do_rs_update * *===========================================================================*/ int do_rs_update(message *m_ptr) { endpoint_t src_e, dst_e, reply_e; int src_p, dst_p; struct vmproc *src_vmp, *dst_vmp; int r, sys_upd_flags; src_e = m_ptr->m_lsys_vm_update.src; dst_e = m_ptr->m_lsys_vm_update.dst; sys_upd_flags = m_ptr->m_lsys_vm_update.flags; reply_e = m_ptr->m_source; /* Lookup slots for source and destination process. */ if(vm_isokendpt(src_e, &src_p) != OK) { printf("do_rs_update: bad src endpoint %d\n", src_e); return EINVAL; } src_vmp = &vmproc[src_p]; if(vm_isokendpt(dst_e, &dst_p) != OK) { printf("do_rs_update: bad dst endpoint %d\n", dst_e); return EINVAL; } dst_vmp = &vmproc[dst_p]; /* Check flags. */ if((sys_upd_flags & (SF_VM_ROLLBACK|SF_VM_NOMMAP)) == 0) { /* Can't preallocate when transfering mmapped regions. */ if(map_region_lookup_type(dst_vmp, VR_PREALLOC_MAP)) { return ENOSYS; } } /* Let the kernel do the update first. */ r = sys_update(src_e, dst_e, sys_upd_flags & SF_VM_ROLLBACK ? SYS_UPD_ROLLBACK : 0); if(r != OK) { return r; } /* Do the update in VM now. */ r = swap_proc_slot(src_vmp, dst_vmp); if(r != OK) { return r; } r = swap_proc_dyn_data(src_vmp, dst_vmp, sys_upd_flags); if(r != OK) { return r; } pt_bind(&src_vmp->vm_pt, src_vmp); pt_bind(&dst_vmp->vm_pt, dst_vmp); /* Reply in case of external request, update-aware. */ if(reply_e != VM_PROC_NR) { if(reply_e == src_e) reply_e = dst_e; else if(reply_e == dst_e) reply_e = src_e; m_ptr->m_type = OK; r = ipc_send(reply_e, m_ptr); if(r != OK) { panic("ipc_send() error"); } } return SUSPEND; }