From a650a7c27a1422540e508f15ea01e1b46b01d224 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 1 Oct 2025 13:35:53 +0100 Subject: [PATCH 1/7] vhost: fix undefined behavior in get_vring_base() By using ioctl_with_ref() instead of ioctl_with_mut_ref(), we attempted to mutate through an immutable reference, so rustc was well within its rights to assume that `vring_state` does not change across the ioctl call, and hence optimize the return value of the function to simply be the value that `vring_state.num` was initialized to (which is 0). Signed-off-by: Patrick Roy --- vhost/CHANGELOG.md | 2 ++ vhost/src/vhost_kern/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vhost/CHANGELOG.md b/vhost/CHANGELOG.md index 3eb54b88..02f12374 100644 --- a/vhost/CHANGELOG.md +++ b/vhost/CHANGELOG.md @@ -12,6 +12,8 @@ ### Deprecated ### Fixed - [[#304]](https://github.com/rust-vmm/vhost/pull/304) Fix building docs. +- [[#326]](https://github.com/rust-vmm/vhots/pull/326) Fix `get_vring_base()` returning 0 instead of + the vring base for vhost-kern backends when compiling in release mode. ## v0.14.0 diff --git a/vhost/src/vhost_kern/mod.rs b/vhost/src/vhost_kern/mod.rs index 4888c08d..a1f404f6 100644 --- a/vhost/src/vhost_kern/mod.rs +++ b/vhost/src/vhost_kern/mod.rs @@ -235,12 +235,12 @@ impl VhostBackend for T { /// Get a bitmask of supported virtio/vhost features. fn get_vring_base(&self, queue_index: usize) -> Result { - let vring_state = vhost_vring_state { + let mut vring_state = vhost_vring_state { index: queue_index as u32, num: 0, }; // SAFETY: This ioctl is called on a valid vhost fd and has its return value checked. - let ret = unsafe { ioctl_with_ref(self, VHOST_GET_VRING_BASE(), &vring_state) }; + let ret = unsafe { ioctl_with_mut_ref(self, VHOST_GET_VRING_BASE(), &mut vring_state) }; ioctl_result(ret, vring_state.num) } From ee8de6a7837888cf979e9791379983098901d4cb Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Thu, 2 Oct 2025 10:51:27 +0100 Subject: [PATCH 2/7] vhost: fix unused function warnings on some feature combos Signed-off-by: Patrick Roy --- vhost/src/vhost_user/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vhost/src/vhost_user/mod.rs b/vhost/src/vhost_user/mod.rs index 0ecb686e..f8d3384c 100644 --- a/vhost/src/vhost_user/mod.rs +++ b/vhost/src/vhost_user/mod.rs @@ -18,7 +18,6 @@ //! Most messages that can be sent via the Unix domain socket implementing vhost-user have an //! equivalent ioctl to the kernel implementation. -use std::fs::File; use std::io::Error as IOError; pub mod message; @@ -214,7 +213,8 @@ pub type HandlerResult = std::result::Result; /// Utility function to take the first element from option of a vector of files. /// Returns `None` if the vector contains no file or more than one file. -pub(crate) fn take_single_file(files: Option>) -> Option { +#[cfg(any(feature = "vhost-user-backend", feature = "vhost-user-frontend"))] +pub(crate) fn take_single_file(files: Option>) -> Option { let mut files = files?; if files.len() != 1 { return None; From 021606ef8cef5d3ba7fa85537449b6c0a50fdb6a Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 1 Oct 2025 12:09:46 +0100 Subject: [PATCH 3/7] chore: update rust-vmm-ci pick up the commit that introduces cargo-all-features. Signed-off-by: Patrick Roy --- rust-vmm-ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-vmm-ci b/rust-vmm-ci index c0f5d4c3..3e248353 160000 --- a/rust-vmm-ci +++ b/rust-vmm-ci @@ -1 +1 @@ -Subproject commit c0f5d4c3f58094c90ea12200f513b21e457983bd +Subproject commit 3e248353468a9aa0efa844d39eecf24e1dbdc3f3 From be29efb3ae6f3f806d5fbefc3fb8fff7eb1fb727 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 1 Oct 2025 12:10:26 +0100 Subject: [PATCH 4/7] configure cargo-all-features Set it up so that it does not try to combine the xen and postcopy features, and also ignore the test-only test_utils feature. Signed-off-by: Patrick Roy --- vhost-user-backend/Cargo.toml | 5 +++++ vhost/Cargo.toml | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/vhost-user-backend/Cargo.toml b/vhost-user-backend/Cargo.toml index 9e380a2d..df840c08 100644 --- a/vhost-user-backend/Cargo.toml +++ b/vhost-user-backend/Cargo.toml @@ -28,3 +28,8 @@ uuid = { version = "1.8.0", features=["v4"] } vhost = { path = "../vhost", version = "0.14.0", features = ["test-utils", "vhost-user-frontend", "vhost-user-backend"] } vm-memory = { workspace = true, features = ["backend-mmap", "backend-atomic"] } tempfile = "3.2.0" + +[package.metadata.cargo-all-features] +skip_feature_sets = [ + ["xen", "postcopy"] +] \ No newline at end of file diff --git a/vhost/Cargo.toml b/vhost/Cargo.toml index 355490a6..88a02c3e 100644 --- a/vhost/Cargo.toml +++ b/vhost/Cargo.toml @@ -37,3 +37,10 @@ vm-memory = { workspace = true, features=["backend-mmap"] } [dev-dependencies] tempfile = "3.2.0" serial_test = "3.0" + +[package.metadata.cargo-all-features] +skip_feature_sets = [ + ["xen", "postcopy"] +] + +denylist = ["test_utils"] From d3cfd784dbcc32606ed18a61fe1b7adfc28d39f6 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 1 Oct 2025 12:18:18 +0100 Subject: [PATCH 5/7] revert to using normal rust-vmm-ci tests Now that rust-vmm-ci uses cargo-all-features, we can deal with the incompatiblity of the xen and postcopy features by simply marking them as incompatible in Cargo.toml, instead of needing to define separate CI steps. note: this commit currently symlinks rust-vmm-ci-tests.json to rust-vmm-ci/.buildkite/test_descriptions.json, and removes all tests from custom-tests.json. This is to illustrate that the new setup works without changes to the buildkite pipeline. Once that is confirmed, the pipeline should be updated to just use the rust-vmm-ci test generaiton routine, and the entire .buildkite directory can be removed. Signed-off-by: Patrick Roy --- .buildkite/README.md | 18 ----- .buildkite/custom-tests.json | 21 ------ .buildkite/rust-vmm-ci-tests.json | 113 +----------------------------- 3 files changed, 1 insertion(+), 151 deletions(-) delete mode 100644 .buildkite/README.md mode change 100644 => 120000 .buildkite/rust-vmm-ci-tests.json diff --git a/.buildkite/README.md b/.buildkite/README.md deleted file mode 100644 index 2fba68d3..00000000 --- a/.buildkite/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# buildkite custom pipelines - -This folder contains the custom pipelines for this repository. - -If we add a new pipeline we need to enable it in -https://buildkite.com/rust-vmm/vhost-ci/steps - -Custom pipelines currently defined are: -- `custom-tests.json` - Custom tests to enable only certain features. - -- `rust-vmm-ci-tests.json` - This is based on `rust-vmm-ci/.buildkite/test_description.json`. - We can't run rust-vmm-ci tests because they enable all the features with - `--all-features` and our crates have features that may not be compatible with - others (e.g. `xen`). Waiting to solve this problem in rust-vmm-ci (see - https://github.com/rust-vmm/rust-vmm-ci/issues/152), we use a custom - pipeline based on that but that does not use `--all-features`. diff --git a/.buildkite/custom-tests.json b/.buildkite/custom-tests.json index 892cbb5b..573f53e2 100644 --- a/.buildkite/custom-tests.json +++ b/.buildkite/custom-tests.json @@ -1,25 +1,4 @@ { "tests": [ - { - "test_name": "build-vhost-kern", - "command": "cargo build --features=vhost-kern", - "platform": [ - "x86_64" - ] - }, - { - "test_name": "build-vhost-user-frontend", - "command": "cargo build --features=vhost-user-frontend", - "platform": [ - "x86_64" - ] - }, - { - "test_name": "build-vhost-user-backend", - "command": "cargo build --features=vhost-user-backend", - "platform": [ - "x86_64" - ] - } ] } diff --git a/.buildkite/rust-vmm-ci-tests.json b/.buildkite/rust-vmm-ci-tests.json deleted file mode 100644 index 630fc618..00000000 --- a/.buildkite/rust-vmm-ci-tests.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "tests": [ - { - "test_name": "build-gnu", - "command": "RUSTFLAGS=\"-D warnings\" cargo build --release", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "build-musl", - "command": "RUSTFLAGS=\"-D warnings\" cargo build --release --target {target_platform}-unknown-linux-musl", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "style", - "command": "cargo fmt --all -- --check --config format_code_in_doc_comments=true" - }, - { - "test_name": "unittests-gnu-all-with-xen", - "command": "cargo test --workspace --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,xen", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "unittests-gnu-all-without-xen", - "command": "cargo test --workspace --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,postcopy", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "unittests-musl-all-with-xen", - "command": "cargo test --workspace --target {target_platform}-unknown-linux-musl --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,xen", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "unittests-musl-all-without-xen", - "command": "cargo test --workspace --target {target_platform}-unknown-linux-musl --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,postcopy", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "clippy-all-with-xen", - "command": "cargo clippy --workspace --bins --examples --benches --all-targets --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,xen -- -D warnings -D clippy::undocumented_unsafe_blocks", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "clippy-all-without-xen", - "command": "cargo clippy --workspace --bins --examples --benches --all-targets --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,postcopy -- -D warnings -D clippy::undocumented_unsafe_blocks", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "check-warnings-all-with-xen", - "command": "RUSTFLAGS=\"-D warnings\" cargo check --all-targets --workspace --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,xen", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "check-warnings-all-without-xen", - "command": "RUSTFLAGS=\"-D warnings\" cargo check --all-targets --workspace --no-default-features --features test-utils,vhost-vsock,vhost-kern,vhost-vdpa,vhost-net,vhost-user,vhost-user-frontend,vhost-user-backend,postcopy", - "platform": [ - "x86_64", - "aarch64" - ] - }, - { - "test_name": "coverage", - "command": "pytest $(find . -type f -name \"test_coverage.py\")", - "docker_plugin": { - "privileged": true - }, - "platform": [ - "x86_64" - ] - }, - { - "test_name": "commit-format", - "command": "pytest $(find . -type f -name \"test_commit_format.py\")", - "docker_plugin": { - "propagate-environment": true - } - }, - { - "test_name": "cargo-audit", - "command": "[ -e Cargo.lock ] || cargo generate-lockfile; cargo audit -q --deny warnings", - "platform": [ - "x86_64" - ] - } - ] -} diff --git a/.buildkite/rust-vmm-ci-tests.json b/.buildkite/rust-vmm-ci-tests.json new file mode 120000 index 00000000..586acc34 --- /dev/null +++ b/.buildkite/rust-vmm-ci-tests.json @@ -0,0 +1 @@ +../rust-vmm-ci/.buildkite/test_description.json \ No newline at end of file From d900ee96a38818acf8c2fb37e5a6e12a5039e600 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 1 Oct 2025 14:32:43 +0100 Subject: [PATCH 6/7] fix cargo doc CI step Introduce a dummy feature to hack around `cargo doc --all-features` always hitting the compile_error!(...) in vhost/src/lib.rs about incompatible features. This is happening because when documenting vhost-user-backend, cargo does not pass --cfg doc to dependencies, meaning the cfg(not(doc)) attribute that is supposed to eliminate this compile_error!() invokation when building docs does not actually trigger. Hence cargo doc fails. Introduce a custom cfg, which we tell docs.rs to set during documentation build, which disables the compile_error!(). Our CI also sets this flag for the rustdoc step (via an ugly `sed` in the pipeline definition). This cfg is also set by rust-vmm-ci for the cargo doc step. Note that we need both cfg(not(doc)) and cfg(not(RUTSDOC_disable_feature_compat_errors)), because lib.rs gets processed twice, onces by rustc (where the --cfg is passed via RUSTFLAGS), and once by rustdoc itself, where RUSTFLAGS are ignored, and instead the cfg(doc) macro comes into play (but rustdoc is only ran on the crate for which we are actually generating docs, not the dependencies). Signed-off-by: Patrick Roy --- vhost-user-backend/Cargo.toml | 5 ++++- vhost-user-backend/src/lib.rs | 13 +++++++++---- vhost/Cargo.toml | 3 +++ vhost/src/lib.rs | 13 +++++++++---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/vhost-user-backend/Cargo.toml b/vhost-user-backend/Cargo.toml index df840c08..5a84fcd6 100644 --- a/vhost-user-backend/Cargo.toml +++ b/vhost-user-backend/Cargo.toml @@ -29,7 +29,10 @@ vhost = { path = "../vhost", version = "0.14.0", features = ["test-utils", "vhos vm-memory = { workspace = true, features = ["backend-mmap", "backend-atomic"] } tempfile = "3.2.0" +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(RUTSDOC_disable_feature_compat_errors)'] } + [package.metadata.cargo-all-features] skip_feature_sets = [ ["xen", "postcopy"] -] \ No newline at end of file +] diff --git a/vhost-user-backend/src/lib.rs b/vhost-user-backend/src/lib.rs index 7e1db9e4..5936e10a 100644 --- a/vhost-user-backend/src/lib.rs +++ b/vhost-user-backend/src/lib.rs @@ -36,10 +36,15 @@ pub use self::vring::{ VringMutex, VringRwLock, VringState, VringStateGuard, VringStateMutGuard, VringT, }; -/// Due to the way `xen` handles memory mappings we can not combine it with -/// `postcopy` feature which relies on persistent memory mappings. Thus we -/// disallow enabling both features at the same time. -#[cfg(all(feature = "postcopy", feature = "xen"))] +// Due to the way `xen` handles memory mappings we can not combine it with +// `postcopy` feature which relies on persistent memory mappings. Thus we +// disallow enabling both features at the same time. +#[cfg(all( + not(RUTSDOC_disable_feature_compat_errors), + not(doc), + feature = "postcopy", + feature = "xen" +))] compile_error!("Both `postcopy` and `xen` features can not be enabled at the same time."); /// An alias for `GuestMemoryAtomic>` to simplify code. diff --git a/vhost/Cargo.toml b/vhost/Cargo.toml index 88a02c3e..3a3add62 100644 --- a/vhost/Cargo.toml +++ b/vhost/Cargo.toml @@ -38,6 +38,9 @@ vm-memory = { workspace = true, features=["backend-mmap"] } tempfile = "3.2.0" serial_test = "3.0" +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(RUTSDOC_disable_feature_compat_errors)'] } + [package.metadata.cargo-all-features] skip_feature_sets = [ ["xen", "postcopy"] diff --git a/vhost/src/lib.rs b/vhost/src/lib.rs index 6a2c0e1a..d386a59c 100644 --- a/vhost/src/lib.rs +++ b/vhost/src/lib.rs @@ -51,10 +51,15 @@ pub mod vhost_user; #[cfg(feature = "vhost-vsock")] pub mod vsock; -/// Due to the way `xen` handles memory mappings we can not combine it with -/// `postcopy` feature which relies on persistent memory mappings. Thus we -/// disallow enabling both features at the same time. -#[cfg(all(not(doc), feature = "postcopy", feature = "xen"))] +// Due to the way `xen` handles memory mappings we can not combine it with +// `postcopy` feature which relies on persistent memory mappings. Thus we +// disallow enabling both features at the same time. +#[cfg(all( + not(RUTSDOC_disable_feature_compat_errors), + not(doc), + feature = "postcopy", + feature = "xen" +))] compile_error!("Both `postcopy` and `xen` features can not be enabled at the same time."); /// Error codes for vhost operations From 1f6aafb59470b2ef7496448020979d041dba7ec9 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Thu, 2 Oct 2025 10:24:54 +0100 Subject: [PATCH 7/7] fix documentation build on docs.rs Instruct the docs.rs documentation builder to pass --cfg RUTSDOC_disable_feature_compat_errors in RUSTFLAGS when building documentation, so that builds dont fail because of compile_error!() and incompatible features [1]. [1]: https://docs.rs/crate/vhost/0.14.0/builds/2193201 Signed-off-by: Patrick Roy --- vhost-user-backend/Cargo.toml | 4 ++++ vhost/Cargo.toml | 1 + 2 files changed, 5 insertions(+) diff --git a/vhost-user-backend/Cargo.toml b/vhost-user-backend/Cargo.toml index 5a84fcd6..bd00652a 100644 --- a/vhost-user-backend/Cargo.toml +++ b/vhost-user-backend/Cargo.toml @@ -8,6 +8,10 @@ repository = "https://github.com/rust-vmm/vhost" edition = "2021" license = "Apache-2.0" +[package.metadata.docs.rs] +all-features = true +rustc-args = ['--cfg RUTSDOC_disable_feature_compat_errors'] + [features] xen = ["vm-memory/xen", "vhost/xen"] postcopy = ["vhost/postcopy", "userfaultfd"] diff --git a/vhost/Cargo.toml b/vhost/Cargo.toml index 3a3add62..d35696f9 100644 --- a/vhost/Cargo.toml +++ b/vhost/Cargo.toml @@ -12,6 +12,7 @@ edition = "2021" [package.metadata.docs.rs] all-features = true +rustc-args = ['--cfg RUTSDOC_disable_feature_compat_errors'] [features] default = []