1use crate::vmx;
7use bitfield_struct::bitfield;
8use open_enum::open_enum;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13
14pub const TDX_SHARED_GPA_BOUNDARY_BITS: u8 = 47;
15pub const TDX_SHARED_GPA_BOUNDARY_ADDRESS_BIT: u64 = 1 << TDX_SHARED_GPA_BOUNDARY_BITS;
16pub const RESET_VECTOR_PAGE: u64 = 0xfffff000;
17
18pub const TDX_REPORT_SIZE: usize = 0x400;
20
21pub const TDX_REPORT_DATA_SIZE: usize = 64;
23
24open_enum! {
25 pub enum TdCallLeaf: u64 {
28 VP_VMCALL = 0,
29 VP_INFO = 1,
30 MR_RTMR_EXTEND = 2,
31 VP_VEINFO_GET = 3,
32 MR_REPORT = 4,
33 VP_CPUIDVE_SET = 5,
34 MEM_PAGE_ACCEPT = 6,
35 VM_RD = 7,
36 VM_WR = 8,
37 VP_RD = 9,
38 VP_WR = 10,
39 MEM_PAGE_ATTR_RD = 23,
40 MEM_PAGE_ATTR_WR = 24,
41 VP_ENTER = 25,
42 VP_INVGLA = 27,
43 }
44}
45
46#[repr(u8)]
48#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49pub enum TdgMemPageLevel {
50 Size4k = 0,
51 Size2Mb = 1,
52 Size1Gb = 2,
53}
54
55impl TdgMemPageLevel {
56 const fn from_bits(value: u64) -> Self {
57 match value {
58 0 => Self::Size4k,
59 1 => Self::Size2Mb,
60 2 => Self::Size1Gb,
61 _ => panic!("invalid TdgMemPageLevel value"),
62 }
63 }
64
65 const fn into_bits(self) -> u64 {
66 self as u64
67 }
68}
69
70#[bitfield(u16)]
72#[derive(PartialEq, Eq)]
73pub struct GpaVmAttributes {
74 pub read: bool,
75 pub write: bool,
76 pub kernel_execute: bool,
77 pub user_execute: bool,
78 #[bits(3)]
79 reserved: u8,
80 suppress_ve: bool,
81 #[bits(7)]
82 reserved2: u8,
83 pub valid: bool,
84}
85
86impl GpaVmAttributes {
88 pub const FULL_ACCESS: Self = Self::new()
89 .with_read(true)
90 .with_write(true)
91 .with_kernel_execute(true)
92 .with_user_execute(true)
93 .with_valid(true);
94}
95
96#[bitfield(u16)]
98pub struct GpaVmAttributesMask {
99 pub read: bool,
100 pub write: bool,
101 pub kernel_execute: bool,
102 pub user_execute: bool,
103 #[bits(3)]
104 reserved: u8,
105 pub suppress_ve: bool,
106 #[bits(7)]
107 reserved2: u8,
108 pub inv_ept: bool,
110}
111
112impl GpaVmAttributesMask {
113 pub const ALL_CHANGED: Self = Self::new()
114 .with_read(true)
115 .with_write(true)
116 .with_kernel_execute(true)
117 .with_user_execute(true);
118}
119
120#[bitfield(u64)]
123#[derive(PartialEq, Eq)]
124pub struct TdgMemPageGpaAttr {
125 #[bits(16)]
127 pub l1: GpaVmAttributes,
128 #[bits(16)]
130 pub l2_vm1: GpaVmAttributes,
131 #[bits(16)]
133 pub l2_vm2: GpaVmAttributes,
134 #[bits(16)]
135 pub l2_vm3: GpaVmAttributes,
136}
137
138#[bitfield(u64)]
139pub struct TdgMemPageAcceptRcx {
140 #[bits(3)]
141 pub level: TdgMemPageLevel,
142 #[bits(9)]
143 pub reserved: u64,
144 #[bits(40)]
146 pub gpa_page_number: u64,
147 #[bits(12)]
148 pub reserved2: u64,
149}
150
151#[bitfield(u64)]
152pub struct TdgMemPageAttrGpaMappingReadRcxResult {
153 #[bits(3)]
154 pub level: TdgMemPageLevel,
155 #[bits(9)]
156 pub reserved: u64,
157 #[bits(40)]
159 pub gpa_page_number: u64,
160 #[bits(10)]
161 pub reserved2: u64,
162 #[bits(1)]
165 pub pending: u8,
166 #[bits(1)]
167 pub reserved3: u64,
168}
169
170#[bitfield(u64)]
172#[derive(PartialEq, Eq)]
173pub struct TdgMemPageAttrWriteRcx {
174 #[bits(3)]
175 pub level: TdgMemPageLevel,
176 #[bits(9)]
177 pub reserved: u64,
178 #[bits(40)]
180 pub gpa_page_number: u64,
181 #[bits(12)]
182 pub reserved2: u64,
183}
184
185#[bitfield(u64)]
187pub struct TdgMemPageAttrWriteR8 {
188 #[bits(16)]
189 pub reserved: u64,
190 #[bits(16)]
192 pub l2_vm1: GpaVmAttributesMask,
193 #[bits(16)]
195 pub l2_vm2: GpaVmAttributesMask,
196 #[bits(16)]
198 pub l2_vm3: GpaVmAttributesMask,
199}
200
201#[repr(u64)]
204pub enum TdVmCallSubFunction {
205 IoInstr = 0x1e,
206 RdMsr = 0x1f,
207 WrMsr = 0x20,
208 MapGpa = 0x10001,
209}
210
211open_enum! {
212 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
214 pub enum TdCallResultCode: u32 {
215 SUCCESS = 0x00000000,
216 NON_RECOVERABLE_VCPU = 0x40000001,
217 NON_RECOVERABLE_TD = 0x60000002,
218 INTERRUPTED_RESUMABLE = 0x80000003,
219 INTERRUPTED_RESTARTABLE = 0x80000004,
220 NON_RECOVERABLE_TD_NON_ACCESSIBLE = 0x60000005,
221 INVALID_RESUMPTION = 0xC0000006,
222 NON_RECOVERABLE_TD_WRONG_APIC_MODE = 0xE0000007,
223 CROSS_TD_FAULT = 0x80000008,
224 CROSS_TD_TRAP = 0x90000009,
225 NON_RECOVERABLE_TD_CORRUPTED_MD = 0x6000000A,
226 OPERAND_INVALID = 0xC0000100,
227 OPERAND_ADDR_RANGE_ERROR = 0xC0000101,
228 OPERAND_BUSY = 0x80000200,
229 PREVIOUS_TLB_EPOCH_BUSY = 0x80000201,
230 SYS_BUSY = 0x80000202,
231 RND_NO_ENTROPY = 0x80000203,
232 OPERAND_BUSY_HOST_PRIORITY = 0x80000204,
233 HOST_PRIORITY_BUSY_TIMEOUT = 0x90000205,
234 PAGE_METADATA_INCORRECT = 0xC0000300,
235 PAGE_ALREADY_FREE = 0x00000301,
236 PAGE_NOT_OWNED_BY_TD = 0xC0000302,
237 PAGE_NOT_FREE = 0xC0000303,
238 TD_ASSOCIATED_PAGES_EXIST = 0xC0000400,
239 SYS_INIT_NOT_PENDING = 0xC0000500,
240 SYS_LP_INIT_NOT_DONE = 0xC0000502,
241 SYS_LP_INIT_DONE = 0xC0000503,
242 SYS_NOT_READY = 0xC0000505,
243 SYS_SHUTDOWN = 0xC0000506,
244 SYS_KEY_CONFIG_NOT_PENDING = 0xC0000507,
245 SYS_STATE_INCORRECT = 0xC0000508,
246 SYS_INVALID_HANDOFF = 0xC0000509,
247 SYS_INCOMPATIBLE_SIGSTRUCT = 0xC000050A,
248 SYS_LP_INIT_NOT_PENDING = 0xC000050B,
249 SYS_CONFIG_NOT_PENDING = 0xC000050C,
250 INCOMPATIBLE_SEAM_CAPABILITIES = 0xC000050D,
251 TD_FATAL = 0xE0000604,
252 TD_NON_DEBUG = 0xC0000605,
253 TDCS_NOT_ALLOCATED = 0xC0000606,
254 LIFECYCLE_STATE_INCORRECT = 0xC0000607,
255 OP_STATE_INCORRECT = 0xC0000608,
256 NO_VCPUS = 0xC0000609,
257 TDCX_NUM_INCORRECT = 0xC0000610,
258 VCPU_STATE_INCORRECT = 0xC0000700,
259 VCPU_ASSOCIATED = 0x80000701,
260 VCPU_NOT_ASSOCIATED = 0x80000702,
261 NO_VALID_VE_INFO = 0xC0000704,
262 MAX_VCPUS_EXCEEDED = 0xC0000705,
263 TSC_ROLLBACK = 0xC0000706,
264 TD_VMCS_FIELD_NOT_INITIALIZED = 0xC0000730,
265 MCS_FIELD_ERROR = 0xC0000731,
266 KEY_GENERATION_FAILED = 0x80000800,
267 TD_KEYS_NOT_CONFIGURED = 0x80000810,
268 KEY_STATE_INCORRECT = 0xC0000811,
269 KEY_CONFIGURED = 0x00000815,
270 WBCACHE_NOT_COMPLETE = 0x80000817,
271 HKID_NOT_FREE = 0xC0000820,
272 NO_HKID_READY_TO_WBCACHE = 0x00000821,
273 WBCACHE_RESUME_ERROR = 0xC0000823,
274 FLUSHVP_NOT_DONE = 0x80000824,
275 NUM_ACTIVATED_HKIDS_NOT_SUPPORTED = 0xC0000825,
276 INCORRECT_CPUID_VALUE = 0xC0000900,
277 LIMIT_CPUID_MAXVAL_SET = 0xC0000901,
278 INCONSISTENT_CPUID_FIELD = 0xC0000902,
279 CPUID_MAX_SUBLEAVES_UNRECOGNIZED = 0xC0000903,
280 CPUID_LEAF_1F_FORMAT_UNRECOGNIZED = 0xC0000904,
281 INVALID_WBINVD_SCOPE = 0xC0000905,
282 INVALID_PKG_ID = 0xC0000906,
283 ENABLE_MONITOR_FSM_NOT_SET = 0xC0000907,
284 CPUID_LEAF_NOT_SUPPORTED = 0xC0000908,
285 SMRR_NOT_LOCKED = 0xC0000910,
286 INVALID_SMRR_CONFIGURATION = 0xC0000911,
287 SMRR_OVERLAPS_CMR = 0xC0000912,
288 SMRR_LOCK_NOT_SUPPORTED = 0xC0000913,
289 SMRR_NOT_SUPPORTED = 0xC0000914,
290 INCONSISTENT_MSR = 0xC0000920,
291 INCORRECT_MSR_VALUE = 0xC0000921,
292 SEAMREPORT_NOT_AVAILABLE = 0xC0000930,
293 SEAMDB_GETREF_NOT_AVAILABLE = 0xC0000931,
294 SEAMDB_REPORT_NOT_AVAILABLE = 0xC0000932,
295 SEAMVERIFYREPORT_NOT_AVAILABLE = 0xC0000933,
296 INVALID_TDMR = 0xC0000A00,
297 NON_ORDERED_TDMR = 0xC0000A01,
298 TDMR_OUTSIDE_CMRS = 0xC0000A02,
299 TDMR_ALREADY_INITIALIZED = 0x00000A03,
300 INVALID_PAMT = 0xC0000A10,
301 PAMT_OUTSIDE_CMRS = 0xC0000A11,
302 PAMT_OVERLAP = 0xC0000A12,
303 INVALID_RESERVED_IN_TDMR = 0xC0000A20,
304 NON_ORDERED_RESERVED_IN_TDMR = 0xC0000A21,
305 CMR_LIST_INVALID = 0xC0000A22,
306 EPT_WALK_FAILED = 0xC0000B00,
307 EPT_ENTRY_FREE = 0xC0000B01,
308 EPT_ENTRY_NOT_FREE = 0xC0000B02,
309 EPT_ENTRY_NOT_PRESENT = 0xC0000B03,
310 EPT_ENTRY_NOT_LEAF = 0xC0000B04,
311 EPT_ENTRY_LEAF = 0xC0000B05,
312 GPA_RANGE_NOT_BLOCKED = 0xC0000B06,
313 GPA_RANGE_ALREADY_BLOCKED = 0x00000B07,
314 TLB_TRACKING_NOT_DONE = 0xC0000B08,
315 EPT_INVALID_PROMOTE_CONDITIONS = 0xC0000B09,
316 PAGE_ALREADY_ACCEPTED = 0x00000B0A,
317 PAGE_SIZE_MISMATCH = 0xC0000B0B,
318 GPA_RANGE_BLOCKED = 0xC0000B0C,
319 EPT_ENTRY_STATE_INCORRECT = 0xC0000B0D,
320 EPT_PAGE_NOT_FREE = 0xC0000B0E,
321 L2_SEPT_WALK_FAILED = 0xC0000B0F,
322 L2_SEPT_ENTRY_NOT_FREE = 0xC0000B10,
323 PAGE_ATTR_INVALID = 0xC0000B11,
324 L2_SEPT_PAGE_NOT_PROVIDED = 0xC0000B12,
325 METADATA_FIELD_ID_INCORRECT = 0xC0000C00,
326 METADATA_FIELD_NOT_WRITABLE = 0xC0000C01,
327 METADATA_FIELD_NOT_READABLE = 0xC0000C02,
328 METADATA_FIELD_VALUE_NOT_VALID = 0xC0000C03,
329 METADATA_LIST_OVERFLOW = 0xC0000C04,
330 INVALID_METADATA_LIST_HEADER = 0xC0000C05,
331 REQUIRED_METADATA_FIELD_MISSING = 0xC0000C06,
332 METADATA_ELEMENT_SIZE_INCORRECT = 0xC0000C07,
333 METADATA_LAST_ELEMENT_INCORRECT = 0xC0000C08,
334 METADATA_FIELD_CURRENTLY_NOT_WRITABLE = 0xC0000C09,
335 METADATA_WR_MASK_NOT_VALID = 0xC0000C0A,
336 METADATA_FIRST_FIELD_ID_IN_CONTEXT = 0x00000C0B,
337 METADATA_FIELD_SKIP = 0x00000C0C,
338 SERVTD_ALREADY_BOUND_FOR_TYPE = 0xC0000D00,
339 SERVTD_TYPE_MISMATCH = 0xC0000D01,
340 SERVTD_ATTR_MISMATCH = 0xC0000D02,
341 SERVTD_INFO_HASH_MISMATCH = 0xC0000D03,
342 SERVTD_UUID_MISMATCH = 0xC0000D04,
343 SERVTD_NOT_BOUND = 0xC0000D05,
344 SERVTD_BOUND = 0xC0000D06,
345 TARGET_UUID_MISMATCH = 0xC0000D07,
346 TARGET_UUID_UPDATED = 0xC0000D08,
347 INVALID_MBMD = 0xC0000E00,
348 INCORRECT_MBMD_MAC = 0xC0000E01,
349 NOT_WRITE_BLOCKED = 0xC0000E02,
350 ALREADY_WRITE_BLOCKED = 0x00000E03,
351 NOT_EXPORTED = 0xC0000E04,
352 MIGRATION_STREAM_STATE_INCORRECT = 0xC0000E05,
353 MAX_MIGS_NUM_EXCEEDED = 0xC0000E06,
354 EXPORTED_DIRTY_PAGES_REMAIN = 0xC0000E07,
355 MIGRATION_DECRYPTION_KEY_NOT_SET = 0xC0000E08,
356 TD_NOT_MIGRATABLE = 0xC0000E09,
357 PREVIOUS_EXPORT_CLEANUP_INCOMPLETE = 0xC0000E0A,
358 NUM_MIGS_HIGHER_THAN_CREATED = 0xC0000E0B,
359 IMPORT_MISMATCH = 0xC0000E0C,
360 MIGRATION_EPOCH_OVERFLOW = 0xC0000E0D,
361 MAX_EXPORTS_EXCEEDED = 0xC0000E0E,
362 INVALID_PAGE_MAC = 0xC0000E0F,
363 MIGRATED_IN_CURRENT_EPOCH = 0xC0000E10,
364 DISALLOWED_IMPORT_OVER_REMOVED = 0xC0000E11,
365 SOME_VCPUS_NOT_MIGRATED = 0xC0000E12,
366 ALL_VCPUS_IMPORTED = 0xC0000E13,
367 MIN_MIGS_NOT_CREATED = 0xC0000E14,
368 VCPU_ALREADY_EXPORTED = 0xC0000E15,
369 INVALID_MIGRATION_DECRYPTION_KEY = 0xC0000E16,
370 INVALID_CPUSVN = 0xC0001000,
371 INVALID_REPORTMACSTRUCT = 0xC0001001,
372 L2_EXIT_HOST_ROUTED_ASYNC = 0x00001100,
373 L2_EXIT_HOST_ROUTED_TDVMCALL = 0x00001101,
374 L2_EXIT_PENDING_INTERRUPT = 0x00001102,
375 PENDING_INTERRUPT = 0x00001120,
376 TD_EXIT_BEFORE_L2_ENTRY = 0x00001140,
377 TD_EXIT_ON_L2_VM_EXIT = 0x00001141,
378 TD_EXIT_ON_L2_TO_L1 = 0x00001142,
379 GLA_NOT_CANONICAL = 0xC0001160,
380 }
381}
382
383impl TdCallResultCode {
384 const fn from_bits(value: u64) -> Self {
385 Self(value as u32)
386 }
387
388 const fn into_bits(self) -> u64 {
389 self.0 as u64
390 }
391}
392
393#[bitfield(u64)]
395pub struct TdCallResult {
396 pub details: u32,
397 #[bits(32)]
398 pub code: TdCallResultCode,
399}
400
401open_enum! {
402 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
404 pub enum TdVmCallR10Result: u64 {
405 SUCCESS = 0,
406 RETRY = 1,
407 OPERAND_INVALID = 0x80000000_00000000,
408 GPA_INUSE = 0x80000000_00000001,
409 ALIGN_ERROR = 0x80000000_00000002,
410 }
411}
412
413#[repr(u64)]
415#[derive(Debug)]
416pub enum FieldSize {
417 Invalid = 0,
418 Size16Bit = 1,
419 Size32Bit = 2,
420 Size64Bit = 3,
421}
422
423impl FieldSize {
424 const fn from_bits(value: u64) -> Self {
425 match value {
426 0 => FieldSize::Invalid,
427 1 => FieldSize::Size16Bit,
428 2 => FieldSize::Size32Bit,
429 3 => FieldSize::Size64Bit,
430 _ => panic!("Invalid field size"),
431 }
432 }
433
434 const fn into_bits(self) -> u64 {
435 self as u64
436 }
437}
438
439open_enum! {
440 pub enum TdVpsClassCode: u8 {
441 TD_VMCS = 0,
442 VAPIC = 1,
443 VE_INFO = 2,
444 GUEST_GPR_STATE = 16,
445 GUEST_STATE = 17,
446 GUEST_EXT_STATE = 18,
447 GUEST_MSR_STATE = 19,
448 MANAGEMENT = 32,
449 CPUID_CONTROL = 33,
450 EPT_VIOLATION_LOG = 34,
451 VMCS_1 = 36,
452 MSR_BITMAPS_1 = 37,
453 MSR_BITMAPS_SHADOW_1 = 38,
454 VMCS_2 = 44,
455 MSR_BITMAPS_2 = 45,
456 MSR_BITMAPS_SHADOW_2 = 46,
457 VMCS_3 = 52,
458 }
459}
460
461open_enum! {
462 pub enum TdxContextCode: u8 {
463 PLATFORM = 0,
464 TD = 1,
465 TD_VCPU = 2,
466 }
467}
468
469impl TdxContextCode {
470 const fn from_bits(value: u64) -> Self {
471 Self(value as u8)
472 }
473 const fn into_bits(self) -> u64 {
474 self.0 as u64
475 }
476}
477
478pub const TDX_FIELD_CODE_L2_CTLS_VM1: TdxExtendedFieldCode =
479 TdxExtendedFieldCode(0xA020000300000051);
480pub const TDX_FIELD_CODE_L2_CTLS_VM2: TdxExtendedFieldCode =
481 TdxExtendedFieldCode(0xA020000300000051);
482
483#[bitfield(u64)]
485pub struct TdxExtendedFieldCode {
486 #[bits(24)]
487 pub field_code: u32,
488 #[bits(8)]
489 _reserved0: u64,
490 #[bits(2)]
491 pub field_size: FieldSize,
492 #[bits(4)]
493 pub last_element: u8,
494 #[bits(9)]
495 pub last_field: u16,
496 #[bits(3)]
497 _reserved1: u64,
498 pub increment_size: bool,
499 pub write_mask_valid: bool,
500 #[bits(3)]
501 pub context_code: TdxContextCode,
502 #[bits(1)]
503 _reserved2: u64,
504 #[bits(6)]
505 pub class_code: u8,
506 #[bits(1)]
507 _reserved3: u64,
508 pub non_arch: bool,
509}
510
511#[bitfield(u64)]
513pub struct TdxInstructionInfo {
514 pub info: u32,
515 pub length: u32,
516}
517
518#[bitfield(u64)]
519pub struct TdxL2Ctls {
520 pub enable_shared_ept: bool,
521 pub enable_tdvmcall: bool,
522 #[bits(62)]
523 pub reserved: u64,
524}
525
526#[bitfield(u64)]
527pub struct TdxVpEnterRaxResult {
528 #[bits(32)]
530 pub vmx_exit: vmx::VmxExit,
531 #[bits(32)]
533 pub tdx_exit: TdCallResultCode,
534}
535
536#[bitfield(u64)]
537pub struct TdxExtendedExitQualification {
538 #[bits(4)]
539 pub ty: TdxExtendedExitQualificationType,
540 #[bits(60)]
541 _reserved: u64,
542}
543
544open_enum! {
545 pub enum TdxExtendedExitQualificationType: u8 {
546 NONE = 0,
547 PENDING_EPT_VIOLATION = 6,
548 }
549}
550
551impl TdxExtendedExitQualificationType {
552 const fn from_bits(value: u64) -> Self {
553 Self(value as u8)
554 }
555
556 const fn into_bits(self) -> u64 {
557 self.0 as u64
558 }
559}
560
561#[repr(C)]
564#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
565pub struct TdxL2EnterGuestState {
566 pub gps: [u64; 16],
568 pub rflags: u64,
569 pub rip: u64,
570 pub ssp: u64,
571 pub rvi: u8, pub svi: u8, pub reserved: [u8; 6],
574}
575
576pub enum TdxGp {}
577impl TdxGp {
578 pub const RAX: usize = 0;
579 pub const RCX: usize = 1;
580 pub const RDX: usize = 2;
581 pub const RBX: usize = 3;
582 pub const RSP: usize = 4;
583 pub const RBP: usize = 5;
584 pub const RSI: usize = 6;
585 pub const RDI: usize = 7;
586 pub const R8: usize = 8;
587 pub const R9: usize = 9;
588 pub const R10: usize = 10;
589 pub const R11: usize = 11;
590 pub const R12: usize = 12;
591 pub const R13: usize = 13;
592 pub const R14: usize = 14;
593 pub const R15: usize = 15;
594}
595
596#[bitfield(u64)]
597pub struct TdxGlaListInfo {
598 #[bits(9)]
599 pub first_entry: u64,
600 #[bits(3)]
601 _reserved_z0: u64,
602 #[bits(40)]
603 pub list_gpa: u64,
604 #[bits(10)]
605 pub num_entries: u64,
606 #[bits(2)]
607 _reserved_z1: u64,
608}
609
610#[bitfield(u64)]
611pub struct TdGlaVmAndFlags {
612 pub list: bool,
613 #[bits(51)]
614 _reserved_z0: u64,
615 #[bits(2)]
616 pub vm_index: u64,
617 #[bits(10)]
618 _reserved_z1: u64,
619}
620
621#[bitfield(u64)]
622#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
623pub struct TdxVmFlags {
624 #[bits(2)]
625 pub invd_translations: u8,
626
627 #[bits(50)]
628 _reserved: u64,
629
630 #[bits(2)]
632 pub vm_index: u8,
633
634 #[bits(10)]
635 _reserved_2: u64,
636}
637
638pub const TDX_VP_ENTER_INVD_INVEPT: u8 = 1;
639pub const TDX_VP_ENTER_INVD_INVVPID: u8 = 2;
640pub const TDX_VP_ENTER_INVD_INVVPID_NON_GLOBAL: u8 = 3;
641
642#[repr(C)]
645#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
646pub struct TdReport {
647 pub report_mac_struct: ReportMac,
649 pub tee_tcb_info: TeeTcbInfo,
651 pub _reserved: [u8; 17],
653 pub td_info: TdInfo,
655}
656
657static_assertions::const_assert_eq!(TDX_REPORT_SIZE, size_of::<TdReport>());
658
659#[repr(C)]
661#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
662pub struct ReportMac {
663 pub report_type: ReportType,
665 pub _reserved0: [u8; 12],
667 pub cpu_svn: [u8; 16],
669 pub tee_tcb_info_hash: [u8; 48],
671 pub tee_info_hash: [u8; 48],
673 pub report_data: [u8; TDX_REPORT_DATA_SIZE],
675 pub _reserved1: [u8; 32],
677 pub mac: [u8; 32],
679}
680
681#[repr(C)]
683#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
684pub struct ReportType {
685 pub tee_type: u8,
689 pub sub_type: u8,
692 pub version: u8,
697 pub _reserved: u8,
699}
700
701#[repr(C)]
703#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
704pub struct TeeTcbInfo {
705 pub valid: [u8; 8],
708 pub tee_tcb_svn: TeeTcbSvn,
711 pub mr_seam: [u8; 48],
714 pub mr_signer_seam: [u8; 48],
716 pub attributes: [u8; 8],
718 pub tee_tcb_svn2: TeeTcbSvn,
720 pub reserved: [u8; 95],
722}
723
724#[repr(C)]
726#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
727pub struct TeeTcbSvn {
728 pub tdx_module_svn_minor: u8,
730 pub tdx_module_svn_major: u8,
732 pub seam_last_patch_svn: u8,
734 pub _reserved: [u8; 13],
736}
737
738#[repr(C)]
740#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
741pub struct TdInfo {
742 pub td_info_base: TdInfoBase,
744 pub td_info_extension: [u8; 64],
746}
747
748pub type Rtmr = [u8; 48];
750
751#[bitfield(u64)]
753#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
754pub struct TdAttributes {
755 #[bits(1)]
756 pub debug: bool,
757 #[bits(3)]
758 _reserved1: u8,
759 #[bits(1)]
760 pub hgs_plus_prof: bool,
761 #[bits(1)]
762 pub perf_prof: bool,
763 #[bits(1)]
764 pub pmt_prof: bool,
765 #[bits(9)]
766 _reserved2: u16,
767 #[bits(7)]
768 _reserved_p: u8,
769 #[bits(4)]
770 _reserved_n: u8,
771 #[bits(1)]
772 pub lass: bool,
773 #[bits(1)]
774 pub sept_ve_disable: bool,
775 #[bits(1)]
776 pub migratable: bool,
777 #[bits(1)]
778 pub pks: bool,
779 #[bits(1)]
780 pub kl: bool,
781 #[bits(24)]
782 _reserved3: u32,
783 #[bits(6)]
784 _reserved4: u32,
785 #[bits(1)]
786 pub tpa: bool,
787 #[bits(1)]
788 pub perfmon: bool,
789}
790
791#[repr(C)]
793#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
794pub struct TdInfoBase {
795 pub attributes: TdAttributes,
797 pub xfam: [u8; 8],
799 pub mr_td: [u8; 48],
801 pub mr_config_id: [u8; 48],
804 pub mr_owner: [u8; 48],
806 pub mr_owner_config: [u8; 48],
809 pub rtmr: [Rtmr; 4],
811 pub servd_hash: [u8; 48],
813}