예제 #1
0
파일: syscall.c 프로젝트: Cai41/mit-6.828
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

//	panic("syscall not implemented");

	switch (syscallno) {
	case SYS_cputs:
		sys_cputs((char *)a1, a2);
		break;
	case SYS_cgetc:
		return sys_cgetc();
	case SYS_env_destroy:
		return sys_env_destroy(a1);
	case SYS_getenvid:
		return sys_getenvid();
	case SYS_yield:
		sys_yield();
		break;
	case SYS_page_alloc:
		return sys_page_alloc(a1, (void *)a2, a3);
	case SYS_page_map:
		return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5);
	case SYS_page_unmap:
		return sys_page_unmap(a1, (void *)a2);
	case SYS_env_set_status:
		return sys_env_set_status(a1, a2);
	case SYS_exofork:
		return sys_exofork();
	case SYS_env_set_pgfault_upcall:
		return sys_env_set_pgfault_upcall(a1, (void *)a2);
	case SYS_ipc_try_send:
		return sys_ipc_try_send(a1, a2, (void*)a3, a4);
	case SYS_ipc_recv:
		return sys_ipc_recv((void*)a1);
	case SYS_env_set_trapframe:
		return sys_env_set_trapframe(a1, (struct Trapframe *)a2);
	case SYS_time_msec:
		return sys_time_msec();
	case SYS_trans_pkt:
		return sys_trans_pkt((void*)a1, a2);
	case SYS_recv_pkt:
		return sys_recv_pkt((void *)a1, (size_t *)a2);
	default:
		return -E_INVAL;
	}

	return 0;
}
예제 #2
0
파일: syscall.c 프로젝트: yuki252111/os
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	switch (syscallno){
		case SYS_getenvid:
			return sys_getenvid();
		case SYS_cputs:
			sys_cputs((const char*)a1, a2);
			return 0;
		case SYS_cgetc:
			return sys_cgetc();
		case SYS_env_destroy:
			return sys_env_destroy(a1);
		case SYS_map_kernel_page:
			return sys_map_kernel_page((void*)a1, (void*)a2);
		case SYS_sbrk:
			return sys_sbrk(a1);
		case SYS_yield:
			sys_yield();
			return 0;
		case SYS_exofork:
			return sys_exofork();
		case SYS_env_set_status:
			return sys_env_set_status((envid_t)a1, (int)a2);
		case SYS_page_alloc:
			return sys_page_alloc((envid_t)a1, (void *)a2, 
						(int)a3);
		case SYS_page_map:
			return sys_page_map((envid_t)*((uint32_t*)a1),
					(void*)*((uint32_t*)a1+1), 
					(envid_t)*((uint32_t*)a1+2), 
					(void*)*((uint32_t*)a1+3), 
					(int)*((uint32_t*)a1+4));
		case SYS_page_unmap:
			return sys_page_unmap((envid_t)a1, (void*)a2);
		case SYS_env_set_priority:
			return sys_env_set_priority((envid_t)a1, (int) a2);
		case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall((envid_t)a1,
						 (void*)a2);
		case SYS_ipc_recv:
			return sys_ipc_recv((void*)a1);
		case SYS_ipc_try_send:
			return sys_ipc_try_send((envid_t)a1, a2, 
						(void*)a3, (int)a4);
		default:
			return -E_INVAL;
	}
}
예제 #3
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	//panic("syscall not implemented");
	int ret = 0;

	switch (syscallno) {
	case SYS_cputs:
		sys_cputs((char*)a1, a2);
		ret = 0;
		break;
	case SYS_cgetc:
		ret = sys_cgetc();
		break;
	case SYS_getenvid:
		ret = sys_getenvid();
		break;
	case SYS_env_destroy:
		sys_env_destroy(a1);
		ret = 0;
		break;
	case SYS_yield:
		sys_yield();
		break;
	case SYS_exofork:
		return sys_exofork();
		break;
	case SYS_page_alloc:
		return sys_page_alloc(a1, (void*)a2, a3);
		break;
	case SYS_page_map:
		return sys_page_map(a1, (void*)a2, a3, (void*)a4, a5);
		break;
	case SYS_page_unmap:
		return sys_page_unmap(a1, (void*)a2);
		break;
	case SYS_env_set_status:
		return sys_env_set_status(a1, a2);
		break;
	case SYS_env_set_pgfault_upcall:
		return sys_env_set_pgfault_upcall(a1, (void*)a2);
		break;
	default:
		ret = -E_INVAL;
	}

	return ret;
}
예제 #4
0
파일: syscall.c 프로젝트: ajsbu/cse506
// Dispatches to the correct kernel function, passing the arguments.
	int64_t
syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	uint64_t retval = 0;

	switch (syscallno) {
		case SYS_cputs:
			sys_cputs((char *) a1, (size_t) a2);
			return retval;
		case SYS_cgetc:
			return (int64_t) sys_cgetc();
		case SYS_getenvid:
			return (int64_t) sys_getenvid();
		case SYS_env_destroy:
			return (int64_t) sys_env_destroy((envid_t) a1);
		case SYS_yield:
			sys_yield();
			return retval;
		case SYS_exofork:
			return (int64_t)sys_exofork();
		case SYS_page_alloc:
			return (int64_t)sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
		case SYS_page_map:
			return (int64_t)sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);
		case SYS_page_unmap:
			return (int64_t)sys_page_unmap((envid_t)a1, (void *)a2);
		case SYS_env_set_status:
			return (int64_t)sys_env_set_status((envid_t)a1, (int)a2);
		case SYS_env_set_pgfault_upcall:
			return (int64_t)sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
		case SYS_ipc_try_send:
			return (int64_t) sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (unsigned) a4);
		case SYS_ipc_recv:
			return (int64_t)sys_ipc_recv((void*)a1);
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
		case SYS_time_msec:
			return sys_time_msec();
		case SYS_net_try_send:
			return sys_net_try_send((char *) a1, (int) a2);
		case SYS_net_try_receive:
			return sys_net_try_receive((char *) a1, (int *) a2);
		default:
			return -E_INVAL;
	}

	panic("syscall not implemented");
}
예제 #5
0
파일: fd.c 프로젝트: AlexandrSalin/mit-jos
// Make file descriptor 'newfdnum' a duplicate of file descriptor 'oldfdnum'.
// For instance, writing onto either file descriptor will affect the
// file and the file offset of the other.
// Closes any previously open file descriptor at 'newfdnum'.
// This is implemented using virtual memory tricks (of course!).
int
dup(int oldfdnum, int newfdnum)
{
	int i, r;
	char *ova, *nva;
	pte_t pte;
	struct Fd *oldfd, *newfd;

	if ((r = fd_lookup(oldfdnum, &oldfd)) < 0)
		return r;
	close(newfdnum);

	newfd = INDEX2FD(newfdnum);
	ova = fd2data(oldfd);
	nva = fd2data(newfd);

	if (vpd[PDX(ova)]) {
		for (i = 0; i < PTSIZE; i += PGSIZE) {
			pte = vpt[VPN(ova + i)];
			if (pte&PTE_P) {
				// should be no error here -- pd is already allocated
				if ((r = sys_page_map(0, ova + i, 0, nva + i, pte & PTE_USER)) < 0)
					goto err;
			}
		}
	}

	if ((r = sys_page_map(0, oldfd, 0, newfd, vpt[VPN(oldfd)] & PTE_USER)) < 0)
		goto err;

	return newfdnum;

err:
	sys_page_unmap(0, newfd);
	for (i = 0; i < PTSIZE; i += PGSIZE)
		sys_page_unmap(0, nva + i);
	return r;
}
예제 #6
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 uvpd, uvpt, 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 childid = sys_exofork();
	if(childid < 0)
		panic("Fork Failed\n");
	if(childid == 0) {
		thisenv = &envs[ENVX(sys_getenvid())];
		return 0;
	}

	int i, j;
	for(i = 0; i < PDX(UTOP); i++) {
		if (!(uvpd[i] & PTE_P)) continue;
		for(j = 0; (j < 1024) && (i*NPDENTRIES + j < PGNUM(UXSTACKTOP - PGSIZE)); j++ ) {
			if(!uvpt[i*NPDENTRIES + j] & PTE_P) continue;
			if(duppage(childid, i*NPDENTRIES + j) < 0)
				panic("dup page failed");
		}
	}
	if ((sys_page_alloc(childid, (void *)(UXSTACKTOP - PGSIZE), PTE_U | PTE_P | PTE_W)) < 0) {
          panic("Allocation of page for Exception stack cups!\n");
        }

        if ((sys_env_set_pgfault_upcall(childid, thisenv->env_pgfault_upcall)) < 0) {
          panic("Unable to set child process' upcall");
        }

	 // Copy own uxstack to temp page
        memmove((void *)(UXSTACKTOP - PGSIZE), PFTEMP, PGSIZE);
	int r;
        // Unmap temp page
        if (sys_page_unmap(sys_getenvid(), PFTEMP) < 0) {
                return -1;
        }        

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

        if ((r = sys_env_set_status(childid, ENV_RUNNABLE)) < 0) {
                cprintf("sys_env_set_status: error %e\n", r);
                return -1;
        }


	return childid;
	panic("fork not implemented");
}
예제 #7
0
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
  void *addr = (void*)utf->utf_fault_va;
  uint32_t err = utf->utf_err;
  int r;
  envid_t e_id = sys_getenvid();

  // // Check that the faulting access was (1) a write, and (2) to a
  // // copy-on-write page.  If not, panic.
  // // Hint:
  // //   Use the read-only page table mappings at uvpt
  // //   (see <inc/memlayout.h>).

  // // LAB 4: Your code here.
  //cprintf("Calling pgfault");
  if (!(err & FEC_WR)) {
    panic("user page fault called on read (should be write)");
  }
  // if (!(uvpt[PGNUM(addr)] & PTE_COW)) {
  //   panic("\n----------------------------------\nuser page fault called on non COW page with: \nAddress %p \nEnvironment=%d", addr, e_id);
  // }

  // Allocate a new page, map it at a temporary location (PFTEMP),
  // copy the data from the old page to the new page, then move the new
  // page to the old page's address.
  // Hint:
  //   You should make three system calls.

  // LAB 4: Your code here.

  void* page_addr = ROUNDDOWN(addr, PGSIZE);
  
  int alloc_err = sys_page_alloc(e_id, PFTEMP, PTE_P | PTE_U | PTE_W);
  if (alloc_err) {
    panic("sys_page_alloc failed");
  }
  memcpy(PFTEMP, page_addr, PGSIZE);
  int map_err = sys_page_map(e_id, PFTEMP, 
                             e_id, page_addr, 
                             PTE_P | PTE_U | PTE_W);
  if (map_err) {
    panic("sys_page_map failed");
  }
  int umap_err = sys_page_unmap(e_id, PFTEMP);
  if (umap_err) {
    panic("sys_page_unmap failed");
  }
  return;
}
예제 #8
0
파일: serv.c 프로젝트: ichaos/jos
void
serve(void)
{
	uint32_t req, whom;
	int perm;

	while (1) {
		perm = 0;
		req = ipc_recv((int32_t *) &whom, (void *) REQVA, &perm);
		if (debug)
			cprintf("fs req %d from %08x [page %08x: %s]\n",
				req, whom, vpt[VPN(REQVA)], REQVA);

		// All requests must contain an argument page
		if (!(perm & PTE_P)) {
			cprintf("Invalid request from %08x: no argument page\n",
				whom);
			continue; // just leave it hanging...
		}

		switch (req) {
		case FSREQ_OPEN:
			serve_open(whom, (struct Fsreq_open*)REQVA);
			break;
		case FSREQ_MAP:
			serve_map(whom, (struct Fsreq_map*)REQVA);
			break;
		case FSREQ_SET_SIZE:
			serve_set_size(whom, (struct Fsreq_set_size*)REQVA);
			break;
		case FSREQ_CLOSE:
			serve_close(whom, (struct Fsreq_close*)REQVA);
			break;
		case FSREQ_DIRTY:
			serve_dirty(whom, (struct Fsreq_dirty*)REQVA);
			break;
		case FSREQ_REMOVE:
			serve_remove(whom, (struct Fsreq_remove*)REQVA);
			break;
		case FSREQ_SYNC:
			serve_sync(whom);
			break;
		default:
			cprintf("Invalid request code %d from %08x\n",
                                whom, req);
			break;
		}
		sys_page_unmap(0, (void*) REQVA);
	}
}
예제 #9
0
파일: fork.c 프로젝트: ren85/jos2006
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;
	pte_t pte;
	envid_t envid;
	void *va;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at vpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.

	//check # 1 - ren
	 if (!(err & FEC_WR))
		panic ("pgfault() - page fault caused not by write!");
	//check # 2 - ren
	pte = (pte_t)vpt[VPN(addr)];
	pte &= 0xF00;
	if (pte != PTE_COW)
		panic ("pgfault() - access was not to a copy-on-write page!");	
	
	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.
	
	// LAB 4: Your code here.
	
	envid = sys_getenvid();
	va = (void*)ROUNDDOWN(addr, PGSIZE);

	if ( (r = sys_page_alloc(envid, PFTEMP, PTE_U | PTE_P | PTE_W)) < 0)
		sys_env_destroy(envid);

	memcpy(PFTEMP, va, PGSIZE);

	if ( (r = sys_page_map(envid, PFTEMP, envid, va, PTE_U | PTE_P | PTE_W)) < 0)
		sys_env_destroy(envid);
	
	if ((r = sys_page_unmap(envid, PFTEMP)) < 0)		//fourth system call, hm - ren
		sys_env_destroy(envid);
}
예제 #10
0
파일: dumbfork.c 프로젝트: eewayhsu/6.828
void
duppage(envid_t dstenv, void *addr)
{
	int r;

	// This is NOT what you should do in your fork.
	if ((r = sys_page_alloc(dstenv, addr, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_alloc: %e", r);
	if ((r = sys_page_map(dstenv, addr, 0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_map: %e", r);
	memmove(UTEMP, addr, PGSIZE);
	if ((r = sys_page_unmap(0, UTEMP)) < 0)
		panic("sys_page_unmap: %e", r);
}
예제 #11
0
파일: fs.c 프로젝트: ren85/jos2006
// Make sure this block is unmapped.
void
unmap_block(uint32_t blockno)
{
	int r;

	if (!block_is_mapped(blockno))
		return;

	assert(block_is_free(blockno) || !block_is_dirty(blockno));

	if ((r = sys_page_unmap(0, diskaddr(blockno))) < 0)
		panic("unmap_block: sys_mem_unmap: %e", r);
	assert(!block_is_mapped(blockno));
}
예제 #12
0
파일: spawn.c 프로젝트: ichaos/jos
static int
map_segment(envid_t child, uintptr_t va, size_t memsz,
	int fd, size_t filesz, off_t fileoffset, int perm)
{
	int i, r;
	void *blk;

	//cprintf("map_segment %x+%x\n", va, memsz);

	if ((i = PGOFF(va))) {
		va -= i;
		memsz += i;
		filesz += i;
		fileoffset -= i;
	}

	for (i = 0; i < memsz; i += PGSIZE) {
		if (i >= filesz) {
			// allocate a blank page
			if ((r = sys_page_alloc(0, UTEMP, perm)) < 0) {
				return r;
			}
                        memset(UTEMP, 0, PGSIZE);
			sys_page_map(0, UTEMP, child, (void *)(va+i), perm);
			return r;
		} else {
			// from file
			if (perm & PTE_W) {
				// must make a copy so it can be writable
				if ((r = sys_page_alloc(0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
					return r;
				if ((r = seek(fd, fileoffset + i)) < 0)
					return r;
				if ((r = read(fd, UTEMP, MIN(PGSIZE, filesz-i))) < 0)
					return r;
                                memset(UTEMP+MIN(PGSIZE, filesz-i), 0, PGSIZE-MIN(PGSIZE, filesz-i));
				if ((r = sys_page_map(0, UTEMP, child, (void*) (va + i), perm)) < 0)
					panic("spawn: sys_page_map data: %e", r);
				sys_page_unmap(0, UTEMP);
			} else {
				// can map buffer cache read only
				if ((r = read_map(fd, fileoffset + i, &blk)) < 0)
					return r;
				if ((r = sys_page_map(0, blk, child, (void*) (va + i), perm)) < 0)
					panic("spawn: sys_page_map text: %e", r);
			}
		}
	}
	return 0;
}
예제 #13
0
파일: fd.c 프로젝트: AlexandrSalin/mit-jos
// Frees file descriptor 'fd' by closing the corresponding file
// and unmapping the file descriptor page.
// If 'must_exist' is 0, then fd can be a closed or nonexistent file
// descriptor; the function will return 0 and have no other effect.
// If 'must_exist' is 1, then fd_close returns -E_INVAL when passed a
// closed or nonexistent file descriptor.
// Returns 0 on success, < 0 on error.
int
fd_close(struct Fd *fd, bool must_exist)
{
	struct Fd *fd2;
	struct Dev *dev;
	int r;
	if ((r = fd_lookup(fd2num(fd), &fd2)) < 0
	    || fd != fd2)
		return (must_exist ? r : 0);
	if ((r = dev_lookup(fd->fd_dev_id, &dev)) >= 0)
		r = (*dev->dev_close)(fd);
	// Make sure fd is unmapped.  Might be a no-op if
	// (*dev->dev_close)(fd) already unmapped it.
	(void) sys_page_unmap(0, fd);
	return r;
}
예제 #14
0
// Send a proof over IPC
void send_proof(envid_t to, Proof p) {
  // Copy the proof to UTEMP
  sys_page_alloc(0, UTEMP, PTE_U | PTE_W);
  Heap tempHeap;
  init_heap(&tempHeap, UTEMP, PGSIZE);
  Heap *oldHeap = set_heap(&tempHeap);
  Proof copy = proof_cp(p);
  size_t offset = (uintptr_t)copy - (uintptr_t)UTEMP;

  // Send the proof
  ipc_send(to, offset, UTEMP, PTE_U);
  sys_page_unmap(0, UTEMP);

  // Reset the heap
  set_heap(oldHeap);
}
예제 #15
0
파일: fork.c 프로젝트: reddragon/cse506
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at vpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.
	//cprintf("In the handler of pgfault with va:%x\n", addr);
	cprintf("Entered in pagefault entered. Fault va: %p, err: %d, perm: %d, VPN(addr): %d, addr>>PGSHIFT: %d\n", \
			addr, err, PTE_COW, vpt[VPN(addr)], (uint32_t)addr>>PGSHIFT);
	if(vpt[VPN(addr)] == 0 || addr == 0)
	{
		cprintf("In \n");
		return;
	}
	if(!((err & FEC_WR) && (vpt[VPN(addr)] & PTE_COW)))
		panic("Incorrectly entered in pagefault entered. Fault va: %p, err: %d, perm: %d, VPN(addr): %d, addr>>PGSHIFT: %d\n", \
			addr, err, PTE_COW, vpt[VPN(addr)], (uint32_t)addr>>PGSHIFT);
	

	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.
	// Allocate a new page at PFTEMP
	//cprintf("Check: %04x %04x\n", env->env_id, sys_getenvid());
	sys_page_alloc(0, (void *)PFTEMP, PTE_W | PTE_U | PTE_P);
	// Copy the old contents into the new page
	memmove((void *)PFTEMP, (void *)ROUNDDOWN((uint32_t)addr, PGSIZE), PGSIZE);	
	// Now map the page to the 
	sys_page_map(0, (void *)PFTEMP, \
		0, (void *)ROUNDDOWN((uint32_t)addr,PGSIZE), PTE_W | PTE_U | PTE_P);		

	sys_page_unmap(0, PFTEMP);
	//panic("pgfault not implemented");
}
예제 #16
0
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;
    //cprintf("envid: %x, eip: %x, fault_va: %x\n", thisenv->env_id, utf->utf_eip, addr);

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at uvpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.
    if (!(err & FEC_WR))
    {
        panic("pgfault: error is not a write. it is %e with falting addr 0x%x\n", err, addr);
    }

    if (!(uvpt[PGNUM(addr)] & PTE_COW))
    {
        panic("pgfault: page not COW\n");
    }

	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.

	// LAB 4: Your code here.
    if ((r = sys_page_alloc(0, PFTEMP, PTE_U|PTE_W|PTE_P)) < 0)
    {
        panic("pgfault: sys_page_alloc fail %e", r);
    }
    memmove(PFTEMP, ROUNDDOWN(addr, PGSIZE), PGSIZE);
    if ((r = sys_page_map(0, PFTEMP, 0, ROUNDDOWN(addr, PGSIZE), PTE_P|PTE_U|PTE_W)) < 0)
    {
        panic("pgfault: sys_page_map: %e", r);
    }

    if ((r = sys_page_unmap(0, PFTEMP)) < 0)
    {
        panic("pgfault: sys_page_unmap: %e", r);
    }
}
예제 #17
0
파일: syscall.c 프로젝트: bdmalab/6.828
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	switch (syscallno) {
		case (SYS_cputs):
			sys_cputs((const char *) a1, a2);
			return 0;
		case (SYS_cgetc):
			return sys_cgetc();
		case (SYS_getenvid):
			return sys_getenvid();
		case (SYS_env_destroy):
			return sys_env_destroy(a1, a2);
		case (SYS_yield):
			sys_yield();
			return 0;
		case (SYS_exofork):
			return sys_exofork();
		case (SYS_env_set_status):
			return sys_env_set_status(a1, a2);
		case (SYS_page_alloc):
			return sys_page_alloc(a1, (void *) a2, a3);
		case (SYS_page_map):
			return sys_page_map(a1, (void *) a2, a3, (void *) a4, a5);
		case (SYS_page_unmap):
			return sys_page_unmap(a1, (void *) a2);
		case (SYS_env_set_pgfault_upcall):
			return sys_env_set_pgfault_upcall(a1, (void *) a2);
		case (SYS_ipc_try_send):
			return sys_ipc_try_send(a1, a2, (void *) a3, a4);
		case (SYS_ipc_recv):
			return sys_ipc_recv((void *) a1);
		case (SYS_env_set_trapframe):
			return sys_env_set_trapframe(a1, (struct Trapframe *) a2);
		case (SYS_time_msec):
			return sys_time_msec();
		case (SYS_e1000_transmit):
			return sys_e1000_transmit(a1, (char *) a2, a3);
	default:
		return -E_INVAL;
	}
}
예제 #18
0
파일: syscall.c 프로젝트: bosswissam/djos
int
sys_env_set_thisenv(envid_t envid, void *thisenv)
{
	void *pgva = (void *) ROUNDDOWN(thisenv, PGSIZE);

	if (sys_page_map(envid, pgva, curenv->env_id, (void *) UTEMP, 
			 PTE_P|PTE_U|PTE_W) < 0) 
		return -E_INVAL;

	*((struct Env **)(UTEMP + PGOFF(thisenv))) = 
		&((struct Env *)UENVS)[ENVX(envid)];

	if (sys_page_unmap(curenv->env_id, (void *) UTEMP) < 0)
		return -E_INVAL;

	return 0;
}
예제 #19
0
파일: fork.c 프로젝트: HVNT/6.828
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
    void *addr = (void *) utf->utf_fault_va;
    uint32_t err = utf->utf_err;
    int r;

    // Check that the faulting access was (1) a write, and (2) to a
    // copy-on-write page.  If not, panic.
    // Hint:
    //   Use the read-only page table mappings at vpt
    //   (see <inc/memlayout.h>).

    // LAB 4: Your code here.
    // seanyliu
    if (!(err & FEC_WR) || !(vpt[VPN(addr)] & PTE_COW)) {
        panic("pgfault, err != FEC_WR or not copy-on-write page");
    }

    // Allocate a new page, map it at a temporary location (PFTEMP),
    // copy the data from the old page to the new page, then move the new
    // page to the old page's address.
    // Hint:
    //   You should make three system calls.
    //   No need to explicitly delete the old page's mapping.

    // LAB 4: Your code here.
    // seanyliu
    addr = ROUNDDOWN(addr, PGSIZE);
    // Allocate a new page, map it at a temporary location (PFTEMP),
    if ((r = sys_page_alloc(sys_getenvid(), (void *)PFTEMP, PTE_U | PTE_W | PTE_P)) < 0) {
        panic("pgfault: sys_page_alloc %d", r);
    }
    // copy the data from the old page to the new page
    memmove(PFTEMP, addr, PGSIZE);
    // move the new page to the old page's address.
    if ((r = sys_page_map(sys_getenvid(), PFTEMP, sys_getenvid(), addr, PTE_U | PTE_W | PTE_P)) < 0) {
        panic("pgfault: sys_page_map %d", r);
    }
    if ((r = sys_page_unmap(sys_getenvid(), PFTEMP)) < 0) {
        panic("pgfault: sys_page_unmap %d", r);
    }

    //panic("pgfault not implemented");
}
예제 #20
0
파일: fork.c 프로젝트: ksandeep/JOS-Labs
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	pte_t pte;
	int r;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at vpt
	//   (see <inc/memlayout.h>).
		
	// LAB 4: Your code here.
	if ((err & FEC_WR) != FEC_WR)
	{
		if (debug)
			cprintf("Error caught = %x\n", err);
		panic ("user panic in lib/fork.c - pgfault(): faulting access is not write\n");
	}
	pte = vpt[VPN(addr)];
	if ((pte & PTE_COW) != PTE_COW)
		panic ("user panic in lib/fork.c - pgfault(): faulting access is not to a COW page\n");

	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.
	if ((r = sys_page_alloc(0, (void*)PFTEMP, PTE_P | PTE_U | PTE_W)) < 0)
		panic ("user panic in lib/fork.c - pgfault(): sys_page_alloc: %e", r);
	
	memmove((void*)PFTEMP, (void*)ROUNDDOWN(addr,PGSIZE), PGSIZE);
		
	if ((r = sys_page_map(0, (void*)PFTEMP, 0, (void*)ROUNDDOWN(addr,PGSIZE), PTE_P | PTE_U | PTE_W)) < 0)	
		panic ("user panic in lib/fork.c - pgfault(): sys_page_map: %e", r);
	if ((r = sys_page_unmap(0, (void*)PFTEMP)) < 0)
		panic ("user panic in lib/fork.c - pgfault(): sys_page_unmap: %e", r);
	// panic("pgfault not implemented");
}
예제 #21
0
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
    static void
pgfault(struct UTrapframe *utf)
{
    void *addr = (void *) utf->utf_fault_va;
    uint32_t err = utf->utf_err;
    int r;

    // Check that the faulting access was (1) a write, and (2) to a
    // copy-on-write page.  If not, panic.
    // Hint:
    //   Use the read-only page table mappings at vpt
    //   (see <inc/memlayout.h>).

    // LAB 4: Your code here.
	
	pte_t pte = vpt[((uint64_t) addr / PGSIZE)];

        if (!(err & FEC_WR))
                panic("Faulting access write(FEC_WR) failed = 0x%x: err %x\n\n", (uint64_t) addr, err);

        if (!(pte & PTE_COW))
                panic("Faulting access copy-on-write(PTE_COW) failed = 0x%x, env_id 0x%x\n", (uint64_t) addr, thisenv->env_id);
    // Allocate a new page, map it at a temporary location (PFTEMP),
    // copy the data from the old page to the new page, then move the new
    // page to the old page's address.
    // Hint:
    //   You should make three system calls.
    //   No need to explicitly delete the old page's mapping.

    // LAB 4: Your code here.
	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, ROUNDDOWN(addr, PGSIZE), PGSIZE);

        void *vaTemp = (void *) ROUNDDOWN((uint64_t) addr, PGSIZE);
        if ((r = sys_page_map(0, (void *)PFTEMP, 0, 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);
    //panic("pgfault not implemented");
}
예제 #22
0
파일: fork.c 프로젝트: chenkexin/jos
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at uvpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.

	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.

  if (!((err & FEC_WR) && (uvpd[PDX(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_COW)))
      panic("not copy-on-write");

  addr = ROUNDDOWN(addr, PGSIZE);
  
  if (sys_page_alloc(0, PFTEMP, PTE_W|PTE_U|PTE_P) < 0)
      panic("sys_page_alloc");
   
  memcpy(PFTEMP, addr, PGSIZE);
 
  if (sys_page_map(0, PFTEMP, 0, addr, PTE_W|PTE_U|PTE_P) < 0)
      panic("sys_page_map");

  if (sys_page_unmap(0, PFTEMP) < 0)
      panic("sys_page_unmap");
 
  return;
//	panic("pgfault not implemented");
}
예제 #23
0
파일: syscall.c 프로젝트: ren85/jos2006
// Dispatches to the correct kernel function, passing the arguments.
uint32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	switch (syscallno){
	
		case SYS_cputs:
			sys_cputs( (const char *)a1, a2);
			return 0;
		case SYS_cgetc:
			return sys_cgetc();
		case SYS_getenvid:
			return sys_getenvid();
		case SYS_env_destroy:
			return sys_env_destroy(a1);		
		case SYS_yield:
			sys_yield();
			return 0;
		case SYS_exofork:
			return sys_exofork();
		case SYS_env_set_status:
			return sys_env_set_status(a1, a2);
		case SYS_page_alloc:	
			return sys_page_alloc(a1, (void *)a2, a3);
		case SYS_page_map:
			return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5);
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe(a1, (struct Trapframe *)a2);		
		case SYS_page_unmap:
			return sys_page_unmap(a1, (void *)a2);
		case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall(a1, (void *)a2);
		case SYS_ipc_try_send:
			return sys_ipc_try_send(a1, a2, (void *)a3, a4);
		case SYS_ipc_recv:
			return sys_ipc_recv((void *)a1);

		default: panic("this syscall ( %d )is not yet implemented", syscallno); 
	}
}
예제 #24
0
void
duppage(envid_t dstenv, void *addr)
{
    int r;

    // This is NOT what you should do in your fork.
    // 这个实现太trick了:
    // 先在dstenv的addr上分配一页,然后将dstenv的addr所在的页面映射到
    // 当前进程的UTEMP位置,最后将current的addr的内容copy到current的
    // UTEMP, 因为经过sys_page_map()之后,current TEMP和dstenv的addr
    // 指向同一实际物理页面,这样就实现了把current'addr -> dstenv's addr
    // 的功能。最后还要对current's UTEMP进行umap。
    if ((r = sys_page_alloc(dstenv, addr, PTE_P|PTE_U|PTE_W)) < 0)
        panic("sys_page_alloc: %e", r);
    if ((r = sys_page_map(dstenv, addr, 0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
        panic("sys_page_map: %e", r);
    memmove(UTEMP, addr, PGSIZE);
    if ((r = sys_page_unmap(0, UTEMP)) < 0)
        panic("sys_page_unmap: %e", r);
}
예제 #25
0
파일: syscall.c 프로젝트: gzs715/JOS
//new added sys_for_fork to 
//augment the system call interface 
//so that it is possible to send a batch of system calls at once
//because switching into the kernel has non-trivial cost!!!
static int
sys_for_fork(envid_t envid, void * func, int status)
{
	int r;
	int perm = PTE_W|PTE_P|PTE_U;
	void * va = (void*)(UXSTACKTOP - PGSIZE);

	if((r = sys_page_alloc(envid, va, perm)) < 0)
			return r;
	if ((r = sys_page_map(envid, va, curenv->env_id, UTEMP, perm)) < 0)
			panic("sys_page_map: %e", r);
	memmove(UTEMP, va, PGSIZE);
	if ((r = sys_page_unmap(curenv->env_id, UTEMP)) < 0)
			panic("sys_page_unmap: %e", r);
	if ((r = sys_env_set_pgfault_upcall(envid, func)) < 0)
		return r;
	if ((r = sys_env_set_status(envid, status)) < 0)
		return r;
	return 0;
}
예제 #26
0
파일: dumbfork.c 프로젝트: Guitang-Lan/OS
// dstenv is the child's env
// addr is the va of the parent
void
duppage(envid_t dstenv, void *addr)
{
	int r;

	// This is NOT what you should do in your fork.
	// allocate a page starting at addr in child's process space
	if ((r = sys_page_alloc(dstenv, addr, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_alloc: %e", r);

	// 								    srcenvid  srcva  dstenvid  dstva
	if ((r = sys_page_map(dstenv,   addr,      0,    UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_map: %e", r);

	memmove(UTEMP, addr, PGSIZE);

	if ((r = sys_page_unmap(0, UTEMP)) < 0)
		panic("sys_page_unmap: %e", r);

}
예제 #27
0
파일: syscall.c 프로젝트: bosswissam/djos
int // user call to lease self
sys_migrate(void *thisenv)
{
	envid_t jdos_client = 0;
	struct Env *e;
	int i, r;

	for (i = 0; i < NENV; i++) {
		if (envs[i].env_type == ENV_TYPE_JDOSC) {
			jdos_client = envs[i].env_id;
			break;
		}
	}

	// jdos client running?
	if (!jdos_client) return -E_BAD_ENV; 

	if ((r = envid2env(jdos_client, &e, 0)) < 0) return r;

	// Mark leased and try to migrate
	curenv->env_status = ENV_SUSPENDED; 
	sys_page_alloc(curenv->env_id, (void *) IPCSND, PTE_U|PTE_P|PTE_W);
	*((envid_t *) IPCSND) = curenv->env_id;
	*((void **)(IPCSND + sizeof(envid_t))) = thisenv;

	//can't write to page
	r = sys_ipc_try_send(jdos_client, CLIENT_LEASE_REQUEST, 
			     (void *) IPCSND, PTE_U|PTE_P); 

	sys_page_unmap(curenv->env_id, (void *) IPCSND);

	// Failed to migrate, back to running!
	if (r < 0) {
		cprintf("==> sys_migrate: failed to send ipc %d\n", r);
		curenv->env_status = ENV_RUNNABLE;
		return r;
	}

	// Migrated! BOOM!
	return 0;
}
예제 #28
0
파일: fork.c 프로젝트: RudoIf/J-O-S
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;
	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at vpt
	//   (see <inc/memlayout.h>).
	//cprintf("pgfault: do page fault here %x\n",utf->utf_eflags);
	// LAB 4: Your code here.
	if((err & FEC_WR) == 0)
		panic("pgfault: fault is not a write (err: %08x va: %08x ip: %08x)",err, addr, utf->utf_eip);
	if ((vpd[PDX(addr)] & PTE_P) == 0 || (vpt[PGNUM(addr)] & PTE_COW) == 0)
		panic ("pgfault: not a write or attempting to access a non-COW page");
	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.
	if ((r = sys_page_alloc (0, (void *)PFTEMP, PTE_U|PTE_P|PTE_W)) < 0)
		panic ("pgfault: page allocation failed : %e", r);
	addr = ROUNDDOWN (addr, PGSIZE);
	memmove (PFTEMP, addr, PGSIZE);
	if((r = sys_page_map (0, PFTEMP, 0, addr, PTE_U|PTE_P|PTE_W)) < 0)
		panic ("pgfault: page mapping failed : %e", r);
	if((r = sys_page_unmap(0,PFTEMP)) < 0)
		panic("pgfault: page unmapping failed : %e", r);
	//cprintf("pgfault: finish\n");
	/* int gaga = 0; */
	/* __asm__ volatile("movl %%esp, %0\n\t" */
	/* 		 :"=r"(gaga) */
	/* 		 ::); */
	/* cprintf("gaga----------%x\n", gaga); */
	//panic("pgfault not implemented");
}
예제 #29
0
파일: bc.c 프로젝트: YYmooon/439h
// Test that the block cache works, by smashing the superblock and
// reading it back.
static void
check_bc(void)
{
    cprintf("Starting..\n");
    struct Super backup;

    // back up super block
    memmove(&backup, diskaddr(1), sizeof(backup));
    BC_DEBUG("Wrote superblock to disk ram block..\n");
    BC_DEBUG("in memory magic number: %08x\n", ((struct Super*)diskaddr(1))->s_magic);

    // smash it
    strcpy(diskaddr(1), "OOPS!\n");
    flush_block(diskaddr(1));
    assert(va_is_mapped(diskaddr(1)));
    assert(!va_is_dirty(diskaddr(1)));
    cprintf("Smashed disk superblock..\n");

    // clear it out
    sys_page_unmap(0, diskaddr(1));
    assert(!va_is_mapped(diskaddr(1)));
    cprintf("Unmapped superblock va..\n");

    // read it back in
    assert(strcmp(diskaddr(1), "OOPS!\n") == 0);
    cprintf("re-read superblock va..\n");

    // fix it
    memmove(diskaddr(1), &backup, sizeof(backup));
    assert(memcmp(diskaddr(1), &backup, sizeof(backup)) == 0);
    
    flush_block(diskaddr(1));

    assert(memcmp(diskaddr(1), &backup, sizeof(backup)) == 0);
    BC_DEBUG("backup magic number   : %08x\n", backup.s_magic);
    BC_DEBUG("in memory magic number: %08x\n", ((struct Super*)diskaddr(1))->s_magic);
    BC_DEBUG("expected magic value  : %08x\n", FS_MAGIC);
    cprintf("Fixed superblock..\n");

    cprintf("block cache is good\n");
}
예제 #30
0
파일: serv.c 프로젝트: nitin-aggarwal/JOS
void
serve(void)
{
	uint32_t req, whom;
	int perm, r;
	void *pg;
	
	while (1) {
		perm = 0;
		req = ipc_recv((int32_t *) &whom, fsreq, &perm);
		if (debug)
			cprintf("fs req %d from %08x [page %08x: %08x]\n",
				req, whom, vpt[VPN(fsreq)], fsreq);
		
		// All requests must contain an argument page
		if (!(perm & PTE_P)) {
			cprintf("Invalid request from %08x: no argument page\n",
				whom);
			continue; // just leave it hanging...
		}

		pg = NULL;
		if (req == FSREQ_OPEN) {
	
//cprintf("\nserv.c 444444\n");
//cprintf("\nwhom : 0x%08x fsreq : 0x%08x pg : 0x%08x perm 0x%08x\n", whom, fsreq, &pg, &perm);
			r = serve_open(whom, (struct Fsreq_open*)fsreq, &pg, &perm);
			//cprintf("serveopen return addr %x \n", pg);
//cprintf("\nserv.c 55555\n");
		} else if (req < NHANDLERS && handlers[req]) {
			r = handlers[req](whom, fsreq);
		} else {
			cprintf("Invalid request code %d from %08x\n", whom, req);
			r = -E_INVAL;
		}
		
		ipc_send(whom, r, pg, perm);
		sys_page_unmap(0, fsreq);
//	cprintf("\nend of serve while loop in serv.c\n");
	}
}