1use crate::AlignedU128;
10use crate::HvX64SegmentRegister;
11use crate::HvX64TableRegister;
12use core::mem::size_of;
13use open_enum::open_enum;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19open_enum! {
24 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
26 pub enum VmSaveChunkId: u32 {
27
28 PROLOG = 0x0000_0000,
30 EPILOG = 0xF000_0000,
31
32 PROCESSOR_CPUID_DATA = 0x2000_0000,
34 OS_ID = 0x2000_1000,
35 PARTITION_VTL = 0x2000_8000,
36 PARTITION_VSM_CONFIG = 0x2000_A000,
37
38 VP_INDICES = 0x3000_0000,
40 VP = 0x3000_1000,
41 VP_CORE = 0x3000_3000,
42 VP_GP_REGISTERS = 0x3000_5000,
43 VP_FP_REGISTERS = 0x3000_6000,
44 VP_VTL_CONTROL_REGISTERS = 0x3000_7000,
45 VP_DEBUG_REGISTERS = 0x3000_8000,
46 VP_SEGMENT_REGISTERS = 0x3000_9000,
47 VP_TABLE_REGISTERS = 0x3000_A000,
48 VP_VIRTUAL_MSRS = 0x3000_B000,
49 VP_XSAVE_CONTROL_REGISTERS = 0x3000_D000,
50 VP_XSAVE_STATE = 0x3000_E100,
51 VP_SYNIC_APIC_STATE = 0x3000_F000,
52 VP_SYNIC_MSRS = 0x3001_0000,
53 VP_VTL_CONTROL_PAGE = 0x3001_8000,
54 VP_VTL = 0x3001_A000,
55 VP_NESTED_BASE = 0x3002_1000,
56 VP_NESTED_CURRENT_VMCS = 0x3002_3000,
57 }
58}
59
60#[repr(C, align(16))]
70#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
71pub struct VmSaveChunkHeader {
72 pub id: VmSaveChunkId,
73 pub data_length: u32,
74 pub _padding: [u8; 8],
75}
76
77static_assertions::const_assert_eq!(size_of::<VmSaveChunkHeader>(), 16);
78
79open_enum! {
84 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
85 pub enum HvProcessorVendor: u32 {
86 AMD = 0x0000,
87 INTEL = 0x0001,
88 HYGON = 0x0002,
89 ARM = 0x0010,
90 }
91}
92
93pub const VM_SAVE_CHUNK_TAG_UNDEFINED: u32 = 0x5054_6475; #[repr(C)]
102#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
103pub struct ObSaveChunkProlog {
104 pub header: VmSaveChunkHeader,
105 pub undefined_tag: u32,
106 pub is_summary_save_state: u8,
107 pub _padding: [u8; 3],
108 pub vendor: HvProcessorVendor,
109 pub _reserved: [u8; 4052],
110}
111
112pub const OB_SAVE_CHUNK_PROLOG_SIZE: usize = 4080;
113static_assertions::const_assert_eq!(size_of::<ObSaveChunkProlog>(), OB_SAVE_CHUNK_PROLOG_SIZE);
114
115#[repr(C)]
117#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
118pub struct ObSaveChunkEpilog {
119 pub header: VmSaveChunkHeader,
120}
121
122#[repr(C)]
128#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
129pub struct ObSaveChunkVp {
130 pub header: VmSaveChunkHeader,
131 pub vp_index: u32,
132 pub _padding: [u8; 12],
133}
134
135#[repr(C)]
137#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
138pub struct ObSaveChunkVtl {
139 pub header: VmSaveChunkHeader,
140 pub vtl: u8,
141 pub _padding: [u8; 15],
142}
143
144pub type ObSaveChunkPartitionVtl = ObSaveChunkVtl;
146
147#[repr(C)]
153#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
154pub struct PtSaveChunkOsId {
155 pub header: VmSaveChunkHeader,
156 pub os_id: u64,
157 pub _padding: [u8; 8],
158}
159
160#[repr(C)]
166#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
167pub struct VpX64SaveChunkGpRegisters {
168 pub header: VmSaveChunkHeader,
169 pub rax: u64,
170 pub rcx: u64,
171 pub rdx: u64,
172 pub rbx: u64,
173 pub rsp: u64,
174 pub rbp: u64,
175 pub rsi: u64,
176 pub rdi: u64,
177 pub r8: u64,
178 pub r9: u64,
179 pub r10: u64,
180 pub r11: u64,
181 pub r12: u64,
182 pub r13: u64,
183 pub r14: u64,
184 pub r15: u64,
185 pub rip: u64,
186 pub rflags: u64,
187}
188
189#[repr(C)]
191#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
192pub struct SynicX64SaveChunkControlRegisters {
193 pub header: VmSaveChunkHeader,
194 pub cr0: u64,
195 pub cr2: u64,
196 pub cr3: u64,
197 pub cr4: u64,
198 pub cr8: u64,
199 pub efer: u64,
200}
201
202#[repr(C)]
204#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
205pub struct VpX64SaveChunkDebugRegisters {
206 pub header: VmSaveChunkHeader,
207 pub dr0: u64,
208 pub dr1: u64,
209 pub dr2: u64,
210 pub dr3: u64,
211 pub dr6: u64,
212 pub dr7: u64,
213}
214
215#[repr(C)]
217#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
218pub struct VpX64SaveChunkSegmentRegisters {
219 pub header: VmSaveChunkHeader,
220 pub es: HvX64SegmentRegister,
221 pub cs: HvX64SegmentRegister,
222 pub ss: HvX64SegmentRegister,
223 pub ds: HvX64SegmentRegister,
224 pub fs: HvX64SegmentRegister,
225 pub gs: HvX64SegmentRegister,
226 pub ldtr: HvX64SegmentRegister,
227 pub tr: HvX64SegmentRegister,
228 pub cpl: u8,
229 pub _padding: [u8; 15],
230}
231
232#[repr(C)]
234#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
235pub struct VpX64SaveChunkTableRegisters {
236 pub header: VmSaveChunkHeader,
237 pub idtr: HvX64TableRegister,
238 pub gdtr: HvX64TableRegister,
239}
240
241#[repr(C)]
243#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
244pub struct VpX64SaveChunkFpRegisters {
245 pub header: VmSaveChunkHeader,
246 pub xmm: [AlignedU128; 16],
247 pub fp_mmx: [AlignedU128; 8],
248 pub fp_control_status: AlignedU128,
249 pub xmm_control_status: AlignedU128,
250}
251
252#[repr(C)]
261#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
262pub struct VpX64SaveChunkXsaveControlRegisters {
263 pub header: VmSaveChunkHeader,
264 pub xfem: u64,
266 pub _reserved: [u64; 7],
267}
268
269#[repr(C)]
275#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
276pub struct VpArm64SaveChunkGpRegisters {
277 pub header: VmSaveChunkHeader,
278 pub x: [u64; 29],
279 pub x_fp: u64,
280 pub x_lr: u64,
281 pub elr_el2: u64,
282 pub spsr_el2: u64,
283 pub esr_el1: u64,
284 pub spsr_el1: u64,
285 pub far_el1: u64,
286 pub par_el1: u64,
287 pub elr_el1: u64,
288 pub sp_el0: u64,
289 pub sp_el1: u64,
290 pub afsr0_el1: u64,
291 pub afsr1_el1: u64,
292}
293
294#[repr(C)]
296#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
297pub struct SynicArm64SaveChunkControlRegisters {
298 pub header: VmSaveChunkHeader,
299 pub vmpidr_el2: u64,
300 pub vpidr_el2: u64,
301 pub sctlr_el1: u64,
302 pub actlr_el1: u64,
303 pub tcr_el1: u64,
304 pub mair_el1: u64,
305 pub tpidr_el1: u64,
306 pub amair_el1: u64,
307 pub tpidrro_el0: u64,
308 pub tpidr_el0: u64,
309 pub contextidr_el1: u64,
310 pub cpacr_el1: u64,
311 pub csselr_el1: u64,
312 pub cntk_ctl_el1: u64,
313 pub cntv_cval_el0: u64,
314 pub cntv_ctl_el0: u64,
315}
316
317#[repr(C)]
319#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
320pub struct VpArm64SaveChunkTableRegisters {
321 pub header: VmSaveChunkHeader,
322 pub ttbr0_el1: u64,
323 pub ttbr1_el1: u64,
324 pub vbar_el1: u64,
325 pub _padding: [u8; 8],
326}
327
328#[repr(C)]
330#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
331pub struct VpArm64SaveChunkFpRegisters {
332 pub header: VmSaveChunkHeader,
333 pub q: [AlignedU128; 32],
334 pub fpsr: u64,
335 pub fpcr: u64,
336}
337
338pub const VSM_SAVE_VP_VTL_CONTROL_BYTES: usize = 24;
344
345#[repr(C)]
350#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
351pub struct VsmSaveChunkVpVtlControlPage {
352 pub header: VmSaveChunkHeader,
353 pub vp_assist_page_vtl_control_contents: [u8; VSM_SAVE_VP_VTL_CONTROL_BYTES],
354 pub vtl_is_runnable: u8,
355 pub _padding: [u8; 7],
356}