Compare commits

..

393 Commits
v26.0 ... v28.2

Author SHA1 Message Date
Bo Chen
3b0d2e796b build: Release v28.2 (bug fix release)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-25 08:44:46 -08:00
Rob Bradford
42357c01f3 .github: Don't try and create releases for created branches
Dependabot will create a branch on the repo for it's updates this
triggers the release action (because it's the same event as a tag) which
will then fail leading to dependabot PRs not being automerged. Instead
only run the release check test on PRs or tag creation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit f6c058da56)
2023-01-24 06:04:01 -08:00
Rob Bradford
b7b5b9d7e6 .github: Re-order release steps to ensure binaries are available
Since we run "cargo clean" before running the aarch64 build we need to
create the release and upload the x86-64 assets before the clean.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 6e9172bf6f)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-24 06:04:01 -08:00
Rob Bradford
a63e064004 .github: Clean source tree before cross building release assets
This address issues with leaking symbols into the cross build.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 547230bb77)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-24 06:04:01 -08:00
Rob Bradford
62c1f39ea2 .github: Run release style builds on all PRs
Adjust the release workflow to move the conditional check on the tag
creation into the steps that create the release/upload the assets.

This allows us to ensure we're always in a releaseable state.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit ef7e177df2)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-24 06:04:01 -08:00
Bo Chen
460ba718d4 github,Cargo.toml: Strip release binaries using toolchain
From Rust 1.59, the cargo command is now able to strip a binary [1].
This can be enabled in Cargo.toml by adding a `strip = "true"` to
the `[profile.release]` section.

Adding such binary stripping support in Cargo.toml of the project,
also change the stripping process in the release workflow to the one
using toolchain, so that the AArch64 release binaries can also
be stripped.

Fixes: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/4916

[1] https://doc.rust-lang.org/beta/cargo/reference/profiles.html#strip

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
(cherry picked from commit 1ff0191b30)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-24 06:04:01 -08:00
Bo Chen
c91a8e1324 misc: Automatically fix cargo clippy issues added in 1.65 (stable)
The code of the stable branch diverges from the main branch, so we
can't directly backport the corresponding commit to fix the clippy
issues.

See: commit 5e52729453

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-01-19 09:12:38 -08:00
Philipp Schuster
1adfb7e9f8 virtio-devices: properly join all threads on Drop
This change is important to do a proper resource cleanup. We decided
to do this repetitive approach as VirtioCommon can't implement Drop
without major changes to the corresponding code. Also, devices such as
Net can't easily use the epoll_threads-abstraction from VirtioCommon as
it has multiple threads with different semantics.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
(cherry picked from commit ad6c0ee52b)
2023-01-19 09:12:38 -08:00
Muminul Islam
8dd4d42053 vmm: Ensure PIO/MMIO exits complete before pausing only for KVM
MSHV does not require to ensure MMIO/PIO exits complete
before pausing. This patch makes sure the above requirement
by checking the hypervisor type run-time.

Fixes #5037

Signed-off-by: Muminul Islam <muislam@microsoft.com>
(cherry picked from commit 4e3bc20f2c)
2023-01-19 09:12:38 -08:00
Sebastien Boeuf
3834b43878 qcow: Fix number of refcount table entries
The number of entries in the refcount table was incorrectly calculated
given there was no need for dividing the number of refblock clusters.
The number of refblock clusters is the number of entries in the refcount
table.

Suggested-by: lv_mz <lv.mengzhao@zte.com.cn>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
(cherry picked from commit 0e7d5d2761)
2023-01-19 09:12:38 -08:00
Bo Chen
52605cc0e4 build: Release v28.1 (bug fix release)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-12-13 13:02:57 -08:00
Rob Bradford
92beda1e32 README: Use consistent path to cloud-hypervisor binary
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 00becda899)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 15:12:40 +00:00
Bo Chen
167fef382a net_util: queue_pair: Avoid integer overflow
This integer overflow was triggered with fuzzing on the virtio-net
device. The integer overflow is from the wrong assumption that the
packets read from or written to the tap device is always larger than the
size of a virtio-net header.

Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 559faa272a)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 15:12:40 +00:00
Yuji Hagiwara
5126e9b26e docs: Fix a typo on the doc for tpm
swtpm accepts --tpmstate option

Signed-off-by: Yuji Hagiwara <yuuzi41@gmail.com>
(cherry picked from commit 47a7ebe434)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 15:12:40 +00:00
Bo Chen
59bd682b1f net_util: queue_pair: Avoid panic and handle error properly
This panic was triggered with fuzzing on the virtio-net device. This
commits handles the error explicitly to avoid the panic, which also
makes the fuzzer happy (as panic is treated as bugs).

Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 4d9a2b17a7)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 15:12:40 +00:00
Rob Bradford
8e3b351038 arch: x86_64: Use host cpuid information for L2 cache for older KVM
If the KVM version is too old (pre Linux 5.7) then fetch the CPUID
information from the host and use that in the guest. We prefer the KVM
version over the host version as that would use the CPUID for the
running CPU vs the CPU that runs this code which might be different due
to a hybrid topology.

Fixes: #4918

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 7c3110e6d5)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 15:12:40 +00:00
Rob Bradford
3f8d06b47e build: Update dependencies in v28.x stable branch
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 14:29:22 +00:00
Rob Bradford
66460765a3 build: Release v28.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-17 15:40:14 +00:00
Rob Bradford
b748b8987d Jenkinsfile: Re-enable metrics CI
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-17 15:34:12 +00:00
Wei Liu
c9483fb080 tracer: avoid unnecessary allocations
Allocation is only required when creating a new entry in the hashmap.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-17 12:52:27 +00:00
Michael Zhao
f52cd3bb85 Revert "Jenkins: Temporarily turn off AArch64 CI"
This reverts commit 345e65c9c2.
The AArch64 server maintenance is done. Now we can enable the CI again.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-11-17 15:26:27 +08:00
dependabot[bot]
57cd12fabc build: Bump remain from 0.2.4 to 0.2.5
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.4 to 0.2.5.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.4...0.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-16 23:48:46 +00:00
dependabot[bot]
869c649e81 build: Bump os_str_bytes from 6.3.1 to 6.4.0 in /fuzz
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.3.1 to 6.4.0.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.3.1...6.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-16 23:24:01 +00:00
Rob Bradford
a9e30c88df README: Update version of Rust Hypervisor Firmware
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-16 08:11:22 -08:00
dependabot[bot]
1666375a31 build: Bump vfio-ioctls from bf7c9b9 to ad86d84
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `bf7c9b9` to `ad86d84`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](bf7c9b997b...ad86d843a2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-16 11:26:45 +00:00
dependabot[bot]
9a0be7db3a build: Bump uuid from 1.2.1 to 1.2.2 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.2.1...1.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-15 23:17:26 +00:00
Praveen K Paladugu
324c5deb37 docs: Add doc for using and testing tpm device
Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
09e79a5e9b vmm: Add tpm device to mmio bus
Add tpm device to mmio bus if appropriate cmdline arguments were
passed.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
af261f231c vmm: Add required acpi entries for vtpm device
Add an TPM2 entry to DSDT ACPI table. Add a TPM2 table to guest's ACPI.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
7122e2989c vmm: Add tpm parameter
Add an optional --tpm parameter that takes UNIX Domain
Socket from swtpm.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
d0b253d15f devices: Add tpm device
This device emulates a tpm device in cloud-hypervisor. Read and write support
to miminal set of control registers is supported.

Non-control commands will be processed as reads and write to
CRB_DATA_BUFFER. Reads and Writes to this data buffer are forwarded to
swtpm via the configured data_fd.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
59baa29deb arch: Add TPM Address ranges to layouts
Add TPM's CRB Interface specific address ranges to layouts

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
19fdf8bc79 tpm: Add emulator module
Emulator module adds methods required to communicate with swtpm
over Ctrl and Data channels.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
58b902d036 tpm: Add socket module
Add SocketDev struct. Methods in SocketDev will be used to read & write
to Ctrl channel created by swtpm.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Praveen K Paladugu
e3213c8a79 tpm: Add library module
Add structures and related methods to process Ctrl requests and responses
from swtpm to tpm library.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Co-authored-by: Sean Yoo <t-seanyoo@microsoft.com>
2022-11-15 16:42:21 +00:00
Wei Liu
2e2ce47271 hypervisor: do not get and set MSR_IA32_TSC for MSHV
Setting that MSR causes the reference TSC page to be disabled.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-15 10:19:57 +00:00
Rob Bradford
d3a8332282 tests: Remove test_reboot
There is no need for this test any longer as we have plenty of other
tests that reboot the VM.

Further this test used unmodified bionic image, which not only will be
EOLed soon but also took a long time to shutdown as it still had snapd
installed.

Fixes: #4849

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-15 09:30:16 +00:00
dependabot[bot]
c64004b9a9 build: Bump mshv-ioctls from ac9c92f to 1a9ca01
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `ac9c92f` to `1a9ca01`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](ac9c92f9b3...1a9ca01801)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 23:45:35 +00:00
Rob Bradford
149e424b6e virtio-devices: block: Return error to driver on writes if read-only
TEST=Boot `--disk readonly=on` along with a guest that tries to write
(unmodified hypervisor-fw) and observe that the virtio device thread no
longer panics.

Fixes: #4888

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-14 15:28:30 +00:00
Wei Liu
b07d471d4f virtio-devices: show the failed block request to help debugging
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-14 14:19:17 +00:00
Michael Zhao
345e65c9c2 Jenkins: Temporarily turn off AArch64 CI
Temporarily turn off AArch64 integration test in Jenkins for server
maintenance.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-11-14 08:34:47 +00:00
dependabot[bot]
f93aa42319 build: Bump once_cell from 1.15.0 to 1.16.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.15.0...v1.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-12 08:30:12 +00:00
dependabot[bot]
fa4bf92feb build: Bump io-uring from 0.5.8 to 0.5.9 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.8 to 0.5.9.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-11-12 08:30:01 +00:00
Rob Bradford
f30d460fa3 virtio-devices: seccomp: Move mprotect() to virtio common rules
It's perfectly reasonable to expect if that some virtio threads trigger
libc behaviour that needs mprotect() that all virtio threads would do
the same.

Fixes: #4874

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-12 08:29:47 +00:00
Rob Bradford
2c94773bdc docs: seccomp: Enhance strace command to print thread name
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-11 16:47:24 +00:00
dependabot[bot]
9f1d2d34e8 build: Bump darling from 0.14.1 to 0.14.2
Bumps [darling](https://github.com/TedDriggs/darling) from 0.14.1 to 0.14.2.
- [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.14.1...v0.14.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-11 08:15:25 +00:00
Rob Bradford
57508a4b1c virtio-net: net: Wait for threads to exit on Drop
It is required to close all file descriptors pointing to an opened TAP
device prior to reopening the TAP device; otherwise it will return
-EBUSY as the device can only be opened once (excluding MQ use cases.)

When rebooting the VM the virtio-net threads would still be running and
so the TAP file descriptor may not have been closed. To ensure that the
TAP FD is closed wait for all the epoll threads to exit after receiving the
KILL_EVENT.

Fixes: #4868

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-10 07:46:16 -08:00
dependabot[bot]
012f2572d5 build: Bump terminal_size from 0.2.1 to 0.2.2
Bumps [terminal_size](https://github.com/eminence/terminal-size) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/eminence/terminal-size/releases)
- [Commits](https://github.com/eminence/terminal-size/compare/v0.2.1...v0.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-10 09:39:09 +00:00
dependabot[bot]
b9dbe3a2f7 build: Bump rustix from 0.35.12 to 0.35.13 in /fuzz
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.12 to 0.35.13.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.12...v0.35.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-09 23:43:39 +00:00
Rob Bradford
6230929d51 openapi: Add thp option to MemoryConfig
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-09 16:51:21 +00:00
Rob Bradford
04d034a0bc docs: Update memory.md for THP
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-09 16:51:21 +00:00
Rob Bradford
f603afc46e vmm: Make Transparent Huge Pages controllable (default on)
Add MemoryConfig::thp and `--memory thp=on|off` to allow control of
Transparent Huge Pages.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-09 16:51:21 +00:00
Rob Bradford
b68add2d0d vmm: Enable THP when using anonymous memory
If the memory is not backed by a file then it is possible to enable
Transparent Huge Pages on the memory and take advantage of the benefits
of huge pages without requiring the specific allocation of an appropriate
number of huge pages.

TEST=Boot and see that in /proc/`pidof cloud-hypervisor`/smaps that the
region is now THPeligible (and that also pages are being used.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-09 16:51:21 +00:00
dependabot[bot]
0f44db5da4 build: Bump openssl-src from 111.23.0+1.1.1r to 111.24.0+1.1.1s
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.23.0+1.1.1r to 111.24.0+1.1.1s.
- [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>
2022-11-08 23:44:15 +00:00
dependabot[bot]
a7dccf94cf build: Bump terminal_size from 0.2.1 to 0.2.2 in /fuzz
Bumps [terminal_size](https://github.com/eminence/terminal-size) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/eminence/terminal-size/releases)
- [Commits](https://github.com/eminence/terminal-size/compare/v0.2.1...v0.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-08 23:36:26 +00:00
Jianyong Wu
0e6e539d9b AArch64/fdt: fix PMU irqflag calculation
Currently, CPU mask involved into PMU irqflag caculation which is used
for Gicv2. It limits the CPU number up to 31. For Gicv3+, CPU mask is no
longer needed. More info see [1].

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>

[1] https://lore.kernel.org/all/165668798833.3744902.12084627427900181326.b4-ty@kernel.org/t/
2022-11-08 11:24:11 +00:00
dependabot[bot]
1cb1cff882 build: Bump env_logger from 0.9.1 to 0.9.3
Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.9.1 to 0.9.3.
- [Release notes](https://github.com/env-logger-rs/env_logger/releases)
- [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.9.1...v0.9.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-07 23:55:26 +00:00
dependabot[bot]
fefbc356a2 build: Bump once_cell from 1.15.0 to 1.16.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.15.0...v1.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-07 23:52:05 +00:00
Muminul Islam
8b37448d28 tests: Disable test_snapshot_restore_hotplug_virtiomem for MSHV
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2022-11-04 12:24:33 -07:00
Muminul Islam
92d083f593 tests: Add a basic test for snapshot/retsore
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2022-11-04 12:24:33 -07:00
Muminul Islam
58d8795b53 tests: Make a wrapper function for snapshot/restore
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2022-11-04 12:24:33 -07:00
Bo Chen
b37e2ed378 virtio-devices: mem: Handle integer overflow properly
An integer overflow from our virtio-mem device can be triggered
from (misbehaved) guest driver with malicious requests. This patch
handles this integer overflow explicitly and treats it as an invalid
request.

Note: this bug was detected by our virtio-mem fuzzer through 'oss-fuzz'.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-04 09:33:21 +00:00
Bo Chen
ef8fb9bd25 fuzz: Add fuzzer for virtio-console
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-03 09:10:41 -07:00
Bo Chen
cfafc85b9c virtio-devices: Custom 'EpollHelper::run_with_timeout' for fuzz
To support all virtio-devices, this patch replaces the customized
EpollHelper::run` with customized `EpollHelper::run_with_timeout` for
fuzzing.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-03 09:10:41 -07:00
Bo Chen
683491a955 virtio-devices: console: Provide 'wait_for_epoll_threads'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-03 09:10:41 -07:00
dependabot[bot]
2bbb08b2a4 build: Bump io-uring from 0.5.7 to 0.5.8
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.7 to 0.5.8.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-11-02 23:56:43 +00:00
dependabot[bot]
b77eb63688 build: Bump darling from 0.14.1 to 0.14.2 in /fuzz
Bumps [darling](https://github.com/TedDriggs/darling) from 0.14.1 to 0.14.2.
- [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.14.1...v0.14.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-02 23:51:00 +00:00
Rob Bradford
6722c303b0 docs: Fix broken link in windows.md
Fixes: #4840

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-02 11:40:44 +00:00
Rob Bradford
6e0bd73c90 build: Bump linux-loader from 0.6.0 to 0.7.0
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-02 11:02:00 +00:00
Rob Bradford
103fe1f48b tests: Skip building kernel if already present
When running the glibc and musl integration tests on the CI after each
other skip building the kernel a second time.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-02 09:42:07 +00:00
Rob Bradford
f4e1b72477 build: Consolidate integration testing to reused built assets
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-02 09:42:07 +00:00
Rob Bradford
65628e8d94 build: Run linter over Jenkinsfile
This has resulted in the content being indented with spaces rather tabs
per Groovy coding style.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-02 09:42:07 +00:00
dependabot[bot]
851de1e0b3 build: Bump io-uring from 0.5.7 to 0.5.8 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.7 to 0.5.8.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-11-02 09:21:17 +00:00
Bo Chen
a9ec0f33c0 misc: Fix clippy issues
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-02 09:41:43 +01:00
dependabot[bot]
9266ea4995 build: Bump clap from 4.0.17 to 4.0.18
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.17 to 4.0.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.17...v4.0.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-01 00:41:51 +00:00
dependabot[bot]
6b8070de95 build: Bump io-lifetimes from 0.7.3 to 0.7.4
Bumps [io-lifetimes](https://github.com/sunfishcode/io-lifetimes) from 0.7.3 to 0.7.4.
- [Release notes](https://github.com/sunfishcode/io-lifetimes/releases)
- [Commits](https://github.com/sunfishcode/io-lifetimes/compare/v0.7.3...v0.7.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-31 23:48:55 +00:00
dependabot[bot]
a5712641d2 build: Bump remain from 0.2.4 to 0.2.5 in /fuzz
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.4 to 0.2.5.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.4...0.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-31 23:46:39 +00:00
Rob Bradford
aad4dc3b6b docs: Update memory.md to indicated that hugepages overrides shared
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
f4495de143 vmm: Improve handling of shared memory backing
As huge pages are always MAP_SHARED then where the shared memory would
be checked (for vhost-user and local migration) we can also check
instead for huge pages.

The checking is also extended to cover the memory zones based
configuration as well.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
99d9a3d299 vmm: memory_manager: Avoid MAP_PRIVATE CoW with VFIO for hugepages too
We can't use MAP_ANONYMOUS and still have huge pages so MAP_SHARED is
effectively required when using huge pages.

Unfortunately it is not as simple as always forcing MAP_SHARED if
hugepages is on as this might be inappropriate in the backing file case
hence why there is additional complexity of assigning to mmap_flags on
each case and the MAP_SHARED is only turned on for the anonymous file
huge page case as well as anonymous shared file case.

See: #4805

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
df7c728399 vmm: memory_manager: Only file back memory when required
If we do not need an anonymous file backing the memory then do not
create one.

As a side effect this addresses an issue with CoW (mmap with MAP_PRIVATE
but no MAP_ANONYMOUS) when the memory is pinned for VFIO.

Fixes: #4805

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
1e5a4e8d77 vmm: memory_manager: Split filesystem backed and anonymous RAM creation
This simplifies the code somewhat making the code paths more readable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
ff3fb91ba6 vmm: Refactor creation of the FileOffset for GuestRegionMmap::new()
Create this earlier so that it is possible to pass a None in for
anonymous mappings.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 22:28:29 +00:00
Rob Bradford
86c19816c6 block_util: Probe for used io_uring opcodes
The probing logic wasn't updated to reflect the actual opcodes in use
for io_uring which are vectored read/writes not the unvectored versions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-31 08:53:54 +01:00
dependabot[bot]
ad1cb130a5 build: Bump openssl-sys from 0.9.76 to 0.9.77
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.76 to 0.9.77.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.76...openssl-sys-v0.9.77)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-28 23:45:06 +00:00
dependabot[bot]
0c75e7f7b2 build: Bump os_str_bytes from 6.3.0 to 6.3.1 in /fuzz
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.3.0...6.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-28 23:40:41 +00:00
Jinrong Liang
cb171d4a23 device_manager: Avoid checking io_uring support when it's not needed
After testing, io_uring_is_supported() causes about 38ms of
overhead when creating virtio-blk. By modifying the position
of io_uring_is_supported(), the overhead of creating virtio-blk
is reduced to less than 1ms when we close io_uring.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
2022-10-27 22:21:51 -07:00
dependabot[bot]
bc310bb173 build: Bump libc from 0.2.135 to 0.2.137
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.135 to 0.2.137.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.135...0.2.137)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-27 23:57:43 +00:00
dependabot[bot]
76f4641004 build: Bump arbitrary from 1.1.7 to 1.2.0 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.7 to 1.2.0.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.1.7...v1.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-27 23:53:53 +00:00
dependabot[bot]
dcb12c05a7 build: Bump pkg-config from 0.3.25 to 0.3.26
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.25 to 0.3.26.
- [Release notes](https://github.com/rust-lang/pkg-config-rs/releases)
- [Changelog](https://github.com/rust-lang/pkg-config-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/pkg-config-rs/compare/0.3.25...0.3.26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-27 07:57:53 +00:00
Bo Chen
078c0408b3 virtio-devices: console: Remove obsoleted 'INPUT_EVENT'
Since the processing of the console inputs was moved from the VMM thread
to the virtio-console thread (#3061), we have been using the 'FILE_EVENT'
to handle input from stdin/pty/file, which made 'INPUT_EVENT' obsoleted.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-27 09:27:12 +02:00
Wei Liu
b99b2bc990 memory_manager: use MFD_CLOEXEC flag when creating memory fd
Until there is a need for sharing the memory fd with a child process, we
should err on the safe side to close it on exec.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-10-27 09:20:08 +02:00
dependabot[bot]
0cd6d96874 build: Bump getrandom from 0.2.7 to 0.2.8 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.7 to 0.2.8.
- [Release notes](https://github.com/rust-random/getrandom/releases)
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.7...v0.2.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-26 23:53:05 +00:00
Bo Chen
a5d0ff7039 virtio-devices: console: Propagate GuestMemory errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-26 09:39:30 +02:00
Bo Chen
da1ab77848 virtio-devices: console: Report error instead of panic
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-26 09:39:30 +02:00
dependabot[bot]
989d3d3960 build: Bump syn from 1.0.102 to 1.0.103
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.102 to 1.0.103.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.102...1.0.103)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-25 23:45:43 +00:00
dependabot[bot]
1559b7b684 build: Bump rustix from 0.35.11 to 0.35.12 in /fuzz
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.11 to 0.35.12.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.11...v0.35.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-25 23:43:02 +00:00
dependabot[bot]
e96474a5bd build: Bump rustix from 0.35.11 to 0.35.12
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.11 to 0.35.12.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.11...v0.35.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-24 23:48:30 +00:00
dependabot[bot]
2a36a18be3 build: Bump syn from 1.0.102 to 1.0.103 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.102 to 1.0.103.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.102...1.0.103)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-24 23:47:19 +00:00
zbleness
0e386581e0 README.md: Add missing backslash to example code
Signed-off-by: zbleness <77726616+zbleness@users.noreply.github.com>
2022-10-24 16:33:14 +02:00
Sebastien Boeuf
1f0e5eb66a vmm: virtio-devices: Restore every VirtioDevice upon creation
Following the new design proposal to improve the restore codepath when
migrating a VM, all virtio devices are supplied with an optional state
they can use to restore from. The restore() implementation every device
was providing has been removed in order to prevent from going through
the restoration twice.

Here is the list of devices now following the new restore design:

- Block (virtio-block)
- Net (virtio-net)
- Rng (virtio-rng)
- Fs (vhost-user-fs)
- Blk (vhost-user-block)
- Net (vhost-user-net)
- Pmem (virtio-pmem)
- Vsock (virtio-vsock)
- Mem (virtio-mem)
- Balloon (virtio-balloon)
- Watchdog (virtio-watchdog)
- Vdpa (vDPA)
- Console (virtio-console)
- Iommu (virtio-iommu)

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-24 14:17:08 +02:00
Sebastien Boeuf
157db33d65 vmm: Refactor hypervisor::Vm creation on restore
This prevents from leaking implementation details to lib.rs, and rather
keep them in vm.rs.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-24 14:17:08 +02:00
dependabot[bot]
40df6c3787 build: Bump serde from 1.0.145 to 1.0.147
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.145 to 1.0.147.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.145...v1.0.147)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-24 08:41:05 +00:00
dependabot[bot]
b425c5f57c build: Bump serde from 1.0.145 to 1.0.147 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.145 to 1.0.147.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.145...v1.0.147)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-21 23:40:25 +00:00
Fabiano Fidêncio
b4e3942708 api: Fix vm.add-device argument type
The add_device() function, from the device manager code, takes a
DeviceConfig as a parameter, instead of a VmAddDevice.

The change was originally done as part of 34412c9b41 and it didn't
break Kata Containers because the VmAddDevice and DeviceConfig structs
share most of their fields, besides the optional for serialization
`pci_segment`, which is not used by the client yet.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-21 11:09:55 -07:00
Bo Chen
802f489e4d fuzz: Add fuzzer for virtio-iommu
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-21 14:21:42 +01:00
Bo Chen
fdecd94b20 virtio-devices: iommu: Provide 'wait_for_epoll_threads()'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-21 14:21:42 +01:00
Bo Chen
2af2cc539f misc: Unify error message punctuation
Considering error messages will be mostly nested, ensuring no
punctuation at the end will make the error log more readable.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-21 12:19:07 +02:00
dependabot[bot]
7d71319210 build: Bump anyhow from 1.0.65 to 1.0.66 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.65 to 1.0.66.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.65...1.0.66)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-21 00:39:56 +00:00
dependabot[bot]
e710e21744 build: Bump anyhow from 1.0.65 to 1.0.66
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.65 to 1.0.66.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.65...1.0.66)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-21 00:04:03 +00:00
Bo Chen
9c658e21a5 virtio-devices: iommu: Remove trivial handling of 'EVENT_Q_EVENT'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-20 10:32:23 -07:00
Bo Chen
38620eaea8 virtio-devices: net: Avoid using vector and direct indexing
With known number of queues and queue events, we can make each of them
more explicit and avoid using vector/direct indexing, which is cleaner
and slightly more efficient.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-20 07:45:36 -07:00
Bo Chen
a388d76228 virtio-devices: console: Avoid using vector and direct indexing
The the number of queues and associated events is known and fixed. We
can define and use each of them explicitly and avoid using vector (and
hence direct indexing), which is cleaner and slightly more efficient.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-20 07:45:36 -07:00
Bo Chen
710a860e9b virtio-devices: iommu: Avoid using vector and direct indexing
The the number of queues and associated events is known and fixed. We
can define and use each of them explicitly and avoid using vector (and
hence direct indexing), which is cleaner and slightly more efficient.
Also, this refactoring makes it clearer that we are not handling "event
queue" events (as "_event_queue" is not being used intentionally).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-20 07:45:36 -07:00
Bo Chen
83f22ac779 virtio-devices: iommu: Specify minimum number of queues to avoid OOB
In this way, the virtio-iommu code can properly report an error when
a wrong number of queues is provided, instead of triggering an
out-of-bound error.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-20 07:45:00 -07:00
dependabot[bot]
71b4aad3f1 build: Bump serde_json from 1.0.86 to 1.0.87 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.86 to 1.0.87.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.86...v1.0.87)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-20 00:19:44 +00:00
dependabot[bot]
d7afa3c47e build: Bump serde_json from 1.0.86 to 1.0.87
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.86 to 1.0.87.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.86...v1.0.87)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-19 23:44:35 +00:00
Rob Bradford
073374e2b0 README.md: Fix path to executable
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-19 15:11:18 +01:00
dependabot[bot]
d4f40487e3 build: Bump clap from 4.0.15 to 4.0.17 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.15 to 4.0.17.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.15...v4.0.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-19 00:23:48 +00:00
dependabot[bot]
f63cf2ebc0 build: Bump clap from 4.0.15 to 4.0.17
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.15 to 4.0.17.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.15...v4.0.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-18 23:47:28 +00:00
dependabot[bot]
46031cb211 build: Bump libfuzzer-sys from 0.4.4 to 0.4.5 in /fuzz
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.4.4 to 0.4.5.
- [Release notes](https://github.com/rust-fuzz/libfuzzer/releases)
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.4...0.4.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-18 23:46:04 +00:00
Sebastien Boeuf
c52ccf3992 vmm: migration: Create destination VM right before to restore it
This is preliminary work to ensure a migrated VM is created right before
it is restored. This will be useful when moving to a design where the VM
is both created and restored simultaneously from the Snapshot.

In details, that means the MemoryManager is the object that must be
created upon receiving the config from the source VM, so that memory
content can be later received and filled into the GuestMemory.
Only after these steps happened, the snapshot is received from the
source VM, and the actual Vm object can be created from both the
snapshot and the MemoryManager previously created.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-18 17:14:29 +02:00
Bo Chen
7b31871a36 fuzz: mem: Avoid using hugepages
The kernel will trigger a SIGBUS upon hugetlb page faults when there is
no huge pages available. We neither have a way to ensure enough huge
pages available on the host system, nor have a way to gracefully report
the lack of huge pages in advance from Cloud Hypervisor. For these
reasons, we have to avoid using huge pages from the virtio-mem fuzzer to
avoid SIGBUS errors.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-18 09:09:35 +01:00
dependabot[bot]
1b58c63734 build: Bump proc-macro2 from 1.0.46 to 1.0.47
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.46 to 1.0.47.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.46...1.0.47)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-18 00:18:37 +00:00
dependabot[bot]
d1435a44af build: Bump proc-macro2 from 1.0.46 to 1.0.47 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.46 to 1.0.47.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.46...1.0.47)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-17 23:42:59 +00:00
Rob Bradford
a75d71f2c8 vmm: Reduce logging severity for unknown MMIO/PIO device accesses
These look alarming if you are booting with the a distro kernel which is
now a recommended approach.

See: #4786

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-17 10:08:36 -07:00
Bo Chen
96209e7a16 vmm: Remove the explicit call to 'Snapshottable:restore()'
The restore path of MemoryManager is handled specially without
implementing a `Snapshottable:restore()`. Removing the explicit call to
it along the migration code path to avoid confusions.

See: #4783

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-17 10:07:44 -07:00
Jinank Jain
7a68689794 hypervisor: Fix a typo in error message
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2022-10-16 09:33:08 +00:00
Bo Chen
6e6b519a74 Revert "tests: Temporarily disable test_live_{migration,upgrade}_watchdog{_local}"
This reverts commit 87fb9cedc9.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-14 13:42:03 +01:00
Bo Chen
958ef69295 tests: Rely on wtmp (the login records) to count reboot times
The systemd journal has a known issue of generating large size logs[1],
which makes it unreliable as a source for retrieving system
information, such as for counting reboot times. This is particularly
problematic on disk-constrained systems, like the VMs we launched for
our integration tests, where the disk size is normally 2GB. By default,
the systemd journal has a size limit of 10% of the size of the
underlying file system (e.g. around 200MB for the VMs of our integration
tests), which would remove archived journal files on demand.

A better alternative to count reboot times is based on information from
`wtmp` (e.g. the login records) which is much more concise and can be
accessed via the `last` command.

[1] https://github.com/systemd/systemd/issues/5285

Fixes: #4749

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-14 13:42:03 +01:00
Rob Bradford
ffc222b26e docs: Modernise README
Refresh our README in a consistent style and update it to reflect:

* A recommendation to use binaries
* Clarify our relationship with other Rust based VMMs/Rust-VMM project
* Ensure instructions result in a usable image (cloud-init)
* Simplify script instructions
* Move compilation details elsewhere
* Add Fedora 36 image details
* Point to CLOUDHV as well as Rust Hypervisor Firmware

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-14 12:04:06 +01:00
Bo Chen
5b706422e8 virtio-devices: iommu: Propagate errors of processing request queue
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-14 11:28:31 +01:00
Bo Chen
84105992b7 virtio-devices: iommu: Switch to use 'thiserror'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-14 11:28:31 +01:00
Bo Chen
0235ed3388 virtio-devices: mem: Report error instead of panic
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-14 11:28:31 +01:00
dependabot[bot]
58066e2da4 build: Bump clap from 4.0.14 to 4.0.15
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.14 to 4.0.15.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.14...v4.0.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-14 00:12:55 +00:00
dependabot[bot]
62d6553714 build: Bump clap from 4.0.14 to 4.0.15 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.14 to 4.0.15.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.14...v4.0.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-13 23:40:57 +00:00
lv.mengzhao
2a45e44bda qcow: Fix the calculation of the number of clusters for L1 table
In function create_for_size(), when calculating the number
of clusters for the L1 table, it incorrectly divides the total number of
entries in the L1 table by the cluster size. In fact, it should be
divided by the number of entries/addresses that can fit into a cluster.

Signed-off-by: lv.mengzhao <lv.mengzhao@zte.com.cn>
2022-10-13 13:43:08 +01:00
Sebastien Boeuf
099cdd2af8 virtio-devices, vmm: vdpa: Implement live migration support
Vdpa now implements the Migratable trait, which allows the device to be
added to the DeviceTree and therefore allows live migrating any vDPA
device that supports being suspended.

Given a vDPA device can't be resumed from a suspended state without
having to reset everything, we don't support pause/resume for a vDPA
device, as well as snapshot/restore (which requires resume to be
supported).

In order for the migration to work locally, reusing the same device on
the same host machine, the vhost-vdpa handler is dropped after the
snapshot has been performed, which allows the destination VM to open the
device without any conflict about the device being busy.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
340fd6571a virtio-devices: vdpa: Make vhost-vdpa handler optional
In order to anticipate for migration support, we need to be able to
create a Vdpa object without VhostKernVdpa object associated with it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
02f951a9c3 virtio-devices: vdpa: Simplify vring enabling
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
22be5f9d0f vmm: Extend list of authorized ioctls for vDPA
Adding VHOST_VDPA_GET_CONFIG_SIZE and VHOST_VDPA_SUSPEND to the list of
authorized ioctls for the vmm thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
a9ccb20e5a vm-migration: Add StartMigration type to MigratableError
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
2b150ac2ea pci, virtio-devices: Restore proper BAR type
When restoring a VM, the BAR type can be found directly from the
snapshot resources. It is more reliable than the previous method which
was using self.use_64bit_bar from VirtioPciDevice because at the time
the BARs are allocated, the VirtioDevice hasn't been restored yet,
meaning the way to determine the value of use_64bit_bar is wrong for a
device like vDPA. At this time, the device type is not known and relying
on the stored resources is the only reliable way.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
Sebastien Boeuf
204bf2e3f5 deps: Rely on latest rust-vmm/vhost version
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-13 10:03:23 +02:00
dependabot[bot]
2a40fe5541 build: Bump clap from 4.0.13 to 4.0.14
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.13 to 4.0.14.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.13...v4.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-13 00:12:47 +00:00
dependabot[bot]
7ae4e2b8fe build: Bump clap from 4.0.13 to 4.0.14 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.13 to 4.0.14.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.13...v4.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 23:39:52 +00:00
Rob Bradford
f17f4079b4 test_data: Use bash TCP support instead of netcat for boot check
This means that the guest image does not need to have netcat installed
making it easier to use unmodified images.

See https://www.gnu.org/software/bash/manual/html_node/Redirections.html

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-12 23:04:42 +01:00
Bo Chen
342851c88c fuzz: Add fuzzer for virtio-mem
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-12 16:09:27 +01:00
Bo Chen
37c3b0429a vmm: Make MemoryManager::create_ram_region() public
So that it can be reused externally, such as for fuzzing.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-12 16:09:27 +01:00
dependabot[bot]
af14044fb8 build: Bump zerocopy-derive from 0.3.1 to 0.3.2
Bumps [zerocopy-derive](https://github.com/google/zerocopy) from 0.3.1 to 0.3.2.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Commits](https://github.com/google/zerocopy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 09:57:50 +00:00
dependabot[bot]
fa39d1e9b9 build: Bump clap from 4.0.12 to 4.0.13
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.12 to 4.0.13.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.12...v4.0.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 09:22:18 +00:00
dependabot[bot]
00714dc54a build: Bump openssl-src from 111.22.0+1.1.1q to 111.23.0+1.1.1r
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.22.0+1.1.1q to 111.23.0+1.1.1r.
- [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>
2022-10-12 09:18:08 +01:00
Rob Bradford
87fb9cedc9 tests: Temporarily disable test_live_{migration,upgrade}_watchdog{_local}
This test has been identified as flaky and is creating CI churn.

See: #4749

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-12 09:17:39 +01:00
dependabot[bot]
ce2928d842 build: Bump clap from 4.0.12 to 4.0.13 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.12 to 4.0.13.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.12...v4.0.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 23:45:11 +00:00
Anatol Belski
a18b08c682 seccomp: mshv: Allow create partition ioctl
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-10-11 09:05:24 +01:00
dependabot[bot]
43935c3b95 build: Bump uuid from 1.1.2 to 1.2.1
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.2 to 1.2.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.2...1.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 03:12:14 +00:00
dependabot[bot]
c3c550c454 build: Bump unicode-ident from 1.0.4 to 1.0.5
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.4...1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 02:38:53 +00:00
dependabot[bot]
7da632def6 build: Bump unicode-ident from 1.0.4 to 1.0.5 in /fuzz
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.4...1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 01:44:58 +00:00
dependabot[bot]
f38ef20e3b build: Bump libc from 0.2.134 to 0.2.135
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.134 to 0.2.135.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.134...0.2.135)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 01:13:44 +00:00
dependabot[bot]
a033b1ef67 build: Bump uuid from 1.1.2 to 1.2.1 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.2 to 1.2.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.2...1.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 01:11:14 +00:00
dependabot[bot]
ffa7d27b5e build: Bump libc from 0.2.134 to 0.2.135 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.134 to 0.2.135.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.134...0.2.135)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 00:22:29 +00:00
dependabot[bot]
da725daca0 build: Bump clap from 4.0.10 to 4.0.12
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.10 to 4.0.12.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.10...v4.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 00:22:25 +00:00
dependabot[bot]
0fe0eb4c97 build: Bump serde_json from 1.0.85 to 1.0.86
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.85 to 1.0.86.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.85...v1.0.86)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-10 23:47:01 +00:00
dependabot[bot]
8877211d9e build: Bump syn from 1.0.101 to 1.0.102
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.101 to 1.0.102.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.101...1.0.102)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-08 00:29:08 +00:00
dependabot[bot]
f907ff5d82 build: Bump syn from 1.0.101 to 1.0.102 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.101 to 1.0.102.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.101...1.0.102)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-07 23:47:54 +00:00
Rob Bradford
89a2562c5a pci: Optimise MSI-X table programming
With an updated Linux kernel the kernel reprograms the same table entry
in the MSI-X table multiple times. Fortunately it does so with entry
masked (the default.)

The costly part of MSI-X table reprogramming is going out to the host
kernel to update the GSI routing entries. This change makes three
optimisations.

1. If the table entry is unchanged: skip handking updates
2. Only update the GSI routing table if the table entry is unmasked
   (this skips extra calls to the ioctl() for reprogramming the
    entries.)
3. Only generate a message on entry unmasking if the global MSI-X enable
   bit is set.

Fixes: #4273

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-07 09:57:27 -07:00
Bo Chen
29cf637f3f vmm: Move 'default_serial/console()' to vm_config.rs
In this way, we have all functions related to generate default values of
vm-config structs in the same location.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-07 09:13:15 -07:00
Bo Chen
fd9fa2a681 virtio-mem: mem: Simplify 'process_queue'
No functional change.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-07 07:57:08 -07:00
Bo Chen
756aebafda virtio-devices: mem: Handle and propagate errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-07 07:57:08 -07:00
dependabot[bot]
d4d63502be build: Bump itoa from 1.0.3 to 1.0.4
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.3...1.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-07 00:41:45 +00:00
dependabot[bot]
961793ba8c build: Bump io-uring from 0.5.6 to 0.5.7 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.6 to 0.5.7.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-10-07 00:23:20 +00:00
dependabot[bot]
cbeed02a7c build: Bump itoa from 1.0.3 to 1.0.4 in /fuzz
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.3...1.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-06 23:51:07 +00:00
dependabot[bot]
10eb687687 build: Bump io-uring from 0.5.6 to 0.5.7
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.6 to 0.5.7.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-10-06 23:49:36 +00:00
Rob Bradford
83cc554f90 vmm: Remove deprecated VmConfig::{kernel, initramfs, cmdline} members
These have been replaced by members of PayloadConfig and should be
removed in v28.0 (mentioned in v26.0 release notes.)

Fixes: #4737

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-06 14:25:29 +01:00
Rob Bradford
7d8d27c1b4 vmm: Rename queue size / number of queues constants
These constants still referenced the long removed (separate vhost-user
structs.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-06 14:25:29 +01:00
Rob Bradford
d692dfb8e3 vmm: Move impl Default for ... to vm_config.rs
This is consistent when considering that some structs have a
`#[derive(Default)`] so it makes sense for the default implementations
to be in the same location.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-06 14:25:29 +01:00
Rob Bradford
7ad58457b0 vmm: Split structs from logic that make up VmConfig
Place the data structures that are required for constructing a VmConfig
into it's own module from the logic that exists to suppot them.

This is useful as a consumer of the API can now clearly see what data
structures make up the API for creating VMs.

This has no functional change and I made no attempt to clean up the
ordering (it's as in the original file) nor any other clean up.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-06 14:25:29 +01:00
dependabot[bot]
62d2189ade build: Bump clap from 4.0.9 to 4.0.10 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.9 to 4.0.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.9...v4.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-06 00:26:05 +00:00
dependabot[bot]
7e7855bc8f build: Bump clap from 4.0.9 to 4.0.10
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.9 to 4.0.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.0.9...v4.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-05 23:51:49 +00:00
dependabot[bot]
11cc35e6b5 build: Bump arbitrary from 1.1.6 to 1.1.7 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.6 to 1.1.7.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.1.6...v1.1.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-05 23:49:28 +00:00
Sebastien Boeuf
89677c3181 build: Bump clap from 3.2.22 to 4.0.9
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.22 to 4.0.9.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](clap-rs/clap@v3.2.22...v4.0.9)

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

Moving to the major version 4 introduced some breaking changes which had
to be handled manually.

Fixes #4709

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-05 12:59:14 +01:00
dependabot[bot]
307cfeba27 build: Bump smallvec from 1.9.0 to 1.10.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.9.0...v1.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-05 01:02:17 +00:00
dependabot[bot]
43bb09df50 build: Bump vm-fdt from 8a19dcc to d942590
Bumps [vm-fdt](https://github.com/rust-vmm/vm-fdt) from `8a19dcc` to `d942590`.
- [Release notes](https://github.com/rust-vmm/vm-fdt/releases)
- [Commits](8a19dcc94a...d942590738)

---
updated-dependencies:
- dependency-name: vm-fdt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-05 00:27:38 +00:00
dependabot[bot]
81d570e271 build: Bump mshv-bindings from 6b0cf3b to ac9c92f
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `6b0cf3b` to `ac9c92f`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](6b0cf3b47f...ac9c92f9b3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-04 23:51:43 +00:00
Rob Bradford
31ca22d4b6 virtio-devices: rng: Fix error message
The RNG device never reads from the guest memory it reads from a file
and writes to the guest memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-04 16:38:41 +01:00
Rob Bradford
cf995451a2 virtio-devices: watchdog: Generate error on invalid queue descriptor
Don't silently ignore the descriptors provided by the guest. This is
consistent with other devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-04 16:38:29 +01:00
Bo Chen
4fea40f008 fuzz: Balloon: Reduce the guest memory size and queue size
With the guest memory size of 1MB, a valid descriptor size can be close
to the guest memory size (e.g. 1MB) and can contain close to 256k
valid pfn entries (each entry is 4 bytes). Multiplying the queue
size (e.g. 256), there can be close to 64 millions pfn entries to
process in a single request. This is why the oss-fuzz reported a
timeout (with a limit of 60s).

By reducing the guest memory size and the queue size, the worst-case now
is 8 million pfn entries for fuzzing, which can be finished in around 20
seconds according to my local experiment.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-04 09:40:12 +01:00
Rob Bradford
2daab89987 vmm: Remove legacy firmware loading
This functionality was deprecated and is for removal in the upcoming
release.

Fixes: #4511

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-03 17:09:02 +01:00
Rob Bradford
1bc63e7848 vmm: Remove legacy I/O ports for ACPI
These addresses have been superseded and replaced with other I/O ports.

Fixes: #4483

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-03 17:08:57 +01:00
Bo Chen
2115a41568 openapi: Add 'firmware' to 'PayloadConfig'
This option is needed for the openapi consumer (e.g. Kata Containers) to
load firmware (e.g. td-shim) for booting.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-10-01 08:45:21 +01:00
dependabot[bot]
4b4354a52c build: Bump rustix from 0.35.10 to 0.35.11
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.10 to 0.35.11.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.10...v0.35.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 01:36:09 +00:00
dependabot[bot]
67751d07d6 build: Bump libc from 0.2.133 to 0.2.134
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.133 to 0.2.134.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.133...0.2.134)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 01:01:13 +00:00
dependabot[bot]
509fd8b03e build: Bump libc from 0.2.133 to 0.2.134 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.133 to 0.2.134.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.133...0.2.134)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 00:26:21 +00:00
dependabot[bot]
1294f052b2 build: Bump mshv-bindings from 2d0aaa1 to 6b0cf3b
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `2d0aaa1` to `6b0cf3b`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](2d0aaa16b0...6b0cf3b47f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-29 23:49:21 +00:00
dependabot[bot]
01b38b9c59 build: Bump proc-macro2 from 1.0.45 to 1.0.46 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.45 to 1.0.46.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.45...1.0.46)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-29 23:46:46 +00:00
dependabot[bot]
db51e9e209 build: Bump proc-macro2 from 1.0.44 to 1.0.46
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.44 to 1.0.46.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.44...1.0.46)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-29 18:15:44 +00:00
Bo Chen
57dfcc06d3 fuzz: Cargo.lock: Bump virtio-queue to 0.6.1
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-29 19:11:38 +01:00
Rob Bradford
2ba6a9bfcf build: Release v27.0
This also incorporates the bump to virtio-queue 0.6.1

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-29 17:56:21 +01:00
Rob Bradford
362f95c825 README.md: Add mailing list details
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-29 14:24:48 +01:00
dependabot[bot]
a02387862d build: Bump rustix from 0.35.10 to 0.35.11 in /fuzz
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.10 to 0.35.11.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.10...v0.35.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-29 00:20:21 +00:00
dependabot[bot]
ee5c2d2765 build: Bump proc-macro2 from 1.0.44 to 1.0.45 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.44 to 1.0.45.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.44...1.0.45)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-28 23:49:13 +00:00
James O. D. Hunt
cd0208fe0a api-client: Allow response to be captured
Previously, the API response was always written to stdout, but that may
not be appropriate for all clients.

The client can now control this behaviour as the client API returns the
response in the `Result`.

Fixes: #4703.

Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
2022-09-28 15:23:03 +01:00
James O. D. Hunt
eea9bcea38 api-client: Refactor to removed hard-coded prefix
The existing API client only allows access to "VM" operations, so added
a new `simple_api_full_command_with_fds()` that allows access to "VMM"
operations too.

Also added a `simple_api_full_command()` to avoid having to specify the
file descriptors, in a similar manner to `simple_api_command()`.

Fixes: #4701.

Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
2022-09-28 12:30:02 +01:00
Smit Gardhariya
45fa8be97a scripts: Remove common feature flag for mshv tests
Commit b2d1dd65f3 ("build: Remove "fwdebug" and "common" feature
flags") removed support for common features flag. But some of the
scripts are still using that parameter specifically test related to mshv
hypervisor. Thus fix those scripts by removing common feature flag.

Signed-off-by: Smit Gardhariya <sgardhariya@microsoft.com>
2022-09-28 10:53:22 +00:00
Bo Chen
f0c55f5245 virtio-devices: rng: Error out of queue execution on invalid requests
With the virtio-rng device the descriptors that are provided by the
guest must be writable and of non-zero length. Also propagate an error
if writing to the guest memory fails.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-28 10:07:44 +01:00
dependabot[bot]
4779265453 build: Bump thiserror from 1.0.36 to 1.0.37 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.36...1.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-28 10:07:09 +01:00
dependabot[bot]
0b9b46bbc8 build: Bump thiserror from 1.0.36 to 1.0.37
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.36...1.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-28 10:06:58 +01:00
Rob Bradford
06eb82d239 build: Consolidate "gdb" build feature into "guest_debug"
This simplifies the CI process but also logical with the existing
functionality under "guest_debug" (dumping guest memory).

Fixes: #4679

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-27 14:30:57 +01:00
Rob Bradford
b8503b5f45 hypervisor: Support compiling "tdx" and "mshv" feature together
TDX functionality is not currently available on MSHV but we should not
preclude building a binary that can run on both.

Fixes: #4677

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-27 14:30:49 +01:00
Sebastien Boeuf
3bf3cca70a vhost_user_net: Allow user to set MTU
Adding the support for the user to set the MTU for the vhost-user-net
backend, which allows the integration test to be extended with the test
of the MTU parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-27 10:37:35 +01:00
Sebastien Boeuf
903c08f8a1 net: Don't override default TAP interface MTU
Adjust MTU logic such that:
1. Apply an MTU to the TAP interface if the user supplies it
2. Always query the TAP interface for the MTU and expose that.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-27 10:37:35 +01:00
dependabot[bot]
44d66ec531 build: Bump proc-macro2 from 1.0.43 to 1.0.44
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.43 to 1.0.44.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.43...1.0.44)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 02:54:16 +00:00
dependabot[bot]
ac77d0923f build: Bump thiserror from 1.0.35 to 1.0.36
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.35 to 1.0.36.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.35...1.0.36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 02:19:05 +00:00
dependabot[bot]
ba3debaa27 build: Bump openssl-sys from 0.9.75 to 0.9.76
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.75 to 0.9.76.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.75...openssl-sys-v0.9.76)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 01:29:28 +00:00
dependabot[bot]
1ff26fbb8a build: Bump thiserror from 1.0.35 to 1.0.36 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.35 to 1.0.36.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.35...1.0.36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 00:54:29 +00:00
dependabot[bot]
4aa5d5a2c1 build: Bump syn from 1.0.100 to 1.0.101
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.100 to 1.0.101.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.100...1.0.101)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 00:37:22 +00:00
dependabot[bot]
023c77bdf3 build: Bump proc-macro2 from 1.0.43 to 1.0.44 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.43 to 1.0.44.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.43...1.0.44)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 00:19:14 +00:00
dependabot[bot]
e2a7972c59 build: Bump syn from 1.0.100 to 1.0.101 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.100 to 1.0.101.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.100...1.0.101)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-26 23:45:54 +00:00
dependabot[bot]
a4791263c9 build: Bump mshv-bindings from bf85430 to 2d0aaa1
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `bf85430` to `2d0aaa1`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](bf85430875...2d0aaa16b0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-26 23:42:43 +00:00
Rob Bradford
b2d1dd65f3 build: Remove "fwdebug" and "common" feature flags
This simplifes the buld and checks with very little overhead and the
fwdebug device is I/O port device on 0x402 that can be used by edk2 as a
very simple character device.

See: #4679

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-26 10:16:33 -07:00
Rob Bradford
36e26f004c .github: Consolidate quality checks into single worklow
Combine aarch64 and x86-64 checks into one workflow

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-26 16:52:42 +01:00
Rob Bradford
66c092e69b build: Bump linux-loader from 0.5.0 to 0.6.0
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Changelog](https://github.com/rust-vmm/linux-loader/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/linux-loader/compare/v0.5.0...v0.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-24 09:54:18 +00:00
dependabot[bot]
76903e5fd0 build: Bump jobserver from 0.1.24 to 0.1.25 in /fuzz
Bumps [jobserver](https://github.com/alexcrichton/jobserver-rs) from 0.1.24 to 0.1.25.
- [Release notes](https://github.com/alexcrichton/jobserver-rs/releases)
- [Commits](https://github.com/alexcrichton/jobserver-rs/compare/0.1.24...0.1.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-23 23:49:08 +00:00
Rob Bradford
cf31a303cf README: Add roadmap section pointing to our new GitHub project
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-23 14:30:15 -07:00
Bo Chen
ef603fde4c fuzz: Reduce the guest memory size for balloon fuzzer
As the virt queues are initialized with random bytes from the fuzzing
engine, a descriptor buffer for the available ring can have a very large
length (e.g. up to 4GB). This means there can be up to 1 billion
entries (e.g. page frame number) for virtio-balloon to process a signal
available descriptor (given each entry is 4 bytes). This is the reason
why oss-fuzz reported a hanging issue for this fuzzer, where the
generated descriptor buffer length is 4,278,321,152.

We can avoid this kind of long execution by reducing the size of guest
memory. For example, with 1MB of guest memory, the number of descriptor
entries for processing is limited ~256K.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-23 08:28:07 +01:00
dependabot[bot]
7a0bfd2e71 build: Bump serde from 1.0.144 to 1.0.145
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.144 to 1.0.145.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.144...v1.0.145)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-23 00:14:50 +00:00
dependabot[bot]
98aab37b00 build: Bump serde from 1.0.144 to 1.0.145 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.144 to 1.0.145.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.144...v1.0.145)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-22 23:38:42 +00:00
Rob Bradford
194b59f44b fuzz: Don't overload meaning of reset()
This function is for really for the transport layer to trigger a device
reset. Instead name it appropriately for the fuzzing specific use case.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 11:01:41 -07:00
Rob Bradford
c98bd2fd4a .github: Add clippy check of tracing feature
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 18:09:31 +01:00
Rob Bradford
e53419ecfc docs: Add documentation of tracing infrastructure
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 18:09:31 +01:00
Rob Bradford
5e811a6823 scripts: Add tracing visualisation script
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 18:09:31 +01:00
Rob Bradford
1202b9a07a vmm: Add some tracing of boot sequence
Add tracing of the VM boot sequence from the point at which the request
to create a VM is received to the hand-off to the vCPU threads running.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 18:09:31 +01:00
Rob Bradford
b35e6f3018 tracing: Tracing infrastructure
Add a new feature "tracing" that enables tracing functionality via the
"tracer" crate (sadly features and crates cannot share the same name.)

Setup: tracer::start()

The main functionality is a tracer::trace_scope()! macro that will add
trace points for the duration of the scope. Tracing events are per
thread.

Finish: tracer::end() this will write the trace file (pretty printed
JSON) to a file in the current directory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 18:09:31 +01:00
dependabot[bot]
56f163170c build: Bump rustix from 0.35.9 to 0.35.10 in /fuzz
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.9 to 0.35.10.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.9...v0.35.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-22 00:23:12 +00:00
dependabot[bot]
98c461e932 build: Bump rustix from 0.35.9 to 0.35.10
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.35.9 to 0.35.10.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.35.9...v0.35.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-21 23:47:11 +00:00
Sebastien Boeuf
76dbf85b79 net: Give the user the ability to set MTU
Add a new "mtu" parameter to the NetConfig structure and therefore to
the --net option. This allows Cloud Hypervisor's users to define the
Maximum Transmission Unit (MTU) they want to use for the network
interface that they create.

In details, there are two main aspects. On the one hand, the TAP
interface is created with the proper MTU if it is provided. And on the
other hand the guest is made aware of the MTU through the VIRTIO
configuration. That means the MTU is properly set on both the TAP on the
host and the network interface in the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-21 16:20:57 +02:00
dependabot[bot]
d95220108a build: Bump once_cell from 1.14.0 to 1.15.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.14.0...v1.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-21 00:35:35 +00:00
dependabot[bot]
5a9fe9855a build: Bump lock_api from 0.4.8 to 0.4.9
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.4.8 to 0.4.9.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.8...lock_api-0.4.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 23:48:00 +00:00
dependabot[bot]
2d0ba3637a build: Bump once_cell from 1.14.0 to 1.15.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.14.0...v1.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 23:42:38 +00:00
Rob Bradford
fdb4b32876 build: Disable SGX build
This was unfortunately missing from
430bfd38be which disabled the other builds
that rely on the bare metal systems.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 21:59:03 +01:00
Sebastien Boeuf
f38056fc9e virtio-devices, vmm: Simplify virtio-mem resize operation
There's no need to delegate the resize operation to the virtio-mem
thread. This can come directly from the vmm thread which will use the
Mem object to update the VIRTIO configuration and trigger the interrupt
for the guest to be notified.

In order to achieve what's described above, the VirtioMemZone structure
now has a handle onto the Mem object directly. This avoids the need for
intermediate Resize and ResizeSender structures.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-20 13:43:40 +02:00
Rob Bradford
430bfd38be build: Disable VFIO, metrics and rate limit testing
Bare metal x86-64 systems are offline

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 11:55:43 +01:00
Rob Bradford
2b53de58b3 build: Remove the exposed "cmos" feature
This only affects the build system; the feature was already always
compiled in with ca68b9e7a9

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 11:18:46 +01:00
Rob Bradford
d4d0780b89 tests: Fix aarch64 beta clippy issues
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 10:59:48 +01:00
Rob Bradford
a375e230b8 misc: Manual beta clippy fixes (boolean to int conversion using if)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 10:59:48 +01:00
Rob Bradford
f32487f8e8 misc: Automatic beta clippy fixes
e.g. cargo clippy --all --tests --all-targets --fix --features=..

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-20 10:59:48 +01:00
Bo Chen
ab0b3f1b7b fuzz: Add fuzzer for virtio-balloon
The fuzzer exercises the inflate, deflate and reporting events of
virtio-balloon via creating three queues and kicking three events.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-20 11:05:53 +02:00
Bo Chen
e1b483fc88 fuzz: Add fuzzer for virtio-rng
To make the fuzzer faster and more effective, the guest memory is
setup with a much smaller size (comparing with other virtio device
fuzzers) and  a hole between the memory for holding virtio queue and
the rest of guest data. It brings two benefits: 1) avoid writing large
chunk of data from 'urandom' into the available descriptor chain (which
makes the fuzzer faster); 2) reduce substantial amount of overwrites to
the virtio queue data by the data from 'urandom (which makes the fuzzer
more deterministic and hence effective).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-20 11:05:53 +02:00
Bo Chen
f815fcbb5d fuzz: Add fuzzer for virtio-watchdog
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-20 11:05:53 +02:00
dependabot[bot]
6a67675442 build: Bump syn from 1.0.99 to 1.0.100
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.99 to 1.0.100.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.99...1.0.100)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 09:34:37 +01:00
dependabot[bot]
50c3aa775b build: Bump libc from 0.2.132 to 0.2.133
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.132 to 0.2.133.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.132...0.2.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 01:24:56 +00:00
dependabot[bot]
14865a58a9 build: Bump env_logger from 0.9.0 to 0.9.1
Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/env-logger-rs/env_logger/releases)
- [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.9.0...v0.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 00:40:44 +00:00
dependabot[bot]
7d5f53439c build: Bump syn from 1.0.99 to 1.0.100 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.99 to 1.0.100.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.99...1.0.100)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-20 00:19:54 +00:00
dependabot[bot]
5123d0b1e1 build: Bump mshv-ioctls from 0106c24 to bf85430
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `0106c24` to `bf85430`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](0106c24a26...bf85430875)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-19 23:43:42 +00:00
dependabot[bot]
beee45a1ce build: Bump libc from 0.2.132 to 0.2.133 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.132 to 0.2.133.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.132...0.2.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-19 23:43:08 +00:00
Bo Chen
5f4a6b42c0 qcow: Fix wrong alignment calculation
With the existing code, `round_up(7, 2)` would generate `6` which is
obviously wrong. Also, following what's done for 'round_down()', the
fixed code does not handle 'alignment == 0' explicitly.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-17 10:23:49 +01:00
Bo Chen
134e555c42 vhdx: Fix wrong alignment calculation
With the existing macro, `align!(7, 4)` would generate `16` which is
obviously wrong. Also, given it is a macro, the compiler catch the error
if the provided 'alignment' is '0'.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-17 10:23:49 +01:00
dependabot[bot]
18f1be0fac build: Bump clap from 3.2.21 to 3.2.22
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.21 to 3.2.22.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.22/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.21...v3.2.22)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-17 00:31:42 +00:00
dependabot[bot]
001f10d614 build: Bump clap from 3.2.21 to 3.2.22 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.21 to 3.2.22.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.22/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.21...v3.2.22)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-16 23:54:11 +00:00
Sebastien Boeuf
1a2cd44e44 virtio-devices: balloon: Simplify the resize operation
There's no need to delegate the resize operation to the virtio-balloon
thread. This can come directly from the vmm thread which will use the
Balloon object to update the VIRTIO configuration and trigger the
interrupt for the guest to be notified.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-16 17:21:04 +02:00
Sebastien Boeuf
1849ffff31 vmm: Remove "amx" feature gate
Given the AMX x86 feature has been made available since kernel v5.17,
and given we don't have any test validating this feature, there's no
need to keep it behing a Rust feature gate.

Fixes #3996

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-16 15:03:31 +01:00
Rob Bradford
0e52be0909 vmm: Ensure default deserialisation for "amx" feature bit
This allows a migration from a binary not compiled with struct member to
be completed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-16 15:03:31 +01:00
Rob Bradford
19b006eb84 devices: legacy: pl011: Move boot timestamping to warn!()
This makes it consistent with x86_64 and allows the performance metrics
tooling to continue to work on aarch64.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-16 14:36:12 +01:00
Sebastien Boeuf
a5f655a032 virtio-devices: watchdog: Update process queue design
Update the implementation of the process_queue() function to match all
other virtio devices implementations. This solves some issue related to
potential out-of-bound accesses to the former used_desc_heads list.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-16 10:04:24 +01:00
Bo Chen
a4f781e142 vitio-devices: watchdog: Avoid panic and propagate errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-16 09:42:41 +02:00
Bo Chen
1c1bff93a1 vitio-devices: rng: Avoid panic and propagate errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-16 09:42:41 +02:00
dependabot[bot]
ec384af29e build: Bump unicode-xid from 0.2.3 to 0.2.4
Bumps [unicode-xid](https://github.com/unicode-rs/unicode-xid) from 0.2.3 to 0.2.4.
- [Release notes](https://github.com/unicode-rs/unicode-xid/releases)
- [Commits](https://github.com/unicode-rs/unicode-xid/commits/v0.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-16 02:23:01 +00:00
dependabot[bot]
f7a013da92 build: Bump textwrap from 0.15.0 to 0.15.1
Bumps [textwrap](https://github.com/mgeisler/textwrap) from 0.15.0 to 0.15.1.
- [Release notes](https://github.com/mgeisler/textwrap/releases)
- [Changelog](https://github.com/mgeisler/textwrap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mgeisler/textwrap/compare/0.15.0...0.15.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-16 01:49:13 +00:00
dependabot[bot]
5dfd64e9e2 build: Bump semver from 1.0.13 to 1.0.14
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.13 to 1.0.14.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.13...1.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-16 00:42:08 +00:00
dependabot[bot]
77bc86c8d3 build: Bump unicode-ident from 1.0.3 to 1.0.4 in /fuzz
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.3...1.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-16 00:18:33 +00:00
dependabot[bot]
3e16c2e257 build: Bump textwrap from 0.15.0 to 0.15.1 in /fuzz
Bumps [textwrap](https://github.com/mgeisler/textwrap) from 0.15.0 to 0.15.1.
- [Release notes](https://github.com/mgeisler/textwrap/releases)
- [Changelog](https://github.com/mgeisler/textwrap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mgeisler/textwrap/compare/0.15.0...0.15.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-15 23:47:56 +00:00
Wei Liu
9fe1643089 build: enable size optimization for release profile
This reduces the binary size from 7.3M to 6.5M.

Also the build time for a clean build shrinks from 1m28s to 1m14s on my
development machine (an eight-core VM on Azure). This goes against the
conventional wisdom but it is what it is.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-09-15 14:37:31 +01:00
Wei Liu
cb00dbe6ec build: update to the latest kvm-ioctls
The latest kvm-ioctls contains a breaking change to its API. Now Arm's
get/set_one_reg use u128 instead of u64.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-09-15 13:35:12 +01:00
Anatol Belski
253d16b4c9 README: Fix contents entry indent
The `#use-prebuilt-binaries` entry shifted to the left due to
wrong markup.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-09-15 12:31:05 +01:00
dependabot[bot]
2656b9b925 build: Bump unicode-ident from 1.0.3 to 1.0.4
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.3...1.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-15 10:12:14 +00:00
Rob Bradford
5aab82ccd2 Jenkinsfile: Move slack alert to new channel
This avoids spamming #general

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-15 10:19:56 +01:00
Anatol Belski
43c4270289 rpm: doc: Remove bundled SPEC and update README
Packages targeting various distributions are now available thanks to the
Open Bulid Service. The SPECS have been moved to a separate repo under

https://github.com/cloud-hypervisor/obs-packaging

which documents how to include pre-compiled binaires in a supported
distribution. Besides the Cloud Hypervisor itself, accompanying pieces
like UEFI bins are available, too.

Any contributions to the packaging can be also accepted in
the aforementioned repo. Further integration with the OBS like PR
validation is to be targeted there, too, as far as it can get. As the
packaging topic has moved in a separate repo, the bundled SPEC became
obsolete is suggested for removal.

Fixes: #4257

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-15 10:19:39 +01:00
dependabot[bot]
651506bfe5 build: Bump semver from 1.0.13 to 1.0.14 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.13 to 1.0.14.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.13...1.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-15 09:04:25 +00:00
dependabot[bot]
d6013904a8 build: Bump seccompiler from 0.2.0 to 0.3.0
Bumps [seccompiler](https://github.com/rust-vmm/seccompiler) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/rust-vmm/seccompiler/releases)
- [Changelog](https://github.com/rust-vmm/seccompiler/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/seccompiler/compare/v0.2.0...seccompiler-v0.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-15 08:29:49 +00:00
Bo Chen
91b8b00f95 fuzz: Add fuzzer for virtio-pmem
The fuzzer is focusing on the virtio-pmem code that processes guest
inputs (e.g. virt queues). Given 'flush' is the only virtio-pmem
request, the fuzzer is essentially testing the code for parsing and
error handling.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-15 09:08:11 +01:00
Bo Chen
67a89f4538 fuzz: Setup virt queue with proper addresses
To make the fuzzers more focused and more efficient, we now provide
default addresses for the descriptor table, available ring, and used
ring, which ensures the virt-queue has a valid memory layout (e.g. no
overlapping between descriptor tables, available ring, and used ring).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-15 09:08:11 +01:00
Anatol Belski
1d3bb63ec8 doc: Add VSOCK doc page
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-15 09:07:21 +01:00
Bo Chen
c8fe101b6f Jenkinsfile: Add CI worker for rate limiter tests
Given rate limiter tests are performance related, they need to be tested
on a bare-metal machine. It is now using the same node as the metrics CI.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
ef1983ee60 scripts: Add script to run rate limiter integration tests
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
d5219525d8 tests: Add rate limiter test for virtio block
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
af0a01c2fb test_infra: Add helper function to parse fio output for IOPS
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
652aa39934 test_infra: Support 'rw' and 'randrw' as FIO operations
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
a15b641c61 tests: Add rate limiter test for virtio net
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
Bo Chen
d8a6725995 performance-metrics: Move some helper functions to test_infra
The helper functions for measuring and parsing the performance of
virtio-net and virtio-block devices are moved to the `test_infra` crate
so that they be reused for integration tests of rate limiter.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-14 15:01:43 +01:00
dependabot[bot]
ecaff8ff1b build: Bulk dependencies update
Multiple rust-vmm crates must be updated at once given the vm-memory one
has been updated and they all rely on vm-memory.

- vm-memory from 0.8.0 to 0.9.0
- vhost from 0.4.0 to 0.5.0
- virtio-queue from 0.5.0 to 0.6.0
- vhost-user-backend from 0.6.0 to 0.7.0
- linux-loader from 0.4.0 to 0.5.0

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-14 15:01:04 +01:00
dependabot[bot]
06d7796190 build: bump anyhow from 1.0.64 to 1.0.65
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.64 to 1.0.65.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.64...1.0.65)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 02:24:55 +00:00
dependabot[bot]
4e589d2e13 build: bump clap from 3.2.20 to 3.2.21
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.20 to 3.2.21.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.21/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.20...v3.2.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 01:49:43 +00:00
dependabot[bot]
bf638a45de build: bump vfio-ioctls from c52e88a to bf7c9b9
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `c52e88a` to `bf7c9b9`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](c52e88ac55...bf7c9b997b)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 01:15:36 +00:00
dependabot[bot]
1d29c31e6b build: bump thiserror from 1.0.34 to 1.0.35
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.34 to 1.0.35.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.34...1.0.35)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 00:23:57 +00:00
dependabot[bot]
b84f41eac4 build: bump anyhow from 1.0.64 to 1.0.65 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.64 to 1.0.65.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.64...1.0.65)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 00:19:05 +00:00
dependabot[bot]
e5287d27b2 build: bump thiserror from 1.0.34 to 1.0.35 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.34 to 1.0.35.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.34...1.0.35)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-13 23:47:37 +00:00
Bo Chen
522e32219c virtio-devices: pmem: Avoid panic and propagate errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-13 09:56:06 -07:00
Bo Chen
4cc3bdba9f virtio-devices: pmem: Report errors from 'process_queue' properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-13 09:56:06 -07:00
Bo Chen
9d3ecefc00 virtio-devices: pmem: Derive thiserror::Error
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-13 09:56:06 -07:00
dependabot[bot]
561af4fd1a build: bump clap from 3.2.20 to 3.2.21 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.20 to 3.2.21.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.21/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.20...v3.2.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-13 00:15:07 +00:00
dependabot[bot]
e0634c48d0 build: bump io-uring from 0.5.5 to 0.5.6 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.5 to 0.5.6.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-12 23:41:43 +00:00
dependabot[bot]
e23319426d build: bump io-uring from 0.5.5 to 0.5.6
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.5 to 0.5.6.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-12 17:33:31 +00:00
dependabot[bot]
df6f1ea40c build: bump serde_with from 2.0.0 to 2.0.1
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v2.0.0...v2.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-10 00:54:08 +00:00
dependabot[bot]
b25f640ef5 build: bump serde_with_macros from 2.0.0 to 2.0.1
Bumps [serde_with_macros](https://github.com/jonasbb/serde_with) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v2.0.0...v2.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-10 00:17:33 +00:00
dependabot[bot]
f37d07c724 build: bump serde_with from 2.0.0 to 2.0.1 in /fuzz
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v2.0.0...v2.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-09 23:41:49 +00:00
dependabot[bot]
92713f7c5e build: bump arbitrary from 1.1.4 to 1.1.6 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.4 to 1.1.6.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.1.4...v1.1.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-08 23:46:12 +00:00
Bo Chen
60f3bd43f5 tests: live-migration: Split numa tests into its own function
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-08 10:31:50 +02:00
Bo Chen
e145b823a5 tests: live-migration: Split balloon tests into its own function
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-08 10:31:50 +02:00
Bo Chen
ff3e9eb668 tests: live-migration: Split watchdog tests into its own function
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-08 10:31:50 +02:00
Bo Chen
e3d7824f09 tests: Provide a function to log guests outputs w/ migration errors
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-08 10:31:50 +02:00
Bo Chen
d5481cddcf tests: Provide a function to start live migration
This function starts the 'receive-migration' for the destination VM,
'send-migration' for the source VM, waits for the live-migration
completion, and prints debug information upon errors.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-08 10:31:50 +02:00
dependabot[bot]
4e91199ff8 build: bump mshv-ioctls from 8094002 to 0106c24
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `8094002` to `0106c24`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](80940020f1...0106c24a26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-07 23:38:42 +00:00
Bo Chen
1817224fe9 tests: Refactor 'test_watchdog' for better readability
This patch moves the actual test logic and assertions from various
functions to the actual tests, which makes these tests more readable and
easier to debug.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-07 09:51:34 +01:00
Sebastien Boeuf
180251f057 Jenkinsfile: Re-enable x86-64 bare metal testing
The baremetal CI for x86-64 was disabled while the machines were out for
maintenance. Now that the machines are back up, let's re-enable the full
CI.

This reverts commit 476e30f5cb.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-07 09:32:03 +01:00
dependabot[bot]
fae801cd70 build: bump once_cell from 1.13.1 to 1.14.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.13.1...v1.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-06 11:29:57 +02:00
dependabot[bot]
2a222b2692 build: bump thiserror from 1.0.33 to 1.0.34
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.33...1.0.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-06 00:31:02 +00:00
dependabot[bot]
1435a58c1e build: bump thiserror from 1.0.33 to 1.0.34 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.33...1.0.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-05 23:52:54 +00:00
dependabot[bot]
d6f8411635 build: bump anyhow from 1.0.63 to 1.0.64
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.63 to 1.0.64.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.63...1.0.64)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-05 17:24:08 +00:00
dependabot[bot]
52d1b5f753 build: bump aho-corasick from 0.7.18 to 0.7.19
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 0.7.18 to 0.7.19.
- [Release notes](https://github.com/BurntSushi/aho-corasick/releases)
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/0.7.18...0.7.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-05 15:46:59 +00:00
Sebastien Boeuf
3b5c2b3718 tests: Disable test_windows_guest_disk_hotplug for aarch64
Until the issue #4583 is resolved, we must disable this test given it's
failing quite often on the aarch64 worker.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-05 17:08:34 +02:00
Rob Bradford
62681a776e README: Add host kernel version details
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-05 12:15:10 +01:00
Sebastien Boeuf
3793ffe888 vmm: config: Move TDX to rely on PayloadConfig
Removing the option --tdx to specify that we want to run a TD VM. Rely
on --platform option by adding the "tdx" boolean parameter. This is the
new way for enabling TDX with Cloud Hypervisor.

Along with this change, the way to retrieve the firmware path has been
updated to rely on the recently introduced PayloadConfig structure.

Fixes #4556

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-05 12:14:59 +01:00
dependabot[bot]
b05bd28321 build: bump mshv-ioctls from b7cd8a0 to 8094002
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `b7cd8a0` to `8094002`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](b7cd8a097c...80940020f1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-05 09:42:37 +00:00
dependabot[bot]
514ec79368 build: bump vm-fdt from ca35d96 to 8a19dcc
Bumps [vm-fdt](https://github.com/rust-vmm/vm-fdt) from `ca35d96` to `8a19dcc`.
- [Release notes](https://github.com/rust-vmm/vm-fdt/releases)
- [Commits](ca35d96191...8a19dcc94a)

---
updated-dependencies:
- dependency-name: vm-fdt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-04 10:27:59 +01:00
dependabot[bot]
39c1102c60 build: bump once_cell from 1.13.1 to 1.14.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.13.1...v1.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-03 09:19:16 +01:00
Rob Bradford
4465bbaf38 devices: acpi: Add generic event controller
Rather than overloading the GED device with the detection of what the
underlying event means move that to a new generic event controller.  The
advantage of this is that that the generic event controller can have a
_CRS that covers the memory for the OperationRegion (the ged driver
rejects _CRS entries that contain anything beyond the single interrupt)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-02 15:15:15 +01:00
Sebastien Boeuf
b3bef3adda vmm: acpi: Don't declare MMIO config space through PCI buses
The PCI buses should not declare the address space related to the MMIO
config space given it's already declared in the MCFG table and through
the motherboard device PNP0C02 in the DSDT table.

The PCI MMIO config region for the segment was being wrongly exposed as
part of the _CRS for the ACPI bus device (using Memory32Fixed). Exposing
it via this object was ineffectual as the equivalent entry in the
PNP0C02 (_SB_.MBRD) marked those ranges as not usable via the kernel.
Either way, with both devices used by the kernel, the kernel will not
try and use those memory ranges for the device BARs. However under
td-shim on TDX the PNP0C02 device is not on the permitted list of
devices so the the memory ranges were not marked as unusable resulting
in the kernel attempting to allocate BARs that collided with the PCI
MMIO configuration space.

This is based on the kernel documentation PCI/acpi-info.rst which relies
on ACPI and PCI Firmware specifications. And here are the interesting
quotes from this document:

"""
Prior to the addition of Extended Address Space descriptors, the failure
of Consumer/Producer meant there was no way to describe bridge registers
in the PNP0A03/PNP0A08 device itself. The workaround was to describe the
bridge registers (including ECAM space) in PNP0C02 catch-all devices.
With the exception of ECAM, the bridge register space is device-specific
anyway, so the generic PNP0A03/PNP0A08 driver (pci_root.c) has no need
to know about it.

PNP0C02 “motherboard” devices are basically a catch-all. There’s no
programming model for them other than “don’t use these resources for
anything else.” So a PNP0C02 _CRS should claim any address space that is
(1) not claimed by _CRS under any other device object in the ACPI
namespace and (2) should not be assigned by the OS to something else.

The address range reported in the MCFG table or by _CBA method (see
Section 4.1.3) must be reserved by declaring a motherboard resource. For
most systems, the motherboard resource would appear at the root of the
ACPI namespace (under _SB) in a node with a _HID of EISAID (PNP0C02),
and the resources in this case should not be claimed in the root PCI
bus’s _CRS. The resources can optionally be returned in Int15 E820 or
EFIGetMemoryMap as reserved memory but must always be reported through
ACPI as a motherboard resource.
"""

This change has been manually tested by running a VM with multiple
segments (4 segments), and by hotplugging an additional disk to the
segment number 2 (third segment).

From one shell:
"""
cloud-hypervisor \
    --cpus boot=1 \
    --memory size=1G \
    --kernel vmlinux \
    --cmdline "root=/dev/vda1 rw console=hvc0" \
    --disk path=jammy-server-cloudimg.raw \
    --api-socket /tmp/ch.sock \
    --platform num_pci_segments=4
"""

From another shell (after the VM is booted):
"""
ch-remote \
    --api-socket=/tmp/ch.sock \
    add-disk \
    path=test-disk.raw,id=disk2,pci_segment=2
"""

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-09-02 14:14:23 +02:00
dependabot[bot]
8e630710f9 build: bump libfuzzer-sys from 0.4.3 to 0.4.4 in /fuzz
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/rust-fuzz/libfuzzer/releases)
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.3...0.4.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-02 03:42:07 +00:00
dependabot[bot]
688602f3fc build: bump clap from 3.2.19 to 3.2.20 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.19 to 3.2.20.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.20/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.19...v3.2.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-02 03:08:07 +00:00
dependabot[bot]
7e4341d9e3 build: bump clap from 3.2.19 to 3.2.20
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.19 to 3.2.20.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.20/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.19...v3.2.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-02 02:07:12 +00:00
dependabot[bot]
817fa0dc81 build: bump io-uring from 0.5.4 to 0.5.5 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.4 to 0.5.5.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-02 01:07:41 +00:00
dependabot[bot]
0322a43312 build: bump mshv-ioctls from fb07da8 to b7cd8a0
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `fb07da8` to `b7cd8a0`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](fb07da88c3...b7cd8a097c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-02 00:48:33 +00:00
dependabot[bot]
75e4ee5362 build: bump io-uring from 0.5.4 to 0.5.5
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.4 to 0.5.5.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-02 00:06:46 +00:00
Bo Chen
3c6014554b tests: ovs_dpdk: Cleanup ovs-dpdk after terminating VMs
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-01 08:39:39 +02:00
Bo Chen
6cf4ea74fc tests: live-migration: Cleanup ovs-dpdk setup correctly on failures
As 'handle_child_output()' may terminate the test on panic, we need to
cleanup ovs-dpdk setup in advance.

see: #4555

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-01 08:39:39 +02:00
Bo Chen
742d6858f7 fuzz: block: Setup the virt queue based on the fuzzed input bytes
Instead of always fuzzing virt-queues with default values (mostly 0s),
the fuzzer now initializes the virt-queue based on the fuzzed input
bytes, such as the tail position of the available ring, queue size
selected by driver, descriptor table address, available ring address,
used ring address, etc. In this way, the fuzzer can explore the
virtio-block code path with various virt-queue setup.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-01 08:39:28 +02:00
dependabot[bot]
dc2365bfd0 build: bump io-uring from 0.5.3 to 0.5.4
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.3 to 0.5.4.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-01 03:40:25 +00:00
dependabot[bot]
41e22a7d03 build: bump thiserror from 1.0.32 to 1.0.33
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.32...1.0.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-01 03:00:36 +00:00
dependabot[bot]
8d68e78957 build: bump io-uring from 0.5.3 to 0.5.4 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.3 to 0.5.4.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [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>
2022-09-01 02:01:00 +00:00
dependabot[bot]
33d9ed9a66 build: bump anyhow from 1.0.62 to 1.0.63
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.62...1.0.63)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-01 01:00:52 +00:00
dependabot[bot]
fb5c792da6 build: bump anyhow from 1.0.62 to 1.0.63 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.62...1.0.63)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-01 01:00:34 +00:00
dependabot[bot]
7b9e826c2c build: bump paste from 1.0.8 to 1.0.9
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.8...1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-01 00:01:04 +00:00
dependabot[bot]
1d164abba4 build: bump thiserror from 1.0.32 to 1.0.33 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.32...1.0.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-01 00:00:24 +00:00
Nuno Das Neves
784a3aaf3c devices: gic: use VgicConfig everywhere
Use VgicConfig to initialize Vgic.
Use Gic::create_default_config everywhere so we don't always recompute
redist/msi registers.
Add a helper create_test_vgic_config for tests in hypervisor crate.

Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
2022-08-31 08:33:05 +01:00
Nuno Das Neves
a832033531 devices: gic: Introduce VgicConfig and Gic::create_default_config()
VgicConfig structure will be used for initializing the Vgic.
Gic::create_default_config will be used everywhere we currently compute
redist/msi registers.

Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
2022-08-31 08:33:05 +01:00
Jianyong Wu
3a19573c69 vmm: unify payload load chain on AArch64 with x86_64
AArch64 can share the same way of loading payload with x86_64. It makes
the payload loading more consistent between different arches.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2022-08-31 08:32:08 +01:00
Michael Zhao
b65639fad3 vmm:AArch64: move uefi_flash to memory manager
uefi_flash is used when load firmware, that is load payload depends on
device manager. move uefi_flash to memory manager can eliminate the
dependency.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-31 08:32:08 +01:00
Jianyong Wu
9b1452f258 vmm:AArch64: load standalone firmware
A new firmware item has been added into payload config, we need
extend ability to load standalone firmware on AArch64.
"load_kernel" method will be the entry of image loading work including
kernel and firmware.

This change is back compatible. So, we can either load firmware through
"-kernel" like before or "-firmware".

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2022-08-31 08:32:08 +01:00
Jianyong Wu
2054c8699a vmm:AArch64: add load_firmware method
Later, we will load standalone firmware. So, refactor load_kernel
by abstracting load_firmware method.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2022-08-31 08:32:08 +01:00
dependabot[bot]
c38d167523 build: bump clap from 3.2.18 to 3.2.19 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.18 to 3.2.19.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.19/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.18...v3.2.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 23:56:06 +00:00
dependabot[bot]
b04baf6017 build: bump clap from 3.2.18 to 3.2.19
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.18 to 3.2.19.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.19/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.18...v3.2.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 23:55:59 +00:00
Bo Chen
6cb214f15c fuzz: block: Rely on custom EpollHelper::run and VirtioCommon:reset
This commit also extends the copyright header.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-30 14:01:33 -07:00
Bo Chen
a9924df2b8 virtio-devices: Custom EpollHelper::run/VirtioCommon:reset for fuzz
It provides fuzzer a reliable way to wait for a sequence of events
to complete for virtio-devices while not using a fixed timeout to
maintain the full speed of fuzzing.

Take virtio-block as an example, the 'queue event' with a valid
available queue setup can trigger a 'completion event'. This is a
meaningful virtio-block code path of processing guest inputs which is
our target for fuzzing virtio devices.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-30 14:01:33 -07:00
Rob Bradford
616ec530a8 .github: workflows: Fail on intermediate steps for commit checks
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-08-30 21:40:31 +01:00
Rob Bradford
850c0c8319 .github: workflows: Fix per commit buildability check
Fetch the whole git repository (not just the specific commit) and use
the github context instead of hardcoded branch.

Unfortunately now that we process the list of revisions correctly it
shows that the checks don't work on aarch64 due to cross limitations so
this has been removed.

Fixes: #4523

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-08-30 21:40:31 +01:00
Sebastien Boeuf
8c02648ac9 vmm: device_manager: Update virtio-console for proper PTY support
Given the virtio-console is now able to buffer its output when no PTY is
connected on the other end, the device manager code is updated to enable
this. Moving the endpoint type from FilePair to PtyPair enables the
proper codepath in the virtio-console implementation, as well as
updating the PTY resize code, and forcing the PTY to always be
non-blocking.

The non-blocking behavior is required to avoid blocking the guest that
would be waiting on the virtio-console driver. When receiving an
EWOULDBLOCK error, the output will simply be redirected to the temporary
buffer so that it can be later flushed.

The PTY resize logic has been slightly modified to ensure the PTY file
descriptors are closed. It avoids the child process to keep a hold onto
the PTY device, which would have caused the PTY to believe something is
connected on the other end, which would have prevented the detection of
any new connection on the PTY.

Fixes #4521

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-30 13:47:51 +02:00
Sebastien Boeuf
a391bce781 virtio-devices: console: Detect PTY connection/disconnection
Through multiple changes, this patch aims at providing a reliable
solution for detecting the state of the PTY's connection. Being able to
find out when the other end of the PTY is connected is essential to
prevent the loss of data being output through the PTY. When the PTY
isn't connected, the output is buffered through the SerialBuffer, the
same solution that was created for the serial port initially.

Fixes #4521

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-30 13:47:51 +02:00
Sebastien Boeuf
9d2e835d14 virtio-devices: Extend EpollHelper and EpollHelperHandler
Extending and improving both the structure and the trait allows for more
flexibility regarding what can be achieved with the epoll loop. It
allows for a timeout to be configured instead of the default blocking
behavior. There is a new method in the trait to notify the caller that
the timeout has been reached. And there's a new knob to be notified with
the full list of events before the internal code will actually loop over
every event.

All of these new features are not affecting the previous behavior, and
using EpollHelper::run() should be unchanged.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-30 13:47:51 +02:00
Sebastien Boeuf
a940f525a8 vmm: Move SerialBuffer to its own crate
We want to be able to reuse the SerialBuffer from the virtio-devices
crate, particularly from the virtio-console implementation. That's why
we move the SerialBuffer definition to its own crate so that it can be
accessed from both vmm and virtio-devices crates, without creating any
cyclic dependency.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-30 13:47:51 +02:00
Sebastien Boeuf
63462fd8ab vmm: serial_manager: Iterate again on EINTR
If the epoll_wait() call returns EINTR, this only means a signal has
been delivered before any of the file descriptors registered triggered
an event or before the end of the timeout (if timeout isn't -1). For
that reason, we should simply try to listen on the epoll loop again.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-30 13:47:51 +02:00
Anatol Belski
2306291720 tests: Enable more Windows guest tests for aarch64
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-08-30 09:02:54 +01:00
dependabot[bot]
e833679428 build: bump clap from 3.2.17 to 3.2.18
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.17 to 3.2.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.18/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.17...v3.2.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 02:51:27 +00:00
dependabot[bot]
956907df97 build: bump mshv-bindings from 8a25e36 to fb07da8
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `8a25e36` to `fb07da8`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](8a25e361ce...fb07da88c3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 01:56:05 +00:00
dependabot[bot]
79be8b6216 build: bump lock_api from 0.4.7 to 0.4.8
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.4.7 to 0.4.8.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.7...lock_api-0.4.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 01:11:22 +00:00
dependabot[bot]
0d5b68d79c build: bump clap from 3.2.17 to 3.2.18 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.17 to 3.2.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v3.2.18/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.17...v3.2.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-30 00:27:09 +00:00
dependabot[bot]
31df1bcac0 build: bump arbitrary from 1.1.3 to 1.1.4 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.1.3...v1.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-29 23:50:51 +00:00
Sebastien Boeuf
0bcb6ff061 vmm: Limit the size of the SerialBuffer
We must limit how much the buffer can grow, otherwise this could lead
the process to consume all the memory on the machine. This could happen
if the output from the guest was very important and nothing would
connect to the PTY for a long time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-24 12:14:59 +02:00
Michael Zhao
d66d64c325 vmm: Restrict the maximum number of HW breakpoints
Set the maximum number of HW breakpoints according to the value returned
from `Hypervisor::get_guest_debug_hw_bps()`.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-23 16:57:12 +02:00
Michael Zhao
223b1f6c51 hypervisor: Introduce get_guest_debug_hw_bps()
Added `Hypervisor::get_guest_debug_hw_bps()` for fetching the number of
supported hardware breakpoints.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-23 16:57:12 +02:00
dependabot[bot]
3126b351c1 build: bump serde_json from 1.0.83 to 1.0.85
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.83 to 1.0.85.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.83...v1.0.85)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-23 05:41:18 +00:00
dependabot[bot]
bfe5aca254 build: bump serde from 1.0.143 to 1.0.144 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.143 to 1.0.144.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.143...v1.0.144)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-22 22:03:39 -07:00
dependabot[bot]
fba95cbc4c build: bump serde from 1.0.143 to 1.0.144
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.143 to 1.0.144.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.143...v1.0.144)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-23 00:22:35 +00:00
dependabot[bot]
86dc1b50e3 build: bump serde_json from 1.0.83 to 1.0.85 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.83 to 1.0.85.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.83...v1.0.85)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-22 23:42:53 +00:00
Wei Liu
3e6b0a5eab vmm: unify TranslateVirtualAddress error for both x86_64 and aarch64
Using anyhow::Error should cover both architectures.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-08-22 09:37:21 -07:00
Michael Zhao
88bbf7989a tests: Enable live upgrade tests on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-22 10:51:18 +08:00
Michael Zhao
c798b958f3 vmm: Extend seccomp rules for GDB
Add 'KVM_SET_GUEST_DEBUG' ioctl to seccomp filter rules.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-21 17:07:26 +08:00
Michael Zhao
575458ded4 hypervisor: Enable gdb HW breakpoint on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-21 17:07:26 +08:00
Michael Zhao
0522e40933 vmm: Implement translate_gva on AArch64
On AArch64, `translate_gva` API is not provided by KVM. We implemented
it in VMM by walking through translation tables.

Address translation is big topic, here we only focus the scenario that
happens in VMM while debugging kernel. This `translate_gva`
implementation is restricted to:
 - Exception Level 1
 - Translate high address range only (kernel space)

This implementation supports following Arm-v8a features related to
address translation:
 - FEAT_LPA
 - FEAT_LVA
 - FEAT_LPA2

The implementation supports page sizes of 4KiB, 16KiB and 64KiB.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-21 17:07:26 +08:00
Michael Zhao
5febdec81a vmm: Enable gdbstub on AArch64
The `gva_translate` function is still missing, it will be added with a
separate commit.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-21 17:07:26 +08:00
Michael Zhao
baa58ad8bf Cargo.lock: Update kvm-ioctls
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-08-21 17:07:26 +08:00
Nuno Das Neves
fdc8546eef vmm: aarch64: Use GIC_V3_* consts instead of magic numbers in create_madt()
Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
2022-08-21 17:06:48 +08:00
Sebastien Boeuf
cdcd4d259e vmm: serial: Wait for PTY to be available before writing to it
The goal of this patch is to provide a reliable way to detect when the
other end of the PTY is connected, and therefore be able to identify
when we can write to the PTY device. This is needed because writing to
the PTY device when the other end isn't connected causes the loss of
the written bytes.

The way to detect the connection on the other end of the PTY is by
knowing the other end is disconnected at first with the presence of the
EPOLLHUP event. Later on, when the connection happens, EPOLLHUP is not
triggered anymore, and that's when we can assume it's okay to write to
the PTY main device.

It's important to note we had to ensure the file descriptor for the
other end was closed, otherwise we would have never seen the EPOLLHUP
event. And we did so by removing the "sub" field from the PtyPair
structure as it was keeping the associated File opened.

Fixes #3170

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-08-19 14:39:06 +01:00
Bo Chen
1ee41a98de virtio-devices: net: Refactor 'handle_event' for readability
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-19 08:54:25 +02:00
Bo Chen
b4fe41ad0c virtio-devices: block: Refactor 'handle_event' for readability
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-19 08:54:25 +02:00
dependabot[bot]
0b15e378c7 build: bump gdbstub_arch from 0.2.3 to 0.2.4
Bumps [gdbstub_arch](https://github.com/daniel5151/gdbstub) from 0.2.3 to 0.2.4.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-19 02:11:15 +00:00
dependabot[bot]
7f51357812 build: bump gdbstub from 0.6.2 to 0.6.3
Bumps [gdbstub](https://github.com/daniel5151/gdbstub) from 0.6.2 to 0.6.3.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.6.2...0.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-19 00:36:29 +00:00
dependabot[bot]
6fefca39e6 build: bump mshv-ioctls from a4c9916 to 8a25e36
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `a4c9916` to `8a25e36`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](a4c9916124...8a25e361ce)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-18 23:49:56 +00:00
dependabot[bot]
0b7d2caf76 build: bump libc from 0.2.131 to 0.2.132 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.131 to 0.2.132.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.131...0.2.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-18 23:41:40 +00:00
Rob Bradford
396f9ce2c6 vmm: Deprecate non-PVH firmware loading
Curently all the firmware blobs we support can use PVH loading.

See: #4511

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-08-18 17:29:44 +01:00
Markus Napierkowski
b49f8b9248 virtio-devices: rng: correctly indicate number of bytes written
Reads from the random file may only be partial, e.g., if the random file is an ordinary text
file. When that happens, the device needs to signal to the driver that only parts of the buffer have
been overwritten.

Signed-off-by: Markus Napierkowski <markus.napierkowski@cyberus-technology.de>
2022-08-18 14:44:58 +01:00
Rob Bradford
31dfe3d02a tests: Enable live upgrade tests
Following our recent v26.0 release we can re-enable our live upgrade
tests to try and make it possible for us to move to making LTS releases.

Currently limited to x86-64 as the live upgrade tests fail on aarch64.

Fixes: #3949

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-08-18 14:41:22 +01:00
Rob Bradford
476e30f5cb Jenkinsfile: Temporarily remove x86-64 bare metal testing
These machines will be temporarily unavailable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-08-17 11:18:47 -07:00
dependabot[bot]
ccc88ccfd2 build: bump libc from 0.2.131 to 0.2.132
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.131 to 0.2.132.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.131...0.2.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-17 16:30:47 +00:00
191 changed files with 12141 additions and 6947 deletions

View File

@@ -36,26 +36,20 @@ jobs:
- name: Build (default features)
run: cargo rustc --locked --bin cloud-hypervisor -- -D warnings
- name: Build (common + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "common,kvm" -- -D warnings
- name: Build (kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "kvm" -- -D warnings
- name: Build (default features + tdx)
run: cargo rustc --locked --bin cloud-hypervisor --features "tdx" -- -D warnings
- name: Build (default features + amx)
run: cargo rustc --locked --bin cloud-hypervisor --features "amx" -- -D warnings
- name: Build (default features + gdb)
run: cargo rustc --locked --bin cloud-hypervisor --features "gdb" -- -D warnings
- name: Build (default features + guest_debug)
run: cargo rustc --locked --bin cloud-hypervisor --features "guest_debug" -- -D warnings
- name: Build (common + mshv)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "common,mshv" -- -D warnings
- name: Build (mshv)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv" -- -D warnings
- name: Build (common + mshv + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "common,mshv,kvm" -- -D warnings
- name: Build (mshv + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv,kvm" -- -D warnings
- name: Release Build (default features)
run: cargo build --locked --all --release --target=${{ matrix.target }}

View File

@@ -1,53 +0,0 @@
name: Cloud Hypervisor Quality Checks
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Quality (clippy, rustfmt)
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
rust:
- stable
target:
- aarch64-unknown-linux-gnu
experimental: [false]
include:
- rust: beta
target: aarch64-unknown-linux-gnu
experimental: true
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
components: rustfmt, clippy
- name: Debug Check (default features)
run: |
git rev-list origin/main..$GITHUB_SHA | xargs -t -I % sh -c 'git checkout %; cargo check --tests --all --target=${{ matrix.target }}'
git checkout $GITHUB_SHA
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (common + kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --tests --all --no-default-features --features "common,kvm" -- -D warnings
- name: Clippy (default features)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --tests --all -- -D warnings

View File

@@ -14,14 +14,21 @@ jobs:
- stable
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
experimental: [false]
include:
- rust: beta
target: x86_64-unknown-linux-gnu
experimental: true
- rust: beta
target: aarch64-unknown-linux-gnu
experimental: true
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
@@ -31,33 +38,67 @@ jobs:
components: rustfmt, clippy
- name: Debug Check (default features)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
run: |
git rev-list origin/main..$GITHUB_SHA | xargs -t -I % sh -c 'git checkout %; cargo check --tests --all --target=${{ matrix.target }}'
git checkout $GITHUB_SHA
set -e
commits=$(git rev-list origin/${{ github.base_ref }}..${{ github.sha }})
for commit in $commits; do git checkout $commit; cargo check --tests --all --target=${{ matrix.target }}; done
git checkout ${{ github.sha }}
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (common + kvm)
run: cargo clippy --locked --all --all-targets --no-default-features --tests --features "common,kvm" -- -D warnings
- name: Clippy (kvm)
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --locked --all --all-targets --no-default-features --tests --features "kvm" -- -D warnings
- name: Clippy (default features)
run: cargo clippy --locked --all --all-targets --tests -- -D warnings
- name: Clippy (default features + amx)
run: cargo clippy --locked --all --all-targets --tests --features "amx" -- -D warnings
- name: Clippy (default features + gdb)
run: cargo clippy --locked --all --all-targets --tests --features "gdb" -- -D warnings
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --locked --all --all-targets --tests -- -D warnings
- name: Clippy (default features + guest_debug)
run: cargo clippy --locked --all --all-targets --tests --features "guest_debug" -- -D warnings
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --locked --all --all-targets --tests --features "guest_debug" -- -D warnings
- name: Clippy (common + mshv)
run: cargo clippy --locked --all --all-targets --no-default-features --tests --features "common,mshv" -- -D warnings
- name: Clippy (default features + tracing)
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --locked --all --all-targets --tests --features "tracing" -- -D warnings
- name: Clippy (common + mshv + kvm)
run: cargo clippy --locked --all --all-targets --no-default-features --tests --features "common,mshv,kvm" -- -D warnings
- name: Clippy (mshv)
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: --locked --all --all-targets --no-default-features --tests --features "mshv" -- -D warnings
- name: Clippy (mshv + kvm)
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: --locked --all --all-targets --no-default-features --tests --features "mshv,kvm" -- -D warnings
- name: Clippy (kvm + tdx)
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: --locked --all --all-targets --no-default-features --tests --features "tdx,kvm" -- -D warnings
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"

View File

@@ -1,28 +1,28 @@
name: Cloud Hypervisor Release
on: [create]
on: [pull_request, create]
jobs:
release:
if: github.event_name == 'create' && github.event.ref_type == 'tag'
if: (github.event_name == 'create' && github.event.ref_type == 'tag') || github.event_name == 'pull_request'
name: Release
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install musl-gcc
run: sudo apt install -y musl-tools
run: sudo apt install -y musl-tools
- name: Create release directory
run: rsync -rv --exclude=.git . ../cloud-hypervisor-${{ github.event.ref }}
- name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.62"
target: x86_64-unknown-linux-gnu
toolchain: "1.62"
target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.62"
target: x86_64-unknown-linux-musl
toolchain: "1.62"
target: x86_64-unknown-linux-musl
- name: Build
uses: actions-rs/cargo@v1
with:
@@ -35,28 +35,14 @@ jobs:
toolchain: "1.62"
command: build
args: --all --release --target=x86_64-unknown-linux-musl
- name: Strip cloud-hypervisor binaries
run: strip target/*/release/cloud-hypervisor
- name: Install Rust toolchain (aarch64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.62"
target: aarch64-unknown-linux-musl
override: true
- name: Static Build (AArch64)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --all --release --target=aarch64-unknown-linux-musl
- name: Vendor
working-directory: ../cloud-hypervisor-${{ github.event.ref }}
run: |
mkdir ../vendor-cargo-home
export CARGO_HOME=$(realpath ../vendor-cargo-home)
mkdir .cargo
cargo vendor > .cargo/config.toml
toolchain: "1.62"
target: aarch64-unknown-linux-musl
override: true
- name: Create Release
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: create_release
uses: actions/create-release@v1
env:
@@ -66,20 +52,8 @@ jobs:
release_name: ${{ github.ref }}
draft: true
prerelease: true
- name: Create vendored source archive
working-directory: ../
run: tar cJf cloud-hypervisor-${{ github.event.ref }}.tar.xz cloud-hypervisor-${{ github.event.ref }}
- name: Upload cloud-hypervisor vendored source archive
id: upload-release-cloud-hypervisor-vendored-sources
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ../cloud-hypervisor-${{ github.event.ref }}.tar.xz
asset_name: cloud-hypervisor-${{ github.event.ref }}.tar.xz
asset_content_type: application/x-xz
- name: Upload cloud-hypervisor
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-cloud-hypervisor
uses: actions/upload-release-asset@v1
env:
@@ -90,6 +64,7 @@ jobs:
asset_name: cloud-hypervisor
asset_content_type: application/octet-stream
- name: Upload static cloud-hypervisor
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-static-cloud-hypervisor
uses: actions/upload-release-asset@v1
env:
@@ -100,6 +75,7 @@ jobs:
asset_name: cloud-hypervisor-static
asset_content_type: application/octet-stream
- name: Upload ch-remote
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-ch-remote
uses: actions/upload-release-asset@v1
env:
@@ -110,6 +86,7 @@ jobs:
asset_name: ch-remote
asset_content_type: application/octet-stream
- name: Upload static-ch-remote
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-static-ch-remote
uses: actions/upload-release-asset@v1
env:
@@ -119,7 +96,18 @@ jobs:
asset_path: target/x86_64-unknown-linux-musl/release/ch-remote
asset_name: ch-remote-static
asset_content_type: application/octet-stream
- name: Clean build tree ahead of cross build
uses: actions-rs/cargo@v1
with:
command: clean
- name: Static Build (AArch64)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --all --release --target=aarch64-unknown-linux-musl
- name: Upload static AArch64 cloud-hypervisor
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-static-aarch64-cloud-hypervisor
uses: actions/upload-release-asset@v1
env:
@@ -130,6 +118,7 @@ jobs:
asset_name: cloud-hypervisor-static-aarch64
asset_content_type: application/octet-stream
- name: Upload static AArch64 ch-remote
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-static-aarch64-ch-remote
uses: actions/upload-release-asset@v1
env:
@@ -139,3 +128,24 @@ jobs:
asset_path: target/aarch64-unknown-linux-musl/release/ch-remote
asset_name: ch-remote-static-aarch64
asset_content_type: application/octet-stream
- name: Vendor
working-directory: ../cloud-hypervisor-${{ github.event.ref }}
run: |
mkdir ../vendor-cargo-home
export CARGO_HOME=$(realpath ../vendor-cargo-home)
mkdir .cargo
cargo vendor > .cargo/config.toml
- name: Create vendored source archive
working-directory: ../
run: tar cJf cloud-hypervisor-${{ github.event.ref }}.tar.xz cloud-hypervisor-${{ github.event.ref }}
- name: Upload cloud-hypervisor vendored source archive
if: github.event_name == 'create' && github.event.ref_type == 'tag'
id: upload-release-cloud-hypervisor-vendored-sources
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ../cloud-hypervisor-${{ github.event.ref }}.tar.xz
asset_name: cloud-hypervisor-${{ github.event.ref }}.tar.xz
asset_content_type: application/x-xz

526
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "26.0.0"
version = "28.2.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -14,54 +14,53 @@ rust-version = "1.60"
[profile.release]
lto = true
codegen-units = 1
opt-level = "s"
strip = true
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.66"
api_client = { path = "api_client" }
clap = { version = "3.2.17", features = ["wrap_help","cargo"] }
clap = { version = "4.0.29", features = ["wrap_help","cargo","string"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.131"
libc = "0.2.138"
log = { version = "0.4.17", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.2.0"
serde_json = "1.0.83"
seccompiler = "0.3.0"
serde_json = "1.0.89"
signal-hook = "0.3.14"
thiserror = "1.0.32"
thiserror = "1.0.37"
tpm = { path = "tpm"}
tracer = { path = "tracer" }
vmm = { path = "vmm" }
vmm-sys-util = "0.10.0"
vm-memory = "0.8.0"
vmm-sys-util = "0.11.0"
vm-memory = "0.10.0"
[build-dependencies]
clap = { version = "3.2.17", features = ["cargo"] }
clap = { version = "4.0.29", features = ["cargo"] }
# List of patched crates
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0-tdx" }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
[dev-dependencies]
dirs = "4.0.0"
net_util = { path = "net_util" }
once_cell = "1.13.1"
serde_json = "1.0.83"
once_cell = "1.16.0"
serde_json = "1.0.89"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
[features]
default = ["common", "kvm"]
# Common features for all hypervisors
common = ["fwdebug"]
amx = ["vmm/amx"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
gdb = ["vmm/gdb"]
default = ["kvm"]
guest_debug = ["vmm/guest_debug"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
tdx = ["vmm/tdx"]
tracing = ["vmm/tracing", "tracer/tracing"]
[workspace]
members = [
@@ -79,7 +78,9 @@ members = [
"performance-metrics",
"qcow",
"rate_limiter",
"serial_buffer",
"test_infra",
"tracer",
"vfio_user",
"vhdx",
"vhost_user_block",

757
Jenkinsfile vendored
View File

@@ -1,452 +1,333 @@
def runWorkers = true
pipeline{
agent none
stages {
stage ('Early checks') {
agent { node { label 'built-in' } }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Check for documentation only changes') {
when {
expression {
return docsFileOnly()
}
}
steps {
script {
runWorkers = false
echo "Documentation only changes, no need to run the CI"
}
}
}
stage ('Check for fuzzer files only changes') {
when {
expression {
return fuzzFileOnly()
}
}
steps {
script {
runWorkers = false
echo "Fuzzer cargo files only changes, no need to run the CI"
}
}
}
stage ('Check for RFC/WIP builds') {
when {
changeRequest comparator: 'REGEXP', title: '.*(rfc|RFC|wip|WIP).*'
beforeAgent true
}
steps {
error("Failing as this is marked as a WIP or RFC PR.")
}
}
stage ('Cancel older builds') {
when { not { branch 'main' } }
steps {
cancelPreviousBuilds()
}
}
}
}
stage ('Build') {
parallel {
stage ('Worker build') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Prepare environment') {
steps {
sh "scripts/prepare_vdpa.sh"
}
}
stage ('Run OpenAPI tests') {
steps {
sh "scripts/run_openapi_tests.sh"
}
}
stage ('Run unit tests') {
steps {
sh "scripts/dev_cli.sh tests --unit"
}
}
stage ('Run integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration"
}
}
}
}
stage ('AArch64 worker build') {
agent { node { label 'bionic-arm64' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run unit tests') {
steps {
sh "scripts/dev_cli.sh tests --unit --libc musl"
}
}
stage ('Run integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration --libc musl"
}
}
stage ('Install azure-cli') {
steps {
installAzureCli("bionic", "arm64")
}
}
stage ('Download Windows image') {
steps {
sh '''#!/bin/bash -x
IMG_BASENAME=windows-11-iot-enterprise-aarch64.raw
IMG_PATH=$HOME/workloads/$IMG_BASENAME
IMG_GZ_PATH=$HOME/workloads/$IMG_BASENAME.gz
IMG_GZ_BLOB_NAME=windows-11-iot-enterprise-aarch64-9-min.raw.gz
cp "scripts/$IMG_BASENAME.sha1" "$HOME/workloads/"
pushd "$HOME/workloads"
if sha1sum "$IMG_BASENAME.sha1" --check; then
exit
fi
popd
mkdir -p "$HOME/workloads"
az storage blob download \
--container-name private-images \
--file "$IMG_GZ_PATH" \
--name "$IMG_GZ_BLOB_NAME" \
--connection-string "$AZURE_CONNECTION_STRING"
gzip -d $IMG_GZ_PATH
'''
}
}
stage ('Run Windows guest integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-windows --libc musl"
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage ('Worker build (musl)') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Prepare environment') {
steps {
sh "scripts/prepare_vdpa.sh"
}
}
stage ('Run unit tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --unit --libc musl"
}
}
stage ('Run integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration --libc musl"
}
}
}
}
stage ('Worker build SGX') {
agent { node { label 'bionic-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 'bionic-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 - Windows guest') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Install azure-cli') {
steps {
installAzureCli("jammy", "amd64")
}
}
stage ('Download assets') {
steps {
sh "mkdir ${env.HOME}/workloads"
sh 'az storage blob download --container-name private-images --file "$HOME/workloads/windows-server-2019.raw" --name windows-server-2019.raw --connection-string "$AZURE_CONNECTION_STRING"'
}
}
stage ('Run Windows guest integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-windows"
}
}
stage ('Run Windows guest integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-windows --libc musl"
}
}
}
}
stage ('Worker build - Live Migration') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run live-migration integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration-live-migration"
}
}
stage ('Run live-migration integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration-live-migration --libc musl"
}
}
}
}
stage ('Worker build - Metrics') {
agent { node { label 'focal-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'
}
}
}
}
}
}
}
post {
regression {
script {
if (env.BRANCH_NAME == 'main') {
slackSend (color: '#ff0000', message: '"main" branch build is now failing')
}
}
}
fixed {
script {
if (env.BRANCH_NAME == 'main') {
slackSend (color: '#00ff00', message: '"main" branch build is now fixed')
}
}
}
}
pipeline {
agent none
stages {
stage('Early checks') {
agent { node { label 'built-in' } }
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Check for documentation only changes') {
when {
expression {
return docsFileOnly()
}
}
steps {
script {
runWorkers = false
echo 'Documentation only changes, no need to run the CI'
}
}
}
stage('Check for fuzzer files only changes') {
when {
expression {
return fuzzFileOnly()
}
}
steps {
script {
runWorkers = false
echo 'Fuzzer cargo files only changes, no need to run the CI'
}
}
}
stage('Check for RFC/WIP builds') {
when {
changeRequest comparator: 'REGEXP', title: '.*(rfc|RFC|wip|WIP).*'
beforeAgent true
}
steps {
error('Failing as this is marked as a WIP or RFC PR.')
}
}
stage('Cancel older builds') {
when { not { branch 'main' } }
steps {
cancelPreviousBuilds()
}
}
}
}
stage('Build') {
parallel {
stage('Worker build') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Prepare environment') {
steps {
sh 'scripts/prepare_vdpa.sh'
}
}
stage('Run OpenAPI tests') {
steps {
sh 'scripts/run_openapi_tests.sh'
}
}
stage('Run unit tests') {
steps {
sh 'scripts/dev_cli.sh tests --unit'
}
}
stage('Run integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration'
}
}
stage('Run live-migration integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration-live-migration'
}
}
stage('Run unit tests for musl') {
steps {
sh 'scripts/dev_cli.sh tests --unit --libc musl'
}
}
stage('Run integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration --libc musl'
}
}
stage('Run live-migration integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration-live-migration --libc musl'
}
}
}
}
stage('AArch64 worker build') {
agent { node { label 'bionic-arm64' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run unit tests') {
steps {
sh 'scripts/dev_cli.sh tests --unit --libc musl'
}
}
stage('Run integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration --libc musl'
}
}
stage('Install azure-cli') {
steps {
installAzureCli('bionic', 'arm64')
}
}
stage('Download Windows image') {
steps {
sh '''#!/bin/bash -x
IMG_BASENAME=windows-11-iot-enterprise-aarch64.raw
IMG_PATH=$HOME/workloads/$IMG_BASENAME
IMG_GZ_PATH=$HOME/workloads/$IMG_BASENAME.gz
IMG_GZ_BLOB_NAME=windows-11-iot-enterprise-aarch64-9-min.raw.gz
cp "scripts/$IMG_BASENAME.sha1" "$HOME/workloads/"
pushd "$HOME/workloads"
if sha1sum "$IMG_BASENAME.sha1" --check; then
exit
fi
popd
mkdir -p "$HOME/workloads"
az storage blob download \
--container-name private-images \
--file "$IMG_GZ_PATH" \
--name "$IMG_GZ_BLOB_NAME" \
--connection-string "$AZURE_CONNECTION_STRING"
gzip -d $IMG_GZ_PATH
'''
}
}
stage('Run Windows guest integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-windows --libc musl'
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage('Worker build - Windows guest') {
agent { node { label 'jammy' } }
when {
beforeAgent true
expression {
return runWorkers
}
}
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install azure-cli') {
steps {
installAzureCli('jammy', 'amd64')
}
}
stage('Download assets') {
steps {
sh "mkdir ${env.HOME}/workloads"
sh 'az storage blob download --container-name private-images --file "$HOME/workloads/windows-server-2019.raw" --name windows-server-2019.raw --connection-string "$AZURE_CONNECTION_STRING"'
}
}
stage('Run Windows guest integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-windows'
}
}
stage('Run Windows guest integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-windows --libc musl'
}
}
}
}
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'
}
}
}
}
}
}
}
post {
regression {
script {
if (env.BRANCH_NAME == 'main') {
slackSend(color: '#ff0000', message: '"main" branch build is now failing', channel: '#jenkins-ci')
}
}
}
fixed {
script {
if (env.BRANCH_NAME == 'main') {
slackSend(color: '#00ff00', message: '"main" branch build is now fixed', channel: '#jenkins-ci')
}
}
}
}
}
def cancelPreviousBuilds() {
// Check for other instances of this particular build, cancel any that are older than the current one
def jobName = env.JOB_NAME
def currentBuildNumber = env.BUILD_NUMBER.toInteger()
def currentJob = Jenkins.instance.getItemByFullName(jobName)
// Check for other instances of this particular build, cancel any that are older than the current one
def jobName = env.JOB_NAME
def currentBuildNumber = env.BUILD_NUMBER.toInteger()
def currentJob = Jenkins.instance.getItemByFullName(jobName)
// Loop through all instances of this particular job/branch
for (def build : currentJob.builds) {
if (build.isBuilding() && (build.number.toInteger() < currentBuildNumber)) {
echo "Older build still queued. Sending kill signal to build number: ${build.number}"
build.doStop()
}
}
// Loop through all instances of this particular job/branch
for (def build : currentJob.builds) {
if (build.isBuilding() && (build.number.toInteger() < currentBuildNumber)) {
echo "Older build still queued. Sending kill signal to build number: ${build.number}"
build.doStop()
}
}
}
def installAzureCli(distro, arch) {
sh "sudo apt install -y ca-certificates curl apt-transport-https lsb-release gnupg"
sh "curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null"
sh "echo \"deb [arch=${arch}] https://packages.microsoft.com/repos/azure-cli/ ${distro} main\" | sudo tee /etc/apt/sources.list.d/azure-cli.list"
sh "sudo apt update"
sh "sudo apt install -y azure-cli"
sh 'sudo apt install -y ca-certificates curl apt-transport-https lsb-release gnupg'
sh 'curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null'
sh "echo \"deb [arch=${arch}] https://packages.microsoft.com/repos/azure-cli/ ${distro} main\" | sudo tee /etc/apt/sources.list.d/azure-cli.list"
sh 'sudo apt update'
sh 'sudo apt install -y azure-cli'
}
def boolean docsFileOnly() {
if (env.CHANGE_TARGET == null) {
return false;
return false
}
return sh(
@@ -457,7 +338,7 @@ def boolean docsFileOnly() {
def boolean fuzzFileOnly() {
if (env.CHANGE_TARGET == null) {
return false;
return false
}
return sh(

352
README.md
View File

@@ -4,42 +4,43 @@
- [Architectures](#architectures)
- [Guest OS](#guest-os)
- [2. Getting Started](#2-getting-started)
- [Preparation](#preparation)
- [Install prerequisites](#install-prerequisites)
- [Clone and build](#clone-and-build)
- [Containerized builds and tests](#containerized-builds-and-tests)
- [Run](#run)
- [Cloud image](#cloud-image)
- [Custom kernel and disk image](#custom-kernel-and-disk-image)
- [Building your kernel](#building-your-kernel)
- [Host OS](#host-os)
- [Use Pre-built Binaries](#use-pre-built-binaries)
- [Packages](#packages)
- [Building from Source](#building-from-source)
- [Booting Linux](#booting-linux)
- [Firmware Booting](#firmware-booting)
- [Custom Kernel and Disk Image](#custom-kernel-and-disk-image)
- [Building your Kernel](#building-your-kernel)
- [Disk image](#disk-image)
- [Booting the guest VM](#booting-the-guest-vm)
- [3. Status](#3-status)
- [Hot Plug](#hot-plug)
- [Device Model](#device-model)
- [TODO](#todo)
- [4. `rust-vmm` project dependency](#4-rust-vmm-project-dependency)
- [Firecracker and crosvm](#firecracker-and-crosvm)
- [Roadmap](#roadmap)
- [4. Relationship with _Rust VMM_ Project](#4-relationship-with-rust-vmm-project)
- [Differences with Firecracker and crosvm](#differences-with-firecracker-and-crosvm)
- [5. Community](#5-community)
- [Contribute](#contribute)
- [Join us](#join-us)
- [Slack](#slack)
- [Mailing list](#mailing-list)
- [Security issues](#security-issues)
# 1. What is Cloud Hypervisor?
Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on
top of [KVM](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
hypervisor and Microsoft Hypervisor (MSHV).
top of the [KVM](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
hypervisor and the Microsoft Hypervisor (MSHV).
The project focuses on exclusively running modern, cloud workloads, on top of
a limited set of hardware architectures and platforms. Cloud workloads refers
to those that are usually run by customers inside a cloud provider. For our
purposes this means modern operating systems with most I/O handled by
paravirtualised devices (i.e. virtio), no requirement for legacy devices, and
The project focuses on running modern, _Cloud Workloads_, on specific, common,
hardware architectures. In this case _Cloud Workloads_ refers to those that are
run by customers inside a Cloud Service Provider. This means modern operating
systems with most I/O handled by
paravirtualised devices (e.g. _virtio_), no requirement for legacy devices, and
64-bit CPUs.
Cloud Hypervisor is implemented in [Rust](https://www.rust-lang.org/) and is
based on the [rust-vmm](https://github.com/rust-vmm) crates.
based on the [Rust VMM](https://github.com/rust-vmm) crates.
## Objectives
@@ -59,7 +60,7 @@ based on the [rust-vmm](https://github.com/rust-vmm) crates.
### Architectures
Cloud Hypervisor supports the `x86-64` and `AArch64` architectures. There are
some small differences in functionality between the two architectures
minor differences in functionality between the two architectures
(see [#1125](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/1125)).
### Guest OS
@@ -68,142 +69,121 @@ Cloud Hypervisor supports `64-bit Linux` and Windows 10/Windows Server 2019.
# 2. Getting Started
Below sections describe how to build and run Cloud Hypervisor on the `x86_64`
platform. For getting started on the `AArch64` platform, please refer to the
[Arm64 documentation](docs/arm64.md).
The following sections describe how to build and run Cloud Hypervisor on the
`x86-64` platform. For getting started on the `AArch64` platform, please refer
to the
[AArch64 documentation](docs/arm64.md).
## Preparation
## Host OS
We create a folder to build and run `cloud-hypervisor` at `$HOME/cloud-hypervisor`
For required KVM functionality the minimum host kernel version is 4.11. For
adequate performance the minimum recommended host kernel version is 5.6. The
majority of the CI currently tests with kernel version 5.15.
## Use Pre-built Binaries
The recommended approach to getting started with Cloud Hypervisor is by using a
pre-built binary. Binaries are available for the [latest
release](https://github.com/cloud-hypervisor/cloud-hypervisor/releases/latest).
Use `cloud-hypervisor-static` for `x86-64` or `cloud-hypervisor-static-aarch64`
for `AArch64` platform.
## Packages
For convenience, packages are also available targeting some popular Linux
distributions. This is thanks to the [Open Build
Service](https://build.opensuse.org). The [OBS
README](https://github.com/cloud-hypervisor/obs-packaging) explains how to
enable the repository in a supported Linux distribution and install Cloud Hypervisor
and accompanying packages. Please report any packaging issues in the
[obs-packaging](https://github.com/cloud-hypervisor/obs-packaging) repository.
## Building from Source
Please see the [instructions for building from source](docs/building.md) if you
do not wish to use the pre-built binaries.
## Booting Linux
The instructions below are for the `x86-64` platform. For `AArch64` please see
the [AArch64 specific documentation](docs/arm64.md).
Cloud Hypervisor supports direct kernel boot (if the kernel is built with PVH
support) or booting via a firmware (either [Rust Hypervisor
Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware) or an
edk2 UEFI firmware called `CLOUDHV`.)
Binary builds of the firmware files are available for the latest release of
[Rust Hyperivor
Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/latest)
and [our edk2
repository](https://github.com/cloud-hypervisor/edk2/releases/latest)
The choice of firmware depends on your guest OS choice; some experimentation
may be required.
### Firmware Booting
Cloud Hypervisor supports booting disk images containing all needed components
to run cloud workloads, a.k.a. cloud images.
The following sample commands will download an Ubuntu Cloud image, converting
it into a format that Cloud Hypervisor can use and a firmware to boot the image
with.
```shell
$ export CLOUDH=$HOME/cloud-hypervisor
$ mkdir $CLOUDH
```
## Install prerequisites
You need to install some prerequisite packages in order to build and test Cloud
Hypervisor. Here, all the steps are based on Ubuntu, for other Linux
distributions please replace the package manager and package name.
```shell
# Install build-essential, git, and qemu-utils
$ sudo apt install git build-essential qemu-utils
# Install rust tool chain
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# If you want to build statically linked binary please add musl target
$ rustup target add x86_64-unknown-linux-musl
```
## Clone and build
First you need to clone and build the cloud-hypervisor repo:
```shell
$ pushd $CLOUDH
$ git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
$ cd cloud-hypervisor
$ cargo build --release
# We need to give the cloud-hypervisor binary the NET_ADMIN capabilities for it to set TAP interfaces up on the host.
$ sudo setcap cap_net_admin+ep ./target/release/cloud-hypervisor
# If you want to build statically linked binary
$ cargo build --release --target=x86_64-unknown-linux-musl --all
$ popd
```
This will build a `cloud-hypervisor` binary under
`$CLOUDH/cloud-hypervisor/target/release/cloud-hypervisor`.
### Containerized builds and tests
If you want to build and test Cloud Hypervisor without having to install all the
required dependencies (The rust toolchain, cargo tools, etc), you can also use
Cloud Hypervisor's development script: `dev_cli.sh`. Please note that upon its
first invocation, this script will pull a fairly large container image.
For example, to build the Cloud Hypervisor release binary:
```shell
$ pushd $CLOUDH
$ cd cloud-hypervisor
$ ./scripts/dev_cli.sh build --release
```
With `dev_cli.sh`, one can also run the Cloud Hypervisor CI locally. This can be
very convenient for debugging CI errors without having to fully rely on the
Cloud Hypervisor CI infrastructure.
For example, to run the Cloud Hypervisor unit tests:
```shell
$ ./scripts/dev_cli.sh tests --unit
```
Run the `./scripts/dev_cli.sh --help` command to view all the supported
development script commands and their related options.
## Run
You can run a guest VM by either using an existing cloud image or booting into
your own kernel and disk image.
### Cloud image
Cloud Hypervisor supports booting disk images containing all needed
components to run cloud workloads, a.k.a. cloud images. To do that we rely on
the [Rust Hypervisor
Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware) project
to provide an ELF formatted KVM firmware for `cloud-hypervisor` to directly
boot into.
We need to get the latest `rust-hypervisor-firmware` release and also a working
cloud image. Here we will use a Ubuntu image:
```shell
$ pushd $CLOUDH
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.4.1/hypervisor-fw
$ popd
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.4.2/hypervisor-fw
```
The Ubuntu cloud images do not ship with a default password so it necessary to
use a `cloud-init` disk image to customise the image on the first boot. A basic
`cloud-init` image is generated by this [script](scripts/create-cloud-init.sh).
This seeds the image with a default username/password of `cloud/cloud123`. It
is only necessary to add this disk image on the first boot.
```shell
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh
$ ./cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw \
--disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="
$ popd
```
Multiple arguments can be given to the `--disk` parameter.
If access to the firmware messages or interaction with the boot loader (e.g.
GRUB) is required then it necessary to switch to the serial console instead of
`virtio-console`.
### Custom kernel and disk image
```shell
$ ./cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--serial tty \
--console off
```
#### Building your kernel
### Custom Kernel and Disk Image
Cloud Hypervisor also supports direct kernel boot into a `vmlinux` ELF kernel.
In order to support virtio-watchdog we have our own development branch. You are
of course able to use your own kernel but these instructions will continue with
the version that we develop and test against.
#### Building your Kernel
Cloud Hypervisor also supports direct kernel boot into a `vmlinux` ELF kernel (compiled with PVH support). In order to support development there is a custom branch; however provided the required options are enabled any recent kernel will suffice.
To build the kernel:
```shell
# Clone the Cloud Hypervisor Linux branch
$ pushd $CLOUDH
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-5.15.12 linux-cloud-hypervisor
$ pushd linux-cloud-hypervisor
# Use the cloud-hypervisor kernel config to build your kernel
$ cp $CLOUDH/cloud-hypervisor/resources/linux-config-x86_64 .config
$ wget https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/main/resources/linux-config-x86_64
$ cp linux-config-x86_64 .config
$ KCFLAGS="-Wa,-mx86-used-note=no" make bzImage -j `nproc`
$ popd
```
@@ -213,42 +193,34 @@ The `vmlinux` kernel image will then be located at
#### Disk image
For the disk image, we will use a Ubuntu cloud image that contains a root
partition:
For the disk image the same Ubuntu image as before can be used. This contains
an `ext4` root filesystem.
```shell
$ pushd $CLOUDH
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
$ popd
```
#### Booting the guest VM
Now we can directly boot into our custom kernel and make it use the Ubuntu root
partition. If we want to have 4 vCPUs and 1024 MBytes of memory:
These sample commands boot the disk image using the custom kernel whilst also
supplying the desired kernel command line.
```shell
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh
$ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--disk path=focal-server-cloudimg-amd64.raw \
--disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="
```
The above example use the `virtio-console` device as the guest console, and this
device may not be enabled soon enough by the guest kernel to get early kernel
debug messages.
If earlier kernel messages are required the serial console should be used instead of `virtio-console`.
When in need for earlier debug messages, using the legacy serial device based
console is preferred:
```
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
```./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \
--serial tty \
@@ -261,8 +233,8 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
# 3. Status
Cloud Hypervisor is under active development. The following stability guarantees
are currently made:
Cloud Hypervisor is under active development. The following stability
guarantees are currently made:
* The API (including command line options) will not be removed or changed in a
breaking way without a minimum of 2 major releases notice. Where possible
@@ -280,16 +252,18 @@ Currently the following items are **not** guaranteed across updates:
* The following features are considered experimental and may change
substantially between releases: TDX, vfio-user, vDPA.
As of 2022-04-05, the following cloud images are supported:
Further details can be found in the [release documentation](docs/releases.md).
- [Ubuntu Bionic](https://cloud-images.ubuntu.com/bionic/current/) (cloudimg)
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (cloudimg)
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (cloudimg)
As of 2022-10-13, the following cloud images are supported:
- [Ubuntu Bionic](https://cloud-images.ubuntu.com/bionic/current/) (bionic-server-cloudimg-amd64.img)
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (focal-server-cloudimg-amd64.img)
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (jammy-server-cloudimg-amd64.img )
- [Fedora 36](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/x86_64/images/) (Fedora-Cloud-Base-36-1.5.x86_64.raw.xz)
Direct kernel boot to userspace should work with a rootfs from most
distributions.
Further details can be found in the [release documentation](docs/releases.md).
distributions although you may need to enable exotic filesystem types in the
reference kernel configuration (e.g. XFS or btrfs.)
## Hot Plug
@@ -302,14 +276,12 @@ Cloud Hypervisor supports hotplug of CPUs, passthrough devices (VFIO),
Details of the device model can be found in this
[documentation](docs/device_model.md).
## TODO
## Roadmap
We are not tracking the Cloud Hypervisor TODO list from a specific git tracked
file but through
[github issues](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new)
instead.
The project roadmap is tracked through a [GitHub
project](https://github.com/orgs/cloud-hypervisor/projects/6).
# 4. `rust-vmm` project dependency
# 4. Relationship with _Rust VMM_ Project
In order to satisfy the design goal of having a high-performance,
security-focused hypervisor the decision was made to use the
@@ -318,39 +290,26 @@ focus on memory and thread safety makes it an ideal candidate for implementing
VMMs.
Instead of implementing the VMM components from scratch, Cloud Hypervisor is
importing the [rust-vmm](https://github.com/rust-vmm) crates, and sharing code
importing the [Rust VMM](https://github.com/rust-vmm) crates, and sharing code
and architecture together with other VMMs like e.g. Amazon's
[Firecracker](https://firecracker-microvm.github.io/) and Google's
[crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm/).
Cloud Hypervisor embraces the rust-vmm project goals, which is to be able to
share and re-use as many virtualization crates as possible. As such, the Cloud
Hypervisor relationship with the rust-vmm project is twofold:
Cloud Hypervisor embraces the _Rust VMM_ project's goals, which is to be able
to share and re-use as many virtualization crates as possible.
1. It will use as much of the rust-vmm code as possible. Any new rust-vmm crate
that's relevant to the project goals will be integrated as soon as possible.
2. As it is likely that the rust-vmm project will lack some of the features that
Cloud Hypervisor needs (e.g. ACPI, VFIO, vhost-user, etc), we will be using
the Cloud Hypervisor VMM to implement and test them, and contribute them back
to the rust-vmm project.
## Firecracker and crosvm
## Differences with Firecracker and crosvm
A large part of the Cloud Hypervisor code is based on either the Firecracker or
the crosvm projects implementations. Both of these are VMMs written in Rust with
a focus on safety and security, like Cloud Hypervisor.
the crosvm project's implementations. Both of these are VMMs written in Rust
with a focus on safety and security, like Cloud Hypervisor.
However we want to emphasize that the Cloud Hypervisor project is neither a fork
nor a reimplementation of any of those projects. The goals and use cases we're
trying to meet are different. We're aiming at supporting cloud workloads, i.e.
those modern, full Linux distribution images currently being run by Cloud
Service Provider (CSP) tenants.
The goal of the Cloud Hypervisor project differs from the aforementioned
projects in that it aims to be a general purpose VMM for _Cloud Workloads_ and
not limited to container/serverless or client workloads.
Our primary target is not to support client or serverless use cases, and as such
our code base already diverges from the crosvm and Firecracker ones. As we add
more features to support our use cases, we believe that the divergence will
increase while at the same time sharing as much of the fundamental
virtualization code through the rust-vmm project crates as possible.
The Cloud Hypervisor community thanks the communities of both the Firecracker
and crosvm projects for their excellent work.
# 5. Community
@@ -360,21 +319,28 @@ repository.
## Contribute
We are working on building a global, diverse and collaborative community around
the Cloud Hypervisor project. Anyone who is interested in
The project strongly believes in building a global, diverse and collaborative
community around the Cloud Hypervisor project. Anyone who is interested in
[contributing](CONTRIBUTING.md) to the project is welcome to participate.
We believe that contributing to a open source project like Cloud Hypervisor
covers a lot more than just sending code. Testing, documentation, pull request
Contributing to a open source project like Cloud Hypervisor covers a lot more
than just sending code. Testing, documentation, pull request
reviews, bug reports, feature requests, project improvement suggestions, etc,
are all equal and welcome means of contribution. See the
[CONTRIBUTING](CONTRIBUTING.md) document for more details.
## Join us
## Slack
Get an [invite to our Slack channel](https://join.slack.com/t/cloud-hypervisor/shared_invite/enQtNjY3MTE3MDkwNDQ4LWQ1MTA1ZDVmODkwMWQ1MTRhYzk4ZGNlN2UwNTI3ZmFlODU0OTcwOWZjMTkwZDExYWE3YjFmNzgzY2FmNDAyMjI)
and [join us on Slack](https://cloud-hypervisor.slack.com/).
## Mailing list
Please report bugs using the [GitHub issue
tracker](https://github.com/cloud-hypervisor/cloud-hypervisor/issues) but for
broader community discussions you may use our [mailing
list](https://lists.cloudhypervisor.org/g/dev/).
## Security issues
Please contact the maintainers listed in the MAINTAINERS.md file with security issues.

View File

@@ -5,4 +5,4 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
vm-memory = "0.8.0"
vm-memory = "0.10.0"

View File

@@ -5,4 +5,4 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
vmm-sys-util = "0.10.0"
vmm-sys-util = "0.11.0"

View File

@@ -22,16 +22,16 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Error::*;
match self {
Socket(e) => write!(f, "Error writing to or reading from HTTP socket: {}", e),
SocketSendFds(e) => write!(f, "Error writing to or reading from HTTP socket: {}", e),
StatusCodeParsing(e) => write!(f, "Error parsing HTTP status code: {}", e),
Socket(e) => write!(f, "Error writing to or reading from HTTP socket: {e}"),
SocketSendFds(e) => write!(f, "Error writing to or reading from HTTP socket: {e}"),
StatusCodeParsing(e) => write!(f, "Error parsing HTTP status code: {e}"),
MissingProtocol => write!(f, "HTTP output is missing protocol statement"),
ContentLengthParsing(e) => write!(f, "Error parsing HTTP Content-Length field: {}", e),
ContentLengthParsing(e) => write!(f, "Error parsing HTTP Content-Length field: {e}"),
ServerResponse(s, o) => {
if let Some(o) = o {
write!(f, "Server responded with an error: {:?}: {}", s, o)
write!(f, "Server responded with an error: {s:?}: {o}")
} else {
write!(f, "Server responded with an error: {:?}", s)
write!(f, "Server responded with an error: {s:?}")
}
}
}
@@ -79,7 +79,7 @@ impl StatusCode {
}
fn get_header<'a>(res: &'a str, header: &'a str) -> Option<&'a str> {
let header_str = format!("{}: ", header);
let header_str = format!("{header}: ");
res.find(&header_str)
.map(|o| &res[o + header_str.len()..o + res[o..].find('\r').unwrap()])
}
@@ -141,18 +141,19 @@ fn parse_http_response(socket: &mut dyn Read) -> Result<Option<String>, Error> {
}
}
pub fn simple_api_command_with_fds<T: Read + Write + ScmSocket>(
/// Make an API request using the fully qualified command name.
/// For example, full_command could be "vm.create" or "vmm.ping".
pub fn simple_api_full_command_with_fds_and_response<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,
c: &str,
full_command: &str,
request_body: Option<&str>,
request_fds: Vec<RawFd>,
) -> Result<(), Error> {
) -> Result<Option<String>, Error> {
socket
.send_with_fds(
&[format!(
"{} /api/v1/vm.{} HTTP/1.1\r\nHost: localhost\r\nAccept: */*\r\n",
method, c
"{method} /api/v1/{full_command} HTTP/1.1\r\nHost: localhost\r\nAccept: */*\r\n"
)
.as_bytes()],
&request_fds,
@@ -175,12 +176,69 @@ pub fn simple_api_command_with_fds<T: Read + Write + ScmSocket>(
socket.flush().map_err(Error::Socket)?;
if let Some(body) = parse_http_response(socket)? {
println!("{}", body);
parse_http_response(socket)
}
pub fn simple_api_full_command_with_fds<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,
full_command: &str,
request_body: Option<&str>,
request_fds: Vec<RawFd>,
) -> Result<(), Error> {
let response = simple_api_full_command_with_fds_and_response(
socket,
method,
full_command,
request_body,
request_fds,
)?;
if response.is_some() {
println!("{}", response.unwrap());
}
Ok(())
}
pub fn simple_api_full_command<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,
full_command: &str,
request_body: Option<&str>,
) -> Result<(), Error> {
simple_api_full_command_with_fds(socket, method, full_command, request_body, Vec::new())
}
pub fn simple_api_full_command_and_response<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,
full_command: &str,
request_body: Option<&str>,
) -> Result<Option<String>, Error> {
simple_api_full_command_with_fds_and_response(
socket,
method,
full_command,
request_body,
Vec::new(),
)
}
pub fn simple_api_command_with_fds<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,
c: &str,
request_body: Option<&str>,
request_fds: Vec<RawFd>,
) -> Result<(), Error> {
// Create the full VM command. For VMM commands, use
// simple_api_full_command().
let full_command = format!("vm.{c}");
simple_api_full_command_with_fds(socket, method, &full_command, request_body, request_fds)
}
pub fn simple_api_command<T: Read + Write + ScmSocket>(
socket: &mut T,
method: &str,

View File

@@ -9,20 +9,20 @@ default = []
tdx = []
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.66"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.131"
linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
libc = "0.2.138"
linux-loader = { version = "0.8.1", features = ["elf", "bzimage", "pe"] }
log = "0.4.17"
serde = { version = "1.0.143", features = ["rc", "derive"] }
thiserror = "1.0.32"
uuid = "1.1.2"
versionize = "0.1.6"
serde = { version = "1.0.150", features = ["rc", "derive"] }
thiserror = "1.0.37"
uuid = "1.2.2"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-bitmap"] }
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.10.0", features = ["with-serde"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
[target.'cfg(target_arch = "aarch64")'.dependencies]
fdt_parser = { version = "0.1.4", package = "fdt" }

View File

@@ -51,8 +51,6 @@ const SIZE_CELLS: u32 = 0x2;
// Look for "The 1st cell..."
const GIC_FDT_IRQ_TYPE_SPI: u32 = 0;
const GIC_FDT_IRQ_TYPE_PPI: u32 = 1;
const GIC_FDT_IRQ_PPI_CPU_SHIFT: u32 = 8;
const GIC_FDT_IRQ_PPI_CPU_MASK: u32 = 0xff << GIC_FDT_IRQ_PPI_CPU_SHIFT;
// From https://elixir.bootlin.com/linux/v4.9.62/source/include/dt-bindings/interrupt-controller/irq.h#L17
const IRQ_TYPE_EDGE_RISING: u32 = 1;
@@ -121,7 +119,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
create_gic_node(&mut fdt, gic_device)?;
create_timer_node(&mut fdt)?;
if pmu_supported {
create_pmu_node(&mut fdt, vcpu_mpidr.len())?;
create_pmu_node(&mut fdt)?;
}
create_clock_node(&mut fdt)?;
create_psci_node(&mut fdt)?;
@@ -162,7 +160,7 @@ fn create_cpu_nodes(
let num_cpus = vcpu_mpidr.len();
for (cpu_id, mpidr) in vcpu_mpidr.iter().enumerate().take(num_cpus) {
let cpu_name = format!("cpu@{:x}", cpu_id);
let cpu_name = format!("cpu@{cpu_id:x}");
let cpu_node = fdt.begin_node(&cpu_name)?;
fdt.property_string("device_type", "cpu")?;
fdt.property_string("compatible", "arm,arm-v8")?;
@@ -194,15 +192,15 @@ fn create_cpu_nodes(
// Create device tree nodes with regard of above mapping.
for cluster_idx in 0..packages {
let cluster_name = format!("cluster{:x}", cluster_idx);
let cluster_name = format!("cluster{cluster_idx:x}");
let cluster_node = fdt.begin_node(&cluster_name)?;
for core_idx in 0..cores_per_package {
let core_name = format!("core{:x}", core_idx);
let core_name = format!("core{core_idx:x}");
let core_node = fdt.begin_node(&core_name)?;
for thread_idx in 0..threads_per_core {
let thread_name = format!("thread{:x}", thread_idx);
let thread_name = format!("thread{thread_idx:x}");
let thread_node = fdt.begin_node(&thread_name)?;
let cpu_idx = threads_per_core * cores_per_package * cluster_idx
+ threads_per_core * core_idx
@@ -249,7 +247,7 @@ fn create_memory_node(
node_memory_addr = memory_region_start_addr;
}
}
let memory_node_name = format!("memory@{:x}", node_memory_addr);
let memory_node_name = format!("memory@{node_memory_addr:x}");
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
@@ -541,16 +539,9 @@ fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Buil
Ok(())
}
fn create_pmu_node(fdt: &mut FdtWriter, cpu_nums: usize) -> FdtWriterResult<()> {
let num_cpus = cpu_nums as u64 as u32;
fn create_pmu_node(fdt: &mut FdtWriter) -> FdtWriterResult<()> {
let compatible = "arm,armv8-pmuv3";
let cpu_mask: u32 =
(((1 << num_cpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) & GIC_FDT_IRQ_PPI_CPU_MASK;
let irq = [
GIC_FDT_IRQ_TYPE_PPI,
AARCH64_PMU_IRQ,
cpu_mask | IRQ_TYPE_LEVEL_HI,
];
let irq = [GIC_FDT_IRQ_TYPE_PPI, AARCH64_PMU_IRQ, IRQ_TYPE_LEVEL_HI];
let pmu_node = fdt.begin_node("pmu")?;
fdt.property_string("compatible", compatible)?;
@@ -679,7 +670,7 @@ fn create_pci_nodes(
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
// for virtio-iommu node settings.
let virtio_iommu_node_name = format!("virtio_iommu@{:x}", virtio_iommu_bdf);
let virtio_iommu_node_name = format!("virtio_iommu@{virtio_iommu_bdf:x}");
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
fdt.property_u32("#iommu-cells", 1)?;
fdt.property_string("compatible", "virtio,pci-iommu")?;

View File

@@ -59,7 +59,7 @@ pub const UEFI_START: GuestAddress = GuestAddress(0);
pub const UEFI_SIZE: u64 = 0x040_0000;
/// Below this address will reside the GIC, above this address will reside the MMIO devices.
pub const MAPPED_IO_START: GuestAddress = GuestAddress(0x0900_0000);
const MAPPED_IO_START: GuestAddress = GuestAddress(0x0900_0000);
/// See kernel file arch/arm64/include/uapi/asm/kvm.h for the GIC related definitions.
/// 0x08ff_0000 ~ 0x0900_0000 is reserved for GICv3 Distributor
@@ -73,7 +73,7 @@ pub const GIC_V3_REDIST_SIZE: u64 = 0x02_0000;
pub const GIC_V3_ITS_SIZE: u64 = 0x02_0000;
/// Space 0x0900_0000 ~ 0x0905_0000 is reserved for legacy devices.
pub const LEGACY_SERIAL_MAPPED_IO_START: GuestAddress = GuestAddress(0x0900_0000);
pub const LEGACY_SERIAL_MAPPED_IO_START: GuestAddress = MAPPED_IO_START;
pub const LEGACY_RTC_MAPPED_IO_START: GuestAddress = GuestAddress(0x0901_0000);
pub const LEGACY_GPIO_MAPPED_IO_START: GuestAddress = GuestAddress(0x0902_0000);
@@ -98,6 +98,11 @@ pub const RAM_START: GuestAddress = GuestAddress(0x4000_0000);
pub const MEM_32BIT_RESERVED_START: GuestAddress = GuestAddress(0xfc00_0000);
pub const MEM_32BIT_RESERVED_SIZE: u64 = 0x0400_0000;
/// TPM Address Range
/// This Address range is specific to CRB Interface
pub const TPM_START: GuestAddress = GuestAddress(0xfed4_0000);
pub const TPM_SIZE: u64 = 0x1000;
/// Start of 64-bit RAM.
pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);

View File

@@ -39,3 +39,6 @@ macro_rules! arm64_sys_reg {
}
arm64_sys_reg!(MPIDR_EL1, 3, 0, 0, 0, 5);
arm64_sys_reg!(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0);
arm64_sys_reg!(TTBR1_EL1, 3, 0, 2, 0, 1);
arm64_sys_reg!(TCR_EL1, 3, 0, 2, 0, 2);

View File

@@ -34,9 +34,7 @@ where
if uefi_size > 0x300000 {
return Err(Error::UefiTooBig);
}
uefi_image
.seek(SeekFrom::Start(0))
.map_err(|_| Error::SeekUefiStart)?;
uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
guest_mem
.read_exact_from(guest_addr, uefi_image, uefi_size)
.map_err(|_| Error::ReadUefiImage)

View File

@@ -145,7 +145,7 @@ pub const PAGE_SIZE: usize = 4096;
impl fmt::Display for DeviceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
write!(f, "{self:?}")
}
}

View File

@@ -107,6 +107,11 @@ pub const KVM_TSS_SIZE: u64 = (3 * 4) << 10;
pub const KVM_IDENTITY_MAP_START: GuestAddress = GuestAddress(KVM_TSS_START.0 + KVM_TSS_SIZE);
pub const KVM_IDENTITY_MAP_SIZE: u64 = 4 << 10;
/// TPM Address Range
/// This Address range is specific to CRB Interface
pub const TPM_START: GuestAddress = GuestAddress(0xfed4_0000);
pub const TPM_SIZE: u64 = 0x1000;
// IOAPIC
pub const IOAPIC_START: GuestAddress = GuestAddress(0xfec0_0000);
pub const IOAPIC_SIZE: u64 = 0x20;

View File

@@ -231,7 +231,7 @@ impl CpuidPatch {
) {
let mut entry_found = false;
for entry in cpuid.iter_mut() {
if entry.function == function && (index == None || index.unwrap() == entry.index) {
if entry.function == function && (index.is_none() || index.unwrap() == entry.index) {
entry_found = true;
match reg {
CpuidReg::EAX => {
@@ -631,6 +631,20 @@ pub fn generate_common_cpuid(
}
}
}
// Copy host L2 cache details if not populated by KVM
0x8000_0006 => {
if entry.eax == 0 && entry.ebx == 0 && entry.ecx == 0 && entry.edx == 0 {
// SAFETY: cpuid called with valid leaves
if unsafe { std::arch::x86_64::__cpuid(0x8000_0000).eax } >= 0x8000_0006 {
// SAFETY: cpuid called with valid leaves
let leaf = unsafe { std::arch::x86_64::__cpuid(0x8000_0006) };
entry.eax = leaf.eax;
entry.ebx = leaf.ebx;
entry.ecx = leaf.ecx;
entry.edx = leaf.edx;
}
}
}
// Set CPU physical bits
0x8000_0008 => {
entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff);
@@ -764,11 +778,11 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
.checked_add(layout::MEM_32BIT_DEVICES_SIZE)
.expect("32-bit reserved region is too large");
let requested_memory_size = GuestAddress(size as u64);
let requested_memory_size = GuestAddress(size);
let mut regions = Vec::new();
// case1: guest memory fits before the gap
if size as u64 <= layout::MEM_32BIT_RESERVED_START.raw_value() {
if size <= layout::MEM_32BIT_RESERVED_START.raw_value() {
regions.push((GuestAddress(0), size as usize, RegionType::Ram));
// case2: guest memory extends beyond the gap
} else {
@@ -865,7 +879,7 @@ fn configure_pvh(
start_info.0.magic = XEN_HVM_START_MAGIC_VALUE;
start_info.0.version = 1; // pvh has version 1
start_info.0.nr_modules = 0;
start_info.0.cmdline_paddr = cmdline_addr.raw_value() as u64;
start_info.0.cmdline_paddr = cmdline_addr.raw_value();
start_info.0.memmap_paddr = layout::MEMMAP_START.raw_value();
if let Some(rsdp_addr) = rsdp_addr {
@@ -934,7 +948,7 @@ fn configure_pvh(
add_memmap_entry(
&mut memmap,
sgx_epc_region.start().raw_value(),
sgx_epc_region.size() as u64,
sgx_epc_region.size(),
E820_RESERVED,
);
}
@@ -1126,7 +1140,7 @@ fn update_cpuid_sgx(
for (i, epc_section) in epc_sections.iter().enumerate() {
let subleaf_idx = i + 2;
let start = epc_section.start().raw_value();
let size = epc_section.size() as u64;
let size = epc_section.size();
let eax = (start & 0xffff_f000) as u32 | 0x1;
let ebx = (start >> 32) as u32;
let ecx = (size & 0xffff_f000) as u32 | (leaf.ecx & 0xf);
@@ -1302,6 +1316,6 @@ mod tests {
add_memmap_entry(&mut memmap, 0, 0x1000, E820_RAM);
add_memmap_entry(&mut memmap, 0x10000, 0xa000, E820_RESERVED);
assert_eq!(format!("{:?}", memmap), format!("{:?}", expected_memmap));
assert_eq!(format!("{memmap:?}"), format!("{expected_memmap:?}"));
}
}

View File

@@ -294,7 +294,7 @@ mod tests {
mpspec::MP_IOAPIC => mem::size_of::<MpcIoapicWrapper>(),
mpspec::MP_INTSRC => mem::size_of::<MpcIntsrcWrapper>(),
mpspec::MP_LINTSRC => mem::size_of::<MpcLintsrcWrapper>(),
_ => panic!("unrecognized mpc table entry type: {}", type_),
_ => panic!("unrecognized mpc table entry type: {type_}"),
}
}

View File

@@ -124,7 +124,7 @@ pub fn configure_segments_and_sregs(
mem: &GuestMemoryMmap,
sregs: &mut SpecialRegisters,
) -> Result<()> {
let gdt_table: [u64; BOOT_GDT_MAX as usize] = {
let gdt_table: [u64; BOOT_GDT_MAX] = {
// Configure GDT entries as specified by PVH boot protocol
[
gdt_entry(0, 0, 0), // NULL

View File

@@ -48,10 +48,10 @@ impl Display for Error {
Clear => "Failure while zeroing out the memory for the SMBIOS table".to_string(),
WriteSmbiosEp => "Failure to write SMBIOS entrypoint structure".to_string(),
WriteData => "Failure to write additional data to memory".to_string(),
ParseUuid(e) => format!("Failure to parse uuid: {}", e),
ParseUuid(e) => format!("Failure to parse uuid: {e}"),
};
write!(f, "SMBIOS error: {}", description)
write!(f, "SMBIOS error: {description}")
}
}

View File

@@ -447,7 +447,7 @@ mod tests {
let mut f = std::fs::File::open("tdvf.fd").unwrap();
let sections = parse_tdvf_sections(&mut f).unwrap();
for section in sections {
eprintln!("{:x?}", section)
eprintln!("{section:x?}")
}
}
}

View File

@@ -8,17 +8,17 @@ edition = "2021"
default = []
[dependencies]
io-uring = "0.5.3"
libc = "0.2.131"
io-uring = "0.5.9"
libc = "0.2.138"
log = "0.4.17"
qcow = { path = "../qcow" }
thiserror = "1.0.32"
versionize = "0.1.6"
thiserror = "1.0.37"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vhdx = { path = "../vhdx" }
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.5.0"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.7.0"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.10.0"
vmm-sys-util = "0.11.0"

View File

@@ -51,23 +51,23 @@ pub const SECTOR_SIZE: u64 = 0x01 << SECTOR_SHIFT;
#[derive(Error, Debug)]
pub enum Error {
#[error("Guest gave us bad memory addresses.")]
#[error("Guest gave us bad memory addresses")]
GuestMemory(GuestMemoryError),
#[error("Guest gave us offsets that would have overflowed a usize.")]
#[error("Guest gave us offsets that would have overflowed a usize")]
CheckedOffset(GuestAddress, usize),
#[error("Guest gave us a write only descriptor that protocol says to read from.")]
#[error("Guest gave us a write only descriptor that protocol says to read from")]
UnexpectedWriteOnlyDescriptor,
#[error("Guest gave us a read only descriptor that protocol says to write to.")]
#[error("Guest gave us a read only descriptor that protocol says to write to")]
UnexpectedReadOnlyDescriptor,
#[error("Guest gave us too few descriptors in a descriptor chain.")]
#[error("Guest gave us too few descriptors in a descriptor chain")]
DescriptorChainTooShort,
#[error("Guest gave us a descriptor that was too short to use.")]
#[error("Guest gave us a descriptor that was too short to use")]
DescriptorLengthTooSmall,
#[error("Getting a block's metadata fails for any reason.")]
#[error("Getting a block's metadata fails for any reason")]
GetFileMetadata,
#[error("The requested operation would cause a seek beyond disk end.")]
#[error("The requested operation would cause a seek beyond disk end")]
InvalidOffset,
#[error("The requested operation does not support multiple descriptors.")]
#[error("The requested operation does not support multiple descriptors")]
TooManyDescriptors,
}
@@ -566,15 +566,15 @@ pub fn block_io_uring_is_supported() -> bool {
return false;
}
// Check IORING_OP_READ is supported
if !probe.is_supported(opcode::Read::CODE) {
info!("{} IORING_OP_READ operation not supported", error_msg);
// Check IORING_OP_READV is supported
if !probe.is_supported(opcode::Readv::CODE) {
info!("{} IORING_OP_READV operation not supported", error_msg);
return false;
}
// Check IORING_OP_WRITE is supported
if !probe.is_supported(opcode::Write::CODE) {
info!("{} IORING_OP_WRITE operation not supported", error_msg);
// Check IORING_OP_WRITEV is supported
if !probe.is_supported(opcode::Writev::CODE) {
info!("{} IORING_OP_WRITEV operation not supported", error_msg);
return false;
}

View File

@@ -26,7 +26,7 @@ impl DiskFile for QcowDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
let mut file = self.qcow_file.lock().unwrap();
Ok(file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)? as u64)
file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {

View File

@@ -23,10 +23,9 @@ impl RawFileDisk {
impl DiskFile for RawFileDisk {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self
.file
self.file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)? as u64)
.map_err(DiskFileError::Size)
}
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {

View File

@@ -22,10 +22,9 @@ impl RawFileDiskSync {
impl DiskFile for RawFileDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self
.file
self.file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)? as u64)
.map_err(DiskFileError::Size)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
@@ -118,7 +117,7 @@ impl AsyncIo for RawFileSync {
}
if let Some(user_data) = user_data {
self.completion_list.push((user_data, result as i32));
self.completion_list.push((user_data, result));
self.eventfd.write(1).unwrap();
}

View File

@@ -11,7 +11,7 @@ use std::process::Command;
fn main() {
let mut version = "v".to_owned() + crate_version!();
if let Ok(git_out) = Command::new("git").args(&["describe", "--dirty"]).output() {
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
version = git_out_str;
@@ -23,5 +23,5 @@ fn main() {
// variable BUILT_VERSION, so that it can be reused from the binary.
// Particularly, this is used from src/main.rs to display the exact
// version.
println!("cargo:rustc-env=BUILT_VERSION={}", version);
println!("cargo:rustc-env=BUILT_VERSION={version}");
}

View File

@@ -6,24 +6,25 @@ edition = "2021"
[dependencies]
acpi_tables = { path = "../acpi_tables" }
anyhow = "1.0.62"
anyhow = "1.0.66"
arch = { path = "../arch" }
bitflags = "1.3.2"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.131"
libc = "0.2.138"
log = "0.4.17"
versionize = "0.1.6"
phf = { version = "0.11.1", features = ["macros"] }
thiserror = "1.0.37"
tpm = { path = "../tpm" }
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-device = { path = "../vm-device" }
vm-memory = "0.8.0"
vm-memory = "0.10.0"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = "0.10.0"
vmm-sys-util = "0.11.0"
[target.'cfg(target_arch = "aarch64")'.dependencies]
arch = { path = "../arch" }
[features]
default = []
cmos = []
fwdebug = []

View File

@@ -105,18 +105,17 @@ impl BusDevice for AcpiGedDevice {
impl Aml for AcpiGedDevice {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
aml::Device::new(
"_SB_.GED_".into(),
"_SB_.GEC_".into(),
vec![
&aml::Name::new("_HID".into(), &"ACPI0013"),
&aml::Name::new("_UID".into(), &aml::ZERO),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_UID".into(), &"Generic Event Controller"),
&aml::Name::new(
"_CRS".into(),
&aml::ResourceTemplate::new(vec![&aml::Interrupt::new(
&aml::ResourceTemplate::new(vec![&aml::AddressSpace::new_memory(
aml::AddressSpaceCachable::NotCacheable,
true,
true,
false,
false,
self.ged_irq,
self.address.0,
self.address.0 + GED_DEVICE_ACPI_SIZE as u64 - 1,
)]),
),
&aml::OpRegion::new(
@@ -132,8 +131,8 @@ impl Aml for AcpiGedDevice {
vec![aml::FieldEntry::Named(*b"GDAT", 8)],
),
&aml::Method::new(
"_EVT".into(),
1,
"ESCN".into(),
0,
true,
vec![
&aml::Store::new(&aml::Local(0), &aml::Path::new("GDAT")),
@@ -164,6 +163,30 @@ impl Aml for AcpiGedDevice {
),
],
)
.append_aml_bytes(bytes);
aml::Device::new(
"_SB_.GED_".into(),
vec![
&aml::Name::new("_HID".into(), &"ACPI0013"),
&aml::Name::new("_UID".into(), &aml::ZERO),
&aml::Name::new(
"_CRS".into(),
&aml::ResourceTemplate::new(vec![&aml::Interrupt::new(
true,
true,
false,
false,
self.ged_irq,
)]),
),
&aml::Method::new(
"_EVT".into(),
1,
true,
vec![&aml::MethodCall::new("\\_SB_.GEC_.ESCN".into(), vec![])],
),
],
)
.append_aml_bytes(bytes)
}
}

View File

@@ -6,14 +6,17 @@ use super::interrupt_controller::{Error, InterruptController};
extern crate arch;
use anyhow::anyhow;
use arch::layout;
use hypervisor::{arch::aarch64::gic::Vgic, CpuState};
use hypervisor::{
arch::aarch64::gic::{Vgic, VgicConfig},
CpuState,
};
use std::result;
use std::sync::{Arc, Mutex};
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup,
LegacyIrqSourceConfig, MsiIrqGroupConfig,
};
use vm_memory::Address;
use vm_memory::address::Address;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
@@ -52,21 +55,28 @@ impl Gic {
})
}
/// Default config implied by arch::layout
pub fn create_default_config(vcpu_count: u64) -> VgicConfig {
let redists_size = layout::GIC_V3_REDIST_SIZE * vcpu_count;
let redists_addr = layout::GIC_V3_DIST_START.raw_value() - redists_size;
VgicConfig {
vcpu_count,
dist_addr: layout::GIC_V3_DIST_START.raw_value(),
dist_size: layout::GIC_V3_DIST_SIZE,
redists_addr,
redists_size,
msi_addr: redists_addr - layout::GIC_V3_ITS_SIZE,
msi_size: layout::GIC_V3_ITS_SIZE,
nr_irqs: layout::IRQ_NUM,
}
}
pub fn create_vgic(
&mut self,
vm: &Arc<dyn hypervisor::Vm>,
vcpu_count: u64,
config: VgicConfig,
) -> Result<Arc<Mutex<dyn Vgic>>> {
let vgic = vm
.create_vgic(
vcpu_count,
layout::GIC_V3_DIST_START.raw_value(),
layout::GIC_V3_DIST_SIZE,
layout::GIC_V3_REDIST_SIZE,
layout::GIC_V3_ITS_SIZE,
layout::IRQ_NUM,
)
.map_err(Error::CreateGic)?;
let vgic = vm.create_vgic(config).map_err(Error::CreateGic)?;
self.vgic = Some(vgic.clone());
Ok(vgic.clone())
}

View File

@@ -40,11 +40,11 @@ impl DebugIoPortRange {
impl fmt::Display for DebugIoPortRange {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DebugIoPortRange::Firmware => write!(f, "{}: Firmware", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Bootloader => write!(f, "{}: Bootloader", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Kernel => write!(f, "{}: Kernel", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Userspace => write!(f, "{}: Userspace", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Custom => write!(f, "{}: Custom", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Firmware => write!(f, "{DEBUG_IOPORT_PREFIX}: Firmware"),
DebugIoPortRange::Bootloader => write!(f, "{DEBUG_IOPORT_PREFIX}: Bootloader"),
DebugIoPortRange::Kernel => write!(f, "{DEBUG_IOPORT_PREFIX}: Kernel"),
DebugIoPortRange::Userspace => write!(f, "{DEBUG_IOPORT_PREFIX}: Userspace"),
DebugIoPortRange::Custom => write!(f, "{DEBUG_IOPORT_PREFIX}: Custom"),
}
}
}

View File

@@ -51,13 +51,13 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {offset}"),
Error::GpioInterruptDisabled => write!(f, "GPIO interrupt disabled by guest driver.",),
Error::GpioInterruptFailure(ref e) => {
write!(f, "Could not trigger GPIO interrupt: {}.", e)
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 triggerd: {key}.")
}
}
}

View File

@@ -8,7 +8,7 @@
mod cmos;
#[cfg(target_arch = "x86_64")]
mod debug_port;
#[cfg(feature = "fwdebug")]
#[cfg(target_arch = "x86_64")]
mod fwdebug;
#[cfg(target_arch = "aarch64")]
mod gpio_pl061;
@@ -22,7 +22,7 @@ mod uart_pl011;
pub use self::cmos::Cmos;
#[cfg(target_arch = "x86_64")]
pub use self::debug_port::DebugPort;
#[cfg(feature = "fwdebug")]
#[cfg(target_arch = "x86_64")]
pub use self::fwdebug::FwDebugDevice;
pub use self::i8042::I8042Device;
pub use self::serial::Serial;

View File

@@ -48,8 +48,8 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {offset}"),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {e}"),
}
}
}

View File

@@ -199,7 +199,7 @@ impl Serial {
}
fn handle_write(&mut self, offset: u8, v: u8) -> Result<()> {
match offset as u8 {
match offset {
DLAB_LOW if self.is_dlab_set() => {
self.baud_divisor = (self.baud_divisor & 0xff00) | u16::from(v)
}

View File

@@ -60,11 +60,11 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {}", offset),
Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {offset}"),
Error::DmaNotImplemented => write!(f, "pl011: DMA not implemented."),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
Error::WriteAllFailure(e) => write!(f, "Failed to write: {}", e),
Error::FlushFailure(e) => write!(f, "Failed to flush: {}", e),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {e}"),
Error::WriteAllFailure(e) => write!(f, "Failed to write: {e}"),
Error::FlushFailure(e) => write!(f, "Failed to flush: {e}"),
}
}
}
@@ -306,25 +306,25 @@ impl Pl011 {
let elapsed = self.timestamp.elapsed();
match self.debug {
0x00..=0x1f => info!(
0x00..=0x1f => warn!(
"[Debug I/O port: Firmware code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x20..=0x3f => info!(
0x20..=0x3f => warn!(
"[Debug I/O port: Bootloader code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x40..=0x5f => info!(
0x40..=0x5f => warn!(
"[Debug I/O port: Kernel code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x60..=0x7f => info!(
0x60..=0x7f => warn!(
"[Debug I/O port: Userspace code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),

View File

@@ -19,6 +19,7 @@ pub mod interrupt_controller;
#[cfg(target_arch = "x86_64")]
pub mod ioapic;
pub mod legacy;
pub mod tpm;
pub use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice};

467
devices/src/tpm.rs Normal file
View File

@@ -0,0 +1,467 @@
// Copyright © 2022, Microsoft Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use anyhow::anyhow;
#[cfg(target_arch = "aarch64")]
use arch::aarch64::layout::{TPM_SIZE, TPM_START};
#[cfg(target_arch = "x86_64")]
use arch::x86_64::layout::{TPM_SIZE, TPM_START};
use phf::phf_map;
use std::cmp;
use std::sync::{Arc, Barrier};
use thiserror::Error;
use tpm::emulator::{BackendCmd, Emulator};
use tpm::TPM_CRB_BUFFER_MAX;
use tpm::TPM_SUCCESS;
use vm_device::BusDevice;
#[derive(Error, Debug)]
pub enum Error {
#[error("Emulator doesn't implement min required capabilities: {0}")]
CheckCaps(#[source] anyhow::Error),
#[error("Failed to initialize tpm: {0}")]
Init(#[source] anyhow::Error),
#[error("Failed to deliver tpm Command: {0}")]
DeliverRequest(#[source] anyhow::Error),
}
type Result<T> = anyhow::Result<T, Error>;
/* crb 32-bit registers */
const CRB_LOC_STATE: u32 = 0x0;
//Register Fields
// Field => (start, length)
// start: lowest bit in the bit field numbered from 0
// length: length of the bit field
const CRB_LOC_STATE_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
"tpmEstablished" => [0, 1],
"locAssigned" => [1,1],
"activeLocality"=> [2, 3],
"reserved" => [5, 2],
"tpmRegValidSts" => [7, 1]
};
const CRB_LOC_CTRL: u32 = 0x08;
const CRB_LOC_CTRL_REQUEST_ACCESS: u32 = 1 << 0;
const CRB_LOC_CTRL_RELINQUISH: u32 = 1 << 1;
const CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT: u32 = 1 << 3;
const CRB_LOC_STS: u32 = 0x0C;
const CRB_LOC_STS_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
"Granted" => [0, 1],
"beenSeized" => [1,1]
};
const CRB_INTF_ID: u32 = 0x30;
const CRB_INTF_ID_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
"InterfaceType" => [0, 4],
"InterfaceVersion" => [4, 4],
"CapLocality" => [8, 1],
"CapCRBIdleBypass" => [9, 1],
"Reserved1" => [10, 1],
"CapDataXferSizeSupport" => [11, 2],
"CapFIFO" => [13, 1],
"CapCRB" => [14, 1],
"CapIFRes" => [15, 2],
"InterfaceSelector" => [17, 2],
"IntfSelLock" => [19, 1],
"Reserved2" => [20, 4],
"RID" => [24, 8]
};
const CRB_INTF_ID2: u32 = 0x34;
const CRB_INTF_ID2_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
"VID" => [0, 16],
"DID" => [16, 16]
};
const CRB_CTRL_REQ: u32 = 0x40;
const CRB_CTRL_REQ_CMD_READY: u32 = 1 << 0;
const CRB_CTRL_REQ_GO_IDLE: u32 = 1 << 1;
const CRB_CTRL_STS: u32 = 0x44;
const CRB_CTRL_STS_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
"tpmSts" => [0, 1],
"tpmIdle" => [1, 1]
};
const CRB_CTRL_CANCEL: u32 = 0x48;
const CRB_CANCEL_INVOKE: u32 = 1 << 0;
const CRB_CTRL_START: u32 = 0x4C;
const CRB_START_INVOKE: u32 = 1 << 0;
const CRB_CTRL_CMD_LADDR: u32 = 0x5C;
const CRB_CTRL_CMD_HADDR: u32 = 0x60;
const CRB_CTRL_RSP_SIZE: u32 = 0x64;
const CRB_CTRL_RSP_ADDR: u32 = 0x68;
const CRB_DATA_BUFFER: u32 = 0x80;
const TPM_CRB_NO_LOCALITY: u32 = 0xff;
const TPM_CRB_ADDR_BASE: u32 = TPM_START.0 as u32;
const TPM_CRB_ADDR_SIZE: usize = TPM_SIZE as usize;
const TPM_CRB_R_MAX: u32 = CRB_DATA_BUFFER;
// CRB Protocol details
const CRB_INTF_TYPE_CRB_ACTIVE: u32 = 0b1;
const CRB_INTF_VERSION_CRB: u32 = 0b1;
const CRB_INTF_CAP_LOCALITY_0_ONLY: u32 = 0b0;
const CRB_INTF_CAP_IDLE_FAST: u32 = 0b0;
const CRB_INTF_CAP_XFER_SIZE_64: u32 = 0b11;
const CRB_INTF_CAP_FIFO_NOT_SUPPORTED: u32 = 0b0;
const CRB_INTF_CAP_CRB_SUPPORTED: u32 = 0b1;
const CRB_INTF_IF_SELECTOR_CRB: u32 = 0b1;
const PCI_VENDOR_ID_IBM: u32 = 0x1014;
const CRB_CTRL_CMD_SIZE_REG: u32 = 0x58;
const CRB_CTRL_CMD_SIZE: usize = TPM_CRB_ADDR_SIZE - CRB_DATA_BUFFER as usize;
fn get_fields_map(reg: u32) -> phf::Map<&'static str, [u32; 2]> {
match reg {
CRB_LOC_STATE => CRB_LOC_STATE_FIELDS,
CRB_LOC_STS => CRB_LOC_STS_FIELDS,
CRB_INTF_ID => CRB_INTF_ID_FIELDS,
CRB_INTF_ID2 => CRB_INTF_ID2_FIELDS,
CRB_CTRL_STS => CRB_CTRL_STS_FIELDS,
_ => {
panic!("Fields in '{reg:?}' register were accessed which are Invalid");
}
}
}
/// Set a particular field in a Register
fn set_reg_field(regs: &mut [u32; TPM_CRB_R_MAX as usize], reg: u32, field: &str, value: u32) {
let reg_fields = get_fields_map(reg);
if reg_fields.contains_key(field) {
let start = reg_fields.get(field).unwrap()[0];
let len = reg_fields.get(field).unwrap()[1];
let mask = (!(0_u32) >> (32 - len)) << start;
regs[reg as usize] = (regs[reg as usize] & !mask) | ((value << start) & mask);
} else {
error!(
"Failed to tpm Register. {:?} is not a valid field in Reg {:#X}",
field, reg
)
}
}
/// Get the value of a particular field in a Register
fn get_reg_field(regs: &[u32; TPM_CRB_R_MAX as usize], reg: u32, field: &str) -> u32 {
let reg_fields = get_fields_map(reg);
if reg_fields.contains_key(field) {
let start = reg_fields.get(field).unwrap()[0];
let len = reg_fields.get(field).unwrap()[1];
let mask = (!(0_u32) >> (32 - len)) << start;
(regs[reg as usize] & mask) >> start
} else {
// TODO: Sensible return value if fields do not exist
0x0
}
}
fn locality_from_addr(addr: u32) -> u8 {
(addr >> 12) as u8
}
pub struct Tpm {
emulator: Emulator,
cmd: Option<BackendCmd>,
regs: [u32; TPM_CRB_R_MAX as usize],
backend_buff_size: usize,
data_buff: [u8; TPM_CRB_BUFFER_MAX],
data_buff_len: usize,
}
impl Tpm {
pub fn new(path: String) -> Result<Self> {
let emulator = Emulator::new(path)
.map_err(|e| Error::Init(anyhow!("Failed while initializing tpm Emulator: {:?}", e)))?;
let mut tpm = Tpm {
emulator,
cmd: None,
regs: [0; TPM_CRB_R_MAX as usize],
backend_buff_size: TPM_CRB_BUFFER_MAX,
data_buff: [0; TPM_CRB_BUFFER_MAX],
data_buff_len: 0,
};
tpm.reset()?;
Ok(tpm)
}
fn get_active_locality(&mut self) -> u32 {
if get_reg_field(&self.regs, CRB_LOC_STATE, "locAssigned") == 0 {
return TPM_CRB_NO_LOCALITY;
}
get_reg_field(&self.regs, CRB_LOC_STATE, "activeLocality")
}
fn request_completed(&mut self, result: isize) {
self.regs[CRB_CTRL_START as usize] = !CRB_START_INVOKE;
if result != 0 {
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmSts", 1);
}
}
fn reset(&mut self) -> Result<()> {
let cur_buff_size = self.emulator.get_buffer_size().unwrap();
self.regs = [0; TPM_CRB_R_MAX as usize];
set_reg_field(&mut self.regs, CRB_LOC_STATE, "tpmRegValidSts", 1);
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 1);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"InterfaceType",
CRB_INTF_TYPE_CRB_ACTIVE,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"InterfaceVersion",
CRB_INTF_VERSION_CRB,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"CapLocality",
CRB_INTF_CAP_LOCALITY_0_ONLY,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"CapCRBIdleBypass",
CRB_INTF_CAP_IDLE_FAST,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"CapDataXferSizeSupport",
CRB_INTF_CAP_XFER_SIZE_64,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"CapFIFO",
CRB_INTF_CAP_FIFO_NOT_SUPPORTED,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"CapCRB",
CRB_INTF_CAP_CRB_SUPPORTED,
);
set_reg_field(
&mut self.regs,
CRB_INTF_ID,
"InterfaceSelector",
CRB_INTF_IF_SELECTOR_CRB,
);
set_reg_field(&mut self.regs, CRB_INTF_ID, "RID", 0b0000);
set_reg_field(&mut self.regs, CRB_INTF_ID2, "VID", PCI_VENDOR_ID_IBM);
self.regs[CRB_CTRL_CMD_SIZE_REG as usize] = CRB_CTRL_CMD_SIZE as u32;
self.regs[CRB_CTRL_CMD_LADDR as usize] = TPM_CRB_ADDR_BASE + CRB_DATA_BUFFER;
self.regs[CRB_CTRL_RSP_SIZE as usize] = CRB_CTRL_CMD_SIZE as u32;
self.regs[CRB_CTRL_RSP_ADDR as usize] = TPM_CRB_ADDR_BASE + CRB_DATA_BUFFER;
self.backend_buff_size = cmp::min(cur_buff_size, TPM_CRB_BUFFER_MAX);
if let Err(e) = self.emulator.startup_tpm(self.backend_buff_size) {
return Err(Error::Init(anyhow!(
"Failed while running Startup TPM. Error: {:?}",
e
)));
}
Ok(())
}
}
//impl BusDevice for TPM
impl BusDevice for Tpm {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let mut offset: u32 = offset as u32;
let read_len: usize = data.len();
if offset >= CRB_DATA_BUFFER
&& (offset + read_len as u32) < (CRB_DATA_BUFFER + self.data_buff.len() as u32)
{
// Read from Data Buffer
let start: usize = (offset as usize) - (CRB_DATA_BUFFER as usize);
let end: usize = start + read_len;
data[..].clone_from_slice(&self.data_buff[start..end]);
} else {
offset &= 0xff;
let mut val = self.regs[offset as usize];
if offset == CRB_LOC_STATE && !self.emulator.get_established_flag() {
val |= 0x1;
}
if data.len() <= 4 {
data.clone_from_slice(val.to_ne_bytes()[0..read_len].as_ref());
} else {
error!(
"Invalid tpm read: offset {:#X}, data length {:?}",
offset,
data.len()
);
}
}
debug!(
"MMIO Read: offset {:#X} len {:?} val = {:02X?} ",
offset,
data.len(),
data
);
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
debug!(
"MMIO Write: offset {:#X} len {:?} input data {:02X?}",
offset,
data.len(),
data
);
let mut offset: u32 = offset as u32;
if offset < CRB_DATA_BUFFER {
offset &= 0xff;
}
let locality = locality_from_addr(offset) as u32;
let write_len = data.len();
if offset >= CRB_DATA_BUFFER
&& (offset + write_len as u32) < (CRB_DATA_BUFFER + self.data_buff.len() as u32)
{
let start: usize = (offset as usize) - (CRB_DATA_BUFFER as usize);
if start == 0 {
// If filling data_buff at index 0, reset length to 0
self.data_buff_len = 0;
self.data_buff.fill(0);
}
let end: usize = start + data.len();
self.data_buff[start..end].clone_from_slice(data);
self.data_buff_len += data.len();
} else {
// Ctrl Commands that take more than 4 bytes as input are not yet supported
// CTRL_RSP_ADDR usually gets 8 byte write request. Last 4 bytes are zeros.
if write_len > 4 && offset != CRB_CTRL_RSP_ADDR {
error!(
"Invalid tpm write: offset {:#X}, data length {}",
offset,
data.len()
);
return None;
}
let mut input: [u8; 4] = [0; 4];
input.copy_from_slice(&data[0..4]);
let v = u32::from_le_bytes(input);
match offset {
CRB_CTRL_CMD_SIZE_REG => {
self.regs[CRB_CTRL_CMD_SIZE_REG as usize] = v;
}
CRB_CTRL_CMD_LADDR => {
self.regs[CRB_CTRL_CMD_LADDR as usize] = v;
}
CRB_CTRL_CMD_HADDR => {
self.regs[CRB_CTRL_CMD_HADDR as usize] = v;
}
CRB_CTRL_RSP_SIZE => {
self.regs[CRB_CTRL_RSP_SIZE as usize] = v;
}
CRB_CTRL_RSP_ADDR => {
self.regs[CRB_CTRL_RSP_ADDR as usize] = v;
}
CRB_CTRL_REQ => match v {
CRB_CTRL_REQ_CMD_READY => {
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 0);
}
CRB_CTRL_REQ_GO_IDLE => {
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 1);
}
_ => {
error!("Invalid value passed to CRTL_REQ register");
return None;
}
},
CRB_CTRL_CANCEL => {
if v == CRB_CANCEL_INVOKE
&& (self.regs[CRB_CTRL_START as usize] & CRB_START_INVOKE != 0)
{
if let Err(e) = self.emulator.cancel_cmd() {
error!("Failed to run cancel command. Error: {:?}", e);
}
}
}
CRB_CTRL_START => {
if v == CRB_START_INVOKE
&& ((self.regs[CRB_CTRL_START as usize] & CRB_START_INVOKE) == 0)
&& self.get_active_locality() == locality
{
self.regs[CRB_CTRL_START as usize] |= CRB_START_INVOKE;
self.cmd = Some(BackendCmd {
locality: locality as u8,
input: self.data_buff[0..self.data_buff_len].to_vec(),
input_len: cmp::min(self.data_buff_len, TPM_CRB_BUFFER_MAX),
output: self.data_buff.to_vec(),
output_len: TPM_CRB_BUFFER_MAX,
selftest_done: false,
});
let mut cmd = self.cmd.as_ref().unwrap().clone();
let output = self.emulator.deliver_request(&mut cmd).map_err(|e| {
Error::DeliverRequest(anyhow!(
"Failed to deliver tpm request. Error :{:?}",
e
))
});
//TODO: drop the copy here
self.data_buff.fill(0);
self.data_buff.clone_from_slice(output.unwrap().as_slice());
self.request_completed(TPM_SUCCESS as isize);
}
}
CRB_LOC_CTRL => {
warn!(
"CRB_LOC_CTRL locality to write = {:?} val = {:?}",
locality, v
);
match v {
CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT => {}
CRB_LOC_CTRL_RELINQUISH => {
set_reg_field(&mut self.regs, CRB_LOC_STATE, "locAssigned", 0);
set_reg_field(&mut self.regs, CRB_LOC_STS, "Granted", 0);
}
CRB_LOC_CTRL_REQUEST_ACCESS => {
set_reg_field(&mut self.regs, CRB_LOC_STS, "Granted", 1);
set_reg_field(&mut self.regs, CRB_LOC_STS, "beenSeized", 0);
set_reg_field(&mut self.regs, CRB_LOC_STATE, "locAssigned", 1);
}
_ => {
error!("Invalid value to write in CRB_LOC_CTRL {:#X} ", v);
}
}
}
_ => {
error!(
"Invalid tpm write: offset {:#X}, data length {:?}",
offset,
data.len()
);
}
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_set_get_reg_field() {
let mut regs: [u32; TPM_CRB_R_MAX as usize] = [0; TPM_CRB_R_MAX as usize];
set_reg_field(&mut regs, CRB_INTF_ID, "RID", 0xAC);
assert_eq!(
get_reg_field(&regs, CRB_INTF_ID, "RID"),
0xAC,
concat!("Test: ", stringify!(set_get_reg_field))
);
}
}

82
docs/building.md Normal file
View File

@@ -0,0 +1,82 @@
- [Building Cloud Hypervisor](#building-cloud-hypervisor)
- [Preparation](#preparation)
- [Install prerequisites](#install-prerequisites)
- [Clone and build](#clone-and-build)
- [Containerized builds and tests](#containerized-builds-and-tests)
# Building Cloud Hypervisor
We recommend users use the pre-built binaries that are mentioned in the README.md file in the root of the repository. Building from source is only necessary if you wish to make modifications.
## Preparation
We create a folder to build and run `cloud-hypervisor` at `$HOME/cloud-hypervisor`
```shell
$ export CLOUDH=$HOME/cloud-hypervisor
$ mkdir $CLOUDH
```
## Install prerequisites
You need to install some prerequisite packages in order to build and test Cloud
Hypervisor. Here, all the steps are based on Ubuntu, for other Linux
distributions please replace the package manager and package name.
```shell
# Install build-essential, git, and qemu-utils
$ sudo apt install git build-essential qemu-utils
# Install rust tool chain
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# If you want to build statically linked binary please add musl target
$ rustup target add x86_64-unknown-linux-musl
```
## Clone and build
First you need to clone and build the Cloud Hypervisor repository:
```shell
$ pushd $CLOUDH
$ git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
$ cd cloud-hypervisor
$ cargo build --release
# We need to give the cloud-hypervisor binary the NET_ADMIN capabilities for it to set TAP interfaces up on the host.
$ sudo setcap cap_net_admin+ep ./target/release/cloud-hypervisor
# If you want to build statically linked binary
$ cargo build --release --target=x86_64-unknown-linux-musl --all
$ popd
```
This will build a `cloud-hypervisor` binary under
`$CLOUDH/cloud-hypervisor/target/release/cloud-hypervisor`.
### Containerized builds and tests
If you want to build and test Cloud Hypervisor without having to install all the
required dependencies (The rust toolchain, cargo tools, etc), you can also use
Cloud Hypervisor's development script: `dev_cli.sh`. Please note that upon its
first invocation, this script will pull a fairly large container image.
For example, to build the Cloud Hypervisor release binary:
```shell
$ pushd $CLOUDH
$ cd cloud-hypervisor
$ ./scripts/dev_cli.sh build --release
```
With `dev_cli.sh`, one can also run the Cloud Hypervisor CI locally. This can be
very convenient for debugging CI errors without having to fully rely on the
Cloud Hypervisor CI infrastructure.
For example, to run the Cloud Hypervisor unit tests:
```shell
$ ./scripts/dev_cli.sh tests --unit
```
Run the `./scripts/dev_cli.sh --help` command to view all the supported
development script commands and their related options.

View File

@@ -2,10 +2,10 @@
This feature allows remote guest debugging using GDB. Note that this feature is only supported on x86_64/KVM.
To enable debugging with GDB, build with the `gdb` feature enabled:
To enable debugging with GDB, build with the `guest_debug` feature enabled:
```bash
cargo build --features gdb
cargo build --features guest_debug
```
To use the `--gdb` option, specify the Unix Domain Socket with `--path` that Cloud Hypervisor will use to communicate with the host's GDB:
@@ -44,4 +44,4 @@ Continuing.
Breakpoint 1, 0x00000000001121b7 in ?? ()
(gdb)
```
```

View File

@@ -61,7 +61,8 @@ meaning it will be printing guest kernel logs to the `virtio-console` device.
```bash
./cloud-hypervisor \
--tdx firmware=edk2-staging/Build/OvmfCh/RELEASE_GCC5/FV/OVMF.fd \
--platform tdx=on
--firmware edk2-staging/Build/OvmfCh/RELEASE_GCC5/FV/OVMF.fd \
--cpus boot=1 \
--memory size=1G \
--disk path=tdx_guest_img
@@ -72,7 +73,8 @@ firmware:
```bash
./cloud-hypervisor \
--tdx firmware=edk2-staging/Build/OvmfCh/DEBUG_GCC5/FV/OVMF.fd \
--platform tdx=on
--firmware edk2-staging/Build/OvmfCh/DEBUG_GCC5/FV/OVMF.fd \
--cpus boot=1 \
--memory size=1G \
--disk path=tdx_guest_img \
@@ -95,7 +97,8 @@ option as well.
```bash
./cloud-hypervisor \
--tdx firmware=tdshim \
--platform tdx=on
--firmware tdshim \
--kernel bzImage \
--cmdline "root=/dev/vda3 console=hvc0 rw"
--cpus boot=1 \

View File

@@ -20,12 +20,13 @@ struct MemoryConfig {
hugepages: bool,
hugepage_size: Option<u64>,
prefault: bool,
thp: bool
zones: Option<Vec<MemoryZoneConfig>>,
}
```
```
--memory <memory> Memory parameters "size=<guest_memory_size>,mergeable=on|off,shared=on|off,hugepages=on|off,hugepage_size=<hugepage_size>,hotplug_method=acpi|virtio-mem,hotplug_size=<hotpluggable_memory_size>,hotplugged_size=<hotplugged_memory_size>,prefault=on|off" [default: size=512M]
--memory <memory> Memory parameters "size=<guest_memory_size>,mergeable=on|off,shared=on|off,hugepages=on|off,hugepage_size=<hugepage_size>,hotplug_method=acpi|virtio-mem,hotplug_size=<hotpluggable_memory_size>,hotplugged_size=<hotplugged_memory_size>,prefault=on|off,thp=on|off" [default: size=512M,thp=on]
```
### `size`
@@ -117,6 +118,9 @@ needing access to the guest RAM content.
By default this option is turned off, which results in performing `mmap(2)`
with `MAP_PRIVATE` flag.
If `hugepages=on` then the value of this field is ignored as huge pages always
requires `MAP_SHARED`.
_Example_
```
@@ -140,6 +144,9 @@ behaviour, e.g. error with `ReadKernelImage` is common. If there is a strange
error with `hugepages` enabled, just disable it or check whether there are enough
huge pages.
If `hugepages=on` then the value of `shared` is ignored as huge pages always
requires `MAP_SHARED`.
By default this option is turned off.
_Example_
@@ -171,6 +178,25 @@ _Example_
--memory size=1G,prefault=on
```
### `thp`
Specifies if private anonymous memory for the guest (i.e. `shared=off` and no
backing file) should be labelled `MADV_HUGEPAGE` with `madvise(2)` indicating
to the kernel that this memory may be backed with huge pages transparently.
The use of transparent huge pages can improve the performance of the guest as
there will fewer virtualisation related page faults. Unlike using
`hugepages=on` a specific number of huge pages do not need to be allocated by
the kernel.
By default this option is turned on.
_Example_
```
--memory size=1G,thp=on
```
## Advanced Parameters
`MemoryZoneConfig` or what is known as `--memory-zone` from the CLI perspective
@@ -271,6 +297,9 @@ other processes running on the host. One can use this option when running
vhost-user devices as part of the VM device model, as they will be driven
by standalone daemons needing access to the guest RAM content.
If `hugepages=on` then the value of this field is ignored as huge pages always
requires `MAP_SHARED`.
By default this option is turned off, which result in performing `mmap(2)`
with `MAP_PRIVATE` flag.
@@ -298,6 +327,9 @@ behaviour, e.g. error with `ReadKernelImage` is common. If there is a strange
error with `hugepages` enabled, just disable it or check whether there are enough
huge pages.
If `hugepages=on` then the value of `shared` is ignored as huge pages always
requires `MAP_SHARED`.
By default this option is turned off.
_Example_

View File

@@ -64,5 +64,5 @@ it will log every system call issued by the process. It is important to use
`-f` option in order to trace each and every thread belonging to the process.
```
strace -f ./cloud-hypervisor ...
strace --decode-pids=comm -f ./cloud-hypervisor ...
```

122
docs/tpm.md Normal file
View File

@@ -0,0 +1,122 @@
# TPM
Tpm in Cloud-Hypervisor is emulated using `swtpm` as the backend. [swtpm](https://github.com/stefanberger/swtpm) is the link to swtpm project.
Current implementation only supports TPM `2.0` version. At the moment only
`CRB Interface` is implemented. This interface is described in
[TCG PC Client Platform TPM Profile Specification for TPM 2.0, Revision 01.05 v4](https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p05p_r14_pub.pdf).
## Usage
`--tpm`, an optional argument, can be passed to enable tpm device.
This argument takes an UNIX domain Socket as a `socket` value.
_Example_
An Example invocation with `--tpm` argument:
```
./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--tpm socket="/var/run/swtpm.socket"
```
## swtpm
Before invoking cloud-hypervisor with `--tpm` argument, a `swtpm`
process should be started to listen at the input socket. Below is an
example invocation of swtpm process.
```
swtpm socket --tpmstate dir=/var/run/swtpm \
--ctrl type=unixio,path="/var/run/swtpm.socket" \
--flags startup-clear \
--tpm2
```
## Guest
After starting a guest with the above commands, ensure below listed modules are
loaded in the guest:
```
# lsmod | grep tpm
tpm_crb 20480 0
tpm 81920 1 tpm_crb
```
Below is the IO Memory map configured in the guest:
```
# cat /proc/iomem | grep MSFT
fed40000-fed40fff : MSFT0101:00
fed40000-fed40fff : MSFT0101:00
```
Below are the devices created in the guest:
```
# ls /dev/tpm*
/dev/tpm0 /dev/tpmrm0
```
## Testing
Inside the guest install `tpm2-tools` package. This package provides some
commands to run against TPM that supports 2.0 version.
_Examples_
```
// Run Self Test
# tpm2_selftest -f
# echo $?
0
# echo "hello" > input.txt
// this command generates hash of the input file using all the algos supported by TPM
# tpm2_pcrevent input.txt
sha1: f572d396fae9206628714fb2ce00f72e94f2258f
sha256: 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
sha384: 1d0f284efe3edea4b9ca3bd514fa134b17eae361ccc7a1eefeff801b9bd6604e01f21f6bf249ef030599f0c
218f2ba8c
sha512: e7c22b994c59d9cf2b48e549b1e24666636045930d3da7c1acb299d1c3b7f931f94aae41edda2c2b207a36e
10f8bcb8d45223e54878f5b316e7ce3b6bc019629
// verify one of the hashes
# sha256sum input.txt
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 input.txt
```
### Bundled Functional Test
Build time dependencies for `tpm2-tss` are captured in [INSTALL](https://github.com/tpm2-software/tpm2-tss/blob/master/INSTALL.md).
```
# git clone https://github.com/tpm2-software/tpm2-tss.git
# cd tpm2-tss
# ./configure --enable-integration --with-devicetests="mandatory,optional" --with-device=/dev/tpm0
# sudo make check-device
.
.
.
.
============================================================================
Testsuite summary for tpm2-tss 3.2.0-74-ge03617d9
============================================================================
# TOTAL: 154
# PASS: 88
# SKIP: 7
# XFAIL: 0
# FAIL: 59
# XPASS: 0
# ERROR: 0
============================================================================
See ./test-suite.log
Please report to https://github.com/tpm2-software/tpm2-tss/issues
============================================================================
```
The same set of failures are noticed while running these tests on `Qemu` with
its TPM implementation.

42
docs/tracing.md Normal file
View File

@@ -0,0 +1,42 @@
# Tracing
Cloud Hypervisor has a basic tracing infrastucture, particularly focussed on
the tracing of the initial VM setup.
## Usage
To enabling tracing, build with "tracing" feature. When compiled without the
feature the tracing is compiled out.
```bash
cargo build --features "tracing"
```
And then run Cloud Hypervisor as you wish, the trace will be written to the current directory as `cloud-hypervisor-<pid>.trace`. This is JSON file which you can inspect yourself.
Alternatively you can use the provided script in
`scripts/ch-trace-visualiser.py` to generate an SVG:
For example:
```bash
scripts/ch-trace-visualiser.py cloud-hypervisor-39466.trace output.svg
```
## Tracing in the codebase
There are existing tracepoints in the code base; extra ones can be added for
more detailed tracing.
The `tracer::trace_scoped!()` macro is used to add the current existing scope
appears as a block in the trace. Other than providing a useful name for the
event nothing else is required from the developer.
The `tracer::start()` and `tracer::end()` functions are already in place for
generating traces of the boot. These can be relocated for focus tracing on a
narrow part of the code base.
A `tracer::trace_point!()` macro is also provided for an instantaneous trace
point however this is not in use in the code base currently nor is handled by
the visualisation script due to the difficulty in representation in the SVG.

84
docs/vsock.md Normal file
View File

@@ -0,0 +1,84 @@
# VSOCK support
VSOCK provides a way for guest and host to communicate through a socket. VSOCK sockets support both stream and datagram types.
The `virtio-vsock` is based on the [Firecracker](https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md) implementation, where additional details can be found.
## What is a CID?
CID is a 32-bit context identifier describing the source or destination. In combination with the port, the complete addressing can be achieved to describe multiple listeners running on the same machine.
The table below depicts the well known CID values:
| CID | Description |
|-----|-------------|
| -1 | Random CID |
| 0 | Hypervisor |
| 1 | Loopback |
| 2 | Host |
## Prerequisites
### Kernel Requirements
Host kernel: CONFIG_VHOST_VSOCK
Guest kernel: CONFIG_VIRTIO_VSOCKETS
### Nested VM support
Linux __v5.5__ or newer is required for the L1 VM.
### Loopback support
Linux __v5.6__ or newer is required.
## Establishing VSOCK Connection
VSOCK device becomes available with `--vsock` option passed by the VM start. Cloud Hypervisor can be invoked for instance as below:
```bash
cloud-hypervisor \
--cpus boot=1 \
--memory size=4G \
--firmware CLOUDHV.fd \
--disk path=jammy-server-cloudimg.raw \
--vsock cid=3,socket=/tmp/ch.vsock
```
The examples use __socat__ `>=1.7.4` to illustrate the VSOCK functionality. However, there are other tools supporting VSOCK, like [ncat](https://stefano-garzarella.github.io/posts/2019-11-08-kvmforum-2019-vsock/).
### Connecting from Host to Guest
The host starts to listen on the defined port:
`$ socat - VSOCK-LISTEN:1234`
Once the host is listening, the guest can send data:
`echo -e "CONNECT 1234\\nHello from host!" | socat - UNIX-CONNECT:/tmp/ch.vsock
Note the string `CONNECT <port>` prepended to the actual data. It is possible for the guest to start listening on different ports, thus the specific command is needed to instruct VSOCK to which listener the host wants to connect. It needs to be sent once per connection. Once the connection established, data transfers can take place directly.
### Connecting from Guest to Host
This first requires a listening UNIX socket on the host side. The UNIX socket path has to be constructed by using the socket path used at the VM launch time with appended `_` and the port number to be used on the guest side. As in the example above, if we'd intended to connect from the guest to the port `1234`, the Unix socket path on the host side would be `/tmp/ch.vsock_1234`.
Also note that the CID used on the guest side is the well known CID value `2`.
Listening on the host side:
`$ socat - UNIX-LISTEN:/tmp/ch.vsock_1234`
From the guest:
`$ echo -e "Hello from guest!" | socat - VSOCK-CONNECT:2:1234`
## Links
- [virtio-vsock in QEMU, Firecracker and Linux: Status, Performance and Challenges](https://kvmforum2019.sched.com/event/TmwK)
- [Leveraging virtio-vsock in the cloud and containers](https://archive.fosdem.org/2021/schedule/event/vai_virtio_vsock/)
- [VSOCK man page](https://manpages.ubuntu.com/manpages/focal/man7/vsock.7.html)
- [https://stefano-garzarella.github.io/posts/2020-02-20-vsock-nested-vms-loopback/](https://stefano-garzarella.github.io/posts/2020-02-20-vsock-nested-vms-loopback/)
- [https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md](https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md)

View File

@@ -131,7 +131,7 @@ See also the [links](#Links) section for a more extended SAC documentation.
## Network
This section illustrates the Windows specific corner points for the VM network configuration. For the extended networking guide, including bridging for multiple VMs, follow [networking.md](networking.md).
This section illustrates the Windows specific aspects of the VM network configuration.
### Basic Networking

View File

@@ -5,6 +5,6 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
libc = "0.2.131"
serde = { version = "1.0.143", features = ["rc", "derive"] }
serde_json = "1.0.83"
libc = "0.2.138"
serde = { version = "1.0.150", features = ["rc", "derive"] }
serde_json = "1.0.89"

448
fuzz/Cargo.lock generated
View File

@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.62"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "api_client"
@@ -24,9 +24,9 @@ dependencies = [
[[package]]
name = "arbitrary"
version = "1.1.3"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60"
checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880"
[[package]]
name = "arc-swap"
@@ -56,23 +56,6 @@ dependencies = [
"vmm-sys-util",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bincode"
version = "1.3.3"
@@ -115,9 +98,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.73"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
@@ -127,33 +113,31 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.2.17"
version = "4.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"is-terminal",
"once_cell",
"strsim",
"termcolor",
"terminal_size",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "cloud-hypervisor"
version = "25.0.0"
version = "28.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -168,6 +152,8 @@ dependencies = [
"serde_json",
"signal-hook",
"thiserror",
"tpm",
"tracer",
"vm-memory",
"vmm",
"vmm-sys-util",
@@ -214,9 +200,9 @@ checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910"
[[package]]
name = "darling"
version = "0.14.1"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
dependencies = [
"darling_core",
"darling_macro",
@@ -224,9 +210,9 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.14.1"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f"
checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
dependencies = [
"fnv",
"ident_case",
@@ -238,9 +224,9 @@ dependencies = [
[[package]]
name = "darling_macro"
version = "0.14.1"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
dependencies = [
"darling_core",
"quote",
@@ -259,6 +245,9 @@ dependencies = [
"hypervisor",
"libc",
"log",
"phf",
"thiserror",
"tpm",
"versionize",
"versionize_derive",
"vm-device",
@@ -277,6 +266,27 @@ dependencies = [
"libc",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "event_monitor"
version = "0.1.0"
@@ -300,26 +310,20 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "getrandom"
version = "0.2.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hermit-abi"
version = "0.1.20"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7a30908dbce072eca83216eab939d2290080e00ca71611b96a09e5cdce5f3fa"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
@@ -360,35 +364,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indexmap"
version = "1.9.1"
name = "io-lifetimes"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
dependencies = [
"autocfg",
"hashbrown",
"libc",
"windows-sys",
]
[[package]]
name = "io-uring"
version = "0.5.3"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427496d698429d86ff947537dff68facb83fe753b7abea4fab4ac1c4b7a4b94b"
checksum = "7ba34abb5175052fc1a2227a10d2275b7386c9990167de9786c0b88d8b062330"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "itoa"
version = "1.0.3"
name = "is-terminal"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "itoa"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]]
name = "jobserver"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
dependencies = [
"libc",
]
[[package]]
name = "kvm-bindings"
version = "0.5.0"
source = "git+https://github.com/cloud-hypervisor/kvm-bindings?branch=ch-v0.5.0-tdx#52e56d0e8ef0f6ea32fc0492e6a175b73617a49f"
version = "0.6.0"
source = "git+https://github.com/cloud-hypervisor/kvm-bindings?branch=ch-v0.6.0-tdx#7d9ffb47e5b9b1989577258800a0f57c93f1445f"
dependencies = [
"serde",
"serde_derive",
@@ -397,8 +422,9 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.11.0"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#1e03e29cdfbb0cb108a98de7a78045a5a517f18e"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3a321cabd827642499c77e27314f388dd83a717a5ca716b86476fb947f73ae4"
dependencies = [
"kvm-bindings",
"libc",
@@ -413,15 +439,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.131"
version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "libfuzzer-sys"
version = "0.4.3"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336244aaeab6a12df46480dc585802aa743a72d66b11937844c61bbca84c991d"
checksum = "c8fff891139ee62800da71b7fd5b508d570b9ad95e614a53c6f453ca08366038"
dependencies = [
"arbitrary",
"cc",
@@ -430,13 +456,19 @@ dependencies = [
[[package]]
name = "linux-loader"
version = "0.4.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a5e77493808403a6bd56a301a64ea6b9342e36ea845044bf0dfdf56fe52fa08"
checksum = "b9259ddbfbb52cc918f6bbc60390004ddd0228cf1d85f402009ff2b3d95de83f"
dependencies = [
"vm-memory",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
[[package]]
name = "log"
version = "0.4.17"
@@ -449,7 +481,7 @@ dependencies = [
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#863b0370ba7e57f7df5b908ada9e5b44809ccae9"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#4b18a043e997da5b5f679e3defc279fec908753e"
dependencies = [
"libc",
"vmm-sys-util",
@@ -485,9 +517,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.13.1"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "option_parser"
@@ -495,9 +527,9 @@ version = "0.1.0"
[[package]]
name = "os_str_bytes"
version = "6.3.0"
version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "pci"
@@ -523,10 +555,52 @@ dependencies = [
]
[[package]]
name = "proc-macro2"
version = "1.0.43"
name = "phf"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c"
dependencies = [
"phf_macros",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676"
dependencies = [
"siphasher",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
@@ -551,6 +625,21 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rate_limiter"
version = "0.1.0"
@@ -562,9 +651,9 @@ dependencies = [
[[package]]
name = "remain"
version = "0.2.4"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06df529c0d271b27ac4a2c260f5ce2914b60bd44702cecec7b9f271adbdde23b"
checksum = "1a81bc6a3aaeb180f767bd2bda8c03bac5b93b3b69a783c66f35d16a4df276cf"
dependencies = [
"proc-macro2",
"quote",
@@ -580,6 +669,20 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "ryu"
version = "1.0.11"
@@ -588,33 +691,33 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "seccompiler"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01d1292a1131b22ccea49f30bd106f1238b5ddeec1a98d39268dcc31d540e68"
checksum = "6f6575e3c2b3a0fe2ef3e53855b6a8dead7c29f783da5e123d378c8c6a89017e"
dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "1.0.13"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
[[package]]
name = "serde"
version = "1.0.143"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.143"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e"
dependencies = [
"proc-macro2",
"quote",
@@ -623,9 +726,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.83"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",
@@ -634,9 +737,9 @@ dependencies = [
[[package]]
name = "serde_with"
version = "2.0.0"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89df7a26519371a3cce44fbb914c2819c84d9b897890987fa3ab096491cc0ea8"
checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef"
dependencies = [
"serde",
"serde_with_macros",
@@ -644,9 +747,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "2.0.0"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de337f322382fcdfbb21a014f7c224ee041a23785651db67b9827403178f698f"
checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa"
dependencies = [
"darling",
"proc-macro2",
@@ -654,6 +757,10 @@ dependencies = [
"syn",
]
[[package]]
name = "serial_buffer"
version = "0.1.0"
[[package]]
name = "signal-hook"
version = "0.3.14"
@@ -673,6 +780,12 @@ dependencies = [
"libc",
]
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "static_assertions"
version = "1.1.0"
@@ -687,9 +800,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.99"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
@@ -707,63 +820,77 @@ dependencies = [
[[package]]
name = "terminal_size"
version = "0.1.17"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
dependencies = [
"terminal_size",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "1.0.32"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.32"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tpm"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"libc",
"log",
"thiserror",
"vmm-sys-util",
]
[[package]]
name = "tracer"
version = "0.1.0"
dependencies = [
"libc",
"log",
"once_cell",
"serde",
"serde_json",
]
[[package]]
name = "unicode-ident"
version = "1.0.3"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "uuid"
version = "1.1.2"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
dependencies = [
"getrandom",
]
[[package]]
name = "versionize"
version = "0.1.6"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7429cf68de8f091b667d27323ed323afd39584a56d533995b12ddd748e5e6ca9"
checksum = "d6e2495726cf917e7ba7ec8bf0f0fceab543dd38d0a4195ed6bef331e38a290f"
dependencies = [
"bincode",
"crc64",
@@ -788,17 +915,16 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43449b404c488f70507dca193debd4bea361fe8089869b947adc19720e464bce"
version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#7ef33f6759ae6d37a54cd66f749aa47c1c81509c"
dependencies = [
"vmm-sys-util",
]
[[package]]
name = "vfio-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#1ff2324e5cb0fccab825f9c96bb9387a1a01863f"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#7ef33f6759ae6d37a54cd66f749aa47c1c81509c"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -841,9 +967,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.4.0"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53567fd9ab820e4f3cc156f24146882fee3c365194c3e1dea74723265f27fc88"
checksum = "c9b791c5b0717a0558888a4cf7240cea836f39a99cb342e12ce633dcaa078072"
dependencies = [
"bitflags",
"libc",
@@ -877,6 +1003,7 @@ dependencies = [
"seccompiler",
"serde",
"serde_json",
"serial_buffer",
"thiserror",
"versionize",
"versionize_derive",
@@ -893,9 +1020,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.5.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f59652909f276e6edd8bf36e9f106480b2202f5f046717b3de14f1b4072a28"
checksum = "19e927d93d54c365034fd7f31a5f458a1f540de4a37c52e892670dad9692173c"
dependencies = [
"log",
"virtio-bindings",
@@ -927,14 +1054,14 @@ dependencies = [
[[package]]
name = "vm-fdt"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#720e48e435b791ec6cbe8d2b229448b71dcb1ab9"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#c5a99ab71b130435927d19b50c85fcd5ce904a8c"
[[package]]
name = "vm-memory"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "767ed8aaebbff902e02e6d3749dc2baef55e46565f8a6414a065e5baee4b4a81"
checksum = "688a70366615b45575a424d9c665561c1b5ab2224d494f706b6a6812911a827c"
dependencies = [
"arc-swap",
"libc",
@@ -990,8 +1117,10 @@ dependencies = [
"seccompiler",
"serde",
"serde_json",
"serial_buffer",
"signal-hook",
"thiserror",
"tracer",
"uuid",
"versionize",
"versionize_derive",
@@ -1010,9 +1139,9 @@ dependencies = [
[[package]]
name = "vmm-sys-util"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08604d7be03eb26e33b3cee3ed4aef2bf550b305d1cca60e84da5d28d3790b62"
checksum = "cc06a16ee8ebf0d9269aed304030b0d20a866b8b3dd3d4ce532596ac567a0d24"
dependencies = [
"bitflags",
"libc",
@@ -1056,3 +1185,60 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"

View File

@@ -12,18 +12,18 @@ cargo-fuzz = true
block_util = { path = "../block_util" }
devices = { path = "../devices" }
epoll = "4.3.1"
libc = "0.2.131"
libfuzzer-sys = "0.4.3"
libc = "0.2.135"
libfuzzer-sys = "0.4.5"
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
once_cell = "1.13.1"
once_cell = "1.16.0"
qcow = { path = "../qcow" }
seccompiler = "0.2.0"
seccompiler = "0.3.0"
vhdx = { path = "../vhdx" }
virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.5.0"
virtio-queue = "0.7.0"
vmm = { path = "../vmm" }
vmm-sys-util = "0.10.0"
vm-memory = "0.8.0"
vmm-sys-util = "0.11.0"
vm-memory = "0.10.0"
vm-device = { path = "../vm-device" }
vm-virtio = { path = "../vm-virtio" }
@@ -31,14 +31,19 @@ vm-virtio = { path = "../vm-virtio" }
path = ".."
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0-tdx" }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
# Prevent this from interfering with workspaces
[workspace]
members = ["."]
[[bin]]
name = "balloon"
path = "fuzz_targets/balloon.rs"
test = false
doc = false
[[bin]]
name = "block"
path = "fuzz_targets/block.rs"
@@ -51,18 +56,48 @@ path = "fuzz_targets/cmos.rs"
test = false
doc = false
[[bin]]
name = "console"
path = "fuzz_targets/console.rs"
test = false
doc = false
[[bin]]
name = "http_api"
path = "fuzz_targets/http_api.rs"
test = false
doc = false
[[bin]]
name = "iommu"
path = "fuzz_targets/iommu.rs"
test = false
doc = false
[[bin]]
name = "mem"
path = "fuzz_targets/mem.rs"
test = false
doc = false
[[bin]]
name = "pmem"
path = "fuzz_targets/pmem.rs"
test = false
doc = false
[[bin]]
name = "qcow"
path = "fuzz_targets/qcow.rs"
test = false
doc = false
[[bin]]
name = "rng"
path = "fuzz_targets/rng.rs"
test = false
doc = false
[[bin]]
name = "serial"
path = "fuzz_targets/serial.rs"
@@ -74,3 +109,9 @@ name = "vhdx"
path = "fuzz_targets/vhdx.rs"
test = false
doc = false
[[bin]]
name = "watchdog"
path = "fuzz_targets/watchdog.rs"
test = false
doc = false

View File

@@ -0,0 +1,153 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::Arc;
use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 512 * 1024;
const BALLOON_SIZE: u64 = 512 * 1024;
// Number of queues
const QUEUE_NUM: usize = 3;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 64;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;
// Descriptor table size
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Available ring size
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Used ring size
const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64;
fuzz_target!(|bytes| {
if bytes.len() < QUEUE_DATA_SIZE * QUEUE_NUM
|| bytes.len() > (QUEUE_DATA_SIZE * QUEUE_NUM + MEM_SIZE)
{
return;
}
let mut balloon = virtio_devices::Balloon::new(
"fuzzer_balloon".to_owned(),
BALLOON_SIZE,
true,
true,
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap();
let queue_data = &bytes[..QUEUE_DATA_SIZE * QUEUE_NUM];
let mem_bytes = &bytes[QUEUE_DATA_SIZE * QUEUE_NUM..];
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
// Setup the virt queues with the input bytes
let mut queues = setup_virt_queues(
&[
&queue_data[..QUEUE_DATA_SIZE].try_into().unwrap(),
&queue_data[QUEUE_DATA_SIZE..QUEUE_DATA_SIZE * 2]
.try_into()
.unwrap(),
&queue_data[QUEUE_DATA_SIZE * 2..QUEUE_DATA_SIZE * 3]
.try_into()
.unwrap(),
],
0,
);
let inflate_q = queues.remove(0);
let inflate_evt = EventFd::new(0).unwrap();
let inflate_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(inflate_evt.as_raw_fd())) };
let deflate_q = queues.remove(0);
let deflate_evt = EventFd::new(0).unwrap();
let deflate_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(deflate_evt.as_raw_fd())) };
let reporting_q = queues.remove(0);
let reporting_evt = EventFd::new(0).unwrap();
let reporting_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(reporting_evt.as_raw_fd())) };
// Kick the 'queue' events before activate the balloon device
inflate_queue_evt.write(1).unwrap();
deflate_queue_evt.write(1).unwrap();
reporting_queue_evt.write(1).unwrap();
balloon
.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![
(0, inflate_q, inflate_evt),
(1, deflate_q, deflate_evt),
(2, reporting_q, reporting_evt),
],
)
.ok();
// Wait for the events to finish and balloon device worker thread to return
balloon.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
macro_rules! align {
($n:expr, $align:expr) => {{
(($n + $align - 1) / $align) * $align
}};
}
fn setup_virt_queues(bytes: &[&[u8; QUEUE_DATA_SIZE]], base_addr: u64) -> Vec<Queue> {
let mut queues = Vec::new();
let mut base_addr = base_addr;
for b in bytes {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
let desc_table_addr = align!(base_addr, DESC_TABLE_ALIGN_SIZE);
let avail_ring_addr = align!(desc_table_addr + DESC_TABLE_SIZE, AVAIL_RING_ALIGN_SIZE);
let used_ring_addr = align!(avail_ring_addr + AVAIL_RING_SIZE, USED_RING_ALIGN_SIZE);
q.try_set_desc_table_address(GuestAddress(desc_table_addr))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(avail_ring_addr))
.unwrap();
q.try_set_used_ring_address(GuestAddress(used_ring_addr))
.unwrap();
q.set_next_avail(b[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(b[1] as u16);
q.set_event_idx(b[2] % 2 != 0);
q.set_size(b[3] as u16 % QUEUE_SIZE);
q.set_ready(true);
queues.push(q);
base_addr = used_ring_addr + USED_RING_SIZE;
}
queues
}

View File

@@ -1,6 +1,10 @@
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
#![no_main]
@@ -16,37 +20,35 @@ use std::sync::Arc;
use virtio_devices::{Block, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm::{EpollContext, EpollDispatch};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const MEM_SIZE: u64 = 256 * 1024 * 1024;
const QUEUE_SIZE: u16 = 16; // Max entries in the queue.
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 256 * 1024 * 1024;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = 0;
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = DESC_TABLE_ADDR + DESC_TABLE_SIZE;
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Guest physical address for used ring (requires to 4-bytes aligned)
const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64;
fuzz_target!(|bytes| {
if bytes.len() as u64 > MEM_SIZE {
if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) {
return;
}
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE as usize)]).unwrap();
if mem.write_slice(bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_ready(true);
q.set_size(QUEUE_SIZE / 2);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
let queue_data = &bytes[..QUEUE_DATA_SIZE];
let mem_bytes = &bytes[QUEUE_DATA_SIZE..];
// Create a virtio-block device backed by a synchronous raw file
let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
let disk_file: File = unsafe { File::from_raw_fd(shm) };
let qcow_disk = Box::new(RawFileDiskSync::new(disk_file)) as Box<dyn DiskFile>;
let mut block = Block::new(
"tmp".to_owned(),
qcow_disk,
@@ -58,9 +60,26 @@ fuzz_target!(|bytes| {
SeccompAction::Allow,
None,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap();
// Setup the virt queue with the input bytes
let q = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
// Kick the 'queue' event before activate the block device
queue_evt.write(1).unwrap();
block
.activate(
guest_memory,
@@ -69,11 +88,8 @@ fuzz_target!(|bytes| {
)
.ok();
queue_evt.write(77).unwrap(); // Rings the doorbell, any byte will do.
wait_queue_event_processed(queue_evt);
block.reset(); // Ensure the virtio-block device thread is killed and joined
// Wait for the events to finish and block device worker thread to return
block.wait_for_epoll_threads();
});
fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> {
@@ -94,28 +110,20 @@ impl VirtioInterrupt for NoopVirtioInterrupt {
}
}
fn wait_queue_event_processed(queue_evt: EventFd) {
let mut epoll = EpollContext::new().unwrap();
epoll.add_event(&queue_evt, EpollDispatch::Api).unwrap();
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
let epoll_fd = epoll.as_raw_fd();
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); 1];
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
loop {
let num_events = match epoll::wait(epoll_fd, 0, &mut events[..]) {
Ok(res) => res,
Err(e) => {
if e.kind() == io::ErrorKind::Interrupted {
continue;
}
println!("Warning: Unexpected epoll::wait() error!");
break;
}
};
if num_events == 0 {
break;
}
}
q
}

View File

@@ -0,0 +1,194 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::fs::File;
use std::io::Write;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Arc;
use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
macro_rules! align {
($n:expr, $align:expr) => {{
(($n + $align - 1) / $align) * $align
}};
}
const CONSOLE_INPUT_SIZE: usize = 128;
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 32 * 1024 * 1024;
// Guest memory gap
const GUEST_MEM_GAP: u64 = 1 * 1024 * 1024;
// Guest physical address for the first virt queue
const BASE_VIRT_QUEUE_ADDR: u64 = MEM_SIZE as u64 + GUEST_MEM_GAP;
// Number of queues
const QUEUE_NUM: usize = 2;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;
// Descriptor table size
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Available ring size
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Padding size before used ring
const PADDING_SIZE: u64 = align!(AVAIL_RING_SIZE, USED_RING_ALIGN_SIZE) - AVAIL_RING_SIZE;
// Used ring size
const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64;
// Virtio-queue size in bytes
const QUEUE_BYTES_SIZE: usize = align!(
DESC_TABLE_SIZE + AVAIL_RING_SIZE + PADDING_SIZE + USED_RING_SIZE,
DESC_TABLE_ALIGN_SIZE
) as usize;
fuzz_target!(|bytes| {
if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + CONSOLE_INPUT_SIZE
|| bytes.len()
> (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + CONSOLE_INPUT_SIZE + MEM_SIZE
{
return;
}
let (pipe_rx, mut pipe_tx) = create_pipe().unwrap();
let output = unsafe {
File::from_raw_fd(
memfd_create(&std::ffi::CString::new("fuzz_console_output").unwrap()).unwrap(),
)
};
let endpoint = virtio_devices::Endpoint::FilePair(output, pipe_rx);
let (mut console, _) = virtio_devices::Console::new(
"fuzzer_console".to_owned(),
endpoint,
None, // resize_pipe
false, // iommu
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap();
let console_input_bytes = &bytes[..CONSOLE_INPUT_SIZE];
let queue_data = &bytes[CONSOLE_INPUT_SIZE..CONSOLE_INPUT_SIZE + QUEUE_DATA_SIZE * QUEUE_NUM];
let queue_bytes = &bytes[CONSOLE_INPUT_SIZE + QUEUE_DATA_SIZE * QUEUE_NUM
..CONSOLE_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM];
let mem_bytes = &bytes[CONSOLE_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM..];
// Setup the virt queues with the input bytes
let mut queues = setup_virt_queues(
&[
&queue_data[..QUEUE_DATA_SIZE].try_into().unwrap(),
&queue_data[QUEUE_DATA_SIZE..QUEUE_DATA_SIZE * 2]
.try_into()
.unwrap(),
],
BASE_VIRT_QUEUE_ADDR,
);
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[
(GuestAddress(0), MEM_SIZE),
(GuestAddress(BASE_VIRT_QUEUE_ADDR), queue_bytes.len()),
])
.unwrap();
if mem
.write_slice(queue_bytes, GuestAddress(BASE_VIRT_QUEUE_ADDR))
.is_err()
{
return;
}
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let input_queue = queues.remove(0);
let input_evt = EventFd::new(0).unwrap();
let input_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(input_evt.as_raw_fd())) };
let output_queue = queues.remove(0);
let output_evt = EventFd::new(0).unwrap();
let output_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(output_evt.as_raw_fd())) };
// Kick the 'queue' events and endpoint event before activate the console device
input_queue_evt.write(1).unwrap();
output_queue_evt.write(1).unwrap();
pipe_tx.write_all(console_input_bytes).unwrap(); // To use fuzzed data;
console
.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![(0, input_queue, input_evt), (1, output_queue, output_evt)],
)
.unwrap();
// Wait for the events to finish and console device worker thread to return
console.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
fn setup_virt_queues(bytes: &[&[u8; QUEUE_DATA_SIZE]], base_addr: u64) -> Vec<Queue> {
let mut queues = Vec::new();
for (i, b) in bytes.iter().enumerate() {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
let desc_table_addr = base_addr + (QUEUE_BYTES_SIZE * i) as u64;
let avail_ring_addr = desc_table_addr + DESC_TABLE_SIZE;
let used_ring_addr = avail_ring_addr + PADDING_SIZE + AVAIL_RING_SIZE;
q.try_set_desc_table_address(GuestAddress(desc_table_addr))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(avail_ring_addr))
.unwrap();
q.try_set_used_ring_address(GuestAddress(used_ring_addr))
.unwrap();
q.set_next_avail(b[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(b[1] as u16);
q.set_event_idx(b[2] % 2 != 0);
q.set_size(b[3] as u16 % QUEUE_SIZE);
q.set_ready(true);
queues.push(q);
}
queues
}
fn memfd_create(name: &std::ffi::CStr) -> Result<RawFd, std::io::Error> {
let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), 0) };
if res < 0 {
Err(std::io::Error::last_os_error())
} else {
Ok(res as RawFd)
}
}
fn create_pipe() -> Result<(File, File), std::io::Error> {
let mut pipe = [-1; 2];
if unsafe { libc::pipe2(pipe.as_mut_ptr(), libc::O_CLOEXEC) } == -1 {
return Err(std::io::Error::last_os_error());
}
let rx = unsafe { File::from_raw_fd(pipe[0]) };
let tx = unsafe { File::from_raw_fd(pipe[1]) };
Ok((rx, tx))
}

145
fuzz/fuzz_targets/iommu.rs Normal file
View File

@@ -0,0 +1,145 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::Arc;
use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
macro_rules! align {
($n:expr, $align:expr) => {{
(($n + $align - 1) / $align) * $align
}};
}
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 32 * 1024 * 1024;
// Reuse what's being done from DeviceManager::get_msi_iova_space()
const IOVA_SPACE_SIZE: usize = (0xfeef_ffff - 0xfee0_0000) + 1;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;
// Descriptor table size
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Available ring size
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Used ring size
const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64;
// Guest memory gap
const GUEST_MEM_GAP: u64 = 1 * 1024 * 1024;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = align!(MEM_SIZE as u64 + GUEST_MEM_GAP, DESC_TABLE_ALIGN_SIZE);
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = align!(DESC_TABLE_ADDR + DESC_TABLE_SIZE, AVAIL_RING_ALIGN_SIZE);
// Guest physical address for used ring
const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ALIGN_SIZE);
// Virtio-queue size in bytes
const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize;
fuzz_target!(|bytes| {
if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE)
|| bytes.len() > (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE)
{
return;
}
let (mut iommu, _) = virtio_devices::Iommu::new(
"fuzzer_iommu".to_owned(),
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
((MEM_SIZE - IOVA_SPACE_SIZE) as u64, (MEM_SIZE - 1) as u64),
None,
)
.unwrap();
let queue_data = &bytes[..QUEUE_DATA_SIZE];
let queue_bytes = &bytes[QUEUE_DATA_SIZE..QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE];
let mem_bytes = &bytes[QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE..];
// Setup the request queue with the input bytes
let request_queue = setup_virt_queue(queue_data.try_into().unwrap());
// Given the "event queue" events are not handled from the current
// implementation of virtio-iommu, we simply setup the 'event_queue'
// with exactly the same content as the 'request_queue'.
let _event_queue = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[
(GuestAddress(0), MEM_SIZE),
(GuestAddress(DESC_TABLE_ADDR), QUEUE_BYTES_SIZE),
])
.unwrap();
if mem
.write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR))
.is_err()
{
return;
}
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let request_evt = EventFd::new(0).unwrap();
let request_queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(request_evt.as_raw_fd())) };
let _event_evt = EventFd::new(0).unwrap();
// Kick the 'queue' event before activate the vIOMMU device
request_queue_evt.write(1).unwrap();
iommu
.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![
(0, request_queue, request_evt),
(0, _event_queue, _event_evt),
],
)
.ok();
// Wait for the events to finish and vIOMMU device worker thread to return
iommu.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
q
}

179
fuzz/fuzz_targets/mem.rs Normal file
View File

@@ -0,0 +1,179 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::{Arc, Mutex};
use virtio_devices::{BlocksState, Mem, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
type GuestRegionMmap = vm_memory::GuestRegionMmap<AtomicBitmap>;
macro_rules! align {
($n:expr, $align:expr) => {{
(($n + $align - 1) / $align) * $align
}};
}
const VIRTIO_MEM_DATA_SIZE: usize = 1;
const QUEUE_DATA_SIZE: usize = 4;
// The size of the guest memory for the virtio-mem region
const MEM_SIZE: usize = 128 * 1024 * 1024;
// The start address of the virtio-mem region in the guest memory
const VIRTIO_MEM_REGION_ADDRESS: u64 = 0;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 64;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;
// Descriptor table size
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Available ring size
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Used ring size
const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64;
// Guest memory gap
const GUEST_MEM_GAP: u64 = 1 * 1024 * 1024;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = align!(MEM_SIZE as u64 + GUEST_MEM_GAP, DESC_TABLE_ALIGN_SIZE);
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = align!(DESC_TABLE_ADDR + DESC_TABLE_SIZE, AVAIL_RING_ALIGN_SIZE);
// Guest physical address for used ring
const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ALIGN_SIZE);
// Virtio-queue size in bytes
const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize;
fuzz_target!(|bytes| {
if bytes.len() < VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE
|| bytes.len() > (VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE)
{
return;
}
let virtio_mem_data = &bytes[..VIRTIO_MEM_DATA_SIZE];
let queue_data = &bytes[VIRTIO_MEM_DATA_SIZE..VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE];
let queue_bytes = &bytes[VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE
..VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE];
let mem_bytes = &bytes[VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE..];
// Create a virtio-mem device based on the input bytes;
let (mut virtio_mem, virtio_mem_region) =
create_dummy_virtio_mem(virtio_mem_data.try_into().unwrap());
// Setup the virt queue with the input bytes
let q = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[
(GuestAddress(DESC_TABLE_ADDR), QUEUE_BYTES_SIZE), // guest region for the virt queue
])
.unwrap();
if mem
.write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR))
.is_err()
{
return;
}
// Add the memory region for the virtio-mem device
let mem = mem.insert_region(virtio_mem_region).unwrap();
if mem
.write_slice(mem_bytes, GuestAddress(VIRTIO_MEM_REGION_ADDRESS))
.is_err()
{
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
// Kick the 'queue' event before activate the virtio-mem device
queue_evt.write(1).unwrap();
virtio_mem
.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)],
)
.ok();
// Wait for the events to finish and virtio-mem device worker thread to return
virtio_mem.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
// Create a dummy virtio-mem device for fuzzing purpose only
fn create_dummy_virtio_mem(bytes: &[u8; VIRTIO_MEM_DATA_SIZE]) -> (Mem, Arc<GuestRegionMmap>) {
let numa_id = if bytes[0] % 2 != 0 { Some(0) } else { None };
let region = vmm::memory_manager::MemoryManager::create_ram_region(
&None,
0,
GuestAddress(VIRTIO_MEM_REGION_ADDRESS),
MEM_SIZE,
false,
false,
false,
None,
numa_id,
None,
false,
)
.unwrap();
let blocks_state = Arc::new(Mutex::new(BlocksState::new(region.size() as u64)));
(
Mem::new(
"fuzzer_mem".to_owned(),
&region,
SeccompAction::Allow,
numa_id.map(|i| i as u16),
0,
false,
EventFd::new(EFD_NONBLOCK).unwrap(),
blocks_state.clone(),
None,
)
.unwrap(),
region,
)
}
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
q
}

151
fuzz/fuzz_targets/pmem.rs Normal file
View File

@@ -0,0 +1,151 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libc::{MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE};
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::ffi;
use std::fs::File;
use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Arc;
use virtio_devices::{Pmem, UserspaceMapping, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::guest_memory::FileOffset;
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic, MmapRegion};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 256 * 1024 * 1024;
const PMEM_FILE_SIZE: usize = 128 * 1024 * 1024;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = 0;
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = DESC_TABLE_ADDR + DESC_TABLE_SIZE;
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Guest physical address for used ring (requires to 4-bytes aligned)
const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64;
fuzz_target!(|bytes| {
if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) {
return;
}
let mut pmem = create_dummy_pmem();
let queue_data = &bytes[..QUEUE_DATA_SIZE];
let mem_bytes = &bytes[QUEUE_DATA_SIZE..];
// Setup the virt queue with the input bytes
let q = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
// Kick the 'queue' event before activate the pmem device
queue_evt.write(1).unwrap();
pmem.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)],
)
.ok();
// Wait for the events to finish and pmem device worker thread to return
pmem.wait_for_epoll_threads();
});
fn memfd_create_with_size(name: &ffi::CStr, flags: u32, size: usize) -> Result<RawFd, io::Error> {
let fd = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
if fd < 0 {
return Err(io::Error::last_os_error());
}
let res = unsafe { libc::syscall(libc::SYS_ftruncate, fd, size) };
if res < 0 {
return Err(io::Error::last_os_error());
}
Ok(fd as RawFd)
}
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
// Create a dummy virtio-pmem device for fuzzing purpose only
fn create_dummy_pmem() -> Pmem {
let shm =
memfd_create_with_size(&ffi::CString::new("fuzz").unwrap(), 0, PMEM_FILE_SIZE).unwrap();
let file: File = unsafe { File::from_raw_fd(shm) };
// The fuzzer is focusing on the virtio-pmem code that processes guest inputs (e.g. virt queues),
// so dummy mappings (both mmap and user mapping) does the job and is faster (using smaller amount of memory).
let dummy_mapping_size = 1;
let cloned_file = file.try_clone().unwrap();
let dummy_mmap_region = MmapRegion::build(
Some(FileOffset::new(cloned_file, 0)),
dummy_mapping_size,
PROT_READ | PROT_WRITE,
MAP_NORESERVE | MAP_PRIVATE,
)
.unwrap();
let guest_addr = GuestAddress(0);
let dummy_user_mapping = UserspaceMapping {
host_addr: dummy_mmap_region.as_ptr() as u64,
mem_slot: 0,
addr: guest_addr,
len: dummy_mapping_size as u64,
mergeable: false,
};
Pmem::new(
"tmp".to_owned(),
file,
guest_addr,
dummy_user_mapping,
dummy_mmap_region,
false,
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap()
}
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
q
}

135
fuzz/fuzz_targets/rng.rs Normal file
View File

@@ -0,0 +1,135 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::Arc;
use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
macro_rules! align {
($n:expr, $align:expr) => {{
(($n + $align - 1) / $align) * $align
}};
}
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 1 * 1024 * 1024;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Descriptor table alignment
const DESC_TABLE_ALIGN_SIZE: u64 = 16;
// Avalable ring alignment
const AVAIL_RING_ALIGN_SIZE: u64 = 2;
// Used ring alignment
const USED_RING_ALIGN_SIZE: u64 = 4;
// Descriptor table size
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Available ring size
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Used ring size
const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64;
// Guest memory gap
const GUEST_MEM_GAP: u64 = 1 * 1024 * 1024;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = align!(MEM_SIZE as u64 + GUEST_MEM_GAP, DESC_TABLE_ALIGN_SIZE);
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = align!(DESC_TABLE_ADDR + DESC_TABLE_SIZE, AVAIL_RING_ALIGN_SIZE);
// Guest physical address for used ring
const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ALIGN_SIZE);
// Virtio-queue size in bytes
const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize;
fuzz_target!(|bytes| {
if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE)
|| bytes.len() > (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE)
{
return;
}
let mut rng = virtio_devices::Rng::new(
"fuzzer_rng".to_owned(),
"/dev/urandom",
false,
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap();
let queue_data = &bytes[..QUEUE_DATA_SIZE];
let queue_bytes = &bytes[QUEUE_DATA_SIZE..QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE];
let mem_bytes = &bytes[QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE..];
// Setup the virt queue with the input bytes
let q = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[
(GuestAddress(0), MEM_SIZE),
(GuestAddress(DESC_TABLE_ADDR), QUEUE_BYTES_SIZE),
])
.unwrap();
if mem
.write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR))
.is_err()
{
return;
}
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
// Kick the 'queue' event before activate the rng device
queue_evt.write(1).unwrap();
rng.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)],
)
.ok();
// Wait for the events to finish and rng device worker thread to return
rng.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
q
}

View File

@@ -0,0 +1,100 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
#![no_main]
use libfuzzer_sys::fuzz_target;
use seccompiler::SeccompAction;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::Arc;
use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const QUEUE_DATA_SIZE: usize = 4;
const MEM_SIZE: usize = 256 * 1024 * 1024;
// Max entries in the queue.
const QUEUE_SIZE: u16 = 256;
// Guest physical address for descriptor table.
const DESC_TABLE_ADDR: u64 = 0;
const DESC_TABLE_SIZE: u64 = 16_u64 * QUEUE_SIZE as u64;
// Guest physical address for available ring
const AVAIL_RING_ADDR: u64 = DESC_TABLE_ADDR + DESC_TABLE_SIZE;
const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64;
// Guest physical address for used ring (requires to 4-bytes aligned)
const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64;
fuzz_target!(|bytes| {
if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) {
return;
}
let mut watchdog = virtio_devices::Watchdog::new(
"fuzzer_watchdog".to_owned(),
EventFd::new(EFD_NONBLOCK).unwrap(),
SeccompAction::Allow,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
)
.unwrap();
let queue_data = &bytes[..QUEUE_DATA_SIZE];
let mem_bytes = &bytes[QUEUE_DATA_SIZE..];
// Setup the virt queue with the input bytes
let q = setup_virt_queue(queue_data.try_into().unwrap());
// Setup the guest memory with the input bytes
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() {
return;
}
let guest_memory = GuestMemoryAtomic::new(mem);
let evt = EventFd::new(0).unwrap();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
// Kick the 'queue' event before activate the watchdog device
queue_evt.write(1).unwrap();
watchdog
.activate(
guest_memory,
Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)],
)
.ok();
// Wait for the events to finish and watchdog device worker thread to return
watchdog.wait_for_epoll_threads();
});
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(&self, _int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
fn setup_virt_queue(bytes: &[u8; QUEUE_DATA_SIZE]) -> Queue {
let mut q = Queue::new(QUEUE_SIZE).unwrap();
q.set_next_avail(bytes[0] as u16); // 'u8' is enough given the 'QUEUE_SIZE' is small
q.set_next_used(bytes[1] as u16);
q.set_event_idx(bytes[2] % 2 != 0);
q.set_size(bytes[3] as u16 % QUEUE_SIZE);
q.try_set_desc_table_address(GuestAddress(DESC_TABLE_ADDR))
.unwrap();
q.try_set_avail_ring_address(GuestAddress(AVAIL_RING_ADDR))
.unwrap();
q.try_set_used_ring_address(GuestAddress(USED_RING_ADDR))
.unwrap();
q.set_ready(true);
q
}

View File

@@ -11,20 +11,20 @@ mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.66"
byteorder = "1.4.3"
thiserror = "1.0.32"
libc = "0.2.131"
thiserror = "1.0.37"
libc = "0.2.138"
log = "0.4.17"
kvm-ioctls = { version = "0.11.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0-tdx", features = ["with-serde", "fam-wrappers"], optional = true }
kvm-ioctls = { version = "0.12.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.143", features = ["rc", "derive"] }
serde_with = { version = "2.0.0", default-features = false, features = ["macros"] }
serde = { version = "1.0.150", features = ["rc", "derive"] }
serde_with = { version = "2.1.0", default-features = false, features = ["macros"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.10.0", features = ["with-serde"] }
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]
version = "1.17.0"
@@ -32,4 +32,4 @@ default-features = false
features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"]
[dev-dependencies]
env_logger = "0.9.0"
env_logger = "0.10.0"

View File

@@ -16,6 +16,18 @@ pub enum Error {
}
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub struct VgicConfig {
pub vcpu_count: u64,
pub dist_addr: u64,
pub dist_size: u64,
pub redists_addr: u64,
pub redists_size: u64,
pub msi_addr: u64,
pub msi_size: u64,
pub nr_irqs: u32,
}
/// Hypervisor agnostic interface for a virtualized GIC
pub trait Vgic: Send + Sync {
/// Returns the fdt compatibility property of the device

View File

@@ -24,10 +24,10 @@ impl<T: Debug> Display for Exception<T> {
self.vector,
self.ip,
self.error
.map(|e| format!(": error {:x}", e))
.map(|e| format!(": error {e:x}"))
.unwrap_or_else(|| "".to_owned()),
self.payload
.map(|payload| format!(": payload {:x}", payload))
.map(|payload| format!(": payload {payload:x}"))
.unwrap_or_else(|| "".to_owned())
)
}

View File

@@ -38,11 +38,7 @@ fn calc_rflags_cpazso(op0: u64, op1: u64, op_size: usize) -> u64 {
// AF cares about the lowest 4 bits (nibble). msb_shift is 3 in this case.
let af = ((cout >> 3) & 0x1) << AF_SHIFT;
let zf = if result & (!0u64 >> (63 - msb_shift)) == 0 {
1
} else {
0
} << ZF_SHIFT;
let zf = u64::from(result & (!0u64 >> (63 - msb_shift)) == 0) << ZF_SHIFT;
let sf = ((result >> msb_shift) & 0x1) << SF_SHIFT;

View File

@@ -56,7 +56,7 @@ fn get_op<T: CpuStateManager>(
OpKind::Immediate16 => insn.immediate16() as u64,
OpKind::Immediate32 => insn.immediate32() as u64,
OpKind::Immediate32to64 => insn.immediate32to64() as u64,
OpKind::Immediate64 => insn.immediate64() as u64,
OpKind::Immediate64 => insn.immediate64(),
k => return Err(PlatformError::InvalidOperand(anyhow!("{:?}", k))),
};

View File

@@ -19,7 +19,6 @@ use crate::kvm::{TdxExitDetails, TdxExitStatus};
use crate::CpuState;
use crate::MpState;
use thiserror::Error;
#[cfg(target_arch = "x86_64")]
use vm_memory::GuestAddress;
#[derive(Error, Debug)]
@@ -49,12 +48,12 @@ pub enum HypervisorCpuError {
///
/// Setting floating point registers error
///
#[error("Failed to set special register: {0}")]
#[error("Failed to set floating point registers: {0}")]
SetFloatingPointRegs(#[source] anyhow::Error),
///
/// Getting floating point register error
///
#[error("Failed to get special register: {0}")]
#[error("Failed to get floating points registers: {0}")]
GetFloatingPointRegs(#[source] anyhow::Error),
///
/// Setting Cpuid error
@@ -347,7 +346,6 @@ pub trait Vcpu: Send + Sync {
fn notify_guest_clock_paused(&self) -> Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets debug registers to set hardware breakpoints and/or enable single step.
///
@@ -408,7 +406,9 @@ pub trait Vcpu: Send + Sync {
/// Initialize TDX support on the vCPU
///
#[cfg(feature = "tdx")]
fn tdx_init(&self, hob_address: u64) -> Result<()>;
fn tdx_init(&self, _hob_address: u64) -> Result<()> {
unimplemented!()
}
///
/// Set the "immediate_exit" state
///
@@ -417,12 +417,16 @@ pub trait Vcpu: Send + Sync {
///
/// Returns the details about TDX exit reason
///
fn get_tdx_exit_details(&mut self) -> Result<TdxExitDetails>;
fn get_tdx_exit_details(&mut self) -> Result<TdxExitDetails> {
unimplemented!()
}
#[cfg(feature = "tdx")]
///
/// Set the status code for TDX exit
///
fn set_tdx_status(&mut self, status: TdxExitStatus);
fn set_tdx_status(&mut self, _status: TdxExitStatus) {
unimplemented!()
}
#[cfg(target_arch = "x86_64")]
///
/// Return the list of initial MSR entries for a VCPU

View File

@@ -117,12 +117,20 @@ pub trait Hypervisor: Send + Sync {
}
#[cfg(target_arch = "aarch64")]
///
/// Retrieve AArch64 host maximum IPA size supported by KVM.
/// Retrieve AArch64 host maximum IPA size supported by KVM
///
fn get_host_ipa_limit(&self) -> i32;
///
/// Retrieve TDX capabilities
///
#[cfg(feature = "tdx")]
fn tdx_capabilities(&self) -> Result<TdxCapabilities>;
fn tdx_capabilities(&self) -> Result<TdxCapabilities> {
unimplemented!()
}
///
/// Get the number of supported hardware breakpoints
///
fn get_guest_debug_hw_bps(&self) -> usize {
unimplemented!()
}
}

View File

@@ -4,7 +4,7 @@ mod dist_regs;
mod icc_regs;
mod redist_regs;
use crate::arch::aarch64::gic::{Error, Result, Vgic};
use crate::arch::aarch64::gic::{Error, Result, Vgic, VgicConfig};
use crate::device::HypervisorDeviceError;
use crate::kvm::{kvm_bindings, KvmVm};
use crate::{CpuState, Vm};
@@ -133,9 +133,7 @@ impl KvmGicV3Its {
/// Setup the device-specific attributes
fn init_device_attributes(&mut self, vm: &KvmVm, nr_irqs: u32) -> Result<()> {
// GicV3 part attributes
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor.
*/
/* Setting up the distributor attribute. */
Self::set_device_attribute(
&self.device,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -144,9 +142,7 @@ impl KvmGicV3Its {
0,
)?;
/* Setting up the redistributors' attribute.
We are calculating here the start of the redistributors address. We have one per CPU.
*/
/* Setting up the redistributors' attribute. */
Self::set_device_attribute(
&self.device,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -248,37 +244,26 @@ impl KvmGicV3Its {
/// Method to initialize the GIC device
#[allow(clippy::new_ret_no_self)]
pub fn new(
vm: &dyn Vm,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> Result<KvmGicV3Its> {
pub fn new(vm: &dyn Vm, config: VgicConfig) -> Result<KvmGicV3Its> {
// This is inside KVM module
let vm = vm.as_any().downcast_ref::<KvmVm>().expect("Wrong VM type?");
let vgic = Self::create_device(vm)?;
let redists_size: u64 = redist_size * vcpu_count;
let redists_addr: u64 = dist_addr - redists_size;
let msi_addr: u64 = redists_addr - msi_size;
let mut gic_device = KvmGicV3Its {
device: vgic,
its_device: None,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
dist_addr,
dist_size,
redists_addr,
redists_size,
msi_addr,
msi_size,
vcpu_count,
gicr_typers: vec![0; config.vcpu_count.try_into().unwrap()],
dist_addr: config.dist_addr,
dist_size: config.dist_size,
redists_addr: config.redists_addr,
redists_size: config.redists_size,
msi_addr: config.msi_addr,
msi_size: config.msi_size,
vcpu_count: config.vcpu_count,
};
gic_device.init_device_attributes(vm, nr_irqs)?;
gic_device.init_device_attributes(vm, config.nr_irqs)?;
Ok(gic_device)
}
@@ -500,23 +485,30 @@ mod tests {
use crate::aarch64::gic::{
get_dist_regs, get_icc_regs, get_redist_regs, set_dist_regs, set_icc_regs, set_redist_regs,
};
use crate::arch::aarch64::gic::VgicConfig;
use crate::kvm::KvmGicV3Its;
fn create_test_vgic_config() -> VgicConfig {
VgicConfig {
vcpu_count: 1,
dist_addr: 0x0900_0000 - 0x01_0000,
dist_size: 0x01_0000,
// dist_addr - redists_size
redists_addr: 0x0900_0000 - 0x01_0000 - 0x02_0000,
redists_size: 0x02_0000,
// redists_addr - msi_size
msi_addr: 0x0900_0000 - 0x01_0000 - 0x02_0000 - 0x02_0000,
msi_size: 0x02_0000,
nr_irqs: 256,
}
}
#[test]
fn test_create_gic() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
assert!(KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256
)
.is_ok());
assert!(KvmGicV3Its::new(&*vm, create_test_vgic_config()).is_ok());
}
#[test]
@@ -524,16 +516,7 @@ mod tests {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
let res = get_dist_regs(&gic.device);
assert!(res.is_ok());
@@ -549,16 +532,7 @@ mod tests {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
let gicr_typer = vec![123];
let res = get_redist_regs(&gic.device, &gicr_typer);
@@ -575,16 +549,7 @@ mod tests {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic");
let gicr_typer = vec![123];
let res = get_icc_regs(&gic.device, &gicr_typer);
@@ -602,14 +567,7 @@ mod tests {
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = vm
.create_vgic(
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.create_vgic(create_test_vgic_config())
.expect("Cannot create gic");
assert!(gic.lock().unwrap().save_data_tables().is_ok());

View File

@@ -200,13 +200,7 @@ pub fn construct_gicr_typers(vcpu_states: &[CpuState]) -> Vec<u64> {
let mut gicr_typers: Vec<u64> = Vec::new();
for (index, state) in vcpu_states.iter().enumerate() {
let state: VcpuKvmState = state.clone().into();
let last = {
if index == vcpu_states.len() - 1 {
1
} else {
0
}
};
let last = (index == vcpu_states.len() - 1) as u64;
// state.sys_regs is a big collection of system registers, including MIPDR_EL1
let mpidr: Vec<Register> = state
.sys_regs

View File

@@ -97,8 +97,7 @@ pub fn is_system_register(regid: u64) -> bool {
assert!(
!(size != KVM_REG_SIZE_U32 && size != KVM_REG_SIZE_U64),
"Unexpected register size for system register {}",
size
"Unexpected register size for system register {size}"
);
true

View File

@@ -16,7 +16,7 @@ pub use crate::aarch64::{
VcpuKvmState,
};
#[cfg(target_arch = "aarch64")]
use crate::arch::aarch64::gic::Vgic;
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
use crate::cpu;
use crate::hypervisor;
use crate::vec_with_array_field;
@@ -60,8 +60,8 @@ use crate::{
use aarch64::{RegList, Register, StandardRegisters};
#[cfg(target_arch = "x86_64")]
use kvm_bindings::{
kvm_enable_cap, kvm_guest_debug, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC,
KVM_CAP_SPLIT_IRQCHIP, KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_GUESTDBG_USE_HW_BP,
kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP,
KVM_GUESTDBG_USE_HW_BP,
};
#[cfg(target_arch = "x86_64")]
use x86_64::check_required_kvm_extensions;
@@ -74,16 +74,17 @@ pub use kvm_bindings;
#[cfg(feature = "tdx")]
use kvm_bindings::KVMIO;
pub use kvm_bindings::{
kvm_clock_data, kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO, kvm_irq_routing,
kvm_irq_routing_entry, kvm_mp_state, kvm_userspace_memory_region, KVM_IRQ_ROUTING_IRQCHIP,
KVM_IRQ_ROUTING_MSI, KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_READONLY, KVM_MSI_VALID_DEVID,
kvm_clock_data, kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO, kvm_guest_debug,
kvm_irq_routing, kvm_irq_routing_entry, kvm_mp_state, kvm_userspace_memory_region,
KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_READONLY, KVM_MSI_VALID_DEVID,
};
#[cfg(target_arch = "aarch64")]
use kvm_bindings::{
kvm_regs, user_fpsimd_state, user_pt_regs, KVM_NR_SPSR, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG,
KVM_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_OP0_MASK,
KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM_CORE,
KVM_REG_SIZE_U128, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
kvm_regs, user_fpsimd_state, user_pt_regs, KVM_GUESTDBG_USE_HW, KVM_NR_SPSR, KVM_REG_ARM64,
KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK,
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK,
KVM_REG_ARM_CORE, KVM_REG_SIZE_U128, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
};
pub use kvm_ioctls;
pub use kvm_ioctls::{Cap, Kvm};
@@ -413,25 +414,9 @@ impl vm::Vm for KvmVm {
///
/// Creates a virtual GIC device.
///
fn create_vgic(
&self,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> vm::Result<Arc<Mutex<dyn Vgic>>> {
let gic_device = KvmGicV3Its::new(
self,
vcpu_count,
dist_addr,
dist_size,
redist_size,
msi_size,
nr_irqs,
)
.map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?;
fn create_vgic(&self, config: VgicConfig) -> vm::Result<Arc<Mutex<dyn Vgic>>> {
let gic_device = KvmGicV3Its::new(self, config)
.map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?;
Ok(Arc::new(Mutex::new(gic_device)))
}
///
@@ -837,7 +822,7 @@ impl vm::Vm for KvmVm {
tdx_command(
&self.fd.as_raw_fd(),
TdxCommand::InitMemRegion,
if measure { 1 } else { 0 },
u32::from(measure),
&data as *const _ as u64,
)
.map_err(vm::HypervisorVmError::InitMemRegionTdx)
@@ -1075,6 +1060,20 @@ impl hypervisor::Hypervisor for KvmHypervisor {
Ok(data)
}
///
/// Get the number of supported hardware breakpoints
///
fn get_guest_debug_hw_bps(&self) -> usize {
#[cfg(target_arch = "x86_64")]
{
4
}
#[cfg(target_arch = "aarch64")]
{
self.kvm.get_guest_debug_hw_bps() as usize
}
}
}
/// Vcpu struct for KVM
pub struct KvmVcpu {
@@ -1124,7 +1123,9 @@ impl cpu::Vcpu for KvmVcpu {
state.regs.regs[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
off += std::mem::size_of::<u64>();
}
@@ -1134,28 +1135,36 @@ impl cpu::Vcpu for KvmVcpu {
state.regs.sp = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
// Second one, the program counter.
let off = offset__of!(user_pt_regs, pc);
state.regs.pc = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
// Next is the processor state.
let off = offset__of!(user_pt_regs, pstate);
state.regs.pstate = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
// The stack pointer associated with EL1
let off = offset__of!(kvm_regs, sp_el1);
state.sp_el1 = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
// Exception Link Register for EL1, when taking an exception to EL1, this register
// holds the address to which to return afterwards.
@@ -1163,7 +1172,9 @@ impl cpu::Vcpu for KvmVcpu {
state.elr_el1 = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
// Saved Program Status Registers, there are 5 of them used in the kernel.
let mut off = offset__of!(kvm_regs, spsr);
@@ -1171,7 +1182,9 @@ impl cpu::Vcpu for KvmVcpu {
state.spsr[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
off += std::mem::size_of::<u64>();
}
@@ -1182,8 +1195,7 @@ impl cpu::Vcpu for KvmVcpu {
state.fp_regs.vregs[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U128, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.into();
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
off += mem::size_of::<u128>();
}
@@ -1193,7 +1205,8 @@ impl cpu::Vcpu for KvmVcpu {
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
as u32;
.try_into()
.unwrap();
// Floating-point Control Register
let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpcr);
@@ -1201,7 +1214,8 @@ impl cpu::Vcpu for KvmVcpu {
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
as u32;
.try_into()
.unwrap();
Ok(state)
}
#[cfg(target_arch = "x86_64")]
@@ -1229,7 +1243,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.regs[i],
state.regs.regs[i].into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += std::mem::size_of::<u64>();
@@ -1237,33 +1251,51 @@ impl cpu::Vcpu for KvmVcpu {
let off = offset__of!(user_pt_regs, sp);
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.regs.sp)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.sp.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
let off = offset__of!(user_pt_regs, pc);
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.regs.pc)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.pc.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
let off = offset__of!(user_pt_regs, pstate);
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.regs.pstate)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.pstate.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
let off = offset__of!(kvm_regs, sp_el1);
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.sp_el1)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.sp_el1.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
let off = offset__of!(kvm_regs, elr_el1);
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.elr_el1)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.elr_el1.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
let mut off = offset__of!(kvm_regs, spsr);
for i in 0..KVM_NR_SPSR as usize {
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), state.spsr[i])
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.spsr[i].into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += std::mem::size_of::<u64>();
}
@@ -1273,7 +1305,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U128, off),
state.fp_regs.vregs[i] as u64,
state.fp_regs.vregs[i],
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += mem::size_of::<u128>();
@@ -1283,7 +1315,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
state.fp_regs.fpsr as u64,
state.fp_regs.fpsr.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1291,7 +1323,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
state.fp_regs.fpcr as u64,
state.fp_regs.fpcr.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
Ok(())
@@ -1582,7 +1614,6 @@ impl cpu::Vcpu for KvmVcpu {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets debug registers to set hardware breakpoints and/or enable single step.
///
@@ -1591,32 +1622,47 @@ impl cpu::Vcpu for KvmVcpu {
addrs: &[vm_memory::GuestAddress],
singlestep: bool,
) -> cpu::Result<()> {
if addrs.len() > 4 {
return Err(cpu::HypervisorCpuError::SetDebugRegs(anyhow!(
"Support 4 breakpoints at most but {} addresses are passed",
addrs.len()
)));
}
let mut dbg = kvm_guest_debug {
#[cfg(target_arch = "x86_64")]
control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP,
#[cfg(target_arch = "aarch64")]
control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW,
..Default::default()
};
if singlestep {
dbg.control |= KVM_GUESTDBG_SINGLESTEP;
}
// Set bits 9 and 10.
// bit 9: GE (global exact breakpoint enable) flag.
// bit 10: always 1.
dbg.arch.debugreg[7] = 0x0600;
// Set the debug registers.
// Here we assume that the number of addresses do not exceed what
// `Hypervisor::get_guest_debug_hw_bps()` specifies.
#[cfg(target_arch = "x86_64")]
{
// Set bits 9 and 10.
// bit 9: GE (global exact breakpoint enable) flag.
// bit 10: always 1.
dbg.arch.debugreg[7] = 0x0600;
for (i, addr) in addrs.iter().enumerate() {
dbg.arch.debugreg[i] = addr.0;
// Set global breakpoint enable flag
dbg.arch.debugreg[7] |= 2 << (i * 2);
for (i, addr) in addrs.iter().enumerate() {
dbg.arch.debugreg[i] = addr.0;
// Set global breakpoint enable flag
dbg.arch.debugreg[7] |= 2 << (i * 2);
}
}
#[cfg(target_arch = "aarch64")]
{
for (i, addr) in addrs.iter().enumerate() {
// DBGBCR_EL1 (Debug Breakpoint Control Registers, D13.3.2):
// bit 0: 1 (Enabled)
// bit 1~2: 0b11 (PMC = EL1/EL0)
// bit 5~8: 0b1111 (BAS = AArch64)
// others: 0
dbg.arch.dbg_bcr[i] = 0b1u64 | 0b110u64 | 0b1_1110_0000u64;
// DBGBVR_EL1 (Debug Breakpoint Value Registers, D13.3.3):
// bit 2~52: VA[2:52]
dbg.arch.dbg_bvr[i] = (!0u64 >> 11) & addr.0;
}
}
self.fd
.set_guest_debug(&dbg)
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))
@@ -1663,9 +1709,12 @@ impl cpu::Vcpu for KvmVcpu {
| KVM_REG_ARM64_SYSREG_CRN_MASK
| KVM_REG_ARM64_SYSREG_CRM_MASK
| KVM_REG_ARM64_SYSREG_OP2_MASK)) as u64);
self.fd
Ok(self
.fd
.get_one_reg(id)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?
.try_into()
.unwrap())
}
///
/// Configure core registers for a given CPU.
@@ -1691,7 +1740,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate),
PSTATE_FAULT_BITS_64,
PSTATE_FAULT_BITS_64.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1700,7 +1749,7 @@ impl cpu::Vcpu for KvmVcpu {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip as u64)
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip.into())
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
@@ -1709,7 +1758,10 @@ impl cpu::Vcpu for KvmVcpu {
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0), fdt_start)
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0),
fdt_start.into(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
}
Ok(())
@@ -1876,7 +1928,9 @@ impl cpu::Vcpu for KvmVcpu {
addr: self
.fd
.get_one_reg(*index)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?,
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?
.try_into()
.unwrap(),
});
}
@@ -1981,7 +2035,7 @@ impl cpu::Vcpu for KvmVcpu {
// Set system registers
for reg in &state.sys_regs {
self.fd
.set_one_reg(reg.id, reg.addr)
.set_one_reg(reg.id, reg.addr.into())
.map_err(|e| cpu::HypervisorCpuError::SetSysRegister(e.into()))?;
}

View File

@@ -61,7 +61,7 @@ pub use vm::{
Vm, VmOps,
};
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum HypervisorType {
Kvm,
Mshv,

View File

@@ -703,7 +703,6 @@ impl cpu::Vcpu for MshvVcpu {
msr!(msr_index::MSR_LSTAR),
msr!(msr_index::MSR_KERNEL_GS_BASE),
msr!(msr_index::MSR_SYSCALL_MASK),
msr!(msr_index::MSR_IA32_TSC),
msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB),
]
.to_vec()
@@ -1093,7 +1092,7 @@ impl vm::Vm for MshvVm {
flags,
guest_pfn: guest_phys_addr >> PAGE_SHIFT,
size: memory_size,
userspace_addr: userspace_addr as u64,
userspace_addr,
}
.into()
}

View File

@@ -11,7 +11,7 @@
#[cfg(target_arch = "aarch64")]
use crate::aarch64::VcpuInit;
#[cfg(target_arch = "aarch64")]
use crate::arch::aarch64::gic::Vgic;
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
#[cfg(feature = "tdx")]
use crate::arch::x86::CpuIdEntry;
use crate::cpu::Vcpu;
@@ -273,15 +273,7 @@ pub trait Vm: Send + Sync + Any {
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
fn create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>;
#[cfg(target_arch = "aarch64")]
fn create_vgic(
&self,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> Result<Arc<Mutex<dyn Vgic>>>;
fn create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>;
/// Registers an event to be signaled whenever a certain address is written to.
fn register_ioevent(
@@ -334,19 +326,25 @@ pub trait Vm: Send + Sync + Any {
fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>;
#[cfg(feature = "tdx")]
/// Initalize TDX on this VM
fn tdx_init(&self, cpuid: &[CpuIdEntry], max_vcpus: u32) -> Result<()>;
fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> {
unimplemented!()
}
#[cfg(feature = "tdx")]
/// Finalize the configuration of TDX on this VM
fn tdx_finalize(&self) -> Result<()>;
fn tdx_finalize(&self) -> Result<()> {
unimplemented!()
}
#[cfg(feature = "tdx")]
/// Initalize a TDX memory region for this VM
fn tdx_init_memory_region(
&self,
host_address: u64,
guest_address: u64,
size: u64,
measure: bool,
) -> Result<()>;
_host_address: u64,
_guest_address: u64,
_size: u64,
_measure: bool,
) -> Result<()> {
unimplemented!()
}
/// Downcast to the underlying hypervisor VM type
fn as_any(&self) -> &dyn Any;
}

View File

@@ -5,4 +5,4 @@ authors = ["The Chromium OS Authors"]
edition = "2021"
[dependencies]
vmm-sys-util = "0.10.0"
vmm-sys-util = "0.11.0"

View File

@@ -6,23 +6,23 @@ edition = "2021"
[dependencies]
epoll = "4.3.1"
getrandom = "0.2.7"
libc = "0.2.131"
getrandom = "0.2.8"
libc = "0.2.138"
log = "0.4.17"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.143"
thiserror = "1.0.32"
versionize = "0.1.6"
serde = "1.0.150"
thiserror = "1.0.37"
versionize = "0.1.9"
versionize_derive = "0.1.4"
virtio-bindings = "0.1.0"
virtio-queue = "0.5.0"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.7.0"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.10.0"
vmm-sys-util = "0.11.0"
[dev-dependencies]
once_cell = "1.13.1"
once_cell = "1.16.0"
pnet = "0.31.0"
pnet_datalink = "0.31.0"
serde_json = "1.0.83"
serde_json = "1.0.89"

View File

@@ -131,17 +131,19 @@ pub fn build_net_config_space(
config: &mut VirtioNetConfig,
mac: MacAddr,
num_queues: usize,
mtu: Option<u16>,
avail_features: &mut u64,
) {
config.mac.copy_from_slice(mac.get_bytes());
*avail_features |= 1 << VIRTIO_NET_F_MAC;
build_net_config_space_with_mq(config, num_queues, avail_features);
build_net_config_space_with_mq(config, num_queues, mtu, avail_features);
}
pub fn build_net_config_space_with_mq(
config: &mut VirtioNetConfig,
num_queues: usize,
mtu: Option<u16>,
avail_features: &mut u64,
) {
let num_queue_pairs = (num_queues / 2) as u16;
@@ -151,6 +153,9 @@ pub fn build_net_config_space_with_mq(
config.max_virtqueue_pairs = num_queue_pairs;
*avail_features |= 1 << VIRTIO_NET_F_MQ;
}
if let Some(mtu) = mtu {
config.mtu = mtu;
}
}
pub fn virtio_features_to_tap_offload(features: u64) -> c_uint {

View File

@@ -125,7 +125,7 @@ impl<'de> Deserialize<'de> for MacAddr {
{
let s = String::deserialize(deserializer)?;
MacAddr::parse_str(&s)
.map_err(|e| D::Error::custom(format!("The provided MAC address is invalid: {}", e)))
.map_err(|e| D::Error::custom(format!("The provided MAC address is invalid: {e}")))
}
}
@@ -161,7 +161,7 @@ mod tests {
let mac = MacAddr::parse_str("12:34:56:78:9a:BC").unwrap();
println!("parsed MAC address: {}", mac);
println!("parsed MAC address: {mac}");
let bytes = mac.get_bytes();
assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);

View File

@@ -12,9 +12,9 @@ use thiserror::Error;
pub enum Error {
#[error("Failed to convert an hexadecimal string into an integer: {0}")]
ConvertHexStringToInt(std::num::ParseIntError),
#[error("Error related to the multiqueue support (no support TAP side).")]
#[error("Error related to the multiqueue support (no support TAP side)")]
MultiQueueNoTapSupport,
#[error("Error related to the multiqueue support (no support device side).")]
#[error("Error related to the multiqueue support (no support device side)")]
MultiQueueNoDeviceSupport,
#[error("Failed to read the TAP flags from sysfs: {0}")]
ReadSysfsTunFlags(io::Error),
@@ -30,6 +30,8 @@ pub enum Error {
TapGetMac(TapError),
#[error("Setting vnet header size failed: {0}")]
TapSetVnetHdrSize(TapError),
#[error("Setting MTU failed: {0}")]
TapSetMtu(TapError),
#[error("Enabling tap interface failed: {0}")]
TapEnable(TapError),
}
@@ -39,7 +41,7 @@ type Result<T> = std::result::Result<T, Error>;
fn check_mq_support(if_name: &Option<&str>, queue_pairs: usize) -> Result<()> {
if let Some(tap_name) = if_name {
let mq = queue_pairs > 1;
let path = format!("/sys/class/net/{}/tun_flags", tap_name);
let path = format!("/sys/class/net/{tap_name}/tun_flags");
// interface does not exist, check is not required
if !Path::new(&path).exists() {
return Ok(());
@@ -63,6 +65,7 @@ pub fn open_tap(
ip_addr: Option<Ipv4Addr>,
netmask: Option<Ipv4Addr>,
host_mac: &mut Option<MacAddr>,
mtu: Option<u16>,
num_rx_q: usize,
flags: Option<i32>,
) -> Result<Vec<Tap>> {
@@ -95,6 +98,9 @@ pub fn open_tap(
} else {
*host_mac = Some(tap.get_mac_addr().map_err(Error::TapGetMac)?)
}
if let Some(mtu) = mtu {
tap.set_mtu(mtu as i32).map_err(Error::TapSetMtu)?;
}
tap.enable().map_err(Error::TapEnable)?;
tap.set_vnet_hdr_size(vnet_hdr_size)

View File

@@ -104,6 +104,10 @@ impl TxVirtio {
return Err(NetQueuePairError::WriteTap(e));
}
if (result as usize) < vnet_hdr_len() {
return Err(NetQueuePairError::InvalidVirtioNetHeader);
}
self.counter_bytes += Wrapping(result as u64 - vnet_hdr_len() as u64);
self.counter_frames += Wrapping(1);
@@ -185,7 +189,7 @@ impl RxVirtio {
.translate_gva(access_platform, desc.len() as usize),
10,
)
.unwrap();
.ok_or(NetQueuePairError::DescriptorInvalidHeader)?;
let mut next_desc = Some(desc);
let mut iovecs = Vec::new();
@@ -238,6 +242,10 @@ impl RxVirtio {
return Err(NetQueuePairError::ReadTap(e));
}
if (result as usize) < vnet_hdr_len() {
return Err(NetQueuePairError::InvalidVirtioNetHeader);
}
// Write num_buffers to guest memory. We simply write 1 as we
// never spread the frame over more than one descriptor chain.
desc_chain
@@ -288,7 +296,7 @@ pub struct NetCounters {
#[derive(Error, Debug)]
pub enum NetQueuePairError {
#[error("No memory configured.")]
#[error("No memory configured")]
NoMemoryConfigured,
#[error("Error registering listener: {0}")]
RegisterListener(io::Error),
@@ -302,9 +310,9 @@ pub enum NetQueuePairError {
GuestMemory(vm_memory::GuestMemoryError),
#[error("Returned an error while iterating through the queue: {0}")]
QueueIteratorFailed(virtio_queue::Error),
#[error("Descriptor chain is too short.")]
#[error("Descriptor chain is too short")]
DescriptorChainTooShort,
#[error("Descriptor chain does not contain valid descriptors.")]
#[error("Descriptor chain does not contain valid descriptors")]
DescriptorChainInvalid,
#[error("Failed to determine if queue needed notification: {0}")]
QueueNeedsNotification(virtio_queue::Error),
@@ -312,6 +320,10 @@ pub enum NetQueuePairError {
QueueEnableNotification(virtio_queue::Error),
#[error("Failed to add used index to the queue: {0}")]
QueueAddUsed(virtio_queue::Error),
#[error("Descriptor with invalid virtio-net header")]
DescriptorInvalidHeader,
#[error("Invalid virtio-net header")]
InvalidVirtioNetHeader,
}
pub struct NetQueuePair {

View File

@@ -26,13 +26,13 @@ pub enum Error {
ConfigureTap(IoError),
#[error("Unable to retrieve features: {0}")]
GetFeatures(IoError),
#[error("Missing multiqueue support in the kernel.")]
#[error("Missing multiqueue support in the kernel")]
MultiQueueKernelSupport,
#[error("ioctl failed: {0}")]
IoctlError(IoError),
#[error("Failed to create a socket: {0}")]
NetUtil(NetUtilError),
#[error("Invalid interface name.")]
#[error("Invalid interface name")]
InvalidIfname,
#[error("Error parsing MAC data: {0}")]
MacParsing(IoError),
@@ -297,6 +297,37 @@ impl Tap {
Ok(())
}
pub fn mtu(&self) -> Result<i32> {
let sock = create_unix_socket().map_err(Error::NetUtil)?;
let ifreq = self.get_ifreq();
// ioctl is safe. Called with a valid sock fd, and we check the return.
let ret = unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFMTU as c_ulong, &ifreq) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
let mtu = unsafe { ifreq.ifr_ifru.ifru_mtu };
Ok(mtu)
}
pub fn set_mtu(&self, mtu: i32) -> Result<()> {
let sock = create_unix_socket().map_err(Error::NetUtil)?;
let mut ifreq = self.get_ifreq();
ifreq.ifr_ifru.ifru_mtu = mtu;
// ioctl is safe. Called with a valid sock fd, and we check the return.
let ret = unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFMTU as c_ulong, &ifreq) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Set the offload flags for the tap interface.
pub fn set_offload(&self, flags: c_uint) -> Result<()> {
// ioctl is safe. Called with a valid tap fd, and we check the return.
@@ -555,7 +586,7 @@ mod tests {
let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let t = Tap::new(1).unwrap();
println!("created tap: {:?}", t);
println!("created tap: {t:?}");
}
#[test]

View File

@@ -28,10 +28,10 @@ pub enum OptionParserError {
impl fmt::Display for OptionParserError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OptionParserError::UnknownOption(s) => write!(f, "unknown option: {}", s),
OptionParserError::InvalidSyntax(s) => write!(f, "invalid syntax:{}", s),
OptionParserError::UnknownOption(s) => write!(f, "unknown option: {s}"),
OptionParserError::InvalidSyntax(s) => write!(f, "invalid syntax:{s}"),
OptionParserError::Conversion(field, value) => {
write!(f, "unable to convert {} for {}", value, field)
write!(f, "unable to convert {value} for {field}")
}
}
}

View File

@@ -10,23 +10,20 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.66"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main", features = ["fam-wrappers"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vfio_user = { path = "../vfio_user" }
vmm-sys-util = "0.10.0"
libc = "0.2.131"
vmm-sys-util = "0.11.0"
libc = "0.2.138"
log = "0.4.17"
serde = { version = "1.0.143", features = ["derive"] }
thiserror = "1.0.32"
versionize = "0.1.6"
serde = { version = "1.0.150", features = ["derive"] }
thiserror = "1.0.37"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = "0.8.0"
vm-migration = { path = "../vm-migration" }
[dependencies.vfio-bindings]
version = "0.3.1"
features = ["fam-wrappers"]
vm-memory = "0.10.0"
vm-migration = { path = "../vm-migration" }

View File

@@ -514,9 +514,9 @@ impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
match self {
BarAddressInvalid(a, s) => write!(f, "address {} size {} too big", a, s),
BarInUse(b) => write!(f, "bar {} already used", b),
BarInUse64(b) => write!(f, "64bit bar {} already used(requires two regs)", b),
BarAddressInvalid(a, s) => write!(f, "address {a} size {s} too big"),
BarInUse(b) => write!(f, "bar {b} already used"),
BarInUse64(b) => write!(f, "64bit bar {b} already used(requires two regs)"),
BarInvalid(b) => write!(f, "bar {} invalid, max {}", b, NUM_BAR_REGS - 1),
BarInvalid64(b) => write!(
f,
@@ -524,18 +524,18 @@ impl Display for Error {
b,
NUM_BAR_REGS - 1
),
BarSizeInvalid(s) => write!(f, "bar address {} not a power of two", s),
BarSizeInvalid(s) => write!(f, "bar address {s} not a power of two"),
CapabilityEmpty => write!(f, "empty capabilities are invalid"),
CapabilityLengthInvalid(l) => write!(f, "Invalid capability length {}", l),
CapabilitySpaceFull(s) => write!(f, "capability of size {} doesn't fit", s),
CapabilityLengthInvalid(l) => write!(f, "Invalid capability length {l}"),
CapabilitySpaceFull(s) => write!(f, "capability of size {s} doesn't fit"),
Decode32BarSize => write!(f, "failed to decode 32 bits BAR size"),
Decode64BarSize => write!(f, "failed to decode 64 bits BAR size"),
Encode32BarSize => write!(f, "failed to encode 32 bits BAR size"),
Encode64BarSize => write!(f, "failed to encode 64 bits BAR size"),
RomBarAddressInvalid(a, s) => write!(f, "address {} size {} too big", a, s),
RomBarInUse(b) => write!(f, "rom bar {} already used", b),
RomBarAddressInvalid(a, s) => write!(f, "address {a} size {s} too big"),
RomBarInUse(b) => write!(f, "rom bar {b} already used"),
RomBarInvalid(b) => write!(f, "rom bar {} invalid, max {}", b, NUM_BAR_REGS - 1),
RomBarSizeInvalid(s) => write!(f, "rom bar address {} not a power of two", s),
RomBarSizeInvalid(s) => write!(f, "rom bar address {s} not a power of two"),
}
}
}

View File

@@ -21,6 +21,8 @@ pub enum Error {
IoRegistrationFailed(u64, configuration::Error),
/// Expected resource not found.
MissingResource,
/// Invalid resource.
InvalidResource(Resource),
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -29,14 +31,15 @@ impl Display for Error {
use self::Error::*;
match self {
CapabilitiesSetup(e) => write!(f, "failed to add capability {}", e),
CapabilitiesSetup(e) => write!(f, "failed to add capability {e}"),
IoAllocationFailed(size) => {
write!(f, "failed to allocate space for an IO BAR, size={}", size)
write!(f, "failed to allocate space for an IO BAR, size={size}")
}
IoRegistrationFailed(addr, e) => {
write!(f, "failed to register an IO BAR, addr={} err={}", addr, e)
write!(f, "failed to register an IO BAR, addr={addr} err={e}")
}
MissingResource => write!(f, "failed to find expected resource"),
InvalidResource(r) => write!(f, "invalid resource {r:?}"),
}
}
}

View File

@@ -35,7 +35,7 @@ enum Error {
UpdateInterruptRoute(io::Error),
}
#[derive(Debug, Clone, Versionize)]
#[derive(Debug, Clone, Versionize, Eq, PartialEq)]
pub struct MsixTableEntry {
pub msg_addr_lo: u32,
pub msg_addr_hi: u32,
@@ -258,7 +258,7 @@ impl MsixConfig {
let modulo_offset = offset % MSIX_TABLE_ENTRIES_MODULO;
// Store the value of the entry before modification
let mut old_entry: Option<MsixTableEntry> = None;
let old_entry = self.table_entries[index].clone();
match data.len() {
4 => {
@@ -268,7 +268,6 @@ impl MsixConfig {
0x4 => self.table_entries[index].msg_addr_hi = value,
0x8 => self.table_entries[index].msg_data = value,
0xc => {
old_entry = Some(self.table_entries[index].clone());
self.table_entries[index].vector_ctl = value;
}
_ => error!("invalid offset"),
@@ -284,7 +283,6 @@ impl MsixConfig {
self.table_entries[index].msg_addr_hi = (value >> 32) as u32;
}
0x8 => {
old_entry = Some(self.table_entries[index].clone());
self.table_entries[index].msg_data = (value & 0xffff_ffffu64) as u32;
self.table_entries[index].vector_ctl = (value >> 32) as u32;
}
@@ -296,10 +294,18 @@ impl MsixConfig {
_ => error!("invalid data length"),
};
// Update interrupt routes
if self.enabled && !self.masked {
let table_entry = &self.table_entries[index];
let table_entry = &self.table_entries[index];
// Optimisation to avoid excessive updates
if &old_entry == table_entry {
return;
}
// Update interrupt routes
// Optimisation: only update routes if the entry is not masked;
// this is safe because if the entry is masked (starts masked as per spec)
// in the table then it won't be triggered. (See: #4273)
if self.enabled && !self.masked && !table_entry.masked() {
let config = MsiIrqSourceConfig {
high_addr: table_entry.msg_addr_hi,
low_addr: table_entry.msg_addr_lo,
@@ -323,15 +329,15 @@ impl MsixConfig {
// has been injected, the pending bit in the PBA needs to be cleared.
// All of this is valid only if MSI-X has not been masked for the whole
// device.
if let Some(old_entry) = old_entry {
// Check if bit has been flipped
if !self.masked()
&& old_entry.masked()
&& !self.table_entries[index].masked()
&& self.get_pba_bit(index as u16) == 1
{
self.inject_msix_and_clear_pba(index);
}
// Check if bit has been flipped
if !self.masked()
&& self.enabled()
&& old_entry.masked()
&& !table_entry.masked()
&& self.get_pba_bit(index as u16) == 1
{
self.inject_msix_and_clear_pba(index);
}
}

View File

@@ -413,7 +413,7 @@ impl VfioCommon {
resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new();
let mut bar_id = VFIO_PCI_BAR0_REGION_INDEX as u32;
let mut bar_id = VFIO_PCI_BAR0_REGION_INDEX;
// Going through all regular regions to compute the BAR size.
// We're not saving the BAR address to restore it, because we
@@ -526,7 +526,7 @@ impl VfioCommon {
}
// Invert and add 1 to to find size
region_size = (!combined_size + 1) as u64;
region_size = !combined_size + 1;
} else {
region_type = PciBarRegionType::Memory32BitRegion;
@@ -599,7 +599,7 @@ impl VfioCommon {
start: bar_addr,
length: region_size,
type_: region_type,
index: bar_id as u32,
index: bar_id,
user_memory_regions: Vec::new(),
});

View File

@@ -276,12 +276,7 @@ impl VfioUserPciDevice {
self.client
.lock()
.unwrap()
.dma_map(
offset,
region.start_addr().raw_value(),
region.len() as u64,
fd,
)
.dma_map(offset, region.start_addr().raw_value(), region.len(), fd)
.map_err(VfioUserPciDeviceError::DmaMap)
}
@@ -292,7 +287,7 @@ impl VfioUserPciDevice {
self.client
.lock()
.unwrap()
.dma_unmap(region.start_addr().raw_value(), region.len() as u64)
.dma_unmap(region.start_addr().raw_value(), region.len())
.map_err(VfioUserPciDeviceError::DmaUnmap)
}
}
@@ -622,13 +617,13 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioUserDmaMappi
.map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::Other,
format!("Error mapping region: {}", e),
format!("Error mapping region: {e}"),
)
})
} else {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Region not found for 0x{:x}", gpa),
format!("Region not found for 0x{gpa:x}"),
))
}
}
@@ -641,7 +636,7 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioUserDmaMappi
.map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::Other,
format!("Error unmapping region: {}", e),
format!("Error unmapping region: {e}"),
)
})
}

View File

@@ -6,13 +6,13 @@ edition = "2021"
build = "build.rs"
[dependencies]
clap = { version = "3.2.17", features = ["wrap_help","cargo"] }
clap = { version = "4.0.29", features = ["wrap_help","cargo"] }
dirs = "4.0.0"
serde = { version = "1.0.143", features = ["rc", "derive"] }
serde_json = "1.0.83"
serde = { version = "1.0.150", features = ["rc", "derive"] }
serde_json = "1.0.89"
test_infra = { path = "../test_infra" }
thiserror = "1.0.32"
thiserror = "1.0.37"
wait-timeout = "0.2.0"
[build-dependencies]
clap = { version = "3.2.17", features = ["cargo"] }
clap = { version = "4.0.29", features = ["cargo"] }

View File

@@ -10,7 +10,7 @@ use std::process::Command;
fn main() {
let mut git_human_readable = "v".to_owned() + crate_version!();
if let Ok(git_out) = Command::new("git").args(&["describe", "--dirty"]).output() {
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
git_human_readable = git_out_str;
@@ -22,5 +22,5 @@ fn main() {
// variable GIT_HUMAN_READABLE, so that it can be reused from the binary.
// Particularly, this is used from the main.rs to display the exact
// version information.
println!("cargo:rustc-env=GIT_HUMAN_READABLE={}", git_human_readable);
println!("cargo:rustc-env=GIT_HUMAN_READABLE={git_human_readable}");
}

View File

@@ -10,7 +10,7 @@ extern crate clap;
mod performance_tests;
use clap::{Arg, Command as ClapCommand};
use clap::{Arg, ArgAction, Command as ClapCommand};
use performance_tests::*;
use serde::{Deserialize, Serialize};
use std::{
@@ -20,6 +20,7 @@ use std::{
thread,
time::Duration,
};
use test_infra::FioOps;
use thiserror::Error;
#[derive(Error, Debug)]
@@ -51,7 +52,7 @@ pub struct MetricsReport {
impl Default for MetricsReport {
fn default() -> Self {
let mut git_human_readable = "".to_string();
if let Ok(git_out) = Command::new("git").args(&["describe", "--dirty"]).output() {
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output() {
if git_out.status.success() {
git_human_readable = String::from_utf8(git_out.stdout)
.unwrap()
@@ -66,7 +67,7 @@ impl Default for MetricsReport {
}
let mut git_revision = "".to_string();
if let Ok(git_out) = Command::new("git").args(&["rev-parse", "HEAD"]).output() {
if let Ok(git_out) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
if git_out.status.success() {
git_revision = String::from_utf8(git_out.stdout)
.unwrap()
@@ -82,7 +83,7 @@ impl Default for MetricsReport {
let mut git_commit_date = "".to_string();
if let Ok(git_out) = Command::new("git")
.args(&["show", "-s", "--format=%cd"])
.args(["show", "-s", "--format=%cd"])
.output()
{
if git_out.status.success() {
@@ -116,7 +117,7 @@ pub struct PerformanceTestOverrides {
impl fmt::Display for PerformanceTestOverrides {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(test_iterations) = self.test_iterations {
write!(f, "test_iterations = {}", test_iterations)?;
write!(f, "test_iterations = {test_iterations}")?;
}
Ok(())
@@ -140,19 +141,19 @@ impl fmt::Display for PerformanceTestControl {
self.test_timeout, self.test_iterations
);
if let Some(o) = self.num_queues {
output = format!("{}, num_queues = {}", output, o);
output = format!("{output}, num_queues = {o}");
}
if let Some(o) = self.queue_size {
output = format!("{}, queue_size = {}", output, o);
output = format!("{output}, queue_size = {o}");
}
if let Some(o) = self.net_rx {
output = format!("{}, net_rx = {}", output, o);
output = format!("{output}, net_rx = {o}");
}
if let Some(o) = &self.fio_ops {
output = format!("{}, fio_ops = {}", output, o);
output = format!("{output}, fio_ops = {o}");
}
write!(f, "{}", output)
write!(f, "{output}")
}
}
@@ -502,29 +503,28 @@ fn main() {
Arg::new("test-filter")
.long("test-filter")
.help("Filter metrics tests to run based on provided keywords")
.multiple_occurrences(true)
.takes_value(true)
.num_args(1)
.required(false),
)
.arg(
Arg::new("list-tests")
.long("list-tests")
.help("Print the list of availale metrics tests")
.multiple_occurrences(true)
.takes_value(false)
.num_args(0)
.action(ArgAction::SetTrue)
.required(false),
)
.arg(
Arg::new("report-file")
.long("report-file")
.help("Report file. Standard error is used if not specified")
.takes_value(true),
.num_args(1),
)
.arg(
Arg::new("iterations")
.long("iterations")
.help("Override number of test iterations")
.takes_value(true),
.num_args(1),
)
.get_matches();
@@ -536,7 +536,7 @@ fn main() {
.filter(|t| !(cfg!(target_arch = "aarch64") && t.name == "virtio_net_latency_us"))
.collect();
if cmd_arguments.is_present("list-tests") {
if cmd_arguments.get_flag("list-tests") {
for test in test_list.iter() {
println!("\"{}\" ({})", test.name, test.control);
}
@@ -544,7 +544,7 @@ fn main() {
return;
}
let test_filter = match cmd_arguments.values_of("test-filter") {
let test_filter = match cmd_arguments.get_many::<String>("test-filter") {
Some(s) => s.collect(),
None => Vec::new(),
};
@@ -556,7 +556,7 @@ fn main() {
let overrides = Arc::new(PerformanceTestOverrides {
test_iterations: cmd_arguments
.value_of("iterations")
.get_one::<String>("iterations")
.map(|s| s.parse())
.transpose()
.unwrap_or_default(),
@@ -569,7 +569,7 @@ fn main() {
metrics_report.results.push(r);
}
Err(e) => {
eprintln!("Aborting test due to error: '{:?}'", e);
eprintln!("Aborting test due to error: '{e:?}'");
std::process::exit(1);
}
};
@@ -579,11 +579,11 @@ fn main() {
cleanup_tests();
let mut report_file: Box<dyn std::io::Write + Send> =
if let Some(file) = cmd_arguments.value_of("report-file") {
if let Some(file) = cmd_arguments.get_one::<String>("report-file") {
Box::new(
std::fs::File::create(std::path::Path::new(file))
.map_err(|e| {
eprintln!("Error opening report file: {}: {}", file, e);
eprintln!("Error opening report file: {file}: {e}");
std::process::exit(1);
})
.unwrap(),
@@ -599,7 +599,7 @@ fn main() {
.as_bytes(),
)
.map_err(|e| {
eprintln!("Error writing report file: {}", e);
eprintln!("Error writing report file: {e}");
std::process::exit(1);
})
.unwrap();

View File

@@ -6,40 +6,23 @@
// Performance tests
use crate::{mean, PerformanceTestControl};
use serde_json::Value;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Stdio};
use std::fs;
use std::path::PathBuf;
use std::string::String;
use std::thread;
use std::time::Duration;
use std::{fmt, fs};
use test_infra::Error as InfraError;
use test_infra::*;
use wait_timeout::ChildExt;
#[cfg(target_arch = "x86_64")]
pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-amd64-custom-20210609-0.raw";
#[cfg(target_arch = "aarch64")]
pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-arm64-custom-20210929-0-update-tool.raw";
#[derive(Debug)]
enum WaitTimeoutError {
Timedout,
ExitStatus,
General(std::io::Error),
}
#[derive(Debug)]
enum Error {
BootTimeParse,
EthrLogFile(std::io::Error),
EthrLogParse,
FioOutputParse,
Iperf3Parse,
Infra(InfraError),
Spawn(std::io::Error),
Scp(SshCommandError),
WaitTimeout(WaitTimeoutError),
}
impl From<InfraError> for Error {
@@ -54,8 +37,7 @@ pub fn init_tests() {
// The test image can not be created on tmpfs (e.g. /tmp) filesystem,
// as tmpfs does not support O_DIRECT
assert!(exec_host_command_output(&format!(
"dd if=/dev/zero of={} bs=1M count=4096",
BLK_IO_TEST_IMG
"dd if=/dev/zero of={BLK_IO_TEST_IMG} bs=1M count=4096"
))
.status
.success());
@@ -63,7 +45,7 @@ pub fn init_tests() {
pub fn cleanup_tests() {
fs::remove_file(BLK_IO_TEST_IMG)
.unwrap_or_else(|_| panic!("Failed to remove file '{}'.", BLK_IO_TEST_IMG));
.unwrap_or_else(|_| panic!("Failed to remove file '{BLK_IO_TEST_IMG}'."));
}
// Performance tests are expected to be executed sequentially, so we can
@@ -94,128 +76,6 @@ fn direct_kernel_boot_path() -> PathBuf {
kernel_path
}
// Wait the child process for a given timeout
fn child_wait_timeout(child: &mut Child, timeout: u64) -> Result<(), WaitTimeoutError> {
match child.wait_timeout(Duration::from_secs(timeout)) {
Err(e) => {
return Err(WaitTimeoutError::General(e));
}
Ok(s) => match s {
None => {
return Err(WaitTimeoutError::Timedout);
}
Some(s) => {
if !s.success() {
return Err(WaitTimeoutError::ExitStatus);
}
}
},
}
Ok(())
}
fn parse_iperf3_output(output: &[u8], sender: bool) -> Result<f64, Error> {
std::panic::catch_unwind(|| {
let s = String::from_utf8_lossy(output);
let v: Value = serde_json::from_str(&s).expect("'iperf3' parse error: invalid json output");
let bps: f64 = if sender {
v["end"]["sum_sent"]["bits_per_second"]
.as_f64()
.expect("'iperf3' parse error: missing entry 'end.sum_sent.bits_per_second'")
} else {
v["end"]["sum_received"]["bits_per_second"]
.as_f64()
.expect("'iperf3' parse error: missing entry 'end.sum_received.bits_per_second'")
};
bps
})
.map_err(|_| {
eprintln!(
"=============== iperf3 output ===============\n\n{}\n\n===========end============\n\n",
String::from_utf8_lossy(output)
);
Error::Iperf3Parse
})
}
fn measure_virtio_net_throughput(
test_timeout: u32,
queue_pairs: u32,
guest: &Guest,
receive: bool,
) -> Result<f64, Error> {
let default_port = 5201;
// 1. start the iperf3 server on the guest
for n in 0..queue_pairs {
guest
.ssh_command(&format!("iperf3 -s -p {} -D", default_port + n))
.map_err(InfraError::SshCommand)?;
}
thread::sleep(Duration::new(1, 0));
// 2. start the iperf3 client on host to measure RX through-put
let mut clients = Vec::new();
for n in 0..queue_pairs {
let mut cmd = Command::new("iperf3");
cmd.args(&[
"-J", // Output in JSON format
"-c",
&guest.network.guest_ip,
"-p",
&format!("{}", default_port + n),
"-t",
&format!("{}", test_timeout),
]);
// For measuring the guest transmit throughput (as a sender),
// use reverse mode of the iperf3 client on the host
if !receive {
cmd.args(&["-R"]);
}
let client = cmd
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.map_err(Error::Spawn)?;
clients.push(client);
}
let mut err: Option<Error> = None;
let mut bps = Vec::new();
let mut failed = false;
for c in clients {
let mut c = c;
if let Err(e) = child_wait_timeout(&mut c, test_timeout as u64 + 5) {
err = Some(Error::WaitTimeout(e));
failed = true;
}
if !failed {
// Safe to unwrap as we know the child has terminated succesffully
let output = c.wait_with_output().unwrap();
bps.push(parse_iperf3_output(&output.stdout, receive)?);
} else {
let _ = c.kill();
let output = c.wait_with_output().unwrap();
println!(
"=============== Client output [Error] ===============\n\n{}\n\n===========end============\n\n",
String::from_utf8_lossy(&output.stdout)
);
}
}
if let Some(e) = err {
Err(e)
} else {
Ok(bps.iter().sum())
}
}
pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 {
let test_timeout = control.test_timeout;
let rx = control.net_rx.unwrap();
@@ -231,12 +91,12 @@ pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 {
);
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", &format!("boot={}", num_queues)])
.args(&["--memory", "size=4G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(["--cpus", &format!("boot={num_queues}")])
.args(["--memory", "size=4G"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.args(&["--net", net_params.as_str()])
.args(["--net", net_params.as_str()])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
@@ -260,95 +120,6 @@ pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 {
}
}
fn parse_ethr_latency_output(output: &[u8]) -> Result<Vec<f64>, Error> {
std::panic::catch_unwind(|| {
let s = String::from_utf8_lossy(output);
let mut latency = Vec::new();
for l in s.lines() {
let v: Value = serde_json::from_str(l).expect("'ethr' parse error: invalid json line");
// Skip header/summary lines
if let Some(avg) = v["Avg"].as_str() {
// Assume the latency unit is always "us"
latency.push(
avg.split("us").collect::<Vec<&str>>()[0]
.parse::<f64>()
.expect("'ethr' parse error: invalid 'Avg' entry"),
);
}
}
assert!(
!latency.is_empty(),
"'ethr' parse error: no valid latency data found"
);
latency
})
.map_err(|_| {
eprintln!(
"=============== ethr output ===============\n\n{}\n\n===========end============\n\n",
String::from_utf8_lossy(output)
);
Error::EthrLogParse
})
}
fn measure_virtio_net_latency(guest: &Guest, test_timeout: u32) -> Result<Vec<f64>, Error> {
// copy the 'ethr' tool to the guest image
let ethr_path = "/usr/local/bin/ethr";
let ethr_remote_path = "/tmp/ethr";
scp_to_guest(
Path::new(ethr_path),
Path::new(ethr_remote_path),
&guest.network.guest_ip,
//DEFAULT_SSH_RETRIES,
1,
DEFAULT_SSH_TIMEOUT,
)
.map_err(Error::Scp)?;
// Start the ethr server on the guest
guest
.ssh_command(&format!("{} -s &> /dev/null &", ethr_remote_path))
.map_err(InfraError::SshCommand)?;
thread::sleep(Duration::new(10, 0));
// Start the ethr client on the host
let log_file = guest
.tmp_dir
.as_path()
.join("ethr.client.log")
.to_str()
.unwrap()
.to_string();
let mut c = Command::new(ethr_path)
.args(&[
"-c",
&guest.network.guest_ip,
"-t",
"l",
"-o",
&log_file, // file output is JSON format
"-d",
&format!("{}s", test_timeout),
])
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.map_err(Error::Spawn)?;
if let Err(e) = child_wait_timeout(&mut c, test_timeout as u64 + 5).map_err(Error::WaitTimeout)
{
let _ = c.kill();
return Err(e);
}
// Parse the ethr latency test output
let content = fs::read(log_file).map_err(Error::EthrLogFile)?;
parse_ethr_latency_output(&content)
}
pub fn performance_net_latency(control: &PerformanceTestControl) -> f64 {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = performance_test_new_guest(Box::new(focal));
@@ -361,12 +132,12 @@ pub fn performance_net_latency(control: &PerformanceTestControl) -> f64 {
);
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", &format!("boot={}", num_queues)])
.args(&["--memory", "size=4G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(["--cpus", &format!("boot={num_queues}")])
.args(["--memory", "size=4G"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.args(&["--net", net_params.as_str()])
.args(["--net", net_params.as_str()])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
@@ -506,14 +277,14 @@ pub fn performance_boot_time(control: &PerformanceTestControl) -> f64 {
let mut cmd = GuestCommand::new(&guest);
let c = cmd
.args(&[
.args([
"--cpus",
&format!("boot={}", control.num_boot_vcpus.unwrap_or(1)),
])
.args(&["--memory", "size=1G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(&["--console", "off"])
.args(["--memory", "size=1G"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(["--console", "off"])
.default_disks();
measure_boot_time(c, control.test_timeout).unwrap()
@@ -533,15 +304,15 @@ pub fn performance_boot_time_pmem(control: &PerformanceTestControl) -> f64 {
let guest = performance_test_new_guest(Box::new(focal));
let mut cmd = GuestCommand::new(&guest);
let c = cmd
.args(&[
.args([
"--cpus",
&format!("boot={}", control.num_boot_vcpus.unwrap_or(1)),
])
.args(&["--memory", "size=1G,hugepages=on"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", "root=/dev/pmem0p1 console=ttyS0 quiet rw"])
.args(&["--console", "off"])
.args(&[
.args(["--memory", "size=1G,hugepages=on"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", "root=/dev/pmem0p1 console=ttyS0 quiet rw"])
.args(["--console", "off"])
.args([
"--pmem",
format!(
"file={}",
@@ -561,78 +332,6 @@ pub fn performance_boot_time_pmem(control: &PerformanceTestControl) -> f64 {
}
}
pub enum FioOps {
Read,
RandomRead,
Write,
RandomWrite,
}
impl fmt::Display for FioOps {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FioOps::Read => write!(f, "read"),
FioOps::RandomRead => write!(f, "randread"),
FioOps::Write => write!(f, "write"),
FioOps::RandomWrite => write!(f, "randwrite"),
}
}
}
fn parse_fio_output(output: &str, fio_ops: &FioOps, num_jobs: u32) -> Result<f64, Error> {
std::panic::catch_unwind(|| {
let v: Value =
serde_json::from_str(output).expect("'fio' parse error: invalid json output");
let jobs = v["jobs"]
.as_array()
.expect("'fio' parse error: missing entry 'jobs'");
assert_eq!(
jobs.len(),
num_jobs as usize,
"'fio' parse error: Unexpected number of 'fio' jobs."
);
let read = match fio_ops {
FioOps::Read | FioOps::RandomRead => true,
FioOps::Write | FioOps::RandomWrite => false,
};
let mut total_bps = 0_f64;
for j in jobs {
if read {
let bytes = j["read"]["io_bytes"]
.as_u64()
.expect("'fio' parse error: missing entry 'read.io_bytes'");
let runtime = j["read"]["runtime"]
.as_u64()
.expect("'fio' parse error: missing entry 'read.runtime'")
as f64
/ 1000_f64;
total_bps += bytes as f64 / runtime as f64;
} else {
let bytes = j["write"]["io_bytes"]
.as_u64()
.expect("'fio' parse error: missing entry 'write.io_bytes'");
let runtime = j["write"]["runtime"]
.as_u64()
.expect("'fio' parse error: missing entry 'write.runtime'")
as f64
/ 1000_f64;
total_bps += bytes as f64 / runtime as f64;
}
}
total_bps
})
.map_err(|_| {
eprintln!(
"=============== Fio output ===============\n\n{}\n\n===========end============\n\n",
output
);
Error::FioOutputParse
})
}
pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
let test_timeout = control.test_timeout;
let num_queues = control.num_queues.unwrap();
@@ -649,11 +348,11 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
.to_string();
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", &format!("boot={}", num_queues)])
.args(&["--memory", "size=4G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(&[
.args(["--cpus", &format!("boot={num_queues}")])
.args(["--memory", "size=4G"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args([
"--disk",
format!(
"path={}",
@@ -665,10 +364,10 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
guest.disk_config.disk(DiskType::CloudInit).unwrap()
)
.as_str(),
format!("path={}", BLK_IO_TEST_IMG).as_str(),
format!("path={BLK_IO_TEST_IMG}").as_str(),
])
.default_net()
.args(&["--api-socket", &api_socket])
.args(["--api-socket", &api_socket])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
@@ -681,8 +380,7 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
let fio_command = format!(
"sudo fio --filename=/dev/vdc --name=test --output-format=json \
--direct=1 --bs=4k --ioengine=io_uring --iodepth=64 \
--rw={} --runtime={} --numjobs={}",
fio_ops, test_timeout, num_queues
--rw={fio_ops} --runtime={test_timeout} --numjobs={num_queues}"
);
let output = guest
.ssh_command(&fio_command)

View File

@@ -10,7 +10,7 @@ path = "src/qcow.rs"
[dependencies]
byteorder = "1.4.3"
libc = "0.2.131"
libc = "0.2.138"
log = "0.4.17"
remain = "0.2.4"
vmm-sys-util = "0.10.0"
remain = "0.2.5"
vmm-sys-util = "0.11.0"

View File

@@ -80,45 +80,41 @@ impl Display for Error {
match self {
BackingFilesNotSupported => write!(f, "backing files not supported"),
CompressedBlocksNotSupported => write!(f, "compressed blocks not supported"),
EvictingCache(e) => write!(f, "failed to evict cache: {}", e),
FileTooBig(size) => write!(
f,
"file larger than max of {}: {}",
MAX_QCOW_FILE_SIZE, size
),
GettingFileSize(e) => write!(f, "failed to get file size: {}", e),
GettingRefcount(e) => write!(f, "failed to get refcount: {}", e),
EvictingCache(e) => write!(f, "failed to evict cache: {e}"),
FileTooBig(size) => write!(f, "file larger than max of {MAX_QCOW_FILE_SIZE}: {size}"),
GettingFileSize(e) => write!(f, "failed to get file size: {e}"),
GettingRefcount(e) => write!(f, "failed to get refcount: {e}"),
InvalidClusterIndex => write!(f, "invalid cluster index"),
InvalidClusterSize => write!(f, "invalid cluster size"),
InvalidIndex => write!(f, "invalid index"),
InvalidL1TableOffset => write!(f, "invalid L1 table offset"),
InvalidL1TableSize(size) => write!(f, "invalid L1 table size {}", size),
InvalidL1TableSize(size) => write!(f, "invalid L1 table size {size}"),
InvalidMagic => write!(f, "invalid magic"),
InvalidOffset(_) => write!(f, "invalid offset"),
InvalidRefcountTableOffset => write!(f, "invalid refcount table offset"),
InvalidRefcountTableSize(size) => write!(f, "invalid refcount table size: {}", size),
InvalidRefcountTableSize(size) => write!(f, "invalid refcount table size: {size}"),
NoFreeClusters => write!(f, "no free clusters"),
NoRefcountClusters => write!(f, "no refcount clusters"),
NotEnoughSpaceForRefcounts => write!(f, "not enough space for refcounts"),
OpeningFile(e) => write!(f, "failed to open file: {}", e),
ReadingData(e) => write!(f, "failed to read data: {}", e),
ReadingHeader(e) => write!(f, "failed to read header: {}", e),
ReadingPointers(e) => write!(f, "failed to read pointers: {}", e),
ReadingRefCountBlock(e) => write!(f, "failed to read ref count block: {}", e),
ReadingRefCounts(e) => write!(f, "failed to read ref counts: {}", e),
RebuildingRefCounts(e) => write!(f, "failed to rebuild ref counts: {}", e),
OpeningFile(e) => write!(f, "failed to open file: {e}"),
ReadingData(e) => write!(f, "failed to read data: {e}"),
ReadingHeader(e) => write!(f, "failed to read header: {e}"),
ReadingPointers(e) => write!(f, "failed to read pointers: {e}"),
ReadingRefCountBlock(e) => write!(f, "failed to read ref count block: {e}"),
ReadingRefCounts(e) => write!(f, "failed to read ref counts: {e}"),
RebuildingRefCounts(e) => write!(f, "failed to rebuild ref counts: {e}"),
RefcountTableOffEnd => write!(f, "refcount table offset past file end"),
RefcountTableTooLarge => write!(f, "too many clusters specified for refcount table"),
SeekingFile(e) => write!(f, "failed to seek file: {}", e),
SettingFileSize(e) => write!(f, "failed to set file size: {}", e),
SettingRefcountRefcount(e) => write!(f, "failed to set refcount refcount: {}", e),
SeekingFile(e) => write!(f, "failed to seek file: {e}"),
SettingFileSize(e) => write!(f, "failed to set file size: {e}"),
SettingRefcountRefcount(e) => write!(f, "failed to set refcount refcount: {e}"),
SizeTooSmallForNumberOfClusters => write!(f, "size too small for number of clusters"),
TooManyL1Entries(count) => write!(f, "l1 entry table too large: {}", count),
TooManyRefcounts(count) => write!(f, "ref count table too large: {}", count),
TooManyL1Entries(count) => write!(f, "l1 entry table too large: {count}"),
TooManyRefcounts(count) => write!(f, "ref count table too large: {count}"),
UnsupportedRefcountOrder => write!(f, "unsupported refcount order"),
UnsupportedVersion(v) => write!(f, "unsupported version: {}", v),
WritingData(e) => write!(f, "failed to write data: {}", e),
WritingHeader(e) => write!(f, "failed to write header: {}", e),
UnsupportedVersion(v) => write!(f, "unsupported version: {v}"),
WritingData(e) => write!(f, "failed to write data: {e}"),
WritingHeader(e) => write!(f, "failed to write header: {e}"),
}
}
}
@@ -190,7 +186,7 @@ pub struct QcowHeader {
impl QcowHeader {
/// Creates a QcowHeader from a reference to a file.
pub fn new(f: &mut RawFile) -> Result<QcowHeader> {
f.seek(SeekFrom::Start(0)).map_err(Error::ReadingHeader)?;
f.rewind().map_err(Error::ReadingHeader)?;
let magic = f.read_u32::<BigEndian>().map_err(Error::ReadingHeader)?;
if magic != QCOW_MAGIC {
return Err(Error::InvalidMagic);
@@ -255,10 +251,10 @@ impl QcowHeader {
let cluster_bits: u32 = DEFAULT_CLUSTER_BITS;
let cluster_size: u32 = 0x01 << cluster_bits;
// L2 blocks are always one cluster long. They contain cluster_size/sizeof(u64) addresses.
let l2_size: u32 = cluster_size / size_of::<u64>() as u32;
let entries_per_cluster: u32 = cluster_size / size_of::<u64>() as u32;
let num_clusters: u32 = div_round_up_u64(size, u64::from(cluster_size)) as u32;
let num_l2_clusters: u32 = div_round_up_u32(num_clusters, l2_size);
let l1_clusters: u32 = div_round_up_u32(num_l2_clusters, cluster_size);
let num_l2_clusters: u32 = div_round_up_u32(num_clusters, entries_per_cluster);
let l1_clusters: u32 = div_round_up_u32(num_l2_clusters, entries_per_cluster);
let header_clusters = div_round_up_u32(size_of::<QcowHeader>() as u32, cluster_size);
QcowHeader {
magic: QCOW_MAGIC,
@@ -473,10 +469,10 @@ impl QcowFile {
QcowFile::rebuild_refcounts(&mut raw_file, header)?;
}
let l2_size = cluster_size / size_of::<u64>() as u64;
let entries_per_cluster = cluster_size / size_of::<u64>() as u64;
let num_clusters = div_round_up_u64(header.size, cluster_size);
let num_l2_clusters = div_round_up_u64(num_clusters, l2_size);
let l1_clusters = div_round_up_u64(num_l2_clusters, cluster_size);
let num_l2_clusters = div_round_up_u64(num_clusters, entries_per_cluster);
let l1_clusters = div_round_up_u64(num_l2_clusters, entries_per_cluster);
let header_clusters = div_round_up_u64(size_of::<QcowHeader>() as u64, cluster_size);
if num_l2_clusters > MAX_RAM_POINTER_TABLE_SIZE {
return Err(Error::TooManyL1Entries(num_l2_clusters));
@@ -559,14 +555,14 @@ impl QcowFile {
/// Creates a new QcowFile at the given path.
pub fn new(mut file: RawFile, version: u32, virtual_size: u64) -> Result<QcowFile> {
let header = QcowHeader::create_for_size(version, virtual_size);
file.seek(SeekFrom::Start(0)).map_err(Error::SeekingFile)?;
file.rewind().map_err(Error::SeekingFile)?;
header.write_to(&mut file)?;
let mut qcow = Self::from(file)?;
// Set the refcount for each refcount table cluster.
let cluster_size = 0x01u64 << qcow.header.cluster_bits;
let refcount_table_base = qcow.header.refcount_table_offset as u64;
let refcount_table_base = qcow.header.refcount_table_offset;
let end_cluster_addr =
refcount_table_base + u64::from(qcow.header.refcount_table_clusters) * cluster_size;
@@ -705,7 +701,8 @@ impl QcowFile {
header: QcowHeader,
cluster_size: u64,
) -> Result<()> {
let l1_clusters = div_round_up_u64(u64::from(header.l1_size), cluster_size);
let entries_per_cluster = cluster_size / size_of::<u64>() as u64;
let l1_clusters = div_round_up_u64(u64::from(header.l1_size), entries_per_cluster);
let l1_table_offset = header.l1_table_offset;
for i in 0..l1_clusters {
add_ref(refcounts, cluster_size, l1_table_offset + i * cluster_size)?;
@@ -776,10 +773,8 @@ impl QcowFile {
refcounts: &mut [u16],
cluster_size: u64,
refblock_clusters: u64,
pointers_per_cluster: u64,
) -> Result<Vec<u64>> {
let refcount_table_entries = div_round_up_u64(refblock_clusters, pointers_per_cluster);
let mut ref_table = vec![0; refcount_table_entries as usize];
let mut ref_table = vec![0; refblock_clusters as usize];
let mut first_free_cluster: u64 = 0;
for refblock_addr in &mut ref_table {
loop {
@@ -811,10 +806,7 @@ impl QcowFile {
) -> Result<()> {
// Rewrite the header with lazy refcounts enabled while we are rebuilding the tables.
header.compatible_features |= COMPATIBLE_FEATURES_LAZY_REFCOUNTS;
raw_file
.file_mut()
.seek(SeekFrom::Start(0))
.map_err(Error::SeekingFile)?;
raw_file.file_mut().rewind().map_err(Error::SeekingFile)?;
header.write_to(raw_file.file_mut())?;
for (i, refblock_addr) in ref_table.iter().enumerate() {
@@ -849,10 +841,7 @@ impl QcowFile {
// Rewrite the header again, now with lazy refcounts disabled.
header.compatible_features &= !COMPATIBLE_FEATURES_LAZY_REFCOUNTS;
raw_file
.file_mut()
.seek(SeekFrom::Start(0))
.map_err(Error::SeekingFile)?;
raw_file.file_mut().rewind().map_err(Error::SeekingFile)?;
header.write_to(raw_file.file_mut())?;
Ok(())
@@ -872,7 +861,7 @@ impl QcowFile {
let pointers_per_cluster = cluster_size / size_of::<u64>() as u64;
let data_clusters = div_round_up_u64(header.size, cluster_size);
let l2_clusters = div_round_up_u64(data_clusters, pointers_per_cluster);
let l1_clusters = div_round_up_u64(l2_clusters, cluster_size);
let l1_clusters = div_round_up_u64(l2_clusters, pointers_per_cluster);
let header_clusters = div_round_up_u64(size_of::<QcowHeader>() as u64, cluster_size);
let max_clusters = data_clusters + l2_clusters + l1_clusters + header_clusters;
let mut max_valid_cluster_index = max_clusters;
@@ -906,12 +895,7 @@ impl QcowFile {
set_refcount_table_refcounts(&mut refcounts, header, cluster_size)?;
// Allocate clusters to store the new reference count blocks.
let ref_table = alloc_refblocks(
&mut refcounts,
cluster_size,
refblock_clusters,
pointers_per_cluster,
)?;
let ref_table = alloc_refblocks(&mut refcounts, cluster_size, refblock_clusters)?;
// Write updated reference counts and point the reftable at them.
write_refblocks(
@@ -962,7 +946,7 @@ impl QcowFile {
// Gets the offset of the given guest address in the host file. If L1, L2, or data clusters have
// yet to be allocated, return None.
fn file_offset_read(&mut self, address: u64) -> std::io::Result<Option<u64>> {
if address >= self.virtual_size() as u64 {
if address >= self.virtual_size() {
return Err(std::io::Error::from_raw_os_error(EINVAL));
}
@@ -1005,7 +989,7 @@ impl QcowFile {
// Gets the offset of the given guest address in the host file. If L1, L2, or data clusters need
// to be allocated, they will be.
fn file_offset_write(&mut self, address: u64) -> std::io::Result<u64> {
if address >= self.virtual_size() as u64 {
if address >= self.virtual_size() {
return Err(std::io::Error::from_raw_os_error(EINVAL));
}
@@ -1122,7 +1106,7 @@ impl QcowFile {
// Returns true if the cluster containing `address` is already allocated.
fn cluster_allocated(&mut self, address: u64) -> std::io::Result<bool> {
if address >= self.virtual_size() as u64 {
if address >= self.virtual_size() {
return Err(std::io::Error::from_raw_os_error(EINVAL));
}
@@ -1194,7 +1178,7 @@ impl QcowFile {
// Deallocate the storage for the cluster starting at `address`.
// Any future reads of this cluster will return all zeroes.
fn deallocate_cluster(&mut self, address: u64) -> std::io::Result<()> {
if address >= self.virtual_size() as u64 {
if address >= self.virtual_size() {
return Err(std::io::Error::from_raw_os_error(EINVAL));
}
@@ -1239,7 +1223,7 @@ impl QcowFile {
.map_err(|e| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("failed to get cluster refcount: {}", e),
format!("failed to get cluster refcount: {e}"),
)
})?;
if refcount == 0 {
@@ -1416,7 +1400,7 @@ impl Drop for QcowFile {
impl Read for QcowFile {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let address: u64 = self.current_offset as u64;
let address: u64 = self.current_offset;
let read_count: usize = self.limit_range_file(address, buf.len());
let mut nread: usize = 0;
@@ -1478,7 +1462,7 @@ impl Seek for QcowFile {
impl Write for QcowFile {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let address: u64 = self.current_offset as u64;
let address: u64 = self.current_offset;
let write_count: usize = self.limit_range_file(address, buf.len());
let mut nwritten: usize = 0;
@@ -1582,12 +1566,12 @@ fn offset_is_cluster_boundary(offset: u64, cluster_bits: u32) -> Result<()> {
// Ceiling of the division of `dividend`/`divisor`.
fn div_round_up_u64(dividend: u64, divisor: u64) -> u64 {
dividend / divisor + if dividend % divisor != 0 { 1 } else { 0 }
dividend / divisor + u64::from(dividend % divisor != 0)
}
// Ceiling of the division of `dividend`/`divisor`.
fn div_round_up_u32(dividend: u32, divisor: u32) -> u32 {
dividend / divisor + if dividend % divisor != 0 { 1 } else { 0 }
dividend / divisor + u32::from(dividend % divisor != 0)
}
fn convert_copy<R, W>(reader: &mut R, writer: &mut W, offset: u64, size: u64) -> Result<()>
@@ -1655,9 +1639,7 @@ where
R: Read + Seek + SeekHole,
{
let src_size = reader.seek(SeekFrom::End(0)).map_err(Error::SeekingFile)?;
reader
.seek(SeekFrom::Start(0))
.map_err(Error::SeekingFile)?;
reader.rewind().map_err(Error::SeekingFile)?;
// Ensure the destination file is empty before writing to it.
dst_file.set_len(0).map_err(Error::SettingFileSize)?;
@@ -1699,10 +1681,8 @@ pub fn convert(mut src_file: RawFile, dst_file: RawFile, dst_type: ImageType) ->
/// Detect the type of an image file by checking for a valid qcow2 header.
pub fn detect_image_type(file: &mut RawFile) -> Result<ImageType> {
let orig_seek = file
.seek(SeekFrom::Current(0))
.map_err(Error::SeekingFile)?;
file.seek(SeekFrom::Start(0)).map_err(Error::SeekingFile)?;
let orig_seek = file.stream_position().map_err(Error::SeekingFile)?;
file.rewind().map_err(Error::SeekingFile)?;
let magic = file.read_u32::<BigEndian>().map_err(Error::ReadingHeader)?;
let image_type = if magic == QCOW_MAGIC {
ImageType::Qcow2
@@ -1793,7 +1773,7 @@ mod tests {
let mut disk_file: RawFile = RawFile::new(TempFile::new().unwrap().into_file(), false);
disk_file.write_all(header).unwrap();
disk_file.set_len(0x1_0000_0000).unwrap();
disk_file.seek(SeekFrom::Start(0)).unwrap();
disk_file.rewind().unwrap();
testfn(disk_file); // File closed when the function exits.
}
@@ -1815,7 +1795,7 @@ mod tests {
header
.write_to(&mut disk_file)
.expect("Failed to write header to temporary file.");
disk_file.seek(SeekFrom::Start(0)).unwrap();
disk_file.rewind().unwrap();
QcowFile::from(disk_file).expect("Failed to create Qcow from default Header");
}
@@ -1826,7 +1806,7 @@ mod tests {
header
.write_to(&mut disk_file)
.expect("Failed to write header to temporary file.");
disk_file.seek(SeekFrom::Start(0)).unwrap();
disk_file.rewind().unwrap();
QcowFile::from(disk_file).expect("Failed to create Qcow from default Header");
}
@@ -1954,7 +1934,7 @@ mod tests {
q.write_all(b"test first bytes")
.expect("Failed to write test string.");
let mut buf = [0u8; 4];
q.seek(SeekFrom::Start(0)).expect("Failed to seek.");
q.rewind().expect("Failed to seek.");
q.read_exact(&mut buf).expect("Failed to read.");
assert_eq!(&buf, b"test");
});
@@ -2006,15 +1986,15 @@ mod tests {
let mut q = QcowFile::from(disk_file).unwrap();
// Write some test data.
let b = [0x55u8; CHUNK_SIZE];
q.seek(SeekFrom::Start(0)).expect("Failed to seek.");
q.rewind().expect("Failed to seek.");
q.write_all(&b).expect("Failed to write test string.");
// Overwrite the full cluster with zeroes.
q.seek(SeekFrom::Start(0)).expect("Failed to seek.");
q.rewind().expect("Failed to seek.");
let nwritten = q.write_zeroes(CHUNK_SIZE).expect("Failed to write zeroes.");
assert_eq!(nwritten, CHUNK_SIZE);
// Verify that the data was zeroed out.
let mut buf = [0u8; CHUNK_SIZE];
q.seek(SeekFrom::Start(0)).expect("Failed to seek.");
q.rewind().expect("Failed to seek.");
q.read_exact(&mut buf).expect("Failed to read.");
assert_eq!(buf[0], 0);
assert_eq!(buf[CHUNK_SIZE - 1], 0);
@@ -2456,7 +2436,7 @@ mod tests {
}
}
// Check that address 0 is still zeros.
qcow_file.seek(SeekFrom::Start(0)).expect("Failed to seek.");
qcow_file.rewind().expect("Failed to seek.");
let nread = qcow_file.read(&mut readback).expect("Failed to read.");
assert_eq!(nread, BLOCK_SIZE);
for read in readback.iter() {
@@ -2480,7 +2460,7 @@ mod tests {
}
fn seek_cur(file: &mut QcowFile) -> u64 {
file.seek(SeekFrom::Current(0)).unwrap()
file.stream_position().unwrap()
}
#[test]
@@ -2544,7 +2524,7 @@ mod tests {
assert_eq!(seek_cur(&mut file), 0xFFFF);
// seek_hole at or after the end of the file should return None
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x30000).unwrap(), None);
assert_eq!(seek_cur(&mut file), 0);
assert_eq!(file.seek_hole(0x30001).unwrap(), None);
@@ -2562,33 +2542,33 @@ mod tests {
assert_eq!(seek_cur(&mut file), 0xFFFF);
// seek_hole within data should return the next hole
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x10000).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x10001).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x1FFFF).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0xFFFF).unwrap(), Some(0xFFFF));
assert_eq!(seek_cur(&mut file), 0xFFFF);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x10000).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x1FFFF).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x20000).unwrap(), Some(0x20000));
assert_eq!(seek_cur(&mut file), 0x20000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x20001).unwrap(), Some(0x20001));
assert_eq!(seek_cur(&mut file), 0x20001);
// seek_hole at EOF should return None
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x30000).unwrap(), None);
assert_eq!(seek_cur(&mut file), 0);
@@ -2599,10 +2579,10 @@ mod tests {
// seek_hole within [0x20000, 0x30000) should now find the hole at EOF
assert_eq!(file.seek_hole(0x20000).unwrap(), Some(0x30000));
assert_eq!(seek_cur(&mut file), 0x30000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x20001).unwrap(), Some(0x30000));
assert_eq!(seek_cur(&mut file), 0x30000);
file.seek(SeekFrom::Start(0)).unwrap();
file.rewind().unwrap();
assert_eq!(file.seek_hole(0x30000).unwrap(), None);
assert_eq!(seek_cur(&mut file), 0);
});

View File

@@ -69,7 +69,7 @@ impl RawFile {
fn round_up(&self, offset: u64) -> u64 {
let align: u64 = self.alignment.try_into().unwrap();
((offset / (align + 1)) + 1) * align
((offset + align - 1) / align) * align
}
fn round_down(&self, offset: u64) -> u64 {

View File

@@ -31,16 +31,14 @@ impl Display for Error {
use self::Error::*;
match self {
EvictingRefCounts(e) => write!(
f,
"failed to write a refblock from the cache to disk: {}",
e
),
EvictingRefCounts(e) => {
write!(f, "failed to write a refblock from the cache to disk: {e}")
}
InvalidIndex => write!(f, "address requested is not within the range of the disk"),
NeedCluster(addr) => write!(f, "cluster with addr={} needs to be read", addr),
NeedCluster(addr) => write!(f, "cluster with addr={addr} needs to be read"),
NeedNewCluster => write!(f, "new cluster needs to be allocated for refcounts"),
ReadingRefCounts(e) => {
write!(f, "failed to read the file into the refcount cache: {}", e)
write!(f, "failed to read the file into the refcount cache: {e}")
}
}
}

View File

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

View File

@@ -888,7 +888,7 @@ pub(crate) mod tests {
fn test_rate_limiter_debug() {
let l = RateLimiter::new(1, 2, 3, 4, 5, 6).unwrap();
assert_eq!(
format!("{:?}", l),
format!("{l:?}"),
format!(
"RateLimiter {{ bandwidth: {:?}, ops: {:?} }}",
l.bandwidth(),

View File

@@ -1,35 +1,57 @@
- [v28.2](#v282)
- [v28.1](#v281)
- [v28.0](#v280)
- [Community Engagement (Reminder)](#community-engagement-reminder)
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
- [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)
- [Removals](#removals)
- [Contributors](#contributors)
- [v27.0](#v270)
- [Community Engagement](#community-engagement)
- [Prebuilt Packages](#prebuilt-packages)
- [Network Device MTU Exposed to Guest](#network-device-mtu-exposed-to-guest)
- [Boot Tracing](#boot-tracing)
- [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-1)
- [Deprecations](#deprecations)
- [Contributors](#contributors-1)
- [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)
- [Deprecations](#deprecations)
- [Removals](#removals)
- [Contributors](#contributors)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Deprecations](#deprecations-1)
- [Removals](#removals-1)
- [Contributors](#contributors-2)
- [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements)
- [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Removals](#removals-1)
- [Contributors](#contributors-1)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Removals](#removals-2)
- [Contributors](#contributors-3)
- [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-2)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations-1)
- [Deprecations](#deprecations-2)
- [New on the Website](#new-on-the-website)
- [Contributors](#contributors-2)
- [Contributors](#contributors-4)
- [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-3)
- [Deprecations](#deprecations-2)
- [Contributors](#contributors-3)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Deprecations](#deprecations-3)
- [Contributors](#contributors-5)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -40,13 +62,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-4)
- [Contributors](#contributors-4)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [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-5)
- [Contributors](#contributors-5)
- [Notable Bug fixes](#notable-bug-fixes-7)
- [Contributors](#contributors-7)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -55,8 +77,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [Notable bug fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-8)
- [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)
@@ -64,8 +86,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-7)
- [Contributors](#contributors-7)
- [Notable bug fixes](#notable-bug-fixes-9)
- [Contributors](#contributors-9)
- [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)
@@ -75,31 +97,31 @@
- [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-8)
- [Contributors](#contributors-8)
- [Notable bug fixes](#notable-bug-fixes-10)
- [Contributors](#contributors-10)
- [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-9)
- [Contributors](#contributors-9)
- [Notable bug fixes](#notable-bug-fixes-11)
- [Contributors](#contributors-11)
- [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-10)
- [Notable bug fixes](#notable-bug-fixes-12)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-10)
- [Contributors](#contributors-12)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
- [Support for runtime control of `virtio-net` guest offload](#support-for-runtime-control-of-virtio-net-guest-offload)
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-3)
- [Contributors](#contributors-11)
- [Deprecations](#deprecations-4)
- [Contributors](#contributors-13)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -108,8 +130,8 @@
- [Updated hotplug documentation](#updated-hotplug-documentation)
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
- [Block device rate limiting](#block-device-rate-limiting)
- [Deprecations](#deprecations-4)
- [Contributors](#contributors-12)
- [Deprecations](#deprecations-5)
- [Contributors](#contributors-14)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -117,13 +139,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-13)
- [Contributors](#contributors-15)
- [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-14)
- [Contributors](#contributors-16)
- [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)
@@ -135,15 +157,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-11)
- [Contributors](#contributors-15)
- [Notable Bug Fixes](#notable-bug-fixes-13)
- [Contributors](#contributors-17)
- [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-12)
- [Contributors](#contributors-16)
- [Notable Bug Fixes](#notable-bug-fixes-14)
- [Contributors](#contributors-18)
- [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)
@@ -156,17 +178,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-13)
- [Contributors](#contributors-17)
- [Notable Bug Fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-19)
- [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-14)
- [Notable Bug Fixes](#notable-bug-fixes-16)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-18)
- [Contributors](#contributors-20)
- [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)
@@ -176,14 +198,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-19)
- [Contributors](#contributors-21)
- [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-20)
- [Contributors](#contributors-22)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -191,7 +213,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-21)
- [Contributors](#contributors-23)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -200,7 +222,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-22)
- [Contributors](#contributors-24)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -227,6 +249,190 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v28.2
This is a bug fix release. The following issues have been addressed:
* Fix QCOW2 refcount table size (#5034)
* Fix unpause support on MSHV in dual binary (#5037)
* Threads inside `virtio` devices are now shutdown on reboot (#5095)
# v28.1
This is a bug fix release. The following issues have been addressed:
* Update dependencies including a version of `linux-loader` that
addresses an infinite loop issue ([details](https://github.com/rust-vmm/linux-loader/security/advisories/GHSA-52h2-m2cf-9jh6))
* Fix bugs related to `virtio-net` including an integer overflow issue
(#4924, #4949)
* Use host `cpuid` information for L2 cache for older KVM on x86 (#4920)
* Improve README and documentation
# v28.0
This release has been tracked in our new [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v28.0.
### Community Engagement (Reminder)
Just a reminder that we have a new mailing list to support broader community
discussions. Please consider
[subscribing](https://lists.cloudhypervisor.org/g/dev/). We plan to use
this to announce a regular meeting for those interested in talking about Cloud
Hypervisor development.
### Long Term Support (LTS) Release
This is the first version of Cloud Hypervisor to be released under the LTS
release process. Point releases for bug fixes will be made for the next 18
months; live migration and live upgrade will be supported between the point
releases of the LTS.
### Virtualised TPM Support
Support for adding an emulated CRB TPM has been added. This has it's own [TPM
documentation](docs/tpm.md).
### Transparent Huge Page Support
By default, but controllable through `--memory thp=off` if it possible to back
the guest memory with Transparent Huge Pages (no file backing/`shared=off`)
then this will be used resulting in improved boot performance.
### README Quick Start Improved
The README has been refreshed with the quick start guide updated to reflect the
different firmware options and to recommend the use of pre-built binaries.
### Notable Bug Fixes
* Inappropriate Copy-on-Write of pinned pages (e.g. VFIO) leading to higher
memory consumption (#4835)
* Multiple `virtio` device bug fixes found through fuzzing (#4859, #4799)
* Large QCOW files (> 4TiB) are now supported (#4767)
* Support for > 31 vCPUS on aarch64 (#4863)
* Multiple fixes to OpenAPI specification file (#4720, #4811)
* Programming of the MSI-X table has been optimised leading to faster boot on
newer Linux kernels (#4744)
* Error on reboot from race to close TAP devices (#4871)
* Non-spec compliant virtio-block read-only support (#4888)
### Removals
The following functionality has been removed:
* Support for non-PVH firmware booting has been removed (#4511)
* I/O ports used for older versions of firmware have been removed (#3926)
* Deprecated API options for kernel/cmdline/initramfs have been removed (#4737)
### Contributors
Many thanks to everyone who has contributed to our release:
* Anatol Belski <anbelski@linux.microsoft.com>
* Bo Chen <chen.bo@intel.com>
* Fabiano Fidêncio <fabiano.fidencio@intel.com>
* Jianyong Wu <jianyong.wu@arm.com>
* Jinank Jain <jinankjain@microsoft.com>
* Jinrong Liang <cloudliang@tencent.com>
* lv.mengzhao <lv.mengzhao@zte.com.cn>
* Michael Zhao <michael.zhao@arm.com>
* Muminul Islam <muislam@microsoft.com>
* Praveen K Paladugu <prapal@linux.microsoft.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Wei Liu <liuwe@microsoft.com>
# v27.0
This release has been tracked in our new [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v27.0.
### Community Engagement
A new mailing list has been created to support broader community discussions.
Please consider [subscribing](https://lists.cloudhypervisor.org/g/dev/); an
announcement of a regular meeting will be announced via this list shortly.
### Prebuilt Packages
Prebuilt packages are now available. Please see [this
document](https://github.com/cloud-hypervisor/obs-packaging/blob/main/README.md)
on how to install. These packages also include packages for the different
firmware options available.
### Network Device MTU Exposed to Guest
The MTU for the TAP device associated with a `virtio-net` device is now exposed
to the guest. If the user provides a MTU with `--net mtu=..` then that MTU is
applied to created TAP interfaces. This functionality is also exposed for
`vhost-user-net` devices including those created with the reference backend
(#4658, #4676.)
### Boot Tracing
Support for generating a trace report for the boot time has been added
including a script for generating an SVG from that trace (#4659.)
### Simplified Build Feature Flags
The set of feature flags, for e.g. experimental features, have been simplified:
* `msvh` and `kvm` features provide support for those specific hypervisors
(with `kvm` enabled by default),
* `tdx` provides support for Intel TDX; and although there is no MSHV support
now it is now possible to compile with the `mshv` feature (#4696,)
* `tracing` adds support for boot tracing,
* `guest_debug` now covers both support for gdbing a guest (formerly `gdb`
feature) and dumping guest memory.
The following feature flags were removed as the functionality was enabled by
default: `amx`, `fwdebug`, `cmos` and `common` (#4679, #4632.)
### Asynchronous Kernel Loading
AArch64 has gained support for loading the guest kernel asynchronously like
x86-64. (#4538)
### GDB Support for AArch64
GDB stub support (accessed through `--gdb` under `guest_debug` feature) is now
available on AArch64 as well as as x86-64.
### Notable Bug Fixes
* This version incorporates a version of `virtio-queue` that addresses an issue
where a rogue guest can potentially DoS the VMM (rust-vmm/vm-virtio#196.)
* Improvements around PTY handling for `virtio-console` and serial devices
(#4520, #4533, #4535.)
* Improved error handling in virtio devices (#4626, #4605, #4509, #4631, #4697)
### Deprecations
Deprecated features will be removed in a subsequent release and users should
plan to use alternatives.
* Booting legacy firmware (compiled without a PVH header) has been deprecated.
All the firmware options (Cloud Hypervisor OVMF and Rust Hypervisor Firmware)
support booting with PVH so support for loading firmware in a legacy mode is no
longer needed. This functionality will be removed in the next release.
### Contributors
Many thanks to everyone who has contributed to our release:
* Anatol Belski <anbelski@linux.microsoft.com>
* Bo Chen <chen.bo@intel.com>
* James O. D. Hunt <james.o.hunt@intel.com>
* Jianyong Wu <jianyong.wu@arm.com>
* Markus Napierkowski <markus.napierkowski@cyberus-technology.de>
* Michael Zhao <michael.zhao@arm.com>
* Nuno Das Neves <nudasnev@microsoft.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Smit Gardhariya <sgardhariya@microsoft.com>
* Wei Liu <liuwe@microsoft.com>
# v26.0
This release has been tracked through the [v26.0

View File

@@ -1,182 +0,0 @@
# If this flag is set to 1, rustup installation needs to exist on the system and
# <arch>-unknown-linux-gnu target is required.
# If this flag is set to 0, distro specific Rust packages will be pulled into the build environment.
%define using_rustup 1
# If this flag is set to 1, <arch>-unknown-linux-musl target is required.
%define using_musl_libc 1
# If this flag is set to 1, the vendored crates archive and cargo.toml need to be prepared and
# offline build is implied. Attached script update_src can be used for the vendorization.
# If this flag is set to 0, access to the internet is required during the build.
%define using_vendored_crates 0
Name: cloud-hypervisor
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
Version: 26.0
Release: 0%{?dist}
License: ASL 2.0 or BSD-3-clause
Group: Applications/System
Source0: https://github.com/cloud-hypervisor/cloud-hypervisor/archive/v%{version}.tar.gz
%if 0%{?using_vendored_crates}
Source1: vendor.tar.gz
Source2: config.toml
%endif
ExclusiveArch: x86_64 aarch64
BuildRequires: gcc
BuildRequires: glibc-devel
BuildRequires: binutils
BuildRequires: git
BuildRequires: openssl-devel
%if ! 0%{?using_rustup}
BuildRequires: rust
BuildRequires: cargo
%endif
Requires: bash
Requires: glibc
Requires: libgcc
Requires: libcap
%ifarch x86_64
%define rust_def_target x86_64-unknown-linux-gnu
%if 0%{?using_musl_libc}
%define rust_musl_target x86_64-unknown-linux-musl
%endif
%endif
%ifarch aarch64
%define rust_def_target aarch64-unknown-linux-gnu
%if 0%{?using_musl_libc}
%define rust_musl_target aarch64-unknown-linux-musl
%endif
%endif
%if 0%{?using_vendored_crates}
%define cargo_offline --offline
%endif
%description
Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM. The project focuses on exclusively running modern, cloud workloads, on top of a limited set of hardware architectures and platforms. Cloud workloads refers to those that are usually run by customers inside a cloud provider. For our purposes this means modern Linux* distributions with most I/O handled by paravirtualised devices (i.e. virtio), no requirement for legacy devices and recent CPUs and KVM.
%prep
%setup -q
%if 0%{?using_vendored_crates}
tar xf %{SOURCE1}
mkdir -p .cargo
cp %{SOURCE2} .cargo/
%endif
%install
rm -rf %{buildroot}
install -d %{buildroot}%{_bindir}
install -D -m755 ./target/%{rust_def_target}/release/cloud-hypervisor %{buildroot}%{_bindir}
install -D -m755 ./target/%{rust_def_target}/release/ch-remote %{buildroot}%{_bindir}
install -d %{buildroot}%{_libdir}
install -d %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/%{rust_def_target}/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/%{rust_def_target}/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor
%if 0%{?using_musl_libc}
install -d %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/cloud-hypervisor %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/ch-remote %{buildroot}%{_libdir}/cloud-hypervisor/static
%endif
%build
cargo_version=$(cargo --version)
if [[ $? -ne 0 ]]; then
echo "Cargo not found, please install cargo. exiting"
exit 0
fi
%if 0%{?using_rustup}
which rustup
if [[ $? -ne 0 ]]; then
echo "Rustup not found please install rustup #curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
fi
%endif
echo ${cargo_version}
%if 0%{?using_rustup}
rustup target list --installed | grep -e "%{rust_def_target}"
if [[ $? -ne 0 ]]; then
echo "Target %{rust_def_target} not found, please install(#rustup target add %{rust_def_target}). exiting"
fi
%if 0%{?using_musl_libc}
rustup target list --installed | grep -e "%{rust_musl_target}"
if [[ $? -ne 0 ]]; then
echo "Target %{rust_musl_target} not found, please install(#rustup target add %{rust_musl_target}). exiting"
fi
%endif
%endif
%if 0%{?using_vendored_crates}
# For vendored build, prepend this so openssl-sys doesn't trigger full OpenSSL build
export OPENSSL_NO_VENDOR=1
%endif
cargo build --release --target=%{rust_def_target} --all %{cargo_offline}
%if 0%{?using_musl_libc}
cargo build --release --target=%{rust_musl_target} --all %{cargo_offline}
%endif
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%{_bindir}/ch-remote
%caps(cap_net_admin=ep) %{_bindir}/cloud-hypervisor
%{_libdir}/cloud-hypervisor/vhost_user_block
%caps(cap_net_admin=ep) %{_libdir}/cloud-hypervisor/vhost_user_net
%if 0%{?using_musl_libc}
%{_libdir}/cloud-hypervisor/static/ch-remote
%caps(cap_net_admim=ep) %{_libdir}/cloud-hypervisor/static/cloud-hypervisor
%{_libdir}/cloud-hypervisor/static/vhost_user_block
%caps(cap_net_admin=ep) %{_libdir}/cloud-hypervisor/static/vhost_user_net
%endif
%license LICENSE-APACHE
%license LICENSE-BSD-3-Clause
%changelog
* Wed Aug 17 2022 Rob Bradford <robert.bradford@intel.com> 26.0-0
- Update to 26.0
* Thu Jul 07 2022 Rob Bradford <robert.bradford@intel.com> 25.0-0
- Update to 25.0
* Wed May 25 2022 Sebastien Boeuf <sebastien.boeuf@intel.com> 24.0-0
- Update to 24.0
* Tue May 18 2022 Anatol Belski <anbelski@linux.microsoft.com> - 23.1-0
- Update to 23.1
- Add support for aarch64 build
- Add offline build configuration using vendored crates
- Fix dependency for openssl-sys
* Thu Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
- Update to 23.0
* Thu Mar 03 2022 Rob Bradford <robert.bradford@intel.com> 22.0-0
- Update to 22.0
* Thu Jan 20 2022 Rob Bradford <robert.bradford@intel.com> 21.0-0
- Update to 21.0
* Thu Dec 02 2021 Sebastien Boeuf <sebastien.boeuf@intel.com> 20.0-0
- Update to 20.0
* Mon Nov 08 2021 Fabiano Fidêncio <fabiano.fidencio@intel.com> 19.0-0
- Update to 19.0
* Fri May 28 2021 Muminul Islam <muislam@microsoft.com> 15.0-0
- Update version to 15.0
* Wed Jul 22 2020 Muminul Islam <muislam@microsoft.com> 0.8.0-0
- Initial version

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