Merge "vmbase: Handle stack overflows"
diff --git a/vmbase/entry.S b/vmbase/entry.S
index 177c9aa..9f6993a 100644
--- a/vmbase/entry.S
+++ b/vmbase/entry.S
@@ -208,8 +208,14 @@
stp q0, q1, [x28], #32
b 2b
-3: /* Prepare the stack. */
+3: /* Prepare the exception handler stack (SP_EL1). */
+ adr_l x30, init_eh_stack_pointer
+ msr spsel, #1
+ mov sp, x30
+
+ /* Prepare the main thread stack (SP_EL0). */
adr_l x30, init_stack_pointer
+ msr spsel, #0
mov sp, x30
/* Set up exception vector. */
diff --git a/vmbase/sections.ld b/vmbase/sections.ld
index 8118363..5232d30 100644
--- a/vmbase/sections.ld
+++ b/vmbase/sections.ld
@@ -60,6 +60,17 @@
} >image
rodata_end = .;
+ .eh_stack (NOLOAD) : ALIGN(4096) {
+ /*
+ * Get stack overflow guard from the previous page being from
+ * .rodata and mapped read-only or left unmapped.
+ */
+ eh_stack_limit = .;
+ . += 4096;
+ . = ALIGN(4096);
+ init_eh_stack_pointer = .;
+ } >writable_data
+
/*
* Collect together the read-write data including .bss at the end which
* will be zero'd by the entry code. This is page aligned so it can be
@@ -91,6 +102,7 @@
init_stack_pointer = ORIGIN(writable_data) + LENGTH(writable_data);
.stack (NOLOAD) : ALIGN(4096) {
+ . += 4096; /* Ensure we have one guard page for overflow. */
stack_limit = .;
. = init_stack_pointer;
} >writable_data
diff --git a/vmbase/src/layout.rs b/vmbase/src/layout.rs
index d07dac4..ead4f8e 100644
--- a/vmbase/src/layout.rs
+++ b/vmbase/src/layout.rs
@@ -72,7 +72,7 @@
/// All writable sections, excluding the stack.
pub fn scratch_range() -> Range<usize> {
- linker_region!(data_begin, bss_end)
+ linker_region!(eh_stack_limit, bss_end)
}
/// Read-write data (original).
diff --git a/vmbase/src/linker.rs b/vmbase/src/linker.rs
index 5f6e05e..97bef3f 100644
--- a/vmbase/src/linker.rs
+++ b/vmbase/src/linker.rs
@@ -33,6 +33,8 @@
pub static dtb_begin: u8;
/// First byte beyond the `.dtb` section.
pub static dtb_end: u8;
+ /// First byte of the region available for the exception handler stack.
+ pub static eh_stack_limit: u8;
/// First byte past the region available for the stack.
pub static init_stack_pointer: u8;
/// First byte of the `.rodata` section.