#![cfg_attr(feature = "unstable", doc = "[`IGVM_FIXED_HEADER_V2`]")]
#![cfg_attr(not(feature = "unstable"), doc = "`IGVM_FIXED_HEADER_V2`")]
#![no_std]
#![warn(missing_docs)]
#![deny(unsafe_code)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(clippy::upper_case_acronyms)]
#![allow(non_camel_case_types)]
use self::packed_nums::*;
use bitfield_struct::bitfield;
use core::mem::size_of;
use open_enum::open_enum;
use static_assertions::const_assert_eq;
use zerocopy::FromBytes;
use zerocopy::Immutable;
use zerocopy::IntoBytes;
use zerocopy::KnownLayout;
pub mod dt;
#[allow(non_camel_case_types)]
mod packed_nums {
pub type u32_le = zerocopy::U32<zerocopy::LittleEndian>;
pub type u64_le = zerocopy::U64<zerocopy::LittleEndian>;
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct IGVM_FIXED_HEADER {
pub magic: u32,
pub format_version: u32,
pub variable_header_offset: u32,
pub variable_header_size: u32,
pub total_file_size: u32,
pub checksum: u32,
}
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct IGVM_FIXED_HEADER_V2 {
pub magic: u32,
pub format_version: u32,
pub variable_header_offset: u32,
pub variable_header_size: u32,
pub total_file_size: u32,
pub checksum: u32,
pub architecture: IgvmArchitecture,
pub page_size: u32,
}
pub const IGVM_MAGIC_VALUE: u32 = u32::from_le_bytes(*b"IGVM");
static_assertions::const_assert_eq!(IGVM_MAGIC_VALUE, 0x4D564749);
pub const IGVM_FORMAT_VERSION_1: u32 = 0x1;
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
pub const IGVM_FORMAT_VERSION_2: u32 = 0x2;
pub const PAGE_SIZE_4K: u64 = 4096;
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum IgvmArchitecture {
X64 = 0x0,
AARCH64 = 0x1,
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum IgvmVariableHeaderType {
INVALID = 0x0,
IGVM_VHT_SUPPORTED_PLATFORM = 0x1,
IGVM_VHT_GUEST_POLICY = 0x101,
IGVM_VHT_RELOCATABLE_REGION = 0x102,
IGVM_VHT_PAGE_TABLE_RELOCATION_REGION = 0x103,
IGVM_VHT_PARAMETER_AREA = 0x301,
IGVM_VHT_PAGE_DATA = 0x302,
IGVM_VHT_PARAMETER_INSERT = 0x303,
IGVM_VHT_VP_CONTEXT = 0x304,
IGVM_VHT_REQUIRED_MEMORY = 0x305,
RESERVED_DO_NOT_USE = 0x306,
IGVM_VHT_VP_COUNT_PARAMETER = 0x307,
IGVM_VHT_SRAT = 0x308,
IGVM_VHT_MADT = 0x309,
IGVM_VHT_MMIO_RANGES = 0x30A,
IGVM_VHT_SNP_ID_BLOCK = 0x30B,
IGVM_VHT_MEMORY_MAP = 0x30C,
IGVM_VHT_ERROR_RANGE = 0x30D,
IGVM_VHT_COMMAND_LINE = 0x30E,
IGVM_VHT_SLIT = 0x30F,
IGVM_VHT_PPTT = 0x310,
IGVM_VHT_VBS_MEASUREMENT = 0x311,
IGVM_VHT_DEVICE_TREE = 0x312,
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
IGVM_VHT_ENVIRONMENT_INFO_PARAMETER = 0x313,
}
pub const IGVM_VHT_RANGE_PLATFORM: core::ops::RangeInclusive<u32> = 0x1..=0x100;
pub const IGVM_VHT_RANGE_INIT: core::ops::RangeInclusive<u32> = 0x101..=0x200;
pub const IGVM_VHT_RANGE_DIRECTIVE: core::ops::RangeInclusive<u32> = 0x301..=0x400;
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct IGVM_VHS_VARIABLE_HEADER {
pub typ: IgvmVariableHeaderType,
pub length: u32,
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum IgvmPlatformType {
NATIVE = 0x00,
VSM_ISOLATION = 0x01,
SEV_SNP = 0x02,
TDX = 0x03,
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
SEV = 0x04,
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
SEV_ES = 0x05,
}
impl Default for IgvmPlatformType {
fn default() -> Self {
IgvmPlatformType::NATIVE
}
}
pub const IGVM_NATIVE_PLATFORM_VERSION: u16 = 0x1;
pub const IGVM_VSM_ISOLATION_PLATFORM_VERSION: u16 = 0x1;
pub const IGVM_SEV_SNP_PLATFORM_VERSION: u16 = 0x1;
pub const IGVM_TDX_PLATFORM_VERSION: u16 = 0x1;
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
pub const IGVM_SEV_PLATFORM_VERSION: u16 = 0x1;
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
pub const IGVM_SEV_ES_PLATFORM_VERSION: u16 = 0x1;
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_SUPPORTED_PLATFORM {
pub compatibility_mask: u32,
pub highest_vtl: u8,
pub platform_type: IgvmPlatformType,
pub platform_version: u16,
pub shared_gpa_boundary: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_GUEST_POLICY {
pub policy: u64,
pub compatibility_mask: u32,
pub reserved: u32,
}
#[bitfield(u64)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct SnpPolicy {
pub abi_minor: u8,
pub abi_major: u8,
#[bits(1)]
pub smt: u8,
#[bits(1)]
pub reserved_must_be_one: u8,
#[bits(1)]
pub migrate_ma: u8,
#[bits(1)]
pub debug: u8,
#[bits(1)]
pub single_socket: u8,
#[bits(43)]
pub reserved: u64,
}
#[bitfield(u64)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct TdxPolicy {
#[bits(1)]
pub debug_allowed: u8,
#[bits(1)]
pub sept_ve_disable: u8,
#[bits(1)]
pub migratable: u8,
#[bits(61)]
pub reserved: u64,
}
pub const IGVM_VHF_RELOCATABLE_REGION_IS_VTL2: u8 = 0x1;
pub const IGVM_VHF_RELOCATABLE_REGION_APPLY_PC: u8 = 0x2;
pub const IGVM_VHF_RELOCATABLE_REGION_APPLY_GDTR: u8 = 0x4;
pub const IGVM_VHF_RELOCATABLE_REGION_APPLY_RIP: u8 = IGVM_VHF_RELOCATABLE_REGION_APPLY_PC;
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_RELOCATABLE_REGION {
pub compatibility_mask: u32,
pub vp_index: u16,
pub vtl: u8,
pub flags: u8,
pub relocation_alignment: u64,
pub relocation_region_gpa: u64,
pub relocation_region_size: u64,
pub minimum_relocation_gpa: u64,
pub maximum_relocation_gpa: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_PAGE_TABLE_RELOCATION {
pub compatibility_mask: u32,
pub vp_index: u16,
pub vtl: u8,
pub reserved: u8,
pub gpa: u64,
pub size: u64,
pub used_size: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_PARAMETER_AREA {
pub number_of_bytes: u64,
pub parameter_area_index: u32,
pub file_offset: u32,
}
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
#[bitfield(u32)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IgvmEnvironmentInfo {
pub memory_is_shared: bool,
#[bits(31)]
pub reserved: u32,
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum IgvmPageDataType {
NORMAL = 0x0,
SECRETS = 0x1,
CPUID_DATA = 0x2,
CPUID_XF = 0x3,
}
impl Default for IgvmPageDataType {
fn default() -> Self {
IgvmPageDataType::NORMAL
}
}
#[bitfield(u32)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IgvmPageDataFlags {
pub is_2mb_page: bool,
pub unmeasured: bool,
pub shared: bool,
#[bits(29)]
pub reserved: u32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_PAGE_DATA {
pub gpa: u64,
pub compatibility_mask: u32,
pub file_offset: u32,
pub flags: IgvmPageDataFlags,
pub data_type: IgvmPageDataType,
pub reserved: u16,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_PARAMETER_INSERT {
pub gpa: u64,
pub compatibility_mask: u32,
pub parameter_area_index: u32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_PARAMETER {
pub parameter_area_index: u32,
pub byte_offset: u32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_VP_CONTEXT {
pub gpa: u64_le,
pub compatibility_mask: u32,
pub file_offset: u32,
pub vp_index: u16,
pub reserved: u16,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_ERROR_RANGE {
pub gpa: u64,
pub compatibility_mask: u32,
pub size_bytes: u32,
}
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IgvmNativeVpContextX64 {
pub rax: u64,
pub rcx: u64,
pub rdx: u64,
pub rbx: u64,
pub rsp: u64,
pub rbp: u64,
pub rsi: u64,
pub rdi: u64,
pub r8: u64,
pub r9: u64,
pub r10: u64,
pub r11: u64,
pub r12: u64,
pub r13: u64,
pub r14: u64,
pub r15: u64,
pub rip: u64,
pub rflags: u64,
pub idtr_base: u64,
pub idtr_limit: u16,
pub reserved: [u16; 2],
pub gdtr_limit: u16,
pub gdtr_base: u64,
pub code_selector: u16,
pub code_attributes: u16,
pub code_base: u32,
pub code_limit: u32,
pub data_selector: u16,
pub data_attributes: u16,
pub data_base: u32,
pub data_limit: u32,
pub gs_base: u64,
pub cr0: u64,
pub cr3: u64,
pub cr4: u64,
pub efer: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct VbsVpContextHeader {
pub register_count: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct VbsVpContextRegister {
pub vtl: u8,
pub register_name: u32_le,
pub mbz: [u8; 11],
pub register_value: [u8; 16],
}
const_assert_eq!(size_of::<VbsVpContextRegister>(), 0x20);
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_REQUIRED_MEMORY {
pub gpa: u64,
pub compatibility_mask: u32,
pub number_of_bytes: u32,
pub flags: RequiredMemoryFlags,
pub reserved: u32,
}
#[bitfield(u32)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct RequiredMemoryFlags {
pub vtl2_protectable: bool,
#[bits(31)]
pub reserved: u32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_MEMORY_RANGE {
pub starting_gpa_page_number: u64,
pub number_of_pages: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_MMIO_RANGES {
pub mmio_ranges: [IGVM_VHS_MEMORY_RANGE; 2],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_SNP_ID_BLOCK_SIGNATURE {
pub r_comp: [u8; 72],
pub s_comp: [u8; 72],
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_SNP_ID_BLOCK_PUBLIC_KEY {
pub curve: u32,
pub reserved: u32,
pub qx: [u8; 72],
pub qy: [u8; 72],
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct IGVM_VHS_SNP_ID_BLOCK {
pub compatibility_mask: u32,
pub author_key_enabled: u8,
pub reserved: [u8; 3],
pub ld: [u8; 48],
pub family_id: [u8; 16],
pub image_id: [u8; 16],
pub version: u32,
pub guest_svn: u32,
pub id_key_algorithm: u32,
pub author_key_algorithm: u32,
pub id_key_signature: IGVM_VHS_SNP_ID_BLOCK_SIGNATURE,
pub id_public_key: IGVM_VHS_SNP_ID_BLOCK_PUBLIC_KEY,
pub author_key_signature: IGVM_VHS_SNP_ID_BLOCK_SIGNATURE,
pub author_public_key: IGVM_VHS_SNP_ID_BLOCK_PUBLIC_KEY,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct IGVM_VHS_VBS_MEASUREMENT {
pub compatibility_mask: u32,
pub version: u32,
pub product_id: u32,
pub module_id: u32,
pub security_version: u32,
pub policy_flags: u32,
pub boot_digest_algo: u32,
pub signing_algo: u32,
pub boot_measurement_digest: [u8; 64],
pub signature: [u8; 256],
pub public_key: [u8; 512],
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum MemoryMapEntryType {
MEMORY = 0x0,
PLATFORM_RESERVED = 0x1,
PERSISTENT = 0x2,
VTL2_PROTECTABLE = 0x3,
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
SPECIFIC_PURPOSE = 0x4,
#[cfg(feature = "unstable")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
HIDDEN = 0x5,
}
impl Default for MemoryMapEntryType {
fn default() -> Self {
Self::MEMORY
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
pub struct IGVM_VHS_MEMORY_MAP_ENTRY {
pub starting_gpa_page_number: u64,
pub number_of_pages: u64,
pub entry_type: MemoryMapEntryType,
pub flags: u16,
pub reserved: u32,
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum VbsDigestAlgorithm {
INVALID = 0x0,
SHA256 = 0x1,
}
#[open_enum]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum VbsSigningAlgorithm {
INVALID = 0x0,
ECDSA_P384 = 0x1,
}