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        /// This memory is used by VTL2 for TDX AP startup page tables, and is
109        /// marked as reserved to the kernel.
110        VTL2_TDX_PAGE_TABLES = 9,
111    }
112}
113
114impl MemoryVtlType {
115    /// Returns true if this range is a ram type.
116    pub fn ram(&self) -> bool {
117        matches!(
118            *self,
119            MemoryVtlType::VTL0
120                | MemoryVtlType::VTL2_RAM
121                | MemoryVtlType::VTL2_CONFIG
122                | MemoryVtlType::VTL2_SIDECAR_IMAGE
123                | MemoryVtlType::VTL2_SIDECAR_NODE
124                | MemoryVtlType::VTL2_RESERVED
125                | MemoryVtlType::VTL2_GPA_POOL
126                | MemoryVtlType::VTL2_TDX_PAGE_TABLES
127        )
128    }
129}
130
131/// This structure describes the initial state of the TD VP. When a VP (both BSP and AP)
132/// starts at ResetVector (RV), this is loaded at the beginning of the RV page.
133/// Fields in the trampoline context must be loaded from memory by the
134/// trampoline code.
135///
136/// Note that this trampoline context must also be used for bringing up APs, as
137/// the code placed in the reset vector will use this format to figure out what
138/// register state to load.
139#[repr(C)]
140#[derive(Debug, Default, Clone, Copy, IntoBytes, Immutable)]
141pub struct TdxTrampolineContext {
142    /// Mailbox command
143    pub mailbox_command: u16,
144    /// Reserved
145    pub mailbox_reserved: u16,
146    /// Mailbox APIC ID
147    pub mailbox_apic_id: u32,
148    /// AP wakeup vector
149    pub mailbox_wakeup_vector: u64,
150    /// Padding
151    pub padding_1: u32,
152    /// Data selector
153    pub data_selector: u16,
154    /// Static GDT limit
155    pub static_gdt_limit: u16,
156    /// Static GDT base
157    pub static_gdt_base: u32,
158    /// Task selector
159    pub task_selector: u16,
160    /// IDTR limit
161    pub idtr_limit: u16,
162    /// IDTR base
163    pub idtr_base: u64,
164    /// Initial RIP
165    pub initial_rip: u64,
166    /// CS
167    pub code_selector: u16,
168    /// Padding
169    pub padding_2: [u16; 2],
170    /// GDTR limit
171    pub gdtr_limit: u16,
172    /// GDTR base
173    pub gdtr_base: u64,
174    /// RSP
175    pub rsp: u64,
176    /// RBP
177    pub rbp: u64,
178    /// RSI
179    pub rsi: u64,
180    /// R8
181    pub r8: u64,
182    /// R9
183    pub r9: u64,
184    /// R10
185    pub r10: u64,
186    /// R11
187    pub r11: u64,
188    /// CR0
189    pub cr0: u64,
190    /// CR3
191    pub cr3: u64,
192    /// CR4
193    pub cr4: u64,
194    /// Transistion CR3
195    pub transition_cr3: u32,
196    /// Padding
197    pub padding_3: u32,
198    /// Statuc GDT
199    pub static_gdt: [u8; 16],
200}