// Copy the mappings for shared pages into the child address space.
    static int
copy_shared_pages(envid_t child)
{
    // LAB 7: Your code here.
    uint64_t vaddr;
    int r;
    for(vaddr=0; vaddr<UTOP; vaddr += PGSIZE) {
        
        // Copying from lib/fork.c bruh.
        if( // Gotta use the virtual types apparently.
            (vpml4e[VPML4E(vaddr)] & PTE_P) // Mota mota level is present.
            && ((vpde[VPDPE(vaddr)] & PTE_U) && (vpde[VPDPE(vaddr)] & PTE_P)) // Slighlt less mota level is also present.
            && ((vpd[VPD(vaddr)] & PTE_U) && (vpd[VPD(vaddr)] & PTE_P))
            &&  ((vpt[VPN(vaddr)] & PTE_U) && (vpt[VPN(vaddr)] & PTE_P))
            )
            if(vpt[VPN(vaddr)]&PTE_SHARE) {
                r = sys_page_map(0, (void*)vaddr, child, (void*)vaddr, vpt[VPN(vaddr)] & PTE_SYSCALL);
                if(r<0) {
                    cprintf("WARN: Your environments are now throughly done for man.\n");
                    return -1;
                }
            }
    }
    return 0;
}
Exemple #2
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
    envid_t
fork(void)
{
    // LAB 4: Your code here.
    envid_t envid;
        uint64_t addr;
        uint32_t err;
        extern unsigned char end[];
        int r;

        set_pgfault_handler(pgfault);
        envid = sys_exofork();

        if (envid < 0)
                panic("sys_exofork: %e", envid);
        if (envid == 0) {
                // We're the child.
                // The copied value of the global variable 'thisenv'
                // is no longer valid (it refers to the parent!).
                // Fix it and return 0.

                thisenv = &envs[ENVX(sys_getenvid())];
                return 0;
        }

        //Allocate exception stack for the child
        if ((err = sys_page_alloc(envid, (void *) (UXSTACKTOP - PGSIZE), PTE_P|PTE_U|PTE_W)) < 0)
                panic("Error in sys_page_alloc: %e", err);

        // We're the parent.
        // Map our entire address space into the child.
        for (addr = UTEXT; addr < USTACKTOP-PGSIZE; addr += PGSIZE) {
               if((vpml4e[VPML4E(addr)] & PTE_P) && (vpde[VPDPE(addr)] & PTE_P)
                        && (vpd[VPD(addr)] & PTE_P) && (vpt[VPN(addr)] & PTE_P)) {
                       duppage(envid, VPN(addr));
                }
        }

        //Allocate a new stack for the child and copy the contents of parent on to it.
        addr = USTACKTOP-PGSIZE;
	if ((r = sys_page_alloc(0, (void *)PFTEMP, PTE_P|PTE_U|PTE_W)) < 0)
                panic("sys_page_alloc failed: %e\n", r);
        memcpy(PFTEMP, (void *) ROUNDDOWN(addr, PGSIZE), PGSIZE);
        void *vaTemp = (void *) ROUNDDOWN(addr, PGSIZE);
        if ((r = sys_page_map(0, (void *)PFTEMP, envid, vaTemp, PTE_P|PTE_U|PTE_W)) < 0)
                panic("sys_page_map failed: %e\n", r);
        if ((r = sys_page_unmap(0, (void *)PFTEMP)) < 0)
                panic("sys_page_unmap failed: %e\n", r);

        //Set child's page fault handler
        if ((err = sys_env_set_pgfault_upcall(envid, _pgfault_upcall) < 0))
                panic("Error in sys_env_set_pgfault_upcall: %e",err);

        //Set the child ready to run
        if ((err = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
                panic("sys_env_set_status: %e", err);

        return envid;
    panic("fork not implemented");
}
Exemple #3
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	int r;
	envid_t envid;
	set_pgfault_handler(pgfault);
	if((envid = sys_exofork())<0)
		panic("sys_exofork error: %e\n",envid);

	if(envid == 0){
		thisenv = &envs[ENVX(sys_getenvid())];
		return 0;
	}	
	


	uint32_t vaddr;
	extern unsigned char end[];

	for (vaddr = 0 ; vaddr < UTOP; vaddr += PGSIZE ){
		//Check sequentially
		if ((vpml4e[VPML4E(vaddr)] & PTE_P ) && (vpde[VPDPE(vaddr)] & PTE_P ) && (vpd[VPD(vaddr)] & PTE_P ) 
				&& (vpt[VPN(vaddr)] & PTE_P)){ //Order is imp...
			if ((vaddr != (UXSTACKTOP - PGSIZE)) && (vaddr != (USTACKTOP - PGSIZE))){
				duppage(envid, (uint64_t)vaddr / PGSIZE);
			}
		}	
	}


	if ((r = sys_page_alloc(envid,(void*)(USTACKTOP - PGSIZE), PTE_U | PTE_W | PTE_P ))<0){
		panic("error from sys_page_alloc: %e\n", r);

	}
	else 
	{
		if ((r = sys_page_alloc(0, PFTEMP, PTE_U|PTE_W|PTE_P)) < 0)
	        panic("error from sys_page_alloc: %e", r);

		memmove(PFTEMP, (void *)(USTACKTOP - PGSIZE), PGSIZE);

		if ((r = sys_page_map(0,PFTEMP, envid, (void *)(USTACKTOP - PGSIZE) , PTE_U|PTE_W|PTE_P)) < 0)
	        panic("error from sys_page_map: %e", r);
	}

	if((r = sys_page_alloc(envid,(void*)(UXSTACKTOP - PGSIZE), PTE_U | PTE_W | PTE_P ))<0)	
		panic("error from sys_page_alloc : %e\n",r);

	if((r=sys_env_set_pgfault_upcall(envid, thisenv->env_pgfault_upcall))!=0)
		panic("error from sys_env_set_pgfault_upcall : %e\n",r);

	if((r = sys_env_set_status(envid, ENV_RUNNABLE))<0)
		panic("error from sys_env_set_status : %e\n",r);
	
	return envid;

}
Exemple #4
0
// Copy the mappings for shared pages into the child address space.
    static int
copy_shared_pages(envid_t child)
{
	// LAB 7: Your code here.
        uint64_t addr;
	for (addr = UTEXT; addr < USTACKTOP-PGSIZE; addr += PGSIZE) {
               if((vpml4e[VPML4E(addr)] & PTE_P) && (vpde[VPDPE(addr)] & PTE_P)  
                 && (vpd[VPD(addr)] & PTE_P) && (vpt[VPN(addr)] & PTE_P)) {
                        int perm_share = vpt[VPN(addr)] & PTE_USER;
                        if (perm_share & PTE_SHARE)
                                sys_page_map(0, (void *)addr, child, (void *)addr, perm_share);
                }
        }

	return 0;
}
int32_t net_host_send(char *pg, int len) {
    // LAB 8: Your code here.

    if (pg == NULL)
        pg = (void*) UTOP;

    uint64_t addr = (uint64_t)pg;                                                                                                                                   

    if( (vpml4e[VPML4E(addr)] & PTE_P)   &&   (vpde[VPDPE(addr)] & PTE_P)                                                                                     
            &&  (vpd[VPD(addr)] & PTE_P)  &&  (vpt[VPN(addr)] & PTE_P)  )
    {
        pg = (void *) PTE_ADDR( vpt[VPN(addr)] );
    }

    int ret =  vm_call( VMX_VMCALL_NETSEND, (uint64_t) pg , (uint64_t) len, 0, 0, 0 );
    return ret;
}
Exemple #6
0
// 		The parent installs pgfault() as the C-level page fault handler, using the set_pgfault_handler() function you implemented above.
//		 The parent calls sys_exofork() to create a child environment.
//		 For each writable or copy-on-write page in its address space below UTOP, the parent calls duppage, which should map the page copy-on-write into the address space of the child and then remap the page copy-on-write in its own address space. duppage sets both PTEs so that the page is not writeable, and to contain PTE_COW in the "avail" field to distinguish copy-on-write pages from genuine read-only pages.
//		 The exception stack is not remapped this way, however. Instead you need to allocate a fresh page in the child for the exception stack. 
// 		Since the page fault handler will be doing the actual copying and the page fault handler runs on the exception stack, the exception stack cannot be made copy-on-write: who would copy it?
// 		fork() also needs to handle pages that are present, but not writable or copy-on-write.
// 		The parent sets the user page fault entrypoint for the child to look like its own.
// 		The child is now ready to run, so the parent marks it runnable.
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
    envid_t
fork(void)
{
	// LAB 4: Your code here.
	set_pgfault_handler(pgfault);
	envid_t eid = sys_exofork();
	if(eid < 0) // error
		panic("couldn't fork child. %e",eid);
	else if(eid == 0) { // child
		thisenv = envs+ENVX(sys_getenvid());
		return 0;
	}
	else { //parent
		uint64_t r;
    		for (r = 0; r < (uint64_t)(UXSTACKTOP-PGSIZE); r += PGSIZE) {
    			if(	(vpml4e[VPML4E(r)] & PTE_P) &&
    				(vpde[VPDPE(r)] & PTE_P) &&
 	   			(vpd[VPD(r)] & PTE_P) && 
 	   			(vpt[VPN(r)] & PTE_P)) 
 	   			{	
					duppage(eid, VPN(r));
				}
			}
		
		//Duppage the stack for the child
		duppage(eid, VPN(USTACKTOP-PGSIZE));
		
		// Instead you need to allocate a fresh page in the child for the exception stack
		if((r= sys_page_alloc(eid, (void *)(UXSTACKTOP-PGSIZE), PTE_U|PTE_P|PTE_W)) < 0)
			panic("fork failed setting UXSTACK for child %e", r);
		
		//The parent sets the user page fault entrypoint for the child to look like its own.
		if((r= sys_env_set_pgfault_upcall(eid, thisenv->env_pgfault_upcall)) < 0) //
			panic("fork failed setting pgfault handler %e", r);
		
		//The child is now ready to run, so the parent marks it runnable.
		if((r= sys_env_set_status(eid, ENV_RUNNABLE)) < 0)
			panic("fork failed setting status %e", r);
		//cprintf("forked the child\n");
		return eid;
	}
	//panic("fork not implemented");
}
Exemple #7
0
// Is this virtual address mapped?
bool
va_is_mapped(void *va)
{
	return (vpml4e[VPML4E(va)] & PTE_P) && (vpde[VPDPE(va)] & PTE_P) && (vpd[VPD(va)] & PTE_P) && (vpt[PPN(va)] & PTE_P);
}