Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/cross-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Cloud Hypervisor Cross Build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 888028a please prefix first commit message line with "build: " and drop gerrit Change-Id

on: [pull_request, create]

jobs:
build:
if: github.event_name == 'pull_request'
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
target:
- aarch64-unknown-linux-gnu
- aarch64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- name: Disable "with-serde" in kvm-bindings
run: sed -i 's/"with-serde",\ //g' vmm/Cargo.toml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a reasonable solution for the time being.

- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --target=${{ matrix.target }} --no-default-features --features "mmio"
44 changes: 40 additions & 4 deletions arch/src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@

pub mod layout;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 24e62df please prefix with "build:" and drop gerrit Change-Id.

use memory_model::{GuestAddress, GuestMemory};
use crate::RegionType;
use kvm_ioctls::*;
use vm_memory::{GuestAddress, GuestMemoryMmap, GuestUsize};

/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize, RegionType)> {
vec![(GuestAddress(0), size, RegionType::Ram)]
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> {
vec![(GuestAddress(0), size as usize, RegionType::Ram)]
}

#[derive(Debug, Copy, Clone)]
/// Specifies the entry point address where the guest must start
/// executing code.
pub struct EntryPoint {
/// Address in guest memory where the guest must start execution
pub entry_addr: GuestAddress,
}

/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn configure_system(
_guest_mem: &GuestMemory,
_guest_mem: &GuestMemoryMmap,
_cmdline_addr: GuestAddress,
_cmdline_size: usize,
_num_cpus: u8,
Expand All @@ -25,3 +35,29 @@ pub fn configure_system(
pub fn get_reserved_mem_addr() -> usize {
0
}

pub fn get_host_cpu_phys_bits() -> u8 {
// The value returned here is used to determine the physical address space size
// for a VM (IPA size).
// In recent kernel versions, the maxium IPA size supported by the host can be
// known by querying cap KVM_CAP_ARM_VM_IPA_SIZE. And the IPA size for a
// guest can be configured smaller.
// But in Cloud-Hypervisor we simply use the maxium value for the VM.
// Reference https://lwn.net/Articles/766767/.
//
// The correct way to query KVM_CAP_ARM_VM_IPA_SIZE is via rust-vmm/kvm-ioctls,
// which wraps all IOCTL's and provides easy interface to user hypervisors.
// For now the cap hasn't been supported. A separate patch will be submitted to
// rust-vmm to add it.
// So a hardcoded value is used here as a temporary solution.
// It will be replace once rust-vmm/kvm-ioctls is ready.
//
40
}

pub fn check_required_kvm_extensions(kvm: &Kvm) -> super::Result<()> {
if !kvm.check_extension(Cap::SignalMsi) {
return Err(super::Error::CapabilityMissing(Cap::SignalMsi));
}
Ok(())
}
13 changes: 9 additions & 4 deletions arch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern crate kvm_ioctls;
extern crate linux_loader;
extern crate vm_memory;

use kvm_ioctls::*;
use std::result;

#[derive(Debug)]
Expand All @@ -47,6 +48,8 @@ pub enum Error {
ModlistSetup(vm_memory::GuestMemoryError),
/// RSDP Beyond Guest Memory
RSDPPastRamEnd,
/// Capability missing
CapabilityMissing(Cap),
}
pub type Result<T> = result::Result<T, Error>;

Expand All @@ -73,20 +76,22 @@ pub mod aarch64;

#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE,
layout::CMDLINE_START,
arch_memory_regions, check_required_kvm_extensions, configure_system, get_host_cpu_phys_bits,
get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, EntryPoint,
};

#[cfg(target_arch = "x86_64")]
pub mod x86_64;

#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::CMDLINE_START, regs, BootProtocol, EntryPoint,
arch_memory_regions, check_required_kvm_extensions, configure_system, get_host_cpu_phys_bits,
initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs,
BootProtocol, EntryPoint,
};

/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
#[cfg(target_arch = "x86_64")]
#[inline(always)]
fn pagesize() -> usize {
// Trivially safe
Expand Down
43 changes: 42 additions & 1 deletion arch/src/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ pub mod layout;
#[cfg(not(feature = "acpi"))]
mod mptable;
pub mod regs;

use crate::InitramfsConfig;
use crate::RegionType;
use kvm_ioctls::*;
use linux_loader::loader::bootparam::{boot_params, setup_header};
use linux_loader::loader::elf::start_info::{
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
Expand Down Expand Up @@ -459,6 +459,47 @@ pub fn initramfs_load_addr(
Ok(aligned_addr)
}

pub fn get_host_cpu_phys_bits() -> u8 {
use std::arch::x86_64;
unsafe {
let leaf = x86_64::__cpuid(0x8000_0000);

// Detect and handle AMD SME (Secure Memory Encryption) properly.
// Some physical address bits may become reserved when the feature is enabled.
// See AMD64 Architecture Programmer's Manual Volume 2, Section 7.10.1
let reduced = if leaf.eax >= 0x8000_001f
&& leaf.ebx == 0x6874_7541 // Vendor ID: AuthenticAMD
&& leaf.ecx == 0x444d_4163
&& leaf.edx == 0x6974_6e65
&& x86_64::__cpuid(0x8000_001f).eax & 0x1 != 0
{
(x86_64::__cpuid(0x8000_001f).ebx >> 6) & 0x3f
} else {
0
};

if leaf.eax >= 0x8000_0008 {
let leaf = x86_64::__cpuid(0x8000_0008);
((leaf.eax & 0xff) - reduced) as u8
} else {
36
}
}
}

pub fn check_required_kvm_extensions(kvm: &Kvm) -> super::Result<()> {
if !kvm.check_extension(Cap::SignalMsi) {
return Err(super::Error::CapabilityMissing(Cap::SignalMsi));
}
if !kvm.check_extension(Cap::TscDeadlineTimer) {
return Err(super::Error::CapabilityMissing(Cap::TscDeadlineTimer));
}
if !kvm.check_extension(Cap::SplitIrqchip) {
return Err(super::Error::CapabilityMissing(Cap::SplitIrqchip));
}
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion net_util/src/tap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl Tap {
unsafe {
let ifru_hwaddr = ifreq.ifr_ifru.ifru_hwaddr.as_mut();
for (i, v) in addr.get_bytes().iter().enumerate() {
ifru_hwaddr.sa_data[i] = *v as i8;
ifru_hwaddr.sa_data[i] = *v as c_char;
}
}

Expand Down
30 changes: 19 additions & 11 deletions resources/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM ubuntu:18.04 as dev

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For b40aea0 please prefix first line of commit message with "build:" and drop trailing full-stop.

Please remove the Gerrit Change-Id.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done for all commits.

ARG TARGETARCH="x86_64"
ARG RUST_TOOLCHAIN="1.42.0"
ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
Expand All @@ -11,9 +12,9 @@ ENV RUSTUP_HOME=$CARGO_HOME
ENV PATH="$PATH:$CARGO_HOME/bin"

# Install all CI dependencies
RUN apt-get update
RUN apt-get -yq upgrade
RUN DEBIAN_FRONTEND=noninteractive apt-get install -yq \
RUN apt-get update \
&& apt-get -yq upgrade \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq \
build-essential \
bc \
docker.io \
Expand All @@ -37,22 +38,29 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -yq \
dosfstools \
cpio \
bsdtar \
gcc-multilib \
libfdt-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN if [ "$TARGETARCH" = "x86_64" ]; then \
apt-get update \
&& apt-get -yq upgrade \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc-multilib \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*; fi

# Fix the libssl-dev install
RUN cp /usr/include/x86_64-linux-gnu/openssl/opensslconf.h /usr/include/openssl/
ENV OPENSSL_DIR=/usr/lib/x86_64-linux-gnu/
ENV OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu/
RUN cp /usr/include/"$TARGETARCH"-linux-gnu/openssl/opensslconf.h /usr/include/openssl/
ENV OPENSSL_DIR=/usr/lib/"$TARGETARCH"-linux-gnu/
ENV OPENSSL_LIB_DIR=/usr/lib/"$TARGETARCH"-linux-gnu/
ENV OPENSSL_INCLUDE_DIR=/usr/include/

# Install the rust toolchain
RUN nohup curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain "$RUST_TOOLCHAIN" \
&& rustup target add x86_64-unknown-linux-musl --toolchain "$RUST_TOOLCHAIN" \
&& rustup toolchain add $RUST_TOOLCHAIN-x86_64-unknown-linux-musl \
&& rustup component add rustfmt \
&& rustup component add clippy \
&& rustup target add $TARGETARCH-unknown-linux-musl --toolchain "$RUST_TOOLCHAIN" \
&& if [ "$TARGETARCH" = "x86_64" ]; then rustup toolchain add $RUST_TOOLCHAIN-x86_64-unknown-linux-musl; fi \
&& if [ "$TARGETARCH" = "x86_64" ]; then rustup component add rustfmt; fi \
&& if [ "$TARGETARCH" = "x86_64" ]; then rustup component add clippy; fi \
&& cargo install cargo-audit \
&& rm -rf "$CARGO_HOME/registry" \
&& ln -s "$CARGO_REGISTRY_DIR" "$CARGO_HOME/registry" \
Expand Down
18 changes: 17 additions & 1 deletion scripts/dev_cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,21 @@ cmd_build() {
cargo_args=("$@")
[ $build = "release" ] && cargo_args+=("--release")
cargo_args+=(--target "$target")
[ $(uname -m) = "aarch64" ] && cargo_args+=("--no-default-features")
[ $(uname -m) = "aarch64" ] && cargo_args+=(--features "mmio")

rustflags=""
if [ $(uname -m) = "aarch64" ] && [ $libc = "musl" ] ; then
rustflags="-C link-arg=-lgcc"
fi

$DOCKER_RUNTIME run \
--user "$(id -u):$(id -g)" \
--workdir "$CTR_CLH_ROOT_DIR" \
--rm \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
--env RUSTFLAGS="$rustflags" \
"$CTR_IMAGE" \
cargo build \
--target-dir "$CTR_CLH_CARGO_TARGET" \
Expand Down Expand Up @@ -336,6 +344,7 @@ cmd_build-container() {
--target $container_type \
-t $CTR_IMAGE \
-f $BUILD_DIR/Dockerfile \
--build-arg TARGETARCH="$(uname -m)" \
$BUILD_DIR
}

Expand Down Expand Up @@ -365,6 +374,13 @@ cmd=cmd_$1
shift

ensure_build_dir
ensure_latest_ctr
if [ $(uname -m) = "x86_64" ]; then
ensure_latest_ctr
fi

# Before a public image for AArch64 ready, we build the container if needed.
if [ $(uname -m) = "aarch64" ]; then
cmd_build-container
fi

$cmd "$@"
8 changes: 8 additions & 0 deletions vhost_user_fs/src/seccomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ fn vuf_filter(action: SeccompAction) -> Result<SeccompFilter, Error> {
allow_syscall(libc::SYS_close),
allow_syscall(libc::SYS_copy_file_range),
allow_syscall(libc::SYS_dup),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_epoll_create),
allow_syscall(libc::SYS_epoll_create1),
allow_syscall(libc::SYS_epoll_ctl),
allow_syscall(libc::SYS_epoll_pwait),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_epoll_wait),
allow_syscall(libc::SYS_eventfd2),
allow_syscall(libc::SYS_exit),
Expand All @@ -59,10 +61,13 @@ fn vuf_filter(action: SeccompAction) -> Result<SeccompFilter, Error> {
allow_syscall(libc::SYS_fremovexattr),
allow_syscall(libc::SYS_fsetxattr),
allow_syscall(libc::SYS_fstat),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_fstatfs),
allow_syscall(libc::SYS_fsync),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_ftruncate),
allow_syscall(libc::SYS_futex),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_getdents),
allow_syscall(libc::SYS_getdents64),
allow_syscall(libc::SYS_getegid),
Expand All @@ -82,6 +87,7 @@ fn vuf_filter(action: SeccompAction) -> Result<SeccompFilter, Error> {
allow_syscall(libc::SYS_mremap),
allow_syscall(libc::SYS_munmap),
allow_syscall(libc::SYS_newfstatat),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_open),
allow_syscall(libc::SYS_openat),
allow_syscall(libc::SYS_prctl), // TODO restrict to just PR_SET_NAME?
Expand Down Expand Up @@ -109,9 +115,11 @@ fn vuf_filter(action: SeccompAction) -> Result<SeccompFilter, Error> {
allow_syscall(libc::SYS_sigaltstack),
allow_syscall(libc::SYS_statx),
allow_syscall(libc::SYS_symlinkat),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_time), // Rarely needed, except on static builds
allow_syscall(libc::SYS_tgkill),
allow_syscall(libc::SYS_umask),
#[cfg(target_arch = "x86_64")]
allow_syscall(libc::SYS_unlink),
allow_syscall(libc::SYS_unlinkat),
allow_syscall(libc::SYS_unshare),
Expand Down
Loading