From 91566327012cad2ca99df47f9321dfc012d8a7ff Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Fri, 19 Jul 2019 08:38:51 -0400 Subject: One way of supporting a guard page below kstack: allocate kstacks in procinit() and map them high up (below TRAMPOLNE) with an empty mapping below each stack. Never free a kernel stack. Another way would be to allocate and map them dynamically, but then we need to reload page table when switching processes in scheduler() and/or have a kernel pagetable per proc (if we want k->stack to be the same virtual address in each process). One gotcha: kernel addresses are not equal to physical addresses for stack addresses. A stack address must be translated if we need its physical address (e.g., virtio passes a stack address to the disk). --- kernel/proc.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'kernel/proc.c') 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"); } } - -- cgit v1.2.3