diff --git a/Cargo.lock b/Cargo.lock index c85bc44..d689ee8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ name = "attestation" version = "0.1.0" dependencies = [ "crypto", - "der 0.7.9", + "der", "policy", "spin 0.9.8", "td-payload", @@ -147,15 +147,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - [[package]] name = "byteorder" version = "1.5.0" @@ -246,12 +237,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e763eef8846b13b380f37dfecda401770b0ca4e56e95170237bd7c25c7db3582" -[[package]] -name = "const-oid" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" - [[package]] name = "const-oid" version = "0.9.6" @@ -272,7 +257,7 @@ name = "crypto" version = "0.1.0" dependencies = [ "cfg-if", - "der 0.7.9", + "der", "ring", "rust_std_stub", "rustls", @@ -321,22 +306,13 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "der" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" -dependencies = [ - "const-oid 0.6.2", -] - [[package]] name = "der" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ - "const-oid 0.9.6", + "const-oid", "der_derive", "zeroize", ] @@ -622,15 +598,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -655,15 +622,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "parse_int" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d695b79916a2c08bcff7be7647ab60d1402885265005a6658ffe6d763553c5a" -dependencies = [ - "num-traits", -] - [[package]] name = "pci" version = "0.1.0" @@ -673,6 +631,7 @@ dependencies = [ "lazy_static", "log", "spin 0.9.8", + "td-payload", "tdx-tdcall", "x86", ] @@ -1097,7 +1056,7 @@ dependencies = [ "anyhow", "cc", "cc-measurement", - "der 0.7.9", + "der", "lazy_static", "r-efi", "ring", @@ -1123,26 +1082,20 @@ dependencies = [ name = "td-shim-tools" version = "0.1.0" dependencies = [ - "anyhow", "argparse", - "block-padding", "byteorder", "cfg-if", "clap", - "der 0.4.5", "env_logger", "hex", "log", - "parse_int", "r-efi", "regex", - "ring", "scroll", "serde", "serde_json", "sha2", "td-layout", - "td-loader", "td-shim", "td-shim-interface", "zeroize", @@ -1548,6 +1501,8 @@ dependencies = [ "anyhow", "clap", "lazy_static", + "serde", + "serde_json", "xshell", ] diff --git a/config/mmio_layout.json b/config/mmio_layout.json new file mode 100644 index 0000000..316f808 --- /dev/null +++ b/config/mmio_layout.json @@ -0,0 +1,8 @@ +{ + "Mmio32Start": "0xC0000000", + "Mmio32Size": "0x20000000", + "PcieConfigBaseAddress": "0xE0000000", + "PcieConfigSize": "0x10000000", + "Mmio64Start": "0x100000000", + "Mmio64Size": "0x40000000" +} \ No newline at end of file diff --git a/src/devices/pci/Cargo.toml b/src/devices/pci/Cargo.toml index ecde9ab..49b4bf0 100644 --- a/src/devices/pci/Cargo.toml +++ b/src/devices/pci/Cargo.toml @@ -11,6 +11,7 @@ lazy_static = { version = "1.0", features = ["spin_no_std"] } log = "0.4.13" spin = "0.9" tdx-tdcall = { path = "../../../deps/td-shim/tdx-tdcall", optional = true } +td-payload = { path = "../../../deps/td-shim/td-payload" } x86 = { version = "0.47.0", optional = true} [features] diff --git a/src/devices/pci/src/config.rs b/src/devices/pci/src/config.rs index d09e540..e8d31a8 100644 --- a/src/devices/pci/src/config.rs +++ b/src/devices/pci/src/config.rs @@ -6,11 +6,10 @@ use bitflags::bitflags; use core::convert::From; use crate::mmio::{alloc_mmio32, alloc_mmio64}; -use crate::{PciCommand, PciError, Result}; +use crate::{PciCommand, PciError, Result, PCI_EX_BAR_BASE_ADDRESS}; pub const PCI_CONFIGURATION_ADDRESS_PORT: u16 = 0xCF8; pub const PCI_CONFIGURATION_DATA_PORT: u16 = 0xCFC; -const PCI_EX_BAR_BASE_ADDRESS: u64 = 0xE0000000u64; const PCI_MEM32_BASE_ADDRESS_MASK: u32 = 0xFFFF_FFF0; const PCI_MEM64_BASE_ADDRESS_MASK: u64 = 0xFFFF_FFFF_FFFF_FFF0; diff --git a/src/devices/pci/src/layout.rs b/src/devices/pci/src/layout.rs new file mode 100644 index 0000000..3f774f5 --- /dev/null +++ b/src/devices/pci/src/layout.rs @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +pub const MMIO32_START: u32 = 0xC0000000; +pub const MMIO32_SIZE: u32 = 0x20000000; +pub const PCI_EX_BAR_BASE_ADDRESS: u64 = 0xE0000000; +pub const PCI_EX_BAR_SIZE: u64 = 0x10000000; +pub const MMIO64_START: u64 = 0x100000000; +pub const MMIO64_SIZE: u64 = 0x40000000; diff --git a/src/devices/pci/src/lib.rs b/src/devices/pci/src/lib.rs index abdf668..6957854 100644 --- a/src/devices/pci/src/lib.rs +++ b/src/devices/pci/src/lib.rs @@ -6,9 +6,11 @@ mod config; mod consts; +mod layout; mod mmio; pub use config::*; pub use consts::*; +pub use layout::*; pub use mmio::*; #[cfg(feature = "fuzz")] diff --git a/src/devices/pci/src/mmio.rs b/src/devices/pci/src/mmio.rs index 09e590d..cee28ef 100644 --- a/src/devices/pci/src/mmio.rs +++ b/src/devices/pci/src/mmio.rs @@ -4,11 +4,9 @@ use lazy_static::lazy_static; use spin::Mutex; +use td_payload::mm::MEMORY_MAP; -use crate::{PciError, Result}; - -pub const MMIO32_START: u32 = 0xC000_0000; -pub const MMIO32_SIZE: u32 = 0x2000_0000; +use crate::{PciError, Result, MMIO32_SIZE, MMIO32_START, MMIO64_SIZE, MMIO64_START}; lazy_static! { static ref MMIO32: Mutex = Mutex::new(0); @@ -20,16 +18,24 @@ lazy_static! { static ref MMIO_OFFSET: Mutex = Mutex::new(0); } -pub fn init_mmio(end_of_ram: u64) { - *MMIO32.lock() = MMIO32_START; - - let mmio64_start = if end_of_ram > u32::MAX as u64 { - end_of_ram - } else { - u32::MAX as u64 + 1 - }; +pub fn init_mmio() { + let memory_map = MEMORY_MAP.lock(); + + // Iterate through each region in the memory map and check if it overlaps with the MMIO32 or MMIO64 space. + // If an overlap is detected, panic with an error message indicating an invalid MMIO configuration. + // This ensures that the MMIO space does not conflict with the RAM space. + for region in memory_map.iter() { + if (region.addr < (MMIO32_START + MMIO32_SIZE) as u64 + && region.addr + region.size > MMIO32_START as u64) + || (region.addr < MMIO64_START + MMIO64_SIZE + && region.addr + region.size > MMIO64_START) + { + panic!("Invalid MMIO configuration: MMIO space overlaps with the RAM space."); + } + } - *MMIO64.lock() = mmio64_start; + *MMIO32.lock() = MMIO32_START; + *MMIO64.lock() = MMIO64_START; } #[cfg(feature = "fuzz")] @@ -45,6 +51,8 @@ pub fn alloc_mmio32(size: u32) -> Result { #[cfg(not(feature = "fuzz"))] pub fn alloc_mmio32(size: u32) -> Result { + use crate::MMIO32_SIZE; + let cur = *MMIO32.lock(); let addr = align_up(cur as u64, size as u64).ok_or(PciError::InvalidParameter)?; diff --git a/src/migtd/src/driver/serial.rs b/src/migtd/src/driver/serial.rs index ce9de6b..188723a 100644 --- a/src/migtd/src/driver/serial.rs +++ b/src/migtd/src/driver/serial.rs @@ -4,6 +4,7 @@ use alloc::boxed::Box; use core::sync::atomic::AtomicBool; +use pci::PCI_EX_BAR_BASE_ADDRESS; use td_payload::mm::shared::{alloc_shared_pages, free_shared_pages}; use virtio_serial::*; @@ -48,12 +49,12 @@ impl Timer for SerailTimer { } } -// #[cfg(feature = "virtio-serial")] -pub fn virtio_serial_device_init(end_of_ram: u64) { +#[cfg(feature = "virtio-serial")] +pub fn virtio_serial_device_init() { pci_ex_bar_initialization(); // Initialize MMIO space - pci::init_mmio(end_of_ram); + pci::init_mmio(); // Enumerate the virtio device let (_b, dev, _f) = pci::find_device(VIRTIO_PCI_VENDOR_ID, VIRTIO_PCI_DEVICE_ID).unwrap(); @@ -74,8 +75,6 @@ pub fn virtio_serial_device_init(end_of_ram: u64) { } pub fn pci_ex_bar_initialization() { - const PCI_EX_BAR_BASE_ADDRESS: u64 = 0xE0000000u64; - // PcdPciExpressBaseAddress TBD let pci_exbar_base = PCI_EX_BAR_BASE_ADDRESS; diff --git a/src/migtd/src/driver/vsock.rs b/src/migtd/src/driver/vsock.rs index 97d767f..ba04424 100644 --- a/src/migtd/src/driver/vsock.rs +++ b/src/migtd/src/driver/vsock.rs @@ -66,11 +66,11 @@ pub fn vmcall_vsock_device_init(mid: u64, cid: u64) { } #[cfg(feature = "virtio-vsock")] -pub fn virtio_vsock_device_init(end_of_ram: u64) { +pub fn virtio_vsock_device_init() { pci_ex_bar_initialization(); // Initialize MMIO space - pci::init_mmio(end_of_ram); + pci::init_mmio(); // Enumerate the virtio device let (_b, dev, _f) = pci::find_device(VIRTIO_PCI_VENDOR_ID, VIRTIO_PCI_DEVICE_ID).unwrap(); @@ -95,7 +95,7 @@ pub fn virtio_vsock_device_init(end_of_ram: u64) { #[cfg(feature = "virtio-vsock")] pub fn pci_ex_bar_initialization() { - const PCI_EX_BAR_BASE_ADDRESS: u64 = 0xE0000000u64; + use pci::PCI_EX_BAR_BASE_ADDRESS; // PcdPciExpressBaseAddress TBD let pci_exbar_base = PCI_EX_BAR_BASE_ADDRESS; diff --git a/src/migtd/src/lib.rs b/src/migtd/src/lib.rs index 7e5fcd7..736832f 100644 --- a/src/migtd/src/lib.rs +++ b/src/migtd/src/lib.rs @@ -23,8 +23,6 @@ pub mod ratls; #[cfg(target_os = "none")] pub extern "C" fn _start(hob: u64, payload: u64) -> ! { use td_payload::arch; - #[cfg(any(feature = "virtio-serial", feature = "virtio-vsock"))] - use td_payload::mm::end_of_ram; use td_payload::mm::layout::*; const STACK_SIZE: usize = 0x1_0000; @@ -57,11 +55,11 @@ pub extern "C" fn _start(hob: u64, payload: u64) -> ! { driver::timer::init_timer(); #[cfg(feature = "virtio-serial")] - driver::serial::virtio_serial_device_init(end_of_ram() as u64); + driver::serial::virtio_serial_device_init(); // Init the vsock-virtio device #[cfg(feature = "virtio-vsock")] - driver::vsock::virtio_vsock_device_init(end_of_ram() as u64); + driver::vsock::virtio_vsock_device_init(); arch::init::init(&layout, main); } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index a01c350..417a507 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -10,3 +10,5 @@ clap = { version = "4.0", features = ["derive"] } xshell = "0.2" lazy_static = "1.4.0" anyhow = "1.0" +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } diff --git a/xtask/src/build.rs b/xtask/src/build.rs index 5b196c9..ec2ea18 100644 --- a/xtask/src/build.rs +++ b/xtask/src/build.rs @@ -11,6 +11,8 @@ use std::{ }; use xshell::{cmd, Shell}; +use crate::config; + const MIGTD_DEFAULT_FEATURES: &str = "stack-guard,virtio-vsock"; const MIGTD_KVM_FEATURES: &str = MIGTD_DEFAULT_FEATURES; const DEFAULT_IMAGE_NAME: &str = "migtd.bin"; @@ -27,6 +29,7 @@ lazy_static! { static ref DEFAULT_SHIM_LAYOUT: PathBuf = PROJECT_ROOT.join("config/shim_layout.json"); static ref DEFAULT_IMAGE_LAYOUT: PathBuf = PROJECT_ROOT.join("config/image_layout.json"); static ref DEFAULT_SERVTD_INFO: PathBuf = PROJECT_ROOT.join("config/servtd_info.json"); + static ref MMIO_LAYOUT_SOURCE: PathBuf = PROJECT_ROOT.join("src/devices/pci/src/layout.rs"); } #[derive(Clone, Args)] @@ -66,6 +69,9 @@ pub(crate) struct BuildArgs { /// Log level control in migtd, default value is `off` for release and `info` for debug #[clap(short, long)] log_level: Option, + /// MMIO space layout configuration for migtd + #[clap(long)] + mmio_config: Option, } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] @@ -112,6 +118,7 @@ impl LogLevel { impl BuildArgs { pub fn build(&self) -> Result { + self.create_mmio_config()?; let (reset_vector, shim) = self.build_shim()?; let migtd = self.build_migtd()?; let bin = self.build_final(reset_vector.as_path(), shim.as_path(), migtd.as_path())?; @@ -165,6 +172,13 @@ impl BuildArgs { Ok(()) } + fn create_mmio_config(&self) -> Result<()> { + if let Some(json_path) = &self.mmio_config { + config::generate_mmio_config(json_path, &MMIO_LAYOUT_SOURCE)?; + } + Ok(()) + } + fn build_migtd(&self) -> Result { let sh = Shell::new()?; sh.set_var("CC_x86_64_unknown_none", "clang"); diff --git a/xtask/src/config.rs b/xtask/src/config.rs new file mode 100644 index 0000000..702ebab --- /dev/null +++ b/xtask/src/config.rs @@ -0,0 +1,96 @@ +use anyhow::{anyhow, Result}; +use serde::Deserialize; +use std::fs; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +#[allow(unused)] +#[derive(Deserialize)] +struct MmioConfig { + #[serde(rename = "Mmio32Start", deserialize_with = "from_hex_str")] + mmio32_start: u64, + #[serde(rename = "Mmio32Size", deserialize_with = "from_hex_str")] + mmio32_size: u64, + #[serde(rename = "PcieConfigBaseAddress", deserialize_with = "from_hex_str")] + pcie_config_base: u64, + #[serde(rename = "PcieConfigSize", deserialize_with = "from_hex_str")] + pcie_config_size: u64, + #[serde(rename = "Mmio64Start", deserialize_with = "from_hex_str")] + mmio64_start: u64, + #[serde(rename = "Mmio64Size", deserialize_with = "from_hex_str")] + mmio64_size: u64, +} + +fn from_hex_str<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let s: String = Deserialize::deserialize(deserializer)?; + u64::from_str_radix(s.trim_start_matches("0x"), 16).map_err(serde::de::Error::custom) +} + +pub fn generate_mmio_config(json_path: &PathBuf, output_path: &PathBuf) -> Result<()> { + let json_content = fs::read_to_string(json_path)?; + let config: MmioConfig = serde_json::from_str(&json_content)?; + + if !is_mmio_config_valid(&config) { + return Err(anyhow!("Invalid MMIO configuration")); + } + + let rust_code = format!( + "// Copyright (c) 2024 Intel Corporation\n\ + //\n\ + // SPDX-License-Identifier: BSD-2-Clause-Patent\n\ + \n\ + pub const MMIO32_START: u32 = 0x{:X};\n\ + pub const MMIO32_SIZE: u32 = 0x{:X};\n\ + pub const PCI_EX_BAR_BASE_ADDRESS: u64 = 0x{:X};\n\ + pub const PCI_EX_BAR_SIZE: u64 = 0x{:X};\n\ + pub const MMIO64_START: u64 = 0x{:X};\n\ + pub const MMIO64_SIZE: u64 = 0x{:X};\n", + config.mmio32_start, + config.mmio32_size, + config.pcie_config_base, + config.pcie_config_size, + config.mmio64_start, + config.mmio64_size, + ); + + let mut file = File::create(output_path)?; + file.write_all(rust_code.as_bytes())?; + Ok(()) +} + +fn is_mmio_config_valid(config: &MmioConfig) -> bool { + // Checks if the MMIO32 values are valid + if config.mmio32_size > u32::MAX as u64 + || config + .mmio32_start + .checked_add(config.mmio32_size) + .is_none_or(|sum| sum > u32::MAX as u64) + { + return false; + } + + // Ensure that the PCIe config range does not overlap with the MMIO32 space. + if config.pcie_config_base < (config.mmio32_start + config.mmio32_size) as u64 + && config.pcie_config_base + config.pcie_config_size > config.mmio32_start as u64 + { + return false; + } + + // Ensure that the MMIO64 range does not overlap with the MMIO32 space. + if config.mmio64_start <= u32::MAX as u64 { + return false; + } + + // Ensure that the MMIO64 range does not overlap with the PCIe space. + if config.mmio64_start < config.pcie_config_base + config.pcie_config_size + && config.mmio64_start + config.mmio64_size > config.pcie_config_base + { + return false; + } + + true +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 0a1b3c9..9eedd00 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: BSD-2-Clause-Patent mod build; +mod config; mod library; mod servtd_info_hash;