mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Handle TDX MMIO and DMA direct
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
461c872c43
commit
37c3a7a48c
@ -10,4 +10,3 @@ x86_64 = "0.14.10"
|
||||
bitflags = "1.3"
|
||||
raw-cpuid = "10"
|
||||
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
||||
|
||||
|
@ -11,6 +11,8 @@ mod asm;
|
||||
pub mod tdcall;
|
||||
pub mod tdvmcall;
|
||||
|
||||
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
|
||||
|
||||
use raw_cpuid::{native_cpuid::cpuid_count, CpuIdResult};
|
||||
use tdcall::{InitError, TdgVpInfo};
|
||||
|
||||
@ -19,8 +21,16 @@ pub use self::{
|
||||
tdvmcall::print,
|
||||
};
|
||||
|
||||
static TDX_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[inline(always)]
|
||||
pub fn tdx_is_enabled() -> bool {
|
||||
TDX_ENABLED.load(Relaxed)
|
||||
}
|
||||
|
||||
pub fn init_tdx() -> Result<TdgVpInfo, InitError> {
|
||||
check_tdx_guest()?;
|
||||
TDX_ENABLED.store(true, Relaxed);
|
||||
Ok(tdcall::get_tdinfo()?)
|
||||
}
|
||||
|
||||
@ -32,7 +42,7 @@ fn check_tdx_guest() -> Result<(), InitError> {
|
||||
}
|
||||
let cpuid_result: CpuIdResult = cpuid_count(TDX_CPUID_LEAF_ID as u32, 0);
|
||||
if &cpuid_result.ebx.to_ne_bytes() != b"Inte"
|
||||
|| &cpuid_result.ebx.to_ne_bytes() != b"lTDX"
|
||||
|| &cpuid_result.edx.to_ne_bytes() != b"lTDX"
|
||||
|| &cpuid_result.ecx.to_ne_bytes() != b" "
|
||||
{
|
||||
return Err(InitError::TdxVendorIdError);
|
||||
|
@ -327,6 +327,7 @@ pub enum TdxVirtualExceptionType {
|
||||
VmCall,
|
||||
Mwait,
|
||||
Monitor,
|
||||
EptViolation,
|
||||
Wbinvd,
|
||||
Rdpmc,
|
||||
Other,
|
||||
@ -344,6 +345,7 @@ impl From<u32> for TdxVirtualExceptionType {
|
||||
32 => Self::MsrWrite,
|
||||
36 => Self::Mwait,
|
||||
39 => Self::Monitor,
|
||||
48 => Self::EptViolation,
|
||||
54 => Self::Wbinvd,
|
||||
_ => Self::Other,
|
||||
}
|
||||
@ -435,10 +437,10 @@ pub fn verify_report(report_mac_gpa: &[u8]) -> Result<(), TdCallError> {
|
||||
/// Accept a pending private page and initialize it to all-0 using the TD ephemeral private key.
|
||||
/// # Safety
|
||||
/// The 'gpa' parameter must be a valid address.
|
||||
pub unsafe fn accept_page(sept_level: u64, gpa: &[u8]) -> Result<(), TdCallError> {
|
||||
pub unsafe fn accept_page(sept_level: u64, gpa: u64) -> Result<(), TdCallError> {
|
||||
let mut args = TdcallArgs {
|
||||
rax: TdcallNum::MemPageAccept as u64,
|
||||
rcx: sept_level | ((gpa.as_ptr() as u64) << 12),
|
||||
rcx: sept_level | gpa,
|
||||
..Default::default()
|
||||
};
|
||||
td_call(&mut args)
|
||||
|
@ -163,12 +163,12 @@ pub fn perform_cache_operation(cache_operation: u64) -> Result<(), TdVmcallError
|
||||
|
||||
/// # Safety
|
||||
/// Make sure the mmio address is valid.
|
||||
pub unsafe fn read_mmio(size: IoSize, mmio_gpa: &[u8]) -> Result<u64, TdVmcallError> {
|
||||
pub unsafe fn read_mmio(size: IoSize, mmio_gpa: u64) -> Result<u64, TdVmcallError> {
|
||||
let mut args = TdVmcallArgs {
|
||||
r11: TdVmcallNum::RequestMmio as u64,
|
||||
r12: size as u64,
|
||||
r13: 0,
|
||||
r14: mmio_gpa.as_ptr() as u64,
|
||||
r14: mmio_gpa,
|
||||
..Default::default()
|
||||
};
|
||||
td_vmcall(&mut args)?;
|
||||
@ -177,18 +177,32 @@ pub unsafe fn read_mmio(size: IoSize, mmio_gpa: &[u8]) -> Result<u64, TdVmcallEr
|
||||
|
||||
/// # Safety
|
||||
/// Make sure the mmio address is valid.
|
||||
pub unsafe fn write_mmio(size: IoSize, mmio_gpa: &[u8], data: u64) -> Result<(), TdVmcallError> {
|
||||
pub unsafe fn write_mmio(size: IoSize, mmio_gpa: u64, data: u64) -> Result<(), TdVmcallError> {
|
||||
let mut args = TdVmcallArgs {
|
||||
r11: TdVmcallNum::RequestMmio as u64,
|
||||
r12: size as u64,
|
||||
r13: 1,
|
||||
r14: mmio_gpa.as_ptr() as u64,
|
||||
r14: mmio_gpa,
|
||||
r15: data,
|
||||
..Default::default()
|
||||
};
|
||||
td_vmcall(&mut args)
|
||||
}
|
||||
|
||||
/// MapGPA TDG.VP.VMCALL is used to help request the host VMM to map a GPA range as private
|
||||
/// or shared-memory mappings. This API may also be used to convert page mappings from
|
||||
/// private to shared. The GPA range passed in this operation can indicate if the mapping is
|
||||
/// requested for a shared or private memory via the GPA.Shared bit in the start address.
|
||||
pub fn map_gpa(gpa: u64, size: u64) -> Result<(), (u64, TdVmcallError)> {
|
||||
let mut args = TdVmcallArgs {
|
||||
r11: TdVmcallNum::Mapgpa as u64,
|
||||
r12: gpa,
|
||||
r13: size,
|
||||
..Default::default()
|
||||
};
|
||||
td_vmcall(&mut args).map_err(|e| (args.r11, e))
|
||||
}
|
||||
|
||||
macro_rules! io_read {
|
||||
($port:expr, $ty:ty) => {{
|
||||
let mut args = TdVmcallArgs {
|
||||
|
Reference in New Issue
Block a user