diff --git a/kernel/defs.h b/kernel/defs.h index bd89af0..3172cb3 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -193,6 +193,8 @@ uint64 walkaddr(pagetable_t, uint64); int copyout(pagetable_t, uint64, char *, uint64); int copyin(pagetable_t, char *, uint64, uint64); int copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max); +char* map_kstack(); +uint64 kernelpa(uint64); // plic.c void plicinit(void); diff --git a/kernel/memlayout.h b/kernel/memlayout.h index 219c308..13d1705 100644 --- a/kernel/memlayout.h +++ b/kernel/memlayout.h @@ -53,3 +53,4 @@ // map the trampoline page to the highest address, // in both user and kernel space. #define TRAMPOLINE (MAXVA - PGSIZE) +#define KSTACK(p) ((TRAMPOLINE-PGSIZE)-p*2*PGSIZE) diff --git a/kernel/proc.c b/kernel/proc.c index 6ba3fec..087d504 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -26,8 +26,14 @@ procinit(void) struct proc *p; initlock(&pid_lock, "nextpid"); - for(p = proc; p < &proc[NPROC]; p++) + for(p = proc; p < &proc[NPROC]; p++) { initlock(&p->lock, "proc"); + // Allocate a page for the kernel stack. + char *kstack = (char *) KSTACK((int) (p - proc)); + if((p->kstack = map_kstack(kstack)) == 0) { + panic("procinit"); + } + } } // Must be called with interrupts disabled, @@ -94,16 +100,8 @@ allocproc(void) found: p->pid = allocpid(); - // Allocate a page for the kernel stack. - if((p->kstack = kalloc()) == 0){ - release(&p->lock); - return 0; - } - // Allocate a trapframe page. if((p->tf = (struct trapframe *)kalloc()) == 0){ - kfree(p->kstack); - p->kstack = 0; release(&p->lock); return 0; } @@ -126,9 +124,6 @@ found: static void freeproc(struct proc *p) { - if(p->kstack) - kfree(p->kstack); - p->kstack = 0; if(p->tf) kfree((void*)p->tf); p->tf = 0; @@ -651,4 +646,3 @@ procdump(void) printf("\n"); } } - diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c index 1a29ce7..6620037 100644 --- a/kernel/virtio_disk.c +++ b/kernel/virtio_disk.c @@ -199,7 +199,7 @@ virtio_disk_rw(struct buf *b) buf0.reserved = 0; buf0.sector = sector; - desc[idx[0]].addr = (uint64) &buf0; + desc[idx[0]].addr = (uint64) kernelpa((uint64) &buf0); desc[idx[0]].len = sizeof(buf0); desc[idx[0]].flags = VRING_DESC_F_NEXT; desc[idx[0]].next = idx[1]; diff --git a/kernel/vm.c b/kernel/vm.c index 412ec8c..d42e719 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -404,3 +404,34 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) return -1; } } + +char *map_kstack(uint64 kstack) +{ + char *k = kalloc(); + if(k == 0) { + return 0; + } + if (mappages(kernel_pagetable, (uint64) kstack, PGSIZE, + (uint64) k, PTE_R | PTE_W) == 0) { + kvminithart(); + return (char *) kstack; + } + kfree(k); + return 0; +} + +// assumes va is page aligned +uint64 +kernelpa(uint64 va) { + uint64 off = va % PGSIZE; + pte_t *pte; + uint64 pa; + + pte = walk(kernel_pagetable, va, 0); + if(pte == 0) + panic("kernelpa"); + if((*pte & PTE_V) == 0) + panic("kernelpa"); + pa = PTE2PA(*pte); + return pa+off; +}