From 99e72be169898904a2615939d2743442406d2a25 Mon Sep 17 00:00:00 2001 From: Henry Wang Date: Fri, 12 Jun 2020 08:58:50 +0800 Subject: [PATCH] unit tests: Fix unit tests and docs for AArch64 Currently, not every feature of the cloud-hypervisor is enabled on AArch64, which means that on AArch64 machines, the `run_unit_tests.sh` needs to be tailored and some unit test cases should be run on x86_64 only. Also this commit fixes the typo and unifies `Arm64` and `AArch64` in the AArch64 document. Signed-off-by: Henry Wang --- arch/src/aarch64/fdt.rs | 9 --------- docs/arm64.md | 6 +++--- pci/src/vfio.rs | 32 ++++++++++++++++++++------------ scripts/run_unit_tests.sh | 7 +++++-- src/main.rs | 9 +++++++++ vm-allocator/src/system.rs | 20 +++++++++++++++----- 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index d76643bda..5ad3f23de 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -553,15 +553,6 @@ mod tests { } } - // The `load` function from the `device_tree` will mistakenly check the actual size - // of the buffer with the allocated size. This works around that. - fn set_size(buf: &mut [u8], pos: usize, val: usize) { - buf[pos] = ((val >> 24) & 0xff) as u8; - buf[pos + 1] = ((val >> 16) & 0xff) as u8; - buf[pos + 2] = ((val >> 8) & 0xff) as u8; - buf[pos + 3] = (val & 0xff) as u8; - } - #[test] fn test_create_fdt_with_devices() { let mut regions = Vec::new(); diff --git a/docs/arm64.md b/docs/arm64.md index f5a7619d0..5bbc5d67c 100644 --- a/docs/arm64.md +++ b/docs/arm64.md @@ -1,11 +1,11 @@ -# How to build and run Cloud-hypervisor on Arm64 +# How to build and run Cloud-hypervisor on AArch64 Cloud-hypervisor is partially enabled on AArch64 architecture. -Although all features are not ready yet, you can begin to test Cloud-hypervisor on a Arm64 host by following this guide. +Although all features are not ready yet, you can begin to test Cloud-hypervisor on a AArch64 host by following this guide. ## Prerequisites -On Arm64 machines, Cloud-hypervisor depends on an external library `libfdt-dev` for generating Flatted Device Tree (FDT). +On AArch64 machines, Cloud-hypervisor depends on an external library `libfdt-dev` for generating Flattened Device Tree (FDT). The long-term plan is to replace `libfdt-dev` with some pure-Rust component to get rid of such dependency. diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index cf9a96d7a..dca217311 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -748,20 +748,25 @@ impl PciDevice for VfioPciDevice { let mut region_type = PciBarRegionType::Memory32BitRegion; if io_bar { - // IO BAR - region_type = PciBarRegionType::IORegion; + #[cfg(target_arch = "x86_64")] + { + // IO BAR + region_type = PciBarRegionType::IORegion; - // Clear first bit. - lsb_size &= 0xffff_fffc; + // Clear first bit. + lsb_size &= 0xffff_fffc; - // Find the first bit that's set to 1. - let first_bit = lsb_size.trailing_zeros(); - region_size = 2u64.pow(first_bit); - // We need to allocate a guest PIO address range for that BAR. - // The address needs to be 4 bytes aligned. - bar_addr = allocator - .allocate_io_addresses(None, region_size, Some(0x4)) - .ok_or_else(|| PciDeviceError::IoAllocationFailed(region_size))?; + // Find the first bit that's set to 1. + let first_bit = lsb_size.trailing_zeros(); + region_size = 2u64.pow(first_bit); + // We need to allocate a guest PIO address range for that BAR. + // The address needs to be 4 bytes aligned. + bar_addr = allocator + .allocate_io_addresses(None, region_size, Some(0x4)) + .ok_or_else(|| PciDeviceError::IoAllocationFailed(region_size))?; + } + #[cfg(target_arch = "aarch64")] + unimplemented!(); } else { if is_64bit_bar { // 64 bits Memory BAR @@ -871,7 +876,10 @@ impl PciDevice for VfioPciDevice { for region in self.mmio_regions.iter() { match region.type_ { PciBarRegionType::IORegion => { + #[cfg(target_arch = "x86_64")] allocator.free_io_addresses(region.start, region.length); + #[cfg(target_arch = "aarch64")] + unimplemented!(); } PciBarRegionType::Memory32BitRegion => { allocator.free_mmio_hole_addresses(region.start, region.length); diff --git a/scripts/run_unit_tests.sh b/scripts/run_unit_tests.sh index e964a10e1..cf6a360be 100755 --- a/scripts/run_unit_tests.sh +++ b/scripts/run_unit_tests.sh @@ -3,8 +3,11 @@ source $HOME/.cargo/env BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu} +cargo_args=("$@") +[ $(uname -m) = "aarch64" ] && cargo_args+=("--no-default-features") +[ $(uname -m) = "aarch64" ] && cargo_args+=("--features mmio") -cargo test --target $BUILD_TARGET --workspace --no-run +cargo test --target $BUILD_TARGET --workspace --no-run ${cargo_args[@]} pushd target/$BUILD_TARGET/debug ls | grep net_util | grep -v "\.d" | xargs -n 1 sudo setcap cap_net_admin,cap_net_raw+ep popd @@ -12,5 +15,5 @@ popd sudo adduser $USER kvm newgrp kvm << EOF || exit 1 export RUST_BACKTRACE=1 - cargo test --target $BUILD_TARGET --workspace "$@" || exit 1; + cargo test --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1; EOF diff --git a/src/main.rs b/src/main.rs index 7250158f7..6fe4a9c0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -908,6 +908,7 @@ mod unit_tests { }"#, true, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", "--kernel", "/path/to/kernel", @@ -922,6 +923,7 @@ mod unit_tests { }"#, false, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", "--kernel", "/path/to/kernel", @@ -1201,6 +1203,7 @@ mod unit_tests { }"#, true, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", @@ -1218,6 +1221,7 @@ mod unit_tests { }"#, true, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", @@ -1234,6 +1238,7 @@ mod unit_tests { }"#, false, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", @@ -1250,6 +1255,7 @@ mod unit_tests { }"#, true, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", @@ -1325,6 +1331,7 @@ mod unit_tests { } #[test] + #[cfg(target_arch = "x86_64")] fn test_valid_vm_config_devices() { vec![ ( @@ -1449,6 +1456,7 @@ mod unit_tests { }"#, false, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", @@ -1464,6 +1472,7 @@ mod unit_tests { }"#, true, ), + #[cfg(target_arch = "x86_64")] ( vec![ "cloud-hypervisor", diff --git a/vm-allocator/src/system.rs b/vm-allocator/src/system.rs index 416c7339c..eb44b6f44 100644 --- a/vm-allocator/src/system.rs +++ b/vm-allocator/src/system.rs @@ -28,16 +28,26 @@ fn pagesize() -> usize { /// # Example - Use the `SystemAddress` builder. /// /// ``` +/// # #[cfg(target_arch = "x86_64")] /// # use vm_allocator::{GsiApic, SystemAllocator}; +/// # #[cfg(target_arch = "aarch64")] +/// # use vm_allocator::SystemAllocator; /// # use vm_memory::{Address, GuestAddress, GuestUsize}; /// let mut allocator = SystemAllocator::new( -/// GuestAddress(0x1000), 0x10000, +/// #[cfg(target_arch = "x86_64")] GuestAddress(0x1000), +/// #[cfg(target_arch = "x86_64")] 0x10000, /// GuestAddress(0x10000000), 0x10000000, /// GuestAddress(0x20000000), 0x100000, -/// vec![GsiApic::new(5, 19)]).unwrap(); -/// assert_eq!(allocator.allocate_irq(), Some(5)); -/// assert_eq!(allocator.allocate_irq(), Some(6)); -/// assert_eq!(allocator.allocate_mmio_addresses(None, 0x1000, Some(0x1000)), Some(GuestAddress(0x1fff_f000))); +/// #[cfg(target_arch = "x86_64")] vec![GsiApic::new(5, 19)]).unwrap(); +/// #[cfg(target_arch = "x86_64")] +/// assert_eq!(allocator.allocate_irq(), Some(5)); +/// #[cfg(target_arch = "aarch64")] +/// assert_eq!(allocator.allocate_irq(), Some(32)); +/// #[cfg(target_arch = "x86_64")] +/// assert_eq!(allocator.allocate_irq(), Some(6)); +/// #[cfg(target_arch = "aarch64")] +/// assert_eq!(allocator.allocate_irq(), Some(33)); +/// assert_eq!(allocator.allocate_mmio_addresses(None, 0x1000, Some(0x1000)), Some(GuestAddress(0x1fff_f000))); /// /// ``` pub struct SystemAllocator {