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 = 0,
473        CR1_READ = 1,
474        CR2_READ = 2,
475        CR3_READ = 3,
476        CR4_READ = 4,
477        CR5_READ = 5,
478        CR6_READ = 6,
479        CR7_READ = 7,
480        CR8_READ = 8,
481        CR9_READ = 9,
482        CR10_READ = 10,
483        CR11_READ = 11,
484        CR12_READ = 12,
485        CR13_READ = 13,
486        CR14_READ = 14,
487        CR15_READ = 15,
488        CR0_WRITE = 16,
489        CR1_WRITE = 17,
490        CR2_WRITE = 18,
491        CR3_WRITE = 19,
492        CR4_WRITE = 20,
493        CR5_WRITE = 21,
494        CR6_WRITE = 22,
495        CR7_WRITE = 23,
496        CR8_WRITE = 24,
497        CR9_WRITE = 25,
498        CR10_WRITE = 26,
499        CR11_WRITE = 27,
500        CR12_WRITE = 28,
501        CR13_WRITE = 29,
502        CR14_WRITE = 30,
503        CR15_WRITE = 31,
504        DR0_READ = 32,
505        DR1_READ = 33,
506        DR2_READ = 34,
507        DR3_READ = 35,
508        DR4_READ = 36,
509        DR5_READ = 37,
510        DR6_READ = 38,
511        DR7_READ = 39,
512        DR8_READ = 40,
513        DR9_READ = 41,
514        DR10_READ = 42,
515        DR11_READ = 43,
516        DR12_READ = 44,
517        DR13_READ = 45,
518        DR14_READ = 46,
519        DR15_READ = 47,
520        DR0_WRITE = 48,
521        DR1_WRITE = 49,
522        DR2_WRITE = 50,
523        DR3_WRITE = 51,
524        DR4_WRITE = 52,
525        DR5_WRITE = 53,
526        DR6_WRITE = 54,
527        DR7_WRITE = 55,
528        DR8_WRITE = 56,
529        DR9_WRITE = 57,
530        DR10_WRITE = 58,
531        DR11_WRITE = 59,
532        DR12_WRITE = 60,
533        DR13_WRITE = 61,
534        DR14_WRITE = 62,
535        DR15_WRITE = 63,
536        EXCP0 = 64,
537        EXCP_DB = 65,
538        EXCP2 = 66,
539        EXCP3 = 67,
540        EXCP4 = 68,
541        EXCP5 = 69,
542        EXCP6 = 70,
543        EXCP7 = 71,
544        EXCP8 = 72,
545        EXCP9 = 73,
546        EXCP10 = 74,
547        EXCP11 = 75,
548        EXCP12 = 76,
549        EXCP13 = 77,
550        EXCP14 = 78,
551        EXCP15 = 79,
552        EXCP16 = 80,
553        EXCP17 = 81,
554        EXCP18 = 82,
555        EXCP19 = 83,
556        EXCP20 = 84,
557        EXCP21 = 85,
558        EXCP22 = 86,
559        EXCP23 = 87,
560        EXCP24 = 88,
561        EXCP25 = 89,
562        EXCP26 = 90,
563        EXCP27 = 91,
564        EXCP28 = 92,
565        EXCP29 = 93,
566        EXCP30 = 94,
567        EXCP31 = 95,
568        INTR = 96,
569        NMI = 97,
570        SMI = 98,
571        INIT = 99,
572        VINTR = 100,
573        CR0_SEL_WRITE = 101,
574        IDTR_READ = 102,
575        GDTR_READ = 103,
576        LDTR_READ = 104,
577        TR_READ = 105,
578        IDTR_WRITE = 106,
579        GDTR_WRITE = 107,
580        LDTR_WRITE = 108,
581        TR_WRITE = 109,
582        RDTSC = 110,
583        RDPMC = 111,
584        PUSHF = 112,
585        POPF = 113,
586        CPUID = 114,
587        RSM = 115,
588        IRET = 116,
589        SWINT = 117,
590        INVD = 118,
591        PAUSE = 119,
592        HLT = 120,
593        INVLPG = 121,
594        INVLPGA = 122,
595        IOIO = 123,
596        MSR = 124,
597        TASK_SWITCH = 125,
598        FERR_FREEZE = 126,
599        SHUTDOWN = 127,
600        VMRUN = 128,
601        VMMCALL = 129,
602        VMLOAD = 130,
603        VMSAVE = 131,
604        STGI = 132,
605        CLGI = 133,
606        SKINIT = 134,
607        RDTSCP = 135,
608        ICEBP = 136,
609        WBINVD = 137,
610        MONITOR = 138,
611        MWAIT = 139,
612        MWAIT_CONDITIONAL = 140,
613        XSETBV = 141,
614        INVLPGB = 160,
615        ILLEGAL_INVLPGB = 161,
616        NPF = 1024,
617        AVIC_INCOMPLETE_IPI = 1025,
618        AVIC_NOACCEL = 1026,
619        VMGEXIT = 1027,
620        PAGE_NOT_VALIDATED = 1028,
621        SNP_GUEST_REQUEST = 0x80000011,
622        SNP_EXTENDED_GUEST_REQUEST = 0x80000012,
623        HV_DOORBELL_PAGE = 0x80000014,
624        INVALID_VMCB = 0xffff_ffff_ffff_ffff,
625    }
626}
627
628#[bitfield(u64)]
629#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
630pub struct GhcbMsr {
631    #[bits(12)]
632    pub info: u64,
633    #[bits(40)]
634    pub pfn: u64,
635    #[bits(12)]
636    pub extra_data: u64,
637}
638
639/// PSP data structures.
640#[repr(C)]
641#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)]
642pub struct HvPspCpuidLeaf {
643    pub eax_in: u32,
644    pub ecx_in: u32,
645    pub xfem_in: u64,
646    pub xss_in: u64,
647    pub eax_out: u32,
648    pub ebx_out: u32,
649    pub ecx_out: u32,
650    pub edx_out: u32,
651    pub reserved_z: u64,
652}
653
654pub const HV_PSP_CPUID_LEAF_COUNT_MAX: usize = 64;
655
656#[repr(C)]
657#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)]
658pub struct HvPspCpuidPage {
659    pub count: u32,
660    pub reserved_z1: u32,
661    pub reserved_z2: u64,
662    pub cpuid_leaf_info: [HvPspCpuidLeaf; HV_PSP_CPUID_LEAF_COUNT_MAX],
663    pub reserved_z3: [u64; 126],
664}
665
666/// Structure describing the pages being read during SNP ID block measurement.
667/// Each structure is hashed with the previous structures digest to create a final
668/// measurement
669#[repr(C)]
670#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)]
671pub struct SnpPageInfo {
672    /// Set to the value of the previous page's launch digest
673    pub digest_current: [u8; 48],
674    /// Hash of page contents, if measured
675    pub contents: [u8; 48],
676    /// Size of the SnpPageInfo struct
677    pub length: u16,
678    /// type of page being measured, described by [`SnpPageType`]
679    pub page_type: SnpPageType,
680    /// imi_page_bit must match IMI_PAGE flag
681    pub imi_page_bit: u8,
682    /// All lower VMPL permissions are denied for SNP
683    pub lower_vmpl_permissions: u32,
684    /// The guest physical address at which this page data should be loaded; it
685    /// must be aligned to a page size boundary.
686    pub gpa: u64,
687}
688
689open_enum::open_enum! {
690    /// The type of page described by [`SnpPageInfo`]
691    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
692    pub enum SnpPageType: u8 {
693        /// Reserved
694        RESERVED = 0x0,
695        /// Normal data page
696        NORMAL = 0x1,
697        /// VMSA page
698        VMSA = 0x2,
699        /// Zero page
700        ZERO = 0x3,
701        /// Page encrypted, but not measured
702        UNMEASURED = 0x4,
703        /// Page storing guest secrets
704        SECRETS = 0x5,
705        /// Page to provide CPUID function values
706        CPUID = 0x6,
707    }
708}
709
710/// Structure containing the completed SNP measurement of the IGVM file.
711/// The signature of the hash of this struct is the id_key_signature for
712/// `igvm_defs::IGVM_VHS_SNP_ID_BLOCK`.
713#[repr(C)]
714#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)]
715pub struct SnpPspIdBlock {
716    /// completed launch digest of IGVM file
717    pub ld: [u8; 48],
718    /// family id of the guest
719    pub family_id: [u8; 16],
720    /// image id of the guest
721    pub image_id: [u8; 16],
722    /// Version of the ID block format, must be 0x1
723    pub version: u32,
724    /// Software version of the guest
725    pub guest_svn: u32,
726    /// SNP Policy of the guest
727    pub policy: u64,
728}
729
730#[bitfield(u64)]
731#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
732pub struct SevStatusMsr {
733    pub sev_enabled: bool,
734    pub es_enabled: bool,
735    pub snp_enabled: bool,
736    pub vtom: bool,
737    pub reflect_vc: bool,
738    pub restrict_injection: bool,
739    pub alternate_injection: bool,
740    pub debug_swap: bool,
741    pub prevent_host_ibs: bool,
742    pub snp_btb_isolation: bool,
743    pub _rsvd1: bool,
744    pub secure_tsc: bool,
745    pub _rsvd2: bool,
746    pub _rsvd3: bool,
747    pub _rsvd4: bool,
748    pub _rsvd5: bool,
749    pub vmsa_reg_prot: bool,
750    #[bits(47)]
751    _unused: u64,
752}
753
754#[bitfield(u64)]
755#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
756pub struct SevInvlpgbRax {
757    pub va_valid: bool,
758    pub pcid_valid: bool,
759    pub asid_valid: bool,
760    pub global: bool,
761    pub final_only: bool,
762    pub nested: bool,
763    #[bits(6)]
764    reserved: u64,
765    #[bits(52)]
766    pub virtual_page_number: u64,
767}
768
769#[bitfield(u32)]
770#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
771pub struct SevInvlpgbEdx {
772    #[bits(16)]
773    pub asid: u64,
774    #[bits(12)]
775    pub pcid: u64,
776    #[bits(4)]
777    reserved: u32,
778}
779
780#[bitfield(u32)]
781#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
782pub struct SevInvlpgbEcx {
783    #[bits(16)]
784    pub additional_count: u64,
785    #[bits(15)]
786    reserved: u64,
787    pub large_page: bool,
788}
789
790#[bitfield(u64)]
791pub struct MovCrxDrxInfo {
792    #[bits(4)]
793    pub gpr_number: u64,
794    #[bits(59)]
795    pub reserved: u64,
796    pub mov_crx: bool,
797}