summaryrefslogtreecommitdiff
path: root/kernel/vm.c
diff options
context:
space:
mode:
authorSanjit Bhat <[email protected]>2023-10-25 19:42:59 -0400
committerSanjit Bhat <[email protected]>2023-10-25 19:42:59 -0400
commit1ed40716eb54e371df9d1814b9129666b3fe4f09 (patch)
tree84666aacb6d6a9554b09500c0b0420870af2e19e /kernel/vm.c
parent74c1eba516fdb0ec1a17b16be7e76613ccba92bf (diff)
downloadxv6-labs-1ed40716eb54e371df9d1814b9129666b3fe4f09.tar.gz
xv6-labs-1ed40716eb54e371df9d1814b9129666b3fe4f09.tar.bz2
xv6-labs-1ed40716eb54e371df9d1814b9129666b3fe4f09.zip
release lab net
Diffstat (limited to 'kernel/vm.c')
-rw-r--r--kernel/vm.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/kernel/vm.c b/kernel/vm.c
index 5c31e87..7119242 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -4,6 +4,8 @@
#include "elf.h"
#include "riscv.h"
#include "defs.h"
+#include "spinlock.h"
+#include "proc.h"
#include "fs.h"
/*
@@ -30,6 +32,14 @@ kvmmake(void)
// virtio mmio disk interface
kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
+#ifdef LAB_NET
+ // PCI-E ECAM (configuration space), for pci.c
+ kvmmap(kpgtbl, 0x30000000L, 0x30000000L, 0x10000000, PTE_R | PTE_W);
+
+ // pci.c maps the e1000's registers here.
+ kvmmap(kpgtbl, 0x40000000L, 0x40000000L, 0x20000, PTE_R | PTE_W);
+#endif
+
// PLIC
kvmmap(kpgtbl, PLIC, PLIC, 0x400000, PTE_R | PTE_W);
@@ -136,9 +146,8 @@ kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
}
// Create PTEs for virtual addresses starting at va that refer to
-// physical addresses starting at pa.
-// va and size MUST be page-aligned.
-// Returns 0 on success, -1 if walk() couldn't
+// physical addresses starting at pa. va and size might not
+// be page-aligned. Returns 0 on success, -1 if walk() couldn't
// allocate a needed page-table page.
int
mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
@@ -146,17 +155,11 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
uint64 a, last;
pte_t *pte;
- if((va % PGSIZE) != 0)
- panic("mappages: va not aligned");
-
- if((size % PGSIZE) != 0)
- panic("mappages: size not aligned");
-
if(size == 0)
panic("mappages: size");
- a = va;
- last = va + size - PGSIZE;
+ a = PGROUNDDOWN(va);
+ last = PGROUNDDOWN(va + size - 1);
for(;;){
if((pte = walk(pagetable, a, 1)) == 0)
return -1;
@@ -186,8 +189,10 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
for(a = va; a < va + npages*PGSIZE; a += PGSIZE){
if((pte = walk(pagetable, a, 0)) == 0)
panic("uvmunmap: walk");
- if((*pte & PTE_V) == 0)
+ if((*pte & PTE_V) == 0) {
+ printf("va=%p pte=%p\n", a, *pte);
panic("uvmunmap: not mapped");
+ }
if(PTE_FLAGS(*pte) == PTE_V)
panic("uvmunmap: not a leaf");
if(do_free){
@@ -363,13 +368,21 @@ copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
while(len > 0){
va0 = PGROUNDDOWN(dstva);
- if(va0 >= MAXVA)
+ if (va0 >= MAXVA)
return -1;
- pte = walk(pagetable, va0, 0);
- if(pte == 0 || (*pte & PTE_V) == 0 || (*pte & PTE_U) == 0 ||
- (*pte & PTE_W) == 0)
+ if((pte = walk(pagetable, va0, 0)) == 0) {
+ // printf("copyout: pte should exist 0x%x %d\n", dstva, len);
+ return -1;
+ }
+
+
+ // forbid copyout over read-only user text pages.
+ if((*pte & PTE_W) == 0)
+ return -1;
+
+ pa0 = walkaddr(pagetable, va0);
+ if(pa0 == 0)
return -1;
- pa0 = PTE2PA(*pte);
n = PGSIZE - (dstva - va0);
if(n > len)
n = len;
@@ -389,7 +402,7 @@ int
copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
{
uint64 n, va0, pa0;
-
+
while(len > 0){
va0 = PGROUNDDOWN(srcva);
pa0 = walkaddr(pagetable, va0);
@@ -449,3 +462,6 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
return -1;
}
}
+
+
+