[kernel][thread] Make stack info easier to reach from exception vectors
Move stack info to start of thread struct and add a stack_high entry.
This makes it easier validate or set the stack pointer from the
exceptions vectors.
Bug: 165825378
Change-Id: I16f0e84b29efc4173d6a052cff131aba192f9b2a
diff --git a/arch/arm/arm/thread.c b/arch/arm/arm/thread.c
index a14528c..ab98e91 100644
--- a/arch/arm/arm/thread.c
+++ b/arch/arm/arm/thread.c
@@ -64,6 +64,16 @@
thread_exit(ret);
}
+void arch_init_thread_initialize(struct thread *thread, uint cpu)
+{
+ extern uint8_t abort_stack[];
+ size_t stack_size = ARCH_DEFAULT_STACK_SIZE;
+ uint8_t *cpu_stack = abort_stack + cpu * stack_size;
+ thread->stack = cpu_stack;
+ thread->stack_high = cpu_stack + stack_size;
+ thread->stack_size = stack_size;
+}
+
void arch_thread_initialize(thread_t *t)
{
// create a default stack frame on the stack
diff --git a/arch/arm64/thread.c b/arch/arm64/thread.c
index cc3e8bd..8bc6b6e 100644
--- a/arch/arm64/thread.c
+++ b/arch/arm64/thread.c
@@ -71,6 +71,16 @@
thread_exit(ret);
}
+void arch_init_thread_initialize(struct thread *thread, uint cpu)
+{
+ extern uint8_t __stack_end[];
+ size_t stack_size = ARCH_DEFAULT_STACK_SIZE;
+ uint8_t *cpu_stack_end = __stack_end - stack_size * cpu;
+ thread->stack = cpu_stack_end - stack_size;
+ thread->stack_high = cpu_stack_end;
+ thread->stack_size = stack_size;
+}
+
void arch_thread_initialize(thread_t *t)
{
// create a default stack frame on the stack
diff --git a/arch/x86/thread.c b/arch/x86/thread.c
index aac0db6..a85f2dc 100644
--- a/arch/x86/thread.c
+++ b/arch/x86/thread.c
@@ -47,6 +47,17 @@
thread_exit(ret);
}
+void arch_init_thread_initialize(struct thread *thread, uint cpu)
+{
+ extern uint8_t _kstack[];
+ size_t stack_size = PAGE_SIZE;
+ uint8_t *cpu_stack = _kstack;
+ ASSERT(cpu == 0);
+ thread->stack = cpu_stack;
+ thread->stack_high = cpu_stack + stack_size;
+ thread->stack_size = stack_size;
+}
+
void arch_thread_initialize(thread_t *t)
{
// create a default stack frame on the stack
diff --git a/include/arch/thread.h b/include/arch/thread.h
index 06de51d..792a959 100644
--- a/include/arch/thread.h
+++ b/include/arch/thread.h
@@ -29,6 +29,7 @@
struct thread;
void arch_thread_initialize(struct thread *);
+void arch_init_thread_initialize(struct thread *thread, uint cpu);
void arch_context_switch(struct thread *oldthread, struct thread *newthread);
#endif
diff --git a/include/kernel/thread.h b/include/kernel/thread.h
index b38b9e8..05619f9 100644
--- a/include/kernel/thread.h
+++ b/include/kernel/thread.h
@@ -84,6 +84,11 @@
#define THREAD_MAGIC (0x74687264) // 'thrd'
typedef struct thread {
+ /* stack stuff, don't move, used by assembly code to validate stack */
+ void *stack;
+ void *stack_high;
+ size_t stack_size;
+
int magic;
struct list_node thread_list_node;
@@ -108,10 +113,6 @@
/* architecture stuff */
struct arch_thread arch;
- /* stack stuff */
- void *stack;
- size_t stack_size;
-
/* entry point */
thread_start_routine entry;
void *arg;
diff --git a/kernel/thread.c b/kernel/thread.c
index 3dfd086..04a0fec 100644
--- a/kernel/thread.c
+++ b/kernel/thread.c
@@ -209,6 +209,7 @@
memset(t->stack, STACK_DEBUG_BYTE, stack_size);
#endif
+ t->stack_high = t->stack + stack_size;
t->stack_size = stack_size;
/* save whether or not we need to free the thread struct and/or stack */
@@ -966,6 +967,8 @@
thread_t *t = idle_thread(0);
init_thread_struct(t, "bootstrap");
+ arch_init_thread_initialize(t, 0);
+
/* half construct this thread, since we're already running */
t->priority = HIGHEST_PRIORITY;
t->state = THREAD_RUNNING;
@@ -1096,6 +1099,8 @@
thread_set_pinned_cpu(t, cpu);
wait_queue_init(&t->retcode_wait_queue);
+ arch_init_thread_initialize(t, cpu);
+
THREAD_LOCK(state);
list_add_head(&thread_list, &t->thread_list_node);