usertests and optional finished
This commit is contained in:
34
kernel/vm.c
34
kernel/vm.c
@@ -99,7 +99,7 @@ pte_t *
|
||||
walk(pagetable_t pagetable, uint64 va, int alloc)
|
||||
{
|
||||
if(va >= MAXVA)
|
||||
panic("walk");
|
||||
return 0;
|
||||
|
||||
for(int level = 2; level > 0; level--) {
|
||||
pte_t *pte = &pagetable[PX(level, va)];
|
||||
@@ -123,8 +123,8 @@ walk(pagetable_t pagetable, uint64 va, int alloc)
|
||||
pte_t *
|
||||
super_walk(pagetable_t pagetable, uint64 va, int alloc)
|
||||
{
|
||||
if (va > MAXVA)
|
||||
panic("walk");
|
||||
if (va >= MAXVA)
|
||||
return 0;
|
||||
|
||||
pte_t *pte = &(pagetable[PX(2, va)]);
|
||||
if (*pte & PTE_V) {
|
||||
@@ -241,33 +241,41 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
|
||||
{
|
||||
uint64 a;
|
||||
pte_t *pte;
|
||||
int sz;
|
||||
uint64 end_va = va + npages * PGSIZE;
|
||||
|
||||
if((va % PGSIZE) != 0)
|
||||
panic("uvmunmap: not aligned");
|
||||
for(a = va; a < va + npages*PGSIZE; a += sz){
|
||||
sz = PGSIZE;
|
||||
if((pte = walk(pagetable, a, 0)) == 0)
|
||||
panic("uvmunmap: walk");
|
||||
|
||||
for(a = va; a < end_va; ){
|
||||
if((pte = walk(pagetable, a, 0)) == 0) {
|
||||
// If we can't find a PTE, skip to next page
|
||||
a += PGSIZE;
|
||||
continue;
|
||||
}
|
||||
if((*pte & PTE_V) == 0) {
|
||||
printf("va=%ld pte=%ld\n", a, *pte);
|
||||
panic("uvmunmap: not mapped");
|
||||
// If page is not valid, skip to next page
|
||||
a += PGSIZE;
|
||||
continue;
|
||||
}
|
||||
if(PTE_FLAGS(*pte) == PTE_V)
|
||||
panic("uvmunmap: not a leaf");
|
||||
|
||||
if ((*pte & PTE_PS)) { /* 释放巨页 */
|
||||
if(do_free){
|
||||
uint64 pa = PTE2PA(*pte);
|
||||
superfree((void*)pa);
|
||||
}
|
||||
*pte = 0;
|
||||
a += SUPERPGSIZE - sz;
|
||||
// Make sure we don't go beyond the requested range
|
||||
uint64 next_a = a + SUPERPGSIZE;
|
||||
a = (next_a > end_va) ? end_va : next_a;
|
||||
} else {
|
||||
if(do_free){
|
||||
uint64 pa = PTE2PA(*pte);
|
||||
kfree((void*)pa);
|
||||
}
|
||||
*pte = 0;
|
||||
a += PGSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,6 +576,8 @@ copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
|
||||
|
||||
while(len > 0){
|
||||
va0 = PGROUNDDOWN(srcva);
|
||||
if (va0 >= MAXVA)
|
||||
return -1;
|
||||
if((pte = walk(pagetable, va0, 0)) == 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -603,6 +613,8 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
|
||||
|
||||
while(got_null == 0 && max > 0){
|
||||
va0 = PGROUNDDOWN(srcva);
|
||||
if (va0 >= MAXVA)
|
||||
return -1;
|
||||
if((pte = walk(pagetable, va0, 0)) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user