loader_defs/
shim.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Loader definitions for the openhcl boot loader (`openhcl_boot`).
5
6use open_enum::open_enum;
7use zerocopy::FromBytes;
8use zerocopy::Immutable;
9use zerocopy::IntoBytes;
10use zerocopy::KnownLayout;
11
12/// Shim parameters set by the loader at IGVM build time. These contain shim
13/// base relative offsets and sizes instead of absolute addresses. Sizes are in
14/// bytes.
15#[repr(C)]
16#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
17pub struct ShimParamsRaw {
18    /// The offset to the Linux kernel entry point.
19    pub kernel_entry_offset: i64,
20    /// The offset to the [`crate::paravisor::ParavisorCommandLine`] structure.
21    pub cmdline_offset: i64,
22    /// The offset to the initrd.
23    pub initrd_offset: i64,
24    /// The size of the initrd.
25    pub initrd_size: u64,
26    /// The crc32 of the initrd.
27    pub initrd_crc: u32,
28    /// Isolation type supported by the igvm file.
29    pub supported_isolation_type: SupportedIsolationType,
30    /// The offset to the start of the VTL2 memory region.
31    pub memory_start_offset: i64,
32    /// The size of the VTL2 memory region.
33    pub memory_size: u64,
34    /// The offset to the parameter region.
35    pub parameter_region_offset: i64,
36    /// The size of the parameter region.
37    pub parameter_region_size: u64,
38    /// The offset to the VTL2 reserved region.
39    pub vtl2_reserved_region_offset: i64,
40    /// The size of the VTL2 reserved region.
41    pub vtl2_reserved_region_size: u64,
42    /// The offset to the sidecar memory region.
43    pub sidecar_offset: i64,
44    /// The size of the sidecar memory region.
45    pub sidecar_size: u64,
46    /// The offset to the entry point for the sidecar.
47    pub sidecar_entry_offset: i64,
48    /// The offset to the populated portion of VTL2 memory.
49    pub used_start: i64,
50    /// The offset to the end of the populated portion of VTL2 memory.
51    pub used_end: i64,
52    /// The offset to the bounce buffer range. This is 0 if unavailable.
53    pub bounce_buffer_start: i64,
54    /// The size of the bounce buffer range. This is 0 if unavailable.
55    pub bounce_buffer_size: u64,
56    /// The offset to the page_tables start address. This is 0 if unavailable.
57    pub page_tables_start: i64,
58    /// The size of the openhcl_boot page tables. This is 0 if unavailable.
59    pub page_tables_size: u64,
60}
61
62open_enum! {
63    /// Possible isolation types supported by the shim.
64    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
65    pub enum SupportedIsolationType: u32 {
66        // Starting from 1 for consistency with None usually being 0, but
67        // the IGVM file for None and Vbs will likely be the same, so None will
68        // not be enumerated here.At runtime, calls will be made to query
69        // the actual isolation type of the partition.
70        /// VBS-isolation is supported.
71        VBS = 1,
72        /// AMD SEV-SNP isolation is supported
73        SNP = 2,
74        /// Intel TDX isolation is supported
75        TDX = 3,
76    }
77}
78
79open_enum! {
80    /// The memory type reported from the bootshim to usermode, for which VTL a
81    /// given memory range is for.
82    pub enum MemoryVtlType: u32 {
83        /// This memory is for VTL0.
84        VTL0 = 0,
85        /// This memory is used by VTL2 as regular ram.
86        VTL2_RAM = 1,
87        /// This memory holds VTL2 config data, which is marked as reserved to
88        /// the kernel.
89        VTL2_CONFIG = 2,
90        /// This memory is used by the VTL2 sidecar as it's image, and is marked
91        /// as reserved to the kernel.
92        VTL2_SIDECAR_IMAGE = 3,
93        /// This memory is used by the VTL2 sidecar as node memory, and is
94        /// marked as reserved to the kernel.
95        VTL2_SIDECAR_NODE = 4,
96        /// This range is mmio for VTL0.
97        VTL0_MMIO = 5,
98        /// This range is mmio for VTL2.
99        VTL2_MMIO = 6,
100        /// This memory holds VTL2 data which should be preserved by the kernel
101        /// and usermode. Today, this is only used for SNP: VMSA, CPUID pages,
102        /// and secrets pages.
103        VTL2_RESERVED = 7,
104        /// This memory is used by VTL2 usermode as a persisted GPA page pool.
105        /// This memory is part of VTL2's address space, not VTL0's. It is
106        /// marked as reserved to the kernel.
107        VTL2_GPA_POOL = 8,
108    }
109}
110
111impl MemoryVtlType {
112    /// Returns true if this range is a ram type.
113    pub fn ram(&self) -> bool {
114        matches!(
115            *self,
116            MemoryVtlType::VTL0
117                | MemoryVtlType::VTL2_RAM
118                | MemoryVtlType::VTL2_CONFIG
119                | MemoryVtlType::VTL2_SIDECAR_IMAGE
120                | MemoryVtlType::VTL2_SIDECAR_NODE
121                | MemoryVtlType::VTL2_RESERVED
122                | MemoryVtlType::VTL2_GPA_POOL
123        )
124    }
125}
126
127/// This structure describes the initial state of the TD VP. When a VP (both BSP and AP)
128/// starts at ResetVector (RV), this is loaded at the beginning of the RV page.
129/// Fields in the trampoline context must be loaded from memory by the
130/// trampoline code.
131///
132/// Note that this trampoline context must also be used for bringing up APs, as
133/// the code placed in the reset vector will use this format to figure out what
134/// register state to load.
135#[repr(C)]
136#[derive(Debug, Default, Clone, Copy, IntoBytes, Immutable)]
137pub struct TdxTrampolineContext {
138    /// Mailbox command
139    pub mailbox_command: u16,
140    /// Reserved
141    pub mailbox_reserved: u16,
142    /// Mailbox APIC ID
143    pub mailbox_apic_id: u32,
144    /// AP wakeup vector
145    pub mailbox_wakeup_vector: u64,
146    /// Padding
147    pub padding_1: u32,
148    /// Data selector
149    pub data_selector: u16,
150    /// Static GDT limit
151    pub static_gdt_limit: u16,
152    /// Static GDT base
153    pub static_gdt_base: u32,
154    /// Task selector
155    pub task_selector: u16,
156    /// IDTR limit
157    pub idtr_limit: u16,
158    /// IDTR base
159    pub idtr_base: u64,
160    /// Initial RIP
161    pub initial_rip: u64,
162    /// CS
163    pub code_selector: u16,
164    /// Padding
165    pub padding_2: [u16; 2],
166    /// GDTR limit
167    pub gdtr_limit: u16,
168    /// GDTR base
169    pub gdtr_base: u64,
170    /// RSP
171    pub rsp: u64,
172    /// RBP
173    pub rbp: u64,
174    /// RSI
175    pub rsi: u64,
176    /// R8
177    pub r8: u64,
178    /// R9
179    pub r9: u64,
180    /// R10
181    pub r10: u64,
182    /// R11
183    pub r11: u64,
184    /// CR0
185    pub cr0: u64,
186    /// CR3
187    pub cr3: u64,
188    /// CR4
189    pub cr4: u64,
190    /// Transistion CR3
191    pub transition_cr3: u32,
192    /// Padding
193    pub padding_3: u32,
194    /// Statuc GDT
195    pub static_gdt: [u8; 16],
196}