Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3399,7 +3399,6 @@ dependencies = [
"thiserror 2.0.12",
"tracing",
"tracing-subscriber",
"underhill_confidentiality",
"vbs_defs",
"x86defs",
"zerocopy 0.8.24",
Expand Down Expand Up @@ -4828,6 +4827,7 @@ dependencies = [
"sha2",
"sidecar_defs",
"tdcall",
"tdx_guest_device",
"underhill_confidentiality",
"x86defs",
"zerocopy 0.8.24",
Expand Down Expand Up @@ -6728,6 +6728,7 @@ version = "0.0.0"
dependencies = [
"hvdef",
"memory_range",
"tdx_guest_device",
"thiserror 2.0.12",
"tracing",
"x86defs",
Expand All @@ -6737,6 +6738,7 @@ dependencies = [
name = "tdx_guest_device"
version = "0.0.0"
dependencies = [
"bitfield-struct 0.10.1",
"nix 0.27.1",
"static_assertions",
"thiserror 2.0.12",
Expand Down
2 changes: 1 addition & 1 deletion openhcl/openhcl_attestation_protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ open_enum.workspace = true
guid.workspace = true
mesh.workspace = true
sev_guest_device.workspace = true
tdx_guest_device.workspace = true
tdx_guest_device = { workspace = true, features = ["std"] }

base64.workspace = true
base64-serde.workspace = true
Expand Down
1 change: 1 addition & 0 deletions openhcl/openhcl_boot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ zerocopy.workspace = true
[target.'cfg(target_arch = "x86_64")'.dependencies]
safe_intrinsics.workspace = true
tdcall.workspace = true
tdx_guest_device.workspace = true
x86defs.workspace = true

[build-dependencies]
Expand Down
7 changes: 7 additions & 0 deletions openhcl/openhcl_boot/src/arch/x86_64/tdx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use tdcall::Tdcall;
use tdcall::TdcallInput;
use tdcall::TdcallOutput;
use tdcall::tdcall_map_gpa;
use tdx_guest_device::protocol::TdReport;
use x86defs::tdx::TdCallResult;

/// Perform a tdcall instruction with the specified inputs.
fn tdcall(input: TdcallInput) -> TdcallOutput {
Expand Down Expand Up @@ -119,3 +121,8 @@ pub fn get_tdx_tsc_reftime() -> Option<u64> {
}
None
}

/// Gets the TdReport.
pub fn get_tdreport(report: &mut TdReport) -> Result<(), TdCallResult> {
tdcall::tdcall_mr_report(&mut TdcallInstruction, report)
}
45 changes: 43 additions & 2 deletions openhcl/openhcl_boot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fn build_kernel_command_line(
cmdline: &mut ArrayString<COMMAND_LINE_SIZE>,
partition_info: &PartitionInfo,
can_trust_host: bool,
is_confidential_debug: bool,
sidecar: Option<&SidecarConfig<'_>>,
) -> Result<(), CommandLineTooLong> {
// For reference:
Expand Down Expand Up @@ -254,6 +255,14 @@ fn build_kernel_command_line(
)?;
}

if is_confidential_debug {
write!(
cmdline,
"{}=1 ",
underhill_confidentiality::OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME
)?;
}

// Only when explicitly supported by Host.
// TODO: Move from command line to device tree when stabilized.
if partition_info.nvme_keepalive && !partition_info.vtl2_pool_memory.is_empty() {
Expand Down Expand Up @@ -581,6 +590,29 @@ fn get_ref_time(isolation: IsolationType) -> Option<u64> {
}
}

fn get_hw_debug_bit(isolation: IsolationType) -> bool {
match isolation {
#[cfg(target_arch = "x86_64")]
IsolationType::Tdx => {
use tdx_guest_device::protocol::TdReport;

use crate::arch::tdx::get_tdreport;

let mut report = off_stack!(PageAlign<TdReport>, zeroed());
match get_tdreport(&mut report.0) {
Ok(()) => report.0.td_info.td_info_base.attributes.debug(),
Err(_) => false,
}
}
#[cfg(target_arch = "x86_64")]
IsolationType::Snp => {
// Not implemented yet for SNP.
false
}
_ => false,
}
}

fn shim_main(shim_params_raw_offset: isize) -> ! {
let p = shim_parameters(shim_params_raw_offset);
if p.isolation_type == IsolationType::None {
Expand Down Expand Up @@ -615,8 +647,10 @@ fn shim_main(shim_params_raw_offset: isize) -> ! {
log!("openhcl_boot: early debugging enabled");
}

let can_trust_host =
p.isolation_type == IsolationType::None || static_options.confidential_debug;
let hw_debug_bit = get_hw_debug_bit(p.isolation_type);
let can_trust_host = p.isolation_type == IsolationType::None
|| static_options.confidential_debug
|| hw_debug_bit;

let boot_reftime = get_ref_time(p.isolation_type);

Expand All @@ -628,6 +662,12 @@ fn shim_main(shim_params_raw_offset: isize) -> ! {
Err(e) => panic!("unable to read device tree params {}", e),
};

// Confidential debug will show up in boot_options only if included in the
// static command line, or if can_trust_host is true (so the dynamic command
// line has been parsed).
let is_confidential_debug = (can_trust_host && p.isolation_type != IsolationType::None)
|| partition_info.boot_options.confidential_debug;

// Fill out the non-devicetree derived parts of PartitionInfo.
if !p.isolation_type.is_hardware_isolated()
&& hvcall().vtl() == Vtl::Vtl2
Expand Down Expand Up @@ -697,6 +737,7 @@ fn shim_main(shim_params_raw_offset: isize) -> ! {
&mut cmdline,
partition_info,
can_trust_host,
is_confidential_debug,
sidecar.as_ref(),
)
.unwrap();
Expand Down
5 changes: 5 additions & 0 deletions openhcl/underhill_core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ use tracing::Instrument;
use tracing::instrument;
use uevent::UeventListener;
use underhill_attestation::AttestationType;
use underhill_confidentiality::confidential_debug_enabled;
use underhill_threadpool::AffinitizedThreadpool;
use underhill_threadpool::ThreadpoolBuilder;
use virt::Partition;
Expand Down Expand Up @@ -1589,6 +1590,10 @@ async fn new_underhill_vm(
);
}

if confidential_debug_enabled() {
tracing::warn!(CVM_ALLOWED, "confidential debug enabled");
}

// Create the `AttestationVmConfig` from `dps`, which will be used in
// - stateful mode (the attestation is not suppressed)
// - stateless mode (isolated VM with attestation suppressed)
Expand Down
4 changes: 4 additions & 0 deletions support/tdx_guest_device/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ name = "tdx_guest_device"
edition.workspace = true
rust-version.workspace = true

[features]
std = []

[dependencies]
bitfield-struct.workspace = true
static_assertions.workspace = true
zerocopy.workspace = true
[target.'cfg(target_os = "linux")'.dependencies]
Expand Down
1 change: 1 addition & 0 deletions support/tdx_guest_device/src/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

//! The module implements the Linux TDX Guest APIs based on ioctl.

#![cfg(feature = "std")]
// UNSAFETY: unsafe needed to make ioctl calls.
#![expect(unsafe_code)]

Expand Down
2 changes: 2 additions & 0 deletions support/tdx_guest_device/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//! The crate includes the abstraction layer of Linux TDX Guest APIs and
//! definitions of data structures according to TDX specification.

#![cfg_attr(not(feature = "std"), no_std)]

pub mod protocol;

#[cfg(target_os = "linux")]
Expand Down
43 changes: 42 additions & 1 deletion support/tdx_guest_device/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

//! The module includes the definitions of data structures according to TDX specification.

use bitfield_struct::bitfield;
use zerocopy::FromBytes;
use zerocopy::Immutable;
use zerocopy::IntoBytes;
Expand Down Expand Up @@ -135,12 +136,52 @@ pub struct TdInfo {
/// Run-time extendable measurement register.
pub type Rtmr = [u8; 48];

/// See `ATTRIBUTES` in Table 3.9, "Intel TDX Module v1.5 ABI specification", March 2024.
#[bitfield(u64)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct TdAttributes {
#[bits(1)]
pub debug: bool,
#[bits(3)]
_reserved1: u8,
#[bits(1)]
pub hgs_plus_prof: bool,
#[bits(1)]
pub perf_prof: bool,
#[bits(1)]
pub pmt_prof: bool,
#[bits(9)]
_reserved2: u16,
#[bits(7)]
_reserved_p: u8,
#[bits(4)]
_reserved_n: u8,
#[bits(1)]
pub lass: bool,
#[bits(1)]
pub sept_ve_disable: bool,
#[bits(1)]
pub migratable: bool,
#[bits(1)]
pub pks: bool,
#[bits(1)]
pub kl: bool,
#[bits(24)]
_reserved3: u32,
#[bits(6)]
_reserved4: u32,
#[bits(1)]
pub tpa: bool,
#[bits(1)]
pub perfmon: bool,
}

/// See `TDINFO_BASE` in Table 3.34, "Intel TDX Module v1.5 ABI specification", March 2024.
#[repr(C)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct TdInfoBase {
/// TD's attributes
pub attributes: [u8; 8],
pub attributes: TdAttributes,
/// TD's XFAM
pub xfam: [u8; 8],
/// Measurement of the initial contents of the TDX in SHA384
Expand Down
2 changes: 1 addition & 1 deletion support/tee_call/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ rust-version.workspace = true

[target.'cfg(target_os = "linux")'.dependencies]
sev_guest_device.workspace = true
tdx_guest_device.workspace = true
tdx_guest_device = { workspace = true, features = ["std"] }

static_assertions.workspace = true
thiserror.workspace = true
Expand Down
1 change: 0 additions & 1 deletion vm/loader/igvmfilegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ loader_defs.workspace = true
hvdef.workspace = true

memory_range.workspace = true
underhill_confidentiality.workspace = true
vbs_defs.workspace = true
x86defs.workspace = true

Expand Down
15 changes: 2 additions & 13 deletions vm/loader/igvmfilegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ use std::io::Write;
use std::path::PathBuf;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::filter::LevelFilter;
use underhill_confidentiality::OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME;
use zerocopy::FromBytes;
use zerocopy::IntoBytes;

Expand Down Expand Up @@ -633,20 +632,10 @@ fn load_image<'a, R: IgvmfilegenRegister + GuestArch + 'static>(
}
};

let command_line = if loader.loader().confidential_debug() {
tracing::info!("enabling underhill confidential debug environment flag");
format!(
"{command_line} {}=1",
OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME
)
} else {
command_line.clone()
};

let command_line = if static_command_line {
CommandLineType::Static(&command_line)
CommandLineType::Static(command_line)
} else {
CommandLineType::HostAppendable(&command_line)
CommandLineType::HostAppendable(command_line)
};

R::load_openhcl(
Expand Down
4 changes: 2 additions & 2 deletions vm/loader/manifests/openhcl-x64-cvm-dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"image": {
"openhcl": {
"command_line": "",
"command_line": "OPENHCL_CONFIDENTIAL_DEBUG=1",
"memory_page_count": 163840,
"memory_page_base": 32768,
"uefi": true
Expand Down Expand Up @@ -49,7 +49,7 @@
},
"image": {
"openhcl": {
"command_line": "",
"command_line": "OPENHCL_CONFIDENTIAL_DEBUG=1",
"memory_page_count": 163840,
"memory_page_base": 32768,
"uefi": true
Expand Down
4 changes: 2 additions & 2 deletions vm/loader/manifests/openhcl-x64-cvm-release.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"image": {
"openhcl": {
"command_line": "",
"command_line": "OPENHCL_CONFIDENTIAL_DEBUG=1",
"memory_page_count": 163840,
"memory_page_base": 32768,
"uefi": true
Expand Down Expand Up @@ -49,7 +49,7 @@
},
"image": {
"openhcl": {
"command_line": "",
"command_line": "OPENHCL_CONFIDENTIAL_DEBUG=1",
"memory_page_count": 32768,
"memory_page_base": 32768,
"uefi": true
Expand Down
4 changes: 4 additions & 0 deletions vm/x86/tdcall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ tracing = ["dep:tracing"]
[dependencies]
hvdef.workspace = true
memory_range.workspace = true
tdx_guest_device.workspace = true
thiserror.workspace = true
x86defs.workspace = true

[target.'cfg(target_os = "linux")'.dependencies]
tdx_guest_device = { workspace = true, features = ["std"] }

tracing = { workspace = true, optional = true }

[lints]
Expand Down
Loading