diff options
| -rw-r--r-- | kernel/defs.h | 2 | ||||
| -rw-r--r-- | kernel/memlayout.h | 1 | ||||
| -rw-r--r-- | kernel/proc.c | 20 | ||||
| -rw-r--r-- | kernel/virtio_disk.c | 2 | ||||
| -rw-r--r-- | kernel/vm.c | 31 | 
5 files changed, 42 insertions, 14 deletions
| 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; +} | 
