Skip to content

Commit 5e6575c

Browse files
committed
arch: prepare crate for aarch64 code
- Refactored crate to support addition of non-x86_64 architectures - Labeled code accordingly - non-x86_64 code was moved outside x86_64 folder - Adjusted vmm related code - Added aarch64 dummy template Signed-off-by: Diana Popa <[email protected]>
1 parent a54496b commit 5e6575c

File tree

7 files changed

+102
-49
lines changed

7 files changed

+102
-49
lines changed

arch/src/aarch64/layout.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/// Kernel command line start address.
5+
pub const CMDLINE_START: usize = 0x0;
6+
/// Kernel command line start address maximum size.
7+
pub const CMDLINE_MAX_SIZE: usize = 0x0;

arch/src/aarch64/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
pub mod layout;
5+
6+
use memory_model::{GuestAddress, GuestMemory};
7+
8+
/// Stub function that needs to be implemented when aarch64 functionality is added.
9+
pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize)> {
10+
vec![(GuestAddress(0), size)]
11+
}
12+
13+
/// Stub function that needs to be implemented when aarch64 functionality is added.
14+
pub fn configure_system(
15+
_guest_mem: &GuestMemory,
16+
_cmdline_addr: GuestAddress,
17+
_cmdline_size: usize,
18+
_num_cpus: u8,
19+
) -> super::Result<()> {
20+
Ok(())
21+
}
22+
23+
/// Stub function that needs to be implemented when aarch64 functionality is added.
24+
pub fn get_reserved_mem_addr() -> usize {
25+
0
26+
}

arch/src/lib.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,33 @@ use std::result;
1414

1515
#[derive(Debug, PartialEq)]
1616
pub enum Error {
17+
#[cfg(target_arch = "x86_64")]
18+
/// X86_64 specific error triggered during system configuration.
19+
X86_64Setup(x86_64::Error),
1720
/// The zero page extends past the end of guest_mem.
1821
ZeroPagePastRamEnd,
1922
/// Error writing the zero page of guest memory.
2023
ZeroPageSetup,
21-
#[cfg(target_arch = "x86_64")]
22-
/// X86_64 specific error triggered during system configuration.
23-
X86_64Setup(x86_64::Error),
2424
}
2525
pub type Result<T> = result::Result<T, Error>;
2626

2727
// 1MB. We don't put anything above here except the kernel itself.
2828
pub const HIMEM_START: usize = 0x100000;
2929

30+
#[cfg(target_arch = "aarch64")]
31+
pub mod aarch64;
32+
33+
#[cfg(target_arch = "aarch64")]
34+
pub use aarch64::{
35+
arch_memory_regions, configure_system, get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE,
36+
layout::CMDLINE_START,
37+
};
38+
3039
#[cfg(target_arch = "x86_64")]
3140
pub mod x86_64;
32-
impl From<x86_64::Error> for Error {
33-
fn from(e: x86_64::Error) -> Error {
34-
Error::X86_64Setup(e)
35-
}
36-
}
41+
42+
#[cfg(target_arch = "x86_64")]
43+
pub use x86_64::{
44+
arch_memory_regions, configure_system, get_32bit_gap_start as get_reserved_mem_addr,
45+
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START,
46+
};

arch/src/x86_64/layout.rs

+3
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ pub const CMDLINE_START: usize = 0x20000;
1616
/// Kernel command line start address maximum size.
1717
pub const CMDLINE_MAX_SIZE: usize = 0x10000;
1818

19+
/// Address for the TSS setup.
20+
pub const KVM_TSS_ADDRESS: usize = 0xfffbd000;
21+
1922
/// The 'zero page', a.k.a linux kernel bootparams.
2023
pub const ZERO_PAGE_START: usize = 0x7000;

arch/src/x86_64/mod.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ use std::mem;
1616
use arch_gen::x86::bootparam::{boot_params, E820_RAM};
1717
use memory_model::{GuestAddress, GuestMemory};
1818

19-
// Where BIOS/VGA magic would live on a real PC.
20-
const EBDA_START: u64 = 0x9fc00;
21-
const FIRST_ADDR_PAST_32BITS: usize = (1 << 32);
22-
const MEM_32BIT_GAP_SIZE: usize = (768 << 20);
23-
2419
#[derive(Debug, PartialEq)]
2520
pub enum Error {
2621
/// Invalid e820 setup params.
@@ -29,6 +24,17 @@ pub enum Error {
2924
MpTableSetup(mptable::Error),
3025
}
3126

27+
impl From<Error> for super::Error {
28+
fn from(e: Error) -> super::Error {
29+
super::Error::X86_64Setup(e)
30+
}
31+
}
32+
33+
// Where BIOS/VGA magic would live on a real PC.
34+
const EBDA_START: u64 = 0x9fc00;
35+
const FIRST_ADDR_PAST_32BITS: usize = (1 << 32);
36+
const MEM_32BIT_GAP_SIZE: usize = (768 << 20);
37+
3238
/// Returns a Vec of the valid memory addresses.
3339
/// These should be used to configure the GuestMemory structure for the platform.
3440
/// For x86_64 all addresses are valid from the start of the kernel except a

vmm/src/lib.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ use std::time::Duration;
6161
use libc::{c_void, siginfo_t};
6262
use timerfd::{ClockId, SetTimeFlags, TimerFd, TimerState};
6363

64-
use arch::x86_64;
6564
use device_manager::legacy::LegacyDeviceManager;
6665
use device_manager::mmio::MMIODeviceManager;
6766
use devices::virtio;
@@ -822,7 +821,7 @@ impl Vmm {
822821
memory_model::GuestMemoryError::MemoryNotInitialized,
823822
))?
824823
<< 20;
825-
let arch_mem_regions = x86_64::arch_memory_regions(mem_size);
824+
let arch_mem_regions = arch::arch_memory_regions(mem_size);
826825
self.guest_memory =
827826
Some(GuestMemory::new(&arch_mem_regions).map_err(StartMicrovmError::GuestMemory)?);
828827
Ok(())
@@ -842,11 +841,11 @@ impl Vmm {
842841
.ok_or(StartMicrovmError::GuestMemory(
843842
memory_model::GuestMemoryError::MemoryNotInitialized,
844843
))?;
844+
845845
// Instantiate the MMIO device manager.
846-
// 'mmio_base' address has to be an address which is protected by the kernel, in this case
847-
// the start of the x86 specific gap of memory (currently hardcoded at 768MiB).
846+
// 'mmio_base' address has to be an address which is protected by the kernel.
848847
let mut device_manager =
849-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
848+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
850849

851850
self.attach_block_devices(&mut device_manager)?;
852851
self.attach_net_devices(&mut device_manager)?;
@@ -1105,7 +1104,7 @@ impl Vmm {
11051104
.vm_config
11061105
.vcpu_count
11071106
.ok_or(StartMicrovmError::VcpusNotConfigured)?;
1108-
x86_64::configure_system(
1107+
arch::configure_system(
11091108
vm_memory,
11101109
kernel_config.cmdline_addr,
11111110
cmdline_cstring.to_bytes().len() + 1,
@@ -1406,7 +1405,7 @@ impl Vmm {
14061405
let kernel_file = File::open(kernel_image_path).map_err(|_| {
14071406
VmmActionError::BootSource(ErrorKind::User, BootSourceConfigError::InvalidKernelPath)
14081407
})?;
1409-
let mut cmdline = kernel_cmdline::Cmdline::new(x86_64::layout::CMDLINE_MAX_SIZE);
1408+
let mut cmdline = kernel_cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
14101409
cmdline
14111410
.insert_str(kernel_cmdline.unwrap_or(String::from(DEFAULT_KERNEL_CMDLINE)))
14121411
.map_err(|_| {
@@ -1419,7 +1418,7 @@ impl Vmm {
14191418
let kernel_config = KernelConfig {
14201419
kernel_file,
14211420
cmdline,
1422-
cmdline_addr: GuestAddress(x86_64::layout::CMDLINE_START),
1421+
cmdline_addr: GuestAddress(arch::CMDLINE_START),
14231422
};
14241423
self.configure_kernel(kernel_config);
14251424

@@ -1878,12 +1877,12 @@ mod tests {
18781877
let kernel_path = String::from(kernel_file_temp.path().to_path_buf().to_str().unwrap());
18791878
let kernel_file = File::open(kernel_path).unwrap();
18801879

1881-
let mut cmdline = kernel_cmdline::Cmdline::new(x86_64::layout::CMDLINE_MAX_SIZE);
1880+
let mut cmdline = kernel_cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
18821881
assert!(cmdline.insert_str(DEFAULT_KERNEL_CMDLINE).is_ok());
18831882
let kernel_cfg = KernelConfig {
18841883
cmdline,
18851884
kernel_file,
1886-
cmdline_addr: GuestAddress(x86_64::layout::CMDLINE_START),
1885+
cmdline_addr: GuestAddress(arch::CMDLINE_START),
18871886
};
18881887
self.configure_kernel(kernel_cfg);
18891888
}
@@ -2446,7 +2445,7 @@ mod tests {
24462445

24472446
let guest_mem = vmm.guest_memory.clone().unwrap();
24482447
let mut device_manager =
2449-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
2448+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
24502449
assert!(vmm.attach_block_devices(&mut device_manager).is_ok());
24512450
assert!(vmm.get_kernel_cmdline_str().contains("root=/dev/vda"));
24522451

@@ -2470,7 +2469,7 @@ mod tests {
24702469

24712470
let guest_mem = vmm.guest_memory.clone().unwrap();
24722471
let mut device_manager =
2473-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
2472+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
24742473
assert!(vmm.attach_block_devices(&mut device_manager).is_ok());
24752474
assert!(vmm
24762475
.get_kernel_cmdline_str()
@@ -2498,7 +2497,7 @@ mod tests {
24982497

24992498
let guest_mem = vmm.guest_memory.clone().unwrap();
25002499
let mut device_manager =
2501-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
2500+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
25022501
assert!(vmm.attach_block_devices(&mut device_manager).is_ok());
25032502
// Test that kernel commandline does not contain either /dev/vda or PARTUUID.
25042503
assert!(!vmm.get_kernel_cmdline_str().contains("root=PARTUUID="));
@@ -2532,7 +2531,7 @@ mod tests {
25322531

25332532
let guest_mem = vmm.guest_memory.clone().unwrap();
25342533
let mut device_manager =
2535-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
2534+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
25362535

25372536
// test create network interface
25382537
let network_interface = NetworkInterfaceConfig {
@@ -2574,8 +2573,7 @@ mod tests {
25742573
// Test valid kernel path and invalid cmdline.
25752574
let kernel_file = NamedTempFile::new().expect("Failed to create temporary kernel file.");
25762575
let kernel_path = String::from(kernel_file.path().to_path_buf().to_str().unwrap());
2577-
let invalid_cmdline =
2578-
String::from_utf8(vec![b'X'; x86_64::layout::CMDLINE_MAX_SIZE + 1]).unwrap();
2576+
let invalid_cmdline = String::from_utf8(vec![b'X'; arch::CMDLINE_MAX_SIZE + 1]).unwrap();
25792577
assert!(vmm
25802578
.configure_boot_source(kernel_path.clone(), Some(invalid_cmdline))
25812579
.is_err());
@@ -2629,14 +2627,14 @@ mod tests {
26292627

26302628
let guest_mem = vmm.guest_memory.clone().unwrap();
26312629
let mut device_manager =
2632-
MMIODeviceManager::new(guest_mem.clone(), x86_64::get_32bit_gap_start() as u64);
2630+
MMIODeviceManager::new(guest_mem.clone(), arch::get_reserved_mem_addr() as u64);
26332631

26342632
let dummy_box = Box::new(DummyDevice { dummy: 0 });
26352633
// Use a dummy command line as it is not used in this test.
26362634
let _addr = device_manager
26372635
.register_device(
26382636
dummy_box,
2639-
&mut kernel_cmdline::Cmdline::new(x86_64::layout::CMDLINE_MAX_SIZE),
2637+
&mut kernel_cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE),
26402638
Some(scratch_id.clone()),
26412639
)
26422640
.unwrap();

vmm/src/vstate.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@ extern crate sys_util;
1313
use std::result;
1414

1515
use super::KvmContext;
16-
use arch::x86_64;
1716
use cpuid::{c3_template, filter_cpuid, t2_template};
1817
use kvm::*;
1918
use logger::{LogOption, LOGGER};
2019
use logger::{Metric, METRICS};
2120
use memory_model::{GuestAddress, GuestMemory, GuestMemoryError};
2221
use sys_util::EventFd;
2322
use vmm_config::machine_config::{CpuFeaturesTemplate, VmConfig};
24-
use x86_64::{interrupts, regs};
2523

26-
pub const KVM_TSS_ADDRESS: usize = 0xfffbd000;
2724
const KVM_MEM_LOG_DIRTY_PAGES: u32 = 0x1;
2825

2926
/// Errors associated with the wrappers over KVM ioctls.
@@ -47,18 +44,23 @@ pub enum Error {
4744
SetSupportedCpusFailed(sys_util::Error),
4845
/// The number of configured slots is bigger than the maximum reported by KVM.
4946
NotEnoughMemorySlots,
47+
#[cfg(target_arch = "x86_64")]
5048
/// Cannot set the local interruption due to bad configuration.
51-
LocalIntConfiguration(interrupts::Error),
49+
LocalIntConfiguration(arch::x86_64::interrupts::Error),
5250
/// Cannot set the memory regions.
5351
SetUserMemoryRegion(sys_util::Error),
52+
#[cfg(target_arch = "x86_64")]
5453
/// Error configuring the MSR registers
55-
MSRSConfiguration(regs::Error),
54+
MSRSConfiguration(arch::x86_64::regs::Error),
55+
#[cfg(target_arch = "x86_64")]
5656
/// Error configuring the general purpose registers
57-
REGSConfiguration(regs::Error),
57+
REGSConfiguration(arch::x86_64::regs::Error),
58+
#[cfg(target_arch = "x86_64")]
5859
/// Error configuring the special registers
59-
SREGSConfiguration(regs::Error),
60+
SREGSConfiguration(arch::x86_64::regs::Error),
61+
#[cfg(target_arch = "x86_64")]
6062
/// Error configuring the floating point related registers
61-
FPUConfiguration(regs::Error),
63+
FPUConfiguration(arch::x86_64::regs::Error),
6264
/// Cannot configure the IRQ.
6365
Irq(sys_util::Error),
6466
}
@@ -113,9 +115,9 @@ impl Vm {
113115
})?;
114116
self.guest_mem = Some(guest_mem);
115117

116-
let tss_addr = GuestAddress(KVM_TSS_ADDRESS);
118+
#[cfg(target_arch = "x86_64")]
117119
self.fd
118-
.set_tss_address(tss_addr.offset())
120+
.set_tss_address(GuestAddress(arch::x86_64::layout::KVM_TSS_ADDRESS).offset())
119121
.map_err(Error::VmSetup)?;
120122

121123
Ok(())
@@ -173,7 +175,8 @@ impl Vcpu {
173175
})
174176
}
175177

176-
/// /// Configures the vcpu and should be called once per vcpu from the vcpu's thread.
178+
#[cfg(target_arch = "x86_64")]
179+
/// Configures the vcpu and should be called once per vcpu from the vcpu's thread.
177180
///
178181
/// # Arguments
179182
///
@@ -217,21 +220,21 @@ impl Vcpu {
217220
.set_cpuid2(&self.cpuid)
218221
.map_err(Error::SetSupportedCpusFailed)?;
219222

220-
x86_64::regs::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?;
223+
arch::x86_64::regs::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?;
221224
// Safe to unwrap because this method is called after the VM is configured
222225
let vm_memory = vm
223226
.get_memory()
224227
.ok_or(Error::GuestMemory(GuestMemoryError::MemoryNotInitialized))?;
225-
x86_64::regs::setup_regs(
228+
arch::x86_64::regs::setup_regs(
226229
&self.fd,
227230
kernel_start_addr.offset() as u64,
228-
x86_64::layout::BOOT_STACK_POINTER as u64,
229-
x86_64::layout::ZERO_PAGE_START as u64,
231+
arch::x86_64::layout::BOOT_STACK_POINTER as u64,
232+
arch::x86_64::layout::ZERO_PAGE_START as u64,
230233
)
231234
.map_err(Error::REGSConfiguration)?;
232-
x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?;
233-
x86_64::regs::setup_sregs(vm_memory, &self.fd).map_err(Error::SREGSConfiguration)?;
234-
x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?;
235+
arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?;
236+
arch::x86_64::regs::setup_sregs(vm_memory, &self.fd).map_err(Error::SREGSConfiguration)?;
237+
arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?;
235238
Ok(())
236239
}
237240

0 commit comments

Comments
 (0)