From d66082b4146056189b3bb5d7bce70b3f79b38c40 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Tue, 7 Feb 2023 03:43:47 +0000 Subject: [PATCH] make grade 140/140 --- kernel/proc.c | 23 +++++++++++++++-------- kernel/proc.h | 1 + kernel/trap.c | 9 +++++++-- time.txt | 1 + 4 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 time.txt diff --git a/kernel/proc.c b/kernel/proc.c index f6090dd..d136132 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -345,6 +345,7 @@ fork(void) newvma->prot = p->map_region[i]->prot; newvma->length = p->map_region[i]->length; newvma->flag = p->map_region[i]->flag; + newvma->offset = p->map_region[i]->offset; release(&lock_vma_pool); np->map_region[i] = newvma; } @@ -756,6 +757,7 @@ uint64 do_mmap(struct proc* p, int length, int prot, int flags, int fd) newvma->prot = prot; newvma->length = length; newvma->flag = flags; + newvma->offset = 0; release(&lock_vma_pool); filedup(newvma->f); @@ -800,6 +802,7 @@ uint64 do_munmap(uint64 addr, int length) } } if (vma0 == 0) { + printf("failed to ummap %p\n", addr); return -1; } // remove all relavant pages @@ -809,15 +812,18 @@ uint64 do_munmap(uint64 addr, int length) uint64 free_start = MAX(PGROUNDDOWN(addr), vma0->addr); uint64 free_end = MIN(PGROUNDUP(addr + length), vma_end); for (uint64 va0 = free_start; va0 < free_end; va0 += PGSIZE) { - if (vma0->flag == MAP_SHARED) { - begin_op(); - ilock(vma0->f->ip); - writei(vma0->f->ip, 1, va0, va0 - addr, PGSIZE); // ? no sure if to write whole page - iunlock(vma0->f->ip); - end_op(); - } - if (walkaddr(p->pagetable, va0)) + if (walkaddr(p->pagetable, va0)){ + if (vma0->flag == MAP_SHARED) { + begin_op(); + ilock(vma0->f->ip); + // int wrsz = + writei(vma0->f->ip, 1, va0, va0 + vma0->offset - vma0->addr, PGSIZE); // ? no sure if to write whole page + // printf("Write %d bytes from %p @offset=%d(off=%x,addr=%x)\n", wrsz, va0, va0 + vma0->offset - vma0->addr, vma0->offset, vma0->addr); + iunlock(vma0->f->ip); + end_op(); + } uvmunmap(p->pagetable, va0, 1, 1); + } } if (free_start <= vma0->addr && free_end >= vma_end) { // all released @@ -828,6 +834,7 @@ uint64 do_munmap(uint64 addr, int length) vma0->length = free_start - vma0->addr; } else if (free_start <= vma0->addr) { vma0->length -= free_end - vma0->addr; + vma0->offset += free_end - vma0->addr; vma0->addr = free_end; } else { panic("unsupported unmap type"); diff --git a/kernel/proc.h b/kernel/proc.h index eab73eb..456efaa 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -86,6 +86,7 @@ struct vma { uint length; uint prot; uint flag; + uint offset; struct file* f; }; diff --git a/kernel/trap.c b/kernel/trap.c index 941171f..c066526 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -72,7 +72,6 @@ usertrap(void) } else if(r_scause() == 13){ int va0 = r_stval(); struct vma* vma0 = 0; - if (va0 < MMAP_START) panic("unknown page fault"); for (int i = 0; i < NMAXVMA; ++ i) { if(p->map_region[i] && p->map_region[i]->addr <= va0 @@ -81,6 +80,9 @@ usertrap(void) break; } } + if (vma0 == 0) { + goto bad; + } uint64 phy_addr = (uint64)kalloc(); uint pgflag = PTE_U | (vma0->prot << 1); // save some code... there is PTE_R/W/X = PROT_READ/WRITE/EXEC << 1 @@ -88,12 +90,15 @@ usertrap(void) memset((void*)phy_addr, 0, PGSIZE); begin_op(); ilock(vma0->f->ip); - readi(vma0->f->ip, 0, phy_addr, va0 - vma0->addr, PGSIZE); + // int rdsz = + readi(vma0->f->ip, 0, phy_addr, va0 + vma0->offset - vma0->addr, PGSIZE); + // printf("Load %d bytes to %p @offset=%d\n", rdsz, va0,va0 + vma0->offset - vma0->addr); iunlock(vma0->f->ip); end_op(); } else if((which_dev = devintr()) != 0){ // ok } else { +bad: printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid); printf(" sepc=%p stval=%p\n", r_sepc(), r_stval()); setkilled(p); diff --git a/time.txt b/time.txt new file mode 100644 index 0000000..62f9457 --- /dev/null +++ b/time.txt @@ -0,0 +1 @@ +6 \ No newline at end of file