Compare commits

...

124 Commits
v34.0 ... v35.1

Author SHA1 Message Date
Bo Chen
9c15de0118 build: Release v35.1 (bug fix release)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-10 11:16:58 -08:00
Bo Chen
ca9e20c27a tests: Temporarily disable vhost_user_blk tests on aarch64
See: #5934

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

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

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

This patch has been tested with PR #6048.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
Tested-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 24f384d239)
2024-01-10 09:09:27 -08:00
Wei Liu
bd6c898b1d scripts: propagate RUSTFLAGS and TARGET_CC to test scripts
There is no need to set them in the test scripts while the main script
already has them.

The consolidates how things are done.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
(cherry picked from commit 8ba5682e3b)
2024-01-10 09:09:27 -08:00
Wei Liu
98c1e21d92 scripts: pass BUILD_TARGET directly to test scripts
There is no need to reconstruct it from within the scripts since the
main script already constructed it once.

Drop the previously useless setting of BUILD_TARGET from various
scripts. The value was always overwritten at a later point.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
(cherry picked from commit c7e51e51e5)
2024-01-10 09:09:27 -08:00
Wei Liu
7992997299 scripts: dev_cli.sh: respect preset RUSTFLAGS
Signed-off-by: Wei Liu <liuwe@microsoft.com>
(cherry picked from commit 9d42f48f49)
2024-01-10 09:09:27 -08:00
dom.song
a1627d295a tests: Update spdk code to support Ampere's new CPU
When performing integration testing on the Ampere One server, an error occurred when compiling spdk and not recognizing the CPU ID.
The latest spdk already contains fixes.

Signed-off-by: dom.song <dom.song@amperecomputing.com>
(cherry picked from commit 7f47a030e7)
2024-01-10 09:09:27 -08:00
Bo Chen
9278d565e2 mis: Fix clippy issues
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-10 09:09:27 -08:00
Yi Wang
f3c6f5c512 build: fix clippy complex closures issue
CI reports clippy errors:

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

Signed-off-by: Yi Wang <foxywang@tencent.com>
(cherry picked from commit 9c2d650cb8)
2024-01-10 09:09:27 -08:00
Bo Chen
7c3c2ee0d6 vmm: tdx: Error out early for TD migration
Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit e64b66054e)
2024-01-10 09:09:27 -08:00
Rui Chang
19e45650a6 vmm: add add-user-device support in cloud-hypervisor.yaml
The change is missed when add "add-user-device" support in
53b2e19934, use this commit to fix it.

Signed-off-by: Rui Chang <rui.chang@arm.com>
(cherry picked from commit 2b457584e0)
2024-01-10 09:09:27 -08:00
Thomas Barrett
c3a4289cbb devices: fix pv_panic alignment
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
(cherry picked from commit 5f3ff3c44a)
2024-01-10 09:09:27 -08:00
Jianyong Wu
0886e79630 aarch64: fdt: Use more appropriate default value for topology
Now, default values for vcpu topology are 0s, that is not correct and may
lead to bug. Fix it by setting default value to 1s. Also add check in
case one or more of these values are zero.

Fixes: #5892
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
(cherry picked from commit 2434e76ee0)
2024-01-10 09:09:27 -08:00
Bo Chen
a40a0268bb vmm: tdx: Fix a deadlock while accessing vm_config
The lock to `vm_config` is held for accessing `cpus.kvm_hyperv` passing
as a reference to `arch::generate_common_cpuid()`, so acquiring the same
lock again while calling to the same function is a deadlock.

Fixes: 3793ffe888

Reported-by: Yi Wang <foxywang@tencent.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit aa6e83126c)
2024-01-10 09:09:27 -08:00
Bo Chen
339912a576 build: Release v35.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-21 15:04:42 +01:00
dependabot[bot]
7ea0bf41be build: Bump smallvec from 1.11.0 to 1.11.1 in /fuzz
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.0 to 1.11.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.0...v1.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 23:40:51 +00:00
Rob Bradford
44f200d67d hypervisor: Set destination vCPU TSC frequency to source
Include the TSC frequency as part of the KVM state so that it will be
restored at the destination.

This ensures migration works correctly between hosts that have a
different TSC frequency if the guest is running with TSC as the source
of timekeeping.

Fixes: #5786

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-20 09:13:42 -07:00
dependabot[bot]
18d8c5669f build: Bump proc-macro2 from 1.0.66 to 1.0.67
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.66 to 1.0.67.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.66...1.0.67)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 00:43:42 +00:00
Bo Chen
57b7f35739 Revert "build: Temporarily disable bare metal workers"
This reverts commit ff818869dd.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-19 17:39:27 -07:00
dependabot[bot]
ed4537f4ae build: Bump vmm-sys-util from 0.11.1 to 0.11.2 in /fuzz
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.11.1 to 0.11.2.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Changelog](https://github.com/rust-vmm/vmm-sys-util/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vmm-sys-util/commits)

---
updated-dependencies:
- dependency-name: vmm-sys-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 00:08:46 +00:00
dependabot[bot]
885412a99e build: Bump serde_json from 1.0.96 to 1.0.107
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.96 to 1.0.107.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.96...v1.0.107)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-19 00:45:18 +00:00
dependabot[bot]
128da81d83 build: Bump io-uring from 0.6.1 to 0.6.2 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.1 to 0.6.2.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

---
updated-dependencies:
- dependency-name: io-uring
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 23:37:10 +00:00
dependabot[bot]
0235bc4cee build: Bump smallvec from 1.10.0 to 1.11.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.10.0...v1.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 16:27:52 +00:00
dependabot[bot]
09a9cce95e build: Bump libc from 0.2.147 to 0.2.148 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.147 to 0.2.148.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.147...0.2.148)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 23:42:37 +00:00
Bo Chen
ff818869dd build: Temporarily disable bare metal workers
The bare metal machines are now not reachable from our Jenkins
controller, and causing CI pipeline timeout for the past few days.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-15 13:53:46 -07:00
Bo Chen
c70f133b72 build: Skip 'test_vfio' on AMD workers
See: #5775

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-15 08:07:31 +01:00
Bo Chen
328cf39be1 tests: Enable "test_vfio" on Azure VM instances
In this way, this test can be run against all PRs.

Fixes: #4324

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-15 08:07:31 +01:00
dependabot[bot]
64ad7657d1 build: Bump darling from 0.20.1 to 0.20.3
Bumps [darling](https://github.com/TedDriggs/darling) from 0.20.1 to 0.20.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.1...v0.20.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 00:17:16 +00:00
dependabot[bot]
cb6a53698c build: Bump unicode-ident from 1.0.11 to 1.0.12 in /fuzz
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.11...1.0.12)

---
updated-dependencies:
- dependency-name: unicode-ident
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-14 23:36:52 +00:00
Alyssa Ross
a91637067a virtio-devices: fix typo in error description
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-09-14 14:09:14 +01:00
Christian Blichmann
88f3537b47 event_monitor: Replace unsound static mut MONITOR
See discussion in https://github.com/rust-lang/rust/issues/53639.
This came up during an internal review.

Signed-off-by: Christian Blichmann <cblichmann@google.com>
2023-09-14 14:08:54 +01:00
dependabot[bot]
f557aadb67 build: Bump is-terminal from 0.4.7 to 0.4.9
Bumps [is-terminal](https://github.com/sunfishcode/is-terminal) from 0.4.7 to 0.4.9.
- [Commits](https://github.com/sunfishcode/is-terminal/compare/v0.4.7...v0.4.9)

---
updated-dependencies:
- dependency-name: is-terminal
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-14 07:55:17 +01:00
dependabot[bot]
ff6514572e build: Bump serde_json from 1.0.106 to 1.0.107 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.106 to 1.0.107.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.106...v1.0.107)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-14 00:17:01 +00:00
dependabot[bot]
11ec1e647c build: Bump cc from 1.0.79 to 1.0.83
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.79 to 1.0.83.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.79...1.0.83)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-13 00:09:38 +00:00
dependabot[bot]
226816bb04 build: Bump crc32c from 0.6.3 to 0.6.4
Bumps [crc32c](https://github.com/zowens/crc32c) from 0.6.3 to 0.6.4.
- [Commits](https://github.com/zowens/crc32c/compare/v0.6.3...v0.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 00:15:22 +00:00
dependabot[bot]
6e32c4531e build: Bump serde_json from 1.0.105 to 1.0.106 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.105 to 1.0.106.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.105...v1.0.106)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 23:34:46 +00:00
Bo Chen
9c994f882a virtio-devices: block: Fix the latency counter for max read/write
See: #5712

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-11 23:08:23 +01:00
Bo Chen
b76d0e8b50 virtio-devices: block: Fix latency counter for average read/write
The cumulative average formula [1] requires to use signed integers
for proper calculations, while calculated result (e.g. cumulative
average) is always positive. This patch reflects the above requirements
in our code.

[1] https://en.wikipedia.org/wiki/Moving_average#Cumulative_average

Fixes: #5745

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-11 23:08:15 +01:00
Ruslan Mstoi
e151483f70 docs: intel_tdx: add info about dependencies
Required Debian packages are the same as described in uefi.md

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-09-11 16:39:16 +01:00
Ruslan Mstoi
b904d666b0 docs: intel_tdx: fix python not found error
Fix make error:
$ make -C BaseTools -j `nproc`

/bin/sh: line 1: python: command not found
make[1]: *** [GNUmakefile:11: test] Error 127

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-09-11 16:39:16 +01:00
dependabot[bot]
0b99f96fc4 build: Bump pnet/pnet_datalink from 0.33.0 to 0.34.0
Bump these crates need to be bumped together to avoid build issues from
shared structures.

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-11 13:15:08 +00:00
Ruslan Mstoi
6d395c51db docs: intel_tdx: add jobs argument to make
This could speed up the build

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-09-11 13:27:40 +01:00
Thomas Barrett
c4e8e653ac block: Add support for user specified ID_SERIAL
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-09-11 12:50:41 +01:00
Ruslan Mstoi
49e342314d tests: test_memory_overhead: use guest.vm_wait_boot
See: #5738

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-09-11 12:50:08 +01:00
Julian Stecklina
0d9749282a vmm: simplify EntryPoint
EntryPoint had an optional entry_addr, but there is no usage of this
struct that makes it necessary that the address is optional.

Remove the Option to avoid being able to express things that are not
useful.

Signed-off-by: Julian Stecklina <julian.stecklina@cyberus-technology.de>
2023-09-09 10:46:51 +01:00
Philipp Schuster
83f3b34405 ci: Run typos
This adds the typos utility as dedicated CI step.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-09-09 10:46:21 +01:00
Philipp Schuster
7bf0cc1ed5 misc: Fix various spelling errors using typos
This fixes all typos found by the typos utility with respect to the config file.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-09-09 10:46:21 +01:00
Philipp Schuster
fa09045f55 misc: Add configuration file for typos
This is a preparation to run the typos utility on the repo.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-09-09 10:46:21 +01:00
Rob Bradford
367201ed1e tests: Temporarily disable test_vdpa_net
This test is consistently failing after the on demand worker kernel
upgrade.

See: #5756

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-09 08:43:53 +01:00
dependabot[bot]
068470696f build: Bump proc-macro2 from 1.0.63 to 1.0.66
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.63 to 1.0.66.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.63...1.0.66)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-08 08:40:23 +01:00
Bo Chen
e2db476f6e virtio-devices: block: Correct the latency for the first op
There is a "LATENCY_SCALE" being used for calculating cumulative average
latency, so it should also be used for the latency of the first op.

See: #5712

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-07 23:00:47 +01:00
Rob Bradford
07d1208dd5 build: Bump vm-memory and its consumers
Update to the latest vm-memory and all the crates that also depend upon
it.

Fix some deprecation warnings.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-07 11:34:51 -07:00
Rob Bradford
4548de194d build: Bump acpi_tables version
Fix newly added deprecation for mispelling of cacheable.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-07 13:58:33 +01:00
Jinank Jain
1b9ce69afa src: Add compile time check for SNP and TDX
We need to make sure that SEV-SNP and TDX are not enabled at the same
time. As these two features belong to mutually exclusive hardware
vendors. So, we should make sure that these two features are not enabled
at the same. Thus, a compile time check for it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-07 12:52:27 +01:00
Jinank Jain
51548471fd github: worflow: Add build and clippy test for snp
Extend the current github actions to add support for snp feature flag.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-07 12:52:27 +01:00
Jinank Jain
70074ddf9f docs: Add documentation for AMD SEV-SNP
Creating some brief documentation for SEV-SNP, summarizing the links on
where to find more information about SEV-SNP, as well as how to build
and run Cloud Hypervisor on it.

This document is a work in progress and will be updated in future PRs
as we add support for it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-07 12:52:27 +01:00
Jinank Jain
200cba0e20 vmm: Refactor VM creation workflow
This refactoring is required to add support for creating SEV-SNP enabled
VM.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-07 12:52:27 +01:00
Jinank Jain
5fd79571b7 vmm: Add a feature flag for SEV-SNP support
This feature flag gates the development for SEV-SNP enabled guest.

Also add a helper function to identify if SNP should be enabled for the
guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-07 12:52:27 +01:00
dependabot[bot]
3e1b0bc124 build: Bump regex-syntax from 0.7.4 to 0.7.5
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.7.4 to 0.7.5.
- [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.7.4...regex-syntax-0.7.5)

---
updated-dependencies:
- dependency-name: regex-syntax
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-07 07:14:34 +00:00
dependabot[bot]
1632dbbf29 build: Bump zerocopy from 0.6.3 to 0.6.4 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.6.3 to 0.6.4.
- [Commits](https://github.com/google/zerocopy/compare/v0.6.3...v0.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 23:18:49 +00:00
Thomas Barrett
8d2e590886 rate-limiter: Allow RateLimiter to be shared between threads
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-09-06 15:02:37 -07:00
dependabot[bot]
e880aeed8d build: Bump openssl-sys from 0.9.91 to 0.9.93
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.91 to 0.9.93.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.91...openssl-sys-v0.9.93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 17:39:14 +00:00
Rob Bradford
8bdf59bbee build: Use focal version of azure-cli client on aarch64
The worker is running focal not bionic - this fixes build issues on that
worker machine due to the bionic version not being installable.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-06 12:06:20 +01:00
dependabot[bot]
14edd6d9de build: Bump thiserror from 1.0.47 to 1.0.48 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.47 to 1.0.48.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.47...1.0.48)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-05 23:43:35 +00:00
Rob Bradford
01097aa130 block: Ensure probing reads are block size aligned
This is necessary for O_DIRECT based use of raw block devices which may
require access at a larger block size than that of a sector (512 bytes.)

Fixes: #5722

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-05 13:09:49 -07:00
Rob Bradford
9ca2c336f2 block: Move DiskTopology to common code
It doens't make sense to limit this to the async_io module and import
across modules so place in default create module.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-05 13:09:49 -07:00
dependabot[bot]
b1a1b2a622 build: Bump nix from 0.26.2 to 0.26.4
Bumps [nix](https://github.com/nix-rust/nix) from 0.26.2 to 0.26.4.
- [Changelog](https://github.com/nix-rust/nix/blob/v0.26.4/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.26.2...v0.26.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 23:52:31 +00:00
Philipp Schuster
556bda74a0 hypervisor: emulator: Use wrapping add for memory offset
Assume rax is 0xfee003e0 and the displacement is negative 0x60. The effective
address is then 0xfee00380. This is perfectly valid.

Example instruction:
c7 40 a0 00 10 00 00    movl   $0x1000,-0x60(%rax)

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-09-01 14:27:54 +01:00
dependabot[bot]
8db85eca1f build: Bump io-uring from 0.6.0 to 0.6.1
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.0 to 0.6.1.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-31 23:59:42 +00:00
Rob Bradford
b5766028a8 virtio-devices: block: Make latency infinite before first op
Logically until we have handled the first operation the latency is
infinite; this logic was applied to the minimum latency originally but
this patch extends that logic to the maximum and average latency.

To prevent the initial average latency being skewed by the inclusion of
infinity the average value is initally seeded with the first measured
latency.

Fixes: #5704

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-31 08:22:07 -07:00
dependabot[bot]
35757ec45a build: Bump mshv-ioctls from a45fbeb to c5a6050
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `a45fbeb` to `c5a6050`.
- [Commits](a45fbeb4a3...c5a6050859)

---
updated-dependencies:
- dependency-name: mshv-ioctls
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-31 00:28:57 +00:00
Ruslan Mstoi
a51b48a095 tests: fix typo expected_events to latest_events
In the documentation of function check_latest_events_exact use same events
argument name as in the implementation

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-08-30 13:06:32 -07:00
dependabot[bot]
d1ee623f0e build: Bump regex-automata from 0.3.3 to 0.3.7
Bumps [regex-automata](https://github.com/rust-lang/regex) from 0.3.3 to 0.3.7.
- [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.3.3...regex-syntax-0.3.7)

---
updated-dependencies:
- dependency-name: regex-automata
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-30 00:22:15 +00:00
Rob Bradford
a2752fe04f virtio-devices: vsock: Support single descriptor
Since kernel v6.3 the vsock packet is not split over two descriptors
and is instead included in a single one.

This change is based on the discovery and fix identified by Stefano
Garzarella for the vm-virtio vsock implementation and adapted for our
very different codebase.

Fixes: #5691

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-29 15:36:49 -07:00
Omer Faruk Bayram
cc5dd8c297 docs: api: document newly added event signal to the D-Bus API
Signed-off-by: Omer Faruk Bayram <omer.faruk@sartura.hr>
2023-08-28 17:01:03 -07:00
Omer Faruk Bayram
2ed96cd3ed vmm: dbus: broadcast event_monitor events over the DBus API
This commit builds on top of the `Monitor::subscribe` function and
makes it possible to broadcast events published from `event-monitor`
over D-Bus.

The broadcasting functionality is enabled if the D-Bus API is enabled
and users who wish to also enable the file based `event-monitor` can do
so with the CLI arg `--event-monitor`.

Signed-off-by: Omer Faruk Bayram <omer.faruk@sartura.hr>
2023-08-28 17:01:03 -07:00
Omer Faruk Bayram
e02efe9ba0 event_monitor: make it possible to subscribe to Monitor
Signed-off-by: Omer Faruk Bayram <omer.faruk@sartura.hr>
2023-08-28 17:01:03 -07:00
dependabot[bot]
654ac49bd6 build: Bump micro_http from b538bf8 to 0d0fdcd
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `b538bf8` to `0d0fdcd`.
- [Commits](b538bf89e5...0d0fdcd50e)

---
updated-dependencies:
- dependency-name: micro_http
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 23:55:16 +00:00
dependabot[bot]
8013e47856 build: Bump openssl-sys from 0.9.90 to 0.9.91
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.90 to 0.9.91.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.90...openssl-sys-v0.9.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-26 00:16:59 +00:00
dependabot[bot]
7216d934de build: Bump quote from 1.0.32 to 1.0.33 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.32...1.0.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-25 23:34:35 +00:00
dependabot[bot]
f45bbbfcac build: Bump serde from 1.0.164 to 1.0.168
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.164 to 1.0.168.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.164...v1.0.168)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-25 09:53:12 +00:00
dependabot[bot]
d87024a752 build: Bump micro_http from b538bf8 to 0d0fdcd in /fuzz
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `b538bf8` to `0d0fdcd`.
- [Commits](b538bf89e5...0d0fdcd50e)

---
updated-dependencies:
- dependency-name: micro_http
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-24 23:46:18 +00:00
dependabot[bot]
bb94dd18ee build: Bump openssl-src from 111.26.0+1.1.1u to 111.27.0+1.1.1v
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.26.0+1.1.1u to 111.27.0+1.1.1v.
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

---
updated-dependencies:
- dependency-name: openssl-src
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-24 08:03:35 +00:00
dependabot[bot]
00e4f28e8f build: Bump thiserror from 1.0.44 to 1.0.47 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.44 to 1.0.47.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.44...1.0.47)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-24 00:01:37 +00:00
Rob Bradford
89661f6579 Revert "build: Temporarily disable bare metal Intel workers"
This reverts commit 96df501b7f.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-23 17:16:50 +01:00
Rob Bradford
cd7eecc0b0 devices: pvpanic: Clean up struct visibility
There is no need for this struct to be public and since it is used in
this module the #[allow(dead_code)] invocation can be removed.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-23 08:05:53 +01:00
dependabot[bot]
78ec651cbf build: Bump serde_with from 3.2.0 to 3.3.0 in /fuzz
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.2.0...v3.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-23 00:04:13 +00:00
dependabot[bot]
3e54a586ce build: Bump async-trait from 0.1.71 to 0.1.73
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.71 to 0.1.73.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.71...0.1.73)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-22 23:52:19 +00:00
Rob Bradford
9d5c5a6410 vmm: sigwinch_listener: Remove unncessary mut from reference
warning: this argument is a mutable reference, but not used mutably
   --> vmm/src/sigwinch_listener.rs:121:38
    |
121 | fn set_foreground_process_group(tty: &mut File) -> io::Result<()> {
    |                                      ^^^^^^^^^ help: consider changing to: `&File`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
8d072fef15 vmm: device_manager: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
    --> vmm/src/device_manager.rs:1908:35
     |
1908 |     fn set_raw_mode(&mut self, f: &mut dyn AsRawFd) -> vmm_sys_util::errno::Result<()> {
     |                                   ^^^^^^^^^^^^^^^^ help: consider changing to: `&dyn AsRawFd`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
     = note: `#[warn(clippy::needless_pass_by_ref_mut)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
1dd1850747 ch-remote: dbus: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
   --> src/bin/ch-remote.rs:397:52
    |
397 | fn dbus_api_do_command(toplevel: &TopLevel, proxy: &mut DBusApi1ProxyBlocking<'_>) -> ApiResult {
    |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&DBusApi1ProxyBlocking<'_>`
    |
    = note: this is cfg-gated and may require further changes
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
    = note: `#[warn(clippy::needless_pass_by_ref_mut)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
0bead9ebe1 vmm: cpu: Fix slow vector initialization
warning: slow zero-filling initialization
    --> vmm/src/cpu.rs:1780:9
     |
1779 |         let mut mat_data: Vec<u8> = Vec::new();
     |                                     ---------- help: consider replacing this with: `vec![0; std::mem::size_of_val(&lapic)]`
1780 |         mat_data.resize(std::mem::size_of_val(&lapic), 0);
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
     = note: `#[warn(clippy::slow_vector_initialization)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
05a86d892e virtio-devices: vsock: Fix slow vector initialization
warning: slow zero-filling initialization
   --> virtio-devices/src/vsock/csm/txbuf.rs:218:9
    |
216 |         let mut tmp: Vec<u8> = Vec::new();
    |                                ---------- help: consider replacing this with: `vec![0; TxBuf::SIZE - 2]`
217 |
218 |         tmp.resize(TxBuf::SIZE - 2, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
    = note: `#[warn(clippy::slow_vector_initialization)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
4d8dacec5e virtio-devices: transport: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
   --> virtio-devices/src/transport/pci_common_config.rs:100:17
    |
100 |         queues: &mut [Queue],
    |                 ^^^^^^^^^^^^ help: consider changing to: `&[Queue]`
    |
    = warning: changing this function will impact semver compatibility
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
    = note: `#[warn(clippy::needless_pass_by_ref_mut)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
cc4422d58b vm-device: bus: Fix incorrect partial_cmp implementation
warning: incorrect implementation of `partial_cmp` on an `Ord` type
  --> vm-device/src/bus.rs:86:1
   |
86 | /  impl PartialOrd for BusRange {
87 | |      fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
   | | _________________________________________________________________-
88 | ||         self.base.partial_cmp(&other.base)
89 | ||     }
   | ||_____- help: change this to: `{ Some(self.cmp(other)) }`
90 | |  }
   | |__^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type
   = note: `#[warn(clippy::incorrect_partial_ord_impl_on_ord_type)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
239f422203 hypervisor: x86: emulator: Remove unncessary mut from reference
warning: this argument is a mutable reference, but not used mutably
  --> hypervisor/src/arch/x86/emulator/instructions/mod.rs:22:15
   |
22 |     platform: &mut dyn PlatformEmulator<CpuState = T>,
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&dyn PlatformEmulator<CpuState = T>`
   |
   = note: this is cfg-gated and may require further changes
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
5636d91524 net_util: queue_pair: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
   --> net_util/src/queue_pair.rs:167:14
    |
167 |         tap: &mut Tap,
    |              ^^^^^^^^ help: consider changing to: `&Tap`
    |
    = warning: changing this function will impact semver compatibility
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
11c58870c4 block: async_io: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
  --> block/src/async_io.rs:68:28
   |
68 |     fn query_block_size(f: &mut File, block_size_type: BlockSize) -> std::io::Result<u64> {
   |                            ^^^^^^^^^ help: consider changing to: `&File`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Rob Bradford
b74907fa1b block: vhdx: Fix block size check
warning: boolean expression will never evaluate to 'true'
   --> block/src/vhdx/vhdx_metadata.rs:136:20
    |
136 |                 if disk_spec.block_size < BLOCK_SIZE_MIN && disk_spec.block_size > BLOCK_SIZE_MAX {
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: since `BLOCK_SIZE_MIN` < `BLOCK_SIZE_MAX`, the expression evaluates to false for any value of `disk_spec.block_size`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons
    = note: `#[warn(clippy::impossible_comparisons)]` on by default

&& was used when || should have been used

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
Wei Liu
dbe67fca7f hypervisor: mshv: handle APIC EOI message
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-08-21 17:20:05 -07:00
dependabot[bot]
d3fc12b160 build: Bump cpufeatures from 0.2.8 to 0.2.9
Bumps [cpufeatures](https://github.com/RustCrypto/utils) from 0.2.8 to 0.2.9.
- [Commits](https://github.com/RustCrypto/utils/compare/cpufeatures-v0.2.8...cpufeatures-v0.2.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-22 00:06:45 +00:00
dependabot[bot]
d73d3203dc build: Bump cc from 1.0.82 to 1.0.83 in /fuzz
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.82 to 1.0.83.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.82...1.0.83)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-21 23:21:46 +00:00
Jianyong Wu
16e1449f1e balloon: let balloon deflation works on page size other than 4k
Similar to balloon inflation, memory allocation is also constrained to
align with the page size. Therefore, memory is allocated in units of the
host page size, one page at a time, until all host pages that the memory
range requested by the guest are managed. If the requested size is
smaller than the page size, the entire page will still be allocated
because smaller allocations are not possible due to the page size
limitation.

Fixes: cloud-hypervisor#5369
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2023-08-21 16:35:23 +01:00
Jianyong Wu
9dd1698556 balloon: let balloon inflation works on page size other than 4k
Currently, virtio-balloon can't work well with page size other than 4k.
The virtio-balloon always works in units of 4kiB (BALLOON_PAGE_SIZE), but
we can only actually discard memory in units of the host page size.

We get some idea from [1] to solve this issue.

What has been done in this commit:

For balloon inflation:

A bitmap is employed to track the memory range to be released in 4k
granularity. Once it accumulates to one host page size, the corresponding
page is released, and the bitmap is cleared to handle the next record.
This process continues until all the memory range is managed. Memory will
only be released when a consecutive set of balloon request entries from
the same host page reaches the full host page size. If a balloon request
entry from a different host page is encountered, the bitmap and the base
host page address will be reset. Consequently, memory is released in
units of the page size, ensuring efficient memory management. That's say
if memory range length to be released smaller than page size or if the
guest scatters requests each of whose size is smaller than page size
across different host pages no memory will be released.

[1] https://patchwork.kernel.org/project/qemu-devel/patch/20190214043916.22128-6-david@gibson.dropbear.id.au/

Fixes: cloud-hypervisor#5369
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2023-08-21 16:35:23 +01:00
Yi Wang
d46dd4b31f vmm: cpu: Add pending removed vcpu check to avoid resize vcpu hang
Add pending removed vcpu check according to VcpuState.removing, which
can avoid cloud hypervisor hangup during continual vcpu resize.

Fix #5419

Signed-off-by: Yi Wang <foxywang@tencent.com>
2023-08-20 10:40:43 +01:00
Anatol Belski
0e75e7d079 scripts: Set LAST_RELEASE_VERSION to v34.0
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-08-20 10:39:11 +01:00
Anatol Belski
be81fea46a tests: Re-enable live migration tests for AMD
These had to be previously disabled because a released binary has to be
used in course of the test scenario. The necessary functionality is now
supported with the release 34.0, thus these tests should now pass.

Fixes: #5660

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-08-20 10:39:11 +01:00
Ruslan Mstoi
cd010052f8 tests: Revert disable test_vfio test
This reverts commit 268c4ea214.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-08-20 10:38:44 +01:00
Ruslan Mstoi
725bb8d038 test_data: fix cloud-hypervisor invocation
Update cloud-hypervisor call in accordance with argh semantics

Fixes #5190

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-08-20 10:38:44 +01:00
dependabot[bot]
ddfac7df0b build: Bump anyhow from 1.0.71 to 1.0.75
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.71 to 1.0.75.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.71...1.0.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-19 21:40:49 +00:00
dependabot[bot]
6118359240 build: Bump serde_json from 1.0.104 to 1.0.105 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.104...v1.0.105)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-18 23:28:23 +00:00
dependabot[bot]
0a294bf2d7 build: Bump tempfile from 3.5.0 to 3.7.1
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.5.0 to 3.7.1.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.5.0...v3.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-18 00:08:02 +00:00
dependabot[bot]
baf10a45a9 build: Bump anyhow from 1.0.74 to 1.0.75 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.74 to 1.0.75.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.74...1.0.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-18 00:01:38 +00:00
dependabot[bot]
c655e22e42 build: Bump pin-project-lite from 0.2.9 to 0.2.12
Bumps [pin-project-lite](https://github.com/taiki-e/pin-project-lite) from 0.2.9 to 0.2.12.
- [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.9...v0.2.12)

---
updated-dependencies:
- dependency-name: pin-project-lite
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-16 23:55:45 +00:00
dependabot[bot]
dd6ee3b39a build: Bump log from 0.4.19 to 0.4.20 in /fuzz
Bumps [log](https://github.com/rust-lang/log) from 0.4.19 to 0.4.20.
- [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.19...0.4.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-16 23:36:23 +00:00
dependabot[bot]
8b651ec7ee build: Bump semver from 1.0.17 to 1.0.18
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.17...1.0.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-16 00:54:29 +00:00
zhongbingnan
5857d4851b aarch64/fdt: fix cache sharing issue for cache passthrough on aarch64
We fixed the L2 and L3 level cache sharing issues and confirmed that the
L2 level cache is independent, while the L3 level cache is shared per-socket.

See:#5505

Signed-off-by: zhongbingnan <zhongbingnan@bytedance.com>
2023-08-16 08:25:20 +08:00
dependabot[bot]
0f63f8d001 build: Bump anyhow from 1.0.72 to 1.0.74 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.72 to 1.0.74.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.72...1.0.74)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-15 23:35:06 +00:00
dependabot[bot]
2571e59438 build: Bump libc from 0.2.144 to 0.2.147
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.144 to 0.2.147.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.144...0.2.147)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-15 00:53:20 +00:00
dependabot[bot]
d32e7fceb5 build: Bump io-uring from 0.6.0 to 0.6.1 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.0 to 0.6.1.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

---
updated-dependencies:
- dependency-name: io-uring
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 23:58:17 +00:00
dependabot[bot]
86655f4967 build: Bump libz-sys from 1.1.9 to 1.1.12
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.9 to 1.1.12.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.9...1.1.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-12 16:46:35 +00:00
dependabot[bot]
d9d1cdb0c6 build: Bump libfuzzer-sys from 0.4.6 to 0.4.7 in /fuzz
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.4.6 to 0.4.7.
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.6...0.4.7)

---
updated-dependencies:
- dependency-name: libfuzzer-sys
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-11 23:34:26 +00:00
dependabot[bot]
ca155a790c build: Bump argh from 0.1.10 to 0.1.12 in /fuzz
Bumps [argh](https://github.com/google/argh) from 0.1.10 to 0.1.12.
- [Release notes](https://github.com/google/argh/releases)
- [Commits](https://github.com/google/argh/compare/0.1.10...0.1.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-11 00:07:42 +00:00
119 changed files with 1918 additions and 1185 deletions

View File

@@ -51,6 +51,9 @@ jobs:
- name: Build (mshv)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (sev_snp)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (mshv + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

View File

@@ -101,6 +101,14 @@ jobs:
command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (sev_snp)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
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 --no-default-features --tests --examples --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (kvm + tdx)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
uses: actions-rs/cargo@v1
@@ -111,3 +119,12 @@ jobs:
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"
typos:
if: github.event_name == 'pull_request'
name: Typos / Spellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Executes "typos ."
- uses: crate-ci/typos@v1.16.11

21
.typos.toml Normal file
View File

@@ -0,0 +1,21 @@
# Configuration for https://github.com/crate-ci/typos
[files]
extend-exclude = [
"hypervisor/src/kvm/x86_64/mod.rs",
"resources/linux-config-*",
]
[default.extend-words]
ba = "ba"
CLASSE = "CLASSE"
conectix = "conectix"
Dake = "Dake"
EXTINT = "EXTINT"
INOUT = "INOUT"
liness = "liness"
outout = "outout"
[default.extend-identifiers]
fo = "fo"
fpr = "fpr"

View File

@@ -5,7 +5,7 @@ License](https://opensource.org/licenses/Apache-2.0) and the [BSD 3
Clause](https://opensource.org/licenses/BSD-3-Clause) license. Individual files
contain details of their licensing and changes to that file are under the same
license unless the contribution changes the license of the file. When importing
code from a third party project (e.g. Firecracker or CrosVM) please respect the
code from a third party project (e.g. Firecracker or crosvm) please respect the
license of those projects.
New code should be under the [Apache v2

296
Cargo.lock generated
View File

@@ -5,9 +5,9 @@ version = 3
[[package]]
name = "acpi_tables"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#05a609136387cc1cc9b499cee4320020325c263f"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#1029d22777f07b04849234bbe756da34a6df2913"
dependencies = [
"zerocopy",
"zerocopy 0.6.1",
]
[[package]]
@@ -36,9 +36,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.71"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "api_client"
@@ -133,7 +133,7 @@ dependencies = [
"async-lock",
"async-task",
"concurrent-queue",
"fastrand",
"fastrand 1.9.0",
"futures-lite",
"slab",
]
@@ -164,7 +164,7 @@ dependencies = [
"log",
"parking",
"polling",
"rustix",
"rustix 0.37.21",
"slab",
"socket2",
"waker-fn",
@@ -192,7 +192,7 @@ dependencies = [
"cfg-if",
"event-listener",
"futures-lite",
"rustix",
"rustix 0.37.21",
"signal-hook",
"windows-sys 0.48.0",
]
@@ -205,7 +205,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -216,13 +216,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae"
[[package]]
name = "async-trait"
version = "0.1.71"
version = "0.1.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -314,7 +314,7 @@ dependencies = [
"async-lock",
"async-task",
"atomic-waker",
"fastrand",
"fastrand 1.9.0",
"futures-lite",
"log",
]
@@ -333,9 +333,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.79"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
@@ -345,7 +348,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cloud-hypervisor"
version = "34.0.0"
version = "35.1.0"
dependencies = [
"anyhow",
"api_client",
@@ -385,18 +388,18 @@ dependencies = [
[[package]]
name = "cpufeatures"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
dependencies = [
"libc",
]
[[package]]
name = "crc32c"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e"
checksum = "d8f48d60e5b4d2c53d5c2b1d8a58c849a70ae5e5509b08a48d047e3b65714a74"
dependencies = [
"rustc_version",
]
@@ -428,9 +431,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core",
"darling_macro",
@@ -438,27 +441,27 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
name = "darling_macro"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -562,7 +565,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -621,6 +624,7 @@ version = "0.1.0"
dependencies = [
"flume",
"libc",
"once_cell",
"serde",
"serde_json",
]
@@ -634,6 +638,12 @@ dependencies = [
"instant",
]
[[package]]
name = "fastrand"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
[[package]]
name = "fdt"
version = "0.1.5"
@@ -713,7 +723,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [
"fastrand",
"fastrand 1.9.0",
"futures-core",
"futures-io",
"memchr",
@@ -730,7 +740,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -915,9 +925,9 @@ dependencies = [
[[package]]
name = "io-uring"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7b36074613a723279637061b40db993208908a94f10ccb14436ce735bc0f57"
checksum = "141a0f4546a50b2ed637c7a6df0d7dff45c9f41523254996764461c8ae0d9424"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -934,13 +944,12 @@ dependencies = [
[[package]]
name = "is-terminal"
version = "0.4.7"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"rustix 0.38.8",
"windows-sys 0.48.0",
]
@@ -987,9 +996,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.144"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libssh2-sys"
@@ -1007,9 +1016,9 @@ dependencies = [
[[package]]
name = "libz-sys"
version = "1.1.9"
version = "1.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
dependencies = [
"cc",
"libc",
@@ -1019,9 +1028,9 @@ dependencies = [
[[package]]
name = "linux-loader"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3adb7b28e189741eca3b1a4a27de0bf15e0907c9d4b0c74bd2d7d84ef72e08"
checksum = "1db6a725c8000971f83fa93ed7ee1b600e55a1471a2a653379d3c84f72effdcf"
dependencies = [
"vm-memory",
]
@@ -1032,6 +1041,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "lock_api"
version = "0.4.10"
@@ -1075,7 +1090,7 @@ dependencies = [
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#b538bf89e50be83b6fa9ab1896727ff61e02fa13"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#0d0fdcd50ea10c1b4777f9a958873fc848a5b7bb"
dependencies = [
"libc",
"vmm-sys-util",
@@ -1103,19 +1118,19 @@ dependencies = [
[[package]]
name = "mshv-bindings"
version = "0.1.1"
source = "git+https://github.com/rust-vmm/mshv?branch=main#a45fbeb4a3930a2d17142e5687fe2f667c2df529"
source = "git+https://github.com/rust-vmm/mshv?branch=main#c5a60508595dc504da469b89102b8b49e91714a9"
dependencies = [
"libc",
"serde",
"serde_derive",
"vmm-sys-util",
"zerocopy",
"zerocopy 0.7.1",
]
[[package]]
name = "mshv-ioctls"
version = "0.1.1"
source = "git+https://github.com/rust-vmm/mshv?branch=main#a45fbeb4a3930a2d17142e5687fe2f667c2df529"
source = "git+https://github.com/rust-vmm/mshv?branch=main#c5a60508595dc504da469b89102b8b49e91714a9"
dependencies = [
"libc",
"mshv-bindings",
@@ -1165,15 +1180,14 @@ dependencies = [
[[package]]
name = "nix"
version = "0.26.2"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
"memoffset",
"static_assertions",
]
[[package]]
@@ -1208,18 +1222,18 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "openssl-src"
version = "111.26.0+1.1.1u"
version = "300.1.3+3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.90"
version = "0.9.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
dependencies = [
"cc",
"libc",
@@ -1361,14 +1375,14 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
[[package]]
name = "pin-utils"
@@ -1384,9 +1398,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "pnet"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd959a8268165518e2bf5546ba84c7b3222744435616381df3c456fe8d983576"
checksum = "130c5b738eeda2dc5796fe2671e49027e6935e817ab51b930a36ec9e6a206a64"
dependencies = [
"ipnetwork",
"pnet_base",
@@ -1398,18 +1412,18 @@ dependencies = [
[[package]]
name = "pnet_base"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872e46346144ebf35219ccaa64b1dffacd9c6f188cd7d012bd6977a2a838f42e"
checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c"
dependencies = [
"no-std-net",
]
[[package]]
name = "pnet_datalink"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c302da22118d2793c312a35fb3da6846cb0fab6c3ad53fd67e37809b06cdafce"
checksum = "ad5854abf0067ebbd3967f7d45ebc8976ff577ff0c7bd101c4973ae3c70f98fe"
dependencies = [
"ipnetwork",
"libc",
@@ -1420,30 +1434,30 @@ dependencies = [
[[package]]
name = "pnet_macros"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a780e80005c2e463ec25a6e9f928630049a10b43945fea83207207d4a7606f4"
checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804"
dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 1.0.109",
"syn 2.0.31",
]
[[package]]
name = "pnet_macros_support"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d932134f32efd7834eb8b16d42418dac87086347d1bc7d142370ef078582bc"
checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56"
dependencies = [
"pnet_base",
]
[[package]]
name = "pnet_packet"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bde678bbd85cb1c2d99dc9fc596e57f03aa725f84f3168b0eaf33eeccb41706"
checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba"
dependencies = [
"glob",
"pnet_base",
@@ -1453,9 +1467,9 @@ dependencies = [
[[package]]
name = "pnet_sys"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf7a58b2803d818a374be9278a1fe8f88fce14b936afbe225000cfcd9c73f16"
checksum = "417c0becd1b573f6d544f73671070b039051e5ad819cc64aa96377b536128d00"
dependencies = [
"libc",
"winapi",
@@ -1463,9 +1477,9 @@ dependencies = [
[[package]]
name = "pnet_transport"
version = "0.33.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "813d1c0e4defbe7ee22f6fe1755f122b77bfb5abe77145b1b5baaf463cab9249"
checksum = "2637e14d7de974ee2f74393afccbc8704f3e54e6eb31488715e72481d1662cc3"
dependencies = [
"libc",
"pnet_base",
@@ -1507,18 +1521,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.63"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.29"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@@ -1605,9 +1619,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.3.3"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
dependencies = [
"aho-corasick",
"memchr",
@@ -1616,9 +1630,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "remain"
@@ -1628,7 +1642,7 @@ checksum = "bce3a7139d2ee67d07538ee5dba997364fbc243e7e7143e96eb830c74bfaa082"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -1662,7 +1676,20 @@ dependencies = [
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"linux-raw-sys 0.3.8",
"windows-sys 0.48.0",
]
[[package]]
name = "rustix"
version = "0.38.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
dependencies = [
"bitflags 2.3.3",
"errno",
"libc",
"linux-raw-sys 0.4.5",
"windows-sys 0.48.0",
]
@@ -1689,35 +1716,35 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.17"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.164"
version = "1.0.168"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
checksum = "d614f89548720367ded108b3c843be93f3a341e22d5674ca0dd5cd57f34926af"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.164"
version = "1.0.168"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
checksum = "d4fe589678c688e44177da4f27152ee2d190757271dc7f1d5b6b9f68d869d641"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
name = "serde_json"
version = "1.0.96"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
dependencies = [
"itoa",
"ryu",
@@ -1732,7 +1759,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -1754,7 +1781,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -1802,9 +1829,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "socket2"
@@ -1862,9 +1889,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.23"
version = "2.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
dependencies = [
"proc-macro2",
"quote",
@@ -1883,15 +1910,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.5.0"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
dependencies = [
"cfg-if",
"fastrand",
"fastrand 2.0.0",
"redox_syscall 0.3.5",
"rustix",
"windows-sys 0.45.0",
"rustix 0.38.8",
"windows-sys 0.48.0",
]
[[package]]
@@ -1935,7 +1962,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -2005,7 +2032,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
]
[[package]]
@@ -2090,7 +2117,7 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#89f8e77dd1a2829197ecde65b686bafcc8a1def4"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
dependencies = [
"vmm-sys-util",
]
@@ -2098,7 +2125,7 @@ dependencies = [
[[package]]
name = "vfio-ioctls"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#89f8e77dd1a2829197ecde65b686bafcc8a1def4"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -2116,7 +2143,7 @@ dependencies = [
[[package]]
name = "vfio_user"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#eef6bec4d421f08ed1688fe67c5ea33aabbf5069"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#2d96b90a7279547356ad8f83aaa3115ad5497302"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -2132,8 +2159,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.7.0"
source = "git+https://github.com/rust-vmm/vhost?branch=main#bdc6f2ab2b3dbd3b9574100ac641a2f8e9667400"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -2143,9 +2171,9 @@ dependencies = [
[[package]]
name = "vhost-user-backend"
version = "0.9.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d3b7affe04f61d19b03c5db823287855789b687218fec139699a0c7f7f2790"
checksum = "ab069cdedaf18a0673766eb0a07a0f4ee3ed1b8e17fbfe4aafe5b988e2de1d01"
dependencies = [
"libc",
"log",
@@ -2195,9 +2223,9 @@ dependencies = [
[[package]]
name = "virtio-bindings"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9084faf91b9aa9676ae2cac8f1432df2839d9566e6f19f29dbc13a8b831dff"
checksum = "c18d7b74098a946470ea265b5bacbbf877abc3373021388454de0d47735a5b98"
[[package]]
name = "virtio-devices"
@@ -2235,9 +2263,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91aebb1df33db33cbf04d4c2445e4f78d0b0c8e65acfd16a4ee95ef63ca252f8"
checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f"
dependencies = [
"log",
"virtio-bindings",
@@ -2274,12 +2302,13 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#77212bd0d62913e445c
[[package]]
name = "vm-memory"
version = "0.11.0"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6ea57fe00f9086c59eeeb68e102dd611686bc3c28520fa465996d4d4bdce07"
checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b"
dependencies = [
"arc-swap",
"libc",
"thiserror",
"winapi",
]
@@ -2316,9 +2345,11 @@ dependencies = [
"bitflags 2.3.3",
"block",
"blocking",
"cfg-if",
"devices",
"epoll",
"event_monitor",
"flume",
"futures",
"gdbstub",
"gdbstub_arch",
@@ -2352,7 +2383,7 @@ dependencies = [
"vm-virtio",
"vmm-sys-util",
"zbus",
"zerocopy",
"zerocopy 0.6.1",
]
[[package]]
@@ -2409,7 +2440,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
"wasm-bindgen-shared",
]
@@ -2431,7 +2462,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.31",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -2697,7 +2728,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236"
dependencies = [
"byteorder",
"zerocopy-derive",
"zerocopy-derive 0.3.2",
]
[[package]]
name = "zerocopy"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f00a66029e63d181fa590cc5694cf2afbc0974a4604824e80017b1789f99c07"
dependencies = [
"byteorder",
"zerocopy-derive 0.7.1",
]
[[package]]
@@ -2711,6 +2752,17 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c682f46403e5d567cb27b79f6279c145759528ba9450fe371f43b921b452bd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.31",
]
[[package]]
name = "zvariant"
version = "3.15.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "34.0.0"
version = "35.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -29,25 +29,25 @@ strip = false
debug = true
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
api_client = { path = "api_client" }
argh = "0.1.9"
dhat = { version = "0.3.2", optional = true }
epoll = "4.3.3"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.139"
libc = "0.2.147"
log = { version = "0.4.17", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.3.0"
serde_json = "1.0.96"
serde_json = "1.0.107"
signal-hook = "0.3.17"
thiserror = "1.0.40"
tpm = { path = "tpm"}
tracer = { path = "tracer" }
vmm = { path = "vmm" }
vmm-sys-util = "0.11.0"
vm-memory = "0.11.0"
vm-memory = "0.12.2"
zbus = { version = "3.11.1", optional = true }
# List of patched crates
@@ -55,13 +55,12 @@ zbus = { version = "3.11.1", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx" }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
vhost = { git = "https://github.com/rust-vmm/vhost", branch = "main" }
[dev-dependencies]
dirs = "5.0.0"
net_util = { path = "net_util" }
once_cell = "1.18.0"
serde_json = "1.0.96"
serde_json = "1.0.107"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
@@ -73,6 +72,7 @@ guest_debug = ["vmm/guest_debug"]
io_uring = ["vmm/io_uring"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
sev_snp = ["vmm/sev_snp", "mshv"]
tdx = ["vmm/tdx"]
tracing = ["vmm/tracing", "tracer/tracing"]

292
Jenkinsfile vendored
View File

@@ -22,7 +22,7 @@ pipeline {
steps {
script {
runWorkers = false
echo 'No changes requring a build'
echo 'No changes requiring a build'
}
}
}
@@ -142,7 +142,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration'
sh 'scripts/dev_cli.sh tests --integration -- -- --skip common_parallel::test_vfio'
}
}
stage('Run live-migration integration tests') {
@@ -151,7 +151,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration-live-migration --integration -- -- --skip live_migration::live_migration_parallel::test_live_upgrade_watchdog --skip live_migration::live_migration_parallel::test_live_upgrade_watchdog_local'
sh 'scripts/dev_cli.sh tests --integration-live-migration'
}
}
stage('Run integration tests for musl') {
@@ -160,7 +160,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration --libc musl'
sh 'scripts/dev_cli.sh tests --integration --libc musl -- -- --skip common_parallel::test_vfio'
}
}
stage('Run live-migration integration tests for musl') {
@@ -169,7 +169,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration-live-migration --libc musl -- -- --skip live_migration::live_migration_parallel::test_live_upgrade_watchdog --skip live_migration::live_migration_parallel::test_live_upgrade_watchdog_local'
sh 'scripts/dev_cli.sh tests --integration-live-migration --libc musl'
}
}
}
@@ -207,7 +207,7 @@ pipeline {
}
stage('Install azure-cli') {
steps {
installAzureCli('bionic', 'arm64')
installAzureCli('focal', 'arm64')
}
}
stage('Download Windows image') {
@@ -295,146 +295,146 @@ pipeline {
}
}
}
// stage('Worker build - Metrics') {
// agent { node { label 'jammy-metrics' } }
// when {
// branch 'main'
// beforeAgent true
// expression {
// return runWorkers
// }
// }
// environment {
// METRICS_PUBLISH_KEY = credentials('52e0945f-ce7a-43d1-87af-67d1d87cc40f')
// }
// stages {
// stage('Checkout') {
// steps {
// checkout scm
// }
// }
// stage('Run metrics tests') {
// options {
// timeout(time: 1, unit: 'HOURS')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --metrics -- -- --report-file /root/workloads/metrics.json'
// }
// }
// stage('Upload metrics report') {
// steps {
// sh 'curl -X PUT https://cloud-hypervisor-metrics.azurewebsites.net/api/publishmetrics -H "x-functions-key: $METRICS_PUBLISH_KEY" -T ~/workloads/metrics.json'
// }
// }
// }
// }
// stage('Worker build - Rate Limiter') {
// agent { node { label 'focal-metrics' } }
// when {
// branch 'main'
// beforeAgent true
// expression {
// return runWorkers
// }
// }
// stages {
// stage('Checkout') {
// steps {
// checkout scm
// }
// }
// stage('Run rate-limiter integration tests') {
// options {
// timeout(time: 10, unit: 'MINUTES')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --integration-rate-limiter'
// }
// }
// }
// }
// stage('Worker build - SGX') {
// agent { node { label 'jammy-sgx' } }
// when {
// beforeAgent true
// allOf {
// branch 'main'
// expression {
// return runWorkers
// }
// }
// }
// stages {
// stage('Checkout') {
// steps {
// checkout scm
// }
// }
// stage('Run SGX integration tests') {
// options {
// timeout(time: 1, unit: 'HOURS')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --integration-sgx'
// }
// }
// stage('Run SGX integration tests for musl') {
// options {
// timeout(time: 1, unit: 'HOURS')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --integration-sgx --libc musl'
// }
// }
// }
// post {
// always {
// sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
// deleteDir()
// }
// }
// }
// stage('Worker build - VFIO') {
// agent { node { label 'jammy-vfio' } }
// when {
// beforeAgent true
// allOf {
// branch 'main'
// expression {
// return runWorkers
// }
// }
// }
// stages {
// stage('Checkout') {
// steps {
// checkout scm
// }
// }
// stage('Run VFIO integration tests') {
// options {
// timeout(time: 1, unit: 'HOURS')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --integration-vfio'
// }
// }
// stage('Run VFIO integration tests for musl') {
// options {
// timeout(time: 1, unit: 'HOURS')
// }
// steps {
// sh 'scripts/dev_cli.sh tests --integration-vfio --libc musl'
// }
// }
// }
// post {
// always {
// sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
// deleteDir()
// }
// }
// }
stage('Worker build - Metrics') {
agent { node { label 'jammy-metrics' } }
when {
branch 'main'
beforeAgent true
expression {
return runWorkers
}
}
environment {
METRICS_PUBLISH_KEY = credentials('52e0945f-ce7a-43d1-87af-67d1d87cc40f')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run metrics tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --metrics -- -- --report-file /root/workloads/metrics.json'
}
}
stage('Upload metrics report') {
steps {
sh 'curl -X PUT https://cloud-hypervisor-metrics.azurewebsites.net/api/publishmetrics -H "x-functions-key: $METRICS_PUBLISH_KEY" -T ~/workloads/metrics.json'
}
}
}
}
stage('Worker build - Rate Limiter') {
agent { node { label 'focal-metrics' } }
when {
branch 'main'
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run rate-limiter integration tests') {
options {
timeout(time: 10, unit: 'MINUTES')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-rate-limiter'
}
}
}
}
stage('Worker build - SGX') {
agent { node { label 'jammy-sgx' } }
when {
beforeAgent true
allOf {
branch 'main'
expression {
return runWorkers
}
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run SGX integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-sgx'
}
}
stage('Run SGX integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-sgx --libc musl'
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage('Worker build - VFIO') {
agent { node { label 'jammy-vfio' } }
when {
beforeAgent true
allOf {
branch 'main'
expression {
return runWorkers
}
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run VFIO integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-vfio'
}
}
stage('Run VFIO integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-vfio --libc musl'
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
}
}
}

View File

@@ -6,21 +6,22 @@ edition = "2021"
[features]
default = []
sev_snp = []
tdx = []
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.139"
linux-loader = { version = "0.9.0", features = ["elf", "bzimage", "pe"] }
libc = "0.2.147"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] }
log = "0.4.17"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde = { version = "1.0.168", features = ["rc", "derive"] }
thiserror = "1.0.40"
uuid = "1.3.4"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-bitmap"] }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }

View File

@@ -98,7 +98,7 @@ pub enum CacheLevel {
L3 = 3,
}
/// NOTE: CACHE SIZE file directory example,
/// NOTE: cache size file directory example,
/// "/sys/devices/system/cpu/cpu0/cache/index0/size".
pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
@@ -111,7 +111,7 @@ pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
error!("File: {} not exist.", file_directory);
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
@@ -132,7 +132,7 @@ pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
}
}
/// NOTE: CACHE COHERENCY LINE SIZE file directory example,
/// NOTE: coherency_line_size file directory example,
/// "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size".
pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
@@ -145,7 +145,7 @@ pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
error!("File: {} not exist.", file_directory);
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
@@ -155,7 +155,7 @@ pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
}
}
/// NOTE: CACHE NUMBER OF SETS file directory example,
/// NOTE: number_of_sets file directory example,
/// "/sys/devices/system/cpu/cpu0/cache/index0/number_of_sets".
pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
@@ -168,7 +168,7 @@ pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
let file_path = Path::new(&file_directory);
if !file_path.exists() {
error!("File: {} not exist.", file_directory);
warn!("File: {} does not exist.", file_directory);
0
} else {
info!("File: {} exist.", file_directory);
@@ -178,6 +178,41 @@ pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
}
}
/// NOTE: shared_cpu_list file directory example,
/// "/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list".
pub fn get_cache_shared(cache_level: CacheLevel) -> bool {
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
let mut result = true;
match cache_level {
CacheLevel::L1D | CacheLevel::L1I => result = false,
CacheLevel::L2 => file_directory += "/index2/shared_cpu_list",
CacheLevel::L3 => file_directory += "/index3/shared_cpu_list",
}
if !result {
return false;
}
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() {
result = false;
} else {
result = src.contains('-') || src.contains(',');
}
}
result
}
/// Creates the flattened device tree for this aarch64 VM.
#[allow(clippy::too_many_arguments)]
pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHasher>(
@@ -255,6 +290,8 @@ 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();
// Add cache info.
// L1 Data Cache Info.
@@ -277,10 +314,14 @@ fn create_cpu_nodes(
let mut l3_cache_line_size: u32 = 0;
let mut l3_cache_sets: u32 = 0;
// Cache Shared Info.
let mut l2_cache_shared: bool = false;
let mut l3_cache_shared: bool = false;
let cache_path = Path::new("/sys/devices/system/cpu/cpu0/cache");
let cache_exist: bool = cache_path.exists();
if !cache_exist {
error!("cache sysfs system does not exist.");
warn!("cache sysfs system does not exist.");
} else {
info!("cache sysfs system exists.");
// L1 Data Cache Info.
@@ -302,6 +343,14 @@ fn create_cpu_nodes(
l3_cache_size = get_cache_size(CacheLevel::L3);
l3_cache_line_size = get_cache_coherency_line_size(CacheLevel::L3);
l3_cache_sets = get_cache_number_of_sets(CacheLevel::L3);
// Cache Shared Info.
if l2_cache_size != 0 {
l2_cache_shared = get_cache_shared(CacheLevel::L2);
}
if l3_cache_size != 0 {
l3_cache_shared = get_cache_shared(CacheLevel::L3);
}
}
for (cpu_id, mpidr) in vcpu_mpidr.iter().enumerate().take(num_cpus) {
@@ -318,21 +367,6 @@ fn create_cpu_nodes(
fdt.property_u32("reg", (mpidr & 0x7FFFFF) as u32)?;
fdt.property_u32("phandle", cpu_id as u32 + FIRST_VCPU_PHANDLE)?;
if cache_exist && l1_d_cache_size != 0 && l1_i_cache_size != 0 {
// Add cache info.
fdt.property_u32("d-cache-size", l1_d_cache_size)?;
fdt.property_u32("d-cache-line-size", l1_d_cache_line_size)?;
fdt.property_u32("d-cache-sets", l1_d_cache_sets)?;
fdt.property_u32("i-cache-size", l1_i_cache_size)?;
fdt.property_u32("i-cache-line-size", l1_i_cache_line_size)?;
fdt.property_u32("i-cache-sets", l1_i_cache_sets)?;
if l2_cache_size != 0 {
fdt.property_u32("next-level-cache", L2_CACHE_PHANDLE)?;
}
}
// Add `numa-node-id` property if there is any numa config.
if numa_nodes.len() > 1 {
for numa_node_idx in 0..numa_nodes.len() {
@@ -343,37 +377,89 @@ fn create_cpu_nodes(
}
}
if cache_exist && l1_d_cache_size != 0 && l1_i_cache_size != 0 {
// Add cache info.
fdt.property_u32("d-cache-size", l1_d_cache_size)?;
fdt.property_u32("d-cache-line-size", l1_d_cache_line_size)?;
fdt.property_u32("d-cache-sets", l1_d_cache_sets)?;
fdt.property_u32("i-cache-size", l1_i_cache_size)?;
fdt.property_u32("i-cache-line-size", l1_i_cache_line_size)?;
fdt.property_u32("i-cache-sets", l1_i_cache_sets)?;
if l2_cache_size != 0 && !l2_cache_shared {
fdt.property_u32(
"next-level-cache",
cpu_id as u32 + max_cpus + FIRST_VCPU_PHANDLE + L2_CACHE_PHANDLE,
)?;
let l2_cache_name = "l2-cache0";
let l2_cache_node = fdt.begin_node(l2_cache_name)?;
// PHANDLE is used to mark device node, and PHANDLE is unique. To avoid phandle
// conflicts with other device nodes, consider the previous CPU PHANDLE, so the
// CPU L2 cache PHANDLE must start from the largest CPU PHANDLE plus 1.
fdt.property_u32(
"phandle",
cpu_id as u32 + max_cpus + FIRST_VCPU_PHANDLE + L2_CACHE_PHANDLE,
)?;
fdt.property_string("compatible", "cache")?;
fdt.property_u32("cache-size", l2_cache_size)?;
fdt.property_u32("cache-line-size", l2_cache_line_size)?;
fdt.property_u32("cache-sets", l2_cache_sets)?;
fdt.property_u32("cache-level", 2)?;
if l3_cache_size != 0 && l3_cache_shared {
let package_id: u32 = cpu_id as u32 / cores_per_package as u32;
fdt.property_u32(
"next-level-cache",
package_id
+ num_cpus as u32
+ max_cpus
+ FIRST_VCPU_PHANDLE
+ L2_CACHE_PHANDLE
+ L3_CACHE_PHANDLE,
)?;
}
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)?;
}
if cache_exist && l2_cache_size != 0 {
let l2_cache_name = "l2-cache0";
let l2_cache_node = fdt.begin_node(l2_cache_name)?;
fdt.property_u32("phandle", L2_CACHE_PHANDLE)?;
fdt.property_string("compatible", "cache")?;
fdt.property_u32("cache-size", l2_cache_size)?;
fdt.property_u32("cache-line-size", l2_cache_line_size)?;
fdt.property_u32("cache-sets", l2_cache_sets)?;
fdt.property_u32("cache-level", 2)?;
if cache_exist && l3_cache_size != 0 && !l2_cache_shared && l3_cache_shared {
let mut i: u32 = 0;
while i < packages.into() {
let l3_cache_name = "l3-cache0";
let l3_cache_node = fdt.begin_node(l3_cache_name)?;
// ARM L3 cache is generally shared within the package (socket), so the
// L3 cache node pointed to by the CPU in the package has the same L3
// cache PHANDLE. The L3 cache phandle must start from the largest L2
// cache PHANDLE plus 1 to avoid duplication.
fdt.property_u32(
"phandle",
i + num_cpus as u32
+ max_cpus
+ FIRST_VCPU_PHANDLE
+ L2_CACHE_PHANDLE
+ L3_CACHE_PHANDLE,
)?;
if l3_cache_size != 0 {
fdt.property_u32("next-level-cache", L3_CACHE_PHANDLE)?;
fdt.property_string("compatible", "cache")?;
fdt.property_null("cache-unified")?;
fdt.property_u32("cache-size", l3_cache_size)?;
fdt.property_u32("cache-line-size", l3_cache_line_size)?;
fdt.property_u32("cache-sets", l3_cache_sets)?;
fdt.property_u32("cache-level", 3)?;
fdt.end_node(l3_cache_node)?;
i += 1;
}
fdt.end_node(l2_cache_node)?;
}
if cache_exist && l3_cache_size != 0 {
let l3_cache_name = "l3-cache0";
let l3_cache_node = fdt.begin_node(l3_cache_name)?;
fdt.property_u32("phandle", L3_CACHE_PHANDLE)?;
fdt.property_string("compatible", "cache")?;
fdt.property_null("cache-unified")?;
fdt.property_u32("cache-size", l3_cache_size)?;
fdt.property_u32("cache-line-size", l3_cache_line_size)?;
fdt.property_u32("cache-sets", l3_cache_sets)?;
fdt.property_u32("cache-level", 3)?;
fdt.end_node(l3_cache_node)?;
}
if let Some(topology) = vcpu_topology {

View File

@@ -60,7 +60,7 @@ pub const _NSIG: i32 = 65;
/// is to be used to configure the guest initial state.
pub struct EntryPoint {
/// Address in guest memory where the guest must start execution
pub entry_addr: Option<GuestAddress>,
pub entry_addr: GuestAddress,
}
const E820_RAM: u32 = 1;
@@ -811,12 +811,10 @@ pub fn configure_vcpu(
regs::setup_msrs(vcpu).map_err(Error::MsrsConfiguration)?;
if let Some((kernel_entry_point, guest_memory)) = boot_setup {
if let Some(entry_addr) = kernel_entry_point.entry_addr {
// Safe to unwrap because this method is called after the VM is configured
regs::setup_regs(vcpu, entry_addr.raw_value()).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&guest_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
}
regs::setup_regs(vcpu, kernel_entry_point.entry_addr.raw_value())
.map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&guest_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
}
interrupts::set_lint(vcpu).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
Ok(())

View File

@@ -98,7 +98,7 @@ fn tdvf_descriptor_offset(file: &mut File) -> Result<(SeekFrom, bool), TdvfError
// We start after the footer GUID and the table length.
let mut offset = table_size - 18;
debug!("Parsing GUIDed structure");
debug!("Parsing GUID structure");
while offset >= 18 {
let entry_uuid = Uuid::from_slice_le(&table[offset - 16..offset])
.map_err(TdvfError::UuidCreation)?;

View File

@@ -10,18 +10,18 @@ io_uring = ["dep:io-uring"]
[dependencies]
byteorder = "1.4.3"
crc32c = "0.6.3"
io-uring = { version = "0.6.0", optional = true }
libc = "0.2.139"
crc32c = "0.6.4"
io-uring = { version = "0.6.1", optional = true }
libc = "0.2.147"
log = "0.4.17"
remain = "0.2.11"
smallvec = "1.10.0"
smallvec = "1.11.0"
thiserror = "1.0.40"
uuid = { version = "1.3.4", features = ["v4"] }
versionize = "0.1.10"
versionize_derive = "0.1.4"
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.8.0"
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.9.0"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"

View File

@@ -2,12 +2,9 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use libc::{ioctl, S_IFBLK, S_IFMT};
use std::fs::File;
use std::os::unix::io::AsRawFd;
use crate::DiskTopology;
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::{ioctl_io_nr, ioctl_ioc_nr};
#[derive(Error, Debug)]
pub enum DiskFileError {
@@ -19,88 +16,6 @@ pub enum DiskFileError {
NewAsyncIo(#[source] std::io::Error),
}
#[derive(Debug)]
pub struct DiskTopology {
pub logical_block_size: u64,
pub physical_block_size: u64,
pub minimum_io_size: u64,
pub optimal_io_size: u64,
}
impl Default for DiskTopology {
fn default() -> Self {
Self {
logical_block_size: 512,
physical_block_size: 512,
minimum_io_size: 512,
optimal_io_size: 0,
}
}
}
ioctl_io_nr!(BLKSSZGET, 0x12, 104);
ioctl_io_nr!(BLKPBSZGET, 0x12, 123);
ioctl_io_nr!(BLKIOMIN, 0x12, 120);
ioctl_io_nr!(BLKIOOPT, 0x12, 121);
enum BlockSize {
LogicalBlock,
PhysicalBlock,
MinimumIo,
OptimalIo,
}
impl DiskTopology {
fn is_block_device(f: &mut File) -> std::io::Result<bool> {
let mut stat = std::mem::MaybeUninit::<libc::stat>::uninit();
// SAFETY: FFI call with a valid fd and buffer
let ret = unsafe { libc::fstat(f.as_raw_fd(), stat.as_mut_ptr()) };
if ret != 0 {
return Err(std::io::Error::last_os_error());
}
// SAFETY: stat is valid at this point
let is_block = unsafe { (*stat.as_ptr()).st_mode & S_IFMT == S_IFBLK };
Ok(is_block)
}
// libc::ioctl() takes different types on different architectures
fn query_block_size(f: &mut File, block_size_type: BlockSize) -> std::io::Result<u64> {
let mut block_size = 0;
// SAFETY: FFI call with correct arguments
let ret = unsafe {
ioctl(
f.as_raw_fd(),
match block_size_type {
BlockSize::LogicalBlock => BLKSSZGET(),
BlockSize::PhysicalBlock => BLKPBSZGET(),
BlockSize::MinimumIo => BLKIOMIN(),
BlockSize::OptimalIo => BLKIOOPT(),
} as _,
&mut block_size,
)
};
if ret != 0 {
return Err(std::io::Error::last_os_error());
};
Ok(block_size)
}
pub fn probe(f: &mut File) -> std::io::Result<Self> {
if !Self::is_block_device(f)? {
return Ok(DiskTopology::default());
}
Ok(DiskTopology {
logical_block_size: Self::query_block_size(f, BlockSize::LogicalBlock)?,
physical_block_size: Self::query_block_size(f, BlockSize::PhysicalBlock)?,
minimum_io_size: Self::query_block_size(f, BlockSize::MinimumIo)?,
optimal_io_size: Self::query_block_size(f, BlockSize::OptimalIo)?,
})
}
}
pub type DiskFileResult<T> = std::result::Result<T, DiskFileError>;
pub trait DiskFile: Send {

View File

@@ -35,6 +35,7 @@ use crate::qcow::{QcowFile, RawFile};
use crate::vhdx::{Vhdx, VhdxError};
#[cfg(feature = "io_uring")]
use io_uring::{opcode, IoUring, Probe};
use libc::{ioctl, S_IFBLK, S_IFMT};
use smallvec::SmallVec;
use std::alloc::{alloc_zeroed, dealloc, Layout};
use std::cmp;
@@ -44,6 +45,7 @@ use std::fmt::Debug;
use std::fs::File;
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::result;
use std::sync::Arc;
@@ -60,6 +62,7 @@ use vm_memory::{
};
use vm_virtio::{AccessPlatform, Translatable};
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::{ioctl_io_nr, ioctl_ioc_nr};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
@@ -113,8 +116,8 @@ fn build_device_id(disk_path: &Path) -> result::Result<String, Error> {
Ok(device_id)
}
pub fn build_disk_image_id(disk_path: &Path) -> Vec<u8> {
let mut default_disk_image_id = vec![0; VIRTIO_BLK_ID_BYTES as usize];
pub fn build_serial(disk_path: &Path) -> Vec<u8> {
let mut default_serial = vec![0; VIRTIO_BLK_ID_BYTES as usize];
match build_device_id(disk_path) {
Err(_) => {
warn!("Could not generate device id. We'll use a default.");
@@ -124,17 +127,17 @@ pub fn build_disk_image_id(disk_path: &Path) -> Vec<u8> {
// This will also zero out any leftover bytes.
let disk_id = m.as_bytes();
let bytes_to_copy = cmp::min(disk_id.len(), VIRTIO_BLK_ID_BYTES as usize);
default_disk_image_id[..bytes_to_copy].clone_from_slice(&disk_id[..bytes_to_copy])
default_serial[..bytes_to_copy].clone_from_slice(&disk_id[..bytes_to_copy])
}
}
default_disk_image_id
default_serial
}
#[derive(Error, Debug)]
pub enum ExecuteError {
#[error("Bad request: {0}")]
BadRequest(Error),
#[error("Falied to flush: {0}")]
#[error("Failed to flush: {0}")]
Flush(io::Error),
#[error("Failed to read: {0}")]
Read(GuestMemoryError),
@@ -327,7 +330,7 @@ impl Request {
disk: &mut T,
disk_nsectors: u64,
mem: &GuestMemoryMmap,
disk_id: &[u8],
serial: &[u8],
) -> result::Result<u32, ExecuteError> {
disk.seek(SeekFrom::Start(self.sector << SECTOR_SHIFT))
.map_err(ExecuteError::Seek)?;
@@ -359,10 +362,10 @@ impl Request {
}
RequestType::Flush => disk.flush().map_err(ExecuteError::Flush)?,
RequestType::GetDeviceId => {
if (*data_len as usize) < disk_id.len() {
if (*data_len as usize) < serial.len() {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
mem.write_slice(disk_id, *data_addr)
mem.write_slice(serial, *data_addr)
.map_err(ExecuteError::Write)?;
}
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
@@ -376,7 +379,7 @@ impl Request {
mem: &GuestMemoryMmap,
disk_nsectors: u64,
disk_image: &mut dyn AsyncIo,
disk_id: &[u8],
serial: &[u8],
user_data: u64,
) -> result::Result<bool, ExecuteError> {
let sector = self.sector;
@@ -403,13 +406,13 @@ impl Request {
let origin_ptr = mem
.get_slice(*data_addr, *data_len as usize)
.map_err(ExecuteError::GetHostAddress)?
.as_ptr();
.ptr_guard();
// Verify the buffer alignment.
// 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 u64) % SECTOR_SIZE != 0 {
let iov_base = if (origin_ptr.as_ptr() as u64) % SECTOR_SIZE != 0 {
let layout =
Layout::from_size_align(*data_len as usize, SECTOR_SIZE as usize).unwrap();
// SAFETY: layout has non-zero size
@@ -425,15 +428,13 @@ impl Request {
if request_type == RequestType::Out {
// SAFETY: destination buffer has been allocated with
// the proper size.
unsafe {
std::ptr::copy(origin_ptr as *const u8, aligned_ptr, *data_len as usize)
};
unsafe { std::ptr::copy(origin_ptr.as_ptr(), aligned_ptr, *data_len as usize) };
}
// Store both origin and aligned pointers for complete_async()
// to process them.
self.aligned_operations.push(AlignedOperation {
origin_ptr: origin_ptr as u64,
origin_ptr: origin_ptr.as_ptr() as u64,
aligned_ptr: aligned_ptr as u64,
size: *data_len as usize,
layout,
@@ -441,7 +442,7 @@ impl Request {
aligned_ptr as *mut libc::c_void
} else {
origin_ptr as *mut libc::c_void
origin_ptr.as_ptr() as *mut libc::c_void
};
let iovec = libc::iovec {
@@ -480,10 +481,10 @@ impl Request {
} else {
return Err(ExecuteError::BadRequest(Error::TooManyDescriptors));
};
if (data_len as usize) < disk_id.len() {
if (data_len as usize) < serial.len() {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
mem.write_slice(disk_id, data_addr)
mem.write_slice(serial, data_addr)
.map_err(ExecuteError::Write)?;
return Ok(false);
}
@@ -728,24 +729,33 @@ pub enum ImageType {
const QCOW_MAGIC: u32 = 0x5146_49fb;
const VHDX_SIGN: u64 = 0x656C_6966_7864_6876;
/// Read a block into memory aligned by the source block size (needed for O_DIRECT)
pub fn read_aligned_block_size(f: &mut File) -> std::io::Result<Vec<u8>> {
let blocksize = DiskTopology::probe(f)?.logical_block_size as usize;
// SAFETY: We are allocating memory that is naturally aligned (size = alignment) and we meet
// requirements for safety from Vec::from_raw_parts() as we are using the global allocator
// and transferring ownership of the memory.
let mut data = unsafe {
Vec::from_raw_parts(
alloc_zeroed(Layout::from_size_align_unchecked(blocksize, blocksize)),
blocksize,
blocksize,
)
};
f.read_exact(&mut data)?;
Ok(data)
}
/// Determine image type through file parsing.
pub fn detect_image_type(f: &mut File) -> std::io::Result<ImageType> {
// We must create a buffer aligned on 512 bytes with a size being a
// multiple of 512 bytes as the file might be opened with O_DIRECT flag.
#[repr(align(512))]
struct Sector {
data: [u8; 512],
}
let mut s = Sector { data: [0; 512] };
f.read_exact(&mut s.data)?;
let block = read_aligned_block_size(f)?;
// Check 4 first bytes to get the header value and determine the image type
let image_type = if u32::from_be_bytes(s.data[0..4].try_into().unwrap()) == QCOW_MAGIC {
let image_type = if u32::from_be_bytes(block[0..4].try_into().unwrap()) == QCOW_MAGIC {
ImageType::Qcow2
} else if vhd::is_fixed_vhd(f)? {
ImageType::FixedVhd
} else if u64::from_le_bytes(s.data[0..8].try_into().unwrap()) == VHDX_SIGN {
} else if u64::from_le_bytes(block[0..8].try_into().unwrap()) == VHDX_SIGN {
ImageType::Vhdx
} else {
ImageType::Raw
@@ -776,3 +786,85 @@ pub fn create_disk_file(mut file: File, direct_io: bool) -> Result<Box<dyn Block
ImageType::Raw => Box::new(RawFile::new(file, direct_io)) as Box<dyn BlockBackend>,
})
}
#[derive(Debug)]
pub struct DiskTopology {
pub logical_block_size: u64,
pub physical_block_size: u64,
pub minimum_io_size: u64,
pub optimal_io_size: u64,
}
impl Default for DiskTopology {
fn default() -> Self {
Self {
logical_block_size: 512,
physical_block_size: 512,
minimum_io_size: 512,
optimal_io_size: 0,
}
}
}
ioctl_io_nr!(BLKSSZGET, 0x12, 104);
ioctl_io_nr!(BLKPBSZGET, 0x12, 123);
ioctl_io_nr!(BLKIOMIN, 0x12, 120);
ioctl_io_nr!(BLKIOOPT, 0x12, 121);
enum BlockSize {
LogicalBlock,
PhysicalBlock,
MinimumIo,
OptimalIo,
}
impl DiskTopology {
fn is_block_device(f: &File) -> std::io::Result<bool> {
let mut stat = std::mem::MaybeUninit::<libc::stat>::uninit();
// SAFETY: FFI call with a valid fd and buffer
let ret = unsafe { libc::fstat(f.as_raw_fd(), stat.as_mut_ptr()) };
if ret != 0 {
return Err(std::io::Error::last_os_error());
}
// SAFETY: stat is valid at this point
let is_block = unsafe { (*stat.as_ptr()).st_mode & S_IFMT == S_IFBLK };
Ok(is_block)
}
// libc::ioctl() takes different types on different architectures
fn query_block_size(f: &File, block_size_type: BlockSize) -> std::io::Result<u64> {
let mut block_size = 0;
// SAFETY: FFI call with correct arguments
let ret = unsafe {
ioctl(
f.as_raw_fd(),
match block_size_type {
BlockSize::LogicalBlock => BLKSSZGET(),
BlockSize::PhysicalBlock => BLKPBSZGET(),
BlockSize::MinimumIo => BLKIOMIN(),
BlockSize::OptimalIo => BLKIOOPT(),
} as _,
&mut block_size,
)
};
if ret != 0 {
return Err(std::io::Error::last_os_error());
};
Ok(block_size)
}
pub fn probe(f: &File) -> std::io::Result<Self> {
if !Self::is_block_device(f)? {
return Ok(DiskTopology::default());
}
Ok(DiskTopology {
logical_block_size: Self::query_block_size(f, BlockSize::LogicalBlock)?,
physical_block_size: Self::query_block_size(f, BlockSize::PhysicalBlock)?,
minimum_io_size: Self::query_block_size(f, BlockSize::MinimumIo)?,
optimal_io_size: Self::query_block_size(f, BlockSize::OptimalIo)?,
})
}
}

View File

@@ -3,8 +3,9 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, DiskTopology,
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
use io_uring::{opcode, squeue, types, IoUring};
use std::fs::File;
use std::io::{Seek, SeekFrom};
@@ -36,7 +37,7 @@ impl DiskFile for RawFileDisk {
}
fn topology(&mut self) -> DiskTopology {
if let Ok(topology) = DiskTopology::probe(&mut self.file) {
if let Ok(topology) = DiskTopology::probe(&self.file) {
topology
} else {
warn!("Unable to get device topology. Using default topology");

View File

@@ -3,8 +3,9 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, DiskTopology,
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
use std::collections::VecDeque;
use std::fs::File;
use std::io::{Seek, SeekFrom};
@@ -33,7 +34,7 @@ impl DiskFile for RawFileDiskSync {
}
fn topology(&mut self) -> DiskTopology {
if let Ok(topology) = DiskTopology::probe(&mut self.file) {
if let Ok(topology) = DiskTopology::probe(&self.file) {
topology
} else {
warn!("Unable to get device topology. Using default topology");

View File

@@ -2,9 +2,10 @@
//
// SPDX-License-Identifier: Apache-2.0
use crate::{read_aligned_block_size, DiskTopology};
use std::convert::TryInto;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::io::{Seek, SeekFrom};
#[derive(Clone, Copy)]
pub struct VhdFooter {
@@ -27,37 +28,33 @@ pub struct VhdFooter {
impl VhdFooter {
pub fn new(file: &mut File) -> std::io::Result<VhdFooter> {
// We must create a buffer aligned on 512 bytes with a size being a
// multiple of 512 bytes as the file might be opened with O_DIRECT flag.
#[repr(align(512))]
struct Sector {
data: [u8; 512],
}
let mut s = Sector { data: [0; 512] };
let blocksize = DiskTopology::probe(file)?.logical_block_size as usize;
// Place the cursor 512 bytes before the end of the file, as this is
// where the footer starts.
file.seek(SeekFrom::End(-512))?;
// Place the cursor in the last block of the file
file.seek(SeekFrom::End(0 - (blocksize as i64)))?;
// Read in the last block
let data = read_aligned_block_size(file)?;
// Fill in the VhdFooter structure
file.read_exact(&mut s.data)?;
// We only care about the last sector
let offset = blocksize - 512;
let sector = &data[offset..];
Ok(VhdFooter {
cookie: u64::from_be_bytes(s.data[0..8].try_into().unwrap()),
features: u32::from_be_bytes(s.data[8..12].try_into().unwrap()),
file_format_version: u32::from_be_bytes(s.data[12..16].try_into().unwrap()),
data_offset: u64::from_be_bytes(s.data[16..24].try_into().unwrap()),
time_stamp: u32::from_be_bytes(s.data[24..28].try_into().unwrap()),
creator_application: u32::from_be_bytes(s.data[28..32].try_into().unwrap()),
creator_version: u32::from_be_bytes(s.data[32..36].try_into().unwrap()),
creator_host_os: u32::from_be_bytes(s.data[36..40].try_into().unwrap()),
original_size: u64::from_be_bytes(s.data[40..48].try_into().unwrap()),
current_size: u64::from_be_bytes(s.data[48..56].try_into().unwrap()),
disk_geometry: u32::from_be_bytes(s.data[56..60].try_into().unwrap()),
disk_type: u32::from_be_bytes(s.data[60..64].try_into().unwrap()),
checksum: u32::from_be_bytes(s.data[64..68].try_into().unwrap()),
unique_id: u128::from_be_bytes(s.data[68..84].try_into().unwrap()),
saved_state: u8::from_be_bytes(s.data[84..85].try_into().unwrap()),
cookie: u64::from_be_bytes(sector[0..8].try_into().unwrap()),
features: u32::from_be_bytes(sector[8..12].try_into().unwrap()),
file_format_version: u32::from_be_bytes(sector[12..16].try_into().unwrap()),
data_offset: u64::from_be_bytes(sector[16..24].try_into().unwrap()),
time_stamp: u32::from_be_bytes(sector[24..28].try_into().unwrap()),
creator_application: u32::from_be_bytes(sector[28..32].try_into().unwrap()),
creator_version: u32::from_be_bytes(sector[32..36].try_into().unwrap()),
creator_host_os: u32::from_be_bytes(sector[36..40].try_into().unwrap()),
original_size: u64::from_be_bytes(sector[40..48].try_into().unwrap()),
current_size: u64::from_be_bytes(sector[48..56].try_into().unwrap()),
disk_geometry: u32::from_be_bytes(sector[56..60].try_into().unwrap()),
disk_type: u32::from_be_bytes(sector[60..64].try_into().unwrap()),
checksum: u32::from_be_bytes(sector[64..68].try_into().unwrap()),
unique_id: u128::from_be_bytes(sector[68..84].try_into().unwrap()),
saved_state: u8::from_be_bytes(sector[84..85].try_into().unwrap()),
})
}

View File

@@ -81,7 +81,7 @@ pub enum VhdxHeaderError {
SeekRegionTableEntries(#[source] io::Error),
#[error("Failed to seek in region table header {0}")]
SeekRegionTableHeader(#[source] io::Error),
#[error("We do not recongize this entry")]
#[error("We do not recognize this entry")]
UnrecognizedRegionEntry,
#[error("Failed to write header {0}")]
WriteHeader(#[source] io::Error),
@@ -305,7 +305,7 @@ impl RegionInfo {
if (entry.required & REGION_ENTRY_REQUIRED) == 1 {
// This implementation doesn't recognize this field.
// Therefore, accoding to the spec, we are throwing an error.
// Therefore, according to the spec, we are throwing an error.
return Err(VhdxHeaderError::UnrecognizedRegionEntry);
}
}
@@ -444,7 +444,7 @@ impl VhdxHeader {
}
}
// Update the provided headers accoding to the spec
// Update the provided headers according to the spec
fn update_headers(
f: &mut File,
header_1: Result<Header>,
@@ -468,7 +468,7 @@ impl VhdxHeader {
}
}
/// Calculates the checksum of a buffer that itself containts its checksum
/// Calculates the checksum of a buffer that itself contains its checksum
/// Therefore, before calculating, the existing checksum is retrieved and the
/// corresponding field is made zero. After the calculation, the existing checksum
/// is put back to the buffer.

View File

@@ -96,7 +96,7 @@ pub struct DiskSpec {
}
impl DiskSpec {
/// Parse all meatadata from the provided file and store info in DiskSpec
/// Parse all metadata from the provided file and store info in DiskSpec
/// structure.
pub fn new(f: &mut File, metadata_region: &RegionTableEntry) -> Result<DiskSpec> {
let mut disk_spec = DiskSpec::default();
@@ -133,7 +133,7 @@ impl DiskSpec {
.map_err(VhdxMetadataError::ReadMetadata)?;
// MUST be at least 1 MiB and not greater than 256 MiB
if disk_spec.block_size < BLOCK_SIZE_MIN && disk_spec.block_size > BLOCK_SIZE_MAX {
if disk_spec.block_size < BLOCK_SIZE_MIN || disk_spec.block_size > BLOCK_SIZE_MAX {
return Err(VhdxMetadataError::InvalidBlockSize);
}

View File

@@ -6,13 +6,13 @@ edition = "2021"
[dependencies]
acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" }
anyhow = "1.0.71"
anyhow = "1.0.75"
arch = { path = "../arch" }
bitflags = "2.3.3"
byteorder = "1.4.3"
event_monitor = { path = "../event_monitor" }
hypervisor = { path = "../hypervisor" }
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
pci = { path = "../pci" }
thiserror = "1.0.40"
@@ -21,7 +21,7 @@ versionize = "0.1.10"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = "0.11.0"
vm-memory = "0.12.2"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = "0.11.0"

View File

@@ -134,7 +134,7 @@ impl Aml for AcpiGedDevice {
&aml::Name::new(
"_CRS".into(),
&aml::ResourceTemplate::new(vec![&aml::AddressSpace::new_memory(
aml::AddressSpaceCachable::NotCacheable,
aml::AddressSpaceCacheable::NotCacheable,
true,
self.address.0,
self.address.0 + GED_DEVICE_ACPI_SIZE as u64 - 1,

View File

@@ -27,7 +27,7 @@ pub const IRQ_LEGACY_BASE: usize = layout::IRQ_BASE as usize;
pub const IRQ_LEGACY_COUNT: usize = 32;
pub const GIC_SNAPSHOT_ID: &str = "gic-v3-its";
// Gic (Generic Interupt Controller) struct provides all the functionality of a
// Gic (Generic Interrupt Controller) struct provides all the functionality of a
// GIC device. It wraps a hypervisor-emulated GIC device (Vgic) provided by the
// `hypervisor` crate.
// Gic struct also implements InterruptController to provide interrupt delivery

View File

@@ -31,7 +31,7 @@ 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.
// Thses registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral.
// 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
@@ -57,7 +57,7 @@ impl fmt::Display for Error {
write!(f, "Could not trigger GPIO interrupt: {e}.")
}
Error::GpioTriggerKeyFailure(key) => {
write!(f, "Invalid GPIO Input key triggerd: {key}.")
write!(f, "Invalid GPIO Input key triggered: {key}.")
}
}
}

View File

@@ -26,6 +26,7 @@ const PVPANIC_VENDOR_ID: u16 = 0x1b36;
const PVPANIC_DEVICE_ID: u16 = 0x0011;
pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2;
pub const PVPANIC_DEVICE_MMIO_ALIGNMENT: u64 = 0x10;
const PVPANIC_PANICKED: u8 = 1 << 0;
const PVPANIC_CRASH_LOADED: u8 = 1 << 1;
@@ -38,9 +39,8 @@ pub enum PvPanicError {
RetrievePciConfigurationState(#[source] anyhow::Error),
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PvPanicSubclass {
enum PvPanicSubclass {
Other = 0x80,
}
@@ -193,7 +193,7 @@ impl PciDevice for PvPanicDevice {
let bar_addr = allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(None, region_size, None)
.allocate_mmio_hole_addresses(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
let bar = PciBarConfiguration::default()

38
docs/amd_sev_snp.md Normal file
View File

@@ -0,0 +1,38 @@
# AMD SEV-SNP
### WARNING
This feature is only currently supported on MSHV.
AMD Secure Encrypted Virtualization & Secure Nested Paging (SEV-SNP) is an AMD
technology designed to add strong memory integrity protection to help prevent
malicious hypervisor-based attacks like data replay, memory-remapping and more
in order to create an isolated execution environment. Here are some useful
links:
* [SNP Homepage] (https://www.amd.com/en/processors/amd-secure-encrypted-virtualization)
more information about SEV-SNP technical aspects, design and specification.
## Cloud Hypervisor support
It is required to use a machine which has enabled support for AMD SEV-SNP in
the BIOS.
On the Cloud Hypervisor side, all you need is to build the project with the
`sev_snp` feature enabled:
```bash
cargo build --no-default-features --features "sev_snp"
```
**Note**
Please note that `sev_snp` cannot be enabled in conjunction with `tdx` feature flag.
You can run a SEV-SNP VM using the following command:
```bash
./cloud-hypervisor \
--platform sev_snp=on \
--cpus boot=1 \
--memory size=1G \
--disk path=ubuntu.img
```

View File

@@ -206,11 +206,14 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1
### D-Bus API
Cloud Hypervisor offers a D-Bus API as an alternative to its REST API. As of
writing this document, the D-Bus API mirrors the functionality of the REST
API and shares the same set of endpoints, meaning that it supports every call
that is supported by the REST API and can be a drop-in replacement since it
also consumes/produces JSON.
Cloud Hypervisor offers a D-Bus API as an alternative to its REST API. This
D-Bus API fully reflects the functionality of the REST API, exposing the
same group of endpoints. It can be a drop-in replacement since it also
consumes/produces JSON.
In addition, the D-Bus API also exposes events from `event-monitor` in the
form of a D-Bus signal to which users can subscribe. For more information,
see [D-Bus API Interface](#d-bus-api-interface).
#### D-Bus API Location and availability
@@ -245,8 +248,23 @@ which in turn can be used to control and manage Cloud Hypervisor.
#### D-Bus API Interface
Please refer to the [REST API](#rest-api) documentation. As previously
mentioned, the D-Bus API currently mirrors the behaviour of the REST API.
Please refer to the [REST API](#rest-api) documentation for everything that
is in common with the REST API. As previously mentioned, the D-Bus API can
be used as a drop-in replacement for the [REST API](#rest-api).
The D-Bus interface also exposes a signal, named `Event`, which is emitted
whenever a new event is published from the `event-monitor` crate. Here is its
definition in XML format:
```xml
<node>
<interface name="org.cloudhypervisor.DBusApi1">
<signal name="Event">
<arg name="event" type="s"/>
</signal>
</interface>
</node>
```
### Command Line Interface

View File

@@ -47,12 +47,15 @@ The custom Linux kernel for the guest can be built with the [TDX Tools](https://
The firmware can be built as follows:
```bash
sudo apt-get update
sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git
git clone https://github.com/tianocore/edk2.git
cd edk2
git checkout 13b97736c876919b9786055829caaa4fa46984b7
git submodule update --init --recursive
make -C BaseTools
source ./edksetup.sh
git submodule update --init --recursive
make -C BaseTools -j `nproc`
build -p OvmfPkg/IntelTdx/IntelTdxX64.dsc -a X64 -t GCC5 -b RELEASE
```

View File

@@ -7,13 +7,13 @@ The target audience of this document is both:
## Control
The number of `-v` parameters passed to the `cloud-hypervisor` binary will determine the log level. Currenly the default is log messages up to `WARN:` (`warn!`) are included by default. The `--log-file` allows the log to be sent to a location other than `stderr`.
The number of `-v` parameters passed to the `cloud-hypervisor` binary will determine the log level. Currently the default is log messages up to `WARN:` (`warn!`) are included by default. The `--log-file` allows the log to be sent to a location other than `stderr`.
## Levels
### `error!()`
For immediate, unrecoverable errors where it does not make sense for the execution to continue as the behaviour of the VM is considerablely impacted.
For immediate, unrecoverable errors where it does not make sense for the execution to continue as the behaviour of the VM is considerably impacted.
Cloud Hypervisor should exit shortly after reporting this error (with a non-zero exit code). Generally this should be used during initial construction of the VM state before the virtual CPUs have begun running code.
@@ -23,7 +23,7 @@ Users should react to this error by checking their initial VM configuration.
### `warn!()`
A serious problem has occured but the execution of the VM can continue although some functionality might be impacted.
A serious problem has occurred but the execution of the VM can continue although some functionality might be impacted.
A typical example of where this level of message should be generated is during an API call request that cannot be fulfilled.

View File

@@ -222,7 +222,7 @@ struct MemoryZoneConfig {
--memory-zone <memory-zone> User defined memory zone parameters "size=<guest_memory_region_size>,file=<backing_file>,shared=on|off,hugepages=on|off,hugepage_size=<hugepage_size>,host_numa_node=<node_id>,id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,hotplugged_size=<hotplugged_memory_size>,prefault=on|off"
```
This parameter expects one or more occurences, allowing for a list of memory
This parameter expects one or more occurrences, allowing for a list of memory
zones to be defined. It must be used with `--memory size=0`, clearly indicating
that the memory will be described through advanced parameters.

View File

@@ -1,6 +1,6 @@
# Tracing
Cloud Hypervisor has a basic tracing infrastucture, particularly focussed on
Cloud Hypervisor has a basic tracing infrastructure, particularly focussed on
the tracing of the initial VM setup.
## Usage

View File

@@ -135,7 +135,7 @@ This section illustrates the Windows specific aspects of the VM network configur
### Basic Networking
As the simplest option, using `--net tap=` in the Cloud Hypervisor command line will create a `vmtapX` device on the host with the default IPv4 adress `192.168.249.1`. After SAC becomes available, the guest configuration can be set with
As the simplest option, using `--net tap=` in the Cloud Hypervisor command line will create a `vmtapX` device on the host with the default IPv4 address `192.168.249.1`. After SAC becomes available, the guest configuration can be set with
<pre>
SAC>i 10 192.168.249.2 255.255.255.0 192.168.249.1
@@ -203,13 +203,13 @@ 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 excercise, [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
#### WinDbg VM
For simplicity, the debugger VM is supposed to be only running under QEMU. It will require VGA and doesn't neccessarily depend on UEFI. As an OS, it can carry any supported Windows OS where the debugger of choice can be installed. The simplest way is to follow the image preparation instructions from the previous chapter, but avoid using the OVMF firmware. It is also not required to use VirtIO drivers, whereby it might be useful in some case. Though, while creating the image file for the debugger VM, be sure to choose a sufficient disk size that counts in the need to save the corresponding debug symbols and sources.
For simplicity, the debugger VM is supposed to be only running under QEMU. It will require VGA and doesn't necessarily depend on UEFI. As an OS, it can carry any supported Windows OS where the debugger of choice can be installed. The simplest way is to follow the image preparation instructions from the previous chapter, but avoid using the OVMF firmware. It is also not required to use VirtIO drivers, whereby it might be useful in some case. Though, while creating the image file for the debugger VM, be sure to choose a sufficient disk size that counts in the need to save the corresponding debug symbols and sources.
To create the debugger Windows VM, the following command can be used:
@@ -244,7 +244,7 @@ This will configure the debugging to be enabled and instruct to use the serial p
bcdedit /dbgsettings serial debugport:1 baudrate:115200
```
##### Turn On Kernel Debuging
##### Turn On Kernel Debugging
```cmd
bcdedit /debug on

View File

@@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
flume = "0.10.14"
libc = "0.2.139"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde_json = "1.0.96"
libc = "0.2.147"
once_cell = "1.18.0"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"

View File

@@ -3,15 +3,17 @@
// SPDX-License-Identifier: Apache-2.0
//
use once_cell::sync::OnceCell;
use serde::Serialize;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use std::time::{Duration, Instant};
static mut MONITOR: Option<MonitorHandle> = None;
static MONITOR: OnceCell<MonitorHandle> = OnceCell::new();
#[derive(Serialize)]
struct Event<'a> {
@@ -23,7 +25,24 @@ struct Event<'a> {
pub struct Monitor {
pub rx: flume::Receiver<String>,
pub file: File,
pub file: Option<File>,
pub broadcast: Vec<flume::Sender<Arc<String>>>,
}
impl Monitor {
pub fn new(rx: flume::Receiver<String>, file: Option<File>) -> Self {
Self {
rx,
file,
broadcast: vec![],
}
}
pub fn subscribe(&mut self) -> flume::Receiver<Arc<String>> {
let (tx, rx) = flume::unbounded();
self.broadcast.push(tx);
rx
}
}
struct MonitorHandle {
@@ -50,32 +69,32 @@ fn set_file_nonblocking(file: &File) -> io::Result<()> {
/// This function must only be called once from the main thread before any threads
/// are created to avoid race conditions.
pub fn set_monitor(file: File) -> io::Result<Monitor> {
// SAFETY: there is only one caller of this function, so MONITOR is written to only once
assert!(unsafe { MONITOR.is_none() });
pub fn set_monitor(file: Option<File>) -> io::Result<Monitor> {
// There is only one caller of this function, so MONITOR is written to only once
assert!(MONITOR.get().is_none());
if let Some(ref file) = file {
set_file_nonblocking(file)?;
}
set_file_nonblocking(&file)?;
let (tx, rx) = flume::unbounded();
let monitor = Monitor { rx, file };
let monitor = Monitor::new(rx, file);
// SAFETY: MONITOR is None. Nobody else can hold a reference to it.
unsafe {
MONITOR = Some(MonitorHandle {
tx,
start: Instant::now(),
});
};
MONITOR.get_or_init(|| MonitorHandle {
tx,
start: Instant::now(),
});
Ok(monitor)
}
pub fn event_log(source: &str, event: &str, properties: Option<&HashMap<Cow<str>, Cow<str>>>) {
// SAFETY: `MONITOR` is always in a valid state (None or Some), because it
// is set only once before any threads are spawned, and it's not mutated
// `MONITOR` is always in a valid state (None or Some), because it is set
// only once before any threads are spawned, and it's not mutated
// afterwards. This function only creates immutable references to `MONITOR`.
// Because `MONITOR.tx` is `Sync`, it's safe to share `MONITOR` across
// threads, making this function thread-safe.
if let Some(monitor_handle) = unsafe { MONITOR.as_ref() } {
if let Some(monitor_handle) = MONITOR.get().as_ref() {
let event = Event {
timestamp: monitor_handle.start.elapsed(),
source,

117
fuzz/Cargo.lock generated
View File

@@ -5,16 +5,16 @@ version = 3
[[package]]
name = "acpi_tables"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#05a609136387cc1cc9b499cee4320020325c263f"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#1029d22777f07b04849234bbe756da34a6df2913"
dependencies = [
"zerocopy",
]
[[package]]
name = "anyhow"
version = "1.0.72"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "api_client"
@@ -59,9 +59,9 @@ dependencies = [
[[package]]
name = "argh"
version = "0.1.10"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219"
dependencies = [
"argh_derive",
"argh_shared",
@@ -69,21 +69,24 @@ dependencies = [
[[package]]
name = "argh_derive"
version = "0.1.10"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a"
dependencies = [
"argh_shared",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.23",
]
[[package]]
name = "argh_shared"
version = "0.1.10"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531"
dependencies = [
"serde",
]
[[package]]
name = "autocfg"
@@ -148,9 +151,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"jobserver",
"libc",
@@ -164,7 +167,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cloud-hypervisor"
version = "33.0.0"
version = "34.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -301,6 +304,7 @@ version = "0.1.0"
dependencies = [
"flume",
"libc",
"once_cell",
"serde",
"serde_json",
]
@@ -381,9 +385,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "io-uring"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7b36074613a723279637061b40db993208908a94f10ccb14436ce735bc0f57"
checksum = "460648e47a07a43110fbfa2e0b14afb2be920093c31e5dccc50e49568e099762"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -436,15 +440,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.147"
version = "0.2.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]]
name = "libfuzzer-sys"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beb09950ae85a0a94b27676cccf37da5ff13f27076aa1adbc6545dd0d0e1bd4e"
checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7"
dependencies = [
"arbitrary",
"cc",
@@ -453,9 +457,9 @@ dependencies = [
[[package]]
name = "linux-loader"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3adb7b28e189741eca3b1a4a27de0bf15e0907c9d4b0c74bd2d7d84ef72e08"
checksum = "1db6a725c8000971f83fa93ed7ee1b600e55a1471a2a653379d3c84f72effdcf"
dependencies = [
"vm-memory",
]
@@ -472,14 +476,14 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.19"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#b538bf89e50be83b6fa9ab1896727ff61e02fa13"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#0d0fdcd50ea10c1b4777f9a958873fc848a5b7bb"
dependencies = [
"libc",
"vmm-sys-util",
@@ -586,9 +590,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.32"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@@ -671,9 +675,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.104"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
dependencies = [
"itoa",
"ryu",
@@ -682,9 +686,9 @@ dependencies = [
[[package]]
name = "serde_with"
version = "3.2.0"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49"
checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237"
dependencies = [
"serde",
"serde_with_macros",
@@ -692,9 +696,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "3.2.0"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7"
checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c"
dependencies = [
"darling",
"proc-macro2",
@@ -727,9 +731,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]]
name = "spin"
@@ -770,18 +774,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.44"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.44"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
dependencies = [
"proc-macro2",
"quote",
@@ -814,9 +818,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.11"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "uuid"
@@ -857,7 +861,7 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#89f8e77dd1a2829197ecde65b686bafcc8a1def4"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
dependencies = [
"vmm-sys-util",
]
@@ -865,7 +869,7 @@ dependencies = [
[[package]]
name = "vfio-ioctls"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#89f8e77dd1a2829197ecde65b686bafcc8a1def4"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -881,7 +885,7 @@ dependencies = [
[[package]]
name = "vfio_user"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#eef6bec4d421f08ed1688fe67c5ea33aabbf5069"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#2d96b90a7279547356ad8f83aaa3115ad5497302"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -897,9 +901,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.7.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84f81f436bca4541f4d33172e1202882c9d437db34ed17fc6d84c8ff2bde21f5"
checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -949,9 +953,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91aebb1df33db33cbf04d4c2445e4f78d0b0c8e65acfd16a4ee95ef63ca252f8"
checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f"
dependencies = [
"log",
"virtio-bindings",
@@ -988,12 +992,13 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#c5a99ab71b130435927
[[package]]
name = "vm-memory"
version = "0.11.0"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6ea57fe00f9086c59eeeb68e102dd611686bc3c28520fa465996d4d4bdce07"
checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b"
dependencies = [
"arc-swap",
"libc",
"thiserror",
"winapi",
]
@@ -1029,9 +1034,11 @@ dependencies = [
"arch",
"bitflags 2.3.3",
"block",
"cfg-if",
"devices",
"epoll",
"event_monitor",
"flume",
"hypervisor",
"libc",
"linux-loader",
@@ -1066,9 +1073,9 @@ dependencies = [
[[package]]
name = "vmm-sys-util"
version = "0.11.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd64fe09d8e880e600c324e7d664760a17f56e9672b7495a86381b49e4f72f46"
checksum = "48b7b084231214f7427041e4220d77dfe726897a6d41fddee450696e66ff2a29"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -1160,9 +1167,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "zerocopy"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3b9c234616391070b0b173963ebc65a9195068e7ed3731c6edac2ec45ebe106"
checksum = "20707b61725734c595e840fb3704378a0cd2b9c74cc9e6e20724838fc6a1e2f9"
dependencies = [
"byteorder",
"zerocopy-derive",
@@ -1170,9 +1177,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f7f3a471f98d0a61c34322fbbfd10c384b07687f680d4119813713f72308d91"
checksum = "56097d5b91d711293a42be9289403896b68654625021732067eac7a4ca388a1f"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -12,18 +12,18 @@ cargo-fuzz = true
block = { path = "../block" }
devices = { path = "../devices" }
epoll = "4.3.1"
libc = "0.2.147"
libfuzzer-sys = "0.4.6"
linux-loader = { version = "0.9.0", features = ["elf", "bzimage", "pe"] }
libc = "0.2.148"
libfuzzer-sys = "0.4.7"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
net_util = { path = "../net_util" }
once_cell = "1.18.0"
seccompiler = "0.3.0"
virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.8.0"
virtio-queue = "0.9.0"
vmm = { path = "../vmm" }
vmm-sys-util = "0.11.1"
vm-memory = "0.11.0"
vmm-sys-util = "0.11.2"
vm-memory = "0.12.2"
vm-device = { path = "../vm-device" }
vm-virtio = { path = "../vm-virtio" }

View File

@@ -24,7 +24,7 @@ const QUEUE_NUM: usize = 3;
const QUEUE_SIZE: u16 = 64;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
// Available ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;

View File

@@ -57,6 +57,7 @@ fuzz_target!(|bytes| {
false,
2,
256,
None,
SeccompAction::Allow,
None,
EventFd::new(EFD_NONBLOCK).unwrap(),

View File

@@ -30,7 +30,7 @@ const IOVA_SPACE_SIZE: usize = (0xfeef_ffff - 0xfee0_0000) + 1;
const QUEUE_SIZE: u16 = 256;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
// Available ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;

View File

@@ -33,7 +33,7 @@ const VIRTIO_MEM_REGION_ADDRESS: u64 = 0;
const QUEUE_SIZE: u16 = 64;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
// Available ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;

View File

@@ -28,7 +28,7 @@ const MEM_SIZE: usize = 1 * 1024 * 1024;
const QUEUE_SIZE: u16 = 256;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
// Available ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;

View File

@@ -8,22 +8,23 @@ license = "Apache-2.0 OR BSD-3-Clause"
[features]
kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"]
mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv", "iced-x86"]
sev_snp = []
tdx = []
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
byteorder = "1.4.3"
thiserror = "1.0.40"
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
kvm-ioctls = { version = "0.13.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-bindings = { git = "https://github.com/rust-vmm/mshv", branch = "main", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", branch = "main", optional = true}
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_with = { version = "3.0.0", default-features = false, features = ["macros"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-atomic"] }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]

View File

@@ -18,7 +18,7 @@ use crate::arch::x86::Exception;
// CMP affects OF, SF, ZF, AF, PF and CF
const FLAGS_MASK: u64 = CF | PF | AF | ZF | SF | OF;
// TODO: Switch to inline asm when that's stable. Executing CMP (or any arthimetic instructions)
// TODO: Switch to inline asm when that's stable. Executing CMP (or any arithmetic instructions)
// natively and extracting RFLAGS will be much faster and make the code simpler.
fn calc_rflags_cpazso(op0: u64, op1: u64, op_size: usize) -> u64 {
let op_bits = op_size * 8;

View File

@@ -18,8 +18,8 @@ fn get_op<T: CpuStateManager>(
insn: &Instruction,
op_index: u32,
op_size: usize,
state: &mut T,
platform: &mut dyn PlatformEmulator<CpuState = T>,
state: &T,
platform: &dyn PlatformEmulator<CpuState = T>,
) -> Result<u64, PlatformError> {
if insn.op_count() < op_index + 1 {
return Err(PlatformError::InvalidOperand(anyhow!(
@@ -124,7 +124,7 @@ fn memory_operand_address<T: CpuStateManager>(
address += index;
}
address += insn.memory_displacement64();
address = address.wrapping_add(insn.memory_displacement64());
// Translate to a linear address.
state.linearize(insn.memory_segment(), address, write)

View File

@@ -242,7 +242,7 @@ pub enum HypervisorCpuError {
UnknownTdxVmCall,
#[cfg(target_arch = "aarch64")]
///
/// Failed to intialize PMU
/// Failed to initialize PMU
///
#[error("Failed to initialize PMU")]
InitializePmu,
@@ -252,6 +252,11 @@ pub enum HypervisorCpuError {
///
#[error("Failed to get TSC frequency: {0}")]
GetTscKhz(#[source] anyhow::Error),
///
/// Error setting TSC frequency
///
#[error("Failed to set TSC frequency: {0}")]
SetTscKhz(#[source] anyhow::Error),
}
#[derive(Debug)]
@@ -447,6 +452,7 @@ pub trait Vcpu: Send + Sync {
/// Return the list of initial MSR entries for a VCPU
///
fn boot_msr_entries(&self) -> Vec<MsrEntry>;
#[cfg(target_arch = "x86_64")]
///
/// Get the frequency of the TSC if available
@@ -454,4 +460,11 @@ pub trait Vcpu: Send + Sync {
fn tsc_khz(&self) -> Result<Option<u32>> {
Ok(None)
}
#[cfg(target_arch = "x86_64")]
///
/// Set the frequency of the TSC if available
///
fn set_tsc_khz(&self, _freq: u32) -> Result<()> {
Ok(())
}
}

View File

@@ -84,6 +84,11 @@ pub enum HypervisorError {
///
#[error("Unsupported CPU:{0}")]
UnsupportedCpu(#[source] anyhow::Error),
///
/// Launching a VM with unsupported VM Type
///
#[error("Unsupported VmType")]
UnsupportedVmType(),
}
///

View File

@@ -1205,7 +1205,7 @@ impl cpu::Vcpu for KvmVcpu {
off += std::mem::size_of::<u64>();
}
// Now moving on to floting point registers which are stored in the user_fpsimd_state in the kernel:
// Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
// https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
let mut off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, vregs);
for i in 0..32 {
@@ -1890,6 +1890,7 @@ impl cpu::Vcpu for KvmVcpu {
};
let vcpu_events = self.get_vcpu_events()?;
let tsc_khz = self.tsc_khz()?;
Ok(VcpuKvmState {
cpuid,
@@ -1902,6 +1903,7 @@ impl cpu::Vcpu for KvmVcpu {
xsave,
xcrs,
mp_state,
tsc_khz,
}
.into())
}
@@ -2004,6 +2006,10 @@ impl cpu::Vcpu for KvmVcpu {
self.set_lapic(&state.lapic_state)?;
self.set_fpu(&state.fpu)?;
if let Some(freq) = state.tsc_khz {
self.set_tsc_khz(freq)?;
}
// Try to set all MSRs previously stored.
// If the number of MSRs set from SET_MSRS is different from the
// expected amount, we fallback onto a slower method by setting MSRs
@@ -2186,6 +2192,23 @@ impl cpu::Vcpu for KvmVcpu {
Ok(v) => Ok(Some(v)),
}
}
#[cfg(target_arch = "x86_64")]
///
/// Set the frequency of the TSC if available
///
fn set_tsc_khz(&self, freq: u32) -> cpu::Result<()> {
match self.fd.set_tsc_khz(freq) {
Err(e) => {
if e.errno() == libc::EIO {
Ok(())
} else {
Err(cpu::HypervisorCpuError::SetTscKhz(e.into()))
}
}
Ok(_) => Ok(()),
}
}
}
impl KvmVcpu {

View File

@@ -67,6 +67,7 @@ pub struct VcpuKvmState {
pub xsave: Xsave,
pub xcrs: ExtendedControlRegisters,
pub mp_state: MpState,
pub tsc_khz: Option<u32>,
}
impl From<StandardRegisters> for kvm_regs {

View File

@@ -140,7 +140,7 @@ pub enum MpState {
#[cfg(feature = "kvm")]
Kvm(kvm_bindings::kvm_mp_state),
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
Mshv, /* MSHV does not supprt MpState yet */
Mshv, /* MSHV does not support MpState yet */
}
#[derive(Debug, Clone, Copy)]
@@ -164,7 +164,7 @@ pub enum ClockData {
#[cfg(feature = "kvm")]
Kvm(kvm_bindings::kvm_clock_data),
#[cfg(feature = "mshv")]
Mshv, /* MSHV does not supprt ClockData yet */
Mshv, /* MSHV does not support ClockData yet */
}
#[cfg(target_arch = "x86_64")]

View File

@@ -14,7 +14,7 @@ use crate::vec_with_array_field;
use crate::vm::{self, InterruptSourceConfig, VmOps};
use crate::HypervisorType;
pub use mshv_bindings::*;
use mshv_ioctls::{set_registers_64, Mshv, NoDatamatch, VcpuFd, VmFd};
use mshv_ioctls::{set_registers_64, Mshv, NoDatamatch, VcpuFd, VmFd, VmType};
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
@@ -210,21 +210,15 @@ impl hypervisor::Hypervisor for MshvHypervisor {
fn hypervisor_type(&self) -> HypervisorType {
HypervisorType::Mshv
}
/// Create a mshv vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result<Arc<dyn crate::Vm>> {
let mshv_vm_type: VmType = match VmType::try_from(vm_type) {
Ok(vm_type) => vm_type,
Err(_) => return Err(hypervisor::HypervisorError::UnsupportedVmType()),
};
let fd: VmFd;
loop {
match self.mshv.create_vm() {
match self.mshv.create_vm_with_type(mshv_vm_type) {
Ok(res) => fd = res,
Err(e) => {
if e.errno() == libc::EINTR {
@@ -271,6 +265,22 @@ impl hypervisor::Hypervisor for MshvHypervisor {
dirty_log_slots: Arc::new(RwLock::new(HashMap::new())),
}))
}
/// Create a mshv vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
let vm_type = 0;
self.create_vm_with_type(vm_type)
}
///
/// Get the supported CpuID
///
@@ -562,6 +572,18 @@ impl cpu::Vcpu for MshvVcpu {
debug!("Exception Info {:?}", { info.exception_vector });
Ok(cpu::VmExit::Ignore)
}
hv_message_type_HVMSG_X64_APIC_EOI => {
let info = x.to_apic_eoi_info().unwrap();
// The kernel should dispatch the EOI to the correct thread.
// Check the VP index is the same as the one we have.
assert!(info.vp_index == self.vp_index as u32);
// The interrupt vector in info is u32, but x86 only supports 256 vectors.
// There is no good way to recover from this if the hypervisor messes around.
// Just unwrap.
Ok(cpu::VmExit::IoapicEoi(
info.interrupt_vector.try_into().unwrap(),
))
}
exit => Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unhandled VCPU exit {:?}",
exit

View File

@@ -325,7 +325,7 @@ pub trait Vm: Send + Sync + Any {
/// Get dirty pages bitmap
fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>;
#[cfg(feature = "tdx")]
/// Initalize TDX on this VM
/// Initialize TDX on this VM
fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> {
unimplemented!()
}
@@ -335,7 +335,7 @@ pub trait Vm: Send + Sync + Any {
unimplemented!()
}
#[cfg(feature = "tdx")]
/// Initalize a TDX memory region for this VM
/// Initialize a TDX memory region for this VM
fn tdx_init_memory_region(
&self,
_host_address: u64,

View File

@@ -7,22 +7,22 @@ edition = "2021"
[dependencies]
epoll = "4.3.3"
getrandom = "0.2.10"
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.164"
serde = "1.0.168"
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
virtio-bindings = "0.2.0"
virtio-queue = "0.8.0"
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.9.0"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"
[dev-dependencies]
once_cell = "1.18.0"
pnet = "0.33.0"
pnet_datalink = "0.33.0"
serde_json = "1.0.96"
pnet = "0.34.0"
pnet_datalink = "0.34.0"
serde_json = "1.0.107"

View File

@@ -38,7 +38,7 @@ impl TxVirtio {
pub fn process_desc_chain(
&mut self,
mem: &GuestMemoryMmap,
tap: &mut Tap,
tap: &Tap,
queue: &mut Queue,
rate_limiter: &mut Option<RateLimiter>,
access_platform: Option<&Arc<dyn AccessPlatform>>,
@@ -64,9 +64,9 @@ impl TxVirtio {
.memory()
.get_slice(desc_addr, desc.len() as usize)
.map_err(NetQueuePairError::GuestMemory)?
.as_ptr();
.ptr_guard_mut();
let iovec = libc::iovec {
iov_base: buf as *mut libc::c_void,
iov_base: buf.as_ptr() as *mut libc::c_void,
iov_len: desc.len() as libc::size_t,
};
iovecs.push(iovec);
@@ -164,7 +164,7 @@ impl RxVirtio {
pub fn process_desc_chain(
&mut self,
mem: &GuestMemoryMmap,
tap: &mut Tap,
tap: &Tap,
queue: &mut Queue,
rate_limiter: &mut Option<RateLimiter>,
access_platform: Option<&Arc<dyn AccessPlatform>>,
@@ -203,9 +203,9 @@ impl RxVirtio {
.memory()
.get_slice(desc_addr, desc.len() as usize)
.map_err(NetQueuePairError::GuestMemory)?
.as_ptr();
.ptr_guard_mut();
let iovec = libc::iovec {
iov_base: buf as *mut libc::c_void,
iov_base: buf.as_ptr() as *mut libc::c_void,
iov_len: desc.len() as libc::size_t,
};
iovecs.push(iovec);
@@ -357,7 +357,7 @@ impl NetQueuePair {
) -> Result<bool, NetQueuePairError> {
let tx_tap_retry = self.tx.process_desc_chain(
mem,
&mut self.tap,
&self.tap,
queue,
&mut self.tx_rate_limiter,
self.access_platform.as_ref(),
@@ -407,7 +407,7 @@ impl NetQueuePair {
) -> Result<bool, NetQueuePairError> {
self.rx_desc_avail = !self.rx.process_desc_chain(
mem,
&mut self.tap,
&self.tap,
queue,
&mut self.rx_rate_limiter,
self.access_platform.as_ref(),

View File

@@ -203,7 +203,7 @@ impl Tap {
let mut ifreq: net_gen::ifreq = Default::default();
// Get current config including name
// SAFETY: IOCTL with correct arugments
// SAFETY: IOCTL with correct arguments
unsafe { Self::ioctl_with_mut_ref(&tap_file, net_gen::TUNGETIFF(), &mut ifreq)? };
// SAFETY: We only access one field of the ifru union

View File

@@ -10,7 +10,7 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main", features = ["fam-wrappers"] }
@@ -18,13 +18,13 @@ vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", defau
vfio_user = { git = "https://github.com/rust-vmm/vfio-user", branch = "main" }
vmm-sys-util = "0.11.0"
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
serde = { version = "1.0.164", features = ["derive"] }
serde = { version = "1.0.168", features = ["derive"] }
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }

View File

@@ -265,10 +265,10 @@ pub enum PciExpressCapabilityId {
VendorSpecificExtendedCapability = 0x000b,
ConfigurationAccessCorrelation = 0x000c,
AccessControlServices = 0x000d,
AlternativeRoutingIdentificationIntepretation = 0x000e,
AlternativeRoutingIdentificationInterpretation = 0x000e,
AddressTranslationServices = 0x000f,
SingleRootIoVirtualization = 0x0010,
DeprecatedMultiRootIoVirtualzation = 0x0011,
DeprecatedMultiRootIoVirtualization = 0x0011,
Multicast = 0x0012,
PageRequestInterface = 0x0013,
ReservedForAmd = 0x0014,
@@ -279,7 +279,7 @@ pub enum PciExpressCapabilityId {
SecondaryPciExpress = 0x0019,
ProtocolMultiplexing = 0x001a,
ProcessAddressSpaceId = 0x001b,
LnRequestor = 0x001c,
LnRequester = 0x001c,
DownstreamPortContainment = 0x001d,
L1PmSubstates = 0x001e,
PrecisionTimeMeasurement = 0x001f,
@@ -319,10 +319,10 @@ impl From<u16> for PciExpressCapabilityId {
0x000b => PciExpressCapabilityId::VendorSpecificExtendedCapability,
0x000c => PciExpressCapabilityId::ConfigurationAccessCorrelation,
0x000d => PciExpressCapabilityId::AccessControlServices,
0x000e => PciExpressCapabilityId::AlternativeRoutingIdentificationIntepretation,
0x000e => PciExpressCapabilityId::AlternativeRoutingIdentificationInterpretation,
0x000f => PciExpressCapabilityId::AddressTranslationServices,
0x0010 => PciExpressCapabilityId::SingleRootIoVirtualization,
0x0011 => PciExpressCapabilityId::DeprecatedMultiRootIoVirtualzation,
0x0011 => PciExpressCapabilityId::DeprecatedMultiRootIoVirtualization,
0x0012 => PciExpressCapabilityId::Multicast,
0x0013 => PciExpressCapabilityId::PageRequestInterface,
0x0014 => PciExpressCapabilityId::ReservedForAmd,
@@ -333,7 +333,7 @@ impl From<u16> for PciExpressCapabilityId {
0x0019 => PciExpressCapabilityId::SecondaryPciExpress,
0x001a => PciExpressCapabilityId::ProtocolMultiplexing,
0x001b => PciExpressCapabilityId::ProcessAddressSpaceId,
0x001c => PciExpressCapabilityId::LnRequestor,
0x001c => PciExpressCapabilityId::LnRequester,
0x001d => PciExpressCapabilityId::DownstreamPortContainment,
0x001e => PciExpressCapabilityId::L1PmSubstates,
0x001f => PciExpressCapabilityId::PrecisionTimeMeasurement,

View File

@@ -502,8 +502,8 @@ impl VfioCommon {
Ok(vfio_common)
}
/// In case msix table offset is not page size aligned, we need do some fixup to achive it.
/// Becuse we don't want the MMIO RW region and trap region overlap each other.
/// In case msix table offset is not page size aligned, we need do some fixup to achieve it.
/// Because we don't want the MMIO RW region and trap region overlap each other.
fn fixup_msix_region(&mut self, bar_id: u32, region_size: u64) -> u64 {
if let Some(msix) = self.interrupt.msix.as_mut() {
let msix_cap = &mut msix.cap;
@@ -911,7 +911,7 @@ impl VfioCommon {
let cap_next: u16 = ((ext_cap_hdr >> 20) & 0xfff) as u16;
match PciExpressCapabilityId::from(cap_id) {
PciExpressCapabilityId::AlternativeRoutingIdentificationIntepretation
PciExpressCapabilityId::AlternativeRoutingIdentificationInterpretation
| PciExpressCapabilityId::ResizeableBar
| PciExpressCapabilityId::SingleRootIoVirtualization => {
let reg_idx = (current_offset / 4) as usize;
@@ -1411,7 +1411,7 @@ impl VfioPciDevice {
// around them, leading to a list of sparse areas.
// We want to make sure we will still trap MMIO accesses
// to these MSI-X specific ranges. If these region don't align
// with pagesize, we can achive it by enlarging its range.
// with pagesize, we can achieve it by enlarging its range.
//
// Using a BtreeMap as the list provided through the iterator is sorted
// by key. This ensures proper split of the whole region.

View File

@@ -8,8 +8,8 @@ build = "../build.rs"
[dependencies]
argh = "0.1.9"
dirs = "5.0.0"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde_json = "1.0.96"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
test_infra = { path = "../test_infra" }
thiserror = "1.0.40"
wait-timeout = "0.2.0"

View File

@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
vmm-sys-util = "0.11.0"

View File

@@ -46,9 +46,11 @@
#[macro_use]
extern crate log;
use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
use std::time::{Duration, Instant};
use std::{fmt, io};
use vmm_sys_util::timerfd::TimerFd;
#[derive(Debug)]
@@ -271,27 +273,27 @@ pub enum BucketUpdate {
/// implementation. These events are meant to be consumed by the user of this struct.
/// On each such event, the user must call the `event_handler()` method.
pub struct RateLimiter {
inner: Mutex<RateLimiterInner>,
// Internal flag that quickly determines timer state.
timer_active: AtomicBool,
}
struct RateLimiterInner {
bandwidth: Option<TokenBucket>,
ops: Option<TokenBucket>,
timer_fd: TimerFd,
// Internal flag that quickly determines timer state.
timer_active: bool,
}
impl PartialEq for RateLimiter {
fn eq(&self, other: &RateLimiter) -> bool {
self.bandwidth == other.bandwidth && self.ops == other.ops
}
}
impl fmt::Debug for RateLimiter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"RateLimiter {{ bandwidth: {:?}, ops: {:?} }}",
self.bandwidth, self.ops
)
impl RateLimiterInner {
// Arm the timer of the rate limiter with the provided `Duration` (which will fire only once).
fn activate_timer(&mut self, dur: Duration, flag: &AtomicBool) {
// Panic when failing to arm the timer (same handling in crate TimerFd::set_state())
self.timer_fd
.reset(dur, None)
.expect("Can't arm the timer (unexpected 'timerfd_settime' failure).");
flag.store(true, Ordering::Relaxed)
}
}
@@ -355,35 +357,28 @@ impl RateLimiter {
}
Ok(RateLimiter {
bandwidth: bytes_token_bucket,
ops: ops_token_bucket,
timer_fd,
timer_active: false,
inner: Mutex::new(RateLimiterInner {
bandwidth: bytes_token_bucket,
ops: ops_token_bucket,
timer_fd,
}),
timer_active: AtomicBool::new(false),
})
}
// Arm the timer of the rate limiter with the provided `Duration` (which will fire only once).
fn activate_timer(&mut self, dur: Duration) {
// Panic when failing to arm the timer (same handling in crate TimerFd::set_state())
self.timer_fd
.reset(dur, None)
.expect("Can't arm the timer (unexpected 'timerfd_settime' failure).");
self.timer_active = true;
}
/// Attempts to consume tokens and returns whether that is possible.
///
/// If rate limiting is disabled on provided `token_type`, this function will always succeed.
pub fn consume(&mut self, tokens: u64, token_type: TokenType) -> bool {
pub fn consume(&self, tokens: u64, token_type: TokenType) -> bool {
// If the timer is active, we can't consume tokens from any bucket and the function fails.
if self.timer_active {
if self.is_blocked() {
return false;
}
let mut guard = self.inner.lock().unwrap();
// Identify the required token bucket.
let token_bucket = match token_type {
TokenType::Bytes => self.bandwidth.as_mut(),
TokenType::Ops => self.ops.as_mut(),
TokenType::Bytes => guard.bandwidth.as_mut(),
TokenType::Ops => guard.ops.as_mut(),
};
// Try to consume from the token bucket.
if let Some(bucket) = token_bucket {
@@ -393,8 +388,8 @@ impl RateLimiter {
// register a timer to replenish the bucket and resume processing;
// make sure there is only one running timer for this limiter.
BucketReduction::Failure => {
if !self.timer_active {
self.activate_timer(TIMER_REFILL_DUR);
if !self.is_blocked() {
guard.activate_timer(TIMER_REFILL_DUR, &self.timer_active);
}
false
}
@@ -409,7 +404,10 @@ impl RateLimiter {
// order to enforce the bandwidth limit we need to prevent
// further calls to the rate limiter for
// `ratio * refill_time` milliseconds.
self.activate_timer(Duration::from_millis((ratio * refill_time as f64) as u64));
guard.activate_timer(
Duration::from_millis((ratio * refill_time as f64) as u64),
&self.timer_active,
);
true
}
}
@@ -424,11 +422,12 @@ impl RateLimiter {
///
/// Can be used to *manually* add tokens to a bucket. Useful for reverting a
/// `consume()` if needed.
pub fn manual_replenish(&mut self, tokens: u64, token_type: TokenType) {
pub fn manual_replenish(&self, tokens: u64, token_type: TokenType) {
let mut guard = self.inner.lock().unwrap();
// Identify the required token bucket.
let token_bucket = match token_type {
TokenType::Bytes => self.bandwidth.as_mut(),
TokenType::Ops => self.ops.as_mut(),
TokenType::Bytes => guard.bandwidth.as_mut(),
TokenType::Ops => guard.ops.as_mut(),
};
// Add tokens to the token bucket.
if let Some(bucket) = token_bucket {
@@ -442,7 +441,7 @@ impl RateLimiter {
/// budget for it.
/// An event will be generated on the exported FD when the limiter 'unblocks'.
pub fn is_blocked(&self) -> bool {
self.timer_active
self.timer_active.load(Ordering::Relaxed)
}
/// This function needs to be called every time there is an event on the
@@ -451,11 +450,12 @@ impl RateLimiter {
/// # Errors
///
/// If the rate limiter is disabled or is not blocked, an error is returned.
pub fn event_handler(&mut self) -> Result<(), Error> {
pub fn event_handler(&self) -> Result<(), Error> {
let mut guard = self.inner.lock().unwrap();
loop {
// Note: As we manually added the `O_NONBLOCK` flag to the FD, the following
// `timer_fd::wait()` won't block (which is different from its default behavior.)
match self.timer_fd.wait() {
match guard.timer_fd.wait() {
Err(e) => {
let err: std::io::Error = e.into();
match err.kind() {
@@ -469,7 +469,7 @@ impl RateLimiter {
}
}
_ => {
self.timer_active = false;
self.timer_active.store(false, Ordering::Relaxed);
return Ok(());
}
}
@@ -479,27 +479,18 @@ impl RateLimiter {
/// Updates the parameters of the token buckets associated with this RateLimiter.
// TODO: Please note that, right now, the buckets become full after being updated.
pub fn update_buckets(&mut self, bytes: BucketUpdate, ops: BucketUpdate) {
let mut guard = self.inner.lock().unwrap();
match bytes {
BucketUpdate::Disabled => self.bandwidth = None,
BucketUpdate::Update(tb) => self.bandwidth = Some(tb),
BucketUpdate::Disabled => guard.bandwidth = None,
BucketUpdate::Update(tb) => guard.bandwidth = Some(tb),
BucketUpdate::None => (),
};
match ops {
BucketUpdate::Disabled => self.ops = None,
BucketUpdate::Update(tb) => self.ops = Some(tb),
BucketUpdate::Disabled => guard.ops = None,
BucketUpdate::Update(tb) => guard.ops = Some(tb),
BucketUpdate::None => (),
};
}
/// Returns an immutable view of the inner bandwidth token bucket.
pub fn bandwidth(&self) -> Option<&TokenBucket> {
self.bandwidth.as_ref()
}
/// Returns an immutable view of the inner ops token bucket.
pub fn ops(&self) -> Option<&TokenBucket> {
self.ops.as_ref()
}
}
impl AsRawFd for RateLimiter {
@@ -510,7 +501,8 @@ impl AsRawFd for RateLimiter {
/// Will return a negative value if rate limiting is disabled on both
/// token types.
fn as_raw_fd(&self) -> RawFd {
self.timer_fd.as_raw_fd()
let guard = self.inner.lock().unwrap();
guard.timer_fd.as_raw_fd()
}
}
@@ -525,6 +517,7 @@ impl Default for RateLimiter {
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use std::fmt;
use std::thread;
use std::time::Duration;
@@ -557,11 +550,33 @@ pub(crate) mod tests {
}
impl RateLimiter {
fn get_token_bucket(&self, token_type: TokenType) -> Option<&TokenBucket> {
match token_type {
TokenType::Bytes => self.bandwidth.as_ref(),
TokenType::Ops => self.ops.as_ref(),
}
pub fn bandwidth(&self) -> Option<TokenBucket> {
let guard = self.inner.lock().unwrap();
guard.bandwidth.clone()
}
pub fn ops(&self) -> Option<TokenBucket> {
let guard = self.inner.lock().unwrap();
guard.ops.clone()
}
}
impl PartialEq for RateLimiter {
fn eq(&self, other: &RateLimiter) -> bool {
let self_guard = self.inner.lock().unwrap();
let other_guard = other.inner.lock().unwrap();
self_guard.bandwidth == other_guard.bandwidth && self_guard.ops == other_guard.ops
}
}
impl fmt::Debug for RateLimiter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let guard = self.inner.lock().unwrap();
write!(
f,
"RateLimiter {{ bandwidth: {:?}, ops: {:?} }}",
guard.bandwidth, guard.ops
)
}
}
@@ -640,7 +655,7 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_default() {
let mut l = RateLimiter::default();
let l = RateLimiter::default();
// limiter should not be blocked
assert!(!l.is_blocked());
@@ -659,14 +674,13 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_new() {
let l = RateLimiter::new(1000, 1001, 1002, 1003, 1004, 1005).unwrap();
let bw = l.bandwidth.unwrap();
let bw = l.bandwidth().unwrap();
assert_eq!(bw.capacity(), 1000);
assert_eq!(bw.one_time_burst(), 1001);
assert_eq!(bw.refill_time_ms(), 1002);
assert_eq!(bw.budget(), 1000);
let ops = l.ops.unwrap();
let ops = l.ops().unwrap();
assert_eq!(ops.capacity(), 1003);
assert_eq!(ops.one_time_burst(), 1004);
assert_eq!(ops.refill_time_ms(), 1005);
@@ -676,20 +690,20 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_manual_replenish() {
// rate limiter with limit of 1000 bytes/s and 1000 ops/s
let mut l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
let l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
// consume 123 bytes
assert!(l.consume(123, TokenType::Bytes));
l.manual_replenish(23, TokenType::Bytes);
{
let bytes_tb = l.get_token_bucket(TokenType::Bytes).unwrap();
let bytes_tb = l.bandwidth().unwrap();
assert_eq!(bytes_tb.budget(), 900);
}
// consume 123 ops
assert!(l.consume(123, TokenType::Ops));
l.manual_replenish(23, TokenType::Ops);
{
let bytes_tb = l.get_token_bucket(TokenType::Ops).unwrap();
let bytes_tb = l.ops().unwrap();
assert_eq!(bytes_tb.budget(), 900);
}
}
@@ -697,7 +711,7 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_bandwidth() {
// rate limiter with limit of 1000 bytes/s
let mut l = RateLimiter::new(1000, 0, 1000, 0, 0, 0).unwrap();
let l = RateLimiter::new(1000, 0, 1000, 0, 0, 0).unwrap();
// limiter should not be blocked
assert!(!l.is_blocked());
@@ -730,7 +744,7 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_ops() {
// rate limiter with limit of 1000 ops/s
let mut l = RateLimiter::new(0, 0, 0, 1000, 0, 1000).unwrap();
let l = RateLimiter::new(0, 0, 0, 1000, 0, 1000).unwrap();
// limiter should not be blocked
assert!(!l.is_blocked());
@@ -763,7 +777,7 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_full() {
// rate limiter with limit of 1000 bytes/s and 1000 ops/s
let mut l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
let l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
// limiter should not be blocked
assert!(!l.is_blocked());
@@ -799,7 +813,7 @@ pub(crate) mod tests {
#[test]
fn test_rate_limiter_overconsumption() {
// initialize the rate limiter
let mut l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
let l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
// try to consume 2.5x the bucket size
// we are "borrowing" 1.5x the bucket size in tokens since
// the bucket is full
@@ -818,7 +832,7 @@ pub(crate) mod tests {
assert!(!l.is_blocked());
// reset the rate limiter
let mut l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
let l = RateLimiter::new(1000, 0, 1000, 1000, 0, 1000).unwrap();
// try to consume 1.5x the bucket size
// we are "borrowing" 1.5x the bucket size in tokens since
// the bucket is full, should arm the timer to 0.5x replenish
@@ -846,7 +860,7 @@ pub(crate) mod tests {
assert!(!l.consume(100, TokenType::Bytes));
// after waiting out the full duration, rate limiter should be
// availale again
// available again
thread::sleep(Duration::from_millis(200));
assert!(l.event_handler().is_ok());
assert!(!l.is_blocked());
@@ -857,12 +871,12 @@ pub(crate) mod tests {
fn test_update_buckets() {
let mut x = RateLimiter::new(1000, 2000, 1000, 10, 20, 1000).unwrap();
let initial_bw = x.bandwidth.clone();
let initial_ops = x.ops.clone();
let initial_bw = x.bandwidth();
let initial_ops = x.ops();
x.update_buckets(BucketUpdate::None, BucketUpdate::None);
assert_eq!(x.bandwidth, initial_bw);
assert_eq!(x.ops, initial_ops);
assert_eq!(x.bandwidth(), initial_bw);
assert_eq!(x.ops(), initial_ops);
let new_bw = TokenBucket::new(123, 0, 57).unwrap();
let new_ops = TokenBucket::new(321, 12346, 89).unwrap();
@@ -871,18 +885,21 @@ pub(crate) mod tests {
BucketUpdate::Update(new_ops.clone()),
);
// We have manually adjust the last_update field, because it changes when update_buckets()
// constructs new buckets (and thus gets a different value for last_update). We do this so
// it makes sense to test the following assertions.
x.bandwidth.as_mut().unwrap().last_update = new_bw.last_update;
x.ops.as_mut().unwrap().last_update = new_ops.last_update;
{
let mut guard = x.inner.lock().unwrap();
// We have manually adjust the last_update field, because it changes when update_buckets()
// constructs new buckets (and thus gets a different value for last_update). We do this so
// it makes sense to test the following assertions.
guard.bandwidth.as_mut().unwrap().last_update = new_bw.last_update;
guard.ops.as_mut().unwrap().last_update = new_ops.last_update;
}
assert_eq!(x.bandwidth, Some(new_bw));
assert_eq!(x.ops, Some(new_ops));
assert_eq!(x.bandwidth(), Some(new_bw));
assert_eq!(x.ops(), Some(new_ops));
x.update_buckets(BucketUpdate::Disabled, BucketUpdate::Disabled);
assert_eq!(x.bandwidth, None);
assert_eq!(x.ops, None);
assert_eq!(x.bandwidth(), None);
assert_eq!(x.ops(), None);
}
#[test]

View File

@@ -1,20 +1,27 @@
- [v35.1](#v351)
- [v35.0](#v350)
- [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63)
- [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block)
- [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [v34.0](#v340)
- [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support)
- [Improvements to VM Core Dump](#improvements-to-vm-core-dump)
- [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files)
- [Minimum Host Kernel Bump](#minimum-host-kernel-bump)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [v33.0](#v330)
- [D-Bus based API](#d-bus-based-api)
- [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [v32.0](#v320)
- [Increased PCI Segment Limit](#increased-pci-segment-limit)
- [API Changes](#api-changes)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [v31.1](#v311)
- [v31.0](#v310)
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
@@ -22,15 +29,15 @@
- [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler)
- [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile)
- [Documentation Improvements](#documentation-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [v30.0](#v300)
- [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size)
- [Basic vfio-user Server Support](#basic-vfio-user-server-support)
- [Heap Profiling Support](#heap-profiling-support)
- [Documentation Improvements](#documentation-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [v28.2](#v282)
- [v29.0](#v290)
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
@@ -40,10 +47,10 @@
- [`AArch64` Documentation Integration](#aarch64-documentation-integration)
- [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement)
- [TCP Offload Control](#tcp-offload-control)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Removals](#removals)
- [Deprecations](#deprecations)
- [Contributors](#contributors-5)
- [Contributors](#contributors-6)
- [v28.1](#v281)
- [v28.0](#v280)
- [Community Engagement (Reminder)](#community-engagement-reminder)
@@ -51,9 +58,9 @@
- [Virtualised TPM Support](#virtualised-tpm-support)
- [Transparent Huge Page Support](#transparent-huge-page-support)
- [README Quick Start Improved](#readme-quick-start-improved)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Removals](#removals-1)
- [Contributors](#contributors-6)
- [Contributors](#contributors-7)
- [v27.0](#v270)
- [Community Engagement](#community-engagement)
- [Prebuilt Packages](#prebuilt-packages)
@@ -62,41 +69,41 @@
- [Simplified Build Feature Flags](#simplified-build-feature-flags)
- [Asynchronous Kernel Loading](#asynchronous-kernel-loading)
- [GDB Support for AArch64](#gdb-support-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-7)
- [Contributors](#contributors-8)
- [v26.0](#v260)
- [SMBIOS Improvements via `--platform`](#smbios-improvements-via---platform)
- [Unified Binary MSHV and KVM Support](#unified-binary-mshv-and-kvm-support)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Deprecations](#deprecations-2)
- [Removals](#removals-2)
- [Contributors](#contributors-8)
- [Contributors](#contributors-9)
- [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements-1)
- [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Removals](#removals-3)
- [Contributors](#contributors-9)
- [Contributors](#contributors-10)
- [v24.0](#v240)
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
- [Sparse Mmap support](#sparse-mmap-support)
- [Expose Platform Serial Number](#expose-platform-serial-number)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations-3)
- [New on the Website](#new-on-the-website)
- [Contributors](#contributors-10)
- [Contributors](#contributors-11)
- [v23.1](#v231)
- [v23.0](#v230)
- [vDPA Support](#vdpa-support)
- [Updated OS Support list](#updated-os-support-list)
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
- [`AMX` Support](#amx-support)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Notable Bug Fixes](#notable-bug-fixes-12)
- [Deprecations](#deprecations-4)
- [Contributors](#contributors-11)
- [Contributors](#contributors-12)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -107,13 +114,13 @@
- [PMU Support for AArch64](#pmu-support-for-aarch64)
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
- [Notable Bug Fixes](#notable-bug-fixes-12)
- [Contributors](#contributors-12)
- [Notable Bug Fixes](#notable-bug-fixes-13)
- [Contributors](#contributors-13)
- [v21.0](#v210)
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
- [Notable Bug fixes](#notable-bug-fixes-13)
- [Contributors](#contributors-13)
- [Notable Bug fixes](#notable-bug-fixes-14)
- [Contributors](#contributors-14)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -122,8 +129,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-14)
- [Contributors](#contributors-14)
- [Notable bug fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-15)
- [v19.0](#v190)
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
- [PCI boot time optimisations](#pci-boot-time-optimisations)
@@ -131,8 +138,8 @@
- [Live migration enhancements](#live-migration-enhancements)
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
- [Notable bug fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-15)
- [Notable bug fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-16)
- [v18.0](#v180)
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
@@ -142,23 +149,23 @@
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
- [Power button support on AArch64](#power-button-support-on-aarch64)
- [Notable bug fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-16)
- [Notable bug fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-17)
- [v17.0](#v170)
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
- [Improved SGX support](#improved-sgx-support)
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
- [Notable bug fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-17)
- [Notable bug fixes](#notable-bug-fixes-18)
- [Contributors](#contributors-18)
- [v16.0](#v160)
- [Improved live migration support](#improved-live-migration-support)
- [Improved `vhost-user` support](#improved-vhost-user-support)
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
- [Notable bug fixes](#notable-bug-fixes-18)
- [Notable bug fixes](#notable-bug-fixes-19)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-18)
- [Contributors](#contributors-19)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
@@ -166,7 +173,7 @@
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-5)
- [Contributors](#contributors-19)
- [Contributors](#contributors-20)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -176,7 +183,7 @@
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
- [Block device rate limiting](#block-device-rate-limiting)
- [Deprecations](#deprecations-6)
- [Contributors](#contributors-20)
- [Contributors](#contributors-21)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -184,13 +191,13 @@
- [VHD disk image support](#vhd-disk-image-support)
- [Improved Virtio device threading](#improved-virtio-device-threading)
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
- [Contributors](#contributors-21)
- [Contributors](#contributors-22)
- [v0.12.0](#v0120)
- [ARM64 enhancements](#arm64-enhancements)
- [Removal of `vhost-user-net` and `vhost-user-block` self spawning](#removal-of-vhost-user-net-and-vhost-user-block-self-spawning)
- [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend)
- [Enhanced "info" API](#enhanced-info-api)
- [Contributors](#contributors-22)
- [Contributors](#contributors-23)
- [v0.11.0](#v0110)
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
- [Windows Guest Support](#windows-guest-support)
@@ -202,15 +209,15 @@
- [Default Log Level Changed](#default-log-level-changed)
- [New `--balloon` Parameter Added](#new---balloon-parameter-added)
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
- [Notable Bug Fixes](#notable-bug-fixes-19)
- [Contributors](#contributors-23)
- [Notable Bug Fixes](#notable-bug-fixes-20)
- [Contributors](#contributors-24)
- [v0.10.0](#v0100)
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
- [Memory Zones](#memory-zones)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
- [Notable Bug Fixes](#notable-bug-fixes-20)
- [Contributors](#contributors-24)
- [Notable Bug Fixes](#notable-bug-fixes-21)
- [Contributors](#contributors-25)
- [v0.9.0](#v090)
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
- [Block and Network Device Statistics](#block-and-network-device-statistics)
@@ -223,17 +230,17 @@
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
- [Intel SGX Support](#intel-sgx-support)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-21)
- [Contributors](#contributors-25)
- [Notable Bug Fixes](#notable-bug-fixes-22)
- [Contributors](#contributors-26)
- [v0.8.0](#v080)
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
- [Experimental ARM64 Support](#experimental-arm64-support)
- [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests)
- [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices)
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-22)
- [Notable Bug Fixes](#notable-bug-fixes-23)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-26)
- [Contributors](#contributors-27)
- [v0.7.0](#v070)
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
- [Alternative `libc` Support](#alternative-libc-support)
@@ -243,14 +250,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-27)
- [Contributors](#contributors-28)
- [v0.6.0](#v060)
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
- [Shared Filesystem Improvements](#shared-filesystem-improvements)
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
- [Command Line Interface](#command-line-interface)
- [PVH Boot](#pvh-boot)
- [Contributors](#contributors-28)
- [Contributors](#contributors-29)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -258,7 +265,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-29)
- [Contributors](#contributors-30)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -267,7 +274,7 @@
- [Userspace IOAPIC by default](#userspace-ioapic-by-default)
- [PCI BAR reprogramming](#pci-bar-reprogramming)
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
- [Contributors](#contributors-30)
- [Contributors](#contributors-31)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -294,6 +301,69 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v35.1
This is a bug fix release. The following issues have been addressed:
* Fix a deadlock when TDX is enabled (#5845)
* Correct default value for vCPU topology on AArch64 (#5893)
* Fix PvPanic device PCI BAR alignment (#5956)
* Bug fix to OpenAPI specification file (#5967)
* Error out early for live migration when TDX is enabled (#6025)
# v35.0
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v35.0. The following user visible changes have been made:
### `virtio-vsock` Support for Linux Guest Kernel v6.3+
Since kernel v6.3, a vsock packet can be included in a single descriptor,
instead of being split over two descriptors. Our `virtio-vsock` implementation
now support both situations.
### User Specified Serial Number for `virtio-block`
A new option `serial` is added to the `--block` command that allows users to
specify a serial number for block devices which will be guest visible.
### vCPU TSC Frequency Included in Migration State
This ensures migration works correctly between hosts that have different TSC
frequencies if the guest is running with TSC as the source of timekeeping.
### Notable Bug Fixes
* Disallow concurrent CPU resizing (#5668)
* Handle APIC EOI message for MSHV (#5681)
* Use wrapping add for memory offset from instruction emulator (#5719)
* Add global spell check via the 'typos' GitHub action (#5720)
* Ensure probing reads are block size aligned (#5727)
* Multiple bug fixes around the latency counter for block devices
(#5712, #5750, #5762, #5763)
* Replace unsound `static mut` with `once_cell` (#5772)
### Contributors
Many thanks to everyone who has contributed to our release:
* Alyssa Ross <hi@alyssa.is>
* Anatol Belski <anbelski@linux.microsoft.com>
* Bo Chen <chen.bo@intel.com>
* Christian Blichmann <cblichmann@google.com>
* Jianyong Wu <jianyong.wu@arm.com>
* Jinank Jain <jinankjain@microsoft.com>
* Julian Stecklina <julian.stecklina@cyberus-technology.de>
* Omer Faruk Bayram <omer.faruk@sartura.hr>
* Philipp Schuster <philipp.schuster@cyberus-technology.de>
* Rob Bradford <rbradford@rivosinc.com>
* Ruslan Mstoi <ruslan.mstoi@intel.com>
* Thomas Barrett <tbarrett@crusoeenergy.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <foxywang@tencent.com>
* zhongbingnan <zhongbingnan@bytedance.com>
# v34.0
This release has been tracked in our [roadmap
@@ -873,7 +943,7 @@ binary with the detection of the hypervisor to use made at runtime.
### Notable Bug Fixes
* The prefetchable flag is preserved on BARs for VFIO devices (#4353, #4454)
* PCI Express capabilties for functionality we do not support are now filtered
* PCI Express capabilities for functionality we do not support are now filtered
out (#4456)
* GDB breakpoint support is more reliable (#4354, #4363)
* `SIGINT` and `SIGTERM` signals are now handled before the VM has booted
@@ -1228,10 +1298,10 @@ is now 5.15. (#3530)
### Notable Bug fixes
* Multiple fixes were made to the OpenAPI YAML file to match the implementaion (#3555,#3562)
* Multiple fixes were made to the OpenAPI YAML file to match the implementation (#3555,#3562)
* Avoid live migration deadlock when triggered during the kernel boot (#3585)
* Support live migration within firmware (#3586)
* Validate the `virtio-net` desciptor chain (#3548)
* Validate the `virtio-net` descriptor chain (#3548)
* `direct=on` (`O_DIRECT`) can now be used with a guest that makes unaligned accesses (e.g. firmware) (#3587)
### Contributors

View File

@@ -3,7 +3,7 @@
# When changing this file don't forget to update the tag name in the
# .github/workflows/docker-image.yaml file if doing multiple per day
FROM ubuntu:20.04 as dev
FROM ubuntu:22.04 as dev
ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.67.1"
@@ -43,7 +43,6 @@ RUN apt-get update \
socat \
dosfstools \
cpio \
python \
python3 \
python3-setuptools \
ntfs-3g \
@@ -130,17 +129,18 @@ RUN echo 'source $CARGO_HOME/env' >> "$HOME"/.bashrc \
RUN if [ "$TARGETARCH" = "amd64" ]; then \
git clone https://github.com/spdk/spdk \
&& cd spdk \
&& git checkout 6301f8915de32baed10dba1eebed556a6749211a \
&& git checkout ef8bcce58f3f02b79c0619a297e4f17e81e62b24 \
&& git submodule update --init \
&& apt-get update \
&& ./scripts/pkgdep.sh \
&& apt-get clean \
&& ./configure --with-vfio-user \
&& make -j $(nproc) TARGET_ARCHITECTURE=skylake \
&& rm -rf /usr/local/bin/spdk-nvme \
&& mkdir /usr/local/bin/spdk-nvme \
&& cp ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \
&& cp ./scripts/rpc.py /usr/local/bin/spdk-nvme \
&& cp -r ./scripts/rpc /usr/local/bin/spdk-nvme \
&& cp -f ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \
&& cp -f ./scripts/rpc.py /usr/local/bin/spdk-nvme \
&& cp -rf ./python /usr/local/bin \
&& cd .. && rm -rf spdk; fi
# install swtpm only for x86_64 arch

View File

@@ -1,7 +1,5 @@
#!/bin/bash
export BUILD_TARGET=${BUILD_TARGET-aarch64-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"

View File

@@ -7,7 +7,7 @@
CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
CTR_IMAGE_VERSION="20230804-0"
CTR_IMAGE_VERSION="20231220-0"
: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
DOCKER_RUNTIME="docker"
@@ -282,11 +282,10 @@ cmd_build() {
[ $build = "release" ] && cargo_args+=("--release")
cargo_args+=(--target "$target")
rustflags=""
rustflags="$RUSTFLAGS"
target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="-C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
target_cc="musl-gcc"
rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
fi
$DOCKER_RUNTIME run \
@@ -396,6 +395,12 @@ cmd_tests() {
process_volumes_args
target="$(uname -m)-unknown-linux-${libc}"
rustflags="$RUSTFLAGS"
target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
fi
if [[ "$unit" = true ]]; then
say "Running unit tests for $target..."
$DOCKER_RUNTIME run \
@@ -406,6 +411,8 @@ cmd_tests() {
--cap-add net_admin \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_unit_tests.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -424,7 +431,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
dbus-run-session ./scripts/run_integration_tests_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -443,7 +452,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_sgx.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -462,7 +473,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_vfio.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -481,7 +494,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_windows_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -500,7 +515,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_live_migration.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -519,7 +536,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_rate_limiter.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -538,7 +557,9 @@ cmd_tests() {
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env CH_LIBC="${libc}" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env RUST_BACKTRACE="${RUST_BACKTRACE}" \
"$CTR_IMAGE" \
./scripts/run_metrics.sh "$@" || fix_dir_perms $? || exit $?

View File

@@ -11,15 +11,16 @@ build_spdk_nvme() {
SPDK_DIR="$WORKLOADS_DIR/spdk"
SPDK_REPO="https://github.com/spdk/spdk.git"
SPDK_DEPLOY_DIR="/usr/local/bin/spdk-nvme"
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "6301f8915de32baed10dba1eebed556a6749211a"
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "ef8bcce58f3f02b79c0619a297e4f17e81e62b24"
if [ ! -f "$SPDK_DIR/.built" ]; then
pushd $SPDK_DIR
git submodule update --init
apt-get update
sed -i "/grpcio/d" scripts/pkgdep/debian.sh
./scripts/pkgdep.sh
./configure --with-vfio-user
chmod +x /usr/local/lib/python3.8/dist-packages/ninja/data/bin/ninja
chmod +x /usr/local/lib/python3.10/dist-packages/ninja/data/bin/ninja
make -j `nproc` || exit 1
touch .built
popd
@@ -29,14 +30,15 @@ build_spdk_nvme() {
fi
cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt
cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py
cp -r "$WORKLOADS_DIR/spdk/scripts/rpc" $SPDK_DEPLOY_DIR/rpc
cp -r "$WORKLOADS_DIR/spdk/python/spdk/" $SPDK_DEPLOY_DIR/
cp -r "$WORKLOADS_DIR/spdk/python" $SPDK_DEPLOY_DIR/../
}
build_virtiofsd() {
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.1.0 "220405d7a2606c92636d31992b5cb3036a41047b"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.8.0 "97ea7908fe7f9bc59916671a771bdcfaf4044b45"
if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then
pushd $VIRTIOFSD_DIR
@@ -156,12 +158,25 @@ update_workloads() {
popd
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v30.0"
LAST_RELEASE_VERSION="v34.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64"
CH_RELEASE_NAME="cloud-hypervisor-static-aarch64"
pushd $WORKLOADS_DIR
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1
chmod +x $CH_RELEASE_NAME
# Repeat a few times to workaround a random wget failure
WGET_RETRY_MAX=10
wget_retry=0
until [ "$wget_retry" -ge "$WGET_RETRY_MAX" ]
do
time wget $CH_RELEASE_URL -O "$CH_RELEASE_NAME" && break
wget_retry=$((wget_retry+1))
done
if [ $wget_retry -ge "$WGET_RETRY_MAX" ]; then
exit 1
else
chmod +x $CH_RELEASE_NAME
fi
popd
# Build custom kernel for guest VMs
@@ -231,12 +246,6 @@ if [ $RES -ne 0 ]; then
exit 1
fi
BUILD_TARGET="aarch64-unknown-linux-${CH_LIBC}"
if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then
export TARGET_CC="musl-gcc"
export RUSTFLAGS="-C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
fi
export RUST_BACKTRACE=1
cargo build --all --release --target $BUILD_TARGET

View File

@@ -4,8 +4,6 @@ set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
export BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -46,7 +44,7 @@ fi
popd
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v30.0"
LAST_RELEASE_VERSION="v34.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static"
CH_RELEASE_NAME="cloud-hypervisor-static"
pushd $WORKLOADS_DIR
@@ -60,11 +58,8 @@ if [ ! -f "$VMLINUX_IMAGE" ]; then
build_custom_linux
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi

View File

@@ -4,8 +4,6 @@ set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
export BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -47,11 +45,8 @@ popd
build_custom_linux
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi

View File

@@ -38,11 +38,8 @@ if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
popd
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi

View File

@@ -68,12 +68,9 @@ cp $FOCAL_OS_RAW_IMAGE $VFIO_DIR
cp $FW $VFIO_DIR
cp $VMLINUX_IMAGE $VFIO_DIR || exit 1
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
@@ -89,7 +86,12 @@ echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1
time cargo test "vfio::test_nvidia" -- --test-threads=1 ${test_binary_args[*]}
time cargo test "vfio::test_vfio" -- ${test_binary_args[*]}
RES=$?
if [ $RES -eq 0 ]; then
time cargo test "vfio::test_nvidia" -- --test-threads=1 ${test_binary_args[*]}
RES=$?
fi
exit $RES

View File

@@ -20,14 +20,6 @@ WIN_IMAGE_FILE="$WORKLOADS_DIR/$WIN_IMAGE_BASENAME"
OVMF_FW="$WORKLOADS_DIR/CLOUDHV_EFI.fd"
build_edk2
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then
export TARGET_CC="musl-gcc"
export RUSTFLAGS="-C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
fi
# Check if the images are present
if [[ ! -f ${WIN_IMAGE_FILE} || ! -f ${OVMF_FW} ]]; then
echo "Windows image/firmware not present in the host"

View File

@@ -22,11 +22,8 @@ if [ ! -f "$OVMF_FW" ]; then
popd
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi

View File

@@ -4,8 +4,6 @@ set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
export BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -124,7 +122,7 @@ if [ ! -f "$VIRTIOFSD" ]; then
pushd $WORKLOADS_DIR
git clone "https://gitlab.com/virtio-fs/virtiofsd.git" $VIRTIOFSD_DIR
pushd $VIRTIOFSD_DIR
git checkout v1.1.0
git checkout v1.8.0
time cargo build --release
cp target/release/virtiofsd $VIRTIOFSD || exit 1
popd
@@ -162,8 +160,6 @@ cp $FOCAL_OS_RAW_IMAGE $VFIO_DIR
cp $FW $VFIO_DIR
cp $VMLINUX_IMAGE $VFIO_DIR || exit 1
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
cargo build --features mshv --all --release --target $BUILD_TARGET
# We always copy a fresh version of our binary for our L2 guest.

View File

@@ -5,8 +5,6 @@ source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
export TEST_ARCH=$(uname -m)
export BUILD_TARGET=${BUILD_TARGET-${TEST_ARCH}-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -84,11 +82,8 @@ fi
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
build_custom_linux
BUILD_TARGET="${TEST_ARCH}-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "${TEST_ARCH}-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/${TEST_ARCH}-linux-musl/ -idirafter /usr/include/"
fi

View File

@@ -5,7 +5,6 @@ source $(dirname "$0")/test-util.sh
process_common_args "$@"
BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
cargo_args=("")
if [[ $hypervisor = "mshv" ]]; then
@@ -14,11 +13,6 @@ elif [[ $(uname -m) = "x86_64" ]]; then
cargo_args+=("--features tdx")
fi
if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then
export TARGET_CC="musl-gcc"
export RUSTFLAGS="-C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
fi
export RUST_BACKTRACE=1
cargo test --lib --bins --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1
cargo test --doc --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1

View File

@@ -394,7 +394,7 @@ fn rest_api_do_command(toplevel: &TopLevel, socket: &mut UnixStream) -> ApiResul
}
#[cfg(feature = "dbus_api")]
fn dbus_api_do_command(toplevel: &TopLevel, proxy: &mut DBusApi1ProxyBlocking<'_>) -> ApiResult {
fn dbus_api_do_command(toplevel: &TopLevel, proxy: &DBusApi1ProxyBlocking<'_>) -> ApiResult {
match toplevel.command {
SubCommandEnum::Boot(_) => proxy.api_vm_boot(),
SubCommandEnum::Delete(_) => proxy.api_vm_delete(),

View File

@@ -449,18 +449,6 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
(None, None)
};
#[cfg(feature = "dbus_api")]
let dbus_options = match (&toplevel.dbus_name, &toplevel.dbus_path) {
(Some(ref name), Some(ref path)) => Ok(Some(DBusApiOptions {
service_name: name.to_owned(),
object_path: path.to_owned(),
system_bus: toplevel.dbus_system_bus,
})),
(Some(_), None) => Err(Error::MissingDBusObjectPath),
(None, Some(_)) => Err(Error::MissingDBusServiceName),
(None, None) => Ok(None),
}?;
let (api_request_sender, api_request_receiver) = channel();
let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?;
@@ -530,31 +518,67 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
if let Some(ref monitor_config) = toplevel.event_monitor {
let mut parser = OptionParser::new();
parser.add("path").add("fd");
parser
.parse(monitor_config)
.map_err(Error::ParsingEventMonitor)?;
#[allow(unused_mut)]
let mut event_monitor = toplevel
.event_monitor
.as_ref()
.map(|monitor_config| {
let mut parser = OptionParser::new();
parser.add("path").add("fd");
parser
.parse(monitor_config)
.map_err(Error::ParsingEventMonitor)?;
let file = if parser.is_set("fd") {
let fd = parser
.convert("fd")
.map_err(Error::ParsingEventMonitor)?
.unwrap();
// SAFETY: fd is valid
unsafe { File::from_raw_fd(fd) }
} else if parser.is_set("path") {
std::fs::OpenOptions::new()
.write(true)
.create(true)
.open(parser.get("path").unwrap())
.map_err(Error::EventMonitorIo)?
} else {
return Err(Error::BareEventMonitor);
};
if parser.is_set("fd") {
let fd = parser
.convert("fd")
.map_err(Error::ParsingEventMonitor)?
.unwrap();
// SAFETY: fd is valid
Ok(Some(unsafe { File::from_raw_fd(fd) }))
} else if parser.is_set("path") {
Ok(Some(
std::fs::OpenOptions::new()
.write(true)
.create(true)
.open(parser.get("path").unwrap())
.map_err(Error::EventMonitorIo)?,
))
} else {
Err(Error::BareEventMonitor)
}
})
.transpose()?
.map(|event_monitor_file| {
event_monitor::set_monitor(event_monitor_file).map_err(Error::EventMonitorIo)
})
.transpose()?;
let monitor = event_monitor::set_monitor(file).map_err(Error::EventMonitorIo)?;
#[cfg(feature = "dbus_api")]
let dbus_options = match (&toplevel.dbus_name, &toplevel.dbus_path) {
(Some(ref name), Some(ref path)) => {
// monitor is either set (file based) or not.
// if it's not set, create one without file support.
let mut monitor = match event_monitor.take() {
Some(monitor) => monitor,
None => event_monitor::set_monitor(None).map_err(Error::EventMonitorIo)?,
};
let options = DBusApiOptions {
service_name: name.to_owned(),
object_path: path.to_owned(),
system_bus: toplevel.dbus_system_bus,
event_monitor_rx: monitor.subscribe(),
};
event_monitor = Some(monitor);
Ok(Some(options))
}
(Some(_), None) => Err(Error::MissingDBusObjectPath),
(None, Some(_)) => Err(Error::MissingDBusServiceName),
(None, None) => Ok(None),
}?;
if let Some(monitor) = event_monitor {
vmm::start_event_monitor_thread(
monitor,
&seccomp_action,
@@ -638,6 +662,9 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
}
fn main() {
#[cfg(all(feature = "tdx", feature = "sev_snp"))]
compile_error!("Feature 'tdx' and 'sev_snp' are mutually exclusive.");
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();

View File

@@ -47,7 +47,7 @@ write_files:
# 1G ram requires 512 pages
echo 512 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
/mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules root=/dev/vda1 VFIOTAG" --disk path=/mnt/focal-server-cloudimg-amd64-custom-20210609-0.raw path=/mnt/cloudinit.img --cpus boot=1 --memory size=512M,hotplug_size=1G,hugepages=on --device path=/sys/bus/pci/devices/0000:00:05.0/ path=/sys/bus/pci/devices/0000:00:07.0/ path=/sys/bus/pci/devices/0000:00:08.0/ --api-socket /tmp/ch_api.sock
/mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules root=/dev/vda1 VFIOTAG" --disk path=/mnt/focal-server-cloudimg-amd64-custom-20210609-0.raw --disk path=/mnt/cloudinit.img --cpus boot=1 --memory size=512M,hotplug_size=1G,hugepages=on --device path=/sys/bus/pci/devices/0000:00:05.0/ --device path=/sys/bus/pci/devices/0000:00:07.0/ --device path=/sys/bus/pci/devices/0000:00:08.0/ --api-socket /tmp/ch_api.sock
-
path: /etc/systemd/system/notify-booted.service

View File

@@ -7,10 +7,10 @@ edition = "2021"
[dependencies]
dirs = "5.0.0"
epoll = "4.3.3"
libc = "0.2.139"
libc = "0.2.147"
once_cell = "1.18.0"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde_json = "1.0.96"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
ssh2 = { version = "0.9.4", features = ["vendored-openssl"] }
vmm-sys-util = "0.11.0"
wait-timeout = "0.2.0"

View File

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

View File

@@ -888,7 +888,7 @@ fn check_sequential_events_exact(expected_events: &[&MetaEvent], event_file: &st
true
}
// Return true if events from the input 'expected_events' are matched exactly
// Return true if events from the input 'latest_events' are matched exactly
// with the most recent events from the 'event_file'
fn check_latest_events_exact(latest_events: &[&MetaEvent], event_file: &str) -> bool {
let json_events = parse_event_file(event_file);
@@ -1844,7 +1844,7 @@ fn test_memory_mergeable(mergeable: bool) {
"mergeable=off"
};
// We are assuming the rest of the system in our CI is not using mergeable memeory
// We are assuming the rest of the system in our CI is not using mergeable memory
let ksm_ps_init = get_ksm_pages_shared();
assert!(ksm_ps_init == 0);
@@ -3297,16 +3297,19 @@ mod common_parallel {
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_default() {
test_vhost_user_blk(2, false, false, Some(&prepare_vubd))
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_readonly() {
test_vhost_user_blk(1, true, false, Some(&prepare_vubd))
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_direct() {
test_vhost_user_blk(1, false, true, Some(&prepare_vubd))
}
@@ -3823,7 +3826,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let serial_path = guest.tmp_dir.as_path().join("/tmp/serial-output");
let serial_path = guest.tmp_dir.as_path().join("serial-output");
#[cfg(target_arch = "x86_64")]
let console_str: &str = "console=ttyS0";
#[cfg(target_arch = "aarch64")]
@@ -4022,7 +4025,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let console_path = guest.tmp_dir.as_path().join("/tmp/console-output");
let console_path = guest.tmp_dir.as_path().join("console-output");
let mut child = GuestCommand::new(&guest)
.args(["--cpus", "boot=1"])
.args(["--memory", "size=512M"])
@@ -4070,7 +4073,6 @@ mod common_parallel {
#[test]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
#[ignore = "See #4324"]
// The VFIO integration test starts cloud-hypervisor guest with 3 TAP
// backed networking interfaces, bound through a simple bridge on the host.
// So if the nested cloud-hypervisor succeeds in getting a directly
@@ -4084,8 +4086,8 @@ mod common_parallel {
fn test_vfio() {
setup_vfio_network_interfaces();
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new_from_ip_range(Box::new(focal), "172.18", 0);
let jammy = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string());
let guest = Guest::new_from_ip_range(Box::new(jammy), "172.18", 0);
let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads");
@@ -4848,12 +4850,13 @@ mod common_parallel {
.args(["--memory", format!("size={guest_memory_size_kb}K").as_str()])
.args(["--kernel", kernel_path.to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_net()
.default_disks()
.capture_output()
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(20, 0));
guest.wait_vm_boot(None).unwrap();
let r = std::panic::catch_unwind(|| {
let overhead = get_vmm_overhead(child.id(), guest_memory_size_kb);
@@ -6175,7 +6178,7 @@ mod common_parallel {
guest.ssh_command("screen -dmS reboot sh -c \"sleep 5; echo s | tee /proc/sysrq-trigger; echo c | sudo tee /proc/sysrq-trigger\"").unwrap();
// Allow some time for the watchdog to trigger (max 30s) and reboot to happen
guest.wait_vm_boot(Some(50)).unwrap();
// Check a reboot is triggerred by the watchdog
// Check a reboot is triggered by the watchdog
expected_reboot_count += 1;
assert_eq!(get_reboot_count(&guest), expected_reboot_count);
@@ -6853,6 +6856,7 @@ mod common_parallel {
#[test]
#[cfg(target_arch = "x86_64")]
#[ignore = "See #5756"]
fn test_vdpa_net() {
// Before trying to run the test, verify the vdpa_sim_net module is correctly loaded.
if !exec_host_command_status("lsmod | grep vdpa_sim_net").success() {
@@ -7809,6 +7813,7 @@ mod windows {
}
#[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug() {
@@ -7904,6 +7909,7 @@ mod windows {
}
#[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug_multi() {
@@ -8787,13 +8793,13 @@ mod live_migration {
);
});
// Check and report any errors occured during the live-migration
// Check and report any errors occurred during the live-migration
if r.is_err() {
print_and_panic(
src_child,
dest_child,
None,
"Error occured during live-migration",
"Error occurred during live-migration",
);
}
@@ -8961,13 +8967,13 @@ mod live_migration {
);
});
// Check and report any errors occured during the live-migration
// Check and report any errors occurred during the live-migration
if r.is_err() {
print_and_panic(
src_child,
dest_child,
None,
"Error occured during live-migration",
"Error occurred during live-migration",
);
}
@@ -9187,13 +9193,13 @@ mod live_migration {
);
});
// Check and report any errors occured during the live-migration
// Check and report any errors occurred during the live-migration
if r.is_err() {
print_and_panic(
src_child,
dest_child,
None,
"Error occured during live-migration",
"Error occurred during live-migration",
);
}
@@ -9406,13 +9412,13 @@ mod live_migration {
);
});
// Check and report any errors occured during the live-migration
// Check and report any errors occurred during the live-migration
if r.is_err() {
print_and_panic(
src_child,
dest_child,
None,
"Error occured during live-migration",
"Error occurred during live-migration",
);
}
@@ -9447,7 +9453,7 @@ mod live_migration {
guest.ssh_command("screen -dmS reboot sh -c \"sleep 5; echo s | tee /proc/sysrq-trigger; echo c | sudo tee /proc/sysrq-trigger\"").unwrap();
// Allow some time for the watchdog to trigger (max 30s) and reboot to happen
guest.wait_vm_boot(Some(50)).unwrap();
// Check a reboot is triggerred by the watchdog
// Check a reboot is triggered by the watchdog
expected_reboot_count += 1;
assert_eq!(get_reboot_count(&guest), expected_reboot_count);
@@ -9516,13 +9522,13 @@ mod live_migration {
);
});
// Check and report any errors occured during the live-migration
// Check and report any errors occurred during the live-migration
if r.is_err() {
print_and_panic(
src_child,
dest_child,
Some(ovs_child),
"Error occured during live-migration",
"Error occurred during live-migration",
);
}
@@ -9667,6 +9673,7 @@ mod live_migration {
// Require to run ovs-dpdk tests sequentially because they rely on the same ovs-dpdk setup
#[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
fn test_live_migration_ovs_dpdk() {
@@ -9681,6 +9688,7 @@ mod live_migration {
}
#[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
fn test_live_upgrade_ovs_dpdk() {

View File

@@ -154,7 +154,7 @@ impl Ptm for PtmCap {
}
}
/* GET_TPMESTABLISHED Reponse */
/* GET_TPMESTABLISHED Response */
#[derive(Debug)]
pub struct PtmEstResp {
pub bit: u8,

View File

@@ -5,11 +5,11 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
once_cell = "1.18.0"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde_json = "1.0.96"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
[features]
tracing = []

View File

@@ -80,7 +80,7 @@ impl Tracer {
if let Some(depth) = self.thread_depths.get_mut(thread_name) {
depth.fetch_sub(1, Ordering::SeqCst);
} else {
panic!("Unmatched decreas for thread: {thread_name}");
panic!("Unmatched decrease for thread: {thread_name}");
}
}

View File

@@ -10,13 +10,13 @@ argh = "0.1.9"
block = { path = "../block" }
env_logger = "0.10.0"
epoll = "4.3.3"
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
option_parser = { path = "../option_parser" }
vhost = { version = "0.7.0", features = ["vhost-user-slave"] }
vhost-user-backend = "0.9.0"
vhost = { version = "0.8.1", features = ["vhost-user-slave"] }
vhost-user-backend = "0.10.1"
virtio-bindings = "0.2.0"
virtio-queue = "0.8.0"
vm-memory = "0.11.0"
virtio-queue = "0.9.0"
vm-memory = "0.12.2"
vmm-sys-util = "0.11.0"

View File

@@ -9,7 +9,7 @@
// SPDX-License-Identifier: (Apache-2.0 AND BSD-3-Clause)
use block::{
build_disk_image_id,
build_serial,
qcow::{self, ImageType, QcowFile},
Request, VirtioBlockConfig,
};
@@ -90,7 +90,7 @@ impl convert::From<Error> for io::Error {
struct VhostUserBlkThread {
disk_image: Arc<Mutex<dyn DiskFile>>,
disk_image_id: Vec<u8>,
serial: Vec<u8>,
disk_nsectors: u64,
event_idx: bool,
kill_evt: EventFd,
@@ -101,14 +101,14 @@ struct VhostUserBlkThread {
impl VhostUserBlkThread {
fn new(
disk_image: Arc<Mutex<dyn DiskFile>>,
disk_image_id: Vec<u8>,
serial: Vec<u8>,
disk_nsectors: u64,
writeback: Arc<AtomicBool>,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
) -> Result<Self> {
Ok(VhostUserBlkThread {
disk_image,
disk_image_id,
serial,
disk_nsectors,
event_idx: false,
kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?,
@@ -137,7 +137,7 @@ impl VhostUserBlkThread {
&mut self.disk_image.lock().unwrap().deref_mut(),
self.disk_nsectors,
desc_chain.memory(),
&self.disk_image_id,
&self.serial,
) {
Ok(l) => {
len = l;
@@ -222,7 +222,7 @@ impl VhostUserBlkBackend {
let image: File = options.open(&image_path).unwrap();
let mut raw_img: qcow::RawFile = qcow::RawFile::new(image, direct);
let image_id = build_disk_image_id(&PathBuf::from(&image_path));
let serial = build_serial(&PathBuf::from(&image_path));
let image_type = qcow::detect_image_type(&mut raw_img).unwrap();
let image = match image_type {
ImageType::Raw => Arc::new(Mutex::new(raw_img)) as Arc<Mutex<dyn DiskFile>>,
@@ -250,7 +250,7 @@ impl VhostUserBlkBackend {
for i in 0..num_queues {
let thread = Mutex::new(VhostUserBlkThread::new(
image.clone(),
image_id.clone(),
serial.clone(),
nsectors,
writeback.clone(),
mem.clone(),

View File

@@ -9,13 +9,13 @@ build = "../build.rs"
argh = "0.1.9"
env_logger = "0.10.0"
epoll = "4.3.3"
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" }
vhost = { version = "0.7.0", features = ["vhost-user-slave"] }
vhost-user-backend = "0.9.0"
vhost = { version = "0.8.1", features = ["vhost-user-slave"] }
vhost-user-backend = "0.10.1"
virtio-bindings = "0.2.0"
vm-memory = "0.11.0"
vm-memory = "0.12.2"
vmm-sys-util = "0.11.0"

View File

@@ -8,31 +8,31 @@ edition = "2021"
default = []
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
arc-swap = "1.5.1"
block = { path = "../block" }
byteorder = "1.4.3"
epoll = "4.3.3"
event_monitor = { path = "../event_monitor" }
libc = "0.2.139"
libc = "0.2.147"
log = "0.4.17"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci" }
rate_limiter = { path = "../rate_limiter" }
seccompiler = "0.3.0"
serde = { version = "1.0.164", features = ["derive"] }
serde_json = "1.0.96"
serde = { version = "1.0.168", features = ["derive"] }
serde_json = "1.0.107"
serial_buffer = { path = "../serial_buffer" }
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vhost = { version = "0.7.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] }
vhost = { version = "0.8.1", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] }
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.8.0"
virtio-queue = "0.9.0"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.11.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"

View File

@@ -29,6 +29,7 @@ use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_queue::{Queue, QueueT};
use vm_allocator::page_size::{align_page_size_down, get_page_size};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryError, GuestMemoryRegion,
@@ -94,6 +95,50 @@ pub struct VirtioBalloonConfig {
actual: u32,
}
#[derive(Clone, Debug)]
struct PartiallyBalloonedPage {
addr: u64,
bitmap: Vec<u64>,
page_size: u64,
}
impl PartiallyBalloonedPage {
fn new() -> Self {
let page_size = get_page_size();
let len = ((page_size >> VIRTIO_BALLOON_PFN_SHIFT) + 63) / 64;
// Initial each padding bit as 1 in bitmap.
let mut bitmap = vec![0_u64; len as usize];
let pad_num = len * 64 - (page_size >> VIRTIO_BALLOON_PFN_SHIFT);
bitmap[(len - 1) as usize] = !((1 << (64 - pad_num)) - 1);
Self {
addr: 0,
bitmap,
page_size,
}
}
fn pfn_match(&self, addr: u64) -> bool {
self.addr == addr & !(self.page_size - 1)
}
fn bitmap_full(&self) -> bool {
self.bitmap.iter().all(|b| *b == u64::MAX)
}
fn set_bit(&mut self, addr: u64) {
let addr_offset = (addr % self.page_size) >> VIRTIO_BALLOON_PFN_SHIFT;
self.bitmap[(addr_offset / 64) as usize] |= 1 << (addr_offset % 64);
}
fn reset(&mut self) {
let len = ((self.page_size >> VIRTIO_BALLOON_PFN_SHIFT) + 63) / 64;
self.addr = 0;
self.bitmap = vec![0; len as usize];
let pad_num = len * 64 - (self.page_size >> VIRTIO_BALLOON_PFN_SHIFT);
self.bitmap[(len - 1) as usize] = !((1 << (64 - pad_num)) - 1);
}
}
const CONFIG_ACTUAL_OFFSET: u64 = 4;
const CONFIG_ACTUAL_SIZE: usize = 4;
@@ -109,6 +154,7 @@ struct BalloonEpollHandler {
reporting_queue_evt: Option<EventFd>,
kill_evt: EventFd,
pause_evt: EventFd,
pbp: Option<PartiallyBalloonedPage>,
}
impl BalloonEpollHandler {
@@ -165,6 +211,43 @@ impl BalloonEpollHandler {
Self::advise_memory_range(memory, range_base, range_len, libc::MADV_DONTNEED)
}
fn release_memory_range_4k(
pbp: &mut Option<PartiallyBalloonedPage>,
memory: &GuestMemoryMmap,
pfn: u32,
) -> result::Result<(), Error> {
let range_base = GuestAddress((pfn as u64) << VIRTIO_BALLOON_PFN_SHIFT);
let range_len = 1 << VIRTIO_BALLOON_PFN_SHIFT;
let page_size: u64 = get_page_size();
if page_size == 1 << VIRTIO_BALLOON_PFN_SHIFT {
return Self::release_memory_range(memory, range_base, range_len);
}
if pbp.is_none() {
*pbp = Some(PartiallyBalloonedPage::new());
}
if !pbp.as_ref().unwrap().pfn_match(range_base.0) {
// We are trying to free memory region in a different pfn with current pbp. Flush pbp.
pbp.as_mut().unwrap().reset();
pbp.as_mut().unwrap().addr = align_page_size_down(range_base.0);
}
pbp.as_mut().unwrap().set_bit(range_base.0);
if pbp.as_ref().unwrap().bitmap_full() {
Self::release_memory_range(
memory,
vm_memory::GuestAddress(pbp.as_ref().unwrap().addr),
page_size as usize,
)?;
pbp.as_mut().unwrap().reset();
}
Ok(())
}
fn process_queue(&mut self, queue_index: usize) -> result::Result<(), Error> {
let mut used_descs = false;
while let Some(mut desc_chain) =
@@ -193,18 +276,18 @@ impl BalloonEpollHandler {
.map_err(Error::GuestMemory)?;
offset += data_chunk_size as u64;
let range_base = GuestAddress((pfn as u64) << VIRTIO_BALLOON_PFN_SHIFT);
let range_len = 1 << VIRTIO_BALLOON_PFN_SHIFT;
match queue_index {
0 => {
Self::release_memory_range(desc_chain.memory(), range_base, range_len)?;
Self::release_memory_range_4k(&mut self.pbp, desc_chain.memory(), pfn)?;
}
1 => {
let page_size = get_page_size() as usize;
let rbase = align_page_size_down((pfn as u64) << VIRTIO_BALLOON_PFN_SHIFT);
Self::advise_memory_range(
desc_chain.memory(),
range_base,
range_len,
vm_memory::GuestAddress(rbase),
page_size,
libc::MADV_WILLNEED,
)?;
}
@@ -543,6 +626,7 @@ impl VirtioDevice for Balloon {
reporting_queue_evt,
kill_evt,
pause_evt,
pbp: None,
};
let paused = self.common.paused.clone();

View File

@@ -20,7 +20,7 @@ use crate::GuestMemoryMmap;
use crate::VirtioInterrupt;
use anyhow::anyhow;
use block::{
async_io::AsyncIo, async_io::AsyncIoError, async_io::DiskFile, build_disk_image_id, Request,
async_io::AsyncIo, async_io::AsyncIoError, async_io::DiskFile, build_serial, Request,
RequestType, VirtioBlockConfig,
};
use rate_limiter::{RateLimiter, TokenType};
@@ -106,13 +106,13 @@ impl Default for BlockCounters {
read_bytes: Arc::new(AtomicU64::new(0)),
read_ops: Arc::new(AtomicU64::new(0)),
read_latency_min: Arc::new(AtomicU64::new(u64::MAX)),
read_latency_max: Arc::new(AtomicU64::new(0)),
read_latency_avg: Arc::new(AtomicU64::new(0)),
read_latency_max: Arc::new(AtomicU64::new(u64::MAX)),
read_latency_avg: Arc::new(AtomicU64::new(u64::MAX)),
write_bytes: Arc::new(AtomicU64::new(0)),
write_ops: Arc::new(AtomicU64::new(0)),
write_latency_min: Arc::new(AtomicU64::new(u64::MAX)),
write_latency_max: Arc::new(AtomicU64::new(0)),
write_latency_avg: Arc::new(AtomicU64::new(0)),
write_latency_max: Arc::new(AtomicU64::new(u64::MAX)),
write_latency_avg: Arc::new(AtomicU64::new(u64::MAX)),
}
}
}
@@ -124,7 +124,7 @@ struct BlockEpollHandler {
disk_image: Box<dyn AsyncIo>,
disk_nsectors: u64,
interrupt_cb: Arc<dyn VirtioInterrupt>,
disk_image_id: Vec<u8>,
serial: Vec<u8>,
kill_evt: EventFd,
pause_evt: EventFd,
writeback: Arc<AtomicBool>,
@@ -205,7 +205,7 @@ impl BlockEpollHandler {
desc_chain.memory(),
self.disk_nsectors,
self.disk_image.as_mut(),
&self.disk_image_id,
&self.serial,
desc_chain.head_index() as u64,
)
.map_err(Error::RequestExecuting)?
@@ -281,10 +281,12 @@ impl BlockEpollHandler {
request.complete_async().map_err(Error::RequestCompleting)?;
let latency = request.start.elapsed().as_micros() as u64;
let read_ops_last = self.counters.read_ops.load(Ordering::Relaxed) as i64;
let write_ops_last = self.counters.write_ops.load(Ordering::Relaxed) as i64;
let mut read_avg = self.counters.read_latency_avg.load(Ordering::Relaxed) as i64;
let mut write_avg = self.counters.write_latency_avg.load(Ordering::Relaxed) as i64;
let read_ops_last = self.counters.read_ops.load(Ordering::Relaxed);
let write_ops_last = self.counters.write_ops.load(Ordering::Relaxed);
let read_max = self.counters.read_latency_max.load(Ordering::Relaxed);
let write_max = self.counters.write_latency_max.load(Ordering::Relaxed);
let mut read_avg = self.counters.read_latency_avg.load(Ordering::Relaxed);
let mut write_avg = self.counters.write_latency_avg.load(Ordering::Relaxed);
let (status, len) = if result >= 0 {
match request.request_type {
RequestType::In => {
@@ -297,14 +299,24 @@ impl BlockEpollHandler {
.read_latency_min
.store(latency, Ordering::Relaxed);
}
if latency > self.counters.read_latency_max.load(Ordering::Relaxed) {
if latency > read_max || read_max == u64::MAX {
self.counters
.read_latency_max
.store(latency, Ordering::Relaxed);
}
read_avg = read_avg
+ ((latency * LATENCY_SCALE) as i64 - read_avg)
/ (read_ops_last + read_ops.0 as i64);
// Special case the first real latency report
read_avg = if read_avg == u64::MAX {
latency * LATENCY_SCALE
} else {
// Cumulative average is guaranteed to be
// positive if being calculated properly
(read_avg as i64
+ ((latency * LATENCY_SCALE) as i64 - read_avg as i64)
/ (read_ops_last + read_ops.0) as i64)
.try_into()
.unwrap()
};
}
RequestType::Out => {
if !request.writeback {
@@ -319,25 +331,35 @@ impl BlockEpollHandler {
.write_latency_min
.store(latency, Ordering::Relaxed);
}
if latency > self.counters.write_latency_max.load(Ordering::Relaxed) {
if latency > write_max || write_max == u64::MAX {
self.counters
.write_latency_max
.store(latency, Ordering::Relaxed);
}
write_avg = write_avg
+ ((latency * LATENCY_SCALE) as i64 - write_avg)
/ (write_ops_last + write_ops.0 as i64);
// Special case the first real latency report
write_avg = if write_avg == u64::MAX {
latency * LATENCY_SCALE
} else {
// Cumulative average is guaranteed to be
// positive if being calculated properly
(write_avg as i64
+ ((latency * LATENCY_SCALE) as i64 - write_avg as i64)
/ (write_ops_last + write_ops.0) as i64)
.try_into()
.unwrap()
}
}
_ => {}
}
self.counters
.read_latency_avg
.store(read_avg as u64, Ordering::Relaxed);
.store(read_avg, Ordering::Relaxed);
self.counters
.write_latency_avg
.store(write_avg as u64, Ordering::Relaxed);
.store(write_avg, Ordering::Relaxed);
(VIRTIO_BLK_S_OK, result as u32)
} else {
@@ -488,6 +510,7 @@ pub struct Block {
rate_limiter_config: Option<RateLimiterConfig>,
exit_evt: EventFd,
read_only: bool,
serial: Vec<u8>,
}
#[derive(Versionize)]
@@ -512,6 +535,7 @@ impl Block {
iommu: bool,
num_queues: usize,
queue_size: u16,
serial: Option<String>,
seccomp_action: SeccompAction,
rate_limiter_config: Option<RateLimiterConfig>,
exit_evt: EventFd,
@@ -592,6 +616,8 @@ impl Block {
(disk_nsectors, avail_features, 0, config, false)
};
let serial = serial.map(Vec::from).unwrap_or(build_serial(&disk_path));
Ok(Block {
common: VirtioCommon {
device_type: VirtioDeviceType::Block as u32,
@@ -614,6 +640,7 @@ impl Block {
rate_limiter_config,
exit_evt,
read_only,
serial,
})
}
@@ -710,7 +737,6 @@ impl VirtioDevice for Block {
) -> ActivateResult {
self.common.activate(&queues, &interrupt_cb)?;
let disk_image_id = build_disk_image_id(&self.disk_path);
self.update_writeback();
let mut epoll_threads = Vec::new();
@@ -738,7 +764,7 @@ impl VirtioDevice for Block {
})?,
disk_nsectors: self.disk_nsectors,
interrupt_cb: interrupt_cb.clone(),
disk_image_id: disk_image_id.clone(),
serial: self.serial.clone(),
kill_evt,
pause_evt,
writeback: self.writeback.clone(),

View File

@@ -97,7 +97,7 @@ impl VirtioPciCommonConfig {
&mut self,
offset: u64,
data: &mut [u8],
queues: &mut [Queue],
queues: &[Queue],
device: Arc<Mutex<dyn VirtioDevice>>,
) {
assert!(data.len() <= 8);
@@ -385,35 +385,35 @@ mod tests {
// Can set all bits of driver_status.
regs.write(0x14, &[0x55], &mut queues, dev.clone());
let mut read_back = vec![0x00];
regs.read(0x14, &mut read_back, &mut queues, dev.clone());
regs.read(0x14, &mut read_back, &queues, dev.clone());
assert_eq!(read_back[0], 0x55);
// The config generation register is read only.
regs.write(0x15, &[0xaa], &mut queues, dev.clone());
let mut read_back = vec![0x00];
regs.read(0x15, &mut read_back, &mut queues, dev.clone());
regs.read(0x15, &mut read_back, &queues, dev.clone());
assert_eq!(read_back[0], 0x55);
// Device features is read-only and passed through from the device.
regs.write(0x04, &[0, 0, 0, 0], &mut queues, dev.clone());
let mut read_back = vec![0, 0, 0, 0];
regs.read(0x04, &mut read_back, &mut queues, dev.clone());
regs.read(0x04, &mut read_back, &queues, dev.clone());
assert_eq!(LittleEndian::read_u32(&read_back), DUMMY_FEATURES as u32);
// Feature select registers are read/write.
regs.write(0x00, &[1, 2, 3, 4], &mut queues, dev.clone());
let mut read_back = vec![0, 0, 0, 0];
regs.read(0x00, &mut read_back, &mut queues, dev.clone());
regs.read(0x00, &mut read_back, &queues, dev.clone());
assert_eq!(LittleEndian::read_u32(&read_back), 0x0403_0201);
regs.write(0x08, &[1, 2, 3, 4], &mut queues, dev.clone());
let mut read_back = vec![0, 0, 0, 0];
regs.read(0x08, &mut read_back, &mut queues, dev.clone());
regs.read(0x08, &mut read_back, &queues, dev.clone());
assert_eq!(LittleEndian::read_u32(&read_back), 0x0403_0201);
// 'queue_select' can be read and written.
regs.write(0x16, &[0xaa, 0x55], &mut queues, dev.clone());
let mut read_back = vec![0x00, 0x00];
regs.read(0x16, &mut read_back, &mut queues, dev);
regs.read(0x16, &mut read_back, &queues, dev);
assert_eq!(read_back[0], 0xaa);
assert_eq!(read_back[1], 0x55);
}

View File

@@ -1116,7 +1116,7 @@ impl PciDevice for VirtioPciDevice {
o if o < COMMON_CONFIG_BAR_OFFSET + COMMON_CONFIG_SIZE => self.common_config.read(
o - COMMON_CONFIG_BAR_OFFSET,
data,
&mut self.queues,
&self.queues,
self.device.clone(),
),
o if (ISR_CONFIG_BAR_OFFSET..ISR_CONFIG_BAR_OFFSET + ISR_CONFIG_SIZE).contains(&o) => {

View File

@@ -123,7 +123,7 @@ pub enum Error {
VhostUserSetLogBase(VhostError),
#[error("Invalid used address")]
UsedAddress,
#[error("Invalid features provided from vhost-user backe")]
#[error("Invalid features provided from vhost-user backend")]
InvalidFeatures,
#[error("Missing file descriptor for the region")]
MissingRegionFd,

View File

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

View File

@@ -213,9 +213,7 @@ mod tests {
fn test_push_wrap() {
let mut txbuf = TxBuf::new();
let mut sink = TestSink::new();
let mut tmp: Vec<u8> = Vec::new();
tmp.resize(TxBuf::SIZE - 2, 0);
let tmp: Vec<u8> = vec![0; TxBuf::SIZE - 2];
txbuf.push(tmp.as_slice()).unwrap();
txbuf.flush_to(&mut sink).unwrap();
sink.clear();

View File

@@ -23,7 +23,7 @@ use super::defs;
use super::{Result, VsockError};
use crate::get_host_address_range;
use virtio_queue::DescriptorChain;
use vm_memory::GuestMemory;
use vm_memory::{Address, GuestMemory};
use vm_virtio::{AccessPlatform, Translatable};
// The vsock packet header is defined by the C struct:
@@ -133,7 +133,7 @@ impl VsockPacket {
hdr: get_host_address_range(
desc_chain.memory(),
head.addr()
.translate_gva(access_platform, head.len() as usize),
.translate_gva(access_platform, VSOCK_PKT_HDR_SIZE),
VSOCK_PKT_HDR_SIZE,
)
.ok_or(VsockError::GuestMemory)?,
@@ -152,32 +152,46 @@ impl VsockPacket {
return Err(VsockError::InvalidPktLen(pkt.len()));
}
// If the packet header showed a non-zero length, there should be a data descriptor here.
let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?;
// Prior to Linux v6.3 there are two descriptors
if head.has_next() {
let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?;
// TX data should be read-only.
if buf_desc.is_write_only() {
return Err(VsockError::UnreadableDescriptor);
// TX data should be read-only.
if buf_desc.is_write_only() {
return Err(VsockError::UnreadableDescriptor);
}
// The data buffer should be large enough to fit the size of the data, as described by
// the header descriptor.
if buf_desc.len() < pkt.len() {
return Err(VsockError::BufDescTooSmall);
}
let buf_size = buf_desc.len() as usize;
pkt.buf_size = buf_size;
pkt.buf = Some(
get_host_address_range(
desc_chain.memory(),
buf_desc.addr().translate_gva(access_platform, buf_size),
pkt.buf_size,
)
.ok_or(VsockError::GuestMemory)?,
);
} else {
let buf_size: usize = head.len() as usize - VSOCK_PKT_HDR_SIZE;
pkt.buf_size = buf_size;
pkt.buf = Some(
get_host_address_range(
desc_chain.memory(),
head.addr()
.checked_add(VSOCK_PKT_HDR_SIZE as u64)
.unwrap()
.translate_gva(access_platform, buf_size),
buf_size,
)
.ok_or(VsockError::GuestMemory)?,
);
}
// The data buffer should be large enough to fit the size of the data, as described by
// the header descriptor.
if buf_desc.len() < pkt.len() {
return Err(VsockError::BufDescTooSmall);
}
pkt.buf_size = buf_desc.len() as usize;
pkt.buf = Some(
get_host_address_range(
desc_chain.memory(),
buf_desc
.addr()
.translate_gva(access_platform, buf_desc.len() as usize),
pkt.buf_size,
)
.ok_or(VsockError::GuestMemory)?,
);
Ok(pkt)
}
@@ -207,33 +221,53 @@ impl VsockPacket {
return Err(VsockError::HdrDescTooSmall(head.len()));
}
// All RX descriptor chains should have a header and a data descriptor.
if !head.has_next() {
return Err(VsockError::BufDescMissing);
}
let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?;
let buf_size = buf_desc.len() as usize;
// Prior to Linux v6.3 there are two descriptors
if head.has_next() {
let buf_desc = desc_chain.next().ok_or(VsockError::BufDescMissing)?;
let buf_size = buf_desc.len() as usize;
Ok(Self {
hdr: get_host_address_range(
desc_chain.memory(),
head.addr()
.translate_gva(access_platform, head.len() as usize),
VSOCK_PKT_HDR_SIZE,
)
.ok_or(VsockError::GuestMemory)?,
buf: Some(
get_host_address_range(
Ok(Self {
hdr: get_host_address_range(
desc_chain.memory(),
buf_desc
.addr()
.translate_gva(access_platform, buf_desc.len() as usize),
buf_size,
head.addr()
.translate_gva(access_platform, VSOCK_PKT_HDR_SIZE),
VSOCK_PKT_HDR_SIZE,
)
.ok_or(VsockError::GuestMemory)?,
),
buf_size,
})
buf: Some(
get_host_address_range(
desc_chain.memory(),
buf_desc.addr().translate_gva(access_platform, buf_size),
buf_size,
)
.ok_or(VsockError::GuestMemory)?,
),
buf_size,
})
} else {
let buf_size: usize = head.len() as usize - VSOCK_PKT_HDR_SIZE;
Ok(Self {
hdr: get_host_address_range(
desc_chain.memory(),
head.addr()
.translate_gva(access_platform, VSOCK_PKT_HDR_SIZE),
VSOCK_PKT_HDR_SIZE,
)
.ok_or(VsockError::GuestMemory)?,
buf: Some(
get_host_address_range(
desc_chain.memory(),
head.addr()
.checked_add(VSOCK_PKT_HDR_SIZE as u64)
.unwrap()
.translate_gva(access_platform, buf_size),
buf_size,
)
.ok_or(VsockError::GuestMemory)?,
),
buf_size,
})
}
}
/// Provides in-place, byte-slice, access to the vsock packet header.
@@ -503,16 +537,6 @@ mod tests {
expect_asm_error!(tx, test_ctx, handler_ctx, VsockError::InvalidPktLen(_));
}
// Test case:
// - packet header advertises some data length; and
// - the data descriptor is missing.
{
create_context!(test_ctx, handler_ctx);
set_pkt_len(1024, &handler_ctx.guest_txvq.dtable[0], &test_ctx.mem);
handler_ctx.guest_txvq.dtable[0].flags.set(0);
expect_asm_error!(tx, test_ctx, handler_ctx, VsockError::BufDescMissing);
}
// Test case: error on write-only buf descriptor.
{
create_context!(test_ctx, handler_ctx);
@@ -568,15 +592,6 @@ mod tests {
.set(VSOCK_PKT_HDR_SIZE as u32 - 1);
expect_asm_error!(rx, test_ctx, handler_ctx, VsockError::HdrDescTooSmall(_));
}
// Test case: RX descriptor chain is missing the packet buffer descriptor.
{
create_context!(test_ctx, handler_ctx);
handler_ctx.guest_rxvq.dtable[0]
.flags
.set(VRING_DESC_F_WRITE.try_into().unwrap());
expect_asm_error!(rx, test_ctx, handler_ctx, VsockError::BufDescMissing);
}
}
#[test]

View File

@@ -5,8 +5,8 @@ authors = ["The Chromium OS Authors"]
edition = "2021"
[dependencies]
libc = "0.2.139"
vm-memory = "0.11.0"
libc = "0.2.147"
vm-memory = "0.12.2"
[target.'cfg(target_arch = "aarch64")'.dependencies]
arch = { path = "../arch" }

View File

@@ -12,7 +12,7 @@
mod address;
mod gsi;
/// page size related utility funtions
/// page size related utility functions
pub mod page_size;
mod system;

View File

@@ -52,7 +52,7 @@ pub struct SystemAllocator {
}
impl SystemAllocator {
/// Creates a new `SystemAllocator` for managing addresses and irq numvers.
/// Creates a new `SystemAllocator` for managing addresses and irq numbers.
/// Can return `None` if `base` + `size` overflows a u64
///
/// * `io_base` - (X86) The starting address of IO memory.

View File

@@ -10,11 +10,11 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.71"
anyhow = "1.0.75"
hypervisor = { path = "../hypervisor" }
thiserror = "1.0.40"
serde = { version = "1.0.164", features = ["rc", "derive"] }
serde = { version = "1.0.168", features = ["rc", "derive"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.11.0", features = ["backend-mmap"] }
vm-memory = { version = "0.12.2", features = ["backend-mmap"] }
vmm-sys-util = "0.11.0"

View File

@@ -85,7 +85,7 @@ impl Ord for BusRange {
impl PartialOrd for BusRange {
fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
self.base.partial_cmp(&other.base)
Some(self.cmp(other))
}
}

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