x86defs/
snp.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! AMD SEV-SNP specific definitions.
5
6use bitfield_struct::bitfield;
7use zerocopy::FromBytes;
8use zerocopy::Immutable;
9use zerocopy::IntoBytes;
10use zerocopy::KnownLayout;
11
12// Interruption Information Field
13pub const SEV_INTR_TYPE_EXT: u32 = 0;
14pub const SEV_INTR_TYPE_NMI: u32 = 2;
15pub const SEV_INTR_TYPE_EXCEPT: u32 = 3;
16pub const SEV_INTR_TYPE_SW: u32 = 4;
17
18// Secrets page layout.
19pub const REG_TWEAK_BITMAP_OFFSET: usize = 0x100;
20pub const REG_TWEAK_BITMAP_SIZE: usize = 0x40;
21
22#[bitfield(u64)]
23#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
24pub struct SevEventInjectInfo {
25    pub vector: u8,
26    #[bits(3)]
27    pub interruption_type: u32,
28    pub deliver_error_code: bool,
29    #[bits(19)]
30    _rsvd1: u64,
31    pub valid: bool,
32    pub error_code: u32,
33}
34
35#[repr(u8)]
36#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
37pub enum Vmpl {
38    Vmpl0 = 0,
39    Vmpl1 = 1,
40    Vmpl2 = 2,
41    Vmpl3 = 3,
42}
43
44impl From<Vmpl> for u8 {
45    fn from(value: Vmpl) -> Self {
46        value as _
47    }
48}
49
50/// A X64 selector register.
51#[repr(C)]
52#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
53pub struct SevSelector {
54    pub selector: u16,
55    pub attrib: u16,
56    pub limit: u32,
57    pub base: u64,
58}
59
60impl SevSelector {
61    pub fn as_u128(&self) -> u128 {
62        ((self.base as u128) << 64)
63            | ((self.limit as u128) << 32)
64            | ((self.attrib as u128) << 16)
65            | self.selector as u128
66    }
67}
68
69impl From<u128> for SevSelector {
70    fn from(val: u128) -> Self {
71        SevSelector {
72            selector: val as u16,
73            attrib: (val >> 16) as u16,
74            limit: (val >> 32) as u32,
75            base: (val >> 64) as u64,
76        }
77    }
78}
79
80/// An X64 XMM register.
81#[repr(C)]
82#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
83pub struct SevXmmRegister {
84    low: u64,
85    high: u64,
86}
87
88impl SevXmmRegister {
89    pub fn as_u128(&self) -> u128 {
90        ((self.high as u128) << 64) | self.low as u128
91    }
92}
93
94impl From<u128> for SevXmmRegister {
95    fn from(val: u128) -> Self {
96        SevXmmRegister {
97            low: val as u64,
98            high: (val >> 64) as u64,
99        }
100    }
101}
102
103#[bitfield(u64)]
104#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
105pub struct SevFeatures {
106    pub snp: bool,
107    pub vtom: bool,
108    pub reflect_vc: bool,
109    pub restrict_injection: bool,
110    pub alternate_injection: bool,
111    pub debug_swap: bool,
112    pub prevent_host_ibs: bool,
113    pub snp_btb_isolation: bool,
114    pub vmpl_isss: bool,
115    pub secure_tsc: bool,
116    pub vmgexit_param: bool,
117    pub pmc_virt: bool,
118    pub ibs_virt: bool,
119    rsvd: bool,
120    pub vmsa_reg_prot: bool,
121    pub smt_prot: bool,
122    pub secure_avic: bool,
123    #[bits(47)]
124    _unused: u64,
125}
126
127#[bitfield(u64)]
128#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
129pub struct SevVirtualInterruptControl {
130    pub tpr: u8,
131    pub irq: bool,
132    pub gif: bool,
133    pub intr_shadow: bool,
134    #[bits(5)]
135    _rsvd1: u64,
136    #[bits(4)]
137    pub priority: u64,
138    pub ignore_tpr: bool,
139    #[bits(11)]
140    _rsvd2: u64,
141    pub vector: u8,
142    #[bits(23)]
143    _rsvd3: u64,
144    pub guest_busy: bool,
145}
146
147#[bitfield(u64)]
148#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
149pub struct SevRmpAdjust {
150    pub target_vmpl: u8,
151    pub enable_read: bool,
152    pub enable_write: bool,
153    pub enable_user_execute: bool,
154    pub enable_kernel_execute: bool,
155    #[bits(4)]
156    _rsvd1: u64,
157    pub vmsa: bool,
158    #[bits(47)]
159    _rsvd2: u64,
160}
161
162#[bitfield(u32)]
163#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
164pub struct SevIoAccessInfo {
165    pub read_access: bool,
166    #[bits(1)]
167    reserved1: u32,
168    pub string_access: bool,
169    pub rep_access: bool,
170    pub access_size8: bool,
171    pub access_size16: bool,
172    pub access_size32: bool,
173    pub address_size8: bool,
174    pub address_size16: bool,
175    pub address_size32: bool,
176    #[bits(3)]
177    pub effective_segment: u32,
178    #[bits(3)]
179    rsvd2: u32,
180    pub port: u16,
181}
182
183#[bitfield(u64)]
184#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
185pub struct SevNpfInfo {
186    pub present: bool,
187    pub read_write: bool,
188    pub user: bool,
189    pub reserved_bit_set: bool,
190    pub fetch: bool,
191    #[bits(1)]
192    rsvd5: u64,
193    pub shadow_stack: bool,
194    #[bits(24)]
195    rsvd7_31: u64,
196    pub rmp_failure: bool,
197    pub caused_by_gpa_access: bool,
198    pub caused_by_page_table_access: bool,
199    pub encrypted_access: bool,
200    pub rmp_size_mismatch: bool,
201    pub vmpl_violation: bool,
202    pub npt_supervisor_shadow_stack: bool,
203    #[bits(26)]
204    rsvd38_63: u64,
205}
206
207/// SEV VMSA structure representing CPU state
208#[repr(C)]
209#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
210pub struct SevVmsa {
211    // Selector Info
212    pub es: SevSelector,
213    pub cs: SevSelector,
214    pub ss: SevSelector,
215    pub ds: SevSelector,
216    pub fs: SevSelector,
217    pub gs: SevSelector,
218
219    // Descriptor Table Info
220    pub gdtr: SevSelector,
221    pub ldtr: SevSelector,
222    pub idtr: SevSelector,
223    pub tr: SevSelector,
224
225    // CET
226    pub pl0_ssp: u64,
227    pub pl1_ssp: u64,
228    pub pl2_ssp: u64,
229    pub pl3_ssp: u64,
230    pub u_cet: u64,
231
232    // Reserved, MBZ
233    pub vmsa_reserved1: [u8; 2],
234
235    // Virtual Machine Privilege Level
236    pub vmpl: u8,
237
238    // CPL
239    pub cpl: u8,
240
241    // Reserved, MBZ
242    pub vmsa_reserved2: u32,
243
244    // EFER
245    pub efer: u64,
246
247    // Reserved, MBZ
248    pub vmsa_reserved3: [u32; 26],
249
250    // XSS (offset 0x140)
251    pub xss: u64,
252
253    // Control registers
254    pub cr4: u64,
255    pub cr3: u64,
256    pub cr0: u64,
257
258    // Debug registers
259    pub dr7: u64,
260    pub dr6: u64,
261
262    // RFLAGS
263    pub rflags: u64,
264
265    // RIP
266    pub rip: u64,
267
268    // Additional saved debug registers
269    pub dr0: u64,
270    pub dr1: u64,
271    pub dr2: u64,
272    pub dr3: u64,
273
274    // Debug register address masks
275    pub dr0_addr_mask: u64,
276    pub dr1_addr_mask: u64,
277    pub dr2_addr_mask: u64,
278    pub dr3_addr_mask: u64,
279
280    // Reserved, MBZ
281    pub vmsa_reserved4: [u64; 3],
282
283    // RSP
284    pub rsp: u64,
285
286    // CET
287    pub s_cet: u64,
288    pub ssp: u64,
289    pub interrupt_ssp_table_addr: u64,
290
291    // RAX
292    pub rax: u64,
293
294    // SYSCALL config registers
295    pub star: u64,
296    pub lstar: u64,
297    pub cstar: u64,
298    pub sfmask: u64,
299
300    // KernelGsBase
301    pub kernel_gs_base: u64,
302
303    // SYSENTER config registers
304    pub sysenter_cs: u64,
305    pub sysenter_esp: u64,
306    pub sysenter_eip: u64,
307
308    // CR2
309    pub cr2: u64,
310
311    // Reserved, MBZ
312    pub vmsa_reserved5: [u64; 4],
313
314    // PAT
315    pub pat: u64,
316
317    // LBR MSRs
318    pub dbgctl: u64,
319    pub last_branch_from_ip: u64,
320    pub last_branch_to_ip: u64,
321    pub last_excp_from_ip: u64,
322    pub last_excp_to_ip: u64,
323
324    // Reserved, MBZ
325    pub vmsa_reserved6: [u64; 9],
326
327    // Speculation control MSR
328    pub spec_ctrl: u64,
329
330    // PKRU
331    pub pkru: u32,
332
333    // TSC_AUX
334    pub tsc_aux: u32,
335
336    // Reserved, MBZ
337    pub vmsa_reserved7: [u32; 4],
338
339    pub register_protection_nonce: u64,
340
341    // GPRs
342    pub rcx: u64,
343    pub rdx: u64,
344    pub rbx: u64,
345    pub vmsa_reserved8: u64, // MBZ
346    pub rbp: u64,
347    pub rsi: u64,
348    pub rdi: u64,
349    pub r8: u64,
350    pub r9: u64,
351    pub r10: u64,
352    pub r11: u64,
353    pub r12: u64,
354    pub r13: u64,
355    pub r14: u64,
356    pub r15: u64,
357
358    // Reserved, MBZ
359    pub vmsa_reserved9: [u64; 2],
360
361    // Exit information following an automatic #VMEXIT
362    pub exit_info1: u64,
363    pub exit_info2: u64,
364    pub exit_int_info: u64,
365
366    // Software scratch register
367    pub next_rip: u64,
368
369    // SEV feature information
370    pub sev_features: SevFeatures,
371
372    // Virtual interrupt control
373    pub v_intr_cntrl: SevVirtualInterruptControl,
374
375    // Guest exiting error code
376    pub guest_error_code: u64,
377
378    // Virtual top of memory
379    pub virtual_tom: u64,
380
381    // TLB control.  Writing a zero to PCPU_ID will force a full TLB
382    // invalidation upon the next entry.
383    pub tlb_id: u64,
384    pub pcpu_id: u64,
385
386    // Event injection
387    pub event_inject: SevEventInjectInfo,
388
389    // XCR0
390    pub xcr0: u64,
391
392    // X87 state save valid bitmap
393    pub xsave_valid_bitmap: [u8; 16],
394
395    // X87 save state
396    pub x87dp: u64,
397    pub mxcsr: u32,
398    pub x87_ftw: u16,
399    pub x87_fsw: u16,
400    pub x87_fcw: u16,
401    pub x87_op: u16,
402    pub x87_ds: u16,
403    pub x87_cs: u16,
404    pub x87_rip: u64,
405
406    // NOTE: Should be 80 bytes. Making it 10 u64 because no code uses it on a
407    // byte-level yet.
408    pub x87_registers: [u64; 10],
409
410    // XMM registers
411    pub xmm_registers: [SevXmmRegister; 16],
412
413    // YMM high registers
414    pub ymm_registers: [SevXmmRegister; 16],
415}
416
417// Info codes for the GHCB MSR protocol.
418open_enum::open_enum! {
419    pub enum GhcbInfo: u64 {
420        NORMAL = 0x000,
421        SEV_INFO_RESPONSE = 0x001,
422        SEV_INFO_REQUEST = 0x002,
423        AP_JUMP_TABLE = 0x003,
424        CPUID_REQUEST = 0x004,
425        CPUID_RESPONSE = 0x005,
426        PREFERRED_REQUEST = 0x010,
427        PREFERRED_RESPONSE = 0x011,
428        REGISTER_REQUEST = 0x012,
429        REGISTER_RESPONSE = 0x013,
430        PAGE_STATE_CHANGE = 0x014,
431        PAGE_STATE_UPDATED = 0x015,
432        HYP_FEATURE_REQUEST = 0x080,
433        HYP_FEATURE_RESPONSE = 0x081,
434        SPECIAL_HYPERCALL = 0xF00,
435        SPECIAL_FAST_CALL = 0xF01,
436        HYPERCALL_OUTPUT = 0xF02,
437        SPECIAL_DBGPRINT = 0xF03,
438        SHUTDOWN_REQUEST = 0x100,
439    }
440}
441
442pub const GHCB_DATA_PAGE_STATE_PRIVATE: u64 = 0x001;
443pub const GHCB_DATA_PAGE_STATE_SHARED: u64 = 0x002;
444pub const GHCB_DATA_PAGE_STATE_PSMASH: u64 = 0x003;
445pub const GHCB_DATA_PAGE_STATE_UNSMASH: u64 = 0x004;
446pub const GHCB_DATA_PAGE_STATE_MASK: u64 = 0x00F;
447pub const GHCB_DATA_PAGE_STATE_LARGE_PAGE: u64 = 0x010;
448
449open_enum::open_enum! {
450    pub enum GhcbUsage: u32 {
451        BASE = 0,
452        HYPERCALL = 1,
453        VTL_RETURN = 2,
454    }
455}
456
457/// Struct representing GHCB hypercall parameters. These are located at the GHCB
458/// page starting at [`GHCB_PAGE_HYPERCALL_PARAMETERS_OFFSET`].
459#[repr(C)]
460#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
461pub struct GhcbHypercallParameters {
462    pub output_gpa: u64,
463    pub input_control: u64,
464}
465
466pub const GHCB_PAGE_HYPERCALL_PARAMETERS_OFFSET: usize = 4072;
467pub const GHCB_PAGE_HYPERCALL_OUTPUT_OFFSET: usize = 4080;
468
469// Exit Codes.
470open_enum::open_enum! {
471    pub enum SevExitCode: u64 {
472        CR0_READ = 0x0,
473        CR1_READ = 0x1,
474        CR2_READ = 0x2,
475        CR3_READ = 0x3,
476        CR4_READ = 0x4,
477        CR5_READ = 0x5,
478        CR6_READ = 0x6,
479        CR7_READ = 0x7,
480        CR8_READ = 0x8,
481        CR9_READ = 0x9,
482        CR10_READ = 0xa,
483        CR11_READ = 0xb,
484        CR12_READ = 0xc,
485        CR13_READ = 0xd,
486        CR14_READ = 0xe,
487        CR15_READ = 0xf,
488        CR0_WRITE = 0x10,
489        CR1_WRITE = 0x11,
490        CR2_WRITE = 0x12,
491        CR3_WRITE = 0x13,
492        CR4_WRITE = 0x14,
493        CR5_WRITE = 0x15,
494        CR6_WRITE = 0x16,
495        CR7_WRITE = 0x17,
496        CR8_WRITE = 0x18,
497        CR9_WRITE = 0x19,
498        CR10_WRITE = 0x1a,
499        CR11_WRITE = 0x1b,
500        CR12_WRITE = 0x1c,
501        CR13_WRITE = 0x1d,
502        CR14_WRITE = 0x1e,
503        CR15_WRITE = 0x1f,
504        DR0_READ = 0x20,
505        DR1_READ = 0x21,
506        DR2_READ = 0x22,
507        DR3_READ = 0x23,
508        DR4_READ = 0x24,
509        DR5_READ = 0x25,
510        DR6_READ = 0x26,
511        DR7_READ = 0x27,
512        DR8_READ = 0x28,
513        DR9_READ = 0x29,
514        DR10_READ = 0x2a,
515        DR11_READ = 0x2b,
516        DR12_READ = 0x2c,
517        DR13_READ = 0x2d,
518        DR14_READ = 0x2e,
519        DR15_READ = 0x2f,
520        DR0_WRITE = 0x30,
521        DR1_WRITE = 0x31,
522        DR2_WRITE = 0x32,
523        DR3_WRITE = 0x33,
524        DR4_WRITE = 0x34,
525        DR5_WRITE = 0x35,
526        DR6_WRITE = 0x36,
527        DR7_WRITE = 0x37,
528        DR8_WRITE = 0x38,
529        DR9_WRITE = 0x39,
530        DR10_WRITE = 0x3a,
531        DR11_WRITE = 0x3b,
532        DR12_WRITE = 0x3c,
533        DR13_WRITE = 0x3d,
534        DR14_WRITE = 0x3e,
535        DR15_WRITE = 0x3f,
536        EXCP0 = 0x40,
537        EXCP_DB = 0x41,
538        EXCP2 = 0x42,
539        EXCP3 = 0x43,
540        EXCP4 = 0x44,
541        EXCP5 = 0x45,
542        EXCP6 = 0x46,
543        EXCP7 = 0x47,
544        EXCP8 = 0x48,
545        EXCP9 = 0x49,
546        EXCP10 = 0x4a,
547        EXCP11 = 0x4b,
548        EXCP12 = 0x4c,
549        EXCP13 = 0x4d,
550        EXCP14 = 0x4e,
551        EXCP15 = 0x4f,
552        EXCP16 = 0x50,
553        EXCP17 = 0x51,
554        EXCP18 = 0x52,
555        EXCP19 = 0x53,
556        EXCP20 = 0x54,
557        EXCP21 = 0x55,
558        EXCP22 = 0x56,
559        EXCP23 = 0x57,
560        EXCP24 = 0x58,
561        EXCP25 = 0x59,
562        EXCP26 = 0x5a,
563        EXCP27 = 0x5b,
564        EXCP28 = 0x5c,
565        EXCP29 = 0x5d,
566        EXCP30 = 0x5e,
567        EXCP31 = 0x5f,
568        INTR = 0x60,
569        NMI = 0x61,
570        SMI = 0x62,
571        INIT = 0x63,
572        VINTR = 0x64,
573        CR0_SEL_WRITE = 0x65,
574        IDTR_READ = 0x66,
575        GDTR_READ = 0x67,
576        LDTR_READ = 0x68,
577        TR_READ = 0x69,
578        IDTR_WRITE = 0x6a,
579        GDTR_WRITE = 0x6b,
580        LDTR_WRITE = 0x6c,
581        TR_WRITE = 0x6d,
582        RDTSC = 0x6e,
583        RDPMC = 0x6f,
584        PUSHF = 0x70,
585        POPF = 0x71,
586        CPUID = 0x72,
587        RSM = 0x73,
588        IRET = 0x74,
589        SWINT = 0x75,
590        INVD = 0x76,
591        PAUSE = 0x77,
592        HLT = 0x78,
593        INVLPG = 0x79,
594        INVLPGA = 0x7a,
595        IOIO = 0x7b,
596        MSR = 0x7c,
597        TASK_SWITCH = 0x7d,
598        FERR_FREEZE = 0x7e,
599        SHUTDOWN = 0x7f,
600        VMRUN = 0x80,
601        VMMCALL = 0x81,
602        VMLOAD = 0x82,
603        VMSAVE = 0x83,
604        STGI = 0x84,
605        CLGI = 0x85,
606        SKINIT = 0x86,
607        RDTSCP = 0x87,
608        ICEBP = 0x88,
609        WBINVD = 0x89,
610        MONITOR = 0x8a,
611        MWAIT = 0x8b,
612        MWAIT_CONDITIONAL = 0x8c,
613        XSETBV = 0x8d,
614        RDPRU = 0x8e,
615        EFER_WRITE_TRAP = 0x8f,
616        CR0_WRITE_TRAP = 0x90,
617        CR1_WRITE_TRAP = 0x91,
618        CR2_WRITE_TRAP = 0x92,
619        CR3_WRITE_TRAP = 0x93,
620        CR4_WRITE_TRAP = 0x94,
621        CR5_WRITE_TRAP = 0x95,
622        CR6_WRITE_TRAP = 0x96,
623        CR7_WRITE_TRAP = 0x97,
624        CR8_WRITE_TRAP = 0x98,
625        CR9_WRITE_TRAP = 0x99,
626        CR10_WRITE_TRAP = 0x9a,
627        CR11_WRITE_TRAP = 0x9b,
628        CR12_WRITE_TRAP = 0x9c,
629        CR13_WRITE_TRAP = 0x9d,
630        CR14_WRITE_TRAP = 0x9e,
631        CR15_WRITE_TRAP = 0x9f,
632        INVLPGB = 0xa0,
633        ILLEGAL_INVLPGB = 0xa1,
634        INVPCID = 0xa2,
635        BUSLOCK = 0xa5,
636        IDLE_HLT = 0xa6,
637        NPF = 0x400,
638        AVIC_INCOMPLETE_IPI = 0x401,
639        AVIC_NOACCEL = 0x402,
640        VMGEXIT = 0x403,
641        PAGE_NOT_VALIDATED = 0x404,
642
643        // SEV-ES software-defined exit codes
644        SNP_GUEST_REQUEST = 0x80000011,
645        SNP_EXTENDED_GUEST_REQUEST = 0x80000012,
646        HV_DOORBELL_PAGE = 0x80000014,
647
648        // SEV-SNP hardware error codes
649        INVALID_VMCB = 0xffff_ffff_ffff_ffff,
650        VMSA_BUSY = 0xffff_ffff_ffff_fffe,
651        IDLE_REQUIRED = 0xffff_ffff_ffff_fffd,
652        INVALID_PMC = 0xffff_ffff_ffff_fffc,
653    }
654}
655
656#[bitfield(u64)]
657#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
658pub struct GhcbMsr {
659    #[bits(12)]
660    pub info: u64,
661    #[bits(40)]
662    pub pfn: u64,
663    #[bits(12)]
664    pub extra_data: u64,
665}
666
667/// PSP data structures.
668#[repr(C)]
669#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)]
670pub struct HvPspCpuidLeaf {
671    pub eax_in: u32,
672    pub ecx_in: u32,
673    pub xfem_in: u64,
674    pub xss_in: u64,
675    pub eax_out: u32,
676    pub ebx_out: u32,
677    pub ecx_out: u32,
678    pub edx_out: u32,
679    pub reserved_z: u64,
680}
681
682pub const HV_PSP_CPUID_LEAF_COUNT_MAX: usize = 64;
683
684#[repr(C)]
685#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)]
686pub struct HvPspCpuidPage {
687    pub count: u32,
688    pub reserved_z1: u32,
689    pub reserved_z2: u64,
690    pub cpuid_leaf_info: [HvPspCpuidLeaf; HV_PSP_CPUID_LEAF_COUNT_MAX],
691    pub reserved_z3: [u64; 126],
692}
693
694/// Structure describing the pages being read during SNP ID block measurement.
695/// Each structure is hashed with the previous structures digest to create a final
696/// measurement
697#[repr(C)]
698#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)]
699pub struct SnpPageInfo {
700    /// Set to the value of the previous page's launch digest
701    pub digest_current: [u8; 48],
702    /// Hash of page contents, if measured
703    pub contents: [u8; 48],
704    /// Size of the SnpPageInfo struct
705    pub length: u16,
706    /// type of page being measured, described by [`SnpPageType`]
707    pub page_type: SnpPageType,
708    /// imi_page_bit must match IMI_PAGE flag
709    pub imi_page_bit: u8,
710    /// All lower VMPL permissions are denied for SNP
711    pub lower_vmpl_permissions: u32,
712    /// The guest physical address at which this page data should be loaded; it
713    /// must be aligned to a page size boundary.
714    pub gpa: u64,
715}
716
717open_enum::open_enum! {
718    /// The type of page described by [`SnpPageInfo`]
719    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
720    pub enum SnpPageType: u8 {
721        /// Reserved
722        RESERVED = 0x0,
723        /// Normal data page
724        NORMAL = 0x1,
725        /// VMSA page
726        VMSA = 0x2,
727        /// Zero page
728        ZERO = 0x3,
729        /// Page encrypted, but not measured
730        UNMEASURED = 0x4,
731        /// Page storing guest secrets
732        SECRETS = 0x5,
733        /// Page to provide CPUID function values
734        CPUID = 0x6,
735    }
736}
737
738/// Structure containing the completed SNP measurement of the IGVM file.
739/// The signature of the hash of this struct is the id_key_signature for
740/// `igvm_defs::IGVM_VHS_SNP_ID_BLOCK`.
741#[repr(C)]
742#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)]
743pub struct SnpPspIdBlock {
744    /// completed launch digest of IGVM file
745    pub ld: [u8; 48],
746    /// family id of the guest
747    pub family_id: [u8; 16],
748    /// image id of the guest
749    pub image_id: [u8; 16],
750    /// Version of the ID block format, must be 0x1
751    pub version: u32,
752    /// Software version of the guest
753    pub guest_svn: u32,
754    /// SNP Policy of the guest
755    pub policy: u64,
756}
757
758#[bitfield(u64)]
759#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
760pub struct SevStatusMsr {
761    pub sev_enabled: bool,
762    pub es_enabled: bool,
763    pub snp_enabled: bool,
764    pub vtom: bool,
765    pub reflect_vc: bool,
766    pub restrict_injection: bool,
767    pub alternate_injection: bool,
768    pub debug_swap: bool,
769    pub prevent_host_ibs: bool,
770    pub snp_btb_isolation: bool,
771    pub _rsvd1: bool,
772    pub secure_tsc: bool,
773    pub _rsvd2: bool,
774    pub _rsvd3: bool,
775    pub _rsvd4: bool,
776    pub _rsvd5: bool,
777    pub vmsa_reg_prot: bool,
778    #[bits(47)]
779    _unused: u64,
780}
781
782#[bitfield(u64)]
783#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
784pub struct SevInvlpgbRax {
785    pub va_valid: bool,
786    pub pcid_valid: bool,
787    pub asid_valid: bool,
788    pub global: bool,
789    pub final_only: bool,
790    pub nested: bool,
791    #[bits(6)]
792    reserved: u64,
793    #[bits(52)]
794    pub virtual_page_number: u64,
795}
796
797#[bitfield(u32)]
798#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
799pub struct SevInvlpgbEdx {
800    #[bits(16)]
801    pub asid: u64,
802    #[bits(12)]
803    pub pcid: u64,
804    #[bits(4)]
805    reserved: u32,
806}
807
808#[bitfield(u32)]
809#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
810pub struct SevInvlpgbEcx {
811    #[bits(16)]
812    pub additional_count: u64,
813    #[bits(15)]
814    reserved: u64,
815    pub large_page: bool,
816}
817
818#[bitfield(u64)]
819pub struct MovCrxDrxInfo {
820    #[bits(4)]
821    pub gpr_number: u64,
822    #[bits(59)]
823    pub reserved: u64,
824    pub mov_crx: bool,
825}