From a4223742a63da5274b8cb2d5210df0215e2a0b57 Mon Sep 17 00:00:00 2001 From: Peter Fang Date: Fri, 18 Oct 2024 00:24:47 -0700 Subject: [PATCH] platform: tdp: Implement page validation interfaces On TDP platforms, page validation means page acceptance. Implement validate_{physical, virtual}_page_range() using the tdx-tdcall crate for this TDCALL operation. Page invalidation simply means zeroing out the page on TDP platforms. Signed-off-by: Peter Fang --- kernel/src/platform/mod.rs | 2 +- kernel/src/platform/tdp.rs | 43 ++++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/kernel/src/platform/mod.rs b/kernel/src/platform/mod.rs index e9171d451..1a6cd68c4 100644 --- a/kernel/src/platform/mod.rs +++ b/kernel/src/platform/mod.rs @@ -98,7 +98,7 @@ pub trait SvsmPlatform { /// Marks a virtual range of pages as valid or invalid for use as private /// pages. Provided primarily for use in stage2 where validation by - /// physical address cannot e supported. + /// physical address cannot be supported. fn validate_virtual_page_range( &self, region: MemoryRegion, diff --git a/kernel/src/platform/tdp.rs b/kernel/src/platform/tdp.rs index 2bfb1eca4..bb210c14b 100644 --- a/kernel/src/platform/tdp.rs +++ b/kernel/src/platform/tdp.rs @@ -10,13 +10,14 @@ use crate::cpu::cpuid::CpuidResult; use crate::cpu::percpu::PerCpu; use crate::error::SvsmError; use crate::io::IOPort; +use crate::mm::{virt_to_frame, PerCPUPageMappingGuard}; use crate::platform::{PageEncryptionMasks, PageStateChangeOp, PageValidateOp, SvsmPlatform}; use crate::types::PageSize; use crate::utils::immut_after_init::ImmutAfterInitCell; -use crate::utils::MemoryRegion; +use crate::utils::{zero_mem_region, MemoryRegion}; use tdx_tdcall::tdx::{ - tdvmcall_io_read_16, tdvmcall_io_read_32, tdvmcall_io_read_8, tdvmcall_io_write_16, - tdvmcall_io_write_32, tdvmcall_io_write_8, + td_accept_memory, tdvmcall_io_read_16, tdvmcall_io_read_32, tdvmcall_io_read_8, + tdvmcall_io_write_16, tdvmcall_io_write_32, tdvmcall_io_write_8, }; static GHCI_IO_DRIVER: GHCIIOPort = GHCIIOPort::new(); @@ -93,18 +94,42 @@ impl SvsmPlatform for TdpPlatform { fn validate_physical_page_range( &self, - _region: MemoryRegion, - _op: PageValidateOp, + region: MemoryRegion, + op: PageValidateOp, ) -> Result<(), SvsmError> { - Err(SvsmError::Tdx) + match op { + PageValidateOp::Validate => { + td_accept_memory(region.start().into(), region.len().try_into().unwrap()); + } + PageValidateOp::Invalidate => { + let mapping = PerCPUPageMappingGuard::create(region.start(), region.end(), 0)?; + zero_mem_region(mapping.virt_addr(), mapping.virt_addr() + region.len()); + } + } + Ok(()) } fn validate_virtual_page_range( &self, - _region: MemoryRegion, - _op: PageValidateOp, + region: MemoryRegion, + op: PageValidateOp, ) -> Result<(), SvsmError> { - Err(SvsmError::Tdx) + match op { + PageValidateOp::Validate => { + let mut va = region.start(); + while va < region.end() { + let pa = virt_to_frame(va); + let sz = pa.end() - pa.address(); + // td_accept_memory() will take care of alignment + td_accept_memory(pa.address().into(), sz.try_into().unwrap()); + va = va + sz; + } + } + PageValidateOp::Invalidate => { + zero_mem_region(region.start(), region.end()); + } + } + Ok(()) } fn configure_alternate_injection(&mut self, _alt_inj_requested: bool) -> Result<(), SvsmError> {