vmbase: Introduce layout::UART_PAGE
As most users of console::BASE_ADDRESS align it to the page granule,
provide a constant that already represent the base of the page. Make it
part of vmbase::layout (instead of vmbase::console) as it is, in fact,
defined by the VM layout.
As console_uart_range() is only used for constructing page tables, which
can only map ranges at page granularity, rework it based on UART_PAGE.
Test: m pvmfw librialto libvmbase_example
Change-Id: I9942e193d575b32072e880fa345c3634b1561298
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 43822a5..cc6e302 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -30,9 +30,9 @@
use log::LevelFilter;
use vmbase::util::RangeExt as _;
use vmbase::{
- configure_heap, console,
+ configure_heap,
hyp::{get_mem_sharer, get_mmio_guard},
- layout::{self, crosvm},
+ layout::{self, crosvm, UART_PAGE_ADDR},
main,
memory::{min_dcache_line_size, MemoryTracker, MEMORY, SIZE_128KB, SIZE_4KB},
power::reboot,
@@ -256,7 +256,7 @@
// Call unshare_all_memory here (instead of relying on the dtor) while UART is still mapped.
MEMORY.lock().as_mut().unwrap().unshare_all_memory();
if let Some(mmio_guard) = get_mmio_guard() {
- mmio_guard.unmap(console::BASE_ADDRESS).map_err(|e| {
+ mmio_guard.unmap(UART_PAGE_ADDR).map_err(|e| {
error!("Failed to unshare the UART: {e}");
RebootReason::InternalError
})?;
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 5a3735e..8d12b57 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -51,7 +51,7 @@
page_table.map_code(&layout::text_range().into())?;
page_table.map_rodata(&layout::rodata_range().into())?;
page_table.map_data_dbm(&appended_payload_range().into())?;
- if let Err(e) = page_table.map_device(&layout::console_uart_range().into()) {
+ if let Err(e) = page_table.map_device(&layout::console_uart_page().into()) {
error!("Failed to remap the UART as a dynamic page table entry: {e}");
return Err(e);
}
diff --git a/rialto/src/main.rs b/rialto/src/main.rs
index 864f5e4..701a287 100644
--- a/rialto/src/main.rs
+++ b/rialto/src/main.rs
@@ -48,7 +48,7 @@
configure_heap,
fdt::SwiotlbInfo,
hyp::{get_mem_sharer, get_mmio_guard},
- layout::{self, crosvm},
+ layout::{self, crosvm, UART_PAGE_ADDR},
main,
memory::{MemoryTracker, PageTable, MEMORY, PAGE_SIZE, SIZE_128KB},
power::reboot,
@@ -78,7 +78,7 @@
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())?;
- page_table.map_device(&layout::console_uart_range().into())?;
+ page_table.map_device(&layout::console_uart_page().into())?;
Ok(page_table)
}
@@ -205,7 +205,7 @@
// No logging after unmapping UART.
if let Some(mmio_guard) = get_mmio_guard() {
- mmio_guard.unmap(vmbase::console::BASE_ADDRESS)?;
+ mmio_guard.unmap(UART_PAGE_ADDR)?;
}
// Unshares all memory and deactivates page table.
drop(MEMORY.lock().take());
diff --git a/vmbase/src/entry.rs b/vmbase/src/entry.rs
index bb5ccef..dedc6ae 100644
--- a/vmbase/src/entry.rs
+++ b/vmbase/src/entry.rs
@@ -15,8 +15,10 @@
//! Rust entry point.
use crate::{
- bionic, console, heap, hyp, logger,
- memory::{page_4kb_of, SIZE_16KB, SIZE_4KB},
+ bionic, console, heap, hyp,
+ layout::UART_PAGE_ADDR,
+ logger,
+ memory::{SIZE_16KB, SIZE_4KB},
power::{reboot, shutdown},
rand,
};
@@ -43,8 +45,8 @@
granule == SIZE_4KB || granule == SIZE_16KB
});
// Validate the assumption above by ensuring that the UART is not moved to another page:
- const_assert_eq!(page_4kb_of(console::BASE_ADDRESS), 0);
- mmio_guard.map(console::BASE_ADDRESS)?;
+ const_assert_eq!(UART_PAGE_ADDR, 0);
+ mmio_guard.map(UART_PAGE_ADDR)?;
}
Ok(())
diff --git a/vmbase/src/exceptions.rs b/vmbase/src/exceptions.rs
index 7833334..11fcd93 100644
--- a/vmbase/src/exceptions.rs
+++ b/vmbase/src/exceptions.rs
@@ -15,15 +15,14 @@
//! Helper functions and structs for exception handlers.
use crate::{
- console, eprintln,
+ eprintln,
+ layout::UART_PAGE_ADDR,
memory::{page_4kb_of, MemoryTrackerError},
read_sysreg,
};
use aarch64_paging::paging::VirtualAddress;
use core::fmt;
-const UART_PAGE: usize = page_4kb_of(console::BASE_ADDRESS);
-
/// Represents an error that can occur while handling an exception.
#[derive(Debug)]
pub enum HandleExceptionError {
@@ -134,6 +133,6 @@
}
fn is_uart_exception(&self) -> bool {
- self.esr == Esr::DataAbortSyncExternalAbort && page_4kb_of(self.far.0) == UART_PAGE
+ self.esr == Esr::DataAbortSyncExternalAbort && page_4kb_of(self.far.0) == UART_PAGE_ADDR
}
}
diff --git a/vmbase/src/layout.rs b/vmbase/src/layout.rs
index f7e8170..993141d 100644
--- a/vmbase/src/layout.rs
+++ b/vmbase/src/layout.rs
@@ -16,15 +16,21 @@
pub mod crosvm;
-use crate::console::BASE_ADDRESS;
+use crate::console;
use crate::linker::__stack_chk_guard;
+use crate::memory::{page_4kb_of, PAGE_SIZE};
use aarch64_paging::paging::VirtualAddress;
use core::ops::Range;
use core::ptr::addr_of;
+use static_assertions::const_assert_eq;
/// First address that can't be translated by a level 1 TTBR0_EL1.
pub const MAX_VIRT_ADDR: usize = 1 << 40;
+/// Address of the single page containing all the UART devices.
+pub const UART_PAGE_ADDR: usize = 0;
+const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(console::BASE_ADDRESS));
+
/// Get an address from a linker-defined symbol.
#[macro_export]
macro_rules! linker_addr {
@@ -86,11 +92,9 @@
linker_region!(eh_stack_limit, bss_end)
}
-/// UART console range.
-pub fn console_uart_range() -> Range<VirtualAddress> {
- const CONSOLE_LEN: usize = 1; // `uart::Uart` only uses one u8 register.
-
- VirtualAddress(BASE_ADDRESS)..VirtualAddress(BASE_ADDRESS + CONSOLE_LEN)
+/// Range of the page at UART_PAGE_ADDR of PAGE_SIZE.
+pub fn console_uart_page() -> Range<VirtualAddress> {
+ VirtualAddress(UART_PAGE_ADDR)..VirtualAddress(UART_PAGE_ADDR + PAGE_SIZE)
}
/// Read-write data (original).
diff --git a/vmbase/src/memory/shared.rs b/vmbase/src/memory/shared.rs
index 5a25d9f..d869b16 100644
--- a/vmbase/src/memory/shared.rs
+++ b/vmbase/src/memory/shared.rs
@@ -17,11 +17,11 @@
use super::dbm::{flush_dirty_range, mark_dirty_block, set_dbm_enabled};
use super::error::MemoryTrackerError;
use super::page_table::{PageTable, MMIO_LAZY_MAP_FLAG};
-use super::util::{page_4kb_of, virt_to_phys};
-use crate::console;
+use super::util::virt_to_phys;
use crate::dsb;
use crate::exceptions::HandleExceptionError;
use crate::hyp::{self, get_mem_sharer, get_mmio_guard};
+use crate::layout;
use crate::util::unchecked_align_down;
use crate::util::RangeExt as _;
use aarch64_paging::paging::{
@@ -412,7 +412,7 @@
let base = unchecked_align_down(phys, self.granule);
// TODO(ptosi): Share the UART using this method and remove the hardcoded check.
- if self.frames.contains(&base) || base == page_4kb_of(console::BASE_ADDRESS) {
+ if self.frames.contains(&base) || base == layout::UART_PAGE_ADDR {
return Err(MemoryTrackerError::DuplicateMmioShare(base));
}