Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5349,6 +5349,8 @@ name = "page_table"
version = "0.0.0"
dependencies = [
"bitfield-struct 0.11.0",
"static_assertions",
"thiserror 2.0.16",
"tracing",
"zerocopy 0.8.25",
]
Expand Down
15 changes: 10 additions & 5 deletions tmk/tmk_vmm/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use vm_topology::processor::ProcessorTopology;
use vm_topology::processor::aarch64::Aarch64Topology;
use vm_topology::processor::x86::X86Topology;
use zerocopy::FromBytes as _;
use zerocopy::FromZeros;
use zerocopy::IntoBytes;

/// Loads a TMK, returning the initial registers for the BSP.
Expand All @@ -38,19 +39,23 @@ pub fn load_x86(
let load_info = load_common(&mut loader, tmk, test)?;

let page_table_base = load_info.next_available_address;
let page_tables = page_table::x64::build_page_tables_64(
let mut page_table_work_buffer: Vec<page_table::x64::PageTable> =
vec![page_table::x64::PageTable::new_zeroed(); page_table::x64::PAGE_TABLE_MAX_COUNT];
let mut page_tables: Vec<u8> = vec![0; page_table::x64::PAGE_TABLE_MAX_BYTES];
let page_table_builder = page_table::x64::IdentityMapBuilder::new(
page_table_base,
0,
page_table::IdentityMapSize::Size4Gb,
None,
);
page_table_work_buffer.as_mut_slice(),
page_tables.as_mut_slice(),
)?;
let page_tables = page_table_builder.build();
loader
.import_pages(
page_table_base >> 12,
page_tables.len() as u64 >> 12,
"page_tables",
loader::importer::BootPageAcceptance::Exclusive,
&page_tables,
page_tables,
)
.context("failed to import page tables")?;

Expand Down
2 changes: 1 addition & 1 deletion vm/loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ aarch64defs.workspace = true
igvm.workspace = true
loader_defs.workspace = true
memory_range.workspace = true
page_table.workspace = true
page_table = {workspace = true, features = ["tracing"] }
hvdef.workspace = true
vm_topology.workspace = true
x86defs.workspace = true
Expand Down
9 changes: 8 additions & 1 deletion vm/loader/page_table/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ rust-version.workspace = true

[dependencies]
bitfield-struct.workspace = true
tracing.workspace = true
thiserror.workspace = true
static_assertions.workspace = true
tracing = { workspace = true, optional = true }
zerocopy.workspace = true

[features]
tracing = ["dep:tracing", "std"]
std = []

[lints]
workspace = true
22 changes: 14 additions & 8 deletions vm/loader/page_table/src/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ impl<'a> Arm64PageTableSpace<'a> {
debug_assert!(aligned(phys_table_start, Arm64PageSize::Small));
debug_assert!(index < PAGE_SIZE_4K as usize / size_of::<Arm64PageTableEntry>());

#[cfg(feature = "tracing")]
tracing::debug!(
"Writing page table entry {entry:#016x}, index {index:#x}, table {phys_table_start:#x}"
);
Expand Down Expand Up @@ -682,8 +683,8 @@ pub fn build_identity_page_tables_aarch64(
start_gpa: u64,
size: u64,
memory_attribute_indirection: MemoryAttributeIndirectionEl1,
page_table_region_size: usize,
) -> Vec<u8> {
page_table_space: &mut [u8],
) -> &[u8] {
// start_gpa and size must be 2MB aligned.
if !aligned(start_gpa, Arm64PageSize::Large) {
panic!("start_gpa not 2mb aligned");
Expand All @@ -693,13 +694,13 @@ pub fn build_identity_page_tables_aarch64(
panic!("size not 2mb aligned");
}

#[cfg(feature = "tracing")]
tracing::debug!(
"Creating Aarch64 page tables at {page_table_gpa:#x} mapping starting at {start_gpa:#x} of size {size} bytes"
);

let mut page_table_space = vec![0; page_table_region_size];
let mut page_tables =
Arm64PageTableSpace::new(page_table_gpa as usize, &mut page_table_space).unwrap();
Arm64PageTableSpace::new(page_table_gpa as usize, page_table_space).unwrap();
page_tables
.map_range(
start_gpa,
Expand All @@ -713,17 +714,22 @@ pub fn build_identity_page_tables_aarch64(
.unwrap();

let used_space = page_tables.used_space();
tracing::debug!("Page tables use {used_space} bytes");
tracing::debug!("Page tables stats by level: {:?}", page_tables.lvl_stats());

page_table_space.truncate(used_space);
#[cfg(feature = "tracing")]
{
tracing::debug!("Page tables use {used_space} bytes");
tracing::debug!("Page tables stats by level: {:?}", page_tables.lvl_stats());
}

page_table_space
&page_table_space[0..used_space]
}

#[cfg(test)]
mod tests {
use std;

use super::*;
use std::vec;

const DUMP_PAGE_TABLES: bool = false;

Expand Down
29 changes: 29 additions & 0 deletions vm/loader/page_table/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,41 @@

//! Methods to construct page tables.
#![cfg_attr(not(feature = "std"), no_std)]
#![expect(missing_docs)]
#![forbid(unsafe_code)]

pub mod aarch64;
pub mod x64;

use thiserror::Error;

/// Errors returned by the Page Table Builder
#[derive(Debug, PartialEq, Eq, Error)]
pub enum Error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an error condition for "not enough bytes to create the pagetable?" I'm trying to find that failure condition in the builder, as well

/// The PageTableBuilder bytes buffer does not match the size of the struct buffer
#[error(
"PageTableBuilder bytes buffer size {bytes_buf} does not match the struct buffer size [{struct_buf}]"
)]
BadBufferSize { bytes_buf: usize, struct_buf: usize },

/// The page table mapping crosses the 512GB boundary
#[error("page table builder address {0:#x} resides above the 512GB boundary")]
MappingTooLarge(u64),

/// The page table builder mapping ranges are not sorted
#[error("the page table builder was invoked with unsorted mapping ranges")]
UnsortedMappings,

/// The page table builder was given an invalid range
#[error("page table builder range.end() < range.start()")]
InvalidRange,

/// The page table builder is generating overlapping mappings
#[error("the page table builder was invoked with overlapping mappings")]
OverlappingMappings,
}

/// Size of the initial identity map
#[derive(Debug, Copy, Clone)]
pub enum IdentityMapSize {
Expand Down
Loading
Loading