Commit graph

9300 commits

Author SHA1 Message Date
Saravanan D
6d4827b5ff vmm: Add device_id field to NUMA configuration
Add an optional device_id string field to NumaConfig for identifying
PCI devices associated with a NUMA node. This is used by the Generic
Initiator support to map devices to their proximity domain.

Update OpenAPI spec (cloud-hypervisor.yaml) to include the
new device_id field in the NumaConfig schema.

The device_id is optional and parsed from the --numa parameter:
  --numa "device_id=<device_id>,distances=[...],..."

The optional field is accepted but not used.

Signed-off-by: Saravanan D <saravanand@crusoe.ai>
2026-02-12 22:54:54 +00:00
Saravanan D
231bbe2d5d vmm: Enforce guest_numa_id on NUMA nodes
The documentation says guest_numa_id is required to be unique and
therefore the parser() giving default value for non-existing
guest_numa_id with .unwrap_or(0) is dangerous.

Return a validation error if guest_numa_id is not provided instead
of silently defaulting to 0.

Signed-off-by: Saravanan D <saravanand@crusoe.ai>
2026-02-12 22:54:54 +00:00
Anatol Belski
9ba9c0819a tests: Add QCOW2 disk resize integration test
Verify live resize of QCOW2 disks works via the API, including
resizing that requires L1 table growth.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-12 22:47:00 +00:00
Anatol Belski
99493c728e block: qcow: Add resize unit tests
- No-op resize when size unchanged
- Growing with L1 table expansion
- Shrink attempts return error
- Resize with backing file returns error

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-12 22:47:00 +00:00
Anatol Belski
629c117ff3 block: qcow: Implement live resize with L1 table growth
Add support for live resizing QCOW2 images. This enables growing
the virtual size of a QCOW2 disk while the VM is running.

Key features:
- Growing the image automatically expands the L1 table if needed
- Shrinking is not supported
- Resizing for images with backing files is not supported

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-12 22:47:00 +00:00
Anirudh Rayabharam
caa362c31f hypervisor: mshv: stub implementation for save_data_tables()
Provide a stub implementation for save_data_tables() to unblock pause
functionality. Without this, pausing a VM causes Cloud Hypervisor to
panic due to the unimplemented!() macro. This unblocks the
test_api_http_pause_resume testcase. We don't need to save any state
just to pause and resume.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2026-02-11 15:57:21 +00:00
Philipp Schuster
2882ccd00a vmm: config validation: add more context to errors
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-02-11 10:04:14 +00:00
Demi Marie Obenour
92b58ba94a virtio-devices: Do not close an unowned FD
Instead of closing a file descriptor that belongs to the vhost-user
frontend, drop the vu_common_ctrl::VhostUserHandle and the
vhost::vhost_user::Frontend it contains.  This causes the destructor to
drop the file descriptor.

This breaks the last DPDK test, so disable it.  See #7689.

Fixes: #7163
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-02-11 09:53:10 +00:00
Damian Barabonkov
dde5f6ef38 vmm: Fix MMIO region removal during VFIO device hot-unplug
When a VFIO device with multiple MMIO regions is hot-unplugged, each
region must be individually matched and removed from the DeviceManager's
mmio_regions list. Compare per-region rather than building an aggregate
across all regions, which would never match any individual entry.

Also remove the now-unused HashSet import.

Signed-off-by: Damian Barabonkov <dbctl@pm.me>
2026-02-11 00:03:01 +00:00
Damian Barabonkov
638848fcff pci: Accept MmioRegion reference in has_matching_slots()
Change has_matching_slots() to compare two MmioRegion instances
directly rather than requiring callers to construct an intermediate
HashSet of slot numbers. Remove the now-unused
user_memory_region_slots() method and HashSet import.

Signed-off-by: Damian Barabonkov <dbctl@pm.me>
2026-02-11 00:03:01 +00:00
Changyuan Lyu
c2add07476 vmm: device_manager: avoid deep cloning device configs
Replace `clone()` with `take()` when retrieving device configurations
from `DeviceManager.config`.

This avoids unnecessarily copying the device configuration lists (e.g.,
`disks`, `net`, `fs`) when they are being processed and subsequently
moved out of the configuration. This optimization improves performance
by reducing memory allocations and cloning overhead.

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
2026-02-10 23:35:54 +00:00
Wei Liu
bf6f0f8352 virtio-devices: vsock: Accept multi-descriptor TX packets
Since kernel commit 6693731487a8 ("vsock/virtio: Allocate nonlinear SKBs
for handling large transmit buffers"), a large vsock packet can be split
into multiple descriptors.

If we encounter such TX packets, pull the content into an owned buffer.

Fixes: #7672
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2026-02-10 22:00:27 +00:00
Muminul Islam
97c5d837ab scripts: allow cloud-init script to accept a custom output file
When running manual tests locally, it is sometimes necessary to
generate a cloud-init file at a custom path instead of defaulting
to /tmp. This is useful for developers and higher-level management
layers where files in /tmp may be cleaned up automatically.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-10 21:50:29 +00:00
Rob Bradford
509832298b vmm: Add option to control backing files
Backing files (e.g. for QCOW2) interact badly with landlock since they
are not obvious from the initial VM configuration. Only enable their use
with an explicit option.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-02-10 17:41:42 +00:00
dependabot[bot]
a702bf1d10 build: Bump the non-rust-vmm group across 2 directories with 19 updates
Includes fix for rand build error (need to use trait).

Bumps the non-rust-vmm group with 15 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.100` | `1.0.101` |
| [clap](https://github.com/clap-rs/clap) | `4.5.56` | `4.5.57` |
| [libc](https://github.com/rust-lang/libc) | `0.2.180` | `0.2.181` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.37` | `0.8.39` |
| [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.8` | `1.1.9` |
| [getrandom](https://github.com/rust-random/getrandom) | `0.4.0` | `0.4.1` |
| [rand](https://github.com/rust-random/rand) | `0.9.2` | `0.10.0` |
| [jiff](https://github.com/BurntSushi/jiff) | `0.2.18` | `0.2.19` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.6` | `2.8.0` |
| [regex](https://github.com/rust-lang/regex) | `1.12.2` | `1.12.3` |
| [regex-automata](https://github.com/rust-lang/regex) | `0.4.13` | `0.4.14` |
| [regex-syntax](https://github.com/rust-lang/regex) | `0.8.8` | `0.8.9` |
| [tempfile](https://github.com/Stebalien/tempfile) | `3.24.0` | `3.25.0` |
| [unicode-ident](https://github.com/dtolnay/unicode-ident) | `1.0.22` | `1.0.23` |
| [zmij](https://github.com/dtolnay/zmij) | `1.0.19` | `1.0.20` |

Bumps the non-rust-vmm group with 8 updates in the /fuzz directory:

| Package | From | To |
| --- | --- | --- |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.100` | `1.0.101` |
| [clap](https://github.com/clap-rs/clap) | `4.5.56` | `4.5.57` |
| [libc](https://github.com/rust-lang/libc) | `0.2.180` | `0.2.181` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.37` | `0.8.39` |
| [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.8` | `1.1.9` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.6` | `2.8.0` |
| [unicode-ident](https://github.com/dtolnay/unicode-ident) | `1.0.22` | `1.0.23` |
| [zmij](https://github.com/dtolnay/zmij) | `1.0.19` | `1.0.20` |

Updates `anyhow` from 1.0.100 to 1.0.101
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.100...1.0.101)

Updates `clap` from 4.5.56 to 4.5.57
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.56...clap_complete-v4.5.57)

Updates `libc` from 0.2.180 to 0.2.181
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.181/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.180...0.2.181)

Updates `zerocopy` from 0.8.37 to 0.8.39
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.37...v0.8.39)

Updates `flate2` from 1.1.8 to 1.1.9
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.8...1.1.9)

Updates `getrandom` from 0.4.0 to 0.4.1
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.4.0...v0.4.1)

Updates `rand` from 0.9.2 to 0.10.0
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.2...0.10.0)

Updates `clap_builder` from 4.5.56 to 4.5.57
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.56...v4.5.57)

Updates `jiff` from 0.2.18 to 0.2.19
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.18...jiff-static-0.2.19)

Updates `jiff-static` from 0.2.18 to 0.2.19
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.18...jiff-static-0.2.19)

Updates `memchr` from 2.7.6 to 2.8.0
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.6...2.8.0)

Updates `regex` from 1.12.2 to 1.12.3
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.12.2...1.12.3)

Updates `regex-automata` from 0.4.13 to 0.4.14
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-automata-0.4.13...regex-automata-0.4.14)

Updates `regex-syntax` from 0.8.8 to 0.8.9
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-syntax-0.8.8...regex-syntax-0.8.9)

Updates `tempfile` from 3.24.0 to 3.25.0
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

Updates `unicode-ident` from 1.0.22 to 1.0.23
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.22...1.0.23)

Updates `zerocopy-derive` from 0.8.37 to 0.8.39
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.37...v0.8.39)

Updates `zmij` from 1.0.19 to 1.0.20
- [Release notes](https://github.com/dtolnay/zmij/releases)
- [Commits](https://github.com/dtolnay/zmij/compare/1.0.19...1.0.20)

Updates `anyhow` from 1.0.100 to 1.0.101
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.100...1.0.101)

Updates `clap` from 4.5.56 to 4.5.57
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.56...clap_complete-v4.5.57)

Updates `libc` from 0.2.180 to 0.2.181
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.181/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.180...0.2.181)

Updates `zerocopy` from 0.8.37 to 0.8.39
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.37...v0.8.39)

Updates `flate2` from 1.1.8 to 1.1.9
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.8...1.1.9)

Updates `clap_builder` from 4.5.56 to 4.5.57
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.56...v4.5.57)

Updates `hashbrown` from 0.16.1 to 0.15.5
- [Release notes](https://github.com/rust-lang/hashbrown/releases)
- [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/hashbrown/compare/v0.16.1...v0.15.5)

Updates `memchr` from 2.7.6 to 2.8.0
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.6...2.8.0)

Updates `unicode-ident` from 1.0.22 to 1.0.23
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.22...1.0.23)

Updates `zerocopy-derive` from 0.8.37 to 0.8.39
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.37...v0.8.39)

Updates `zmij` from 1.0.19 to 1.0.20
- [Release notes](https://github.com/dtolnay/zmij/releases)
- [Commits](https://github.com/dtolnay/zmij/compare/1.0.19...1.0.20)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.57
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.181
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.39
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: flate2
  dependency-version: 1.1.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: getrandom
  dependency-version: 0.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: rand
  dependency-version: 0.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.57
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: jiff
  dependency-version: 0.2.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: jiff-static
  dependency-version: 0.2.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.8.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: regex
  dependency-version: 1.12.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-automata
  dependency-version: 0.4.14
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-syntax
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: tempfile
  dependency-version: 3.25.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: unicode-ident
  dependency-version: 1.0.23
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.39
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zmij
  dependency-version: 1.0.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anyhow
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.57
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.181
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.39
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: flate2
  dependency-version: 1.1.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.57
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: hashbrown
  dependency-version: 0.15.5
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.8.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: unicode-ident
  dependency-version: 1.0.23
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.39
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zmij
  dependency-version: 1.0.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-02-10 15:26:04 +00:00
Anatol Belski
279344800e block: qcow: Add test for reads beyond backing file size
Test reading from overlay at offsets beyond backing file returns
zeros. Covers reads within backing range, beyond backing, and
boundary spanning.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-10 08:39:57 +00:00
Anatol Belski
c569a4cbd4 block: qcow: Return zeros for reads beyond backing file size
When an overlay QCOW2 image is larger than its backing file, reads
from offsets beyond the backing file virtual size would previously
fail with an I/O error.

The backing file virtual size is determined at open time and stored
for bounds checking during read operations:

- If the entire read is beyond the backing size, return all zeros
- If the read spans the boundary, read available data from backing and
  fill the remainder with zeros

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-10 08:39:57 +00:00
Wei Liu
2c49f4f4f3 hypervisor: Add an unreachable arm to get/set_x86_64_reg
This is useful when neither kvm nor mshv is defined.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2026-02-10 08:33:43 +00:00
dependabot[bot]
7157e97083 build: Bump crate-ci/typos from 1.43.3 to 1.43.4
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.43.3 to 1.43.4.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.43.3...v1.43.4)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.43.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 02:51:10 +00:00
Anatol Belski
a00189cf72 hypervisor: vmm: mshv: Enable SMT for guests with threads_per_core > 1
Set HV_PARTITION_CREATION_FLAG_SMT_ENABLED_GUEST when the guest
topology has more than one thread per core. This allows the
hypervisor to schedule guest VPs correctly on SMT-enabled hosts.

Without this flag, the hypervisor schedules guest VPs incorrectly,
causing SMT unusable.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-07 09:55:17 +00:00
Anatol Belski
e3a2bf0870 build: Update mshv crates to 0.6.7
Release notes: https://github.com/rust-vmm/mshv/pull/307

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-07 09:55:17 +00:00
dependabot[bot]
7314a77d43 build: Bump crate-ci/typos from 1.43.2 to 1.43.3
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.43.2 to 1.43.3.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.43.2...v1.43.3)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.43.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-07 00:45:27 +00:00
Champ-Goblem
1e0eba60af vmm: always try THP for VM RAM
The kernel allows madvise on shared memory if
/sys/kernel/mm/transparent_hugepage/shmem_enabled is set.
Always try and configure THP via madvise when
the user requests THP be enabled.
If this fails, only a warning log is emitted and THP won't be enabled.

Signed-off-by: Champ-Goblem <cameron@northflank.com>
2026-02-06 18:40:26 +00:00
Rowen-Ye
2c2f5d2431 vmm: open backing file read-only when not shared
When restoring from snapshot with shared=false, write access to the
backing file is not required. Opening it read-only allows restore to
succeed on read-only media and overlay lower layers while preserving
MAP_PRIVATE semantics.

Signed-off-by: Rowen-Ye <rowenye1@gmail.com>
2026-02-06 16:06:48 +00:00
Muminul Islam
258f826027 tests: Add initial support of CVM test on MSHV
This patch adds the skeleton of the CVM test
support and modify existing scripts and test framework
to enable such scenario. Split the sha1sum to support both
regular and CVM guest. Add one test case for CVM. Will further
add more test cases.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-06 06:37:26 +00:00
Muminul Islam
f391a37a35 scripts: add common image download code to utility script
X64_64 image download steps is being used for both
regular and CVM guest. Keeping the steps withing a function
in the test-util.sh

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-06 06:37:26 +00:00
Muminul Islam
6042eb969e tests: remove timeout argument
Now Guest struct has an option to set timeout.
No need to pass timeout while booting the guest.
If no timeout is set, default is used.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-06 06:37:26 +00:00
Muminul Islam
12f66b7ddc tests: Add option to pass guest for tests
Modify Guest struct to keep some test specific
data so that test cases could be shared between
regular guest and CVM.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-06 06:37:26 +00:00
dependabot[bot]
96f663b5f9 build: Bump crate-ci/typos from 1.43.1 to 1.43.2
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.43.1 to 1.43.2.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.43.1...v1.43.2)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.43.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-06 00:46:42 +00:00
Demi Marie Obenour
093a8497d0 scripts: Upgrade virtiofsd to 1.13.3
Testing generic vhost-user devices will require virtiofsd to support the
--tag option, which v1.8.0 does not support.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-02-04 17:29:48 +00:00
Anatol Belski
8c168d928f block: qcow: Add SyncingHeader error variant for fsync operations
Replace generic WritingHeader error with specific SyncingHeader
error for header fsync operations. This provides more precise
error reporting when syncing QCOW2 header changes to disk fails.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-04 10:33:22 +00:00
dependabot[bot]
7667e8c0bc build: Bump crate-ci/typos from 1.43.0 to 1.43.1
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.43.0 to 1.43.1.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.43.0...v1.43.1)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.43.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-04 01:25:57 +00:00
Anatol Belski
9bc367a27b block: qcow: Use Arc<Mutex<>> for thread safe multiqueue access
Wrap QcowFile in Arc<Mutex<>> to ensure thread safety when multiple
virtio queues access the same QCOW2 image concurrently.

Previously, each queue received its own QcowSync instance via
new_async_io() that shared the underlying QcowFile through Clone.
However, cloned QcowFile instances share internal mutable state
(L2 cache, reference counts, file seek position) without
synchronization, leading to data corruption under concurrent I/O.

This change serializes all QCOW2 operations through a mutex, which
ensures correctness at the cost of parallelism. A more performant
solution would require separating metadata locking from actual I/O
operations, tracked in #7560.

Related: #7560

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-03 22:43:38 +00:00
Anatol Belski
51662159c0 tests: qcow: Add multiqueue stress tests
Add stress tests for QCOW2 with >=8 virtio queues to verify
thread safety of multiqueue concurrent disk access:

- parallel dd writes
- 4 readers + 4 writers mixed I/O
- overlay with backing file
- random 4K writes
- parallel small writes + fsync
- mkdir/touch/rm/rename metadata operations

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-03 22:43:38 +00:00
Philipp Schuster
e690d258cc ci: reduce CI load by refining workflow concurrency groups
TL;DR: Would reduce CI pressure by cancelling more "unnecessary" runs
       but I can't verify without running a merge queue.

A common development pattern is to push a change and then immediately
check CI results. Follow-up fix pushes are quite common, which leads to
multiple CI runs being queued for the same pull request.

In Cloud Hypervisor, the size and cost of the CI matrix means that
several consecutive pushes (for example 3-4 in a short time) put
significant pressure on CI runners and noticeably increase feedback
latency.

In practice, concurrency handling is especially tricky for the merge
queue. From personal experience: If one does not take special care, CI
runs triggered by a `merge_group` can cancel each other, as in a merge
queue there are two runs for each job by default: one for the normal PR
and one for the merge commit. This is easy to run into, also because the
available documentation and best practices for this feature are not very
good.

At the same time, our workflows do not run on `push` events, but only
on `pull_request` and `merge_group`. Because of this, using
`${{ github.ref }}` alone as a concurrency key is not very meaningful,
and in practice only few runs are actually cancelled for successive PR
updates. Therefore, we should improve the usage of this feature.

This change tries to improve the situation by refining the concurrency
group key. The goal is to keep cancellation for multiple PR pushes,
while at the same time preventing unintended cancellations in the merge
queue by separating `merge_group` runs from regular PR runs.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-02-03 17:19:09 +00:00
Philipp Schuster
591aeb8ed8 misc: fix spellcheck CI step (caused by typos v1.43)
Unfortunately, we merged a typos bump [0] with failing CI.

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7654

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-02-03 16:27:46 +00:00
stevenhorsman
512c3ea58d api_client: Add license info to api_client crate
In kata-containers we use the api_client crate, but it's currently
failing our cargo deny check due to missing license, and there aren't
any license files within the crate, so I haven't found a good way to
work around this.

Alternatively I'd be happy to add the license to the workspace crate
and then reference it here, but that seems to clash with the direction
of the project in #7525.

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-02-03 15:31:03 +00:00
Anatol Belski
4ba0db5948 block: qcow: Add unit tests for autoclear features
- Autoclear bits cleared when opening for write
- Autoclear bits preserved when opening readonly
- V2 images not affected

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-03 14:39:18 +00:00
Anatol Belski
4545fe113e block: qcow: Clear autoclear features on writable open
QCOW2 v3 autoclear_features field contains bits for features whose
metadata becomes invalid when the image is modified by software that
doesn't understand them. Defined bits:

- Bit 0: Bitmaps extension
- Bit 1: Raw external data

Cloud-hypervisor doesn't support bitmaps or external data files, so
all autoclear bits are cleared on writable open. This signals other
tools that these features' data may be stale.

Readonly opens preserve autoclear bits unchanged.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-03 14:39:18 +00:00
dependabot[bot]
57fd672db6 build: Bump the non-rust-vmm group across 2 directories with 14 updates
Bumps the non-rust-vmm group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.54` | `4.5.56` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.34` | `0.8.37` |
| [arc-swap](https://github.com/vorner/arc-swap) | `1.8.0` | `1.8.1` |
| [getrandom](https://github.com/rust-random/getrandom) | `0.3.4` | `0.4.0` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.54` | `1.2.55` |
| [openssl-src](https://github.com/alexcrichton/openssl-src-rs) | `300.5.4+3.5.4` | `300.5.5+3.5.5` |
| [portable-atomic](https://github.com/taiki-e/portable-atomic) | `1.13.0` | `1.13.1` |
| [portable-atomic-util](https://github.com/taiki-e/portable-atomic) | `0.2.4` | `0.2.5` |
| [slab](https://github.com/tokio-rs/slab) | `0.4.11` | `0.4.12` |
| [zmij](https://github.com/dtolnay/zmij) | `1.0.17` | `1.0.19` |

Bumps the non-rust-vmm group with 5 updates in the /fuzz directory:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.54` | `4.5.56` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.34` | `0.8.37` |
| [arc-swap](https://github.com/vorner/arc-swap) | `1.8.0` | `1.8.1` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.54` | `1.2.55` |
| [zmij](https://github.com/dtolnay/zmij) | `1.0.17` | `1.0.19` |



Updates `clap` from 4.5.54 to 4.5.56
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.54...clap_complete-v4.5.56)

Updates `zerocopy` from 0.8.34 to 0.8.37
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.34...v0.8.37)

Updates `arc-swap` from 1.8.0 to 1.8.1
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.8.0...v1.8.1)

Updates `getrandom` from 0.3.4 to 0.4.0
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.3.4...v0.4.0)

Updates `cc` from 1.2.54 to 1.2.55
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.54...cc-v1.2.55)

Updates `clap_builder` from 4.5.54 to 4.5.56
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.54...v4.5.56)

Updates `find-msvc-tools` from 0.1.8 to 0.1.9
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.8...find-msvc-tools-v0.1.9)

Updates `hashbrown` from 0.16.1 to 0.15.5
- [Release notes](https://github.com/rust-lang/hashbrown/releases)
- [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/hashbrown/compare/v0.16.1...v0.15.5)

Updates `openssl-src` from 300.5.4+3.5.4 to 300.5.5+3.5.5
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

Updates `portable-atomic` from 1.13.0 to 1.13.1
- [Release notes](https://github.com/taiki-e/portable-atomic/releases)
- [Changelog](https://github.com/taiki-e/portable-atomic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/portable-atomic/compare/v1.13.0...v1.13.1)

Updates `portable-atomic-util` from 0.2.4 to 0.2.5
- [Release notes](https://github.com/taiki-e/portable-atomic/releases)
- [Changelog](https://github.com/taiki-e/portable-atomic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/portable-atomic/compare/portable-atomic-util-0.2.4...portable-atomic-util-0.2.5)

Updates `slab` from 0.4.11 to 0.4.12
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.11...v0.4.12)

Updates `zerocopy-derive` from 0.8.34 to 0.8.37
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.34...v0.8.37)

Updates `zmij` from 1.0.17 to 1.0.19
- [Release notes](https://github.com/dtolnay/zmij/releases)
- [Commits](https://github.com/dtolnay/zmij/compare/1.0.17...1.0.19)

Updates `clap` from 4.5.54 to 4.5.56
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.54...clap_complete-v4.5.56)

Updates `zerocopy` from 0.8.34 to 0.8.37
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.34...v0.8.37)

Updates `arc-swap` from 1.8.0 to 1.8.1
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.8.0...v1.8.1)

Updates `cc` from 1.2.54 to 1.2.55
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.54...cc-v1.2.55)

Updates `clap_builder` from 4.5.54 to 4.5.56
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.54...v4.5.56)

Updates `find-msvc-tools` from 0.1.8 to 0.1.9
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/find-msvc-tools-v0.1.8...find-msvc-tools-v0.1.9)

Updates `zerocopy-derive` from 0.8.34 to 0.8.37
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.34...v0.8.37)

Updates `zmij` from 1.0.17 to 1.0.19
- [Release notes](https://github.com/dtolnay/zmij/releases)
- [Commits](https://github.com/dtolnay/zmij/compare/1.0.17...1.0.19)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.56
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.37
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: arc-swap
  dependency-version: 1.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: getrandom
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.55
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.56
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: hashbrown
  dependency-version: 0.15.5
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: openssl-src
  dependency-version: 300.5.5+3.5.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: portable-atomic
  dependency-version: 1.13.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: portable-atomic-util
  dependency-version: 0.2.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: slab
  dependency-version: 0.4.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.37
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zmij
  dependency-version: 1.0.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.56
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.37
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: arc-swap
  dependency-version: 1.8.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.55
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.56
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.37
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zmij
  dependency-version: 1.0.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 05:49:17 +00:00
dependabot[bot]
009af915bb build: Bump crate-ci/typos from 1.42.3 to 1.43.0
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.42.3 to 1.43.0.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.42.3...v1.43.0)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 05:35:45 +00:00
Rob Bradford
01bd6b8b1a virtio-devices: vhost-user: net: Use default vhost-user virtio features
This adds some missing features that are useful. In particular it adds
VIRTIO_F_RING_INDIRECT_DESC which gives a performance improvement.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Reported-by: Daniel Farina <daniel@ubicloud.com>
2026-02-02 11:52:52 +00:00
Zhibin Li
28686bba46 vmm: fix rsdp_addr assertion for TDX
TDX builds its own ACPI tables in `create_acpi_tables_tdx` so it will
return None in the standard `create_acpi_tables` function and the
assertion for `rsdp_addr` will fail.

Signed-off-by: Zhibin Li <banlu.lzb@antgroup.com>
2026-01-29 16:23:22 +00:00
Anatol Belski
2da05d4258 block: qcow: Extend corrupt bit unit tests
Add tests for corrupt bit behavior during I/O operations.

- Unaligned L2 table address triggers corrupt bit on read
- Unaligned cluster address triggers corrupt bit on read and write
- Normal operations do not set the corrupt bit
- V2 images work correctly without feature bits

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-29 09:28:51 +00:00
Anirudh Rayabharam
323b8230a3 tests: fix tests that expect ITS for mshv arm64
MSHV doesn't present an ITS to guests. So, /proc/interrupts would never
have "ITS-PCI-MSIX".

Instead, a Gicv2m frame is presented to guests. So expect
"GICv2m-PCI-MSIX" in testcases.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2026-01-28 19:18:57 +00:00
Anatol Belski
edaeaed5f7 tests: qcow: Add corrupt bit integration tests
Add integration tests for QCOW2 corrupt bit handling. Verify that
images with the corrupt bit set are rejected for writable access but
allowed for read-only access with a warning.

Helper functions are added to read and modify the corrupt flag in the
QCOW2 v3 header.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-28 15:30:33 +00:00
Anatol Belski
9baa904a5c block: qcow: Add offset alignment checks for corruption detection
Validate that L2 table offsets and refcount block offsets are cluster
aligned. Set the corrupt bit when unaligned offsets are detected, as
this indicates corrupted L1 or refcount table entries.

Validate that data cluster offsets from L2 entries are cluster aligned
during both reads and writes to existing clusters. Set the corrupt bit
when unaligned data cluster offsets are detected.

Prevent allocation of clusters at offset 0, which contains the QCOW2
header and should never be allocated. This catches corruption in the
available clusters list. Set the corrupt bit when this condition is
detected.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-28 15:30:33 +00:00
Anatol Belski
2d86fc8422 block: qcow: Set corrupt bit on known inconsistencies
Set the QCOW2 corrupt bit when internal inconsistencies are detected
that indicate image metadata may be corrupted:

- Decompression decode failure, meaning compressed cluster data is
  invalid
- Decompression size mismatch, where decompressed data doesn't match
  expected cluster size
- Partial write after decompression, where L2 table was updated but
  data cluster not fully written, leaving metadata inconsistent
- Invalid refcount index, where cluster address is outside valid
  refcount table range, indicating a corrupted L2 entry
- Dirty L2 with zero L1 address, where L2 table is marked dirty but
  L1 has no address for it

Note: Marking decompression failures as corrupt is more conservative
than QEMU, which returns EIO without setting the corrupt bit. This is
debatable since corrupted compressed data doesn't necessarily indicate
metadata corruption, but it provides a stronger safety guarantee by
preventing further writes to potentially damaged images.

Once set, the image can only be opened read-only until repaired with
qemu-img check -r.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-28 15:30:33 +00:00
Anatol Belski
c2fcb9bac9 block: qcow: Add unit tests for corrupt bit
Add comprehensive tests for the corrupt bit handling. Cover writable
rejection, read-only access, persistence, and dirty bit
coexistence.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-28 15:30:33 +00:00
Anatol Belski
771ab1d5a3 block: qcow: Add corrupt bit support for QCOW2 v3 images
Implement proper handling of the QCOW2 corrupt bit (incompatible feature
bit 1) according to the specification:

- Add Error::CorruptImage for rejecting writable opens of corrupt images
- Add CORRUPT to SUPPORTED features (handled specially, not rejected)
- Add QcowHeader::set_corrupt_bit() to mark images as corrupt
- Add QcowHeader::is_corrupt() helper method
- Reject writable opens of corrupt images with Error::CorruptImage
- Allow readonly opens of corrupt images with a warning

The corrupt bit indicates that image metadata may be inconsistent. Per
spec, such images must not be written to until repaired by external
tools like qemu-img. Read-only access is permitted to allow data
recovery.

Users can open corrupt images read-only using:
  --disk path=/path/to/image.qcow2,readonly=on

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-01-28 15:30:33 +00:00