Compare commits

...

236 Commits
v47.0 ... v49.0

Author SHA1 Message Date
Bo Chen
9acf610a7b build: Release v49.0
Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-11-08 04:05:16 +00:00
Aastha Rawat
c4cce38631 scripts: aarch64: replace guestmount for image modification
Replace the use of `guestmount and `guestunmount` with standard tools
(losetup, mount) to modify cloud disk image. This eliminates
dependency on guestmount which requires /dev/kvm and is not available
in MSHV root partition.

Signed-off-by: Aastha Rawat <aastharawat@microsoft.com>
2025-11-06 19:33:53 +00:00
Aastha Rawat
e302d50b09 scripts: aarch64: enable MSHV support
Refactor MSHV hypervisor selection logic to enable aarch64 support
instead of exiting. Use `--features mshv` to conditionally build &
test when hypervisor is mshv replacing hard exit for aarch64 on mshv.

Signed-off-by: Aastha Rawat <aastharawat@microsoft.com>
2025-11-06 19:33:53 +00:00
Eugene Korenevsky
3791062b23 block: qcow: refactor: extract method cache_l2_cluster()
There are several copy-pasted code fragments in impl QcowFile. All of
them add L2 entry to the cache and one of them (in file_offset_write())
does also allocating new L2 entry if necessary.

Fold all these code fragments (except of one in l2_table() which does
error handling in special way) into cache_l2_cluster() method without
changing the logic.
This will make the code more compact and clean.

Signed-off-by: Eugene Korenevsky <ekorenevsky@aliyun.com>
2025-11-05 16:58:24 +00:00
Muminul Islam
e3fa27e251 scripts: Fix issue when extra docker volumes provided
With the current syntax docker gives 'docker: invalid reference format'
error. Also during parsing /xxx:/yyy in process_volumes_args
with \" inside variable i.e arr_vols=("${arg_vols//#/ }")
gives wrong output.

Example:
scripts/dev_cli.sh tests --integration --volumes /mshv:/mshv
Error: The volume /mshv /mshv does not exist.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-11-05 10:45:24 +00:00
Rob Bradford
932e1a636a tests: Disable integration tests that use virtio-mem on MSHV
These tests are now failing

See: #7456

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-11-04 19:44:02 +00:00
Alyssa Ross
d59dfdf8b6 vmm: seccomp: allow http-server to use sendto
Fixes: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7449
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-11-03 12:41:18 +00:00
Ariel Chenet
9158c36dbf docs: Update documentation to reflect initial VMM output
The API documentation tells users to expect a message when Cloud
Hypervisor is launched, this message was removed in commit 13724db

This change updates the documentation to reflect how the program
actually functions, which is to say no message.

Signed-off-by: Ariel Chenet <achenet@fastmail.com>
2025-11-03 10:30:05 +00:00
dependabot[bot]
2a39b4a4e5 build: Bump crate-ci/typos from 1.38.1 to 1.39.0
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.38.1 to 1.39.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.38.1...v1.39.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 00:03:30 +00:00
Alyssa Ross
0395b10b29 openapi: add missing NetConfig offload parameters
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-10-30 18:40:07 +00:00
Alyssa Ross
1356b26c0f build: bump bitfield-struct from 0.11.0 to 0.12.1
Should fix beta clippy.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-10-30 00:40:50 +00:00
Philipp Schuster
7536a95424 misc: cleanup &Arc<dyn T> -> &dyn T
Consuming `&Arc<T>` as argument is almost always an antipattern as it
hides whether the callee is going to take over (shared) ownership
(by .clone()) or not. Instead, it is better to consume `&dyn T` or
`Arc<dyn T>` to be more explicit. This commit cleans up the code.

The change is very mechanic and was very easy to implement across the
code base.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-28 17:37:49 +00:00
Anirudh Rayabharam
e295719967 tests: disable test_snapshot_restore_hotplug_virtiomem for mshv
Disable test_snapshot_restore_hotplug_virtiomem for mshv. It is failing
frequently in the CI. It needs to be stabilized before enabling again.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-28 15:31:58 +00:00
Anirudh Rayabharam
6198fa7a79 tests: disable broken ivshmem tests for MSHV
The ivshmem tests involving snapshot/restore & live migration are
failing in the MSHV CI with this error:

Could not get vCPU state GetMsrEntries(
  Hypercall 80 failed with 0x5 : InvalidParameter ...<snip>)

This needs more investigation. It is worth noting that the general live
migration tests are also not run in the CI for MSHV.

Disable these tests for MSHV for the time being.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-28 15:31:58 +00:00
Anirudh Rayabharam
f74cde7882 scripts: build mshv feature for ivshmem testing
The ivshmem tests are all failing in the CI for MSHV because Cloud
Hypervisor is built without the mshv feature.

Error: Cloud Hypervisor exited with the following chain of errors:
  0: Failed to open hypervisor interface (is hypervisor interface
       available?)
  1: Failed to create the hypervisor
  2: no supported hypervisor

Modify the build command to include the mshv feature.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-28 15:31:58 +00:00
AASTHA RAWAT
f033c5837b ci: prevent cross-PR CI cancellation for mshv workflows
The existing concurrency configuration causes workflow runs for one Pull
Request to cancel in-progress runs for another Pull Request. When the
workflow is triggered by the `pull_request_target event`, `github.ref`
is always set to the base branch, regardless of which branch raised the
PR. This causes every new pull request to share the same concurrency key
and thus cancel the running CI of any other open pull request.

This commit updates the `concurrency.group` to use
`github.event.pull_request.number` for unique isolation when running on
PR, falling back to `github.ref` for non-PR push (e.g., merge group).

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-27 12:43:08 +00:00
AASTHA RAWAT
03349e7523 tests: disable skipped integration tests for mshv
Disable the following common parallel and common sequential tests for
mshv since these are failing consistently in the CI.

Common parallel:
- test_tpm
- test_cpu_topology_421
- test_cpu_topology_142
- test_cpu_topology_262
- test_cpu_hotplug

Common sequential:
- test_snapshot_restore_basic
- test_snapshot_restore_with_fd
- test_snapshot_restore_pvpanic

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-25 12:57:16 +01:00
AASTHA RAWAT
5d9f75ca6d ci: remove skipped tests from integration workflow
Move the list of skipped tests from integration test workflow for
mshv.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-25 12:57:16 +01:00
Anirudh Rayabharam
861b7ab64d tests: exclude test_fw_cfg for mshv
test_fw_cfg is frequently failing in the CI for MSHV. Exclude it for
now. It needs further investigation. See issue #7434 for details.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-25 10:16:24 +00:00
dependabot[bot]
fe32002141 build: Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-24 23:58:01 +00:00
Anirudh Rayabharam
3e339439a4 arch: move GICv2M SPI base to leave room for legacy IRQs
Move the GICv2M MSI frame SPI base from 32 to 128 to avoid conflicts
with platform device interrupts.

While at it, rename the constants to make it explicit that they are
associated with the GICv2m MSI Frame.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-24 17:11:35 +00:00
Rob Bradford
cb5aaca809 hypervisor, vmm: Remove inner Mutex protecting VcpuFd
This was added in 7be69edf51 to deal with
changes to the KVM bindings that made run() and set_immediate_exit()
take &mut self. Instead adopt a Box<> value in Vcpu allowing the removal
of this internal Mutex.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-24 13:13:12 +00:00
dependabot[bot]
0a25a77095 build: Bump crate-ci/typos from 1.38.0 to 1.38.1
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.38.0 to 1.38.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.38.0...v1.38.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-23 00:03:36 +00:00
Rob Bradford
7d6c450cee virtio-devices: pci_common_config: Remove warning for feature pages > 2
The virtio spec defines the feature bit range and 4 x 32-bit pages.
However no features are currently defined with bits > 63. However Linux
has now started acking features in those higher pages. Since this is
harmless (we drop the acks to those feature pages) and quietly return 0
for available features in those higher pages this warning can be
removed.

Fixes: #7414

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-22 08:39:56 +00:00
Philipp Schuster
d39b56544a vmm: fix CpuManager::resume(): gracefully wait for run vCPU loop ACK
Fix a race condition that happens in resume()-pause() cycles.

It is odd that for pause(), the CpuManager waited via `state.paused`
for the vCPU thread to ACK the state change but not for `resume()`.
In the `resume()` case, oddly CpuManager "owned" the state change
in `state.paused`. This commit changes this so that the vCPU ACKs
its state change itself in `state.paused` when it transitions from
pause->run. Further, `CpuManager::resume()` now gracefully waits for
the vCPU to be resumed.

More technical:

This change ensures proper synchronization and prevents situations
in that park() follows right after unpark(), causing deadlocks and
other weird behavior due to race conditions.

Calling resume() now takes slightly longer, very similar to pause().
This is, however, even for 254 vCPUs in the range of less than 10ms,
and ultimately we now have correct behaviour.

## Reproducer

Since [0] is merged, the underlying problem can be tested without this
commit by modifying the pause() API call to run `CpuManager::pause()`
and `CpuManager::resume()` in a loop a thousand times.

`ch-remote --api-socket ... pause`

```patch
diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs
index d7bba25cc..35557d58f 100644
--- a/vmm/src/vm.rs
+++ b/vmm/src/vm.rs
@@ -2687,6 +2687,10 @@ impl Pausable for Vm {
             MigratableError::Pause(anyhow!("Error activating pending virtio devices: {:?}", e))
         })?;

+        for _ in 0..1000 {
+            self.cpu_manager.lock().unwrap().pause()?;
+            self.cpu_manager.lock().unwrap().resume()?;
+        }
         self.cpu_manager.lock().unwrap().pause()?;
         self.device_manager.lock().unwrap().pause()?;
```

## Outlook

Decades of experience in VMM development showed us that using
many AtomicBools is a footgun. They are not synchronized with each
other at all. On the long term, we might want to refactor things to
have a single shared AtomicU64 with different bits having different
meanings.

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

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-22 07:54:08 +00:00
Philipp Schuster
8481026b60 vmm: refactor poor naming
These bindings actually refer to atomic bool shared across all
vCPUs to instruct single vCPUs with their next action. As there
are already enough Arc<AtomicBool>, this helps while debugging
things to see that different bindings refer to the same atomic
bool.

In other words: This naming really confused us while debugging.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-22 07:54:08 +00:00
Philipp Schuster
e6ddfe07c3 vmm: remove noop
The vCPU lifecycle is already complicated. Let's remove dead
code (the impl is a no-op).

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-22 07:54:08 +00:00
dependabot[bot]
221cbeba5a build: Bump fsfe/reuse-action from 5 to 6
Bumps [fsfe/reuse-action](https://github.com/fsfe/reuse-action) from 5 to 6.
- [Release notes](https://github.com/fsfe/reuse-action/releases)
- [Commits](https://github.com/fsfe/reuse-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: fsfe/reuse-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-22 10:24:42 +01:00
Rob Bradford
99d08a2b7f tests: Replace fixed wait for VM to boot in test_net_hotplug
Use the notification mechanism now that the VM has it's primary network
attached.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-21 23:41:37 +00:00
Rob Bradford
1b4b4fb0c2 tests: Validate secondary network connection in test_net_hotplug
Test that additional network interface by SSHing in using that secondary
IP.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-21 23:41:37 +00:00
Rob Bradford
3ed44c41a6 tests: Use a secondary network interface for test_net_hotplug
This gives a reliable way of identifying if the VM has booted as well as
a reliable way to validate the addition of the network interface.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-21 23:41:37 +00:00
Rob Bradford
11eabaf97d tests: Add second network interface definition to guest
Add a second L1 network interface definition to the guest Cloud Init
configuration, including an additional host IP. Do this by splitting the
network range into two /25s. For clarity the network struct members have
also been renamed.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-21 23:41:37 +00:00
dependabot[bot]
4290d4f20e build: Bump the non-rust-vmm group across 2 directories with 25 updates
Bumps the non-rust-vmm group with 20 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [igvm](https://github.com/microsoft/igvm) | ``9b67b6f`` | ``5d2b5a5`` |
| [clap](https://github.com/clap-rs/clap) | `4.5.48` | `4.5.49` |
| [libc](https://github.com/rust-lang/libc) | `0.2.176` | `0.2.177` |
| [gdbstub](https://github.com/daniel5151/gdbstub) | `0.7.7` | `0.7.8` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.40` | `1.2.41` |
| [clap_lex](https://github.com/clap-rs/clap) | `0.7.5` | `0.7.6` |
| [env_filter](https://github.com/rust-cli/env_logger) | `0.1.3` | `0.1.4` |
| [regex](https://github.com/rust-lang/regex) | `1.11.3` | `1.12.2` |
| [regex-syntax](https://github.com/rust-lang/regex) | `0.8.6` | `0.8.8` |
| [toml_datetime](https://github.com/toml-rs/toml) | `0.7.2` | `0.7.3` |
| [toml_edit](https://github.com/toml-rs/toml) | `0.23.6` | `0.23.7` |
| [windows-targets](https://github.com/microsoft/windows-rs) | `0.53.2` | `0.53.5` |
| [windows_aarch64_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_aarch64_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_gnu](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_gnu](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |

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

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.48` | `4.5.49` |
| [libc](https://github.com/rust-lang/libc) | `0.2.176` | `0.2.177` |
| [gdbstub](https://github.com/daniel5151/gdbstub) | `0.7.7` | `0.7.8` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.40` | `1.2.41` |
| [clap_lex](https://github.com/clap-rs/clap) | `0.7.5` | `0.7.6` |
| [toml_datetime](https://github.com/toml-rs/toml) | `0.7.2` | `0.7.3` |
| [toml_edit](https://github.com/toml-rs/toml) | `0.23.6` | `0.23.7` |



Updates `igvm` from `9b67b6f` to `5d2b5a5`
- [Release notes](https://github.com/microsoft/igvm/releases)
- [Commits](9b67b6fa77...5d2b5a58e0)

Updates `igvm_defs` from `9b67b6f` to `5d2b5a5`
- [Release notes](https://github.com/microsoft/igvm/releases)
- [Commits](9b67b6fa77...5d2b5a58e0)

Updates `clap` from 4.5.48 to 4.5.49
- [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.48...clap_complete-v4.5.49)

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

Updates `gdbstub` from 0.7.7 to 0.7.8
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.7.7...0.7.8)

Updates `cc` from 1.2.40 to 1.2.41
- [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.40...cc-v1.2.41)

Updates `clap_builder` from 4.5.48 to 4.5.49
- [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.48...v4.5.49)

Updates `clap_lex` from 0.7.5 to 0.7.6
- [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_lex-v0.7.5...clap_lex-v0.7.6)

Updates `env_filter` from 0.1.3 to 0.1.4
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/env_filter-v0.1.3...env_filter-v0.1.4)

Updates `find-msvc-tools` from 0.1.3 to 0.1.4
- [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.3...find-msvc-tools-v0.1.4)

Updates `regex` from 1.11.3 to 1.12.2
- [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.11.3...1.12.2)

Updates `regex-automata` from 0.4.11 to 0.4.13
- [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.11...regex-automata-0.4.13)

Updates `regex-syntax` from 0.8.6 to 0.8.8
- [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.6...regex-syntax-0.8.8)

Updates `toml_datetime` from 0.7.2 to 0.7.3
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.7.2...toml_datetime-v0.7.3)

Updates `toml_edit` from 0.23.6 to 0.23.7
- [Commits](https://github.com/toml-rs/toml/compare/v0.23.6...v0.23.7)

Updates `toml_parser` from 1.0.3 to 1.0.4
- [Commits](https://github.com/toml-rs/toml/compare/toml_parser-v1.0.3...toml_parser-v1.0.4)

Updates `windows-targets` from 0.53.2 to 0.53.5
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `clap` from 4.5.48 to 4.5.49
- [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.48...clap_complete-v4.5.49)

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

Updates `gdbstub` from 0.7.7 to 0.7.8
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.7.7...0.7.8)

Updates `cc` from 1.2.40 to 1.2.41
- [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.40...cc-v1.2.41)

Updates `clap_builder` from 4.5.48 to 4.5.49
- [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.48...v4.5.49)

Updates `clap_lex` from 0.7.5 to 0.7.6
- [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_lex-v0.7.5...clap_lex-v0.7.6)

Updates `find-msvc-tools` from 0.1.3 to 0.1.4
- [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.3...find-msvc-tools-v0.1.4)

Updates `toml_datetime` from 0.7.2 to 0.7.3
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.7.2...toml_datetime-v0.7.3)

Updates `toml_edit` from 0.23.6 to 0.23.7
- [Commits](https://github.com/toml-rs/toml/compare/v0.23.6...v0.23.7)

Updates `toml_parser` from 1.0.3 to 1.0.4
- [Commits](https://github.com/toml-rs/toml/compare/toml_parser-v1.0.3...toml_parser-v1.0.4)

---
updated-dependencies:
- dependency-name: igvm
  dependency-version: 5d2b5a58e0b294e2adfc923ac4baddfd270eb5a8
  dependency-type: direct:production
  dependency-group: non-rust-vmm
- dependency-name: igvm_defs
  dependency-version: 5d2b5a58e0b294e2adfc923ac4baddfd270eb5a8
  dependency-type: direct:production
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.49
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.177
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: gdbstub
  dependency-version: 0.7.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.41
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.49
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_lex
  dependency-version: 0.7.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: env_filter
  dependency-version: 0.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex
  dependency-version: 1.12.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: regex-automata
  dependency-version: 0.4.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-syntax
  dependency-version: 0.8.8
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_datetime
  dependency-version: 0.7.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_edit
  dependency-version: 0.23.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_parser
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.53.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnu
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.49
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.177
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: gdbstub
  dependency-version: 0.7.8
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.41
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.49
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_lex
  dependency-version: 0.7.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_datetime
  dependency-version: 0.7.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_edit
  dependency-version: 0.23.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_parser
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 09:20:56 +00:00
Ruoqing He
a8335d0b06 ci: Extend typos to accept MSIS
Previous RISC-V ACPI related change introduced MSIS which will be
rejected by typo check, let's extend the typos to accept it.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-10-21 07:57:28 +01:00
Can Zhang
d10f6dd357 vmm: Enable RISC-V ACPI support
Add necessary definitions and RISC-V ACPI tables to enable ACPI feature.
More specifically, this commit add MADT definitions for RISC-V AIA
interrupt chips.

Signed-off-by: Can Zhang <icloud9957@gmail.com>
2025-10-18 08:30:18 +00:00
Anirudh Rayabharam
4dcd689cd9 ci: update MSHV workflow & job names
Rename the MSHV CI workflow to better align with the existing naming
scheme and also make the arch explicit.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-17 10:54:41 +00:00
AASTHA RAWAT
68f9e82447 ci: set continue-on-error for mshv infra workflow
Set `continue-on-error` for infra-setup job so that the entire workflow
doesn't fail.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-14 15:00:30 +00:00
AASTHA RAWAT
f256317ac6 ci: add timeout to mshv integration test workflow
Add step-level timeout for running integration tests so that the
workflow doesn't get stuck on any test.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-14 15:00:30 +00:00
Ruoqing He
0a785c1db2 build: Use v0.3.0 of vm-fdt instead of main branch
We are actually using v0.3.0 of vm-fdt since main branch of that crate
already includes everything. Let's pin vm-fdt to v0.3.0 instead.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-10-14 09:05:47 +00:00
Ruoqing He
d3b8300e9c build: Update linux-loader to v0.13.1
Required kernel header are made public in v0.13.1, let's bump to consume
the change.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-10-14 09:05:47 +00:00
AASTHA RAWAT
bb9d3529db ci: update PR trigger for mshv workflow
Pull requests from forked repos cannot access GitHub secrets which
results in failure of MSHV CI. Switching to pull_request_target
resolves this. It allows the workflow to run with access to repo secrets
and ensures that code from the base branch is used instead of forked
code, preventing potential security risks.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-11 08:41:23 +00:00
AASTHA RAWAT
3cf310229c ci: add tag for mshv runner
Use mshv runner for mshv workflows. Disable manual trigger.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-11 08:41:23 +00:00
AASTHA RAWAT
0e50cc320e ci: add mshv integration tests workflow
Add workflow to run integration tests on mshv. It calls the azure
infra setup workflow and executes integration tests in the
provisioned environment.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-11 08:41:23 +00:00
AASTHA RAWAT
9cdcd920b2 ci: add azure infra setup workflow
Add workflow to setup Azure infra to validate MSHV.
This is used to provision the environment before executing tests
on it.

Signed-off-by: AASTHA RAWAT <aastharawat@microsoft.com>
2025-10-11 08:41:23 +00:00
Bo Chen
256f0c39e9 vmm: Drop 'vfio container' when no active vfio devices
This provides clearer life-cycle management of resources around vfio,
and aligns better with the kernel behavior as reported below with vfio
legacy mode (with vfio container/group).

Fixes: #7328

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Yi Wang <foxywang@tencent.com>
2025-10-09 23:59:37 +00:00
Bo Chen
205e62aaa8 scripts: Download jammy images for rate-limiter tests
We recently moved many of our tests to use focal to jammy as the guest
images, including rate-limiter tests (#7367). We forgot to update the
rate-limiter scripts to reflect such change.

Our CI pipeline failed to report such error because our self-host runner
happened to be not working at the time we land the changes (see #7405).

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-10-09 22:49:12 +00:00
Rob Bradford
d760301c8d tests: Reduce parallelism on x86-64 testing
Only use 75% of the available threads - this will reduce dislk and
memory pressure. Reducing the chance of flaky tests.

See: #7405

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-09 11:02:49 +00:00
Muminul Islam
8e40413886 vmm: validate payload correctly when IGVM is provided
While an IGVM is provided validation fails as there is
no kernel or firmware. This patch fixes the sev_snp boot
failure.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-10-09 08:29:07 +01:00
Anirudh Rayabharam
5549d846da vmm: support firmware boot on mshv arm64
MSHV (Microsoft Hypervisor) doesn't expose an ITS to guests. Instead it
exposes a GICv2m MSI Frame for mapping MSIs to SPIs.

Update the MADT generation code to create the GIC MSI Frame structure
instead of the ITS structure whenever the guest vGIC is using a GICv2m
frame. This allows booting guests via firmware on MSHV.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-10-07 21:34:03 +00:00
Philipp Schuster
76bd1418a2 api_client: fix clippy
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-07 16:13:31 +00:00
dependabot[bot]
15db321245 build: Bump the non-rust-vmm group across 2 directories with 20 updates
Bumps the non-rust-vmm group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [serde_with](https://github.com/jonasbb/serde_with) | `3.14.1` | `3.15.0` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.20` | `0.6.21` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.39` | `1.2.40` |
| [lock_api](https://github.com/Amanieu/parking_lot) | `0.4.13` | `0.4.14` |
| [openssl-src](https://github.com/alexcrichton/openssl-src-rs) | `300.5.2+3.5.2` | `300.5.3+3.5.4` |
| [parking_lot](https://github.com/Amanieu/parking_lot) | `0.12.4` | `0.12.5` |
| redox_syscall | `0.5.17` | `0.5.18` |
| [windows-link](https://github.com/microsoft/windows-rs) | `0.2.0` | `0.2.1` |

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

| Package | From | To |
| --- | --- | --- |
| [serde_with](https://github.com/jonasbb/serde_with) | `3.14.1` | `3.15.0` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.20` | `0.6.21` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.39` | `1.2.40` |
| [lock_api](https://github.com/Amanieu/parking_lot) | `0.4.13` | `0.4.14` |
| [windows-link](https://github.com/microsoft/windows-rs) | `0.2.0` | `0.2.1` |
| [windows-targets](https://github.com/microsoft/windows-rs) | `0.53.4` | `0.53.5` |
| [windows_aarch64_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_aarch64_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_gnu](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_i686_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_gnu](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_gnullvm](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |
| [windows_x86_64_msvc](https://github.com/microsoft/windows-rs) | `0.53.0` | `0.53.1` |



Updates `serde_with` from 3.14.1 to 3.15.0
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.1...v3.15.0)

Updates `anstream` from 0.6.20 to 0.6.21
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.20...anstream-v0.6.21)

Updates `cc` from 1.2.39 to 1.2.40
- [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.39...cc-v1.2.40)

Updates `find-msvc-tools` from 0.1.2 to 0.1.3
- [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.2...find-msvc-tools-v0.1.3)

Updates `lock_api` from 0.4.13 to 0.4.14
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-v0.4.13...lock_api-v0.4.14)

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

Updates `parking_lot` from 0.12.4 to 0.12.5
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/parking_lot-v0.12.4...parking_lot-v0.12.5)

Updates `parking_lot_core` from 0.9.11 to 0.9.12
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/parking_lot_core-v0.9.11...parking_lot_core-v0.9.12)

Updates `redox_syscall` from 0.5.17 to 0.5.18

Updates `serde_with_macros` from 3.14.1 to 3.15.0
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.1...v3.15.0)

Updates `windows-link` from 0.2.0 to 0.2.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows-targets` from 0.52.6 to 0.53.2
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `serde_with` from 3.14.1 to 3.15.0
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.1...v3.15.0)

Updates `anstream` from 0.6.20 to 0.6.21
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.20...anstream-v0.6.21)

Updates `cc` from 1.2.39 to 1.2.40
- [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.39...cc-v1.2.40)

Updates `find-msvc-tools` from 0.1.2 to 0.1.3
- [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.2...find-msvc-tools-v0.1.3)

Updates `lock_api` from 0.4.13 to 0.4.14
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-v0.4.13...lock_api-v0.4.14)

Updates `serde_with_macros` from 3.14.1 to 3.15.0
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.1...v3.15.0)

Updates `windows-link` from 0.2.0 to 0.2.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows-targets` from 0.53.4 to 0.53.5
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.53.0 to 0.53.1
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: anstream
  dependency-version: 0.6.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: lock_api
  dependency-version: 0.4.14
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: openssl-src
  dependency-version: 300.5.3+3.5.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: parking_lot
  dependency-version: 0.12.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: parking_lot_core
  dependency-version: 0.9.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: redox_syscall
  dependency-version: 0.5.18
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with_macros
  dependency-version: 3.15.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows-link
  dependency-version: 0.2.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.53.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnu
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: serde_with
  dependency-version: 3.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: anstream
  dependency-version: 0.6.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: find-msvc-tools
  dependency-version: 0.1.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: lock_api
  dependency-version: 0.4.14
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with_macros
  dependency-version: 3.15.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows-link
  dependency-version: 0.2.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.53.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnu
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.53.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-07 00:50:02 +00:00
dependabot[bot]
15ca4751b7 build: Bump crate-ci/typos from 1.37.1 to 1.38.0
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.37.1 to 1.38.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.37.1...v1.38.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-07 00:18:43 +00:00
Rob Bradford
017a366a6e tests: First pass at replacing focal images with jammy
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-02 07:02:27 +00:00
Rob Bradford
4e008e2dbc tests: Reduce use of focal/jammy variable names
In preparation for removing focal support - start by using a more
generic "disk_config" variable name for the DiskConfig struct vs
embedding the image type.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-02 07:02:27 +00:00
dependabot[bot]
7eb5a6cd70 build: Bump crate-ci/typos from 1.37.0 to 1.37.1
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.37.0 to 1.37.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.37.0...v1.37.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-02 00:11:14 +00:00
Rob Bradford
4961b93e69 tests: Fix typo/grammar in live migration tests
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-10-01 08:57:57 +01:00
dependabot[bot]
44f187715f build: Bump crate-ci/typos from 1.36.3 to 1.37.0
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.36.3 to 1.37.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.36.3...v1.37.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 00:10:44 +00:00
dependabot[bot]
39e540ebb1 build: Bump the non-rust-vmm group across 2 directories with 20 updates
Bumps the non-rust-vmm group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [serde](https://github.com/serde-rs/serde) | `1.0.226` | `1.0.228` |
| [libc](https://github.com/rust-lang/libc) | `0.2.175` | `0.2.176` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.16` | `2.0.17` |
| [anstyle](https://github.com/rust-cli/anstyle) | `1.0.11` | `1.0.13` |
| [async-channel](https://github.com/smol-rs/async-channel) | `2.3.1` | `2.5.0` |
| [backtrace](https://github.com/rust-lang/backtrace-rs) | `0.3.75` | `0.3.76` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.38` | `1.2.39` |
| [hashbrown](https://github.com/rust-lang/hashbrown) | `0.15.5` | `0.16.0` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.5` | `2.7.6` |
| [quote](https://github.com/dtolnay/quote) | `1.0.40` | `1.0.41` |
| [regex](https://github.com/rust-lang/regex) | `1.11.2` | `1.11.3` |
| [rustix](https://github.com/bytecodealliance/rustix) | `1.0.7` | `1.1.2` |

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

| Package | From | To |
| --- | --- | --- |
| [serde](https://github.com/serde-rs/serde) | `1.0.226` | `1.0.228` |
| [libc](https://github.com/rust-lang/libc) | `0.2.175` | `0.2.176` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.16` | `2.0.17` |
| [anstyle](https://github.com/rust-cli/anstyle) | `1.0.11` | `1.0.13` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.38` | `1.2.39` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.5` | `2.7.6` |
| [quote](https://github.com/dtolnay/quote) | `1.0.40` | `1.0.41` |
| [windows-targets](https://github.com/microsoft/windows-rs) | `0.53.3` | `0.53.4` |



Updates `serde` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

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

Updates `thiserror` from 2.0.16 to 2.0.17
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.16...2.0.17)

Updates `anstyle` from 1.0.11 to 1.0.13
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.11...v1.0.13)

Updates `async-channel` from 2.3.1 to 2.5.0
- [Release notes](https://github.com/smol-rs/async-channel/releases)
- [Changelog](https://github.com/smol-rs/async-channel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-channel/compare/v2.3.1...v2.5.0)

Updates `backtrace` from 0.3.75 to 0.3.76
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Changelog](https://github.com/rust-lang/backtrace-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.75...backtrace-v0.3.76)

Updates `cc` from 1.2.38 to 1.2.39
- [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.38...cc-v1.2.39)

Updates `gimli` from 0.31.1 to 0.32.3
- [Changelog](https://github.com/gimli-rs/gimli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/gimli/compare/0.31.1...0.32.3)

Updates `hashbrown` from 0.15.5 to 0.16.0
- [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.15.5...v0.16.0)

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

Updates `object` from 0.36.7 to 0.37.3
- [Changelog](https://github.com/gimli-rs/object/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/0.36.7...0.37.3)

Updates `quote` from 1.0.40 to 1.0.41
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.40...1.0.41)

Updates `regex` from 1.11.2 to 1.11.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.11.2...1.11.3)

Updates `regex-automata` from 0.4.10 to 0.4.11
- [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/commits)

Updates `rustix` from 1.0.7 to 1.1.2
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGES.md)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v1.0.7...v1.1.2)

Updates `serde_core` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

Updates `serde_derive` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

Updates `windows-sys` from 0.59.0 to 0.60.2
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `serde` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

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

Updates `thiserror` from 2.0.16 to 2.0.17
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.16...2.0.17)

Updates `bitfield-struct` from 0.10.1 to 0.11.0
- [Release notes](https://github.com/wrenger/bitfield-struct-rs/releases)
- [Commits](https://github.com/wrenger/bitfield-struct-rs/compare/0.10.1...0.11.0)

Updates `anstyle` from 1.0.11 to 1.0.13
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.11...v1.0.13)

Updates `cc` from 1.2.38 to 1.2.39
- [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.38...cc-v1.2.39)

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

Updates `quote` from 1.0.40 to 1.0.41
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.40...1.0.41)

Updates `serde_core` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

Updates `serde_derive` from 1.0.226 to 1.0.228
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228)

Updates `windows-targets` from 0.53.3 to 0.53.4
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

---
updated-dependencies:
- dependency-name: serde
  dependency-version: 1.0.228
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.176
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: thiserror
  dependency-version: 2.0.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle
  dependency-version: 1.0.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: async-channel
  dependency-version: 2.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: backtrace
  dependency-version: 0.3.76
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.39
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: gimli
  dependency-version: 0.32.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: hashbrown
  dependency-version: 0.16.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.7.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: object
  dependency-version: 0.37.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: quote
  dependency-version: 1.0.41
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex
  dependency-version: 1.11.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-automata
  dependency-version: 0.4.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: rustix
  dependency-version: 1.1.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: serde_core
  dependency-version: 1.0.228
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_derive
  dependency-version: 1.0.228
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-sys
  dependency-version: 0.60.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: serde
  dependency-version: 1.0.228
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.176
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: thiserror
  dependency-version: 2.0.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: bitfield-struct
  dependency-version: 0.11.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: anstyle
  dependency-version: 1.0.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.39
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.7.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: quote
  dependency-version: 1.0.41
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_core
  dependency-version: 1.0.228
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_derive
  dependency-version: 1.0.228
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.53.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 03:05:01 +00:00
Philipp Schuster
690741de13 hypervisor: kvm/x86_64: get and set nested guest state
Since the functionality of [0] was backported to
kvm-bindings@v0.12.1 and kvm-ioctls@v0.22.1 [1, 2], we
can now save nested KVM state. This way, nesting works across
state save/resume and live-migration.

[0] https://github.com/rust-vmm/kvm/pull/322
[1] https://github.com/rust-vmm/kvm/pull/349
[2] https://github.com/rust-vmm/kvm/pull/350

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-29 11:44:36 +00:00
Oliver Anderson
4c16285dde vmm: Fix UB in AMX support checks
Rust's aliasing rules do not permit mutating a `usize` through a shared
reference. Unsafe blocks and FFI are no exception.

This PR fixes such a violation detected in the AMX support checks by
passing a raw mutable pointer instead of a shared reference in the
syscall.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP <oliver.anderson@sap.com>
2025-09-26 15:10:21 +00:00
dependabot[bot]
bb713e8c01 build: Bump crate-ci/typos from 1.36.2 to 1.36.3
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.36.2 to 1.36.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.36.2...v1.36.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 07:49:10 +00:00
Philipp Schuster
a6426e3615 devices: gracefully close preserved FDs on device remove
For a graceful resource management of externally provided FDs in Cloud
Hypervisor, corresponding FDs need to be closed on a device removal.
This is the case for virtio-net devices using external FDs, for example.

With the fix introduced in this commit, we allow management software to
properly clean up resources, e.g., libvirt can clean up tap devices.

PS: CHV uses "added" and "removed", which has the same meaning as
hot device attach/hotplug and hot device detach/unplug.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-25 21:25:36 +00:00
Philipp Schuster
f1206a19df block: fix error style
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-25 21:17:06 +00:00
Ruoqing He
f2dfa7f6e0 misc: Use variables directly in format! string
Fix clippy warning `uninlined_format_args` reported by rustc rustc
1.89.0 (29483883e 2025-08-04).

```console
warning: variables can be used directly in the `format!` string
   --> block/src/lib.rs:649:17
    |
649 |                 info!("{} failed to create io_uring instance: {}", error_msg, e);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    = note: `#[warn(clippy::uninlined_format_args)]` on by default
help: change this to
    |
649 -                 info!("{} failed to create io_uring instance: {}", error_msg, e);
649 +                 info!("{error_msg} failed to create io_uring instance: {e}");
    |
```

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-09-24 02:28:12 +00:00
dependabot[bot]
ea83fe314c build: Bump the non-rust-vmm group across 2 directories with 107 updates
Bumps the non-rust-vmm group with 57 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [zbus](https://github.com/dbus2/zbus) | `5.7.1` | `5.11.0` |
| [serde](https://github.com/serde-rs/serde) | `1.0.208` | `1.0.226` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.143` | `1.0.145` |
| [serde_with](https://github.com/jonasbb/serde_with) | `3.14.0` | `3.14.1` |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.99` | `1.0.100` |
| [cfg-if](https://github.com/rust-lang/cfg-if) | `1.0.0` | `1.0.3` |
| [clap](https://github.com/clap-rs/clap) | `4.5.47` | `4.5.48` |
| [log](https://github.com/rust-lang/log) | `0.4.22` | `0.4.28` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.12` | `2.0.16` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.26` | `0.8.27` |
| [bitfield-struct](https://github.com/wrenger/bitfield-struct-rs) | `0.10.1` | `0.11.0` |
| [num_enum](https://github.com/illicitonion/num_enum) | `0.7.3` | `0.7.4` |
| [blocking](https://github.com/smol-rs/blocking) | `1.6.1` | `1.6.2` |
| [gdbstub](https://github.com/daniel5151/gdbstub) | `0.7.6` | `0.7.7` |
| [micro_http](https://github.com/firecracker-microvm/micro-http) | ``bf50989`` | ``3248cee`` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.19` | `0.6.20` |
| [anstyle-query](https://github.com/rust-cli/anstyle) | `1.1.2` | `1.1.4` |
| [anstyle-wincon](https://github.com/rust-cli/anstyle) | `3.0.6` | `3.0.10` |
| [async-broadcast](https://github.com/smol-rs/async-broadcast) | `0.7.1` | `0.7.2` |
| [async-executor](https://github.com/smol-rs/async-executor) | `1.13.1` | `1.13.3` |
| [async-io](https://github.com/smol-rs/async-io) | `2.5.0` | `2.6.0` |
| [async-lock](https://github.com/smol-rs/async-lock) | `3.4.0` | `3.4.1` |
| [async-signal](https://github.com/smol-rs/async-signal) | `0.2.12` | `0.2.13` |
| [bumpalo](https://github.com/fitzgen/bumpalo) | `3.16.0` | `3.19.0` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.34` | `1.2.38` |
| [clap_lex](https://github.com/clap-rs/clap) | `0.7.4` | `0.7.5` |
| [colorchoice](https://github.com/rust-cli/anstyle) | `1.0.3` | `1.0.4` |
| [crc32fast](https://github.com/srijs/rust-crc32fast) | `1.4.2` | `1.5.0` |
| [env_filter](https://github.com/rust-cli/env_logger) | `0.1.2` | `0.1.3` |
| [errno](https://github.com/lambda-fairy/rust-errno) | `0.3.13` | `0.3.14` |
| [event-listener-strategy](https://github.com/smol-rs/event-listener-strategy) | `0.5.3` | `0.5.4` |
| [futures-lite](https://github.com/smol-rs/futures-lite) | `2.6.0` | `2.6.1` |
| [glob](https://github.com/rust-lang/glob) | `0.3.2` | `0.3.3` |
| [hashbrown](https://github.com/rust-lang/hashbrown) | `0.15.4` | `0.15.5` |
| [indexmap](https://github.com/indexmap-rs/indexmap) | `2.8.0` | `2.11.4` |
| libredox | `0.1.3` | `0.1.10` |
| [libz-sys](https://github.com/rust-lang/libz-sys) | `1.1.18` | `1.1.22` |
| [lock_api](https://github.com/Amanieu/parking_lot) | `0.4.12` | `0.4.13` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.2` | `2.7.5` |
| [once_cell](https://github.com/matklad/once_cell) | `1.20.2` | `1.21.3` |
| [openssl-src](https://github.com/alexcrichton/openssl-src-rs) | `300.3.2+3.3.2` | `300.5.2+3.5.2` |
| [openssl-sys](https://github.com/sfackler/rust-openssl) | `0.9.104` | `0.9.109` |
| [parking_lot](https://github.com/Amanieu/parking_lot) | `0.12.1` | `0.12.4` |
| [pin-project-lite](https://github.com/taiki-e/pin-project-lite) | `0.2.15` | `0.2.16` |
| [pkg-config](https://github.com/rust-lang/pkg-config-rs) | `0.3.31` | `0.3.32` |
| [polling](https://github.com/smol-rs/polling) | `3.6.0` | `3.11.0` |
| [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) | `0.2.20` | `0.2.21` |
| [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) | `3.3.0` | `3.4.0` |
| [regex](https://github.com/rust-lang/regex) | `1.11.1` | `1.11.2` |
| [regex-automata](https://github.com/rust-lang/regex) | `0.4.9` | `0.4.10` |
| [regex-syntax](https://github.com/rust-lang/regex) | `0.8.5` | `0.8.6` |
| [serde_repr](https://github.com/dtolnay/serde-repr) | `0.1.19` | `0.1.20` |
| [tempfile](https://github.com/Stebalien/tempfile) | `3.12.0` | `3.23.0` |
| [tracing](https://github.com/tokio-rs/tracing) | `0.1.40` | `0.1.41` |
| [unicode-ident](https://github.com/dtolnay/unicode-ident) | `1.0.18` | `1.0.19` |
| [wasi](https://github.com/bytecodealliance/wasi-rs) | `0.11.0+wasi-snapshot-preview1` | `0.11.1+wasi-snapshot-preview1` |
| [zvariant_utils](https://github.com/dbus2/zbus) | `3.2.0` | `3.2.1` |

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

| Package | From | To |
| --- | --- | --- |
| [serde](https://github.com/serde-rs/serde) | `1.0.208` | `1.0.226` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.143` | `1.0.145` |
| [serde_with](https://github.com/jonasbb/serde_with) | `3.14.0` | `3.14.1` |
| [cfg-if](https://github.com/rust-lang/cfg-if) | `1.0.0` | `1.0.3` |
| [clap](https://github.com/clap-rs/clap) | `4.5.47` | `4.5.48` |
| [log](https://github.com/rust-lang/log) | `0.4.22` | `0.4.28` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.12` | `2.0.16` |
| [zerocopy](https://github.com/google/zerocopy) | `0.8.26` | `0.8.27` |
| [num_enum](https://github.com/illicitonion/num_enum) | `0.7.2` | `0.7.4` |
| [getrandom](https://github.com/rust-random/getrandom) | `0.2.15` | `0.2.16` |
| [gdbstub](https://github.com/daniel5151/gdbstub) | `0.7.6` | `0.7.7` |
| [micro_http](https://github.com/firecracker-microvm/micro-http) | ``bf50989`` | ``3248cee`` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.15` | `0.6.20` |
| [anstyle](https://github.com/rust-cli/anstyle) | `1.0.8` | `1.0.11` |
| [anstyle-parse](https://github.com/rust-cli/anstyle) | `0.2.5` | `0.2.7` |
| [anstyle-query](https://github.com/rust-cli/anstyle) | `1.1.1` | `1.1.4` |
| [autocfg](https://github.com/cuviper/autocfg) | `1.3.0` | `1.5.0` |
| [bumpalo](https://github.com/fitzgen/bumpalo) | `3.16.0` | `3.19.0` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.1.11` | `1.2.38` |
| [colorchoice](https://github.com/rust-cli/anstyle) | `1.0.2` | `1.0.4` |
| [enumflags2](https://github.com/meithecatte/enumflags2) | `0.7.10` | `0.7.12` |
| [equivalent](https://github.com/indexmap-rs/equivalent) | `1.0.1` | `1.0.2` |
| [futures-core](https://github.com/rust-lang/futures-rs) | `0.3.30` | `0.3.31` |
| [futures-sink](https://github.com/rust-lang/futures-rs) | `0.3.30` | `0.3.31` |
| [indexmap](https://github.com/indexmap-rs/indexmap) | `2.5.0` | `2.11.4` |
| [itoa](https://github.com/dtolnay/itoa) | `1.0.11` | `1.0.15` |
| [lock_api](https://github.com/Amanieu/parking_lot) | `0.4.12` | `0.4.13` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.4` | `2.7.5` |
| [once_cell](https://github.com/matklad/once_cell) | `1.20.2` | `1.21.3` |
| [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) | `0.2.20` | `0.2.21` |
| [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) | `3.2.0` | `3.4.0` |
| [proc-macro2](https://github.com/dtolnay/proc-macro2) | `1.0.92` | `1.0.101` |
| [quote](https://github.com/dtolnay/quote) | `1.0.37` | `1.0.40` |
| [r-efi](https://github.com/r-efi/r-efi) | `5.2.0` | `5.3.0` |
| [rand](https://github.com/rust-random/rand) | `0.9.0` | `0.9.2` |
| [rustversion](https://github.com/dtolnay/rustversion) | `1.0.21` | `1.0.22` |
| [ryu](https://github.com/dtolnay/ryu) | `1.0.18` | `1.0.20` |
| [signal-hook-registry](https://github.com/vorner/signal-hook) | `1.4.2` | `1.4.6` |
| [syn](https://github.com/dtolnay/syn) | `2.0.95` | `2.0.106` |
| [unicode-ident](https://github.com/dtolnay/unicode-ident) | `1.0.13` | `1.0.19` |
| [wasi](https://github.com/bytecodealliance/wasi-rs) | `0.11.0+wasi-snapshot-preview1` | `0.11.1+wasi-snapshot-preview1` |
| [arbitrary](https://github.com/rust-fuzz/arbitrary) | `1.4.1` | `1.4.2` |
| [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) | `0.4.7` | `0.4.10` |
| [jobserver](https://github.com/rust-lang/jobserver-rs) | `0.1.32` | `0.1.34` |



Updates `zbus` from 5.7.1 to 5.11.0
- [Release notes](https://github.com/dbus2/zbus/releases)
- [Commits](https://github.com/dbus2/zbus/compare/zbus-5.7.1...zbus-5.11.0)

Updates `serde` from 1.0.208 to 1.0.226
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.226)

Updates `serde_json` from 1.0.143 to 1.0.145
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.143...v1.0.145)

Updates `serde_with` from 3.14.0 to 3.14.1
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.0...v3.14.1)

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

Updates `cfg-if` from 1.0.0 to 1.0.3
- [Release notes](https://github.com/rust-lang/cfg-if/releases)
- [Changelog](https://github.com/rust-lang/cfg-if/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cfg-if/compare/1.0.0...v1.0.3)

Updates `clap` from 4.5.47 to 4.5.48
- [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.47...clap_complete-v4.5.48)

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

Updates `thiserror` from 2.0.12 to 2.0.16
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.12...2.0.16)

Updates `zerocopy` from 0.8.26 to 0.8.27
- [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.26...v0.8.27)

Updates `bitfield-struct` from 0.10.1 to 0.11.0
- [Release notes](https://github.com/wrenger/bitfield-struct-rs/releases)
- [Commits](https://github.com/wrenger/bitfield-struct-rs/compare/0.10.1...0.11.0)

Updates `num_enum` from 0.7.3 to 0.7.4
- [Commits](https://github.com/illicitonion/num_enum/compare/0.7.3...0.7.4)

Updates `blocking` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/smol-rs/blocking/releases)
- [Changelog](https://github.com/smol-rs/blocking/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/blocking/compare/v1.6.1...v1.6.2)

Updates `gdbstub` from 0.7.6 to 0.7.7
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.7.6...0.7.7)

Updates `micro_http` from `bf50989` to `3248cee`
- [Commits](bf50989160...3248ceeae4)

Updates `anstream` from 0.6.19 to 0.6.20
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.19...anstream-v0.6.20)

Updates `anstyle-query` from 1.1.2 to 1.1.4
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.1.2...anstyle-query-v1.1.4)

Updates `anstyle-wincon` from 3.0.6 to 3.0.10
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.6...anstyle-wincon-v3.0.10)

Updates `async-broadcast` from 0.7.1 to 0.7.2
- [Release notes](https://github.com/smol-rs/async-broadcast/releases)
- [Changelog](https://github.com/smol-rs/async-broadcast/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-broadcast/compare/0.7.1...0.7.2)

Updates `async-executor` from 1.13.1 to 1.13.3
- [Release notes](https://github.com/smol-rs/async-executor/releases)
- [Changelog](https://github.com/smol-rs/async-executor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-executor/compare/v1.13.1...v1.13.3)

Updates `async-io` from 2.5.0 to 2.6.0
- [Release notes](https://github.com/smol-rs/async-io/releases)
- [Changelog](https://github.com/smol-rs/async-io/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-io/compare/v2.5.0...v2.6.0)

Updates `async-lock` from 3.4.0 to 3.4.1
- [Release notes](https://github.com/smol-rs/async-lock/releases)
- [Changelog](https://github.com/smol-rs/async-lock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-lock/compare/v3.4.0...v3.4.1)

Updates `async-signal` from 0.2.12 to 0.2.13
- [Release notes](https://github.com/smol-rs/async-signal/releases)
- [Changelog](https://github.com/smol-rs/async-signal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-signal/compare/v0.2.12...v0.2.13)

Updates `bumpalo` from 3.16.0 to 3.19.0
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/commits)

Updates `cc` from 1.2.34 to 1.2.38
- [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.34...cc-v1.2.38)

Updates `clap_builder` from 4.5.47 to 4.5.48
- [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.47...v4.5.48)

Updates `clap_lex` from 0.7.4 to 0.7.5
- [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_lex-v0.7.4...clap_lex-v0.7.5)

Updates `colorchoice` from 1.0.3 to 1.0.4
- [Commits](https://github.com/rust-cli/anstyle/compare/colorchoice-v1.0.3...colorchoice-v1.0.4)

Updates `crc32fast` from 1.4.2 to 1.5.0
- [Commits](https://github.com/srijs/rust-crc32fast/compare/v1.4.2...v1.5.0)

Updates `darling` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `darling_core` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `darling_macro` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `env_filter` from 0.1.2 to 0.1.3
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/env_filter-v0.1.2...env_filter-v0.1.3)

Updates `errno` from 0.3.13 to 0.3.14
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/commits)

Updates `event-listener-strategy` from 0.5.3 to 0.5.4
- [Release notes](https://github.com/smol-rs/event-listener-strategy/releases)
- [Changelog](https://github.com/smol-rs/event-listener-strategy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/event-listener-strategy/compare/v0.5.3...v0.5.4)

Updates `futures-lite` from 2.6.0 to 2.6.1
- [Release notes](https://github.com/smol-rs/futures-lite/releases)
- [Changelog](https://github.com/smol-rs/futures-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/futures-lite/compare/v2.6.0...v2.6.1)

Updates `glob` from 0.3.2 to 0.3.3
- [Release notes](https://github.com/rust-lang/glob/releases)
- [Changelog](https://github.com/rust-lang/glob/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/glob/compare/v0.3.2...v0.3.3)

Updates `hashbrown` from 0.15.4 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.15.4...v0.15.5)

Updates `indexmap` from 2.8.0 to 2.11.4
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.8.0...2.11.4)

Updates `libredox` from 0.1.3 to 0.1.10

Updates `libz-sys` from 1.1.18 to 1.1.22
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.18...1.1.22)

Updates `lock_api` from 0.4.12 to 0.4.13
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.12...lock_api-v0.4.13)

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

Updates `num_enum_derive` from 0.7.3 to 0.7.4
- [Commits](https://github.com/illicitonion/num_enum/compare/0.7.3...0.7.4)

Updates `once_cell` from 1.20.2 to 1.21.3
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.20.2...v1.21.3)

Updates `openssl-src` from 300.3.2+3.3.2 to 300.5.2+3.5.2
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

Updates `openssl-sys` from 0.9.104 to 0.9.109
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.104...openssl-sys-v0.9.109)

Updates `parking_lot` from 0.12.1 to 0.12.4
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.12.1...parking_lot-v0.12.4)

Updates `parking_lot_core` from 0.9.9 to 0.9.11
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/core-0.9.9...parking_lot_core-v0.9.11)

Updates `pin-project-lite` from 0.2.15 to 0.2.16
- [Release notes](https://github.com/taiki-e/pin-project-lite/releases)
- [Changelog](https://github.com/taiki-e/pin-project-lite/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project-lite/compare/v0.2.15...v0.2.16)

Updates `pkg-config` from 0.3.31 to 0.3.32
- [Changelog](https://github.com/rust-lang/pkg-config-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/pkg-config-rs/compare/0.3.31...0.3.32)

Updates `polling` from 3.6.0 to 3.11.0
- [Release notes](https://github.com/smol-rs/polling/releases)
- [Changelog](https://github.com/smol-rs/polling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/polling/compare/v3.6.0...v3.11.0)

Updates `ppv-lite86` from 0.2.20 to 0.2.21
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/commits/ppv-lite86-0.2.21)

Updates `proc-macro-crate` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/bkchr/proc-macro-crate/releases)
- [Commits](https://github.com/bkchr/proc-macro-crate/compare/v3.3.0...v3.4.0)

Updates `redox_syscall` from 0.4.1 to 0.5.17

Updates `regex` from 1.11.1 to 1.11.2
- [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.11.1...1.11.2)

Updates `regex-automata` from 0.4.9 to 0.4.10
- [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.9...regex-automata-0.4.10)

Updates `regex-syntax` from 0.8.5 to 0.8.6
- [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.5...regex-syntax-0.8.6)

Updates `serde_derive` from 1.0.208 to 1.0.226
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.226)

Updates `serde_repr` from 0.1.19 to 0.1.20
- [Release notes](https://github.com/dtolnay/serde-repr/releases)
- [Commits](https://github.com/dtolnay/serde-repr/compare/0.1.19...0.1.20)

Updates `serde_with_macros` from 3.14.0 to 3.14.1
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.0...v3.14.1)

Updates `tempfile` from 3.12.0 to 3.23.0
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.12.0...v3.23.0)

Updates `toml_datetime` from 0.6.11 to 0.7.2
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.6.11...toml_datetime-v0.7.2)

Updates `toml_edit` from 0.22.24 to 0.23.6
- [Commits](https://github.com/toml-rs/toml/compare/v0.22.24...v0.23.6)

Updates `tracing` from 0.1.40 to 0.1.41
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.40...tracing-0.1.41)

Updates `tracing-attributes` from 0.1.27 to 0.1.30
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-attributes-0.1.27...tracing-attributes-0.1.30)

Updates `tracing-core` from 0.1.32 to 0.1.34
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-core-0.1.32...tracing-core-0.1.34)

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

Updates `wasi` from 0.11.0+wasi-snapshot-preview1 to 0.11.1+wasi-snapshot-preview1
- [Commits](https://github.com/bytecodealliance/wasi-rs/compare/0.11.0...0.11.1)

Updates `windows-sys` from 0.52.0 to 0.59.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/compare/0.52.0...0.59.0)

Updates `windows-targets` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_msvc` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.48.5 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `winnow` from 0.7.2 to 0.7.13
- [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md)
- [Commits](https://github.com/winnow-rs/winnow/compare/v0.7.2...v0.7.13)

Updates `zbus_macros` from 5.7.1 to 5.11.0
- [Release notes](https://github.com/dbus2/zbus/releases)
- [Commits](https://github.com/dbus2/zbus/compare/zbus-5.7.1...zbus-5.11.0)

Updates `zerocopy-derive` from 0.7.35 to 0.8.27
- [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.7.35...v0.8.27)

Updates `zvariant_utils` from 3.2.0 to 3.2.1
- [Release notes](https://github.com/dbus2/zbus/releases)
- [Commits](https://github.com/dbus2/zbus/compare/zvariant_utils-3.2.0...zvariant-3.2.1)

Updates `serde` from 1.0.208 to 1.0.226
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.226)

Updates `serde_json` from 1.0.143 to 1.0.145
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.143...v1.0.145)

Updates `serde_with` from 3.14.0 to 3.14.1
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.0...v3.14.1)

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

Updates `cfg-if` from 1.0.0 to 1.0.3
- [Release notes](https://github.com/rust-lang/cfg-if/releases)
- [Changelog](https://github.com/rust-lang/cfg-if/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cfg-if/compare/1.0.0...v1.0.3)

Updates `clap` from 4.5.47 to 4.5.48
- [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.47...clap_complete-v4.5.48)

Updates `epoll` from 4.3.3 to 4.4.0
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/compare/4.3.3...4.4.0)

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

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

Updates `thiserror` from 2.0.12 to 2.0.16
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.12...2.0.16)

Updates `zerocopy` from 0.8.26 to 0.8.27
- [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.26...v0.8.27)

Updates `num_enum` from 0.7.2 to 0.7.4
- [Commits](https://github.com/illicitonion/num_enum/compare/0.7.3...0.7.4)

Updates `getrandom` from 0.2.15 to 0.2.16
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.15...v0.2.16)

Updates `gdbstub` from 0.7.6 to 0.7.7
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.7.6...0.7.7)

Updates `landlock` from 0.4.2 to 0.4.3
- [Release notes](https://github.com/landlock-lsm/rust-landlock/releases)
- [Changelog](https://github.com/landlock-lsm/rust-landlock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/landlock-lsm/rust-landlock/compare/v0.4.2...v0.4.3)

Updates `micro_http` from `bf50989` to `3248cee`
- [Commits](bf50989160...3248ceeae4)

Updates `anstream` from 0.6.15 to 0.6.20
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.19...anstream-v0.6.20)

Updates `anstyle` from 1.0.8 to 1.0.11
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.8...v1.0.11)

Updates `anstyle-parse` from 0.2.5 to 0.2.7
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.5...anstyle-parse-v0.2.7)

Updates `anstyle-query` from 1.1.1 to 1.1.4
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.1.2...anstyle-query-v1.1.4)

Updates `anstyle-wincon` from 3.0.4 to 3.0.10
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.6...anstyle-wincon-v3.0.10)

Updates `autocfg` from 1.3.0 to 1.5.0
- [Commits](https://github.com/cuviper/autocfg/compare/1.3.0...1.5.0)

Updates `bumpalo` from 3.16.0 to 3.19.0
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/commits)

Updates `cc` from 1.1.11 to 1.2.38
- [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.34...cc-v1.2.38)

Updates `clap_builder` from 4.5.47 to 4.5.48
- [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.47...v4.5.48)

Updates `colorchoice` from 1.0.2 to 1.0.4
- [Commits](https://github.com/rust-cli/anstyle/compare/colorchoice-v1.0.3...colorchoice-v1.0.4)

Updates `darling` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `darling_core` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `darling_macro` from 0.20.10 to 0.21.3
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.10...v0.21.3)

Updates `enumflags2` from 0.7.10 to 0.7.12
- [Release notes](https://github.com/meithecatte/enumflags2/releases)
- [Commits](https://github.com/meithecatte/enumflags2/compare/v0.7.10...v0.7.12)

Updates `enumflags2_derive` from 0.7.10 to 0.7.12
- [Release notes](https://github.com/meithecatte/enumflags2/releases)
- [Commits](https://github.com/meithecatte/enumflags2/compare/v0.7.10...v0.7.12)

Updates `equivalent` from 1.0.1 to 1.0.2
- [Commits](https://github.com/indexmap-rs/equivalent/compare/v1.0.1...v1.0.2)

Updates `futures-core` from 0.3.30 to 0.3.31
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.30...0.3.31)

Updates `futures-sink` from 0.3.30 to 0.3.31
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.30...0.3.31)

Updates `indexmap` from 2.5.0 to 2.11.4
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.8.0...2.11.4)

Updates `itoa` from 1.0.11 to 1.0.15
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.11...1.0.15)

Updates `lock_api` from 0.4.12 to 0.4.13
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.12...lock_api-v0.4.13)

Updates `memchr` from 2.7.4 to 2.7.5
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.2...2.7.5)

Updates `num_enum_derive` from 0.7.2 to 0.7.4
- [Commits](https://github.com/illicitonion/num_enum/compare/0.7.3...0.7.4)

Updates `once_cell` from 1.20.2 to 1.21.3
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.20.2...v1.21.3)

Updates `ppv-lite86` from 0.2.20 to 0.2.21
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/commits/ppv-lite86-0.2.21)

Updates `proc-macro-crate` from 3.2.0 to 3.4.0
- [Release notes](https://github.com/bkchr/proc-macro-crate/releases)
- [Commits](https://github.com/bkchr/proc-macro-crate/compare/v3.3.0...v3.4.0)

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

Updates `quote` from 1.0.37 to 1.0.40
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.37...1.0.40)

Updates `r-efi` from 5.2.0 to 5.3.0
- [Release notes](https://github.com/r-efi/r-efi/releases)
- [Changelog](https://github.com/r-efi/r-efi/blob/main/NEWS.md)
- [Commits](https://github.com/r-efi/r-efi/compare/v5.2.0...v5.3.0)

Updates `rand` from 0.9.0 to 0.9.2
- [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/0.9.0...rand_core-0.9.2)

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

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

Updates `serde_derive` from 1.0.208 to 1.0.226
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.226)

Updates `serde_with_macros` from 3.14.0 to 3.14.1
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.14.0...v3.14.1)

Updates `signal-hook-registry` from 1.4.2 to 1.4.6
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/registry-v1.4.2...registry-v1.4.6)

Updates `syn` from 2.0.95 to 2.0.106
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.95...2.0.106)

Updates `toml_datetime` from 0.6.8 to 0.7.2
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.6.11...toml_datetime-v0.7.2)

Updates `toml_edit` from 0.22.22 to 0.23.6
- [Commits](https://github.com/toml-rs/toml/compare/v0.22.24...v0.23.6)

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

Updates `wasi` from 0.11.0+wasi-snapshot-preview1 to 0.11.1+wasi-snapshot-preview1
- [Commits](https://github.com/bytecodealliance/wasi-rs/compare/0.11.0...0.11.1)

Updates `windows-sys` from 0.52.0 to 0.60.2
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/compare/0.52.0...0.59.0)

Updates `windows-targets` from 0.52.6 to 0.53.3
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits/0.53.0)

Updates `windows_i686_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.52.6 to 0.53.0
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `winnow` from 0.6.19 to 0.7.13
- [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md)
- [Commits](https://github.com/winnow-rs/winnow/compare/v0.7.2...v0.7.13)

Updates `zerocopy-derive` from 0.7.35 to 0.8.27
- [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.7.35...v0.8.27)

Updates `arbitrary` from 1.4.1 to 1.4.2
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.4.1...v1.4.2)

Updates `libfuzzer-sys` from 0.4.7 to 0.4.10
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.7...0.4.10)

Updates `jobserver` from 0.1.32 to 0.1.34
- [Commits](https://github.com/rust-lang/jobserver-rs/compare/0.1.32...0.1.34)

---
updated-dependencies:
- dependency-name: zbus
  dependency-version: 5.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: serde
  dependency-version: 1.0.226
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_json
  dependency-version: 1.0.145
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anyhow
  dependency-version: 1.0.100
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cfg-if
  dependency-version: 1.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.48
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: log
  dependency-version: 0.4.28
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: thiserror
  dependency-version: 2.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: bitfield-struct
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: num_enum
  dependency-version: 0.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: blocking
  dependency-version: 1.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: gdbstub
  dependency-version: 0.7.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: micro_http
  dependency-version: 3248ceeae41461d034624b582d5d358cd6e6f89f
  dependency-type: direct:production
  dependency-group: non-rust-vmm
- dependency-name: anstream
  dependency-version: 0.6.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle-query
  dependency-version: 1.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle-wincon
  dependency-version: 3.0.10
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: async-broadcast
  dependency-version: 0.7.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: async-executor
  dependency-version: 1.13.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: async-io
  dependency-version: 2.6.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: async-lock
  dependency-version: 3.4.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: async-signal
  dependency-version: 0.2.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: bumpalo
  dependency-version: 3.19.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.38
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.48
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap_lex
  dependency-version: 0.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: colorchoice
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: crc32fast
  dependency-version: 1.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: darling
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: darling_core
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: darling_macro
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: env_filter
  dependency-version: 0.1.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: errno
  dependency-version: 0.3.14
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: event-listener-strategy
  dependency-version: 0.5.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: futures-lite
  dependency-version: 2.6.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: glob
  dependency-version: 0.3.3
  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-patch
  dependency-group: non-rust-vmm
- dependency-name: indexmap
  dependency-version: 2.11.4
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: libredox
  dependency-version: 0.1.10
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libz-sys
  dependency-version: 1.1.22
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: lock_api
  dependency-version: 0.4.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: num_enum_derive
  dependency-version: 0.7.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: once_cell
  dependency-version: 1.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: openssl-src
  dependency-version: 300.5.2+3.5.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: openssl-sys
  dependency-version: 0.9.109
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: parking_lot
  dependency-version: 0.12.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: parking_lot_core
  dependency-version: 0.9.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: pin-project-lite
  dependency-version: 0.2.16
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: pkg-config
  dependency-version: 0.3.32
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: polling
  dependency-version: 3.11.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: ppv-lite86
  dependency-version: 0.2.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: proc-macro-crate
  dependency-version: 3.4.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: redox_syscall
  dependency-version: 0.5.17
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: regex
  dependency-version: 1.11.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-automata
  dependency-version: 0.4.10
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: regex-syntax
  dependency-version: 0.8.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_derive
  dependency-version: 1.0.226
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_repr
  dependency-version: 0.1.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with_macros
  dependency-version: 3.14.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: tempfile
  dependency-version: 3.23.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: toml_datetime
  dependency-version: 0.7.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: toml_edit
  dependency-version: 0.23.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: tracing
  dependency-version: 0.1.41
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: tracing-attributes
  dependency-version: 0.1.30
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: tracing-core
  dependency-version: 0.1.34
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: unicode-ident
  dependency-version: 1.0.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: wasi
  dependency-version: 0.11.1+wasi-snapshot-preview1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-sys
  dependency-version: 0.59.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnu
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: winnow
  dependency-version: 0.7.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zbus_macros
  dependency-version: 5.11.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.27
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: zvariant_utils
  dependency-version: 3.2.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde
  dependency-version: 1.0.226
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_json
  dependency-version: 1.0.145
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anyhow
  dependency-version: 1.0.100
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: cfg-if
  dependency-version: 1.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: clap
  dependency-version: 4.5.48
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: epoll
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: libc
  dependency-version: 0.2.175
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: log
  dependency-version: 0.4.28
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: thiserror
  dependency-version: 2.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: zerocopy
  dependency-version: 0.8.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: num_enum
  dependency-version: 0.7.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: getrandom
  dependency-version: 0.2.16
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: gdbstub
  dependency-version: 0.7.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: landlock
  dependency-version: 0.4.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: micro_http
  dependency-version: 3248ceeae41461d034624b582d5d358cd6e6f89f
  dependency-type: direct:production
  dependency-group: non-rust-vmm
- dependency-name: anstream
  dependency-version: 0.6.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle
  dependency-version: 1.0.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle-parse
  dependency-version: 0.2.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle-query
  dependency-version: 1.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: anstyle-wincon
  dependency-version: 3.0.10
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: autocfg
  dependency-version: 1.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: bumpalo
  dependency-version: 3.19.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: cc
  dependency-version: 1.2.38
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: clap_builder
  dependency-version: 4.5.48
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: colorchoice
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: darling
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: darling_core
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: darling_macro
  dependency-version: 0.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: enumflags2
  dependency-version: 0.7.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: enumflags2_derive
  dependency-version: 0.7.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: equivalent
  dependency-version: 1.0.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: futures-core
  dependency-version: 0.3.31
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: futures-sink
  dependency-version: 0.3.31
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: indexmap
  dependency-version: 2.11.4
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: itoa
  dependency-version: 1.0.15
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: lock_api
  dependency-version: 0.4.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: num_enum_derive
  dependency-version: 0.7.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: once_cell
  dependency-version: 1.21.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: ppv-lite86
  dependency-version: 0.2.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: proc-macro-crate
  dependency-version: 3.4.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: proc-macro2
  dependency-version: 1.0.101
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: quote
  dependency-version: 1.0.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: r-efi
  dependency-version: 5.3.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: rand
  dependency-version: 0.9.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: rustversion
  dependency-version: 1.0.22
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: ryu
  dependency-version: 1.0.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_derive
  dependency-version: 1.0.226
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: serde_with_macros
  dependency-version: 3.14.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: signal-hook-registry
  dependency-version: 1.4.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: syn
  dependency-version: 2.0.106
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: toml_datetime
  dependency-version: 0.7.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: toml_edit
  dependency-version: 0.23.6
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: unicode-ident
  dependency-version: 1.0.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: wasi
  dependency-version: 0.11.1+wasi-snapshot-preview1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: windows-sys
  dependency-version: 0.60.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows-targets
  dependency-version: 0.53.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnu
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_i686_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: winnow
  dependency-version: 0.7.13
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: zerocopy-derive
  dependency-version: 0.8.27
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: non-rust-vmm
- dependency-name: arbitrary
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: libfuzzer-sys
  dependency-version: 0.4.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
- dependency-name: jobserver
  dependency-version: 0.1.34
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: non-rust-vmm
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 02:28:12 +00:00
Ruoqing He
ad0f695352 ci: Make package-ecosystem combination unique
"Update configs must have a unique combination of 'package-ecosystem',
'directory', and 'target-branch'. Ecosystem 'cargo' has overlapping
directories for target branch 'main'."

Drop `target-branch` in rust-vmm group to make those two unique.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-09-23 11:08:31 +01:00
dependabot[bot]
70c798d2b9 build: Bump landlock from 0.4.2 to 0.4.3
Bumps [landlock](https://github.com/landlock-lsm/rust-landlock) from 0.4.2 to 0.4.3.
- [Release notes](https://github.com/landlock-lsm/rust-landlock/releases)
- [Changelog](https://github.com/landlock-lsm/rust-landlock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/landlock-lsm/rust-landlock/compare/v0.4.2...v0.4.3)

---
updated-dependencies:
- dependency-name: landlock
  dependency-version: 0.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 23:50:49 +00:00
Ruoqing He
db37ef2ad7 ci: Group dependabot updates to reduce noise
Use a workaround [1] to group rust-vmm and non-rust-vmm updates raised
by dependabot, which reduces noise from dependabot.

[1] https://github.com/dependabot/dependabot-core/issues/1778#issuecomment-1988140219

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-09-22 22:27:44 +01:00
Philipp Schuster
452424b66e vmm: api: abstract FD handling behind functions
## TL;DR

This unifies error handling, implementation, and logging of config
objects that are populated with additional FDs received as part of
the HTTP API request from the management software. This prevents current
and future code in repetition.

In the future, if we want to support let's say virtio-blk with external
FDs, the AddBlk API handler simply needs a call to `attach_fds_to_cfg()`
and gets all the magic for free.

## Motivation

The motivation of the new abstraction is to provide a verbose, solid,
and bulletproof solution for a complex domain. The interaction between

- the management layer,
- the passing of file descriptors over UNIX domain sockets via
  SCM_RIGHTS,
- the attachment of configurations to those FDs,
- and the ability to give new developers clear insights into what
  happens under the hood

is not trivial. These factors justify encapsulating the complexity
behind a convenient and well-documented abstraction, making the system
both robust in production and approachable for new developers.

In addition, it allows us to perform unit testing. Further, We get rid
of existing partial code duplication and inconsistencies.

Finally, while this approach may initially result in more code, every
new handler that accepts FDs benefits from reduced duplication and a
correct implementation by relying on the shared abstraction. This will
also enable future functionality, such as virtio-blk devices backed by
FDs which can then be integrated with ease.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:29:54 +00:00
Philipp Schuster
ed27e93b81 vmm: remove special serialization of network FDs
Deserializing values as `-1` makes sense to prevent errors, so let's
keep it. However, serializing them differently adds confusion. For
example, a `ch-remote info` call should not report `-1` but the actual
FDs.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:29:54 +00:00
Philipp Schuster
0cd87053ee vmm: document + FD (de)serialization + warn -> debug
(1) The old messages are missing the "why" part. With this change, users
    of Cloud Hypervisor have somehow more context and people looking at
    the code perfectly know what's going on.

(2) Using warn! implies that the user should take action, but in this
    case, there’s nothing the user can do. If the API is used correctly
    and file descriptors are passed via an SCM_RIGHTS message over a
    UNIX domain socket, everything works as intended. In that case,
    there's no need to issue a warning — debug! is sufficient.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:29:54 +00:00
Philipp Schuster
60efa1aa03 vmm: doc improvement for "magic" network FD handling
Live migration, state save/resume, and hotplug are not trivial when it
comes to virtio-net devices backed by externally provided FDs. As the
mechanism behind it can be considered as quite "multi-step magic" even
for experienced programmers, it makes sense to thoroughly document this
to ease debugging and to improve the mental model of developers working
on this in the future.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:29:54 +00:00
Philipp Schuster
fae32412dc vmm: logger: improve code, remove duplication
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:28:35 +00:00
Philipp Schuster
7a5781e5a2 vmm: logger: improve output of timestamp
Streamline the output format of the timestamp of a message.
The old format doesn't nicely align across multiple lines.

# Example (old style)
```
cloud-hypervisor: 858.465660ms: <vcpu0> DEBUG:devices/src/ioapic.rs:154 -- IOAPIC_R @ offset 0x10
cloud-hypervisor: 858.507342ms: <vcpu0> DEBUG:devices/src/ioapic.rs:298 -- IOAPIC_R reg 0x1
cloud-hypervisor: 1.010001s: <vcpu0> DEBUG:devices/src/ioapic.rs:174 -- IOAPIC_W @ offset 0x0
cloud-hypervisor: 1.010067s: <vcpu0> DEBUG:devices/src/ioapic.rs:154 -- IOAPIC_R @ offset 0x10
```

# Example (new style)
```
cloud-hypervisor:   0.731399s: <vcpu0> DEBUG:devices/src/ioapic.rs:174 -- IOAPIC_W @ offset 0x10
cloud-hypervisor:   0.731420s: <vcpu0> DEBUG:devices/src/ioapic.rs:252 -- IOAPIC_W reg 0x2a, val 0x10000
cloud-hypervisor:  17.026073s: <vmm> INFO:vmm/src/api/mod.rs:898 -- API request event: VmInfo
cloud-hypervisor:  17.263210s: <vmm> INFO:vmm/src/api/mod.rs:898 -- API request event: VmInfo
cloud-hypervisor:  17.547915s: <vmm> INFO:vmm/src/api/mod.rs:898 -- API request event: VmInfo
```

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-22 14:28:35 +00:00
dependabot[bot]
e5c9f7d615 build: Bump igvm_defs from dff4ebc to 9b67b6f
Bumps [igvm_defs](https://github.com/microsoft/igvm) from `dff4ebc` to `9b67b6f`.
- [Release notes](https://github.com/microsoft/igvm/releases)
- [Commits](dff4ebc9c5...9b67b6fa77)

---
updated-dependencies:
- dependency-name: igvm_defs
  dependency-version: 9b67b6fa774f4a842718c5c70645973fe73ef616
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 14:25:01 +00:00
Wei Liu
78a16227d2 scripts: Exit create-cloud-init.sh on error
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-09-22 14:24:50 +00:00
Maximilian Güntner
66aa0743f0 vmm: allow net devices without ip and mask
This change enables easier integration with third-party
tools by removing the requirement for a dummy IP address
when configuring tap devices. The modification applies to
both CLI and API interactions.

Previously, cloud-hypervisor would automatically set a
default static IP address (192.168.249.1) if none was provided.

This could lead to:

* multiple devices without explicit IP configurations
  would end up with the same default IP
* unnecessary inclusion of this IP in firewall rules
* the IP address could clash with host networking and
  routing

This introduces a new constraint:
When providing an IP, the mask must also be provided.

Removes warnings introduced in #7179.
Closes issue #7083.

Signed-off-by: Maximilian Güntner <code@mguentner.de>
2025-09-22 14:12:47 +00:00
Maximilian Güntner
d28d9eb34e virtio-devices: refactor VSOCK "connect" parsing
The function `read_local_stream_port` had no proper handling for
unexpected or incomplete input.
When the control socket of the VSOCK device was closed without sending
the expected `CONNECT <PORT>\n` statement completely, the thread
got stuck in an infinite loop as it attempted to read from a closed
socket over and over again which never returned any data.

This resulted in the thread responsible for `epoll` being completely
blocked. New VSOCK connections could not be established and existing
ones became defunct, effectively leading to a Denial of Service of
the entire VSOCK device.

The issue can be reproduced by opening a socket and immediately
closing it.

```
socat - UNIX-CONNECT:/socket.vsock
<Ctrl-C>
```

Instead of applying a quick fix by handling the `EPOLLHUP` event before
reading, the function is refactored to remove the error-prone `while`
loop and multiple `read`s.
Notably, we now check if the number of bytes read is zero, which occurs
when `event_set == EPOLLHUP | EPOLLIN`, indicating that the socket has
been closed by the client.

Additionally, the actual parsing code is now extracted into a dedicated
function that is tested.

Fixes: #6798
Signed-off-by: Maximilian Güntner <code@mguentner.de>
2025-09-17 17:10:12 +00:00
Muminul Islam
1e8996f94f vmm: hypervisor: simplify VM creation API
For MSHV customers don't want to make everything
default during partition creation. For example
nested support, some synthetic features could be
controlled from CLI through platform argument.
Create_vm API getting messy after adding more flags.
This patch introduces common data struct to be passed
from vmm crate to hypervisor crate during partition creation.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-17 16:40:10 +00:00
Bo Chen
f122398262 misc: Fix beta clippy issues
Fixed with 'cargo clippy --fix' mostly.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-09-17 03:59:57 +00:00
Anirudh Rayabharam
10fb713218 hypervisor: mshv: handle reset intercepts for arm64
Handle MSHV reset intercepts on arm64 such that guests can gracefully
shutdown/reboot instead of panicking due to unhandled intercept.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-09-17 01:34:39 +00:00
dependabot[bot]
90b0dc911c build: Bump epoll from 4.3.3 to 4.4.0
Bumps [epoll](https://github.com/nathansizemore/epoll) from 4.3.3 to 4.4.0.
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/compare/4.3.3...4.4.0)

---
updated-dependencies:
- dependency-name: epoll
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 23:52:39 +00:00
dependabot[bot]
79fe396da9 build: Bump tj-actions/changed-files from 46 to 47
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 46 to 47.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v46...v47)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: '47'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 00:23:42 +00:00
dependabot[bot]
72dc280a0c build: Bump async-process from 2.4.0 to 2.5.0
Bumps [async-process](https://github.com/smol-rs/async-process) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/smol-rs/async-process/releases)
- [Changelog](https://github.com/smol-rs/async-process/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-process/compare/v2.4.0...v2.5.0)

---
updated-dependencies:
- dependency-name: async-process
  dependency-version: 2.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 00:03:02 +00:00
Muminul Islam
ad9a1878bf hypervisor: remove invalid url
Reference link to set_device_attribut for aarch64
is invalid. Looks like the code browsing does not
have the reference anymore.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-13 08:30:58 +00:00
Philipp Schuster
8fd8523042 vmm: add info! message on graceful shutdown
This message makes it easier to confirm a successful shutdown when
scanning logs during development and in production. If the message is
missing and the last log entry is not an error, the most likely cause
is a livelock (e.g. contention on a lock) introduced while developing
new Cloud Hypervisor features.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-13 07:43:29 +00:00
dependabot[bot]
d002090afe build: Bump anyhow from 1.0.98 to 1.0.99
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.98 to 1.0.99.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.98...1.0.99)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.99
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-12 23:53:47 +00:00
Bo Chen
95e3c8f8fd build: Release v48.0
Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-09-12 20:23:29 +00:00
Peter Oskolkov
5f399fc06d vmm: fix hotplugging when max_cpus > 255
Signed-off-by: Peter Oskolkov <posk@posk.io>
2025-09-12 07:23:55 +00:00
dependabot[bot]
43a6a914b8 build: Bump ssh2 from 0.9.4 to 0.9.5
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.9.4 to 0.9.5.
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.9.4...0.9.5)

---
updated-dependencies:
- dependency-name: ssh2
  dependency-version: 0.9.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 23:52:25 +00:00
Bo Chen
ad3f94638f docs: Clarify our policy on AI generated code
Fix: #7162

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-09-11 17:40:51 +00:00
dependabot[bot]
4dd635a56a build: Bump bitflags from 2.9.3 to 2.9.4
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.3 to 2.9.4.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.3...2.9.4)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 23:54:06 +00:00
Philipp Schuster
1179a1a1c9 vmm: refactor alignment
Context [0].

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7256#discussion_r2298538384

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
c995b72384 build: treewide: clippy: collapse nested ifs, use let chains
This bumps the MSRV to 1.88 (also, Rust edition 2024 is mandatory).

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
f73a6c8d8e build: treewide: clippy for edition 2024
This commit includes all simple clippy fixes excluding the
collapsing of nested ifs using the let-chains feature. This
follows in the next commit.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
061351d82d build: upgrade whole* workspace to Rust edition 2024
This upgrades the Cargo workspace to Rust edition 2024 to keep the
code base clean and up to date.

The commit only contains the adjustments to the Cargo.toml files and
basic compiler error fixes. Also, this commit includes new SAFETY
comments as discussed in [1]. The changes were not automatically
fixed by `cargo fix --edition` but needed manual adjustments.

Apart from that, all formatting and clippy adjustments follow in
subsequent commits.

*
As only exception, workspace member net_gen sticks to edition 2021
for now as discussed in [0].

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7295#discussion_r2310851041
[1] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7256#issuecomment-3271888674

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
dependabot[bot]
5790bcefee build: Bump miniz_oxide from 0.8.8 to 0.8.9
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.8.8 to 0.8.9.
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/commits)

---
updated-dependencies:
- dependency-name: miniz_oxide
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 00:01:54 +00:00
Anirudh Rayabharam
86c736fe76 build: bump mshv and vfio crates
Bump mshv-ioctls and mshv-bindings to 0.6.0. Most notably, this version
contains fixes and new bindings for arm64 guests.

Bump the vfio crates too so that they point to the latest mshv crates.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-09-09 22:58:01 +00:00
Wei Liu
5737e58f29 tests: Use serial console in test_cpu_hotplug
Virtio console is activated much later in boot. The output it spits out
lacks the initial CPU configuration of the guest.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-09-09 21:58:42 +00:00
Alyssa Ross
e4af58b88e arch: aarch64: fdt: reduce log verbosity
This module warns for a lot of routine things that the user cannot do
anything about.

Closes: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7220
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 17:41:05 +00:00
Alyssa Ross
093f62858f seccomp: avoid hardcoding ioctl numbers
These can differ between platforms, so it's better to use centralized
definitions of them.  We can't currently do this for the KVM and VFIO
ioctls, because the corresponding crates don't publicly expose the
ioctl numbers.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 16:43:35 +00:00
Alyssa Ross
305bec056f arch: aarch64: fdt: replace broken link
The previously linked file was converted to ReStructuredText, then
later removed from the kernel, with part of the justification being
"Most of what booting-without-of.rst contains is now in the DT
specification", so point to that instead.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 16:34:26 +00:00
Alyssa Ross
6cac99bd76 vmm: error if landlock can't be enabled
Since the user has to explicitly ask for Landlock to be enabled in
Cloud Hypervisor, it's surprising that, even when they've done that,
Landlock will silently not be enabled if the kernel doesn't support
it.

To prevent accidental absence of a desired security protection, exit
with an error if Landlock, or the one feature of it we use in Cloud
Hypervisor (file access) is not supported.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 15:08:24 +00:00
Alyssa Ross
533d3a85d1 vmm: fix landlock on aarch64
arch::aarch64::fdt::create_cpu_nodes will always look at this if it
exists.  (If it doesn't exist, this is a no-op —
add_rule_with_access() won't add rules for paths that don't exist.)

Fixes: b3e5738b4 ("vmm: Introduce ApplyLandlock trait")
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 11:53:45 +00:00
dependabot[bot]
c7eac0f65a build: Bump clap from 4.5.13 to 4.5.47
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.13 to 4.5.47.
- [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.13...clap_complete-v4.5.47)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.47
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-09 11:13:10 +00:00
Muminul Islam
e7e850bbdd tests: enable more test cases for MSHV
MSHV now supports movable pages i.e VA backed guest.
Also with more features and stability in the MSHV
Kernel drives MSHV now supports more test scenario.
This patch enables more integration test cases.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-09 10:10:53 +00:00
Alyssa Ross
08b197bbc1 vmm: fix vsock with landlock
Without write access to the directory the socket will go in, it's not
possible to create the socket.

I've tested outgoing connections from the VM, and they don't seem to
need read permissions on that directory to connect to a socket on the
host.

Fixes: b3e5738b4 ("vmm: Introduce ApplyLandlock trait")
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 10:09:22 +00:00
Alyssa Ross
3259234e58 vmm: drop unnecessary copies
path_beneath_rules() just needs the paths given to it to be
AsRef<Path>, so there's no need to create new PathBufs for it.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-09 04:23:13 +00:00
Peter Oskolkov
05d222f0eb vmm: raise the (v)CPU limit on kvm/x86_64
Raise the max number of supported (v)CPUs on kvm x86_64 hosts
to 8192 (the max allowed value of CONFIG_NR_CPUS in the Linux kernel).

Other platfroms keep their existing CPU limits pending further
development and testing.

The change has been tested on Intel and AMD hosts.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-09-08 22:54:31 +00:00
Peter Oskolkov
57bc78da4f arch: x86_64: make MAX_SUPPORTED_CPUS_LEGACY public
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-09-08 22:54:31 +00:00
Alyssa Ross
47cff7c37f vmm: allow TCGETS2/TCSETS2 where TCGETS/TCSETS are
These are now used by Cloud Hypervisor when linked with Glibc 2.42.

These values should be correct for all currently supported Cloud
Hypervisor platforms, although they are not for all Linux platforms.

Closes: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7276
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-09-06 13:33:25 +00:00
dependabot[bot]
3f5c719705 build: Bump crate-ci/typos from 1.36.1 to 1.36.2
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.36.1 to 1.36.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.36.1...v1.36.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-06 00:12:14 +00:00
dependabot[bot]
706b56e97d build: Bump async-trait from 0.1.88 to 0.1.89
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.88 to 0.1.89.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.88...0.1.89)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-version: 0.1.89
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-05 23:50:25 +00:00
Shubham Chakrawar
2d9e243163 misc: Remove SGX support from Cloud Hypervisor
This commit removes the SGX support from cloud hypervisor. SGX support
was deprecated in May as part of #7090.

Signed-off-by: Shubham Chakrawar <schakrawar@crusoe.ai>
2025-09-05 18:08:36 +00:00
dependabot[bot]
7281459bf9 build: Bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-05 00:07:57 +00:00
dependabot[bot]
9bf4696b09 build: Bump libssh2-sys from 0.3.0 to 0.3.1
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.3.0 to 0.3.1.
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.3.0...libssh2-sys-0.3.1)

---
updated-dependencies:
- dependency-name: libssh2-sys
  dependency-version: 0.3.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 23:54:35 +00:00
dependabot[bot]
f7f79642ab build: Bump io-uring from 0.6.4 to 0.7.10
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.4 to 0.7.10.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

---
updated-dependencies:
- dependency-name: io-uring
  dependency-version: 0.7.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 16:49:07 +00:00
dependabot[bot]
1cc193ea3c build: Bump anstyle from 1.0.8 to 1.0.11
Bumps [anstyle](https://github.com/rust-cli/anstyle) from 1.0.8 to 1.0.11.
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.8...v1.0.11)

---
updated-dependencies:
- dependency-name: anstyle
  dependency-version: 1.0.11
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 13:14:17 +00:00
dependabot[bot]
676fb93c1a build: Bump crate-ci/typos from 1.35.7 to 1.36.1
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.7 to 1.36.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.35.7...v1.36.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:19:34 +00:00
dependabot[bot]
f7e72456b9 build: Bump anstyle-parse from 0.2.6 to 0.2.7
Bumps [anstyle-parse](https://github.com/rust-cli/anstyle) from 0.2.6 to 0.2.7.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.6...anstyle-parse-v0.2.7)

---
updated-dependencies:
- dependency-name: anstyle-parse
  dependency-version: 0.2.7
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:08:18 +00:00
dependabot[bot]
bd22190043 build: Bump uuid from 1.17.0 to 1.18.1
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.17.0 to 1.18.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.17.0...v1.18.1)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.18.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 08:12:29 +00:00
dependabot[bot]
92325fc073 build: Bump zvariant from 5.6.0 to 5.7.0
Bumps [zvariant](https://github.com/dbus2/zbus) from 5.6.0 to 5.7.0.
- [Release notes](https://github.com/dbus2/zbus/releases)
- [Commits](https://github.com/dbus2/zbus/compare/zvariant-5.6.0...zvariant-5.7.0)

---
updated-dependencies:
- dependency-name: zvariant
  dependency-version: 5.7.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-03 18:55:17 +00:00
Muminul Islam
1ca6c159ef tests: option to override default migratable version
This patch gives user an option to override the
default migratable version to any later release.
This option makes MSHV specific tests suitable for
tests since MSHV is stable after some breaking changes.
This patch is also necessary for MSHV CI.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-03 18:51:24 +00:00
dependabot[bot]
c38596d6d3 build: Bump serde_json from 1.0.120 to 1.0.143
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.120 to 1.0.143.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.120...v1.0.143)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.143
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 23:32:14 +00:00
dependabot[bot]
456f9b3871 build: Bump bitflags from 2.9.2 to 2.9.3
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.2 to 2.9.3.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.2...2.9.3)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 21:41:41 +00:00
dependabot[bot]
f68880600c build: Bump crate-ci/typos from 1.35.6 to 1.35.7
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.6 to 1.35.7.
- [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.35.6...v1.35.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 16:31:43 +00:00
Philipp Schuster
c3a809696a docs: add Safety section to unsafe functions
This step was done manually by searching for "unsafe fn" in
the code base and adding corresponding Safety sections.
`clippy::missing_safety_doc` only works for public functions
but none of the corresponding functions is public.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-02 16:31:25 +00:00
Muminul Islam
a9d6807522 block: batch submit requests for fixed VHD
Updated VHD async implementation to call the batch submit
method via the raw async IO layer.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
c4bab33020 block: Enable request submission in batch when using io_uring
Implement the batch submission function for raw disk, default it is
enabled. After parsing the requests this method is
called for better IO latency and bandwidth.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
245bce23fa block, virtio-devices: Support request submission in batch
Cache and batch IO requests after parsing all
items in the queue, improving performance—especially
for small block sizes—by reducing per-request overhead.

Introduced two methods in the AsyncIo trait for batch
submission, with implementation in the raw disk backend.
This method should be called during/after parsing all block IO requests
in the available queue. If the batch submission is not enabled, by
default it does the old way of submitting requests.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
67ab81874a block: virtio-devices: block: Clarify the return of execute_async()
Instead of returning boolean return an struct of completion status
so that it can be cached for batch submission.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
dependabot[bot]
8b2af1a2c8 build: Bump crate-ci/typos from 1.35.5 to 1.35.6
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.5 to 1.35.6.
- [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.35.5...v1.35.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 00:14:07 +00:00
dependabot[bot]
41930d11f7 build: Bump syn from 2.0.104 to 2.0.106
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.104 to 2.0.106.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.104...2.0.106)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.106
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 23:51:00 +00:00
dependabot[bot]
9c85fbb1af build: Bump proc-macro2 from 1.0.95 to 1.0.101
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.95 to 1.0.101.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.95...1.0.101)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.101
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 18:36:49 +00:00
dependabot[bot]
5357761c37 build: Bump async-io from 2.4.1 to 2.5.0
Bumps [async-io](https://github.com/smol-rs/async-io) from 2.4.1 to 2.5.0.
- [Release notes](https://github.com/smol-rs/async-io/releases)
- [Changelog](https://github.com/smol-rs/async-io/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-io/compare/v2.4.1...v2.5.0)

---
updated-dependencies:
- dependency-name: async-io
  dependency-version: 2.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-26 20:36:12 +00:00
dependabot[bot]
bec975a7fc build: Bump wait-timeout from 0.2.0 to 0.2.1
Bumps [wait-timeout](https://github.com/alexcrichton/wait-timeout) from 0.2.0 to 0.2.1.
- [Commits](https://github.com/alexcrichton/wait-timeout/compare/0.2.0...0.2.1)

---
updated-dependencies:
- dependency-name: wait-timeout
  dependency-version: 0.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-26 18:19:48 +00:00
Songqian Li
92370e8ff1 block: Using feature bits to check the read-only flag
This patch changes the read-only check using acked features bit, which
will help to check more features.

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-26 15:45:45 +00:00
dependabot[bot]
4a1eb0c485 build: Bump cc from 1.2.27 to 1.2.34
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.27 to 1.2.34.
- [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.27...cc-v1.2.34)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.34
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-26 14:47:49 +00:00
Peter Oskolkov
6e6cf099ef hypervisor: enable x2apic API in kvm on x86_64
Also tweak extended interrupt handlings, as needed.

Most credit should go to Neel Natu, who figured out the magic
bits needed to make things work and provided detailed comments.

This patch is still NOOP, as VM config allows only up to
254 vCPUs on x86_64.

Note: changes in this and related previous patches/PRs have
only been tested on Linux hosts running on Intel x86_64 hardware.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-25 23:20:19 +00:00
Anirudh Rayabharam
6e002defe2 tests: remove redundant arch check in bzimage test
test_direct_kernel_boot_bzimage runs only on x86, so the cfg!() branch
for selecting grep_cmd is unnecessary. Remove it for clarity.

Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
2025-08-24 16:37:47 +00:00
Philipp Schuster
a51998605a net_util: add Tap::if_name_as_str
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-23 08:43:33 +00:00
Philipp Schuster
b8be33dff7 net_util: tap: remove needless copy
One can call `to_vec()` anyway if one needs an owned copy. This change
further helps to prevent needless copies in upcoming changes.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-23 08:43:33 +00:00
dependabot[bot]
3864230430 build: Bump autocfg from 1.4.0 to 1.5.0
Bumps [autocfg](https://github.com/cuviper/autocfg) from 1.4.0 to 1.5.0.
- [Commits](https://github.com/cuviper/autocfg/compare/1.4.0...1.5.0)

---
updated-dependencies:
- dependency-name: autocfg
  dependency-version: 1.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-23 08:20:59 +00:00
Philipp Schuster
2c6426460e vmm: harmonize bootpath across architectures
On aarch64 and RISC-V, calling load_firmware() through load_kernel()
provides no benefit and only duplicates checks already performed in
load_payload(). load_payload() now directly invokes load_firmware() or
load_kernel(), removing unnecessary indirection and redundancy.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-22 16:41:29 +00:00
Bo Chen
1a63b4b2ff vmm: Consolidate 'load_firmware/kernel' for aarch64 and riscv
Both functions are defined separately for the two architecture with
minor differences.

* `load_firmware()`: call `arch::uefi::load_uefi` which are available on
both architecture;
* `load_kernel()`: manually align to `arch::layout::KERNEL_START` 2MB
for both architecture (e.g. no-op for `aarch64`);

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-08-21 15:32:05 +00:00
Philipp Schuster
c1f4df600f vmm: cpu_manager: massively accelerate .pause()
With 254 vCPUs, pausing now takes ~4ms instead of >254ms. This
improvement is visible when running `ch-remote pause` and is
particularly important for live migration, where every millisecond
of downtime matters.

For the wait logic, it is fine to stick to the approach of
sleeping 1ms on the first missed ACK as:

1) we have to wait anyway
2) we give time to the OS, enabling it to schedule a vCPU thread next

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-20 12:51:23 +00:00
Ruoqing He
34c5a081aa ci: Enable kvm build test on RISC-V
Enable kvm build test and clippy test on RISC-V 64-bit platform to
ensure whole projects builds properly.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-20 03:20:09 +00:00
dependabot[bot]
3bff69734e build: Bump crate-ci/typos from 1.35.4 to 1.35.5
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.4 to 1.35.5.
- [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.35.4...v1.35.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 02:57:03 +00:00
dependabot[bot]
91d15c331d build: Bump signal-hook-registry from 1.4.2 to 1.4.6
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.4.2 to 1.4.6.
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/registry-v1.4.2...registry-v1.4.6)

---
updated-dependencies:
- dependency-name: signal-hook-registry
  dependency-version: 1.4.6
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-19 18:07:05 +00:00
dependabot[bot]
e454bb629a build: Bump mintex from 0.1.3 to 0.1.4
Bumps [mintex](https://github.com/garypen/mintex) from 0.1.3 to 0.1.4.
- [Commits](https://github.com/garypen/mintex/compare/v0.1.3...v0.1.4)

---
updated-dependencies:
- dependency-name: mintex
  dependency-version: 0.1.4
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-19 12:37:27 +00:00
dependabot[bot]
09cf8fba5b build: Bump bitflags from 2.9.0 to 2.9.2
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.0 to 2.9.2.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.0...2.9.2)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-19 10:34:42 +00:00
Philipp Schuster
c34baac649 build: fix warnings from latest nightly (1.91)
The underlying problem currently causes unrelated PRs to fail.
This commit fixes that.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-18 10:52:23 +00:00
dependabot[bot]
a132001021 build: Bump smallvec from 1.13.2 to 1.15.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.13.2 to 1.15.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.13.2...v1.15.1)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-version: 1.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-16 00:16:43 +00:00
Peter Oskolkov
2c7d6be3f4 arch: don't construct mptable on x86_64 if too many CPUs
MP table is a legacy device that is incompatible
with x2apic CPU IDs exceeding 254. The Linux kernel
is perfectly happy without MP table in these cases.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-15 19:15:11 +00:00
Philipp Schuster
dd8687aebb vmm: add enum PayloadConfigError validation to improve error reporting
Currently, the following scenarios are supported by Cloud Hypervisor to
bootstrap a VM:

1. provide firmware
2. provide kernel
3. provide kernel + cmdline
4. provide kernel + initrd
5. provide kernel + cmdline + initrd

As the difference between `--firmware` and `--kernel` is not very clear
currently, especially as both use/support a Xen PVH entry, adding this
helps to identify the cause of misconfiguration.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-15 17:08:37 +00:00
Philipp Schuster
dac0638fe8 misc: fix clippy
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-15 10:55:48 +00:00
Philipp Schuster
92f415ea3f build: Bump MSRV to 1.88
This is necessary to use the let-chains feature in a
follow-up. After upgrading to Rust edition 2024, clippy
wants to collapse various if's with let-chains.

Update image to 20250815-0 since MSRV in Dockerfile is updated.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-15 10:55:48 +00:00
dependabot[bot]
78799187e8 build: Bump event-listener from 5.4.0 to 5.4.1
Bumps [event-listener](https://github.com/smol-rs/event-listener) from 5.4.0 to 5.4.1.
- [Release notes](https://github.com/smol-rs/event-listener/releases)
- [Changelog](https://github.com/smol-rs/event-listener/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/event-listener/compare/v5.4.0...v5.4.1)

---
updated-dependencies:
- dependency-name: event-listener
  dependency-version: 5.4.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-15 00:40:17 +00:00
Songqian Li
9011ff2161 tests: add ivshmem live migration test case
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
5128ee9ba6 devices, vmm: Handle ivshmem bar reprogramming properly
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
51e095c54d ci: add build and quality check for ivshmem feature
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
4c1ee0329e tests: add ivshmem integration test case
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
a09c8329fb fuzz: add ivshmem device config
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
f0febcae3d docs: add ivshmem device introduction
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
2c282a5a54 vmm: ivshmem device support
Signed-off-by: Yi Wang <foxywang@tencent.com>
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
c72414552b devices: introduce ivshmem device
This patch introduces the inter-vm shared memory(ivshmem) device
to share a memory region between multiple processes running
different guests and the host.

This patch supports the basic ivshmem functions like ivshmem-plain
in QEMU[1].

[1] https://www.qemu.org/docs/master/specs/ivshmem-spec.html

Signed-off-by: Yi Wang <foxywang@tencent.com>
Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
Songqian Li
bd17c84d3c virtio-devices: move userspace mapping to vm-device
Move UserspaceMapping to vm-device to avoid redefinition since
UserspaceMapping is used by both `virtio-devices` and `device`
crate.

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-14 22:14:34 +00:00
dependabot[bot]
55212b0437 build: Bump crate-ci/typos from 1.35.3 to 1.35.4
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.3 to 1.35.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.35.3...v1.35.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-14 17:31:00 +00:00
Peter Oskolkov
84613d4273 arch: enable x2apic mode on x86_64 if max apic id > 254
This patch builds on PRs

https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7231
https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7261

As before, the changes won't be effective until config
parsing/validation raises the vCPU limit.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-14 08:39:15 +00:00
Peter Oskolkov
34385e99f2 misc: simplify configure_vcpu() signature on x86_64
It is always called with topology provided, so there is no
need to pass topology as an Option. Simplifying the signature
makes further topology-related changes to arc/src/x86_64 module
simpler.

Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-14 08:39:15 +00:00
dependabot[bot]
10b79431f6 build: Bump linux-loader from d5f39c0 to 5fdaed8
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `d5f39c0` to `5fdaed8`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](d5f39c09d5...5fdaed87dd)

---
updated-dependencies:
- dependency-name: linux-loader
  dependency-version: 5fdaed87ddafc89d6abf0b50195a12d19133000d
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 23:50:30 +00:00
dependabot[bot]
3d5e5f318b build: Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 18:11:18 +00:00
dependabot[bot]
68a1bf38e5 build: Bump gdbstub_arch from 0.3.0 to 0.3.2
Bumps [gdbstub_arch](https://github.com/daniel5151/gdbstub) from 0.3.0 to 0.3.2.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/commits)

---
updated-dependencies:
- dependency-name: gdbstub_arch
  dependency-version: 0.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 07:31:57 +00:00
Peter Oskolkov
6e0403a959 misc: make topology a 4-tuple of u16s
This is the second patch in a series intended to let Cloud Hypervisor
support more than 255 vCPUs in guest VMs; the first patch/commit is
https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7231

At the moment, CPU topology in Cloud Hypervisor is using
u8 for components, and somewhat inconsistently:

- struct CpuTopology in vmm/src/vm_config.rs uses four components
  (threads_per_core, cores_per_die, dies_per_package, packages);

- when passed around as a tuple, it is a 3-tuple of u8, with
  some inconsistency:

- in get_x2apic_id in arch/src/x86_64/mod.rs  the three u8
    are assumed to be (correctly)
    threads_per_core, cores_per_die, and dies_per_package, but

- in get_vcpu_topology() in vmm/src/cpu.rs the three-tuple is
    threads_per_core, cores_per_die, and packages (dies_per_package
    is assumed to always be one? not clear).

So for consistency, a 4-tuple is always passed around.

In addition, the types of the tuple components is changed from u8 to
u16, as on x86_64 subcomponents can consume up to 16 bits.

Again, config constraints have not been changed, so this patch
is mostly NOOP.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-13 07:31:22 +00:00
dependabot[bot]
364a0972f0 build: Bump rustversion from 1.0.21 to 1.0.22
Bumps [rustversion](https://github.com/dtolnay/rustversion) from 1.0.21 to 1.0.22.
- [Release notes](https://github.com/dtolnay/rustversion/releases)
- [Commits](https://github.com/dtolnay/rustversion/compare/1.0.21...1.0.22)

---
updated-dependencies:
- dependency-name: rustversion
  dependency-version: 1.0.22
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 23:57:55 +00:00
dependabot[bot]
9283f87f90 build: Bump igvm from 01daa63 to dff4ebc
Bumps [igvm](https://github.com/microsoft/igvm) from `01daa63` to `dff4ebc`.
- [Release notes](https://github.com/microsoft/igvm/releases)
- [Commits](01daa631a5...dff4ebc9c5)

---
updated-dependencies:
- dependency-name: igvm
  dependency-version: dff4ebc9c5bd16707ff75de26ccabe2d4dfdbcd8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 22:06:14 +00:00
dependabot[bot]
458721629c build: Bump zvariant from 5.5.3 to 5.6.0
Bumps [zvariant](https://github.com/dbus2/zbus) from 5.5.3 to 5.6.0.
- [Release notes](https://github.com/dbus2/zbus/releases)
- [Commits](https://github.com/dbus2/zbus/compare/zvariant-5.5.3...zvariant-5.6.0)

---
updated-dependencies:
- dependency-name: zvariant
  dependency-version: 5.6.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 18:05:31 +00:00
dependabot[bot]
d70d132a5c build: Bump errno from 0.3.12 to 0.3.13
Bumps [errno](https://github.com/lambda-fairy/rust-errno) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.12...v0.3.13)

---
updated-dependencies:
- dependency-name: errno
  dependency-version: 0.3.13
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 11:29:15 +00:00
dependabot[bot]
35121c44db build: Bump slab from 0.4.9 to 0.4.11
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.9 to 0.4.11.
- [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.9...v0.4.11)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.11
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 07:44:17 +00:00
Peter Oskolkov
aa8e9cd91a misc: Change cpu ID type from u8 to u32
This is the first change to Cloud Hypervisor in a series of changes
intended to increase the max number of supported vCPUs in guest VMs,
which is currently limited to 255 (254 on x86_64).

No user-visible/behavior changes are expected as a result of
applying this patch, as the type of boot_cpus and related
fields in config structs remains u8 for now, and all configuration
validations remain the same.

Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Neel Natu <neelnatu@google.com>
Signed-off-by: Ofir Weisse <oweisse@google.com>
Signed-off-by: Peter Oskolkov <posk@google.com>
2025-08-11 20:31:50 +00:00
Alex Orozco
5d478c534e tests: Add fw_cfg device integration test
This test verifies that we can see custom items added to the fw_cfg
device from inside the guest

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
a70c1b38e7 devices: Add fw_cfg cli options
This allows us to enable/disable the fw_cfg device via the cli

We can also now upload files into the guest vm using fw_cfg_items
via the cli

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
971f552e09 vmm: Add acpi table for fw_cfg device
This allows the fw_cfg device to be recognized by the guest linux
kernel. This becomes more relavnt in the following cl where I add
the option to load files into the guest via fw_cfg. The Linux kernel
already has a fw_cfg driver that will automatically load these files
under /sys when CONFIG_FW_CFG_SYSFS is enabled in the kernel config

For arm we must add fw_cfg to the devices tree

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
edee53ac1a devices: Implement DMA for fw_cfg device
We pass a reference to the guest memory when we create the device
in DeviceManager. This allows us to access the guest memory for DMA.

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
1f51e4525b devices: Add acpi tables to fw_cfg
The acpi tables are created in the same place the acpi tables would be
created for the regular bootflow, except here we add them to the
fw_cfg device to be measured by the fw and then the fw will put the
acpi tables into memory.

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
f0b69d56d0 devices: Add e820/memory_map to fw_cfg device
We build the memory map in the fw_cfg device based on the memory size.

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
623fadfa9d devices: Add kernel cmdline, kernel, and initramfs to fw_cfg device
The kernel and initramfs are passed to the fw_cfg device as
file references. The cmdline is passed directly.

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Alex Orozco
777b7ee11e devices: Add fw_cfg device
Here we add the fw_cfg device as a legacy device to the device manager.
It is guarded behind a fw_cfg flag in vmm at creation of the
DeviceManager. In this cl we implement the fw_cfg device with one
function (signature).

Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-11 17:29:51 +00:00
Philipp Schuster
5226ceb974 misc: switch error output from error! back to stderr
This partially reverts
ed8f347fe6 from #7183 and
6277d7d5f2 from #7201.

# Output how it was merged for v47 (#7066)
```
Error: Cloud Hypervisor exited with the following chain of errors:
 0: Error booting VM
 1: The VM could not boot
 2: Error manipulating firmware file
 3: No such file or directory (os error 2)

Debug Info: VmBoot(VmBoot(FirmwareFile(Os { code: 2, kind: NotFound, message: "No such file or directory" })))
```

# Output after #7183 and #7201
```
cloud-hypervisor: 31.385730ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:27 -- Error: Cloud Hypervisor exited with the following chain of errors:
cloud-hypervisor: 31.417961ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 --   0: Error booting VM
cloud-hypervisor: 31.448078ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 --   1: The VM could not boot
cloud-hypervisor: 31.486711ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 --   2: Error manipulating firmware file
cloud-hypervisor: 31.513331ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 --   3: No such file or directory (os error 2)
cloud-hypervisor: 31.548037ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:44 --
cloud-hypervisor: 31.568045ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:45 -- Debug Info: VmBoot(VmBoot(FirmwareFile(Os { code: 2, kind: NotFound, message: "No such file or directory" })))
```

The "proper logger" has indeed the advantage that messages can
be gracefully redirected to log files etc. However, this makes the
error message hardly readable.

Therefore, I propose to use error!() only for runtime errors messages
but not a pretty-printed version of those.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-08-11 10:41:11 +00:00
Ruoqing He
17195e1a46 vmm: Enable firmware boot for riscv64
Implement firmware boot (UEFI boot) for riscv64 architecture.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-11 10:10:27 +00:00
Ruoqing He
0df4b1ac4f vmm: Define riscv64 UEFI Error
Error::UefiLoad is required for load_firmware to propagate errors
encountered, define it for riscv64.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-11 10:10:27 +00:00
Ruoqing He
2e0ec8095c vmm: Enable uefi_flash field for riscv64
uefi_flash field in memory_manager is required for uefi loading and
booting, enable it for riscv64 architecture.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-11 10:10:27 +00:00
Ruoqing He
ef2bbe5012 arch: riscv: Introduce UEFI module
Provide Error definitions and load_uefi to be referenced while loading
firmware.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-11 10:10:27 +00:00
Ruoqing He
2524b015b8 arch: riscv: Introduce UEFI related constants
Set UEFI_START and UEFI_SIZE for riscv64 layout.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-08-11 10:10:27 +00:00
Demi Marie Obenour
9825397350 misc: option_parser: allow quoting special characters
The option parser did not allow quoting any special characters, which
means that some strings could not be passed via command-line options.
Fix this by allowing double quotes to quote all the special characters,
such as '@', ',', '[', and ']'.  '"' can be escaped by doubling it.  The
implementation uses some tricks to stay modular.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2025-08-10 11:25:24 +00:00
Songqian Li
a637940be7 ci: Fix link check failed
### Errors in src/main.rs

* [404] <https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new
/n> | Rejected status code (this depends on your "accept" configuration)
: Not Found

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-10 09:14:07 +00:00
Songqian Li
684fb1dfce ci: Improve link checker conditions
Link checker excludes checks on local links and links with variables.

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-10 09:14:07 +00:00
dependabot[bot]
e718e0ad36 build: Bump async-trait from 0.1.86 to 0.1.88
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.86 to 0.1.88.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.86...0.1.88)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-version: 0.1.88
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-09 01:23:59 +00:00
dependabot[bot]
f87772cd36 build: Bump crate-ci/typos from 1.35.2 to 1.35.3
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.2 to 1.35.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.35.2...v1.35.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-09 00:29:54 +00:00
dependabot[bot]
0d9a941a2c build: Bump redox_users from 0.5.0 to 0.5.2
Bumps redox_users from 0.5.0 to 0.5.2.

---
updated-dependencies:
- dependency-name: redox_users
  dependency-version: 0.5.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 04:58:07 +00:00
dependabot[bot]
4f4940b02a build: Bump crate-ci/typos from 1.35.1 to 1.35.2
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.35.1 to 1.35.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.35.1...v1.35.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 00:18:56 +00:00
Songqian Li
0bfa160360 hypervisor: Replacing pdf link with new available link
Replacing pdf link with new available link to fix the failed CI.

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-07 16:53:59 +00:00
Songqian Li
530719a57a build: Bump MSRV to 1.87.0
rustc 1.90.0-beta.1 (788da80fc 2025-08-04) suggests using library
feature `unsigned_is_multiple_of`. It is stabled in Rust 1.87.0.

Update image to 20250807-0 since MSRV in Dockerfile is updated.

Signed-off-by: Songqian Li <sionli@tencent.com>
Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-08-07 16:53:59 +00:00
Songqian Li
cd2c43b489 misc: Fix beta clippy errors
Fix clippy error: "error: manual implementation of `.is_multiple_of()
`" from rustc 1.90.0-beta.1 (788da80fc 2025-08-04).

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-07 16:53:59 +00:00
Bo Chen
394fd230b0 vmm: acpi: Clarify the return of 'create_acpi_tables_internal'
Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-08-06 21:11:27 +00:00
Bo Chen
abcec231eb vmm: acpi: Clarify variable naming in 'create_acpi_tables_internal'
When generating ACPI tables, we are not using "offset", instead we
are using (guest physical) addresses.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-08-06 21:11:27 +00:00
Bo Chen
cda1ea53a5 vmm: acpi: Make 'create_acpi_tables' more flexible
Now 'create_acpi_tables_internal()' can generate ACPI tables with
different dsdt offset, so that it can be reused for generating ACPI
tables for `fw_cfg`.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Alex Orozco <alexorozco@google.com>
2025-08-06 21:11:27 +00:00
dependabot[bot]
e2d2b2f2f0 build: Bump rand from 0.9.1 to 0.9.2
Bumps [rand](https://github.com/rust-random/rand) from 0.9.1 to 0.9.2.
- [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.1...rand_core-0.9.2)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 12:12:45 +00:00
dependabot[bot]
9ee3b29a11 build: Bump crate-ci/typos from 1.34.0 to 1.35.1
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.34.0 to 1.35.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.34.0...v1.35.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 08:15:40 +00:00
dependabot[bot]
eb147cb3cc build: Bump rustc-demangle from 0.1.24 to 0.1.26
Bumps [rustc-demangle](https://github.com/rust-lang/rustc-demangle) from 0.1.24 to 0.1.26.
- [Release notes](https://github.com/rust-lang/rustc-demangle/releases)
- [Changelog](https://github.com/rust-lang/rustc-demangle/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/rustc-demangle/compare/0.1.24...rustc-demangle-v0.1.26)

---
updated-dependencies:
- dependency-name: rustc-demangle
  dependency-version: 0.1.26
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 07:06:06 +00:00
dependabot[bot]
b630b22ed9 build: Bump landlock from 0.4.0 to 0.4.2
Bumps [landlock](https://github.com/landlock-lsm/rust-landlock) from 0.4.0 to 0.4.2.
- [Release notes](https://github.com/landlock-lsm/rust-landlock/releases)
- [Changelog](https://github.com/landlock-lsm/rust-landlock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/landlock-lsm/rust-landlock/compare/v0.4.0...v0.4.2)

---
updated-dependencies:
- dependency-name: landlock
  dependency-version: 0.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-02 00:20:14 +00:00
dependabot[bot]
a7645ae9d6 build: Bump async-process from 2.3.0 to 2.4.0
Bumps [async-process](https://github.com/smol-rs/async-process) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/smol-rs/async-process/releases)
- [Changelog](https://github.com/smol-rs/async-process/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-process/compare/v2.3.0...v2.4.0)

---
updated-dependencies:
- dependency-name: async-process
  dependency-version: 2.4.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 00:05:35 +00:00
dependabot[bot]
254db85a33 build: Bump anyhow from 1.0.94 to 1.0.98
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.94 to 1.0.98.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.94...1.0.98)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.98
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-31 03:29:16 +00:00
dependabot[bot]
16b0e08482 build: Bump tj-actions/changed-files from 40 to 46 in /.github/workflows
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 40 to 46.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v40...v46)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: '46'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-31 00:01:11 +00:00
Shubham Chakrawar
8a37e154db ci: Prevent link checker rate limits
Optimize lychee workflow to check only changed
files in pull requests, avoiding excessive API
calls to prevent rate limits.

Fixes #7056

Signed-off-by: Shubham Chakrawar <schakrawar@crusoe.ai>
2025-07-30 22:30:36 +00:00
dependabot[bot]
003e89e8cd build: Bump anstream from 0.6.15 to 0.6.19
Bumps [anstream](https://github.com/rust-cli/anstyle) from 0.6.15 to 0.6.19.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.15...anstream-v0.6.19)

---
updated-dependencies:
- dependency-name: anstream
  dependency-version: 0.6.19
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 00:37:23 +00:00
Muminul Islam
8e010f1aa3 vmm: don't configure system if rsdp is not available
In case of CVM guest rsdp is set to none. Unwrapping it
make the vmm crashed. Don't call configure system if the
rsdb address is none.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-07-29 15:55:06 +00:00
dependabot[bot]
7c631b2d1b build: Bump toml_datetime from 0.6.8 to 0.6.11
Bumps [toml_datetime](https://github.com/toml-rs/toml) from 0.6.8 to 0.6.11.
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.6.8...toml_datetime-v0.6.11)

---
updated-dependencies:
- dependency-name: toml_datetime
  dependency-version: 0.6.11
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-29 05:33:35 +00:00
dependabot[bot]
ba962a30d5 build: Bump r-efi from 5.2.0 to 5.3.0
Bumps [r-efi](https://github.com/r-efi/r-efi) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/r-efi/r-efi/releases)
- [Changelog](https://github.com/r-efi/r-efi/blob/main/NEWS.md)
- [Commits](https://github.com/r-efi/r-efi/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: r-efi
  dependency-version: 5.3.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-29 03:50:24 +00:00
Oliver Anderson
8c136041cb build: Use workspace dependencies
Many of the workspace members in the Cloud-hypervisor workspace share
common dependencies. Making these workspace dependencies reduces
duplication and improves maintainability.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP oliver.anderson@sap.com
2025-07-28 20:19:27 +00:00
dependabot[bot]
b0bf889d58 build: Bump serde_with from 3.9.0 to 3.14.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.9.0 to 3.14.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.9.0...v3.14.0)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-26 00:03:54 +00:00
Lucas Grosche
2c3e6cd93d docs: Add Windows 11 support information
The current documentation only mentions Windows
server support. Since only minimal adjustments
are needed for Windows 11 support, these were
added where applicable.

Also contains whitespace fixes, adds missing `\`
in example code and adds more cross references.

Signed-off-by: Lucas Grosche <lucas.grosche@cyberus-technology.de>
2025-07-25 22:30:59 +00:00
dependabot[bot]
985dcfbf3e build: Bump async-signal from 0.2.11 to 0.2.12
Bumps [async-signal](https://github.com/smol-rs/async-signal) from 0.2.11 to 0.2.12.
- [Release notes](https://github.com/smol-rs/async-signal/releases)
- [Changelog](https://github.com/smol-rs/async-signal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-signal/compare/v0.2.11...v0.2.12)

---
updated-dependencies:
- dependency-name: async-signal
  dependency-version: 0.2.12
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 00:38:42 +00:00
Oliver Anderson
511a100842 tpm: Use the same log version as other workspace members
The other workspace members in the Cloud-hypervisor workspace
currently declare log version 0.4.22, but the tpm crate
has an older version. This inconsistency is addressed by this PR
which opens the door for declaring log as a workspace dependency.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP oliver.anderson@sap.com
2025-07-24 23:52:45 +00:00
Wei Liu
8a26380657 performance-metrics: Add all supported formats to block tests
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 23:37:09 +00:00
Wei Liu
76d8d47f6a performance-metrics: Initialize tests after setting overrides
No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 23:37:09 +00:00
dependabot[bot]
423280fb96 build: Bump enumflags2 from 0.7.10 to 0.7.12
Bumps [enumflags2](https://github.com/meithecatte/enumflags2) from 0.7.10 to 0.7.12.
- [Release notes](https://github.com/meithecatte/enumflags2/releases)
- [Commits](https://github.com/meithecatte/enumflags2/compare/v0.7.10...v0.7.12)

---
updated-dependencies:
- dependency-name: enumflags2
  dependency-version: 0.7.12
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-24 16:47:13 +00:00
Wei Liu
5f2392c095 tests: Avoid repeatedly downloading files from GitHub
Running one or two tests in a tight loop can cause the download
functions to quickly hit GitHub's API rate limit. That causes the test
script to fail for no apparent reason.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 16:46:43 +00:00
Wei Liu
2d9fc3beb6 tests: Reenable test_virtio_block_dynamic_vhdx_expand
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 01:06:12 +00:00
Wei Liu
4cae96f070 tests: Avoid races in the VHDX expansion test
Generate the data disk under a temporary directory so that multiple
instances of the test suites can run at the same time.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 01:06:12 +00:00
Wei Liu
f6568042ce tests: Fix an error message in VHDX expansion test
The VHDX image is generated directly, not converted from a RAW image.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-24 01:06:12 +00:00
Oliver Anderson
2ae5b2567b tpm: Use the same libc crate version as other workspace members
The other workspace members in the Cloud-hypervisor workspace
currently declare libc crate version 0.2.167, but the tpm crate
has an older version. This inconsistency is addressed by this PR
which opens the door for declaring libc as a workspace dependency.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP oliver.anderson@sap.com
2025-07-24 01:05:08 +00:00
Oliver Anderson
6d70c570f3 tpm: Use the same anyhow version as other workspace members
The other workspace members in the Cloud-hypervisor workspace
currently declare anyhow version 1.0.94, but the tpm crate
has an older version. This inconsistency is addressed by this PR
which opens the door for declaring anyhow as a workspace dependency.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP oliver.anderson@sap.com
2025-07-23 16:29:34 +00:00
Wei Liu
930a911862 block: Simplify AsyncAdaptor
It shouldn't be necessary to lock the file for the adaptor. This removes
two layers of indirection for QcowDiskSync and VhdxDiskSync.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-22 22:00:35 +00:00
Bo Chen
03b22a510d tests: Disable 'test_virtio_block_dynamic_vhdx_expand'
This issue is tracked via #7209.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-07-22 21:06:54 +00:00
241 changed files with 9945 additions and 5771 deletions

View File

@@ -1,21 +1,66 @@
version: 2
updates:
- package-ecosystem: cargo
directory: "/"
directories:
- "/"
- "/fuzz"
schedule:
interval: daily
open-pull-requests-limit: 1
interval: weekly
allow:
- dependency-type: direct
- dependency-type: indirect
- dependency-name: "acpi_tables"
- dependency-name: "kvm-bindings"
- dependency-name: "kvm-ioctls"
- dependency-name: "linux-loader"
- dependency-name: "mshv-bindings"
- dependency-name: "mshv-ioctls"
- dependency-name: "seccompiler"
- dependency-name: "vfio-bindings"
- dependency-name: "vfio-ioctls"
- dependency-name: "vfio_user"
- dependency-name: "vhost"
- dependency-name: "vhost-user-backend"
- dependency-name: "virtio-bindings"
- dependency-name: "virtio-queue"
- dependency-name: "vm-fdt"
- dependency-name: "vm-memory"
- dependency-name: "vmm-sys-util"
groups:
rust-vmm:
patterns:
- "*"
- package-ecosystem: cargo
directory: "/fuzz"
directories:
- "/"
- "/fuzz"
schedule:
interval: daily
open-pull-requests-limit: 1
interval: weekly
allow:
- dependency-type: direct
- dependency-type: indirect
- dependency-type: all
ignore:
- dependency-name: "acpi_tables"
- dependency-name: "kvm-bindings"
- dependency-name: "kvm-ioctls"
- dependency-name: "linux-loader"
- dependency-name: "mshv-bindings"
- dependency-name: "mshv-ioctls"
- dependency-name: "seccompiler"
- dependency-name: "vfio-bindings"
- dependency-name: "vfio-ioctls"
- dependency-name: "vfio_user"
- dependency-name: "vhost"
- dependency-name: "vhost-user-backend"
- dependency-name: "virtio-bindings"
- dependency-name: "virtio-queue"
- dependency-name: "vm-fdt"
- dependency-name: "vm-memory"
- dependency-name: "vmm-sys-util"
groups:
non-rust-vmm:
patterns:
- "*"
# Makes it possible to have another config for the same directory.
# https://github.com/dependabot/dependabot-core/issues/1778#issuecomment-1988140219
target-branch: main
- package-ecosystem: github-actions
directory: "/"
schedule:

View File

@@ -10,7 +10,7 @@ jobs:
name: Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions-rust-lang/audit@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -15,13 +15,13 @@ jobs:
- stable
- beta
- nightly
- "1.83.0"
- "1.88.0"
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -52,6 +52,12 @@ jobs:
- name: Build (default features + pvmemcontrol)
run: cargo rustc --locked --bin cloud-hypervisor --features "pvmemcontrol" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Build (default features + fw_cfg)
run: cargo rustc --locked --bin cloud-hypervisor --features "fw_cfg" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Build (default features + ivshmem)
run: cargo rustc --locked --bin cloud-hypervisor --features "ivshmem" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Build (mshv)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states

View File

@@ -6,9 +6,9 @@ jobs:
name: DCO Check ("Signed-Off-By")
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up Python 3.x
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Check DCO

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -41,7 +41,7 @@ jobs:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# generate Docker tags based on the following events/attributes
tags: |
type=raw,value=20250412-0
type=raw,value=20250815-0
type=sha
- name: Build and push

View File

@@ -19,7 +19,7 @@ jobs:
RUSTFLAGS: -D warnings
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Rust toolchain (${{ matrix.rust }})
uses: dtolnay/rust-toolchain@stable
with:

View File

@@ -18,7 +18,7 @@ jobs:
RUSTFLAGS: -D warnings
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Rust toolchain (${{ matrix.rust }})
uses: dtolnay/rust-toolchain@stable
with:

View File

@@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Set up Python 3.10
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install dependencies

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Lint Dockerfile
uses: hadolint/hadolint-action@master

View File

@@ -13,7 +13,7 @@ jobs:
- name: Fix workspace permissions
run: sudo chown -R runner:runner ${GITHUB_WORKSPACE}
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run unit tests (musl)

View File

@@ -12,7 +12,7 @@ jobs:
METRICS_PUBLISH_KEY: ${{ secrets.METRICS_PUBLISH_KEY }}
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run metrics tests

View File

@@ -13,7 +13,7 @@ jobs:
steps:
- name: Code checkout
if: ${{ github.event_name != 'pull_request' }}
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run rate-limiter integration tests

View File

@@ -16,7 +16,7 @@ jobs:
run: sudo chown -R runner:runner ${GITHUB_WORKSPACE}
- name: Code checkout
if: ${{ github.event_name != 'pull_request' }}
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run VFIO integration tests

View File

@@ -11,7 +11,7 @@ jobs:
steps:
- name: Code checkout
if: ${{ github.event_name != 'pull_request' }}
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Docker

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- name: Code checkout
if: ${{ github.event_name != 'pull_request' || (matrix.runner == 'garm-jammy' && matrix.libc == 'gnu') }}
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Docker

View File

@@ -1,16 +1,45 @@
name: Link Check (lychee)
on:
pull_request
on: pull_request
jobs:
link_check:
name: Link Check
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# Fetch the entire history so git diff can compare against the base branch
fetch-depth: 0
- name: Get changed files in PR
id: changed-files
uses: tj-actions/changed-files@v47 # Using a dedicated action for robustness
with:
# Compare the HEAD of the PR with the merge-base (where the PR branches off)
base_sha: ${{ github.event.pull_request.base.sha }}
- name: Link Availability Check
# NEW STEP: Print all changed-files outputs for verification
- name: Verify Changed Files
run: |
echo "--- tj-actions/changed-files Outputs ---"
echo "any_changed: ${{ steps.changed-files.outputs.any_changed }}"
echo "all_changed_files: ${{ steps.changed-files.outputs.all_changed_files }}"
echo "added_files: ${{ steps.changed-files.outputs.added_files }}"
echo "modified_files: ${{ steps.changed-files.outputs.modified_files }}"
echo "deleted_files: ${{ steps.changed-files.outputs.deleted_files }}"
echo "renamed_files: ${{ steps.changed-files.outputs.renamed_files }}"
echo "----------------------------------------"
# This will also show if the all_changed_files string is empty or not
if [ -n "${{ steps.changed-files.outputs.all_changed_files }}" ]; then
echo "Detected changes: all_changed_files output is NOT empty."
else
echo "No changes detected: all_changed_files output IS empty."
fi
- name: Link Availability Check (Diff Only)
# MODIFIED: Only run lychee if the 'all_changed_files' output is not an empty string
if: ${{ steps.changed-files.outputs.all_changed_files != '' }}
uses: lycheeverse/lychee-action@master
with:
args: --verbose --config .lychee.toml .
# Pass the space-separated list of changed files to lychee
args: --verbose --config .lychee.toml ${{ steps.changed-files.outputs.all_changed_files }}
failIfEmpty: false
fail: true

237
.github/workflows/mshv-infra.yaml vendored Normal file
View File

@@ -0,0 +1,237 @@
name: MSHV Infra Setup
on:
workflow_call:
inputs:
ARCH:
description: 'Architecture for the VM'
required: true
type: string
KEY:
description: 'SSH Key Name'
required: true
type: string
OS_DISK_SIZE:
description: 'OS Disk Size in GB'
required: true
type: string
RG:
description: 'Resource Group Name'
required: true
type: string
VM_SKU:
description: 'VM SKU'
required: true
type: string
secrets:
MI_CLIENT_ID:
required: true
RUNNER_RG:
required: true
STORAGE_ACCOUNT_PATHS:
required: true
ARCH_SOURCE_PATH:
required: true
USERNAME:
required: true
outputs:
PRIVATE_IP:
description: 'Private IP of the VM'
value: ${{ jobs.infra-setup.outputs.PRIVATE_IP }}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
infra-setup:
name: ${{ inputs.ARCH }} VM Provision
runs-on: mshv
continue-on-error: true
outputs:
PRIVATE_IP: ${{ steps.get-vm-ip.outputs.PRIVATE_IP }}
steps:
- name: Install & login to AZ CLI
env:
MI_CLIENT_ID: ${{ secrets.MI_CLIENT_ID }}
run: |
set -e
echo "Installing Azure CLI if not already installed"
if ! command -v az &>/dev/null; then
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
else
echo "Azure CLI already installed"
fi
az --version
echo "Logging into Azure CLI using Managed Identity"
az login --identity --client-id ${MI_CLIENT_ID}
- name: Get Location
id: get-location
env:
SKU: ${{ inputs.VM_SKU }}
STORAGE_ACCOUNT_PATHS: ${{ secrets.STORAGE_ACCOUNT_PATHS }}
run: |
set -e
# Extract vCPU count from SKU (e.g., "Standard_D2s_v3" => 2)
vcpu=$(echo "$SKU" | sed -n 's/^Standard_[A-Za-z]\+\([0-9]\+\).*/\1/p')
if [[ -z "$vcpu" ]]; then
echo "Cannot extract vCPU count from SKU: $SKU"
exit 1
fi
SUPPORTED_LOCATIONS=$(echo "$STORAGE_ACCOUNT_PATHS" | jq -r 'to_entries[] | .key')
for location in $SUPPORTED_LOCATIONS; do
family=$(az vm list-skus --size "$SKU" --location "$location" --resource-type "virtualMachines" --query '[0].family' -o tsv)
if [[ -z "$family" ]]; then
echo "Cannot determine VM family for SKU: $SKU in $location"
continue
fi
usage=$(az vm list-usage --location "$location" --query "[?name.value=='$family'] | [0]" -o json)
current=$(echo "$usage" | jq -r '.currentValue')
limit=$(echo "$usage" | jq -r '.limit')
if [[ $((limit - current)) -ge $vcpu ]]; then
echo "Sufficient quota found in $location"
echo "location=$location" >> "$GITHUB_OUTPUT"
exit 0
fi
done
echo "No location found with sufficient vCPU quota for SKU: $SKU"
exit 1
- name: Create Resource Group
id: rg-setup
env:
LOCATION: ${{ steps.get-location.outputs.location }}
RG: ${{ inputs.RG }}
STORAGE_ACCOUNT_PATHS: ${{ secrets.STORAGE_ACCOUNT_PATHS }}
run: |
set -e
echo "Creating Resource Group: $RG"
# Create the resource group
echo "Creating resource group in location: ${LOCATION}"
az group create --name ${RG} --location ${LOCATION}
echo "Resource group created successfully."
- name: Generate SSH Key
id: generate-ssh-key
env:
KEY: ${{ inputs.KEY }}
run: |
set -e
echo "Generating SSH key: $KEY"
mkdir -p ~/.ssh
ssh-keygen -t rsa -b 4096 -f ~/.ssh/${KEY} -N ""
- name: Create VM
id: vm-setup
env:
KEY: ${{ inputs.KEY }}
LOCATION: ${{ steps.get-location.outputs.location }}
OS_DISK_SIZE: ${{ inputs.OS_DISK_SIZE }}
RG: ${{ inputs.RG }}
RUNNER_RG: ${{ secrets.RUNNER_RG }}
USERNAME: ${{ secrets.USERNAME }}
VM_SKU: ${{ inputs.VM_SKU }}
VM_IMAGE_NAME: ${{ inputs.ARCH }}_${{ steps.get-location.outputs.location }}_image
VM_NAME: ${{ inputs.ARCH }}_${{ steps.get-location.outputs.location }}_${{ github.run_id }}
run: |
set -e
echo "Creating $VM_SKU VM: $VM_NAME"
# Extract subnet ID from the runner VM
echo "Retrieving subnet ID..."
SUBNET_ID=$(az network vnet list --resource-group ${RUNNER_RG} --query "[?contains(location, '${LOCATION}')].{SUBNETS:subnets}" | jq -r ".[0].SUBNETS[0].id")
if [[ -z "${SUBNET_ID}" ]]; then
echo "ERROR: Failed to retrieve Subnet ID."
exit 1
fi
# Extract image ID from the runner VM
echo "Retrieving image ID..."
IMAGE_ID=$(az image show --resource-group ${RUNNER_RG} --name ${VM_IMAGE_NAME} --query "id" -o tsv)
if [[ -z "${IMAGE_ID}" ]]; then
echo "ERROR: Failed to retrieve Image ID."
exit 1
fi
# Create VM
az vm create \
--resource-group ${RG} \
--name ${VM_NAME} \
--subnet ${SUBNET_ID} \
--size ${VM_SKU} \
--location ${LOCATION} \
--image ${IMAGE_ID} \
--os-disk-size-gb ${OS_DISK_SIZE} \
--public-ip-sku Standard \
--storage-sku Premium_LRS \
--public-ip-address "" \
--admin-username ${USERNAME} \
--ssh-key-value ~/.ssh/${KEY}.pub \
--security-type Standard \
--output json
echo "VM creation process completed successfully."
- name: Get VM Private IP
id: get-vm-ip
env:
RG: ${{ inputs.RG }}
VM_NAME: ${{ inputs.ARCH }}_${{ steps.get-location.outputs.location }}_${{ github.run_id }}
run: |
set -e
echo "Retrieving VM Private IP address..."
# Retrieve VM Private IP address
PRIVATE_IP=$(az vm show -g ${RG} -n ${VM_NAME} -d --query privateIps -o tsv)
if [[ -z "$PRIVATE_IP" ]]; then
echo "ERROR: Failed to retrieve private IP address."
exit 1
fi
echo "PRIVATE_IP=$PRIVATE_IP" >> $GITHUB_OUTPUT
- name: Wait for SSH availability
env:
KEY: ${{ inputs.KEY }}
PRIVATE_IP: ${{ steps.get-vm-ip.outputs.PRIVATE_IP }}
USERNAME: ${{ secrets.USERNAME }}
run: |
echo "Waiting for SSH to be accessible..."
timeout 120 bash -c 'until ssh -o StrictHostKeyChecking=no -i ~/.ssh/${KEY} ${USERNAME}@${PRIVATE_IP} "exit" 2>/dev/null; do sleep 5; done'
echo "VM is accessible!"
- name: Remove Old Host Key
env:
PRIVATE_IP: ${{ steps.get-vm-ip.outputs.PRIVATE_IP }}
run: |
set -e
echo "Removing the old host key"
ssh-keygen -R $PRIVATE_IP
- name: SSH into VM and Install Dependencies
env:
KEY: ${{ inputs.KEY }}
PRIVATE_IP: ${{ steps.get-vm-ip.outputs.PRIVATE_IP }}
USERNAME: ${{ secrets.USERNAME }}
run: |
set -e
ssh -i ~/.ssh/${KEY} -o StrictHostKeyChecking=no ${USERNAME}@${PRIVATE_IP} << EOF
set -e
echo "Logged in successfully."
echo "Installing dependencies..."
sudo tdnf install -y git moby-engine moby-cli clang llvm pkg-config make gcc glibc-devel
echo "Installing Rust..."
curl -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable --profile default -y
export PATH="\$HOME/.cargo/bin:\$PATH"
cargo --version
sudo mkdir -p /etc/docker/
echo '{"default-ulimits":{"nofile":{"Hard":65535,"Name":"nofile","Soft":65535}}}' | sudo tee /etc/docker/daemon.json
sudo systemctl stop docker
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
sudo systemctl start docker
sudo groupadd -f docker
sudo usermod -a -G docker ${USERNAME}
sudo systemctl restart docker
EOF

109
.github/workflows/mshv-integration.yaml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Cloud Hypervisor Tests (MSHV) (x86_64)
on: [pull_request_target, merge_group]
jobs:
infra-setup:
name: MSHV Infra Setup (x86_64)
uses: ./.github/workflows/mshv-infra.yaml
with:
ARCH: x86_64
KEY: azure_key_${{ github.run_id }}
OS_DISK_SIZE: 512
RG: MSHV-INTEGRATION-${{ github.run_id }}
VM_SKU: Standard_D16s_v5
secrets:
MI_CLIENT_ID: ${{ secrets.MSHV_MI_CLIENT_ID }}
RUNNER_RG: ${{ secrets.MSHV_RUNNER_RG }}
STORAGE_ACCOUNT_PATHS: ${{ secrets.MSHV_STORAGE_ACCOUNT_PATHS }}
ARCH_SOURCE_PATH: ${{ secrets.MSHV_X86_SOURCE_PATH }}
USERNAME: ${{ secrets.MSHV_USERNAME }}
run-tests:
name: Integration Tests (x86_64)
needs: infra-setup
if: ${{ always() && needs.infra-setup.result == 'success' }}
runs-on: mshv
continue-on-error: true
steps:
- name: Run integration tests
timeout-minutes: 60
env:
KEY: azure_key_${{ github.run_id }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO_URL: https://github.com/cloud-hypervisor/cloud-hypervisor.git
REPO_DIR: cloud-hypervisor
PRIVATE_IP: ${{ needs.infra-setup.outputs.PRIVATE_IP }}
RG: MSHV-${{ github.run_id }}
USERNAME: ${{ secrets.MSHV_USERNAME }}
run: |
set -e
echo "Connecting to the VM via SSH..."
ssh -i ~/.ssh/${KEY} -o StrictHostKeyChecking=no ${USERNAME}@${PRIVATE_IP} << EOF
set -e
echo "Logged in successfully."
export PATH="\$HOME/.cargo/bin:\$PATH"
if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then
git clone --depth 1 "$REPO_URL" "$REPO_DIR"
cd "$REPO_DIR"
git fetch origin pull/${{ github.event.pull_request.number }}/merge
git checkout FETCH_HEAD
else
git clone --depth 1 --single-branch --branch "${{ github.ref_name }}" "$REPO_URL" "$REPO_DIR"
cd "$REPO_DIR"
fi
echo "Loading VDPA kernel modules..."
sudo modprobe vdpa
sudo modprobe vhost_vdpa
sudo modprobe vdpa_sim
sudo modprobe vdpa_sim_blk
sudo modprobe vdpa_sim_net
echo "Creating VDPA devices..."
sudo vdpa dev add name vdpa-blk0 mgmtdev vdpasim_blk
sudo vdpa dev add name vdpa-blk1 mgmtdev vdpasim_blk
sudo vdpa dev add name vdpa-blk2 mgmtdev vdpasim_net
echo "Setting permissions..."
for i in 0 1 2; do
dev="/dev/vhost-vdpa-$i"
if [ -e "$dev" ]; then
sudo chown $USER:$USER "$dev"
sudo chmod 660 "$dev"
else
echo "Warning: Device $dev not found"
fi
done
sudo ./scripts/dev_cli.sh tests --hypervisor mshv --integration
EOF
cleanup:
name: Cleanup
needs: run-tests
if: always()
runs-on: mshv
steps:
- name: Delete RG
env:
RG: MSHV-INTEGRATION-${{ github.run_id }}
run: |
if az group exists --name ${RG}; then
az group delete --name ${RG} --yes --no-wait
else
echo "Resource Group ${RG} does not exist. Skipping deletion."
fi
echo "Cleanup process completed."
- name: Delete SSH Key
env:
KEY: azure_key_${{ github.run_id }}
run: |
if [ -f ~/.ssh/${KEY} ]; then
rm -f ~/.ssh/${KEY} ~/.ssh/${KEY}.pub
echo "SSH key deleted successfully."
else
echo "SSH key does not exist. Skipping deletion."
fi
echo "Cleanup process completed."

View File

@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
container: openapitools/openapi-generator-cli
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Validate OpenAPI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

View File

@@ -0,0 +1,30 @@
name: Cloud Hypervisor RISC-V 64-bit kvm build Preview
on: [pull_request, merge_group]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Cargo
runs-on: riscv64-qemu-host
strategy:
fail-fast: false
steps:
- name: Code checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Rust toolchain
run: /opt/scripts/exec-in-qemu.sh rustup default 1.88.0
- name: Build test (kvm)
run: /opt/scripts/exec-in-qemu.sh cargo rustc --locked --no-default-features --features "kvm"
- name: Clippy test (kvm)
run: /opt/scripts/exec-in-qemu.sh cargo clippy --locked --no-default-features --features "kvm"
- name: Check no files were modified
run: test -z "$(git status --porcelain)"

View File

@@ -19,12 +19,12 @@ jobs:
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Rust toolchain
run: /opt/scripts/exec-in-qemu.sh rustup default 1.83.0
run: /opt/scripts/exec-in-qemu.sh rustup default 1.88.0
- name: Build ${{ matrix.module }} Module (kvm)
run: /opt/scripts/exec-in-qemu.sh cargo rustc --locked -p ${{ matrix.module }} --no-default-features --features "kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -111,6 +111,21 @@ jobs:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
args: --locked --all --all-targets --tests --examples --features "tracing" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Clippy (default features + fw_cfg)
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --tests --examples --features "fw_cfg" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Clippy (default features + ivshmem)
uses: houseabsolute/actions-rust-cross@v1
with:
command: clippy
cross-version: 3e0957637b49b1bbced23ad909170650c5b70635
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
args: --locked --all --all-targets --tests --examples --features "ivshmem" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
- name: Clippy (sev_snp)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
@@ -150,6 +165,6 @@ jobs:
name: Typos / Spellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
# Executes "typos ."
- uses: crate-ci/typos@v1.34.0
- uses: crate-ci/typos@v1.39.0

View File

@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install musl-gcc
if: contains(matrix.platform.target, 'musl')
run: sudo apt install -y musl-tools
@@ -45,7 +45,7 @@ jobs:
target: ${{ matrix.platform.target }}
args: ${{ matrix.platform.args }}
strip: true
toolchain: "1.83.0"
toolchain: "1.88.0"
- name: Copy Release Binaries
if: github.event_name == 'create' && github.event.ref_type == 'tag'
shell: bash
@@ -54,7 +54,7 @@ jobs:
cp target/${{ matrix.platform.target }}/release/ch-remote ./${{ matrix.platform.name_ch_remote }}
- name: Upload Release Artifacts
if: github.event_name == 'create' && github.event.ref_type == 'tag'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: Artifacts for ${{ matrix.platform.target }}
path: |
@@ -80,7 +80,7 @@ jobs:
github.event_name == 'create' && github.event.ref_type == 'tag' &&
matrix.platform.target == 'x86_64-unknown-linux-gnu'
id: upload-release-cloud-hypervisor-vendored-sources
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
path: cloud-hypervisor-${{ github.event.ref }}.tar.xz
name: cloud-hypervisor-${{ github.event.ref }}.tar.xz

View File

@@ -7,6 +7,6 @@ jobs:
name: REUSE Compliance Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v5
uses: fsfe/reuse-action@v6

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run the shell script checkers
uses: luizm/action-sh-checker@master
env:

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install build dependencies

View File

@@ -2,8 +2,6 @@ verbose = "info"
exclude = [
# Availability of links below should be manually verified.
# Page for intel SGX support, returns 403 while querying.
'^https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html',
# Page for intel TDX support, returns 403 while querying.
'^https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html',
# Page for TPM, returns 403 while querying.
@@ -14,8 +12,16 @@ exclude = [
# OSDev has added bot protection and accesses my result in 403 Forbidden.
'^https://wiki.osdev.org',
# Exclude all pages with $ in the URL since $XXX is a variable
"\\$.*",
# Exclude local files
"file://.*",
]
# Exclude loopback addresses
exclude_loopback = true
max_retries = 3
retry_wait_time = 5

View File

@@ -1,4 +1,4 @@
edition = "2021"
edition = "2024"
group_imports="StdExternalCrate"
imports_granularity="Module"

View File

@@ -11,6 +11,7 @@ CLASSE = "CLASSE"
Dake = "Dake"
EXTINT = "EXTINT"
INOUT = "INOUT"
MSIS = "MSIS" # MSIs (Message Signaled Interrupt)
SME = "SME" # Secure Memory Encryption
THR = "THR" # Transmitter Holding Register
TRANSLATER = "TRANSLATER"

View File

@@ -114,3 +114,13 @@ Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Then, after the corresponding PR is merged, GitHub will automatically close that issue when parsing the
[commit message](https://help.github.com/articles/closing-issues-via-commit-messages/).
## AI Generated Code
Our policy is to decline any contributions known to contain contents
generated or derived from using Large Language Models (LLMs). This
includes ChatGPT, Gemini, Claude, Copilot and similar tools.
The goal is to avoid ambiguity in license compliance and optimize the
use of limited project resources, especially for code review and
maintenance. This policy can be revisited as LLMs evolve and mature.

950
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,11 @@ authors = ["The Cloud Hypervisor Authors"]
build = "build.rs"
default-run = "cloud-hypervisor"
description = "Open source Virtual Machine Monitor (VMM) that runs on top of KVM & MSHV"
edition = "2021"
edition = "2024"
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
license = "Apache-2.0 AND BSD-3-Clause"
name = "cloud-hypervisor"
version = "47.0.0"
version = "49.0.0"
# Minimum buildable version:
# Keep in sync with version in .github/workflows/build.yaml
# Policy on MSRV (see #4318):
@@ -15,7 +15,7 @@ version = "47.0.0"
# a.) A dependency requires it,
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
# c.) There is a security issue that is addressed by the toolchain update.
rust-version = "1.83.0"
rust-version = "1.88.0"
[profile.release]
codegen-units = 1
@@ -29,20 +29,20 @@ inherits = "release"
strip = false
[dependencies]
anyhow = "1.0.94"
anyhow = { workspace = true }
api_client = { path = "api_client" }
clap = { version = "4.5.13", features = ["string"] }
dhat = { version = "0.3.3", optional = true }
clap = { workspace = true, features = ["string"] }
dhat = { workspace = true, optional = true }
env_logger = { workspace = true }
epoll = "4.3.3"
epoll = { workspace = true }
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.167"
log = { version = "0.4.22", features = ["std"] }
libc = { workspace = true }
log = { workspace = true, features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = { workspace = true }
serde_json = { workspace = true }
signal-hook = "0.3.18"
signal-hook = { workspace = true }
thiserror = { workspace = true }
tpm = { path = "tpm" }
tracer = { path = "tracer" }
@@ -52,11 +52,11 @@ vmm-sys-util = { workspace = true }
zbus = { version = "5.7.1", optional = true }
[dev-dependencies]
dirs = "6.0.0"
dirs = { workspace = true }
net_util = { path = "net_util" }
serde_json = { workspace = true }
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
wait-timeout = { workspace = true }
# Please adjust `vmm::feature_list()` accordingly when changing the
# feature list below
@@ -64,9 +64,11 @@ wait-timeout = "0.2.0"
dbus_api = ["vmm/dbus_api", "zbus"]
default = ["io_uring", "kvm"]
dhat-heap = ["dhat", "vmm/dhat-heap"] # For heap profiling
fw_cfg = ["vmm/fw_cfg"]
guest_debug = ["vmm/guest_debug"]
igvm = ["mshv", "vmm/igvm"]
io_uring = ["vmm/io_uring"]
ivshmem = ["vmm/ivshmem"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
pvmemcontrol = ["vmm/pvmemcontrol"]
@@ -100,24 +102,25 @@ members = [
"vm-virtio",
"vmm",
]
package.edition = "2024"
[workspace.dependencies]
# rust-vmm crates
acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" }
kvm-bindings = "0.12.0"
kvm-ioctls = "0.22.0"
linux-loader = "0.13.0"
mshv-bindings = "0.5.2"
mshv-ioctls = "0.5.2"
kvm-bindings = "0.12.1"
kvm-ioctls = "0.22.1"
linux-loader = "0.13.1"
mshv-bindings = "0.6.0"
mshv-ioctls = "0.6.0"
seccompiler = "0.5.0"
vfio-bindings = { version = "0.5.0", default-features = false }
vfio-ioctls = { version = "0.5.0", default-features = false }
vfio_user = { version = "0.1.0", default-features = false }
vfio-bindings = { version = "0.6.0", default-features = false }
vfio-ioctls = { version = "0.5.1", default-features = false }
vfio_user = { version = "0.1.1", default-features = false }
vhost = { version = "0.14.0", default-features = false }
vhost-user-backend = { version = "0.20.0", default-features = false }
virtio-bindings = "0.2.6"
virtio-queue = "0.16.0"
vm-fdt = { git = "https://github.com/rust-vmm/vm-fdt", branch = "main" }
vm-fdt = "0.3.0"
vm-memory = "0.16.1"
vmm-sys-util = "0.14.0"
@@ -127,10 +130,25 @@ igvm = { git = "https://github.com/microsoft/igvm", branch = "main" }
igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main" }
# serde crates
serde_json = "1.0.120"
serde = "1.0.228"
serde_json = "1.0.145"
serde_with = { version = "3.15.0", default-features = false }
# other crates
anyhow = "1.0.99"
bitflags = "2.9.4"
byteorder = "1.5.0"
cfg-if = "1.0.3"
clap = "4.5.49"
dhat = "0.3.3"
dirs = "6.0.0"
env_logger = "0.11.8"
thiserror = "2.0.12"
uuid = { version = "1.17.0" }
zerocopy = { version = "0.8.26", default-features = false }
epoll = "4.4.0"
flume = "0.11.1"
libc = "0.2.177"
log = "0.4.28"
signal-hook = "0.3.18"
thiserror = "2.0.17"
uuid = { version = "1.18.1" }
wait-timeout = "0.2.1"
zerocopy = { version = "0.8.27", default-features = false }

View File

@@ -153,7 +153,7 @@ interface will be enabled as per `network-config` details.
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh
$ ./cloud-hypervisor \
--kernel ./hypervisor-fw \
--firmware ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
@@ -175,6 +175,18 @@ $ ./cloud-hypervisor \
--console off
```
## Booting: `--firmware` vs `--kernel`
The following scenarios are supported by Cloud Hypervisor to bootstrap a VM, i.e.,
to load a payload/bootitem(s):
- Provide firmware
- Provide kernel \[+ cmdline\]\ [+ initrd\]
Please note that our Cloud Hypervisor firmware (`hypervisor-fw`) has a Xen PVH
boot entry, therefore it can also be booted via the `--kernel` parameter, as
seen in some examples.
### Custom Kernel and Disk Image
#### Building your Kernel

View File

@@ -1,6 +1,6 @@
[package]
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
edition.workspace = true
name = "api_client"
version = "0.1.0"

View File

@@ -118,12 +118,11 @@ fn parse_http_response(socket: &mut dyn Read) -> Result<Option<String>, Error> {
}
}
if let Some(body_offset) = body_offset {
if let Some(content_length) = content_length {
if res.len() >= content_length + body_offset {
break;
}
}
if let Some(body_offset) = body_offset
&& let Some(content_length) = content_length
&& res.len() >= content_length + body_offset
{
break;
}
}
let body_string = content_length.and(body_offset.map(|o| String::from(&res[o..])));
@@ -189,8 +188,8 @@ pub fn simple_api_full_command_with_fds<T: Read + Write + ScmSocket>(
request_fds,
)?;
if response.is_some() {
println!("{}", response.unwrap());
if let Some(response) = response {
println!("{response}");
}
Ok(())

View File

@@ -1,23 +1,24 @@
[package]
authors = ["The Chromium OS Authors"]
edition = "2021"
edition.workspace = true
name = "arch"
version = "0.1.0"
[features]
default = []
fw_cfg = []
kvm = ["hypervisor/kvm"]
sev_snp = []
tdx = []
[dependencies]
anyhow = "1.0.94"
byteorder = "1.5.0"
anyhow = { workspace = true }
byteorder = { workspace = true }
hypervisor = { path = "../hypervisor" }
libc = "0.2.167"
libc = { workspace = true }
linux-loader = { workspace = true, features = ["bzimage", "elf", "pe"] }
log = "0.4.22"
serde = { version = "1.0.208", features = ["derive", "rc"] }
log = { workspace = true }
serde = { workspace = true, features = ["derive", "rc"] }
thiserror = { workspace = true }
uuid = { workspace = true }
vm-memory = { workspace = true, features = ["backend-bitmap", "backend-mmap"] }

View File

@@ -25,8 +25,9 @@ use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion
use super::super::{DeviceType, GuestMemoryMmap, InitramfsConfig};
use super::layout::{
GIC_V2M_COMPATIBLE, IRQ_BASE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE,
MEM_PCI_IO_START, PCI_HIGH_BASE, PCI_MMIO_CONFIG_SIZE_PER_SEGMENT, SPI_BASE, SPI_NUM,
GIC_V2M_COMPATIBLE, GICV2M_SPI_BASE, GICV2M_SPI_NUM, IRQ_BASE, MEM_32BIT_DEVICES_SIZE,
MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START, PCI_HIGH_BASE,
PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
};
use crate::{NumaNodes, PciSpaceInfo};
@@ -110,11 +111,8 @@ pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
// The content of the file is as simple as a size, like: "32K"
let src = src.trim();
@@ -144,11 +142,8 @@ pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
src.trim().parse::<u32>().unwrap()
}
@@ -167,11 +162,8 @@ pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
src.trim().parse::<u32>().unwrap()
}
@@ -195,11 +187,8 @@ pub fn get_cache_shared(cache_level: CacheLevel) -> bool {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
warn!("File: {} does not exist.", file_directory);
result = false;
} else {
info!("File: {} exist.", file_directory);
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
let src = src.trim();
if src.is_empty() {
@@ -218,7 +207,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
guest_mem: &GuestMemoryMmap,
cmdline: &str,
vcpu_mpidr: Vec<u64>,
vcpu_topology: Option<(u8, u8, u8)>,
vcpu_topology: Option<(u16, u16, u16, u16)>,
device_info: &HashMap<(DeviceType, String), T, S>,
gic_device: &Arc<Mutex<dyn Vgic>>,
initrd: &Option<InitramfsConfig>,
@@ -231,8 +220,8 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
let mut fdt = FdtWriter::new().unwrap();
// For an explanation why these nodes were introduced in the blob take a look at
// https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L845
// Look for "Required nodes and properties".
// the "Device Node Requirements" chapter of the Devicetree Specification.
// https://www.devicetree.org/specifications/
// Header or the root node as per above mentioned documentation.
let root_node = fdt.begin_node("")?;
@@ -280,7 +269,7 @@ pub fn write_fdt_to_memory(fdt_final: Vec<u8>, guest_mem: &GuestMemoryMmap) -> R
fn create_cpu_nodes(
fdt: &mut FdtWriter,
vcpu_mpidr: &[u64],
vcpu_topology: Option<(u8, u8, u8)>,
vcpu_topology: Option<(u16, u16, u16, u16)>,
numa_nodes: &NumaNodes,
) -> FdtWriterResult<()> {
// See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/arm/cpus.yaml.
@@ -289,8 +278,11 @@ fn create_cpu_nodes(
fdt.property_u32("#size-cells", 0x0)?;
let num_cpus = vcpu_mpidr.len();
let (threads_per_core, cores_per_package, packages) = vcpu_topology.unwrap_or((1, 1, 1));
let max_cpus: u32 = (threads_per_core * cores_per_package * packages).into();
let (threads_per_core, cores_per_die, dies_per_package, packages) =
vcpu_topology.unwrap_or((1, 1, 1, 1));
let cores_per_package = cores_per_die * dies_per_package;
let max_cpus: u32 =
threads_per_core as u32 * cores_per_die as u32 * dies_per_package as u32 * packages as u32;
// Add cache info.
// L1 Data Cache Info.
@@ -322,7 +314,6 @@ fn create_cpu_nodes(
if !cache_exist {
warn!("cache sysfs system does not exist.");
} else {
info!("cache sysfs system exists.");
// L1 Data Cache Info.
l1_d_cache_size = get_cache_size(CacheLevel::L1D);
l1_d_cache_line_size = get_cache_coherency_line_size(CacheLevel::L1D);
@@ -370,7 +361,7 @@ fn create_cpu_nodes(
if numa_nodes.len() > 1 {
for numa_node_idx in 0..numa_nodes.len() {
let numa_node = numa_nodes.get(&(numa_node_idx as u32));
if numa_node.unwrap().cpus.contains(&(cpu_id as u8)) {
if numa_node.unwrap().cpus.contains(&(cpu_id as u32)) {
fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
}
}
@@ -423,9 +414,6 @@ fn create_cpu_nodes(
fdt.end_node(l2_cache_node)?;
}
if l2_cache_size != 0 && l2_cache_shared {
warn!("L2 cache shared with other cpus");
}
}
fdt.end_node(cpu_node)?;
@@ -462,7 +450,8 @@ fn create_cpu_nodes(
}
if let Some(topology) = vcpu_topology {
let (threads_per_core, cores_per_package, packages) = topology;
let (threads_per_core, cores_per_die, dies_per_package, packages) = topology;
let cores_per_package = cores_per_die * dies_per_package;
let cpu_map_node = fdt.begin_node("cpu-map")?;
// Create device tree nodes with regard of above mapping.
@@ -678,8 +667,8 @@ fn create_gic_node(fdt: &mut FdtWriter, gic_device: &Arc<Mutex<dyn Vgic>>) -> Fd
fdt.property_array_u64("reg", &msi_reg_prop)?;
if msi_compatibility == GIC_V2M_COMPATIBLE {
fdt.property_u32("arm,msi-base-spi", SPI_BASE)?;
fdt.property_u32("arm,msi-num-spis", SPI_NUM)?;
fdt.property_u32("arm,msi-base-spi", GICV2M_SPI_BASE)?;
fdt.property_u32("arm,msi-num-spis", GICV2M_SPI_NUM)?;
}
fdt.end_node(msic_node)?;
@@ -850,6 +839,21 @@ fn create_gpio_node<T: DeviceInfoForFdt + Clone + Debug>(
Ok(())
}
// https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/fw-cfg.txt
#[cfg(feature = "fw_cfg")]
fn create_fw_cfg_node<T: DeviceInfoForFdt + Clone + Debug>(
fdt: &mut FdtWriter,
dev_info: &T,
) -> FdtWriterResult<()> {
// FwCfg node
let fw_cfg_node = fdt.begin_node(&format!("fw-cfg@{:x}", dev_info.addr()))?;
fdt.property("compatible", b"qemu,fw-cfg-mmio\0")?;
fdt.property_array_u64("reg", &[dev_info.addr(), dev_info.length()])?;
fdt.end_node(fw_cfg_node)?;
Ok(())
}
fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHasher>(
fdt: &mut FdtWriter,
dev_info: &HashMap<(DeviceType, String), T, S>,
@@ -865,6 +869,8 @@ fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Buil
DeviceType::Virtio(_) => {
ordered_virtio_device.push(info);
}
#[cfg(feature = "fw_cfg")]
DeviceType::FwCfg => create_fw_cfg_node(fdt, info)?,
}
}
@@ -994,39 +1000,39 @@ fn create_pci_nodes(
fdt.property_array_u32("msi-map", &msi_map)?;
fdt.property_u32("msi-parent", MSI_PHANDLE)?;
if pci_device_info_elem.pci_segment_id == 0 {
if let Some(virtio_iommu_bdf) = virtio_iommu_bdf {
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
// for 'iommu-map' attribute setting.
let iommu_map = [
0_u32,
VIRTIO_IOMMU_PHANDLE,
0_u32,
virtio_iommu_bdf,
virtio_iommu_bdf + 1,
VIRTIO_IOMMU_PHANDLE,
virtio_iommu_bdf + 1,
0xffff - virtio_iommu_bdf,
];
fdt.property_array_u32("iommu-map", &iommu_map)?;
if pci_device_info_elem.pci_segment_id == 0
&& let Some(virtio_iommu_bdf) = virtio_iommu_bdf
{
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
// for 'iommu-map' attribute setting.
let iommu_map = [
0_u32,
VIRTIO_IOMMU_PHANDLE,
0_u32,
virtio_iommu_bdf,
virtio_iommu_bdf + 1,
VIRTIO_IOMMU_PHANDLE,
virtio_iommu_bdf + 1,
0xffff - virtio_iommu_bdf,
];
fdt.property_array_u32("iommu-map", &iommu_map)?;
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
// for virtio-iommu node settings.
let virtio_iommu_node_name = format!("virtio_iommu@{virtio_iommu_bdf:x}");
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
fdt.property_u32("#iommu-cells", 1)?;
fdt.property_string("compatible", "virtio,pci-iommu")?;
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
// for virtio-iommu node settings.
let virtio_iommu_node_name = format!("virtio_iommu@{virtio_iommu_bdf:x}");
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
fdt.property_u32("#iommu-cells", 1)?;
fdt.property_string("compatible", "virtio,pci-iommu")?;
// 'reg' is a five-cell address encoded as
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
// should be zero.
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
fdt.property_array_u32("reg", &reg)?;
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
// 'reg' is a five-cell address encoded as
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
// should be zero.
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
fdt.property_array_u32("reg", &reg)?;
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
fdt.end_node(virtio_iommu_node)?;
}
fdt.end_node(virtio_iommu_node)?;
}
fdt.end_node(pci_node)?;

View File

@@ -139,11 +139,11 @@ pub const IRQ_BASE: u32 = 32;
/// Number of supported interrupts
pub const IRQ_NUM: u32 = 256;
/// Base SPI interrupt number
pub const SPI_BASE: u32 = 32;
/// Base SPI interrupt number for the GICv2M MSI frame
pub const GICV2M_SPI_BASE: u32 = 128;
/// Total number of SPIs
pub const SPI_NUM: u32 = 64;
/// Total number of SPIs for the GICv2M MSI frame
pub const GICV2M_SPI_NUM: u32 = 64;
/// GICv2M compatible string
pub const GIC_V2M_COMPATIBLE: &str = "arm,gic-v2m-frame";

View File

@@ -15,7 +15,7 @@ use std::sync::{Arc, Mutex};
use hypervisor::arch::aarch64::gic::Vgic;
use hypervisor::arch::aarch64::regs::MPIDR_EL1;
use log::{log_enabled, Level};
use log::{Level, log_enabled};
use thiserror::Error;
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic};
@@ -66,8 +66,8 @@ pub struct EntryPoint {
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
vcpu: &dyn hypervisor::Vcpu,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<u64> {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
@@ -126,7 +126,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
guest_mem: &GuestMemoryMmap,
cmdline: &str,
vcpu_mpidr: Vec<u64>,
vcpu_topology: Option<(u8, u8, u8)>,
vcpu_topology: Option<(u16, u16, u16, u16)>,
device_info: &HashMap<(DeviceType, String), T, S>,
initrd: &Option<super::InitramfsConfig>,
pci_space_info: &[PciSpaceInfo],
@@ -180,7 +180,7 @@ pub fn initramfs_load_addr(
}
}
pub fn get_host_cpu_phys_bits(hypervisor: &Arc<dyn hypervisor::Hypervisor>) -> u8 {
pub fn get_host_cpu_phys_bits(hypervisor: &dyn hypervisor::Hypervisor) -> u8 {
let host_cpu_phys_bits = hypervisor.get_host_ipa_limit().try_into().unwrap();
if host_cpu_phys_bits == 0 {
// Host kernel does not support `get_host_ipa_limit`,

View File

@@ -18,9 +18,6 @@ use std::{fmt, result};
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::SgxEpcSection;
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<vm_memory::bitmap::AtomicBitmap>;
type GuestRegionMmap = vm_memory::GuestRegionMmap<vm_memory::bitmap::AtomicBitmap>;
@@ -84,9 +81,9 @@ pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::IRQ_BASE, uefi, EntryPoint, _NSIG,
_NSIG, EntryPoint, arch_memory_regions, configure_system, configure_vcpu,
fdt::DeviceInfoForFdt, get_host_cpu_phys_bits, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, uefi,
};
/// Module for riscv64 related functionality.
@@ -95,9 +92,9 @@ pub mod riscv64;
#[cfg(target_arch = "riscv64")]
pub use riscv64::{
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::IRQ_BASE, EntryPoint, _NSIG,
_NSIG, EntryPoint, arch_memory_regions, configure_system, configure_vcpu,
fdt::DeviceInfoForFdt, get_host_cpu_phys_bits, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, uefi,
};
#[cfg(target_arch = "x86_64")]
@@ -105,10 +102,9 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid,
generate_ram_ranges, get_host_cpu_phys_bits, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry,
EntryPoint, _NSIG,
_NSIG, CpuidConfig, CpuidFeatureEntry, EntryPoint, arch_memory_regions, configure_system,
configure_vcpu, generate_common_cpuid, generate_ram_ranges, get_host_cpu_phys_bits,
initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs,
};
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
@@ -123,12 +119,10 @@ fn pagesize() -> usize {
pub struct NumaNode {
pub memory_regions: Vec<Arc<GuestRegionMmap>>,
pub hotplug_regions: Vec<Arc<GuestRegionMmap>>,
pub cpus: Vec<u8>,
pub cpus: Vec<u32>,
pub pci_segments: Vec<u16>,
pub distances: BTreeMap<u32, u8>,
pub memory_zones: Vec<String>,
#[cfg(target_arch = "x86_64")]
pub sgx_epc_sections: Vec<SgxEpcSection>,
}
pub type NumaNodes = BTreeMap<u32, NumaNode>;
@@ -155,6 +149,9 @@ pub enum DeviceType {
/// Device Type: GPIO.
#[cfg(target_arch = "aarch64")]
Gpio,
/// Device Type: fw_cfg.
#[cfg(feature = "fw_cfg")]
FwCfg,
}
/// Default (smallest) memory page size for the supported architectures.

View File

@@ -119,7 +119,7 @@ fn create_cpu_nodes(fdt: &mut FdtWriter, num_cpus: u32) -> FdtWriterResult<()> {
fdt.property_u32("timebase-frequency", timebase_frequency)?;
for cpu_index in 0..num_cpus {
let cpu = fdt.begin_node(&format!("cpu@{:x}", cpu_index))?;
let cpu = fdt.begin_node(&format!("cpu@{cpu_index:x}"))?;
fdt.property_string("device_type", "cpu")?;
fdt.property_string("compatible", "riscv")?;
fdt.property_string("mmu-type", "sv48")?;
@@ -184,7 +184,7 @@ fn create_memory_node(fdt: &mut FdtWriter, guest_mem: &GuestMemoryMmap) -> FdtWr
}
let ram_start = super::layout::RAM_START.raw_value();
let memory_node_name = format!("memory@{:x}", ram_start);
let memory_node_name = format!("memory@{ram_start:x}");
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_property)?;
@@ -448,10 +448,7 @@ fn print_node(node: fdt_parser::node::FdtNode<'_, '_>, n_spaces: usize) {
// - At first, try to convert it to CStr and print,
// - If failed, print it as u32 array.
let value_result = match CStr::from_bytes_with_nul(value) {
Ok(value_cstr) => match value_cstr.to_str() {
Ok(value_str) => Some(value_str),
Err(_e) => None,
},
Ok(value_cstr) => value_cstr.to_str().ok(),
Err(_e) => None,
};

View File

@@ -44,16 +44,23 @@
// | |
// | APLICs |
// | |
// 4 MB +---------------------------------------------------------------+
// | UEFI flash |
// 0 GB +---------------------------------------------------------------+
//
//
use vm_memory::GuestAddress;
/// 0x0 ~ 0x40_0000 (4 MiB) is reserved to UEFI
/// UEFI binary size is required less than 3 MiB, reserving 4 MiB is enough.
pub const UEFI_START: GuestAddress = GuestAddress(0);
pub const UEFI_SIZE: u64 = 0x040_0000;
/// AIA related devices
/// See https://elixir.bootlin.com/linux/v6.10/source/arch/riscv/include/uapi/asm/kvm.h
/// 0x0 ~ 0x0400_0000 (64 MiB) resides APLICs
pub const APLIC_START: GuestAddress = GuestAddress(0);
/// 0x40_0000 ~ 0x0400_0000 (64 MiB) resides APLICs
pub const APLIC_START: GuestAddress = GuestAddress(0x40_0000);
pub const APLIC_SIZE: u64 = 0x4000;
/// 0x0400_0000 ~ 0x0800_0000 (64 MiB) resides IMSICs
@@ -91,7 +98,12 @@ pub const CMDLINE_MAX_SIZE: usize = 1024;
pub const FDT_START: GuestAddress = RAM_START;
pub const FDT_MAX_SIZE: u64 = 0x1_0000;
/// Kernel start after FDT
/// Put ACPI table above dtb
pub const ACPI_START: GuestAddress = GuestAddress(RAM_START.0 + FDT_MAX_SIZE);
pub const ACPI_MAX_SIZE: u64 = 0x20_0000;
pub const RSDP_POINTER: GuestAddress = ACPI_START;
/// Kernel start after FDT and ACPI
pub const KERNEL_START: GuestAddress = GuestAddress(RAM_START.0 + FDT_MAX_SIZE);
/// Pci high memory base

View File

@@ -7,19 +7,26 @@
pub mod fdt;
/// Layout for this riscv64 system.
pub mod layout;
/// Module for loading UEFI binary.
pub mod uefi;
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use hypervisor::arch::riscv64::aia::Vaia;
use log::{log_enabled, Level};
use log::{Level, log_enabled};
use thiserror::Error;
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic};
pub use self::fdt::DeviceInfoForFdt;
use crate::{DeviceType, GuestMemoryMmap, PciSpaceInfo, RegionType};
pub const CLOUDHV_IRQCHIP_NUM_MSIS: u16 = 255;
pub const CLOUDHV_IRQCHIP_NUM_SOURCES: u8 = 96;
pub const CLOUDHV_IRQCHIP_NUM_PRIO_BITS: u8 = 3;
pub const CLOUDHV_IRQCHIP_MAX_GUESTS_BITS: u8 = 3;
pub const CLOUDHV_IRQCHIP_MAX_GUESTS: u8 = (1 << CLOUDHV_IRQCHIP_MAX_GUESTS_BITS) - 1;
pub const _NSIG: i32 = 65;
/// Errors thrown while configuring riscv64 system.
@@ -56,8 +63,8 @@ pub struct EntryPoint {
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
vcpu: &dyn hypervisor::Vcpu,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<()> {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
@@ -149,7 +156,7 @@ pub fn initramfs_load_addr(
}
}
pub fn get_host_cpu_phys_bits(_hypervisor: &Arc<dyn hypervisor::Hypervisor>) -> u8 {
pub fn get_host_cpu_phys_bits(_hypervisor: &dyn hypervisor::Hypervisor) -> u8 {
40
}

50
arch/src/riscv64/uefi.rs Normal file
View File

@@ -0,0 +1,50 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
use std::io::{Read, Seek, SeekFrom};
use std::os::fd::AsFd;
use std::result;
use thiserror::Error;
use vm_memory::{GuestAddress, GuestMemory};
/// Errors thrown while loading UEFI binary
#[derive(Debug, Error)]
pub enum Error {
/// Unable to seek to UEFI image start.
#[error("Unable to seek to UEFI image start")]
SeekUefiStart,
/// Unable to seek to UEFI image end.
#[error("Unable to seek to UEFI image end")]
SeekUefiEnd,
/// UEFI image too big.
#[error("UEFI image too big")]
UefiTooBig,
/// Unable to read UEFI image
#[error("Unable to read UEFI image")]
ReadUefiImage,
}
type Result<T> = result::Result<T, Error>;
pub fn load_uefi<F, M: GuestMemory>(
guest_mem: &M,
guest_addr: GuestAddress,
uefi_image: &mut F,
) -> Result<()>
where
F: Read + Seek + AsFd,
{
let uefi_size = uefi_image
.seek(SeekFrom::End(0))
.map_err(|_| Error::SeekUefiEnd)? as usize;
// edk2 image on virtual platform is smaller than 3M
if uefi_size > 0x300000 {
return Err(Error::UefiTooBig);
}
uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
guest_mem
.read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
.map_err(|_| Error::ReadUefiImage)
}

View File

@@ -6,7 +6,6 @@
// found in the LICENSE-BSD-3-Clause file.
use std::result;
use std::sync::Arc;
pub type Result<T> = result::Result<T, hypervisor::HypervisorCpuError>;
@@ -24,7 +23,7 @@ pub fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
///
/// # Arguments
/// * `vcpu` - The VCPU object to configure.
pub fn set_lint(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
pub fn set_lint(vcpu: &dyn hypervisor::Vcpu) -> Result<()> {
let mut klapic = vcpu.get_lapic()?;
let lvt_lint0 = klapic.get_klapic_reg(APIC_LVT0);

View File

@@ -6,16 +6,14 @@
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use std::sync::Arc;
pub mod interrupts;
pub mod layout;
mod mpspec;
mod mptable;
pub mod regs;
use std::collections::BTreeMap;
use std::mem;
use hypervisor::arch::x86::{CpuIdEntry, CPUID_FLAG_VALID_INDEX};
use hypervisor::arch::x86::{CPUID_FLAG_VALID_INDEX, CpuIdEntry};
use hypervisor::{CpuVendor, HypervisorCpuError, HypervisorError};
use linux_loader::loader::bootparam::{boot_params, setup_header};
use linux_loader::loader::elf::start_info::{
@@ -24,7 +22,7 @@ use linux_loader::loader::elf::start_info::{
use thiserror::Error;
use vm_memory::{
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryRegion, GuestUsize,
GuestMemoryRegion,
};
use crate::{GuestMemoryMmap, InitramfsConfig, RegionType};
@@ -33,6 +31,10 @@ use std::arch::x86_64;
#[cfg(feature = "tdx")]
pub mod tdx;
// While modern architectures support more than 255 CPUs via x2APIC,
// legacy devices such as mptable support at most 254 CPUs.
pub const MAX_SUPPORTED_CPUS_LEGACY: u32 = 254;
// CPUID feature bits
#[cfg(feature = "kvm")]
const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit.
@@ -57,6 +59,8 @@ const KVM_FEATURE_ASYNC_PF_VMEXIT_BIT: u8 = 10;
#[cfg(feature = "tdx")]
const KVM_FEATURE_STEAL_TIME_BIT: u8 = 5;
const KVM_FEATURE_MSI_EXT_DEST_ID: u8 = 15;
pub const _NSIG: i32 = 65;
#[derive(Debug, Copy, Clone)]
@@ -73,55 +77,7 @@ pub struct EntryPoint {
const E820_RAM: u32 = 1;
const E820_RESERVED: u32 = 2;
#[derive(Clone)]
pub struct SgxEpcSection {
start: GuestAddress,
size: GuestUsize,
}
impl SgxEpcSection {
pub fn new(start: GuestAddress, size: GuestUsize) -> Self {
SgxEpcSection { start, size }
}
pub fn start(&self) -> GuestAddress {
self.start
}
pub fn size(&self) -> GuestUsize {
self.size
}
}
#[derive(Clone)]
pub struct SgxEpcRegion {
start: GuestAddress,
size: GuestUsize,
epc_sections: BTreeMap<String, SgxEpcSection>,
}
impl SgxEpcRegion {
pub fn new(start: GuestAddress, size: GuestUsize) -> Self {
SgxEpcRegion {
start,
size,
epc_sections: BTreeMap::new(),
}
}
pub fn start(&self) -> GuestAddress {
self.start
}
pub fn size(&self) -> GuestUsize {
self.size
}
pub fn epc_sections(&self) -> &BTreeMap<String, SgxEpcSection> {
&self.epc_sections
}
pub fn insert(&mut self, id: String, epc_section: SgxEpcSection) {
self.epc_sections.insert(id, epc_section);
}
}
pub struct CpuidConfig {
pub sgx_epc_sections: Option<Vec<SgxEpcSection>>,
pub phys_bits: u8,
pub kvm_hyperv: bool,
#[cfg(feature = "tdx")]
@@ -163,18 +119,6 @@ pub enum Error {
#[error("Error setting up SMBIOS table")]
SmbiosSetup(#[source] smbios::Error),
/// Could not find any SGX EPC section
#[error("Could not find any SGX EPC section")]
NoSgxEpcSection,
/// Missing SGX CPU feature
#[error("Missing SGX CPU feature")]
MissingSgxFeature,
/// Missing SGX_LC CPU feature
#[error("Missing SGX_LC CPU feature")]
MissingSgxLaunchControlFeature,
/// Error getting supported CPUID through the hypervisor (kvm/mshv) API
#[error("Error getting supported CPUID through the hypervisor API")]
CpuidGetSupported(#[source] HypervisorError),
@@ -209,11 +153,11 @@ pub enum Error {
E820Configuration,
}
pub fn get_x2apic_id(cpu_id: u32, topology: Option<(u8, u8, u8)>) -> u32 {
pub fn get_x2apic_id(cpu_id: u32, topology: Option<(u16, u16, u16, u16)>) -> u32 {
if let Some(t) = topology {
let thread_mask_width = u8::BITS - (t.0 - 1).leading_zeros();
let core_mask_width = u8::BITS - (t.1 - 1).leading_zeros();
let die_mask_width = u8::BITS - (t.2 - 1).leading_zeros();
let thread_mask_width = u16::BITS - (t.0 - 1).leading_zeros();
let core_mask_width = u16::BITS - (t.1 - 1).leading_zeros();
let die_mask_width = u16::BITS - (t.2 - 1).leading_zeros();
let thread_id = cpu_id % (t.0 as u32);
let core_id = cpu_id / (t.0 as u32) % (t.1 as u32);
@@ -229,6 +173,13 @@ pub fn get_x2apic_id(cpu_id: u32, topology: Option<(u8, u8, u8)>) -> u32 {
cpu_id
}
pub fn get_max_x2apic_id(topology: (u16, u16, u16, u16)) -> u32 {
get_x2apic_id(
(topology.0 as u32 * topology.1 as u32 * topology.2 as u32 * topology.3 as u32) - 1,
Some(topology),
)
}
#[derive(Copy, Clone, Debug)]
pub enum CpuidReg {
EAX,
@@ -454,7 +405,7 @@ impl CpuidFeatureEntry {
feature_reg: CpuidReg::EDX,
compatible_check: CpuidCompatibleCheck::BitwiseSubset,
},
// KVM CPUID bits: https://www.kernel.org/doc/html/latest/virt/kvm/cpuid.html
// KVM CPUID bits: https://www.kernel.org/doc/html/latest/virt/kvm/x86/cpuid.html
// Leaf 0x4000_0000, EAX/EBX/ECX/EDX, KVM CPUID SIGNATURE
CpuidFeatureEntry {
function: 0x4000_0000,
@@ -573,9 +524,13 @@ impl CpuidFeatureEntry {
error!(
"Detected incompatible CPUID entry: leaf={:#02x} (subleaf={:#02x}), register='{:?}', \
compatible_check='{:?}', source VM feature='{:#04x}', destination VM feature'{:#04x}'.",
entry.function, entry.index, entry.feature_reg,
entry.compatible_check, src_vm_feature, dest_vm_feature
);
entry.function,
entry.index,
entry.feature_reg,
entry.compatible_check,
src_vm_feature,
dest_vm_feature
);
compatible = false;
}
@@ -591,7 +546,7 @@ impl CpuidFeatureEntry {
}
pub fn generate_common_cpuid(
hypervisor: &Arc<dyn hypervisor::Hypervisor>,
hypervisor: &dyn hypervisor::Hypervisor,
config: &CpuidConfig,
) -> super::Result<Vec<CpuIdEntry>> {
// SAFETY: cpuid called with valid leaves
@@ -662,10 +617,6 @@ pub fn generate_common_cpuid(
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
if let Some(sgx_epc_sections) = &config.sgx_epc_sections {
update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?;
}
#[cfg(feature = "tdx")]
let tdx_capabilities = if config.tdx {
let caps = hypervisor
@@ -738,6 +689,10 @@ pub fn generate_common_cpuid(
entry.eax = (entry.eax & 0xffff_ff00) | (config.phys_bits as u32 & 0xff);
}
0x4000_0001 => {
// Enable KVM_FEATURE_MSI_EXT_DEST_ID. This allows the guest to target
// device interrupts to cpus with APIC IDs > 254 without interrupt remapping.
entry.eax |= 1 << KVM_FEATURE_MSI_EXT_DEST_ID;
// These features are not supported by TDX
#[cfg(feature = "tdx")]
if config.tdx {
@@ -819,15 +774,15 @@ pub fn generate_common_cpuid(
}
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
vcpu: &dyn hypervisor::Vcpu,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
cpuid: Vec<CpuIdEntry>,
kvm_hyperv: bool,
cpu_vendor: CpuVendor,
topology: Option<(u8, u8, u8)>,
topology: (u16, u16, u16, u16),
) -> super::Result<()> {
let x2apic_id = get_x2apic_id(id as u32, topology);
let x2apic_id = get_x2apic_id(id, Some(topology));
// Per vCPU CPUID changes; common are handled via generate_common_cpuid()
let mut cpuid = cpuid;
@@ -849,40 +804,31 @@ pub fn configure_vcpu(
}
assert!(apic_id_patched);
if let Some(t) = topology {
update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id);
}
update_cpuid_topology(
&mut cpuid, topology.0, topology.1, topology.2, topology.3, cpu_vendor, id,
);
// The TSC frequency CPUID leaf should not be included when running with HyperV emulation
if !kvm_hyperv {
if let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {
// Need to check that the TSC doesn't vary with dynamic frequency
// SAFETY: cpuid called with valid leaves
if unsafe { std::arch::x86_64::__cpuid(0x8000_0007) }.edx
& (1u32 << INVARIANT_TSC_EDX_BIT)
> 0
{
CpuidPatch::set_cpuid_reg(
&mut cpuid,
0x4000_0000,
None,
CpuidReg::EAX,
0x4000_0010,
);
cpuid.retain(|c| c.function != 0x4000_0010);
cpuid.push(CpuIdEntry {
function: 0x4000_0010,
eax: tsc_khz,
ebx: 1000000, /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's
* APIC_BUS_CYCLE_NS */
..Default::default()
});
};
}
if !kvm_hyperv && let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {
// Need to check that the TSC doesn't vary with dynamic frequency
// SAFETY: cpuid called with valid leaves
if unsafe { std::arch::x86_64::__cpuid(0x8000_0007) }.edx & (1u32 << INVARIANT_TSC_EDX_BIT)
> 0
{
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x4000_0000, None, CpuidReg::EAX, 0x4000_0010);
cpuid.retain(|c| c.function != 0x4000_0010);
cpuid.push(CpuIdEntry {
function: 0x4000_0010,
eax: tsc_khz,
ebx: 1000000, /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's
* APIC_BUS_CYCLE_NS */
..Default::default()
});
};
}
for c in &cpuid {
debug!("{}", c);
debug!("{c}");
}
vcpu.set_cpuid2(&cpuid)
@@ -896,7 +842,15 @@ pub fn configure_vcpu(
if let Some((kernel_entry_point, guest_memory)) = boot_setup {
regs::setup_regs(vcpu, kernel_entry_point).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&guest_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
// CPUs are required (by Intel sdm spec) to boot in x2apic mode if any
// of the apic IDs is larger than 255. Experimentally, the Linux kernel
// does not recognize the last vCPU if x2apic is not enabled when
// there are 256 vCPUs in a flat hierarchy (i.e. max x2apic ID is 255),
// so we need to enable x2apic in this case as well.
let enable_x2_apic_mode = get_max_x2apic_id(topology) > MAX_SUPPORTED_CPUS_LEGACY;
regs::setup_sregs(&guest_memory.memory(), vcpu, enable_x2_apic_mode)
.map_err(Error::SregsConfiguration)?;
}
interrupts::set_lint(vcpu).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
Ok(())
@@ -946,14 +900,13 @@ pub fn configure_system(
cmdline_addr: GuestAddress,
cmdline_size: usize,
initramfs: &Option<InitramfsConfig>,
_num_cpus: u8,
_num_cpus: u32,
setup_header: Option<setup_header>,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
serial_number: Option<&str>,
uuid: Option<&str>,
oem_strings: Option<&[&str]>,
topology: Option<(u8, u8, u8)>,
topology: Option<(u16, u16, u16, u16)>,
) -> super::Result<()> {
// Write EBDA address to location where ACPICA expects to find it
guest_mem
@@ -969,10 +922,10 @@ pub fn configure_system(
mptable::setup_mptable(offset, guest_mem, _num_cpus, topology).map_err(Error::MpTableSetup)?;
// Check that the RAM is not smaller than the RSDP start address
if let Some(rsdp_addr) = rsdp_addr {
if rsdp_addr.0 > guest_mem.last_addr().0 {
return Err(super::Error::RsdpPastRamEnd);
}
if let Some(rsdp_addr) = rsdp_addr
&& rsdp_addr.0 > guest_mem.last_addr().0
{
return Err(super::Error::RsdpPastRamEnd);
}
match setup_header {
@@ -983,15 +936,8 @@ pub fn configure_system(
initramfs,
hdr,
rsdp_addr,
sgx_epc_region,
),
None => configure_pvh(
guest_mem,
cmdline_addr,
initramfs,
rsdp_addr,
sgx_epc_region,
),
None => configure_pvh(guest_mem, cmdline_addr, initramfs, rsdp_addr),
}
}
@@ -1048,17 +994,15 @@ pub fn generate_ram_ranges(guest_mem: &GuestMemoryMmap) -> super::Result<Vec<Ram
&& (first_region_end <= &mem_32bit_reserved_start))
{
error!(
"Unexpected first memory region layout: (start: 0x{:08x}, end: 0x{:08x}).
high_ram_start: 0x{:08x}, mem_32bit_reserved_start: 0x{:08x}",
first_region_start, first_region_end, high_ram_start, mem_32bit_reserved_start
"Unexpected first memory region layout: (start: 0x{first_region_start:08x}, end: 0x{first_region_end:08x}).
high_ram_start: 0x{high_ram_start:08x}, mem_32bit_reserved_start: 0x{mem_32bit_reserved_start:08x}"
);
return Err(super::Error::MemmapTableSetup);
}
info!(
"first usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
high_ram_start, first_region_end
"first usable physical memory range, start: 0x{high_ram_start:08x}, end: 0x{first_region_end:08x}"
);
(high_ram_start, *first_region_end)
@@ -1083,7 +1027,6 @@ fn configure_pvh(
cmdline_addr: GuestAddress,
initramfs: &Option<InitramfsConfig>,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
) -> super::Result<()> {
const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578;
@@ -1149,15 +1092,6 @@ fn configure_pvh(
E820_RESERVED,
);
if let Some(sgx_epc_region) = sgx_epc_region {
add_memmap_entry(
&mut memmap,
sgx_epc_region.start().raw_value(),
sgx_epc_region.size(),
E820_RESERVED,
);
}
start_info.memmap_entries = memmap.len() as u32;
// Copy the vector with the memmap table to the MEMMAP_START address
@@ -1204,7 +1138,6 @@ fn configure_32bit_entry(
initramfs: &Option<InitramfsConfig>,
setup_hdr: setup_header,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
) -> super::Result<()> {
const KERNEL_LOADER_OTHER: u8 = 0xff;
@@ -1260,15 +1193,6 @@ fn configure_32bit_entry(
E820_RESERVED,
)?;
if let Some(sgx_epc_region) = sgx_epc_region {
add_e820_entry(
&mut params,
sgx_epc_region.start().raw_value(),
sgx_epc_region.size(),
E820_RESERVED,
)?;
}
if let Some(rsdp_addr) = rsdp_addr {
params.acpi_rsdp_addr = rsdp_addr.0;
}
@@ -1333,7 +1257,7 @@ pub fn initramfs_load_addr(
Ok(aligned_addr)
}
pub fn get_host_cpu_phys_bits(hypervisor: &Arc<dyn hypervisor::Hypervisor>) -> u8 {
pub fn get_host_cpu_phys_bits(hypervisor: &dyn hypervisor::Hypervisor) -> u8 {
// SAFETY: call cpuid with valid leaves
unsafe {
let leaf = x86_64::__cpuid(0x8000_0000);
@@ -1361,21 +1285,24 @@ pub fn get_host_cpu_phys_bits(hypervisor: &Arc<dyn hypervisor::Hypervisor>) -> u
fn update_cpuid_topology(
cpuid: &mut Vec<CpuIdEntry>,
threads_per_core: u8,
cores_per_die: u8,
dies_per_package: u8,
threads_per_core: u16,
cores_per_die: u16,
dies_per_package: u16,
packages: u16,
cpu_vendor: CpuVendor,
id: u8,
id: u32,
) {
let x2apic_id = get_x2apic_id(
id as u32,
Some((threads_per_core, cores_per_die, dies_per_package)),
id,
Some((threads_per_core, cores_per_die, dies_per_package, packages)),
);
let thread_width = 8 - (threads_per_core - 1).leading_zeros();
let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width;
let die_width = (8 - (dies_per_package - 1).leading_zeros()) + core_width;
// Note: the topology defined here is per "package" (~NUMA node).
let thread_width = u16::BITS - (threads_per_core - 1).leading_zeros();
let core_width = u16::BITS - (cores_per_die - 1).leading_zeros() + thread_width;
let die_width = u16::BITS - (dies_per_package - 1).leading_zeros() + core_width;
// The very old way: a flat number of logical CPUs per package: CPUID.1H:EBX[23:16] bits.
let mut cpu_ebx = CpuidPatch::get_cpuid_reg(cpuid, 0x1, None, CpuidReg::EBX).unwrap_or(0);
cpu_ebx |= ((dies_per_package as u32) * (cores_per_die as u32) * (threads_per_core as u32))
& (0xff << 16);
@@ -1385,6 +1312,7 @@ fn update_cpuid_topology(
cpu_edx |= 1 << 28;
CpuidPatch::set_cpuid_reg(cpuid, 0x1, None, CpuidReg::EDX, cpu_edx);
// The legacy way: threads+cores per package.
// CPU Topology leaf 0xb
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::EAX, thread_width);
CpuidPatch::set_cpuid_reg(
@@ -1407,6 +1335,7 @@ fn update_cpuid_topology(
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::ECX, 2 << 8);
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::EDX, x2apic_id);
// The modern way: many-level hierarchy (but we here only support four levels).
// CPU Topology leaf 0x1f
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(0), CpuidReg::EAX, thread_width);
CpuidPatch::set_cpuid_reg(
@@ -1497,57 +1426,6 @@ fn update_cpuid_topology(
}
}
}
// The goal is to update the CPUID sub-leaves to reflect the number of EPC
// sections exposed to the guest.
fn update_cpuid_sgx(
cpuid: &mut Vec<CpuIdEntry>,
epc_sections: &[SgxEpcSection],
) -> Result<(), Error> {
// Something's wrong if there's no EPC section.
if epc_sections.is_empty() {
return Err(Error::NoSgxEpcSection);
}
// We can't go further if the hypervisor does not support SGX feature.
if !CpuidPatch::is_feature_enabled(cpuid, 0x7, 0, CpuidReg::EBX, 2) {
return Err(Error::MissingSgxFeature);
}
// We can't go further if the hypervisor does not support SGX_LC feature.
if !CpuidPatch::is_feature_enabled(cpuid, 0x7, 0, CpuidReg::ECX, 30) {
return Err(Error::MissingSgxLaunchControlFeature);
}
// Get host CPUID for leaf 0x12, subleaf 0x2. This is to retrieve EPC
// properties such as confidentiality and integrity.
// SAFETY: call cpuid with valid leaves
let leaf = unsafe { std::arch::x86_64::__cpuid_count(0x12, 0x2) };
for (i, epc_section) in epc_sections.iter().enumerate() {
let subleaf_idx = i + 2;
let start = epc_section.start().raw_value();
let size = epc_section.size();
let eax = (start & 0xffff_f000) as u32 | 0x1;
let ebx = (start >> 32) as u32;
let ecx = (size & 0xffff_f000) as u32 | (leaf.ecx & 0xf);
let edx = (size >> 32) as u32;
// CPU Topology leaf 0x12
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EAX, eax);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EBX, ebx);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::ECX, ecx);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EDX, edx);
}
// Add one NULL entry to terminate the dynamic list
let subleaf_idx = epc_sections.len() + 2;
// CPU Topology leaf 0x12
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EAX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EBX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::ECX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EDX, 0);
Ok(())
}
#[cfg(test)]
mod tests {
use linux_loader::loader::bootparam::boot_e820_entry;
@@ -1578,7 +1456,6 @@ mod tests {
None,
None,
None,
None,
);
config_err.unwrap_err();
@@ -1603,7 +1480,6 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
@@ -1633,7 +1509,6 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
@@ -1649,7 +1524,6 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
}
@@ -1721,22 +1595,27 @@ mod tests {
#[test]
fn test_get_x2apic_id() {
let x2apic_id = get_x2apic_id(0, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(0, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 0);
let x2apic_id = get_x2apic_id(1, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(1, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 1);
let x2apic_id = get_x2apic_id(2, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(2, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 2);
let x2apic_id = get_x2apic_id(6, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(6, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 8);
let x2apic_id = get_x2apic_id(7, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(7, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 9);
let x2apic_id = get_x2apic_id(8, Some((2, 3, 1)));
let x2apic_id = get_x2apic_id(8, Some((2, 3, 1, 1)));
assert_eq!(x2apic_id, 10);
let x2apic_id = get_x2apic_id(257, Some((1, 312, 1, 1)));
assert_eq!(x2apic_id, 257);
assert_eq!(255, get_max_x2apic_id((1, 256, 1, 1)));
}
}

View File

@@ -11,9 +11,10 @@ use libc::c_uchar;
use thiserror::Error;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError};
use super::MAX_SUPPORTED_CPUS_LEGACY;
use crate::GuestMemoryMmap;
use crate::layout::{APIC_START, HIGH_RAM_START, IOAPIC_START};
use crate::x86_64::{get_x2apic_id, mpspec};
use crate::GuestMemoryMmap;
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `ByteValued`) where:
@@ -61,9 +62,6 @@ pub enum Error {
/// Failure while zeroing out the memory for the MP table.
#[error("Failure while zeroing out the memory for the MP table")]
Clear(#[source] GuestMemoryError),
/// Number of CPUs exceeds the maximum supported CPUs
#[error("Number of CPUs exceeds the maximum supported CPUs")]
TooManyCpus,
/// Failure to write the MP floating pointer.
#[error("Failure to write the MP floating pointer")]
WriteMpfIntel(#[source] GuestMemoryError),
@@ -89,11 +87,6 @@ pub enum Error {
pub type Result<T> = result::Result<T, Error>;
// With APIC/xAPIC, there are only 255 APIC IDs available. And IOAPIC occupies
// one APIC ID, so only 254 CPUs at maximum may be supported. Actually it's
// a large number for FC usecases.
pub const MAX_SUPPORTED_CPUS: u32 = 254;
// Most of these variables are sourced from the Intel MP Spec 1.4.
const SMP_MAGIC_IDENT: &[c_uchar; 4] = b"_MP_";
const MPC_SIGNATURE: &[c_uchar; 4] = b"PCMP";
@@ -121,7 +114,7 @@ fn mpf_intel_compute_checksum(v: &mpspec::mpf_intel) -> u8 {
(!checksum).wrapping_add(1)
}
fn compute_mp_size(num_cpus: u8) -> usize {
fn compute_mp_size(num_cpus: u32) -> usize {
mem::size_of::<MpfIntelWrapper>()
+ mem::size_of::<MpcTableWrapper>()
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
@@ -135,14 +128,15 @@ fn compute_mp_size(num_cpus: u8) -> usize {
pub fn setup_mptable(
offset: GuestAddress,
mem: &GuestMemoryMmap,
num_cpus: u8,
topology: Option<(u8, u8, u8)>,
num_cpus: u32,
topology: Option<(u16, u16, u16, u16)>,
) -> Result<()> {
if num_cpus > 0 {
let cpu_id_max = num_cpus - 1;
let x2apic_id_max = get_x2apic_id(cpu_id_max.into(), topology);
if x2apic_id_max >= MAX_SUPPORTED_CPUS {
return Err(Error::TooManyCpus);
let x2apic_id_max = get_x2apic_id(cpu_id_max, topology);
if x2apic_id_max >= MAX_SUPPORTED_CPUS_LEGACY {
info!("Skipping mptable creation due to too many CPUs");
return Ok(());
}
}
@@ -157,7 +151,7 @@ pub fn setup_mptable(
}
let mut checksum: u8 = 0;
let ioapicid: u8 = MAX_SUPPORTED_CPUS as u8 + 1;
let ioapicid: u8 = MAX_SUPPORTED_CPUS_LEGACY as u8 + 1;
// The checked_add here ensures the all of the following base_mp.unchecked_add's will be without
// overflow.
@@ -195,7 +189,7 @@ pub fn setup_mptable(
for cpu_id in 0..num_cpus {
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
mpc_cpu.0.apicid = get_x2apic_id(cpu_id as u32, topology) as u8;
mpc_cpu.0.apicid = get_x2apic_id(cpu_id, topology) as u8;
mpc_cpu.0.apicver = APIC_VERSION;
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
| if cpu_id == 0 {
@@ -394,11 +388,11 @@ mod tests {
fn cpu_entry_count() {
let mem = GuestMemoryMmap::from_ranges(&[(
MPTABLE_START,
compute_mp_size(MAX_SUPPORTED_CPUS as u8),
compute_mp_size(MAX_SUPPORTED_CPUS_LEGACY),
)])
.unwrap();
for i in 0..MAX_SUPPORTED_CPUS as u8 {
for i in 0..MAX_SUPPORTED_CPUS_LEGACY {
setup_mptable(MPTABLE_START, &mem, i, None).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
@@ -428,11 +422,9 @@ mod tests {
#[test]
fn cpu_entry_count_max() {
let cpus = MAX_SUPPORTED_CPUS + 1;
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let cpus = MAX_SUPPORTED_CPUS_LEGACY + 1;
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus))]).unwrap();
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8, None);
result.unwrap_err();
setup_mptable(MPTABLE_START, &mem, cpus, None).unwrap();
}
}

View File

@@ -6,7 +6,6 @@
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use std::sync::Arc;
use std::{mem, result};
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
@@ -67,7 +66,7 @@ pub type Result<T> = result::Result<T, Error>;
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_fpu(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
pub fn setup_fpu(vcpu: &dyn hypervisor::Vcpu) -> Result<()> {
let fpu: FpuState = FpuState {
fcw: 0x37f,
mxcsr: 0x1f80,
@@ -82,7 +81,7 @@ pub fn setup_fpu(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
pub fn setup_msrs(vcpu: &dyn hypervisor::Vcpu) -> Result<()> {
vcpu.set_msrs(&vcpu.boot_msr_entries())
.map_err(Error::SetModelSpecificRegisters)?;
@@ -95,7 +94,7 @@ pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
/// * `entry_point` - Description of the boot entry to set up.
pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, entry_point: EntryPoint) -> Result<()> {
pub fn setup_regs(vcpu: &dyn hypervisor::Vcpu, entry_point: EntryPoint) -> Result<()> {
let mut regs = vcpu.create_standard_regs();
match entry_point.setup_header {
None => {
@@ -119,9 +118,13 @@ pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, entry_point: EntryPoint) ->
///
/// * `mem` - The memory that will be passed to the guest.
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
pub fn setup_sregs(
mem: &GuestMemoryMmap,
vcpu: &dyn hypervisor::Vcpu,
enable_x2_apic_mode: bool,
) -> Result<()> {
let mut sregs: SpecialRegisters = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
configure_segments_and_sregs(mem, &mut sregs)?;
configure_segments_and_sregs(mem, &mut sregs, enable_x2_apic_mode)?;
vcpu.set_sregs(&sregs).map_err(Error::SetStatusRegisters)
}
@@ -148,6 +151,7 @@ fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> {
pub fn configure_segments_and_sregs(
mem: &GuestMemoryMmap,
sregs: &mut SpecialRegisters,
enable_x2_apic_mode: bool,
) -> Result<()> {
let gdt_table: [u64; BOOT_GDT_MAX] = {
// Configure GDT entries as specified by PVH boot protocol
@@ -183,6 +187,11 @@ pub fn configure_segments_and_sregs(
sregs.cr0 = CR0_PE;
sregs.cr4 = 0;
if enable_x2_apic_mode {
const X2APIC_ENABLE_BIT: u64 = 1 << 10;
sregs.apic_base |= X2APIC_ENABLE_BIT;
}
Ok(())
}
@@ -204,7 +213,7 @@ mod tests {
fn segments_and_sregs() {
let mut sregs: SpecialRegisters = Default::default();
let gm = create_guest_mem();
configure_segments_and_sregs(&gm, &mut sregs).unwrap();
configure_segments_and_sregs(&gm, &mut sregs, false).unwrap();
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_START));
assert_eq!(
0xcf9b000000ffff,

View File

@@ -12,8 +12,8 @@ use thiserror::Error;
use uuid::Uuid;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress};
use crate::layout::SMBIOS_START;
use crate::GuestMemoryMmap;
use crate::layout::SMBIOS_START;
#[derive(Debug, Error)]
pub enum Error {

View File

@@ -108,7 +108,7 @@ fn tdvf_descriptor_offset(file: &mut File) -> Result<(SeekFrom, bool), TdvfError
u16::from_le_bytes(table[offset - 18..offset - 16].try_into().unwrap()) as usize;
debug!(
"Entry GUID = {}, size = {}",
entry_uuid.hyphenated().to_string(),
entry_uuid.hyphenated(),
entry_size
);

View File

@@ -1,6 +1,6 @@
[package]
authors = ["The Chromium OS Authors", "The Cloud Hypervisor Authors"]
edition = "2021"
edition.workspace = true
name = "block"
version = "0.1.0"
@@ -9,14 +9,14 @@ default = []
io_uring = ["dep:io-uring"]
[dependencies]
byteorder = "1.5.0"
byteorder = { workspace = true }
crc-any = "2.5.0"
io-uring = { version = "0.6.4", optional = true }
libc = "0.2.167"
log = "0.4.22"
io-uring = { version = "0.7.10", optional = true }
libc = { workspace = true }
log = { workspace = true }
remain = "0.2.15"
serde = { version = "1.0.208", features = ["derive"] }
smallvec = "1.13.2"
serde = { workspace = true, features = ["derive"] }
smallvec = "1.15.1"
thiserror = { workspace = true }
uuid = { workspace = true, features = ["v4"] }
virtio-bindings = { workspace = true }

View File

@@ -8,7 +8,7 @@ use std::os::fd::{AsRawFd, OwnedFd, RawFd};
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
use crate::DiskTopology;
use crate::{BatchRequest, DiskTopology};
#[derive(Error, Debug)]
pub enum DiskFileError {
@@ -79,6 +79,9 @@ pub enum AsyncIoError {
/// Failed synchronizing file.
#[error("Failed synchronizing file")]
Fsync(#[source] std::io::Error),
/// Failed submitting batch requests.
#[error("Failed submitting batch requests")]
SubmitBatchRequests(#[source] std::io::Error),
}
pub type AsyncIoResult<T> = std::result::Result<T, AsyncIoError>;
@@ -99,4 +102,10 @@ pub trait AsyncIo: Send {
) -> AsyncIoResult<()>;
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()>;
fn next_completed_request(&mut self) -> Option<(u64, i32)>;
fn batch_requests_enabled(&self) -> bool {
false
}
fn submit_batch_requests(&mut self, _batch_request: &[BatchRequest]) -> AsyncIoResult<()> {
Ok(())
}
}

View File

@@ -6,8 +6,8 @@ use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write};
use std::os::unix::io::{AsRawFd, RawFd};
use crate::vhd::VhdFooter;
use crate::BlockBackend;
use crate::vhd::VhdFooter;
#[derive(Debug)]
pub struct FixedVhd {

View File

@@ -12,7 +12,7 @@ use crate::async_io::{
};
use crate::fixed_vhd::FixedVhd;
use crate::raw_async::RawFileAsync;
use crate::BlockBackend;
use crate::{BatchRequest, BlockBackend};
pub struct FixedVhdDiskAsync(FixedVhd);
@@ -106,4 +106,12 @@ impl AsyncIo for FixedVhdAsync {
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.raw_file_async.next_completed_request()
}
fn batch_requests_enabled(&self) -> bool {
true
}
fn submit_batch_requests(&mut self, batch_request: &[BatchRequest]) -> AsyncIoResult<()> {
self.raw_file_async.submit_batch_requests(batch_request)
}
}

View File

@@ -7,12 +7,12 @@ use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
use crate::BlockBackend;
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::fixed_vhd::FixedVhd;
use crate::raw_sync::RawFileSync;
use crate::BlockBackend;
pub struct FixedVhdDiskSync(FixedVhd);

View File

@@ -31,7 +31,7 @@ pub mod vhd;
pub mod vhdx;
pub mod vhdx_sync;
use std::alloc::{alloc_zeroed, dealloc, Layout};
use std::alloc::{Layout, alloc_zeroed, dealloc};
use std::collections::VecDeque;
use std::fmt::Debug;
use std::fs::File;
@@ -39,13 +39,12 @@ use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use std::os::linux::fs::MetadataExt;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::sync::{Arc, MutexGuard};
use std::time::Instant;
use std::{cmp, result};
#[cfg(feature = "io_uring")]
use io_uring::{opcode, IoUring, Probe};
use libc::{ioctl, S_IFBLK, S_IFMT};
use io_uring::{IoUring, Probe, opcode};
use libc::{S_IFBLK, S_IFMT, ioctl};
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
use thiserror::Error;
@@ -139,6 +138,8 @@ pub enum ExecuteError {
Read(#[source] GuestMemoryError),
#[error("Failed to read_exact")]
ReadExact(#[source] io::Error),
#[error("Can't execute an operation other than `read` on a read-only device")]
ReadOnly,
#[error("Failed to seek")]
Seek(#[source] io::Error),
#[error("Failed to write")]
@@ -168,6 +169,7 @@ impl ExecuteError {
ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::ReadExact(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::ReadOnly => VIRTIO_BLK_S_IOERR,
ExecuteError::Seek(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Write(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::WriteAll(_) => VIRTIO_BLK_S_IOERR,
@@ -229,6 +231,20 @@ pub struct AlignedOperation {
layout: Layout,
}
pub struct BatchRequest {
pub offset: libc::off_t,
pub iovecs: SmallVec<[libc::iovec; DEFAULT_DESCRIPTOR_VEC_SIZE]>,
pub user_data: u64,
pub request_type: RequestType,
}
pub struct ExecuteAsync {
// `true` if the execution will complete asynchronously
pub async_complete: bool,
// request need to be batched for submission if any
pub batch_request: Option<BatchRequest>,
}
#[derive(Debug)]
pub struct Request {
pub request_type: RequestType,
@@ -243,7 +259,7 @@ pub struct Request {
impl Request {
pub fn parse<B: Bitmap + 'static>(
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<vm_memory::GuestMemoryMmap<B>>>,
access_platform: Option<&Arc<dyn AccessPlatform>>,
access_platform: Option<&dyn AccessPlatform>,
) -> result::Result<Request, Error> {
let hdr_desc = desc_chain
.next()
@@ -276,14 +292,14 @@ impl Request {
.next()
.ok_or(Error::DescriptorChainTooShort)
.inspect_err(|_| {
error!("Only head descriptor present: request = {:?}", req);
error!("Only head descriptor present: request = {req:?}");
})?;
if !desc.has_next() {
status_desc = desc;
// Only flush requests are allowed to skip the data descriptor.
if req.request_type != RequestType::Flush {
error!("Need a data descriptor: request = {:?}", req);
error!("Need a data descriptor: request = {req:?}");
return Err(Error::DescriptorChainTooShort);
}
} else {
@@ -308,7 +324,7 @@ impl Request {
.next()
.ok_or(Error::DescriptorChainTooShort)
.inspect_err(|_| {
error!("DescriptorChain corrupted: request = {:?}", req);
error!("DescriptorChain corrupted: request = {req:?}");
})?;
}
status_desc = desc;
@@ -394,7 +410,7 @@ impl Request {
disk_image: &mut dyn AsyncIo,
serial: &[u8],
user_data: u64,
) -> result::Result<bool, ExecuteError> {
) -> result::Result<ExecuteAsync, ExecuteError> {
let sector = self.sector;
let request_type = self.request_type;
let offset = (sector << SECTOR_SHIFT) as libc::off_t;
@@ -431,7 +447,7 @@ impl Request {
// In case it's not properly aligned, an intermediate buffer is
// created with the correct alignment, and a copy from/to the
// origin buffer is performed, depending on the type of operation.
let iov_base = if (origin_ptr.as_ptr() as u64) % SECTOR_SIZE != 0 {
let iov_base = if !(origin_ptr.as_ptr() as u64).is_multiple_of(SECTOR_SIZE) {
let layout = Layout::from_size_align(data_len, SECTOR_SIZE as usize).unwrap();
// SAFETY: layout has non-zero size
let aligned_ptr = unsafe { alloc_zeroed(layout) };
@@ -470,6 +486,10 @@ impl Request {
iovecs.push(iovec);
}
let mut ret = ExecuteAsync {
async_complete: true,
batch_request: None,
};
// Queue operations expected to be submitted.
match request_type {
RequestType::In => {
@@ -479,14 +499,32 @@ impl Request {
.bitmap()
.mark_dirty(0, *data_len as usize);
}
disk_image
.read_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncRead)?;
if disk_image.batch_requests_enabled() {
ret.batch_request = Some(BatchRequest {
offset,
iovecs,
user_data,
request_type,
});
} else {
disk_image
.read_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncRead)?;
}
}
RequestType::Out => {
disk_image
.write_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncWrite)?;
if disk_image.batch_requests_enabled() {
ret.batch_request = Some(BatchRequest {
offset,
iovecs,
user_data,
request_type,
});
} else {
disk_image
.write_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncWrite)?;
}
}
RequestType::Flush => {
disk_image
@@ -504,12 +542,13 @@ impl Request {
}
mem.write_slice(serial, data_addr)
.map_err(ExecuteError::Write)?;
return Ok(false);
ret.async_complete = false;
return Ok(ret);
}
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
}
Ok(true)
Ok(ret)
}
pub fn complete_async(&mut self) -> result::Result<(), Error> {
@@ -646,10 +685,7 @@ pub fn block_io_uring_is_supported() -> bool {
}
}
pub trait AsyncAdaptor<F>
where
F: Read + Write + Seek,
{
pub trait AsyncAdaptor {
fn read_vectored_sync(
&mut self,
offset: libc::off_t,
@@ -657,7 +693,10 @@ where
user_data: u64,
eventfd: &EventFd,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
) -> AsyncIoResult<()>
where
Self: Read + Seek,
{
// Convert libc::iovec into IoSliceMut
let mut slices: SmallVec<[IoSliceMut; DEFAULT_DESCRIPTOR_VEC_SIZE]> =
SmallVec::with_capacity(iovecs.len());
@@ -669,15 +708,13 @@ where
}
let result = {
let mut file = self.file();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
self.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?;
let mut r = 0;
for b in slices.iter_mut() {
r += file.read(b).map_err(AsyncIoError::ReadVectored)?;
r += self.read(b).map_err(AsyncIoError::ReadVectored)?;
}
r
};
@@ -695,7 +732,10 @@ where
user_data: u64,
eventfd: &EventFd,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
) -> AsyncIoResult<()>
where
Self: Write + Seek,
{
// Convert libc::iovec into IoSlice
let mut slices: SmallVec<[IoSlice; DEFAULT_DESCRIPTOR_VEC_SIZE]> =
SmallVec::with_capacity(iovecs.len());
@@ -707,15 +747,13 @@ where
}
let result = {
let mut file = self.file();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
self.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?;
let mut r = 0;
for b in slices.iter() {
r += file.write(b).map_err(AsyncIoError::WriteVectored)?;
r += self.write(b).map_err(AsyncIoError::WriteVectored)?;
}
r
};
@@ -731,12 +769,13 @@ where
user_data: Option<u64>,
eventfd: &EventFd,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
) -> AsyncIoResult<()>
where
Self: Write,
{
let result: i32 = {
let mut file = self.file();
// Flush
file.flush().map_err(AsyncIoError::Fsync)?;
self.flush().map_err(AsyncIoError::Fsync)?;
0
};
@@ -748,8 +787,6 @@ where
Ok(())
}
fn file(&mut self) -> MutexGuard<'_, F>;
}
pub enum ImageType {

View File

@@ -24,11 +24,11 @@ use vmm_sys_util::file_traits::{FileSetLen, FileSync};
use vmm_sys_util::seek_hole::SeekHole;
use vmm_sys_util::write_zeroes::{PunchHole, WriteZeroesAt};
use crate::BlockBackend;
use crate::qcow::qcow_raw_file::QcowRawFile;
pub use crate::qcow::raw_file::RawFile;
use crate::qcow::refcount::RefCount;
use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
use crate::BlockBackend;
/// Nesting depth limit for disk formats that can open other disk files.
const MAX_NESTING_DEPTH: u32 = 10;
@@ -287,11 +287,12 @@ impl QcowHeader {
let cluster_bits: u32 = DEFAULT_CLUSTER_BITS;
let cluster_size: u32 = 0x01 << cluster_bits;
let max_length: usize = (cluster_size - header_size) as usize;
if let Some(path) = backing_file {
if path.len() > max_length {
return Err(Error::BackingFileTooLong(path.len() - max_length));
}
if let Some(path) = backing_file
&& path.len() > max_length
{
return Err(Error::BackingFileTooLong(path.len() - max_length));
}
// L2 blocks are always one cluster long. They contain cluster_size/sizeof(u64) addresses.
let entries_per_cluster: u32 = cluster_size / size_of::<u64>() as u32;
let num_clusters: u32 = div_round_up_u64(size, u64::from(cluster_size)) as u32;
@@ -425,7 +426,7 @@ fn max_refcount_clusters(refcount_order: u32, cluster_size: u32, num_clusters: u
/// # Ok(())
/// # }
/// ```
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct QcowFile {
raw_file: QcowRawFile,
header: QcowHeader,
@@ -589,14 +590,12 @@ impl QcowFile {
// Check for compressed blocks
for l2_addr_disk in l1_table.get_values() {
if *l2_addr_disk != 0 {
if let Err(e) = Self::read_l2_cluster(&mut raw_file, *l2_addr_disk) {
if let Some(os_error) = e.raw_os_error() {
if os_error == ENOTSUP {
return Err(Error::CompressedBlocksNotSupported);
}
}
}
if *l2_addr_disk != 0
&& let Err(e) = Self::read_l2_cluster(&mut raw_file, *l2_addr_disk)
&& let Some(os_error) = e.raw_os_error()
&& os_error == ENOTSUP
{
return Err(Error::CompressedBlocksNotSupported);
}
}
@@ -1071,21 +1070,7 @@ impl QcowFile {
let l2_index = self.l2_table_index(address) as usize;
if !self.l2_cache.contains_key(l1_index) {
// Not in the cache.
let table =
VecCache::from_vec(Self::read_l2_cluster(&mut self.raw_file, l2_addr_disk)?);
let l1_table = &self.l1_table;
let raw_file = &mut self.raw_file;
self.l2_cache.insert(l1_index, table, |index, evicted| {
raw_file.write_pointer_table(
l1_table[index],
evicted.get_values(),
CLUSTER_USED_FLAG,
)
})?;
};
self.cache_l2_cluster(l1_index, l2_addr_disk, false)?;
let cluster_addr = self.l2_cache.get(l1_index).unwrap()[l2_index];
if cluster_addr == 0 {
@@ -1110,28 +1095,9 @@ impl QcowFile {
let mut set_refcounts = Vec::new();
if !self.l2_cache.contains_key(l1_index) {
// Not in the cache.
let l2_table = if l2_addr_disk == 0 {
// Allocate a new cluster to store the L2 table and update the L1 table to point
// to the new table.
let new_addr: u64 = self.get_new_cluster(None)?;
// The cluster refcount starts at one meaning it is used but doesn't need COW.
set_refcounts.push((new_addr, 1));
self.l1_table[l1_index] = new_addr;
VecCache::new(self.l2_entries as usize)
} else {
VecCache::from_vec(Self::read_l2_cluster(&mut self.raw_file, l2_addr_disk)?)
};
let l1_table = &self.l1_table;
let raw_file = &mut self.raw_file;
self.l2_cache.insert(l1_index, l2_table, |index, evicted| {
raw_file.write_pointer_table(
l1_table[index],
evicted.get_values(),
CLUSTER_USED_FLAG,
)
})?;
if let Some(new_addr) = self.cache_l2_cluster(l1_index, l2_addr_disk, true)? {
// The cluster refcount starts at one meaning it is used but doesn't need COW.
set_refcounts.push((new_addr, 1));
}
let cluster_addr = match self.l2_cache.get(l1_index).unwrap()[l2_index] {
@@ -1248,20 +1214,7 @@ impl QcowFile {
return Ok(false);
}
if !self.l2_cache.contains_key(l1_index) {
// Not in the cache.
let table =
VecCache::from_vec(Self::read_l2_cluster(&mut self.raw_file, l2_addr_disk)?);
let l1_table = &self.l1_table;
let raw_file = &mut self.raw_file;
self.l2_cache.insert(l1_index, table, |index, evicted| {
raw_file.write_pointer_table(
l1_table[index],
evicted.get_values(),
CLUSTER_USED_FLAG,
)
})?;
}
self.cache_l2_cluster(l1_index, l2_addr_disk, false)?;
let cluster_addr = self.l2_cache.get(l1_index).unwrap()[l2_index];
// If cluster_addr != 0, the cluster is allocated.
@@ -1320,20 +1273,7 @@ impl QcowFile {
return Ok(());
}
if !self.l2_cache.contains_key(l1_index) {
// Not in the cache.
let table =
VecCache::from_vec(Self::read_l2_cluster(&mut self.raw_file, l2_addr_disk)?);
let l1_table = &self.l1_table;
let raw_file = &mut self.raw_file;
self.l2_cache.insert(l1_index, table, |index, evicted| {
raw_file.write_pointer_table(
l1_table[index],
evicted.get_values(),
CLUSTER_USED_FLAG,
)
})?;
}
self.cache_l2_cluster(l1_index, l2_addr_disk, false)?;
let cluster_addr = self.l2_cache.get(l1_index).unwrap()[l2_index];
if cluster_addr == 0 {
@@ -1418,6 +1358,41 @@ impl QcowFile {
.collect())
}
// Put an L2 cluster to the cache with evicting less-used cluster
// The new cluster may be allocated if necessary
// (may_alloc argument is true and l2_addr_disk == 0)
fn cache_l2_cluster(
&mut self,
l1_index: usize,
l2_addr_disk: u64,
may_alloc: bool,
) -> std::io::Result<Option<u64>> {
let mut new_cluster: Option<u64> = None;
if !self.l2_cache.contains_key(l1_index) {
// Not in the cache.
let l2_table = if may_alloc && l2_addr_disk == 0 {
// Allocate a new cluster to store the L2 table and update the L1 table to point
// to the new table.
let new_addr: u64 = self.get_new_cluster(None)?;
new_cluster = Some(new_addr);
self.l1_table[l1_index] = new_addr;
VecCache::new(self.l2_entries as usize)
} else {
VecCache::from_vec(Self::read_l2_cluster(&mut self.raw_file, l2_addr_disk)?)
};
let l1_table = &self.l1_table;
let raw_file = &mut self.raw_file;
self.l2_cache.insert(l1_index, l2_table, |index, evicted| {
raw_file.write_pointer_table(
l1_table[index],
evicted.get_values(),
CLUSTER_USED_FLAG,
)
})?;
}
Ok(new_cluster)
}
// Set the refcount for a cluster with the given address.
// Returns a list of any refblocks that can be reused, this happens when a refblock is moved,
// the old location can be reused.
@@ -1584,11 +1559,11 @@ impl Seek for QcowFile {
}
};
if let Some(o) = new_offset {
if o <= self.virtual_size() {
self.current_offset = o;
return Ok(o);
}
if let Some(o) = new_offset
&& o <= self.virtual_size()
{
self.current_offset = o;
return Ok(o);
}
Err(std::io::Error::from_raw_os_error(EINVAL))
}
@@ -1705,12 +1680,12 @@ fn offset_is_cluster_boundary(offset: u64, cluster_bits: u32) -> Result<()> {
// Ceiling of the division of `dividend`/`divisor`.
fn div_round_up_u64(dividend: u64, divisor: u64) -> u64 {
dividend / divisor + u64::from(dividend % divisor != 0)
dividend / divisor + u64::from(!dividend.is_multiple_of(divisor))
}
// Ceiling of the division of `dividend`/`divisor`.
fn div_round_up_u32(dividend: u32, divisor: u32) -> u32 {
dividend / divisor + u32::from(dividend % divisor != 0)
dividend / divisor + u32::from(!dividend.is_multiple_of(divisor))
}
fn convert_copy<R, W>(reader: &mut R, writer: &mut W, offset: u64, size: u64) -> Result<()>

View File

@@ -8,7 +8,7 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::alloc::{alloc_zeroed, dealloc, Layout};
use std::alloc::{Layout, alloc_zeroed, dealloc};
use std::fs::{File, Metadata};
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::os::unix::io::{AsRawFd, RawFd};
@@ -89,9 +89,9 @@ impl RawFile {
let align64: u64 = self.alignment.try_into().unwrap();
(self.position % align64 == 0)
&& ((buf.as_ptr() as usize) % self.alignment == 0)
&& (buf.len() % self.alignment == 0)
self.position.is_multiple_of(align64)
&& (buf.as_ptr() as usize).is_multiple_of(self.alignment)
&& buf.len().is_multiple_of(self.alignment)
}
pub fn set_len(&self, size: u64) -> std::io::Result<()> {

View File

@@ -4,8 +4,8 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::collections::hash_map::IterMut;
use std::collections::HashMap;
use std::collections::hash_map::IterMut;
use std::io;
use std::ops::{Index, IndexMut};
use std::slice::SliceIndex;
@@ -123,10 +123,10 @@ impl<T: Cacheable> CacheMap<T> {
if self.map.len() == self.capacity {
// TODO(dgreid) - smarter eviction strategy.
let to_evict = *self.map.iter().next().unwrap().0;
if let Some(evicted) = self.map.remove(&to_evict) {
if evicted.dirty() {
write_callback(to_evict, evicted)?;
}
if let Some(evicted) = self.map.remove(&to_evict)
&& evicted.dirty()
{
write_callback(to_evict, evicted)?;
}
}
self.map.insert(index, block);

View File

@@ -6,33 +6,32 @@ use std::collections::VecDeque;
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::os::fd::AsRawFd;
use std::sync::{Arc, Mutex, MutexGuard};
use vmm_sys_util::eventfd::EventFd;
use crate::AsyncAdaptor;
use crate::async_io::{
AsyncIo, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::qcow::{QcowFile, RawFile, Result as QcowResult};
use crate::AsyncAdaptor;
pub struct QcowDiskSync {
qcow_file: Arc<Mutex<QcowFile>>,
qcow_file: QcowFile,
}
impl QcowDiskSync {
pub fn new(file: File, direct_io: bool) -> QcowResult<Self> {
Ok(QcowDiskSync {
qcow_file: Arc::new(Mutex::new(QcowFile::from(RawFile::new(file, direct_io))?)),
qcow_file: QcowFile::from(RawFile::new(file, direct_io))?,
})
}
}
impl DiskFile for QcowDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
let mut file = self.qcow_file.lock().unwrap();
file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)
self.qcow_file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
@@ -40,19 +39,18 @@ impl DiskFile for QcowDiskSync {
}
fn fd(&mut self) -> BorrowedDiskFd<'_> {
let lock = self.qcow_file.lock().unwrap();
BorrowedDiskFd::new(lock.as_raw_fd())
BorrowedDiskFd::new(self.qcow_file.as_raw_fd())
}
}
pub struct QcowSync {
qcow_file: Arc<Mutex<QcowFile>>,
qcow_file: QcowFile,
eventfd: EventFd,
completion_list: VecDeque<(u64, i32)>,
}
impl QcowSync {
pub fn new(qcow_file: Arc<Mutex<QcowFile>>) -> Self {
pub fn new(qcow_file: QcowFile) -> Self {
QcowSync {
qcow_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)
@@ -62,11 +60,7 @@ impl QcowSync {
}
}
impl AsyncAdaptor<QcowFile> for Arc<Mutex<QcowFile>> {
fn file(&mut self) -> MutexGuard<'_, QcowFile> {
self.lock().unwrap()
}
}
impl AsyncAdaptor for QcowFile {}
impl AsyncIo for QcowSync {
fn notifier(&self) -> &EventFd {

View File

@@ -6,13 +6,13 @@ use std::fs::File;
use std::io::{Error, Seek, SeekFrom};
use std::os::unix::io::{AsRawFd, RawFd};
use io_uring::{opcode, types, IoUring};
use io_uring::{IoUring, opcode, types};
use vmm_sys_util::eventfd::EventFd;
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
use crate::{BatchRequest, DiskTopology, RequestType};
pub struct RawFileDisk {
file: File,
@@ -168,4 +168,77 @@ impl AsyncIo for RawFileAsync {
.next()
.map(|entry| (entry.user_data(), entry.result()))
}
fn batch_requests_enabled(&self) -> bool {
true
}
fn submit_batch_requests(&mut self, batch_request: &[BatchRequest]) -> AsyncIoResult<()> {
if !self.batch_requests_enabled() {
return Ok(());
}
let (submitter, mut sq, _) = self.io_uring.split();
let mut submitted = false;
for req in batch_request {
match req.request_type {
RequestType::In => {
// SAFETY: we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
unsafe {
sq.push(
&opcode::Readv::new(
types::Fd(self.fd),
req.iovecs.as_ptr(),
req.iovecs.len() as u32,
)
.offset(req.offset as u64)
.build()
.user_data(req.user_data),
)
.map_err(|_| {
AsyncIoError::ReadVectored(Error::other("Submission queue is full"))
})?
};
submitted = true;
}
RequestType::Out => {
// SAFETY: we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
unsafe {
sq.push(
&opcode::Writev::new(
types::Fd(self.fd),
req.iovecs.as_ptr(),
req.iovecs.len() as u32,
)
.offset(req.offset as u64)
.build()
.user_data(req.user_data),
)
.map_err(|_| {
AsyncIoError::WriteVectored(Error::other("Submission queue is full"))
})?
};
submitted = true;
}
_ => {
unreachable!("Unexpected batch request type: {:?}", req.request_type)
}
}
}
// Only submit if we actually queued something
if submitted {
// Update the submission queue and submit new operations to the
// io_uring instance.
sq.sync();
submitter
.submit()
.map_err(AsyncIoError::SubmitBatchRequests)?;
}
Ok(())
}
}

View File

@@ -12,10 +12,10 @@ use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::aio;
use vmm_sys_util::eventfd::EventFd;
use crate::DiskTopology;
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
pub struct RawFileDiskAio {
file: File,

View File

@@ -9,10 +9,10 @@ use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
use crate::DiskTopology;
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
pub struct RawFileDiskSync {
file: File,

View File

@@ -5,7 +5,7 @@
use std::fs::File;
use std::io::{Seek, SeekFrom};
use crate::{read_aligned_block_size, DiskTopology};
use crate::{DiskTopology, read_aligned_block_size};
#[derive(Clone, Copy)]
pub struct VhdFooter {
@@ -123,7 +123,7 @@ mod tests {
use vmm_sys_util::tempfile::TempFile;
use super::{is_fixed_vhd, VhdFooter};
use super::{VhdFooter, is_fixed_vhd};
fn valid_fixed_vhd_footer() -> Vec<u8> {
vec![

View File

@@ -12,11 +12,11 @@ use remain::sorted;
use thiserror::Error;
use uuid::Uuid;
use crate::BlockBackend;
use crate::vhdx::vhdx_bat::{BatEntry, VhdxBatError};
use crate::vhdx::vhdx_header::{RegionInfo, RegionTableEntry, VhdxHeader, VhdxHeaderError};
use crate::vhdx::vhdx_io::VhdxIoError;
use crate::vhdx::vhdx_metadata::{DiskSpec, VhdxMetadataError};
use crate::BlockBackend;
mod vhdx_bat;
mod vhdx_header;
@@ -187,11 +187,11 @@ impl Seek for Vhdx {
}
};
if let Some(o) = new_offset {
if o <= self.virtual_disk_size() {
self.current_offset = o;
return Ok(o);
}
if let Some(o) = new_offset
&& o <= self.virtual_disk_size()
{
self.current_offset = o;
return Ok(o);
}
Err(std::io::Error::new(

View File

@@ -35,9 +35,7 @@ pub enum VhdxIoError {
pub type Result<T> = std::result::Result<T, VhdxIoError>;
macro_rules! align {
($n:expr, $align:expr) => {{
$n.div_ceil($align) * $align
}};
($n:expr, $align:expr) => {{ $n.div_ceil($align) * $align }};
}
#[derive(Default)]

View File

@@ -5,31 +5,30 @@
use std::collections::VecDeque;
use std::fs::File;
use std::os::fd::AsRawFd;
use std::sync::{Arc, Mutex, MutexGuard};
use vmm_sys_util::eventfd::EventFd;
use crate::AsyncAdaptor;
use crate::async_io::{
AsyncIo, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult,
};
use crate::vhdx::{Result as VhdxResult, Vhdx};
use crate::AsyncAdaptor;
pub struct VhdxDiskSync {
vhdx_file: Arc<Mutex<Vhdx>>,
vhdx_file: Vhdx,
}
impl VhdxDiskSync {
pub fn new(f: File) -> VhdxResult<Self> {
Ok(VhdxDiskSync {
vhdx_file: Arc::new(Mutex::new(Vhdx::new(f)?)),
vhdx_file: Vhdx::new(f)?,
})
}
}
impl DiskFile for VhdxDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self.vhdx_file.lock().unwrap().virtual_disk_size())
Ok(self.vhdx_file.virtual_disk_size())
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
@@ -40,19 +39,18 @@ impl DiskFile for VhdxDiskSync {
}
fn fd(&mut self) -> BorrowedDiskFd<'_> {
let lock = self.vhdx_file.lock().unwrap();
BorrowedDiskFd::new(lock.as_raw_fd())
BorrowedDiskFd::new(self.vhdx_file.as_raw_fd())
}
}
pub struct VhdxSync {
vhdx_file: Arc<Mutex<Vhdx>>,
vhdx_file: Vhdx,
eventfd: EventFd,
completion_list: VecDeque<(u64, i32)>,
}
impl VhdxSync {
pub fn new(vhdx_file: Arc<Mutex<Vhdx>>) -> std::io::Result<Self> {
pub fn new(vhdx_file: Vhdx) -> std::io::Result<Self> {
Ok(VhdxSync {
vhdx_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)?,
@@ -61,11 +59,7 @@ impl VhdxSync {
}
}
impl AsyncAdaptor<Vhdx> for Arc<Mutex<Vhdx>> {
fn file(&mut self) -> MutexGuard<'_, Vhdx> {
self.lock().unwrap()
}
}
impl AsyncAdaptor for Vhdx {}
impl AsyncIo for VhdxSync {
fn notifier(&self) -> &EventFd {

View File

@@ -9,14 +9,13 @@ use std::process::Command;
fn main() {
let mut version = "v".to_owned() + env!("CARGO_PKG_VERSION");
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
version = git_out_str;
// Pop the trailing newline.
version.pop();
}
}
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output()
&& git_out.status.success()
&& let Ok(git_out_str) = String::from_utf8(git_out.stdout)
{
version = git_out_str;
// Pop the trailing newline.
version.pop();
}
// Append CH_EXTRA_VERSION to version if it is set.

View File

@@ -1,22 +1,28 @@
[package]
authors = ["The Chromium OS Authors"]
edition = "2021"
edition.workspace = true
name = "devices"
version = "0.1.0"
[dependencies]
acpi_tables = { workspace = true }
anyhow = "1.0.94"
anyhow = { workspace = true }
arch = { path = "../arch" }
bitflags = "2.9.0"
byteorder = "1.5.0"
bitfield-struct = { version = "0.12.0", optional = true }
bitflags = { workspace = true }
byteorder = { workspace = true }
event_monitor = { path = "../event_monitor" }
hypervisor = { path = "../hypervisor" }
libc = "0.2.167"
log = "0.4.22"
num_enum = "0.7.2"
libc = { workspace = true }
linux-loader = { workspace = true, features = [
"bzimage",
"elf",
"pe",
], optional = true }
log = { workspace = true }
num_enum = "0.7.4"
pci = { path = "../pci" }
serde = { version = "1.0.208", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
tpm = { path = "../tpm" }
vm-allocator = { path = "../vm-allocator" }
@@ -28,11 +34,17 @@ vm-memory = { workspace = true, features = [
] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { workspace = true }
zerocopy = { version = "0.8.27", features = [
"alloc",
"derive",
], optional = true }
[target.'cfg(any(target_arch = "aarch64", target_arch = "riscv64"))'.dependencies]
arch = { path = "../arch" }
[features]
default = []
fw_cfg = ["arch/fw_cfg", "bitfield-struct", "linux-loader", "zerocopy"]
ivshmem = []
kvm = ["arch/kvm"]
pvmemcontrol = []

View File

@@ -8,9 +8,9 @@ use std::sync::{Arc, Barrier};
use std::thread;
use std::time::Instant;
use acpi_tables::{aml, Aml, AmlSink};
use vm_device::interrupt::InterruptSourceGroup;
use acpi_tables::{Aml, AmlSink, aml};
use vm_device::BusDevice;
use vm_device::interrupt::InterruptSourceGroup;
use vm_memory::GuestAddress;
use vmm_sys_util::eventfd::EventFd;
@@ -51,7 +51,7 @@ impl BusDevice for AcpiShutdownDevice {
if data[0] == 1 {
info!("ACPI Reboot signalled");
if let Err(e) = self.reset_evt.write(1) {
error!("Error triggering ACPI reset event: {}", e);
error!("Error triggering ACPI reset event: {e}");
}
// Spin until we are sure the reset_evt has been handled and that when
// we return from the KVM_RUN we will exit rather than re-enter the guest.
@@ -68,7 +68,7 @@ impl BusDevice for AcpiShutdownDevice {
if data[0] == (S5_SLEEP_VALUE << SLEEP_VALUE_BIT) | (1 << SLEEP_STATUS_EN_BIT) {
info!("ACPI Shutdown signalled");
if let Err(e) = self.exit_evt.write(1) {
error!("Error triggering ACPI shutdown event: {}", e);
error!("Error triggering ACPI shutdown event: {e}");
}
// Spin until we are sure the reset_evt has been handled and that when
// we return from the KVM_RUN we will exit rather than re-enter the guest.

View File

@@ -40,7 +40,7 @@ pub struct Aia {
impl Aia {
pub fn new(
vcpu_count: u8,
vcpu_count: u32,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vm: Arc<dyn hypervisor::Vm>,
) -> Result<Aia> {

View File

@@ -9,8 +9,8 @@ use std::sync::{Arc, Mutex};
use anyhow::anyhow;
use arch::layout;
use hypervisor::arch::aarch64::gic::{GicState, Vgic, VgicConfig};
use hypervisor::CpuState;
use hypervisor::arch::aarch64::gic::{GicState, Vgic, VgicConfig};
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup,
LegacyIrqSourceConfig, MsiIrqGroupConfig,
@@ -39,7 +39,7 @@ pub struct Gic {
impl Gic {
pub fn new(
vcpu_count: u8,
vcpu_count: u32,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vm: Arc<dyn hypervisor::Vm>,
) -> Result<Gic> {

View File

@@ -14,11 +14,11 @@ use std::sync::{Arc, Barrier};
use byteorder::{ByteOrder, LittleEndian};
use serde::{Deserialize, Serialize};
use vm_device::BusDevice;
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup,
MsiIrqGroupConfig, MsiIrqSourceConfig,
};
use vm_device::BusDevice;
use vm_memory::GuestAddress;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
@@ -151,13 +151,13 @@ impl BusDevice for Ioapic {
return;
}
debug!("IOAPIC_R @ offset 0x{:x}", offset);
debug!("IOAPIC_R @ offset 0x{offset:x}");
let value: u32 = match offset as u8 {
IOREGSEL_OFF => self.reg_sel,
IOWIN_OFF => self.ioapic_read(),
_ => {
error!("IOAPIC: failed reading at offset {}", offset);
error!("IOAPIC: failed reading at offset {offset}");
return;
}
};
@@ -171,7 +171,7 @@ impl BusDevice for Ioapic {
return None;
}
debug!("IOAPIC_W @ offset 0x{:x}", offset);
debug!("IOAPIC_W @ offset 0x{offset:x}");
let value = LittleEndian::read_u32(data);
@@ -179,7 +179,7 @@ impl BusDevice for Ioapic {
IOREGSEL_OFF => self.reg_sel = value,
IOWIN_OFF => self.ioapic_write(value),
_ => {
error!("IOAPIC: failed writing at offset {}", offset);
error!("IOAPIC: failed writing at offset {offset}");
}
}
None
@@ -266,7 +266,7 @@ impl Ioapic {
IOWIN_OFF..=REG_MAX_OFFSET => {
let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8);
if index > NUM_IOAPIC_PINS {
warn!("IOAPIC index out of range: {}", index);
warn!("IOAPIC index out of range: {index}");
return;
}
if is_high_bits {
@@ -282,7 +282,7 @@ impl Ioapic {
// The entry must be updated through the interrupt source
// group.
if let Err(e) = self.update_entry(index, true) {
error!("Failed updating IOAPIC entry: {:?}", e);
error!("Failed updating IOAPIC entry: {e:?}");
}
// Store the information this IRQ is now being used.
self.used_entries[index] = true;
@@ -303,7 +303,7 @@ impl Ioapic {
IOWIN_OFF..=REG_MAX_OFFSET => {
let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8);
if index > NUM_IOAPIC_PINS {
warn!("IOAPIC index out of range: {}", index);
warn!("IOAPIC index out of range: {index}");
return 0;
}
if is_high_bits {

420
devices/src/ivshmem.rs Normal file
View File

@@ -0,0 +1,420 @@
// Copyright © 2024 Tencent Corporation. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
use std::any::Any;
use std::path::PathBuf;
use std::result;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Arc, Barrier, Mutex};
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
use pci::{
BarReprogrammingParams, PCI_CONFIGURATION_ID, PciBarConfiguration, PciBarPrefetchable,
PciBarRegionType, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType,
PciSubclass,
};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use vm_allocator::{AddressAllocator, SystemAllocator};
use vm_device::{BusDevice, Resource, UserspaceMapping};
use vm_memory::bitmap::AtomicBitmap;
use vm_memory::{Address, GuestAddress};
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
const IVSHMEM_BAR0_IDX: usize = 0;
const IVSHMEM_BAR1_IDX: usize = 1;
const IVSHMEM_BAR2_IDX: usize = 2;
const IVSHMEM_VENDOR_ID: u16 = 0x1af4;
const IVSHMEM_DEVICE_ID: u16 = 0x1110;
const IVSHMEM_REG_BAR_SIZE: u64 = 0x100;
type GuestRegionMmap = vm_memory::GuestRegionMmap<AtomicBitmap>;
#[derive(Debug, Error)]
pub enum IvshmemError {
#[error("Failed to retrieve PciConfigurationState: {0}")]
RetrievePciConfigurationState(#[source] anyhow::Error),
#[error("Failed to retrieve IvshmemDeviceState: {0}")]
RetrieveIvshmemDeviceStateState(#[source] anyhow::Error),
#[error("Failed to remove user memory region")]
RemoveUserMemoryRegion,
#[error("Failed to create user memory region.")]
CreateUserMemoryRegion,
#[error("Failed to create userspace mapping.")]
CreateUserspaceMapping,
#[error("Failed to remove old userspace mapping.")]
RemoveUserspaceMapping,
}
#[derive(Copy, Clone)]
pub enum IvshmemSubclass {
Other = 0x00,
}
impl PciSubclass for IvshmemSubclass {
fn get_register_value(&self) -> u8 {
*self as u8
}
}
pub trait IvshmemOps: Send + Sync {
fn map_ram_region(
&mut self,
start_addr: u64,
size: usize,
backing_file: Option<PathBuf>,
) -> Result<(Arc<GuestRegionMmap>, UserspaceMapping), IvshmemError>;
fn unmap_ram_region(&mut self, mapping: UserspaceMapping) -> Result<(), IvshmemError>;
}
/// Inner-Vm Shared Memory Device (Ivshmem device)
///
/// This device can share memory between host and guest(ivshmem-plain)
/// and share memory between guests(ivshmem-doorbell).
/// But only ivshmem-plain support now, ivshmem-doorbell doesn't support yet.
pub struct IvshmemDevice {
id: String,
// ivshmem device registers
// (only used for ivshmem-doorbell, ivshmem-doorbell don't support yet)
_interrupt_mask: u32,
_interrupt_status: Arc<AtomicU32>,
_iv_position: u32,
_doorbell: u32,
// PCI configuration registers.
configuration: PciConfiguration,
bar_regions: Vec<PciBarConfiguration>,
region_size: u64,
ivshmem_ops: Arc<Mutex<dyn IvshmemOps>>,
backend_file: Option<PathBuf>,
region: Option<Arc<GuestRegionMmap>>,
userspace_mapping: Option<UserspaceMapping>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct IvshmemDeviceState {
interrupt_mask: u32,
interrupt_status: u32,
iv_position: u32,
doorbell: u32,
}
impl IvshmemDevice {
pub fn new(
id: String,
region_size: u64,
backend_file: Option<PathBuf>,
ivshmem_ops: Arc<Mutex<dyn IvshmemOps>>,
snapshot: Option<Snapshot>,
) -> Result<Self, IvshmemError> {
let pci_configuration_state =
vm_migration::state_from_id(snapshot.as_ref(), PCI_CONFIGURATION_ID).map_err(|e| {
IvshmemError::RetrievePciConfigurationState(anyhow!(
"Failed to get PciConfigurationState from Snapshot: {e}",
))
})?;
let state: Option<IvshmemDeviceState> = snapshot
.as_ref()
.map(|s| s.to_state())
.transpose()
.map_err(|e| {
IvshmemError::RetrieveIvshmemDeviceStateState(anyhow!(
"Failed to get IvshmemDeviceState from Snapshot: {e}",
))
})?;
let configuration = PciConfiguration::new(
IVSHMEM_VENDOR_ID,
IVSHMEM_DEVICE_ID,
0x1,
PciClassCode::MemoryController,
&IvshmemSubclass::Other,
None,
PciHeaderType::Device,
0,
0,
None,
pci_configuration_state,
);
let device = if let Some(s) = state {
IvshmemDevice {
id,
configuration,
bar_regions: vec![],
_interrupt_mask: s.interrupt_mask,
_interrupt_status: Arc::new(AtomicU32::new(s.interrupt_status)),
_iv_position: s.iv_position,
_doorbell: s.doorbell,
region_size,
ivshmem_ops,
region: None,
userspace_mapping: None,
backend_file,
}
} else {
IvshmemDevice {
id,
configuration,
bar_regions: vec![],
_interrupt_mask: 0,
_interrupt_status: Arc::new(AtomicU32::new(0)),
_iv_position: 0,
_doorbell: 0,
region_size,
ivshmem_ops,
region: None,
userspace_mapping: None,
backend_file,
}
};
Ok(device)
}
pub fn set_region(
&mut self,
region: Arc<GuestRegionMmap>,
userspace_mapping: UserspaceMapping,
) {
self.region = Some(region);
self.userspace_mapping = Some(userspace_mapping);
}
pub fn config_bar_addr(&self) -> u64 {
self.configuration.get_bar_addr(IVSHMEM_BAR0_IDX)
}
pub fn data_bar_addr(&self) -> u64 {
self.configuration.get_bar_addr(IVSHMEM_BAR2_IDX)
}
fn state(&self) -> IvshmemDeviceState {
IvshmemDeviceState {
interrupt_mask: self._interrupt_mask,
interrupt_status: self._interrupt_status.load(Ordering::SeqCst),
iv_position: self._iv_position,
doorbell: self._doorbell,
}
}
}
impl BusDevice for IvshmemDevice {
fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) {
self.read_bar(base, offset, data)
}
fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
self.write_bar(base, offset, data)
}
}
impl PciDevice for IvshmemDevice {
fn allocate_bars(
&mut self,
_allocator: &Arc<Mutex<SystemAllocator>>,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new();
let mut bar0_addr = None;
let mut bar2_addr = None;
let restoring = resources.is_some();
if let Some(resources) = resources {
for resource in resources {
match resource {
Resource::PciBar { index, base, .. } => {
match index {
IVSHMEM_BAR0_IDX => {
bar0_addr = Some(GuestAddress(base));
}
IVSHMEM_BAR1_IDX => {}
IVSHMEM_BAR2_IDX => {
bar2_addr = Some(GuestAddress(base));
}
_ => {
error!("Unexpected pci bar index {index}");
}
};
}
_ => {
error!("Unexpected resource {resource:?}");
}
}
}
if bar0_addr.is_none() || bar2_addr.is_none() {
return Err(PciDeviceError::MissingResource);
}
}
// BAR0 holds device registers (256 Byte MMIO)
let bar0_addr = mmio32_allocator
.allocate(bar0_addr, IVSHMEM_REG_BAR_SIZE, None)
.ok_or(PciDeviceError::IoAllocationFailed(IVSHMEM_REG_BAR_SIZE))?;
debug!("ivshmem bar0 address 0x{:x}", bar0_addr.0);
let bar0 = PciBarConfiguration::default()
.set_index(IVSHMEM_BAR0_IDX)
.set_address(bar0_addr.raw_value())
.set_size(IVSHMEM_REG_BAR_SIZE)
.set_region_type(PciBarRegionType::Memory32BitRegion)
.set_prefetchable(PciBarPrefetchable::NotPrefetchable);
// BAR1 holds MSI-X table and PBA (only ivshmem-doorbell).
// BAR2 maps the shared memory object
let bar2_size = self.region_size;
let bar2_addr = mmio64_allocator
.allocate(bar2_addr, bar2_size, None)
.ok_or(PciDeviceError::IoAllocationFailed(bar2_size))?;
debug!("ivshmem bar2 address 0x{:x}", bar2_addr.0);
let bar2 = PciBarConfiguration::default()
.set_index(IVSHMEM_BAR2_IDX)
.set_address(bar2_addr.raw_value())
.set_size(bar2_size)
.set_region_type(PciBarRegionType::Memory64BitRegion)
.set_prefetchable(PciBarPrefetchable::Prefetchable);
if !restoring {
self.configuration
.add_pci_bar(&bar0)
.map_err(|e| PciDeviceError::IoRegistrationFailed(bar0_addr.raw_value(), e))?;
self.configuration
.add_pci_bar(&bar2)
.map_err(|e| PciDeviceError::IoRegistrationFailed(bar2_addr.raw_value(), e))?;
}
bars.push(bar0);
bars.push(bar2);
self.bar_regions = bars.clone();
Ok(bars)
}
fn free_bars(
&mut self,
_allocator: &mut SystemAllocator,
_mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> std::result::Result<(), PciDeviceError> {
unimplemented!("Device hotplug and remove are not supported for ivshmem");
}
fn write_config_register(
&mut self,
reg_idx: usize,
offset: u64,
data: &[u8],
) -> (Vec<BarReprogrammingParams>, Option<Arc<Barrier>>) {
(
self.configuration
.write_config_register(reg_idx, offset, data),
None,
)
}
fn read_config_register(&mut self, reg_idx: usize) -> u32 {
self.configuration.read_reg(reg_idx)
}
fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) {
debug!("read base {base:x} offset {offset}");
let mut bar_idx = 0;
for (idx, bar) in self.bar_regions.iter().enumerate() {
if bar.addr() == base {
bar_idx = idx;
}
}
match bar_idx {
// bar 0
0 => {
// ivshmem don't use interrupt, we return zero now.
LittleEndian::write_u32(data, 0);
}
// bar 2
1 => warn!("Unexpected read ivshmem memory idx: {offset}"),
_ => {
warn!("Invalid bar_idx: {bar_idx}");
}
};
}
fn write_bar(&mut self, base: u64, offset: u64, _data: &[u8]) -> Option<Arc<Barrier>> {
debug!("write base {base:x} offset {offset}");
warn!("Unexpected write ivshmem memory idx: {offset}");
None
}
fn move_bar(&mut self, old_base: u64, new_base: u64) -> result::Result<(), std::io::Error> {
if new_base == self.data_bar_addr() {
if let Some(old_mapping) = self.userspace_mapping.take() {
self.ivshmem_ops
.lock()
.unwrap()
.unmap_ram_region(old_mapping)
.map_err(std::io::Error::other)?;
}
let (region, new_mapping) = self
.ivshmem_ops
.lock()
.unwrap()
.map_ram_region(
new_base,
self.region_size as usize,
self.backend_file.clone(),
)
.map_err(std::io::Error::other)?;
self.set_region(region, new_mapping);
}
for bar in self.bar_regions.iter_mut() {
if bar.addr() == old_base {
*bar = bar.set_address(new_base);
}
}
Ok(())
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn id(&self) -> Option<String> {
Some(self.id.clone())
}
}
impl Pausable for IvshmemDevice {}
impl Snapshottable for IvshmemDevice {
fn id(&self) -> String {
self.id.clone()
}
// The snapshot/restore (also live migration) support only work for ivshmem-plain mode.
// Additional work is needed for supporting ivshmem-doorbell.
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let mut snapshot = Snapshot::new_from_state(&self.state())?;
// Snapshot PciConfiguration
snapshot.add_snapshot(self.configuration.id(), self.configuration.snapshot()?);
Ok(snapshot)
}
}
impl Transportable for IvshmemDevice {}
impl Migratable for IvshmemDevice {}

View File

@@ -12,7 +12,7 @@ use std::{mem, thread};
// https://github.com/rust-lang/libc/issues/1848
#[cfg_attr(target_env = "musl", allow(deprecated))]
use libc::time_t;
use libc::{clock_gettime, gmtime_r, timespec, tm, CLOCK_REALTIME};
use libc::{CLOCK_REALTIME, clock_gettime, gmtime_r, timespec, tm};
use vm_device::BusDevice;
use vmm_sys_util::eventfd::EventFd;
@@ -90,7 +90,7 @@ impl BusDevice for Cmos {
self.data[(self.index & INDEX_MASK) as usize] = data[0]
}
}
o => warn!("bad write offset on CMOS device: {}", o),
o => warn!("bad write offset on CMOS device: {o}"),
};
None
}
@@ -164,7 +164,7 @@ impl BusDevice for Cmos {
}
}
o => {
warn!("bad read offset on CMOS device: {}", o);
warn!("bad read offset on CMOS device: {o}");
0
}
}

View File

@@ -0,0 +1,954 @@
// Copyright 2025 Google LLC.
//
// SPDX-License-Identifier: Apache-2.0
//
/// Cloud Hypervisor implementation of Qemu's fw_cfg spec
/// https://www.qemu.org/docs/master/specs/fw_cfg.html
/// Linux kernel fw_cfg driver header
/// https://github.com/torvalds/linux/blob/master/include/uapi/linux/qemu_fw_cfg.h
/// Uploading files to the guest via fw_cfg is supported for all kernels 4.6+ w/ CONFIG_FW_CFG_SYSFS enabled
/// https://cateee.net/lkddb/web-lkddb/FW_CFG_SYSFS.html
/// No kernel requirement if above functionality is not required,
/// only firmware must implement mechanism to interact with this fw_cfg device
use std::{
fs::File,
io::{ErrorKind, Read, Result, Seek, SeekFrom},
mem::offset_of,
os::unix::fs::FileExt,
sync::{Arc, Barrier},
};
use acpi_tables::rsdp::Rsdp;
use arch::RegionType;
#[cfg(target_arch = "aarch64")]
use arch::aarch64::layout::{
MEM_32BIT_DEVICES_START, MEM_32BIT_RESERVED_START, RAM_64BIT_START, RAM_START as HIGH_RAM_START,
};
#[cfg(target_arch = "x86_64")]
use arch::layout::{
EBDA_START, HIGH_RAM_START, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START,
MEM_32BIT_RESERVED_START, PCI_MMCONFIG_SIZE, PCI_MMCONFIG_START, RAM_64BIT_START,
};
use bitfield_struct::bitfield;
#[cfg(target_arch = "x86_64")]
use linux_loader::bootparam::boot_params;
#[cfg(target_arch = "aarch64")]
use linux_loader::loader::pe::arm64_image_header as boot_params;
use vm_device::BusDevice;
use vm_memory::bitmap::AtomicBitmap;
use vm_memory::{
ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap,
};
use vmm_sys_util::sock_ctrl_msg::IntoIovec;
use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes};
#[cfg(target_arch = "x86_64")]
// https://github.com/project-oak/oak/tree/main/stage0_bin#memory-layout
const STAGE0_START_ADDRESS: GuestAddress = GuestAddress(0xfffe_0000);
#[cfg(target_arch = "x86_64")]
const STAGE0_SIZE: usize = 0x2_0000;
const E820_RAM: u32 = 1;
const E820_RESERVED: u32 = 2;
#[cfg(target_arch = "x86_64")]
const PORT_FW_CFG_SELECTOR: u64 = 0x510;
#[cfg(target_arch = "x86_64")]
const PORT_FW_CFG_DATA: u64 = 0x511;
#[cfg(target_arch = "x86_64")]
const PORT_FW_CFG_DMA_HI: u64 = 0x514;
#[cfg(target_arch = "x86_64")]
const PORT_FW_CFG_DMA_LO: u64 = 0x518;
#[cfg(target_arch = "x86_64")]
pub const PORT_FW_CFG_BASE: u64 = 0x510;
#[cfg(target_arch = "x86_64")]
pub const PORT_FW_CFG_WIDTH: u64 = 0xc;
#[cfg(target_arch = "aarch64")]
const PORT_FW_CFG_SELECTOR: u64 = 0x9030008;
#[cfg(target_arch = "aarch64")]
const PORT_FW_CFG_DATA: u64 = 0x9030000;
#[cfg(target_arch = "aarch64")]
const PORT_FW_CFG_DMA_HI: u64 = 0x9030010;
#[cfg(target_arch = "aarch64")]
const PORT_FW_CFG_DMA_LO: u64 = 0x9030014;
#[cfg(target_arch = "aarch64")]
pub const PORT_FW_CFG_BASE: u64 = 0x9030000;
#[cfg(target_arch = "aarch64")]
pub const PORT_FW_CFG_WIDTH: u64 = 0x10;
const FW_CFG_SIGNATURE: u16 = 0x00;
const FW_CFG_ID: u16 = 0x01;
const FW_CFG_KERNEL_SIZE: u16 = 0x08;
const FW_CFG_INITRD_SIZE: u16 = 0x0b;
const FW_CFG_KERNEL_DATA: u16 = 0x11;
const FW_CFG_INITRD_DATA: u16 = 0x12;
const FW_CFG_CMDLINE_SIZE: u16 = 0x14;
const FW_CFG_CMDLINE_DATA: u16 = 0x15;
const FW_CFG_SETUP_SIZE: u16 = 0x17;
const FW_CFG_SETUP_DATA: u16 = 0x18;
const FW_CFG_FILE_DIR: u16 = 0x19;
const FW_CFG_KNOWN_ITEMS: usize = 0x20;
pub const FW_CFG_FILE_FIRST: u16 = 0x20;
pub const FW_CFG_DMA_SIGNATURE: [u8; 8] = *b"QEMU CFG";
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/qemu_fw_cfg.h
pub const FW_CFG_ACPI_ID: &str = "QEMU0002";
// Reserved (must be enabled)
const FW_CFG_F_RESERVED: u8 = 1 << 0;
// DMA Toggle Bit (enabled by default)
const FW_CFG_F_DMA: u8 = 1 << 1;
pub const FW_CFG_FEATURE: [u8; 4] = [FW_CFG_F_RESERVED | FW_CFG_F_DMA, 0, 0, 0];
const COMMAND_ALLOCATE: u32 = 0x1;
const COMMAND_ADD_POINTER: u32 = 0x2;
const COMMAND_ADD_CHECKSUM: u32 = 0x3;
const ALLOC_ZONE_HIGH: u8 = 0x1;
const ALLOC_ZONE_FSEG: u8 = 0x2;
const FW_CFG_FILENAME_TABLE_LOADER: &str = "etc/table-loader";
const FW_CFG_FILENAME_RSDP: &str = "acpi/rsdp";
const FW_CFG_FILENAME_ACPI_TABLES: &str = "acpi/tables";
#[derive(Debug)]
pub enum FwCfgContent {
Bytes(Vec<u8>),
Slice(&'static [u8]),
File(u64, File),
U32(u32),
}
struct FwCfgContentAccess<'a> {
content: &'a FwCfgContent,
offset: u32,
}
impl Read for FwCfgContentAccess<'_> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
match self.content {
FwCfgContent::File(offset, f) => {
Seek::seek(&mut (&*f), SeekFrom::Start(offset + self.offset as u64))?;
Read::read(&mut (&*f), buf)
}
FwCfgContent::Bytes(b) => match b.get(self.offset as usize..) {
Some(mut s) => s.read(buf),
None => Err(ErrorKind::UnexpectedEof)?,
},
FwCfgContent::Slice(b) => match b.get(self.offset as usize..) {
Some(mut s) => s.read(buf),
None => Err(ErrorKind::UnexpectedEof)?,
},
FwCfgContent::U32(n) => match n.to_le_bytes().get(self.offset as usize..) {
Some(mut s) => s.read(buf),
None => Err(ErrorKind::UnexpectedEof)?,
},
}
}
}
impl Default for FwCfgContent {
fn default() -> Self {
FwCfgContent::Slice(&[])
}
}
impl FwCfgContent {
fn size(&self) -> Result<u32> {
let ret = match self {
FwCfgContent::Bytes(v) => v.len(),
FwCfgContent::File(offset, f) => (f.metadata()?.len() - offset) as usize,
FwCfgContent::Slice(s) => s.len(),
FwCfgContent::U32(n) => size_of_val(n),
};
u32::try_from(ret).map_err(|_| std::io::ErrorKind::InvalidInput.into())
}
fn access(&self, offset: u32) -> FwCfgContentAccess<'_> {
FwCfgContentAccess {
content: self,
offset,
}
}
}
#[derive(Debug, Default)]
pub struct FwCfgItem {
pub name: String,
pub content: FwCfgContent,
}
/// https://www.qemu.org/docs/master/specs/fw_cfg.html
#[derive(Debug)]
pub struct FwCfg {
selector: u16,
data_offset: u32,
dma_address: u64,
items: Vec<FwCfgItem>, // 0x20 and above
known_items: [FwCfgContent; FW_CFG_KNOWN_ITEMS], // 0x0 to 0x19
memory: GuestMemoryAtomic<GuestMemoryMmap<AtomicBitmap>>,
}
#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes)]
struct FwCfgDmaAccess {
control_be: u32,
length_be: u32,
address_be: u64,
}
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/qemu_fw_cfg.h#L67
#[bitfield(u32)]
struct AccessControl {
// FW_CFG_DMA_CTL_ERROR = 0x01
error: bool,
// FW_CFG_DMA_CTL_READ = 0x02
read: bool,
#[bits(1)]
_unused2: u8,
// FW_CFG_DMA_CTL_SKIP = 0x04
skip: bool,
#[bits(3)]
_unused3: u8,
// FW_CFG_DMA_CTL_ERROR = 0x08
select: bool,
#[bits(7)]
_unused4: u8,
// FW_CFG_DMA_CTL_WRITE = 0x10
write: bool,
#[bits(16)]
_unused: u32,
}
#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes)]
struct FwCfgFilesHeader {
count_be: u32,
}
pub const FILE_NAME_SIZE: usize = 56;
pub fn create_file_name(name: &str) -> [u8; FILE_NAME_SIZE] {
let mut c_name = [0u8; FILE_NAME_SIZE];
let c_len = std::cmp::min(FILE_NAME_SIZE - 1, name.len());
c_name[0..c_len].copy_from_slice(&name.as_bytes()[0..c_len]);
c_name
}
#[allow(dead_code)]
#[repr(C, packed)]
#[derive(Debug, IntoBytes, FromBytes, Clone, Copy)]
struct BootE820Entry {
addr: u64,
size: u64,
type_: u32,
}
#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes)]
struct FwCfgFile {
size_be: u32,
select_be: u16,
_reserved: u16,
name: [u8; FILE_NAME_SIZE],
}
#[repr(C, align(4))]
#[derive(Debug, IntoBytes, Immutable)]
struct Allocate {
command: u32,
file: [u8; FILE_NAME_SIZE],
align: u32,
zone: u8,
_pad: [u8; 63],
}
#[repr(C, align(4))]
#[derive(Debug, IntoBytes, Immutable)]
struct AddPointer {
command: u32,
dst: [u8; FILE_NAME_SIZE],
src: [u8; FILE_NAME_SIZE],
offset: u32,
size: u8,
_pad: [u8; 7],
}
#[repr(C, align(4))]
#[derive(Debug, IntoBytes, Immutable)]
struct AddChecksum {
command: u32,
file: [u8; FILE_NAME_SIZE],
offset: u32,
start: u32,
len: u32,
_pad: [u8; 56],
}
fn create_intra_pointer(name: &str, offset: usize, size: u8) -> AddPointer {
AddPointer {
command: COMMAND_ADD_POINTER,
dst: create_file_name(name),
src: create_file_name(name),
offset: offset as u32,
size,
_pad: [0; 7],
}
}
fn create_acpi_table_checksum(offset: usize, len: usize) -> AddChecksum {
AddChecksum {
command: COMMAND_ADD_CHECKSUM,
file: create_file_name(FW_CFG_FILENAME_ACPI_TABLES),
offset: (offset + offset_of!(AcpiTableHeader, checksum)) as u32,
start: offset as u32,
len: len as u32,
_pad: [0; 56],
}
}
#[repr(C, align(4))]
#[derive(Debug, Clone, Default, FromBytes, IntoBytes)]
struct AcpiTableHeader {
signature: [u8; 4],
length: u32,
revision: u8,
checksum: u8,
oem_id: [u8; 6],
oem_table_id: [u8; 8],
oem_revision: u32,
asl_compiler_id: [u8; 4],
asl_compiler_revision: u32,
}
struct AcpiTable {
rsdp: Rsdp,
tables: Vec<u8>,
table_pointers: Vec<usize>,
table_checksums: Vec<(usize, usize)>,
}
impl AcpiTable {
fn pointers(&self) -> &[usize] {
&self.table_pointers
}
fn checksums(&self) -> &[(usize, usize)] {
&self.table_checksums
}
fn take(self) -> (Rsdp, Vec<u8>) {
(self.rsdp, self.tables)
}
}
// Creates fw_cfg items used by firmware to load and verify Acpi tables
// https://github.com/qemu/qemu/blob/master/hw/acpi/bios-linker-loader.c
fn create_acpi_loader(acpi_table: AcpiTable) -> [FwCfgItem; 3] {
let mut table_loader_bytes: Vec<u8> = Vec::new();
let allocate_rsdp = Allocate {
command: COMMAND_ALLOCATE,
file: create_file_name(FW_CFG_FILENAME_RSDP),
align: 4,
zone: ALLOC_ZONE_FSEG,
_pad: [0; 63],
};
table_loader_bytes.extend(allocate_rsdp.as_bytes());
let allocate_tables = Allocate {
command: COMMAND_ALLOCATE,
file: create_file_name(FW_CFG_FILENAME_ACPI_TABLES),
align: 4,
zone: ALLOC_ZONE_HIGH,
_pad: [0; 63],
};
table_loader_bytes.extend(allocate_tables.as_bytes());
for pointer_offset in acpi_table.pointers().iter() {
let pointer = create_intra_pointer(FW_CFG_FILENAME_ACPI_TABLES, *pointer_offset, 8);
table_loader_bytes.extend(pointer.as_bytes());
}
for (offset, len) in acpi_table.checksums().iter() {
let checksum = create_acpi_table_checksum(*offset, *len);
table_loader_bytes.extend(checksum.as_bytes());
}
let pointer_rsdp_to_xsdt = AddPointer {
command: COMMAND_ADD_POINTER,
dst: create_file_name(FW_CFG_FILENAME_RSDP),
src: create_file_name(FW_CFG_FILENAME_ACPI_TABLES),
offset: offset_of!(Rsdp, xsdt_addr) as u32,
size: 8,
_pad: [0; 7],
};
table_loader_bytes.extend(pointer_rsdp_to_xsdt.as_bytes());
let checksum_rsdp = AddChecksum {
command: COMMAND_ADD_CHECKSUM,
file: create_file_name(FW_CFG_FILENAME_RSDP),
offset: offset_of!(Rsdp, checksum) as u32,
start: 0,
len: offset_of!(Rsdp, length) as u32,
_pad: [0; 56],
};
let checksum_rsdp_ext = AddChecksum {
command: COMMAND_ADD_CHECKSUM,
file: create_file_name(FW_CFG_FILENAME_RSDP),
offset: offset_of!(Rsdp, extended_checksum) as u32,
start: 0,
len: size_of::<Rsdp>() as u32,
_pad: [0; 56],
};
table_loader_bytes.extend(checksum_rsdp.as_bytes());
table_loader_bytes.extend(checksum_rsdp_ext.as_bytes());
let table_loader = FwCfgItem {
name: FW_CFG_FILENAME_TABLE_LOADER.to_owned(),
content: FwCfgContent::Bytes(table_loader_bytes),
};
let (rsdp, tables) = acpi_table.take();
let acpi_rsdp = FwCfgItem {
name: FW_CFG_FILENAME_RSDP.to_owned(),
content: FwCfgContent::Bytes(rsdp.as_bytes().to_owned()),
};
let apci_tables = FwCfgItem {
name: FW_CFG_FILENAME_ACPI_TABLES.to_owned(),
content: FwCfgContent::Bytes(tables),
};
[table_loader, acpi_rsdp, apci_tables]
}
impl FwCfg {
pub fn new(memory: GuestMemoryAtomic<GuestMemoryMmap<AtomicBitmap>>) -> FwCfg {
const DEFAULT_ITEM: FwCfgContent = FwCfgContent::Slice(&[]);
let mut known_items = [DEFAULT_ITEM; FW_CFG_KNOWN_ITEMS];
known_items[FW_CFG_SIGNATURE as usize] = FwCfgContent::Slice(&FW_CFG_DMA_SIGNATURE);
known_items[FW_CFG_ID as usize] = FwCfgContent::Slice(&FW_CFG_FEATURE);
let file_buf = Vec::from(FwCfgFilesHeader { count_be: 0 }.as_mut_bytes());
known_items[FW_CFG_FILE_DIR as usize] = FwCfgContent::Bytes(file_buf);
FwCfg {
selector: 0,
data_offset: 0,
dma_address: 0,
items: vec![],
known_items,
memory,
}
}
pub fn populate_fw_cfg(
&mut self,
mem_size: Option<usize>,
kernel: Option<File>,
initramfs: Option<File>,
cmdline: Option<std::ffi::CString>,
fw_cfg_item_list: Option<Vec<FwCfgItem>>,
) -> Result<()> {
if let Some(mem_size) = mem_size {
self.add_e820(mem_size)?
}
if let Some(kernel) = kernel {
self.add_kernel_data(&kernel)?;
}
if let Some(cmdline) = cmdline {
self.add_kernel_cmdline(cmdline);
}
if let Some(initramfs) = initramfs {
self.add_initramfs_data(&initramfs)?
}
if let Some(fw_cfg_item_list) = fw_cfg_item_list {
for item in fw_cfg_item_list {
self.add_item(item)?;
}
}
Ok(())
}
pub fn add_e820(&mut self, mem_size: usize) -> Result<()> {
#[cfg(target_arch = "x86_64")]
let mut mem_regions = vec![
(GuestAddress(0), EBDA_START.0 as usize, RegionType::Ram),
(
MEM_32BIT_DEVICES_START,
MEM_32BIT_DEVICES_SIZE as usize,
RegionType::Reserved,
),
(
PCI_MMCONFIG_START,
PCI_MMCONFIG_SIZE as usize,
RegionType::Reserved,
),
(STAGE0_START_ADDRESS, STAGE0_SIZE, RegionType::Reserved),
];
#[cfg(target_arch = "aarch64")]
let mut mem_regions = arch::aarch64::arch_memory_regions();
if mem_size < MEM_32BIT_DEVICES_START.0 as usize {
mem_regions.push((
HIGH_RAM_START,
mem_size - HIGH_RAM_START.0 as usize,
RegionType::Ram,
));
} else {
mem_regions.push((
HIGH_RAM_START,
MEM_32BIT_RESERVED_START.0 as usize - HIGH_RAM_START.0 as usize,
RegionType::Ram,
));
mem_regions.push((
RAM_64BIT_START,
mem_size - (MEM_32BIT_DEVICES_START.0 as usize),
RegionType::Ram,
));
}
let mut bytes = vec![];
for (addr, size, region) in mem_regions.iter() {
let type_ = match region {
RegionType::Ram => E820_RAM,
RegionType::Reserved => E820_RESERVED,
RegionType::SubRegion => continue,
};
let mut entry = BootE820Entry {
addr: addr.0,
size: *size as u64,
type_,
};
bytes.extend_from_slice(entry.as_mut_bytes());
}
let item = FwCfgItem {
name: "etc/e820".to_owned(),
content: FwCfgContent::Bytes(bytes),
};
self.add_item(item)
}
fn file_dir_mut(&mut self) -> &mut Vec<u8> {
let FwCfgContent::Bytes(file_buf) = &mut self.known_items[FW_CFG_FILE_DIR as usize] else {
unreachable!("fw_cfg: selector {FW_CFG_FILE_DIR:#x} should be FwCfgContent::Byte!")
};
file_buf
}
fn update_count(&mut self) {
let mut header = FwCfgFilesHeader {
count_be: (self.items.len() as u32).to_be(),
};
self.file_dir_mut()[0..4].copy_from_slice(header.as_mut_bytes());
}
pub fn add_item(&mut self, item: FwCfgItem) -> Result<()> {
let index = self.items.len();
let c_name = create_file_name(&item.name);
let size = item.content.size()?;
let mut cfg_file = FwCfgFile {
size_be: size.to_be(),
select_be: (FW_CFG_FILE_FIRST + index as u16).to_be(),
_reserved: 0,
name: c_name,
};
self.file_dir_mut()
.extend_from_slice(cfg_file.as_mut_bytes());
self.items.push(item);
self.update_count();
Ok(())
}
fn dma_read_content(
&self,
content: &FwCfgContent,
offset: u32,
len: u32,
address: u64,
) -> Result<u32> {
let content_size = content.size()?.saturating_sub(offset);
let op_size = std::cmp::min(content_size, len);
let mut access = content.access(offset);
let mut buf = vec![0u8; op_size as usize];
access.read_exact(buf.as_mut_bytes())?;
let r = self
.memory
.memory()
.write(buf.as_bytes(), GuestAddress(address));
match r {
Err(e) => {
error!("fw_cfg: dma read error: {e:x?}");
Err(ErrorKind::InvalidInput.into())
}
Ok(size) => Ok(size as u32),
}
}
fn dma_read(&mut self, selector: u16, len: u32, address: u64) -> Result<()> {
let op_size = if let Some(content) = self.known_items.get(selector as usize) {
self.dma_read_content(content, self.data_offset, len, address)
} else if let Some(item) = self.items.get((selector - FW_CFG_FILE_FIRST) as usize) {
self.dma_read_content(&item.content, self.data_offset, len, address)
} else {
error!("fw_cfg: selector {selector:#x} does not exist.");
Err(ErrorKind::NotFound.into())
}?;
self.data_offset += op_size;
Ok(())
}
fn do_dma(&mut self) {
let dma_address = self.dma_address;
let mut access = FwCfgDmaAccess::new_zeroed();
let dma_access = match self
.memory
.memory()
.read(access.as_mut_bytes(), GuestAddress(dma_address))
{
Ok(_) => access,
Err(e) => {
error!("fw_cfg: invalid address of dma access {dma_address:#x}: {e:?}");
return;
}
};
let control = AccessControl(u32::from_be(dma_access.control_be));
if control.select() {
self.selector = control.select() as u16;
}
let len = u32::from_be(dma_access.length_be);
let addr = u64::from_be(dma_access.address_be);
let ret = if control.read() {
self.dma_read(self.selector, len, addr)
} else if control.write() {
Err(ErrorKind::InvalidInput.into())
} else if control.skip() {
self.data_offset += len;
Ok(())
} else {
Err(ErrorKind::InvalidData.into())
};
let mut access_resp = AccessControl(0);
if let Err(e) = ret {
error!("fw_cfg: dma operation {dma_access:x?}: {e:x?}");
access_resp.set_error(true);
}
if let Err(e) = self.memory.memory().write(
&access_resp.0.to_be_bytes(),
GuestAddress(dma_address + core::mem::offset_of!(FwCfgDmaAccess, control_be) as u64),
) {
error!("fw_cfg: finishing dma: {e:?}")
}
}
pub fn add_kernel_data(&mut self, file: &File) -> Result<()> {
let mut buffer = vec![0u8; size_of::<boot_params>()];
file.read_exact_at(&mut buffer, 0)?;
let bp = boot_params::from_mut_slice(&mut buffer).unwrap();
#[cfg(target_arch = "x86_64")]
{
// must set to 4 for backwards compatibility
// https://docs.kernel.org/arch/x86/boot.html#the-real-mode-kernel-header
if bp.hdr.setup_sects == 0 {
bp.hdr.setup_sects = 4;
}
// wildcard boot loader type
bp.hdr.type_of_loader = 0xff;
}
#[cfg(target_arch = "aarch64")]
let kernel_start = bp.text_offset;
#[cfg(target_arch = "x86_64")]
let kernel_start = (bp.hdr.setup_sects as usize + 1) * 512;
self.known_items[FW_CFG_SETUP_SIZE as usize] = FwCfgContent::U32(buffer.len() as u32);
self.known_items[FW_CFG_SETUP_DATA as usize] = FwCfgContent::Bytes(buffer);
self.known_items[FW_CFG_KERNEL_SIZE as usize] =
FwCfgContent::U32(file.metadata()?.len() as u32 - kernel_start as u32);
self.known_items[FW_CFG_KERNEL_DATA as usize] =
FwCfgContent::File(kernel_start as u64, file.try_clone()?);
Ok(())
}
pub fn add_kernel_cmdline(&mut self, s: std::ffi::CString) {
let bytes = s.into_bytes_with_nul();
self.known_items[FW_CFG_CMDLINE_SIZE as usize] = FwCfgContent::U32(bytes.len() as u32);
self.known_items[FW_CFG_CMDLINE_DATA as usize] = FwCfgContent::Bytes(bytes);
}
pub fn add_acpi(
&mut self,
rsdp: Rsdp,
tables: Vec<u8>,
table_checksums: Vec<(usize, usize)>,
table_pointers: Vec<usize>,
) -> Result<()> {
let acpi_table = AcpiTable {
rsdp,
tables,
table_checksums,
table_pointers,
};
let [table_loader, acpi_rsdp, apci_tables] = create_acpi_loader(acpi_table);
self.add_item(table_loader)?;
self.add_item(acpi_rsdp)?;
self.add_item(apci_tables)
}
pub fn add_initramfs_data(&mut self, file: &File) -> Result<()> {
let initramfs_size = file.metadata()?.len();
self.known_items[FW_CFG_INITRD_SIZE as usize] = FwCfgContent::U32(initramfs_size as _);
self.known_items[FW_CFG_INITRD_DATA as usize] = FwCfgContent::File(0, file.try_clone()?);
Ok(())
}
fn read_content(content: &FwCfgContent, offset: u32, data: &mut [u8], size: u32) -> Option<u8> {
let start = offset as usize;
let end = start + size as usize;
match content {
FwCfgContent::Bytes(b) => {
if b.len() >= size as usize {
data.copy_from_slice(&b[start..end]);
}
}
FwCfgContent::Slice(s) => {
if s.len() >= size as usize {
data.copy_from_slice(&s[start..end]);
}
}
FwCfgContent::File(o, f) => {
f.read_exact_at(data, o + offset as u64).ok()?;
}
FwCfgContent::U32(n) => {
let bytes = n.to_le_bytes();
data.copy_from_slice(&bytes[start..end]);
}
};
Some(size as u8)
}
fn read_data(&mut self, data: &mut [u8], size: u32) -> u8 {
let ret = if let Some(content) = self.known_items.get(self.selector as usize) {
Self::read_content(content, self.data_offset, data, size)
} else if let Some(item) = self.items.get((self.selector - FW_CFG_FILE_FIRST) as usize) {
Self::read_content(&item.content, self.data_offset, data, size)
} else {
error!("fw_cfg: selector {:#x} does not exist.", self.selector);
None
};
if let Some(val) = ret {
self.data_offset += size;
val
} else {
0
}
}
}
impl BusDevice for FwCfg {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let port = offset + PORT_FW_CFG_BASE;
let size = data.len();
match (port, size) {
(PORT_FW_CFG_SELECTOR, _) => {
error!("fw_cfg: selector register is write-only.");
}
(PORT_FW_CFG_DATA, _) => _ = self.read_data(data, size as u32),
(PORT_FW_CFG_DMA_HI, 4) => {
let addr = self.dma_address;
let addr_hi = (addr >> 32) as u32;
data.copy_from_slice(&addr_hi.to_be_bytes());
}
(PORT_FW_CFG_DMA_LO, 4) => {
let addr = self.dma_address;
let addr_lo = (addr & 0xffff_ffff) as u32;
data.copy_from_slice(&addr_lo.to_be_bytes());
}
_ => {
debug!(
"fw_cfg: read from unknown port {port:#x}: {size:#x} bytes and offset {offset:#x}."
);
}
};
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
let port = offset + PORT_FW_CFG_BASE;
let size = data.size();
match (port, size) {
(PORT_FW_CFG_SELECTOR, 2) => {
let mut buf = [0u8; 2];
buf[..size].copy_from_slice(&data[..size]);
#[cfg(target_arch = "x86_64")]
let val = u16::from_le_bytes(buf);
#[cfg(target_arch = "aarch64")]
let val = u16::from_be_bytes(buf);
self.selector = val;
self.data_offset = 0;
}
(PORT_FW_CFG_DATA, 1) => error!("fw_cfg: data register is read-only."),
(PORT_FW_CFG_DMA_HI, 4) => {
let mut buf = [0u8; 4];
buf[..size].copy_from_slice(&data[..size]);
let val = u32::from_be_bytes(buf);
self.dma_address &= 0xffff_ffff;
self.dma_address |= (val as u64) << 32;
}
(PORT_FW_CFG_DMA_LO, 4) => {
let mut buf = [0u8; 4];
buf[..size].copy_from_slice(&data[..size]);
let val = u32::from_be_bytes(buf);
self.dma_address &= !0xffff_ffff;
self.dma_address |= val as u64;
self.do_dma();
}
_ => debug!(
"fw_cfg: write to unknown port {port:#x}: {size:#x} bytes and offset {offset:#x} ."
),
};
None
}
}
#[cfg(test)]
mod tests {
use std::ffi::CString;
use std::io::Write;
use vmm_sys_util::tempfile::TempFile;
use super::*;
#[cfg(target_arch = "x86_64")]
const SELECTOR_OFFSET: u64 = 0;
#[cfg(target_arch = "aarch64")]
const SELECTOR_OFFSET: u64 = 8;
#[cfg(target_arch = "x86_64")]
const DATA_OFFSET: u64 = 1;
#[cfg(target_arch = "aarch64")]
const DATA_OFFSET: u64 = 0;
#[cfg(target_arch = "x86_64")]
const DMA_OFFSET: u64 = 4;
#[cfg(target_arch = "aarch64")]
const DMA_OFFSET: u64 = 16;
#[test]
fn test_signature() {
let gm = GuestMemoryAtomic::new(
GuestMemoryMmap::from_ranges(&[(GuestAddress(0), RAM_64BIT_START.0 as usize)]).unwrap(),
);
let mut fw_cfg = FwCfg::new(gm);
let mut data = vec![0u8];
let mut sig_iter = FW_CFG_DMA_SIGNATURE.into_iter();
fw_cfg.write(0, SELECTOR_OFFSET, &[FW_CFG_SIGNATURE as u8, 0]);
loop {
if let Some(char) = sig_iter.next() {
fw_cfg.read(0, DATA_OFFSET, &mut data);
assert_eq!(data[0], char);
} else {
return;
}
}
}
#[test]
fn test_kernel_cmdline() {
let gm = GuestMemoryAtomic::new(
GuestMemoryMmap::from_ranges(&[(GuestAddress(0), RAM_64BIT_START.0 as usize)]).unwrap(),
);
let mut fw_cfg = FwCfg::new(gm);
let cmdline = *b"cmdline\0";
fw_cfg.add_kernel_cmdline(CString::from_vec_with_nul(cmdline.to_vec()).unwrap());
let mut data = vec![0u8];
let mut cmdline_iter = cmdline.into_iter();
fw_cfg.write(0, SELECTOR_OFFSET, &[FW_CFG_CMDLINE_DATA as u8, 0]);
loop {
if let Some(char) = cmdline_iter.next() {
fw_cfg.read(0, DATA_OFFSET, &mut data);
assert_eq!(data[0], char);
} else {
return;
}
}
}
#[test]
fn test_initram_fs() {
let gm = GuestMemoryAtomic::new(
GuestMemoryMmap::from_ranges(&[(GuestAddress(0), RAM_64BIT_START.0 as usize)]).unwrap(),
);
let mut fw_cfg = FwCfg::new(gm);
let temp = TempFile::new().unwrap();
let mut temp_file = temp.as_file();
let initram_content = b"this is the initramfs";
let written = temp_file.write(initram_content);
assert_eq!(written.unwrap(), 21);
let _ = fw_cfg.add_initramfs_data(temp_file);
let mut data = vec![0u8];
let mut initram_iter = (*initram_content).into_iter();
fw_cfg.write(0, SELECTOR_OFFSET, &[FW_CFG_INITRD_DATA as u8, 0]);
loop {
if let Some(char) = initram_iter.next() {
fw_cfg.read(0, DATA_OFFSET, &mut data);
assert_eq!(data[0], char);
} else {
return;
}
}
}
#[test]
fn test_dma() {
let code = [
0xba, 0xf8, 0x03, 0x00, 0xd8, 0x04, b'0', 0xee, 0xb0, b'\n', 0xee, 0xf4,
];
let content = FwCfgContent::Bytes(code.to_vec());
let mem_size = 0x1000;
let load_addr = GuestAddress(0x1000);
let mem: GuestMemoryMmap<AtomicBitmap> =
GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap();
// Note: In firmware we would just allocate FwCfgDmaAccess struct
// and use address of struct (&) as dma address
let mut access_control = AccessControl(0);
// bit 1 = read access
access_control.set_read(true);
// length of data to access
let length_be = (code.len() as u32).to_be();
// guest address for data
let code_address = 0x1900_u64;
let address_be = code_address.to_be();
let mut access = FwCfgDmaAccess {
control_be: access_control.0.to_be(), // bit(1) = read bit
length_be,
address_be,
};
// access address is where to put the code
let access_address = GuestAddress(load_addr.0);
let address_bytes = access_address.0.to_be_bytes();
let dma_lo: [u8; 4] = address_bytes[0..4].try_into().unwrap();
let dma_hi: [u8; 4] = address_bytes[4..8].try_into().unwrap();
// writing the FwCfgDmaAccess to mem (this would just be self.dma_access.as_ref() in guest)
let _ = mem.write(access.as_mut_bytes(), access_address);
let mem_m = GuestMemoryAtomic::new(mem.clone());
let mut fw_cfg = FwCfg::new(mem_m);
let cfg_item = FwCfgItem {
name: "code".to_string(),
content,
};
let _ = fw_cfg.add_item(cfg_item);
let mut data = [0u8; 12];
let _ = mem.read(&mut data, GuestAddress(code_address));
assert_ne!(data, code);
fw_cfg.write(0, SELECTOR_OFFSET, &[FW_CFG_FILE_FIRST as u8, 0]);
fw_cfg.write(0, DMA_OFFSET, &dma_lo);
fw_cfg.write(0, DMA_OFFSET + 4, &dma_hi);
let _ = mem.read(&mut data, GuestAddress(code_address));
assert_eq!(data, code);
}
}

View File

@@ -12,8 +12,8 @@ use std::{io, result};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_device::interrupt::InterruptSourceGroup;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use crate::{read_le_u32, write_le_u32};
@@ -28,10 +28,10 @@ const GPIORIE: u64 = 0x414; // Raw Interrupt Status Register
const GPIOMIS: u64 = 0x418; // Masked Interrupt Status Register
const GPIOIC: u64 = 0x41c; // Interrupt Clear Register
const GPIOAFSEL: u64 = 0x420; // Mode Control Select Register
// From 0x424 to 0xFDC => reserved space.
// From 0xFE0 to 0xFFC => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// These registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral.
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
// From 0x424 to 0xFDC => reserved space.
// From 0xFE0 to 0xFFC => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// These registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral.
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
const GPIO_ID: [u8; 8] = [0x61, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
// ID Margins
const GPIO_ID_LOW: u64 = 0xfe0;

View File

@@ -45,7 +45,7 @@ impl BusDevice for I8042Device {
if data.len() == 1 && data[0] == 0xfe && offset == 3 {
info!("i8042 reset signalled");
if let Err(e) = self.reset_evt.write(1) {
error!("Error triggering i8042 reset event: {}", e);
error!("Error triggering i8042 reset event: {e}");
}
// Spin until we are sure the reset_evt has been handled and that when
// we return from the KVM_RUN we will exit rather than re-enter the guest.

View File

@@ -8,6 +8,8 @@
mod cmos;
#[cfg(target_arch = "x86_64")]
mod debug_port;
#[cfg(feature = "fw_cfg")]
pub mod fw_cfg;
#[cfg(target_arch = "x86_64")]
mod fwdebug;
#[cfg(target_arch = "aarch64")]
@@ -22,6 +24,8 @@ mod uart_pl011;
pub use self::cmos::Cmos;
#[cfg(target_arch = "x86_64")]
pub use self::debug_port::DebugPort;
#[cfg(feature = "fw_cfg")]
pub use self::fw_cfg::FwCfg;
#[cfg(target_arch = "x86_64")]
pub use self::fwdebug::FwDebugDevice;
#[cfg(target_arch = "aarch64")]

View File

@@ -31,11 +31,11 @@ const RTCIMSC: u64 = 0x10; // Interrupt Mask Set or Clear Register.
const RTCRIS: u64 = 0x14; // Raw Interrupt Status.
const RTCMIS: u64 = 0x18; // Masked Interrupt Status.
const RTCICR: u64 = 0x1c; // Interrupt Clear Register.
// From 0x020 to 0xFDC => reserved space.
// From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity
// of these devices (i.e look at the `amba_device_try_add` function).
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
// From 0x020 to 0xFDC => reserved space.
// From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity
// of these devices (i.e look at the `amba_device_try_add` function).
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
const PL031_ID: [u8; 8] = [0x31, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
// We are only interested in the margins.
const AMBA_ID_LOW: u64 = 0xFE0;

View File

@@ -10,8 +10,8 @@ use std::sync::{Arc, Barrier};
use std::{io, result};
use serde::{Deserialize, Serialize};
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_device::interrupt::InterruptSourceGroup;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::errno::Result;

View File

@@ -13,8 +13,8 @@ use std::{io, result};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_device::interrupt::InterruptSourceGroup;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use crate::{read_le_u32, write_le_u32};

View File

@@ -24,6 +24,8 @@ pub mod gic;
pub mod interrupt_controller;
#[cfg(target_arch = "x86_64")]
pub mod ioapic;
#[cfg(feature = "ivshmem")]
pub mod ivshmem;
pub mod legacy;
#[cfg(feature = "pvmemcontrol")]
pub mod pvmemcontrol;
@@ -33,7 +35,9 @@ pub mod pvpanic;
pub mod tpm;
pub use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice};
pub use self::pvpanic::{PvPanicDevice, PVPANIC_DEVICE_MMIO_SIZE};
#[cfg(feature = "ivshmem")]
pub use self::ivshmem::IvshmemDevice;
pub use self::pvpanic::{PVPANIC_DEVICE_MMIO_SIZE, PvPanicDevice};
bitflags! {
pub struct AcpiNotificationFlags: u8 {

View File

@@ -137,7 +137,8 @@ impl PvmemcontrolTransport {
}
unsafe fn as_register(self) -> PvmemcontrolTransportRegister {
self.payload.register
// SAFETY: We access initialized data.
unsafe { self.payload.register }
}
}
@@ -519,7 +520,7 @@ impl PvmemcontrolBusDevice {
ret_value: get_page_size().into(),
arg0: MAJOR_VERSION.into(),
arg1: MINOR_VERSION.into(),
})
});
}
FunctionCode::Dontneed => self.madvise(addr, length, libc::MADV_DONTNEED),
FunctionCode::Remove => self.madvise(addr, length, libc::MADV_REMOVE),

View File

@@ -9,9 +9,9 @@ use std::sync::{Arc, Barrier, Mutex};
use anyhow::anyhow;
use pci::{
BarReprogrammingParams, PciBarConfiguration, PciBarPrefetchable, PciBarRegionType,
PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciSubclass,
PCI_CONFIGURATION_ID,
BarReprogrammingParams, PCI_CONFIGURATION_ID, PciBarConfiguration, PciBarPrefetchable,
PciBarRegionType, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType,
PciSubclass,
};
use serde::{Deserialize, Serialize};
use thiserror::Error;
@@ -68,8 +68,7 @@ impl PvPanicDevice {
let pci_configuration_state =
vm_migration::state_from_id(snapshot.as_ref(), PCI_CONFIGURATION_ID).map_err(|e| {
PvPanicError::RetrievePciConfigurationState(anyhow!(
"Failed to get PciConfigurationState from Snapshot: {}",
e
"Failed to get PciConfigurationState from Snapshot: {e}"
))
})?;
@@ -100,8 +99,7 @@ impl PvPanicDevice {
.transpose()
.map_err(|e| {
PvPanicError::CreatePvPanicDevice(anyhow!(
"Failed to get PvPanicDeviceState from Snapshot: {}",
e
"Failed to get PvPanicDeviceState from Snapshot: {e}"
))
})?;
let events = if let Some(state) = state {
@@ -148,7 +146,7 @@ impl BusDevice for PvPanicDevice {
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
let event = self.event_to_string(data[0]);
info!("pvpanic got guest event {}", event);
info!("pvpanic got guest event {event}");
event!("guest", "panic", "event", &event);
None
}

View File

@@ -12,8 +12,8 @@ use arch::aarch64::layout::{TPM_SIZE, TPM_START};
#[cfg(target_arch = "x86_64")]
use arch::x86_64::layout::{TPM_SIZE, TPM_START};
use thiserror::Error;
use tpm::emulator::{BackendCmd, Emulator};
use tpm::TPM_CRB_BUFFER_MAX;
use tpm::emulator::{BackendCmd, Emulator};
use vm_device::BusDevice;
#[derive(Error, Debug)]
@@ -221,7 +221,7 @@ pub struct Tpm {
impl Tpm {
pub fn new(path: String) -> Result<Self> {
let emulator = Emulator::new(path)
.map_err(|e| Error::Init(anyhow!("Failed while initializing tpm Emulator: {:?}", e)))?;
.map_err(|e| Error::Init(anyhow!("Failed while initializing tpm Emulator: {e:?}")))?;
let mut tpm = Tpm {
emulator,
regs: [0; TPM_CRB_R_MAX],
@@ -331,8 +331,7 @@ impl Tpm {
if let Err(e) = self.emulator.startup_tpm(self.backend_buff_size) {
return Err(Error::Init(anyhow!(
"Failed while running Startup TPM. Error: {:?}",
e
"Failed while running Startup TPM. Error: {e:?}"
)));
}
Ok(())
@@ -458,10 +457,9 @@ impl BusDevice for Tpm {
CRB_CTRL_CANCEL => {
if v == CRB_CANCEL_INVOKE
&& (self.regs[CRB_CTRL_START as usize] & CRB_START_INVOKE != 0)
&& let Err(e) = self.emulator.cancel_cmd()
{
if let Err(e) = self.emulator.cancel_cmd() {
error!("Failed to run cancel command. Error: {:?}", e);
}
error!("Failed to run cancel command. Error: {e:?}");
}
}
CRB_CTRL_START => {
@@ -482,10 +480,7 @@ impl BusDevice for Tpm {
}
}
CRB_LOC_CTRL => {
warn!(
"CRB_LOC_CTRL locality to write = {:?} val = {:?}",
locality, v
);
warn!("CRB_LOC_CTRL locality to write = {locality:?} val = {v:?}");
match v {
CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT => {}
CRB_LOC_CTRL_RELINQUISH => {
@@ -518,7 +513,7 @@ impl BusDevice for Tpm {
);
}
_ => {
error!("Invalid value to write in CRB_LOC_CTRL {:#X} ", v);
error!("Invalid value to write in CRB_LOC_CTRL {v:#X} ");
}
}
}

View File

@@ -56,13 +56,6 @@ or a fd with `--api-socket fd=...`.
```
$ ./target/debug/cloud-hypervisor --api-socket path=/tmp/cloud-hypervisor.sock
Cloud Hypervisor Guest
API server: /tmp/cloud-hypervisor.sock
vCPUs: 1
Memory: 512 MB
Kernel: None
Kernel cmdline:
Disk(s): None
```
#### REST API Endpoints
@@ -121,13 +114,6 @@ the REST API available at `/tmp/cloud-hypervisor.sock`:
```
$ ./target/debug/cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
Cloud Hypervisor Guest
API server: /tmp/cloud-hypervisor.sock
vCPUs: 1
Memory: 512 MB
Kernel: None
Kernel cmdline:
Disk(s): None
```
##### Create a Virtual Machine

77
docs/fw_cfg.md Normal file
View File

@@ -0,0 +1,77 @@
# Firmware Configuration (fw_cfg) Device
The `fw_cfg` device is a QEMU-compatible device that allows the hypervisor to pass configuration and data to the guest operating system. This is particularly useful for firmware to access information like ACPI tables, kernel images, initramfs, kernel command lines, and other arbitrary data blobs.
Cloud Hypervisor implements the `fw_cfg` device with DMA-enabled access.
## Purpose
The `fw_cfg` device serves as a generic information channel between the VMM and the guest. It can be used to:
* Load the kernel, initramfs, and kernel command line for direct kernel boot with firmware.
* Provide ACPI tables to the guest firmware or OS.
* Pass custom configuration files or data blobs (e.g., attestation data, SEV-SNP launch secrets) to the guest.
* Supply an E820 memory map to the guest.
## Enabling `fw_cfg`
The `fw_cfg` device is enabled via the `fw_cfg` feature flag when building Cloud Hypervisor:
```bash
cargo build --features fw_cfg
```
## Guest Kernel Configuration
For the guest Linux kernel to recognize and use the `fw_cfg` device via sysfs, the following kernel configuration option must be enabled:
* `CONFIG_FW_CFG_SYSFS=y`
This option allows the kernel to expose `fw_cfg` entries under `/sys/firmware/qemu_fw_cfg/by_name/`.
## Command Line Options
The `fw_cfg` device is configured using the `--fw-cfg-config` command-line option.
**Parameters:**
* `e820=on|off`: (Default: `on`) Whether to add an E820 memory map entry to `fw_cfg`.
* `kernel=on|off`: (Default: `on`) Whether to add the kernel image (specified by `--kernel`) to `fw_cfg`.
* `cmdline=on|off`: (Default: `on`) Whether to add the kernel command line (specified by `--cmdline`) to `fw_cfg`.
* `initramfs=on|off`: (Default: `on`) Whether to add the initramfs image (specified by `--initramfs`) to `fw_cfg`.
* `acpi_table=on|off`: (Default: `on`) Whether to add generated ACPI tables to `fw_cfg`.
* `items=[... : ...]`: A list of custom key-value pairs to be exposed via `fw_cfg`.
* `name=<guest_sysfs_path>`: The path under which the item will appear in the guest's sysfs (e.g., `opt/org.example/my-data`).
* `file=<host_file_path>`: The path to the file on the host whose content will be provided to the guest for this item.
**Example Usage:**
1. **Direct kernel boot with custom `fw_cfg` entries:**
```bash
cloud-hypervisor \
--kernel /path/to/vmlinux \
--cmdline "console=hvc0 root=/dev/vda1" \
--disk path=/path/to/rootfs.img \
--fw-cfg-config initramfs=off,items=[name=opt/org.mycorp/setup_info,file=/tmp/guest_setup.txt] \
...
```
In the guest, `/tmp/guest_setup.txt` from the host will be accessible at `/sys/firmware/qemu_fw_cfg/by_name/opt/org.mycorp/setup_info/raw`.
2. **Disabling `fw_cfg` explicitly:**
```bash
cloud-hypervisor \
--fw-cfg-config disable \
...
```
## Accessing `fw_cfg` Items in the Guest
If `CONFIG_FW_CFG_SYSFS` is enabled in the guest kernel, items added to `fw_cfg` can be accessed via sysfs.
For example, an item added with `name=opt/org.example/my-data` will be available at:
`/sys/firmware/qemu_fw_cfg/by_name/opt/org.example/my-data/raw`
The `raw` file contains the binary content of the host file provided.
Standard items like kernel, initramfs, cmdline, and ACPI tables also have predefined names (e.g., `etc/kernel`, `etc/cmdline`) if they are enabled to be passed via `fw_cfg`.

View File

@@ -1,54 +0,0 @@
# Intel SGX
Intel® Software Guard Extensions (Intel® SGX) is an Intel technology designed
to increase the security of application code and data. Cloud Hypervisor supports
SGX virtualization through KVM. Because SGX is built on hardware features that
cannot be emulated in software, virtualizing SGX requires support in KVM and in
the host kernel. The required Linux and KVM changes can be found in Linux 5.13+.
Utilizing SGX in the guest requires a kernel/OS with SGX support, e.g. a kernel
since release 5.11, see
[here](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html).
Running Linux 5.13+ as the guest kernel allows nested virtualization of SGX.
For more information about SGX, please refer to the [SGX Homepage](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html).
For more information about SGX SDK and how to test SGX, please refer to the
following [instructions](https://github.com/intel/linux-sgx).
## Cloud Hypervisor support
Assuming the host exposes `/dev/sgx_vepc`, we can pass SGX enclaves through
the guest.
In order to use SGX enclaves within a Cloud Hypervisor VM, we must define one
or several Enclave Page Cache (EPC) sections. Here is an example of a VM being
created with 2 EPC sections, the first one being 64MiB with pre-allocated
memory, the second one being 32MiB with no pre-allocated memory.
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=1G \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel vmlinux \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--sgx-epc id=epc0,size=64M,prefault=on id=epc1,size=32M,prefault=off
```
Once booted, and assuming your guest kernel contains the patches from the
[KVM SGX Tree](https://github.com/intel/kvm-sgx), you can validate SGX devices
have been correctly created under `/dev/sgx`:
```bash
ls /dev/sgx*
/dev/sgx_enclave /dev/sgx_provision /dev/sgx_vepc
```
From this point, it is possible to run any SGX application from the guest, as
it will access `/dev/sgx_enclave` device to create dedicated SGX enclaves.
Note: There is only one contiguous SGX EPC region, which contains all SGX EPC
sections. This region is exposed through ACPI and marked as reserved through
the e820 table. It is treated as yet another device, which means it should
appear at the end of the guest address space.

51
docs/ivshmem.md Normal file
View File

@@ -0,0 +1,51 @@
# Inter-VM shared memory device
The Inter-VM shared memory device (ivshmem) is designed to share a memory
region between a guest and the host. In order for all guests to be able to
pick up the shared memory area, it is modeled as a PCI device exposing said
memory to the guest as a PCI BAR.
Device Specification is
at https://www.qemu.org/docs/master/specs/ivshmem-spec.html.
Now we support setting a backend file to share data between host and guest.
In other words, we only support ivshmem-plain and ivshmem-doorbell is not
supported yet.
## Usage
`--ivshmem`, an optional argument, can be passed to enable ivshmem device.
This argument takes a file as a `path` value and a file size as a `size` value.
```
--ivshmem <ivshmem> device backend file "path=</path/to/a/file>,size=<file_size/must=2^n>";
```
## Example
Create a file with a size bigger than passed to `cloud-hypervisor`:
```
truncate -s 1M /tmp/ivshmem.data
```
Start application to mmap the file data to a memory region:
```
./cloud-hypervisor \
--api-socket /tmp/cloud-hypervisor.sock \
--kernel vmlinux \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4 \
--memory size=1024M \
--ivshmem path=/tmp/ivshmem.data,size=1M
```
Insmod a ivshmem device driver to enable the device. The file data will be
mmapped to the PCI `bar2` of ivshmem device,
guest can r/w data by accessing this memory.
A simple example of ivshmem driver can get from:
https://github.com/lisongqian/clh-linux/commits/ch-6.12.8-ivshmem
The host process can r/w this data by remmaping the `/tmp/ivshmem.data`.

View File

@@ -437,12 +437,11 @@ struct NumaConfig {
cpus: Option<Vec<u8>>,
distances: Option<Vec<NumaDistance>>,
memory_zones: Option<Vec<String>>,
sgx_epc_sections: Option<Vec<String>>,
}
```
```
--numa <numa> Settings related to a given NUMA node "guest_numa_id=<node_id>,cpus=<cpus_id>,distances=<list_of_distances_to_destination_nodes>,memory_zones=<list_of_memory_zones>,sgx_epc_sections=<list_of_sgx_epc_sections>"
--numa <numa> Settings related to a given NUMA node "guest_numa_id=<node_id>,cpus=<cpus_id>,distances=<list_of_distances_to_destination_nodes>,memory_zones=<list_of_memory_zones>
```
### `guest_numa_id`
@@ -550,26 +549,6 @@ _Example_
--numa guest_numa_id=0,memory_zones=[mem0,mem2] guest_numa_id=1,memory_zones=mem1
```
### `sgx_epc_sections`
List of SGX EPC sections attached to the guest NUMA node identified by the
`guest_numa_id` option. This allows for describing a list of SGX EPC sections
which must be seen by the guest as belonging to the NUMA node `guest_numa_id`.
Multiple values can be provided to define the list. Each value is a string
referring to an existing SGX EPC section identifier. Values are separated from
each other with the `,` separator.
As soon as one tries to describe a list of values, `[` and `]` must be used to
demarcate the list.
_Example_
```
--sgx-epc id=epc0,size=32M id=epc1,size=64M id=epc2,size=32M
--numa guest_numa_id=0,sgx_epc_sections=epc1 guest_numa_id=1,sgx_epc_sections=[epc0,epc2]
```
### PCI bus
Cloud Hypervisor supports guests with one or more PCI segments. The default PCI segment always

View File

@@ -110,4 +110,4 @@ from the restored VM.
## Limitations
VFIO devices and Intel SGX are out of scope.
VFIO devices is out of scope.

View File

@@ -4,10 +4,10 @@ Starting with the release version [0.10.0](https://github.com/cloud-hypervisor/c
__Requirements__
- Host with KVM enabled
- Host with KVM enabled
- [UEFI](uefi.md) capable Windows guest image with Virtio drivers integrated
Any modern Windows Server version is compatible. Cloud Hypervisor has been successfully tested with Windows Server 2019 and Windows Server Core 2004.
Any modern Windows Server version is compatible, as well as Windows 11. Cloud Hypervisor has been successfully tested with Windows Server 2019, Windows Server Core 2004 and Windows 11 IoT Enterprise LTSC 2024.
At the current stage, only UEFI capable Windows images are supported. This implies the presence of the OVMF firmware during the Windows installation and in any subsequent usage. BIOS boot is not supported.
@@ -20,10 +20,15 @@ The subsequent sections will tell, in detail, how to prepare an appropriate Wind
__Prerequisites__
- QEMU, version >=5.0.0 is recommended.
- Windows installation ISO. Obtained through MSDN, Visual Studio subscription, evaluation center, etc.
- Windows installation ISO. Obtained through MSDN, Visual Studio subscription, evaluation center, etc.
- [VirtIO driver ISO](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/)
- Please use the [VirtIO Windows 11 attestation file](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/upstream-virtio/virtio-win11-attestation-0.1-258.zip)
for Windows 11
- Suitable firmware for Cloud Hypervisor (`CLOUDHV.fd`) and for QEMU (`OVMF.fd`)
- With the suggested image size of 30G, there should be enough free disk space to hold the installation ISO and any other necessary files
- With the suggested image size of 30G for Windows Server, there should be enough free disk space to hold the installation ISO and any other necessary files
- For Windows 11, increasing this image size to 64GB is recommended (see [minimal requirements](https://support.microsoft.com/en-us/windows/windows-11-system-requirements-86c11283-ea52-4782-9efd-7674389a7ba3))
- Windows 11 only: TPM 2.0 support
- Windows 11 only: 2 or more cores
This step currently requires QEMU to install Windows onto the guest. QEMU is only used at the preparation stage, the resulting image is then fully functional with Cloud Hypervisor.
@@ -37,11 +42,13 @@ OVMF_DIR=./FV
```
Create an empty image file, `raw` is supported.
```shell
qemu-img create -f raw $IMG_FILE 30G
```
Begin the Windows installation process under QEMU
Begin the Windows installation process under QEMU for Windows Server:
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
@@ -57,13 +64,56 @@ qemu-system-x86_64 \
-vga std
```
Before the installation can proceed, point the Windows installation program to the VirtIO disk and install the necessary storage controller drivers. After that, the attached hard drive will become visible and the actual installation can commence.
For Windows 11 you can use `swtpm` to fulfill the TPM 2.0 requirement:
After the installation has completed, proceed further to the configuration section. QEMU will be needed at least once more to enable the Windows Special Administration Console (SAC) and to possibly install extra device drivers.
```shell
# Create directory to store state
mkdir -p /tmp/mytpm1
# Start swtpm daemon for TPM 2.0 support
swtpm socket \
--tpm2 \
--ctrl type=unixio,path=/tmp/swtpm-sock \
--tpmstate dir=/tmp/mytpm1 \
--flags startup-clear \
--log level=20 \
--log file=/tmp/swtpm.log \
--daemon
```
Begin the Windows 11 installation process under QEMU like this:
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
-cpu host \
-m 4G \
-bios ./$OVMF_DIR/OVMF.fd \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom \
-drive if=none,id=root,file=./$IMG_FILE \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
-netdev user,id=mynet0 \
-vga std \
-smp 4 \
-chardev socket,id=chrtpm,path=/tmp/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis,tpmdev=tpm0
```
This command needs at least `-smp 2` (2 cores), as well as the last three lines (TPM 2.0), to support Windows 11 minimal requirements. Additionally, using `OVMF_CODE.fd` leads to the following error: `qemu: could not load PC BIOS '././FV/OVMF_CODE.fd'`. Switching to `OVMF.fd` is therefore necessary.
For more details about TPM specifically, please continue with the [TPM documentation](./tpm.md).
Before the installation can proceed, point the Windows installation program to the VirtIO disk and install the necessary storage controller drivers. For Windows 11 with the attestation drivers, you need to navigate to the `viostor` directory to be able to see and install it. After that, the attached hard drive will become visible and the actual installation can commence.
Do not install network drivers for Windows 11 just yet, if you don't want to be forced to log-in to/create a Microsoft account. Simply select `I don't have internet` for now.
After the installation has completed, proceed further to the [configuration section](#image-configuration). QEMU will be needed at least once more to enable/install the Windows Special Administration Console (SAC) and to possibly install extra device drivers.
## Image Usage
The basic command to boot a Windows image. The configuration section should be checked before executing it for the first time.
The basic command to boot a Windows image is shown in the next code snippet. The [configuration section](#image-configuration), as well as the [Getting Started section](../README.md#2-getting-started) should be checked before executing it for the first time. Please especially read the documentation for giving the cloud-hypervisor binary the correct capabilities for it to set TAP interfaces up on the host, otherwise the command below will fail:
```shell
cloud-hypervisor \
@@ -85,19 +135,25 @@ In cases where the host processor supports address space > 39 bits, it might be
To daemonize the Cloud Hypervisor process, `nohup` can be used. Some STDIO redirections might need to be done. In a simple case it is sufficient to just redirect all the output to `/dev/null`.
Be aware, currently, running the Windows 11 VM on Cloud Hypervisor with TPM 2.0 was not proven successful: `thread 'vcpu0' panicked`. Running the VM without TPM is a valid option though. Therefore the command as shown above is also valid for a Windows 11 VM.
## Image Configuration
### Device Drivers
After the Windows installation has finished under QEMU, there might be still devices with no drivers installed. This might happen for example, when a device was not used during the installation. In particular it is important to ensure that the VirtIO network device is setup correctly because further steps for the configuration and the usage require network in most case.
Boot once more under QEMU and use the [Device Manager](https://support.microsoft.com/en-in/help/4028443/windows-10-update-drivers), to ensure all the device drivers, and especially the network card, are installed correctly. Also, as Cloud Hypervisor can introduce new devices, it is advisable to repeat the procedure while booted under Cloud Hypervisor, when the RDP access to the image is functional.
Boot once more under QEMU and use the [Device Manager](https://support.microsoft.com/en-in/help/4028443/windows-10-update-drivers), to ensure all the device drivers, and especially the network card, are installed correctly. If not, right click on the unknown network device, choose `Update driver` and browse to the `NetKvm` directory on the CD.
Also, as Cloud Hypervisor can introduce new devices, it is advisable to repeat the procedure while booted under Cloud Hypervisor, when the [RDP](#remote-desktop-protocol-rdp-enablement) access to the image is functional.
### Windows Special Administration Console (SAC) enablement
SAC provides a text based console access to the Windows guest. As Cloud Hypervisor doesn't implement a VGA adaptor, SAC is an important instrument for the Windows guest management.
Boot the Windows image under QEMU and execute the below commands to permanently enable SAC
Boot the Windows image under QEMU. For all non-server Windows versions, the SAC needs to be downloaded and enabled first in the `Optional features` menu of Windows.
Execute the below commands to permanently enable SAC. You might need admin privileges.
```cmd
bcdedit /emssettings emsport:1 emsbaudrate:115200
@@ -105,15 +161,14 @@ bcdedit /ems on
bcdedit /bootems on
```
Once SAC is enabled, the image can be booted under Cloud Hypervisor. The SAC prompt will show up
Once SAC is enabled, the image can be booted under Cloud Hypervisor. The SAC prompt will show up
<pre>
Computer is booting, SAC started and initialized.
Use the "ch -?" command for information about using channels.
Use the "?" command for general help.
Computer is booting, SAC started and initialized.
Use the "ch -?" command for information about using channels.
Use the "?" command for general help.
SAC>
</pre>
@@ -139,7 +194,7 @@ As the simplest option, using `--net tap=` in the Cloud Hypervisor command line
<pre>
SAC>i 10 192.168.249.2 255.255.255.0 192.168.249.1
</pre>
</pre>
Where `10` is the device index as shown by the `i` command.
@@ -149,26 +204,38 @@ Additional steps are necessary to provide the guest with internet access.
- On the guest, add the DNS server either by using `netsh` or by opening `Network and Connectivity Center` and editing the adapter properties.
- On the host, configure the traffic forwarding. Replace the `NET_DEV` with the name of your network device.
```shell
NET_DEV=wlp3s0
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $NET_DEV -j MASQUERADE
```
If needed, you can also allow ICMP from host to guest via the following command executed on the guest:
```shell
netsh advfirewall firewall add rule name="Allow ICMPv4" protocol=icmpv4:8,any dir=in action=allow
```
This will enable simple `ping` requests from your host to the guest.
### Remote Desktop Protocol (RDP) enablement
#### Using QEMU
- Execute `SystemPropertiesRemote`
- In the properties window, choose "Allow remote connections to this computer"
- Click "Select Users" and add some user to the allow list
- Execute `SystemPropertiesRemote`
- In the properties window, choose "Allow remote connections to this computer"
- Click "Select Users" and add some user to the allow list
#### Using powershell
```powershell
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\" -Name "fDenyTSConnections" -Value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
Add-LocalGroupMember -Group "Remote Desktop Users" -Member someuser
```
Administrators can always RDP, non administrator users have to be explicitly enabled.
Administrators can always RDP, non administrator users have to be explicitly enabled.
Once the configuration is set, RDP clients can connect to `192.168.249.2`.
@@ -182,7 +249,15 @@ Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
```
This allows for SSH login from a remote machine, for example through the `administrator` user: `ssh administrator@192.168.249.2`. For a more detailed OpenSSH guide, please follow the MSDN article from the [links](#links) section.
This allows for SSH login from a remote machine, for example through the `administrator` user: `ssh administrator@192.168.249.2`.
On Windows 11, opening the firewall was needed as well:
```powershell
New-NetFirewallRule -Name sshd -DisplayName "OpenSSH Server" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
```
For a more detailed OpenSSH guide, please follow the MSDN article from the [links](#links) section.
## Hotplug capability
@@ -196,6 +271,8 @@ Disk hotplug and hot-remove are supported. After the device has been hotplugged,
## Debugging
Disclaimer: This chapter was not verified on Windows 11 yet. Proceed with care.
The Windows guest debugging process relies heavily on QEMU and [socat](http://www.dest-unreach.org/socat/). The procedure requires two Windows VMs:
- A debugger VM running under QEMU.
@@ -203,7 +280,7 @@ The Windows guest debugging process relies heavily on QEMU and [socat](http://ww
The connection between both guests happens over TCP, whereby on the guest side it is automatically translated to a COM port. Because the VMs are connected through TCP, the debugging infrastructure can be distributed over the network. The serial port, while slowly transferring data, is common enough to support a wide range of cases and tools.
In this exercise, [WinDbg](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) is used. Any other debugger of choice with the ability to use serial connection can be used instead.
In this exercise, [WinDbg](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) is used. Any other debugger of choice with the ability to use serial connection can be used instead.
### Debugger and Debuggee
@@ -220,7 +297,7 @@ qemu-system-x86_64 \
-smp 1 \
-m 4G \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom \
-drive if=none,id=root,file=./windbg-disk.raw \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
@@ -256,7 +333,7 @@ bcdedit /debug on
bcdedit /bootdebug on
```
##### Turn on boot manager debug
##### Turn on boot manager debug
```cmd
bcdedit /set {bootmgr} bootdebug on
@@ -308,6 +385,7 @@ Once started, WinDbg will wait for an incoming connection which is going to be i
##### Under QEMU
Essentially it would be the command like depicted in the guest preparation sections, with a few modifications:
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
@@ -315,7 +393,7 @@ qemu-system-x86_64 \
-m 4G \
-bios ./$OVMF_DIR/OVMF_CODE.fd \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom \
-drive if=none,id=root,file=./$IMG_FILE \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \

View File

@@ -1,11 +1,11 @@
[package]
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
edition.workspace = true
name = "event_monitor"
version = "0.1.0"
[dependencies]
flume = "0.11.1"
libc = "0.2.167"
serde = { version = "1.0.208", features = ["derive", "rc"] }
flume = { workspace = true }
libc = { workspace = true }
serde = { workspace = true, features = ["derive", "rc"] }
serde_json = { workspace = true }

499
fuzz/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,20 +11,21 @@ cargo-fuzz = true
[features]
default = ["mshv_emulator"]
igvm = []
ivshmem = []
mshv_emulator = ["hypervisor/mshv_emulator"]
pvmemcontrol = []
[dependencies]
arbitrary = "1.4.1"
arbitrary = "1.4.2"
block = { path = "../block" }
devices = { path = "../devices" }
epoll = "4.3.3"
hypervisor = { path = "../hypervisor", features = ["mshv_emulator"] }
libc = "0.2.155"
libfuzzer-sys = "0.4.7"
linux-loader = { version = "0.13.0", features = ["bzimage", "elf", "pe"] }
libc = "0.2.177"
libfuzzer-sys = "0.4.10"
linux-loader = { version = "0.13.1", features = ["bzimage", "elf", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
mshv-bindings = "0.5.2"
mshv-bindings = "0.6.0"
net_util = { path = "../net_util" }
seccompiler = "0.5.0"
virtio-devices = { path = "../virtio-devices" }

View File

@@ -186,8 +186,6 @@ impl RequestHandler for StubApiRequestHandler {
#[cfg(feature = "pvmemcontrol")]
pvmemcontrol: None,
iommu: false,
#[cfg(target_arch = "x86_64")]
sgx_epc: None,
numa: None,
watchdog: false,
gdb: false,
@@ -197,6 +195,8 @@ impl RequestHandler for StubApiRequestHandler {
preserved_fds: None,
landlock_enable: false,
landlock_rules: None,
#[cfg(feature = "ivshmem")]
ivshmem: None,
}),
state: VmState::Running,
memory_actual_size: 0,
@@ -221,7 +221,7 @@ impl RequestHandler for StubApiRequestHandler {
Ok(())
}
fn vm_resize(&mut self, _: Option<u8>, _: Option<u64>, _: Option<u64>) -> Result<(), VmError> {
fn vm_resize(&mut self, _: Option<u32>, _: Option<u64>, _: Option<u64>) -> Result<(), VmError> {
Ok(())
}

View File

@@ -12,8 +12,9 @@ use std::{ffi, io};
use libc::{MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE};
use libfuzzer_sys::{fuzz_target, Corpus};
use seccompiler::SeccompAction;
use virtio_devices::{Pmem, UserspaceMapping, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_devices::{Pmem, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_device::UserspaceMapping;
use vm_memory::bitmap::AtomicBitmap;
use vm_memory::guest_memory::FileOffset;
use vm_memory::{Bytes, GuestAddress, GuestMemoryAtomic, MmapRegion};

View File

@@ -1,6 +1,6 @@
[package]
authors = ["Microsoft Authors"]
edition = "2021"
edition.workspace = true
license = "Apache-2.0 OR BSD-3-Clause"
name = "hypervisor"
version = "0.1.0"
@@ -13,27 +13,27 @@ sev_snp = ["igvm", "igvm_defs"]
tdx = []
[dependencies]
anyhow = "1.0.94"
anyhow = { workspace = true }
arc-swap = "1.7.1"
bitfield-struct = "0.10.1"
byteorder = "1.5.0"
cfg-if = "1.0.0"
bitfield-struct = "0.12.0"
byteorder = { workspace = true }
cfg-if = { workspace = true }
concat-idents = "1.1.5"
igvm = { workspace = true, optional = true }
igvm_defs = { workspace = true, optional = true }
kvm-bindings = { workspace = true, optional = true, features = ["serde"] }
kvm-ioctls = { workspace = true, optional = true }
libc = "0.2.167"
log = "0.4.22"
libc = { workspace = true }
log = { workspace = true }
mshv-bindings = { workspace = true, features = [
"fam-wrappers",
"with-serde",
], optional = true }
mshv-ioctls = { workspace = true, optional = true }
open-enum = "0.5.2"
serde = { version = "1.0.208", features = ["derive", "rc"] }
serde = { workspace = true, features = ["derive", "rc"] }
serde_json = { workspace = true }
serde_with = { version = "3.9.0", default-features = false, features = [
serde_with = { workspace = true, default-features = false, features = [
"macros",
] }
thiserror = { workspace = true }

Some files were not shown because too many files have changed in this diff Show More