Compare commits

..

219 Commits
v35.0 ... v37.0

Author SHA1 Message Date
Bo Chen
5e702dcd5e build: Release v37.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 09:49:25 -08:00
Bo Chen
602d704558 tests: Stabilize 'test_vfio_user' with retries to run host commands
The 'test_vfio_user' is prone to fail when the system is under high
workloads with errors:

```
Error while connecting to /var/tmp/spdk.sock
Is SPDK application running?
Error details: Invalid or non-existing address: '/var/tmp/spdk.sock'
```

This is because SPDK is not fully functional before we request to
create a nvme device using the vfio_user protocol. This patch stabilize
this test with allowing retires to execute host commands.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 07:12:04 -08:00
Bo Chen
38a2808d85 arch: x86_64: Refactor the way to generate e820 RAM maps
This patch defines a new function 'generate_ram_ranges', to generate
usable physical memory ranges for the guest based on the existing guest
memory managed by VMM. This function is also made public, so that it can
be reused, say by the IGVM loader in the future [1].

No functional change.

See: #6020

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 07:11:53 -08:00
dependabot[bot]
5e2f218832 build: Bump async-executor from 1.5.1 to 1.8.0
Bumps [async-executor](https://github.com/smol-rs/async-executor) from 1.5.1 to 1.8.0.
- [Release notes](https://github.com/smol-rs/async-executor/releases)
- [Changelog](https://github.com/smol-rs/async-executor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-executor/compare/v1.5.1...v1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 00:46:10 +00:00
dependabot[bot]
2fb8854ff6 build: Bump once_cell from 1.18.0 to 1.19.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.18.0 to 1.19.0.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.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-12-13 23:54:27 +00:00
dependabot[bot]
883bb22b65 build: Bump mshv-ioctls from 6901f9c to 0dd4d34
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `6901f9c` to `0dd4d34`.
- [Commits](6901f9cbd3...0dd4d3452a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 23:24:43 +00:00
dependabot[bot]
442fe6afcb build: Bump anstyle-query from 1.0.0 to 1.0.2 in /fuzz
Bumps [anstyle-query](https://github.com/rust-cli/anstyle) from 1.0.0 to 1.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.0.0...anstyle-query-v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 23:44:37 +00:00
Bo Chen
e64b66054e vmm: tdx: Error out early for TD migration
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-12 11:45:40 -08:00
Bo Chen
ceb1be9f50 vmm: Fix a typo from send_migration()
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-12 11:45:40 -08:00
Muminul Islam
7d5ea5ca37 hypervisor: fix few typos and cosmetic issues
This patch adds missing new lines after functions,
fixes few typos in the comments, adds few missing
comments to SNP related functions.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-12 14:42:22 +00:00
dependabot[bot]
d5839fe03c build: Bump pin-project from 1.1.2 to 1.1.3
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v1.1.2...v1.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 00:21:51 +00:00
dependabot[bot]
de1b7f5e83 build: Bump ryu from 1.0.15 to 1.0.16 in /fuzz
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.15...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 23:59:23 +00:00
Jinank Jain
cf8a348238 docs: Add a missing backslash
There is missing backslash in the qemu command to launch windows guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:30:24 +00:00
Jinank Jain
2197989782 vmm: igvm: Remove redundant copy_from_slice
There is no requirement to call copy_from_slice, since all the member
variables are identical and we can directly assign them value.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:30:05 +00:00
Jinank Jain
5d4fe8efb9 github: ci: Move to action/checkout v4
There is a mix of v2, v3 and v4 in the codebase. Let's move to v4
everywhere because v2 seems to be using a deprecated version of nodejs.
This is throwing warnings when the Github action CI is running.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:29:11 +00:00
Jinank Jain
638e29bdcc hypervisor: vmm: Fix warnings in Cargo.toml
Currently there are some inconsistencies in Cargo.toml which is causing
the following warnings during the build process:

Error parsing Cargo.toml manifest, fallback to caching entire file:
Invalid TOML document: expected key-value, found comma

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:29:11 +00:00
dependabot[bot]
d1560b4223 build: Bump futures-core from 0.3.28 to 0.3.29
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-09 00:45:57 +00:00
dependabot[bot]
6d7224dfee build: Bump anstream from 0.6.4 to 0.6.5 in /fuzz
Bumps [anstream](https://github.com/rust-cli/anstyle) from 0.6.4 to 0.6.5.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.4...anstream-v0.6.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 23:41:32 +00:00
Muminul Islam
f38adfa166 vmm: Pass IGVM file to the loader
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
7030b15e63 vmm: Add igvm module and loader module
vmm: Add igvm module and loader module

Add a separate module named igvm to the vmm crate
with definitions to parse and load igvm to the guest memory.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
ec79820b3f hypervisor: Add api to retrieve CPUID leaf
Add necessary API to retrieve cpuid leaf on MSHV.
This API is used to update cpuid information
during the parsing of the igvm file.

Microsoft hypervisor does not provide common
CpuID like KVM. That's why we need to call this API
during the IGVM parsing.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
b9117c9c50 github: workflow: Build/quality test for igvm
Extend the current github actions to build and
test clippy for igvm feature.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
13ef424bf1 vmm: Add IGVM to the config/commandline
This patch adds igvm to the Vm config and params as well as
the command line argument to pass igvm file to load into
guest memory. The file must maintain the IGVM format.
The CLI option is featured guarded by igvm feature gate.

The IGVM(Independent Guest Virtual Machine) file format
is designed to encapsulate all information required to
launch a virtual machine on any given virtualization stack,
with support for different isolation technologies such as
AMD SEV-SNP and Intel TDX.

At a conceptual level, this file format is a set of commands created
by the tool that generated the file, used by the loader to construct
the initial guest state. The file format also contains measurement
information that the underlying platform will use to confirm that
the file was loaded correctly and signed by the appropriate authorities.

The IGVM file is generated by the tool:
https://github.com/microsoft/igvm-tooling

The IGVM file is parsed by the following crates:
https://github.com/microsoft/igvm

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Bo Chen
c0faa75922 tests: Print ExitStatus for 'test_serial_socket_interaction'
This test has been failing fairly often on the AMD worker. Let's
collect more log for debugging.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-08 11:26:33 +00:00
Bo Chen
5d411d257a tests: Stabilize snapshot_restore tests
See: #5938

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-08 11:26:33 +00:00
dependabot[bot]
77f4e35bc8 build: Bump io-uring from 0.6.1 to 0.6.2
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.1 to 0.6.2.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 17:47:36 -08:00
dependabot[bot]
b2249827f5 build: Bump zerocopy from 0.7.26 to 0.7.29 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.26 to 0.7.29.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.26...v0.7.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 00:10:23 +00:00
Michael Zhao
f0c5592ba1 scripts: Workaround random wget failures on AArch64
Random failures of downloading `cloud-hypervisor-static-aarch64` with
`wget` were seen. The commit applies a workaround to retry the download
for a few times.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2023-12-07 14:29:22 -08:00
dependabot[bot]
b92856f41b build: Bump anstyle-wincon from 3.0.1 to 3.0.2 in /fuzz
Bumps [anstyle-wincon](https://github.com/rust-cli/anstyle) from 3.0.1 to 3.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.1...anstyle-wincon-v3.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 00:08:28 +00:00
dependabot[bot]
6a90902a4b build: Bump anstyle-parse from 0.2.2 to 0.2.3 in /fuzz
Bumps [anstyle-parse](https://github.com/rust-cli/anstyle) from 0.2.2 to 0.2.3.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.2...anstyle-parse-v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 00:08:06 +00:00
Markus Sütter
0e9513f2b7 vmm: Allow IP configuration on named TAP interfaces
This commit changes existing behavior of named TAP interfaces.
When booting a VM with configuration for a named TAP interface,
cloud-hypervisor will create the interface and apply a given
IP configuration to that interface. If the named interface
already exists on the system, the configuration is NOT overwritten.

Setting the ip and netmask fields in a tap interface configuration
for a named tap interface now works by handing this configuration
to the virtio_devices::Net object when it is created with a name.

This commit also touches net_util to make sure that the ip configuration
of existing TAP interfaces is not modified with ip or netmask handed to
open_tap.

Signed-off-by: Markus Sütter <markus.suetter@secunet.com>
2023-12-05 08:59:04 -08:00
Bo Chen
283ae7b33e build: Bump gdbstub and gdbstub_arch
This commit also makes changes due to the breaking API changes from the
`gdbstub` crate [1].

[1] https://github.com/daniel5151/gdbstub/releases/tag/0.7.0

Fix: #5997

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-05 10:50:06 +00:00
dependabot[bot]
102a1c9abc build: Bump clap from 4.4.10 to 4.4.11 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.10 to 4.4.11.
- [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.4.10...v4.4.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 23:38:13 +00:00
Bo Chen
32124bce13 scripts: Show wget details for aarch64 worker
The wget has been causing frequent CI failure for the past few days,
while it can't be reproduced manually. Let's show the wget details in
our CI pipeline to understand better future errors.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-04 11:54:50 -08:00
dependabot[bot]
5f89461a7e build: Bump js-sys from 0.3.65 to 0.3.66 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.65 to 0.3.66.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-02 00:01:27 +00:00
dependabot[bot]
b00cc483f9 build: Bump clap from 4.4.9 to 4.4.10 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.9 to 4.4.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.4.9...v4.4.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 23:20:47 +00:00
dependabot[bot]
705fbefebe build: Bump proc-macro2 from 1.0.67 to 1.0.70
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.67 to 1.0.70.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.67...1.0.70)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 08:59:14 +00:00
dependabot[bot]
d448dbd751 build: Bump wasm-bindgen from 0.2.88 to 0.2.89 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.88 to 0.2.89.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.88...0.2.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 00:13:32 +00:00
dependabot[bot]
9d29769536 build: Bump indexmap from 2.0.2 to 2.1.0
Bumps [indexmap](https://github.com/bluss/indexmap) from 2.0.2 to 2.1.0.
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/2.0.2...2.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 10:25:13 +00:00
dependabot[bot]
d9f7fd1db8 build: Bump proc-macro2 from 1.0.69 to 1.0.70 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.69 to 1.0.70.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.69...1.0.70)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 23:56:56 +00:00
dependabot[bot]
a6d994bf75 build: Bump toml_datetime from 0.6.3 to 0.6.5
Bumps [toml_datetime](https://github.com/toml-rs/toml) from 0.6.3 to 0.6.5.
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.6.3...toml_datetime-v0.6.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 00:09:58 +00:00
dependabot[bot]
86aa60a226 build: Bump clap from 4.4.8 to 4.4.9 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.8 to 4.4.9.
- [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.4.8...v4.4.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 23:12:42 +00:00
Ruslan Mstoi
800f971381 tests: test_watchdog: use event monitor
See: #5127

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-24 21:37:25 +00:00
Ruslan Mstoi
341a4558fe tests: test_vdpa_block: fix false positive
Running on host where vdpa_sim_blk module is not correctly loaded
test_vdpa_block passes.

"test common_parallel::test_vdpa_block ... ok"

This commit fixes the vdpa_sim_blk test to fail in that case.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-24 21:37:06 +00:00
dependabot[bot]
81b30bf390 build: Bump log from 0.4.17 to 0.4.20
Bumps [log](https://github.com/rust-lang/log) from 0.4.17 to 0.4.20.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.17...0.4.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 08:47:05 +00:00
dependabot[bot]
526eba90e7 build: Bump uuid from 1.5.0 to 1.6.1 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.5.0 to 1.6.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.5.0...1.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-23 13:41:27 +00:00
dependabot[bot]
451a084881 build: Bump futures-task from 0.3.28 to 0.3.29
Bumps [futures-task](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-23 13:41:12 +00:00
dependabot[bot]
a5f60338a2 build: Bump object from 0.30.3 to 0.30.4
Bumps [object](https://github.com/gimli-rs/object) from 0.30.3 to 0.30.4.
- [Changelog](https://github.com/gimli-rs/object/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/0.30.3...0.30.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-22 17:35:02 +00:00
dependabot[bot]
a18896bd63 build: Bump serde from 1.0.192 to 1.0.193 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-21 23:29:19 +00:00
Rui Chang
2b457584e0 vmm: add add-user-device support in cloud-hypervisor.yaml
The change is missed when add "add-user-device" support in
53b2e19934, use this commit to fix it.

Signed-off-by: Rui Chang <rui.chang@arm.com>
2023-11-21 09:13:22 +00:00
dependabot[bot]
57ee9b4f9c build: Bump rustix from 0.37.25 to 0.37.27
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.25 to 0.37.27.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.25...v0.37.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-21 00:06:15 +00:00
Thomas Barrett
45b01d592a vmm: assign each pci segment 32-bit mmio allocator
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-20 15:33:50 -08:00
dependabot[bot]
ef16ee37d9 build: Bump getrandom from 0.2.10 to 0.2.11 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.10 to 0.2.11.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 23:31:17 +00:00
Ruslan Mstoi
851ab0ad43 gitlint: validate title components
Valid title format:
component1[, component2, componentN]: submodule: summary

Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated

See: #5846

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-20 08:39:43 -08:00
Michael Zhao
70380d289f ci: Enable OpenAPI validate action
Pull the container `openapitools/openapi-generator-cli` and run the
validation.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2023-11-20 07:45:55 +00:00
dependabot[bot]
4b87964093 build: Bump num-traits from 0.2.16 to 0.2.17
Bumps [num-traits](https://github.com/rust-num/num-traits) from 0.2.16 to 0.2.17.
- [Changelog](https://github.com/rust-num/num-traits/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-num/num-traits/compare/num-traits-0.2.16...num-traits-0.2.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-18 00:14:41 +00:00
dependabot[bot]
16809026cd build: Bump clap from 4.4.7 to 4.4.8 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.7 to 4.4.8.
- [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.4.7...v4.4.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-17 23:16:02 +00:00
Bo Chen
c427f3a862 Jenkinsfile: Skip worker build for more cases
We can skip the CI worker build if the changes are only from gitlint, or
the hidden files in the root folder, such as .github, .gitignore,
.gitlint, .rustfmt.toml, and .typos.toml.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:19 -08:00
Bo Chen
07475d2bc1 gitlint: Increase the title length limit to 72
This is particularly useful for commits with long component names. Of
course, it is better to have concise subject that is less than 50 char.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:19 -08:00
Bo Chen
4d80be3a04 tests: Enable live-upgrade tests based on release v36.0
These live-upgrade tests were disabled due to CLI changes (#5791).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:13 +00:00
dependabot[bot]
af06adfd65 build: Bump serde_repr from 0.1.12 to 0.1.17
Bumps [serde_repr](https://github.com/dtolnay/serde-repr) from 0.1.12 to 0.1.17.
- [Release notes](https://github.com/dtolnay/serde-repr/releases)
- [Commits](https://github.com/dtolnay/serde-repr/compare/0.1.12...0.1.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-17 00:30:50 +00:00
dependabot[bot]
5ff53db239 build: Bump js-sys from 0.3.64 to 0.3.65 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.64 to 0.3.65.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-16 23:54:04 +00:00
Jinank Jain
84b643f80b hypervisor: Add support to bringup AP threads for SEV-SNP guest
As part SMP bringup for a SEV-SNP guest, BSP sets up the VMSA page for
each AP threads and informs hypervisor about the same using a VMGEXIT.
Thus, extend the current GHCB interface to handle this scenario.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Jinank Jain
d7d6054b8c hypervisor: Add support for handling SNP guest request
SEV-SNP guest can request AMD's secure co-processor i.e., PSP to
generate an runtime attesation report. During this process guest needs
to inform PSP about the request and response GPAs where that report
would be generated by the PSP. This is handled via a VMGEXIT request.
Thus, extend the current GHCB handling to add support for it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Jinank Jain
96bc282759 hypervisor: mshv: Add VmFd to MshvVcpu struct
This would be required later to implement few additional operations on
top of it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Yi Wang
a69d8c63b3 vmm: speed up JSON load when reading snap files
We found that it's slow to load JSON when reading snap files. As
described in [1], using from_slice instead of from_reader can fix
this.

Also, fix the error type being returned.

1. https://github.com/serde-rs/json/issues/160

Signed-off-by: Yi Wang <foxywang@tencent.com>
2023-11-16 14:56:04 -08:00
Rob Bradford
0eade51306 build: Remove OpenAPI validation
This container is now failing.

See: #5960

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-16 16:44:04 +00:00
Ruslan Mstoi
ea7999e064 build: add gitlint commit message linter
Implement commit message check workflow using gitlint

Fixes: #5840

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-16 16:09:17 +00:00
Thomas Barrett
5f3ff3c44a devices: fix pv_panic alignment
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-16 08:28:23 +00:00
dependabot[bot]
0299bec152 build: Bump async-recursion from 1.0.4 to 1.0.5
Bumps [async-recursion](https://github.com/dcchut/async-recursion) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dcchut/async-recursion/releases)
- [Commits](https://github.com/dcchut/async-recursion/compare/v1.0.4...v1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-16 00:42:43 +00:00
dependabot[bot]
61529a6158 build: Bump zerocopy from 0.7.25 to 0.7.26 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.25 to 0.7.26.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.25...v0.7.26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-15 23:40:17 +00:00
dependabot[bot]
e5370cddf0 build: Bump concurrent-queue from 2.2.0 to 2.3.0
Bumps [concurrent-queue](https://github.com/smol-rs/concurrent-queue) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/smol-rs/concurrent-queue/releases)
- [Changelog](https://github.com/smol-rs/concurrent-queue/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/concurrent-queue/compare/v2.2.0...v2.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-15 00:45:15 +00:00
dependabot[bot]
c30339debc build: Bump arbitrary from 1.3.1 to 1.3.2 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/derive_arbitrary@1.3.1...v1.3.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 23:27:53 +00:00
dependabot[bot]
819e7f7e4d build: Bump micro_http from 0d0fdcd to a4d632f
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `0d0fdcd` to `a4d632f`.
- [Commits](0d0fdcd50e...a4d632f2c5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 16:00:25 +00:00
Bo Chen
de2fcc2d87 tests: Stabilize snapshot_restore tests
Since the 'write()' to the event file was moved to its own thread
(see #5633), we have no reliable way to read the latest contents of
the event file from our integration tests, since we can't ensure the
'read()' from our test always happen after 'write()' is completed from
Cloud Hypervisor. This is also why we started to see random failures on
snapshot_restore tests (particularly when the system workload is high).

This patch adds a 1s sleep before reading the event file to mitigate the
random failures.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:19:25 +00:00
Bo Chen
d4892f41b3 misc: Stop using deprecated functions from vm-memory crate
See: https://github.com/rust-vmm/vm-memory/pull/247

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:17:42 +00:00
Bo Chen
4d7a4c598a build: Upgrade vm-memory crates and its consumers
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:17:42 +00:00
Bo Chen
d4a163dd39 virtio-devices: Fix beta clippy issue
error: use of a fallible conversion when an infallible one could be used
Error:    --> virtio-devices/src/vhost_user/vu_common_ctrl.rs:206:51
    |
206 |             let actual_size: usize = queue.size().try_into().unwrap();
    |                                                   ^^^^^^^^^^^^^^^^^^^ help: use: `into()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions
    = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`

error: could not compile `virtio-devices` (lib) due to previous error
Error: warning: build failed, waiting for other jobs to finish...
error: could not compile `virtio-devices` (lib test) due to previous error
Error: The process '/home/runner/.cargo/bin/cargo' failed with exit code 101

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:15:45 +00:00
dependabot[bot]
c1e613a9ff build: Bump serde from 1.0.189 to 1.0.192 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.192.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.192)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 16:01:50 -08:00
dependabot[bot]
fcebc4491a build: Bump vfio-ioctls from 847b0aa to 59c604f
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `847b0aa` to `59c604f`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](847b0aa504...59c604fa6e)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-11 09:04:38 +00:00
dependabot[bot]
f75515eedb build: Bump smallvec from 1.11.1 to 1.11.2 in /fuzz
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.1...v1.11.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-10 23:36:27 +00:00
Muminul Islam
4cea713adf docs: Add documentations for MSHV and related features
This patch adds brief overview and relation of mshv,
igvm, and sev-snp features.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-11-10 11:30:40 -08:00
dependabot[bot]
148955f725 build: Bump async-task from 4.4.0 to 4.5.0
Bumps [async-task](https://github.com/smol-rs/async-task) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/smol-rs/async-task/releases)
- [Changelog](https://github.com/smol-rs/async-task/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-task/compare/v4.4.0...v4.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-10 09:01:28 +00:00
dependabot[bot]
49ef29c9b5 build: Bump wasm-bindgen from 0.2.87 to 0.2.88 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.87 to 0.2.88.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.87...0.2.88)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-09 23:45:20 +00:00
Bo Chen
62db13ba0e tests: Temporarily disable vhost_user_blk tests on aarch64
See: #5934

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-09 07:57:44 +00:00
Thomas Barrett
d9ed281719 block: fix aio backend behavior when writeback enabled
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-08 19:24:40 -08:00
dependabot[bot]
56f0cfefa8 build: Bump libc from 0.2.149 to 0.2.150 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.150.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.149...0.2.150)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-08 19:23:47 -08:00
dependabot[bot]
815c7f45c4 build: Bump clap from 4.3.11 to 4.4.7
Bumps [clap](https://github.com/clap-rs/clap) from 4.3.11 to 4.4.7.
- [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.3.11...v4.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-08 17:01:37 -08:00
Rob Bradford
4817578ce9 build: Bump version used into container for clap crate
See: #5925

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-08 08:13:45 -08:00
Rob Bradford
13fae28635 build: Bump MSRV to 1.70 for clap crate
See: #5925

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-08 08:13:45 -08:00
Wei Liu
14907d0752 scripts: fix the check for GitHub authentication token
When the script is invoked via dev_cli.sh, it always gets AUTH_DOWNLOAD_TOKEN
from the environment. The original test always returns true.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-11-08 10:02:15 +00:00
dependabot[bot]
aad5cd7858 build: Bump futures-sink from 0.3.28 to 0.3.29 in /fuzz
Bumps [futures-sink](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-07 16:12:11 -08:00
Rob Bradford
99a2551046 scripts: Propagate AUTH_DOWNLOAD_TOKEN into container
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
8d31dfb154 build: Populate AUTH_DOWNLOAD_TOKEN environment variable
Use a stored credential in Jenkins to authenticate the downloads against
GitHub.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
5e1806aed2 scripts: Authenticate to GitHub if token present
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
72e213ebda scripts: Extract downloading hypervisor-fw to a function
This will reduce the number of locations that it will be necessary to
add authentication support.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
dependabot[bot]
df242e9468 build: Bump zerocopy from 0.7.24 to 0.7.25 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.24 to 0.7.25.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.24...v0.7.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 16:58:27 -08:00
dependabot[bot]
3ce463f482 build: Bump mshv-bindings from af397ea to f00c7d4
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `af397ea` to `f00c7d4`.
- [Commits](af397ea851...f00c7d483c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 16:58:11 -08:00
dependabot[bot]
d38e951234 build: Bump parking from 2.1.1 to 2.2.0
Bumps [parking](https://github.com/smol-rs/parking) from 2.1.1 to 2.2.0.
- [Release notes](https://github.com/smol-rs/parking/releases)
- [Changelog](https://github.com/smol-rs/parking/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/parking/compare/v2.1.1...v2.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 17:42:38 +00:00
Bo Chen
1be40e2339 tests: Improve debuggability for "test_vfio"
Instead of relying on "wc" and "grep", this patch provides helper
functions for checking line counts and searching/counting keywords.
To understand assertion failures better, it also generate logs for the
L1/L2 VM commands when checks fail.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
bc04e75b4b test_infra, tests: Unify error message formatting
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
5f7a847822 test_infra: Print error and output if host commands failed
It helps with understanding integration test errors when host commands
failed to run or complete.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
5976a37cf4 tests: Print details when checks on event monitor failed
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
dependabot[bot]
1cfb793528 build: Bump zerocopy from 0.7.23 to 0.7.24 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.23 to 0.7.24.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.23...v0.7.24)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-03 23:51:34 +00:00
dependabot[bot]
30bc8ffa8d build: Bump unicode-ident from 1.0.11 to 1.0.12
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.11...1.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-03 00:13:49 +00:00
dependabot[bot]
8b7c859d14 build: Bump zerocopy from 0.7.20 to 0.7.23 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.20 to 0.7.23.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.20...v0.7.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-02 23:22:08 +00:00
Yong He
d1ba50f10e tests: Add a test simultaneously set serial and console as TTY mode
Add a test that supports configuring serial and console as TTY mode
at the same time. With this configuration, the VM can set up a legacy
serial device as an early printk console device, and then change to a
virito console device after the virito console device is initialized.

In this case, we can capture the logs printed by legacy serial on early
boot, and later by the virtio console.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-11-02 11:06:30 -07:00
Yong He
bb38e4e599 vmm: Allow simultaneously set serial and console as TTY mode
Cloud Hypovrisor supports legacy serial device and virito console device
for VMs. Using legacy serial device, CH can capture full VM console logs,
but its implementation is based on KVM PIO emulation and has poor
performance. Using the virtio console device, the VM console logs will
be sent to CH through the virtio ring, the performance is better, but CH
will only capture the VM console logs after the virtio console device is
initialized, the VM early startup logs will be discarded.

This patch provides a way to enable both the legacy serial device and the
virtio console device as a TTY mode by setting the leagcy serial port as
the VM's early printk device and setting the virtio console as the VM's
main console device.

Then CH can capture early boot logs from the legacy serial device and
capture later logs from the virito console device with better performance.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-11-02 11:06:30 -07:00
Bo Chen
f5899d15f6 build: Release v36.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-02 08:15:04 -07:00
Bo Chen
a4d83ce9c5 main: Add the '--serial socket=' option help information
See: #5708

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-02 08:15:41 +00:00
dependabot[bot]
e1a893793a build: Bump zerocopy from 0.7.8 to 0.7.21
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.8 to 0.7.21.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.8...v0.7.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 23:55:45 +00:00
dependabot[bot]
4c411e1836 build: Bump serde_json from 1.0.107 to 1.0.108 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.108.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.108)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 23:51:29 +00:00
Bo Chen
04ec80c012 Jenkinsfile: Skip 'test_vfio' and 'test_vfio_user' on AMD workers
See: #5895

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-01 15:00:41 +00:00
Bo Chen
bd0ee6236a scripts: Simplify the script for running bare-metal VFIO tests
The script "run_integration_tests_vfio.sh" requires to be ran on a
specific machine with specific hardware (e.g. the "vfio" bera-metal
worker equipped with a Nvidia Tesla T4 card). So the provisioning of the
running machine is out of the scope of this script, including the custom
guest image with Nvidia drivers installed, and properly configured
Nvidia Tesla T4 card.

See: #4405, #5509

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-01 15:00:41 +00:00
Bo Chen
4afd8d96f9 tests: Remove "test_vfio" from the bare-metal worker
With #4324 being resolved, the nested VFIO test (e.g. "test_vfio") is
now a part of the general Azure VM-based workers. No need to run it on
the bare-metal worker.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-01 15:00:41 +00:00
Jianyong Wu
2434e76ee0 aarch64: fdt: Use more appropriate default value for topology
Now, default values for vcpu topology are 0s, that is not correct and may
lead to bug. Fix it by setting default value to 1s. Also add check in
case one or more of these values are zero.

Fixes: #5892
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2023-11-01 21:29:08 +08:00
Bo Chen
1670a5d8af build: Bump toml_edit from 0.19.8 to 0.19.15
Bumps [toml_edit](https://github.com/toml-rs/toml) from 0.19.8 to 0.19.15.
- [Commits](https://github.com/toml-rs/toml/compare/v0.19.8...v0.19.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-01 13:05:30 +00:00
Bo Chen
b312293604 build: Bump MSRV to 1.66
This is required for the following dependency:

toml_edit v0.19.15
└── proc-macro-crate v1.3.1
    ├── zbus_macros v3.14.1 (proc-macro)
        └── zbus v3.14.1
            ├── cloud-hypervisor v35.0.0 (/home/chenb/project/cloud-hypervisor/cloud-hypervisor)
            └── vmm v0.1.0 (/home/chenb/project/cloud-hypervisor/cloud-hypervisor/vmm)
                └── cloud-hypervisor v35.0.0 (/home/chenb/project/cloud-hypervisor/cloud-hypervisor)

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-01 13:05:30 +00:00
dependabot[bot]
0974e06900 build: Bump winapi-util from 0.1.5 to 0.1.6
Bumps [winapi-util](https://github.com/BurntSushi/winapi-util) from 0.1.5 to 0.1.6.
- [Commits](https://github.com/BurntSushi/winapi-util/compare/winapi-util-0.1.5...0.1.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 11:38:04 +00:00
Rob Bradford
2b607da2b3 scripts: Clear the toolchain environment variables for virtiofsd
virtiofsd must be built with the default gnu toolchain so clear the
environment variables that may poisoned by the alternative C library
support.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-01 11:37:04 +00:00
dependabot[bot]
85ec160fa1 build: Bump futures-core from 0.3.28 to 0.3.29 in /fuzz
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-31 23:36:15 +00:00
Bo Chen
d2f71cebca virtio-devices, vmm: Update seccomp list
The seccompiler v0.4.0 started to use `seccomp` syscall instead of the
`prctl` syscall. Also, threads for virtio-deivces should not need any of
these syscalls anyway.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-31 15:34:17 +00:00
Bo Chen
c1f496d912 build: Bump seccompiler from 0.3.0 to 0.4.0
Bumps [seccompiler](https://github.com/rust-vmm/seccompiler) from 0.3.0 to 0.4.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/seccompiler-v0.3.0...v0.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-31 15:34:17 +00:00
dependabot[bot]
c17a11c1b8 build: Bump zerocopy from 0.7.11 to 0.7.20 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.11 to 0.7.20.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.11...v0.7.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-31 00:06:53 +00:00
Thomas Barrett
4980a5f778 block: add copyright text to raw_async_aio.rs
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-10-30 12:34:23 -07:00
Jinank Jain
0287e6a603 hypervisor: Add support for MMIO write emulation
This is very similar MMIO read emulation for SEV-SNP guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
ac43825f79 hypervisor: Add support MMIO read VMGEXIT
MMIO emulation is also performed via VMGEXIT in case of SEV-SNP guest.
Emulation is done in a very similar way like a regular guest. Just need
to make sure that guest memory is access via read/write GPA hypercall
instead of directly accessing it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
7975207e0f hypervisor: Add support for legacy I/O port emulation
Legacy port emulation requires reading RAX register from GHCB page for
SEV-SNP guest. This is the major difference between a regular guest and
SEV-SNP enabled guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
e2288a8d2c hypervisor: Add support for handling extended guest request
Currently MSHV does not support fetching extended guest report and thus
return an appropriate error stating the NAE event is not valid.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
cb5ea05945 hypervisor: Add support for handling #HV Doorbell Page
As part of this handling there are 4 different operations:

1. Getting the hypervisor preffered doorbell page GPA.
2. Informing hypervisor about the doorbell page chosen by the guest
3. Querying the GPA of the doorbell page
4. Clearing the GPA of the doorbell page from hypervisor

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
d6db3a9d32 build: Bump mshv-ioctls from c5a6050 to af397ea
Manually bumped the dependency for mshv-ioctl to get the definition of
required constants.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
d68fec594e hypervisor: Add support for handling SEV INFO request
As part of handling this request, hypervisor is expected to three
things:

1. Maximum GHCB protocol version supported.
2. Minimum GHCB protocol version supported.
3. SEV-page table encryption bit number.

If the guest cannot support the protocol range supplied by the
hypervisor, it should terminate

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
6f4d82bd61 hypervisor: Add support for registering GHCB GPA with hypervisor
SEV-SNP guest allocates a GHCB page and in order to update hypervisor
about the same, there is a vmgexit which allows registering GHCB page
with the hypervisor.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
Jinank Jain
437e6088e6 hypervisor: Add support for handling VMGEXIT for SEV-SNP guest
A VMGEXIT exit occurs for any of the listed NAE events in the GHCB
specification [1] (e.g. CPUID, RDMSR/WRMSR, MMIO, port IO, etc.). Some
of these events are handled by hypervisor while other are handled by
VMM. Currently, we are adding support for one such request i.e.,
report supported SEV-SNP features by hypervisor.

[1] GHCB protocol specification:
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-30 10:23:52 -07:00
dependabot[bot]
7cba80484b build: Bump typenum from 1.16.0 to 1.17.0
Bumps [typenum](https://github.com/paholg/typenum) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/paholg/typenum/releases)
- [Changelog](https://github.com/paholg/typenum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/paholg/typenum/compare/v1.16.0...v1.17.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 13:28:54 +00:00
dependabot[bot]
4cbfccc166 build: Bump paste from 1.0.12 to 1.0.14
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.12 to 1.0.14.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.12...1.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 08:57:40 -07:00
dependabot[bot]
9dca409210 build: Bump clap from 4.4.6 to 4.4.7 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.6 to 4.4.7.
- [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.4.6...v4.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 00:21:36 +00:00
dependabot[bot]
ffb9a051c3 build: Bump arbitrary from 1.3.0 to 1.3.1 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.3.0 to 1.3.1.
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.3.0...derive_arbitrary@1.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 00:16:21 +00:00
dependabot[bot]
53eaa8b89a build: Bump anstyle-wincon from 1.0.1 to 1.0.2
Bumps [anstyle-wincon](https://github.com/rust-cli/anstyle) from 1.0.1 to 1.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v1.0.1...anstyle-wincon-v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 00:02:07 +00:00
Thomas Barrett
bae13c5c56 block: add aio disk backend
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-10-25 10:19:23 -07:00
dependabot[bot]
6105d3ca83 build: Bump async-trait from 0.1.73 to 0.1.74
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.73 to 0.1.74.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.73...0.1.74)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 00:36:36 +00:00
dependabot[bot]
668b210055 build: Bump serde_with from 3.0.0 to 3.4.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.0.0 to 3.4.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.0.0...v3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-24 20:53:50 +00:00
Muminul Islam
5bd113e625 hypervisor: Add API to complete isolated import
This is the function that needs to be called by the VMM
to inform the MSHV that isolation is complete and inform
PSP about this completion.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-24 13:02:34 -07:00
Muminul Islam
dc3903012d hypervisor: Add API to import the isolated pages
Add hypervisor VM specific API to import the isolated
pages. Hypervisor adds those pages for PSP measurement.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-24 13:02:34 -07:00
dependabot[bot]
3a67537227 build: Bump uuid from 1.4.1 to 1.5.0 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.4.1...1.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 23:33:58 +00:00
Muminul Islam
afe798fc19 vmm: Fix clippy warnings
This patch fixes following warnings:

error: boolean to int conversion using if
   --> vmm/src/vm.rs:866:42
|
|                       .create_vm_with_type(if sev_snp_enabled.into() {
    |  __________________________________________^
| |                         1 // SEV_SNP_ENABLED
| |                     } else {
| |                         0 // SEV_SNP_DISABLED
| |                     })
| |_____________________^ help: replace with from: `u64::from(sev_snp_enabled.into())`
|
  = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
  = note: `sev_snp_enabled.into() as u64` or `sev_snp_enabled.into().into()` can also be valid options
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bool_to_int_with_if

error: useless conversion to the same type: `bool`
   --> vmm/src/vm.rs:866:45
|
|                     .create_vm_with_type(if sev_snp_enabled.into() {
|                                             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `sev_snp_enabled`
|
  = note: `-D clippy::useless-conversion` implied by `-D warnings`
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

error: could not compile `vmm` due to 2 previous errors

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-23 16:03:16 -07:00
Thomas Barrett
53b8e1d01e tests: Enable "test_pci_multiple_segments_numa_node"
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-10-21 09:12:50 +01:00
dependabot[bot]
3f67a002a2 build: Bump thiserror from 1.0.49 to 1.0.50 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.49 to 1.0.50.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.49...1.0.50)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-20 23:42:30 +00:00
Bo Chen
43a6eda400 vmm: Add help information for "--numa pci_segments="
See: #5844

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-20 11:44:28 -07:00
Ravi kumar Veeramally
ce902c19ec performance-metrics: switch to clap
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Ravi kumar Veeramally
f160ba41b5 vhost_user_blk: switch to clap
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Ravi kumar Veeramally
627a1456a7 vhost_user_net: switch to clap
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Ravi kumar Veeramally
d1f337aef1 ch-remote: switch to clap
Porting back using clap crate

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Ravi kumar Veeramally
fa22cb0be5 docs: update command line options to use clap
Reverts commit a0922930b1
and update to latest changes.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Wei Liu
7bc3452139 main: switch command parsing to use clap
Partially revert 111225a2a5
and add the new dbus and pvpanic arguments.

As we are switching back to clap observe the following changes.

A few examples:

1. `-v -v -v` needs to be written as`-vvv`
2. `--disk D1 --disk D2` and others need to be written as `--disk D1 D2`.
3. `--option value` needs to be written as `--option=value.`

Change integration tests to adapt to the breaking changes.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2023-10-20 11:44:28 -07:00
Wei Liu
6113483363 docs: add notes on collecting coverage data from in-tree tests
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-10-20 10:35:13 -07:00
Wei Liu
8ba5682e3b scripts: propagate RUSTFLAGS and TARGET_CC to test scripts
There is no need to set them in the test scripts while the main script
already has them.

The consolidates how things are done.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-10-20 10:35:13 -07:00
Wei Liu
c7e51e51e5 scripts: pass BUILD_TARGET directly to test scripts
There is no need to reconstruct it from within the scripts since the
main script already constructed it once.

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

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-10-20 10:35:13 -07:00
Wei Liu
9d42f48f49 scripts: dev_cli.sh: respect preset RUSTFLAGS
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-10-20 10:35:13 -07:00
dependabot[bot]
ec0e0b1b96 build: Bump iced-x86 from 1.19.0 to 1.20.0
Bumps [iced-x86](https://github.com/icedland/iced) from 1.19.0 to 1.20.0.
- [Release notes](https://github.com/icedland/iced/releases)
- [Commits](https://github.com/icedland/iced/compare/v1.19.0...v1.20.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-10-20 11:07:18 +01:00
dependabot[bot]
2123a65288 build: Bump serde from 1.0.188 to 1.0.189 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.188 to 1.0.189.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.188...v1.0.189)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-19 23:47:11 +00:00
Wei Liu
fc6ff07fd7 docs: add a document for collecting coverage data
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-10-19 13:07:54 -07:00
Yi Wang
83b1a30f29 docs: fix the description of host/guest in vsock
In Connecting from Host to Guest section, the host/guest are misused,
this patch fix that.

Signed-off-by: Yi Wang <foxywang@tencent.com>
2023-10-19 09:39:17 -07:00
Muminul Islam
274f1aa2e7 virtio-devices,vm-allocator: Fix clippy warnings
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-19 08:42:17 +01:00
Muminul Islam
a1ce37c2af build: Bump MSRV to 1.65
Sev-Snp on MSHV uses igvm crate to parse the igvm file.
igvm crate needs minimum rust version 1.65 to build.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-10-19 08:42:17 +01:00
dependabot[bot]
6e35fe741e build: Bump bitflags from 2.3.3 to 2.4.1
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.3.3 to 2.4.1.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.3.3...2.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 23:58:34 +00:00
dependabot[bot]
b713ded414 build: Bump lock_api from 0.4.10 to 0.4.11 in /fuzz
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.4.10 to 0.4.11.
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.10...lock_api-0.4.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 23:43:08 +00:00
dependabot[bot]
88aceca983 build: Bump rustix from 0.37.21 to 0.37.25
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.21 to 0.37.25.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.21...v0.37.25)

---
updated-dependencies:
- dependency-name: rustix
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 20:25:58 +00:00
Thomas Barrett
3029fbeafd vmm: Allow assignment of PCI segments to NUMA node
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-10-18 11:18:15 -07:00
Bo Chen
0b4c153d4d arch, vmm: Clear AMX CPUID bits if the feature is not enabled
Fixes: #5833

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-18 11:13:12 -07:00
Bo Chen
7dd260f82f arch, vmm: Add new struct CpuidConfig
This struct contains all configuration fields that controls the way how
we generate CPUID for the guest on x86_64. This allows cleaner extension
when adding new configuration fields.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-18 11:13:12 -07:00
dependabot[bot]
30975ea102 build: Bump serde_with from 3.3.0 to 3.4.0 in /fuzz
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.3.0...v3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 00:04:08 +00:00
Jinank Jain
1afac185ff hypervisor: Enable VMGEXIT offload for SEV-SNP partition
For a SEV-SNP enabled partition on MSHV, some of the VMGEXITS are
offloaded for Hypervisor to handle while the rest are handled by VMM.
By setting this additional partition property hypervisor is informed
about the VMGEXITs it needs to take care off, rest all would be handled
by the CloudHypervisor.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-10-17 14:15:38 -07:00
Bo Chen
aa6e83126c vmm: tdx: Fix a deadlock while accessing vm_config
The lock to `vm_config` is held for accessing `cpus.kvm_hyperv` passing
as a reference to `arch::generate_common_cpuid()`, so acquiring the same
lock again while calling to the same function is a deadlock.

Fixes: 3793ffe888

Reported-by: Yi Wang <foxywang@tencent.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-17 19:41:33 +01:00
Jinank Jain
1b59ab3d7b vmm, hypervisor: Initialize SEV-SNP VM
As part of this initialization for a SEV-SNP VM on MSHV, it is required
that we transition the guest state to secure state using partition
hypercall. This implies all the created VPs will transition to secure
state and could access the guest encrypted memory.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-10-17 17:45:28 +01:00
Anatol Belski
311fc05417 cpu: Store hypervisor object directly instead of separate props
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-10-17 18:43:22 +02:00
Anatol Belski
b52966a12c cpu: Implement AMD compatible topology handling
cpu: Pass APIC id explicitly where needed
topology: Set subleaf number explicitly

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-10-17 18:43:22 +02:00
dependabot[bot]
31686b91d3 build: Bump semver from 1.0.19 to 1.0.20
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.19...1.0.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 03:56:17 +00:00
dependabot[bot]
1a23a98847 build: Bump jobserver from 0.1.26 to 0.1.27 in /fuzz
Bumps [jobserver](https://github.com/alexcrichton/jobserver-rs) from 0.1.26 to 0.1.27.
- [Commits](https://github.com/alexcrichton/jobserver-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-13 23:30:44 +00:00
dependabot[bot]
2b8b04c129 build: Bump regex from 1.9.1 to 1.9.4
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.1 to 1.9.4.
- [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.9.1...1.9.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-13 00:12:19 +00:00
dependabot[bot]
d8e71da071 build: Bump zerocopy from 0.7.8 to 0.7.11 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.8 to 0.7.11.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.8...v0.7.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-12 23:26:07 +00:00
dom.song
7f47a030e7 tests: Update spdk code to support Ampere's new CPU
When performing integration testing on the Ampere One server, an error occurred when compiling spdk and not recognizing the CPU ID.
The latest spdk already contains fixes.

Signed-off-by: dom.song <dom.song@amperecomputing.com>
2023-10-12 11:25:38 -07:00
dependabot[bot]
88f7124c5f build: Bump hermit-abi from 0.3.2 to 0.3.3
Bumps [hermit-abi](https://github.com/hermitcore/hermit-rs) from 0.3.2 to 0.3.3.
- [Release notes](https://github.com/hermitcore/hermit-rs/releases)
- [Commits](https://github.com/hermitcore/hermit-rs/compare/hermit-abi-0.3.2...hermit-abi-0.3.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-12 03:32:24 +00:00
dependabot[bot]
85894476d8 build: Bump semver from 1.0.19 to 1.0.20 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.19...1.0.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-12 00:17:32 +00:00
Jinank Jain
a5763bcb6c hypervisor: Set isolation policy for SNP guest
It's a requirement that a SEV-SNP enabled guest on MSHV must have
isolation policy set before launching the guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-10-11 17:15:51 -07:00
dependabot[bot]
3981642dd1 build: Bump tempfile from 3.7.1 to 3.8.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.7.1 to 3.8.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.7.1...v3.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 08:46:02 +01:00
dependabot[bot]
4889c4847c build: Bump errno from 0.3.2 to 0.3.5
Bumps [errno](https://github.com/lambda-fairy/rust-errno) from 0.3.2 to 0.3.5.
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 00:22:44 +00:00
dependabot[bot]
0e798c0e92 build: Bump proc-macro2 from 1.0.67 to 1.0.69 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.67 to 1.0.69.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.67...1.0.69)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-10 23:39:53 +00:00
dependabot[bot]
032098b10c build: Bump zerocopy from 0.7.1 to 0.7.8
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.1 to 0.7.8.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.1...v0.7.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-10 00:17:50 +00:00
dependabot[bot]
81bee58ab3 build: Bump libc from 0.2.148 to 0.2.149 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.148 to 0.2.149.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.148...0.2.149)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 23:40:40 +00:00
dependabot[bot]
328a1710f6 build: Bump sha1 from 0.10.5 to 0.10.6
Bumps [sha1](https://github.com/RustCrypto/hashes) from 0.10.5 to 0.10.6.
- [Commits](https://github.com/RustCrypto/hashes/compare/sha1-v0.10.5...sha1-v0.10.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-08 08:31:47 +00:00
dependabot[bot]
12120c2e3e build: Bump byteorder from 1.4.3 to 1.5.0 in /fuzz
Bumps [byteorder](https://github.com/BurntSushi/byteorder) from 1.4.3 to 1.5.0.
- [Changelog](https://github.com/BurntSushi/byteorder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/byteorder/compare/1.4.3...1.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-06 23:44:05 +00:00
Praveen K Paladugu
cf1ec56d3a tests: Add test for socket backend of serial port
This test creates a pty link to the socket and checks pty
interactions.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2023-10-05 15:26:29 +01:00
Praveen K Paladugu
044f3f758e serial_manager: Remove serial socket
Remove the backend socket of serial port while shutting down guest.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2023-10-05 15:26:29 +01:00
Praveen K Paladugu
6d1077fc3c vmm: Unix socket backend for serial port
Cloud-Hypervisor takes a path for Unix socket, where it will listen
on. Users can connect to the other end of the socket and access serial
port on the guest.

    "--serial socket=/path/to/socket" is the cmdline option to pass to
cloud-hypervisor.

Users can use socat like below to access guest's serial port once the
guest starts to boot:

    socat -,crnl UNIX-CONNECT:/path/to/socket

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
2023-10-05 15:26:29 +01:00
dependabot[bot]
399c596af8 build: Bump zerocopy from 0.7.6 to 0.7.8 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.6 to 0.7.8.
- [Commits](https://github.com/google/zerocopy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-05 07:49:43 +00:00
Bo Chen
1e01b5eabc main: Report enabled features from CLI with "--version -v"
Fixes: #5817

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-05 08:40:50 +01:00
Bo Chen
ff651e0e28 vmm: Report enabled features from the '/vmm.ping' endpoint
Fixes: #5817

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-10-05 08:40:50 +01:00
dependabot[bot]
11838fca11 build: Bump openssl-src from 300.1.3+3.1.2 to 300.1.5+3.1.3
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 300.1.3+3.1.2 to 300.1.5+3.1.3.
- [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-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-05 00:10:10 +00:00
dependabot[bot]
ddf332b127 build: Bump enumflags2 from 0.7.7 to 0.7.8
Bumps [enumflags2](https://github.com/meithecatte/enumflags2) from 0.7.7 to 0.7.8.
- [Release notes](https://github.com/meithecatte/enumflags2/releases)
- [Commits](https://github.com/meithecatte/enumflags2/compare/v0.7.7...v0.7.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 00:02:28 +00:00
dependabot[bot]
eaee6eec2b build: Bump atomic-waker from 1.1.1 to 1.1.2
Bumps [atomic-waker](https://github.com/smol-rs/atomic-waker) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/smol-rs/atomic-waker/releases)
- [Changelog](https://github.com/smol-rs/atomic-waker/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/atomic-waker/compare/v1.1.1...v1.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-03 10:06:28 -07:00
dependabot[bot]
0692cb99fb build: Bump zerocopy from 0.7.5 to 0.7.6 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.5 to 0.7.6.
- [Commits](https://github.com/google/zerocopy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 23:58:10 +00:00
dependabot[bot]
b1cc3e3cc3 build: Bump semver from 1.0.18 to 1.0.19
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.18...1.0.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-30 08:29:40 +01:00
dependabot[bot]
c31b34c9f8 build: Bump thiserror from 1.0.48 to 1.0.49 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.48 to 1.0.49.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.48...1.0.49)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-29 23:56:41 +00:00
dependabot[bot]
821e606663 build: Bump async-process from 1.7.0 to 1.8.0
Bumps [async-process](https://github.com/smol-rs/async-process) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/smol-rs/async-process/releases)
- [Changelog](https://github.com/smol-rs/async-process/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-process/compare/v1.7.0...v1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-29 00:35:26 +00:00
dependabot[bot]
66520de49b build: Bump micro_http from 0d0fdcd to a4d632f in /fuzz
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `0d0fdcd` to `a4d632f`.
- [Commits](0d0fdcd50e...a4d632f2c5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-28 23:25:53 +00:00
dependabot[bot]
e80a3847ca build: Bump num-traits from 0.2.15 to 0.2.16
Bumps [num-traits](https://github.com/rust-num/num-traits) from 0.2.15 to 0.2.16.
- [Changelog](https://github.com/rust-num/num-traits/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-num/num-traits/compare/num-traits-0.2.15...num-traits-0.2.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-28 15:22:36 +01:00
dependabot[bot]
11c0aa3f24 build: Bump semver from 1.0.18 to 1.0.19 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.18...1.0.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-27 23:41:19 +00:00
Bo Chen
9abb12fd71 vmm: Return the right error from Vcpu::snapshot()
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-27 08:51:40 +01:00
Jinank Jain
db785e6969 tests: Enable testing for multi PCI segment for mshv
This test is now supported on MSHV so we can re-enable the support for
it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-09-27 08:51:19 +01:00
dependabot[bot]
0604721c72 build: Bump serde from 1.0.168 to 1.0.188 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.168 to 1.0.188.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.168...v1.0.188)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-27 00:25:21 +00:00
dependabot[bot]
3bcf22fbb0 build: Bump parking from 2.1.0 to 2.1.1
Bumps [parking](https://github.com/smol-rs/parking) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/smol-rs/parking/releases)
- [Changelog](https://github.com/smol-rs/parking/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/parking/compare/v2.1.0...v2.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-26 23:55:11 +00:00
Anatol Belski
830da38e5a Revert "build: Skip 'test_vfio' on AMD workers"
This reverts commit c70f133b72.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-09-26 10:40:18 +01:00
Anatol Belski
8d0e12b1d1 resources: Add CONFIG_KVM_AMD=y to x86 config
This is required for test_vfio to run on AMD.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2023-09-26 10:40:18 +01:00
Bo Chen
3ca684b26e build: Bump versions of acpi_tables and zerocopy
The 'derive' feature of `zerocopy` crate now is optional and requires to
be enabled explicitly [1]. Also, a version bump on `acpi_tables` is
needed to reply on a single version of `zerocopy` to avoid compilation
errors.

[1] https://github.com/google/zerocopy/pull/176

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-09-26 08:47:39 +01:00
dependabot[bot]
50bdd1bf84 build: Bump waker-fn from 1.1.0 to 1.1.1
Bumps [waker-fn](https://github.com/smol-rs/waker-fn) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/smol-rs/waker-fn/releases)
- [Changelog](https://github.com/smol-rs/waker-fn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/waker-fn/compare/v1.1.0...v1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-26 00:27:25 +00:00
dependabot[bot]
a24cafd051 build: Bump bumpalo from 3.13.0 to 3.14.0 in /fuzz
Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.13.0 to 3.14.0.
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/compare/3.13.0...3.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 23:45:57 +00:00
Dario Nieuwenhuis
beeb2f5136 docs/balloon: fix typos
Signed-off-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2023-09-23 09:37:32 +01:00
dependabot[bot]
3fe4c3eafb build: Bump proc-macro2 from 1.0.66 to 1.0.67 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.66 to 1.0.67.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.66...1.0.67)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-21 23:31:58 +00:00
128 changed files with 5980 additions and 2640 deletions

View File

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

View File

@@ -13,13 +13,13 @@ jobs:
- stable - stable
- beta - beta
- nightly - nightly
- "1.64" - "1.70"
target: target:
- x86_64-unknown-linux-gnu - x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl - x86_64-unknown-linux-musl
steps: steps:
- name: Code checkout - name: Code checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -54,6 +54,9 @@ jobs:
- name: Build (sev_snp) - name: Build (sev_snp)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (igvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "igvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (mshv + kvm) - name: Build (mshv + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

View File

@@ -5,7 +5,7 @@ jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Set up Python 3.x - name: Set up Python 3.x
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Code checkout - name: Code checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v1

View File

@@ -14,7 +14,7 @@ jobs:
- x86_64-unknown-linux-gnu - x86_64-unknown-linux-gnu
steps: steps:
- name: Code checkout - name: Code checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Rust toolchain (${{ matrix.rust }}) - name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:

26
.github/workflows/gitlint.yaml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Commit messages check
on:
pull_request:
jobs:
gitlint:
name: Check commit messages
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade gitlint
- name: Lint git commit messages
run: |
gitlint --commits origin/$GITHUB_BASE_REF..

View File

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

16
.github/workflows/openapi.yaml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Cloud Hypervisor OpenAPI Validation
on:
pull_request:
jobs:
Validate:
runs-on: ubuntu-latest
container: openapitools/openapi-generator-cli
steps:
- uses: actions/checkout@v4
- name: Validate OpenAPI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
/usr/local/bin/docker-entrypoint.sh validate -i vmm/src/api/openapi/cloud-hypervisor.yaml

View File

@@ -34,7 +34,7 @@ jobs:
experimental: true experimental: true
steps: steps:
- name: Code checkout - name: Code checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -109,6 +109,14 @@ jobs:
command: clippy command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (igvm)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "igvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (kvm + tdx) - name: Clippy (kvm + tdx)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }} if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
@@ -125,6 +133,6 @@ jobs:
name: Typos / Spellcheck name: Typos / Spellcheck
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
# Executes "typos ." # Executes "typos ."
- uses: crate-ci/typos@v1.16.11 - uses: crate-ci/typos@v1.16.11

View File

@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Code checkout - name: Code checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install musl-gcc - name: Install musl-gcc
run: sudo apt install -y musl-tools run: sudo apt install -y musl-tools
- name: Create release directory - name: Create release directory
@@ -16,29 +16,29 @@ jobs:
- name: Install Rust toolchain (x86_64-unknown-linux-gnu) - name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: "1.67.1" toolchain: "1.70"
target: x86_64-unknown-linux-gnu target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl) - name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: "1.67.1" toolchain: "1.70"
target: x86_64-unknown-linux-musl target: x86_64-unknown-linux-musl
- name: Build - name: Build
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
toolchain: "1.67.1" toolchain: "1.70"
command: build command: build
args: --all --release --features mshv --target=x86_64-unknown-linux-gnu args: --all --release --features mshv --target=x86_64-unknown-linux-gnu
- name: Static Build - name: Static Build
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
toolchain: "1.67.1" toolchain: "1.70"
command: build command: build
args: --all --release --features mshv --target=x86_64-unknown-linux-musl args: --all --release --features mshv --target=x86_64-unknown-linux-musl
- name: Install Rust toolchain (aarch64-unknown-linux-musl) - name: Install Rust toolchain (aarch64-unknown-linux-musl)
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: "1.67.1" toolchain: "1.70"
target: aarch64-unknown-linux-musl target: aarch64-unknown-linux-musl
override: true override: true
- name: Create Release - name: Create Release

15
.gitlint Normal file
View File

@@ -0,0 +1,15 @@
[general]
extra-path=scripts/gitlint/rules.py
regex-style-search=true
[ignore-by-author-name]
regex=dependabot
ignore=all
# default 72
[title-max-length]
line-length=72
# default 80
[body-max-line-length]
line-length=72

632
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "cloud-hypervisor" name = "cloud-hypervisor"
version = "35.0.0" version = "37.0.0"
authors = ["The Cloud Hypervisor Authors"] authors = ["The Cloud Hypervisor Authors"]
edition = "2021" edition = "2021"
default-run = "cloud-hypervisor" default-run = "cloud-hypervisor"
@@ -15,7 +15,7 @@ homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
# a.) A dependency requires it, # a.) A dependency requires it,
# b.) If we want to use a new feature and that MSRV is at least 6 months old, # 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. # c.) There is a security issue that is addressed by the toolchain update.
rust-version = "1.64" rust-version = "1.70"
[profile.release] [profile.release]
lto = true lto = true
@@ -31,15 +31,15 @@ debug = true
[dependencies] [dependencies]
anyhow = "1.0.75" anyhow = "1.0.75"
api_client = { path = "api_client" } api_client = { path = "api_client" }
argh = "0.1.9" clap = { version = "4.4.7", features = ["string"] }
dhat = { version = "0.3.2", optional = true } dhat = { version = "0.3.2", optional = true }
epoll = "4.3.3" epoll = "4.3.3"
event_monitor = { path = "event_monitor" } event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" } hypervisor = { path = "hypervisor" }
libc = "0.2.147" libc = "0.2.147"
log = { version = "0.4.17", features = ["std"] } log = { version = "0.4.20", features = ["std"] }
option_parser = { path = "option_parser" } option_parser = { path = "option_parser" }
seccompiler = "0.3.0" seccompiler = "0.4.0"
serde_json = "1.0.107" serde_json = "1.0.107"
signal-hook = "0.3.17" signal-hook = "0.3.17"
thiserror = "1.0.40" thiserror = "1.0.40"
@@ -47,7 +47,7 @@ tpm = { path = "tpm"}
tracer = { path = "tracer" } tracer = { path = "tracer" }
vmm = { path = "vmm" } vmm = { path = "vmm" }
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"
vm-memory = "0.12.2" vm-memory = "0.13.1"
zbus = { version = "3.11.1", optional = true } zbus = { version = "3.11.1", optional = true }
# List of patched crates # List of patched crates
@@ -64,15 +64,18 @@ serde_json = "1.0.107"
test_infra = { path = "test_infra" } test_infra = { path = "test_infra" }
wait-timeout = "0.2.0" wait-timeout = "0.2.0"
# Please adjust `vmm::feature_list()` accordingly when changing the
# feature list below
[features] [features]
default = ["kvm", "io_uring"] default = ["kvm", "io_uring"]
dbus_api = ["zbus", "vmm/dbus_api"] dbus_api = ["zbus", "vmm/dbus_api"]
dhat-heap = ["dhat"] # For heap profiling dhat-heap = ["dhat"] # For heap profiling
guest_debug = ["vmm/guest_debug"] guest_debug = ["vmm/guest_debug"]
igvm = ["vmm/igvm", "mshv"]
io_uring = ["vmm/io_uring"] io_uring = ["vmm/io_uring"]
kvm = ["vmm/kvm"] kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"] mshv = ["vmm/mshv"]
sev_snp = ["vmm/sev_snp", "mshv"] sev_snp = ["igvm", "vmm/sev_snp", "mshv"]
tdx = ["vmm/tdx"] tdx = ["vmm/tdx"]
tracing = ["vmm/tracing", "tracer/tracing"] tracing = ["vmm/tracing", "tracer/tracing"]

31
Jenkinsfile vendored
View File

@@ -53,6 +53,9 @@ pipeline {
return runWorkers return runWorkers
} }
} }
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages { stages {
stage('Checkout') { stage('Checkout') {
steps { steps {
@@ -64,11 +67,6 @@ pipeline {
sh 'scripts/prepare_vdpa.sh' sh 'scripts/prepare_vdpa.sh'
} }
} }
stage('Run OpenAPI tests') {
steps {
sh 'scripts/run_openapi_tests.sh'
}
}
stage('Run unit tests') { stage('Run unit tests') {
steps { steps {
sh 'scripts/dev_cli.sh tests --unit' sh 'scripts/dev_cli.sh tests --unit'
@@ -125,6 +123,9 @@ pipeline {
return runWorkers return runWorkers
} }
} }
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages { stages {
stage('Checkout') { stage('Checkout') {
steps { steps {
@@ -364,6 +365,9 @@ pipeline {
} }
} }
} }
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages { stages {
stage('Checkout') { stage('Checkout') {
steps { steps {
@@ -405,6 +409,9 @@ pipeline {
} }
} }
} }
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages { stages {
stage('Checkout') { stage('Checkout') {
steps { steps {
@@ -505,5 +512,19 @@ def boolean skipWorkerBuild() {
return true return true
} }
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v '^\\.'"
) != 0) {
return true
}
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v 'gitlint'"
) != 0) {
return true
}
return false return false
} }

View File

@@ -150,7 +150,7 @@ $ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh $ ./create-cloud-init.sh
$ ./cloud-hypervisor \ $ ./cloud-hypervisor \
--kernel ./hypervisor-fw \ --kernel ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw --disk path=/tmp/ubuntu-cloudinit.img \ --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \ --cpus boot=4 \
--memory size=1024M \ --memory size=1024M \
--net "tap=,mac=,ip=,mask=" --net "tap=,mac=,ip=,mask="
@@ -163,7 +163,7 @@ GRUB) is required then it necessary to switch to the serial console instead of
```shell ```shell
$ ./cloud-hypervisor \ $ ./cloud-hypervisor \
--kernel ./hypervisor-fw \ --kernel ./hypervisor-fw \
--disk path=focal-server-cloudimg-amd64.raw --disk path=/tmp/ubuntu-cloudinit.img \ --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \ --cpus boot=4 \
--memory size=1024M \ --memory size=1024M \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
@@ -225,7 +225,7 @@ $ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh $ ./create-cloud-init.sh
$ ./cloud-hypervisor \ $ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--disk path=focal-server-cloudimg-amd64.raw --disk path=/tmp/ubuntu-cloudinit.img \ --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cmdline "console=hvc0 root=/dev/vda1 rw" \ --cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \ --cpus boot=4 \
--memory size=1024M \ --memory size=1024M \
@@ -239,7 +239,7 @@ $ sudo setcap cap_net_admin+ep ./cloud-hypervisor
$ ./create-cloud-init.sh $ ./create-cloud-init.sh
$ ./cloud-hypervisor \ $ ./cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/arm64/boot/Image \ --kernel ./linux-cloud-hypervisor/arch/arm64/boot/Image \
--disk path=focal-server-cloudimg-arm64.raw --disk path=/tmp/ubuntu-cloudinit.img \ --disk path=focal-server-cloudimg-arm64.raw path=/tmp/ubuntu-cloudinit.img \
--cmdline "console=hvc0 root=/dev/vda1 rw" \ --cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \ --cpus boot=4 \
--memory size=1024M \ --memory size=1024M \

View File

@@ -14,14 +14,14 @@ anyhow = "1.0.75"
byteorder = "1.4.3" byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" } hypervisor = { path = "../hypervisor" }
libc = "0.2.147" libc = "0.2.147"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] } linux-loader = { version = "0.10.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.17" log = "0.4.20"
serde = { version = "1.0.168", features = ["rc", "derive"] } serde = { version = "1.0.168", features = ["rc", "derive"] }
thiserror = "1.0.40" thiserror = "1.0.40"
uuid = "1.3.4" uuid = "1.3.4"
versionize = "0.1.10" versionize = "0.1.10"
versionize_derive = "0.1.4" versionize_derive = "0.1.4"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-bitmap"] } vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" } vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] } vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }

View File

@@ -290,10 +290,7 @@ fn create_cpu_nodes(
fdt.property_u32("#size-cells", 0x0)?; fdt.property_u32("#size-cells", 0x0)?;
let num_cpus = vcpu_mpidr.len(); let num_cpus = vcpu_mpidr.len();
let threads_per_core = vcpu_topology.unwrap_or_default().0; let (threads_per_core, cores_per_package, packages) = vcpu_topology.unwrap_or((1, 1, 1));
let cores_per_package = vcpu_topology.unwrap_or_default().1;
let packages = vcpu_topology.unwrap_or_default().2;
let max_cpus: u32 = (threads_per_core * cores_per_package * packages).into(); let max_cpus: u32 = (threads_per_core * cores_per_package * packages).into();
// Add cache info. // Add cache info.

View File

@@ -1,8 +1,9 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved. // Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
use std::os::fd::AsFd;
use std::result; use std::result;
use vm_memory::{Bytes, GuestAddress, GuestMemory}; use vm_memory::{GuestAddress, GuestMemory};
/// Errors thrown while loading UEFI binary /// Errors thrown while loading UEFI binary
#[derive(Debug)] #[derive(Debug)]
@@ -24,7 +25,7 @@ pub fn load_uefi<F, M: GuestMemory>(
uefi_image: &mut F, uefi_image: &mut F,
) -> Result<()> ) -> Result<()>
where where
F: Read + Seek, F: Read + Seek + AsFd,
{ {
let uefi_size = uefi_image let uefi_size = uefi_image
.seek(SeekFrom::End(0)) .seek(SeekFrom::End(0))
@@ -36,6 +37,6 @@ where
} }
uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?; uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
guest_mem guest_mem
.read_exact_from(guest_addr, uefi_image, uefi_size) .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
.map_err(|_| Error::ReadUefiImage) .map_err(|_| Error::ReadUefiImage)
} }

View File

@@ -91,8 +91,9 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use x86_64::{ pub use x86_64::{
arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid, arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, generate_ram_ranges, get_host_cpu_phys_bits, initramfs_load_addr, layout,
layout::CMDLINE_START, regs, CpuidFeatureEntry, EntryPoint, _NSIG, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry,
EntryPoint, _NSIG,
}; };
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`. /// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
@@ -108,6 +109,7 @@ pub struct NumaNode {
pub memory_regions: Vec<Arc<GuestRegionMmap>>, pub memory_regions: Vec<Arc<GuestRegionMmap>>,
pub hotplug_regions: Vec<Arc<GuestRegionMmap>>, pub hotplug_regions: Vec<Arc<GuestRegionMmap>>,
pub cpus: Vec<u8>, pub cpus: Vec<u8>,
pub pci_segments: Vec<u16>,
pub distances: BTreeMap<u32, u8>, pub distances: BTreeMap<u32, u8>,
pub memory_zones: Vec<String>, pub memory_zones: Vec<String>,
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]

View File

@@ -37,6 +37,9 @@ const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit.
const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit. const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit.
const MTRR_EDX_BIT: u8 = 12; // Hypervisor ecx bit. const MTRR_EDX_BIT: u8 = 12; // Hypervisor ecx bit.
const INVARIANT_TSC_EDX_BIT: u8 = 8; // Invariant TSC bit on 0x8000_0007 EDX const INVARIANT_TSC_EDX_BIT: u8 = 8; // Invariant TSC bit on 0x8000_0007 EDX
const AMX_BF16: u8 = 22; // AMX tile computation on bfloat16 numbers
const AMX_TILE: u8 = 24; // AMX tile load/store instructions
const AMX_INT8: u8 = 25; // AMX tile computation on 8-bit integers
// KVM feature bits // KVM feature bits
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
@@ -145,6 +148,15 @@ struct BootParamsWrapper(boot_params);
// SAFETY: BootParamsWrap is a wrapper over `boot_params` (a series of ints). // SAFETY: BootParamsWrap is a wrapper over `boot_params` (a series of ints).
unsafe impl ByteValued for BootParamsWrapper {} unsafe impl ByteValued for BootParamsWrapper {}
pub struct CpuidConfig {
pub sgx_epc_sections: Option<Vec<SgxEpcSection>>,
pub phys_bits: u8,
pub kvm_hyperv: bool,
#[cfg(feature = "tdx")]
pub tdx: bool,
pub amx: bool,
}
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Error writing MP table to memory. /// Error writing MP table to memory.
@@ -552,11 +564,7 @@ impl CpuidFeatureEntry {
pub fn generate_common_cpuid( pub fn generate_common_cpuid(
hypervisor: &Arc<dyn hypervisor::Hypervisor>, hypervisor: &Arc<dyn hypervisor::Hypervisor>,
topology: Option<(u8, u8, u8)>, config: &CpuidConfig,
sgx_epc_sections: Option<Vec<SgxEpcSection>>,
phys_bits: u8,
kvm_hyperv: bool,
#[cfg(feature = "tdx")] tdx_enabled: bool,
) -> super::Result<Vec<CpuIdEntry>> { ) -> super::Result<Vec<CpuIdEntry>> {
// SAFETY: cpuid called with valid leaves // SAFETY: cpuid called with valid leaves
if unsafe { x86_64::__cpuid(1) }.ecx & 1 << HYPERVISOR_ECX_BIT == 1 << HYPERVISOR_ECX_BIT { if unsafe { x86_64::__cpuid(1) }.ecx & 1 << HYPERVISOR_ECX_BIT == 1 << HYPERVISOR_ECX_BIT {
@@ -574,7 +582,10 @@ pub fn generate_common_cpuid(
); );
} }
info!("Generating guest CPUID for with physical address size: {phys_bits}"); info!(
"Generating guest CPUID for with physical address size: {}",
config.phys_bits
);
let cpuid_patches = vec![ let cpuid_patches = vec![
// Patch tsc deadline timer bit // Patch tsc deadline timer bit
CpuidPatch { CpuidPatch {
@@ -615,16 +626,12 @@ pub fn generate_common_cpuid(
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
if let Some(t) = topology { if let Some(sgx_epc_sections) = &config.sgx_epc_sections {
update_cpuid_topology(&mut cpuid, t.0, t.1, t.2);
}
if let Some(sgx_epc_sections) = sgx_epc_sections {
update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?; update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?;
} }
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
let tdx_capabilities = if tdx_enabled { let tdx_capabilities = if config.tdx {
let caps = hypervisor let caps = hypervisor
.tdx_capabilities() .tdx_capabilities()
.map_err(Error::TdxCapabilities)?; .map_err(Error::TdxCapabilities)?;
@@ -637,6 +644,12 @@ pub fn generate_common_cpuid(
// Update some existing CPUID // Update some existing CPUID
for entry in cpuid.as_mut_slice().iter_mut() { for entry in cpuid.as_mut_slice().iter_mut() {
match entry.function { match entry.function {
// Clear AMX related bits if the AMX feature is not enabled
0x7 => {
if !config.amx && entry.index == 0 {
entry.edx &= !(1 << AMX_BF16 | 1 << AMX_TILE | 1 << AMX_INT8)
}
}
0xd => 0xd =>
{ {
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
@@ -672,12 +685,12 @@ pub fn generate_common_cpuid(
} }
// Set CPU physical bits // Set CPU physical bits
0x8000_0008 => { 0x8000_0008 => {
entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff); entry.eax = (entry.eax & 0xffff_ff00) | (config.phys_bits as u32 & 0xff);
} }
0x4000_0001 => { 0x4000_0001 => {
// These features are not supported by TDX // These features are not supported by TDX
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
if tdx_enabled { if config.tdx {
entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT
| 1 << KVM_FEATURE_CLOCKSOURCE2_BIT | 1 << KVM_FEATURE_CLOCKSOURCE2_BIT
| 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT | 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT
@@ -705,7 +718,7 @@ pub fn generate_common_cpuid(
}); });
} }
if kvm_hyperv { if config.kvm_hyperv {
// Remove conflicting entries // Remove conflicting entries
cpuid.retain(|c| c.function != 0x4000_0000); cpuid.retain(|c| c.function != 0x4000_0000);
cpuid.retain(|c| c.function != 0x4000_0001); cpuid.retain(|c| c.function != 0x4000_0001);
@@ -761,11 +774,26 @@ pub fn configure_vcpu(
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>, boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
cpuid: Vec<CpuIdEntry>, cpuid: Vec<CpuIdEntry>,
kvm_hyperv: bool, kvm_hyperv: bool,
cpu_vendor: CpuVendor,
topology: Option<(u8, u8, u8)>,
) -> super::Result<()> { ) -> super::Result<()> {
// Per vCPU CPUID changes; common are handled via generate_common_cpuid() // Per vCPU CPUID changes; common are handled via generate_common_cpuid()
let mut cpuid = cpuid; let mut cpuid = cpuid;
CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id)); CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id));
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id)); CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id));
if matches!(cpu_vendor, CpuVendor::AMD) {
CpuidPatch::set_cpuid_reg(
&mut cpuid,
0x8000_001e,
Some(0),
CpuidReg::EAX,
u32::from(id),
);
}
if let Some(t) = topology {
update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id);
}
// Set ApicId in cpuid for each vcpu // Set ApicId in cpuid for each vcpu
// SAFETY: get host cpuid when eax=1 // SAFETY: get host cpuid when eax=1
@@ -898,6 +926,112 @@ pub fn configure_system(
) )
} }
type RamRange = (u64, u64);
/// Returns usable physical memory ranges for the guest
/// These should be used to create e820_RAM memory maps
///
/// There are up to two usable physical memory ranges,
/// divided by the gap at the end of 32bit address space.
pub fn generate_ram_ranges(
guest_mem: &GuestMemoryMmap,
) -> super::Result<(RamRange, Option<RamRange>)> {
// Merge continuous memory regions into one region.
// Note: memory regions from "GuestMemory" are sorted and non-zero sized.
let ram_regions = {
let mut ram_regions = Vec::new();
let mut current_start = guest_mem
.iter()
.next()
.map(GuestMemoryRegion::start_addr)
.expect("GuestMemory must have one memory region at least")
.raw_value();
let mut current_end = current_start;
for (start, size) in guest_mem
.iter()
.map(|m| (m.start_addr().raw_value(), m.len()))
{
if current_end == start {
// This zone is continuous with the previous one.
current_end += size;
} else {
ram_regions.push((current_start, current_end));
current_start = start;
current_end = start + size;
}
}
ram_regions.push((current_start, current_end));
ram_regions
};
if ram_regions.len() > 2 {
error!(
"There should be up to two usable physical memory ranges, devidided by the
gap at the end of 32bit address space (e.g. between 3G and 4G)."
);
return Err(super::Error::MemmapTableSetup);
}
// Generate the first usable physical memory range before the gap
let first_ram_range = {
let (first_region_start, first_region_end) =
ram_regions.first().ok_or(super::Error::MemmapTableSetup)?;
let high_ram_start = layout::HIGH_RAM_START.raw_value();
let mem_32bit_reserved_start = layout::MEM_32BIT_RESERVED_START.raw_value();
if !((first_region_start <= &high_ram_start)
&& (first_region_end > &high_ram_start)
&& (first_region_end <= &mem_32bit_reserved_start))
{
error!(
"Unexpected first memory region layout: (start: 0x{:08x}, end: 0x{:08x}).
high_ram_start: 0x{:08x}, mem_32bit_reserved_start: 0x{:08x}",
first_region_start, first_region_end, high_ram_start, mem_32bit_reserved_start
);
return Err(super::Error::MemmapTableSetup);
}
info!(
"first usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
high_ram_start, first_region_end
);
(high_ram_start, *first_region_end)
};
// Generate the second usable physical memory range after the gap if any
let second_ram_range = if let Some((second_region_start, second_region_end)) =
ram_regions.get(1)
{
let ram_64bit_start = layout::RAM_64BIT_START.raw_value();
if second_region_start != &ram_64bit_start {
error!(
"Unexpected second memory region layout: start: 0x{:08x}, ram_64bit_start: 0x{:08x}",
second_region_start, ram_64bit_start
);
return Err(super::Error::MemmapTableSetup);
}
info!(
"Second usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
ram_64bit_start, second_region_end
);
Some((ram_64bit_start, *second_region_end))
} else {
None
};
Ok((first_ram_range, second_ram_range))
}
fn configure_pvh( fn configure_pvh(
guest_mem: &GuestMemoryMmap, guest_mem: &GuestMemoryMmap,
cmdline_addr: GuestAddress, cmdline_addr: GuestAddress,
@@ -944,100 +1078,31 @@ fn configure_pvh(
// Create the memory map entries. // Create the memory map entries.
add_memmap_entry(&mut memmap, 0, layout::EBDA_START.raw_value(), E820_RAM); add_memmap_entry(&mut memmap, 0, layout::EBDA_START.raw_value(), E820_RAM);
// Merge continuous memory regions into one region. // Get usable physical memory ranges
// Note: memory regions from "GuestMemory" are sorted and non-zero sized. let (first_ram_range, second_ram_range) = generate_ram_ranges(guest_mem)?;
let ram_regions = {
let mut ram_regions = Vec::new();
let mut current_start = guest_mem
.iter()
.next()
.map(GuestMemoryRegion::start_addr)
.expect("GuestMemory must have one memory region at least")
.raw_value();
let mut current_end = current_start;
for (start, size) in guest_mem // Create e820 memory map entry before the gap
.iter() info!(
.map(|m| (m.start_addr().raw_value(), m.len())) "create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
{ first_ram_range.0, first_ram_range.1
if current_end == start { );
// This zone is continuous with the previous one. add_memmap_entry(
current_end += size; &mut memmap,
} else { first_ram_range.0,
ram_regions.push((current_start, current_end)); first_ram_range.1 - first_ram_range.0,
E820_RAM,
current_start = start; );
current_end = start + size;
}
}
ram_regions.push((current_start, current_end));
ram_regions
};
if ram_regions.len() > 2 {
error!(
"There should be up to two non-continuous regions, devidided by the
gap at the end of 32bit address space (e.g. between 3G and 4G)."
);
return Err(super::Error::MemmapTableSetup);
}
// Create the memory map entry for memory region before the gap
{
let (first_region_start, first_region_end) =
ram_regions.first().ok_or(super::Error::MemmapTableSetup)?;
let high_ram_start = layout::HIGH_RAM_START.raw_value();
let mem_32bit_reserved_start = layout::MEM_32BIT_RESERVED_START.raw_value();
if !((first_region_start <= &high_ram_start)
&& (first_region_end > &high_ram_start)
&& (first_region_end <= &mem_32bit_reserved_start))
{
error!(
"Unexpected first memory region layout: (start: 0x{:08x}, end: 0x{:08x}).
high_ram_start: 0x{:08x}, mem_32bit_reserved_start: 0x{:08x}",
first_region_start, first_region_end, high_ram_start, mem_32bit_reserved_start
);
return Err(super::Error::MemmapTableSetup);
}
// Create e820 memory map after the gap if any
if let Some(second_ram_range) = second_ram_range {
info!( info!(
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}", "create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
high_ram_start, first_region_end second_ram_range.0, second_ram_range.1
);
add_memmap_entry(
&mut memmap,
high_ram_start,
first_region_end - high_ram_start,
E820_RAM,
);
}
// Create the memory map entry for memory region after the gap if any
if let Some((second_region_start, second_region_end)) = ram_regions.get(1) {
let ram_64bit_start = layout::RAM_64BIT_START.raw_value();
if second_region_start != &ram_64bit_start {
error!(
"Unexpected second memory region layout: start: 0x{:08x}, ram_64bit_start: 0x{:08x}",
second_region_start, ram_64bit_start
);
return Err(super::Error::MemmapTableSetup);
}
info!(
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
ram_64bit_start, second_region_end
); );
add_memmap_entry( add_memmap_entry(
&mut memmap, &mut memmap,
ram_64bit_start, second_ram_range.0,
second_region_end - ram_64bit_start, second_ram_range.1 - second_ram_range.0,
E820_RAM, E820_RAM,
); );
} }
@@ -1160,6 +1225,8 @@ fn update_cpuid_topology(
threads_per_core: u8, threads_per_core: u8,
cores_per_die: u8, cores_per_die: u8,
dies_per_package: u8, dies_per_package: u8,
cpu_vendor: CpuVendor,
id: u8,
) { ) {
let thread_width = 8 - (threads_per_core - 1).leading_zeros(); let thread_width = 8 - (threads_per_core - 1).leading_zeros();
let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width; let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width;
@@ -1216,13 +1283,72 @@ fn update_cpuid_topology(
u32::from(dies_per_package * cores_per_die * threads_per_core), u32::from(dies_per_package * cores_per_die * threads_per_core),
); );
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::ECX, 5 << 8); CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::ECX, 5 << 8);
if matches!(cpu_vendor, CpuVendor::AMD) {
CpuidPatch::set_cpuid_reg(
cpuid,
0x8000_001e,
Some(0),
CpuidReg::EBX,
((threads_per_core as u32 - 1) << 8) | (id as u32 & 0xff),
);
CpuidPatch::set_cpuid_reg(
cpuid,
0x8000_001e,
Some(0),
CpuidReg::ECX,
((dies_per_package as u32 - 1) << 8) | (thread_width + die_width) & 0xff,
);
CpuidPatch::set_cpuid_reg(cpuid, 0x8000_001e, Some(0), CpuidReg::EDX, 0);
if cores_per_die * threads_per_core > 1 {
CpuidPatch::set_cpuid_reg(
cpuid,
0x8000_0001,
Some(0),
CpuidReg::ECX,
(1u32 << 1) | (1u32 << 22),
);
CpuidPatch::set_cpuid_reg(
cpuid,
0x0000_0001,
Some(0),
CpuidReg::EBX,
((id as u32) << 24)
| (8 << 8)
| (((cores_per_die * threads_per_core) as u32) << 16),
);
let cpuid_patches = vec![
// Patch tsc deadline timer bit
CpuidPatch {
function: 1,
index: 0,
flags_bit: None,
eax_bit: None,
ebx_bit: None,
ecx_bit: None,
edx_bit: Some(28),
},
];
CpuidPatch::patch_cpuid(cpuid, cpuid_patches);
CpuidPatch::set_cpuid_reg(
cpuid,
0x8000_0008,
Some(0),
CpuidReg::ECX,
((thread_width + core_width + die_width) << 12)
| ((cores_per_die * threads_per_core) - 1) as u32,
);
} else {
CpuidPatch::set_cpuid_reg(cpuid, 0x8000_0008, Some(0), CpuidReg::ECX, 0u32);
}
}
} }
// The goal is to update the CPUID sub-leaves to reflect the number of EPC // The goal is to update the CPUID sub-leaves to reflect the number of EPC
// sections exposed to the guest. // sections exposed to the guest.
fn update_cpuid_sgx( fn update_cpuid_sgx(
cpuid: &mut Vec<CpuIdEntry>, cpuid: &mut Vec<CpuIdEntry>,
epc_sections: Vec<SgxEpcSection>, epc_sections: &Vec<SgxEpcSection>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Something's wrong if there's no EPC section. // Something's wrong if there's no EPC section.
if epc_sections.is_empty() { if epc_sections.is_empty() {

View File

@@ -9,7 +9,6 @@ use crate::layout::{APIC_START, HIGH_RAM_START, IOAPIC_START};
use crate::x86_64::mpspec; use crate::x86_64::mpspec;
use crate::GuestMemoryMmap; use crate::GuestMemoryMmap;
use libc::c_char; use libc::c_char;
use std::io;
use std::mem; use std::mem;
use std::result; use std::result;
use std::slice; use std::slice;
@@ -154,7 +153,7 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
return Err(Error::AddressOverflow); return Err(Error::AddressOverflow);
} }
mem.read_exact_from(base_mp, &mut io::repeat(0), mp_size) mem.read_exact_volatile_from(base_mp, &mut vec![0; mp_size].as_slice(), mp_size)
.map_err(Error::Clear)?; .map_err(Error::Clear)?;
{ {
@@ -291,7 +290,10 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
mod tests { mod tests {
use super::*; use super::*;
use crate::layout::MPTABLE_START; use crate::layout::MPTABLE_START;
use vm_memory::{GuestAddress, GuestUsize}; use vm_memory::{
bitmap::BitmapSlice, GuestAddress, GuestUsize, VolatileMemoryError, VolatileSlice,
WriteVolatile,
};
fn table_entry_size(type_: u8) -> usize { fn table_entry_size(type_: u8) -> usize {
match type_ as u32 { match type_ as u32 {
@@ -351,20 +353,24 @@ mod tests {
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap(); let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
struct Sum(u8); struct Sum(u8);
impl io::Write for Sum { impl WriteVolatile for Sum {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write_volatile<B: BitmapSlice>(
for v in buf.iter() { &mut self,
buf: &VolatileSlice<B>,
) -> result::Result<usize, VolatileMemoryError> {
let mut tmp = vec![0u8; buf.len()];
tmp.write_all_volatile(buf)?;
for v in tmp.iter() {
self.0 = self.0.wrapping_add(*v); self.0 = self.0.wrapping_add(*v);
} }
Ok(buf.len()) Ok(buf.len())
} }
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
} }
let mut sum = Sum(0); let mut sum = Sum(0);
mem.write_to(mpc_offset, &mut sum, mpc_table.0.length as usize) mem.write_volatile_to(mpc_offset, &mut sum, mpc_table.0.length as usize)
.unwrap(); .unwrap();
assert_eq!(sum.0, 0); assert_eq!(sum.0, 0);
} }

View File

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

View File

@@ -24,6 +24,7 @@ pub mod qcow_sync;
/// ///
/// Enabled with the `"io_uring"` feature /// Enabled with the `"io_uring"` feature
pub mod raw_async; pub mod raw_async;
pub mod raw_async_aio;
pub mod raw_sync; pub mod raw_sync;
pub mod vhd; pub mod vhd;
pub mod vhdx; pub mod vhdx;
@@ -61,6 +62,7 @@ use vm_memory::{
GuestMemoryError, GuestMemoryLoadGuard, GuestMemoryError, GuestMemoryLoadGuard,
}; };
use vm_virtio::{AccessPlatform, Translatable}; use vm_virtio::{AccessPlatform, Translatable};
use vmm_sys_util::aio;
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::{ioctl_io_nr, ioctl_ioc_nr}; use vmm_sys_util::{ioctl_io_nr, ioctl_ioc_nr};
@@ -141,10 +143,14 @@ pub enum ExecuteError {
Flush(io::Error), Flush(io::Error),
#[error("Failed to read: {0}")] #[error("Failed to read: {0}")]
Read(GuestMemoryError), Read(GuestMemoryError),
#[error("Failed to read_exact: {0}")]
ReadExact(io::Error),
#[error("Failed to seek: {0}")] #[error("Failed to seek: {0}")]
Seek(io::Error), Seek(io::Error),
#[error("Failed to write: {0}")] #[error("Failed to write: {0}")]
Write(GuestMemoryError), Write(GuestMemoryError),
#[error("Failed to write_all: {0}")]
WriteAll(io::Error),
#[error("Unsupported request: {0}")] #[error("Unsupported request: {0}")]
Unsupported(u32), Unsupported(u32),
#[error("Failed to submit io uring: {0}")] #[error("Failed to submit io uring: {0}")]
@@ -167,8 +173,10 @@ impl ExecuteError {
ExecuteError::BadRequest(_) => VIRTIO_BLK_S_IOERR, ExecuteError::BadRequest(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR, ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR, ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::ReadExact(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Seek(_) => VIRTIO_BLK_S_IOERR, ExecuteError::Seek(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Write(_) => VIRTIO_BLK_S_IOERR, ExecuteError::Write(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::WriteAll(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Unsupported(_) => VIRTIO_BLK_S_UNSUPP, ExecuteError::Unsupported(_) => VIRTIO_BLK_S_UNSUPP,
ExecuteError::SubmitIoUring(_) => VIRTIO_BLK_S_IOERR, ExecuteError::SubmitIoUring(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::GetHostAddress(_) => VIRTIO_BLK_S_IOERR, ExecuteError::GetHostAddress(_) => VIRTIO_BLK_S_IOERR,
@@ -349,13 +357,21 @@ impl Request {
match self.request_type { match self.request_type {
RequestType::In => { RequestType::In => {
mem.read_exact_from(*data_addr, disk, *data_len as usize) let mut buf = vec![0u8; *data_len as usize];
.map_err(ExecuteError::Read)?; disk.read_exact(&mut buf).map_err(ExecuteError::ReadExact)?;
mem.read_exact_volatile_from(
*data_addr,
&mut buf.as_slice(),
*data_len as usize,
)
.map_err(ExecuteError::Read)?;
len += data_len; len += data_len;
} }
RequestType::Out => { RequestType::Out => {
mem.write_all_to(*data_addr, disk, *data_len as usize) let mut buf: Vec<u8> = Vec::new();
mem.write_all_volatile_to(*data_addr, &mut buf, *data_len as usize)
.map_err(ExecuteError::Write)?; .map_err(ExecuteError::Write)?;
disk.write_all(&buf).map_err(ExecuteError::WriteAll)?;
if !self.writeback { if !self.writeback {
disk.flush().map_err(ExecuteError::Flush)?; disk.flush().map_err(ExecuteError::Flush)?;
} }
@@ -565,6 +581,11 @@ unsafe impl ByteValued for VirtioBlockConfig {}
// SAFETY: data structure only contain a series of integers // SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for VirtioBlockGeometry {} unsafe impl ByteValued for VirtioBlockGeometry {}
/// Check if aio can be used on the current system.
pub fn block_aio_is_supported() -> bool {
aio::IoContext::new(1).is_ok()
}
/// Check if io_uring for block device can be used on the current system, as /// Check if io_uring for block device can be used on the current system, as
/// it correctly supports the expected io_uring features. /// it correctly supports the expected io_uring features.
pub fn block_io_uring_is_supported() -> bool { pub fn block_io_uring_is_supported() -> bool {

150
block/src/raw_async_aio.rs Normal file
View File

@@ -0,0 +1,150 @@
// Copyright © 2023 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//
// Copyright © 2023 Crusoe Energy Systems LLC
//
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::DiskTopology;
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::aio;
use vmm_sys_util::eventfd::EventFd;
pub struct RawFileDiskAio {
file: File,
}
impl RawFileDiskAio {
pub fn new(file: File) -> Self {
RawFileDiskAio { file }
}
}
impl DiskFile for RawFileDiskAio {
fn size(&mut self) -> DiskFileResult<u64> {
self.file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)
}
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
RawFileAsyncAio::new(self.file.as_raw_fd(), ring_depth)
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
fn topology(&mut self) -> DiskTopology {
if let Ok(topology) = DiskTopology::probe(&self.file) {
topology
} else {
warn!("Unable to get device topology. Using default topology");
DiskTopology::default()
}
}
}
pub struct RawFileAsyncAio {
fd: RawFd,
ctx: aio::IoContext,
eventfd: EventFd,
}
impl RawFileAsyncAio {
pub fn new(fd: RawFd, queue_depth: u32) -> std::io::Result<Self> {
let eventfd = EventFd::new(libc::EFD_NONBLOCK)?;
let ctx = aio::IoContext::new(queue_depth)?;
Ok(RawFileAsyncAio { fd, ctx, eventfd })
}
}
impl AsyncIo for RawFileAsyncAio {
fn notifier(&self) -> &EventFd {
&self.eventfd
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
let iocbs = [&mut aio::IoControlBlock {
aio_fildes: self.fd.as_raw_fd() as u32,
aio_lio_opcode: aio::IOCB_CMD_PREADV as u16,
aio_buf: iovecs.as_ptr() as u64,
aio_nbytes: iovecs.len() as u64,
aio_offset: offset,
aio_data: user_data,
aio_flags: aio::IOCB_FLAG_RESFD,
aio_resfd: self.eventfd.as_raw_fd() as u32,
..Default::default()
}];
let _ = self
.ctx
.submit(&iocbs[..])
.map_err(AsyncIoError::ReadVectored)?;
Ok(())
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: &[libc::iovec],
user_data: u64,
) -> AsyncIoResult<()> {
let iocbs = [&mut aio::IoControlBlock {
aio_fildes: self.fd.as_raw_fd() as u32,
aio_lio_opcode: aio::IOCB_CMD_PWRITEV as u16,
aio_buf: iovecs.as_ptr() as u64,
aio_nbytes: iovecs.len() as u64,
aio_offset: offset,
aio_data: user_data,
aio_flags: aio::IOCB_FLAG_RESFD,
aio_resfd: self.eventfd.as_raw_fd() as u32,
..Default::default()
}];
let _ = self
.ctx
.submit(&iocbs[..])
.map_err(AsyncIoError::WriteVectored)?;
Ok(())
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
if let Some(user_data) = user_data {
let iocbs = [&mut aio::IoControlBlock {
aio_fildes: self.fd.as_raw_fd() as u32,
aio_lio_opcode: aio::IOCB_CMD_FSYNC as u16,
aio_data: user_data,
aio_flags: aio::IOCB_FLAG_RESFD,
aio_resfd: self.eventfd.as_raw_fd() as u32,
..Default::default()
}];
let _ = self.ctx.submit(&iocbs[..]).map_err(AsyncIoError::Fsync)?;
} else {
// SAFETY: FFI call with a valid fd
unsafe { libc::fsync(self.fd) };
}
Ok(())
}
fn next_completed_request(&mut self) -> Option<(u64, i32)> {
let mut events: [aio::IoEvent; 1] = [aio::IoEvent::default()];
let rc = self.ctx.get_events(0, &mut events, None).unwrap();
if rc == 0 {
None
} else {
Some((events[0].data, events[0].res as i32))
}
}
}

View File

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

View File

@@ -166,8 +166,8 @@ impl Serial {
Self::new(id, interrupt, None, state) Self::new(id, interrupt, None, state)
} }
pub fn set_out(&mut self, out: Box<dyn io::Write + Send>) { pub fn set_out(&mut self, out: Option<Box<dyn io::Write + Send>>) {
self.out = Some(out); self.out = out;
} }
/// Queues raw bytes for the guest to read and signals the interrupt if the line status would /// Queues raw bytes for the guest to read and signals the interrupt if the line status would

View File

@@ -201,8 +201,8 @@ impl Pl011 {
} }
} }
pub fn set_out(&mut self, out: Box<dyn io::Write + Send>) { pub fn set_out(&mut self, out: Option<Box<dyn io::Write + Send>>) {
self.out = Some(out); self.out = out;
} }
fn state(&self) -> Pl011State { fn state(&self) -> Pl011State {

View File

@@ -26,6 +26,7 @@ const PVPANIC_VENDOR_ID: u16 = 0x1b36;
const PVPANIC_DEVICE_ID: u16 = 0x0011; const PVPANIC_DEVICE_ID: u16 = 0x0011;
pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2; pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2;
pub const PVPANIC_DEVICE_MMIO_ALIGNMENT: u64 = 0x10;
const PVPANIC_PANICKED: u8 = 1 << 0; const PVPANIC_PANICKED: u8 = 1 << 0;
const PVPANIC_CRASH_LOADED: u8 = 1 << 1; const PVPANIC_CRASH_LOADED: u8 = 1 << 1;
@@ -180,8 +181,9 @@ impl PciDevice for PvPanicDevice {
fn allocate_bars( fn allocate_bars(
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, _allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new(); let mut bars = Vec::new();
@@ -189,10 +191,8 @@ impl PciDevice for PvPanicDevice {
let bar_id = 0; let bar_id = 0;
let region_size = PVPANIC_DEVICE_MMIO_SIZE; let region_size = PVPANIC_DEVICE_MMIO_SIZE;
let restoring = resources.is_some(); let restoring = resources.is_some();
let bar_addr = allocator let bar_addr = mmio32_allocator
.lock() .allocate(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
.unwrap()
.allocate_mmio_hole_addresses(None, region_size, None)
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?; .ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
let bar = PciBarConfiguration::default() let bar = PciBarConfiguration::default()
@@ -217,11 +217,12 @@ impl PciDevice for PvPanicDevice {
fn free_bars( fn free_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, _allocator: &mut SystemAllocator,
_mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> std::result::Result<(), PciDeviceError> { ) -> std::result::Result<(), PciDeviceError> {
for bar in self.bar_regions.drain(..) { for bar in self.bar_regions.drain(..) {
allocator.free_mmio_hole_addresses(GuestAddress(bar.addr()), bar.size()); mmio32_allocator.free(GuestAddress(bar.addr()), bar.size());
} }
Ok(()) Ok(())

View File

@@ -36,3 +36,5 @@ You can run a SEV-SNP VM using the following command:
--memory size=1G \ --memory size=1G \
--disk path=ubuntu.img --disk path=ubuntu.img
``` ```
For more information related to Microsoft Hypervisor please see [mshv.md](mshv.md)

View File

@@ -295,7 +295,7 @@ From the CLI, one can:
The REST API, D-Bus API and the CLI all rely on a common, [internal API](#internal-api). The REST API, D-Bus API and the CLI all rely on a common, [internal API](#internal-api).
The CLI options are parsed by the The CLI options are parsed by the
[argh crate](https://docs.rs/argh/latest/argh/) and then translated into [clap crate](https://docs.rs/clap/4.3.11/clap/) and then translated into
[internal API](#internal-api) commands. [internal API](#internal-api) commands.
The REST API is processed by an HTTP thread using the The REST API is processed by an HTTP thread using the
@@ -327,7 +327,7 @@ As a summary, the REST API, the D-Bus API and the CLI are essentially frontends
| | +------------------------+ | | +------------------------+
| +----------+ | VMM | +----------+ | VMM
| CLI | | | | CLI | | |
+----------->+ argh +--------------+ +----------->+ clap +--------------+
| | | |
+----------+ +----------+

View File

@@ -54,7 +54,7 @@ Value is a boolean set to `off` by default.
_Example_ _Example_
``` ```
--ballloon size=2G,deflate_on_oom=on --balloon size=2G,deflate_on_oom=on
``` ```
### `free_page_reporting` ### `free_page_reporting`
@@ -72,5 +72,5 @@ Value is a boolean set to `off` by default.
_Example_ _Example_
``` ```
--ballloon size=0,free_page_reporting=on --balloon size=0,free_page_reporting=on
``` ```

81
docs/coverage.md Normal file
View File

@@ -0,0 +1,81 @@
# Code coverage
LLVM provides a set of tools to collect code coverage data and present the data
in human-consumable forms.
## Building a suitable binary
The compiler flag to generate code coverage data has been stabilized since Rust
1.60.
An instrumented binary can be built with the following command:
```shell
cargo clean && RUSTFLAGS='-C instrument-coverage' cargo build
```
Using either `debug` or `release` profile is fine. You will need to adjust
the path for some commands.
## Running the binary
Run the binary as you normally would. When the process exits, you will see
files with the prefix `profraw`.
Multiple runs of the same binary will produce multiple `profraw` files.
The more diverse the runs are, the better. Try to exercise different features
as much as possible.
## Combining raw data
Raw data files can be combined with `llvm-profdata`.
```shell
rustup component add llvm-tools-preview
# Assuming profraw files reside in the current directory and its children directories
find . -name '*.profraw' -exec llvm-profdata merge -sparse {} -o coverage.profdata \;
```
A file named `coverage.profdata` will be generated.
## Generating HTML files for human consumption
This can be done either with LLVM or `grcov`.
Here is an example using grcov.
```shell
cargo install grcov
# Assuming the profdata file is in the top level directory of the Cloud Hypervisor repository
grcov . --binary-path ./target/x86_64-unknown-linux-gnu/release -s . -t html --branch --ignore-not-existing -o coverage-html-output/
```
You can then open the `index.html` file under coverage-html-output to see the
results.
## Notes on running the in-tree integration tests and unit tests
Please set RUSTFLAGS the same way while invoking `dev_cli.sh`. The script will
pass RUSTFLAGS to the container.
Since the `profraw` files are generated from within the container, the file
paths embedded in the data files are going to be different. It is easier to do
the data processing from within the container if you don't want to fight the
tool chain.
```shell
# Get a shell
./scripts/dev_cli.sh shell
# Install llvm-tools-preview for llvm-profdata
rustup component add llvm-tools-preview
# Merge data files by using the following command
find . -name '*.profraw' -exec `rustc --print sysroot`/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse {} -o coverage.profdata \;
# As of writing, the container has Rust 1.67.1. It is too old for grcov.
rustup install stable
cargo +stable install grcov
# Run grcov as usual
grcov . --binary-path ./target/x86_64-unknown-linux-gnu/release -s . -t html --branch --ignore-not-existing -o coverage-html-output/
```

View File

@@ -36,7 +36,7 @@ Assuming parts of the guest software stack have been instrumented to use the
`cloud-hypervisor` debug I/O port, we may want to gather the related logs. `cloud-hypervisor` debug I/O port, we may want to gather the related logs.
To do so we need to start `cloud-hypervisor` with the right debug level To do so we need to start `cloud-hypervisor` with the right debug level
(`-v -v -v`). It is also recommended to have it log into a dedicated file in order (`-vvv`). It is also recommended to have it log into a dedicated file in order
to easily grep for the tracing logs (e.g. to easily grep for the tracing logs (e.g.
`--log-file /tmp/cloud-hypervisor.log`): `--log-file /tmp/cloud-hypervisor.log`):
@@ -48,7 +48,7 @@ to easily grep for the tracing logs (e.g.
--memory size=1024M \ --memory size=1024M \
--rng \ --rng \
--log-file /tmp/ch-fw.log \ --log-file /tmp/ch-fw.log \
-v -v -v -vvv
``` ```
After booting the guest, we then have to grep for the debug I/O port traces in After booting the guest, we then have to grep for the debug I/O port traces in

View File

@@ -8,7 +8,7 @@ To enable debugging with GDB, build with the `guest_debug` feature enabled:
cargo build --features guest_debug 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: To use the `--gdb` option, specify the Unix Domain Socket with `--path` that Cloud Hypervisor will use to communicate with the host's GDB:
```bash ```bash
./cloud-hypervisor \ ./cloud-hypervisor \

View File

@@ -27,16 +27,16 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--memory size=1024M \ --memory size=1024M \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
--rng \ --rng \
--api-socket /tmp/ch-socket --api-socket=/tmp/ch-socket
$ popd $ popd
``` ```
Notice the addition of `--api-socket /tmp/ch-socket` and a `max` parameter on `--cpus boot=4,max=8`. Notice the addition of `--api-socket=/tmp/ch-socket` and a `max` parameter on `--cpus boot=4,max=8`.
To ask the VMM to add additional vCPUs then use the resize API: To ask the VMM to add additional vCPUs then use the resize API:
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket resize --cpus 8 ./ch-remote --api-socket=/tmp/ch-socket resize --cpus 8
``` ```
The extra vCPU threads will be created and advertised to the running kernel. The kernel does not bring up the CPUs immediately and instead the user must "online" them from inside the VM: The extra vCPU threads will be created and advertised to the running kernel. The kernel does not bring up the CPUs immediately and instead the user must "online" them from inside the VM:
@@ -56,7 +56,7 @@ After a reboot the added CPUs will remain.
Removing CPUs works similarly by reducing the number in the "desired_vcpus" field of the reisze API. The CPUs will be automatically offlined inside the guest so there is no need to run any commands inside the guest: Removing CPUs works similarly by reducing the number in the "desired_vcpus" field of the reisze API. The CPUs will be automatically offlined inside the guest so there is no need to run any commands inside the guest:
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket resize --cpus 2 ./ch-remote --api-socket=/tmp/ch-socket resize --cpus 2
``` ```
As per adding CPUs to the guest, after a reboot the VM will be running with the reduced number of vCPUs. As per adding CPUs to the guest, after a reboot the VM will be running with the reduced number of vCPUs.
@@ -85,7 +85,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--memory size=1024M,hotplug_size=8192M \ --memory size=1024M,hotplug_size=8192M \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
--rng \ --rng \
--api-socket /tmp/ch-socket --api-socket=/tmp/ch-socket
$ popd $ popd
``` ```
@@ -98,7 +98,7 @@ root@ch-guest ~ # echo online | sudo tee /sys/devices/system/memory/auto_online_
To ask the VMM to expand the RAM for the VM: To ask the VMM to expand the RAM for the VM:
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket resize --memory 3G ./ch-remote --api-socket=/tmp/ch-socket resize --memory 3G
``` ```
The new memory is now available to use inside the VM: The new memory is now available to use inside the VM:
@@ -134,14 +134,14 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--disk path=focal-server-cloudimg-amd64.raw \ --disk path=focal-server-cloudimg-amd64.raw \
--memory size=1024M,hotplug_size=8192M,hotplug_method=virtio-mem \ --memory size=1024M,hotplug_size=8192M,hotplug_method=virtio-mem \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
--api-socket /tmp/ch-socket --api-socket=/tmp/ch-socket
$ popd $ popd
``` ```
To ask the VMM to expand the RAM for the VM (request is in bytes): To ask the VMM to expand the RAM for the VM (request is in bytes):
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket resize --memory 3G ./ch-remote --api-socket=/tmp/ch-socket resize --memory 3G
``` ```
The new memory is now available to use inside the VM: The new memory is now available to use inside the VM:
@@ -172,17 +172,17 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--cpus boot=4 \ --cpus boot=4 \
--memory size=1024M \ --memory size=1024M \
--net "tap=,mac=,ip=,mask=" \ --net "tap=,mac=,ip=,mask=" \
--api-socket /tmp/ch-socket --api-socket=/tmp/ch-socket
``` ```
Notice the addition of `--api-socket /tmp/ch-socket`. Notice the addition of `--api-socket=/tmp/ch-socket`.
### Add VFIO Device ### Add VFIO Device
To ask the VMM to add additional VFIO device then use the `add-device` API. To ask the VMM to add additional VFIO device then use the `add-device` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-device path=/sys/bus/pci/devices/0000:01:00.0/ ./ch-remote --api-socket=/tmp/ch-socket add-device path=/sys/bus/pci/devices/0000:01:00.0/
``` ```
### Add Disk Device ### Add Disk Device
@@ -190,7 +190,7 @@ To ask the VMM to add additional VFIO device then use the `add-device` API.
To ask the VMM to add additional disk device then use the `add-disk` API. To ask the VMM to add additional disk device then use the `add-disk` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-disk path=/foo/bar/cloud.img ./ch-remote --api-socket=/tmp/ch-socket add-disk path=/foo/bar/cloud.img
``` ```
### Add Fs Device ### Add Fs Device
@@ -198,7 +198,7 @@ To ask the VMM to add additional disk device then use the `add-disk` API.
To ask the VMM to add additional fs device then use the `add-fs` API. To ask the VMM to add additional fs device then use the `add-fs` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-fs tag=myfs,socket=/foo/bar/virtiofs.sock ./ch-remote --api-socket=/tmp/ch-socket add-fs tag=myfs,socket=/foo/bar/virtiofs.sock
``` ```
### Add Net Device ### Add Net Device
@@ -206,7 +206,7 @@ To ask the VMM to add additional fs device then use the `add-fs` API.
To ask the VMM to add additional network device then use the `add-net` API. To ask the VMM to add additional network device then use the `add-net` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-net tap=chtap0 ./ch-remote --api-socket=/tmp/ch-socket add-net tap=chtap0
``` ```
### Add Pmem Device ### Add Pmem Device
@@ -214,7 +214,7 @@ To ask the VMM to add additional network device then use the `add-net` API.
To ask the VMM to add additional PMEM device then use the `add-pmem` API. To ask the VMM to add additional PMEM device then use the `add-pmem` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-pmem file=/foo/bar.cloud.img ./ch-remote --api-socket=/tmp/ch-socket add-pmem file=/foo/bar.cloud.img
``` ```
### Add Vsock Device ### Add Vsock Device
@@ -222,7 +222,7 @@ To ask the VMM to add additional PMEM device then use the `add-pmem` API.
To ask the VMM to add additional vsock device then use the `add-vsock` API. To ask the VMM to add additional vsock device then use the `add-vsock` API.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket add-vsock cid=3,socket=/foo/bar/vsock.sock ./ch-remote --api-socket=/tmp/ch-socket add-vsock cid=3,socket=/foo/bar/vsock.sock
``` ```
### Common Across All PCI Devices ### Common Across All PCI Devices
@@ -244,7 +244,7 @@ After a reboot the added PCI device will remain.
Removing a PCI device works the same way for all kind of PCI devices. The unique identifier related to the device must be provided. This identifier can be provided by the user when adding the new device, or by default Cloud Hypervisor will assign one. Removing a PCI device works the same way for all kind of PCI devices. The unique identifier related to the device must be provided. This identifier can be provided by the user when adding the new device, or by default Cloud Hypervisor will assign one.
```shell ```shell
./ch-remote --api-socket /tmp/ch-socket remove-device _disk0 ./ch-remote --api-socket=/tmp/ch-socket remove-device _disk0
``` ```
As per adding a PCI device to the guest, after a reboot the VM will be running without the removed PCI device. As per adding a PCI device to the guest, after a reboot the VM will be running without the removed PCI device.

View File

@@ -245,7 +245,7 @@ e.g.
```bash ```bash
./cloud-hypervisor \ ./cloud-hypervisor \
--api-socket /tmp/api \ --api-socket=/tmp/api \
--cpus boot=1 \ --cpus boot=1 \
--memory size=4G,hugepages=on \ --memory size=4G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \ --disk path=focal-server-cloudimg-amd64.raw \
@@ -260,7 +260,7 @@ requiring the IOMMU then may be hotplugged:
e.g. e.g.
```bash ```bash
./ch-remote --api-socket /tmp/api add-device path=/sys/bus/pci/devices/0000:00:04.0,iommu=on,pci_segment=1 ./ch-remote --api-socket=/tmp/api add-device path=/sys/bus/pci/devices/0000:00:04.0,iommu=on,pci_segment=1
``` ```
Devices that cannot be placed behind an IOMMU (e.g. lacking an `iommu=` option) Devices that cannot be placed behind an IOMMU (e.g. lacking an `iommu=` option)

View File

@@ -16,22 +16,22 @@ $ target/release/cloud-hypervisor
--disk path=~/workloads/focal.raw \ --disk path=~/workloads/focal.raw \
--cpus boot=1 --memory size=1G,shared=on \ --cpus boot=1 --memory size=1G,shared=on \
--cmdline "root=/dev/vda1 console=ttyS0" \ --cmdline "root=/dev/vda1 console=ttyS0" \
--serial tty --console off --api-socket /tmp/api1 --serial tty --console off --api-socket=/tmp/api1
``` ```
Launch the destination VM from the same directory (on the host machine): Launch the destination VM from the same directory (on the host machine):
```bash ```bash
$ target/release/cloud-hypervisor --api-socket /tmp/api2 $ target/release/cloud-hypervisor --api-socket=/tmp/api2
``` ```
Get ready for receiving migration for the destination VM (on the host machine): Get ready for receiving migration for the destination VM (on the host machine):
```bash ```bash
$ target/release/ch-remote --api-socket /tmp/api2 receive-migration unix:/tmp/sock $ target/release/ch-remote --api-socket=/tmp/api2 receive-migration unix:/tmp/sock
``` ```
Start to send migration for the source VM (on the host machine): Start to send migration for the source VM (on the host machine):
```bash ```bash
$ target/release/ch-remote --api-socket /tmp/api1 send-migration --local unix:/tmp/sock $ target/release/ch-remote --api-socket=/tmp/api1 send-migration --local unix:/tmp/sock
``` ```
When the above commands completed, the source VM should be successfully When the above commands completed, the source VM should be successfully
@@ -51,7 +51,7 @@ $ sudo /target/release/cloud-hypervisor \
--cpus boot=1 --memory size=512M \ --cpus boot=1 --memory size=512M \
--kernel vmlinux \ --kernel vmlinux \
--cmdline "root=/dev/vda1 console=ttyS0" \ --cmdline "root=/dev/vda1 console=ttyS0" \
--disk path=focal-1.raw path=focal-nested.raw --disk path=tmp.img\ --disk path=focal-1.raw path=focal-nested.raw path=tmp.img\
--net ip=192.168.101.1 --net ip=192.168.101.1
``` ```
@@ -63,7 +63,7 @@ $ sudo /target/release/cloud-hypervisor \
--cpus boot=1 --memory size=512M \ --cpus boot=1 --memory size=512M \
--kernel vmlinux \ --kernel vmlinux \
--cmdline "root=/dev/vda1 console=ttyS0" \ --cmdline "root=/dev/vda1 console=ttyS0" \
--disk path=focal-2.raw path=focal-nested.raw --disk path=tmp.img\ --disk path=focal-2.raw path=focal-nested.raw path=tmp.img\
--net ip=192.168.102.1 --net ip=192.168.102.1
``` ```
@@ -74,8 +74,8 @@ vm-1:~$ sudo ./cloud-hypervisor \
--memory size=128M \ --memory size=128M \
--kernel vmlinux \ --kernel vmlinux \
--cmdline "console=ttyS0 root=/dev/vda1" \ --cmdline "console=ttyS0 root=/dev/vda1" \
--disk path=/dev/vdb --disk path=/dev/vdc \ --disk path=/dev/vdb path=/dev/vdc \
--api-socket /tmp/api1 \ --api-socket=/tmp/api1 \
--net ip=192.168.100.1 --net ip=192.168.100.1
vm-1:~$ # setup the guest network if needed vm-1:~$ # setup the guest network if needed
vm-1:~$ sudo ip addr add 192.168.101.2/24 dev ens4 vm-1:~$ sudo ip addr add 192.168.101.2/24 dev ens4
@@ -108,7 +108,7 @@ echo "tmp = $tmp"
Launch the nested destination VM (inside the guest OS of the VM 2): Launch the nested destination VM (inside the guest OS of the VM 2):
```bash ```bash
vm-2:~$ sudo ./cloud-hypervisor --api-socket /tmp/api2 vm-2:~$ sudo ./cloud-hypervisor --api-socket=/tmp/api2
vm-2:~$ # setup the guest network with the following commands if needed vm-2:~$ # setup the guest network with the following commands if needed
vm-2:~$ sudo ip addr add 192.168.102.2/24 dev ens4 vm-2:~$ sudo ip addr add 192.168.102.2/24 dev ens4
vm-2:~$ sudo ip link set up dev ens4 vm-2:~$ sudo ip link set up dev ens4
@@ -122,7 +122,7 @@ vm-2:~$ ping 192.168.101.2 # This should succeed
Get ready for receiving migration for the nested destination VM (inside Get ready for receiving migration for the nested destination VM (inside
the guest OS of the VM 2): the guest OS of the VM 2):
```bash ```bash
vm-2:~$ sudo ./ch-remote --api-socket /tmp/api2 receive-migration unix:/tmp/sock2 vm-2:~$ sudo ./ch-remote --api-socket=/tmp/api2 receive-migration unix:/tmp/sock2
vm-2:~$ sudo socat TCP-LISTEN:6000,reuseaddr UNIX-CLIENT:/tmp/sock2 vm-2:~$ sudo socat TCP-LISTEN:6000,reuseaddr UNIX-CLIENT:/tmp/sock2
``` ```
@@ -130,7 +130,7 @@ Start to send migration for the nested source VM (inside the guest OS of
the VM 1): the VM 1):
```bash ```bash
vm-1:~$ sudo socat UNIX-LISTEN:/tmp/sock1,reuseaddr TCP:192.168.102.2:6000 vm-1:~$ sudo socat UNIX-LISTEN:/tmp/sock1,reuseaddr TCP:192.168.102.2:6000
vm-1:~$ sudo ./ch-remote --api-socket /tmp/api1 send-migration unix:/tmp/sock1 vm-1:~$ sudo ./ch-remote --api-socket=/tmp/api1 send-migration unix:/tmp/sock1
``` ```
When the above commands completed, the source VM should be successfully When the above commands completed, the source VM should be successfully

View File

@@ -38,6 +38,6 @@ This level is for the benefit of developers. It should be used for sporadic and
### `debug!()` ### `debug!()`
Use `-v -v` to enable. Use `-vv` to enable.
For the most verbose of logging messages. It is acceptable to "spam" the log with repeated invocations of the same message. This level of logging would be combined with `--log-file`. For the most verbose of logging messages. It is acceptable to "spam" the log with repeated invocations of the same message. This level of logging would be combined with `--log-file`.

View File

@@ -516,7 +516,7 @@ different distances, it can be described with the following example.
_Example_ _Example_
``` ```
--numa guest_numa_id=0,distances=[1@15,2@25] --numa guest_numa_id=1,distances=[0@15,2@20] guest_numa_id=2,distances=[0@25,1@20] --numa guest_numa_id=0,distances=[1@15,2@25] guest_numa_id=1,distances=[0@15,2@20] guest_numa_id=2,distances=[0@25,1@20]
``` ```
### `memory_zones` ### `memory_zones`
@@ -540,14 +540,14 @@ demarcate the list.
Note that a memory zone must belong to a single NUMA node. The following Note that a memory zone must belong to a single NUMA node. The following
configuration is incorrect, therefore not allowed: configuration is incorrect, therefore not allowed:
`--numa guest_numa_id=0,memory_zones=mem0 --numa guest_numa_id=1,memory_zones=mem0` `--numa guest_numa_id=0,memory_zones=mem0 guest_numa_id=1,memory_zones=mem0`
_Example_ _Example_
``` ```
--memory size=0 --memory size=0
--memory-zone id=mem0,size=1G id=mem1,size=1G --memory-zone id=mem2,size=1G --memory-zone id=mem0,size=1G id=mem1,size=1G id=mem2,size=1G
--numa guest_numa_id=0,memory_zones=[mem0,mem2] --numa guest_numa_id=1,memory_zones=mem1 --numa guest_numa_id=0,memory_zones=[mem0,mem2] guest_numa_id=1,memory_zones=mem1
``` ```
### `sgx_epc_sections` ### `sgx_epc_sections`
@@ -567,12 +567,21 @@ _Example_
``` ```
--sgx-epc id=epc0,size=32M id=epc1,size=64M id=epc2,size=32M --sgx-epc id=epc0,size=32M id=epc1,size=64M id=epc2,size=32M
--numa guest_numa_id=0,sgx_epc_sections=epc1 --numa guest_numa_id=1,sgx_epc_sections=[epc0,epc2] --numa guest_numa_id=0,sgx_epc_sections=epc1 guest_numa_id=1,sgx_epc_sections=[epc0,epc2]
``` ```
### PCI bus ### PCI bus
Cloud Hypervisor supports only one PCI bus, which is why it has been tied to Cloud Hypervisor supports guests with one or more PCI segments. The default PCI segment always
the NUMA node 0 by default. It is the user responsibility to organize the NUMA has affinity to NUMA node 0. Be default, all other PCI segments have afffinity to NUMA node 0.
nodes correctly so that vCPUs and guest RAM which should be located on the same The user may configure the NUMA affinity for any additional PCI segments.
NUMA node as the PCI bus end up on the NUMA node 0.
_Example_
```
--platform num_pci_segments=2
--memory-zone size=16G,host_numa_node=0,id=mem0
--memory-zone size=16G,host_numa_node=1,id=mem1
--numa guest_numa_id=0,memory_zones=mem0,pci_segments=[0]
--numa guest_numa_id=1,memory_zones=mem1,pci_segments=[1]
```

48
docs/mshv.md Normal file
View File

@@ -0,0 +1,48 @@
# Microsoft Hypervisor
The Microsoft Hypervisor is a Type 1 hypervisor which runs on x64 and ARM64 architectures. As the foundation of the Hyper-V virtualization stack, it runs millions of Linux and Windows guests in Azure and on-premises deployments. It supports nested virtualization, and security features like AMD's SEV-SNP. It also supports various features in Windows such as [Device guard and confidential guard](https://techcommunity.microsoft.com/t5/iis-support-blog/windows-10-device-guard-and-credential-guard-demystified/ba-p/376419), and [WSL2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq)
Since 2020, Microsoft has been releasing open-source components to support Linux running as root partition on the Microsoft Hypervisor.
1. Kernel patches to support Linux booting as root partition
2. A Linux kernel driver exposing an IOCTL interface for managing guest partitions, via a device node - /dev/mshv
3. Rust bindings and IOCTL wrappers
4. IGVM related crates
## Components
The following components are related to MSHV support with Cloud-Hypervisor:
* [igvm-crates](https://github.com/microsoft/igvm) : Parsing IGVM file
* [mshv-crates](https://github.com/rust-vmm/mshv) : Rust crates to interact with kernel module (/dev/mshv)
* [igvm-tooling](https://github.com/microsoft/igvm-tooling) : Tool to generate IGVM file
## IGVM
Independent Guest Virtual Machine (IGVM) file format.The format specification can be found in the igvm_defs crate, with a Rust implementation of the binary format in the igvm crate.
The IGVM file format is designed to encapsulate all information required to launch a virtual machine on any given virtualization stack, with support for different isolation technologies such as AMD SEV-SNP and Intel TDX.
At a conceptual level, this file format is a set of commands created by the tool that generated the file, used by the loader to construct the initial guest state. The file format also contains measurement information that the underlying platform will use to confirm that the file was loaded correctly and signed by the appropriate authorities.
Cloud Hypervisor can be built using igvm feature flag along with mshv and/or sev-snp. IGVM only works with MSHV.
## SEV-SNP
AMD's [Secure Encrypted Virtualization (SEV)](https://www.amd.com/en/developer/sev.html) and extensions such as Secure Nested Paging (SEV-SNP) encrypt memory and restrict access to a guest VM's memory and registers, securing it against a compromised hypervisor or VMM. They utilize the Platform Security Processor (PSP) to store keys and encrypt/decrypt the data. Microsoft has been continuously adding/improving support for SEV-SNP on Microsoft Hyper-V. Cloud-Hypervisor can be built with the sev_snp feature including mshv and igvm feature.
## Use Cases
Cloud Hypervisor can be built to run on an MSHV root partition by enabling the mshv feature, e.g.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features mshv```
Cloud Hypervisor on MSHV can boot Linux guests using an IGVM file. IGVM feature depends on mshv for running legacy VMs.e.g.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features igvm```
For running confidential VMs on mshv, you will only need to enable sev_snp, it requires and enables mshv and igvm automatically, eg.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features sev_snp```

View File

@@ -25,7 +25,7 @@ $ perf record -g target/profiling/cloud-hypervisor \
--cpus boot=1 --memory size=1G \ --cpus boot=1 --memory size=1G \
--cmdline "root=/dev/pmem0p1 console=ttyS0" \ --cmdline "root=/dev/pmem0p1 console=ttyS0" \
--serial tty --console off \ --serial tty --console off \
--api-socket /tmp/api1 --api-socket=/tmp/api1
``` ```
For analysing the samples: For analysing the samples:
@@ -52,5 +52,5 @@ $ perf record --call-graph lbr --all-user --user-callchains -g target/release/cl
--cpus boot=1 --memory size=1G \ --cpus boot=1 --memory size=1G \
--cmdline "root=/dev/pmem0p1 console=ttyS0" \ --cmdline "root=/dev/pmem0p1 console=ttyS0" \
--serial tty --console off \ --serial tty --console off \
--api-socket /tmp/api1 --api-socket=/tmp/api1
``` ```

View File

@@ -25,14 +25,14 @@ First thing, we must run a Cloud Hypervisor VM:
At any point in time when the VM is running, one might choose to pause it: At any point in time when the VM is running, one might choose to pause it:
```bash ```bash
./ch-remote --api-socket /tmp/cloud-hypervisor.sock pause ./ch-remote --api-socket=/tmp/cloud-hypervisor.sock pause
``` ```
Once paused, the VM can be safely snapshot into the specified directory and Once paused, the VM can be safely snapshot into the specified directory and
using the following command: using the following command:
```bash ```bash
./ch-remote --api-socket /tmp/cloud-hypervisor.sock snapshot file:///home/foo/snapshot ./ch-remote --api-socket=/tmp/cloud-hypervisor.sock snapshot file:///home/foo/snapshot
``` ```
Given the directory was present on the system, the snapshot will succeed and Given the directory was present on the system, the snapshot will succeed and
@@ -79,7 +79,7 @@ Or using two different commands from two terminals:
./cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock ./cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
# Second terminal # Second terminal
./ch-remote --api-socket /tmp/cloud-hypervisor.sock restore source_url=file:///home/foo/snapshot ./ch-remote --api-socket=/tmp/cloud-hypervisor.sock restore source_url=file:///home/foo/snapshot
``` ```
Remember the VM is restored in a `paused` state, which was the VM's state when Remember the VM is restored in a `paused` state, which was the VM's state when
@@ -87,7 +87,7 @@ it was snapshot. For this reason, one must explicitly `resume` the VM before to
start using it. start using it.
```bash ```bash
./ch-remote --api-socket /tmp/cloud-hypervisor.sock resume ./ch-remote --api-socket=/tmp/cloud-hypervisor.sock resume
``` ```
At this point, the VM is fully restored and is identical to the VM which was At this point, the VM is fully restored and is identical to the VM which was

View File

@@ -94,7 +94,7 @@ VMs run in client mode. They connect to the socket created by the `dpdkvhostuser
--memory size=1024M,hugepages=on,shared=true \ --memory size=1024M,hugepages=on,shared=true \
--kernel linux/arch/x86/boot/compressed/vmlinux.bin \ --kernel linux/arch/x86/boot/compressed/vmlinux.bin \
--cmdline "console=ttyS0 root=/dev/vda1 rw iommu=off" \ --cmdline "console=ttyS0 root=/dev/vda1 rw iommu=off" \
--disk path=images/focal-server-cloudimg-amd64.raw --disk vhost_user=true,socket=/var/tmp/vhost.1,num_queues=4,queue_size=128 \ --disk path=images/focal-server-cloudimg-amd64.raw vhost_user=true,socket=/var/tmp/vhost.1,num_queues=4,queue_size=128 \
--console off \ --console off \
--serial tty \ --serial tty \
--rng --rng

View File

@@ -50,14 +50,14 @@ The examples use __socat__ `>=1.7.4` to illustrate the VSOCK functionality. Howe
### Connecting from Host to Guest ### Connecting from Host to Guest
The host starts to listen on the defined port: The guest starts to listen on the defined port:
`$ socat - VSOCK-LISTEN:1234` `$ socat - VSOCK-LISTEN:1234`
Once the host is listening, the guest can send data: Once the guest is listening, the host can send data:
`echo -e "CONNECT 1234\\nHello from host!" | socat - UNIX-CONNECT:/tmp/ch.vsock `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. 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 ### Connecting from Guest to Host

View File

@@ -49,7 +49,7 @@ qemu-system-x86_64 \
-m 4G \ -m 4G \
-bios ./$OVMF_DIR/OVMF_CODE.fd \ -bios ./$OVMF_DIR/OVMF_CODE.fd \
-cdrom ./$WIN_ISO_FILE \ -cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom -drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom \
-drive if=none,id=root,file=./$IMG_FILE \ -drive if=none,id=root,file=./$IMG_FILE \
-device virtio-blk-pci,drive=root,disable-legacy=on \ -device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \ -device virtio-net-pci,netdev=mynet0,disable-legacy=on \

383
fuzz/Cargo.lock generated
View File

@@ -5,11 +5,59 @@ version = 3
[[package]] [[package]]
name = "acpi_tables" name = "acpi_tables"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#1029d22777f07b04849234bbe756da34a6df2913" source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#1a733bf690ccc10bdfeacad33e3c9f6cce0008fd"
dependencies = [ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "anstream"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.75" version = "1.0.75"
@@ -25,9 +73,9 @@ dependencies = [
[[package]] [[package]]
name = "arbitrary" name = "arbitrary"
version = "1.3.0" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]] [[package]]
name = "arc-swap" name = "arc-swap"
@@ -57,37 +105,6 @@ dependencies = [
"vmm-sys-util", "vmm-sys-util",
] ]
[[package]]
name = "argh"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219"
dependencies = [
"argh_derive",
"argh_shared",
]
[[package]]
name = "argh_derive"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a"
dependencies = [
"argh_shared",
"proc-macro2",
"quote",
"syn 2.0.23",
]
[[package]]
name = "argh_shared"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@@ -111,9 +128,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.3.3" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]] [[package]]
name = "block" name = "block"
@@ -139,15 +156,15 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.13.0" version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "cc" name = "cc"
@@ -165,13 +182,40 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_lex"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]] [[package]]
name = "cloud-hypervisor" name = "cloud-hypervisor"
version = "34.0.0" version = "36.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"api_client", "api_client",
"argh", "clap",
"epoll", "epoll",
"event_monitor", "event_monitor",
"hypervisor", "hypervisor",
@@ -213,6 +257,12 @@ dependencies = [
"vmm-sys-util", "vmm-sys-util",
] ]
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]] [[package]]
name = "crc32c" name = "crc32c"
version = "0.6.4" version = "0.6.4"
@@ -249,7 +299,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
@@ -260,7 +310,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
@@ -270,7 +320,7 @@ dependencies = [
"acpi_tables", "acpi_tables",
"anyhow", "anyhow",
"arch", "arch",
"bitflags 2.3.3", "bitflags 2.4.1",
"byteorder", "byteorder",
"event_monitor", "event_monitor",
"hypervisor", "hypervisor",
@@ -294,7 +344,7 @@ version = "4.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74351c3392ea1ff6cd2628e0042d268ac2371cb613252ff383b6dfa50d22fa79" checksum = "74351c3392ea1ff6cd2628e0042d268ac2371cb613252ff383b6dfa50d22fa79"
dependencies = [ dependencies = [
"bitflags 2.3.3", "bitflags 2.4.1",
"libc", "libc",
] ]
@@ -336,21 +386,21 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.28" version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
@@ -401,18 +451,18 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.26" version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.64" version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@@ -440,9 +490,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.148" version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]] [[package]]
name = "libfuzzer-sys" name = "libfuzzer-sys"
@@ -457,18 +507,18 @@ dependencies = [
[[package]] [[package]]
name = "linux-loader" name = "linux-loader"
version = "0.9.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db6a725c8000971f83fa93ed7ee1b600e55a1471a2a653379d3c84f72effdcf" checksum = "132a531b85b3a164012ab682c72f8f2cce7757f187be5f60782fd2b4cda9cb34"
dependencies = [ dependencies = [
"vm-memory", "vm-memory",
] ]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.10" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
@@ -483,7 +533,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]] [[package]]
name = "micro_http" name = "micro_http"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#0d0fdcd50ea10c1b4777f9a958873fc848a5b7bb" source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#a4d632f2c5ea45712c0d2002dc909a63879e85c3"
dependencies = [ dependencies = [
"libc", "libc",
"vmm-sys-util", "vmm-sys-util",
@@ -528,9 +578,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.18.0" version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "option_parser" name = "option_parser"
@@ -576,14 +626,14 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -614,7 +664,7 @@ checksum = "bce3a7139d2ee67d07538ee5dba997364fbc243e7e7143e96eb830c74bfaa082"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
@@ -628,9 +678,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
@@ -640,44 +690,44 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "seccompiler" name = "seccompiler"
version = "0.3.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f6575e3c2b3a0fe2ef3e53855b6a8dead7c29f783da5e123d378c8c6a89017e" checksum = "345a3e4dddf721a478089d4697b83c6c0a8f5bf16086f6c13397e4534eb6e2e5"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.18" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.168" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d614f89548720367ded108b3c843be93f3a341e22d5674ca0dd5cd57f34926af" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.168" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fe589678c688e44177da4f27152ee2d190757271dc7f1d5b6b9f68d869d641" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.107" version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@@ -686,9 +736,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_with" name = "serde_with"
version = "3.3.0" version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
dependencies = [ dependencies = [
"serde", "serde",
"serde_with_macros", "serde_with_macros",
@@ -696,14 +746,14 @@ dependencies = [
[[package]] [[package]]
name = "serde_with_macros" name = "serde_with_macros"
version = "3.3.0" version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788"
dependencies = [ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
@@ -731,9 +781,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spin" name = "spin"
@@ -763,9 +813,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.23" version = "2.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -774,22 +824,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.48" version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.48" version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]
[[package]] [[package]]
@@ -823,10 +873,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "uuid" name = "utf8parse"
version = "1.4.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [ dependencies = [
"getrandom", "getrandom",
] ]
@@ -861,7 +917,7 @@ dependencies = [
[[package]] [[package]]
name = "vfio-bindings" name = "vfio-bindings"
version = "0.4.0" version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0" source = "git+https://github.com/rust-vmm/vfio?branch=main#59c604fa6e42080f0a47c124ba29454fe4cb7475"
dependencies = [ dependencies = [
"vmm-sys-util", "vmm-sys-util",
] ]
@@ -869,7 +925,7 @@ dependencies = [
[[package]] [[package]]
name = "vfio-ioctls" name = "vfio-ioctls"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0" source = "git+https://github.com/rust-vmm/vfio?branch=main#59c604fa6e42080f0a47c124ba29454fe4cb7475"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"kvm-bindings", "kvm-bindings",
@@ -885,7 +941,7 @@ dependencies = [
[[package]] [[package]]
name = "vfio_user" name = "vfio_user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#2d96b90a7279547356ad8f83aaa3115ad5497302" source = "git+https://github.com/rust-vmm/vfio-user?branch=main#6c72e997e61d9e84b8ee691ad63ece6c717cf5aa"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"libc", "libc",
@@ -901,11 +957,11 @@ dependencies = [
[[package]] [[package]]
name = "vhost" name = "vhost"
version = "0.8.1" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6" checksum = "289adfce099c71f8310f895932ccd978f352ca494ea47496dbe20d4241888b82"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 2.4.1",
"libc", "libc",
"vm-memory", "vm-memory",
"vmm-sys-util", "vmm-sys-util",
@@ -913,9 +969,9 @@ dependencies = [
[[package]] [[package]]
name = "virtio-bindings" name = "virtio-bindings"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c18d7b74098a946470ea265b5bacbbf877abc3373021388454de0d47735a5b98" checksum = "878bcb1b2812a10c30d53b0ed054999de3d98f25ece91fc173973f9c57aaae86"
[[package]] [[package]]
name = "virtio-devices" name = "virtio-devices"
@@ -953,9 +1009,9 @@ dependencies = [
[[package]] [[package]]
name = "virtio-queue" name = "virtio-queue"
version = "0.9.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f" checksum = "73a01db2cfb6c4b9bc20608b1336263d16714ea8db05de9fec2a254e076f9385"
dependencies = [ dependencies = [
"log", "log",
"virtio-bindings", "virtio-bindings",
@@ -992,9 +1048,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#c5a99ab71b130435927
[[package]] [[package]]
name = "vm-memory" name = "vm-memory"
version = "0.12.2" version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b" checksum = "5376c9ee5ebe2103a310d8241936cfb93c946734b0479a4fa5bdf7a64abbacd8"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"libc", "libc",
@@ -1032,9 +1088,10 @@ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",
"arch", "arch",
"bitflags 2.3.3", "bitflags 2.4.1",
"block", "block",
"cfg-if", "cfg-if",
"clap",
"devices", "devices",
"epoll", "epoll",
"event_monitor", "event_monitor",
@@ -1091,9 +1148,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.87" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@@ -1101,24 +1158,24 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.87" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"log", "log",
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.87" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -1126,22 +1183,22 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.87" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.87" version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
[[package]] [[package]]
name = "winapi" name = "winapi"
@@ -1166,10 +1223,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "zerocopy" name = "windows-sys"
version = "0.6.4" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20707b61725734c595e840fb3704378a0cd2b9c74cc9e6e20724838fc6a1e2f9" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
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.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "zerocopy"
version = "0.7.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d075cf85bbb114e933343e087b92f2146bac0d55b534cbb8188becf0039948e"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"zerocopy-derive", "zerocopy-derive",
@@ -1177,11 +1300,11 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.6.4" version = "0.7.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56097d5b91d711293a42be9289403896b68654625021732067eac7a4ca388a1f" checksum = "86cd5ca076997b97ef09d3ad65efe811fa68c9e874cb636ccb211223a813b0c2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.23", "syn 2.0.32",
] ]

View File

@@ -8,22 +8,25 @@ edition = "2021"
[package.metadata] [package.metadata]
cargo-fuzz = true cargo-fuzz = true
[features]
igvm = []
[dependencies] [dependencies]
block = { path = "../block" } block = { path = "../block" }
devices = { path = "../devices" } devices = { path = "../devices" }
epoll = "4.3.1" epoll = "4.3.1"
libc = "0.2.148" libc = "0.2.150"
libfuzzer-sys = "0.4.7" libfuzzer-sys = "0.4.7"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] } linux-loader = { version = "0.10.0", features = ["elf", "bzimage", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" } micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
net_util = { path = "../net_util" } net_util = { path = "../net_util" }
once_cell = "1.18.0" once_cell = "1.19.0"
seccompiler = "0.3.0" seccompiler = "0.4.0"
virtio-devices = { path = "../virtio-devices" } virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.9.0" virtio-queue = "0.10.0"
vmm = { path = "../vmm" } vmm = { path = "../vmm" }
vmm-sys-util = "0.11.2" vmm-sys-util = "0.11.2"
vm-memory = "0.12.2" vm-memory = "0.13.1"
vm-device = { path = "../vm-device" } vm-device = { path = "../vm-device" }
vm-virtio = { path = "../vm-virtio" } vm-virtio = { path = "../vm-virtio" }

View File

@@ -23,6 +23,8 @@ fuzz_target!(|bytes| {
kernel: None, kernel: None,
cmdline: Some(String::from_utf8_lossy(&bytes).to_string()), cmdline: Some(String::from_utf8_lossy(&bytes).to_string()),
initramfs: None, initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
}; };
let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) { let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) {
Ok(cmdline) => cmdline, Ok(cmdline) => cmdline,

View File

@@ -8,28 +8,30 @@ license = "Apache-2.0 OR BSD-3-Clause"
[features] [features]
kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"] kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"]
mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv", "iced-x86"] mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv", "iced-x86"]
sev_snp = [] sev_snp = ["igvm_parser", "igvm_defs"]
tdx = [] tdx = []
[dependencies] [dependencies]
anyhow = "1.0.75" anyhow = "1.0.75"
byteorder = "1.4.3" byteorder = "1.4.3"
thiserror = "1.0.40" igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main", package = "igvm_defs", optional = true }
igvm_parser = { git = "https://github.com/microsoft/igvm", branch = "main", package = "igvm", optional = true }
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
kvm-ioctls = { version = "0.13.0", optional = true } kvm-ioctls = { version = "0.13.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx", features = ["with-serde", "fam-wrappers"], optional = true } 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-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} mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", branch = "main", optional = true}
serde = { version = "1.0.168", features = ["rc", "derive"] } serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_with = { version = "3.0.0", default-features = false, features = ["macros"] } serde_with = { version = "3.4.0", default-features = false, features = ["macros"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false } vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic"] } vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] } vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
thiserror = "1.0.40"
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86] [target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]
optional = true optional = true
version = "1.19.0" version = "1.20.0"
default-features = false default-features = false
features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"] features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"]

View File

@@ -95,12 +95,12 @@ pub enum HypervisorCpuError {
#[error("Failed to get Msr entries: {0}")] #[error("Failed to get Msr entries: {0}")]
GetMsrEntries(#[source] anyhow::Error), GetMsrEntries(#[source] anyhow::Error),
/// ///
/// Setting MSR entries error /// Setting multi-processing state error
/// ///
#[error("Failed to set MP state: {0}")] #[error("Failed to set MP state: {0}")]
SetMpState(#[source] anyhow::Error), SetMpState(#[source] anyhow::Error),
/// ///
/// Getting Msr entries error /// Getting multi-processing state error
/// ///
#[error("Failed to get MP state: {0}")] #[error("Failed to get MP state: {0}")]
GetMpState(#[source] anyhow::Error), GetMpState(#[source] anyhow::Error),
@@ -257,6 +257,21 @@ pub enum HypervisorCpuError {
/// ///
#[error("Failed to set TSC frequency: {0}")] #[error("Failed to set TSC frequency: {0}")]
SetTscKhz(#[source] anyhow::Error), SetTscKhz(#[source] anyhow::Error),
///
/// Error reading value at given GPA
///
#[error("Failed to read from GPA: {0}")]
GpaRead(#[source] anyhow::Error),
///
/// Error writing value at given GPA
///
#[error("Failed to write to GPA: {0}")]
GpaWrite(#[source] anyhow::Error),
///
/// Error getting CPUID leaf
///
#[error("Failed to get CPUID entries: {0}")]
GetCpuidVales(#[source] anyhow::Error),
} }
#[derive(Debug)] #[derive(Debug)]
@@ -467,4 +482,17 @@ pub trait Vcpu: Send + Sync {
fn set_tsc_khz(&self, _freq: u32) -> Result<()> { fn set_tsc_khz(&self, _freq: u32) -> Result<()> {
Ok(()) Ok(())
} }
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve cpuid leaf
///
fn get_cpuid_values(
&self,
_function: u32,
_index: u32,
_xfem: u64,
_xss: u64,
) -> Result<[u32; 4]> {
unimplemented!()
}
} }

View File

@@ -356,6 +356,7 @@ impl vm::Vm for KvmVm {
.set_identity_map_address(address) .set_identity_map_address(address)
.map_err(|e| vm::HypervisorVmError::SetIdentityMapAddress(e.into())) .map_err(|e| vm::HypervisorVmError::SetIdentityMapAddress(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the address of the three-page region in the VM's address space. /// Sets the address of the three-page region in the VM's address space.
@@ -365,6 +366,7 @@ impl vm::Vm for KvmVm {
.set_tss_address(offset) .set_tss_address(offset)
.map_err(|e| vm::HypervisorVmError::SetTssAddress(e.into())) .map_err(|e| vm::HypervisorVmError::SetTssAddress(e.into()))
} }
/// ///
/// Creates an in-kernel interrupt controller. /// Creates an in-kernel interrupt controller.
/// ///
@@ -373,6 +375,7 @@ impl vm::Vm for KvmVm {
.create_irq_chip() .create_irq_chip()
.map_err(|e| vm::HypervisorVmError::CreateIrq(e.into())) .map_err(|e| vm::HypervisorVmError::CreateIrq(e.into()))
} }
/// ///
/// Registers an event that will, when signaled, trigger the `gsi` IRQ. /// Registers an event that will, when signaled, trigger the `gsi` IRQ.
/// ///
@@ -381,6 +384,7 @@ impl vm::Vm for KvmVm {
.register_irqfd(fd, gsi) .register_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::RegisterIrqFd(e.into())) .map_err(|e| vm::HypervisorVmError::RegisterIrqFd(e.into()))
} }
/// ///
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ. /// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
/// ///
@@ -389,6 +393,7 @@ impl vm::Vm for KvmVm {
.unregister_irqfd(fd, gsi) .unregister_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::UnregisterIrqFd(e.into())) .map_err(|e| vm::HypervisorVmError::UnregisterIrqFd(e.into()))
} }
/// ///
/// Creates a VcpuFd object from a vcpu RawFd. /// Creates a VcpuFd object from a vcpu RawFd.
/// ///
@@ -411,6 +416,7 @@ impl vm::Vm for KvmVm {
}; };
Ok(Arc::new(vcpu)) Ok(Arc::new(vcpu))
} }
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
/// ///
/// Creates a virtual GIC device. /// Creates a virtual GIC device.
@@ -420,6 +426,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?; .map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?;
Ok(Arc::new(Mutex::new(gic_device))) Ok(Arc::new(Mutex::new(gic_device)))
} }
/// ///
/// Registers an event to be signaled whenever a certain address is written to. /// Registers an event to be signaled whenever a certain address is written to.
/// ///
@@ -447,6 +454,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())) .map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into()))
} }
} }
/// ///
/// Unregisters an event from a certain address it has been previously registered to. /// Unregisters an event from a certain address it has been previously registered to.
/// ///
@@ -541,6 +549,7 @@ impl vm::Vm for KvmVm {
.set_gsi_routing(&irq_routing[0]) .set_gsi_routing(&irq_routing[0])
.map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into())) .map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into()))
} }
/// ///
/// Creates a memory region structure that can be used with {create/remove}_user_memory_region /// Creates a memory region structure that can be used with {create/remove}_user_memory_region
/// ///
@@ -567,6 +576,7 @@ impl vm::Vm for KvmVm {
} }
.into() .into()
} }
/// ///
/// Creates a guest physical memory region. /// Creates a guest physical memory region.
/// ///
@@ -603,6 +613,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::CreateUserMemory(e.into())) .map_err(|e| vm::HypervisorVmError::CreateUserMemory(e.into()))
} }
} }
/// ///
/// Removes a guest physical memory region. /// Removes a guest physical memory region.
/// ///
@@ -621,6 +632,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::RemoveUserMemory(e.into())) .map_err(|e| vm::HypervisorVmError::RemoveUserMemory(e.into()))
} }
} }
/// ///
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host. /// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
/// ///
@@ -630,6 +642,7 @@ impl vm::Vm for KvmVm {
.get_preferred_target(kvi) .get_preferred_target(kvi)
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into())) .map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> vm::Result<()> { fn enable_split_irq(&self) -> vm::Result<()> {
// Create split irqchip // Create split irqchip
@@ -645,6 +658,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::EnableSplitIrq(e.into()))?; .map_err(|e| vm::HypervisorVmError::EnableSplitIrq(e.into()))?;
Ok(()) Ok(())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn enable_sgx_attribute(&self, file: File) -> vm::Result<()> { fn enable_sgx_attribute(&self, file: File) -> vm::Result<()> {
let mut cap = kvm_enable_cap { let mut cap = kvm_enable_cap {
@@ -657,6 +671,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::EnableSgxAttribute(e.into()))?; .map_err(|e| vm::HypervisorVmError::EnableSgxAttribute(e.into()))?;
Ok(()) Ok(())
} }
/// Retrieve guest clock. /// Retrieve guest clock.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> vm::Result<ClockData> { fn get_clock(&self) -> vm::Result<ClockData> {
@@ -666,6 +681,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::GetClock(e.into()))? .map_err(|e| vm::HypervisorVmError::GetClock(e.into()))?
.into()) .into())
} }
/// Set guest clock. /// Set guest clock.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn set_clock(&self, data: &ClockData) -> vm::Result<()> { fn set_clock(&self, data: &ClockData) -> vm::Result<()> {
@@ -674,6 +690,7 @@ impl vm::Vm for KvmVm {
.set_clock(&data) .set_clock(&data)
.map_err(|e| vm::HypervisorVmError::SetClock(e.into())) .map_err(|e| vm::HypervisorVmError::SetClock(e.into()))
} }
/// Create a device that is used for passthrough /// Create a device that is used for passthrough
fn create_passthrough_device(&self) -> vm::Result<VfioDeviceFd> { fn create_passthrough_device(&self) -> vm::Result<VfioDeviceFd> {
let mut vfio_dev = kvm_create_device { let mut vfio_dev = kvm_create_device {
@@ -685,6 +702,7 @@ impl vm::Vm for KvmVm {
self.create_device(&mut vfio_dev) self.create_device(&mut vfio_dev)
.map_err(|e| vm::HypervisorVmError::CreatePassthroughDevice(e.into())) .map_err(|e| vm::HypervisorVmError::CreatePassthroughDevice(e.into()))
} }
/// ///
/// Start logging dirty pages /// Start logging dirty pages
/// ///
@@ -826,6 +844,7 @@ impl vm::Vm for KvmVm {
) )
.map_err(vm::HypervisorVmError::InitMemRegionTdx) .map_err(vm::HypervisorVmError::InitMemRegionTdx)
} }
/// Downcast to the underlying KvmVm type /// Downcast to the underlying KvmVm type
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
@@ -892,7 +911,9 @@ pub enum KvmError {
#[error("Capability missing: {0:?}")] #[error("Capability missing: {0:?}")]
CapabilityMissing(Cap), CapabilityMissing(Cap),
} }
pub type KvmResult<T> = result::Result<T, KvmError>; pub type KvmResult<T> = result::Result<T, KvmError>;
impl KvmHypervisor { impl KvmHypervisor {
/// Create a hypervisor based on Kvm /// Create a hypervisor based on Kvm
#[allow(clippy::new_ret_no_self)] #[allow(clippy::new_ret_no_self)]
@@ -906,6 +927,7 @@ impl KvmHypervisor {
Ok(Arc::new(KvmHypervisor { kvm: kvm_obj })) Ok(Arc::new(KvmHypervisor { kvm: kvm_obj }))
} }
/// Check if the hypervisor is available /// Check if the hypervisor is available
pub fn is_available() -> hypervisor::Result<bool> { pub fn is_available() -> hypervisor::Result<bool> {
match std::fs::metadata("/dev/kvm") { match std::fs::metadata("/dev/kvm") {
@@ -917,6 +939,7 @@ impl KvmHypervisor {
} }
} }
} }
/// Implementation of Hypervisor trait for KVM /// Implementation of Hypervisor trait for KVM
/// ///
/// # Examples /// # Examples
@@ -935,6 +958,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
fn hypervisor_type(&self) -> HypervisorType { fn hypervisor_type(&self) -> HypervisorType {
HypervisorType::Kvm HypervisorType::Kvm
} }
/// Create a KVM vm object of a specific VM type and return the object as Vm trait object /// Create a KVM vm object of a specific VM type and return the object as Vm trait object
/// ///
/// # Examples /// # Examples
@@ -1090,6 +1114,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
self.kvm.get_max_vcpus().min(u32::MAX as usize) as u32 self.kvm.get_max_vcpus().min(u32::MAX as usize) as u32
} }
} }
/// Vcpu struct for KVM /// Vcpu struct for KVM
pub struct KvmVcpu { pub struct KvmVcpu {
fd: VcpuFd, fd: VcpuFd,
@@ -1099,6 +1124,7 @@ pub struct KvmVcpu {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
hyperv_synic: AtomicBool, hyperv_synic: AtomicBool,
} }
/// Implementation of Vcpu trait for KVM /// Implementation of Vcpu trait for KVM
/// ///
/// # Examples /// # Examples
@@ -1123,6 +1149,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))?
.into()) .into())
} }
/// ///
/// Returns the vCPU general purpose registers. /// Returns the vCPU general purpose registers.
/// The `KVM_GET_REGS` ioctl is not available on AArch64, `KVM_GET_ONE_REG` /// The `KVM_GET_REGS` ioctl is not available on AArch64, `KVM_GET_ONE_REG`
@@ -1235,6 +1262,7 @@ impl cpu::Vcpu for KvmVcpu {
.unwrap(); .unwrap();
Ok(state) Ok(state)
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the vCPU general purpose registers using the `KVM_SET_REGS` ioctl. /// Sets the vCPU general purpose registers using the `KVM_SET_REGS` ioctl.
@@ -1357,6 +1385,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the vCPU special registers using the `KVM_SET_SREGS` ioctl. /// Sets the vCPU special registers using the `KVM_SET_SREGS` ioctl.
@@ -1367,6 +1396,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_sregs(&sregs) .set_sregs(&sregs)
.map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the floating point state (FPU) from the vCPU. /// Returns the floating point state (FPU) from the vCPU.
@@ -1378,6 +1408,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct. /// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct.
@@ -1388,6 +1419,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_fpu(&fpu) .set_fpu(&fpu)
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call to setup the CPUID registers. /// X86 specific call to setup the CPUID registers.
@@ -1402,6 +1434,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_cpuid2(&kvm_cpuid) .set_cpuid2(&kvm_cpuid)
.map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call to enable HyperV SynIC /// X86 specific call to enable HyperV SynIC
@@ -1419,6 +1452,7 @@ impl cpu::Vcpu for KvmVcpu {
.enable_cap(&cap) .enable_cap(&cap)
.map_err(|e| cpu::HypervisorCpuError::EnableHyperVSyncIc(e.into())) .map_err(|e| cpu::HypervisorCpuError::EnableHyperVSyncIc(e.into()))
} }
/// ///
/// X86 specific call to retrieve the CPUID registers. /// X86 specific call to retrieve the CPUID registers.
/// ///
@@ -1433,6 +1467,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(v) Ok(v)
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller). /// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1444,6 +1479,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller). /// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1454,6 +1490,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_lapic(&klapic) .set_lapic(&klapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the model-specific registers (MSR) for this vCPU. /// Returns the model-specific registers (MSR) for this vCPU.
@@ -1475,6 +1512,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(succ) Ok(succ)
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Setup the model-specific registers (MSR) for this vCPU. /// Setup the model-specific registers (MSR) for this vCPU.
@@ -1487,6 +1525,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_msrs(&kvm_msrs) .set_msrs(&kvm_msrs)
.map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into()))
} }
/// ///
/// Returns the vcpu's current "multiprocessing state". /// Returns the vcpu's current "multiprocessing state".
/// ///
@@ -1497,6 +1536,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))?
.into()) .into())
} }
/// ///
/// Sets the vcpu's current "multiprocessing state". /// Sets the vcpu's current "multiprocessing state".
/// ///
@@ -1505,6 +1545,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_mp_state(mp_state.into()) .set_mp_state(mp_state.into())
.map_err(|e| cpu::HypervisorCpuError::SetMpState(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetMpState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Translates guest virtual address to guest physical address using the `KVM_TRANSLATE` ioctl. /// Translates guest virtual address to guest physical address using the `KVM_TRANSLATE` ioctl.
@@ -1523,6 +1564,7 @@ impl cpu::Vcpu for KvmVcpu {
_ => Ok((tr.physical_address, 0)), _ => Ok((tr.physical_address, 0)),
} }
} }
/// ///
/// Triggers the running of the current virtual CPU returning an exit reason. /// Triggers the running of the current virtual CPU returning an exit reason.
/// ///
@@ -1614,6 +1656,7 @@ impl cpu::Vcpu for KvmVcpu {
}, },
} }
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Let the guest know that it has been paused, which prevents from /// Let the guest know that it has been paused, which prevents from
@@ -1631,6 +1674,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(()) Ok(())
} }
/// ///
/// Sets debug registers to set hardware breakpoints and/or enable single step. /// Sets debug registers to set hardware breakpoints and/or enable single step.
/// ///
@@ -1684,12 +1728,14 @@ impl cpu::Vcpu for KvmVcpu {
.set_guest_debug(&dbg) .set_guest_debug(&dbg)
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))
} }
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> { fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
self.fd self.fd
.vcpu_init(kvi) .vcpu_init(kvi)
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into())) .map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
} }
/// ///
/// Gets a list of the guest registers that are supported for the /// Gets a list of the guest registers that are supported for the
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. /// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
@@ -1700,6 +1746,7 @@ impl cpu::Vcpu for KvmVcpu {
.get_reg_list(reg_list) .get_reg_list(reg_list)
.map_err(|e| cpu::HypervisorCpuError::GetRegList(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetRegList(e.into()))
} }
/// ///
/// Gets the value of a system register /// Gets the value of a system register
/// ///
@@ -1733,6 +1780,7 @@ impl cpu::Vcpu for KvmVcpu {
.try_into() .try_into()
.unwrap()) .unwrap())
} }
/// ///
/// Configure core registers for a given CPU. /// Configure core registers for a given CPU.
/// ///
@@ -1907,6 +1955,7 @@ impl cpu::Vcpu for KvmVcpu {
} }
.into()) .into())
} }
/// ///
/// Get the current AArch64 CPU state /// Get the current AArch64 CPU state
/// ///
@@ -1956,6 +2005,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(state.into()) Ok(state.into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Restore the previously saved CPU state /// Restore the previously saved CPU state
@@ -2045,6 +2095,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(()) Ok(())
} }
/// ///
/// Restore the previously saved AArch64 CPU state /// Restore the previously saved AArch64 CPU state
/// ///
@@ -2119,6 +2170,7 @@ impl cpu::Vcpu for KvmVcpu {
TdxExitStatus::InvalidOperand => TDG_VP_VMCALL_INVALID_OPERAND, TdxExitStatus::InvalidOperand => TDG_VP_VMCALL_INVALID_OPERAND,
}; };
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Return the list of initial MSR entries for a VCPU /// Return the list of initial MSR entries for a VCPU
@@ -2144,6 +2196,7 @@ impl cpu::Vcpu for KvmVcpu {
] ]
.to_vec() .to_vec()
} }
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
fn has_pmu_support(&self) -> bool { fn has_pmu_support(&self) -> bool {
let cpu_attr = kvm_bindings::kvm_device_attr { let cpu_attr = kvm_bindings::kvm_device_attr {
@@ -2154,6 +2207,7 @@ impl cpu::Vcpu for KvmVcpu {
}; };
self.fd.has_device_attr(&cpu_attr).is_ok() self.fd.has_device_attr(&cpu_attr).is_ok()
} }
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
fn init_pmu(&self, irq: u32) -> cpu::Result<()> { fn init_pmu(&self, irq: u32) -> cpu::Result<()> {
let cpu_attr = kvm_bindings::kvm_device_attr { let cpu_attr = kvm_bindings::kvm_device_attr {
@@ -2221,6 +2275,7 @@ impl KvmVcpu {
.get_xsave() .get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that sets the vcpu's current "xsave struct". /// X86 specific call that sets the vcpu's current "xsave struct".
@@ -2230,6 +2285,7 @@ impl KvmVcpu {
.set_xsave(xsave) .set_xsave(xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that returns the vcpu's current "xcrs". /// X86 specific call that returns the vcpu's current "xcrs".
@@ -2239,6 +2295,7 @@ impl KvmVcpu {
.get_xcrs() .get_xcrs()
.map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that sets the vcpu's current "xcrs". /// X86 specific call that sets the vcpu's current "xcrs".
@@ -2248,6 +2305,7 @@ impl KvmVcpu {
.set_xcrs(xcrs) .set_xcrs(xcrs)
.map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related /// Returns currently pending exceptions, interrupts, and NMIs as well as related
@@ -2258,6 +2316,7 @@ impl KvmVcpu {
.get_vcpu_events() .get_vcpu_events()
.map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets pending exceptions, interrupts, and NMIs as well as related states /// Sets pending exceptions, interrupts, and NMIs as well as related states

View File

@@ -20,13 +20,21 @@ use std::collections::HashMap;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use vfio_ioctls::VfioDeviceFd; use vfio_ioctls::VfioDeviceFd;
use vm::DataMatch; use vm::DataMatch;
#[cfg(feature = "sev_snp")]
mod snp_constants;
// x86_64 dependencies // x86_64 dependencies
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub mod x86_64; pub mod x86_64;
#[cfg(feature = "sev_snp")]
use snp_constants::*;
use crate::{ use crate::{
ClockData, CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion, ClockData, CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
}; };
#[cfg(feature = "sev_snp")]
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use x86_64::VcpuMshvState; pub use x86_64::VcpuMshvState;
@@ -192,6 +200,7 @@ impl MshvHypervisor {
} }
} }
} }
/// Implementation of Hypervisor trait for Mshv /// Implementation of Hypervisor trait for Mshv
/// ///
/// # Examples /// # Examples
@@ -234,6 +243,33 @@ impl hypervisor::Hypervisor for MshvHypervisor {
break; break;
} }
// Set additional partition property for SEV-SNP partition.
if mshv_vm_type == VmType::Snp {
let snp_policy = snp::get_default_snp_guest_policy();
let vmgexit_offloads = snp::get_default_vmgexit_offload_features();
// SAFETY: access union fields
unsafe {
debug!(
"Setting the partition isolation policy as: 0x{:x}",
snp_policy.as_uint64
);
fd.set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_ISOLATION_POLICY,
snp_policy.as_uint64,
)
.map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?;
debug!(
"Setting the partition property to enable VMGEXIT offloads as : 0x{:x}",
vmgexit_offloads.as_uint64
);
fd.set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_SEV_VMGEXIT_OFFLOADS,
vmgexit_offloads.as_uint64,
)
.map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?;
}
}
// Default Microsoft Hypervisor behavior for unimplemented MSR is to // Default Microsoft Hypervisor behavior for unimplemented MSR is to
// send a fault to the guest if it tries to access it. It is possible // send a fault to the guest if it tries to access it. It is possible
// to override this behavior with a more suitable option i.e., ignore // to override this behavior with a more suitable option i.e., ignore
@@ -303,6 +339,8 @@ pub struct MshvVcpu {
cpuid: Vec<CpuIdEntry>, cpuid: Vec<CpuIdEntry>,
msrs: Vec<MsrEntry>, msrs: Vec<MsrEntry>,
vm_ops: Option<Arc<dyn vm::VmOps>>, vm_ops: Option<Arc<dyn vm::VmOps>>,
#[cfg(feature = "sev_snp")]
vm_fd: Arc<VmFd>,
} }
/// Implementation of Vcpu trait for Microsoft Hypervisor /// Implementation of Vcpu trait for Microsoft Hypervisor
@@ -329,6 +367,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the vCPU general purpose registers. /// Sets the vCPU general purpose registers.
@@ -339,6 +378,7 @@ impl cpu::Vcpu for MshvVcpu {
.set_regs(&regs) .set_regs(&regs)
.map_err(|e| cpu::HypervisorCpuError::SetStandardRegs(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetStandardRegs(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the vCPU special registers. /// Returns the vCPU special registers.
@@ -350,6 +390,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the vCPU special registers. /// Sets the vCPU special registers.
@@ -360,6 +401,7 @@ impl cpu::Vcpu for MshvVcpu {
.set_sregs(&sregs) .set_sregs(&sregs)
.map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the floating point state (FPU) from the vCPU. /// Returns the floating point state (FPU) from the vCPU.
@@ -371,6 +413,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Set the floating point state (FPU) of a vCPU. /// Set the floating point state (FPU) of a vCPU.
@@ -403,6 +446,7 @@ impl cpu::Vcpu for MshvVcpu {
Ok(succ) Ok(succ)
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Setup the model-specific registers (MSR) for this vCPU. /// Setup the model-specific registers (MSR) for this vCPU.
@@ -424,6 +468,7 @@ impl cpu::Vcpu for MshvVcpu {
/* We always have SynIC enabled on MSHV */ /* We always have SynIC enabled on MSHV */
Ok(()) Ok(())
} }
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
fn run(&self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> { fn run(&self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
let hv_message: hv_message = hv_message::default(); let hv_message: hv_message = hv_message::default();
@@ -584,6 +629,427 @@ impl cpu::Vcpu for MshvVcpu {
info.interrupt_vector.try_into().unwrap(), info.interrupt_vector.try_into().unwrap(),
)) ))
} }
#[cfg(feature = "sev_snp")]
hv_message_type_HVMSG_X64_SEV_VMGEXIT_INTERCEPT => {
let info = x.to_vmg_intercept_info().unwrap();
let ghcb_data = info.ghcb_msr >> GHCB_INFO_BIT_WIDTH;
let ghcb_msr = svm_ghcb_msr {
as_uint64: info.ghcb_msr,
};
// SAFETY: Accessing a union element from bindgen generated bindings.
let ghcb_op = unsafe { ghcb_msr.__bindgen_anon_2.ghcb_info() as u32 };
// Sanity check on the header fields before handling other operations.
assert!(info.header.intercept_access_type == HV_INTERCEPT_ACCESS_EXECUTE as u8);
match ghcb_op {
GHCB_INFO_HYP_FEATURE_REQUEST => {
// Pre-condition: GHCB data must be zero
assert!(ghcb_data == 0);
let mut ghcb_response = GHCB_INFO_HYP_FEATURE_RESPONSE as u64;
// Indicate support for basic SEV-SNP features
ghcb_response |=
(GHCB_HYP_FEATURE_SEV_SNP << GHCB_INFO_BIT_WIDTH) as u64;
// Indicate support for SEV-SNP AP creation
ghcb_response |= (GHCB_HYP_FEATURE_SEV_SNP_AP_CREATION
<< GHCB_INFO_BIT_WIDTH)
as u64;
debug!(
"GHCB_INFO_HYP_FEATURE_REQUEST: Supported features: {:0x}",
ghcb_response
);
let arr_reg_name_value =
[(hv_register_name_HV_X64_REGISTER_GHCB, ghcb_response)];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
}
GHCB_INFO_REGISTER_REQUEST => {
let mut ghcb_gpa = hv_x64_register_sev_ghcb::default();
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe {
ghcb_gpa.__bindgen_anon_1.set_enabled(1);
ghcb_gpa
.__bindgen_anon_1
.set_page_number(ghcb_msr.__bindgen_anon_2.gpa_page_number());
}
// SAFETY: Accessing a union element from bindgen generated bindings.
let reg_name_value = unsafe {
[(
hv_register_name_HV_X64_REGISTER_SEV_GHCB_GPA,
ghcb_gpa.as_uint64,
)]
};
set_registers_64!(self.fd, reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
let mut resp_ghcb_msr = svm_ghcb_msr::default();
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe {
resp_ghcb_msr
.__bindgen_anon_2
.set_ghcb_info(GHCB_INFO_REGISTER_RESPONSE as u64);
resp_ghcb_msr.__bindgen_anon_2.set_gpa_page_number(
ghcb_msr.__bindgen_anon_2.gpa_page_number(),
);
}
// SAFETY: Accessing a union element from bindgen generated bindings.
let reg_name_value = unsafe {
[(
hv_register_name_HV_X64_REGISTER_GHCB,
resp_ghcb_msr.as_uint64,
)]
};
set_registers_64!(self.fd, reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
}
GHCB_INFO_SEV_INFO_REQUEST => {
let sev_cpuid_function = 0x8000_001F;
let cpu_leaf = self
.fd
.get_cpuid_values(sev_cpuid_function, 0, 0, 0)
.unwrap();
let ebx = cpu_leaf[1];
// First 6-byte of EBX represents page table encryption bit number
let pbit_encryption = (ebx & 0x3f) as u8;
let mut ghcb_response = GHCB_INFO_SEV_INFO_RESPONSE as u64;
// GHCBData[63:48] specifies the maximum GHCB protocol version supported
ghcb_response |= (GHCB_PROTOCOL_VERSION_MAX as u64) << 48;
// GHCBData[47:32] specifies the minimum GHCB protocol version supported
ghcb_response |= (GHCB_PROTOCOL_VERSION_MIN as u64) << 32;
// GHCBData[31:24] specifies the SEV page table encryption bit number.
ghcb_response |= (pbit_encryption as u64) << 24;
let arr_reg_name_value =
[(hv_register_name_HV_X64_REGISTER_GHCB, ghcb_response)];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
}
GHCB_INFO_NORMAL => {
let exit_code =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_code as u32;
// SAFETY: Accessing a union element from bindgen generated bindings.
let pfn = unsafe { ghcb_msr.__bindgen_anon_2.gpa_page_number() };
let ghcb_gpa = pfn << GHCB_INFO_BIT_WIDTH;
match exit_code {
SVM_EXITCODE_HV_DOORBELL_PAGE => {
let exit_info1 =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32;
match exit_info1 {
SVM_NAE_HV_DOORBELL_PAGE_GET_PREFERRED => {
// Hypervisor does not have any preference for doorbell GPA.
let preferred_doorbell_gpa: u64 = 0xFFFFFFFFFFFFFFFF;
let mut swei2_rw_gpa_arg =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
swei2_rw_gpa_arg.data.copy_from_slice(
&preferred_doorbell_gpa.to_le_bytes(),
);
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
}
SVM_NAE_HV_DOORBELL_PAGE_SET => {
let exit_info2 = info
.__bindgen_anon_2
.__bindgen_anon_1
.sw_exit_info2;
let mut ghcb_doorbell_gpa =
hv_x64_register_sev_hv_doorbell::default();
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe {
ghcb_doorbell_gpa.__bindgen_anon_1.set_enabled(1);
ghcb_doorbell_gpa
.__bindgen_anon_1
.set_page_number(exit_info2 >> PAGE_SHIFT);
}
// SAFETY: Accessing a union element from bindgen generated bindings.
let reg_names = unsafe {
[(
hv_register_name_HV_X64_REGISTER_SEV_DOORBELL_GPA,
ghcb_doorbell_gpa.as_uint64,
)]
};
set_registers_64!(self.fd, reg_names).map_err(|e| {
cpu::HypervisorCpuError::SetRegister(e.into())
})?;
let mut swei2_rw_gpa_arg =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
swei2_rw_gpa_arg.data[0..8]
.copy_from_slice(&exit_info2.to_le_bytes());
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
// Clear the SW_EXIT_INFO1 register to indicate no error
let mut swei1_rw_gpa_arg =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd.gpa_write(&mut swei1_rw_gpa_arg).map_err(
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
}
SVM_NAE_HV_DOORBELL_PAGE_QUERY => {
let mut reg_assocs = [ hv_register_assoc {
name: hv_register_name_HV_X64_REGISTER_SEV_DOORBELL_GPA,
..Default::default()
} ];
self.fd.get_reg(&mut reg_assocs).unwrap();
// SAFETY: Accessing a union element from bindgen generated bindings.
let doorbell_gpa = unsafe { reg_assocs[0].value.reg64 };
let mut swei2_rw_gpa_arg =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
swei2_rw_gpa_arg
.data
.copy_from_slice(&doorbell_gpa.to_le_bytes());
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
}
SVM_NAE_HV_DOORBELL_PAGE_CLEAR => {
let mut swei2_rw_gpa_arg =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
}
_ => {
panic!(
"SVM_EXITCODE_HV_DOORBELL_PAGE: Unhandled exit code: {:0x}",
exit_info1
);
}
}
}
SVM_EXITCODE_SNP_EXTENDED_GUEST_REQUEST => {
warn!("Fetching extended guest request is not supported");
// Extended guest request is not supported by the Hypervisor
// Returning the error to the guest
// 0x6 means `The NAE event was not valid`
// Reference: GHCB Spec, page 42
let value: u64 = 0x6;
let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
swei2_rw_gpa_arg.data.copy_from_slice(&value.to_le_bytes());
self.fd
.gpa_write(&mut swei2_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
SVM_EXITCODE_IOIO_PROT => {
let exit_info1 =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32;
let port_info = hv_sev_vmgexit_port_info {
as_uint32: exit_info1,
};
let port =
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe { port_info.__bindgen_anon_1.intercepted_port() };
let mut len = 4;
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe {
if port_info.__bindgen_anon_1.operand_size_16bit() == 1 {
len = 2;
} else if port_info.__bindgen_anon_1.operand_size_8bit()
== 1
{
len = 1;
}
}
let is_write =
// SAFETY: Accessing a union element from bindgen generated bindings.
unsafe { port_info.__bindgen_anon_1.access_type() == 0 };
let mut rax_rw_gpa_arg: mshv_read_write_gpa =
mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_RAX_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_read(&mut rax_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaRead(e.into()))?;
if is_write {
if let Some(vm_ops) = &self.vm_ops {
vm_ops
.pio_write(
port.into(),
&rax_rw_gpa_arg.data[0..len],
)
.map_err(|e| {
cpu::HypervisorCpuError::RunVcpu(e.into())
})?;
}
} else {
if let Some(vm_ops) = &self.vm_ops {
vm_ops
.pio_read(
port.into(),
&mut rax_rw_gpa_arg.data[0..len],
)
.map_err(|e| {
cpu::HypervisorCpuError::RunVcpu(e.into())
})?;
}
self.fd.gpa_write(&mut rax_rw_gpa_arg).map_err(|e| {
cpu::HypervisorCpuError::GpaWrite(e.into())
})?;
}
// Clear the SW_EXIT_INFO1 register to indicate no error
let mut swei1_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_write(&mut swei1_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
SVM_EXITCODE_MMIO_READ => {
let src_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let dst_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_scratch;
let data_len =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2
as usize;
// Sanity check to make sure data len is within supported range.
assert!(data_len <= 0x8);
let mut data: Vec<u8> = vec![0; data_len];
if let Some(vm_ops) = &self.vm_ops {
vm_ops.mmio_read(src_gpa, &mut data[0..data_len]).map_err(
|e| cpu::HypervisorCpuError::RunVcpu(e.into()),
)?;
}
let mut arg: mshv_read_write_gpa =
mshv_bindings::mshv_read_write_gpa {
base_gpa: dst_gpa,
byte_count: data_len as u32,
..Default::default()
};
arg.data[0..data_len].copy_from_slice(&data);
self.fd
.gpa_write(&mut arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
SVM_EXITCODE_MMIO_WRITE => {
let dst_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let src_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_scratch;
let data_len =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2
as usize;
// Sanity check to make sure data len is within supported range.
assert!(data_len <= 0x8);
let mut arg: mshv_read_write_gpa =
mshv_bindings::mshv_read_write_gpa {
base_gpa: src_gpa,
byte_count: data_len as u32,
..Default::default()
};
self.fd
.gpa_read(&mut arg)
.map_err(|e| cpu::HypervisorCpuError::GpaRead(e.into()))?;
if let Some(vm_ops) = &self.vm_ops {
vm_ops
.mmio_write(dst_gpa, &arg.data[0..data_len])
.map_err(|e| {
cpu::HypervisorCpuError::RunVcpu(e.into())
})?;
}
}
SVM_EXITCODE_SNP_GUEST_REQUEST => {
let req_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let rsp_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2;
let mshv_psp_req =
mshv_issue_psp_guest_request { req_gpa, rsp_gpa };
self.vm_fd
.psp_issue_guest_request(&mshv_psp_req)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
debug!(
"SNP guest request: req_gpa {:0x} rsp_gpa {:0x}",
req_gpa, rsp_gpa
);
let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_write(&mut swei2_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
SVM_EXITCODE_SNP_AP_CREATION => {
let vmsa_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2;
let apic_id =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 >> 32;
debug!(
"SNP AP CREATE REQUEST with VMSA GPA {:0x}, and APIC ID {:?}",
vmsa_gpa, apic_id
);
let mshv_ap_create_req = mshv_sev_snp_ap_create {
vp_id: apic_id,
vmsa_gpa,
};
self.vm_fd
.sev_snp_ap_create(&mshv_ap_create_req)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_write(&mut swei2_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
_ => panic!(
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
exit_code
),
}
}
_ => panic!("Unsupported VMGEXIT operation: {:0x}", ghcb_op),
}
Ok(cpu::VmExit::Ignore)
}
exit => Err(cpu::HypervisorCpuError::RunVcpu(anyhow!( exit => Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unhandled VCPU exit {:?}", "Unhandled VCPU exit {:?}",
exit exit
@@ -599,6 +1065,7 @@ impl cpu::Vcpu for MshvVcpu {
}, },
} }
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call to setup the CPUID registers. /// X86 specific call to setup the CPUID registers.
@@ -612,6 +1079,7 @@ impl cpu::Vcpu for MshvVcpu {
.register_intercept_result_cpuid(&mshv_cpuid) .register_intercept_result_cpuid(&mshv_cpuid)
.map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call to retrieve the CPUID registers. /// X86 specific call to retrieve the CPUID registers.
@@ -619,6 +1087,23 @@ impl cpu::Vcpu for MshvVcpu {
fn get_cpuid2(&self, _num_entries: usize) -> cpu::Result<Vec<CpuIdEntry>> { fn get_cpuid2(&self, _num_entries: usize) -> cpu::Result<Vec<CpuIdEntry>> {
Ok(self.cpuid.clone()) Ok(self.cpuid.clone())
} }
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve cpuid leaf
///
fn get_cpuid_values(
&self,
function: u32,
index: u32,
xfem: u64,
xss: u64,
) -> cpu::Result<[u32; 4]> {
self.fd
.get_cpuid_values(function, index, xfem, xss)
.map_err(|e| cpu::HypervisorCpuError::GetCpuidVales(e.into()))
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller). /// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -630,6 +1115,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))? .map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))?
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller). /// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -640,18 +1126,21 @@ impl cpu::Vcpu for MshvVcpu {
.set_lapic(&lapic) .set_lapic(&lapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
} }
/// ///
/// Returns the vcpu's current "multiprocessing state". /// Returns the vcpu's current "multiprocessing state".
/// ///
fn get_mp_state(&self) -> cpu::Result<MpState> { fn get_mp_state(&self) -> cpu::Result<MpState> {
Ok(MpState::Mshv) Ok(MpState::Mshv)
} }
/// ///
/// Sets the vcpu's current "multiprocessing state". /// Sets the vcpu's current "multiprocessing state".
/// ///
fn set_mp_state(&self, _mp_state: MpState) -> cpu::Result<()> { fn set_mp_state(&self, _mp_state: MpState) -> cpu::Result<()> {
Ok(()) Ok(())
} }
/// ///
/// Set CPU state /// Set CPU state
/// ///
@@ -677,6 +1166,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))?; .map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))?;
Ok(()) Ok(())
} }
/// ///
/// Get CPU State /// Get CPU State
/// ///
@@ -713,6 +1203,7 @@ impl cpu::Vcpu for MshvVcpu {
} }
.into()) .into())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Translate guest virtual address to guest physical address /// Translate guest virtual address to guest physical address
@@ -729,6 +1220,7 @@ impl cpu::Vcpu for MshvVcpu {
Ok((gpa, result_code)) Ok((gpa, result_code))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Return the list of initial MSR entries for a VCPU /// Return the list of initial MSR entries for a VCPU
@@ -761,6 +1253,7 @@ impl MshvVcpu {
.get_xsave() .get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that sets the vcpu's current "xsave struct". /// X86 specific call that sets the vcpu's current "xsave struct".
@@ -770,6 +1263,7 @@ impl MshvVcpu {
.set_xsave(xsave) .set_xsave(xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that returns the vcpu's current "xcrs". /// X86 specific call that returns the vcpu's current "xcrs".
@@ -779,6 +1273,7 @@ impl MshvVcpu {
.get_xcrs() .get_xcrs()
.map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// X86 specific call that sets the vcpu's current "xcrs". /// X86 specific call that sets the vcpu's current "xcrs".
@@ -788,6 +1283,7 @@ impl MshvVcpu {
.set_xcrs(xcrs) .set_xcrs(xcrs)
.map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into())) .map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related /// Returns currently pending exceptions, interrupts, and NMIs as well as related
@@ -798,6 +1294,7 @@ impl MshvVcpu {
.get_vcpu_events() .get_vcpu_events()
.map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into())) .map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into()))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets pending exceptions, interrupts, and NMIs as well as related states /// Sets pending exceptions, interrupts, and NMIs as well as related states
@@ -977,6 +1474,7 @@ impl vm::Vm for MshvVm {
fn set_identity_map_address(&self, _address: u64) -> vm::Result<()> { fn set_identity_map_address(&self, _address: u64) -> vm::Result<()> {
Ok(()) Ok(())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Sets the address of the three-page region in the VM's address space. /// Sets the address of the three-page region in the VM's address space.
@@ -984,12 +1482,14 @@ impl vm::Vm for MshvVm {
fn set_tss_address(&self, _offset: usize) -> vm::Result<()> { fn set_tss_address(&self, _offset: usize) -> vm::Result<()> {
Ok(()) Ok(())
} }
/// ///
/// Creates an in-kernel interrupt controller. /// Creates an in-kernel interrupt controller.
/// ///
fn create_irq_chip(&self) -> vm::Result<()> { fn create_irq_chip(&self) -> vm::Result<()> {
Ok(()) Ok(())
} }
/// ///
/// Registers an event that will, when signaled, trigger the `gsi` IRQ. /// Registers an event that will, when signaled, trigger the `gsi` IRQ.
/// ///
@@ -1002,6 +1502,7 @@ impl vm::Vm for MshvVm {
Ok(()) Ok(())
} }
/// ///
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ. /// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
/// ///
@@ -1014,6 +1515,7 @@ impl vm::Vm for MshvVm {
Ok(()) Ok(())
} }
/// ///
/// Creates a VcpuFd object from a vcpu RawFd. /// Creates a VcpuFd object from a vcpu RawFd.
/// ///
@@ -1032,17 +1534,22 @@ impl vm::Vm for MshvVm {
cpuid: Vec::new(), cpuid: Vec::new(),
msrs: self.msrs.clone(), msrs: self.msrs.clone(),
vm_ops, vm_ops,
#[cfg(feature = "sev_snp")]
vm_fd: self.fd.clone(),
}; };
Ok(Arc::new(vcpu)) Ok(Arc::new(vcpu))
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> vm::Result<()> { fn enable_split_irq(&self) -> vm::Result<()> {
Ok(()) Ok(())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn enable_sgx_attribute(&self, _file: File) -> vm::Result<()> { fn enable_sgx_attribute(&self, _file: File) -> vm::Result<()> {
Ok(()) Ok(())
} }
fn register_ioevent( fn register_ioevent(
&self, &self,
fd: &EventFd, fd: &EventFd,
@@ -1073,6 +1580,7 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())) .map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into()))
} }
} }
/// Unregister an event from a certain address it has been previously registered to. /// Unregister an event from a certain address it has been previously registered to.
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> { fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> {
let addr = &mshv_ioctls::IoEventAddress::from(*addr); let addr = &mshv_ioctls::IoEventAddress::from(*addr);
@@ -1197,6 +1705,7 @@ impl vm::Vm for MshvVm {
.set_msi_routing(&msi_routing[0]) .set_msi_routing(&msi_routing[0])
.map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into())) .map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into()))
} }
/// ///
/// Start logging dirty pages /// Start logging dirty pages
/// ///
@@ -1205,6 +1714,7 @@ impl vm::Vm for MshvVm {
.enable_dirty_page_tracking() .enable_dirty_page_tracking()
.map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into())) .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))
} }
/// ///
/// Stop logging dirty pages /// Stop logging dirty pages
/// ///
@@ -1223,6 +1733,7 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?; .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?;
Ok(()) Ok(())
} }
/// ///
/// Get dirty pages bitmap (one bit per page) /// Get dirty pages bitmap (one bit per page)
/// ///
@@ -1235,18 +1746,115 @@ impl vm::Vm for MshvVm {
) )
.map_err(|e| vm::HypervisorVmError::GetDirtyLog(e.into())) .map_err(|e| vm::HypervisorVmError::GetDirtyLog(e.into()))
} }
/// Retrieve guest clock. /// Retrieve guest clock.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> vm::Result<ClockData> { fn get_clock(&self) -> vm::Result<ClockData> {
Ok(ClockData::Mshv) Ok(ClockData::Mshv)
} }
/// Set guest clock. /// Set guest clock.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn set_clock(&self, _data: &ClockData) -> vm::Result<()> { fn set_clock(&self, _data: &ClockData) -> vm::Result<()> {
Ok(()) Ok(())
} }
/// Downcast to the underlying MshvVm type /// Downcast to the underlying MshvVm type
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
/// Initialize the SEV-SNP VM
#[cfg(feature = "sev_snp")]
fn sev_snp_init(&self) -> vm::Result<()> {
self.fd
.set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_ISOLATION_STATE,
hv_partition_isolation_state_HV_PARTITION_ISOLATION_SECURE as u64,
)
.map_err(|e| vm::HypervisorVmError::InitializeSevSnp(e.into()))
}
///
/// Importing isolated pages, these pages will be used
/// for the PSP(Platform Security Processor) measurement.
#[cfg(feature = "sev_snp")]
fn import_isolated_pages(
&self,
page_type: u32,
page_size: u32,
pages: &[u64],
) -> vm::Result<()> {
if pages.is_empty() {
return Ok(());
}
let mut isolated_pages =
vec_with_array_field::<mshv_import_isolated_pages, u64>(pages.len());
isolated_pages[0].num_pages = pages.len() as u64;
isolated_pages[0].page_type = page_type;
isolated_pages[0].page_size = page_size;
// SAFETY: isolated_pages initialized with pages.len() and now it is being turned into
// pages_slice with pages.len() again. It is guaranteed to be large enough to hold
// everything from pages.
unsafe {
let pages_slice: &mut [u64] = isolated_pages[0].page_number.as_mut_slice(pages.len());
pages_slice.copy_from_slice(pages);
}
self.fd
.import_isolated_pages(&isolated_pages[0])
.map_err(|e| vm::HypervisorVmError::ImportIsolatedPages(e.into()))
}
///
/// Complete isolated import, telling the hypervisor that
/// importing the pages to guest memory is complete.
///
#[cfg(feature = "sev_snp")]
fn complete_isolated_import(
&self,
snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
host_data: &[u8],
id_block_enabled: u8,
) -> vm::Result<()> {
let mut auth_info = hv_snp_id_auth_info {
id_key_algorithm: snp_id_block.id_key_algorithm,
auth_key_algorithm: snp_id_block.author_key_algorithm,
..Default::default()
};
// Each of r/s component is 576 bits long
auth_info.id_block_signature[..SIG_R_COMPONENT_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_key_signature.r_comp.as_ref());
auth_info.id_block_signature
[SIG_R_COMPONENT_SIZE_IN_BYTES..SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_key_signature.s_comp.as_ref());
auth_info.id_key[..ECDSA_CURVE_ID_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_public_key.curve.to_le_bytes().as_ref());
auth_info.id_key[ECDSA_SIG_X_COMPONENT_START..ECDSA_SIG_X_COMPONENT_END]
.copy_from_slice(snp_id_block.id_public_key.qx.as_ref());
auth_info.id_key[ECDSA_SIG_Y_COMPONENT_START..ECDSA_SIG_Y_COMPONENT_END]
.copy_from_slice(snp_id_block.id_public_key.qy.as_ref());
let data = mshv_complete_isolated_import {
import_data: hv_partition_complete_isolated_import_data {
psp_parameters: hv_psp_launch_finish_data {
id_block: hv_snp_id_block {
launch_digest: snp_id_block.ld,
family_id: snp_id_block.family_id,
image_id: snp_id_block.image_id,
version: snp_id_block.version,
guest_svn: snp_id_block.guest_svn,
policy: get_default_snp_guest_policy(),
},
id_auth_info: auth_info,
host_data: host_data[0..32].try_into().unwrap(),
id_block_enabled,
author_key_enabled: 0,
},
},
};
self.fd
.complete_isolated_import(&data)
.map_err(|e| vm::HypervisorVmError::CompleteIsolatedImport(e.into()))
}
} }

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Reference: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56860.pdf
// Chapter 10
pub const SIG_R_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES: usize = 144;
pub const ECDSA_CURVE_ID_SIZE_IN_BYTES: usize = 4;
pub const ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const ECDSA_SIG_X_COMPONENT_START: usize = ECDSA_CURVE_ID_SIZE_IN_BYTES;
pub const ECDSA_SIG_X_COMPONENT_END: usize =
ECDSA_SIG_X_COMPONENT_START + ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES;
pub const ECDSA_SIG_Y_COMPONENT_START: usize = ECDSA_SIG_X_COMPONENT_END;
pub const ECDSA_SIG_Y_COMPONENT_END: usize =
ECDSA_SIG_X_COMPONENT_END + ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES;
// These constants are derived from GHCB spec Sect. 2.6 Table 3 GHCB Layout
// Link: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf
pub const GHCB_RAX_OFFSET: u64 = 0x01F8;
pub const GHCB_SW_EXITINFO1_OFFSET: u64 = 0x398;
pub const GHCB_SW_EXITINFO2_OFFSET: u64 = 0x3A0;

View File

@@ -19,6 +19,8 @@ use crate::cpu::Vcpu;
use crate::ClockData; use crate::ClockData;
use crate::UserMemoryRegion; use crate::UserMemoryRegion;
use crate::{IoEventAddress, IrqRoutingEntry}; use crate::{IoEventAddress, IrqRoutingEntry};
#[cfg(feature = "sev_snp")]
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
use std::any::Any; use std::any::Any;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::fs::File; use std::fs::File;
@@ -190,6 +192,13 @@ pub enum HypervisorVmError {
#[error("Failed to assert virtual Interrupt: {0}")] #[error("Failed to assert virtual Interrupt: {0}")]
AsserttVirtualInterrupt(#[source] anyhow::Error), AsserttVirtualInterrupt(#[source] anyhow::Error),
#[cfg(feature = "sev_snp")]
///
/// Error initializing SEV-SNP on the VM
///
#[error("Failed to initialize SEV-SNP: {0}")]
InitializeSevSnp(#[source] std::io::Error),
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
/// ///
/// Error initializing TDX on the VM /// Error initializing TDX on the VM
@@ -213,6 +222,15 @@ pub enum HypervisorVmError {
/// ///
#[error("Failed to create Vgic: {0}")] #[error("Failed to create Vgic: {0}")]
CreateVgic(#[source] anyhow::Error), CreateVgic(#[source] anyhow::Error),
///
/// Import isolated pages error
///
#[error("Failed to import isolated pages: {0}")]
ImportIsolatedPages(#[source] anyhow::Error),
/// Failed to complete isolated import
///
#[error("Failed to complete isolated import: {0}")]
CompleteIsolatedImport(#[source] anyhow::Error),
} }
/// ///
/// Result type for returning from a function /// Result type for returning from a function
@@ -324,6 +342,11 @@ pub trait Vm: Send + Sync + Any {
fn stop_dirty_log(&self) -> Result<()>; fn stop_dirty_log(&self) -> Result<()>;
/// Get dirty pages bitmap /// Get dirty pages bitmap
fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>; fn get_dirty_log(&self, slot: u32, base_gpa: u64, memory_size: u64) -> Result<Vec<u64>>;
#[cfg(feature = "sev_snp")]
/// Initialize SEV-SNP on this VM
fn sev_snp_init(&self) -> Result<()> {
unimplemented!()
}
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
/// Initialize TDX on this VM /// Initialize TDX on this VM
fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> { fn tdx_init(&self, _cpuid: &[CpuIdEntry], _max_vcpus: u32) -> Result<()> {
@@ -347,6 +370,26 @@ pub trait Vm: Send + Sync + Any {
} }
/// Downcast to the underlying hypervisor VM type /// Downcast to the underlying hypervisor VM type
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
/// Import the isolated pages
#[cfg(feature = "sev_snp")]
fn import_isolated_pages(
&self,
_page_type: u32,
_page_size: u32,
_pages: &[u64],
) -> Result<()> {
unimplemented!()
}
/// Complete the isolated import
#[cfg(feature = "sev_snp")]
fn complete_isolated_import(
&self,
_snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
_host_data: &[u8],
_id_block_enabled: u8,
) -> Result<()> {
unimplemented!()
}
} }
pub trait VmOps: Send + Sync { pub trait VmOps: Send + Sync {

View File

@@ -8,7 +8,7 @@ edition = "2021"
epoll = "4.3.3" epoll = "4.3.3"
getrandom = "0.2.10" getrandom = "0.2.10"
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
net_gen = { path = "../net_gen" } net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" } rate_limiter = { path = "../rate_limiter" }
serde = "1.0.168" serde = "1.0.168"
@@ -16,8 +16,8 @@ thiserror = "1.0.40"
versionize = "0.1.10" versionize = "0.1.10"
versionize_derive = "0.1.4" versionize_derive = "0.1.4"
virtio-bindings = "0.2.0" virtio-bindings = "0.2.0"
virtio-queue = "0.9.0" virtio-queue = "0.10.0"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] } vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" } vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"

View File

@@ -72,6 +72,10 @@ pub fn open_tap(
let mut taps: Vec<Tap> = Vec::new(); let mut taps: Vec<Tap> = Vec::new();
let mut ifname: String = String::new(); let mut ifname: String = String::new();
let vnet_hdr_size = vnet_hdr_len() as i32; let vnet_hdr_size = vnet_hdr_len() as i32;
// Check if the given interface exists before we create it.
let tap_existed = if_name.map_or(false, |n| {
Path::new(&format!("/sys/class/net/{n}")).exists()
});
// In case the tap interface already exists, check if the number of // In case the tap interface already exists, check if the number of
// queues is appropriate. The tap might not support multiqueue while // queues is appropriate. The tap might not support multiqueue while
@@ -87,11 +91,19 @@ pub fn open_tap(
Some(name) => Tap::open_named(name, num_rx_q, flags).map_err(Error::TapOpen)?, Some(name) => Tap::open_named(name, num_rx_q, flags).map_err(Error::TapOpen)?,
None => Tap::new(num_rx_q).map_err(Error::TapOpen)?, None => Tap::new(num_rx_q).map_err(Error::TapOpen)?,
}; };
if let Some(ip) = ip_addr { // Don't overwrite ip configuration of existing interfaces:
tap.set_ip_addr(ip).map_err(Error::TapSetIp)?; if !tap_existed {
} if let Some(ip) = ip_addr {
if let Some(mask) = netmask { tap.set_ip_addr(ip).map_err(Error::TapSetIp)?;
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?; }
if let Some(mask) = netmask {
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
}
} else {
warn!(
"Tap {} already exists. IP configuration will not be overwritten.",
if_name.unwrap_or_default()
);
} }
if let Some(mac) = host_mac { if let Some(mac) = host_mac {
tap.set_mac_addr(*mac).map_err(Error::TapSetMac)? tap.set_mac_addr(*mac).map_err(Error::TapSetMac)?

View File

@@ -19,12 +19,12 @@ vfio_user = { git = "https://github.com/rust-vmm/vfio-user", branch = "main" }
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
serde = { version = "1.0.168", features = ["derive"] } serde = { version = "1.0.168", features = ["derive"] }
thiserror = "1.0.40" thiserror = "1.0.40"
versionize = "0.1.10" versionize = "0.1.10"
versionize_derive = "0.1.4" versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" } vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" } vm-device = { path = "../vm-device" }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] } vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" } vm-migration = { path = "../vm-migration" }

View File

@@ -58,7 +58,8 @@ pub trait PciDevice: BusDevice {
fn allocate_bars( fn allocate_bars(
&mut self, &mut self,
_allocator: &Arc<Mutex<SystemAllocator>>, _allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator, _mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
_resources: Option<Vec<Resource>>, _resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>> { ) -> Result<Vec<PciBarConfiguration>> {
Ok(Vec::new()) Ok(Vec::new())
@@ -68,7 +69,8 @@ pub trait PciDevice: BusDevice {
fn free_bars( fn free_bars(
&mut self, &mut self,
_allocator: &mut SystemAllocator, _allocator: &mut SystemAllocator,
_mmio_allocator: &mut AddressAllocator, _mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> Result<()> { ) -> Result<()> {
Ok(()) Ok(())
} }

View File

@@ -529,10 +529,13 @@ impl VfioCommon {
} }
} }
// The `allocator` argument is unused on `aarch64`
#[allow(unused_variables)]
pub(crate) fn allocate_bars( pub(crate) fn allocate_bars(
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new(); let mut bars = Vec::new();
@@ -681,21 +684,15 @@ impl VfioCommon {
} }
PciBarRegionType::Memory32BitRegion => { PciBarRegionType::Memory32BitRegion => {
// BAR allocation must be naturally aligned // BAR allocation must be naturally aligned
allocator mmio32_allocator
.lock() .allocate(restored_bar_addr, region_size, Some(region_size))
.unwrap()
.allocate_mmio_hole_addresses(
restored_bar_addr,
region_size,
Some(region_size),
)
.ok_or(PciDeviceError::IoAllocationFailed(region_size))? .ok_or(PciDeviceError::IoAllocationFailed(region_size))?
} }
PciBarRegionType::Memory64BitRegion => { PciBarRegionType::Memory64BitRegion => {
// We need do some fixup to keep MMIO RW region and msix cap region page size // We need do some fixup to keep MMIO RW region and msix cap region page size
// aligned. // aligned.
region_size = self.fixup_msix_region(bar_id, region_size); region_size = self.fixup_msix_region(bar_id, region_size);
mmio_allocator mmio64_allocator
.allocate( .allocate(
restored_bar_addr, restored_bar_addr,
region_size, region_size,
@@ -742,10 +739,13 @@ impl VfioCommon {
Ok(bars) Ok(bars)
} }
// The `allocator` argument is unused on `aarch64`
#[allow(unused_variables)]
pub(crate) fn free_bars( pub(crate) fn free_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> { ) -> Result<(), PciDeviceError> {
for region in self.mmio_regions.iter() { for region in self.mmio_regions.iter() {
match region.type_ { match region.type_ {
@@ -756,10 +756,10 @@ impl VfioCommon {
error!("I/O region is not supported"); error!("I/O region is not supported");
} }
PciBarRegionType::Memory32BitRegion => { PciBarRegionType::Memory32BitRegion => {
allocator.free_mmio_hole_addresses(region.start, region.length); mmio32_allocator.free(region.start, region.length);
} }
PciBarRegionType::Memory64BitRegion => { PciBarRegionType::Memory64BitRegion => {
mmio_allocator.free(region.start, region.length); mmio64_allocator.free(region.start, region.length);
} }
} }
} }
@@ -1694,19 +1694,22 @@ impl PciDevice for VfioPciDevice {
fn allocate_bars( fn allocate_bars(
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common self.common
.allocate_bars(allocator, mmio_allocator, resources) .allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
} }
fn free_bars( fn free_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> { ) -> Result<(), PciDeviceError> {
self.common.free_bars(allocator, mmio_allocator) self.common
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
} }
fn write_config_register( fn write_config_register(

View File

@@ -397,19 +397,22 @@ impl PciDevice for VfioUserPciDevice {
fn allocate_bars( fn allocate_bars(
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common self.common
.allocate_bars(allocator, mmio_allocator, resources) .allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
} }
fn free_bars( fn free_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> { ) -> Result<(), PciDeviceError> {
self.common.free_bars(allocator, mmio_allocator) self.common
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
} }
fn as_any(&mut self) -> &mut dyn Any { fn as_any(&mut self) -> &mut dyn Any {

View File

@@ -6,7 +6,7 @@ edition = "2021"
build = "../build.rs" build = "../build.rs"
[dependencies] [dependencies]
argh = "0.1.9" clap = { version = "4.4.7", features = ["wrap_help"] }
dirs = "5.0.0" dirs = "5.0.0"
serde = { version = "1.0.168", features = ["rc", "derive"] } serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107" serde_json = "1.0.107"

View File

@@ -8,11 +8,11 @@ extern crate test_infra;
mod performance_tests; mod performance_tests;
use argh::FromArgs; use clap::{Arg, ArgAction, Command as ClapCommand};
use performance_tests::*; use performance_tests::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
fmt, env, fmt,
process::Command, process::Command,
sync::{mpsc::channel, Arc}, sync::{mpsc::channel, Arc},
thread, thread,
@@ -639,41 +639,45 @@ fn date() -> String {
String::from_utf8_lossy(&output.stdout).trim().to_string() String::from_utf8_lossy(&output.stdout).trim().to_string()
} }
#[derive(FromArgs)]
/// Generate the performance metrics data for Cloud Hypervisor
struct Options {
#[argh(switch, long = "list-tests")]
/// print the list of available metrics tests
list_tests: bool,
#[argh(option, long = "test-filter")]
/// filter metrics tests to run based on provided keywords
keywords: Vec<String>,
#[argh(option, long = "report-file")]
/// report file. Stderr is used if not specified
report_file: Option<String>,
#[argh(option, long = "iterations")]
/// override number of test iterations
iterations: Option<u32>,
#[argh(option, long = "timeout")]
/// override test timeout, Ex. --timeout 5
timeout: Option<u32>,
#[argh(switch, short = 'V', long = "version")]
/// print version information
version: bool,
}
fn main() { fn main() {
let opts: Options = argh::from_env(); let cmd_arguments = ClapCommand::new("performance-metrics")
.version(env!("CARGO_PKG_VERSION"))
if opts.version { .author(env!("CARGO_PKG_AUTHORS"))
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION")); .about("Generate the performance metrics data for Cloud Hypervisor")
return; .arg(
} Arg::new("test-filter")
.long("test-filter")
.help("Filter metrics tests to run based on provided keywords")
.num_args(1)
.required(false),
)
.arg(
Arg::new("list-tests")
.long("list-tests")
.help("Print the list of available metrics tests")
.num_args(0)
.action(ArgAction::SetTrue)
.required(false),
)
.arg(
Arg::new("report-file")
.long("report-file")
.help("Report file. Standard error is used if not specified")
.num_args(1),
)
.arg(
Arg::new("iterations")
.long("iterations")
.help("Override number of test iterations")
.num_args(1),
)
.arg(
Arg::new("timeout")
.long("timeout")
.help("Override test timeout, Ex. --timeout 5")
.num_args(1),
)
.get_matches();
// It seems that the tool (ethr) used for testing the virtio-net latency // It seems that the tool (ethr) used for testing the virtio-net latency
// is not stable on AArch64, and therefore the latency test is currently // is not stable on AArch64, and therefore the latency test is currently
@@ -683,7 +687,7 @@ fn main() {
.filter(|t| !(cfg!(target_arch = "aarch64") && t.name == "virtio_net_latency_us")) .filter(|t| !(cfg!(target_arch = "aarch64") && t.name == "virtio_net_latency_us"))
.collect(); .collect();
if opts.list_tests { if cmd_arguments.get_flag("list-tests") {
for test in test_list.iter() { for test in test_list.iter() {
println!("\"{}\" ({})", test.name, test.control); println!("\"{}\" ({})", test.name, test.control);
} }
@@ -691,7 +695,10 @@ fn main() {
return; return;
} }
let test_filter = opts.keywords.iter().collect::<Vec<&String>>(); let test_filter = match cmd_arguments.get_many::<String>("test-filter") {
Some(s) => s.collect(),
None => Vec::new(),
};
// Run performance tests sequentially and report results (in both readable/json format) // Run performance tests sequentially and report results (in both readable/json format)
let mut metrics_report: MetricsReport = Default::default(); let mut metrics_report: MetricsReport = Default::default();
@@ -699,8 +706,16 @@ fn main() {
init_tests(); init_tests();
let overrides = Arc::new(PerformanceTestOverrides { let overrides = Arc::new(PerformanceTestOverrides {
test_iterations: opts.iterations, test_iterations: cmd_arguments
test_timeout: opts.timeout, .get_one::<String>("iterations")
.map(|s| s.parse())
.transpose()
.unwrap_or_default(),
test_timeout: cmd_arguments
.get_one::<String>("timeout")
.map(|s| s.parse())
.transpose()
.unwrap_or_default(),
}); });
for test in test_list.iter() { for test in test_list.iter() {
@@ -719,18 +734,19 @@ fn main() {
cleanup_tests(); cleanup_tests();
let mut report_file: Box<dyn std::io::Write + Send> = if let Some(ref file) = opts.report_file { let mut report_file: Box<dyn std::io::Write + Send> =
Box::new( if let Some(file) = cmd_arguments.get_one::<String>("report-file") {
std::fs::File::create(std::path::Path::new(file)) Box::new(
.map_err(|e| { std::fs::File::create(std::path::Path::new(file))
eprintln!("Error opening report file: {file}: {e}"); .map_err(|e| {
std::process::exit(1); eprintln!("Error opening report file: {file}: {e}");
}) std::process::exit(1);
.unwrap(), })
) .unwrap(),
} else { )
Box::new(std::io::stdout()) } else {
}; Box::new(std::io::stdout())
};
report_file report_file
.write_all( .write_all(

View File

@@ -358,13 +358,11 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
guest.disk_config.disk(DiskType::OperatingSystem).unwrap() guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
) )
.as_str(), .as_str(),
"--disk",
format!( format!(
"path={}", "path={}",
guest.disk_config.disk(DiskType::CloudInit).unwrap() guest.disk_config.disk(DiskType::CloudInit).unwrap()
) )
.as_str(), .as_str(),
"--disk",
format!("path={BLK_IO_TEST_IMG}").as_str(), format!("path={BLK_IO_TEST_IMG}").as_str(),
]) ])
.default_net() .default_net()

View File

@@ -5,5 +5,5 @@ edition = "2021"
[dependencies] [dependencies]
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"

View File

@@ -1,42 +1,60 @@
- [v37.0](#v370)
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
- [Improved VFIO Device Passthrough with Multiple PCI Segments](#improved-vfio-device-passthrough-with-multiple-pci-segments)
- [Configurable Named TAP Devices](#configurable-named-tap-devices)
- [TTY Output from Both Serial Device and Virtio Console](#tty-output-from-both-serial-device-and-virtio-console)
- [Faster VM Restoration from Snapshots](#faster-vm-restoration-from-snapshots)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [v36.0](#v360)
- [Command Line Changes](#command-line-changes)
- [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli)
- [NUMA Support for PCI segments](#numa-support-for-pci-segments)
- [CPU Topology Support on AMD Platforms](#cpu-topology-support-on-amd-platforms)
- [Unix Socket Backend for Serial Port](#unix-socket-backend-for-serial-port)
- [AIO Backend for Block Devices](#aio-backend-for-block-devices)
- [Documentation Improvements](#documentation-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [v35.0](#v350) - [v35.0](#v350)
- [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63) - [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63)
- [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block) - [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block)
- [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state) - [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state)
- [Notable Bug Fixes](#notable-bug-fixes) - [Notable Bug Fixes](#notable-bug-fixes-2)
- [Contributors](#contributors) - [Contributors](#contributors-2)
- [v34.0](#v340) - [v34.0](#v340)
- [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support) - [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support)
- [Improvements to VM Core Dump](#improvements-to-vm-core-dump) - [Improvements to VM Core Dump](#improvements-to-vm-core-dump)
- [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files) - [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files)
- [Minimum Host Kernel Bump](#minimum-host-kernel-bump) - [Minimum Host Kernel Bump](#minimum-host-kernel-bump)
- [Notable Bug Fixes](#notable-bug-fixes-1) - [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-1) - [Contributors](#contributors-3)
- [v33.0](#v330) - [v33.0](#v330)
- [D-Bus based API](#d-bus-based-api) - [D-Bus based API](#d-bus-based-api)
- [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64) - [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-2) - [Notable Bug Fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-2) - [Contributors](#contributors-4)
- [v32.0](#v320) - [v32.0](#v320)
- [Increased PCI Segment Limit](#increased-pci-segment-limit) - [Increased PCI Segment Limit](#increased-pci-segment-limit)
- [API Changes](#api-changes) - [API Changes](#api-changes)
- [Notable Bug Fixes](#notable-bug-fixes-3) - [Notable Bug Fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-3) - [Contributors](#contributors-5)
- [v31.1](#v311) - [v31.1](#v311)
- [v31.0](#v310) - [v31.0](#v310)
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables) - [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
- [Update Reference Kernel to 6.2](#update-reference-kernel-to-62) - [Update Reference Kernel to 6.2](#update-reference-kernel-to-62)
- [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler) - [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler)
- [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile) - [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile)
- [Documentation Improvements](#documentation-improvements) - [Documentation Improvements](#documentation-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-4) - [Notable Bug Fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-4) - [Contributors](#contributors-6)
- [v30.0](#v300) - [v30.0](#v300)
- [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size) - [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size)
- [Basic vfio-user Server Support](#basic-vfio-user-server-support) - [Basic vfio-user Server Support](#basic-vfio-user-server-support)
- [Heap Profiling Support](#heap-profiling-support) - [Heap Profiling Support](#heap-profiling-support)
- [Documentation Improvements](#documentation-improvements-1) - [Documentation Improvements](#documentation-improvements-2)
- [Notable Bug Fixes](#notable-bug-fixes-5) - [Notable Bug Fixes](#notable-bug-fixes-7)
- [Contributors](#contributors-5) - [Contributors](#contributors-7)
- [v28.2](#v282) - [v28.2](#v282)
- [v29.0](#v290) - [v29.0](#v290)
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm) - [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
@@ -46,20 +64,20 @@
- [`AArch64` Documentation Integration](#aarch64-documentation-integration) - [`AArch64` Documentation Integration](#aarch64-documentation-integration)
- [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement) - [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement)
- [TCP Offload Control](#tcp-offload-control) - [TCP Offload Control](#tcp-offload-control)
- [Notable Bug Fixes](#notable-bug-fixes-6) - [Notable Bug Fixes](#notable-bug-fixes-8)
- [Removals](#removals) - [Removals](#removals)
- [Deprecations](#deprecations) - [Deprecations](#deprecations)
- [Contributors](#contributors-6) - [Contributors](#contributors-8)
- [v28.1](#v281) - [v28.1](#v281)
- [v28.0](#v280) - [v28.0](#v280)
- [Community Engagement (Reminder)](#community-engagement-reminder) - [Community Engagement (Reminder)](#community-engagement-reminder)
- [Long Term Support (LTS) Release](#long-term-support-lts-release) - [Long Term Support (LTS) Release](#long-term-support-lts-release-1)
- [Virtualised TPM Support](#virtualised-tpm-support) - [Virtualised TPM Support](#virtualised-tpm-support)
- [Transparent Huge Page Support](#transparent-huge-page-support) - [Transparent Huge Page Support](#transparent-huge-page-support)
- [README Quick Start Improved](#readme-quick-start-improved) - [README Quick Start Improved](#readme-quick-start-improved)
- [Notable Bug Fixes](#notable-bug-fixes-7) - [Notable Bug Fixes](#notable-bug-fixes-9)
- [Removals](#removals-1) - [Removals](#removals-1)
- [Contributors](#contributors-7) - [Contributors](#contributors-9)
- [v27.0](#v270) - [v27.0](#v270)
- [Community Engagement](#community-engagement) - [Community Engagement](#community-engagement)
- [Prebuilt Packages](#prebuilt-packages) - [Prebuilt Packages](#prebuilt-packages)
@@ -68,41 +86,41 @@
- [Simplified Build Feature Flags](#simplified-build-feature-flags) - [Simplified Build Feature Flags](#simplified-build-feature-flags)
- [Asynchronous Kernel Loading](#asynchronous-kernel-loading) - [Asynchronous Kernel Loading](#asynchronous-kernel-loading)
- [GDB Support for AArch64](#gdb-support-for-aarch64) - [GDB Support for AArch64](#gdb-support-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-8) - [Notable Bug Fixes](#notable-bug-fixes-10)
- [Deprecations](#deprecations-1) - [Deprecations](#deprecations-1)
- [Contributors](#contributors-8) - [Contributors](#contributors-10)
- [v26.0](#v260) - [v26.0](#v260)
- [SMBIOS Improvements via `--platform`](#smbios-improvements-via---platform) - [SMBIOS Improvements via `--platform`](#smbios-improvements-via---platform)
- [Unified Binary MSHV and KVM Support](#unified-binary-mshv-and-kvm-support) - [Unified Binary MSHV and KVM Support](#unified-binary-mshv-and-kvm-support)
- [Notable Bug Fixes](#notable-bug-fixes-9) - [Notable Bug Fixes](#notable-bug-fixes-11)
- [Deprecations](#deprecations-2) - [Deprecations](#deprecations-2)
- [Removals](#removals-2) - [Removals](#removals-2)
- [Contributors](#contributors-9) - [Contributors](#contributors-11)
- [v25.0](#v250) - [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements-1) - [`ch-remote` Improvements](#ch-remote-improvements-1)
- [VM "Coredump" Support](#vm-coredump-support) - [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes-10) - [Notable Bug Fixes](#notable-bug-fixes-12)
- [Removals](#removals-3) - [Removals](#removals-3)
- [Contributors](#contributors-10) - [Contributors](#contributors-12)
- [v24.0](#v240) - [v24.0](#v240)
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu) - [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness) - [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
- [Sparse Mmap support](#sparse-mmap-support) - [Sparse Mmap support](#sparse-mmap-support)
- [Expose Platform Serial Number](#expose-platform-serial-number) - [Expose Platform Serial Number](#expose-platform-serial-number)
- [Notable Bug Fixes](#notable-bug-fixes-11) - [Notable Bug Fixes](#notable-bug-fixes-13)
- [Notable Improvements](#notable-improvements) - [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations-3) - [Deprecations](#deprecations-3)
- [New on the Website](#new-on-the-website) - [New on the Website](#new-on-the-website)
- [Contributors](#contributors-11) - [Contributors](#contributors-13)
- [v23.1](#v231) - [v23.1](#v231)
- [v23.0](#v230) - [v23.0](#v230)
- [vDPA Support](#vdpa-support) - [vDPA Support](#vdpa-support)
- [Updated OS Support list](#updated-os-support-list) - [Updated OS Support list](#updated-os-support-list)
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements) - [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
- [`AMX` Support](#amx-support) - [`AMX` Support](#amx-support)
- [Notable Bug Fixes](#notable-bug-fixes-12) - [Notable Bug Fixes](#notable-bug-fixes-14)
- [Deprecations](#deprecations-4) - [Deprecations](#deprecations-4)
- [Contributors](#contributors-12) - [Contributors](#contributors-14)
- [v22.1](#v221) - [v22.1](#v221)
- [v22.0](#v220) - [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support) - [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -113,13 +131,13 @@
- [PMU Support for AArch64](#pmu-support-for-aarch64) - [PMU Support for AArch64](#pmu-support-for-aarch64)
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license) - [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd) - [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
- [Notable Bug Fixes](#notable-bug-fixes-13) - [Notable Bug Fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-13) - [Contributors](#contributors-15)
- [v21.0](#v210) - [v21.0](#v210)
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade) - [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515) - [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
- [Notable Bug fixes](#notable-bug-fixes-14) - [Notable Bug fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-14) - [Contributors](#contributors-16)
- [v20.2](#v202) - [v20.2](#v202)
- [v20.1](#v201) - [v20.1](#v201)
- [v20.0](#v200) - [v20.0](#v200)
@@ -128,8 +146,8 @@
- [Improved VFIO support](#improved-vfio-support) - [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code) - [Safer code](#safer-code)
- [Extended documentation](#extended-documentation) - [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-15) - [Notable bug fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-15) - [Contributors](#contributors-17)
- [v19.0](#v190) - [v19.0](#v190)
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console) - [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
- [PCI boot time optimisations](#pci-boot-time-optimisations) - [PCI boot time optimisations](#pci-boot-time-optimisations)
@@ -137,8 +155,8 @@
- [Live migration enhancements](#live-migration-enhancements) - [Live migration enhancements](#live-migration-enhancements)
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user) - [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu) - [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
- [Notable bug fixes](#notable-bug-fixes-16) - [Notable bug fixes](#notable-bug-fixes-18)
- [Contributors](#contributors-16) - [Contributors](#contributors-18)
- [v18.0](#v180) - [v18.0](#v180)
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support) - [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices) - [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
@@ -148,23 +166,23 @@
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor) - [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
- [AArch64 CPU topology support](#aarch64-cpu-topology-support) - [AArch64 CPU topology support](#aarch64-cpu-topology-support)
- [Power button support on AArch64](#power-button-support-on-aarch64) - [Power button support on AArch64](#power-button-support-on-aarch64)
- [Notable bug fixes](#notable-bug-fixes-17) - [Notable bug fixes](#notable-bug-fixes-19)
- [Contributors](#contributors-17) - [Contributors](#contributors-19)
- [v17.0](#v170) - [v17.0](#v170)
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi) - [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend) - [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices) - [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
- [Improved SGX support](#improved-sgx-support) - [Improved SGX support](#improved-sgx-support)
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices) - [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
- [Notable bug fixes](#notable-bug-fixes-18) - [Notable bug fixes](#notable-bug-fixes-20)
- [Contributors](#contributors-18) - [Contributors](#contributors-20)
- [v16.0](#v160) - [v16.0](#v160)
- [Improved live migration support](#improved-live-migration-support) - [Improved live migration support](#improved-live-migration-support)
- [Improved `vhost-user` support](#improved-vhost-user-support) - [Improved `vhost-user` support](#improved-vhost-user-support)
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support) - [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
- [Notable bug fixes](#notable-bug-fixes-19) - [Notable bug fixes](#notable-bug-fixes-21)
- [Removed functionality](#removed-functionality) - [Removed functionality](#removed-functionality)
- [Contributors](#contributors-19) - [Contributors](#contributors-21)
- [v15.0](#v150) - [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees) - [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting) - [Network device rate limiting](#network-device-rate-limiting)
@@ -172,7 +190,7 @@
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter) - [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes) - [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-5) - [Deprecations](#deprecations-5)
- [Contributors](#contributors-20) - [Contributors](#contributors-22)
- [v0.14.1](#v0141) - [v0.14.1](#v0141)
- [v0.14.0](#v0140) - [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring) - [Structured event monitoring](#structured-event-monitoring)
@@ -182,7 +200,7 @@
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console) - [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
- [Block device rate limiting](#block-device-rate-limiting) - [Block device rate limiting](#block-device-rate-limiting)
- [Deprecations](#deprecations-6) - [Deprecations](#deprecations-6)
- [Contributors](#contributors-21) - [Contributors](#contributors-23)
- [v0.13.0](#v0130) - [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support) - [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support) - [Improved huge page support](#improved-huge-page-support)
@@ -190,13 +208,13 @@
- [VHD disk image support](#vhd-disk-image-support) - [VHD disk image support](#vhd-disk-image-support)
- [Improved Virtio device threading](#improved-virtio-device-threading) - [Improved Virtio device threading](#improved-virtio-device-threading)
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button) - [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
- [Contributors](#contributors-22) - [Contributors](#contributors-24)
- [v0.12.0](#v0120) - [v0.12.0](#v0120)
- [ARM64 enhancements](#arm64-enhancements) - [ARM64 enhancements](#arm64-enhancements)
- [Removal of `vhost-user-net` and `vhost-user-block` self spawning](#removal-of-vhost-user-net-and-vhost-user-block-self-spawning) - [Removal of `vhost-user-net` and `vhost-user-block` self spawning](#removal-of-vhost-user-net-and-vhost-user-block-self-spawning)
- [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend) - [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend)
- [Enhanced "info" API](#enhanced-info-api) - [Enhanced "info" API](#enhanced-info-api)
- [Contributors](#contributors-23) - [Contributors](#contributors-25)
- [v0.11.0](#v0110) - [v0.11.0](#v0110)
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block) - [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
- [Windows Guest Support](#windows-guest-support) - [Windows Guest Support](#windows-guest-support)
@@ -208,15 +226,15 @@
- [Default Log Level Changed](#default-log-level-changed) - [Default Log Level Changed](#default-log-level-changed)
- [New `--balloon` Parameter Added](#new---balloon-parameter-added) - [New `--balloon` Parameter Added](#new---balloon-parameter-added)
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support) - [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
- [Notable Bug Fixes](#notable-bug-fixes-20) - [Notable Bug Fixes](#notable-bug-fixes-22)
- [Contributors](#contributors-24) - [Contributors](#contributors-26)
- [v0.10.0](#v0100) - [v0.10.0](#v0100)
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors) - [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
- [Memory Zones](#memory-zones) - [Memory Zones](#memory-zones)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements) - [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control) - [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
- [Notable Bug Fixes](#notable-bug-fixes-21) - [Notable Bug Fixes](#notable-bug-fixes-23)
- [Contributors](#contributors-25) - [Contributors](#contributors-27)
- [v0.9.0](#v090) - [v0.9.0](#v090)
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support) - [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
- [Block and Network Device Statistics](#block-and-network-device-statistics) - [Block and Network Device Statistics](#block-and-network-device-statistics)
@@ -229,17 +247,17 @@
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support) - [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
- [Intel SGX Support](#intel-sgx-support) - [Intel SGX Support](#intel-sgx-support)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1) - [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-22) - [Notable Bug Fixes](#notable-bug-fixes-24)
- [Contributors](#contributors-26) - [Contributors](#contributors-28)
- [v0.8.0](#v080) - [v0.8.0](#v080)
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support) - [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
- [Experimental ARM64 Support](#experimental-arm64-support) - [Experimental ARM64 Support](#experimental-arm64-support)
- [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests) - [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests)
- [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices) - [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices)
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements) - [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-23) - [Notable Bug Fixes](#notable-bug-fixes-25)
- [Command Line and API Changes](#command-line-and-api-changes) - [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-27) - [Contributors](#contributors-29)
- [v0.7.0](#v070) - [v0.7.0](#v070)
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug) - [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
- [Alternative `libc` Support](#alternative-libc-support) - [Alternative `libc` Support](#alternative-libc-support)
@@ -249,14 +267,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing) - [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support) - [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1) - [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-28) - [Contributors](#contributors-30)
- [v0.6.0](#v060) - [v0.6.0](#v060)
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug) - [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
- [Shared Filesystem Improvements](#shared-filesystem-improvements) - [Shared Filesystem Improvements](#shared-filesystem-improvements)
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading) - [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
- [Command Line Interface](#command-line-interface) - [Command Line Interface](#command-line-interface)
- [PVH Boot](#pvh-boot) - [PVH Boot](#pvh-boot)
- [Contributors](#contributors-29) - [Contributors](#contributors-31)
- [v0.5.1](#v051) - [v0.5.1](#v051)
- [v0.5.0](#v050) - [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing) - [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -264,7 +282,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework) - [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools) - [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration) - [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-30) - [Contributors](#contributors-32)
- [v0.4.0](#v040) - [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition) - [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation) - [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -273,7 +291,7 @@
- [Userspace IOAPIC by default](#userspace-ioapic-by-default) - [Userspace IOAPIC by default](#userspace-ioapic-by-default)
- [PCI BAR reprogramming](#pci-bar-reprogramming) - [PCI BAR reprogramming](#pci-bar-reprogramming)
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization) - [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
- [Contributors](#contributors-31) - [Contributors](#contributors-33)
- [v0.3.0](#v030) - [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading) - [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend) - [Network device backend](#network-device-backend)
@@ -300,6 +318,143 @@
- [Unit testing](#unit-testing) - [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization) - [Integration tests parallelization](#integration-tests-parallelization)
# v37.0
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v37.0. The following user visible changes have been made:
### Long Term Support (LTS) Release
This release is a LTS release. Point releases for bug fixes will be made
for the next 18 months; live migration and live upgrade will be
supported between the point releases of the LTS.
### Multiple PCI segments Support for 32-bit VFIO devices
Now VFIO devices with 32-bit memory BARs can be attached to non-zero PCI
segments on the guest, allowing users to have more 32-bit devices and
assign such devices to appropriate NUMA nodes for better performance.
### Configurable Named TAP Devices
Named TAP devices now accepts IP configuration from users, such as IP
and MAC address, as long as the named TAP device is created by Cloud
Hypervisor (e.g. not existing TAP devices).
### TTY Output from Both Serial Device and Virtio Console
Now legacy serial device and virtio console can be set as TTY mode as
the same time. This allows users to capture early boot logs with the
legacy serial device without losing performance benefits of using
virtio-console, when appropriate kernel configuration is used (such as
using kernel command-line `console=hvc0 earlyprintk=ttyS0` on x86).
### Faster VM Restoration from Snapshots
The speed of VM restoration from snapshots is improved with a better
implementation of deserializing JSON files.
### Notable Bug Fixes
* Fix aio backend behavior for block devices when writeback cache
disabled (#5930)
* Fix PvPanic device PCI BAR alignment (#5956)
* Bug fix to OpenAPI specification file (#5967)
* Error out early for live migration when TDX is enabled (#6025)
### Contributors
Many thanks to everyone who has contributed to our release:
* Bo Chen <chen.bo@intel.com>
* Jinank Jain <jinankjain@microsoft.com>
* Markus Sütter <markus.suetter@secunet.com>
* Michael Zhao <michael.zhao@arm.com>
* Muminul Islam <muislam@microsoft.com>
* Rob Bradford <rbradford@rivosinc.com>
* Rui Chang <rui.chang@arm.com>
* Ruslan Mstoi <ruslan.mstoi@intel.com>
* Thomas Barrett <tbarrett@crusoeenergy.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <foxywang@tencent.com>
* Yong He <alexyonghe@tencent.com>
# v36.0
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v36.0. The following user visible changes have been made:
### Command Line Changes
We switched back to use the `clap` crate to create our command line,
since the `argh` crate is barely maintained. There were several syntax
changes:
* All `--option value` commands now are `--option=value`.
* The `--disk DISK1 --disk DISK2` command now is `--disk DISK1 DISK2`.
* The `-v -v -v`command now is `-vvv`.
Note: the released binary size increased around 0.3M due to this change.
### Enabled Features Reported via API Endpoint and CLI
Now the enabled (Cargo) features of the running Cloud Hypervisor
instance can be queried via API endpoint (`/vmm.ping`) and CLI
(`--version -v`).
### NUMA Support for PCI segments
The `--numa` command is augmented with a new option `pci_segment=`, so
that users can define the relationship between PCI segments and NUMA
nodes. Examples can be found from the [memory documentation](docs/memory.md)
### CPU Topology Support on AMD Platforms
Now the CPU topology on x86_64 platforms supports multiple vendors.
### Unix Socket Backend for Serial Port
The `--serial` command is augmented with a new option `socket=`, allowing
users to access the serial port using a Unix socket.
### AIO Backend for Block Devices
An AIO backend is added for `virtio-block` devices to improve block
device performance when the `io_uring` feature is not supported by the
host Operating System.
### Documentation Improvements
* New [documentation](docs/coverage.md) for collecting coverage data
* Various typo fixes
### Notable Bug Fixes
* Fix a deadlock when TDX is enabled (#5845)
* Only advertise AMX feature bits to guest when the AMX cpu feature is
enabled (#5834)
* Correct default value for vCPU topology on AArch64 (#5893)
### Contributors
Many thanks to everyone who has contributed to our release:
* Anatol Belski <anbelski@linux.microsoft.com>
* Bo Chen <chen.bo@intel.com>
* Dario Nieuwenhuis <dirbaio@dirbaio.net>
* Jianyong Wu <jianyong.wu@arm.com>
* Jinank Jain <jinankjain@microsoft.com>
* Muminul Islam <muislam@microsoft.com>
* Praveen K Paladugu <prapal@linux.microsoft.com>
* Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
* Rob Bradford <rbradford@rivosinc.com>
* Thomas Barrett <tbarrett@crusoeenergy.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <foxywang@tencent.com>
* dom.song <dom.song@amperecomputing.com>
# v35.0 # v35.0
This release has been tracked in our [roadmap This release has been tracked in our [roadmap

View File

@@ -6,7 +6,7 @@
FROM ubuntu:20.04 as dev FROM ubuntu:20.04 as dev
ARG TARGETARCH ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.67.1" ARG RUST_TOOLCHAIN="1.70.0"
ARG CLH_SRC_DIR="/cloud-hypervisor" ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build" ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry" ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"
@@ -130,17 +130,18 @@ RUN echo 'source $CARGO_HOME/env' >> "$HOME"/.bashrc \
RUN if [ "$TARGETARCH" = "amd64" ]; then \ RUN if [ "$TARGETARCH" = "amd64" ]; then \
git clone https://github.com/spdk/spdk \ git clone https://github.com/spdk/spdk \
&& cd spdk \ && cd spdk \
&& git checkout 6301f8915de32baed10dba1eebed556a6749211a \ && git checkout ef8bcce58f3f02b79c0619a297e4f17e81e62b24 \
&& git submodule update --init \ && git submodule update --init \
&& apt-get update \ && apt-get update \
&& ./scripts/pkgdep.sh \ && ./scripts/pkgdep.sh \
&& apt-get clean \ && apt-get clean \
&& ./configure --with-vfio-user \ && ./configure --with-vfio-user \
&& make -j $(nproc) TARGET_ARCHITECTURE=skylake \ && make -j $(nproc) TARGET_ARCHITECTURE=skylake \
&& rm -rf /usr/local/bin/spdk-nvme \
&& mkdir /usr/local/bin/spdk-nvme \ && mkdir /usr/local/bin/spdk-nvme \
&& cp ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \ && cp -f ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \
&& cp ./scripts/rpc.py /usr/local/bin/spdk-nvme \ && cp -f ./scripts/rpc.py /usr/local/bin/spdk-nvme \
&& cp -r ./scripts/rpc /usr/local/bin/spdk-nvme \ && cp -rf ./python /usr/local/bin \
&& cd .. && rm -rf spdk; fi && cd .. && rm -rf spdk; fi
# install swtpm only for x86_64 arch # install swtpm only for x86_64 arch

View File

@@ -639,7 +639,7 @@ CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y CONFIG_KVM=y
# CONFIG_KVM_WERROR is not set # CONFIG_KVM_WERROR is not set
CONFIG_KVM_INTEL=y CONFIG_KVM_INTEL=y
# CONFIG_KVM_AMD is not set CONFIG_KVM_AMD=y
CONFIG_KVM_SMM=y CONFIG_KVM_SMM=y
# CONFIG_KVM_XEN is not set # CONFIG_KVM_XEN is not set
CONFIG_AS_AVX512=y CONFIG_AS_AVX512=y

View File

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

View File

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

91
scripts/gitlint/rules.py Normal file
View File

@@ -0,0 +1,91 @@
from gitlint.rules import LineRule, RuleViolation, CommitMessageTitle
import re
class TitleStartsWithComponent(LineRule):
"""A rule to enforce valid commit message title
Valid title format:
component1[, component2, componentN]: submodule: summary
Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated
"""
# A rule MUST have a human friendly name
name = "title-has-valid-component"
# A rule MUST have a *unique* id.
# We recommend starting with UL (for User-defined Line-rule)
id = "UL1"
# A line-rule MUST have a target (not required for CommitRules).
target = CommitMessageTitle
def validate(self, line, _commit):
valid_components = (
'api_client',
'arch',
'block',
'build',
'ch-remote',
'ci',
'devices',
'docs',
'event_monitor',
'fuzz',
'github',
'gitignore',
'gitlint',
'hypervisor',
'Jenkinsfile',
'misc',
'net_gen',
'net_util',
'option_parser',
'pci',
'performance-metrics',
'rate_limiter',
'README',
'resources',
'scripts',
'serial_buffer',
'test_data',
'test_infra',
'tests',
'tpm',
'tracer',
'vhost_user_block',
'vhost_user_net',
'virtio-devices',
'vm-allocator',
'vm-device',
'vmm',
'vm-migration',
'vm-virtio')
ptrn_title = re.compile(r'^(.+?):\s(.+)$')
match = ptrn_title.match(line)
if not match:
self.log.debug("Invalid commit title {}", line)
return [RuleViolation(self.id, "Commit title does not comply with "
"rule: 'component: change summary'")]
components = match.group(1)
summary = match.group(2)
self.log.debug(f"\nComponents: {components}\nSummary: {summary}")
ptrn_components = re.compile(r',\s')
components_list = re.split(ptrn_components, components)
self.log.debug("components list: %s" % components_list)
for component in components_list:
if component not in valid_components:
return [RuleViolation(self.id,
f"Invalid component: {component}, "
"\nValid components are: {}".format(
" ".join(valid_components)))]

View File

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

View File

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

View File

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

View File

@@ -14,12 +14,7 @@ fi
WORKLOADS_DIR="$HOME/workloads" WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR" mkdir -p "$WORKLOADS_DIR"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]') download_hypervisor_fw
FW="$WORKLOADS_DIR/hypervisor-fw"
pushd $WORKLOADS_DIR
rm -f $FW
time wget --quiet $FW_URL || exit 1
popd
JAMMY_OS_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.qcow2" JAMMY_OS_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.qcow2"
JAMMY_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_IMAGE_NAME" JAMMY_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_IMAGE_NAME"
@@ -38,11 +33,8 @@ if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
popd popd
fi fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS="" CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/" CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi fi

View File

@@ -1,100 +1,30 @@
#!/bin/bash #!/bin/bash
set -x set -x
# This set of vfio tests require to be ran on a specific machine with
# specific hardware (e.g. the "vfio" bera-metal worker equipped with a
# Nvidia Tesla T4 card). So the provisioning of the running machine is
# out of the scope of this script, including the custom guest image with
# Nvidia drivers installed, and properly configured Nvidia Tesla T4 card.
source $HOME/.cargo/env source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh source $(dirname "$0")/test-util.sh
process_common_args "$@" process_common_args "$@"
WORKLOADS_DIR="$HOME/workloads" WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR download_hypervisor_fw
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
FW="$WORKLOADS_DIR/hypervisor-fw"
if [ ! -f "$FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $FW_URL || exit 1
popd
fi
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $FOCAL_OS_IMAGE_URL || exit 1
popd
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
time qemu-img convert -p -f qcow2 -O raw $FOCAL_OS_IMAGE_NAME $FOCAL_OS_RAW_IMAGE_NAME || exit 1
popd
fi
pushd $WORKLOADS_DIR
sha1sum sha1sums-x86_64 --check --ignore-missing
if [ $? -ne 0 ]; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
build_custom_linux
BLK_IMAGE="$WORKLOADS_DIR/blk.img"
MNT_DIR="mount_image"
rm -rf $BLK_IMAGE
pushd $WORKLOADS_DIR
fallocate -l 16M $BLK_IMAGE
mkfs.ext4 -j $BLK_IMAGE
mkdir $MNT_DIR
sudo mount -t ext4 $BLK_IMAGE $MNT_DIR
sudo bash -c "echo bar > $MNT_DIR/foo" || exit 1
sudo umount $BLK_IMAGE
rm -r $MNT_DIR
popd
VFIO_DIR="$WORKLOADS_DIR/vfio"
VFIO_DISK_IMAGE="$WORKLOADS_DIR/vfio.img"
rm -rf $VFIO_DIR $VFIO_DISK_IMAGE
mkdir -p $VFIO_DIR
cp $FOCAL_OS_RAW_IMAGE $VFIO_DIR
cp $FW $VFIO_DIR
cp $VMLINUX_IMAGE $VFIO_DIR || exit 1
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS="" CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc" CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi fi
cargo build --features mshv --all --release --target $BUILD_TARGET cargo build --features mshv --all --release --target $BUILD_TARGET
# We always copy a fresh version of our binary for our L2 guest.
cp target/$BUILD_TARGET/release/cloud-hypervisor $VFIO_DIR
cp target/$BUILD_TARGET/release/ch-remote $VFIO_DIR
# test_vfio rely on hugepages
HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
PAGE_NUM=`echo $((12288 * 1024 / $HUGEPAGESIZE))`
echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1 export RUST_BACKTRACE=1
time cargo test "vfio::test_vfio" -- ${test_binary_args[*]} time cargo test "vfio::test_nvidia" -- --test-threads=1 ${test_binary_args[*]}
RES=$? RES=$?
if [ $RES -eq 0 ]; then
time cargo test "vfio::test_nvidia" -- --test-threads=1 ${test_binary_args[*]}
RES=$?
fi
exit $RES exit $RES

View File

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

View File

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

View File

@@ -4,8 +4,6 @@ set -x
source $HOME/.cargo/env source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh source $(dirname "$0")/test-util.sh
export BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads" WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR" mkdir -p "$WORKLOADS_DIR"
@@ -20,13 +18,7 @@ fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]') download_hypervisor_fw
FW="$WORKLOADS_DIR/hypervisor-fw"
if [ ! -f "$FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $FW_URL || exit 1
popd
fi
OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]') OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd" OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
@@ -162,8 +154,6 @@ cp $FOCAL_OS_RAW_IMAGE $VFIO_DIR
cp $FW $VFIO_DIR cp $FW $VFIO_DIR
cp $VMLINUX_IMAGE $VFIO_DIR || exit 1 cp $VMLINUX_IMAGE $VFIO_DIR || exit 1
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
cargo build --features mshv --all --release --target $BUILD_TARGET cargo build --features mshv --all --release --target $BUILD_TARGET
# We always copy a fresh version of our binary for our L2 guest. # We always copy a fresh version of our binary for our L2 guest.

View File

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

View File

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

View File

@@ -107,3 +107,20 @@ process_common_args() {
test_binary_args=($@) test_binary_args=($@)
} }
download_hypervisor_fw() {
if [ -n "$AUTH_DOWNLOAD_TOKEN" ]; then
echo "Using authenticated download from GitHub"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest \
--header "Authorization: Token $AUTH_DOWNLOAD_TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28" | grep "browser_download_url" | grep -o 'https://.*[^ "]')
else
echo "Using anonymous download from GitHub"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
fi
FW="$WORKLOADS_DIR/hypervisor-fw"
pushd $WORKLOADS_DIR
rm -f $FW
time wget --quiet $FW_URL || exit 1
popd
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
#[macro_use] #[macro_use]
extern crate event_monitor; extern crate event_monitor;
use argh::FromArgs; use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command};
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use log::{warn, LevelFilter}; use log::{warn, LevelFilter};
use option_parser::OptionParser; use option_parser::OptionParser;
@@ -128,6 +128,10 @@ impl log::Log for Logger {
fn flush(&self) {} fn flush(&self) {}
} }
fn prepare_default_values() -> (String, String, String) {
(default_vcpus(), default_memory(), default_rng())
}
fn default_vcpus() -> String { fn default_vcpus() -> String {
format!( format!(
"boot={},max_phys_bits={}", "boot={},max_phys_bits={}",
@@ -144,280 +148,330 @@ fn default_rng() -> String {
format!("src={}", config::DEFAULT_RNG_SOURCE) format!("src={}", config::DEFAULT_RNG_SOURCE)
} }
#[derive(FromArgs)] fn create_app(default_vcpus: String, default_memory: String, default_rng: String) -> Command {
/// Launch a cloud-hypervisor VMM. #[allow(clippy::let_and_return)]
pub struct TopLevel { let app = Command::new("cloud-hypervisor")
#[argh(option, long = "cpus", default = "default_vcpus()")] // 'BUILD_VERSION' is set by the build script 'build.rs' at
/// boot=<boot_vcpus>, max=<max_vcpus>, topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>, kvm_hyperv=on|off, max_phys_bits=<maximum_number_of_physical_bits>, affinity=<list_of_vcpus_with_their_associated_cpuset>, features=<list_of_features_to_enable> // compile time
cpus: String, .author(env!("CARGO_PKG_AUTHORS"))
.about("Launch a cloud-hypervisor VMM.")
#[argh(option, long = "platform")] .group(ArgGroup::new("vm-config").multiple(true))
/// num_pci_segments=<num_pci_segments>, iommu_segments=<list_of_segments>, serial_number=<dmi_device_serial_number>, uuid=<dmi_device_uuid>, oem_strings=<list_of_strings> .group(ArgGroup::new("vmm-config").multiple(true))
platform: Option<String>, .group(ArgGroup::new("logging").multiple(true))
.arg(
#[argh(option, long = "memory", default = "default_memory()")] Arg::new("cpus")
/// 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 .long("cpus")
memory: String, .help(
"boot=<boot_vcpus>,max=<max_vcpus>,\
#[argh(option, long = "memory-zone")] topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,\
/// size=<guest_memory_region_size>, file=<backing_file>, shared=on|off, hugepages=on|off, hugepage_size=<hugepage_size>, host_numa_node=<node_id>, id=<zone_identifier>, hotplug_size=<hotpluggable_memory_size>, hotplugged_size=<hotplugged_memory_size>, prefault=on|off kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,\
memory_zone: Vec<String>, affinity=<list_of_vcpus_with_their_associated_cpuset>,\
features=<list_of_features_to_enable>",
#[argh(option, long = "firmware")] )
/// path to firmware that is loaded in an architectural specific way .default_value(default_vcpus)
firmware: Option<String>, .group("vm-config"),
)
#[argh(option, long = "kernel")] .arg(
/// path to kernel or firmware that supports a PVH entry point or architecture equivalent Arg::new("platform")
kernel: Option<String>, .long("platform")
.help("num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>")
#[argh(option, long = "initramfs")] .num_args(1)
/// path to initramfs image .group("vm-config"),
initramfs: Option<String>, )
.arg(
#[argh(option, long = "cmdline")] Arg::new("memory")
/// kernel command line .long("memory")
cmdline: Option<String>, .help(
"Memory parameters \
#[argh(option, long = "disk")] \"size=<guest_memory_size>,mergeable=on|off,shared=on|off,\
/// path=<disk_image_path>, readonly=on|off, direct=on|off, iommu=on|off, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, vhost_user=on|off, socket=<vhost_user_socket_path>, bw_size=<bytes>, bw_one_time_burst=<bytes>, bw_refill_time=<ms>, ops_size=<io_ops>, ops_one_time_burst=<io_ops>, ops_refill_time=<ms>, id=<device_id>, pci_segment=<segment_id> hugepages=on|off,hugepage_size=<hugepage_size>,\
disk: Vec<String>, hotplug_method=acpi|virtio-mem,\
hotplug_size=<hotpluggable_memory_size>,\
#[argh(option, long = "net")] hotplugged_size=<hotplugged_memory_size>,\
/// tap=<if_name>, ip=<ip_addr>, mask=<net_mask>, mac=<mac_addr>, fd=<fd1,fd2...>, iommu=on|off, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, id=<device_id>, vhost_user=<vhost_user_enable>, socket=<vhost_user_socket_path>, vhost_mode=client|server, bw_size=<bytes>, bw_one_time_burst=<bytes>, bw_refill_time=<ms>, ops_size=<io_ops>, ops_one_time_burst=<io_ops>, ops_refill_time=<ms>, pci_segment=<segment_id>, offload_tso=on|off, offload_ufo=on|off, offload_csum=on|off prefault=on|off,thp=on|off\"",
net: Vec<String>, )
.default_value(default_memory)
#[argh(option, long = "rng", default = "default_rng()")] .group("vm-config"),
/// src=<entropy_source_path>, iommu=on|off )
rng: String, .arg(
Arg::new("memory-zone")
#[argh(option, long = "balloon")] .long("memory-zone")
/// size=<balloon_size>, deflate_on_oom=on|off, free_page_reporting=on|off .help(
balloon: Option<String>, "User defined memory zone parameters \
\"size=<guest_memory_region_size>,file=<backing_file>,\
#[argh(option, long = "fs")] shared=on|off,\
/// tag=<tag_name>, socket=<socket_path>, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, id=<device_id>, pci_segment=<segment_id> hugepages=on|off,hugepage_size=<hugepage_size>,\
fs: Vec<String>, host_numa_node=<node_id>,\
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
#[argh(option, long = "pmem")] hotplugged_size=<hotplugged_memory_size>,\
/// file=<backing_file_path>, size=<persistent_memory_size>, iommu=on|off, discard_writes=on|off, id=<device_id>, pci_segment=<segment_id> prefault=on|off\"",
pmem: Vec<String>, )
.num_args(1..)
#[argh(option, long = "serial", default = "String::from(\"null\")")] .group("vm-config"),
/// off|null|pty|tty|file=/path/to/a/file )
serial: String, .arg(
Arg::new("firmware")
#[argh(option, long = "console", default = "String::from(\"tty\")")] .long("firmware")
/// off|null|pty|tty|file=/path/to/a/file, iommu=on|off .help("Path to firmware that is loaded in an architectural specific way")
console: String, .num_args(1)
.group("vm-config"),
#[argh(option, long = "device")] )
/// path=<device_path>, iommu=on|off, id=<device_id>, pci_segment=<segment_id> .arg(
device: Vec<String>, Arg::new("kernel")
.long("kernel")
#[argh(option, long = "user-device")] .help(
/// socket=<socket_path>, id=<device_id>, pci_segment=<segment_id> "Path to kernel to load. This may be a kernel or firmware that supports a PVH \
user_device: Vec<String>, entry point (e.g. vmlinux) or architecture equivalent",
)
#[argh(option, long = "vdpa")] .num_args(1)
/// path=<device_path>, num_queues=<number_of_queues>, iommu=on|off, id=<device_id>, pci_segment=<segment_id> .group("vm-config"),
vdpa: Vec<String>, )
.arg(
#[argh(option, long = "vsock")] Arg::new("initramfs")
/// cid=<context_id>, socket=<socket_path>, iommu=on|off, id=<device_id>, pci_segment=<segment_id> .long("initramfs")
vsock: Option<String>, .help("Path to initramfs image")
.num_args(1)
#[argh(switch, long = "pvpanic")] .group("vm-config"),
/// enable pvpanic device )
pvpanic: bool, .arg(
Arg::new("cmdline")
#[argh(option, long = "numa")] .long("cmdline")
/// guest_numa_id=<node_id>, cpus=<cpus_id>, distances=<list_of_distances_to_destination_nodes>, memory_zones=<list_of_memory_zones>, sgx_epc_sections=<list_of_sgx_epc_sections> .help("Kernel command line")
numa: Vec<String>, .num_args(1)
.group("vm-config"),
#[argh(switch, long = "watchdog")] )
/// enable virtio-watchdog .arg(
watchdog: bool, Arg::new("disk")
.long("disk")
#[argh(switch, short = 'v')] .help(config::DiskConfig::SYNTAX)
/// set the level of debugging output .num_args(1..)
verbosity: u8, .group("vm-config"),
)
#[argh(option, long = "log-file")] .arg(
/// path to log file Arg::new("net")
log_file: Option<String>, .long("net")
.help(config::NetConfig::SYNTAX)
#[argh(option, long = "api-socket")] .num_args(1..)
/// path=<path/to/a/file>|fd=<fd> .group("vm-config"),
api_socket: Option<String>, )
.arg(
#[cfg(feature = "dbus_api")] Arg::new("rng")
#[argh(option, long = "dbus-service-name")] .long("rng")
/// well known name of the service .help(
dbus_name: Option<String>, "Random number generator parameters \"src=<entropy_source_path>,iommu=on|off\"",
)
#[cfg(feature = "dbus_api")] .default_value(default_rng)
#[argh(option, long = "dbus-object-path")] .group("vm-config"),
/// object path to serve the dbus interface )
dbus_path: Option<String>, .arg(
Arg::new("balloon")
#[cfg(feature = "dbus_api")] .long("balloon")
#[argh(switch, long = "dbus-system-bus")] .help(config::BalloonConfig::SYNTAX)
/// use the system bus instead of a session bus .num_args(1)
dbus_system_bus: bool, .group("vm-config"),
)
#[argh(option, long = "event-monitor")] .arg(
/// path=<path/to/a/file>|fd=<fd> Arg::new("fs")
event_monitor: Option<String>, .long("fs")
.help(config::FsConfig::SYNTAX)
#[argh(option, long = "restore")] .num_args(1..)
/// source_url=<source_url>, prefault=on|off .group("vm-config"),
restore: Option<String>, )
.arg(
#[argh(option, long = "seccomp", default = "String::from(\"true\")")] Arg::new("pmem")
/// seccomp configuration (true, false or log) .long("pmem")
seccomp: String, .help(config::PmemConfig::SYNTAX)
.num_args(1..)
#[argh(option, long = "tpm")] .group("vm-config"),
/// socket=<path/to/a/socket> )
tpm: Option<String>, .arg(
Arg::new("serial")
.long("serial")
.help("Control serial port: off|null|pty|tty|file=</path/to/a/file>|socket=</path/to/a/file>")
.default_value("null")
.group("vm-config"),
)
.arg(
Arg::new("console")
.long("console")
.help(
"Control (virtio) console: \"off|null|pty|tty|file=</path/to/a/file>,iommu=on|off\"",
)
.default_value("tty")
.group("vm-config"),
)
.arg(
Arg::new("device")
.long("device")
.help(config::DeviceConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
)
.arg(
Arg::new("user-device")
.long("user-device")
.help(config::UserDeviceConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
)
.arg(
Arg::new("vdpa")
.long("vdpa")
.help(config::VdpaConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
)
.arg(
Arg::new("vsock")
.long("vsock")
.help(config::VsockConfig::SYNTAX)
.num_args(1)
.group("vm-config"),
)
.arg(
Arg::new("pvpanic")
.long("pvpanic")
.help("Enable pvpanic device")
.num_args(0)
.action(ArgAction::SetTrue)
.group("vm-config"),
)
.arg(
Arg::new("numa")
.long("numa")
.help(config::NumaConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
)
.arg(
Arg::new("watchdog")
.long("watchdog")
.help("Enable virtio-watchdog")
.num_args(0)
.action(ArgAction::SetTrue)
.group("vm-config"),
)
.arg(
Arg::new("v")
.short('v')
.action(ArgAction::Count)
.help("Sets the level of debugging output")
.group("logging"),
)
.arg(
Arg::new("log-file")
.long("log-file")
.help("Log file. Standard error is used if not specified")
.num_args(1)
.group("logging"),
)
.arg(
Arg::new("api-socket")
.long("api-socket")
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
.num_args(1)
.group("vmm-config"),
)
.arg(
Arg::new("event-monitor")
.long("event-monitor")
.help("File to report events on: path=</path/to/a/file> or fd=<fd>")
.num_args(1)
.group("vmm-config"),
)
.arg(
Arg::new("restore")
.long("restore")
.help(config::RestoreConfig::SYNTAX)
.num_args(1)
.group("vmm-config"),
)
.arg(
Arg::new("seccomp")
.long("seccomp")
.num_args(1)
.value_parser(["true", "false", "log"])
.default_value("true"),
)
.arg(
Arg::new("tpm")
.long("tpm")
.num_args(1)
.help(config::TpmConfig::SYNTAX)
.group("vmm-config"),
);
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[argh(option, long = "sgx-epc")] let app = app.arg(
/// id=<epc_section_identifier>, size=<epc_section_size>, prefault=on|off Arg::new("sgx-epc")
sgx_epc: Vec<String>, .long("sgx-epc")
.help(config::SgxEpcConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
);
#[cfg(feature = "guest_debug")] #[cfg(feature = "guest_debug")]
#[argh(option, long = "gdb")] let app = app.arg(
/// path=<path/to/a/file> Arg::new("gdb")
gdb: Option<String>, .long("gdb")
.help("GDB socket (UNIX domain socket): path=</path/to/a/file>")
.num_args(1)
.group("vmm-config"),
);
#[argh(switch, short = 'V', long = "version")] #[cfg(feature = "dbus_api")]
/// print version information let app = app
version: bool, .arg(
Arg::new("dbus-service-name")
.long("dbus-service-name")
.help("Well known name of the device")
.num_args(1)
.group("vmm-config"),
)
.arg(
Arg::new("dbus-object-path")
.long("dbus-object-path")
.help("Object path to serve the dbus interface")
.num_args(1)
.group("vmm-config"),
)
.arg(
Arg::new("dbus-system-bus")
.long("dbus-system-bus")
.action(ArgAction::SetTrue)
.help("Use the system bus instead of a session bus")
.num_args(0)
.group("vmm-config"),
);
#[cfg(feature = "igvm")]
let app = app.arg(
Arg::new("igvm")
.long("igvm")
.help("Path to IGVM file to load.")
.num_args(1)
.group("vm-config"),
);
app.arg(
Arg::new("version")
.short('V')
.long("version")
.action(ArgAction::SetTrue)
.help("Print version")
.num_args(0),
)
} }
impl TopLevel { fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
fn to_vm_params(&self) -> config::VmParams<'_> { let log_level = match cmd_arguments.get_count("v") {
let cpus = &self.cpus;
let memory = &self.memory;
let memory_zones = if !self.memory_zone.is_empty() {
Some(self.memory_zone.iter().map(|x| x.as_str()).collect())
} else {
None
};
let rng = &self.rng;
let serial = &self.serial;
let firmware = self.firmware.as_deref();
let kernel = self.kernel.as_deref();
let initramfs = self.initramfs.as_deref();
let cmdline = self.cmdline.as_deref();
let disks = if !self.disk.is_empty() {
Some(self.disk.iter().map(|x| x.as_str()).collect())
} else {
None
};
let net = if !self.net.is_empty() {
Some(self.net.iter().map(|x| x.as_str()).collect())
} else {
None
};
let console = &self.console;
let balloon = self.balloon.as_deref();
let fs = if !self.fs.is_empty() {
Some(self.fs.iter().map(|x| x.as_str()).collect())
} else {
None
};
let pmem = if !self.pmem.is_empty() {
Some(self.pmem.iter().map(|x| x.as_str()).collect())
} else {
None
};
let devices = if !self.device.is_empty() {
Some(self.device.iter().map(|x| x.as_str()).collect())
} else {
None
};
let user_devices = if !self.user_device.is_empty() {
Some(self.user_device.iter().map(|x| x.as_str()).collect())
} else {
None
};
let vdpa = if !self.vdpa.is_empty() {
Some(self.vdpa.iter().map(|x| x.as_str()).collect())
} else {
None
};
let vsock = self.vsock.as_deref();
let pvpanic = self.pvpanic;
#[cfg(target_arch = "x86_64")]
let sgx_epc = if !self.sgx_epc.is_empty() {
Some(self.sgx_epc.iter().map(|x| x.as_str()).collect())
} else {
None
};
let numa = if !self.numa.is_empty() {
Some(self.numa.iter().map(|x| x.as_str()).collect())
} else {
None
};
let watchdog = self.watchdog;
let platform = self.platform.as_deref();
#[cfg(feature = "guest_debug")]
let gdb = self.gdb.is_some();
let tpm = self.tpm.as_deref();
config::VmParams {
cpus,
memory,
memory_zones,
firmware,
kernel,
initramfs,
cmdline,
disks,
net,
rng,
balloon,
fs,
pmem,
serial,
console,
devices,
user_devices,
vdpa,
vsock,
pvpanic,
#[cfg(target_arch = "x86_64")]
sgx_epc,
numa,
watchdog,
#[cfg(feature = "guest_debug")]
gdb,
platform,
tpm,
}
}
}
fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
let log_level = match toplevel.verbosity {
0 => LevelFilter::Warn, 0 => LevelFilter::Warn,
1 => LevelFilter::Info, 1 => LevelFilter::Info,
2 => LevelFilter::Debug, 2 => LevelFilter::Debug,
_ => LevelFilter::Trace, _ => LevelFilter::Trace,
}; };
let log_file: Box<dyn std::io::Write + Send> = if let Some(ref file) = toplevel.log_file { let log_file: Box<dyn std::io::Write + Send> = if let Some(ref file) =
cmd_arguments.get_one::<String>("log-file")
{
Box::new(std::fs::File::create(std::path::Path::new(file)).map_err(Error::LogFileCreation)?) Box::new(std::fs::File::create(std::path::Path::new(file)).map_err(Error::LogFileCreation)?)
} else { } else {
Box::new(std::io::stderr()) Box::new(std::io::stderr())
@@ -430,37 +484,47 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
.map(|()| log::set_max_level(log_level)) .map(|()| log::set_max_level(log_level))
.map_err(Error::LoggerSetup)?; .map_err(Error::LoggerSetup)?;
let (api_socket_path, api_socket_fd) = if let Some(ref socket_config) = toplevel.api_socket { let (api_socket_path, api_socket_fd) =
let mut parser = OptionParser::new(); if let Some(socket_config) = cmd_arguments.get_one::<String>("api-socket") {
parser.add("path").add("fd"); let mut parser = OptionParser::new();
parser.parse(socket_config).unwrap_or_default(); parser.add("path").add("fd");
parser.parse(socket_config).unwrap_or_default();
if let Some(fd) = parser.get("fd") { if let Some(fd) = parser.get("fd") {
( (
None, None,
Some(fd.parse::<RawFd>().map_err(Error::ParsingApiSocket)?), Some(fd.parse::<RawFd>().map_err(Error::ParsingApiSocket)?),
) )
} else if let Some(path) = parser.get("path") { } else if let Some(path) = parser.get("path") {
(Some(path), None) (Some(path), None)
} else {
(
cmd_arguments
.get_one::<String>("api-socket")
.map(|s| s.to_string()),
None,
)
}
} else { } else {
(toplevel.api_socket.as_ref().map(|s| s.to_string()), None) (None, None)
} };
} else {
(None, None)
};
let (api_request_sender, api_request_receiver) = channel(); let (api_request_sender, api_request_receiver) = channel();
let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?; let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?;
let api_request_sender_clone = api_request_sender.clone(); let api_request_sender_clone = api_request_sender.clone();
let seccomp_action = match &toplevel.seccomp as &str { let seccomp_action = if let Some(seccomp_value) = cmd_arguments.get_one::<String>("seccomp") {
"true" => SeccompAction::Trap, match seccomp_value as &str {
"false" => SeccompAction::Allow, "true" => SeccompAction::Trap,
"log" => SeccompAction::Log, "false" => SeccompAction::Allow,
val => { "log" => SeccompAction::Log,
// The user providing an invalid value will be rejected val => {
panic!("Invalid parameter {val} for \"--seccomp\" flag"); // The user providing an invalid value will be rejected
panic!("Invalid parameter {val} for \"--seccomp\" flag");
}
} }
} else {
SeccompAction::Trap
}; };
if seccomp_action == SeccompAction::Trap { if seccomp_action == SeccompAction::Trap {
@@ -498,7 +562,7 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?; let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?;
#[cfg(feature = "guest_debug")] #[cfg(feature = "guest_debug")]
let gdb_socket_path = if let Some(ref gdb_config) = toplevel.gdb { let gdb_socket_path = if let Some(gdb_config) = cmd_arguments.get_one::<String>("gdb") {
let mut parser = OptionParser::new(); let mut parser = OptionParser::new();
parser.add("path"); parser.add("path");
parser.parse(gdb_config).map_err(Error::ParsingGdb)?; parser.parse(gdb_config).map_err(Error::ParsingGdb)?;
@@ -519,8 +583,8 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?; let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
#[allow(unused_mut)] #[allow(unused_mut)]
let mut event_monitor = toplevel let mut event_monitor = cmd_arguments
.event_monitor .get_one::<String>("event-monitor")
.as_ref() .as_ref()
.map(|monitor_config| { .map(|monitor_config| {
let mut parser = OptionParser::new(); let mut parser = OptionParser::new();
@@ -555,8 +619,11 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
.transpose()?; .transpose()?;
#[cfg(feature = "dbus_api")] #[cfg(feature = "dbus_api")]
let dbus_options = match (&toplevel.dbus_name, &toplevel.dbus_path) { let dbus_options = match (
(Some(ref name), Some(ref path)) => { cmd_arguments.get_one::<String>("dbus-service-name"),
cmd_arguments.get_one::<String>("dbus-object-path"),
) {
(Some(name), Some(path)) => {
// monitor is either set (file based) or not. // monitor is either set (file based) or not.
// if it's not set, create one without file support. // if it's not set, create one without file support.
let mut monitor = match event_monitor.take() { let mut monitor = match event_monitor.take() {
@@ -564,9 +631,9 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
None => event_monitor::set_monitor(None).map_err(Error::EventMonitorIo)?, None => event_monitor::set_monitor(None).map_err(Error::EventMonitorIo)?,
}; };
let options = DBusApiOptions { let options = DBusApiOptions {
service_name: name.to_owned(), service_name: name.to_string(),
object_path: path.to_owned(), object_path: path.to_string(),
system_bus: toplevel.dbus_system_bus, system_bus: cmd_arguments.get_flag("dbus-system-bus"),
event_monitor_rx: monitor.subscribe(), event_monitor_rx: monitor.subscribe(),
}; };
@@ -612,10 +679,11 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
.map_err(Error::StartVmmThread)?; .map_err(Error::StartVmmThread)?;
let r: Result<(), Error> = (|| { let r: Result<(), Error> = (|| {
let payload_present = toplevel.kernel.is_some() || toplevel.firmware.is_some(); let payload_present =
cmd_arguments.contains_id("kernel") || cmd_arguments.contains_id("firmware");
if payload_present { if payload_present {
let vm_params = toplevel.to_vm_params(); let vm_params = config::VmParams::from_arg_matches(&cmd_arguments);
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?; let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
// Create and boot the VM based off the VM config we just built. // Create and boot the VM based off the VM config we just built.
@@ -627,12 +695,12 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
) )
.map_err(Error::VmCreate)?; .map_err(Error::VmCreate)?;
vmm::api::vm_boot(api_evt.try_clone().unwrap(), sender).map_err(Error::VmBoot)?; vmm::api::vm_boot(api_evt.try_clone().unwrap(), sender).map_err(Error::VmBoot)?;
} else if let Some(restore_params) = toplevel.restore { } else if let Some(restore_params) = cmd_arguments.get_one::<String>("restore") {
vmm::api::vm_restore( vmm::api::vm_restore(
api_evt.try_clone().unwrap(), api_evt.try_clone().unwrap(),
api_request_sender, api_request_sender,
Arc::new( Arc::new(
config::RestoreConfig::parse(&restore_params).map_err(Error::ParsingRestore)?, config::RestoreConfig::parse(restore_params).map_err(Error::ParsingRestore)?,
), ),
) )
.map_err(Error::VmRestore)?; .map_err(Error::VmRestore)?;
@@ -672,14 +740,20 @@ fn main() {
// SAFETY: trivially safe // SAFETY: trivially safe
let _ = unsafe { libc::umask(0o077) }; let _ = unsafe { libc::umask(0o077) };
let toplevel: TopLevel = argh::from_env(); let (default_vcpus, default_memory, default_rng) = prepare_default_values();
let cmd_arguments = create_app(default_vcpus, default_memory, default_rng).get_matches();
if toplevel.version { if cmd_arguments.get_flag("version") {
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION")); println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION"));
if cmd_arguments.get_count("v") != 0 {
println!("Enabled features: {:?}", vmm::feature_list());
}
return; return;
} }
let exit_code = match start_vmm(toplevel) { let exit_code = match start_vmm(cmd_arguments) {
Ok(path) => { Ok(path) => {
path.map(|s| std::fs::remove_file(s).ok()); path.map(|s| std::fs::remove_file(s).ok());
0 0
@@ -699,45 +773,18 @@ fn main() {
#[cfg(test)] #[cfg(test)]
mod unit_tests { mod unit_tests {
use crate::config::HotplugMethod; use crate::config::HotplugMethod;
use crate::TopLevel; use crate::{create_app, prepare_default_values};
use std::path::PathBuf; use std::path::PathBuf;
use vmm::config::{ use vmm::config::{
ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, PayloadConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, PayloadConfig,
RngConfig, VmConfig, RngConfig, VmConfig, VmParams,
}; };
// Taken from argh
fn cmd<'a>(default: &'a str, path: &'a str) -> &'a str {
std::path::Path::new(path)
.file_name()
.and_then(|s| s.to_str())
.unwrap_or(default)
}
// Some code taken from argh since it does not provide a helper to parse arbitrary strings
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig { fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
let strings: Vec<String> = args.iter().map(|x| x.to_string()).collect(); let (default_vcpus, default_memory, default_rng) = prepare_default_values();
let cmd = cmd(&strings[0], &strings[0]); let cmd_arguments =
let strs: Vec<&str> = strings.iter().map(|s| s.as_str()).collect(); create_app(default_vcpus, default_memory, default_rng).get_matches_from(args);
let toplevel = <TopLevel as argh::FromArgs>::from_args(&[cmd], &strs[1..]).unwrap_or_else( let vm_params = VmParams::from_arg_matches(&cmd_arguments);
|early_exit| {
std::process::exit(match early_exit.status {
Ok(()) => {
println!("{}", early_exit.output);
0
}
Err(()) => {
eprintln!(
"{}\nRun {} --help for more information.",
early_exit.output, cmd
);
1
}
})
},
);
let vm_params = toplevel.to_vm_params();
VmConfig::parse(vm_params).unwrap() VmConfig::parse(vm_params).unwrap()
} }
@@ -808,11 +855,13 @@ mod unit_tests {
file: None, file: None,
mode: ConsoleOutputMode::Null, mode: ConsoleOutputMode::Null,
iommu: false, iommu: false,
socket: None,
}, },
console: ConsoleConfig { console: ConsoleConfig {
file: None, file: None,
mode: ConsoleOutputMode::Tty, mode: ConsoleOutputMode::Tty,
iommu: false, iommu: false,
socket: None,
}, },
devices: None, devices: None,
user_devices: None, user_devices: None,
@@ -998,7 +1047,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--disk", "--disk",
"path=/path/to/disk/1", "path=/path/to/disk/1",
"--disk",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
@@ -1017,7 +1065,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--disk", "--disk",
"path=/path/to/disk/1", "path=/path/to/disk/1",
"--disk",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
@@ -1292,7 +1339,6 @@ mod unit_tests {
"--memory", "shared=true", "--memory", "shared=true",
"--fs", "--fs",
"tag=virtiofs1,socket=/path/to/sock1", "tag=virtiofs1,socket=/path/to/sock1",
"--fs",
"tag=virtiofs2,socket=/path/to/sock2", "tag=virtiofs2,socket=/path/to/sock2",
], ],
r#"{ r#"{
@@ -1311,7 +1357,6 @@ mod unit_tests {
"--memory", "shared=true", "--memory", "shared=true",
"--fs", "--fs",
"tag=virtiofs1,socket=/path/to/sock1", "tag=virtiofs1,socket=/path/to/sock1",
"--fs",
"tag=virtiofs2,socket=/path/to/sock2", "tag=virtiofs2,socket=/path/to/sock2",
], ],
r#"{ r#"{
@@ -1373,7 +1418,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G", "file=/path/to/img/1,size=1G",
"--pmem",
"file=/path/to/img/2,size=2G", "file=/path/to/img/2,size=2G",
], ],
r#"{ r#"{
@@ -1540,7 +1584,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--device", "--device",
"path=/path/to/device/1", "path=/path/to/device/1",
"--device",
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
@@ -1559,7 +1602,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--device", "--device",
"path=/path/to/device/1", "path=/path/to/device/1",
"--device",
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
@@ -1636,7 +1678,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--vdpa", "--vdpa",
"path=/path/to/device/1", "path=/path/to/device/1",
"--vdpa",
"path=/path/to/device/2,num_queues=2", "path=/path/to/device/2,num_queues=2",
], ],
r#"{ r#"{
@@ -1655,7 +1696,6 @@ mod unit_tests {
"/path/to/kernel", "/path/to/kernel",
"--vdpa", "--vdpa",
"path=/path/to/device/1", "path=/path/to/device/1",
"--vdpa",
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{

View File

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

View File

@@ -147,13 +147,13 @@ impl GuestNetworkConfig {
Err(e) => { Err(e) => {
let duration = start.elapsed(); let duration = start.elapsed();
eprintln!( eprintln!(
"\n\n==== Start 'wait_vm_boot' (FAILED) ====\n\n\ "\n\n==== Start 'wait_vm_boot' (FAILED) ==== \
duration =\"{duration:?}, timeout = {timeout}s\"\n\ \n\nduration =\"{duration:?}, timeout = {timeout}s\" \
listen_addr=\"{listen_addr}\"\n\ \nlisten_addr=\"{listen_addr}\" \
expected_guest_addr=\"{expected_guest_addr}\"\n\ \nexpected_guest_addr=\"{expected_guest_addr}\" \
message=\"{s}\"\n\ \nmessage=\"{s}\" \
error=\"{e:?}\"\n\ \nerror=\"{e:?}\" \
\n==== End 'wait_vm_boot' outout ====\n\n" \n\n==== End 'wait_vm_boot' outout ====\n\n"
); );
Err(e) Err(e)
@@ -718,18 +718,77 @@ pub fn ssh_command_ip(
) )
} }
pub fn exec_host_command_with_retries(command: &str, retries: u32, interval: Duration) -> bool {
for _ in 0..retries {
let s = exec_host_command_output(command).status;
if !s.success() {
eprintln!("\n\n==== retrying in {:?} ===\n\n", interval);
thread::sleep(interval);
} else {
return true;
}
}
false
}
pub fn exec_host_command_status(command: &str) -> ExitStatus { pub fn exec_host_command_status(command: &str) -> ExitStatus {
std::process::Command::new("bash") exec_host_command_output(command).status
.args(["-c", command])
.status()
.unwrap_or_else(|_| panic!("Expected '{command}' to run"))
} }
pub fn exec_host_command_output(command: &str) -> Output { pub fn exec_host_command_output(command: &str) -> Output {
std::process::Command::new("bash") let output = std::process::Command::new("bash")
.args(["-c", command]) .args(["-c", command])
.output() .output()
.unwrap_or_else(|_| panic!("Expected '{command}' to run")) .unwrap_or_else(|e| panic!("Expected '{command}' to run. Error: {:?}", e));
if !output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!(
"\n\n==== Start 'exec_host_command' failed ==== \
\n\n---stdout---\n{stdout}\n---stderr---{stderr} \
\n\n==== End 'exec_host_command' failed ====",
);
}
output
}
pub fn check_lines_count(input: &str, line_count: usize) -> bool {
if input.lines().count() == line_count {
true
} else {
eprintln!(
"\n\n==== Start 'check_lines_count' failed ==== \
\n\ninput = {input}\nline_count = {line_count} \
\n\n==== End 'check_lines_count' failed ====",
);
false
}
}
pub fn check_matched_lines_count(input: &str, keywords: Vec<&str>, line_count: usize) -> bool {
let mut matches = String::new();
for line in input.lines() {
if keywords.iter().all(|k| line.contains(k)) {
matches += line;
}
}
if matches.lines().count() == line_count {
true
} else {
eprintln!(
"\n\n==== Start 'check_matched_lines_count' failed ==== \
\nkeywords = {keywords:?}, line_count = {line_count} \
\n\ninput = {input} matches = {matches} \
\n\n==== End 'check_matched_lines_count' failed ====",
);
false
}
} }
pub const PIPE_SIZE: i32 = 32 << 20; pub const PIPE_SIZE: i32 = 32 << 20;
@@ -1152,7 +1211,7 @@ impl ToString for VerbosityLevel {
match self { match self {
Warn => "".to_string(), Warn => "".to_string(),
Info => "-v".to_string(), Info => "-v".to_string(),
Debug => "-v -v".to_string(), Debug => "-vv".to_string(),
} }
} }
} }
@@ -1203,7 +1262,7 @@ impl<'a> GuestCommand<'a> {
self.command.arg("-v"); self.command.arg("-v");
} }
Debug => { Debug => {
self.command.args(["-v", "-v"]); self.command.args(["-vv"]);
} }
}; };
@@ -1271,7 +1330,6 @@ impl<'a> GuestCommand<'a> {
.unwrap() .unwrap()
) )
.as_str(), .as_str(),
"--disk",
format!( format!(
"path={}", "path={}",
self.guest.disk_config.disk(DiskType::CloudInit).unwrap() self.guest.disk_config.disk(DiskType::CloudInit).unwrap()
@@ -1338,7 +1396,7 @@ pub fn parse_iperf3_output(output: &[u8], sender: bool, bandwidth: bool) -> Resu
}) })
.map_err(|_| { .map_err(|_| {
eprintln!( eprintln!(
"=============== iperf3 output ===============\n\n{}\n\n===========end============\n\n", "==== Start iperf3 output ===\n\n{}\n\n=== End iperf3 output ===\n\n",
String::from_utf8_lossy(output) String::from_utf8_lossy(output)
); );
Error::Iperf3Parse Error::Iperf3Parse
@@ -1416,9 +1474,7 @@ pub fn parse_fio_output(output: &str, fio_ops: &FioOps, num_jobs: u32) -> Result
total_bps total_bps
}) })
.map_err(|_| { .map_err(|_| {
eprintln!( eprintln!("=== Start Fio output ===\n\n{output}\n\n=== End Fio output ===\n\n");
"=============== Fio output ===============\n\n{output}\n\n===========end============\n\n"
);
Error::FioOutputParse Error::FioOutputParse
}) })
} }
@@ -1471,9 +1527,7 @@ pub fn parse_fio_output_iops(output: &str, fio_ops: &FioOps, num_jobs: u32) -> R
total_iops total_iops
}) })
.map_err(|_| { .map_err(|_| {
eprintln!( eprintln!("=== Start Fio output ===\n\n{output}\n\n=== End Fio output ===\n\n");
"=============== Fio output ===============\n\n{output}\n\n===========end============\n\n"
);
Error::FioOutputParse Error::FioOutputParse
}) })
} }
@@ -1606,7 +1660,7 @@ pub fn parse_ethr_latency_output(output: &[u8]) -> Result<Vec<f64>, Error> {
}) })
.map_err(|_| { .map_err(|_| {
eprintln!( eprintln!(
"=============== ethr output ===============\n\n{}\n\n===========end============\n\n", "=== Start ethr output ===\n\n{}\n\n=== End ethr output ===\n\n",
String::from_utf8_lossy(output) String::from_utf8_lossy(output)
); );
Error::EthrLogParse Error::EthrLogParse

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
once_cell = "1.18.0" once_cell = "1.18.0"
serde = { version = "1.0.168", features = ["rc", "derive"] } serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107" serde_json = "1.0.107"

View File

@@ -6,17 +6,16 @@ edition = "2021"
build = "../build.rs" build = "../build.rs"
[dependencies] [dependencies]
argh = "0.1.9" clap = { version = "4.4.7", features = ["wrap_help","cargo"] }
block = { path = "../block" } block = { path = "../block" }
env_logger = "0.10.0" env_logger = "0.10.0"
epoll = "4.3.3" epoll = "4.3.3"
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
option_parser = { path = "../option_parser" } option_parser = { path = "../option_parser" }
vhost = { version = "0.8.1", features = ["vhost-user-slave"] } vhost = { version = "0.9.0", features = ["vhost-user-backend"] }
vhost-user-backend = "0.10.1" vhost-user-backend = "0.11.0"
virtio-bindings = "0.2.0" virtio-bindings = "0.2.0"
virtio-queue = "0.9.0" virtio-queue = "0.10.0"
vm-memory = "0.12.2" vm-memory = "0.13.1"
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"

View File

@@ -74,6 +74,11 @@ enum Error {
SocketParameterMissing, SocketParameterMissing,
} }
pub const SYNTAX: &str = "vhost-user-block backend parameters \
\"path=<image_path>,socket=<socket_path>,num_queues=<number_of_queues>,\
queue_size=<size_of_each_queue>,readonly=true|false,direct=true|false,\
poll_queue=true|false\"";
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "vhost_user_block_error: {self:?}") write!(f, "vhost_user_block_error: {self:?}")
@@ -294,9 +299,10 @@ impl VhostUserBlkBackend {
} }
} }
impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, AtomicBitmap> impl VhostUserBackendMut for VhostUserBlkBackend {
for VhostUserBlkBackend type Bitmap = AtomicBitmap;
{ type Vring = VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>;
fn num_queues(&self) -> usize { fn num_queues(&self) -> usize {
self.config.num_queues as usize self.config.num_queues as usize
} }
@@ -345,7 +351,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
evset: EventSet, evset: EventSet,
vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>], vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>],
thread_id: usize, thread_id: usize,
) -> VhostUserBackendResult<bool> { ) -> VhostUserBackendResult<()> {
if evset != EventSet::IN { if evset != EventSet::IN {
return Err(Error::HandleEventNotEpollIn.into()); return Err(Error::HandleEventNotEpollIn.into());
} }
@@ -389,7 +395,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
thread.process_queue(&mut vring); thread.process_queue(&mut vring);
} }
Ok(false) Ok(())
} }
_ => Err(Error::HandleEventUnknownEvent.into()), _ => Err(Error::HandleEventUnknownEvent.into()),
} }

View File

@@ -10,36 +10,25 @@
extern crate vhost_user_block; extern crate vhost_user_block;
use argh::FromArgs; use clap::{Arg, Command};
use vhost_user_block::start_block_backend; use vhost_user_block::start_block_backend;
#[derive(FromArgs)]
/// Launch a vhost-user-blk backend.
struct TopLevel {
#[argh(option, long = "block-backend")]
/// vhost-user-block backend parameters
/// path=<image_path>,socket=<socket_path>,num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,readonly=true|false,direct=true|false,poll_queue=true|false
backend_command: Option<String>,
#[argh(switch, short = 'V', long = "version")]
/// print version information
version: bool,
}
fn main() { fn main() {
env_logger::init(); env_logger::init();
let toplevel: TopLevel = argh::from_env(); let cmd_arguments = Command::new("vhost-user-blk backend")
.version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS"))
.about("Launch a vhost-user-blk backend.")
.arg(
Arg::new("block-backend")
.long("block-backend")
.help(vhost_user_block::SYNTAX)
.num_args(1)
.required(true),
)
.get_matches();
if toplevel.version { let backend_command = cmd_arguments.get_one::<String>("block-backend").unwrap();
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION")); start_block_backend(backend_command);
return;
}
if toplevel.backend_command.is_none() {
println!("Please specify --block-backend");
std::process::exit(1)
}
start_block_backend(&toplevel.backend_command.unwrap());
} }

View File

@@ -6,16 +6,16 @@ edition = "2021"
build = "../build.rs" build = "../build.rs"
[dependencies] [dependencies]
argh = "0.1.9" clap = { version = "4.4.7", features = ["wrap_help","cargo"] }
env_logger = "0.10.0" env_logger = "0.10.0"
epoll = "4.3.3" epoll = "4.3.3"
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
net_util = { path = "../net_util" } net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" } option_parser = { path = "../option_parser" }
vhost = { version = "0.8.1", features = ["vhost-user-slave"] } vhost = { version = "0.9.0", features = ["vhost-user-backend"] }
vhost-user-backend = "0.10.1" vhost-user-backend = "0.11.0"
virtio-bindings = "0.2.0" virtio-bindings = "0.2.0"
vm-memory = "0.12.2" vm-memory = "0.13.1"
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"

View File

@@ -158,9 +158,10 @@ impl VhostUserNetBackend {
} }
} }
impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, AtomicBitmap> impl VhostUserBackendMut for VhostUserNetBackend {
for VhostUserNetBackend type Bitmap = AtomicBitmap;
{ type Vring = VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>;
fn num_queues(&self) -> usize { fn num_queues(&self) -> usize {
self.num_queues self.num_queues
} }
@@ -203,7 +204,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
_evset: EventSet, _evset: EventSet,
vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>], vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>],
thread_id: usize, thread_id: usize,
) -> VhostUserBackendResult<bool> { ) -> VhostUserBackendResult<()> {
let mut thread = self.threads[thread_id].lock().unwrap(); let mut thread = self.threads[thread_id].lock().unwrap();
match device_event { match device_event {
0 => { 0 => {
@@ -245,7 +246,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
_ => return Err(Error::HandleEventUnknownEvent.into()), _ => return Err(Error::HandleEventUnknownEvent.into()),
} }
Ok(false) Ok(())
} }
fn exit_event(&self, thread_index: usize) -> Option<EventFd> { fn exit_event(&self, thread_index: usize) -> Option<EventFd> {

View File

@@ -6,36 +6,25 @@
// //
// SPDX-License-Identifier: (Apache-2.0 AND BSD-3-Clause) // SPDX-License-Identifier: (Apache-2.0 AND BSD-3-Clause)
use argh::FromArgs; use clap::{Arg, Command};
use vhost_user_net::start_net_backend; use vhost_user_net::start_net_backend;
#[derive(FromArgs)]
/// Launch a vhost-user-net backend.
struct TopLevel {
#[argh(option, long = "net-backend")]
/// vhost-user-net backend parameters
/// ip=<ip_addr>,mask=<net_mask>,socket=<socket_path>,client=on|off,num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,tap=<if_name>
backend_command: Option<String>,
#[argh(switch, short = 'V', long = "version")]
/// print version information
version: bool,
}
fn main() { fn main() {
env_logger::init(); env_logger::init();
let toplevel: TopLevel = argh::from_env(); let cmd_arguments = Command::new("vhost-user-net backend")
.version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS"))
.about("Launch a vhost-user-net backend.")
.arg(
Arg::new("net-backend")
.long("net-backend")
.help(vhost_user_net::SYNTAX)
.num_args(1)
.required(true),
)
.get_matches();
if toplevel.version { let backend_command = cmd_arguments.get_one::<String>("net-backend").unwrap();
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION")); start_net_backend(backend_command);
return;
}
if toplevel.backend_command.is_none() {
println!("Please specify --net-backend");
std::process::exit(1)
}
start_net_backend(&toplevel.backend_command.unwrap());
} }

View File

@@ -15,24 +15,24 @@ byteorder = "1.4.3"
epoll = "4.3.3" epoll = "4.3.3"
event_monitor = { path = "../event_monitor" } event_monitor = { path = "../event_monitor" }
libc = "0.2.147" libc = "0.2.147"
log = "0.4.17" log = "0.4.20"
net_gen = { path = "../net_gen" } net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" } net_util = { path = "../net_util" }
pci = { path = "../pci" } pci = { path = "../pci" }
rate_limiter = { path = "../rate_limiter" } rate_limiter = { path = "../rate_limiter" }
seccompiler = "0.3.0" seccompiler = "0.4.0"
serde = { version = "1.0.168", features = ["derive"] } serde = { version = "1.0.168", features = ["derive"] }
serde_json = "1.0.107" serde_json = "1.0.107"
serial_buffer = { path = "../serial_buffer" } serial_buffer = { path = "../serial_buffer" }
thiserror = "1.0.40" thiserror = "1.0.40"
versionize = "0.1.10" versionize = "0.1.10"
versionize_derive = "0.1.4" versionize_derive = "0.1.4"
vhost = { version = "0.8.1", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] } vhost = { version = "0.9.0", features = ["vhost-user-frontend", "vhost-user-backend", "vhost-kern", "vhost-vdpa"] }
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] } virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.9.0" virtio-queue = "0.10.0"
vm-allocator = { path = "../vm-allocator" } vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" } vm-device = { path = "../vm-device" }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] } vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" } vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" } vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0" vmm-sys-util = "0.11.0"

View File

@@ -616,7 +616,9 @@ impl Block {
(disk_nsectors, avail_features, 0, config, false) (disk_nsectors, avail_features, 0, config, false)
}; };
let serial = serial.map(Vec::from).unwrap_or(build_serial(&disk_path)); let serial = serial
.map(Vec::from)
.unwrap_or_else(|| build_serial(&disk_path));
Ok(Block { Ok(Block {
common: VirtioCommon { common: VirtioCommon {

View File

@@ -28,7 +28,7 @@ use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult}; use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize; use versionize_derive::Versionize;
use virtio_queue::{Queue, QueueT}; use virtio_queue::{Queue, QueueT};
use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic}; use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemory, GuestMemoryAtomic};
use vm_migration::VersionMapped; use vm_migration::VersionMapped;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vm_virtio::{AccessPlatform, Translatable}; use vm_virtio::{AccessPlatform, Translatable};
@@ -59,6 +59,8 @@ enum Error {
GuestMemoryRead(vm_memory::guest_memory::Error), GuestMemoryRead(vm_memory::guest_memory::Error),
#[error("Failed to write to guest memory: {0}")] #[error("Failed to write to guest memory: {0}")]
GuestMemoryWrite(vm_memory::guest_memory::Error), GuestMemoryWrite(vm_memory::guest_memory::Error),
#[error("Failed to write_all output: {0}")]
OutputWriteAll(io::Error),
#[error("Failed to flush output: {0}")] #[error("Failed to flush output: {0}")]
OutputFlush(io::Error), OutputFlush(io::Error),
#[error("Failed to add used index: {0}")] #[error("Failed to add used index: {0}")]
@@ -264,15 +266,18 @@ impl ConsoleEpollHandler {
while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) { while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) {
let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?; let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
if let Some(out) = &mut self.out { if let Some(out) = &mut self.out {
let mut buf: Vec<u8> = Vec::new();
desc_chain desc_chain
.memory() .memory()
.write_to( .write_volatile_to(
desc.addr() desc.addr()
.translate_gva(self.access_platform.as_ref(), desc.len() as usize), .translate_gva(self.access_platform.as_ref(), desc.len() as usize),
out, &mut buf,
desc.len() as usize, desc.len() as usize,
) )
.map_err(Error::GuestMemoryRead)?; .map_err(Error::GuestMemoryRead)?;
out.write_all(&buf).map_err(Error::OutputWriteAll)?;
out.flush().map_err(Error::OutputFlush)?; out.flush().map_err(Error::OutputFlush)?;
} }
trans_queue trans_queue

View File

@@ -24,7 +24,7 @@ use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult}; use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize; use versionize_derive::Versionize;
use virtio_queue::{Queue, QueueT}; use virtio_queue::{Queue, QueueT};
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic}; use vm_memory::{GuestAddressSpace, GuestMemory, GuestMemoryAtomic};
use vm_migration::VersionMapped; use vm_migration::VersionMapped;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vm_virtio::{AccessPlatform, Translatable}; use vm_virtio::{AccessPlatform, Translatable};
@@ -75,7 +75,7 @@ impl RngEpollHandler {
// Fill the read with data from the random device on the host. // Fill the read with data from the random device on the host.
let len = desc_chain let len = desc_chain
.memory() .memory()
.read_from( .read_volatile_from(
desc.addr() desc.addr()
.translate_gva(self.access_platform.as_ref(), desc.len() as usize), .translate_gva(self.access_platform.as_ref(), desc.len() as usize),
&mut self.random_file, &mut self.random_file,

View File

@@ -86,9 +86,11 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_fsync, vec![]), (libc::SYS_fsync, vec![]),
(libc::SYS_ftruncate, vec![]), (libc::SYS_ftruncate, vec![]),
(libc::SYS_getrandom, vec![]), (libc::SYS_getrandom, vec![]),
(libc::SYS_io_destroy, vec![]),
(libc::SYS_io_getevents, vec![]),
(libc::SYS_io_submit, vec![]),
(libc::SYS_io_uring_enter, vec![]), (libc::SYS_io_uring_enter, vec![]),
(libc::SYS_lseek, vec![]), (libc::SYS_lseek, vec![]),
(libc::SYS_prctl, vec![]),
(libc::SYS_pread64, vec![]), (libc::SYS_pread64, vec![]),
(libc::SYS_preadv, vec![]), (libc::SYS_preadv, vec![]),
(libc::SYS_pwritev, vec![]), (libc::SYS_pwritev, vec![]),
@@ -102,7 +104,6 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_console_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> { fn virtio_console_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![ vec![
(libc::SYS_ioctl, create_virtio_console_ioctl_seccomp_rule()), (libc::SYS_ioctl, create_virtio_console_ioctl_seccomp_rule()),
(libc::SYS_prctl, vec![]),
(libc::SYS_sched_getaffinity, vec![]), (libc::SYS_sched_getaffinity, vec![]),
(libc::SYS_set_robust_list, vec![]), (libc::SYS_set_robust_list, vec![]),
] ]
@@ -143,7 +144,6 @@ fn virtio_pmem_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_rng_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> { fn virtio_rng_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![ vec![
(libc::SYS_prctl, vec![]),
(libc::SYS_sched_getaffinity, vec![]), (libc::SYS_sched_getaffinity, vec![]),
(libc::SYS_set_robust_list, vec![]), (libc::SYS_set_robust_list, vec![]),
] ]
@@ -214,7 +214,6 @@ fn virtio_vsock_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_watchdog_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> { fn virtio_watchdog_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![ vec![
(libc::SYS_prctl, vec![]),
(libc::SYS_sched_getaffinity, vec![]), (libc::SYS_sched_getaffinity, vec![]),
(libc::SYS_set_robust_list, vec![]), (libc::SYS_set_robust_list, vec![]),
(libc::SYS_timerfd_settime, vec![]), (libc::SYS_timerfd_settime, vec![]),

View File

@@ -955,8 +955,9 @@ impl PciDevice for VirtioPciDevice {
fn allocate_bars( fn allocate_bars(
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, _allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new(); let mut bars = Vec::new();
@@ -995,7 +996,7 @@ impl PciDevice for VirtioPciDevice {
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004 // See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
let (virtio_pci_bar_addr, region_type) = if use_64bit_bar { let (virtio_pci_bar_addr, region_type) = if use_64bit_bar {
let region_type = PciBarRegionType::Memory64BitRegion; let region_type = PciBarRegionType::Memory64BitRegion;
let addr = mmio_allocator let addr = mmio64_allocator
.allocate( .allocate(
settings_bar_addr, settings_bar_addr,
CAPABILITY_BAR_SIZE, CAPABILITY_BAR_SIZE,
@@ -1005,10 +1006,8 @@ impl PciDevice for VirtioPciDevice {
(addr, region_type) (addr, region_type)
} else { } else {
let region_type = PciBarRegionType::Memory32BitRegion; let region_type = PciBarRegionType::Memory32BitRegion;
let addr = allocator let addr = mmio32_allocator
.lock() .allocate(
.unwrap()
.allocate_mmio_hole_addresses(
settings_bar_addr, settings_bar_addr,
CAPABILITY_BAR_SIZE, CAPABILITY_BAR_SIZE,
Some(CAPABILITY_BAR_SIZE), Some(CAPABILITY_BAR_SIZE),
@@ -1078,16 +1077,17 @@ impl PciDevice for VirtioPciDevice {
fn free_bars( fn free_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, _allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator, mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> std::result::Result<(), PciDeviceError> { ) -> std::result::Result<(), PciDeviceError> {
for bar in self.bar_regions.drain(..) { for bar in self.bar_regions.drain(..) {
match bar.region_type() { match bar.region_type() {
PciBarRegionType::Memory32BitRegion => { PciBarRegionType::Memory32BitRegion => {
allocator.free_mmio_hole_addresses(GuestAddress(bar.addr()), bar.size()); mmio32_allocator.free(GuestAddress(bar.addr()), bar.size());
} }
PciBarRegionType::Memory64BitRegion => { PciBarRegionType::Memory64BitRegion => {
mmio_allocator.free(GuestAddress(bar.addr()), bar.size()); mmio64_allocator.free(GuestAddress(bar.addr()), bar.size());
} }
_ => error!("Unexpected PCI bar type"), _ => error!("Unexpected PCI bar type"),
} }

View File

@@ -23,7 +23,7 @@ use vhost::vhost_user::message::{
VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures,
VHOST_USER_CONFIG_OFFSET, VHOST_USER_CONFIG_OFFSET,
}; };
use vhost::vhost_user::{MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler}; use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler};
use virtio_bindings::virtio_blk::{ use virtio_bindings::virtio_blk::{
VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_FLUSH,
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_SEG_MAX,
@@ -50,8 +50,8 @@ pub struct State {
impl VersionMapped for State {} impl VersionMapped for State {}
struct SlaveReqHandler {} struct BackendReqHandler {}
impl VhostUserMasterReqHandler for SlaveReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {}
pub struct Blk { pub struct Blk {
common: VirtioCommon, common: VirtioCommon,
@@ -294,7 +294,7 @@ impl VirtioDevice for Blk {
self.common.activate(&queues, &interrupt_cb)?; self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone()); self.guest_memory = Some(mem.clone());
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None; let backend_req_handler: Option<FrontendReqHandler<BackendReqHandler>> = None;
// Run a dedicated thread for handling potential reconnections with // Run a dedicated thread for handling potential reconnections with
// the backend. // the backend.
@@ -305,7 +305,7 @@ impl VirtioDevice for Blk {
queues, queues,
interrupt_cb, interrupt_cb,
self.common.acked_features, self.common.acked_features,
slave_req_handler, backend_req_handler,
kill_evt, kill_evt,
pause_evt, pause_evt,
)?; )?;

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