return(EPERM);
}
- /* Now fork and branch for parent and child process (and check for error). */
+ /* Now fork and branch for parent and child process (and check for error).
+ * After fork()ing, we need to pin RS memory again or pagefaults will occur
+ * on future writes.
+ */
if(rs_verbose)
printf("RS: forking child with srv_fork()...\n");
child_pid= srv_fork();
|| (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) {
printf("unable to set privilege structure: %d\n", s);
cleanup_service(rp);
+ vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return ENOMEM;
}
if ((s = sched_init_proc(rp)) != OK) {
printf("unable to start scheduling: %d\n", s);
cleanup_service(rp);
+ vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s;
}
- /* Copy the executable image into the child process. If this call
- * fails, the child process may or may not be killed already. If it is
- * not killed, it's blocked because of NO_PRIV. Kill it now either way.
- * If no copy exists, allocate one and free it right after exec completes.
+ /* Copy the executable image into the child process. If no copy exists,
+ * allocate one and free it right after exec completes.
*/
if(use_copy) {
if(rs_verbose)
if ((s = read_exec(rp)) != OK) {
printf("read_exec failed: %d\n", s);
cleanup_service(rp);
+ vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s;
}
}
printf("RS: execing child with srv_execve()...\n");
s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv,
environ);
+ vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
if (s != OK) {
printf("srv_execve failed: %d\n", s);
if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
return kill_service(rp,"can't let the script run",r);
}
+ /* Pin RS memory again after fork()ing. */
+ vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
}
return OK;
}
PUBLIC int map_pin_memory(struct vmproc *vmp)
{
struct vir_region *vr;
- int offset, r;
+ int r;
/* Scan all memory regions. */
for(vr = vmp->vm_regions; vr; vr = vr->next) {
- vir_bytes offset;
- /* Skip regions that can't pagefault. */
- if((vr->flags & VR_NOPF) || (vr->flags & VR_SHARED)) {
- continue;
- }
- /* Map other regions. */
- for(offset=0;offset<vr->length;offset += VM_PAGE_SIZE) {
- if((r=map_pf(vmp, vr, offset, 1 /* write */))
- != OK) {
- printf("VM: map_pf failed\n");
- return r;
- }
+ /* Make sure region is mapped to physical memory and writable.*/
+ r = map_handle_memory(vmp, vr, 0, vr->length, 1);
+ if(r != OK) {
+ panic("map_pin_memory: map_handle_memory failed: %d", r);
}
}