From 24062ed4db04dbb858b798024c930b549b4e104a Mon Sep 17 00:00:00 2001 From: Milan Zamazal Date: Mon, 30 Mar 2026 18:55:30 +0200 Subject: [PATCH 01/10] init: Set up a dummy network interface with TSI Some applications check for network availability by looking for a network device configured for Internet access. When TSI is used, there is no such device available by default, although Internet is accessible. Then those applications behave like when the connection is not available. Let's solve this problem by setting up a dummy network interface. The dummy interface is automatically created when CONFIG_DUMMY is enabled in kernel or the corresponding kernel module is loaded. This means a sufficiently recent libkrunfw version is needed (see https://github.com/containers/libkrunfw/pull/116). The dummy interface is initially down. In order to make the applications happy, the interface must be brought up and set up for Internet connections. This is ensured by setting the IP address to 10.0.0.1/8 (an arbitrary choice without any special reason) in init.c if TSI is enabled. The netmask is selected to be sane; it doesn't cover the whole IP range and we cannot set a default route because then TSI has problems, but it's OK for the tested application. We can change it if some application has trouble with that. TSI availability is determined by checking the presence of `tsi_hijack' in the kernel command line, before `--' delimiter if present. The dummy interface simply swallows all packets. But it is effectively bypassed by TSI for practical purposes. Things like ICMP don't work in either case. When the kernel support is not available, the device is not present and init.c cannot set it up. We skip the configuration silently in such a case, to not spam users with errors if they use older libkrunfw or custom kernels. Fixes: #576 Signed-off-by: Milan Zamazal (cherry picked from commit 2593accd9b57da23912d1824216bcc53866c838d) Signed-off-by: Sergio Lopez --- init/init.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/init/init.c b/init/init.c index b7696ab6f..9193bf8e1 100644 --- a/init/init.c +++ b/init/init.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -1179,6 +1180,109 @@ char *clone_str(const char *str) return strdup(str); } +#if __linux__ +static bool tsi_enabled() +{ + const char *const option = "tsi_hijack"; + bool enabled = false; + char *cmdline = NULL; + size_t cmdline_length = 0; + FILE *f; + const char *const delimiters = " \n"; + char *token; + + f = fopen("/proc/cmdline", "r"); + if (f == NULL) { + perror("fopen(/proc/cmdline)"); + return false; + } + + if (getline(&cmdline, &cmdline_length, f) < 0) { + perror("getline(/proc/cmdline)"); + fclose(f); + goto cleanup; + } + fclose(f); + + token = strtok(cmdline, delimiters); + while (token != NULL) { + if (strcmp(token, "--") == 0) { + break; + } + if (strcmp(token, option) == 0) { + enabled = true; + break; + } + token = strtok(NULL, delimiters); + } + +cleanup: + free(cmdline); + + return enabled; +} + +static int enable_dummy_interface() +{ + // See https://www.man7.org/linux/man-pages/man7/netdevice.7.html + + const char *const name = "dummy0"; + struct ifreq ifr; + int sockfd; + struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr; + struct sockaddr_in *netmask = (struct sockaddr_in *)&ifr.ifr_netmask; + int result = -1; + + if (snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name) >= IFNAMSIZ) { + printf("dummy interface name too long\n"); + return -1; + } + + sockfd = socket(PF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { + perror("dummy interface socket"); + return -1; + } + + ifr.ifr_flags = IFF_UP; + if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { + if (errno == ENODEV) { + // Most likely not enabled in the kernel, ignore quietly + result = 0; + goto close_socket; + } + perror("dummy interface up"); + goto close_socket; + } + + addr->sin_family = AF_INET; + if (inet_pton(AF_INET, "10.0.0.1", &addr->sin_addr) <= 0) { + printf("inet_pton address conversion failed\n"); + goto close_socket; + } + if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { + perror("dummy interface address"); + goto close_socket; + } + + netmask->sin_family = AF_INET; + if (inet_pton(AF_INET, "255.0.0.0", &netmask->sin_addr) <= 0) { + printf("inet_pton netmask conversion failed\n"); + goto close_socket; + } + if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { + perror("dummy interface mask"); + goto close_socket; + } + + result = 0; + +close_socket: + close(sockfd); + return result; +} +#endif + int main(int argc, char **argv) { struct ifreq ifr; @@ -1328,6 +1432,14 @@ int main(int argc, char **argv) close(sockfd); } +#if __linux__ + if (tsi_enabled()) { + if (enable_dummy_interface() < 0) { + printf("Warning: Couldn't enable dummy interface\n"); + } + } +#endif + config_argv = NULL; config_workdir = NULL; From 352a1ad1c11a9a83e0806b6416a8eb3a23aeb205 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Sun, 26 Apr 2026 08:21:11 +0200 Subject: [PATCH 02/10] Bump libspa to v0.9 Fixes #650. Signed-off-by: Sven-Hendrik Haase (cherry picked from commit e12b9b3780ffa8df9f3e1797b217d13453479167) Signed-off-by: Sergio Lopez --- Cargo.lock | 285 ++++-------------- src/devices/Cargo.toml | 2 +- .../src/virtio/snd/audio_backends/pipewire.rs | 22 +- 3 files changed, 77 insertions(+), 232 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a39aca285..e2c7a049c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,12 +25,12 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "annotate-snippets" -version = "0.9.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" dependencies = [ + "anstyle", "unicode-width", - "yansi-term", ] [[package]] @@ -131,41 +131,21 @@ dependencies = [ "virtue", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "annotate-snippets", - "bitflags 2.11.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", -] - [[package]] name = "bindgen" version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ + "annotate-snippets", "bitflags 2.11.0", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools", "proc-macro2", "quote", "regex", - "rustc-hash 2.1.1", + "rustc-hash", "shlex", "syn", ] @@ -263,14 +243,14 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom", + "nom 7.1.3", ] [[package]] name = "cfg-expr" -version = "0.15.8" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368" dependencies = [ "smallvec", "target-lexicon", @@ -307,9 +287,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "convert_case" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" dependencies = [ "unicode-segmentation", ] @@ -319,9 +299,6 @@ name = "cookie-factory" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" -dependencies = [ - "futures", -] [[package]] name = "cpufeatures" @@ -454,94 +431,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" -[[package]] -name = "futures" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -629,15 +518,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -789,7 +669,7 @@ dependencies = [ name = "krun-display" version = "0.1.0" dependencies = [ - "bindgen 0.72.1", + "bindgen", "bitflags 2.11.0", "log", "static_assertions", @@ -810,7 +690,7 @@ dependencies = [ name = "krun-input" version = "0.1.0" dependencies = [ - "bindgen 0.72.1", + "bindgen", "bitflags 2.11.0", "libc", "log", @@ -927,18 +807,6 @@ dependencies = [ "vmm-sys-util 0.14.0", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.183" @@ -994,9 +862,9 @@ dependencies = [ [[package]] name = "libspa" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f3a4b81b2a2d8c7f300643676202debd1b7c929dbf5c9bb89402ea11d19810" +checksum = "b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4" dependencies = [ "bitflags 2.11.0", "cc", @@ -1004,18 +872,18 @@ dependencies = [ "cookie-factory", "libc", "libspa-sys", - "nix 0.27.1", - "nom", + "nix 0.30.1", + "nom 8.0.0", "system-deps", ] [[package]] name = "libspa-sys" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0d9716420364790e85cbb9d3ac2c950bde16a7dd36f3209b7dfdfc4a24d01f" +checksum = "901049455d2eb6decf9058235d745237952f4804bc584c5fcb41412e6adcc6e0" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", "system-deps", ] @@ -1128,17 +996,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.11.0", - "cfg-if", - "libc", -] - [[package]] name = "nix" version = "0.30.1" @@ -1175,6 +1032,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1211,28 +1077,28 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pipewire" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08e645ba5c45109106d56610b3ee60eb13a6f2beb8b74f8dc8186cf261788dda" +checksum = "9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44" dependencies = [ "anyhow", "bitflags 2.11.0", "libc", "libspa", "libspa-sys", - "nix 0.27.1", + "nix 0.30.1", "once_cell", "pipewire-sys", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] name = "pipewire-sys" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "849e188f90b1dda88fe2bfe1ad31fe5f158af2c98f80fb5d13726c44f3f01112" +checksum = "cb028afee0d6ca17020b090e3b8fa2d7de23305aef975c7e5192a5050246ea36" dependencies = [ - "bindgen 0.69.5", + "bindgen", "libspa-sys", "system-deps", ] @@ -1375,12 +1241,6 @@ dependencies = [ "syn", ] -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -1466,11 +1326,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -1516,12 +1376,6 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "sm3" version = "0.4.2" @@ -1577,9 +1431,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.2.2" +version = "7.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" dependencies = [ "cfg-expr", "heck", @@ -1601,9 +1455,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "tdx" @@ -1671,38 +1525,43 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ - "serde", + "serde_core", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_parser" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", "winnow", ] +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -1754,9 +1613,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unty" @@ -1944,12 +1803,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.15" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] +checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" [[package]] name = "wit-bindgen" @@ -1967,15 +1823,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "yansi-term" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" -dependencies = [ - "winapi", -] - [[package]] name = "zerocopy" version = "0.8.47" diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index 91b5e6953..0aeb82dc7 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -29,7 +29,7 @@ libc = ">=0.2.39" libloading = "0.8" log = "0.4.0" nix = { version = "0.30.1", features = ["ioctl", "net", "poll", "socket", "fs"] } -pw = { package = "pipewire", version = "0.8.0", optional = true } +pw = { package = "pipewire", version = "0.9.2", optional = true } rand = "0.9.2" thiserror = { version = "2.0", optional = true } virtio-bindings = "0.2.0" diff --git a/src/devices/src/virtio/snd/audio_backends/pipewire.rs b/src/devices/src/virtio/snd/audio_backends/pipewire.rs index cd9945085..89415b2fb 100644 --- a/src/devices/src/virtio/snd/audio_backends/pipewire.rs +++ b/src/devices/src/virtio/snd/audio_backends/pipewire.rs @@ -11,8 +11,8 @@ use std::{ use log::debug; use pw::{ - context::Context, core::Core, properties::properties, spa, sys::PW_ID_CORE, - thread_loop::ThreadLoop, + context::ContextRc, core::CoreRc, properties::properties, spa, sys::PW_ID_CORE, + thread_loop::ThreadLoopRc, }; use spa::{ param::{ @@ -74,27 +74,25 @@ unsafe impl Sync for PwBackend {} #[allow(clippy::non_send_fields_in_send_ty)] pub struct PwBackend { pub stream_params: Arc>>, - thread_loop: ThreadLoop, - pub core: Core, + thread_loop: ThreadLoopRc, + pub core: CoreRc, #[allow(dead_code)] - context: Context, - pub stream_hash: RwLock>, + context: ContextRc, + pub stream_hash: RwLock>, pub stream_listener: RwLock>>, } impl PwBackend { pub fn new(stream_params: Arc>>) -> Self { - pw::init(); - // SAFETY: safe as the thread loop cannot access objects associated // with the loop while the lock is held - let thread_loop = unsafe { ThreadLoop::new(Some("Pipewire thread loop"), None).unwrap() }; + let thread_loop = unsafe { ThreadLoopRc::new(Some("Pipewire thread loop"), None).unwrap() }; let lock_guard = thread_loop.lock(); - let context = Context::new(&thread_loop).expect("failed to create context"); + let context = ContextRc::new(&thread_loop, None).expect("failed to create context"); thread_loop.start(); - let core = context.connect(None).expect("Failed to connect to core"); + let core = context.connect_rc(None).expect("Failed to connect to core"); // Create new reference for the variable so that it can be moved into the // closure. @@ -341,7 +339,7 @@ impl AudioBackend for PwBackend { *pw::keys::MEDIA_CATEGORY => media_category, }; - let stream = pw::stream::Stream::new(&self.core, stream_name, props) + let stream = pw::stream::StreamRc::new(self.core.clone(), stream_name, props) .expect("could not create new stream"); let streams = self.stream_params.clone(); From a1e22b2a707973b6cdb41157bc24c5e3a652087f Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Wed, 29 Apr 2026 12:47:08 +0200 Subject: [PATCH 03/10] virtio/vsock: use device's peer_buf_alloc In commit c0e42fb0e0 ("vsock/virtio: cap TX credit to local buffer size") the kernel stopped honoring our peer_buf_alloc value, capping it to its own. Use the kernel's peer_buf_alloc instead of CONN_TX_BUF_SIZE as a hint of when we need to send a credit update. Signed-off-by: Sergio Lopez (cherry picked from commit 4b5b451e6b169b63210d85986ca5446eaaa6b569) Signed-off-by: Sergio Lopez --- src/devices/src/virtio/vsock/tsi_stream.rs | 4 +--- src/devices/src/virtio/vsock/unix.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/devices/src/virtio/vsock/tsi_stream.rs b/src/devices/src/virtio/vsock/tsi_stream.rs index a9cfa82d8..c819398d3 100644 --- a/src/devices/src/virtio/vsock/tsi_stream.rs +++ b/src/devices/src/virtio/vsock/tsi_stream.rs @@ -613,9 +613,7 @@ impl Proxy for TsiStreamProxy { -libc::EINVAL }; - if ret > 0 - && (self.tx_cnt - self.last_tx_cnt_sent).0 as usize >= (defs::CONN_TX_BUF_SIZE / 2) - { + if ret > 0 && (self.tx_cnt - self.last_tx_cnt_sent).0 >= self.peer_buf_alloc / 2 { debug!( "sending credit update: id={}, tx_cnt={}, last_tx_cnt={}", self.id, self.tx_cnt, self.last_tx_cnt_sent diff --git a/src/devices/src/virtio/vsock/unix.rs b/src/devices/src/virtio/vsock/unix.rs index 88bf89931..2f51c05fa 100644 --- a/src/devices/src/virtio/vsock/unix.rs +++ b/src/devices/src/virtio/vsock/unix.rs @@ -418,9 +418,7 @@ impl Proxy for UnixProxy { -libc::EINVAL }; - if ret > 0 - && (self.tx_cnt - self.last_tx_cnt_sent).0 as usize >= (defs::CONN_TX_BUF_SIZE / 2) - { + if ret > 0 && (self.tx_cnt - self.last_tx_cnt_sent).0 >= self.peer_buf_alloc / 2 { debug!( "sending credit update: id={}, tx_cnt={}, last_tx_cnt={}", self.id, self.tx_cnt, self.last_tx_cnt_sent From 6b6d60ed49c2ac74380bd681c51ba6ba48076b37 Mon Sep 17 00:00:00 2001 From: Matej Hrica Date: Wed, 26 Nov 2025 14:43:23 +0100 Subject: [PATCH 04/10] vsock/tsi_dgram: Make sendto_addr bind to correct socket adress structs We need to bind to the correct socket types (IPv6, Unix) instead of only IPv4. This fixes UDP and unix dgram tests hanging when waiting for reply. Reported-by: Jan Noha Signed-off-by: Matej Hrica (cherry picked from commit 4380b32b57001bda78f51ccbf1f81fc4e27eed48) Signed-off-by: Sergio Lopez --- src/devices/src/virtio/vsock/tsi_dgram.rs | 26 +++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/devices/src/virtio/vsock/tsi_dgram.rs b/src/devices/src/virtio/vsock/tsi_dgram.rs index 896f539b8..de0850c37 100644 --- a/src/devices/src/virtio/vsock/tsi_dgram.rs +++ b/src/devices/src/virtio/vsock/tsi_dgram.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; -use std::net::{Ipv4Addr, SocketAddrV4}; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; use std::num::Wrapping; use std::os::fd::OwnedFd; use std::os::unix::io::{AsRawFd, RawFd}; use std::sync::{Arc, Mutex}; use nix::fcntl::{fcntl, FcntlArg, OFlag}; +#[cfg(target_os = "linux")] +use nix::sys::socket::UnixAddr; use nix::sys::socket::{ bind, connect, getpeername, recv, send, sendto, socket, AddressFamily, MsgFlags, SockFlag, SockType, SockaddrIn, SockaddrLike, SockaddrStorage, @@ -35,6 +37,7 @@ pub struct TsiDgramProxy { pub status: ProxyStatus, sendto_addr: Option, listening: bool, + family: AddressFamily, mem: GuestMemoryMmap, queue: Arc>, rxq: Arc>, @@ -102,6 +105,7 @@ impl TsiDgramProxy { status: ProxyStatus::Idle, sendto_addr: None, listening: false, + family, mem, queue, rxq, @@ -339,7 +343,25 @@ impl Proxy for TsiDgramProxy { self.sendto_addr = Some(req.addr); if !self.listening { - match bind(self.fd.as_raw_fd(), &SockaddrIn::new(0, 0, 0, 0, 0)) { + let bind_result = match self.family { + AddressFamily::Inet => bind(self.fd.as_raw_fd(), &SockaddrIn::new(0, 0, 0, 0, 0)), + AddressFamily::Inet6 => { + let addr6: SockaddrStorage = + SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0).into(); + bind(self.fd.as_raw_fd(), &addr6) + } + #[cfg(target_os = "linux")] + AddressFamily::Unix => { + let addr = UnixAddr::new_unnamed(); + bind(self.fd.as_raw_fd(), &addr) + } + _ => { + warn!("sendto_addr: unsupported address family: {:?}", self.family); + return update; + } + }; + + match bind_result { Ok(_) => { self.listening = true; update.polling = Some((self.id, self.fd.as_raw_fd(), EventSet::IN)); From fa962c341b2ecfdb10dcd631d5d4c2301ed39e06 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 5 May 2026 10:46:52 -0500 Subject: [PATCH 05/10] rutabaga_gfx/cross_domain: handle CMD_WRITE on Eventfd items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cross_domain `write` handler only matched `CrossDomainItem::WaylandWritePipe`, falling into the catch-all for every other item type after the unconditional `remove()` at the top of the function had already dropped the entry from the table. PipeWire (and other clients that share host-created eventfds via SCM_RIGHTS for per-period wakeups) sends CMD_WRITE on those eventfd identifiers — the first such write returns InvalidCrossDomainItemType *after* removing the item, and every subsequent write on the same identifier returns InvalidCrossDomainItemId, masquerading on the guest as the opaque VIRTIO_GPU_RESP_ERR_UNSPEC (0x1200). Reproduced inside a libkrun guest on x86_64 by routing PipeWire's ALSA-shim audio through a host PipeWire daemon. With a paired BT speaker as the sink, `speaker-test -D pipewire -c2 -t wav -l 1` produces, per stream, ~10 entries of: [ 0.682819] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.723762] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.767615] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.807779] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.852469] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.896552] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.936504] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 0.980567] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 1.024476] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) [ 1.064636] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207) with audio still playing — PipeWire has socket-based fallback timing that doesn't depend on eventfd ack, so the failures are cosmetic for playback. They are not cosmetic for clients that strictly require the eventfd handshake (PipeWire's ALSA shim under heavier loads, and the buffer-pool wakeup path used by V4L2 capture streams). Add an Eventfd arm that mirrors the WaylandWritePipe semantics: `write_volatile` performs the 8-byte counter increment, and the item is re-inserted into the table unless the guest signaled `hang_up`. Verified post-fix: zero CMD_WRITE failures, zero `0x1200` entries in guest dmesg, audio playback unchanged. Camera capture (gst-launch pipewiresrc → MJPEG) also exercises this path for buffer-pool wakeups and runs cleanly with valid 98%-non-zero JPEG frames. Signed-off-by: Adam Ford (cherry picked from commit 5835d529ca6c892247d1637772590a46a764c27e) Signed-off-by: Sergio Lopez --- src/rutabaga_gfx/src/cross_domain/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/rutabaga_gfx/src/cross_domain/mod.rs b/src/rutabaga_gfx/src/cross_domain/mod.rs index 5a36f081e..81d7b71c7 100644 --- a/src/rutabaga_gfx/src/cross_domain/mod.rs +++ b/src/rutabaga_gfx/src/cross_domain/mod.rs @@ -991,6 +991,28 @@ impl CrossDomainContext { Ok(()) } + // Handle writes to Eventfd items. PipeWire (and other clients + // that pass eventfds via SCM_RIGHTS) uses these for per-period + // wakeups: an 8-byte write to the eventfd's counter signals + // the host. Without this arm, the first such write hits the + // catch-all below, returning InvalidCrossDomainItemType after + // the unconditional remove() above has already dropped the + // item — leaving every subsequent write to the same id + // failing with InvalidCrossDomainItemId. Mirrors the + // WaylandWritePipe re-insert semantics on hang_up == 0. + CrossDomainItem::Eventfd(file) => { + if len != 0 { + write_volatile(&file, opaque_data)?; + } + + if cmd_write.hang_up == 0 { + items + .table + .insert(cmd_write.identifier, CrossDomainItem::Eventfd(file)); + } + + Ok(()) + } _ => Err(RutabagaError::InvalidCrossDomainItemType), } } From cc069edeeee0562ecd1a30031662462933979f7c Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Wed, 13 May 2026 20:01:04 +0000 Subject: [PATCH 06/10] init: fix unescape_string() not advancing past escape characters The unescape_string() function in init.c, which handles JSON escape sequences when parsing environment variables from .krun_config.json, had a bug where the pointer 'val' was not advanced past the escape character after processing it. When encountering a two-character JSON escape sequence like \n or \", the switch statement pre-increments val to point at the escape character (e.g., 'n' or '"') and writes the unescaped byte to the output. However, it never advances val past that character. On the next loop iteration, the character is not a backslash, so it gets copied again as a literal character. This causes: - \n (JSON-escaped newline) to produce a newline followed by a literal 'n' - \" (JSON-escaped double quote) to produce two double quotes For example, an environment variable set to a JSON string like: {\"key\": \"value\"} would be rendered inside the krun VM as: {""key"": ""value""} Fix this by adding val++ after writing the unescaped character in each case of the switch statement. The 'u' (unicode) case already handles its own pointer arithmetic and is not affected. Fixes: https://github.com/containers/libkrun/issues/678 Assisted-by: Signed-off-by: Dusty Mabe (cherry picked from commit 60fe4f67e5e22c88fcdad284f97011e92db7aae6) Signed-off-by: Sergio Lopez --- init/init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/init/init.c b/init/init.c index 9193bf8e1..929c59814 100644 --- a/init/init.c +++ b/init/init.c @@ -641,27 +641,35 @@ static void unescape_string(char *string, int len) switch (*++val) { case 'n': string[i++] = '\n'; + val++; break; case 't': string[i++] = '\t'; + val++; break; case 'r': string[i++] = '\r'; + val++; break; case 'b': string[i++] = '\b'; + val++; break; case 'f': string[i++] = '\f'; + val++; break; case '\\': string[i++] = '\\'; + val++; break; case '\"': string[i++] = '\"'; + val++; break; case '/': string[i++] = '/'; + val++; break; case 'u': { const char *unescaped = "?"; From a3974b35fcb07a2a0326e82646e602b9f69b6c32 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Sat, 2 May 2026 14:34:55 +0200 Subject: [PATCH 07/10] add musl cfg flag musl_v1_2_3 to enable statx building using musl fails with: error[E0412]: cannot find type `statx` in crate `libc` --> src/devices/src/virtio/fs/linux/passthrough.rs:187:39 musl_v1_2_3 allows builds targeting musl 1.2.3 or newer to use statx rust-lang/libc/src/unix/linux_like/mod.rs#L264-L269: cfg_if! { if #[cfg(any( target_env = "gnu", target_os = "android", all(target_env = "musl", musl_v1_2_3) ))] { fixes: #431 Signed-off-by: Pepper Gray (cherry picked from commit c9c92e3d8bbd799b15065c2e15ff23dedb7b8fec) Signed-off-by: Sergio Lopez --- .cargo/config.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index ad32b48a4..f874a5e58 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ [target.aarch64-apple-darwin] runner = ".cargo/macos-test-runner.sh" + +[target.'cfg(target_env = "musl")'] +rustflags = ["--cfg", "musl_v1_2_3"] \ No newline at end of file From d8f4b2b73f6f48b8dfdc1a905c1bf1f2a079fce4 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Thu, 7 May 2026 11:13:41 -0500 Subject: [PATCH 08/10] rutabaga_gfx/cross_domain: fix audio glitches by dropping write lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous write() held item_state.lock() across the write_volatile call that performs the actual syscall, serializing every cross-domain CMD_WRITE behind any other operation on the items table — including add_item from process_receive, which fires for every new fd received via SCM_RIGHTS as guests open additional channels. For per-period eventfd wakeups (e.g. PipeWire audio streams signaling host playback every audio period), this means the write completes only after any in-flight item_state operation finishes. Under stream-create churn — many guest applications opening streams concurrently, each delivering new fds via SCM_RIGHTS that hit add_item under the same lock — the wait can exceed the audio period budget and produce missed-deadline glitches at the host's audio output. This change shrinks the critical section to a brief fd dup() under the lock, performs the syscall lock-free, and only re-acquires the lock if hang_up indicates the item should be removed. In the common case (hang_up == 0, e.g. repeated eventfd wakeups for an active stream) the table is no longer touched per write, eliminating both the contention and the previous "remove + conditional re-insert" churn. Behavioral changes vs the old code: - Common case (hang_up == 0): item stays in the table; we hand out a dup'd fd for the write. Net behavior identical, lock hold time bounded by dup(). - hang_up == 1: item removed in a separate phase after the write, instead of "removed unconditionally then re-inserted on hang_up == 0". Same observed end state. - Concurrent writes to the same id (no longer serialized): the kernel guarantees atomicity for eventfd writes (8 bytes) and pipe writes <= PIPE_BUF, which are the only two CrossDomainItem variants this branch handles. Each caller dup's its own fd and writes through it independently. Verified with a synthetic reproducer: a sustained 1 kHz sine playing through a guest PipeWire stream while ~200 short-lived guest streams open and close concurrently (each issuing SCM_RIGHTS for new eventfds, contending with the sustained stream's per-period writes for item_state). Capturing the host sink monitor and counting sample-to-sample deltas exceeding a clean-sine threshold, the stress workload produced ~10 distinct glitch bursts in an 8-second capture before this change, and zero across five consecutive runs after. Signed-off-by: Adam Ford (cherry picked from commit d9041439eaf2932337348e5616ae1f6631e7d620) Signed-off-by: Sergio Lopez --- src/rutabaga_gfx/src/cross_domain/mod.rs | 77 +++++++++++------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/src/rutabaga_gfx/src/cross_domain/mod.rs b/src/rutabaga_gfx/src/cross_domain/mod.rs index 81d7b71c7..72ffd4742 100644 --- a/src/rutabaga_gfx/src/cross_domain/mod.rs +++ b/src/rutabaga_gfx/src/cross_domain/mod.rs @@ -965,56 +965,47 @@ impl CrossDomainContext { } fn write(&self, cmd_write: &CrossDomainReadWrite, opaque_data: &[u8]) -> RutabagaResult<()> { - let mut items = self.item_state.lock().unwrap(); - - // Most of the time, hang-up and writing will be paired. In lieu of this, remove the - // item rather than getting a reference. In case of an error, there's not much to do - // besides reporting it. - let item = items - .table - .remove(&cmd_write.identifier) - .ok_or(RutabagaError::InvalidCrossDomainItemId)?; - let len: usize = cmd_write.opaque_data_size.try_into()?; - match item { - CrossDomainItem::WaylandWritePipe(file) => { - if len != 0 { - write_volatile(&file, opaque_data)?; - } - if cmd_write.hang_up == 0 { - items.table.insert( - cmd_write.identifier, - CrossDomainItem::WaylandWritePipe(file), - ); + // Phase 1 (under lock): look up the item and dup() its fd. We release + // the lock before the actual write syscall so unrelated operations on + // item_state aren't serialized behind it. The previous design held + // the lock across write_volatile, which was the dominant contention + // source for per-period eventfd writes from active audio streams + // competing with concurrent stream-create churn (process_receive's + // add_item path also takes this lock). Cloning the fd is a cheap + // dup() syscall; the actual write — which can be longer for pipe + // writes, and rate-limited for eventfds — happens lock-free. + let fd = { + let items = self.item_state.lock().unwrap(); + let item = items + .table + .get(&cmd_write.identifier) + .ok_or(RutabagaError::InvalidCrossDomainItemId)?; + match item { + CrossDomainItem::WaylandWritePipe(file) | CrossDomainItem::Eventfd(file) => { + file.try_clone()? } - - Ok(()) + _ => return Err(RutabagaError::InvalidCrossDomainItemType), } - // Handle writes to Eventfd items. PipeWire (and other clients - // that pass eventfds via SCM_RIGHTS) uses these for per-period - // wakeups: an 8-byte write to the eventfd's counter signals - // the host. Without this arm, the first such write hits the - // catch-all below, returning InvalidCrossDomainItemType after - // the unconditional remove() above has already dropped the - // item — leaving every subsequent write to the same id - // failing with InvalidCrossDomainItemId. Mirrors the - // WaylandWritePipe re-insert semantics on hang_up == 0. - CrossDomainItem::Eventfd(file) => { - if len != 0 { - write_volatile(&file, opaque_data)?; - } + }; - if cmd_write.hang_up == 0 { - items - .table - .insert(cmd_write.identifier, CrossDomainItem::Eventfd(file)); - } + // Phase 2 (lock-free): do the actual write. + if len != 0 { + write_volatile(&fd, opaque_data)?; + } - Ok(()) - } - _ => Err(RutabagaError::InvalidCrossDomainItemType), + // Phase 3 (under lock): on hang_up, drop the item from the table. + // Without hang_up the item stays — common for Eventfd repeated wakeups + // and for any pipe being held open for further writes. This matches + // the previous "remove + conditional re-insert" behavior, but in the + // common (hang_up == 0) case avoids touching the table at all. + if cmd_write.hang_up != 0 { + let mut items = self.item_state.lock().unwrap(); + items.table.remove(&cmd_write.identifier); } + + Ok(()) } fn process_cmd_send( From c6764af4ffee6f050db27bf62876c91f6d1f7b89 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Thu, 14 May 2026 11:43:13 +0000 Subject: [PATCH 09/10] devices/vsock: support multi-descriptor TX chains from_tx_virtq_head assumed a fixed 2-descriptor layout (header + one data descriptor), which breaks with newer kernels that may combine header and data in a single descriptor (Linux 6.2+) or split data across multiple descriptors. Handle three cases: single combined descriptor (zero-copy), classic two-descriptor (zero-copy, unchanged), and multi-descriptor data (copied into an owned contiguous buffer). The RX path already handled the combined case; this brings the TX path to parity and beyond. Assisted-by: Claude Code:claude-opus-4.6 Signed-off-by: Sergio Lopez (cherry picked from commit 0ecf4d5f791afcc7c964e3f4f729f77ee00761c0) Signed-off-by: Sergio Lopez --- src/devices/src/virtio/vsock/packet.rs | 127 ++++++++++++++++++++----- 1 file changed, 103 insertions(+), 24 deletions(-) diff --git a/src/devices/src/virtio/vsock/packet.rs b/src/devices/src/virtio/vsock/packet.rs index 9d1349cab..51b3cf1b2 100644 --- a/src/devices/src/virtio/vsock/packet.rs +++ b/src/devices/src/virtio/vsock/packet.rs @@ -191,6 +191,7 @@ pub struct VsockPacket { hdr: *mut u8, buf: Option<*mut u8>, buf_size: usize, + owned_buf: Option>, } fn get_host_address( @@ -224,38 +225,107 @@ impl VsockPacket { .map_err(VsockError::GuestMemoryMmap)?, buf: None, buf_size: 0, + owned_buf: None, }; + let pkt_len = pkt.len(); // No point looking for a data/buffer descriptor, if the packet is zero-lengthed. - if pkt.len() == 0 { + if pkt_len == 0 { return Ok(pkt); } // Reject weirdly-sized packets. // - if pkt.len() > defs::MAX_PKT_BUF_SIZE as u32 { - return Err(VsockError::InvalidPktLen(pkt.len())); + if pkt_len > defs::MAX_PKT_BUF_SIZE as u32 { + return Err(VsockError::InvalidPktLen(pkt_len)); } - // If the packet header showed a non-zero length, there should be a data descriptor here. - let buf_desc = head.next_descriptor().ok_or(VsockError::BufDescMissing)?; + let head_data_size = head.len as usize - VSOCK_PKT_HDR_SIZE; + + // Single combined descriptor: header + data with no next descriptor. + if !head.has_next() { + if head_data_size == 0 { + return Err(VsockError::BufDescMissing); + } + let buf_addr = head + .addr + .checked_add(VSOCK_PKT_HDR_SIZE as u64) + .ok_or(VsockError::GuestMemoryBounds)?; + pkt.buf_size = head_data_size; + pkt.buf = Some( + get_host_address(head.mem, buf_addr, pkt.buf_size) + .map_err(VsockError::GuestMemoryMmap)?, + ); + if pkt.buf_size < pkt_len as usize { + return Err(VsockError::BufDescTooSmall); + } + return Ok(pkt); + } - // TX data should be read-only. + let buf_desc = head.next_descriptor().ok_or(VsockError::BufDescMissing)?; if buf_desc.is_write_only() { return Err(VsockError::UnreadableDescriptor); } - // The data buffer should be large enough to fit the size of the data, as described by - // the header descriptor. - if buf_desc.len < pkt.len() { + // Classic two-descriptor case: header in first, all data in second. Zero-copy. + if head_data_size == 0 && !buf_desc.has_next() { + if buf_desc.len < pkt_len { + return Err(VsockError::BufDescTooSmall); + } + pkt.buf_size = buf_desc.len as usize; + pkt.buf = Some( + get_host_address(buf_desc.mem, buf_desc.addr, pkt.buf_size) + .map_err(VsockError::GuestMemoryMmap)?, + ); + return Ok(pkt); + } + + // Multiple data regions: inline data after header and/or multiple data descriptors. + // Copy into a contiguous owned buffer. + let mut owned_buf: Vec = Vec::with_capacity(pkt_len as usize); + + if head_data_size > 0 { + let buf_addr = head + .addr + .checked_add(VSOCK_PKT_HDR_SIZE as u64) + .ok_or(VsockError::GuestMemoryBounds)?; + let src = get_host_address(head.mem, buf_addr, head_data_size) + .map_err(VsockError::GuestMemoryMmap)?; + owned_buf.extend_from_slice(unsafe { + std::slice::from_raw_parts(src as *const u8, head_data_size) + }); + } + + // First data descriptor (already validated as readable above). + if buf_desc.len > 0 { + let src = get_host_address(buf_desc.mem, buf_desc.addr, buf_desc.len as usize) + .map_err(VsockError::GuestMemoryMmap)?; + owned_buf.extend_from_slice(unsafe { + std::slice::from_raw_parts(src as *const u8, buf_desc.len as usize) + }); + } + + let mut next = buf_desc.next_descriptor(); + while let Some(desc) = next { + if desc.is_write_only() { + return Err(VsockError::UnreadableDescriptor); + } + if desc.len > 0 { + let src = get_host_address(desc.mem, desc.addr, desc.len as usize) + .map_err(VsockError::GuestMemoryMmap)?; + owned_buf.extend_from_slice(unsafe { + std::slice::from_raw_parts(src as *const u8, desc.len as usize) + }); + } + next = desc.next_descriptor(); + } + + if owned_buf.len() < (pkt_len as usize) { return Err(VsockError::BufDescTooSmall); } - pkt.buf_size = buf_desc.len as usize; - pkt.buf = Some( - get_host_address(buf_desc.mem, buf_desc.addr, pkt.buf_size) - .map_err(VsockError::GuestMemoryMmap)?, - ); + pkt.buf_size = owned_buf.len(); + pkt.owned_buf = Some(owned_buf); Ok(pkt) } @@ -281,6 +351,7 @@ impl VsockPacket { .map_err(VsockError::GuestMemoryMmap)?, buf: None, buf_size: 0, + owned_buf: None, }; // Starting from Linux 6.2 the virtio-vsock driver can use a single descriptor for both @@ -331,11 +402,15 @@ impl VsockPacket { /// (and often is) larger than the length of the packet data. The packet data length /// is stored in the packet header, and accessible via `VsockPacket::len()`. pub fn buf(&self) -> Option<&[u8]> { - self.buf.map(|ptr| { - // This is safe since bound checks have already been performed when creating the packet - // from the virtq descriptor. - unsafe { std::slice::from_raw_parts(ptr as *const u8, self.buf_size) } - }) + if let Some(ref owned) = self.owned_buf { + Some(owned.as_slice()) + } else { + self.buf.map(|ptr| { + // This is safe since bound checks have already been performed when creating the + // packet from the virtq descriptor. + unsafe { std::slice::from_raw_parts(ptr as *const u8, self.buf_size) } + }) + } } /// Provides in-place, byte-slice, mutable access to the vsock packet data buffer. @@ -346,11 +421,15 @@ impl VsockPacket { /// (and often is) larger than the length of the packet data. The packet data length /// is stored in the packet header, and accessible via `VsockPacket::len()`. pub fn buf_mut(&mut self) -> Option<&mut [u8]> { - self.buf.map(|ptr| { - // This is safe since bound checks have already been performed when creating the packet - // from the virtq descriptor. - unsafe { std::slice::from_raw_parts_mut(ptr, self.buf_size) } - }) + if let Some(ref mut owned) = self.owned_buf { + Some(owned.as_mut_slice()) + } else { + self.buf.map(|ptr| { + // This is safe since bound checks have already been performed when creating the + // packet from the virtq descriptor. + unsafe { std::slice::from_raw_parts_mut(ptr, self.buf_size) } + }) + } } pub fn src_cid(&self) -> u64 { From 3411afd8db989ad694a60db782e56df9e2bc9f3d Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Mon, 18 May 2026 18:13:51 +0200 Subject: [PATCH 10/10] Bump patch version to 1.18.1 This is a patch version update for the stable-1.18.x series. Signed-off-by: Sergio Lopez --- Cargo.lock | 26 +++++++++++++------------- Makefile | 2 +- examples/Cargo.lock | 2 +- src/arch/Cargo.toml | 10 +++++----- src/arch_gen/Cargo.toml | 2 +- src/aws_nitro/Cargo.toml | 4 ++-- src/cpuid/Cargo.toml | 2 +- src/devices/Cargo.toml | 14 +++++++------- src/hvf/Cargo.toml | 4 ++-- src/kernel/Cargo.toml | 4 ++-- src/libkrun/Cargo.toml | 14 +++++++------- src/polly/Cargo.toml | 4 ++-- src/rutabaga_gfx/Cargo.toml | 2 +- src/rutabaga_gfx/ffi/Cargo.toml | 4 ++-- src/smbios/Cargo.toml | 2 +- src/utils/Cargo.toml | 2 +- src/vmm/Cargo.toml | 20 ++++++++++---------- 17 files changed, 59 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2c7a049c..d12d59fcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -594,7 +594,7 @@ dependencies = [ [[package]] name = "krun-arch" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "krun-arch-gen", "krun-smbios", @@ -609,11 +609,11 @@ dependencies = [ [[package]] name = "krun-arch-gen" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" [[package]] name = "krun-aws-nitro" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "krun-devices", "libc", @@ -627,7 +627,7 @@ dependencies = [ [[package]] name = "krun-cpuid" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "kvm-bindings", "kvm-ioctls", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "krun-devices" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "bitflags 1.3.2", "caps", @@ -678,7 +678,7 @@ dependencies = [ [[package]] name = "krun-hvf" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "crossbeam-channel", "krun-arch", @@ -700,7 +700,7 @@ dependencies = [ [[package]] name = "krun-kernel" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "krun-utils", "vm-memory", @@ -708,7 +708,7 @@ dependencies = [ [[package]] name = "krun-polly" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "krun-utils", "libc", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "krun-rutabaga-gfx" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "anyhow", "cfg-if", @@ -733,14 +733,14 @@ dependencies = [ [[package]] name = "krun-smbios" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "vm-memory", ] [[package]] name = "krun-utils" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "bitflags 1.3.2", "crossbeam-channel", @@ -753,7 +753,7 @@ dependencies = [ [[package]] name = "krun-vmm" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "bitfield", "bitflags 2.11.0", @@ -815,7 +815,7 @@ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libkrun" -version = "1.18.0" +version = "1.18.1" dependencies = [ "crossbeam-channel", "env_logger", diff --git a/Makefile b/Makefile index 31cbe24d7..9ca56bd96 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ LIBRARY_HEADER_DISPLAY = include/libkrun_display.h LIBRARY_HEADER_INPUT = include/libkrun_input.h ABI_VERSION=1 -FULL_VERSION=1.18.0 +FULL_VERSION=1.18.1 AWS_NITRO_INIT_SRC = \ init/aws-nitro/include/* \ diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 67475ad23..b11ebf9d7 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -704,7 +704,7 @@ dependencies = [ [[package]] name = "krun-utils" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" dependencies = [ "bitflags 1.3.2", "crossbeam-channel", diff --git a/src/arch/Cargo.toml b/src/arch/Cargo.toml index 5434d698d..4f18062bc 100644 --- a/src/arch/Cargo.toml +++ b/src/arch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-arch" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Architecture-specific VM support for libkrun" @@ -18,9 +18,9 @@ libc = ">=0.2.39" vm-memory = { version = "0.17", features = ["backend-mmap"] } vmm-sys-util = "0.14" -arch_gen = { package = "krun-arch-gen", version = "=0.1.0-1.18.0", path = "../arch_gen" } -smbios = { package = "krun-smbios", version = "=0.1.0-1.18.0", path = "../smbios" } -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } +arch_gen = { package = "krun-arch-gen", version = "=0.1.0-1.18.1", path = "../arch_gen" } +smbios = { package = "krun-smbios", version = "=0.1.0-1.18.1", path = "../smbios" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } [target.'cfg(target_os = "linux")'.dependencies] kvm-bindings = { version = "0.12", features = ["fam-wrappers"] } @@ -28,4 +28,4 @@ kvm-ioctls = "0.22" tdx = { version = "0.1.0", optional = true } [dev-dependencies] -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } diff --git a/src/arch_gen/Cargo.toml b/src/arch_gen/Cargo.toml index 5dad64c27..16f1d59ef 100644 --- a/src/arch_gen/Cargo.toml +++ b/src/arch_gen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-arch-gen" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Generated architecture-specific definitions for libkrun" diff --git a/src/aws_nitro/Cargo.toml b/src/aws_nitro/Cargo.toml index 3db64b14d..f99e8134c 100644 --- a/src/aws_nitro/Cargo.toml +++ b/src/aws_nitro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-aws-nitro" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" edition = "2021" description = "AWS Nitro Enclaves support for libkrun" license = "Apache-2.0" @@ -15,7 +15,7 @@ nix = { version = "0.30", features = ["poll"] } tar = "0.4" vsock = "0.5" -devices = { package = "krun-devices", version = "=0.1.0-1.18.0", path = "../devices" } +devices = { package = "krun-devices", version = "=0.1.0-1.18.1", path = "../devices" } log = "0.4" signal-hook = "0.3" diff --git a/src/cpuid/Cargo.toml b/src/cpuid/Cargo.toml index 8066b3c49..baac9c49c 100644 --- a/src/cpuid/Cargo.toml +++ b/src/cpuid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-cpuid" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "CPUID handling for libkrun" diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index 0aeb82dc7..8a16dce1b 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-devices" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" build = "build.rs" @@ -38,18 +38,18 @@ zerocopy = { version = "0.8.26", optional = true, features = ["derive"] } krun_display = { package = "krun-display", version = "0.1.0", path = "../display", optional = true, features = ["bindgen_clang_runtime"] } krun_input = { package = "krun-input", version = "0.1.0", path = "../input", features = ["bindgen_clang_runtime"], optional = true } -arch = { package = "krun-arch", version = "=0.1.0-1.18.0", path = "../arch" } -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } -polly = { package = "krun-polly", version = "=0.1.0-1.18.0", path = "../polly" } -rutabaga_gfx = { package = "krun-rutabaga-gfx", version = "=0.1.0-1.18.0", path = "../rutabaga_gfx", features = ["virgl_renderer", "virgl_renderer_next"], optional = true } +arch = { package = "krun-arch", version = "=0.1.0-1.18.1", path = "../arch" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } +polly = { package = "krun-polly", version = "=0.1.0-1.18.1", path = "../polly" } +rutabaga_gfx = { package = "krun-rutabaga-gfx", version = "=0.1.0-1.18.1", path = "../rutabaga_gfx", features = ["virgl_renderer", "virgl_renderer_next"], optional = true } imago = { version = "0.2.2", features = ["sync-wrappers", "vm-memory"] } [target.'cfg(target_os = "macos")'.dependencies] -hvf = { package = "krun-hvf", version = "=0.1.0-1.18.0", path = "../hvf" } +hvf = { package = "krun-hvf", version = "=0.1.0-1.18.1", path = "../hvf" } lru = ">=0.9" [target.'cfg(target_os = "linux")'.dependencies] -rutabaga_gfx = { package = "krun-rutabaga-gfx", version = "=0.1.0-1.18.0", path = "../rutabaga_gfx", features = ["x"], optional = true } +rutabaga_gfx = { package = "krun-rutabaga-gfx", version = "=0.1.0-1.18.1", path = "../rutabaga_gfx", features = ["x"], optional = true } caps = "0.5.5" kvm-bindings = { version = "0.12", features = ["fam-wrappers"] } kvm-ioctls = "0.22" diff --git a/src/hvf/Cargo.toml b/src/hvf/Cargo.toml index 510ec48a4..048e5be73 100644 --- a/src/hvf/Cargo.toml +++ b/src/hvf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-hvf" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Apple Hypervisor.framework backend for libkrun" @@ -12,4 +12,4 @@ crossbeam-channel = ">=0.5.15" libloading = "0.8" log = "0.4.0" -arch = { package = "krun-arch", version = "=0.1.0-1.18.0", path = "../arch" } +arch = { package = "krun-arch", version = "=0.1.0-1.18.1", path = "../arch" } diff --git a/src/kernel/Cargo.toml b/src/kernel/Cargo.toml index 044b326ef..dfdafdbb0 100644 --- a/src/kernel/Cargo.toml +++ b/src/kernel/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-kernel" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" edition = "2021" description = "Kernel loading support for libkrun" license = "Apache-2.0" @@ -9,4 +9,4 @@ repository = "https://github.com/containers/libkrun" [dependencies] vm-memory = { version = "0.17", features = ["backend-mmap"] } -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } diff --git a/src/libkrun/Cargo.toml b/src/libkrun/Cargo.toml index c80075996..8488b98d3 100644 --- a/src/libkrun/Cargo.toml +++ b/src/libkrun/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libkrun" -version = "1.18.0" +version = "1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "A dynamic library providing Virtualization-based process isolation capabilities" @@ -31,19 +31,19 @@ once_cell = "1.4.1" krun_display = { package = "krun-display", version = "0.1.0", path = "../display", optional = true, features = ["bindgen_clang_runtime"] } krun_input = { package = "krun-input", version = "0.1.0", path = "../input", optional = true, features = ["bindgen_clang_runtime"] } -devices = { package = "krun-devices", version = "=0.1.0-1.18.0", path = "../devices" } -polly = { package = "krun-polly", version = "=0.1.0-1.18.0", path = "../polly" } -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } -vmm = { package = "krun-vmm", version = "=0.1.0-1.18.0", path = "../vmm" } +devices = { package = "krun-devices", version = "=0.1.0-1.18.1", path = "../devices" } +polly = { package = "krun-polly", version = "=0.1.0-1.18.1", path = "../polly" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } +vmm = { package = "krun-vmm", version = "=0.1.0-1.18.1", path = "../vmm" } rand = "0.9.2" [target.'cfg(target_os = "macos")'.dependencies] -hvf = { package = "krun-hvf", version = "=0.1.0-1.18.0", path = "../hvf" } +hvf = { package = "krun-hvf", version = "=0.1.0-1.18.1", path = "../hvf" } [target.'cfg(target_os = "linux")'.dependencies] kvm-bindings = { version = "0.12", features = ["fam-wrappers"] } kvm-ioctls = "0.22" -aws-nitro = { package = "krun-aws-nitro", version = "=0.1.0-1.18.0", path = "../aws_nitro", optional = true } +aws-nitro = { package = "krun-aws-nitro", version = "=0.1.0-1.18.1", path = "../aws_nitro", optional = true } nitro-enclaves = { version = "0.5.0", optional = true } vm-memory = { version = "0.17", features = ["backend-mmap"] } diff --git a/src/polly/Cargo.toml b/src/polly/Cargo.toml index 93c9d57bc..f4a5c106c 100644 --- a/src/polly/Cargo.toml +++ b/src/polly/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-polly" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Event-driven I/O polling for libkrun" @@ -9,4 +9,4 @@ repository = "https://github.com/containers/libkrun" [dependencies] libc = ">=0.2.39" -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path="../utils" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path="../utils" } diff --git a/src/rutabaga_gfx/Cargo.toml b/src/rutabaga_gfx/Cargo.toml index f8e8efa2c..c015e88f8 100644 --- a/src/rutabaga_gfx/Cargo.toml +++ b/src/rutabaga_gfx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-rutabaga-gfx" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "[highly unstable] Handling virtio-gpu protocols" diff --git a/src/rutabaga_gfx/ffi/Cargo.toml b/src/rutabaga_gfx/ffi/Cargo.toml index 48f48a804..8cef405d0 100644 --- a/src/rutabaga_gfx/ffi/Cargo.toml +++ b/src/rutabaga_gfx/ffi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-rutabaga-gfx-ffi" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Handling virtio-gpu protocols with C API" @@ -12,7 +12,7 @@ name = "rutabaga_gfx_ffi" crate-type = ["cdylib", "staticlib"] [dependencies] -rutabaga_gfx = { package = "krun-rutabaga-gfx", path = "../", version = "=0.1.0-1.18.0"} +rutabaga_gfx = { package = "krun-rutabaga-gfx", path = "../", version = "=0.1.0-1.18.1"} libc = "0.2.93" log = "0.4" once_cell = "1.7" diff --git a/src/smbios/Cargo.toml b/src/smbios/Cargo.toml index 161858644..a65372b5d 100644 --- a/src/smbios/Cargo.toml +++ b/src/smbios/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-smbios" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" edition = "2021" description = "SMBIOS table generation for libkrun" license = "Apache-2.0" diff --git a/src/utils/Cargo.toml b/src/utils/Cargo.toml index 9a8c4937e..7f03bb922 100644 --- a/src/utils/Cargo.toml +++ b/src/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-utils" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" description = "Utility helpers for libkrun" diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 565adcd82..e26e59ecc 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krun-vmm" -version = "0.1.0-1.18.0" +version = "0.1.0-1.18.1" authors = ["The libkrun Authors"] edition = "2021" build = "build.rs" @@ -32,12 +32,12 @@ vmm-sys-util = "0.14" krun_display = { package = "krun-display", version = "0.1.0", path = "../display", optional = true, features = ["bindgen_clang_runtime"] } krun_input = { package = "krun-input", version = "0.1.0", path = "../input", optional = true, features = ["bindgen_clang_runtime"] } -arch = { package = "krun-arch", version = "=0.1.0-1.18.0", path = "../arch" } -arch_gen = { package = "krun-arch-gen", version = "=0.1.0-1.18.0", path = "../arch_gen" } -devices = { package = "krun-devices", version = "=0.1.0-1.18.0", path = "../devices" } -kernel = { package = "krun-kernel", version = "=0.1.0-1.18.0", path = "../kernel" } -utils = { package = "krun-utils", version = "=0.1.0-1.18.0", path = "../utils" } -polly = { package = "krun-polly", version = "=0.1.0-1.18.0", path = "../polly" } +arch = { package = "krun-arch", version = "=0.1.0-1.18.1", path = "../arch" } +arch_gen = { package = "krun-arch-gen", version = "=0.1.0-1.18.1", path = "../arch_gen" } +devices = { package = "krun-devices", version = "=0.1.0-1.18.1", path = "../devices" } +kernel = { package = "krun-kernel", version = "=0.1.0-1.18.1", path = "../kernel" } +utils = { package = "krun-utils", version = "=0.1.0-1.18.1", path = "../utils" } +polly = { package = "krun-polly", version = "=0.1.0-1.18.1", path = "../polly" } # Dependencies for amd-sev kbs-types = { version = "0.13.0", optional = true } @@ -49,7 +49,7 @@ bitflags = { version = "2.10.0", optional = true } [target.'cfg(target_arch = "x86_64")'.dependencies] bzip2 = "0.5" -cpuid = { package = "krun-cpuid", version = "=0.1.0-1.18.0", path = "../cpuid" } +cpuid = { package = "krun-cpuid", version = "=0.1.0-1.18.1", path = "../cpuid" } zstd = "0.13" [target.'cfg(target_os = "linux")'.dependencies] @@ -58,7 +58,7 @@ kvm-bindings = { version = "0.12", features = ["fam-wrappers"] } kvm-ioctls = "0.22" [target.'cfg(target_os = "macos")'.dependencies] -hvf = { package = "krun-hvf", version = "=0.1.0-1.18.0", path = "../hvf" } +hvf = { package = "krun-hvf", version = "=0.1.0-1.18.1", path = "../hvf" } [dev-dependencies] -devices = { package = "krun-devices", version = "=0.1.0-1.18.0", path = "../devices", features = ["test_utils"] } +devices = { package = "krun-devices", version = "=0.1.0-1.18.1", path = "../devices", features = ["test_utils"] }