make grade 140/140
This commit is contained in:
parent
294e926e52
commit
d66082b414
@ -345,6 +345,7 @@ fork(void)
|
|||||||
newvma->prot = p->map_region[i]->prot;
|
newvma->prot = p->map_region[i]->prot;
|
||||||
newvma->length = p->map_region[i]->length;
|
newvma->length = p->map_region[i]->length;
|
||||||
newvma->flag = p->map_region[i]->flag;
|
newvma->flag = p->map_region[i]->flag;
|
||||||
|
newvma->offset = p->map_region[i]->offset;
|
||||||
release(&lock_vma_pool);
|
release(&lock_vma_pool);
|
||||||
np->map_region[i] = newvma;
|
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->prot = prot;
|
||||||
newvma->length = length;
|
newvma->length = length;
|
||||||
newvma->flag = flags;
|
newvma->flag = flags;
|
||||||
|
newvma->offset = 0;
|
||||||
release(&lock_vma_pool);
|
release(&lock_vma_pool);
|
||||||
|
|
||||||
filedup(newvma->f);
|
filedup(newvma->f);
|
||||||
@ -800,6 +802,7 @@ uint64 do_munmap(uint64 addr, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vma0 == 0) {
|
if (vma0 == 0) {
|
||||||
|
printf("failed to ummap %p\n", addr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// remove all relavant pages
|
// remove all relavant pages
|
||||||
@ -809,16 +812,19 @@ uint64 do_munmap(uint64 addr, int length)
|
|||||||
uint64 free_start = MAX(PGROUNDDOWN(addr), vma0->addr);
|
uint64 free_start = MAX(PGROUNDDOWN(addr), vma0->addr);
|
||||||
uint64 free_end = MIN(PGROUNDUP(addr + length), vma_end);
|
uint64 free_end = MIN(PGROUNDUP(addr + length), vma_end);
|
||||||
for (uint64 va0 = free_start; va0 < free_end; va0 += PGSIZE) {
|
for (uint64 va0 = free_start; va0 < free_end; va0 += PGSIZE) {
|
||||||
|
if (walkaddr(p->pagetable, va0)){
|
||||||
if (vma0->flag == MAP_SHARED) {
|
if (vma0->flag == MAP_SHARED) {
|
||||||
begin_op();
|
begin_op();
|
||||||
ilock(vma0->f->ip);
|
ilock(vma0->f->ip);
|
||||||
writei(vma0->f->ip, 1, va0, va0 - addr, PGSIZE); // ? no sure if to write whole page
|
// 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);
|
iunlock(vma0->f->ip);
|
||||||
end_op();
|
end_op();
|
||||||
}
|
}
|
||||||
if (walkaddr(p->pagetable, va0))
|
|
||||||
uvmunmap(p->pagetable, va0, 1, 1);
|
uvmunmap(p->pagetable, va0, 1, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (free_start <= vma0->addr && free_end >= vma_end) {
|
if (free_start <= vma0->addr && free_end >= vma_end) {
|
||||||
// all released
|
// all released
|
||||||
fileclose(vma0->f);
|
fileclose(vma0->f);
|
||||||
@ -828,6 +834,7 @@ uint64 do_munmap(uint64 addr, int length)
|
|||||||
vma0->length = free_start - vma0->addr;
|
vma0->length = free_start - vma0->addr;
|
||||||
} else if (free_start <= vma0->addr) {
|
} else if (free_start <= vma0->addr) {
|
||||||
vma0->length -= free_end - vma0->addr;
|
vma0->length -= free_end - vma0->addr;
|
||||||
|
vma0->offset += free_end - vma0->addr;
|
||||||
vma0->addr = free_end;
|
vma0->addr = free_end;
|
||||||
} else {
|
} else {
|
||||||
panic("unsupported unmap type");
|
panic("unsupported unmap type");
|
||||||
|
|||||||
@ -86,6 +86,7 @@ struct vma {
|
|||||||
uint length;
|
uint length;
|
||||||
uint prot;
|
uint prot;
|
||||||
uint flag;
|
uint flag;
|
||||||
|
uint offset;
|
||||||
struct file* f;
|
struct file* f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,6 @@ usertrap(void)
|
|||||||
} else if(r_scause() == 13){
|
} else if(r_scause() == 13){
|
||||||
int va0 = r_stval();
|
int va0 = r_stval();
|
||||||
struct vma* vma0 = 0;
|
struct vma* vma0 = 0;
|
||||||
if (va0 < MMAP_START) panic("unknown page fault");
|
|
||||||
for (int i = 0; i < NMAXVMA; ++ i) {
|
for (int i = 0; i < NMAXVMA; ++ i) {
|
||||||
if(p->map_region[i]
|
if(p->map_region[i]
|
||||||
&& p->map_region[i]->addr <= va0
|
&& p->map_region[i]->addr <= va0
|
||||||
@ -81,6 +80,9 @@ usertrap(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (vma0 == 0) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
uint64 phy_addr = (uint64)kalloc();
|
uint64 phy_addr = (uint64)kalloc();
|
||||||
uint pgflag = PTE_U | (vma0->prot << 1);
|
uint pgflag = PTE_U | (vma0->prot << 1);
|
||||||
// save some code... there is PTE_R/W/X = PROT_READ/WRITE/EXEC << 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);
|
memset((void*)phy_addr, 0, PGSIZE);
|
||||||
begin_op();
|
begin_op();
|
||||||
ilock(vma0->f->ip);
|
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);
|
iunlock(vma0->f->ip);
|
||||||
end_op();
|
end_op();
|
||||||
} else if((which_dev = devintr()) != 0){
|
} else if((which_dev = devintr()) != 0){
|
||||||
// ok
|
// ok
|
||||||
} else {
|
} else {
|
||||||
|
bad:
|
||||||
printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
|
printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
|
||||||
printf(" sepc=%p stval=%p\n", r_sepc(), r_stval());
|
printf(" sepc=%p stval=%p\n", r_sepc(), r_stval());
|
||||||
setkilled(p);
|
setkilled(p);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user