diff --git a/kernel/aster-nix/src/device/mod.rs b/kernel/aster-nix/src/device/mod.rs index 5258a4fdf..f728d9e8f 100644 --- a/kernel/aster-nix/src/device/mod.rs +++ b/kernel/aster-nix/src/device/mod.rs @@ -12,6 +12,8 @@ mod zero; pub use pty::{new_pty_pair, PtyMaster, PtySlave}; pub use random::Random; #[cfg(feature = "intel_tdx")] +use tdx_guest::tdx_is_enabled; +#[cfg(feature = "intel_tdx")] pub use tdxguest::TdxGuest; pub use urandom::Urandom; @@ -35,7 +37,9 @@ pub fn init() -> Result<()> { #[cfg(feature = "intel_tdx")] let tdx_guest = Arc::new(tdxguest::TdxGuest); #[cfg(feature = "intel_tdx")] - add_node(tdx_guest, "tdx-guest")?; + if tdx_is_enabled() { + add_node(tdx_guest, "tdx_guest")?; + } let random = Arc::new(random::Random); add_node(random, "random")?; let urandom = Arc::new(urandom::Urandom); diff --git a/kernel/aster-nix/src/device/tdxguest/mod.rs b/kernel/aster-nix/src/device/tdxguest/mod.rs index df9a78db2..70721a21e 100644 --- a/kernel/aster-nix/src/device/tdxguest/mod.rs +++ b/kernel/aster-nix/src/device/tdxguest/mod.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 -use tdx_guest::tdcall::TdCallError; +use aster_frame::mm::{DmaCoherent, FrameAllocOptions, HasPaddr, VmIo}; +use tdx_guest::tdcall::{get_report, TdCallError}; use super::*; use crate::{ @@ -8,6 +9,7 @@ use crate::{ events::IoEvents, fs::{inode_handle::FileIo, utils::IoctlCmd}, process::signal::Poller, + util::{read_val_from_user, write_bytes_to_user}, }; const TDX_REPORTDATA_LEN: usize = 64; @@ -16,8 +18,8 @@ const TDX_REPORT_LEN: usize = 1024; #[derive(Debug, Clone, Copy, Pod)] #[repr(C)] pub struct TdxReportRequest { - reportdata: [u8; TDX_REPORTDATA_LEN], - tdreport: [u8; TDX_REPORT_LEN], + report_data: [u8; TDX_REPORTDATA_LEN], + tdx_report: [u8; TDX_REPORT_LEN], } pub struct TdxGuest; @@ -64,11 +66,9 @@ impl FileIo for TdxGuest { return_errno_with_message!(Errno::EPERM, "Write operation not supported") } - fn ioctl(&self, cmd: IoctlCmd, _arg: usize) -> Result { + fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { match cmd { - IoctlCmd::TDXGETREPORT => { - todo!() - } + IoctlCmd::TDXGETREPORT => handle_get_report(arg), _ => return_errno_with_message!(Errno::EPERM, "Unsupported ioctl"), } } @@ -78,3 +78,38 @@ impl FileIo for TdxGuest { events & mask } } + +fn handle_get_report(arg: usize) -> Result { + const SHARED_BIT: u8 = 51; + const SHARED_MASK: u64 = 1u64 << SHARED_BIT; + let user_request: TdxReportRequest = read_val_from_user(arg)?; + + let vm_segment = FrameAllocOptions::new(2) + .is_contiguous(true) + .alloc_contiguous() + .unwrap(); + let dma_coherent = DmaCoherent::map(vm_segment, false).unwrap(); + dma_coherent + .write_bytes(0, &user_request.report_data) + .unwrap(); + // 1024-byte alignment. + dma_coherent + .write_bytes(1024, &user_request.tdx_report) + .unwrap(); + + if let Err(err) = get_report( + ((dma_coherent.paddr() + 1024) as u64) | SHARED_MASK, + (dma_coherent.paddr() as u64) | SHARED_MASK, + ) { + println!("[kernel]: get TDX report error: {:?}", err); + return Err(err.into()); + } + + let tdx_report_vaddr = arg + TDX_REPORTDATA_LEN; + let mut generated_report = vec![0u8; TDX_REPORT_LEN]; + dma_coherent + .read_bytes(1024, &mut generated_report) + .unwrap(); + write_bytes_to_user(tdx_report_vaddr, &generated_report)?; + Ok(0) +}