Use macro to handle TDX-related code

This commit is contained in:
Hsy-Intel 2025-03-13 21:58:10 +00:00 committed by Tate, Hongliang Tian
parent dd3aa8fe81
commit 49e6cd2712
14 changed files with 166 additions and 193 deletions

View File

@ -14,12 +14,11 @@ cfg_if! {
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] {
mod tdxguest; mod tdxguest;
use tdx_guest::tdx_is_enabled;
pub use tdxguest::TdxGuest; pub use tdxguest::TdxGuest;
} }
} }
use ostd::if_tdx_enabled;
pub use pty::{new_pty_pair, PtyMaster, PtySlave}; pub use pty::{new_pty_pair, PtyMaster, PtySlave};
pub use random::Random; pub use random::Random;
pub use urandom::Urandom; pub use urandom::Urandom;
@ -41,15 +40,10 @@ pub fn init() -> Result<()> {
add_node(console, "console")?; add_node(console, "console")?;
let tty = Arc::new(tty::TtyDevice); let tty = Arc::new(tty::TtyDevice);
add_node(tty, "tty")?; add_node(tty, "tty")?;
cfg_if! { if_tdx_enabled!({
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { #[cfg(target_arch = "x86_64")]
let tdx_guest = Arc::new(tdxguest::TdxGuest); add_node(Arc::new(tdxguest::TdxGuest), "tdx_guest")?;
});
if tdx_is_enabled() {
add_node(tdx_guest, "tdx_guest")?;
}
}
}
let random = Arc::new(random::Random); let random = Arc::new(random::Random);
add_node(random, "random")?; add_node(random, "random")?;
let urandom = Arc::new(urandom::Urandom); let urandom = Arc::new(urandom::Urandom);

View File

@ -8,10 +8,12 @@ use core::ffi::CStr;
use linux_boot_params::{BootParams, E820Type, LINUX_BOOT_HEADER_MAGIC}; use linux_boot_params::{BootParams, E820Type, LINUX_BOOT_HEADER_MAGIC};
use crate::{ use crate::{
arch::init_cvm_guest,
boot::{ boot::{
memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType}, memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType},
BootloaderAcpiArg, BootloaderFramebufferArg, BootloaderAcpiArg, BootloaderFramebufferArg,
}, },
if_tdx_enabled,
mm::{ mm::{
kspace::{paddr_to_vaddr, LINEAR_MAPPING_BASE_VADDR}, kspace::{paddr_to_vaddr, LINEAR_MAPPING_BASE_VADDR},
Paddr, Paddr,
@ -114,6 +116,18 @@ fn parse_memory_regions(boot_params: &BootParams) -> MemoryRegionArray {
// Add regions from E820. // Add regions from E820.
let num_entries = boot_params.e820_entries as usize; let num_entries = boot_params.e820_entries as usize;
for e820_entry in &boot_params.e820_table[0..num_entries] { for e820_entry in &boot_params.e820_table[0..num_entries] {
if_tdx_enabled!({
if (e820_entry.addr..(e820_entry.addr + e820_entry.size)).contains(&0x800000) {
regions
.push(MemoryRegion::new(
e820_entry.addr as usize,
e820_entry.size as usize,
MemoryRegionType::Reclaimable,
))
.unwrap();
continue;
}
});
regions regions
.push(MemoryRegion::new( .push(MemoryRegion::new(
e820_entry.addr as usize, e820_entry.addr as usize,
@ -165,6 +179,9 @@ unsafe extern "sysv64" fn __linux_boot(params_ptr: *const BootParams) -> ! {
use crate::boot::{call_ostd_main, EarlyBootInfo, EARLY_INFO}; use crate::boot::{call_ostd_main, EarlyBootInfo, EARLY_INFO};
#[cfg(feature = "cvm_guest")]
init_cvm_guest();
EARLY_INFO.call_once(|| EarlyBootInfo { EARLY_INFO.call_once(|| EarlyBootInfo {
bootloader_name: parse_bootloader_name(params), bootloader_name: parse_bootloader_name(params),
kernel_cmdline: parse_kernel_commandline(params), kernel_cmdline: parse_kernel_commandline(params),

View File

@ -27,8 +27,6 @@
//! This sequence does not need to be strictly followed, and there may be //! This sequence does not need to be strictly followed, and there may be
//! different considerations in different systems. //! different considerations in different systems.
use cfg_if::cfg_if;
use crate::{ use crate::{
arch::x86::kernel::{ arch::x86::kernel::{
acpi::get_acpi_tables, acpi::get_acpi_tables,
@ -37,17 +35,10 @@ use crate::{
Level, TriggerMode, Level, TriggerMode,
}, },
}, },
if_tdx_enabled,
mm::{paddr_to_vaddr, PAGE_SIZE}, mm::{paddr_to_vaddr, PAGE_SIZE},
}; };
cfg_if! {
if #[cfg(feature = "cvm_guest")] {
use tdx_guest::tdx_is_enabled;
use crate::arch::x86::kernel::acpi::AcpiMemoryHandler;
use acpi::platform::wakeup_aps;
}
}
/// Get the number of processors /// Get the number of processors
/// ///
/// This function needs to be called after the OS initializes the ACPI table. /// This function needs to be called after the OS initializes the ACPI table.
@ -73,12 +64,14 @@ pub(crate) fn bringup_all_aps(num_cpus: u32) {
copy_ap_boot_code(); copy_ap_boot_code();
fill_boot_stack_array_ptr(); fill_boot_stack_array_ptr();
fill_boot_pt_ptr(); fill_boot_pt_ptr();
cfg_if! { if_tdx_enabled!({
if #[cfg(feature = "cvm_guest")] { use crate::arch::x86::kernel::acpi::AcpiMemoryHandler;
if tdx_is_enabled() { use acpi::platform::wakeup_aps;
let acpi_tables = get_acpi_tables().unwrap();
for ap_num in 1..num_cpus { for ap_num in 1..num_cpus {
wakeup_aps( wakeup_aps(
&ACPI_TABLES.get().unwrap().lock(), &acpi_tables,
AcpiMemoryHandler {}, AcpiMemoryHandler {},
ap_num, ap_num,
AP_BOOT_START_PA as u64, AP_BOOT_START_PA as u64,
@ -88,11 +81,7 @@ pub(crate) fn bringup_all_aps(num_cpus: u32) {
} }
} else { } else {
send_boot_ipis(); send_boot_ipis();
} });
} else {
send_boot_ipis();
}
}
} }
/// This is where the linker load the symbols in the `.ap_boot` section. /// This is where the linker load the symbols in the `.ap_boot` section.

View File

@ -16,6 +16,7 @@ use volatile::{
use crate::{ use crate::{
arch::{iommu::has_interrupt_remapping, x86::kernel::acpi::get_platform_info}, arch::{iommu::has_interrupt_remapping, x86::kernel::acpi::get_platform_info},
if_tdx_enabled,
mm::paddr_to_vaddr, mm::paddr_to_vaddr,
sync::SpinLock, sync::SpinLock,
trap::IrqLine, trap::IrqLine,
@ -24,7 +25,6 @@ use crate::{
cfg_if! { cfg_if! {
if #[cfg(feature = "cvm_guest")] { if #[cfg(feature = "cvm_guest")] {
use ::tdx_guest::tdx_is_enabled;
use crate::arch::tdx_guest; use crate::arch::tdx_guest;
} }
} }
@ -184,16 +184,15 @@ pub fn init() {
// FIXME: Is it possible to have an address that is not the default 0xFEC0_0000? // FIXME: Is it possible to have an address that is not the default 0xFEC0_0000?
// Need to find a way to determine if it is a valid address or not. // Need to find a way to determine if it is a valid address or not.
const IO_APIC_DEFAULT_ADDRESS: usize = 0xFEC0_0000; const IO_APIC_DEFAULT_ADDRESS: usize = 0xFEC0_0000;
#[cfg(feature = "cvm_guest")] if_tdx_enabled!({
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the `IO_APIC_DEFAULT_ADDRESS` is a valid MMIO address before this operation. // This is safe because we are ensuring that the `IO_APIC_DEFAULT_ADDRESS` is a valid MMIO address before this operation.
// The `IO_APIC_DEFAULT_ADDRESS` is a well-known address used for IO APICs in x86 systems. // The `IO_APIC_DEFAULT_ADDRESS` is a well-known address used for IO APICs in x86 systems.
// We are also ensuring that we are only unprotecting a single page. // We are also ensuring that we are only unprotecting a single page.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(IO_APIC_DEFAULT_ADDRESS, 1).unwrap(); tdx_guest::unprotect_gpa_range(IO_APIC_DEFAULT_ADDRESS, 1).unwrap();
} }
} });
let mut io_apic = unsafe { IoApicAccess::new(IO_APIC_DEFAULT_ADDRESS) }; let mut io_apic = unsafe { IoApicAccess::new(IO_APIC_DEFAULT_ADDRESS) };
io_apic.set_id(0); io_apic.set_id(0);
let id = io_apic.id(); let id = io_apic.id();
@ -217,15 +216,14 @@ pub fn init() {
let mut vec = Vec::new(); let mut vec = Vec::new();
for id in 0..apic.io_apics.len() { for id in 0..apic.io_apics.len() {
let io_apic = apic.io_apics.get(id).unwrap(); let io_apic = apic.io_apics.get(id).unwrap();
#[cfg(feature = "cvm_guest")] if_tdx_enabled!({
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the `io_apic.address` is a valid MMIO address before this operation. // This is safe because we are ensuring that the `io_apic.address` is a valid MMIO address before this operation.
// We are also ensuring that we are only unprotecting a single page. // We are also ensuring that we are only unprotecting a single page.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(io_apic.address as usize, 1).unwrap(); tdx_guest::unprotect_gpa_range(io_apic.address as usize, 1).unwrap();
} }
} });
let interrupt_base = io_apic.global_system_interrupt_base; let interrupt_base = io_apic.global_system_interrupt_base;
let mut io_apic = unsafe { IoApicAccess::new(io_apic.address as usize) }; let mut io_apic = unsafe { IoApicAccess::new(io_apic.address as usize) };
io_apic.set_id(id as u8); io_apic.set_id(id as u8);

View File

@ -21,13 +21,15 @@ use cfg_if::cfg_if;
use spin::Once; use spin::Once;
use x86::cpuid::{CpuId, FeatureInfo}; use x86::cpuid::{CpuId, FeatureInfo};
use crate::if_tdx_enabled;
cfg_if! { cfg_if! {
if #[cfg(feature = "cvm_guest")] { if #[cfg(feature = "cvm_guest")] {
pub(crate) mod tdx_guest; pub(crate) mod tdx_guest;
use { use {
crate::early_println, crate::early_println,
::tdx_guest::{init_tdx, tdcall::InitError, tdx_is_enabled}, ::tdx_guest::{init_tdx, tdcall::InitError},
}; };
} }
} }
@ -94,21 +96,13 @@ pub(crate) unsafe fn late_init_on_bsp() {
timer::init(); timer::init();
cfg_if! { if_tdx_enabled!({
if #[cfg(feature = "cvm_guest")] {
if !tdx_is_enabled() {
match iommu::init() {
Ok(_) => {}
Err(err) => warn!("IOMMU initialization error:{:?}", err),
}
}
} else { } else {
match iommu::init() { match iommu::init() {
Ok(_) => {} Ok(_) => {}
Err(err) => warn!("IOMMU initialization error:{:?}", err), Err(err) => warn!("IOMMU initialization error:{:?}", err),
} }
} });
}
// Some driver like serial may use PIC // Some driver like serial may use PIC
kernel::pic::init(); kernel::pic::init();
@ -215,3 +209,39 @@ pub(crate) fn enable_cpu_features() {
}); });
} }
} }
/// Inserts a TDX-specific code block.
///
/// This macro conditionally executes a TDX-specific code block based on the following conditions:
/// (1) The `cvm_guest` feature is enabled at compile time.
/// (2) The TDX feature is detected at runtime via `::tdx_guest::tdx_is_enabled()`.
///
/// If both conditions are met, the `if_block` is executed. If an `else_block` is provided, it will be executed
/// when either the `cvm_guest` feature is not enabled or the TDX feature is not detected at runtime.
#[macro_export]
macro_rules! if_tdx_enabled {
// Match when there is an else block
($if_block:block else $else_block:block) => {{
#[cfg(feature = "cvm_guest")]
{
if ::tdx_guest::tdx_is_enabled() {
$if_block
} else {
$else_block
}
}
#[cfg(not(feature = "cvm_guest"))]
{
$else_block
}
}};
// Match when there is no else block
($if_block:block) => {{
#[cfg(feature = "cvm_guest")]
{
if ::tdx_guest::tdx_is_enabled() {
$if_block
}
}
}};
}

View File

@ -29,7 +29,7 @@ use super::ex_table::ExTable;
use crate::{ use crate::{
arch::irq::{disable_local, enable_local}, arch::irq::{disable_local, enable_local},
cpu::{CpuException, CpuExceptionInfo, PageFaultErrorCode}, cpu::{CpuException, CpuExceptionInfo, PageFaultErrorCode},
cpu_local_cell, cpu_local_cell, if_tdx_enabled,
mm::{ mm::{
kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE}, kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE},
page_prop::{CachePolicy, PageProperty}, page_prop::{CachePolicy, PageProperty},
@ -40,7 +40,7 @@ use crate::{
cfg_if! { cfg_if! {
if #[cfg(feature = "cvm_guest")] { if #[cfg(feature = "cvm_guest")] {
use tdx_guest::{tdcall, tdx_is_enabled, handle_virtual_exception}; use tdx_guest::{tdcall, handle_virtual_exception};
use crate::arch::tdx_guest::TrapFrameWrapper; use crate::arch::tdx_guest::TrapFrameWrapper;
} }
} }
@ -354,17 +354,11 @@ fn handle_kernel_page_fault(f: &TrapFrame, page_fault_vaddr: u64) {
let vaddr = (page_fault_vaddr as usize).align_down(PAGE_SIZE); let vaddr = (page_fault_vaddr as usize).align_down(PAGE_SIZE);
let paddr = vaddr - LINEAR_MAPPING_BASE_VADDR; let paddr = vaddr - LINEAR_MAPPING_BASE_VADDR;
cfg_if! { let priv_flags = if_tdx_enabled!({
if #[cfg(feature = "cvm_guest")] {
let priv_flags = if tdx_is_enabled() {
PrivFlags::SHARED | PrivFlags::GLOBAL PrivFlags::SHARED | PrivFlags::GLOBAL
} else { } else {
PrivFlags::GLOBAL PrivFlags::GLOBAL
}; });
} else {
let priv_flags = PrivFlags::GLOBAL;
}
}
// SAFETY: // SAFETY:
// 1. We have checked that the page fault address falls within the address range of the direct // 1. We have checked that the page fault address falls within the address range of the direct

View File

@ -7,8 +7,6 @@ use core::sync::atomic::{AtomicBool, Ordering};
use spin::Once; use spin::Once;
#[cfg(feature = "cvm_guest")]
use crate::mm::frame::allocator;
use crate::{ use crate::{
arch::boot::smp::{bringup_all_aps, get_num_processors}, arch::boot::smp::{bringup_all_aps, get_num_processors},
cpu, cpu,
@ -103,9 +101,6 @@ pub fn boot_all_aps() {
bringup_all_aps(num_cpus); bringup_all_aps(num_cpus);
wait_for_all_aps_started(); wait_for_all_aps_started();
#[cfg(feature = "cvm_guest")]
allocator::reclaim_tdx_ap_boot_memory();
log::info!("All application processors started. The BSP continues to run."); log::info!("All application processors started. The BSP continues to run.");
} }

View File

@ -15,12 +15,12 @@ use log::debug;
use self::bus::MmioBus; use self::bus::MmioBus;
use crate::{ use crate::{
bus::mmio::common_device::MmioCommonDevice, mm::paddr_to_vaddr, sync::SpinLock, trap::IrqLine, bus::mmio::common_device::MmioCommonDevice, if_tdx_enabled, mm::paddr_to_vaddr, sync::SpinLock,
trap::IrqLine,
}; };
cfg_if! { cfg_if! {
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] {
use ::tdx_guest::tdx_is_enabled;
use crate::arch::tdx_guest; use crate::arch::tdx_guest;
} }
} }
@ -32,17 +32,17 @@ pub static MMIO_BUS: SpinLock<MmioBus> = SpinLock::new(MmioBus::new());
static IRQS: SpinLock<Vec<IrqLine>> = SpinLock::new(Vec::new()); static IRQS: SpinLock<Vec<IrqLine>> = SpinLock::new(Vec::new());
pub(crate) fn init() { pub(crate) fn init() {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the address range 0xFEB0_0000 to 0xFEB0_4000 is valid before this operation. // This is safe because we are ensuring that the address range 0xFEB0_0000 to 0xFEB0_4000 is valid before this operation.
// The address range is page-aligned and falls within the MMIO range, which is a requirement for the `unprotect_gpa_range` function. // The address range is page-aligned and falls within the MMIO range, which is a requirement for the `unprotect_gpa_range` function.
// We are also ensuring that we are only unprotecting four pages. // We are also ensuring that we are only unprotecting four pages.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the `unprotect_gpa_range` function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the `unprotect_gpa_range` function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(0xFEB0_0000, 4).unwrap(); tdx_guest::unprotect_gpa_range(0xFEB0_0000, 4).unwrap();
} }
} });
// FIXME: The address 0xFEB0_0000 is obtained from an instance of microvm, and it may not work in other architecture. // FIXME: The address 0xFEB0_0000 is obtained from an instance of microvm, and it may not work in other architecture.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
iter_range(0xFEB0_0000..0xFEB0_4000); iter_range(0xFEB0_0000..0xFEB0_4000);

View File

@ -16,13 +16,13 @@ use crate::{
common_device::PciCommonDevice, common_device::PciCommonDevice,
device_info::PciDeviceLocation, device_info::PciDeviceLocation,
}, },
if_tdx_enabled,
mm::VmIoOnce, mm::VmIoOnce,
trap::IrqLine, trap::IrqLine,
}; };
cfg_if! { cfg_if! {
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] {
use ::tdx_guest::tdx_is_enabled;
use crate::arch::tdx_guest; use crate::arch::tdx_guest;
} }
} }
@ -108,7 +108,8 @@ impl CapabilityMsixData {
// Set message address 0xFEE0_0000 // Set message address 0xFEE0_0000
for i in 0..table_size { for i in 0..table_size {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the physical address of the MSI-X table is valid before this operation. // This is safe because we are ensuring that the physical address of the MSI-X table is valid before this operation.
// We are also ensuring that we are only unprotecting a single page. // We are also ensuring that we are only unprotecting a single page.
@ -117,11 +118,10 @@ impl CapabilityMsixData {
// It is better to add a judgment here in case the device deliberately uses so many interrupt numbers. // It is better to add a judgment here in case the device deliberately uses so many interrupt numbers.
// In addition, due to granularity, the minimum value that can be set here is only one page. // In addition, due to granularity, the minimum value that can be set here is only one page.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the `unprotect_gpa_range` function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the `unprotect_gpa_range` function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(table_bar.io_mem().paddr(), 1).unwrap(); tdx_guest::unprotect_gpa_range(table_bar.io_mem().paddr(), 1).unwrap();
} }
} });
// Set message address and disable this msix entry // Set message address and disable this msix entry
table_bar table_bar
.io_mem() .io_mem()

View File

@ -5,9 +5,9 @@
use core::ops::{Deref, Range}; use core::ops::{Deref, Range};
use align_ext::AlignExt; use align_ext::AlignExt;
use cfg_if::cfg_if;
use crate::{ use crate::{
if_tdx_enabled,
mm::{ mm::{
kspace::kvirt_area::{KVirtArea, Untracked}, kspace::kvirt_area::{KVirtArea, Untracked},
page_prop::{CachePolicy, PageFlags, PageProperty, PrivilegedPageFlags}, page_prop::{CachePolicy, PageFlags, PageProperty, PrivilegedPageFlags},
@ -47,17 +47,11 @@ impl IoMem {
let last_page_end = range.end.align_up(PAGE_SIZE); let last_page_end = range.end.align_up(PAGE_SIZE);
let mut new_kvirt_area = KVirtArea::<Untracked>::new(last_page_end - first_page_start); let mut new_kvirt_area = KVirtArea::<Untracked>::new(last_page_end - first_page_start);
cfg_if! { let priv_flags = if_tdx_enabled!({
if #[cfg(all(feature = "cvm_guest", target_arch = "x86_64"))] {
let priv_flags = if tdx_guest::tdx_is_enabled() {
PrivilegedPageFlags::SHARED PrivilegedPageFlags::SHARED
} else { } else {
PrivilegedPageFlags::empty() PrivilegedPageFlags::empty()
}; });
} else {
let priv_flags = PrivilegedPageFlags::empty();
}
}
let prop = PageProperty { let prop = PageProperty {
flags, flags,

View File

@ -79,9 +79,6 @@ unsafe fn init() {
arch::serial::init(); arch::serial::init();
#[cfg(feature = "cvm_guest")]
arch::init_cvm_guest();
logger::init(); logger::init();
// SAFETY: They are only called once on BSP and ACPI has been initialized. // SAFETY: They are only called once on BSP and ACPI has been initialized.

View File

@ -8,6 +8,7 @@ use cfg_if::cfg_if;
use super::{check_and_insert_dma_mapping, remove_dma_mapping, DmaError, HasDaddr}; use super::{check_and_insert_dma_mapping, remove_dma_mapping, DmaError, HasDaddr};
use crate::{ use crate::{
arch::iommu, arch::iommu,
if_tdx_enabled,
mm::{ mm::{
dma::{dma_type, Daddr, DmaType}, dma::{dma_type, Daddr, DmaType},
io::VmIoOnce, io::VmIoOnce,
@ -21,7 +22,6 @@ use crate::{
cfg_if! { cfg_if! {
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] {
use ::tdx_guest::tdx_is_enabled;
use crate::arch::tdx_guest; use crate::arch::tdx_guest;
} }
} }
@ -75,17 +75,17 @@ impl DmaCoherent {
} }
let start_daddr = match dma_type() { let start_daddr = match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped. // The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the 'unprotect_gpa_range' function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the 'unprotect_gpa_range' function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(start_paddr, frame_count).unwrap(); tdx_guest::unprotect_gpa_range(start_paddr, frame_count).unwrap();
} }
} });
start_paddr as Daddr start_paddr as Daddr
} }
DmaType::Iommu => { DmaType::Iommu => {
@ -135,17 +135,17 @@ impl Drop for DmaCoherentInner {
start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap(); start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap();
match dma_type() { match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `start_paddr()` ensures the `start_paddr` is page-aligned. // The `start_paddr()` ensures the `start_paddr` is page-aligned.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the `protect_gpa_range` function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the `protect_gpa_range` function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::protect_gpa_range(start_paddr, frame_count).unwrap(); tdx_guest::protect_gpa_range(start_paddr, frame_count).unwrap();
} }
} });
} }
DmaType::Iommu => { DmaType::Iommu => {
for i in 0..frame_count { for i in 0..frame_count {

View File

@ -9,6 +9,7 @@ use super::{check_and_insert_dma_mapping, remove_dma_mapping, DmaError, HasDaddr
use crate::{ use crate::{
arch::iommu, arch::iommu,
error::Error, error::Error,
if_tdx_enabled,
mm::{ mm::{
dma::{dma_type, Daddr, DmaType}, dma::{dma_type, Daddr, DmaType},
HasPaddr, Infallible, Paddr, USegment, UntypedMem, VmIo, VmReader, VmWriter, PAGE_SIZE, HasPaddr, Infallible, Paddr, USegment, UntypedMem, VmIo, VmReader, VmWriter, PAGE_SIZE,
@ -17,7 +18,6 @@ use crate::{
cfg_if! { cfg_if! {
if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] { if #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] {
use ::tdx_guest::tdx_is_enabled;
use crate::arch::tdx_guest; use crate::arch::tdx_guest;
} }
} }
@ -72,17 +72,17 @@ impl DmaStream {
start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap(); start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap();
let start_daddr = match dma_type() { let start_daddr = match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped. // The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the 'unprotect_gpa_range' function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the 'unprotect_gpa_range' function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::unprotect_gpa_range(start_paddr, frame_count).unwrap(); tdx_guest::unprotect_gpa_range(start_paddr, frame_count).unwrap();
} }
} });
start_paddr as Daddr start_paddr as Daddr
} }
DmaType::Iommu => { DmaType::Iommu => {
@ -182,17 +182,17 @@ impl Drop for DmaStreamInner {
start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap(); start_paddr.checked_add(frame_count * PAGE_SIZE).unwrap();
match dma_type() { match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] if_tdx_enabled!({
#[cfg(target_arch = "x86_64")]
// SAFETY: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `start_paddr()` ensures the `start_paddr` is page-aligned. // The `start_paddr()` ensures the `start_paddr` is page-aligned.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the `protect_gpa_range` function. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the `protect_gpa_range` function.
if tdx_is_enabled() {
unsafe { unsafe {
tdx_guest::protect_gpa_range(start_paddr, frame_count).unwrap(); tdx_guest::protect_gpa_range(start_paddr, frame_count).unwrap();
} }
} });
} }
DmaType::Iommu => { DmaType::Iommu => {
for i in 0..frame_count { for i in 0..frame_count {

View File

@ -356,38 +356,3 @@ pub(crate) unsafe fn init_early_allocator() {
let mut early_allocator = EARLY_ALLOCATOR.lock(); let mut early_allocator = EARLY_ALLOCATOR.lock();
*early_allocator = Some(EarlyFrameAllocator::new()); *early_allocator = Some(EarlyFrameAllocator::new());
} }
#[cfg(feature = "cvm_guest")]
pub(crate) fn reclaim_tdx_ap_boot_memory() {
let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
for region in regions.iter() {
if region.typ() == MemoryRegionType::Usable {
// Make the memory region page-aligned, and skip if it is too small.
let start = region.base().align_up(PAGE_SIZE) / PAGE_SIZE;
let region_end = region.base().checked_add(region.len()).unwrap();
let end = region_end.align_down(PAGE_SIZE) / PAGE_SIZE;
if end <= start {
continue;
}
// 0x800000 is temporarily used for AP boot in Intel TDX environment.
// We should include this frame into page allocator after AP initialization.
if (start..end).contains(&(0x800000 / PAGE_SIZE)) {
info!(
"Found usable region, start:{:x}, end:{:x}",
region.base(),
region.base() + region.len()
);
FRAME_ALLOCATOR
.get()
.unwrap()
.disable_irq()
.lock()
.allocator
.add_frame(start, end);
FRAME_ALLOCATOR.get().unwrap().disable_irq().lock().total +=
(end - start) * PAGE_SIZE;
}
}
}
}