cowtest fixed and try to finish usertests
This commit is contained in:
@@ -16,6 +16,9 @@ void kernelvec();
|
||||
|
||||
extern int devintr();
|
||||
|
||||
typedef uint64 pte_t;
|
||||
pte_t *walk(pagetable_t pagetable, uint64 va, int alloc);
|
||||
|
||||
void
|
||||
trapinit(void)
|
||||
{
|
||||
@@ -50,7 +53,10 @@ usertrap(void)
|
||||
// save user program counter.
|
||||
p->trapframe->epc = r_sepc();
|
||||
|
||||
if(r_scause() == 8){
|
||||
uint64 scause = r_scause();
|
||||
uint64 stval = r_stval();
|
||||
|
||||
if(scause == 8){
|
||||
// system call
|
||||
|
||||
if(killed(p))
|
||||
@@ -67,6 +73,23 @@ usertrap(void)
|
||||
syscall();
|
||||
} else if((which_dev = devintr()) != 0){
|
||||
// ok
|
||||
} else if((scause == 15 || scause == 13)) { // store/load page fault
|
||||
pte_t *pte = walk(p->pagetable, stval, 0);
|
||||
if(pte && (*pte & PTE_V) && (*pte & PTE_U) && (*pte & PTE_COW)) {
|
||||
uint64 pa = PTE2PA(*pte);
|
||||
char *mem = kalloc();
|
||||
if(mem == 0) {
|
||||
setkilled(p);
|
||||
} else {
|
||||
memmove(mem, (void*)pa, PGSIZE);
|
||||
*pte = PA2PTE(mem) | (PTE_FLAGS(*pte) & ~PTE_COW) | PTE_W;
|
||||
kfree((void*)pa);
|
||||
}
|
||||
} else {
|
||||
printf("usertrap(): unexpected scause 0x%lx pid=%d\n", scause, p->pid);
|
||||
printf(" sepc=0x%lx stval=0x%lx\n", r_sepc(), r_stval());
|
||||
setkilled(p);
|
||||
}
|
||||
} else {
|
||||
printf("usertrap(): unexpected scause 0x%lx pid=%d\n", r_scause(), p->pid);
|
||||
printf(" sepc=0x%lx stval=0x%lx\n", r_sepc(), r_stval());
|
||||
@@ -216,3 +239,6 @@ devintr()
|
||||
}
|
||||
}
|
||||
|
||||
void kfree(void *pa);
|
||||
void *kalloc(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user