/*===========================================================================* * swap_proc_dyn_data * *===========================================================================*/ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp, int sys_upd_flags) { int is_vm; int r; is_vm = (dst_vmp->vm_endpoint == VM_PROC_NR); /* For VM, transfer memory mapped regions first. */ if(is_vm) { #if LU_DEBUG printf("VM: swap_proc_dyn_data: tranferring memory mapped regions from old (%d) to new VM (%d)\n", src_vmp->vm_endpoint, dst_vmp->vm_endpoint); #endif r = pt_map_in_range(src_vmp, dst_vmp, VM_OWN_HEAPBASE, VM_OWN_MMAPTOP); if(r != OK) { printf("swap_proc_dyn_data: pt_map_in_range failed\n"); return r; } r = pt_map_in_range(src_vmp, dst_vmp, VM_STACKTOP, VM_DATATOP); if(r != OK) { printf("swap_proc_dyn_data: pt_map_in_range failed\n"); return r; } } #if LU_DEBUG printf("VM: swap_proc_dyn_data: swapping regions' parents for %d (%d) and %d (%d)\n", src_vmp->vm_endpoint, src_vmp->vm_slot, dst_vmp->vm_endpoint, dst_vmp->vm_slot); #endif /* Swap vir_regions' parents. */ map_setparent(src_vmp); map_setparent(dst_vmp); /* Don't transfer mmapped regions if not required. */ if(is_vm || (sys_upd_flags & (SF_VM_ROLLBACK|SF_VM_NOMMAP))) { return OK; } /* Make sure regions are consistent. */ assert(region_search_root(&src_vmp->vm_regions_avl) && region_search_root(&dst_vmp->vm_regions_avl)); /* Source and destination are intentionally swapped here! */ return map_proc_dyn_data(dst_vmp, src_vmp); }
/*===========================================================================* * swap_proc_dyn_data * *===========================================================================*/ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp) { int is_vm; int r; is_vm = (dst_vmp->vm_endpoint == VM_PROC_NR); /* For VM, transfer memory regions above the stack first. */ if(is_vm) { #if LU_DEBUG printf("VM: swap_proc_dyn_data: tranferring regions above the stack from old VM (%d) to new VM (%d)\n", src_vmp->vm_endpoint, dst_vmp->vm_endpoint); #endif r = pt_map_in_range(src_vmp, dst_vmp, VM_STACKTOP, 0); if(r != OK) { printf("swap_proc_dyn_data: pt_map_in_range failed\n"); return r; } } #if LU_DEBUG printf("VM: swap_proc_dyn_data: swapping regions' parents for %d (%d) and %d (%d)\n", src_vmp->vm_endpoint, src_vmp->vm_slot, dst_vmp->vm_endpoint, dst_vmp->vm_slot); #endif /* Swap vir_regions' parents. */ map_setparent(src_vmp); map_setparent(dst_vmp); /* For regular processes, transfer regions above the stack now. * In case of rollback, we need to skip this step. To sandbox the * new instance and prevent state corruption on rollback, we share all * the regions between the two instances as COW. */ if(!is_vm) { struct vir_region *vr; vr = map_lookup(dst_vmp, VM_STACKTOP, NULL); if(vr && !map_lookup(src_vmp, VM_STACKTOP, NULL)) { #if LU_DEBUG printf("VM: swap_proc_dyn_data: tranferring regions above the stack from %d to %d\n", src_vmp->vm_endpoint, dst_vmp->vm_endpoint); #endif r = map_proc_copy_from(src_vmp, dst_vmp, vr); if(r != OK) { return r; } } } return OK; }