Skip to content

Commit 580bb93

Browse files
committed
pvh: Introduce hvm_start_info structure
Introduce the layout and define the start_info and memory map table entry structures used by the PVH boot protocol. The hvm_start_info structure is akin to the 'zeropage' in Linux boot protocol, specifying the small set of parameters required by the PVH protocol. Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
1 parent 60fedeb commit 580bb93

File tree

1 file changed

+298
-0
lines changed

1 file changed

+298
-0
lines changed

src/loader/start_info.rs

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
// Copyright © 2020, Oracle and/or its affiliates.
2+
//
3+
/*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to
6+
* deal in the Software without restriction, including without limitation the
7+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8+
* sell copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*
22+
* Copyright (c) 2016, Citrix Systems, Inc.
23+
*/
24+
25+
/*
26+
* A canonical version of this file is provided by Xen's
27+
* xen/include/public/arch-x86/hvm/start_info.h
28+
*
29+
* Start of day structure passed to PVH guests and to HVM guests in %ebx.
30+
*
31+
* NOTE: nothing will be loaded at physical address 0, so a 0 value in any
32+
* of the address fields should be treated as not present.
33+
*
34+
* 0 +----------------+
35+
* | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE
36+
* | | ("xEn3" with the 0x80 bit of the "E" set).
37+
* 4 +----------------+
38+
* | version | Version of this structure. Current version is 1. New
39+
* | | versions are guaranteed to be backwards-compatible.
40+
* 8 +----------------+
41+
* | flags | SIF_xxx flags.
42+
* 12 +----------------+
43+
* | nr_modules | Number of modules passed to the kernel.
44+
* 16 +----------------+
45+
* | modlist_paddr | Physical address of an array of modules
46+
* | | (layout of the structure below).
47+
* 24 +----------------+
48+
* | cmdline_paddr | Physical address of the command line,
49+
* | | a zero-terminated ASCII string.
50+
* 32 +----------------+
51+
* | rsdp_paddr | Physical address of the RSDP ACPI data structure.
52+
* 40 +----------------+
53+
* | memmap_paddr | Physical address of the (optional) memory map. Only
54+
* | | present in version 1 and newer of the structure.
55+
* 48 +----------------+
56+
* | memmap_entries | Number of entries in the memory map table. Zero
57+
* | | if there is no memory map being provided. Only
58+
* | | present in version 1 and newer of the structure.
59+
* 52 +----------------+
60+
* | reserved | Version 1 and newer only.
61+
* 56 +----------------+
62+
*
63+
* The layout of each entry in the module structure is the following:
64+
*
65+
* 0 +----------------+
66+
* | paddr | Physical address of the module.
67+
* 8 +----------------+
68+
* | size | Size of the module in bytes.
69+
* 16 +----------------+
70+
* | cmdline_paddr | Physical address of the command line,
71+
* | | a zero-terminated ASCII string.
72+
* 24 +----------------+
73+
* | reserved |
74+
* 32 +----------------+
75+
*
76+
* The layout of each entry in the memory map table is as follows:
77+
*
78+
* 0 +----------------+
79+
* | addr | Base address
80+
* 8 +----------------+
81+
* | size | Size of mapping in bytes
82+
* 16 +----------------+
83+
* | type | Type of mapping as defined between the hypervisor
84+
* | | and guest.
85+
* 20 +----------------|
86+
* | reserved |
87+
* 24 +----------------+
88+
*
89+
* The address and sizes are always a 64bit little endian unsigned integer.
90+
*/
91+
92+
// Rust definitions needed to enable PVH boot protocol
93+
#[repr(C)]
94+
#[derive(Debug, Copy, Clone, Default)]
95+
pub struct hvm_start_info {
96+
pub magic: u32,
97+
pub version: u32,
98+
pub flags: u32,
99+
pub nr_modules: u32,
100+
pub modlist_paddr: u64,
101+
pub cmdline_paddr: u64,
102+
pub rsdp_paddr: u64,
103+
pub memmap_paddr: u64,
104+
pub memmap_entries: u32,
105+
pub reserved: u32,
106+
}
107+
108+
#[repr(C)]
109+
#[derive(Debug, Copy, Clone, Default)]
110+
pub struct hvm_memmap_table_entry {
111+
pub addr: u64,
112+
pub size: u64,
113+
pub type_: u32,
114+
pub reserved: u32,
115+
}
116+
117+
#[cfg(test)]
118+
mod tests {
119+
use super::*;
120+
121+
#[test]
122+
fn bindgen_test_layout_hvm_start_info() {
123+
assert_eq!(
124+
::std::mem::size_of::<hvm_start_info>(),
125+
56usize,
126+
concat!("Size of: ", stringify!(hvm_start_info))
127+
);
128+
assert_eq!(
129+
::std::mem::align_of::<hvm_start_info>(),
130+
8usize,
131+
concat!("Alignment of ", stringify!(hvm_start_info))
132+
);
133+
assert_eq!(
134+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).magic as *const _ as usize },
135+
0usize,
136+
concat!(
137+
"Offset of field: ",
138+
stringify!(hvm_start_info),
139+
"::",
140+
stringify!(magic)
141+
)
142+
);
143+
assert_eq!(
144+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).version as *const _ as usize },
145+
4usize,
146+
concat!(
147+
"Offset of field: ",
148+
stringify!(hvm_start_info),
149+
"::",
150+
stringify!(version)
151+
)
152+
);
153+
assert_eq!(
154+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).flags as *const _ as usize },
155+
8usize,
156+
concat!(
157+
"Offset of field: ",
158+
stringify!(hvm_start_info),
159+
"::",
160+
stringify!(flags)
161+
)
162+
);
163+
assert_eq!(
164+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).nr_modules as *const _ as usize },
165+
12usize,
166+
concat!(
167+
"Offset of field: ",
168+
stringify!(hvm_start_info),
169+
"::",
170+
stringify!(nr_modules)
171+
)
172+
);
173+
assert_eq!(
174+
unsafe {
175+
&(*(::std::ptr::null::<hvm_start_info>())).modlist_paddr as *const _ as usize
176+
},
177+
16usize,
178+
concat!(
179+
"Offset of field: ",
180+
stringify!(hvm_start_info),
181+
"::",
182+
stringify!(modlist_paddr)
183+
)
184+
);
185+
assert_eq!(
186+
unsafe {
187+
&(*(::std::ptr::null::<hvm_start_info>())).cmdline_paddr as *const _ as usize
188+
},
189+
24usize,
190+
concat!(
191+
"Offset of field: ",
192+
stringify!(hvm_start_info),
193+
"::",
194+
stringify!(cmdline_paddr)
195+
)
196+
);
197+
assert_eq!(
198+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).rsdp_paddr as *const _ as usize },
199+
32usize,
200+
concat!(
201+
"Offset of field: ",
202+
stringify!(hvm_start_info),
203+
"::",
204+
stringify!(rsdp_paddr)
205+
)
206+
);
207+
assert_eq!(
208+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).memmap_paddr as *const _ as usize },
209+
40usize,
210+
concat!(
211+
"Offset of field: ",
212+
stringify!(hvm_start_info),
213+
"::",
214+
stringify!(memmap_paddr)
215+
)
216+
);
217+
assert_eq!(
218+
unsafe {
219+
&(*(::std::ptr::null::<hvm_start_info>())).memmap_entries as *const _ as usize
220+
},
221+
48usize,
222+
concat!(
223+
"Offset of field: ",
224+
stringify!(hvm_start_info),
225+
"::",
226+
stringify!(memmap_entries)
227+
)
228+
);
229+
assert_eq!(
230+
unsafe { &(*(::std::ptr::null::<hvm_start_info>())).reserved as *const _ as usize },
231+
52usize,
232+
concat!(
233+
"Offset of field: ",
234+
stringify!(hvm_start_info),
235+
"::",
236+
stringify!(reserved)
237+
)
238+
);
239+
}
240+
241+
#[test]
242+
fn bindgen_test_layout_hvm_memmap_table_entry() {
243+
assert_eq!(
244+
::std::mem::size_of::<hvm_memmap_table_entry>(),
245+
24usize,
246+
concat!("Size of: ", stringify!(hvm_memmap_table_entry))
247+
);
248+
assert_eq!(
249+
::std::mem::align_of::<hvm_memmap_table_entry>(),
250+
8usize,
251+
concat!("Alignment of ", stringify!(hvm_memmap_table_entry))
252+
);
253+
assert_eq!(
254+
unsafe { &(*(::std::ptr::null::<hvm_memmap_table_entry>())).addr as *const _ as usize },
255+
0usize,
256+
concat!(
257+
"Offset of field: ",
258+
stringify!(hvm_memmap_table_entry),
259+
"::",
260+
stringify!(addr)
261+
)
262+
);
263+
assert_eq!(
264+
unsafe { &(*(::std::ptr::null::<hvm_memmap_table_entry>())).size as *const _ as usize },
265+
8usize,
266+
concat!(
267+
"Offset of field: ",
268+
stringify!(hvm_memmap_table_entry),
269+
"::",
270+
stringify!(size)
271+
)
272+
);
273+
assert_eq!(
274+
unsafe {
275+
&(*(::std::ptr::null::<hvm_memmap_table_entry>())).type_ as *const _ as usize
276+
},
277+
16usize,
278+
concat!(
279+
"Offset of field: ",
280+
stringify!(hvm_memmap_table_entry),
281+
"::",
282+
stringify!(type_)
283+
)
284+
);
285+
assert_eq!(
286+
unsafe {
287+
&(*(::std::ptr::null::<hvm_memmap_table_entry>())).reserved as *const _ as usize
288+
},
289+
20usize,
290+
concat!(
291+
"Offset of field: ",
292+
stringify!(hvm_memmap_table_entry),
293+
"::",
294+
stringify!(reserved)
295+
)
296+
);
297+
}
298+
}

0 commit comments

Comments
 (0)