Merge "vmbase: Clients separate eh_stack from .data+.bss" into main am: ff84daefc8

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/3383329

Change-Id: I1e2863208fdd8ff7483746ca73043d457b45880c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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...");
diff --git a/libs/libvmbase/src/layout.rs b/libs/libvmbase/src/layout.rs
index adcb2fa..2f710ef 100644
--- a/libs/libvmbase/src/layout.rs
+++ b/libs/libvmbase/src/layout.rs
@@ -80,6 +80,11 @@
     linker_region!(bss_begin, bss_end)
 }
 
+/// Writable data region for .data and .bss.
+pub fn data_bss_range() -> Range<VirtualAddress> {
+    linker_region!(data_begin, bss_end)
+}
+
 /// Writable data region for the stack.
 pub fn stack_range(stack_size: usize) -> Range<VirtualAddress> {
     let end = linker_addr!(init_stack_pointer);
@@ -89,9 +94,9 @@
     start..end
 }
 
-/// All writable sections, excluding the stack.
-pub fn scratch_range() -> Range<VirtualAddress> {
-    linker_region!(eh_stack_limit, bss_end)
+/// Writable data region for the exception handler stack.
+pub fn eh_stack_range() -> Range<VirtualAddress> {
+    linker_region!(eh_stack_limit, init_eh_stack_pointer)
 }
 
 /// Range of the page at UART_PAGE_ADDR of PAGE_SIZE.
diff --git a/libs/libvmbase/src/linker.rs b/libs/libvmbase/src/linker.rs
index 97bef3f..40afce5 100644
--- a/libs/libvmbase/src/linker.rs
+++ b/libs/libvmbase/src/linker.rs
@@ -35,6 +35,8 @@
     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 exception handler stack.
+    pub static init_eh_stack_pointer: u8;
     /// First byte past the region available for the stack.
     pub static init_stack_pointer: u8;
     /// First byte of the `.rodata` section.