Compare commits

...

13 Commits
main ... v36.1

Author SHA1 Message Date
Bo Chen
d725400158 build: Release v36.1 (bug fix release)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-10 11:36:39 -08:00
Bo Chen
7026a08569 tests: Temporarily disable vhost_user_blk tests on aarch64
See: #5934

Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 62db13ba0e)
2024-01-10 09:09:15 -08:00
Michael Zhao
b6945b649a scripts: Workaround random wget failures on AArch64
Random failures of downloading `cloud-hypervisor-static-aarch64` with
`wget` were seen. The commit applies a workaround to retry the download
for a few times.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
(cherry picked from commit f0c5592ba1)
2024-01-10 09:09:15 -08:00
Ravi kumar Veeramally
4c0052f355 tests: Migrate docker container from ubuntu 20.04 to 22.04
The following tests have been temporarily disabled:

1. Live upgrade/migration test with ovs-dpdk (#5532);
2. Disk hotplug tests on windows guests (#6037);

This patch has been tested with PR #6048.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
Tested-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 24f384d239)
2024-01-10 09:09:15 -08:00
Bo Chen
758930bc65 virtio-devices: Fix beta clippy issue
error: use of a fallible conversion when an infallible one could be used
Error:    --> virtio-devices/src/vhost_user/vu_common_ctrl.rs:206:51
    |
206 |             let actual_size: usize = queue.size().try_into().unwrap();
    |                                                   ^^^^^^^^^^^^^^^^^^^ help: use: `into()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions
    = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`

error: could not compile `virtio-devices` (lib) due to previous error
Error: warning: build failed, waiting for other jobs to finish...
error: could not compile `virtio-devices` (lib test) due to previous error
Error: The process '/home/runner/.cargo/bin/cargo' failed with exit code 101

Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit d4a163dd39)
2024-01-10 09:09:15 -08:00
Yi Wang
7b46d06171 build: fix clippy ptr arg issue
CI reports errors:

error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> arch/src/x86_64/mod.rs:1351:19
     |
1351 |     epc_sections: &Vec<SgxEpcSection>,
     |                   ^^^^^^^^^^^^^^^^^^^ help: change this to: `&[SgxEpcSection]`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
     = note: `-D clippy::ptr-arg` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]`

Signed-off-by: Yi Wang <foxywang@tencent.com>
(cherry picked from commit 3d6594a594)
2024-01-10 09:09:15 -08:00
Yi Wang
e16b06f894 build: fix clippy Path::join issue
CI reports clippy errors:

error: argument to `Path::join` starts with a path separator
    --> tests/integration.rs:4076:58
     |
4076 |         let serial_socket = guest.tmp_dir.as_path().join("/tmp/serial.socket");
     |                                                          ^^^^^^^^^^^^^^^^^^^^
     |
     = note: joining a path starting with separator will replace the path instead
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths

Signed-off-by: Yi Wang <foxywang@tencent.com>
(cherry picked from commit ee2f0c3cb4)
2024-01-10 09:09:15 -08:00
Yi Wang
4e001e2ad5 build: fix clippy complex closures issue
CI reports clippy errors:

error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
   --> test_infra/src/lib.rs:93:51
    |
93  |           match (|| -> Result<(), WaitForBootError> {
    |  ___________________________________________________^
94  | |             let listener =
95  | |                 TcpListener::bind(listen_addr.as_str()).map_err(WaitForBootError::Listen)?;
96  | |             listener
...   |
145 | |             }
146 | |         })() {
    | |_________^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions
    = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`

Signed-off-by: Yi Wang <foxywang@tencent.com>
(cherry picked from commit 9c2d650cb8)
2024-01-10 09:09:15 -08:00
Bo Chen
e309ed0a38 test: Enable live-upgrade based on release v36.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-10 09:09:15 -08:00
Bo Chen
948e7ca61a vmm: tdx: Error out early for TD migration
Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit e64b66054e)
2024-01-10 09:09:15 -08:00
Rui Chang
920564b281 vmm: add add-user-device support in cloud-hypervisor.yaml
The change is missed when add "add-user-device" support in
53b2e19934, use this commit to fix it.

Signed-off-by: Rui Chang <rui.chang@arm.com>
(cherry picked from commit 2b457584e0)
2024-01-10 09:09:15 -08:00
Thomas Barrett
014c19e189 devices: fix pv_panic alignment
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
(cherry picked from commit 5f3ff3c44a)
2024-01-10 09:09:15 -08:00
Thomas Barrett
dbf4891eb2 block: fix aio backend behavior when writeback enabled
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
(cherry picked from commit d9ed281719)
2024-01-10 09:09:15 -08:00
18 changed files with 129 additions and 61 deletions

2
Cargo.lock generated
View File

@@ -427,7 +427,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]] [[package]]
name = "cloud-hypervisor" name = "cloud-hypervisor"
version = "36.0.0" version = "36.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"api_client", "api_client",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "cloud-hypervisor" name = "cloud-hypervisor"
version = "36.0.0" version = "36.1.0"
authors = ["The Cloud Hypervisor Authors"] authors = ["The Cloud Hypervisor Authors"]
edition = "2021" edition = "2021"
default-run = "cloud-hypervisor" default-run = "cloud-hypervisor"

View File

@@ -1311,7 +1311,7 @@ fn update_cpuid_topology(
// sections exposed to the guest. // sections exposed to the guest.
fn update_cpuid_sgx( fn update_cpuid_sgx(
cpuid: &mut Vec<CpuIdEntry>, cpuid: &mut Vec<CpuIdEntry>,
epc_sections: &Vec<SgxEpcSection>, epc_sections: &[SgxEpcSection],
) -> Result<(), Error> { ) -> Result<(), Error> {
// Something's wrong if there's no EPC section. // Something's wrong if there's no EPC section.
if epc_sections.is_empty() { if epc_sections.is_empty() {

View File

@@ -120,15 +120,20 @@ impl AsyncIo for RawFileAsyncAio {
} }
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> { fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
let iocbs = [&mut aio::IoControlBlock { if let Some(user_data) = user_data {
aio_fildes: self.fd.as_raw_fd() as u32, let iocbs = [&mut aio::IoControlBlock {
aio_lio_opcode: aio::IOCB_CMD_FSYNC as u16, aio_fildes: self.fd.as_raw_fd() as u32,
aio_data: user_data.unwrap_or(0), aio_lio_opcode: aio::IOCB_CMD_FSYNC as u16,
aio_flags: aio::IOCB_FLAG_RESFD, aio_data: user_data,
aio_resfd: self.eventfd.as_raw_fd() as u32, aio_flags: aio::IOCB_FLAG_RESFD,
..Default::default() aio_resfd: self.eventfd.as_raw_fd() as u32,
}]; ..Default::default()
let _ = self.ctx.submit(&iocbs[..]).map_err(AsyncIoError::Fsync)?; }];
let _ = self.ctx.submit(&iocbs[..]).map_err(AsyncIoError::Fsync)?;
} else {
// SAFETY: FFI call with a valid fd
unsafe { libc::fsync(self.fd) };
}
Ok(()) Ok(())
} }

View File

@@ -26,6 +26,7 @@ const PVPANIC_VENDOR_ID: u16 = 0x1b36;
const PVPANIC_DEVICE_ID: u16 = 0x0011; const PVPANIC_DEVICE_ID: u16 = 0x0011;
pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2; pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2;
pub const PVPANIC_DEVICE_MMIO_ALIGNMENT: u64 = 0x10;
const PVPANIC_PANICKED: u8 = 1 << 0; const PVPANIC_PANICKED: u8 = 1 << 0;
const PVPANIC_CRASH_LOADED: u8 = 1 << 1; const PVPANIC_CRASH_LOADED: u8 = 1 << 1;
@@ -192,7 +193,7 @@ impl PciDevice for PvPanicDevice {
let bar_addr = allocator let bar_addr = allocator
.lock() .lock()
.unwrap() .unwrap()
.allocate_mmio_hole_addresses(None, region_size, None) .allocate_mmio_hole_addresses(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?; .ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
let bar = PciBarConfiguration::default() let bar = PciBarConfiguration::default()

View File

@@ -1,3 +1,4 @@
- [v36.1](#v361)
- [v36.0](#v360) - [v36.0](#v360)
- [Command Line Changes](#command-line-changes) - [Command Line Changes](#command-line-changes)
- [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli) - [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli)
@@ -310,6 +311,16 @@
- [Unit testing](#unit-testing) - [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization) - [Integration tests parallelization](#integration-tests-parallelization)
# v36.1
This is a bug fix release. The following issues have been addressed:
* Fix aio backend behavior for block devices when writeback cache
disabled (#5930)
* Fix PvPanic device PCI BAR alignment (#5956)
* Bug fix to OpenAPI specification file (#5967)
* Error out early for live migration when TDX is enabled (#6025)
# v36.0 # v36.0
This release has been tracked in our [roadmap This release has been tracked in our [roadmap

View File

@@ -3,7 +3,7 @@
# When changing this file don't forget to update the tag name in the # When changing this file don't forget to update the tag name in the
# .github/workflows/docker-image.yaml file if doing multiple per day # .github/workflows/docker-image.yaml file if doing multiple per day
FROM ubuntu:20.04 as dev FROM ubuntu:22.04 as dev
ARG TARGETARCH ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.67.1" ARG RUST_TOOLCHAIN="1.67.1"
@@ -43,7 +43,6 @@ RUN apt-get update \
socat \ socat \
dosfstools \ dosfstools \
cpio \ cpio \
python \
python3 \ python3 \
python3-setuptools \ python3-setuptools \
ntfs-3g \ ntfs-3g \

View File

@@ -7,7 +7,7 @@
CLI_NAME="Cloud Hypervisor" CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor" CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
CTR_IMAGE_VERSION="20231012-0" CTR_IMAGE_VERSION="20231220-0"
: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}" : "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
DOCKER_RUNTIME="docker" DOCKER_RUNTIME="docker"
@@ -285,8 +285,7 @@ cmd_build() {
rustflags="$RUSTFLAGS" rustflags="$RUSTFLAGS"
target_cc="" target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="$rustflags -C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs" rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
target_cc="musl-gcc"
fi fi
$DOCKER_RUNTIME run \ $DOCKER_RUNTIME run \
@@ -399,8 +398,7 @@ cmd_tests() {
rustflags="$RUSTFLAGS" rustflags="$RUSTFLAGS"
target_cc="" target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="$rustflags -C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs" rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
target_cc="musl-gcc"
fi fi
if [[ "$unit" = true ]]; then if [[ "$unit" = true ]]; then

View File

@@ -20,7 +20,7 @@ build_spdk_nvme() {
sed -i "/grpcio/d" scripts/pkgdep/debian.sh sed -i "/grpcio/d" scripts/pkgdep/debian.sh
./scripts/pkgdep.sh ./scripts/pkgdep.sh
./configure --with-vfio-user ./configure --with-vfio-user
chmod +x /usr/local/lib/python3.8/dist-packages/ninja/data/bin/ninja chmod +x /usr/local/lib/python3.10/dist-packages/ninja/data/bin/ninja
make -j `nproc` || exit 1 make -j `nproc` || exit 1
touch .built touch .built
popd popd
@@ -30,7 +30,7 @@ build_spdk_nvme() {
fi fi
cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt
cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py
cp -r "$WORKLOADS_DIR/spdk/scripts/rpc" $SPDK_DEPLOY_DIR/rpc cp -r "$WORKLOADS_DIR/spdk/python/spdk/" $SPDK_DEPLOY_DIR/
cp -r "$WORKLOADS_DIR/spdk/python" $SPDK_DEPLOY_DIR/../ cp -r "$WORKLOADS_DIR/spdk/python" $SPDK_DEPLOY_DIR/../
} }
@@ -38,7 +38,7 @@ build_virtiofsd() {
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build" VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git" VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.1.0 "220405d7a2606c92636d31992b5cb3036a41047b" checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.8.0 "97ea7908fe7f9bc59916671a771bdcfaf4044b45"
if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then
pushd $VIRTIOFSD_DIR pushd $VIRTIOFSD_DIR
@@ -159,12 +159,25 @@ update_workloads() {
popd popd
# Download Cloud Hypervisor binary from its last stable release # Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v34.0" LAST_RELEASE_VERSION="v36.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64" CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64"
CH_RELEASE_NAME="cloud-hypervisor-static-aarch64" CH_RELEASE_NAME="cloud-hypervisor-static-aarch64"
pushd $WORKLOADS_DIR pushd $WORKLOADS_DIR
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1 # Repeat a few times to workaround a random wget failure
chmod +x $CH_RELEASE_NAME WGET_RETRY_MAX=10
wget_retry=0
until [ "$wget_retry" -ge "$WGET_RETRY_MAX" ]
do
time wget $CH_RELEASE_URL -O "$CH_RELEASE_NAME" && break
wget_retry=$((wget_retry+1))
done
if [ $wget_retry -ge "$WGET_RETRY_MAX" ]; then
exit 1
else
chmod +x $CH_RELEASE_NAME
fi
popd popd
# Build custom kernel for guest VMs # Build custom kernel for guest VMs

View File

@@ -44,7 +44,7 @@ fi
popd popd
# Download Cloud Hypervisor binary from its last stable release # Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v34.0" LAST_RELEASE_VERSION="v36.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static" CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static"
CH_RELEASE_NAME="cloud-hypervisor-static" CH_RELEASE_NAME="cloud-hypervisor-static"
pushd $WORKLOADS_DIR pushd $WORKLOADS_DIR

View File

@@ -122,7 +122,7 @@ if [ ! -f "$VIRTIOFSD" ]; then
pushd $WORKLOADS_DIR pushd $WORKLOADS_DIR
git clone "https://gitlab.com/virtio-fs/virtiofsd.git" $VIRTIOFSD_DIR git clone "https://gitlab.com/virtio-fs/virtiofsd.git" $VIRTIOFSD_DIR
pushd $VIRTIOFSD_DIR pushd $VIRTIOFSD_DIR
git checkout v1.1.0 git checkout v1.8.0
time cargo build --release time cargo build --release
cp target/release/virtiofsd $VIRTIOFSD || exit 1 cp target/release/virtiofsd $VIRTIOFSD || exit 1
popd popd

View File

@@ -90,7 +90,7 @@ impl GuestNetworkConfig {
None => DEFAULT_TCP_LISTENER_TIMEOUT, None => DEFAULT_TCP_LISTENER_TIMEOUT,
}; };
match (|| -> Result<(), WaitForBootError> { let mut closure = || -> Result<(), WaitForBootError> {
let listener = let listener =
TcpListener::bind(listen_addr.as_str()).map_err(WaitForBootError::Listen)?; TcpListener::bind(listen_addr.as_str()).map_err(WaitForBootError::Listen)?;
listener listener
@@ -143,7 +143,9 @@ impl GuestNetworkConfig {
Err(WaitForBootError::Accept(e)) Err(WaitForBootError::Accept(e))
} }
} }
})() { };
match closure() {
Err(e) => { Err(e) => {
let duration = start.elapsed(); let duration = start.elapsed();
eprintln!( eprintln!(
@@ -559,7 +561,7 @@ fn scp_to_guest_with_auth(
) -> Result<(), SshCommandError> { ) -> Result<(), SshCommandError> {
let mut counter = 0; let mut counter = 0;
loop { loop {
match (|| -> Result<(), SshCommandError> { let closure = || -> Result<(), SshCommandError> {
let tcp = let tcp =
TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?; TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?;
let mut sess = Session::new().unwrap(); let mut sess = Session::new().unwrap();
@@ -592,7 +594,9 @@ fn scp_to_guest_with_auth(
let _ = channel.wait_close(); let _ = channel.wait_close();
Ok(()) Ok(())
})() { };
match closure() {
Ok(_) => break, Ok(_) => break,
Err(e) => { Err(e) => {
counter += 1; counter += 1;
@@ -647,7 +651,7 @@ pub fn ssh_command_ip_with_auth(
let mut counter = 0; let mut counter = 0;
loop { loop {
match (|| -> Result<(), SshCommandError> { let mut closure = || -> Result<(), SshCommandError> {
let tcp = let tcp =
TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?; TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?;
let mut sess = Session::new().unwrap(); let mut sess = Session::new().unwrap();
@@ -676,7 +680,9 @@ pub fn ssh_command_ip_with_auth(
} else { } else {
Ok(()) Ok(())
} }
})() { };
match closure() {
Ok(_) => break, Ok(_) => break,
Err(e) => { Err(e) => {
counter += 1; counter += 1;

View File

@@ -3405,16 +3405,19 @@ mod common_parallel {
} }
#[test] #[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_default() { fn test_vhost_user_blk_default() {
test_vhost_user_blk(2, false, false, Some(&prepare_vubd)) test_vhost_user_blk(2, false, false, Some(&prepare_vubd))
} }
#[test] #[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_readonly() { fn test_vhost_user_blk_readonly() {
test_vhost_user_blk(1, true, false, Some(&prepare_vubd)) test_vhost_user_blk(1, true, false, Some(&prepare_vubd))
} }
#[test] #[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_direct() { fn test_vhost_user_blk_direct() {
test_vhost_user_blk(1, false, true, Some(&prepare_vubd)) test_vhost_user_blk(1, false, true, Some(&prepare_vubd))
} }
@@ -3929,7 +3932,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string()); let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal)); let guest = Guest::new(Box::new(focal));
let serial_path = guest.tmp_dir.as_path().join("/tmp/serial-output"); let serial_path = guest.tmp_dir.as_path().join("serial-output");
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
let console_str: &str = "console=ttyS0"; let console_str: &str = "console=ttyS0";
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
@@ -4042,8 +4045,8 @@ mod common_parallel {
fn test_serial_socket_interaction() { fn test_serial_socket_interaction() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string()); let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal)); let guest = Guest::new(Box::new(focal));
let serial_socket = guest.tmp_dir.as_path().join("/tmp/serial.socket"); let serial_socket = guest.tmp_dir.as_path().join("serial.socket");
let serial_socket_pty = guest.tmp_dir.as_path().join("/tmp/serial.pty"); let serial_socket_pty = guest.tmp_dir.as_path().join("serial.pty");
let serial_option = if cfg!(target_arch = "x86_64") { let serial_option = if cfg!(target_arch = "x86_64") {
" console=ttyS0" " console=ttyS0"
} else { } else {
@@ -4151,7 +4154,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string()); let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal)); let guest = Guest::new(Box::new(focal));
let console_path = guest.tmp_dir.as_path().join("/tmp/console-output"); let console_path = guest.tmp_dir.as_path().join("console-output");
let mut child = GuestCommand::new(&guest) let mut child = GuestCommand::new(&guest)
.args(["--cpus", "boot=1"]) .args(["--cpus", "boot=1"])
.args(["--memory", "size=512M"]) .args(["--memory", "size=512M"])
@@ -4212,8 +4215,8 @@ mod common_parallel {
fn test_vfio() { fn test_vfio() {
setup_vfio_network_interfaces(); setup_vfio_network_interfaces();
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string()); let jammy = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string());
let guest = Guest::new_from_ip_range(Box::new(focal), "172.18", 0); let guest = Guest::new_from_ip_range(Box::new(jammy), "172.18", 0);
let mut workload_path = dirs::home_dir().unwrap(); let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads"); workload_path.push("workloads");
@@ -7929,6 +7932,7 @@ mod windows {
} }
#[test] #[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))] #[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug() { fn test_windows_guest_disk_hotplug() {
@@ -8024,6 +8028,7 @@ mod windows {
} }
#[test] #[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))] #[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug_multi() { fn test_windows_guest_disk_hotplug_multi() {
@@ -9458,51 +9463,43 @@ mod live_migration {
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_basic() { fn test_live_upgrade_basic() {
_test_live_migration(true, false) _test_live_migration(true, false)
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_local() { fn test_live_upgrade_local() {
_test_live_migration(true, true) _test_live_migration(true, true)
} }
#[test] #[test]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_numa() { fn test_live_upgrade_numa() {
_test_live_migration_numa(true, false) _test_live_migration_numa(true, false)
} }
#[test] #[test]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_numa_local() { fn test_live_upgrade_numa_local() {
_test_live_migration_numa(true, true) _test_live_migration_numa(true, true)
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_watchdog() { fn test_live_upgrade_watchdog() {
_test_live_migration_watchdog(true, false) _test_live_migration_watchdog(true, false)
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_watchdog_local() { fn test_live_upgrade_watchdog_local() {
_test_live_migration_watchdog(true, true) _test_live_migration_watchdog(true, true)
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_balloon() { fn test_live_upgrade_balloon() {
_test_live_migration_balloon(true, false) _test_live_migration_balloon(true, false)
} }
#[test] #[test]
#[ignore = "See #5791"]
fn test_live_upgrade_balloon_local() { fn test_live_upgrade_balloon_local() {
_test_live_migration_balloon(true, true) _test_live_migration_balloon(true, true)
} }
@@ -9515,6 +9512,7 @@ mod live_migration {
// Require to run ovs-dpdk tests sequentially because they rely on the same ovs-dpdk setup // Require to run ovs-dpdk tests sequentially because they rely on the same ovs-dpdk setup
#[test] #[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
fn test_live_migration_ovs_dpdk() { fn test_live_migration_ovs_dpdk() {
@@ -9529,9 +9527,9 @@ mod live_migration {
} }
#[test] #[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_ovs_dpdk() { fn test_live_upgrade_ovs_dpdk() {
_test_live_migration_ovs_dpdk(true, false); _test_live_migration_ovs_dpdk(true, false);
} }
@@ -9539,7 +9537,6 @@ mod live_migration {
#[test] #[test]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))] #[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_ovs_dpdk_local() { fn test_live_upgrade_ovs_dpdk_local() {
_test_live_migration_ovs_dpdk(true, true); _test_live_migration_ovs_dpdk(true, true);
} }

View File

@@ -7,7 +7,6 @@ use crate::{
get_host_address_range, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VirtioInterrupt, get_host_address_range, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VirtioInterrupt,
VirtioInterruptType, VirtioInterruptType,
}; };
use std::convert::TryInto;
use std::ffi; use std::ffi;
use std::fs::File; use std::fs::File;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
@@ -201,7 +200,7 @@ impl VhostUserHandle {
let mut vrings_info = Vec::new(); let mut vrings_info = Vec::new();
for (queue_index, queue, queue_evt) in queues.iter() { for (queue_index, queue, queue_evt) in queues.iter() {
let actual_size: usize = queue.size().try_into().unwrap(); let actual_size: usize = queue.size().into();
let config_data = VringConfigData { let config_data = VringConfigData {
queue_max_size: queue.max_size(), queue_max_size: queue.max_size(),

View File

@@ -13,7 +13,7 @@ pub mod protocol;
/// Global VMM version for versioning /// Global VMM version for versioning
const MAJOR_VERSION: u16 = 36; const MAJOR_VERSION: u16 = 36;
const MINOR_VERSION: u16 = 0; const MINOR_VERSION: u16 = 1;
const VMM_VERSION: u16 = MAJOR_VERSION << 12 | MINOR_VERSION & 0b1111; const VMM_VERSION: u16 = MAJOR_VERSION << 12 | MINOR_VERSION & 0b1111;
pub trait VersionMapped { pub trait VersionMapped {

View File

@@ -347,6 +347,28 @@ paths:
500: 500:
description: The new vDPA device could not be added to the VM instance. description: The new vDPA device could not be added to the VM instance.
/vm.add-user-device:
put:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VmAddUserDevice'
description: The path of the new device
required: true
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"404":
description: The new device could not be added to the VM instance.
summary: Add a new userspace device to the VM
/vm.snapshot: /vm.snapshot:
put: put:
summary: Returns a VM snapshot. summary: Returns a VM snapshot.
@@ -1156,3 +1178,11 @@ components:
type: string type: string
local: local:
type: boolean type: boolean
VmAddUserDevice:
required:
- socket
type: object
properties:
socket:
type: string

View File

@@ -1664,7 +1664,12 @@ impl Vmm {
#[cfg(all(feature = "kvm", target_arch = "x86_64"))] #[cfg(all(feature = "kvm", target_arch = "x86_64"))]
let common_cpuid = { let common_cpuid = {
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
let tdx = vm_config.lock().unwrap().is_tdx_enabled(); if vm_config.lock().unwrap().is_tdx_enabled() {
return Err(MigratableError::MigrateSend(anyhow!(
"Live Migration is not supported when TDX is enabled"
)));
};
let amx = vm_config.lock().unwrap().cpus.features.amx; let amx = vm_config.lock().unwrap().cpus.features.amx;
let phys_bits = let phys_bits =
vm::physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits); vm::physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits);
@@ -1675,7 +1680,7 @@ impl Vmm {
phys_bits, phys_bits,
kvm_hyperv: vm_config.lock().unwrap().cpus.kvm_hyperv, kvm_hyperv: vm_config.lock().unwrap().cpus.kvm_hyperv,
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
tdx, tdx: false,
amx, amx,
}, },
) )
@@ -1854,6 +1859,13 @@ impl Vmm {
src_vm_config: &Arc<Mutex<VmConfig>>, src_vm_config: &Arc<Mutex<VmConfig>>,
src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry], src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry],
) -> result::Result<(), MigratableError> { ) -> result::Result<(), MigratableError> {
#[cfg(feature = "tdx")]
if src_vm_config.lock().unwrap().is_tdx_enabled() {
return Err(MigratableError::MigrateReceive(anyhow!(
"Live Migration is not supported when TDX is enabled"
)));
};
// We check the `CPUID` compatibility of between the source vm and destination, which is // We check the `CPUID` compatibility of between the source vm and destination, which is
// mostly about feature compatibility and "topology/sgx" leaves are not relevant. // mostly about feature compatibility and "topology/sgx" leaves are not relevant.
let dest_cpuid = &{ let dest_cpuid = &{
@@ -1867,7 +1879,7 @@ impl Vmm {
phys_bits, phys_bits,
kvm_hyperv: vm_config.cpus.kvm_hyperv, kvm_hyperv: vm_config.cpus.kvm_hyperv,
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
tdx: vm_config.is_tdx_enabled(), tdx: false,
amx: vm_config.cpus.features.amx, amx: vm_config.cpus.features.amx,
}, },
) )

View File

@@ -2390,12 +2390,9 @@ impl Snapshottable for Vm {
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> { fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
event!("vm", "snapshotting"); event!("vm", "snapshotting");
#[cfg(feature = "tdx")]
let tdx_enabled = self.config.lock().unwrap().is_tdx_enabled();
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
{ {
if tdx_enabled { if self.config.lock().unwrap().is_tdx_enabled() {
return Err(MigratableError::Snapshot(anyhow!( return Err(MigratableError::Snapshot(anyhow!(
"Snapshot not possible with TDX VM" "Snapshot not possible with TDX VM"
))); )));
@@ -2423,7 +2420,7 @@ impl Snapshottable for Vm {
phys_bits, phys_bits,
kvm_hyperv: self.config.lock().unwrap().cpus.kvm_hyperv, kvm_hyperv: self.config.lock().unwrap().cpus.kvm_hyperv,
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
tdx: tdx_enabled, tdx: false,
amx, amx,
}, },
) )