diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-07-11 06:23:44 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-07-11 06:23:44 +1000 |
| commit | 6a6d5142d19638177c79c45d828f4b95db14799c (patch) | |
| tree | ef5426c5ab366010b00f2a6496aeb1cafd568c90 | |
| parent | 59cac783f5ba12a47308b05b87d5cfa769473a49 (diff) | |
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.
| -rw-r--r-- | kernel/sched.c | 20 |
1 files changed, 14 insertions, 6 deletions
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" \ |
