Compare commits

..

613 Commits
v26.0 ... v29.0

Author SHA1 Message Date
Rob Bradford
6e9172bf6f .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>
2023-01-14 12:12:11 +00:00
Rob Bradford
22cf8c97e5 build: Release v29.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-13 17:10:35 +00:00
Wei Liu
9e6301be70 Reland: build: drop clap from dev-dependencies
Some crates don't need it at all.

Some crates are using it for a simple functionality which can be
replaced easily.

Signed-off-by: Wei Liu <liuwe@microsoft.com>

This was causing issues with the release build process but we now have a
fix to clean residual build assets.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-13 16:44:59 +00:00
Rob Bradford
547230bb77 .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>
2023-01-13 16:44:59 +00:00
Rob Bradford
ef7e177df2 .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>
2023-01-13 14:38:15 +00:00
Rob Bradford
375e094c77 Revert "build: drop clap from dev-dependencies"
This reverts commit 998fb48ff2.

This is breaking the release build process (cross build for aarch64
musl) so temporarily reverting until we can identify the cause to allow
the release proceeed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-13 14:38:15 +00:00
dependabot[bot]
3df82337f1 build: Bump thiserror from 1.0.37 to 1.0.38
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.37...1.0.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-13 01:34:59 +00:00
dependabot[bot]
0e273e8b0d build: Bump once_cell from 1.16.0 to 1.17.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.16.0 to 1.17.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.16.0...v1.17.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>
2023-01-13 00:34:13 +00:00
Philipp Schuster
ad6c0ee52b 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>
2023-01-12 18:03:33 +00:00
dependabot[bot]
b1f6a59579 build: Bump semver from 1.0.14 to 1.0.16
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.14 to 1.0.16.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.14...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-12 12:54:36 +00:00
Yong He
3494080e2f vmm: add configuration for network offloading features
Add new configuration for offloading features, including
Checksum/TSO/UFO, and set these offloading features as
enabled by default.

Fixes: #4792.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-01-12 09:05:45 +00:00
Muminul Islam
06e583c9ab vmm: move kvm feature gate right before the if condition
This change uses the kvm feature gate cleaner way
in the handling of PIO/MMIO exits.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-01-12 09:03:28 +01:00
Muminul Islam
7d8f795430 hypervisor: remove unnecessary derive of HypervisorType
There was an unnecessary change in previous PR #5077.
This is the follow-up clean up patch.

Right now there is no use case of the drive of
Eq and PartialEq.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-01-12 09:03:28 +01:00
dependabot[bot]
f8c6d7fe37 build: Bump micro_http from 4b18a04 to fbef706 in /fuzz
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `4b18a04` to `fbef706`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](4b18a043e9...fbef706e28)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-11 23:19:57 +00:00
Yong He
0dc122a9a9 virto-device: add latency account for virtio-block
Add new latency counters for virtio-block device, including
minimal latency, maximal latency, and average latency for block
read and write.

The average latency is calculated based on cumulative average.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-01-11 17:38:42 +00:00
Yong He
e2ea9e2821 block_util: add timestamp in request
Add timestamp per request, so that we could account
block process latency base request.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-01-11 17:38:42 +00:00
Muminul Islam
4e3bc20f2c 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>
2023-01-11 17:15:56 +00:00
Rob Bradford
e661139e1e arch: Print details of host hypervisor status & address space size
e.g. on QEMU on KVM:

cloud-hypervisor: 17.079406ms: <vmm> INFO:arch/src/x86_64/mod.rs:565 -- Running under nested virtualisation. Hypervisor string: KVMKVMKVM

Or under Azure:

cloud-hypervisor: 3.881263ms: <vmm> INFO:arch/src/x86_64/mod.rs:565 -- Running under nested virtualisation. Hypervisor string: Microsoft Hv

Fixes: #5067

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-11 14:38:22 +00:00
dependabot[bot]
c99a5fc7a5 build: Bump io-uring from 0.5.9 to 0.5.11
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.9 to 0.5.11.
- [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>
2023-01-10 23:41:07 +00:00
dependabot[bot]
5b2adb398a build: Bump serde_with_macros from 2.1.0 to 2.2.0 in /fuzz
Bumps [serde_with_macros](https://github.com/jonasbb/serde_with) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v2.1.0...v2.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-10 23:18:05 +00:00
Rob Bradford
db5582f7d1 block_util: Preserve ordering of sync file backend completions
For the synchronous backends efficiently preserve the order for
completion requests through the use of VecDequeue. Preserving the order
is not required but is beneficial as it matches the existing
optimisation that looks to match completions and requests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 17:30:25 +00:00
Rob Bradford
ce51755109 block_util: Avoid intermediate completion queue allocation
Rather than aggregate the completion list into an intermediate vector
instead adjust the API to provide one completion item at a time.

With DHAT this shows the number of heap allocations has decreased.

Before:

    dhat: Total:     623,852 bytes in 8,157 blocks

After:

    dhat: Total:     380,444 bytes in 3,469 blocks

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 17:30:25 +00:00
Rob Bradford
67ff0d7819 block_util: Use SmallVec for I/O requests
The number of buffers in the request is usually one so by using SmallVec
the number of heap allocations can be significantly reduced.

DHAT reports:

Before:

dhat: Total:     1,166,412 bytes in 40,383 blocks

After:

dhat: Total:     623,852 bytes in 8,157 blocks

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 17:30:25 +00:00
Rob Bradford
e7a51cde78 block_util: Pass a reference to the slice of iovecs
Rather than passing the vector of iovecs for the I/O to act on pass a
reference to the slice of values inside them. This removes the explicit
container type from the API allowing the use of e.g. SmallVec.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 17:30:25 +00:00
Rob Bradford
9ba06ce5f5 vmm: memory_manager: Deprecate directory backing for memory
This functionality has been obsoleted by our native support for
hugepages and shared memory.

See: #5082

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 15:08:34 +00:00
Sebastien Boeuf
0e7d5d2761 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>
2023-01-10 12:05:15 +00:00
Rob Bradford
ba9554389b virtio-devices: block: Replace use of HashMap for inflight requests
During analysis of the asynchrous block I/O handling it was observed
that the majority of the time the completion events occur in the same
order as submissions. Further the maximum number of inflight requests
during the boot time is much lower than the size of the queue.

Through the use of a double ended queue (VecDequeue) with a reasonable
pre-allocation capacity we can have O(1) allocation free addition of
items to the list of inflight requests and mostly O(1) matching of
completed requests to submissions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 10:41:24 +00:00
Rob Bradford
c89b8e061f Revert "vmm: Deprecate MemoryZoneConfig::file"
This reverts commit 9fb0274479.

A user was identified of this functionality.

See: #4837
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-10 10:31:18 +00:00
Sebastien Boeuf
c2450bd055 tests: Remove unnecessary filename
Since SGX testing doesn't rely on a custom guest image anymore, there's
no need to keep the custom filename around as it's already not in use.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2023-01-10 09:22:59 +00:00
dependabot[bot]
bae9799259 build: Bump mshv-bindings from dda85d3 to fb19bb3
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `dda85d3` to `fb19bb3`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](dda85d32b9...fb19bb3011)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 23:45:35 +00:00
dependabot[bot]
3dd487c2cf build: Bump syn from 1.0.105 to 1.0.107 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.105 to 1.0.107.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.105...1.0.107)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 23:24:11 +00:00
Rob Bradford
eb87538100 block_util: Avoid reallocation of Vec on push
When using DHAT[1] for analysis the amount heap allocations change from:

dhat: Total:     3,186,536 bytes in 41,452 blocks

 to

dhat: Total:     1,059,816 bytes in 34,747 blocks

When running against virtio-block; this still more allocations than
virtio-pmem but a significant improvement without any cost.

[1] https://docs.rs/dhat/latest/dhat/

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-09 10:41:56 -08:00
Philipp Schuster
9e8296b696 log: align log message timestamp
With this change, all log messages will have the same width for the
timestamp. The number of ms is rounded to 6 decimal places.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-01-09 16:38:29 +01:00
Philipp Schuster
0dc3282ae0 lifecycle: align "KILL_EVENT received" messages across code-base
To align the logging messages with the rest of the code, this
message should be aligned with another similar occurrence in
epoll_helper.rs

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-01-09 15:16:48 +00:00
dependabot[bot]
67340c5295 build: Bump clap from 4.0.29 to 4.0.32
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.29 to 4.0.32.
- [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.29...v4.0.32)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-06 23:41:55 +00:00
dependabot[bot]
160ea00d6b build: Bump ryu from 1.0.11 to 1.0.12 in /fuzz
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.11...1.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-06 23:14:20 +00:00
Wei Liu
0389190c64 build: drop the need to import macros from Clap
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-06 13:06:16 -08:00
Wei Liu
998fb48ff2 build: drop clap from dev-dependencies
Some crates don't need it at all.

Some crates are using it for a simple functionality which can be
replaced easily.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-06 13:06:16 -08:00
Wei Liu
03d8a3ebcf performance-metrics: add metrics for UDP PPS
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-06 11:03:08 +00:00
Wei Liu
08e4d1f481 test_infra: make measure_virtio_net_throughput & co measure PPS too
While measuring UDP PPS, we saturate the link, so there are packets
lost. We only account for the packets that are not lost.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-06 11:03:08 +00:00
Wei Liu
d50a4cbb6b test_infra: do not output interval values for iperf3
We only care about the end result.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-06 11:03:08 +00:00
dependabot[bot]
28eeb8a492 build: Bump libc from 0.2.138 to 0.2.139
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.138 to 0.2.139.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.138...0.2.139)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-05 23:41:28 +00:00
dependabot[bot]
ec3520d8b2 build: Bump semver from 1.0.14 to 1.0.16 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.14 to 1.0.16.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.14...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-05 23:14:59 +00:00
Rob Bradford
19661d36af build: Re-enable Jenkins bare metal workers
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-05 17:55:03 +00:00
dependabot[bot]
9747cd1059 build: Bump remain from 0.2.5 to 0.2.6
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.5 to 0.2.6.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.5...0.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-04 23:40:40 +00:00
dependabot[bot]
0bdc7dcc1c build: Bump proc-macro2 from 1.0.47 to 1.0.49 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.47 to 1.0.49.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.47...1.0.49)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-04 23:18:36 +00:00
Wei Liu
e16817ea14 performance-metrics: add IOPS tests for FIO
Change fio_ops to fio_control and add a new field to indicate whether it
should report bandwidth or IOPS.

All existing tests are bandwidth tests. Adapt the code accordingly. Add
a set of new tests to report IOPS.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-01-04 09:47:44 +00:00
dependabot[bot]
3de0a6d401 build: Bump iced-x86 from 1.17.0 to 1.18.0
Bumps [iced-x86](https://github.com/icedland/iced) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/icedland/iced/releases)
- [Commits](https://github.com/icedland/iced/compare/v1.17.0...v1.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-03 23:41:28 +00:00
dependabot[bot]
bb9c5e5faf build: Bump serde from 1.0.151 to 1.0.152 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.151 to 1.0.152.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.151...v1.0.152)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-03 23:12:47 +00:00
Rob Bradford
0036302fc9 tests: Remove support for Ubuntu Bionic
This OS is EOL this year and is well tested by the Rust Hypervisor
Firmware CI so there is no need to duplicate this effort.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2023-01-03 14:42:24 +01:00
dependabot[bot]
b4ec59cb0c build: Bump openssl-sys from 0.9.79 to 0.9.80
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.79 to 0.9.80.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.79...openssl-sys-v0.9.80)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-03 12:20:54 +00:00
dependabot[bot]
8511603fdb build: Bump io-uring from 0.5.9 to 0.5.11 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.9 to 0.5.11.
- [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>
2023-01-02 23:13:05 +00:00
dependabot[bot]
df6e17840a build: Bump remain from 0.2.5 to 0.2.6 in /fuzz
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.5 to 0.2.6.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.5...0.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 09:43:01 +00:00
dependabot[bot]
fdb2d673d3 build: Bump anyhow from 1.0.66 to 1.0.68
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.68.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.68)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-30 23:40:35 +00:00
dependabot[bot]
2d828121a6 build: Bump quote from 1.0.21 to 1.0.23
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.21 to 1.0.23.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.21...1.0.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-29 23:41:08 +00:00
dependabot[bot]
55a8d3a0ea build: Bump paste from 1.0.10 to 1.0.11
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.10 to 1.0.11.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.10...1.0.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-28 23:41:07 +00:00
dependabot[bot]
8e373f52a9 build: Bump mshv-ioctls from 2852337 to dda85d3
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `2852337` to `dda85d3`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](2852337bf4...dda85d32b9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-28 02:10:58 +00:00
dependabot[bot]
6eb0330bed build: Bump clap from 4.0.29 to 4.0.32 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.29 to 4.0.32.
- [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.29...v4.0.32)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 23:13:24 +00:00
dependabot[bot]
c4c384bd1e build: Bump is-terminal from 0.4.1 to 0.4.2 in /fuzz
Bumps [is-terminal](https://github.com/sunfishcode/is-terminal) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/sunfishcode/is-terminal/releases)
- [Commits](https://github.com/sunfishcode/is-terminal/compare/v0.4.1...v0.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-23 23:18:08 +00:00
dependabot[bot]
180cc12b46 build: Bump is-terminal from 0.4.1 to 0.4.2
Bumps [is-terminal](https://github.com/sunfishcode/is-terminal) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/sunfishcode/is-terminal/releases)
- [Commits](https://github.com/sunfishcode/is-terminal/compare/v0.4.1...v0.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-22 23:40:50 +00:00
dependabot[bot]
ccb76fc19f build: Bump itoa from 1.0.4 to 1.0.5 in /fuzz
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.4...1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-22 23:13:42 +00:00
dependabot[bot]
5668d7dfb7 build: Bump unicode-ident from 1.0.5 to 1.0.6
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.5...1.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-21 23:42:28 +00:00
dependabot[bot]
7ca2a771c2 build: Bump anyhow from 1.0.66 to 1.0.68 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.68.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.68)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-21 23:13:54 +00:00
dependabot[bot]
09abb5b709 build: Bump mshv-bindings from ef01a5a to 2852337
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `ef01a5a` to `2852337`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](ef01a5abd0...2852337bf4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-20 23:40:27 +00:00
dependabot[bot]
7bac36bea4 build: Bump unicode-ident from 1.0.5 to 1.0.6 in /fuzz
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.5...1.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-20 23:19:44 +00:00
dependabot[bot]
0f5702f297 build: Bump itoa from 1.0.4 to 1.0.5
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.4...1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-20 10:10:57 +00:00
Jinank Jain
8914ce9da8 build: Bump mshv-ioctls from 10d0c52 to ef01a5a
With this bump there was a change in one of the externally exposed
variable. Thus, the use of that variable in CLH must be adjusted
accordingly.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2022-12-20 10:10:34 +00:00
dependabot[bot]
1f191d8130 build: Bump serde_json from 1.0.89 to 1.0.91 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.89 to 1.0.91.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.89...v1.0.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 23:18:39 +00:00
dependabot[bot]
129416de5c build: Bump serde from 1.0.150 to 1.0.151
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.150 to 1.0.151.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.150...v1.0.151)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-17 00:08:58 +00:00
dependabot[bot]
b3980f581b build: Bump serde from 1.0.150 to 1.0.151 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.150 to 1.0.151.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.150...v1.0.151)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-16 23:24:12 +00:00
Wei Liu
3a232ef31a hypervisor: kvm: aarch64: remove repetition in offset_of
The repetition served no purpose.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-12-16 17:04:43 +00:00
Wei Liu
cd83d258b8 hypervisor: kvm: aarch64: rename offset__of to offset_of
The double underscore made it different from how other projects would
name this particular macro.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-12-16 17:04:43 +00:00
Hao Xu
1b0f35e42d virtio-devices: block: Remove duplicated code in handle_event()
There is duplicated code when handlin queue events in handle_event()
refactor and introduce a new helper function.

Signed-off-by: Hao Xu <howeyxu@tencent.com>
2022-12-16 14:52:48 +00:00
Rob Bradford
85f818421f build: Skip Jenkins build on .github only changes
Fixes: #4988

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-16 09:39:55 +00:00
Rob Bradford
0031dacd7b build: Consolidate touched file checks
This will make it easier to add more in the future.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-16 09:39:55 +00:00
dependabot[bot]
2f855c9a67 build: Bump cc from 1.0.77 to 1.0.78
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.77 to 1.0.78.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.77...1.0.78)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-16 00:04:51 +00:00
dependabot[bot]
b7e7455b49 build: Bump cc from 1.0.77 to 1.0.78 in /fuzz
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.77 to 1.0.78.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.77...1.0.78)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-15 23:23:12 +00:00
Rob Bradford
795f2a5558 vmm: memory_manager: Mark guest memory mappings as non-dumpable
Including the guest RAM (or other mapped memory) in a coredump is not
useful.

See: #5014

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-15 20:36:40 +01:00
dependabot[bot]
2b92a2778b build: Bump linux-raw-sys from 0.1.3 to 0.1.4
Bumps [linux-raw-sys](https://github.com/sunfishcode/linux-raw-sys) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/sunfishcode/linux-raw-sys/releases)
- [Commits](https://github.com/sunfishcode/linux-raw-sys/compare/v0.1.3...v0.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 23:43:43 +00:00
Rob Bradford
cbe988d33e .build: Add .vscode to .gitignore
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-14 14:27:32 +00:00
Rob Bradford
5e52729453 misc: Automatically fix cargo clippy issues added in 1.65 (stable)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-14 14:27:19 +00:00
Rob Bradford
8b59316718 build: Temporarily disable bare metal x86-64 workers
These machines are unreachable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-14 10:47:15 +00:00
dependabot[bot]
6e8972372e build: Bump linux-raw-sys from 0.1.3 to 0.1.4 in /fuzz
Bumps [linux-raw-sys](https://github.com/sunfishcode/linux-raw-sys) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/sunfishcode/linux-raw-sys/releases)
- [Commits](https://github.com/sunfishcode/linux-raw-sys/compare/v0.1.3...v0.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 10:28:13 +01:00
dependabot[bot]
748ba1f50d build: Bump paste from 1.0.9 to 1.0.10
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 10:28:05 +01:00
Rob Bradford
a48d7c281e vmm: seccomp: Remove unreachable patterns
Make HypervisorType enum's members conditional on build time features.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 18:10:42 +00:00
Rob Bradford
aea1f7743b devices: Remove unnecessary clippy directives
Clippy passes fine without these and remove some genuinely unused code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 18:10:42 +00:00
Rob Bradford
ab8e559343 block_util: Use anonymous case to handle ioctl signature difference
Between musl and glibc there is a difference in the signature of the
ioctl libc function. Use an anonymous cast to force the type coversion.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 18:10:42 +00:00
Rob Bradford
1b314cff5b acpi_tables: sdt: Implement Std::is_empty()
This allows the removal of [allow(clippy::len_without_is_empty)]

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-13 18:10:42 +00:00
Claudio Fontana
683d116416 docs: update UEFI.md to reference upstream tianocore EDK2 repository
after testing the build briefly, it seems upstream tianocore EDK2 works fine,
no need for the separate cloud-hypervisor edk2 repo.

Signed-off-by: Claudio Fontana <claudio.fontana@gmail.com>
2022-12-13 18:16:34 +01:00
Henry Wang
b93d50582d docs: Consolidate AArch64 guest booting doc into README
Take the opportunity to fix a bug in the `Booting the guest VM` doc
in README.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
Henry Wang
de4cd49c6d docs: Consolidate AArch64 kernel building doc into README
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
Henry Wang
709545920e docs: Consolidate AArch64 cloud-img related doc into README
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
Henry Wang
2b11966faa docs: Consolidate AArch64 UEFI doc into uefi.md
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
Henry Wang
6835dfa5e9 docs: Consolidate building on AArch64 to building.md
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
Henry Wang
d15e1f1a13 docs: Move AArch64 hardware requirements to README
Also drop the SWAP enabling requirements for AArch64 because this
is an AArch64 specific issue.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-12-13 13:38:11 +00:00
dependabot[bot]
8ab15b9a98 build: Bump serde from 1.0.149 to 1.0.150
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.149 to 1.0.150.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.149...v1.0.150)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-13 00:08:23 +00:00
dependabot[bot]
287ec367d6 build: Bump serde from 1.0.149 to 1.0.150 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.149 to 1.0.150.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.149...v1.0.150)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-12 23:27:28 +00:00
Rob Bradford
9fb0274479 vmm: Deprecate MemoryZoneConfig::file
Remove from the documentation and API definition but continue support
using the field (with a deprecation warning.)

See: #4837

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-12 16:44:04 +00:00
Bo Chen
51307dd509 fuzz: Add fuzzer for 'linux loader' cmdline
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-12-12 13:50:28 +00:00
Bo Chen
de06bf4aed vmm: Make "Vm::generate_cmdline()" public for fuzzing
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-12-12 13:50:28 +00:00
Bo Chen
32ded2c72b fuzz: Add fuzzer for 'linux loader'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-12-12 13:50:28 +00:00
Sebastien Boeuf
8ecce8876e tests: Disable live upgrade testing
Since the refactoring of the vm-migration crate broke the backward
compatibility, we must disable the live upgrade tests until next
release.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
3931b99d4e vm-migration: Introduce new constructor for Snapshot
This simplifies the Snapshot creation as we expect a SnapshotData to be
provided most of the time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
4ae6b595d7 vm-migration: Rename add_data_section() into add_data()
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
748018ace3 vm-migration: Don't store the id as part of Snapshot structure
The information about the identifier related to a Snapshot is only
relevant from the BTreeMap perspective, which is why we can get rid of
the duplicated identifier in every Snapshot structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
426ee39972 vm-migration: Simplify SnapshotData implementation
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
1d1043316b vm-migration: Don't store snapshots through a Box
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
4517b76a23 vm-migration: Rename SnapshotDataSection into SnapshotData
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
1b32e2f8b2 vm-migration: Simplify SnapshotDataSection structure
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
5b3bcfa233 vm-migration: Snapshot should have a unique SnapshotDataSection
There's no reason to carry a HashMap of SnapshotDataSection per
Snapshot. And given we now provide at most one SnapshotDataSection per
Snapshot, there's no need to keep the id part of the SnapshotDataSection
structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
0489b6314e tdx: Support new way of declaring memory resources
Without breaking the former way of declaring them. This is simply based
on the presence of the GUID TDX Metadata offset. If not present, we
consider the firmware is quite old and therefore we fallback onto the
previous way to expose memory resources.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-08 10:13:12 -08:00
Rob Bradford
2c367bdde8 misc: Bulk update dependencies
In particular update to latest linux-loader release and point to latest
vfio repository for both crates hosted there.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-07 18:24:58 +00:00
Sebastien Boeuf
4f3f36fe5f tdx: Add support for new method of TDVF descriptor discovery
The preferred way of retrieving the offset where to find the TDVF
descriptor structure is by going through a table of GUIDs that can be
found at a specific offset in the firmware file. If the expected GUIDs
can't be found, we can fallback onto the former way, which is to read
directly the value at a specific offset in the file.

This patch implements the new mechanism without breaking compatibility
for older firmwares as it keeps supporting the previous mechanism.

As a reference, here is the documentation from the EDK2 code, and
particularly from the OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm file:

```
GUIDed structure.  To traverse this you should first verify the
presence of the table footer guid
(96b582de-1fb2-45f7-baea-a366c55a082d) at 0xffffffd0.  If that
is found, the two bytes at 0xffffffce are the entire table length.

The table is composed of structures with the form:

Data (arbitrary bytes identified by guid)
length from start of data to end of guid (2 bytes)
guid (16 bytes)

so work back from the footer using the length to traverse until you
either find the guid you're looking for or run off the beginning of
the table.
```

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-07 17:55:54 +00:00
Rob Bradford
4b08142117 misc: Remove #![allow(clippy::significant_drop_in_scrutinee)]
This isn't supported by clippy on Rust 1.60 but also no longer seems to
be required.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-07 17:50:48 +00:00
Rob Bradford
b3e3a5fdd7 vmm: Fix clippy on musl toolchains
The datatype used for the ioctl() C library call is different between it
and the glibc toolchains. The easiest solution is to have the compiler
type cast to type of the parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-07 17:50:48 +00:00
Rob Bradford
a1c6ef8385 .github: Add musl variants to quality (clippy) checks
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-07 17:50:48 +00:00
dependabot[bot]
16d0906dfd build: Bump mshv-ioctls from 0983996 to 10d0c52
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `0983996` to `10d0c52`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](098399606d...10d0c5208c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 23:44:44 +00:00
dependabot[bot]
3e9ce6012c build: Bump rustix from 0.36.4 to 0.36.5 in /fuzz
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.36.4 to 0.36.5.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.36.4...v0.36.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 23:21:09 +00:00
Shuaiyi Zhang
389264351e ch-remote: Add support for vmm.shutdown
Signed-off-by: Shuaiyi Zhang <zhangsy28@lenovo.com>
2022-12-06 13:21:55 -08:00
Rob Bradford
00becda899 README: Use consistent path to cloud-hypervisor binary
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-06 17:30:34 +00:00
dependabot[bot]
fe5bde236a build: Bump libc from 0.2.137 to 0.2.138
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.137 to 0.2.138.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.137...0.2.138)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 00:10:07 +00:00
dependabot[bot]
80cc2b6ef8 build: Bump libc from 0.2.137 to 0.2.138 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.137 to 0.2.138.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.137...0.2.138)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-05 23:25:56 +00:00
Rob Bradford
c37dadcc9a .github: Enable "guest_debug" clippy on aarch64
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-05 17:23:52 +00:00
Rob Bradford
cefbf6b4a3 vmm: guest_debug: Mark coredump functionality x86_64 only
The coredump functionality is only implemented for x86_64 so it should
only be compiled in there.

Fixes: #4964

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-05 17:23:52 +00:00
Sebastien Boeuf
31209474b3 vmm: Move TDX initialization before vCPUs creation
TDX was broken by the recent refactoring moving the vCPU creation
earlier than before. The simple and correct way to fix this problem is
by moving the TDX initialization right before the vCPUs creation. The
rest of the TDX setup can remain where it is.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-05 07:49:40 -08:00
Shuaiyi Zhang
0e09b537e3 ch-remote: Add support for vmm.ping
Signed-off-by: Shuaiyi Zhang <zhangsy28@lenovo.com>
2022-12-05 07:45:01 -08:00
dependabot[bot]
ca6d338ffa build: Bump clap from 4.0.27 to 4.0.29
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.27 to 4.0.29.
- [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.27...v4.0.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 23:45:26 +00:00
dependabot[bot]
166b73e106 build: Bump io-lifetimes from 1.0.2 to 1.0.3 in /fuzz
Bumps [io-lifetimes](https://github.com/sunfishcode/io-lifetimes) from 1.0.2 to 1.0.3.
- [Release notes](https://github.com/sunfishcode/io-lifetimes/releases)
- [Commits](https://github.com/sunfishcode/io-lifetimes/compare/v1.0.2...v1.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 23:21:11 +00:00
dependabot[bot]
9398a0bd80 build: Bump syn from 1.0.104 to 1.0.105
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.104...1.0.105)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 00:00:29 +00:00
dependabot[bot]
55f7df2e21 build: Bump syn from 1.0.104 to 1.0.105 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.104...1.0.105)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 23:16:35 +00:00
Rob Bradford
7fb1280666 devices: gic: Pass slice rather than &Vec
This addresses a clippy issue

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Rob Bradford
bfa31f9c56 vmm: Propagate vCPU configure error correctly
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Rob Bradford
725e388684 vmm: Seperate the CPUID setup from the CpuManager::new()
This allows the decoupling of CpuManager and MemoryManager.

See: #4761

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Rob Bradford
c5eac2e822 vmm: Don't store GuestMemoryMmap for "guest_debug" functionality
This removes the storage of the GuestMemoryMmap on the CpuManager
further allowing the decoupling of the CpuManager from the
MemoryManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Rob Bradford
c7b22156da aarch, vmm: Reduce requirement for guest memory to vCPU boot only
When configuring the vCPUs it is only necessary to provide the guest
memory when booting fresh (for populating the guest memory). As such
refactor the vCPU configuration to remove the use of the
GuestMemoryMmap stored on the CpuManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Rob Bradford
e5e5a89e65 vmm: cpu: Rename "vm_memory" parameter/member to "guest_memory"
This gives consistency across the file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 22:41:01 +00:00
Sebastien Boeuf
d98f2618bd vmm: Create restored Vm as paused
Thanks to the new way of restoring Vm, we can now create the Vm object
directly with the appropriate VmState rather than having to patch it at
a later time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 10:16:44 -08:00
Sebastien Boeuf
2e01bf7f74 vmm: Provide an owned Snapshot rather than a reference
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 10:16:44 -08:00
Sebastien Boeuf
a4160c1fef vmm: Simplify list of parameters to Vm::new()
No need to provide a boolean to know if the VM is being restored given
we already have this information from the Option<Snapshot>.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 10:16:44 -08:00
Sebastien Boeuf
d0c53a5357 vmm: Move Vm to the new restore design
Now the entire codebase has been moved to the new restore design, we can
complete the work by creating a dedicated restore() function for the Vm
object and get rid of the method restore() from the Snapshottable trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 10:16:44 -08:00
Rob Bradford
3888f57600 aarch64: Remove unnecessary casts (beta clippy check)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 17:02:30 +00:00
Rob Bradford
7fd2022e8e .github: Ensure target used for clippy tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 17:02:30 +00:00
Rob Bradford
1b6dd597b2 .github: Remove build testing for aarch64 with guest_debug feature
See: #4964

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 17:02:30 +00:00
Rob Bradford
ad817f19b5 main: Allow the use of let ahead and immediate return
On aarch64 there is no modification of the app struct however
refactoring to remove this would be very intrusive.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-12-01 17:02:30 +00:00
Michael Zhao
a8839c4a4e tests: Disable live_upgrade test on AArch64
The `live_upgrade` test was broken when the Gic snapshot moved from `Vm`
to `DeviceManager`.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-12-01 17:07:25 +01:00
Michael Zhao
b173f6f654 vmm,devices: Change Gic snapshot and restore path
The snapshot and restore of AArch64 Gic was done in Vm. Now it is moved
to DeviceManager.

The benefit is that the restore can be done while the Gic is created in
DeviceManager.

While the moving of state data from Vm snapshot to DeviceManager
snapshot breaks the compatability of migration from older versions.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-12-01 17:07:25 +01:00
Michael Zhao
def1d7cf86 vmm: Remove GICR typers in snapshot on AArch64
The GICR typers are also set in restoring the GIC. Saving them in
snapshot is not needed.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-12-01 17:07:25 +01:00
Sebastien Boeuf
e8c6d83f3f vmm: Merge Vm::new_from_snapshot with Vm::new
Given the recent factorization that happened in vm.rs, we're now able to
merge Vm::new_from_snapshot with Vm::new.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 13:46:31 +01:00
Sebastien Boeuf
1c36065754 vmm: Move devices creation to Vm creation
This moves the devices creation out of the dedicated restore function
which will be eventually removed.

This factorizes the creation of all devices into a single location.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 13:46:31 +01:00
Sebastien Boeuf
bccfa81368 vmm: Restore clock from Vm creation (x86_64 only)
This allows the clock restoration to be moved out of the dedicated
restore function, which will eventually be removed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 13:46:31 +01:00
Sebastien Boeuf
a6959a7469 vmm: Move DeviceManager to new restore design
Based on all the work that has already been merged, it is now possible
to fully move DeviceManager out of the previous restore model, meaning
there's no need for a dedicated restore() function to be implemented
there.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 13:46:31 +01:00
Sebastien Boeuf
4487c8376b vmm: Move CpuManager and Vcpu to the new restore design
Every Vcpu is now created with the right state if there's an available
snapshot associated with it. This simplifies the restore logic.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 09:27:00 +01:00
Sebastien Boeuf
b62a40efae virtio-devices, vmm: Always restore virtio devices in paused state
Following the new restore design, it is not appropriate to set every
virtio device threads into a paused state after they've been started.

This is why we remove the line of code pausing the devices only after
they've been restored, and replace it with a small patch in every virtio
device implementation. When a virtio device is created as part of a
restored VM, the associated "paused" boolean is set to true. This
ensures the corresponding thread will be directly parked when being
started, avoiding the thread to be in a different state than the one it
was on the source VM during the snapshot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 09:27:00 +01:00
dependabot[bot]
8f1e03fcf4 build: Bump terminal_size from 0.2.2 to 0.2.3
Bumps [terminal_size](https://github.com/eminence/terminal-size) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/eminence/terminal-size/releases)
- [Commits](https://github.com/eminence/terminal-size/compare/v0.2.2...v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 00:08:19 +00:00
dependabot[bot]
5ee68b1ee3 build: Bump terminal_size from 0.2.2 to 0.2.3 in /fuzz
Bumps [terminal_size](https://github.com/eminence/terminal-size) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/eminence/terminal-size/releases)
- [Commits](https://github.com/eminence/terminal-size/compare/v0.2.2...v0.2.3)

---
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-30 23:23:46 +00:00
Bo Chen
e2e02c8f69 fuzz: Add fuzzer for virtio-net
To synthesize the interactions between the virtio-net device and the tap
interface, the fuzzer utilizes a pair of unix domain sockets: one socket
(e.g. the dummy tap frontend) is used to construct the 'net_util::Tap'
instance for creating a virtio-net device; the other socket (e.g. the
dummy tap backend) is used in a epoll loop for handling the tx and rx
requests from the virtio-net device.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-30 12:13:14 +00:00
Bo Chen
ec94ae31ee vmm: EpollContext: Allow to add custom epoll events for fuzzing
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-30 12:13:14 +00:00
Bo Chen
83ab5ea528 virtio-devices: net: Provide custom functions for fuzzing
Three functions are added:
* 'Tap::new_for_fuzzing()' a custom constructor that creates a dummy
`Tap` interface directly from `File` backed by Unix domain socket;
* 'Tap::mtu()' a custom function that returns hard-coded mtu;
* 'Net::wait_for_epoll_threads()'.

Two functions are reused with modifications to work with the dummy 'Tap'
interface:
* 'Net::new_with_tap()' is made public for fuzzing;
* 'Net::activate()' is modified to not call into 'Tap::set_offload()'
for fuzzing.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-11-30 12:13:14 +00:00
Rob Bradford
30a7a8033e build: Move to released versions of vhost and vhost-user-backend crates
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-30 12:12:34 +00:00
dependabot[bot]
fc43a50f34 build: Bump vfio-ioctls from ad86d84 to 3d82543
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `ad86d84` to `3d82543`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](ad86d843a2...3d82543586)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-29 23:46:48 +00:00
dependabot[bot]
105c6cfc5a build: Bump clap from 4.0.27 to 4.0.29 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.27 to 4.0.29.
- [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.27...v4.0.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-29 23:15:39 +00:00
Rob Bradford
ee5792c0bb build: Document the project's MSRV policy
To me the most logical place to document the policy is right next to the
version itself.

Fixes: #4318

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-29 18:09:11 +00:00
Sebastien Boeuf
30e421d2e5 pci: Remove unused restore() implementations
Now that VirtioPciDevice, VfioPciDevice and VfioUserPciDevice have all
been moved to the new restore design, there's no need to keep the old
way around, therefore the restore() implementations for MsiConfig,
MsixConfig and PciConfiguration can be removed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-29 13:46:30 +01:00
Sebastien Boeuf
90b5014a50 vmm: device_manager: Remove 'restoring' attribute
Given 'restoring' isn't needed anymore from the DeviceManager structure,
let's simplify it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-29 13:46:30 +01:00
Sebastien Boeuf
cc3706afe1 pci, vmm: Move VfioPciDevice and VfioUserPciDevice to new restore design
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-29 13:46:30 +01:00
Sebastien Boeuf
1eac37bd5f pci: msi: Move MsiConfig to the new restore design
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-29 13:46:30 +01:00
Sebastien Boeuf
d6bf1f5eb0 pci: Move VfioCommon creation to a dedicated function
This is some preliminatory work for moving both VfioUser and Vfio to the
new restore design.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-29 13:46:30 +01:00
Bo Chen
559faa272a 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>
2022-11-28 17:19:53 +00:00
Rob Bradford
6f8bd27cf7 build: Bulk update dependencies
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-28 16:57:49 +00:00
Yuji Hagiwara
47a7ebe434 docs: Fix a typo on the doc for tpm
swtpm accepts --tpmstate option

Signed-off-by: Yuji Hagiwara <yuuzi41@gmail.com>
2022-11-27 18:55:07 +00:00
dependabot[bot]
1fd5384062 build: Bump regex-syntax from 0.6.27 to 0.6.28
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.27 to 0.6.28.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-25 23:46:39 +00:00
Sebastien Boeuf
81862e8ed3 devices, vmm: Move Gpio to new restore design
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 17:37:29 +00:00
Sebastien Boeuf
9fbf52b998 devices, vmm: Move Pl011 to new restore design
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 17:37:29 +00:00
Sebastien Boeuf
0bd910e8b0 devices, vmm: Move Serial to new restore design
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 17:37:29 +00:00
Sebastien Boeuf
ef92e55998 devices, vmm: Move Ioapic to new restore design
Moving the Ioapic object to the new restore design, meaning the Ioapic
is created directly with the right state, and it shares the same
codepath as when it's created from scratch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 17:18:21 +01:00
Sebastien Boeuf
9f7ccb34cd docs: Provide documentation for creating custom image for VFIO CI
Extend the existing `custom-image.md` document with a new section on how
to create a custom image that contains NVIDIA drivers that are required
for our VFIO baremetal CI.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 13:39:25 +01:00
Sebastien Boeuf
e23f4e0783 tests: Enable VFIO integration tests
Re-enable the VFIO integration now the machine is back online.

The image has been updated to rely on Ubuntu 22.04 (Jammy) and it's
smaller given only the NVIDIA drivers along with the nvidia-smi tool are
installed.

The test to verify the GPU is functional has been simplified given it
only relies on nvidia-smi to validate it has been able to find the Tesla
T4 card, meaning the associated driver was loaded correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-25 08:55:14 +00:00
dependabot[bot]
6a29eba69e build: Bump regex from 1.6.0 to 1.7.0
Bumps [regex](https://github.com/rust-lang/regex) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.6.0...1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-24 23:44:40 +00:00
dependabot[bot]
98e10062e8 build: Bump clap from 4.0.26 to 4.0.27 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.26 to 4.0.27.
- [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.26...v4.0.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-24 23:13:36 +00:00
Rob Bradford
c95b82d975 scripts: Build dual kvm/mshv binary (like release.yaml) for integration testing
This means we are testing the same binary as we use in our releases.

Fixes: #4915

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-24 17:06:56 +00:00
Rob Bradford
d83fc7f663 scripts: Make --hypervisor=mshv only affect features used by tests
This uncouples it from the features used for building the binary under
test allowing it to use the default build features.

This change also removes the feature control from the test scripts where
it was never used (e.g. run_integration_tests_sgx.sh)

This allows the combined binary to be used for all testing but allows
the disabling of tests known not to work under mshv.

Fixes: #4915

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-24 17:06:56 +00:00
Rob Bradford
e3a5102f85 net_util: tap: Include ioctl code in failure errors
This will help with debugging issues like #4917 since we can find which
ioctl causes the error.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-24 16:18:39 +00:00
Rob Bradford
ea39fcca3f net_util: tap: Refactor TAP ioctl calls
Consolidate the identical code that tests the return values of the ioctl
into helper functions

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-24 16:18:39 +00:00
dependabot[bot]
7e10b236d4 build: Bump serde_json from 1.0.87 to 1.0.89 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.87 to 1.0.89.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.87...v1.0.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-23 23:15:07 +00:00
Sebastien Boeuf
405b4a6829 tests: Increase time for proper shutdown in test_simple_launch()
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-23 18:37:40 +00:00
Sebastien Boeuf
a50b3784fe virtio-devices: Create a proper result type for VirtioPciDevice
Creating a dedicated Result type for VirtioPciDevice, associated with
the new VirtioPciDeviceError enum. This allows for a clearer handling of
the errors generated through VirtioPciDevice::new().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-23 18:37:40 +00:00
Sebastien Boeuf
eae8043890 pci, virtio-devices: Move VirtioPciDevice to the new restore design
The code for restoring a VirtioPciDevice has been updated, including the
dependencies VirtioPciCommonConfig, MsixConfig and PciConfiguration.

It's important to note that both PciConfiguration and MsixConfig still
have restore() implementations because Vfio and VfioUser devices still
rely on the old way for restore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-23 18:37:40 +00:00
Rob Bradford
8868c9c950 tests: Use Ubuntu Jammy for test_multi_cpu
This allows the unification of the same testing methodology with aarch64
and removes a user of the Bionic image.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-23 18:02:03 +00:00
Michael Zhao
7d16c74020 vmm: Refactor AArch64 GIC initialization process
In the new process, `device::Gic::new()` covers additional actions:
1. Creating `hypervisor::vGic`
2. Initializing interrupt routings

The change makes the vGic device ready in the beginning of
`DeviceManager::create_devices()`. This can unblock the GIC related
devices initialization in the `DeviceManager`.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-11-23 11:49:57 +01:00
Sebastien Boeuf
86e7f07485 vmm: cpu: Create vCPUs before the DeviceManager
Moving the creation of the vCPUs before the DeviceManager gets created
will allow for the aarch64 vGIC to be created before the DeviceManager
as well in a follow up patch. The end goal being to adopt the same
creation sequence for both x86_64 and aarch64, and keeping in mind that
the vGIC requires every vCPU to be created.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-23 11:49:57 +01:00
Sebastien Boeuf
578780ed0c vmm: cpu: Split vCPU creation
Split the vCPU creation into two distincts parts. On the one hand we
create the actual Vcpu object with the creation of the hypervisor::Vcpu.
And on the other hand, we configure the existing Vcpu, setting registers
to proper values (such as setting the entry point).

This will allow for further work to move the creation earlier in the
boot, so that the hypervisor::Vcpu will be already created when the
DeviceManager gets created.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-11-23 11:49:57 +01:00
Sebastien Boeuf
ec01062ada vmm: Switch order between DeviceManager and CpuManager creation
The CpuManager is now created before the DeviceManager. This is required
as preliminary work for creating the vCPUs before the DeviceManager,
which is required to ensure both x86_64 and aarch64 follow the same
sequence.

It's important to note the optimization for faster PIO accesses on the
PCI config space had to be removed given the VmOps was required by the
CpuManager and by the Vcpu by extension. But given the PciConfigIo is
created as part of the DeviceManager, there was no proper way of moving
things around so that we could provide PciConfigIo early enough.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-11-23 11:49:57 +01:00
dependabot[bot]
d828fcd4ed build: Bump cc from 1.0.76 to 1.0.77
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.76 to 1.0.77.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.76...1.0.77)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-23 00:21:21 +00:00
dependabot[bot]
d330f5389e build: Bump cc from 1.0.73 to 1.0.77 in /fuzz
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.73 to 1.0.77.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.73...1.0.77)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-22 23:36:54 +00:00
Rob Bradford
e37ec26ccf vmm: Remove PCI PIO optimisation
This optimisation provided some peformance improvement when measured by
perf however when considered in terms of boot time peformance this
optimisation doesn't have any impact measurable using our
peformance-metrics tooling.

Removing this optimisation helps simplify the VMM internals as it allows
the reordering of the VM creation process permitting refactoring of the
restore code path.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-22 19:47:53 +00:00
Bo Chen
4d9a2b17a7 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>
2022-11-22 09:31:50 +00:00
Rob Bradford
7c3110e6d5 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>
2022-11-22 09:32:30 +01:00
dependabot[bot]
1c25d71127 build: Bump os_str_bytes from 6.4.0 to 6.4.1 in /fuzz
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.4.0 to 6.4.1.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.4.0...6.4.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-11-22 00:47:55 +00:00
Rob Bradford
8724ac1fe6 scripts: Remove stripping from testing scripts
The binary stripping is now done by the toolchain for release builds.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-21 07:54:39 -08:00
Henry Wang
1ff0191b30 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>
2022-11-21 13:39:29 +00:00
dependabot[bot]
464ead57ec build: Bump cc from 1.0.73 to 1.0.76
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.73 to 1.0.76.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.73...1.0.76)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-19 00:27:00 +00:00
dependabot[bot]
cee2d6627d build: Bump clap from 4.0.18 to 4.0.26 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.0.18 to 4.0.26.
- [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.18...v4.0.26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-18 23:44:01 +00:00
Muminul Islam
bfeab9f69f .github: do release build with both KVM and MSHV enabled
Fixes: #4678

Currently release build is done on kvm feature only,
that makes live upgrade test on MSHV failing since
it does not find /dev/kvm. As Cloud-Hypervisor
supports both kvm and mshv in a single binary we should
make the release build with both KVM/MSHV feature enabled.
That way live upgrade test does not fail on MSHV.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2022-11-18 19:15:25 +00:00
Rob Bradford
3504947f0e Jenkinsfile: Re-enable SGX CI testing
With the modernised testing of SGX the testing can be re-enabled on the
CI.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-18 18:31:55 +00:00
Rob Bradford
d2442d39a8 tests: Update version of jammy image in use
This version has the cpuid binary installed which can be used for SGX
integration testing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-18 18:31:55 +00:00
Rob Bradford
1e87a409c7 docs: Add cpuid to custom disk image instructions
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-18 18:31:55 +00:00
Rob Bradford
1a2185ea96 tests: Modernise SGX testing
The jammy disk image has a new enough kernel to support SGX and if we
rely on just the CPUid information (which is sufficient) then we can use
the regular jammy test image for testing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-18 18:31:55 +00:00
Rob Bradford
8cea5db955 Jenkinsfile: Re-enable rate limiter CI
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-11-18 07:48:07 -08:00
Wei Liu
3ca6c29e28 github: do not allow undocumented unsafe blocks
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
d05586f520 vmm: modify or provide safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
d5f294b326 main: add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
145df4b689 tests: allow undocumented unsafe blocks in integration test
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
c45d24df16 virtio-devices: modify or provide safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
f110029acf block_util: modify or provide safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
8a7f4b47cb net_util: modify or provide safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
c5bd8cabc4 pci: add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
d1b9d9d7f7 test_infra: allow undocumented unsafe blocks
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
9806d83e7c devices: modify safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
f16b57716d arch: modify or add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
3edf12accf block_util: modify and add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
7f2723d9c6 hypervisor: x86: add two safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
6c89c541da hypervisor: kvm: add two safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
d272113d0c hypervisor: mshv: modify two safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
93883681be tracer: add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
ca02a69fdf qcow: add a safety comment
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
c4ffdad4bc vfio_user: modify the style of safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
2a5c248f32 vm-migration: add two safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
926d149881 net_gen: add a safety comment
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
7f4b5dfae5 tpm: change the style of safety comments
To satisfy clippy's check.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
58b7057c7f rate_limiter: add a safety comment
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
b1efa5b26b event_monitor: add safety comments
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
b9ad3eda27 vhdx: add some safety comments
Also add some assertions to some places along side the safety comments.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
1d9050dbe3 acpi_tables: add a safety comment for the write function
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
3d08a0fba9 vm-allocator: fix a clippy warning on missing safety comments
There is already a comment but Clippy isn't happy with its form.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
Wei Liu
d274fe9cb8 vmm: fix tdx check
The field has been moved in 3793ffe888.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-11-18 12:50:01 +00:00
dependabot[bot]
cd24f470f4 build: Bump getrandom from 0.2.7 to 0.2.8
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: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-17 23:46:30 +00:00
dependabot[bot]
2e22f950b7 build: Bump serde_with from 2.0.1 to 2.1.0 in /fuzz
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v2.0.1...v2.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-17 23:14:56 +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
228 changed files with 15521 additions and 9161 deletions

View File

@@ -34,28 +34,22 @@ jobs:
override: true
- name: Build (default features)
run: cargo rustc --locked --bin cloud-hypervisor -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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 -D clippy::undocumented_unsafe_blocks
- 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
run: cargo rustc --locked --bin cloud-hypervisor --features "tdx" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (default features + guest_debug)
run: cargo rustc --locked --bin cloud-hypervisor --features "guest_debug" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --features "guest_debug" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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 -D clippy::undocumented_unsafe_blocks
- 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 -D clippy::undocumented_unsafe_blocks
- 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

@@ -13,15 +13,31 @@ jobs:
rust:
- stable
target:
- aarch64-unknown-linux-gnu
- aarch64-unknown-linux-musl
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
experimental: [false]
include:
- rust: beta
target: aarch64-unknown-linux-gnu
experimental: true
- rust: beta
target: aarch64-unknown-linux-musl
experimental: true
- rust: beta
target: x86_64-unknown-linux-gnu
experimental: true
- rust: beta
target: x86_64-unknown-linux-musl
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 +47,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: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --features "kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --tests -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --tests --features "guest_debug" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --tests --features "tracing" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --features "mshv" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- 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: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --features "tdx,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"

View File

@@ -1,62 +1,47 @@
name: Cloud Hypervisor Release
on: [create]
on: [pull_request, create]
jobs:
release:
if: github.event_name == 'create' && github.event.ref_type == 'tag'
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:
toolchain: "1.62"
command: build
args: --all --release --target=x86_64-unknown-linux-gnu
toolchain: "1.62"
command: build
args: --all --release --no-default-features --features "kvm,mshv" --target=x86_64-unknown-linux-gnu
- name: Static Build
uses: actions-rs/cargo@v1
with:
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
toolchain: "1.62"
command: build
args: --all --release --no-default-features --features "kvm,mshv" --target=x86_64-unknown-linux-musl
- 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 +51,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 +63,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 +74,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 +85,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 +95,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 +117,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 +127,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

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@
**/Cargo.lock
**/rusty-tags.vi
/rpm/SOURCES
/.vscode

538
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 = "29.0.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -10,58 +10,59 @@ description = "Open source Virtual Machine Monitor (VMM) that runs on top of KVM
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
# Minimum buildable version:
# Keep in sync with version in .github/workflows/build.yaml
# Policy on MSRV (see #4318):
# Can only be bumped by:
# a.) A dependency requires it,
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
# c.) There is a security issue that is addressed by the toolchain update.
rust-version = "1.60"
[profile.release]
lto = true
codegen-units = 1
opt-level = "s"
strip = true
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.68"
api_client = { path = "api_client" }
clap = { version = "3.2.17", features = ["wrap_help","cargo"] }
clap = { version = "4.0.32", features = ["wrap_help","cargo","string"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.131"
libc = "0.2.139"
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.38"
tpm = { path = "tpm"}
tracer = { path = "tracer" }
vmm = { path = "vmm" }
vmm-sys-util = "0.10.0"
vm-memory = "0.8.0"
[build-dependencies]
clap = { version = "3.2.17", features = ["cargo"] }
vmm-sys-util = "0.11.0"
vm-memory = "0.10.0"
# 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 +80,9 @@ members = [
"performance-metrics",
"qcow",
"rate_limiter",
"serial_buffer",
"test_infra",
"tracer",
"vfio_user",
"vhdx",
"vhost_user_block",

876
Jenkinsfile vendored
View File

@@ -1,467 +1,449 @@
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 if worker build can be skipped') {
when {
expression {
return skipWorkerBuild()
}
}
steps {
script {
runWorkers = false
echo 'No changes requring a build'
}
}
}
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'
}
}
}
}
stage('Worker build - Rate Limiter') {
agent { node { label 'focal-metrics' } }
when {
branch 'main'
beforeAgent true
expression {
return runWorkers
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run rate-limiter integration tests') {
options {
timeout(time: 10, unit: 'MINUTES')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-rate-limiter'
}
}
}
}
stage('Worker build - SGX') {
agent { node { label 'jammy-sgx' } }
when {
beforeAgent true
allOf {
branch 'main'
expression {
return runWorkers
}
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run SGX integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-sgx'
}
}
stage('Run SGX integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-sgx --libc musl'
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage('Worker build - VFIO') {
agent { node { label 'jammy-vfio' } }
when {
beforeAgent true
allOf {
branch 'main'
expression {
return runWorkers
}
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Run VFIO integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-vfio'
}
}
stage('Run VFIO integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh 'scripts/dev_cli.sh tests --integration-vfio --libc musl'
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
}
}
}
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() {
def boolean skipWorkerBuild() {
if (env.CHANGE_TARGET == null) {
return false;
return false
}
return sh(
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v '\\.md'"
) != 0
}
def boolean fuzzFileOnly() {
if (env.CHANGE_TARGET == null) {
return false;
) != 0) {
return true
}
return sh(
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v -E 'fuzz/'"
) != 0
) != 0) {
return true
}
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v -E '.github/'"
) != 0) {
return true
}
return false
}

399
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,187 +69,186 @@ 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.
## Preparation
## Prerequisites for AArch64
We create a folder to build and run `cloud-hypervisor` at `$HOME/cloud-hypervisor`
- AArch64 servers (recommended) or development boards equipped with the GICv3
interrupt controller.
## Host OS
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
Cloud Hypervisor supports direct kernel boot (the x86-64 kernel requires the kernel
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` / `CLOUDHV_EFI`.)
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. For x86-64, a `vmlinux` ELF kernel (compiled with PVH support) is needed. 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
# Use the x86-64 cloud-hypervisor kernel config to build your kernel for x86-64
$ wget https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/main/resources/linux-config-x86_64
# Use the AArch64 cloud-hypervisor kernel config to build your kernel for AArch64
$ wget https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/main/resources/linux-config-aarch64
$ cp linux-config-x86_64 .config # x86-64
$ cp linux-config-aarch64 .config # AArch64
# Do native build of the x86-64 kernel
$ KCFLAGS="-Wa,-mx86-used-note=no" make bzImage -j `nproc`
# Do native build of the AArch64 kernel
$ make -j `nproc`
$ popd
```
The `vmlinux` kernel image will then be located at
For x86-64, the `vmlinux` kernel image will then be located at
`linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin`.
For AArch64, the `Image` kernel image will then be located at
`linux-cloud-hypervisor/arch/arm64/boot/Image`.
#### 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
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img # x86-64
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-arm64.img # AArch64
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw # x86-64
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-arm64.img focal-server-cloudimg-arm64.raw # AArch64
```
#### 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.
- x86-64
```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.
When in need for earlier debug messages, using the legacy serial device based
console is preferred:
- AArch64
```shell
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh
$ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/arm64/boot/Image \
--disk path=focal-server-cloudimg-arm64.raw path=/tmp/ubuntu-cloudinit.img \
--cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="
```
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
If earlier kernel messages are required the serial console should be used instead of `virtio-console`.
- x86-64
```shell
$ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \
--serial tty \
@@ -259,10 +259,24 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--net "tap=,mac=,ip=,mask="
```
- AArch64
```shell
$ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/arm64/boot/Image \
--console off \
--serial tty \
--disk path=focal-server-cloudimg-arm64.raw \
--cmdline "console=ttyAMA0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="
```
# 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 +294,17 @@ 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 2023-01-03, the following cloud images are supported:
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (focal-server-cloudimg-{amd64,arm64}.img)
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (jammy-server-cloudimg-{amd64,arm64}.img )
- [Fedora 36](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/) ([Fedora-Cloud-Base-36-1.5.x86_64.raw.xz](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/x86_64/images/) / [Fedora-Cloud-Base-36-1.5.aarch64.raw.xz](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/aarch64/images/))
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 +317,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 +331,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 +360,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

@@ -38,7 +38,6 @@ pub struct Sdt {
data: Vec<u8>,
}
#[allow(clippy::len_without_is_empty)]
impl Sdt {
pub fn new(
signature: [u8; 4],
@@ -98,6 +97,7 @@ impl Sdt {
/// Write a value at the given offset
pub fn write<T>(&mut self, offset: usize, value: T) {
assert!((offset + (std::mem::size_of::<T>() - 1)) < self.data.len());
// SAFETY: The assertion above makes sure we don't do out of bounds write.
unsafe {
*(((self.data.as_mut_ptr() as usize) + offset) as *mut T) = value;
}
@@ -123,6 +123,10 @@ impl Sdt {
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
#[cfg(test)]

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.68"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.131"
linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
libc = "0.2.139"
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.151", features = ["rc", "derive"] }
thiserror = "1.0.38"
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)?;
@@ -261,7 +259,7 @@ fn create_memory_node(
if last_addr < super::layout::MEM_32BIT_RESERVED_START.raw_value() {
// Case 1: all RAM is under the hole
let mem_size = last_addr - super::layout::RAM_START.raw_value() + 1;
let mem_reg_prop = [super::layout::RAM_START.raw_value() as u64, mem_size as u64];
let mem_reg_prop = [super::layout::RAM_START.raw_value(), mem_size];
let memory_node = fdt.begin_node("memory")?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
@@ -271,7 +269,7 @@ fn create_memory_node(
// Region 1: RAM before the hole
let mem_size = super::layout::MEM_32BIT_RESERVED_START.raw_value()
- super::layout::RAM_START.raw_value();
let mem_reg_prop = [super::layout::RAM_START.raw_value() as u64, mem_size as u64];
let mem_reg_prop = [super::layout::RAM_START.raw_value(), mem_size];
let memory_node_name = format!("memory@{:x}", super::layout::RAM_START.raw_value());
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
@@ -280,10 +278,7 @@ fn create_memory_node(
// Region 2: RAM after the hole
let mem_size = last_addr - super::layout::RAM_64BIT_START.raw_value() + 1;
let mem_reg_prop = [
super::layout::RAM_64BIT_START.raw_value() as u64,
mem_size as u64,
];
let mem_reg_prop = [super::layout::RAM_64BIT_START.raw_value(), mem_size];
let memory_node_name =
format!("memory@{:x}", super::layout::RAM_64BIT_START.raw_value());
let memory_node = fdt.begin_node(&memory_node_name)?;
@@ -305,7 +300,7 @@ fn create_chosen_node(
fdt.property_string("bootargs", cmdline)?;
if let Some(initrd_config) = initrd {
let initrd_start = initrd_config.address.raw_value() as u64;
let initrd_start = initrd_config.address.raw_value();
let initrd_end = initrd_config.address.raw_value() + initrd_config.size as u64;
fdt.property_u64("linux,initrd-start", initrd_start)?;
fdt.property_u64("linux,initrd-end", initrd_end)?;
@@ -541,16 +536,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 +667,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

@@ -19,7 +19,7 @@ use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestUsize};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic, GuestUsize};
/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
@@ -64,9 +64,9 @@ pub struct EntryPoint {
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<u64> {
if let Some(kernel_entry_point) = kernel_entry_point {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
vcpu.setup_regs(
id,
kernel_entry_point.entry_addr.raw_value(),
@@ -108,7 +108,7 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
// RAM space
// Case1: guest memory fits before the gap
if size as u64 <= ram_32bit_space_size {
if size <= ram_32bit_space_size {
regions.push((layout::RAM_START, size as usize, RegionType::Ram));
// Case2: guest memory extends beyond the gap
} else {
@@ -231,7 +231,7 @@ mod tests {
layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START) as usize;
assert_eq!(6, regions.len());
assert_eq!(layout::RAM_START, regions[3].0);
assert_eq!(ram_32bit_space_size as usize, regions[3].1);
assert_eq!(ram_32bit_space_size, regions[3].1);
assert_eq!(RegionType::Ram, regions[3].2);
assert_eq!(RegionType::Reserved, regions[5].2);
assert_eq!(RegionType::Ram, regions[4].2);

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

@@ -99,7 +99,7 @@ pub use x86_64::{
#[cfg(target_arch = "x86_64")]
#[inline(always)]
fn pagesize() -> usize {
// Trivially safe
// SAFETY: Trivially safe
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
}
@@ -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

@@ -125,9 +125,11 @@ struct MemmapTableEntryWrapper(hvm_memmap_table_entry);
#[derive(Copy, Clone, Default)]
struct ModlistEntryWrapper(hvm_modlist_entry);
// SAFETY: These data structures only contain a series of integers
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for StartInfoWrapper {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for MemmapTableEntryWrapper {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for ModlistEntryWrapper {}
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
@@ -231,7 +233,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 => {
@@ -545,13 +547,30 @@ impl CpuidFeatureEntry {
}
pub fn generate_common_cpuid(
hypervisor: Arc<dyn hypervisor::Hypervisor>,
hypervisor: &Arc<dyn hypervisor::Hypervisor>,
topology: Option<(u8, u8, u8)>,
sgx_epc_sections: Option<Vec<SgxEpcSection>>,
phys_bits: u8,
kvm_hyperv: bool,
#[cfg(feature = "tdx")] tdx_enabled: bool,
) -> super::Result<Vec<CpuIdEntry>> {
// SAFETY: cpuid called with valid leaves
if unsafe { x86_64::__cpuid(1) }.ecx & 1 << HYPERVISOR_ECX_BIT == 1 << HYPERVISOR_ECX_BIT {
// SAFETY: cpuid called with valid leaves
let hypervisor_cpuid = unsafe { x86_64::__cpuid(0x4000_0000) };
let mut identifier: [u8; 12] = [0; 12];
identifier[0..4].copy_from_slice(&hypervisor_cpuid.ebx.to_le_bytes()[..]);
identifier[4..8].copy_from_slice(&hypervisor_cpuid.ecx.to_le_bytes()[..]);
identifier[8..12].copy_from_slice(&hypervisor_cpuid.edx.to_le_bytes()[..]);
info!(
"Running under nested virtualisation. Hypervisor string: {}",
String::from_utf8_lossy(&identifier)
);
}
info!("Generating guest CPUID for with physical address size: {phys_bits}");
let cpuid_patches = vec![
// Patch tsc deadline timer bit
CpuidPatch {
@@ -631,6 +650,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);
@@ -661,6 +694,7 @@ pub fn generate_common_cpuid(
// Copy CPU identification string
for i in 0x8000_0002..=0x8000_0004 {
cpuid.retain(|c| c.function != i);
// SAFETY: call cpuid with valid leaves
let leaf = unsafe { std::arch::x86_64::__cpuid(i) };
cpuid.push(CpuIdEntry {
function: i,
@@ -725,8 +759,7 @@ pub fn generate_common_cpuid(
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
cpuid: Vec<CpuIdEntry>,
kvm_hyperv: bool,
) -> super::Result<()> {
@@ -743,12 +776,12 @@ pub fn configure_vcpu(
}
regs::setup_msrs(vcpu).map_err(Error::MsrsConfiguration)?;
if let Some(kernel_entry_point) = kernel_entry_point {
if let Some((kernel_entry_point, guest_memory)) = boot_setup {
if let Some(entry_addr) = kernel_entry_point.entry_addr {
// Safe to unwrap because this method is called after the VM is configured
regs::setup_regs(vcpu, entry_addr.raw_value()).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&vm_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
regs::setup_sregs(&guest_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
}
}
interrupts::set_lint(vcpu).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
@@ -764,11 +797,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 +898,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 +967,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,
);
}
@@ -1011,6 +1044,7 @@ pub fn initramfs_load_addr(
}
pub fn get_host_cpu_phys_bits() -> u8 {
// SAFETY: call cpuid with valid leaves
unsafe {
let leaf = x86_64::__cpuid(0x8000_0000);
@@ -1121,12 +1155,13 @@ fn update_cpuid_sgx(
// Get host CPUID for leaf 0x12, subleaf 0x2. This is to retrieve EPC
// properties such as confidentiality and integrity.
// SAFETY: call cpuid with valid leaves
let leaf = unsafe { std::arch::x86_64::__cpuid_count(0x12, 0x2) };
for (i, epc_section) in epc_sections.iter().enumerate() {
let subleaf_idx = i + 2;
let start = epc_section.start().raw_value();
let size = epc_section.size() 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 +1337,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

@@ -37,11 +37,17 @@ struct MpfIntelWrapper(mpspec::mpf_intel);
// SAFETY: These `mpspec` wrapper types are only data, reading them from data is a safe initialization.
unsafe impl ByteValued for MpcBusWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpcCpuWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpcIntsrcWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpcIoapicWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpcTableWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpcLintsrcWrapper {}
// SAFETY: see above
unsafe impl ByteValued for MpfIntelWrapper {}
#[derive(Debug)]
@@ -95,7 +101,7 @@ const CPU_FEATURE_APIC: u32 = 0x200;
const CPU_FEATURE_FPU: u32 = 0x001;
fn compute_checksum<T: Copy>(v: &T) -> u8 {
// Safe because we are only reading the bytes within the size of the `T` reference `v`.
// SAFETY: we are only reading the bytes within the size of the `T` reference `v`.
let v_slice = unsafe { slice::from_raw_parts(v as *const T as *const u8, mem::size_of::<T>()) };
let mut checksum: u8 = 0;
for i in v_slice.iter() {
@@ -294,7 +300,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}")
}
}
@@ -67,7 +67,7 @@ const PCI_SUPPORTED: u64 = 1 << 7;
const IS_VIRTUAL_MACHINE: u8 = 1 << 4;
fn compute_checksum<T: Copy>(v: &T) -> u8 {
// Safe because we are only reading the bytes within the size of the `T` reference `v`.
// SAFETY: we are only reading the bytes within the size of the `T` reference `v`.
let v_slice = unsafe { slice::from_raw_parts(v as *const T as *const u8, mem::size_of::<T>()) };
let mut checksum: u8 = 0;
for i in v_slice.iter() {
@@ -145,11 +145,15 @@ struct SmbiosEndOfTable {
handle: u16,
}
// SAFETY: These data structures only contain a series of integers
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for Smbios30Entrypoint {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for SmbiosBiosInfo {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for SmbiosSysInfo {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for SmbiosOemStrings {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for SmbiosEndOfTable {}
fn write_and_incr<T: ByteValued>(

View File

@@ -4,7 +4,9 @@
use crate::GuestMemoryMmap;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::str::FromStr;
use thiserror::Error;
use uuid::Uuid;
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemoryError};
#[derive(Error, Debug)]
@@ -13,6 +15,8 @@ pub enum TdvfError {
ReadDescriptor(#[source] std::io::Error),
#[error("Failed read TDVF descriptor offset: {0}")]
ReadDescriptorOffset(#[source] std::io::Error),
#[error("Failed read GUID table: {0}")]
ReadGuidTable(#[source] std::io::Error),
#[error("Invalid descriptor signature")]
InvalidDescriptorSignature,
#[error("Invalid descriptor size")]
@@ -21,8 +25,13 @@ pub enum TdvfError {
InvalidDescriptorVersion,
#[error("Failed to write HOB details to guest memory: {0}")]
GuestMemoryWriteHob(#[source] GuestMemoryError),
#[error("Failed to create Uuid: {0}")]
UuidCreation(#[source] uuid::Error),
}
const TABLE_FOOTER_GUID: &str = "96b582de-1fb2-45f7-baea-a366c55a082d";
const TDVF_METADATA_OFFSET_GUID: &str = "e47a6535-984a-4798-865e-4685a7bf8ec2";
// TDVF_DESCRIPTOR
#[repr(packed)]
#[derive(Default)]
@@ -64,7 +73,72 @@ impl Default for TdvfSectionType {
}
}
pub fn parse_tdvf_sections(file: &mut File) -> Result<Vec<TdvfSection>, TdvfError> {
fn tdvf_descriptor_offset(file: &mut File) -> Result<(SeekFrom, bool), TdvfError> {
// Let's first try to identify the presence of the table footer GUID
file.seek(SeekFrom::End(-0x30))
.map_err(TdvfError::ReadGuidTable)?;
let mut table_footer_guid: [u8; 16] = [0; 16];
file.read_exact(&mut table_footer_guid)
.map_err(TdvfError::ReadGuidTable)?;
let uuid =
Uuid::from_slice_le(table_footer_guid.as_slice()).map_err(TdvfError::UuidCreation)?;
let expected_uuid = Uuid::from_str(TABLE_FOOTER_GUID).map_err(TdvfError::UuidCreation)?;
if uuid == expected_uuid {
// Retrieve the table size
file.seek(SeekFrom::End(-0x32))
.map_err(TdvfError::ReadGuidTable)?;
let mut table_size: [u8; 2] = [0; 2];
file.read_exact(&mut table_size)
.map_err(TdvfError::ReadGuidTable)?;
let table_size = u16::from_le_bytes(table_size) as usize;
let mut table: Vec<u8> = vec![0; table_size];
// Read the entire table
file.seek(SeekFrom::End(-(table_size as i64 + 0x20)))
.map_err(TdvfError::ReadGuidTable)?;
file.read_exact(table.as_mut_slice())
.map_err(TdvfError::ReadGuidTable)?;
// Let's start from the top and go backward down the table.
// We start after the footer GUID and the table length.
let mut offset = table_size - 18;
debug!("Parsing GUIDed structure");
while offset >= 18 {
let entry_uuid = Uuid::from_slice_le(&table[offset - 16..offset])
.map_err(TdvfError::UuidCreation)?;
let entry_size =
u16::from_le_bytes(table[offset - 18..offset - 16].try_into().unwrap()) as usize;
debug!(
"Entry GUID = {}, size = {}",
entry_uuid.hyphenated().to_string(),
entry_size
);
// Avoid going through an infinite loop if the entry size is 0
if entry_size == 0 {
break;
}
offset -= entry_size;
let expected_uuid =
Uuid::from_str(TDVF_METADATA_OFFSET_GUID).map_err(TdvfError::UuidCreation)?;
if entry_uuid == expected_uuid && entry_size == 22 {
return Ok((
SeekFrom::End(
-(u32::from_le_bytes(table[offset..offset + 4].try_into().unwrap()) as i64),
),
true,
));
}
}
}
// If we end up here, this means the firmware doesn't support the new way
// of exposing the TDVF descriptor offset through the table of GUIDs.
// That's why we fallback onto the deprecated method.
// The 32-bit offset to the TDVF metadata is located 32 bytes from
// the end of the file.
// See "TDVF Metadata Pointer" in "TDX Virtual Firmware Design Guide
@@ -74,13 +148,21 @@ pub fn parse_tdvf_sections(file: &mut File) -> Result<Vec<TdvfSection>, TdvfErro
let mut descriptor_offset: [u8; 4] = [0; 4];
file.read_exact(&mut descriptor_offset)
.map_err(TdvfError::ReadDescriptorOffset)?;
let descriptor_offset = u32::from_le_bytes(descriptor_offset) as u64;
file.seek(SeekFrom::Start(descriptor_offset))
Ok((
SeekFrom::Start(u32::from_le_bytes(descriptor_offset) as u64),
false,
))
}
pub fn parse_tdvf_sections(file: &mut File) -> Result<(Vec<TdvfSection>, bool), TdvfError> {
let (descriptor_offset, guid_found) = tdvf_descriptor_offset(file)?;
file.seek(descriptor_offset)
.map_err(TdvfError::ReadDescriptor)?;
let mut descriptor: TdvfDescriptor = Default::default();
// Safe as we read exactly the size of the descriptor header
// SAFETY: we read exactly the size of the descriptor header
file.read_exact(unsafe {
std::slice::from_raw_parts_mut(
&mut descriptor as *mut _ as *mut u8,
@@ -107,7 +189,7 @@ pub fn parse_tdvf_sections(file: &mut File) -> Result<Vec<TdvfSection>, TdvfErro
let mut sections = Vec::new();
sections.resize_with(descriptor.num_sections as usize, TdvfSection::default);
// Safe as we read exactly the advertised sections
// SAFETY: we read exactly the advertised sections
file.read_exact(unsafe {
std::slice::from_raw_parts_mut(
sections.as_mut_ptr() as *mut u8,
@@ -116,7 +198,7 @@ pub fn parse_tdvf_sections(file: &mut File) -> Result<Vec<TdvfSection>, TdvfErro
})
.map_err(TdvfError::ReadDescriptor)?;
Ok(sections)
Ok((sections, guid_found))
}
#[repr(u16)]
@@ -211,12 +293,17 @@ struct TdPayload {
payload_info: PayloadInfo,
}
// SAFETY: These data structures only contain a series of integers
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for HobHeader {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for HobHandoffInfoTable {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for HobResourceDescriptor {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for HobGuidType {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for PayloadInfo {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for TdPayload {}
pub struct TdHob {
@@ -312,12 +399,19 @@ impl TdHob {
physical_start: u64,
resource_length: u64,
ram: bool,
guid_found: bool,
) -> Result<(), TdvfError> {
self.add_resource(
mem,
physical_start,
resource_length,
if ram {
if guid_found {
0x7 /* EFI_RESOURCE_MEMORY_UNACCEPTED */
} else {
0 /* EFI_RESOURCE_SYSTEM_MEMORY */
}
} else if guid_found {
0 /* EFI_RESOURCE_SYSTEM_MEMORY */
} else {
0x5 /*EFI_RESOURCE_MEMORY_RESERVED */
@@ -445,9 +539,9 @@ mod tests {
#[ignore]
fn test_parse_tdvf_sections() {
let mut f = std::fs::File::open("tdvf.fd").unwrap();
let sections = parse_tdvf_sections(&mut f).unwrap();
let (sections, _) = parse_tdvf_sections(&mut f).unwrap();
for section in sections {
eprintln!("{:x?}", section)
eprintln!("{section:x?}")
}
}
}

View File

@@ -8,17 +8,18 @@ edition = "2021"
default = []
[dependencies]
io-uring = "0.5.3"
libc = "0.2.131"
io-uring = "0.5.11"
libc = "0.2.139"
log = "0.4.17"
qcow = { path = "../qcow" }
thiserror = "1.0.32"
versionize = "0.1.6"
smallvec = "1.10.0"
thiserror = "1.0.38"
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

@@ -3,7 +3,6 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use libc::{ioctl, S_IFBLK, S_IFMT};
use std::convert::TryInto;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use thiserror::Error;
@@ -54,19 +53,21 @@ enum BlockSize {
impl DiskTopology {
fn is_block_device(f: &mut File) -> std::io::Result<bool> {
let mut stat = std::mem::MaybeUninit::<libc::stat>::uninit();
// SAFETY: FFI call with a valid fd and buffer
let ret = unsafe { libc::fstat(f.as_raw_fd(), stat.as_mut_ptr()) };
if ret != 0 {
return Err(std::io::Error::last_os_error());
}
// SAFETY: stat is valid at this point
let is_block = unsafe { (*stat.as_ptr()).st_mode & S_IFMT == S_IFBLK };
Ok(is_block)
}
// libc::ioctl() takes different types on different architectures
#[allow(clippy::useless_conversion)]
fn query_block_size(f: &mut File, block_size_type: BlockSize) -> std::io::Result<u64> {
let mut block_size = 0;
// SAFETY: FFI call with correct arguments
let ret = unsafe {
ioctl(
f.as_raw_fd(),
@@ -75,9 +76,7 @@ impl DiskTopology {
BlockSize::PhysicalBlock => BLKPBSZGET(),
BlockSize::MinimumIo => BLKIOMIN(),
BlockSize::OptimalIo => BLKIOOPT(),
}
.try_into()
.unwrap(),
} as _,
&mut block_size,
)
};
@@ -132,15 +131,15 @@ pub trait AsyncIo: Send {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()>;
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()>;
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()>;
fn complete(&mut self) -> Vec<(u64, i32)>;
fn next_completed_request(&mut self) -> Option<(u64, i32)>;
}

View File

@@ -64,7 +64,7 @@ impl AsyncIo for FixedVhdAsync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
@@ -83,7 +83,7 @@ impl AsyncIo for FixedVhdAsync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
@@ -104,7 +104,7 @@ impl AsyncIo for FixedVhdAsync {
self.raw_file_async.fsync(user_data)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.raw_file_async.complete()
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.raw_file_async.next_completed_request()
}
}

View File

@@ -62,7 +62,7 @@ impl AsyncIo for FixedVhdSync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
@@ -81,7 +81,7 @@ impl AsyncIo for FixedVhdSync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
@@ -101,7 +101,7 @@ impl AsyncIo for FixedVhdSync {
self.raw_file_sync.fsync(user_data)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.raw_file_sync.complete()
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.raw_file_sync.next_completed_request()
}
}

View File

@@ -22,8 +22,10 @@ pub mod vhdx_sync;
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
use io_uring::{opcode, IoUring, Probe};
use smallvec::SmallVec;
use std::alloc::{alloc_zeroed, dealloc, Layout};
use std::cmp;
use std::collections::VecDeque;
use std::convert::TryInto;
use std::fs::File;
use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
@@ -32,6 +34,7 @@ use std::path::Path;
use std::result;
use std::sync::Arc;
use std::sync::MutexGuard;
use std::time::Instant;
use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
@@ -51,23 +54,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,
}
@@ -195,10 +198,11 @@ pub struct AlignedOperation {
pub struct Request {
pub request_type: RequestType,
pub sector: u64,
pub data_descriptors: Vec<(GuestAddress, u32)>,
pub data_descriptors: SmallVec<[(GuestAddress, u32); 1]>,
pub status_addr: GuestAddress,
pub writeback: bool,
pub aligned_operations: Vec<AlignedOperation>,
pub start: Instant,
}
impl Request {
@@ -226,10 +230,11 @@ impl Request {
let mut req = Request {
request_type: request_type(desc_chain.memory(), hdr_desc_addr)?,
sector: sector(desc_chain.memory(), hdr_desc_addr)?,
data_descriptors: Vec::new(),
data_descriptors: SmallVec::with_capacity(1),
status_addr: GuestAddress(0),
writeback: true,
aligned_operations: Vec::new(),
start: Instant::now(),
};
let status_desc;
@@ -249,6 +254,7 @@ impl Request {
return Err(Error::DescriptorChainTooShort);
}
} else {
req.data_descriptors.reserve_exact(1);
while desc.has_next() {
if desc.is_write_only() && req.request_type == RequestType::Out {
return Err(Error::UnexpectedWriteOnlyDescriptor);
@@ -353,7 +359,8 @@ impl Request {
let request_type = self.request_type;
let offset = (sector << SECTOR_SHIFT) as libc::off_t;
let mut iovecs = Vec::new();
let mut iovecs: SmallVec<[libc::iovec; 1]> =
SmallVec::with_capacity(self.data_descriptors.len());
for (data_addr, data_len) in &self.data_descriptors {
if *data_len == 0 {
continue;
@@ -381,7 +388,7 @@ impl Request {
let iov_base = if (origin_ptr as u64) % SECTOR_SIZE != 0 {
let layout =
Layout::from_size_align(*data_len as usize, SECTOR_SIZE as usize).unwrap();
// Safe because layout has non-zero size
// SAFETY: layout has non-zero size
let aligned_ptr = unsafe { alloc_zeroed(layout) };
if aligned_ptr.is_null() {
return Err(ExecuteError::TemporaryBufferAllocation(
@@ -392,7 +399,7 @@ impl Request {
// We need to perform the copy beforehand in case we're writing
// data out.
if request_type == RequestType::Out {
// Safe because destination buffer has been allocated with
// SAFETY: destination buffer has been allocated with
// the proper size.
unsafe {
std::ptr::copy(origin_ptr as *const u8, aligned_ptr, *data_len as usize)
@@ -430,12 +437,12 @@ impl Request {
.mark_dirty(0, *data_len as usize);
}
disk_image
.read_vectored(offset, iovecs, user_data)
.read_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncRead)?;
}
RequestType::Out => {
disk_image
.write_vectored(offset, iovecs, user_data)
.write_vectored(offset, &iovecs, user_data)
.map_err(ExecuteError::AsyncWrite)?;
}
RequestType::Flush => {
@@ -467,7 +474,7 @@ impl Request {
// We need to perform the copy after the data has been read inside
// the aligned buffer in case we're reading data in.
if self.request_type == RequestType::In {
// Safe because origin buffer has been allocated with the
// SAFETY: origin buffer has been allocated with the
// proper size.
unsafe {
std::ptr::copy(
@@ -479,7 +486,7 @@ impl Request {
}
// Free the temporary aligned buffer.
// Safe because aligned_ptr was allocated by alloc_zeroed with the same
// SAFETY: aligned_ptr was allocated by alloc_zeroed with the same
// layout
unsafe {
dealloc(
@@ -528,8 +535,9 @@ pub struct VirtioBlockGeometry {
pub sectors: u8,
}
// SAFETY: these data structures only contain a series of integers
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for VirtioBlockConfig {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for VirtioBlockGeometry {}
/// Check if io_uring for block device can be used on the current system, as
@@ -566,15 +574,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;
}
@@ -588,14 +596,15 @@ where
fn read_vectored_sync(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSliceMut
let mut slices = Vec::new();
for iovec in iovecs.iter() {
// SAFETY: on Linux IoSliceMut wraps around libc::iovec
slices.push(IoSliceMut::new(unsafe { std::mem::transmute(*iovec) }));
}
@@ -611,7 +620,7 @@ where
.map_err(AsyncIoError::ReadVectored)?
};
completion_list.push((user_data, result as i32));
completion_list.push_back((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
@@ -620,14 +629,15 @@ where
fn write_vectored_sync(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSlice
let mut slices = Vec::new();
for iovec in iovecs.iter() {
// SAFETY: on Linux IoSliceMut wraps around libc::iovec
slices.push(IoSlice::new(unsafe { std::mem::transmute(*iovec) }));
}
@@ -643,7 +653,7 @@ where
.map_err(AsyncIoError::WriteVectored)?
};
completion_list.push((user_data, result as i32));
completion_list.push_back((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
@@ -653,7 +663,7 @@ where
&mut self,
user_data: Option<u64>,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
completion_list: &mut VecDeque<(u64, i32)>,
) -> AsyncIoResult<()> {
let result: i32 = {
let mut file = self.file();
@@ -665,7 +675,7 @@ where
};
if let Some(user_data) = user_data {
completion_list.push((user_data, result));
completion_list.push_back((user_data, result));
eventfd.write(1).unwrap();
}

View File

@@ -5,6 +5,7 @@
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult};
use crate::AsyncAdaptor;
use qcow::{QcowFile, RawFile, Result as QcowResult};
use std::collections::VecDeque;
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::sync::{Arc, Mutex, MutexGuard};
@@ -26,7 +27,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>> {
@@ -37,7 +38,7 @@ impl DiskFile for QcowDiskSync {
pub struct QcowSync {
qcow_file: Arc<Mutex<QcowFile>>,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
completion_list: VecDeque<(u64, i32)>,
}
impl QcowSync {
@@ -46,7 +47,7 @@ impl QcowSync {
qcow_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)
.expect("Failed creating EventFd for QcowSync"),
completion_list: Vec::new(),
completion_list: VecDeque::new(),
}
}
}
@@ -65,7 +66,7 @@ impl AsyncIo for QcowSync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
self.qcow_file.read_vectored_sync(
@@ -80,7 +81,7 @@ impl AsyncIo for QcowSync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
self.qcow_file.write_vectored_sync(
@@ -97,7 +98,7 @@ impl AsyncIo for QcowSync {
.fsync_sync(user_data, &self.eventfd, &mut self.completion_list)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.completion_list.drain(..).collect()
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.completion_list.pop_front()
}
}

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>> {
@@ -77,12 +76,12 @@ impl AsyncIo for RawFileAsync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid and we
// SAFETY: we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
sq.push(
@@ -105,12 +104,12 @@ impl AsyncIo for RawFileAsync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid and we
// SAFETY: we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
sq.push(
@@ -134,7 +133,7 @@ impl AsyncIo for RawFileAsync {
if let Some(user_data) = user_data {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid.
// SAFETY: we know the file descriptor is valid.
let _ = unsafe {
sq.push(
&opcode::Fsync::new(types::Fd(self.fd))
@@ -149,20 +148,17 @@ impl AsyncIo for RawFileAsync {
sq.sync();
submitter.submit().map_err(AsyncIoError::Fsync)?;
} else {
// SAFETY: FFI call with a valid fd
unsafe { libc::fsync(self.fd) };
}
Ok(())
}
fn complete(&mut self) -> Vec<(u64, i32)> {
let mut completion_list = Vec::new();
let cq = self.io_uring.completion();
for cq_entry in cq {
completion_list.push((cq_entry.user_data(), cq_entry.result()));
}
completion_list
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.io_uring
.completion()
.next()
.map(|entry| (entry.user_data(), entry.result()))
}
}

View File

@@ -5,6 +5,7 @@
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, DiskTopology,
};
use std::collections::VecDeque;
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::os::unix::io::{AsRawFd, RawFd};
@@ -22,10 +23,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>> {
@@ -45,7 +45,7 @@ impl DiskFile for RawFileDiskSync {
pub struct RawFileSync {
fd: RawFd,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
completion_list: VecDeque<(u64, i32)>,
}
impl RawFileSync {
@@ -53,7 +53,7 @@ impl RawFileSync {
RawFileSync {
fd,
eventfd: EventFd::new(libc::EFD_NONBLOCK).expect("Failed creating EventFd for RawFile"),
completion_list: Vec::new(),
completion_list: VecDeque::new(),
}
}
}
@@ -66,9 +66,10 @@ impl AsyncIo for RawFileSync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
// SAFETY: FFI call with valid arguments
let result = unsafe {
libc::preadv(
self.fd as libc::c_int,
@@ -81,7 +82,7 @@ impl AsyncIo for RawFileSync {
return Err(AsyncIoError::ReadVectored(std::io::Error::last_os_error()));
}
self.completion_list.push((user_data, result as i32));
self.completion_list.push_back((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
@@ -90,9 +91,10 @@ impl AsyncIo for RawFileSync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
// SAFETY: FFI call with valid arguments
let result = unsafe {
libc::pwritev(
self.fd as libc::c_int,
@@ -105,27 +107,28 @@ impl AsyncIo for RawFileSync {
return Err(AsyncIoError::WriteVectored(std::io::Error::last_os_error()));
}
self.completion_list.push((user_data, result as i32));
self.completion_list.push_back((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
// SAFETY: FFI call
let result = unsafe { libc::fsync(self.fd as libc::c_int) };
if result < 0 {
return Err(AsyncIoError::Fsync(std::io::Error::last_os_error()));
}
if let Some(user_data) = user_data {
self.completion_list.push((user_data, result as i32));
self.completion_list.push_back((user_data, result));
self.eventfd.write(1).unwrap();
}
Ok(())
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.completion_list.drain(..).collect()
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.completion_list.pop_front()
}
}

View File

@@ -4,6 +4,7 @@
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult};
use crate::AsyncAdaptor;
use std::collections::VecDeque;
use std::fs::File;
use std::sync::{Arc, Mutex, MutexGuard};
use vhdx::vhdx::{Result as VhdxResult, Vhdx};
@@ -37,7 +38,7 @@ impl DiskFile for VhdxDiskSync {
pub struct VhdxSync {
vhdx_file: Arc<Mutex<Vhdx>>,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
completion_list: VecDeque<(u64, i32)>,
}
impl VhdxSync {
@@ -45,7 +46,7 @@ impl VhdxSync {
Ok(VhdxSync {
vhdx_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)?,
completion_list: Vec::new(),
completion_list: VecDeque::new(),
})
}
}
@@ -64,7 +65,7 @@ impl AsyncIo for VhdxSync {
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
self.vhdx_file.read_vectored_sync(
@@ -79,7 +80,7 @@ impl AsyncIo for VhdxSync {
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
self.vhdx_file.write_vectored_sync(
@@ -96,7 +97,7 @@ impl AsyncIo for VhdxSync {
.fsync_sync(user_data, &self.eventfd, &mut self.completion_list)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.completion_list.drain(..).collect()
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
self.completion_list.pop_front()
}
}

View File

@@ -3,15 +3,12 @@
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use(crate_version)]
extern crate clap;
use std::process::Command;
fn main() {
let mut version = "v".to_owned() + crate_version!();
let mut version = "v".to_owned() + env!("CARGO_PKG_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 +20,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.68"
arch = { path = "../arch" }
bitflags = "1.3.2"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.131"
libc = "0.2.139"
log = "0.4.17"
versionize = "0.1.6"
phf = { version = "0.11.1", features = ["macros"] }
thiserror = "1.0.38"
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, GicState,
};
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;
@@ -22,6 +25,7 @@ type Result<T> = result::Result<T, Error>;
// Reserve 32 IRQs for legacy devices.
pub const IRQ_LEGACY_BASE: usize = layout::IRQ_BASE as usize;
pub const IRQ_LEGACY_COUNT: usize = 32;
pub const GIC_SNAPSHOT_ID: &str = "gic-v3-its";
// Gic (Generic Interupt Controller) struct provides all the functionality of a
// GIC device. It wraps a hypervisor-emulated GIC device (Vgic) provided by the
@@ -36,8 +40,9 @@ pub struct Gic {
impl Gic {
pub fn new(
_vcpu_count: u8,
vcpu_count: u8,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vm: Arc<dyn hypervisor::Vm>,
) -> Result<Gic> {
let interrupt_source_group = interrupt_manager
.create_group(MsiIrqGroupConfig {
@@ -46,38 +51,34 @@ impl Gic {
})
.map_err(Error::CreateInterruptSourceGroup)?;
Ok(Gic {
interrupt_source_group,
vgic: None,
})
}
pub fn create_vgic(
&mut self,
vm: &Arc<dyn hypervisor::Vm>,
vcpu_count: u64,
) -> 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,
)
.create_vgic(Gic::create_default_config(vcpu_count as u64))
.map_err(Error::CreateGic)?;
self.vgic = Some(vgic.clone());
Ok(vgic.clone())
let gic = Gic {
interrupt_source_group,
vgic: Some(vgic),
};
gic.enable()?;
Ok(gic)
}
pub fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock().unwrap().set_gicr_typers(vcpu_states);
pub fn restore_vgic(
&mut self,
state: Option<GicState>,
saved_vcpu_states: &[CpuState],
) -> Result<()> {
self.set_gicr_typers(saved_vcpu_states);
self.vgic
.clone()
.unwrap()
.lock()
.unwrap()
.set_state(&state.unwrap())
.map_err(Error::RestoreGic)
}
}
impl InterruptController for Gic {
fn enable(&self) -> Result<()> {
// Set irqfd for legacy interrupts
self.interrupt_source_group
@@ -103,6 +104,33 @@ impl InterruptController for Gic {
Ok(())
}
/// 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 get_vgic(&mut self) -> Result<Arc<Mutex<dyn Vgic>>> {
Ok(self.vgic.clone().unwrap())
}
pub fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock().unwrap().set_gicr_typers(vcpu_states);
}
}
impl InterruptController for Gic {
// This should be called anytime an interrupt needs to be injected into the
// running guest.
fn service_irq(&mut self, irq: usize) -> Result<()> {
@@ -118,27 +146,15 @@ impl InterruptController for Gic {
}
}
pub const GIC_V3_ITS_SNAPSHOT_ID: &str = "gic-v3-its";
impl Snapshottable for Gic {
fn id(&self) -> String {
GIC_V3_ITS_SNAPSHOT_ID.to_string()
GIC_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let vgic = self.vgic.as_ref().unwrap().clone();
let state = vgic.lock().unwrap().state().unwrap();
Snapshot::new_from_state(&self.id(), &state)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock()
.unwrap()
.set_state(&snapshot.to_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3ITS state {:?}", e))
})?;
Ok(())
Snapshot::new_from_state(&state)
}
}

View File

@@ -24,8 +24,12 @@ pub enum Error {
UpdateInterrupt(io::Error),
/// Failed enabling the interrupt.
EnableInterrupt(io::Error),
#[cfg(target_arch = "aarch64")]
/// Failed creating GIC device.
CreateGic(hypervisor::HypervisorVmError),
#[cfg(target_arch = "aarch64")]
/// Failed restoring GIC device.
RestoreGic(hypervisor::arch::aarch64::gic::Error),
}
type Result<T> = result::Result<T, Error>;
@@ -55,8 +59,6 @@ pub struct MsiMessage {
// IOAPIC (X86) or GIC (Arm).
pub trait InterruptController: Send {
fn service_irq(&mut self, irq: usize) -> Result<()>;
#[cfg(target_arch = "aarch64")]
fn enable(&self) -> Result<()>;
#[cfg(target_arch = "x86_64")]
fn end_of_interrupt(&mut self, vec: u8);
fn notifier(&self, irq: usize) -> Option<EventFd>;

View File

@@ -10,7 +10,6 @@
// See https://pdos.csail.mit.edu/6.828/2016/readings/ia32/ioapic.pdf for a specification.
use super::interrupt_controller::{Error, InterruptController};
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
use std::result;
use std::sync::{Arc, Barrier};
@@ -194,6 +193,7 @@ impl Ioapic {
id: String,
apic_address: GuestAddress,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
state: Option<IoapicState>,
) -> Result<Ioapic> {
let interrupt_source_group = interrupt_manager
.create_group(MsiIrqGroupConfig {
@@ -202,17 +202,47 @@ impl Ioapic {
})
.map_err(Error::CreateInterruptSourceGroup)?;
let (id_reg, reg_sel, reg_entries, used_entries, apic_address) = if let Some(state) = &state
{
(
state.id_reg,
state.reg_sel,
state.reg_entries,
state.used_entries,
GuestAddress(state.apic_address),
)
} else {
(
0,
0,
[0x10000; NUM_IOAPIC_PINS],
[false; NUM_IOAPIC_PINS],
apic_address,
)
};
// The IOAPIC is created with entries already masked. The guest will be
// in charge of unmasking them if/when necessary.
Ok(Ioapic {
let ioapic = Ioapic {
id,
id_reg: 0,
reg_sel: 0,
reg_entries: [0x10000; NUM_IOAPIC_PINS],
used_entries: [false; NUM_IOAPIC_PINS],
id_reg,
reg_sel,
reg_entries,
used_entries,
apic_address,
interrupt_source_group,
})
};
// When restoring the Ioapic, we must enable used entries.
if state.is_some() {
for (irq, entry) in ioapic.used_entries.iter().enumerate() {
if *entry {
ioapic.update_entry(irq)?;
}
}
}
Ok(ioapic)
}
fn ioapic_write(&mut self, val: u32) {
@@ -299,21 +329,6 @@ impl Ioapic {
}
}
fn set_state(&mut self, state: &IoapicState) -> Result<()> {
self.id_reg = state.id_reg;
self.reg_sel = state.reg_sel;
self.reg_entries = state.reg_entries;
self.used_entries = state.used_entries;
self.apic_address = GuestAddress(state.apic_address);
for (irq, entry) in self.used_entries.iter().enumerate() {
if *entry {
self.update_entry(irq)?;
}
}
Ok(())
}
fn update_entry(&self, irq: usize) -> Result<()> {
let entry = self.reg_entries[irq];
@@ -423,18 +438,7 @@ impl Snapshottable for Ioapic {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id, &self.state())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.set_state(&snapshot.to_versioned_state(&self.id)?)
.map_err(|e| {
MigratableError::Restore(anyhow!(
"Could not restore state for {}: {:?}",
self.id,
e
))
})
Snapshot::new_from_versioned_state(&self.state())
}
}

View File

@@ -97,7 +97,7 @@ impl BusDevice for Cmos {
let day;
let month;
let year;
// The clock_gettime and gmtime_r calls are safe as long as the structs they are
// SAFETY: The clock_gettime and gmtime_r calls are safe as long as the structs they are
// given are large enough, and neither of them fail. It is safe to zero initialize
// the tm and timespec struct because it contains only plain data.
let update_in_progress = unsafe {

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}.")
}
}
}
@@ -106,18 +106,39 @@ impl VersionMapped for GpioState {}
impl Gpio {
/// Constructs an PL061 GPIO device.
pub fn new(id: String, interrupt: Arc<dyn InterruptSourceGroup>) -> Self {
pub fn new(
id: String,
interrupt: Arc<dyn InterruptSourceGroup>,
state: Option<GpioState>,
) -> Self {
let (data, old_in_data, dir, isense, ibe, iev, im, istate, afsel) =
if let Some(state) = state {
(
state.data,
state.old_in_data,
state.dir,
state.isense,
state.ibe,
state.iev,
state.im,
state.istate,
state.afsel,
)
} else {
(0, 0, 0, 0, 0, 0, 0, 0, 0)
};
Self {
id,
data: 0,
old_in_data: 0,
dir: 0,
isense: 0,
ibe: 0,
iev: 0,
im: 0,
istate: 0,
afsel: 0,
data,
old_in_data,
dir,
isense,
ibe,
iev,
im,
istate,
afsel,
interrupt,
}
}
@@ -136,24 +157,12 @@ impl Gpio {
}
}
fn set_state(&mut self, state: &GpioState) {
self.data = state.data;
self.old_in_data = state.old_in_data;
self.dir = state.dir;
self.isense = state.isense;
self.ibe = state.ibe;
self.iev = state.iev;
self.im = state.im;
self.istate = state.istate;
self.afsel = state.afsel;
}
fn pl061_internal_update(&mut self) {
// FIXME:
// Missing Output Interrupt Emulation.
// Input Edging Interrupt Emulation.
let changed = ((self.old_in_data ^ self.data) & !self.dir) as u32;
let changed = (self.old_in_data ^ self.data) & !self.dir;
if changed > 0 {
self.old_in_data = self.data;
for i in 0..N_GPIOS {
@@ -319,12 +328,7 @@ impl Snapshottable for Gpio {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id, &self.state())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.set_state(&snapshot.to_versioned_state(&self.id)?);
Ok(())
Snapshot::new_from_versioned_state(&self.state())
}
}
@@ -378,6 +382,7 @@ mod tests {
let mut gpio = Gpio::new(
String::from(GPIO_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
None,
);
let mut data = [0; 4];

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}"),
}
}
}
@@ -61,12 +61,10 @@ pub enum ClockType {
/// Equivalent to `libc::CLOCK_MONOTONIC`.
Monotonic,
/// Equivalent to `libc::CLOCK_REALTIME`.
#[allow(dead_code)]
Real,
/// Equivalent to `libc::CLOCK_PROCESS_CPUTIME_ID`.
ProcessCpu,
/// Equivalent to `libc::CLOCK_THREAD_CPUTIME_ID`.
#[allow(dead_code)]
ThreadCpu,
}
@@ -101,7 +99,7 @@ pub struct LocalTime {
impl LocalTime {
/// Returns the [LocalTime](struct.LocalTime.html) structure for the calling moment.
#[allow(dead_code)]
#[cfg(test)]
pub fn now() -> LocalTime {
let mut timespec = libc::timespec {
tv_sec: 0,
@@ -121,7 +119,7 @@ impl LocalTime {
tm_zone: std::ptr::null(),
};
// Safe because the parameters are valid.
// SAFETY: the parameters are valid.
unsafe {
libc::clock_gettime(libc::CLOCK_REALTIME, &mut timespec);
libc::localtime_r(&timespec.tv_sec, &mut tm);
@@ -173,22 +171,6 @@ impl Default for TimestampUs {
}
}
/// Returns a timestamp in nanoseconds from a monotonic clock.
///
/// Uses `_rdstc` on `x86_64` and [`get_time`](fn.get_time.html) on other architectures.
#[allow(dead_code)]
pub fn timestamp_cycles() -> u64 {
#[cfg(target_arch = "x86_64")]
// Safe because there's nothing that can go wrong with this call.
unsafe {
std::arch::x86_64::_rdtsc() as u64
}
#[cfg(not(target_arch = "x86_64"))]
{
get_time(ClockType::Monotonic)
}
}
/// Returns a timestamp in nanoseconds based on the provided clock type.
///
/// # Arguments
@@ -199,7 +181,7 @@ pub fn get_time(clock_type: ClockType) -> u64 {
tv_sec: 0,
tv_nsec: 0,
};
// Safe because the parameters are valid.
// SAFETY: the parameters are valid.
unsafe { libc::clock_gettime(clock_type.into(), &mut time_struct) };
seconds_to_nanoseconds(time_struct.tv_sec).unwrap() as u64 + (time_struct.tv_nsec as u64)
}
@@ -525,7 +507,6 @@ mod tests {
($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr, $data_type: ty) => {
#[test]
fn $test_name() {
#[allow(overflowing_literals)]
let test_cases = [
(
0x0123_4567_89AB_CDEF as u64,

View File

@@ -63,7 +63,6 @@ pub struct Serial {
id: String,
interrupt_enable: u8,
interrupt_identification: u8,
interrupt: Arc<dyn InterruptSourceGroup>,
line_control: u8,
line_status: u8,
modem_control: u8,
@@ -71,6 +70,7 @@ pub struct Serial {
scratch: u8,
baud_divisor: u16,
in_buffer: VecDeque<u8>,
interrupt: Arc<dyn InterruptSourceGroup>,
out: Option<Box<dyn io::Write + Send>>,
}
@@ -93,19 +93,56 @@ impl Serial {
id: String,
interrupt: Arc<dyn InterruptSourceGroup>,
out: Option<Box<dyn io::Write + Send>>,
state: Option<SerialState>,
) -> Serial {
let (
interrupt_enable,
interrupt_identification,
line_control,
line_status,
modem_control,
modem_status,
scratch,
baud_divisor,
in_buffer,
) = if let Some(state) = state {
(
state.interrupt_enable,
state.interrupt_identification,
state.line_control,
state.line_status,
state.modem_control,
state.modem_status,
state.scratch,
state.baud_divisor,
state.in_buffer.into(),
)
} else {
(
0,
DEFAULT_INTERRUPT_IDENTIFICATION,
DEFAULT_LINE_CONTROL,
DEFAULT_LINE_STATUS,
DEFAULT_MODEM_CONTROL,
DEFAULT_MODEM_STATUS,
0,
DEFAULT_BAUD_DIVISOR,
VecDeque::new(),
)
};
Serial {
id,
interrupt_enable: 0,
interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION,
interrupt_enable,
interrupt_identification,
line_control,
line_status,
modem_control,
modem_status,
scratch,
baud_divisor,
in_buffer,
interrupt,
line_control: DEFAULT_LINE_CONTROL,
line_status: DEFAULT_LINE_STATUS,
modem_control: DEFAULT_MODEM_CONTROL,
modem_status: DEFAULT_MODEM_STATUS,
scratch: 0,
baud_divisor: DEFAULT_BAUD_DIVISOR,
in_buffer: VecDeque::new(),
out,
}
}
@@ -115,13 +152,18 @@ impl Serial {
id: String,
interrupt: Arc<dyn InterruptSourceGroup>,
out: Box<dyn io::Write + Send>,
state: Option<SerialState>,
) -> Serial {
Self::new(id, interrupt, Some(out))
Self::new(id, interrupt, Some(out), state)
}
/// Constructs a Serial port with no connected output.
pub fn new_sink(id: String, interrupt: Arc<dyn InterruptSourceGroup>) -> Serial {
Self::new(id, interrupt, None)
pub fn new_sink(
id: String,
interrupt: Arc<dyn InterruptSourceGroup>,
state: Option<SerialState>,
) -> Serial {
Self::new(id, interrupt, None, state)
}
pub fn set_out(&mut self, out: Box<dyn io::Write + Send>) {
@@ -199,7 +241,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)
}
@@ -242,18 +284,6 @@ impl Serial {
in_buffer: self.in_buffer.clone().into(),
}
}
fn set_state(&mut self, state: &SerialState) {
self.interrupt_enable = state.interrupt_enable;
self.interrupt_identification = state.interrupt_identification;
self.line_control = state.line_control;
self.line_status = state.line_status;
self.modem_control = state.modem_control;
self.modem_status = state.modem_status;
self.scratch = state.scratch;
self.baud_divisor = state.baud_divisor;
self.in_buffer = state.in_buffer.clone().into();
}
}
impl BusDevice for Serial {
@@ -304,12 +334,7 @@ impl Snapshottable for Serial {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id, &self.state())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.set_state(&snapshot.to_versioned_state(&self.id)?);
Ok(())
Snapshot::new_from_versioned_state(&self.state())
}
}
@@ -384,6 +409,7 @@ mod tests {
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Box::new(serial_out.clone()),
None,
);
serial.write(0, DATA as u64, &[b'x', b'y']);
@@ -404,6 +430,7 @@ mod tests {
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Box::new(serial_out),
None,
);
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
@@ -440,6 +467,7 @@ mod tests {
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
None,
);
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
@@ -462,6 +490,7 @@ mod tests {
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
None,
);
serial.write(0, LCR as u64, &[LCR_DLAB_BIT]);
@@ -483,6 +512,7 @@ mod tests {
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
None,
);
serial.write(0, MCR as u64, &[MCR_LOOP_BIT]);
@@ -509,6 +539,7 @@ mod tests {
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
None,
);
serial.write(0, SCR as u64, &[0x12]);

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}"),
}
}
}
@@ -122,24 +122,79 @@ impl Pl011 {
irq: Arc<dyn InterruptSourceGroup>,
out: Option<Box<dyn io::Write + Send>>,
timestamp: Instant,
state: Option<Pl011State>,
) -> Self {
let (
flags,
lcr,
rsr,
cr,
dmacr,
debug,
int_enabled,
int_level,
read_fifo,
ilpr,
ibrd,
fbrd,
ifl,
read_count,
read_trigger,
) = if let Some(state) = state {
(
state.flags,
state.lcr,
state.rsr,
state.cr,
state.dmacr,
state.debug,
state.int_enabled,
state.int_level,
state.read_fifo.into(),
state.ilpr,
state.ibrd,
state.fbrd,
state.ifl,
state.read_count,
state.read_trigger,
)
} else {
(
0x90,
0,
0,
0x300,
0,
0,
0,
0,
VecDeque::new(),
0,
0,
0,
0x12,
0,
1,
)
};
Self {
id,
flags: 0x90u32,
lcr: 0u32,
rsr: 0u32,
cr: 0x300u32,
dmacr: 0u32,
debug: 0u32,
int_enabled: 0u32,
int_level: 0u32,
read_fifo: VecDeque::new(),
ilpr: 0u32,
ibrd: 0u32,
fbrd: 0u32,
ifl: 0x12u32,
read_count: 0u32,
read_trigger: 1u32,
flags,
lcr,
rsr,
cr,
dmacr,
debug,
int_enabled,
int_level,
read_fifo,
ilpr,
ibrd,
fbrd,
ifl,
read_count,
read_trigger,
irq,
out,
timestamp,
@@ -170,24 +225,6 @@ impl Pl011 {
}
}
fn set_state(&mut self, state: &Pl011State) {
self.flags = state.flags;
self.lcr = state.lcr;
self.rsr = state.rsr;
self.cr = state.cr;
self.dmacr = state.dmacr;
self.debug = state.debug;
self.int_enabled = state.int_enabled;
self.int_level = state.int_level;
self.read_fifo = state.read_fifo.clone().into();
self.ilpr = state.ilpr;
self.ibrd = state.ibrd;
self.fbrd = state.fbrd;
self.ifl = state.ifl;
self.read_count = state.read_count;
self.read_trigger = state.read_trigger;
}
/// Queues raw bytes for the guest to read and signals the interrupt
pub fn queue_input_bytes(&mut self, c: &[u8]) -> vmm_sys_util::errno::Result<()> {
self.read_fifo.extend(c);
@@ -306,25 +343,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(),
@@ -417,12 +454,7 @@ impl Snapshottable for Pl011 {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id, &self.state())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.set_state(&snapshot.to_versioned_state(&self.id)?);
Ok(())
Snapshot::new_from_versioned_state(&self.state())
}
}
@@ -498,12 +530,13 @@ mod tests {
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Some(Box::new(pl011_out.clone())),
Instant::now(),
None,
);
pl011.write(0, UARTDR as u64, &[b'x', b'y']);
pl011.write(0, UARTDR as u64, &[b'a']);
pl011.write(0, UARTDR as u64, &[b'b']);
pl011.write(0, UARTDR as u64, &[b'c']);
pl011.write(0, UARTDR, &[b'x', b'y']);
pl011.write(0, UARTDR, &[b'a']);
pl011.write(0, UARTDR, &[b'b']);
pl011.write(0, UARTDR, &[b'c']);
assert_eq!(
pl011_out.buf.lock().unwrap().as_slice(),
&[b'x', b'a', b'b', b'c']
@@ -519,6 +552,7 @@ mod tests {
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Some(Box::new(pl011_out)),
Instant::now(),
None,
);
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
@@ -529,11 +563,11 @@ mod tests {
assert_eq!(intr_evt.read().unwrap(), 2);
let mut data = [0u8];
pl011.read(0, UARTDR as u64, &mut data);
pl011.read(0, UARTDR, &mut data);
assert_eq!(data[0], b'a');
pl011.read(0, UARTDR as u64, &mut data);
pl011.read(0, UARTDR, &mut data);
assert_eq!(data[0], b'b');
pl011.read(0, UARTDR as u64, &mut data);
pl011.read(0, UARTDR, &mut data);
assert_eq!(data[0], b'c');
}
}

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};
@@ -32,11 +33,9 @@ bitflags! {
}
}
#[allow(unused_macros)]
#[cfg(target_arch = "aarch64")]
macro_rules! generate_read_fn {
($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => {
#[allow(dead_code)]
pub fn $fn_name(input: &[$byte_type]) -> $data_type {
assert!($type_size == std::mem::size_of::<$data_type>());
let mut array = [0u8; $type_size];
@@ -48,11 +47,9 @@ macro_rules! generate_read_fn {
};
}
#[allow(unused_macros)]
#[cfg(target_arch = "aarch64")]
macro_rules! generate_write_fn {
($fn_name: ident, $data_type: ty, $byte_type: ty, $endian_type: ident) => {
#[allow(dead_code)]
pub fn $fn_name(buf: &mut [$byte_type], n: $data_type) {
for (byte, read) in buf
.iter_mut()

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))
);
}
}

View File

@@ -1,152 +0,0 @@
# How to build and test Cloud Hypervisor on AArch64
This document introduces how to build and test Cloud Hypervisor on AArch64.
Currently, Cloud Hypervisor supports 2 methods of booting on AArch64: UEFI
booting and direct-kernel booting. The document covers both methods.
All the steps are based on Ubuntu. We use the Ubuntu cloud image for guest VM
disk.
## Hardware requirements
- AArch64 servers (recommended) or development boards equipped with the GICv3
interrupt controller.
- On development boards that have constrained RAM resources, if the creation of
a VM consumes a large portion of the free memory on the host, it may be required
to enable swap. For example, this was required on a board with 3 GB of RAM
booting a 2 GB VM at a point in time when 2.8 GB were free. Without enabling
swap the `cloud-hypervisor` process was terminated by the OOM killer. In this
situation memory was allocated for the virtual machine using memfd while the
page cache was filled, leading to a situation where the kernel could not even
drop caches. Making a small section of swap available (observably, 1 to 15 MB),
this situation can be resolved and the resulting memory footprint of
`cloud-hypervisor` is as expected.
## Getting started
We create a folder to build and run Cloud Hypervisor at `$HOME/cloud-hypervisor`
```shell
$ export CLOUDH=$HOME/cloud-hypervisor
$ mkdir $CLOUDH
```
## Prerequisites
You need to install some prerequisite packages to build and test Cloud Hypervisor.
### Tools
```bash
# Install rust tool chain
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install the tools used for building guest kernel, EDK2 and converting guest disk
$ sudo apt-get update
$ sudo apt-get install git build-essential m4 bison flex uuid-dev qemu-utils
```
### Building Cloud Hypervisor
```bash
$ pushd $CLOUDH
$ git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
$ cd cloud-hypervisor
$ cargo build
$ popd
```
### Disk image
Download the Ubuntu cloud image and convert the image type.
```bash
$ pushd $CLOUDH
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-arm64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-arm64.img focal-server-cloudimg-arm64.raw
$ popd
```
## UEFI booting
This part introduces how to build EDK2 firmware and boot Cloud Hypervisor with it.
### Building EDK2
```bash
$ pushd $CLOUDH
# Clone source code repos
$ git clone --depth 1 https://github.com/tianocore/edk2.git -b master
$ cd edk2
$ git submodule update --init
$ cd ..
$ git clone --depth 1 https://github.com/tianocore/edk2-platforms.git -b master
$ git clone --depth 1 https://github.com/acpica/acpica.git -b master
# Build tools
$ export PACKAGES_PATH="$PWD/edk2:$PWD/edk2-platforms"
$ export IASL_PREFIX="$PWD/acpica/generate/unix/bin/"
$ make -C acpica
$ cd edk2/
$ . edksetup.sh
$ cd ..
$ make -C edk2/BaseTools
# Build EDK2
$ build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtCloudHv.dsc -b RELEASE
$ popd
```
If the build goes well, the EDK2 binary is available at
`edk2/Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd`.
### Booting the guest VM
```bash
$ pushd $CLOUDH
$ sudo RUST_BACKTRACE=1 $CLOUDH/cloud-hypervisor/target/debug/cloud-hypervisor \
--api-socket /tmp/cloud-hypervisor.sock \
--kernel $CLOUDH/edk2/Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd \
--disk path=$CLOUDH/focal-server-cloudimg-arm64.raw \
--cpus boot=4 \
--memory size=4096M \
--net tap=,mac=12:34:56:78:90:01,ip=192.168.1.1,mask=255.255.255.0 \
--serial tty \
--console off
$ popd
```
## Direct-kernel booting
Alternativelly, you can build your own kernel for guest VM. This way, UEFI is
not involved and ACPI cannot be enabled.
### Building kernel
```bash
$ pushd $CLOUDH
$ git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b ch-5.12
$ cd linux
$ cp $CLOUDH/cloud-hypervisor/resources/linux-config-aarch64 .config
$ make -j `nproc`
$ popd
```
### Booting the guest VM
```bash
$ pushd $CLOUDH
$ sudo $CLOUDH/cloud-hypervisor/target/debug/cloud-hypervisor \
--api-socket /tmp/cloud-hypervisor.sock \
--kernel $CLOUDH/linux/arch/arm64/boot/Image \
--disk path=focal-server-cloudimg-arm64.raw \
--cmdline "keep_bootcon console=ttyAMA0 reboot=k panic=1 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=4096M \
--net tap=,mac=12:34:56:78:90:01,ip=192.168.1.1,mask=255.255.255.0 \
--serial tty \
--console off
$ popd
```

86
docs/building.md Normal file
View File

@@ -0,0 +1,86 @@
- [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 basic packages needed. For a package list targeting for more
# functionalities for example the test, please see resources/Dockerfile.
$ sudo apt-get update
$ sudo apt install git build-essential m4 bison flex uuid-dev 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 # x86-64
$ rustup target add aarch64-unknown-linux-musl # AArch64
```
## 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 # x86-64
$ cargo build --release --target=aarch64-unknown-linux-musl --all # AArch64
$ 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

@@ -88,7 +88,7 @@ Ubuntu distributions.
```bash
apt update
apt install fio iperf iperf3 socat stress
apt install fio iperf iperf3 socat stress cpuid
```
### Remove counterproductive packages
@@ -158,3 +158,172 @@ as we might need to update the direct kernel boot command line, replacing
`/dev/vda1` with the appropriate partition number.
Update all references to the previous image name to the new one.
## NVIDIA image for VFIO baremetal CI
Here we are going to describe how to create a cloud image that contains the
necessary NVIDIA drivers for our VFIO baremetal CI.
### Download base image
We usually start from one of the custom cloud image we have previously created
but we can use a stock cloud image as well.
```bash
wget https://cloud-hypervisor.azureedge.net/jammy-server-cloudimg-amd64-custom-20221118-1.raw
mv jammy-server-cloudimg-amd64-custom-20221118-1.raw jammy-server-cloudimg-amd64-nvidia.raw
```
### Extend the image size
The NVIDIA drivers consume lots of space, which is why we must resize the image
before we proceed any further.
```bash
qemu-img resize jammy-server-cloudimg-amd64-nvidia.raw 5G
```
### Resize the partition
We use `parted` for fixing the GPT after the image was resized, as well as for
resizing the `Linux` partition.
```bash
sudo parted jammy-server-cloudimg-amd64-nvidia.raw
(parted) print
Warning: Not all of the space available to jammy-server-cloudimg-amd64-nvidia.raw
appears to be used, you can fix the GPT to use all of the space (an extra 5873664
blocks) or continue with the current setting?
Fix/Ignore? Fix
Model: (file)
Disk jammy-server-cloudimg-amd64-nvidia.raw: 5369MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
15 5243kB 116MB 111MB fat32 boot, esp
1 116MB 2361MB 2245MB ext4
(parted) resizepart 1 5369MB
(parted) print
Model: (file)
Disk jammy-server-cloudimg-amd64-nvidia.raw: 5369MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
15 5243kB 116MB 111MB fat32 boot, esp
1 116MB 5369MB 5252MB ext4
(parted) quit
```
### Create a macvtap interface
Rely on the following [documentation](docs/macvtap-bridge.md) to set up a
macvtap interface to provide your VM with proper connectivity.
### Boot the image
It is particularly important to boot with a `cloud-init` disk attached to the
VM as it will automatically resize the Linux `ext4` filesystem based on the
partition that we have previously resized.
```bash
./cloud-hypervisor \
--kernel hypervisor-fw \
--disk path=focal-server-cloudimg-amd64-nvidia.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=4G \
--net fd=3,mac=$mac 3<>$"$tapdevice"
```
### Bring up connectivity
If your network has a DHCP server, run the following from your VM
```bash
sudo dhclient
```
But if that's not the case, let's give it an IP manually (the IP addresses
depend on your actual network) and set the DNS server IP address as well.
```bash
sudo ip addr add 192.168.2.10/24 dev ens4
sudo ip link set up dev ens4
sudo ip route add default via 192.168.2.1
sudo resolvectl dns ens4 8.8.8.8
```
#### Check connectivity and update the image
```bash
sudo apt update
sudo apt upgrade
```
### Install NVIDIA drivers
The following steps and commands are referenced from the
[NVIDIA official documentation](https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html#ubuntu-lts)
about Tesla compute cards.
```bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed -e 's/\.//g')
wget https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt-key del 7fa2af80
sudo apt update
sudo apt -y install cuda-drivers
```
### Check the `nvidia-smi` tool
Quickly validate that you can find and run the `nvidia-smi` command from your
VM. At this point it should fail given no NVIDIA card has been passed through
the VM, therefore no NVIDIA driver is loaded.
### Workaround LA57 reboot issue
Add `reboot=a` to `GRUB_CMDLINE_LINUX` in `etc/default/grub` so that the VM
will be booted with the ACPI reboot type. This resolves a reboot issue when
running on 5-level paging systems.
```bash
sudo vim /etc/default/grub
sudo update-grub
sudo reboot
```
### Remove previous logins
Since our integration tests rely on past logins to count the number of reboots,
we must ensure to clear the list.
```bash
>/var/log/lastlog
>/var/log/wtmp
>/var/log/btmp
```
### Clear history
```
history -c
rm /home/cloud/.bash_history
```
### Reset cloud-init
This is mandatory as we want `cloud-init` provisioning to work again when a new
VM will be booted with this image.
```
sudo cloud-init clean
```

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.

View File

@@ -2,17 +2,19 @@
Cloud Hypervisor supports UEFI boot through the utilization of the EDK II based UEFI firmware.
## Building UEFI Firmware
## Building UEFI Firmware for x86-64
To avoid any unnecessary issues, it is recommended to use Ubuntu 18.04 and its default toolset. Any other compatible Linux distribution is otherwise suitable, however it is suggested to use a temporary Docker container with Ubuntu 18.04 for a quick build on an existing Linux machine.
Please note that nasm-2.15 is required for the build to succeed.
The commands below will compile an OVMF firmware suitable for Cloud Hypervisor.
```shell
sudo apt-get update
sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git
git clone https://github.com/cloud-hypervisor/edk2 -b ch
git clone https://github.com/tianocore/edk2
cd edk2
. edksetup.sh
git submodule update --init
@@ -27,11 +29,40 @@ build
After the successful build, the resulting firmware binaries are available under `Build/CloudHvX64/DEBUG_GCC5/FV` underneath the edk2 checkout.
## Building UEFI Firmware for AArch64
```shell
# On an AArch64 machine:
$ sudo apt-get update
$ sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git
$ git clone --depth 1 https://github.com/tianocore/edk2.git -b master
$ cd edk2
$ git submodule update --init
$ cd ..
$ git clone --depth 1 https://github.com/tianocore/edk2-platforms.git -b master
$ git clone --depth 1 https://github.com/acpica/acpica.git -b master
# Build tools
$ export PACKAGES_PATH="$PWD/edk2:$PWD/edk2-platforms"
$ export IASL_PREFIX="$PWD/acpica/generate/unix/bin/"
$ make -C acpica
$ cd edk2/
$ . edksetup.sh
$ cd ..
$ make -C edk2/BaseTools
# Build EDK2
$ build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtCloudHv.dsc -b RELEASE
```
If the build goes well, the EDK2 binary is available at
`edk2/Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd`.
## Using OVMF Binaries
Any UEFI capable image can be booted using the Cloud Hypervisor specific firmware. Windows guests under Cloud Hypervisor only support UEFI boot, therefore OVMF is mandatory there.
To make Cloud Hypervisor use UEFI boot, pass the `CLOUDHV.fd` file path as an argument to the `--kernel` option. The firmware file will be opened in read only mode.
To make Cloud Hypervisor use UEFI boot, pass the `CLOUDHV.fd` (for x86-64) / `CLOUDHV_EFI.fd` (for AArch64) file path as an argument to the `--kernel` option. The firmware file will be opened in read only mode.
# Links

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.139"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.89"

View File

@@ -16,8 +16,10 @@ static mut MONITOR: Option<(File, Instant)> = None;
/// This function must only be called once from the main process before any threads
/// are created to avoid race conditions
pub fn set_monitor(file: File) -> Result<(), std::io::Error> {
// SAFETY: there is only one caller of this function, so MONITOR is written to only once
assert!(unsafe { MONITOR.is_none() });
let fd = file.as_raw_fd();
// SAFETY: FFI call to configure the fd
let ret = unsafe {
let mut flags = libc::fcntl(fd, libc::F_GETFL);
flags |= libc::O_NONBLOCK;
@@ -26,6 +28,7 @@ pub fn set_monitor(file: File) -> Result<(), std::io::Error> {
if ret < 0 {
return Err(std::io::Error::last_os_error());
}
// SAFETY: MONITOR is None. Nobody else can hold a reference to it.
unsafe {
MONITOR = Some((file, Instant::now()));
};
@@ -41,6 +44,7 @@ struct Event<'a> {
}
pub fn event_log(source: &str, event: &str, properties: Option<&HashMap<Cow<str>, Cow<str>>>) {
// SAFETY: MONITOR is always in a valid state (None or Some).
if let Some((file, start)) = unsafe { MONITOR.as_ref() } {
let e = Event {
timestamp: start.elapsed(),

468
fuzz/Cargo.lock generated
View File

@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.62"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
[[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"
@@ -96,6 +79,7 @@ dependencies = [
"libc",
"log",
"qcow",
"smallvec",
"thiserror",
"versionize",
"versionize_derive",
@@ -115,9 +99,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.73"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
@@ -127,33 +114,31 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.2.17"
version = "4.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
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 +153,8 @@ dependencies = [
"serde_json",
"signal-hook",
"thiserror",
"tpm",
"tracer",
"vm-memory",
"vmm",
"vmm-sys-util",
@@ -183,7 +170,9 @@ dependencies = [
"epoll",
"libc",
"libfuzzer-sys",
"linux-loader",
"micro_http",
"net_util",
"once_cell",
"qcow",
"seccompiler",
@@ -214,9 +203,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 +213,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 +227,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 +248,9 @@ dependencies = [
"hypervisor",
"libc",
"log",
"phf",
"thiserror",
"tpm",
"versionize",
"versionize_derive",
"vm-device",
@@ -277,6 +269,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 +313,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",
]
@@ -345,12 +352,11 @@ dependencies = [
[[package]]
name = "iced-x86"
version = "1.17.0"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "158f5204401d08f91d19176112146d75e99b3cf745092e268fa7be33e09adcec"
checksum = "1dd04b950d75b3498320253b17fb92745b2cc79ead8814aede2f7c1bab858bec"
dependencies = [
"lazy_static",
"static_assertions",
]
[[package]]
@@ -360,35 +366,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.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427496d698429d86ff947537dff68facb83fe753b7abea4fab4ac1c4b7a4b94b"
checksum = "c9ddf18110cedc09617f5a965bdb51adb0c0fb02c791e4ab22f7a21bb25269b0"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "itoa"
version = "1.0.3"
name = "is-terminal"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[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 +424,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 +441,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.131"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[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 +458,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.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "log"
version = "0.4.17"
@@ -449,7 +483,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#fbef706e28c7ca7cce8dfec7ca073f3b359879d3"
dependencies = [
"libc",
"vmm-sys-util",
@@ -485,9 +519,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.13.1"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "option_parser"
@@ -495,9 +529,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 +557,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.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
dependencies = [
"unicode-ident",
]
@@ -551,6 +627,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 +653,9 @@ dependencies = [
[[package]]
name = "remain"
version = "0.2.4"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06df529c0d271b27ac4a2c260f5ce2914b60bd44702cecec7b9f271adbdde23b"
checksum = "5704e2cda92fd54202f05430725317ba0ea7d0c96b246ca0a92e45177127ba3b"
dependencies = [
"proc-macro2",
"quote",
@@ -581,40 +672,54 @@ dependencies = [
]
[[package]]
name = "ryu"
version = "1.0.11"
name = "rustix"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "ryu"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[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.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "serde"
version = "1.0.143"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.143"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
@@ -623,9 +728,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.83"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa",
"ryu",
@@ -634,9 +739,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 +749,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "2.0.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de337f322382fcdfbb21a014f7c224ee041a23785651db67b9827403178f698f"
checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e"
dependencies = [
"darling",
"proc-macro2",
@@ -654,6 +759,10 @@ dependencies = [
"syn",
]
[[package]]
name = "serial_buffer"
version = "0.1.0"
[[package]]
name = "signal-hook"
version = "0.3.14"
@@ -674,10 +783,16 @@ dependencies = [
]
[[package]]
name = "static_assertions"
version = "1.1.0"
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "strsim"
@@ -687,9 +802,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.99"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
@@ -707,63 +822,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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[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 +917,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 +969,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 +1005,7 @@ dependencies = [
"seccompiler",
"serde",
"serde_json",
"serial_buffer",
"thiserror",
"versionize",
"versionize_derive",
@@ -893,9 +1022,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 +1056,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 +1119,10 @@ dependencies = [
"seccompiler",
"serde",
"serde_json",
"serial_buffer",
"signal-hook",
"thiserror",
"tracer",
"uuid",
"versionize",
"versionize_derive",
@@ -1010,9 +1141,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 +1187,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,20 @@ 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.138"
libfuzzer-sys = "0.4.5"
linux-loader = { version = "0.8.1", features = ["elf", "bzimage", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
once_cell = "1.13.1"
net_util = { path = "../net_util" }
once_cell = "1.17.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 +33,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 +58,66 @@ 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 = "linux_loader"
path = "fuzz_targets/linux_loader.rs"
test = false
doc = false
[[bin]]
name = "linux_loader_cmdline"
path = "fuzz_targets/linux_loader_cmdline.rs"
test = false
doc = false
[[bin]]
name = "mem"
path = "fuzz_targets/mem.rs"
test = false
doc = false
[[bin]]
name = "net"
path = "fuzz_targets/net.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 +129,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
}

View File

@@ -0,0 +1,50 @@
// 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]
use libfuzzer_sys::fuzz_target;
use linux_loader::loader::KernelLoader;
use std::ffi;
use std::fs::File;
use std::io;
use std::io::{Seek, SeekFrom, Write};
use std::os::unix::io::{FromRawFd, RawFd};
use vm_memory::{bitmap::AtomicBitmap, GuestAddress};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const MEM_SIZE: usize = 256 * 1024 * 1024;
// From 'arch::x86_64::layout::HIGH_RAM_START'
const HIGH_RAM_START: GuestAddress = GuestAddress(0x100000);
fuzz_target!(|bytes| {
let shm = memfd_create(&ffi::CString::new("fuzz_load_kernel").unwrap(), 0).unwrap();
let mut kernel_file: File = unsafe { File::from_raw_fd(shm) };
kernel_file.write_all(&bytes).unwrap();
kernel_file.seek(SeekFrom::Start(0)).unwrap();
let guest_memory = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
linux_loader::loader::elf::Elf::load(
&guest_memory,
None,
&mut kernel_file,
Some(HIGH_RAM_START),
)
.ok();
});
fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> {
let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
if res < 0 {
Err(io::Error::last_os_error())
} else {
Ok(res as RawFd)
}
}

View File

@@ -0,0 +1,34 @@
// 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]
use libfuzzer_sys::fuzz_target;
use vm_memory::{bitmap::AtomicBitmap, GuestAddress};
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
const MEM_SIZE: usize = 256 * 1024 * 1024;
// From 'arch::x86_64::layout::CMDLINE_START'
const CMDLINE_START: GuestAddress = GuestAddress(0x20000);
fuzz_target!(|bytes| {
let payload_config = vmm::config::PayloadConfig {
firmware: None,
kernel: None,
cmdline: Some(String::from_utf8_lossy(&bytes).to_string()),
initramfs: None,
};
let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) {
Ok(cmdline) => cmdline,
_ => return,
};
let guest_memory = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap();
linux_loader::loader::load_cmdline(&guest_memory, CMDLINE_START, &kernel_cmdline).ok();
});

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
}

285
fuzz/fuzz_targets/net.rs Normal file
View File

@@ -0,0 +1,285 @@
// 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::{Read, Write};
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::EpollContext;
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 TAP_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() < TAP_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM
|| bytes.len()
> TAP_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + MEM_SIZE
{
return;
}
let (dummy_tap_frontend, dummy_tap_backend) = create_socketpair().unwrap();
let if_name = "fuzzer_tap_name".as_bytes().to_vec();
let tap = net_util::Tap::new_for_fuzzing(dummy_tap_frontend, if_name);
let mut net = virtio_devices::Net::new_with_tap(
"fuzzer_net".to_owned(),
vec![tap],
None, // guest_mac
false, // iommu
QUEUE_NUM,
QUEUE_SIZE,
SeccompAction::Allow,
None,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
true,
true,
true,
)
.unwrap();
let tap_input_bytes = &bytes[..TAP_INPUT_SIZE];
let queue_data = &bytes[TAP_INPUT_SIZE..TAP_INPUT_SIZE + QUEUE_DATA_SIZE * QUEUE_NUM];
let queue_bytes = &bytes[TAP_INPUT_SIZE + QUEUE_DATA_SIZE * QUEUE_NUM
..TAP_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM];
let mem_bytes = &bytes[TAP_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())) };
// Start the thread of dummy tap backend to handle the rx and tx from the virtio-net
let exit_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let tap_backend_thread = {
let dummy_tap_backend = dummy_tap_backend.try_clone().unwrap();
let tap_input_bytes: [u8; TAP_INPUT_SIZE] = tap_input_bytes[..].try_into().unwrap();
let exit_evt = exit_evt.try_clone().unwrap();
std::thread::Builder::new()
.name("dummy_tap_backend".to_string())
.spawn(move || {
tap_backend_stub(dummy_tap_backend, &tap_input_bytes, exit_evt);
})
.unwrap()
};
// Kick the 'queue' events and endpoint event before activate the net device
input_queue_evt.write(1).unwrap();
output_queue_evt.write(1).unwrap();
net.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 net device worker thread to return
net.wait_for_epoll_threads();
// Terminate the thread for the dummy tap backend
exit_evt.write(1).ok();
tap_backend_thread.join().unwrap();
});
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 create_socketpair() -> Result<(File, File), std::io::Error> {
let mut fds = [-1, -1];
unsafe {
let ret = libc::socketpair(
libc::AF_UNIX,
libc::SOCK_STREAM | libc::SOCK_NONBLOCK,
0,
fds.as_mut_ptr(),
);
if ret == -1 {
return Err(std::io::Error::last_os_error());
}
}
let socket1 = unsafe { File::from_raw_fd(fds[0]) };
let socket2 = unsafe { File::from_raw_fd(fds[1]) };
Ok((socket1, socket2))
}
enum EpollEvent {
Exit = 0,
Rx = 1,
Tx = 2,
Unknown,
}
impl From<u64> for EpollEvent {
fn from(v: u64) -> Self {
use EpollEvent::*;
match v {
0 => Exit,
1 => Rx,
2 => Tx,
_ => Unknown,
}
}
}
// Handle the rx and tx requests from the virtio-net device
fn tap_backend_stub(
mut dummy_tap: File,
tap_input_bytes: &[u8; TAP_INPUT_SIZE],
exit_evt: EventFd,
) {
let mut epoll = EpollContext::new().unwrap();
epoll
.add_event_custom(&exit_evt, EpollEvent::Exit as u64, epoll::Events::EPOLLIN)
.unwrap();
let dummy_tap_write = dummy_tap.try_clone().unwrap();
epoll
.add_event_custom(
&dummy_tap_write,
EpollEvent::Rx as u64,
epoll::Events::EPOLLOUT,
)
.unwrap();
epoll
.add_event_custom(&dummy_tap, EpollEvent::Tx as u64, epoll::Events::EPOLLIN)
.unwrap();
let epoll_fd = epoll.as_raw_fd();
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); 3];
loop {
let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) {
Ok(num_events) => num_events,
Err(e) => match e.raw_os_error() {
Some(libc::EAGAIN) | Some(libc::EINTR) => continue,
_ => panic!("Unexpected epoll::wait error!"),
},
};
for event in events.iter().take(num_events) {
let dispatch_event: EpollEvent = event.data.into();
match dispatch_event {
EpollEvent::Exit => {
return;
}
EpollEvent::Rx => {
dummy_tap.write_all(tap_input_bytes).unwrap();
break;
}
EpollEvent::Tx => {
let mut buffer = Vec::new();
dummy_tap.read_to_end(&mut buffer).ok();
break;
}
_ => {
panic!("Unexpected Epoll event");
}
}
}
}
}

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

@@ -15,6 +15,7 @@ fuzz_target!(|bytes| {
let mut serial = Serial::new_sink(
"serial".into(),
Arc::new(TestInterrupt::new(EventFd::new(EFD_NONBLOCK).unwrap())),
None,
);
let mut i = 0;

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,25 +11,25 @@ mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.62"
anyhow = "1.0.68"
byteorder = "1.4.3"
thiserror = "1.0.32"
libc = "0.2.131"
thiserror = "1.0.38"
libc = "0.2.139"
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.151", 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"
version = "1.18.0"
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

@@ -272,6 +272,7 @@ impl LapicState {
use std::io::Cursor;
use std::mem;
// SAFETY: plain old data type
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
@@ -290,6 +291,7 @@ impl LapicState {
use std::io::Cursor;
use std::mem;
// SAFETY: plain old data type
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).

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

@@ -39,8 +39,8 @@ const GICR_ICFGR0: u32 = GICR_SGI_OFFSET + 0x0C00;
const KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT: u32 = 32;
const KVM_DEV_ARM_VGIC_V3_MPIDR_MASK: u64 = 0xffffffff << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT as u64;
const KVM_ARM64_SYSREG_MPIDR_EL1: u64 = KVM_REG_ARM64 as u64
| KVM_REG_SIZE_U64 as u64
const KVM_ARM64_SYSREG_MPIDR_EL1: u64 = KVM_REG_ARM64
| KVM_REG_SIZE_U64
| KVM_REG_ARM64_SYSREG as u64
| (((3_u64) << KVM_REG_ARM64_SYSREG_OP0_SHIFT) & KVM_REG_ARM64_SYSREG_OP0_MASK as u64)
| (((5_u64) << KVM_REG_ARM64_SYSREG_OP2_SHIFT) & KVM_REG_ARM64_SYSREG_OP2_MASK as u64);
@@ -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

@@ -24,8 +24,8 @@ pub use {kvm_ioctls::Cap, kvm_ioctls::Kvm};
// This macro gets the offset of a structure (i.e `str`) member (i.e `field`) without having
// an instance of that structure.
#[macro_export]
macro_rules! offset__of {
($str:ty, $($field:ident)+) => ({
macro_rules! offset_of {
($str:ty, $field:ident) => {{
let tmp: std::mem::MaybeUninit<$str> = std::mem::MaybeUninit::uninit();
let base = tmp.as_ptr();
@@ -34,14 +34,16 @@ macro_rules! offset__of {
// SAFETY: The pointer is valid and aligned, just not initialised. Using `addr_of` ensures
// that we don't actually read from `base` (which would be UB) nor create an intermediate
// reference.
let member = unsafe { core::ptr::addr_of!((*base).$($field)*) } as *const u8;
let member = unsafe { core::ptr::addr_of!((*base).$field) } as *const u8;
// Avoid warnings when nesting `unsafe` blocks.
#[allow(unused_unsafe)]
// SAFETY: The two pointers are within the same allocated object `tmp`. All requirements
// from offset_from are upheld.
unsafe { member.offset_from(base as *const u8) as usize }
});
unsafe {
member.offset_from(base as *const u8) as usize
}
}};
}
// Following are macros that help with getting the ID of a aarch64 core register.
@@ -97,8 +99,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,14 +16,14 @@ 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;
use crate::vm::{self, InterruptSourceConfig, VmOps};
use crate::HypervisorType;
#[cfg(target_arch = "aarch64")]
use crate::{arm64_core_reg_id, offset__of};
use crate::{arm64_core_reg_id, offset_of};
use kvm_ioctls::{NoDatamatch, VcpuFd, VmFd};
use std::any::Any;
use std::collections::HashMap;
@@ -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 {
@@ -1115,7 +1114,7 @@ impl cpu::Vcpu for KvmVcpu {
#[cfg(target_arch = "aarch64")]
fn get_regs(&self) -> cpu::Result<StandardRegisters> {
let mut state: StandardRegisters = kvm_regs::default();
let mut off = offset__of!(user_pt_regs, regs);
let mut off = offset_of!(user_pt_regs, regs);
// There are 31 user_pt_regs:
// https://elixir.free-electrons.com/linux/v4.14.174/source/arch/arm64/include/uapi/asm/ptrace.h#L72
// These actually are the general-purpose registers of the Armv8-a
@@ -1124,84 +1123,99 @@ 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>();
}
// We are now entering the "Other register" section of the ARMv8-a architecture.
// First one, stack pointer.
let off = offset__of!(user_pt_regs, sp);
let off = offset_of!(user_pt_regs, sp);
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);
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);
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);
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.
let off = offset__of!(kvm_regs, elr_el1);
let off = offset_of!(kvm_regs, elr_el1);
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);
let mut off = offset_of!(kvm_regs, spsr);
for i in 0..KVM_NR_SPSR as usize {
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>();
}
// Now moving on to floting point registers which are stored in the user_fpsimd_state in the kernel:
// https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
let mut off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, vregs);
let mut off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, vregs);
for i in 0..32 {
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>();
}
// Floating-point Status Register
let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpsr);
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpsr);
state.fp_regs.fpsr = self
.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);
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpcr);
state.fp_regs.fpcr = self
.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")]
@@ -1224,74 +1238,92 @@ impl cpu::Vcpu for KvmVcpu {
fn set_regs(&self, state: &StandardRegisters) -> cpu::Result<()> {
// The function follows the exact identical order from `state`. Look there
// for some additional info on registers.
let mut off = offset__of!(user_pt_regs, regs);
let mut off = offset_of!(user_pt_regs, regs);
for i in 0..31 {
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>();
}
let off = offset__of!(user_pt_regs, sp);
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);
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);
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);
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);
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);
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>();
}
let mut off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, vregs);
let mut off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, vregs);
for i in 0..32 {
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>();
}
let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpsr);
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpsr);
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()))?;
let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpcr);
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpcr);
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()))
@@ -1654,8 +1700,8 @@ impl cpu::Vcpu for KvmVcpu {
// it to the corresponding KVM ID, and call `KVM_GET_ONE_REG` API to
// get the value of the system parameter.
//
let id: u64 = KVM_REG_ARM64 as u64
| KVM_REG_SIZE_U64 as u64
let id: u64 = KVM_REG_ARM64
| KVM_REG_SIZE_U64
| KVM_REG_ARM64_SYSREG as u64
| ((((sys_reg) >> 5)
& (KVM_REG_ARM64_SYSREG_OP0_MASK
@@ -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.
@@ -1684,32 +1733,35 @@ impl cpu::Vcpu for KvmVcpu {
const PSTATE_FAULT_BITS_64: u64 =
PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT;
let kreg_off = offset__of!(kvm_regs, regs);
let kreg_off = offset_of!(kvm_regs, regs);
// Get the register index of the PSTATE (Processor State) register.
let pstate = offset__of!(user_pt_regs, pstate) + kreg_off;
let pstate = offset_of!(user_pt_regs, pstate) + kreg_off;
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()))?;
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
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).
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
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()))?;
}
@@ -2012,6 +2066,7 @@ impl cpu::Vcpu for KvmVcpu {
#[cfg(feature = "tdx")]
fn get_tdx_exit_details(&mut self) -> cpu::Result<TdxExitDetails> {
let kvm_run = self.fd.get_kvm_run();
// SAFETY: accessing a union field in a valid structure
let tdx_vmcall = unsafe { &mut kvm_run.__bindgen_anon_1.tdx.u.vmcall };
tdx_vmcall.status_code = TDG_VP_VMCALL_INVALID_OPERAND;
@@ -2035,6 +2090,7 @@ impl cpu::Vcpu for KvmVcpu {
#[cfg(feature = "tdx")]
fn set_tdx_status(&mut self, status: TdxExitStatus) {
let kvm_run = self.fd.get_kvm_run();
// SAFETY: accessing a union field in a valid structure
let tdx_vmcall = unsafe { &mut kvm_run.__bindgen_anon_1.tdx.u.vmcall };
tdx_vmcall.status_code = match status {

View File

@@ -18,8 +18,6 @@
//! - arm64
//!
#![allow(clippy::significant_drop_in_scrutinee)]
#[macro_use]
extern crate anyhow;
#[cfg(target_arch = "x86_64")]
@@ -63,7 +61,9 @@ pub use vm::{
#[derive(Debug, Copy, Clone)]
pub enum HypervisorType {
#[cfg(feature = "kvm")]
Kvm,
#[cfg(feature = "mshv")]
Mshv,
}

View File

@@ -446,10 +446,10 @@ impl cpu::Vcpu for MshvVcpu {
/* Advance RIP and update RAX */
let arr_reg_name_value = [
(
hv_register_name::HV_X64_REGISTER_RIP,
hv_x64_register_name_HV_X64_REGISTER_RIP,
info.header.rip + insn_len,
),
(hv_register_name::HV_X64_REGISTER_RAX, ret_rax),
(hv_x64_register_name_HV_X64_REGISTER_RAX, ret_rax),
];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
@@ -458,12 +458,13 @@ impl cpu::Vcpu for MshvVcpu {
_ => {}
}
// SAFETY: access_info is valid, otherwise we won't be here
assert!(
// SAFETY: access_info is valid, otherwise we won't be here
(unsafe { access_info.__bindgen_anon_1.string_op() } != 1),
"String IN/OUT not supported"
);
assert!(
// SAFETY: access_info is valid, otherwise we won't be here
(unsafe { access_info.__bindgen_anon_1.rep_prefix() } != 1),
"Rep IN/OUT not supported"
);
@@ -494,10 +495,10 @@ impl cpu::Vcpu for MshvVcpu {
/* Advance RIP and update RAX */
let arr_reg_name_value = [
(
hv_register_name::HV_X64_REGISTER_RIP,
hv_x64_register_name_HV_X64_REGISTER_RIP,
info.header.rip + insn_len,
),
(hv_register_name::HV_X64_REGISTER_RAX, ret_rax),
(hv_x64_register_name_HV_X64_REGISTER_RAX, ret_rax),
];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
@@ -703,7 +704,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 +1093,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

@@ -1187,6 +1187,7 @@ pub struct ifreq {
impl Default for ifreq {
fn default() -> Self {
// SAFETY: all zeros is a valid pattern for this data type
unsafe { std::mem::zeroed() }
}
}

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.139"
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.151"
thiserror = "1.0.38"
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

@@ -66,32 +66,34 @@ fn create_sockaddr(ip_addr: net::Ipv4Addr) -> net_gen::sockaddr {
let addr_in = net_gen::sockaddr_in {
sin_family: net_gen::AF_INET as u16,
sin_port: 0,
// SAFETY: ip_addr can be safely transmute to in_addr
sin_addr: unsafe { mem::transmute(ip_addr.octets()) },
__pad: [0; 8usize],
};
// SAFETY: addr_in can be safely transmute to sockaddr
unsafe { mem::transmute(addr_in) }
}
fn create_inet_socket() -> Result<net::UdpSocket> {
// This is safe since we check the return value.
// SAFETY: we check the return value.
let sock = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) };
if sock < 0 {
return Err(Error::CreateSocket(IoError::last_os_error()));
}
// This is safe; nothing else will use or hold onto the raw sock fd.
// SAFETY: nothing else will use or hold onto the raw sock fd.
Ok(unsafe { net::UdpSocket::from_raw_fd(sock) })
}
fn create_unix_socket() -> Result<net::UdpSocket> {
// This is safe since we check the return value.
// SAFETY: we check the return value.
let sock = unsafe { libc::socket(libc::AF_UNIX, libc::SOCK_DGRAM, 0) };
if sock < 0 {
return Err(Error::CreateSocket(IoError::last_os_error()));
}
// This is safe; nothing else will use or hold onto the raw sock fd.
// SAFETY: nothing else will use or hold onto the raw sock fd.
Ok(unsafe { net::UdpSocket::from_raw_fd(sock) })
}
@@ -131,17 +133,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 +155,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

@@ -83,6 +83,7 @@ impl TxVirtio {
}
let len = if !iovecs.is_empty() {
// SAFETY: FFI call with correct arguments
let result = unsafe {
libc::writev(
tap.as_raw_fd() as libc::c_int,
@@ -104,6 +105,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 +190,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();
@@ -217,6 +222,7 @@ impl RxVirtio {
}
let len = if !iovecs.is_empty() {
// SAFETY: FFI call with correct arguments
let result = unsafe {
libc::readv(
tap.as_raw_fd() as libc::c_int,
@@ -238,6 +244,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 +298,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 +312,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 +322,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 {

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