From 6a6d5142d19638177c79c45d828f4b95db14799c Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Wed, 11 Jul 2018 06:23:44 +1000 Subject: Memory is now allocated for a kernel stack unique to each address space during process creation. This new kernel stack is placed at 0xFFFFFFFF, as the last page in the 4GB address space. The base of the user's stack has been moved down to 0xFFFFDFFF, exactly two pages below. The extra page below the kernel's stack page will be left unmapped so as to trigger a page fault if the kernel's stack overflows. The initial values of the user's TSS have also been updated to reflect the new bases of the stacks, and to ensure that the kernel's unique stack is loaded when an interrupt occurs. --- kernel/sched.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/sched.c b/kernel/sched.c index 8469005..c9f0da9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -67,12 +67,12 @@ struct task_struct *create_proc(void *bin, size_t len) { int c; size_t totpages, npages, ntables; void *p, *page, *tab, *map; - void *pdir, *stackt, *stackp; + void *pdir, *stackt, *stackp, *kstackp; struct task_struct *task = NULL; npages = pages(len); ntables = tables(pages(len)); - totpages = npages + ntables + 3; + totpages = npages + ntables + 4; /* find an unused task structure */ for(i = 0; i < NRTASKS; i++) { @@ -102,8 +102,9 @@ struct task_struct *create_proc(void *bin, size_t len) { * will hold the binary image, the following * pages are allocated: * - page directory (1 page) - * - page tables + * - page tables (1 per every 1024 pages) * - stack page (1 page) + * - kernel stack page (1 page) * - stack table (1 page) */ p = alloc_physical_pages(totpages); @@ -113,6 +114,7 @@ struct task_struct *create_proc(void *bin, size_t len) { getpage(pdir, p); getpage(stackt, p); getpage(stackp, p); + getpage(kstackp, p); /* populate the page directory */ c = npages; @@ -141,7 +143,13 @@ struct task_struct *create_proc(void *bin, size_t len) { /* populate the stack table */ map = map_page(stackt); empty_table(map); - ((uint32_t*) map)[PGENT - 1] = (uint32_t) stackp | 0x007; + ((uint32_t*) map)[PGENT - 3] = (uint32_t) stackp | 0x007; + /* + * NOTE: we leave a single 4KB gap between the kernel + * and user's stacks so we can detect overflows of the + * kernel's stack. + */ + ((uint32_t*) map)[PGENT - 1] = (uint32_t) kstackp | 0x003; /* add the stack page table to the directory */ map = map_page(pdir); @@ -169,8 +177,8 @@ struct task_struct *create_proc(void *bin, size_t len) { task->state.gs = 0x23; task->state.ss = 0x23; task->state.eip = (uint32_t) USRSTART; - task->state.esp = 0xFFFFFFFF; - task->state.esp0 = 0x80000; + task->state.esp = 0xFFFFDFFF; + task->state.esp0 = 0xFFFFFFFF; task->state.ss0 = 0x10; __asm__ ( "pushf\n" \ -- cgit v1.3