Jump to a real kstack ASAP during boot
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 26 Oct 2016 23:40:50 +0000 (19:40 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 29 Nov 2016 16:27:40 +0000 (11:27 -0500)
We actually were using the bootstack, which was never actually given out
by a memory allocator, for a long time.  Eventually, we'd give it back,
when the kthread code thought it was a spare it needed to free.  This
would confuse the arena allocator, which never gave out the memory in
the first place.

Now, we'll switch to using a kernel stack that was given to us by
get_kstack() right away.  This helps both with the allocator as well as
with whatever safety checks we'll use for the kernel stacks (e.g. guard
pages).  It'd be brutal if we had one unlucky kernel stack that didn't
have the protections we thought all stacks had (or will have, in this
case).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/kthread.h
kern/src/init.c
kern/src/kthread.c

index c3a456f..863a983 100644 (file)
@@ -101,6 +101,7 @@ void put_kstack(uintptr_t stacktop);
 uintptr_t *kstack_bottom_addr(uintptr_t stacktop);
 void kthread_init(void);
 struct kthread *__kthread_zalloc(void);
+void __use_real_kstack(void (*f)(void *arg));
 void restart_kthread(struct kthread *kthread);
 void kthread_runnable(struct kthread *kthread);
 void kthread_yield(void);
index 22cbf90..f5be4f8 100644 (file)
@@ -118,6 +118,8 @@ static void extract_multiboot_cmdline(struct multiboot_info *mbi)
        }
 }
 
+static void __kernel_init_part_deux(void *arg);
+
 void kernel_init(multiboot_info_t *mboot_info)
 {
        extern char __start_bss[], __stop_bss[];
@@ -150,6 +152,12 @@ void kernel_init(multiboot_info_t *mboot_info)
        file_init();
        page_check();
        idt_init();
+       /* After kthread_init and idt_init, we can use a real kstack. */
+       __use_real_kstack(__kernel_init_part_deux);
+}
+
+static void __kernel_init_part_deux(void *arg)
+{
        kernel_msg_init();
        timer_init();
        vfs_init();
index afd7544..b8ba447 100644 (file)
@@ -59,6 +59,24 @@ struct kthread *__kthread_zalloc(void)
        return kthread;
 }
 
+/* Helper during early boot, where we jump from the bootstack to a real kthread
+ * stack, then run f().  Note that we don't have a kthread yet (done in smp.c).
+ *
+ * After this, our callee (f) can free the bootstack, if we care, by adding it
+ * to the base arena (use the KERNBASE addr, not the KERN_LOAD_ADDR). */
+void __use_real_kstack(void (*f)(void *arg))
+{
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       uintptr_t new_stacktop;
+
+       new_stacktop = get_kstack();
+#ifdef CONFIG_KTHREAD_POISON
+       *kstack_bottom_addr(new_stacktop) = 0xdeadbeef;
+#endif /* CONFIG_KTHREAD_POISON */
+       set_stack_top(new_stacktop);
+       __reset_stack_pointer(0, new_stacktop, f);
+}
+
 /* Starts kthread on the calling core.  This does not return, and will handle
  * the details of cleaning up whatever is currently running (freeing its stack,
  * etc).  Pairs with sem_down(). */