5
5
// Use of this source code is governed by a BSD-style license that can be
6
6
// found in the THIRD-PARTY file.
7
7
8
- extern crate byteorder;
9
- extern crate kvm;
10
- extern crate kvm_gen;
11
- extern crate libc;
12
- extern crate memory_model;
13
- extern crate sys_util;
14
-
15
- #[ allow( dead_code) ]
16
- #[ allow( non_upper_case_globals) ]
17
- #[ allow( non_camel_case_types) ]
18
- #[ allow( non_snake_case) ]
19
- mod bootparam;
20
- // boot_params is just a series of ints, it is safe to initialize it.
21
- unsafe impl memory_model:: DataInit for bootparam:: boot_params { }
22
-
23
- #[ allow( dead_code) ]
24
- #[ allow( non_upper_case_globals) ]
25
- mod msr_index;
26
-
27
- #[ allow( dead_code) ]
28
- #[ allow( non_upper_case_globals) ]
29
- #[ allow( non_camel_case_types) ]
30
- mod mpspec;
31
- // These mpspec types are only data, reading them from data is a safe initialization.
32
- unsafe impl memory_model:: DataInit for mpspec:: mpc_bus { }
33
- unsafe impl memory_model:: DataInit for mpspec:: mpc_cpu { }
34
- unsafe impl memory_model:: DataInit for mpspec:: mpc_intsrc { }
35
- unsafe impl memory_model:: DataInit for mpspec:: mpc_ioapic { }
36
- unsafe impl memory_model:: DataInit for mpspec:: mpc_table { }
37
- unsafe impl memory_model:: DataInit for mpspec:: mpc_lintsrc { }
38
- unsafe impl memory_model:: DataInit for mpspec:: mpf_intel { }
39
-
40
8
mod gdt;
41
9
pub mod interrupts;
42
- pub mod layout;
43
10
mod mptable;
44
11
pub mod regs;
45
12
46
13
use std:: mem;
47
- use std:: result;
48
14
49
- use bootparam:: boot_params;
50
- use bootparam:: E820_RAM ;
15
+ use arch_gen:: x86:: bootparam:: { boot_params, E820_RAM } ;
51
16
use memory_model:: { GuestAddress , GuestMemory } ;
52
17
53
- pub use interrupts:: Error as IntError ;
54
- pub use mptable:: Error as MpTableError ;
55
- pub use regs:: Error as RegError ;
56
-
57
18
#[ derive( Debug ) ]
58
19
pub enum Error {
59
20
/// Invalid e820 setup params.
60
21
E820Configuration ,
61
22
/// Error writing MP table to memory.
62
- MpTableSetup ( MpTableError ) ,
63
- /// The zero page extends past the end of guest_mem.
64
- ZeroPagePastRamEnd ,
65
- /// Error writing the zero page of guest memory.
66
- ZeroPageSetup ,
23
+ MpTableSetup ( mptable:: Error ) ,
67
24
}
68
- pub type Result < T > = result:: Result < T , Error > ;
25
+
26
+ // Magic addresses used to lay out x86_64 VMs.
27
+
28
+ // Initial stack for the boot CPU.
29
+ pub const BOOT_STACK_POINTER : usize = 0x8ff0 ;
30
+
31
+ // Kernel command line.
32
+ pub const CMDLINE_START : usize = 0x20000 ;
33
+ pub const CMDLINE_MAX_SIZE : usize = 0x10000 ;
34
+
35
+ // The 'zero page', a.k.a linux kernel bootparams.
36
+ pub const ZERO_PAGE_START : usize = 0x7000 ;
37
+
38
+ // Where BIOS/VGA magic would live on a real PC.
39
+ const EBDA_START : u64 = 0x9fc00 ;
40
+
41
+ // MPTABLE, describing VCPUS.
42
+ const MPTABLE_START : usize = 0x9fc00 ;
43
+
44
+ // Initial pagetables.
45
+ const PDE_START : usize = 0xb000 ;
46
+ const PDPTE_START : usize = 0xa000 ;
47
+ const PML4_START : usize = 0x9000 ;
69
48
70
49
const FIRST_ADDR_PAST_32BITS : usize = ( 1 << 32 ) ;
71
50
const MEM_32BIT_GAP_SIZE : usize = ( 768 << 20 ) ;
@@ -97,7 +76,6 @@ pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize)> {
97
76
}
98
77
99
78
/// X86 specific memory hole/ memory mapped devices/ reserved area.
100
- ///
101
79
pub fn get_32bit_gap_start ( ) -> usize {
102
80
FIRST_ADDR_PAST_32BITS - MEM_32BIT_GAP_SIZE
103
81
}
@@ -115,15 +93,15 @@ pub fn configure_system(
115
93
cmdline_addr : GuestAddress ,
116
94
cmdline_size : usize ,
117
95
num_cpus : u8 ,
118
- ) -> Result < ( ) > {
96
+ ) -> super :: Result < ( ) > {
119
97
const KERNEL_BOOT_FLAG_MAGIC : u16 = 0xaa55 ;
120
98
const KERNEL_HDR_MAGIC : u32 = 0x53726448 ;
121
99
const KERNEL_LOADER_OTHER : u8 = 0xff ;
122
100
const KERNEL_MIN_ALIGNMENT_BYTES : u32 = 0x1000000 ; // Must be non-zero.
123
101
let first_addr_past_32bits = GuestAddress ( FIRST_ADDR_PAST_32BITS ) ;
124
102
let end_32bit_gap_start = GuestAddress ( get_32bit_gap_start ( ) ) ;
125
103
126
- let himem_start = GuestAddress ( layout :: HIMEM_START ) ;
104
+ let himem_start = GuestAddress ( super :: HIMEM_START ) ;
127
105
128
106
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
129
107
mptable:: setup_mptable ( guest_mem, num_cpus) . map_err ( Error :: MpTableSetup ) ?;
@@ -137,7 +115,7 @@ pub fn configure_system(
137
115
params. hdr . cmdline_size = cmdline_size as u32 ;
138
116
params. hdr . kernel_alignment = KERNEL_MIN_ALIGNMENT_BYTES ;
139
117
140
- add_e820_entry ( & mut params, 0 , layout :: EBDA_START , E820_RAM ) ?;
118
+ add_e820_entry ( & mut params, 0 , EBDA_START , E820_RAM ) ?;
141
119
142
120
let mem_end = guest_mem. end_addr ( ) ;
143
121
if mem_end < end_32bit_gap_start {
@@ -164,20 +142,25 @@ pub fn configure_system(
164
142
}
165
143
}
166
144
167
- let zero_page_addr = GuestAddress ( layout :: ZERO_PAGE_START ) ;
145
+ let zero_page_addr = GuestAddress ( ZERO_PAGE_START ) ;
168
146
guest_mem
169
147
. checked_offset ( zero_page_addr, mem:: size_of :: < boot_params > ( ) )
170
- . ok_or ( Error :: ZeroPagePastRamEnd ) ?;
148
+ . ok_or ( super :: Error :: ZeroPagePastRamEnd ) ?;
171
149
guest_mem
172
150
. write_obj_at_addr ( params, zero_page_addr)
173
- . map_err ( |_| Error :: ZeroPageSetup ) ?;
151
+ . map_err ( |_| super :: Error :: ZeroPageSetup ) ?;
174
152
175
153
Ok ( ( ) )
176
154
}
177
155
178
156
/// Add an e820 region to the e820 map.
179
157
/// Returns Ok(()) if successful, or an error if there is no space left in the map.
180
- fn add_e820_entry ( params : & mut boot_params , addr : u64 , size : u64 , mem_type : u32 ) -> Result < ( ) > {
158
+ fn add_e820_entry (
159
+ params : & mut boot_params ,
160
+ addr : u64 ,
161
+ size : u64 ,
162
+ mem_type : u32 ,
163
+ ) -> Result < ( ) , Error > {
181
164
if params. e820_entries >= params. e820_map . len ( ) as u8 {
182
165
return Err ( Error :: E820Configuration ) ;
183
166
}
@@ -193,7 +176,7 @@ fn add_e820_entry(params: &mut boot_params, addr: u64, size: u64, mem_type: u32)
193
176
#[ cfg( test) ]
194
177
mod tests {
195
178
use super :: * ;
196
- use bootparam:: e820entry;
179
+ use arch_gen :: x86 :: bootparam:: e820entry;
197
180
198
181
#[ test]
199
182
fn regions_lt_4gb ( ) {
@@ -223,7 +206,12 @@ mod tests {
223
206
fn test_system_configuration ( ) {
224
207
let no_vcpus = 4 ;
225
208
let gm = GuestMemory :: new ( & vec ! [ ( GuestAddress ( 0 ) , 0x10000 ) ] ) . unwrap ( ) ;
226
- assert ! ( configure_system( & gm, GuestAddress ( 0 ) , 0 , 1 ) . is_err( ) ) ;
209
+ let config_err = configure_system ( & gm, GuestAddress ( 0 ) , 0 , 1 ) ;
210
+ assert ! ( config_err. is_err( ) ) ;
211
+ assert_eq ! (
212
+ format!( "{:?}" , config_err) ,
213
+ "Err(X86_64Setup(MpTableSetup(NotEnoughMemory)))"
214
+ ) ;
227
215
228
216
// Now assigning some memory that falls before the 32bit memory hole.
229
217
let mem_size = 128 << 20 ;
0 commit comments