vmbase: Clients separate eh_stack from .data+.bss
Remove the assumption that .data, .bss, and EH stack region are
contiguous e.g. when mapping or clearing them. This prepares the code
for an upcoming change moving the EH stack to a different part of the
writable_data region.
Bug: 377276983
Bug: 381440625
Test: m {pvmfw,rialto,vmbase_example_{bios,kernel}}_bin
Change-Id: Iae6220b1623b81ff9d7b6595be74504f6ec80865
diff --git a/guest/pvmfw/src/entry.rs b/guest/pvmfw/src/entry.rs
index ce911b8..39e51c5 100644
--- a/guest/pvmfw/src/entry.rs
+++ b/guest/pvmfw/src/entry.rs
@@ -189,7 +189,7 @@
const SCTLR_EL1_VAL: u64 = SCTLR_EL1_RES1 | SCTLR_EL1_ITD | SCTLR_EL1_SED | SCTLR_EL1_I;
- let scratch = layout::scratch_range();
+ let scratch = layout::data_bss_range();
assert_ne!(scratch.end - scratch.start, 0, "scratch memory is empty.");
assert_eq!(scratch.start.0 % ASM_STP_ALIGN, 0, "scratch memory is misaligned.");
@@ -205,6 +205,12 @@
assert_eq!(stack.start.0 % ASM_STP_ALIGN, 0, "Misaligned stack region.");
assert_eq!(stack.end.0 % ASM_STP_ALIGN, 0, "Misaligned stack region.");
+ let eh_stack = layout::eh_stack_range();
+
+ assert_ne!(eh_stack.end - eh_stack.start, 0, "EH stack region is empty.");
+ assert_eq!(eh_stack.start.0 % ASM_STP_ALIGN, 0, "Misaligned EH stack region.");
+ assert_eq!(eh_stack.end.0 % ASM_STP_ALIGN, 0, "Misaligned EH stack region.");
+
// Zero all memory that could hold secrets and that can't be safely written to from Rust.
// Disable the exception vector, caches and page table and then jump to the payload at the
// given address, passing it the given FDT pointer.
@@ -250,6 +256,18 @@
"cmp {cache_line}, {stack_end}",
"b.lo 0b",
+ "mov {cache_line}, {eh_stack}",
+ // Zero EH stack region.
+ "0: stp xzr, xzr, [{eh_stack}], 16",
+ "cmp {eh_stack}, {eh_stack_end}",
+ "b.lo 0b",
+
+ // Flush d-cache over EH stack region.
+ "0: dc cvau, {cache_line}",
+ "add {cache_line}, {cache_line}, {dcache_line_size}",
+ "cmp {cache_line}, {eh_stack_end}",
+ "b.lo 0b",
+
"msr sctlr_el1, {sctlr_el1_val}",
"isb",
"mov x1, xzr",
@@ -293,6 +311,8 @@
scratch_end = in(reg) u64::try_from(scratch.end.0).unwrap(),
stack = in(reg) u64::try_from(stack.start.0).unwrap(),
stack_end = in(reg) u64::try_from(stack.end.0).unwrap(),
+ eh_stack = in(reg) u64::try_from(eh_stack.start.0).unwrap(),
+ eh_stack_end = in(reg) u64::try_from(eh_stack.end.0).unwrap(),
dcache_line_size = in(reg) u64::try_from(min_dcache_line_size()).unwrap(),
in("x0") fdt_address,
in("x30") payload_start,
diff --git a/guest/pvmfw/src/memory.rs b/guest/pvmfw/src/memory.rs
index 8e8b338..67a95f4 100644
--- a/guest/pvmfw/src/memory.rs
+++ b/guest/pvmfw/src/memory.rs
@@ -54,7 +54,8 @@
// Stack and scratch ranges are explicitly zeroed and flushed before jumping to payload,
// so dirty state management can be omitted.
- page_table.map_data(&layout::scratch_range().into())?;
+ page_table.map_data(&layout::data_bss_range().into())?;
+ page_table.map_data(&layout::eh_stack_range().into())?;
page_table.map_data(&stack_range().into())?;
page_table.map_code(&layout::text_range().into())?;
page_table.map_rodata(&layout::rodata_range().into())?;
diff --git a/guest/rialto/src/main.rs b/guest/rialto/src/main.rs
index ec26e0f..61e9948 100644
--- a/guest/rialto/src/main.rs
+++ b/guest/rialto/src/main.rs
@@ -73,7 +73,8 @@
fn new_page_table() -> Result<PageTable> {
let mut page_table = PageTable::default();
- page_table.map_data(&layout::scratch_range().into())?;
+ page_table.map_data(&layout::data_bss_range().into())?;
+ page_table.map_data(&layout::eh_stack_range().into())?;
page_table.map_data(&layout::stack_range(40 * PAGE_SIZE).into())?;
page_table.map_code(&layout::text_range().into())?;
page_table.map_rodata(&layout::rodata_range().into())?;
diff --git a/guest/vmbase_example/src/main.rs b/guest/vmbase_example/src/main.rs
index c7ef061..f00effa 100644
--- a/guest/vmbase_example/src/main.rs
+++ b/guest/vmbase_example/src/main.rs
@@ -37,7 +37,10 @@
bionic, configure_heap,
fdt::pci::PciInfo,
generate_image_header,
- layout::{console_uart_page, crosvm::FDT_MAX_SIZE, rodata_range, scratch_range, text_range},
+ layout::{
+ console_uart_page, crosvm::FDT_MAX_SIZE, data_bss_range, eh_stack_range, rodata_range,
+ text_range,
+ },
linker, logger, main,
memory::{PageTable, SIZE_64KB},
};
@@ -54,7 +57,8 @@
page_table.map_device(&console_uart_page().into())?;
page_table.map_code(&text_range().into())?;
page_table.map_rodata(&rodata_range().into())?;
- page_table.map_data(&scratch_range().into())?;
+ page_table.map_data(&data_bss_range().into())?;
+ page_table.map_data(&eh_stack_range().into())?;
page_table.map_data(&boot_stack_range().into())?;
info!("Activating IdMap...");