Compare commits

..

369 Commits
v23.0 ... v25.0

Author SHA1 Message Date
Rob Bradford
b132cd2145 build: Release v25.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-07 15:18:55 +01:00
Sebastien Boeuf
a650b8645f deps: bump virtio-queue from 0.3.0 to 0.4.0
And along with virtio-queue, we must also bump vhost-user-backend from
0.3.0 to 0.5.0 (since it relies on virtio-queue 0.4.0).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-06 16:57:09 +02:00
Sebastien Boeuf
f94a5fb4e3 virtio-devices: Pass negotiated queue size to vhost-user backend
The vhost-user backend was always provided the maximum queue size but
this is incorrect. Instead it must be informed of the actual queue size
that has been negotiated with the virtio driver running in the guest.

This ensures proper functioning of vhost-user-block with the Rust
Hypervisor Firmware, which uses a hardcoded queue size of 16.

Partially fixes #4285

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-06 14:45:46 +01:00
Sebastien Boeuf
00800b8499 virtio-devices: Remove deprecated call to VHOST_USER_RESET_OWNER
The latest vhost-user specification describes VHOST_USER_RESET_OWNER
command as deprecated with the following explanation:

  This is no longer used. Used to be sent to request disabling all
  rings, but some back-ends interpreted it to also discard connection
  state (this interpretation would lead to bugs). It is recommended that
  back-ends either ignore this message, or use it to disable all rings.

Also, it's been observed that when using either Rust Hypervisor Firmware
or EDK2 OVMF firmware with SPDK (using the block device as the boot
disk), the virtio reset that happens when the firmware no longer needs
to access the block device caused a failure by triggering the command
VHOST_USER_RESET_OWNER.

For all these reasons, this patch simplifies the virtio reset
implementation by simply disabling the virtqueues and no longer calling
into VHOST_USER_RESET_OWNER.

Partially fixes #4285

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-06 14:45:46 +01:00
dependabot[bot]
0b311f6c4c build: bump once_cell from 1.12.1 to 1.13.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.1 to 1.13.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.1...v1.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 02:35:11 +00:00
dependabot[bot]
8063c00e67 build: bump openssl-src from 111.21.0+1.1.1p to 111.22.0+1.1.1q
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.21.0+1.1.1p to 111.22.0+1.1.1q.
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 01:47:30 +00:00
dependabot[bot]
4f611c8654 build: bump serde from 1.0.137 to 1.0.138
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.137 to 1.0.138.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.137...v1.0.138)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 00:56:48 +00:00
dependabot[bot]
d291b87288 build: bump regex from 1.5.6 to 1.6.0
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.6 to 1.6.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.6...1.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 00:02:30 +00:00
dependabot[bot]
51787d30da build: bump once_cell from 1.12.1 to 1.13.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.1 to 1.13.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.1...v1.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-05 23:47:51 +00:00
Sebastien Boeuf
63579341e1 net_util: Don't expect the interface to be IFF_RUNNING
Enabling the TAP interface is only about the IFF_UP flag, meaning we
shouldn't be testing the presence of IFF_RUNNING, and therefore we
shouldn't set it when not present.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-05 16:35:58 +01:00
dependabot[bot]
9c0872def7 build: bump once_cell from 1.12.0 to 1.12.1
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.0...v1.12.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-05 11:39:42 +00:00
Rob Bradford
5dfc49c9fa build: Update development container to Rust 1.62
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-05 11:50:46 +01:00
dependabot[bot]
65f8c3682f build: bump serde from 1.0.137 to 1.0.138 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.137 to 1.0.138.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.137...v1.0.138)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-05 00:04:25 +00:00
dependabot[bot]
c87466eea2 build: bump once_cell from 1.12.0 to 1.12.1 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.0...v1.12.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 23:36:34 +00:00
Rob Bradford
6c365617ee Revert "scripts, README.md: Bump reference kernel to 5.18.8"
This reverts commit 1999ab5707.

See: #4273

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-04 10:55:28 +01:00
Rob Bradford
30da293d8f tests: Report stderr on ch-remote command failure
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-04 09:18:18 +02:00
Rob Bradford
67bfd4e234 tests: tests_api_create_boot: Use ch-remote for creating and booting vm
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-04 09:18:18 +02:00
Rob Bradford
46bbe0e612 ch-remote: Simplify ch-remote create from config file
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-04 09:18:18 +02:00
dependabot[bot]
216f330f4e build: bump semver from 1.0.11 to 1.0.12
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.11...1.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-02 00:51:37 +00:00
dependabot[bot]
bd075872d4 build: bump mshv-bindings from d94c305 to 7ac1b80
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `d94c305` to `7ac1b80`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](d94c30583f...7ac1b80bff)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 23:57:38 +00:00
dependabot[bot]
7fd5f41623 build: bump semver from 1.0.11 to 1.0.12 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.11...1.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 23:44:45 +00:00
Rob Bradford
93237f0106 vmm: Set MADT "Online Capable" flag
The Linux kernel now checks for this before marking CPUs as
hotpluggable:

commit aa06e20f1be628186f0c2dcec09ea0009eb69778
Author: Mario Limonciello <mario.limonciello@amd.com>
Date:   Wed Sep 8 16:41:46 2021 -0500

    x86/ACPI: Don't add CPUs that are not online capable

    A number of systems are showing "hotplug capable" CPUs when they
    are not really hotpluggable.  This is because the MADT has extra
    CPU entries to support different CPUs that may be inserted into
    the socket with different numbers of cores.

    Starting with ACPI 6.3 the spec has an Online Capable bit in the
    MADT used to determine whether or not a CPU is hotplug capable
    when the enabled bit is not set.

    Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html?#local-apic-flags
    Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-01 18:45:05 +01:00
Rob Bradford
0c82e7593d tests: Remove test on available entropy bits
As far as I can tell this always reports 256 for us now:
https://lore.kernel.org/lkml/YmlMGx6+uigkGiZ0@zx2c4.com/

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-01 18:45:05 +01:00
Rob Bradford
1999ab5707 scripts, README.md: Bump reference kernel to 5.18.8
This marginally reduced the number of patches in the fork.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-07-01 18:45:05 +01:00
dependabot[bot]
5c22f02f32 build: bump clap from 3.2.7 to 3.2.8
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.7 to 3.2.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/v3.2.7...v3.2.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 22:07:39 +00:00
dependabot[bot]
c7afb44c5a build: bump smallvec from 1.8.1 to 1.9.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.8.1...v1.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 22:00:55 +01:00
Rob Bradford
b0afeeeb65 ch-remote: Add "create" command to ch-remote
Tested by:
1. Path: ch-remote --api-socket .. create test-config.json
2. stdin with "-" path: ch-remote --api-socket .. create - < test-config.json
2. stding with implicit "-": ch-remote --api-socket .. create < test-config.json

Fixes: #4250

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 21:29:54 +01:00
dependabot[bot]
cb53a8b40c build: bump semver from 1.0.10 to 1.0.11
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.10 to 1.0.11.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.10...1.0.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 20:51:02 +01:00
Rob Bradford
adf5881757 build: #[allow(clippy::significant_drop_in_scrutinee) in some crates
This check is new in the beta version of clippy and exists to avoid
potential deadlocks by highlighting when the test in an if or for loop
is something that holds a lock. In many cases we would need to make
significant refactorings to be able to pass this check so disable in the
affected crates.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 20:50:45 +01:00
Rob Bradford
44eca31642 build: Fix beta clippy issue (needless_return)
warning: accessing first element with `data.get(0)`
    --> virtio-devices/src/transport/pci_device.rs:1055:34
     |
1055 |                 if let Some(v) = data.get(0) {
     |                                  ^^^^^^^^^^^ help: try: `data.first()`
     |
     = note: `#[warn(clippy::get_first)]` on by default
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 20:50:45 +01:00
Rob Bradford
b57d7b258d build: Fix beta clippy issue (needless_return)
warning: unneeded `return` statement
   --> pci/src/vfio_user.rs:627:13
    |
627 | /             return Err(std::io::Error::new(
628 | |                 std::io::ErrorKind::Other,
629 | |                 format!("Region not found for 0x{:x}", gpa),
630 | |             ));
    | |_______________^
    |
    = note: `#[warn(clippy::needless_return)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
help: remove `return`
    |
627 ~             Err(std::io::Error::new(
628 +                 std::io::ErrorKind::Other,
629 +                 format!("Region not found for 0x{:x}", gpa),
630 +             ))
    |

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 20:50:45 +01:00
Rob Bradford
d7decfd525 build: Fix beta clippy issue (unnecessary_to_owned)
warning: unnecessary use of `to_vec`
  --> acpi_tables/src/aml.rs:71:37
   |
71 |             bytes.extend_from_slice(&part.to_vec());
   |                                     ^^^^^^^^^^^^^^ help: use: `part.as_ref()`
   |
   = note: `#[warn(clippy::unnecessary_to_owned)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 20:50:45 +01:00
Rob Bradford
2716bc3311 build: Fix beta clippy issue (derive_partial_eq_without_eq)
warning: you are deriving `PartialEq` and can implement `Eq`
  --> vmm/src/serial_manager.rs:59:30
   |
59 | #[derive(Debug, Clone, Copy, PartialEq)]
   |                              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-30 20:50:45 +01:00
dependabot[bot]
9cf0dee264 build: bump mshv-ioctls from 27477b7 to d94c305
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `27477b7` to `d94c305`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](27477b713d...d94c30583f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 18:22:23 +01:00
dependabot[bot]
d8b3d07825 build: bump clap from 3.2.7 to 3.2.8 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.7 to 3.2.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/v3.2.7...v3.2.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 17:57:04 +01:00
dependabot[bot]
3d66e86604 build: bump serde_json from 1.0.81 to 1.0.82
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.81 to 1.0.82.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.81...v1.0.82)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 17:56:47 +01:00
dependabot[bot]
a2164873ac build: bump semver from 1.0.10 to 1.0.11 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.10 to 1.0.11.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.10...1.0.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 17:37:28 +01:00
dependabot[bot]
7f8cf4f8e7 build: bump serde_json from 1.0.81 to 1.0.82 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.81 to 1.0.82.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.81...v1.0.82)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 17:05:29 +01:00
dependabot[bot]
aedbd7ae27 build: bump clap_lex from 0.2.3 to 0.2.4 in /fuzz
Bumps [clap_lex](https://github.com/clap-rs/clap) from 0.2.3 to 0.2.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.2.3...clap_lex-v0.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 16:20:56 +01:00
dependabot[bot]
bb4461e951 build: bump clap_lex from 0.2.3 to 0.2.4
Bumps [clap_lex](https://github.com/clap-rs/clap) from 0.2.3 to 0.2.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.2.3...clap_lex-v0.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-29 01:23:11 +00:00
dependabot[bot]
54fe5fb9f5 build: bump clap from 3.2.6 to 3.2.7
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.6 to 3.2.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/v3.2.6...v3.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-29 00:26:54 +00:00
dependabot[bot]
5a9e7ee7fe build: bump clap from 3.2.6 to 3.2.7 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.6 to 3.2.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/v3.2.6...v3.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-28 23:39:43 +00:00
Rob Bradford
2e664dca64 vmm: Always reset the console mode on VMM exit
Tested:

1. SIGTERM based
2. VM shutdown/poweroff
3. Injected VM boot failure after calling Vm::setup_tty()

Fixes: #4248

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-28 16:45:27 +01:00
dependabot[bot]
a26f86f8ad build: bump smallvec from 1.8.0 to 1.8.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.8.0...v1.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 23:56:42 +00:00
dependabot[bot]
fde13889f4 build: bump arbitrary from 1.1.2 to 1.1.3 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.1.2...v1.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 23:43:02 +00:00
Rob Bradford
65ec6631fb vmm: cpu: Store the vCPU snapshots in ascending order
The snapshots are stored in a BTree which is ordered however as the ids
are strings lexical ordering places "11" ahead of "2". So encode the
vCPU id with zero padding so it is lexically sorted.

This fixes issues with CPU restore on aarch64.

See: #4239

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-27 16:20:57 +01:00
Dylan Bargatze
6ac8dc8745 Change to .
Signed-off-by: Dylan Bargatze <dbargatz@users.noreply.github.com>
2022-06-27 11:24:57 +01:00
Wei Liu
2f514523dd hypervisor: emulator: use matches!
No functional change. Just make the code a bit nicer to read.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-23 17:30:21 +02:00
dependabot[bot]
92f559f6f2 build: bump vfio-ioctls from f75a77c to 38272d3
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `f75a77c` to `38272d3`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](f75a77c1ab...38272d3f06)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-23 06:19:10 +00:00
dependabot[bot]
3972e38371 build: bump mshv-bindings from bec9eba to 27477b7
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `bec9eba` to `27477b7`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](bec9ebaac3...27477b713d)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-23 05:32:24 +00:00
dependabot[bot]
a1a016526f build: bump clap from 3.2.5 to 3.2.6
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.5 to 3.2.6.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.5...v3.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 04:35:13 +00:00
dependabot[bot]
a5692a95c1 build: bump quote from 1.0.19 to 1.0.20
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.19...1.0.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 03:28:22 +00:00
dependabot[bot]
0fd25b3246 build: bump clap_lex from 0.2.2 to 0.2.3 in /fuzz
Bumps [clap_lex](https://github.com/clap-rs/clap) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.2.2...clap_lex-v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 02:55:23 +00:00
dependabot[bot]
e6127df703 build: bump clap_lex from 0.2.2 to 0.2.3
Bumps [clap_lex](https://github.com/clap-rs/clap) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.2.2...clap_lex-v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 02:23:56 +00:00
dependabot[bot]
559657eecc build: bump indexmap from 1.9.0 to 1.9.1 in /fuzz
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/1.9.0...1.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 01:52:44 +00:00
dependabot[bot]
66f1ec0063 build: bump indexmap from 1.9.0 to 1.9.1
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/1.9.0...1.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 01:19:00 +00:00
dependabot[bot]
13d081ac47 build: bump quote from 1.0.19 to 1.0.20 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.19...1.0.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 00:49:19 +00:00
dependabot[bot]
b12f4ccade build: bump openssl-src from 111.20.0+1.1.1o to 111.21.0+1.1.1p
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.20.0+1.1.1o to 111.21.0+1.1.1p.
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 00:27:48 +00:00
dependabot[bot]
1f8bca4840 build: bump clap from 3.2.5 to 3.2.6 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.5 to 3.2.6.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.5...v3.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 00:13:52 +00:00
dependabot[bot]
833eb2ebe6 build: bump proc-macro2 from 1.0.39 to 1.0.40
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.39 to 1.0.40.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.39...1.0.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 11:50:46 +00:00
dependabot[bot]
7c7f0f1f5f build: bump proc-macro2 from 1.0.39 to 1.0.40 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.39 to 1.0.40.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.39...1.0.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 11:42:40 +01:00
dependabot[bot]
d445ec7633 build: bump syn from 1.0.96 to 1.0.98
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.96 to 1.0.98.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.96...1.0.98)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 11:42:30 +01:00
dependabot[bot]
039e758f15 build: bump syn from 1.0.96 to 1.0.98 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.96 to 1.0.98.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.96...1.0.98)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 01:05:33 +00:00
dependabot[bot]
eb55d0809e build: bump anyhow from 1.0.57 to 1.0.58
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.57...1.0.58)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 00:46:25 +00:00
dependabot[bot]
ecde44617b build: bump quote from 1.0.18 to 1.0.19 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.18...1.0.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 00:31:52 +00:00
dependabot[bot]
58e567b309 build: bump quote from 1.0.18 to 1.0.19
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.18...1.0.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 23:58:53 +00:00
dependabot[bot]
fa0140a183 build: bump anyhow from 1.0.57 to 1.0.58 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.57...1.0.58)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 23:40:45 +00:00
Wei Liu
c6c5e4ee87 vhost_user_block: drop Sync bound for DiskFile
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 23:28:57 +01:00
Wei Liu
a64bdcf3f5 hypervisor: drop Send+Sync bounds for PlatformEmulator
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 23:28:57 +01:00
Wei Liu
439823e7ea virtio-devices: drop Send+Sync bounds for DmaRemapping
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 23:28:57 +01:00
Wei Liu
9019086625 block_util: drop Sync bound for DiskFile and AsyncIo
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 23:28:57 +01:00
Wei Liu
bccd7c7e48 vmm: drop Sync+Send bounds for EndpointHandler
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 23:28:57 +01:00
Wei Liu
f1dc7f442a net_util: switch from lazy_static to once_cell
Once_cell does not require using macro and is slated to become part of
Rust std at some point.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 16:03:07 +01:00
Wei Liu
32b855df3a tests: switch from lazy_static to once_cell
Once_cell does not require using macro and is slated to become part of
Rust std at some point.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 16:03:07 +01:00
Wei Liu
8fa1098629 vmm: switch from lazy_static to once_cell
Once_cell does not require using macro and is slated to become part of
Rust std at some point.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-06-20 16:03:07 +01:00
dependabot[bot]
41cec53bb8 build: bump indexmap from 1.8.2 to 1.9.0
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.2 to 1.9.0.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.2...1.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-18 00:40:57 +00:00
dependabot[bot]
fd9f14893b build: bump indexmap from 1.8.2 to 1.9.0 in /fuzz
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.2 to 1.9.0.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.2...1.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 23:52:48 +00:00
Rob Bradford
7c8719b4ea tests: Unify API based boot across architectures
Use direct kernel boot for all the tests that create the VM via API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-17 16:52:56 +01:00
Sebastien Boeuf
335a4e1cc0 vmm: api: Expose kvm_hyperv parameter in OpenAPI description
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-17 15:11:53 +01:00
dependabot[bot]
6dbbd0363f build: bump mshv-bindings from cda9d65 to bec9eba
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `cda9d65` to `bec9eba`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](cda9d658f4...bec9ebaac3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 13:11:28 +00:00
dependabot[bot]
40e1ad3f62 build: bump arbitrary from 1.1.1 to 1.1.2 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/1.1.1...v1.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-16 23:43:08 +00:00
Rob Bradford
094625242d tests: Add tests for vm.delete and vm.shutdown
Fixes: #1295

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-16 11:29:33 +01:00
Rob Bradford
b3569f084d ch-remote: Add missing boot and delete commands
These are simple commands so require no further enabling than adding to
the list of commands.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-16 11:29:33 +01:00
dependabot[bot]
3800212def build: bump clap from 3.2.4 to 3.2.5
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.4 to 3.2.5.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.4...v3.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-16 10:09:02 +00:00
dependabot[bot]
e9f5052fcd build: bump mshv-ioctls from 82be857 to cda9d65
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `82be857` to `cda9d65`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](82be8577d1...cda9d658f4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-16 10:08:50 +01:00
Rob Bradford
a583b055f5 docs: Add LBR profiling instructions to profiling.md
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-16 07:43:36 +01:00
dependabot[bot]
2b33e66bb4 build: bump clap from 3.2.4 to 3.2.5 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.4 to 3.2.5.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.2.4...v3.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 23:41:07 +00:00
dependabot[bot]
92ceef52c8 build: bump mshv-ioctls from ae24471 to 82be857
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `ae24471` to `82be857`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](ae244716b3...82be8577d1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 03:09:04 +00:00
dependabot[bot]
d7baa58e11 build: bump unicode-ident from 1.0.0 to 1.0.1
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.0...1.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 02:04:21 +00:00
dependabot[bot]
2d39b6ed06 build: bump getrandom from 0.2.6 to 0.2.7 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.6 to 0.2.7.
- [Release notes](https://github.com/rust-random/getrandom/releases)
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.6...v0.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 01:09:41 +00:00
dependabot[bot]
ed31ca9041 build: bump gdbstub_arch from 0.2.2 to 0.2.3
Bumps [gdbstub_arch](https://github.com/daniel5151/gdbstub) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 00:59:21 +00:00
dependabot[bot]
06b880e99f build: bump clap from 3.2.1 to 3.2.4 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.2.1 to 3.2.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.2.1...v3.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 00:39:46 +00:00
dependabot[bot]
742ca68070 build: bump clap from 3.1.18 to 3.2.4
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.18 to 3.2.4.
- [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/v3.1.18...v3.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 23:58:30 +00:00
dependabot[bot]
f950cb1fdb build: bump arbitrary from 1.1.0 to 1.1.1 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/rust-fuzz/arbitrary/releases)
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/commits/1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 23:50:22 +00:00
dependabot[bot]
c6c5dca651 build: bump micro_http from a730d86 to 863b037
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `a730d86` to `863b037`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](a730d86940...863b0370ba)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 14:59:13 +00:00
dependabot[bot]
d646e10079 build: bump clap_lex from 0.2.0 to 0.2.2
Bumps [clap_lex](https://github.com/clap-rs/clap) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.2.0...clap_lex-v0.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 09:44:39 +00:00
dependabot[bot]
efe0429a9a build: bump getrandom from 0.2.6 to 0.2.7
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.6 to 0.2.7.
- [Release notes](https://github.com/rust-random/getrandom/releases)
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.6...v0.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 08:57:32 +00:00
dependabot[bot]
1f3321c50e build: bump gdbstub from 0.6.1 to 0.6.2
Bumps [gdbstub](https://github.com/daniel5151/gdbstub) from 0.6.1 to 0.6.2.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.6.1...0.6.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 08:09:13 +00:00
dependabot[bot]
c0d51eecf1 build: bump unicode-ident from 1.0.0 to 1.0.1 in /fuzz
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.0...1.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 00:13:03 +00:00
dependabot[bot]
1b9dc80469 build: bump clap from 3.1.18 to 3.2.1 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.18 to 3.2.1.
- [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/v3.1.18...clap_complete-v3.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 23:46:23 +00:00
dependabot[bot]
43d32a7288 build: bump semver from 1.0.9 to 1.0.10 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-11 01:49:02 +00:00
dependabot[bot]
27e04e41bf build: bump semver from 1.0.9 to 1.0.10
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-11 01:13:07 +00:00
dependabot[bot]
41ac48d332 build: bump uuid from 1.1.1 to 1.1.2
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.1...1.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-11 00:25:45 +00:00
dependabot[bot]
2afaed9111 build: bump uuid from 1.1.1 to 1.1.2 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.1...1.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 23:39:30 +00:00
Rob Bradford
f1ea69474d scripts: Mark git repository as safe
Git will refuse to generate information for the report if the repository
is owned by a different user (root in the container vs the real owner
outside).

e.g:

Error generating human readable git reference: fatal: unsafe repository ('/cloud-hypervisor' is owned by someone else)
To add an exception for this directory, call:

	git config --global --add safe.directory /cloud-hypervisor

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-10 17:20:13 +01:00
Rob Bradford
cac42301f8 performance-metrics: Produce some error messages if git commands fail
It is reasonable for these to fail as it the tool could be run outside
of a git repository but by not giving any error message we cannot see
issues when we expect the report to have the git details.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-10 17:20:13 +01:00
Jinank Jain
ada85f68f6 hypervisor: mshv: Override hypervisor R/W behavior for unknown MSR
By default Microsoft Hypervisor send a GP to the guest if it tries
read/write an unimplemented MSR from the hypervisor prospective. Instead
change this behavior to ignore read/write operations for unimplemented
MSRs

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2022-06-09 20:53:58 +01:00
Rob Bradford
64b4b7205e Revert "build: Temporarily disable VFIO, SGX and metrics build steps"
This reverts commit d96614fe42.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-09 10:30:07 +01:00
dependabot[bot]
4a4352f9d9 build: bump mshv-ioctls from 67e13fa to ae24471
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `67e13fa` to `ae24471`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](67e13faa36...ae244716b3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-09 08:46:46 +00:00
Sebastien Boeuf
81ba70a497 pci, vmm: Defer mapping VFIO MMIO regions on restore
When restoring a VM, the restore codepath will take care of mapping the
MMIO regions based on the information from the snapshot, rather than
having the mapping being performed during device creation.

When the device is created, information such as which BARs contain the
MSI-X tables are missing, preventing to perform the mapping of the MMIO
regions.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
7df7061610 pci, vmm: Add migratable support to vfio-user devices
Based on recent changes to VfioUserPciDevice, the vfio-user devices can
now be migrated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
c021dda267 pci, vmm: Add migratable support to VFIO devices
Based on recent changes to VfioPciDevice, the VFIO devices can now be
migrated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
f48b05eee6 pci: vfio_user: Implement Migratable for VfioUserPciDevice
Based on the VfioCommon implementation, the VfioUserPciDevice now
implements the Migratable trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
3b59e57001 pci: vfio: Implement Migratable for VfioPciDevice
Based on the VfioCommon implementation, the VfioPciDevice now implements
the Migratable trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
49069d8474 pci: Implement Migratable for VfioCommon
Introduces the common code to handle one aspect of the migration
support. Particularly, the ability to store VMM internal states related
to such device. The internal state of the device will happen later in a
dedicated patchset that will implement the VFIO migration API.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
8eaefa6e8e pci: msix: Derive Versionize for MsixCap
So that we can save and restore the whole structure through snapshot and
restore operations.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Sebastien Boeuf
a1b996ac37 pci: msi: Make MsiCap field public
So that it can be accessed during a VM snapshot to store its state.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-09 09:19:58 +02:00
Rob Bradford
4ddc6ffd73 .github: Add missing clippy check with "guest_debug" feature
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-08 11:40:56 +01:00
Rob Bradford
94fb9f817d vmm: Fix clippy issues under "guest_debug" feature
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-08 11:40:56 +01:00
Rob Bradford
133a5a858a vmm: Pull in gdb dependencies only when building with feature
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-08 11:30:20 +01:00
Jinank Jain
3a18860326 Reapply "Jenkinsfile: Bypass running CI for fuzzer Cargo file changes"
This reverts commit 0d0013c46e.

Grovvy shell script execution engine does not like backslash as the
escape character. So we need to put another backslash to escape the
backslash character. This would most likely fix the issue that we saw
with the CI.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2022-06-07 07:40:33 +01:00
Rob Bradford
0d0013c46e Revert "Jenkinsfile: Bypass running CI for fuzzer Cargo file changes"
This reverts commit 86d243938e.

Build error:

Obtained Jenkinsfile from 86d243938e
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 311: unexpected char: '\' @ line 311, column 88.
   _TARGET}... | grep -v -E 'fuzz\/Cargo.(t

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-06 15:38:18 +01:00
Jinank Jain
86d243938e Jenkinsfile: Bypass running CI for fuzzer Cargo file changes
In order to conserve resources it is better to not run CI, whenever there
are changes only in fuzz/Cargo.toml or fuzz/Cargo.lock.

Fixes #4148

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2022-06-06 15:29:19 +01:00
Michael Zhao
a7a15d56dd aarch64: Move setup_regs to hypervisor
`setup_regs` of AArch64 calls KVM sepecific code. Now move it to
`hypervisor` crate.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 11:07:46 +01:00
Sebastien Boeuf
65dc1c83a9 vmm: cpu: Save and restore CPU states during snapshot/restore
Based on recent KVM host patches (merged in Linux 5.16), it's forbidden
to call into KVM_SET_CPUID2 after the first successful KVM_RUN returned.
That means saving CPU states during the pause sequence, and restoring
these states during the resume sequence will not work with the current
design starting with kernel version 5.16.

In order to solve this problem, let's simply move the save/restore logic
to the snapshot/restore sequences rather than the pause/resume ones.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-06 11:07:29 +01:00
Sebastien Boeuf
3edaa8adb6 vmm: Ensure restore matches boot sequence
The vCPU is created and set after all the devices on a VM's boot.
There's no reason to follow a different order on the restore codepath as
this could cause some unexpected behaviors.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-06-06 11:07:17 +01:00
Michael Zhao
9260c3816e vmm: Update unit test for GIC refactoring
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
5d45d6d0fb vmm: Move GIC unit test to hypervisor crate
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
957d3a7443 aarch64: Simplify GIC related structs definition
Combined the `GicDevice` struct in `arch` crate and the `Gic` struct in
`devices` crate.

After moving the KVM specific code for GIC in `arch`, a very thin wapper
layer `GicDevice` was left in `arch` crate. It is easy to combine it
with the `Gic` in `devices` crate.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
04949755c0 arch: Switch to new GIC interface
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
b8dbb26647 hypervisor: Refactor save_pending_tables of Vgic
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
3fe7d61a02 hypervisor: Remove some redundant parameters
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
c2862b6947 hypervisor: Move GitV3Its code from arch
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
Michael Zhao
03b01c02cd hypervisor: Define Vgic trait
Defined `Vgic` trait as the hypervisor agnostic interface for a virtual
GIC.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-06-06 10:17:26 +08:00
dependabot[bot]
435d769511 build: bump syn from 1.0.95 to 1.0.96
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.95 to 1.0.96.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.95...1.0.96)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-03 12:15:08 +00:00
dependabot[bot]
9ba6767a90 build: bump pnet from 0.30.0 to 0.31.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.30.0...v0.31.0)

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

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: dependabot[bot] <support@github.com>
2022-06-03 08:59:43 +00:00
dependabot[bot]
3742cc42ae build: bump syn from 1.0.95 to 1.0.96 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.95 to 1.0.96.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.95...1.0.96)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-03 01:57:33 +00:00
dependabot[bot]
e0dd2e41c2 build: bump openssl-sys from 0.9.73 to 0.9.74
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.73 to 0.9.74.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.73...openssl-sys-v0.9.74)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-02 09:41:05 +00:00
dependabot[bot]
f1495b5767 build: bump uuid from 1.1.0 to 1.1.1
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.0...1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-02 00:48:36 +00:00
dependabot[bot]
6bd4bdfa26 build: bump uuid from 1.1.0 to 1.1.1 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.1.0...1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-02 00:02:36 +00:00
Rob Bradford
ade3a9c8f6 virtio-devices, vmm: Optimised async virtio device activation
In order to ensure that the virtio device thread is spawned from the vmm
thread we use an asynchronous activation mechanism for the virtio
devices. This change optimises that code so that we do not need to
iterate through all virtio devices on the platform in order to find the
one that requires activation. We solve this by creating a separate short
lived VirtioPciDeviceActivator that holds the required state for the
activation (e.g. the clones of the queues) this can then be stored onto
the device manager ready for asynchronous activation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-06-01 09:42:02 +02:00
dependabot[bot]
15e2763753 build: bump indexmap from 1.8.1 to 1.8.2
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/1.8.2/RELEASES.rst)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.1...1.8.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-31 23:58:11 +00:00
dependabot[bot]
8b87b752b5 build: bump indexmap from 1.8.1 to 1.8.2 in /fuzz
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/1.8.2/RELEASES.rst)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.1...1.8.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 23:55:59 +00:00
dependabot[bot]
7864f91a2b build: bump libz-sys from 1.1.6 to 1.1.8
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.6 to 1.1.8.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 23:50:20 +00:00
Yi Wang
6ab93a08ec build: Add GitHub action to build test guest_debug feature
Add guest_debug feature test for github workflows.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-05-30 13:41:40 +02:00
Yi Wang
fd41892065 tests: Add integration test for coredump
As coredump function is to make a vmcore for crash tool to analyze,
in order not to introduce a big thing in integration, we just check
if ch-remote command runs no error report here.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-05-30 13:41:40 +02:00
Yi Wang
dbeb922882 doc: add vm coredump support
Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-30 13:41:40 +02:00
Yi Wang
0bb2060ca7 ch-remote: add support for coredump
Adding the wrapping layer to be able to coredump the guest
from the ch-remote tool.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-05-30 13:41:40 +02:00
Yi Wang
8b585b96c1 vmm: enable coredump
Based on the newly added guest_debug feature, this patch adds http
endpoint support.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-30 13:41:40 +02:00
Yi Wang
ccb604e1e1 vmm: add cpu segment note for coredump
The crash tool use a special note segment which named 'QEMU' to
analyze kaslr info and so on. If we don't add the 'QEMU' note
segment, crash tool can't find linux version to move on.

For now, the most convenient way is to add 'QEMU' note segment to
make crash tool happy.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-05-30 13:41:40 +02:00
Yi Wang
0e65ca4a6c vmm: save guest memory for coredump
Guest memory is needed for analysis in crash tool, so save it
for coredump.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-30 13:41:40 +02:00
Yi Wang
7e280b6f70 vmm: save elf header for coredump
The vmcore file of guest is an elf format, so the first step of coredump
is to save the elf header.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-05-30 13:41:40 +02:00
Yi Wang
90034fd6ba vmm: add GuestDebuggable trait
It's useful to dump the guest, which named coredump so that crash
tool can be used to analysize it when guest hung up.

Let's add GuestDebuggable trait and Coredumpxxx error to support
coredump firstly.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-30 13:41:40 +02:00
Rob Bradford
642309f141 deps: Bump version of kvm-ioctls
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 16:36:02 +02:00
Rob Bradford
5da8a1c08e tests: Use smaller hotplug size for live migration tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 11:30:27 +02:00
Rob Bradford
465db7f08c vmm: config: Remove mergeable option from PmemConfig
Fixes: #3968

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:48:49 +02:00
Rob Bradford
55c5961f43 vmm: config: Remove dax & cache_size options from FsConfig
Fixes: #3889

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Rob Bradford
7c3582b4a8 vmm: config: Fix error message regarding use of cache size without dax
The error message incorrectly said that the user was trying to combine
cache_size without dax whereas it is only usuable with dax.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Rob Bradford
979797786d vmm: Remove DAX cache setup for virtio-fs devices
Remove the code from the DeviceManager that prepares the DAX cache since
the functionality has now been removed.

Fixes: #3889

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Rob Bradford
62120f9afe tests: Remove testing of virtio-fs DAX cache
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Rob Bradford
56c11600db tests: Rename test_virtio_fs helper
This is so we can have a test called test_virtio_fs

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Rob Bradford
f2336413be tests: Simplify virtiofsd spawning
The cache methodology is never changed so it can be hardcoded.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-27 09:47:13 +02:00
Michael Zhao
0fd6521759 aarch64: Avoid depending on layout in GIC code
Removing the dependency on `layout` helps moving GIC code into
`hypervisor` crate.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-05-27 10:57:50 +08:00
Michael Zhao
4a2d3cb4f5 aarch64: Refactor KvmGicV3Its::new()
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-05-27 10:57:50 +08:00
Michael Zhao
3fe20cc09a aarch64: Remove GicDevice trait
`GicDevice` trait was defined for the common part of GicV3 and ITS.
Now that the standalone GicV3 do not exist, `GicDevice` is not needed.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-05-27 10:57:50 +08:00
Michael Zhao
fd581b1afb aarch64: Combine the code of GicV3 and GicV3Its
Why combine:
- GicV3 is not required alone
- GicV3 and GicV3Its has separate snapshot/pause code. But the code of
  GicV3 was never used.
- Reduce the code complexity of GIC related traits and structs.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-05-27 10:57:50 +08:00
Michael Zhao
1e732bf532 aarch64: Remove versionize & versionize_derive
Remove the not-mandatory dependencies in gic source code.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-05-27 10:57:50 +08:00
dependabot[bot]
ad8295e11d build: bump os_str_bytes from 6.0.1 to 6.1.0
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.0.1 to 6.1.0.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.0.1...6.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-27 00:36:04 +00:00
dependabot[bot]
fe1f0ef49e build: bump os_str_bytes from 6.0.1 to 6.1.0 in /fuzz
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.0.1 to 6.1.0.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.0.1...6.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 23:48:45 +00:00
dependabot[bot]
f9fcc3722f build: bump uuid from 1.0.0 to 1.1.0 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.0.0...1.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 01:13:18 +00:00
dependabot[bot]
c0cbaff519 build: bump uuid from 1.0.0 to 1.1.0
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.0.0...1.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 00:27:34 +00:00
Rob Bradford
ebaea6fe0f .github: Use 1.60 toolchain consistently in release process
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-25 23:56:51 +02:00
Sebastien Boeuf
0150de55d2 build: Release v24.0
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-25 23:31:50 +02:00
Rob Bradford
75e3a3d982 tests: Use default timeout for booting in live migration tests
From the logs it appears that booting the VM to the point at which it
can signal to the host can sometimes take longer than then 30 seconds
specified.

Fixes: #4136

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-25 17:05:45 +01:00
Rob Bradford
3b10699743 scripts: Use correct date for container image
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-25 09:38:20 +01:00
Anatol Belski
d0798aad59 rpm: Extend spec to support aarch64 and more
Refactoring and features in this patch:

- Add support for aarch64 build
- Add offline build configuration using vendored crates
- Add script to generate vendored sources
- Fix openssl-sys dependency

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-05-25 10:08:27 +02:00
dependabot[bot]
e52175c2ab build: bump pnet from 0.29.0 to 0.30.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.29.0 to 0.30.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.29.0...v0.30.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-24 16:43:11 +00:00
Rob Bradford
ffd1411e7c build: Bump minimum Rust version to 1.60
Some dependencies (e.g. pnet 0.30.0) require it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-24 16:02:08 +01:00
dependabot[bot]
a14ebbb758 build: bump once_cell from 1.11.0 to 1.12.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.11.0...v1.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-24 12:09:51 +00:00
Rob Bradford
02358d3091 Revert ".github: Fix Rust version for release to 1.58"
This reverts commit 6a099257e8.

It is now clear that pinning the toolchain for cross compilation is not
necessary since we only use it for building to aarch64:

https://github.com/rust-lang/rust/issues/95926#issue-1199547707

"This problem doesn't currently show up when cross-compiling from x86_64
to aarch64, since aarch64 doesn't use static-pie by default, but
enabling PIE with -C relocation-model=pie triggers the same bug and
makes the resulting binaries segfault."

Fixes: #3962

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 16:38:27 +01:00
Rob Bradford
025447e8cc performance-metrics: Add ability to override test iterations
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 11:14:53 +01:00
Rob Bradford
d582121143 performance-metrics: Reduce verbosity for performance tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 11:14:53 +01:00
Rob Bradford
38b8e387ea test_infra: Add control of verbosity level
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 11:14:53 +01:00
Rob Bradford
3538afc1fe devices: debug_port: Move 0x80 output to warn!() level
This allows the capturing of the debug port event without requiring more
verbose logging which itself has a performance impact.

Unless users are using our custom kernel or their own custom patches
they are unlikely to see the impact.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 11:14:53 +01:00
Rob Bradford
d96614fe42 build: Temporarily disable VFIO, SGX and metrics build steps
These require machines that are currently offline.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-23 11:14:01 +01:00
dependabot[bot]
7076684124 build: bump regex from 1.5.5 to 1.5.6
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.5 to 1.5.6.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.5...1.5.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-21 21:11:50 +00:00
Rob Bradford
fa07d83565 Revert "virtio-devices, vmm: Optimised async virtio device activation"
This reverts commit f160572f9d.

There has been increased flakiness around the live migration tests since
this was merged. Speculatively reverting to see if there is increased
stability.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-21 21:27:33 +01:00
dependabot[bot]
80f6dda932 build: bump regex-syntax from 0.6.25 to 0.6.26
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.25 to 0.6.26.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-20 23:54:04 +00:00
Rob Bradford
f160572f9d virtio-devices, vmm: Optimised async virtio device activation
In order to ensure that the virtio device thread is spawned from the vmm
thread we use an asynchronous activation mechanism for the virtio
devices. This change optimises that code so that we do not need to
iterate through all virtio devices on the platform in order to find the
one that requires activation. We solve this by creating a separate short
lived VirtioPciDeviceActivator that holds the required state for the
activation (e.g. the clones of the queues) this can then be stored onto
the device manager ready for asynchronous activation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-20 17:07:13 +01:00
dependabot[bot]
9626288d4f build: bump openssl-src from 111.19.0+1.1.1o to 111.20.0+1.1.1o
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.19.0+1.1.1o to 111.20.0+1.1.1o.
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-20 10:00:25 +01:00
dependabot[bot]
e2f9c4e756 build: bump once_cell from 1.10.0 to 1.11.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.10.0...v1.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-20 10:00:08 +01:00
Sebastien Boeuf
e674577ea9 tests: Fix clippy error on latest cargo beta version
The current patch fixes the following error that was raised by clippy:

error: this let-binding has unit value
    --> tests/integration.rs:6538:13
     |
6538 | /             let _ = stdin
6539 | |                 .write_all("type=7".as_bytes())
6540 | |                 .expect("failed to write stdin");
     | |_________________________________________________^
     |
     = note: `-D clippy::let-unit-value` implied by `-D warnings`
     = help: for further information visit
https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
help: omit the `let` binding
     |
6538 ~             stdin
6539 +                 .write_all("type=7".as_bytes())
6540 +                 .expect("failed to write stdin");
     |

error: could not compile `cloud-hypervisor` due to previous error

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-20 09:59:43 +01:00
Sebastien Boeuf
49db713124 virtio-devices, vmm: Remove unused macro rules
Latest cargo beta version raises warnings about unused macro rules.
Simply remove them to fix the beta build.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-20 09:59:43 +01:00
dependabot[bot]
f0aa70c78b build: bump openssl-src from 111.18.0+1.1.1n to 111.19.0+1.1.1o
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.18.0+1.1.1n to 111.19.0+1.1.1o.
- [Release notes](https://github.com/alexcrichton/openssl-src-rs/releases)
- [Commits](https://github.com/alexcrichton/openssl-src-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-19 01:06:07 +00:00
dependabot[bot]
db3bd6bb16 build: bump mshv-bindings from e2c7657 to 67e13fa
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `e2c7657` to `67e13fa`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](e2c765737c...67e13faa36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-19 00:19:39 +00:00
Rob Bradford
5e7a77e5f9 docs: Update CONTRIBUTING.md
This document does not reflect the way the project is run. Update it to
reflect that.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-18 22:32:56 +01:00
Sebastien Boeuf
ea753b4f32 ci: Adding a CODEOWNERS file
In order to assign reviewers automatically on each pull request.

Fixes #4113

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-18 14:03:37 +01:00
Steven Dake
5587245bf2 docs: Remove an extra CR
Cut and paste doesn't quite work. Not that cut and pasters will get
this far along, but the docs should be correct in any regards.

Signed-off-by: Steven Dake <steven.dake@gmail.com>
2022-05-18 10:18:52 +01:00
Steven Dake
bc5f70d1ed docs: Add dependency qemu-img
The qemu-img tool is used as part of the tutorial but is not installed
by default on a fresh ubuntu 22.04 server.

Signed-off-by: Steven Dake <steven.dake@gmail.com>
2022-05-18 10:18:24 +01:00
dependabot[bot]
0e16ffbcff build: bump libc from 0.2.125 to 0.2.126
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.125 to 0.2.126.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.125...0.2.126)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-18 07:14:37 +00:00
Maksym Pavlenko
3a0429c998 cargo: Clean up serde dependencies
There is no need to include serde_derive separately,
as it can be specified as serde feature instead.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2022-05-18 08:21:19 +02:00
dependabot[bot]
7f29cef5d2 build: bump libc from 0.2.125 to 0.2.126 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.125 to 0.2.126.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.125...0.2.126)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 10:08:44 +00:00
dependabot[bot]
4a32f17aad build: bump syn from 1.0.94 to 1.0.95 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.94 to 1.0.95.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.94...1.0.95)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 09:22:38 +00:00
dependabot[bot]
0c452ac895 build: bump itoa from 1.0.1 to 1.0.2 in /fuzz
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.1...1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 08:32:15 +00:00
Bo Chen
32353fa389 event_monitor: Append double newlines after each event
This allows to consume and parse the output event output file.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-17 09:55:03 +02:00
Bo Chen
33e2a7121e tests: Extend 'resize_command()' with event-monitor checks
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-17 09:55:03 +02:00
Bo Chen
2eb984b45d tests: Extend existing tests with checks on event monitor
In this way, we can cover a broad range of events from the event monitor
while avoiding code duplication.

Fixes: #4054

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-17 09:55:03 +02:00
dependabot[bot]
3bcd3e7f4c build: bump ryu from 1.0.9 to 1.0.10
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 06:06:54 +00:00
dependabot[bot]
58966e952d build: bump signal-hook from 0.3.13 to 0.3.14
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.13 to 0.3.14.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.13...v0.3.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 04:18:48 +00:00
dependabot[bot]
f809f44c02 build: bump proc-macro2 from 1.0.38 to 1.0.39 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.38 to 1.0.39.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.38...1.0.39)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 03:35:39 +00:00
dependabot[bot]
c0cc5cb01d build: bump itoa from 1.0.1 to 1.0.2
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.1...1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 02:52:12 +00:00
dependabot[bot]
da4fdeb017 build: bump os_str_bytes from 6.0.0 to 6.0.1 in /fuzz
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.0.0...6.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 02:30:36 +00:00
dependabot[bot]
f5f63130bf build: bump os_str_bytes from 6.0.0 to 6.0.1
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.0.0...6.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 01:26:27 +00:00
dependabot[bot]
cb8075e53b build: bump ryu from 1.0.9 to 1.0.10 in /fuzz
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-17 00:41:52 +00:00
dependabot[bot]
30c5aeff23 build: bump syn from 1.0.94 to 1.0.95
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.94 to 1.0.95.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.94...1.0.95)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 23:59:14 +00:00
dependabot[bot]
86d09f6caa build: bump signal-hook from 0.3.13 to 0.3.14 in /fuzz
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.13 to 0.3.14.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.13...v0.3.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 23:51:05 +00:00
dependabot[bot]
7db7410920 build: bump virtio-queue from 0.2.0 to 0.3.0
Bumps [virtio-queue](https://github.com/rust-vmm/vm-virtio) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/rust-vmm/vm-virtio/releases)
- [Commits](https://github.com/rust-vmm/vm-virtio/compare/virtio-queue-v0.2.0...virtio-queue-v0.3.0)

Also relies on main branch from vhost-user-backend since it moved to
virtio-queue 0.3.0 as well, and without this change it wouldn't compile.

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-16 11:47:20 +02:00
Sebastien Boeuf
64c76693c4 virtio-devices: Clone Queue with method from vm-virtio
Rely on the newly added helper from vm-virtio crate to keep cloning the
list of Queue structures.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-16 11:47:20 +02:00
Sebastien Boeuf
c622b43f85 vm-virtio: Provide a way to clone a Queue
Since the QueueState structure has been updated by not implementing
Clone anymore, we need a way to keep cloning the Queue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-16 11:47:20 +02:00
dependabot[bot]
1651253777 build: bump syn from 1.0.93 to 1.0.94
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.93 to 1.0.94.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.93...1.0.94)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-14 00:37:27 +00:00
dependabot[bot]
3824f17516 build: bump syn from 1.0.93 to 1.0.94 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.93 to 1.0.94.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.93...1.0.94)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-13 23:50:52 +00:00
Rob Bradford
8ab3aaee6a hypervisor: emulator: Remove some glob use imports
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
12f11b5619 arch: x86_64: Remove glob import from hypervisor regs module
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
16a9882153 vmm: cpu: tdx: Don't use fd suffix for something not an FD
The hypervisor::Vcpu is the abstraction over the fd.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
2caf5e3b2b arch: Use more descriptive name for hypervisor::Vcpu than fd
This variable name is residual from when these functions acted directly
on the vCPU fd rather than the hypervisor wrapper.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
218be2642e hypervisor: Explicitly pub use at the hypervisor crate top-level
Explicitly re-export types from the hypervisor specific modules. This
makes it much clearer what the common functionality that is exposed is.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
cd0df05808 vmm, arch: CpuId is x86_64 specific so import from the x86_64 module
It will be removed as a top-level export from the hypervisor crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
4ff0686d37 hypervisor: mshv: Move CpuIdEntry alias into x86_64 module
This is consistent with kvm and correctly reflects the architectural
dependency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
288cea917e hypervisor: Make hypervisor module private
All the required functionality is already exported from the hypervisor
crate so for consistency make this module private.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
Rob Bradford
d3f66f8702 hypervisor: Make vm module private
And thus only export what is necessary through a `pub use`. This is
consistent with some of the other modules and makes it easier to
understand what the external interface of the hypervisor crate is.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-13 15:39:22 +02:00
dependabot[bot]
8e1ba99e8d build: bump clap from 3.1.17 to 3.1.18
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.17 to 3.1.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.17...v3.1.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-12 23:51:40 +00:00
Rob Bradford
3ffc105f83 hypervisor, vm-device: Relocate InterruptSourceConfig
Move this enum from vm-device to hypervisor crate so that hypervisor
crate does not gain an extra dependency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-11 11:19:14 +01:00
Rob Bradford
b1bd87df19 vmm: Simplify MsiInterruptManager generics
By taking advantage of the fact that IrqRoutingEntry is exported by the
hypervisor crate (that is typedef'ed to the hypervisor specific version)
then the code for handling the MsiInterruptManager can be simplified.

This is particularly useful if in this future it is not a typedef but
rather a wrapper type.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-11 11:19:14 +01:00
Rob Bradford
3f9e8d676a hypervisor: Move creation of irq routing struct to hypervisor crate
This removes the requirement to leak as many datastructures from the
hypervisor crate into the vmm crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-11 11:19:14 +01:00
dependabot[bot]
fe82322727 build: bump syn from 1.0.92 to 1.0.93
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.92 to 1.0.93.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.92...1.0.93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-11 02:07:09 +00:00
dependabot[bot]
e89e5c9beb build: bump syn from 1.0.92 to 1.0.93 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.92 to 1.0.93.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.92...1.0.93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-11 00:43:39 +00:00
dependabot[bot]
e85ac2695f build: bump clap from 3.1.17 to 3.1.18 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.17 to 3.1.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.17...v3.1.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-10 23:54:27 +00:00
Rob Bradford
c2c813599d vmm: Don't use kvm_ioctls directly
The IoEventAddress is re-exported through the crate at the top-level.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-10 15:57:43 +01:00
Rob Bradford
3c0817a1b7 performance-metrics: Add boot time metrics using multiple vCPUs
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-10 13:10:11 +01:00
Rob Bradford
387d56879b vmm, hypervisor: Clean up nomenclature around offloading VM operations
The trait and functionality is about operations on the VM rather than
the VMM so should be named appropriately. This clashed with with
existing struct for the concrete implementation that was renamed
appropriately.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-10 13:10:01 +01:00
dependabot[bot]
f24f35b65d build: bump proc-macro2 from 1.0.37 to 1.0.38
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.37...1.0.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-07 02:12:48 +00:00
dependabot[bot]
28926c7454 build: bump clap from 3.1.15 to 3.1.17
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.15 to 3.1.17.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.15...v3.1.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-07 01:06:10 +00:00
dependabot[bot]
24543e7076 build: bump proc-macro2 from 1.0.37 to 1.0.38 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.37...1.0.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-07 00:45:13 +00:00
dependabot[bot]
21474e280d build: bump clap from 3.1.15 to 3.1.17 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.15 to 3.1.17.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.15...v3.1.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-07 00:02:45 +00:00
Sebastien Boeuf
5f722d0d3f vmm: Fix loading RAW firmware
Whenever going through the codepath of loading a RAW firmware, we always
add an extra RAM region to the guest memory through the memory manager.
But we must be careful to use the updated guest memory rather than a
previous reference that wasn't containing the new region, as this can
lead to the following error:

VmBoot(FirmwareLoad(InvalidGuestAddress(GuestAddress(4290772992))))

This is fixed by the current patch, getting the latest reference onto
the guest memory from the memory manager right after the new region has
been added.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-06 18:13:28 +02:00
Bo Chen
06f57abdf9 pci: vfio: Fix potential mmap leaks from the mmio regions
We can return prematurely from 'map_mmio_regions()' (e.g. when a mmap call
failed for vfio or 'create_user_memory_region()' failed for vfio-user)
without updating the 'MmioRegion::user_memory_regions' with the
information of previous successful mmaps, which in turn would cause mmap
leaks particularly for the case of hotplug where the 'vmm' thread will
keep running. To fix the issue, let's keep 'MmioRegion::user_memory_regions'
updated right after successful mmap calls.

Fixes: #4068

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-06 08:57:16 +02:00
Bo Chen
42c19e14c5 vmm: Add 'shutdown()' to vCPU seccomp filter
This is required when hot-removing a vfio-user device. Details code path
below:

Thread 6 "vcpu0" received signal SIGSYS, Bad system call.
[Switching to Thread 0x7f8196889700 (LWP 2358305)]
0x00007f8196dae7ab in shutdown () at ../sysdeps/unix/syscall-template.S:78
78	T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) bt
  0x00007f8196dae7ab in shutdown () at ../sysdeps/unix/syscall-template.S:78
  0x000056189240737d in std::sys::unix::net::Socket::shutdown ()
    at library/std/src/sys/unix/net.rs:383
  std::os::unix::net::stream::UnixStream::shutdown () at library/std/src/os/unix/net/stream.rs:479
  0x000056189210e23d in vfio_user::Client::shutdown (self=0x7f8190014300)
    at vfio_user/src/lib.rs:787
  0x00005618920b9d02 in <pci::vfio_user::VfioUserPciDevice as core::ops::drop::Drop>::drop (
    self=0x7f819002d7c0) at pci/src/vfio_user.rs:551
  0x00005618920b8787 in core::ptr::drop_in_place<pci::vfio_user::VfioUserPciDevice> ()
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920b92e3 in core::ptr::drop_in_place<core::cell::UnsafeCell<dyn pci::device::PciDevice>>
    () at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920b9362 in core::ptr::drop_in_place<std::sync::mutex::Mutex<dyn pci::device::PciDevice>> () at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920d8a3e in alloc::sync::Arc<T>::drop_slow (self=0x7f81968852b8)
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/sync.rs:1092
  0x00005618920ba273 in <alloc::sync::Arc<T> as core::ops::drop::Drop>::drop (self=0x7f81968852b8)
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/sync.rs:1688
 0x00005618920b76fb in core::ptr::drop_in_place<alloc::sync::Arc<std::sync::mutex::Mutex<dyn pci::device::PciDevice>>> ()
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
 0x0000561891b5e47d in vmm::device_manager::DeviceManager::eject_device (self=0x7f8190009600,
    pci_segment_id=0, device_id=3) at vmm/src/device_manager.rs:4000
 0x0000561891b674bc in <vmm::device_manager::DeviceManager as vm_device::bus::BusDevice>::write (
    self=0x7f8190009600, base=70368744108032, offset=8, data=&[u8](size=4) = {...})
    at vmm/src/device_manager.rs:4625
 0x00005618921927d5 in vm_device::bus::Bus::write (self=0x7f8190006e00, addr=70368744108040,
    data=&[u8](size=4) = {...}) at vm-device/src/bus.rs:235
 0x0000561891b72e10 in <vmm::vm::VmOps as hypervisor::vm::VmmOps>::mmio_write (
    self=0x7f81900097b0, gpa=70368744108040, data=&[u8](size=4) = {...}) at vmm/src/vm.rs:378
 0x0000561892133ae2 in <hypervisor::kvm::KvmVcpu as hypervisor::cpu::Vcpu>::run (
    self=0x7f8190013c90) at hypervisor/src/kvm/mod.rs:1114
 0x0000561891914e85 in vmm::cpu::Vcpu::run (self=0x7f819001b230) at vmm/src/cpu.rs:348
 0x000056189189f2cb in vmm::cpu::CpuManager::start_vcpu::{{closure}}::{{closure}} ()
    at vmm/src/cpu.rs:953

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-05 15:33:26 -07:00
Sebastien Boeuf
058a61148c vmm: Factorize net creation
Since both Net and vhost_user::Net implement the Migratable trait, we
can factorize the common part to simplify the code related to the net
creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-05 13:08:41 +02:00
Sebastien Boeuf
425902b296 vmm: Factorize disk creation
Since both Block and vhost_user::Blk implement the Migratable trait, we
can factorize the common part to simplify the code related to the disk
creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-05 13:08:41 +02:00
Sebastien Boeuf
54f39aa8cb vmm: Validate vhost-user-block/net are not configured with iommu=on
Extend the validate() function for both DiskConfig and NetConfig so that
we return an error if a vhost-user-block or vhost-user-net device is
expected to be placed behind the virtual IOMMU. Since these devices
don't support this feature, we can't allow iommu to be set to true in
these cases.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-05 13:08:41 +02:00
Sebastien Boeuf
1108bd1967 pci: vfio: Implement support for sparse mmap
Reorganizing the code to leverage the same mechanics implemented for
vfio-user and aimed at supporting sparse memory mappings for a single
region.

Relying on the capabilities returned by the vfio-ioctls crate, we create
a list of sparse areas depending if we get SPARSE_MMAP or MSIX_MAPPABLE
capability, or a single sparse area in case we couldn't find any
capability.

The list of sparse areas is then used to create both the memory mappings
in the Cloud Hypervisor address space and the hypervisor user memory
regions.

This allowed for the simplification of the MmioRegion structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-05 09:28:46 +02:00
Rob Bradford
707cea2182 vmm, devices: Move logging of 0x80 timestamp to its own device
This is a cleaner approach to handling the I/O port write to 0x80.
Whilst doing this also use generate the timestamp at the start of the VM
creation. For consistency use the same timestamp for the ARM equivalent.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-04 23:02:53 +01:00
Rob Bradford
c47e3b8689 gdb: Do not use VmmOps for memory manipulation
We don't use the VmmOps trait directly for manipulating memory in the
core of the VMM as it's really designed for the MSHV crate to handle
instruction decoding. As I plan to make this trait MSHV specific to
allow reduced locking for MMIO and PIO handling when running on KVM this
use should be removed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-04 11:33:02 -07:00
Bo Chen
5bd7a1f03c pci: vfio_user: Simplify 'unmap_mmio_regions()'
Instead of always creating a single large mmap for the MMIO region of a
BAR, we create multiple mmaps for the BARs that need multiple kvm user
memory regions. In this way, we can simplify 'unmap_mmio_regions()' (by
reusing information kept from 'MmioRegion::user_memory_region').

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
c614dcb9f7 vfio_user: Embed retry of getting region caps into 'get_region_info'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
7fe399598d vmm: device_manager: Map MMIO regions to the guest correctly
To correctly map MMIO regions to the guest, we will need to wait for valid
MMIO region information which is generated from 'PciDevice::allocate_bars()'
(as a part of 'DeviceManager::add_pci_device()').

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
25a38b25c4 pci: vfio_user: Create user memory regions based on sparse areas
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
b9fb849b83 vfio_user: Parse region capability 'VFIO_REGION_INFO_CAP_SPARSE_MMAP'
Fixes: #4018

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
0c00da1dd8 vfio_user: Split the function for getting device regions
To prepare the support of region capabilities, this commit factorizes
the `VFIO_USER_DEVICE_GET_REGION_INFO` operation in its own function. In
this process, it also removes the need of the hard-coded arbitrary value
for `vfio_region_info.argsz` (the maximum size of the reply payload).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
28fb2d3235 vfio_user: Import "std::mem::size_of" for shorter reference
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Bo Chen
bf39146caa pci: vfio_user: Allow a BAR to have multiple user memory regions
Similar to what's being supported for vfio devices, vfio-user devices
may also have BARs that need multiple kvm user memory regions,
e.g. device regions with `VFIO_REGION_INFO_CAP_SPARSE_MMAP`.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-05-04 13:53:47 +02:00
Rob Bradford
1dfe4eda5c vmm: Prevent "internal" identifiers being used by user
For devices that cannot be named by the user use the "__" prefix to
identify them as internal devices. Check that any identifiers provided
in the config do not clash with those internal names. This prevents the
user from creating a disk such as "__serial" which would then cause a
failure in unpredictable manner.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-04 12:34:11 +02:00
dependabot[bot]
5530795898 build: bump serde_json from 1.0.80 to 1.0.81 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.80 to 1.0.81.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.80...v1.0.81)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 02:02:20 +00:00
dependabot[bot]
db06ef78ba build: bump num-traits from 0.2.14 to 0.2.15 in /fuzz
Bumps [num-traits](https://github.com/rust-num/num-traits) from 0.2.14 to 0.2.15.
- [Release notes](https://github.com/rust-num/num-traits/releases)
- [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.14...num-traits-0.2.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 00:58:14 +00:00
dependabot[bot]
95c6ee3e6a build: bump serde_json from 1.0.80 to 1.0.81
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.80 to 1.0.81.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.80...v1.0.81)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 00:37:09 +00:00
dependabot[bot]
d4168056be build: bump num-traits from 0.2.14 to 0.2.15
Bumps [num-traits](https://github.com/rust-num/num-traits) from 0.2.14 to 0.2.15.
- [Release notes](https://github.com/rust-num/num-traits/releases)
- [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.14...num-traits-0.2.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 23:52:08 +00:00
Rob Bradford
592a65f52e qcow: Reject files with compressed blocks early
Fixes: #3727

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-03 18:34:38 +01:00
Sebastien Boeuf
6e101f479c vmm: Ensure hotplugged device identifier is unique
Whenever a device (virtio, vfio, vfio-user or vdpa) is hotplugged, we
must verify the provided identifier is unique, otherwise we must return
an error.

Particularly, this will prevent issues with identifiers for serial,
console, IOAPIC, balloon, rng, watchdog, iommu and gpio since all of
these are hardcoded by the VMM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-03 18:34:24 +01:00
Rob Bradford
6d4862245d vmm: Generate event when device is removed
The new event contains the BDF and the device id:

{
  "timestamp": {
    "secs": 2,
    "nanos": 731073396
  },
  "source": "vm",
  "event": "device-removed",
  "properties": {
    "bdf": "0000:00:02.0",
    "id": "test-disk"
  }
}

Fixes: #4038

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-03 17:10:36 +02:00
dependabot[bot]
78abbfa604 build: bump semver from 1.0.7 to 1.0.9 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.7 to 1.0.9.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.7...1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 11:34:23 +00:00
dependabot[bot]
664c9e3eb3 build: bump clap from 3.1.14 to 3.1.15
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.14 to 3.1.15.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.14...v3.1.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 03:12:26 +00:00
dependabot[bot]
1f71c28656 build: bump openssl-sys from 0.9.72 to 0.9.73
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.72 to 0.9.73.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.72...openssl-sys-v0.9.73)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 02:25:34 +00:00
dependabot[bot]
30e06eaaba build: bump log from 0.4.16 to 0.4.17
Bumps [log](https://github.com/rust-lang/log) from 0.4.16 to 0.4.17.
- [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/commits/0.4.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 01:00:20 +00:00
dependabot[bot]
0ed196820e build: bump unicode-xid from 0.2.2 to 0.2.3 in /fuzz
Bumps [unicode-xid](https://github.com/unicode-rs/unicode-xid) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/unicode-rs/unicode-xid/releases)
- [Commits](https://github.com/unicode-rs/unicode-xid/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 00:38:13 +00:00
dependabot[bot]
bde2370b18 build: bump log from 0.4.16 to 0.4.17 in /fuzz
Bumps [log](https://github.com/rust-lang/log) from 0.4.16 to 0.4.17.
- [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/commits/0.4.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 23:54:54 +00:00
dependabot[bot]
960a9e0ff7 build: bump libc from 0.2.124 to 0.2.125
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.124 to 0.2.125.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.124...0.2.125)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 18:15:25 +00:00
dependabot[bot]
3277c27e0d build: bump serde_derive from 1.0.136 to 1.0.137
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.136 to 1.0.137.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.136...v1.0.137)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 17:27:47 +00:00
dependabot[bot]
dea10b5500 build: bump semver from 1.0.7 to 1.0.9
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.7 to 1.0.9.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.7...1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 16:40:40 +00:00
dependabot[bot]
691d9b16db build: bump serde from 1.0.136 to 1.0.137
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.136 to 1.0.137.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.136...v1.0.137)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 15:52:41 +00:00
dependabot[bot]
400a351bb0 build: bump memchr from 2.4.1 to 2.5.0
Bumps [memchr](https://github.com/BurntSushi/memchr) from 2.4.1 to 2.5.0.
- [Release notes](https://github.com/BurntSushi/memchr/releases)
- [Commits](https://github.com/BurntSushi/memchr/compare/2.4.1...2.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 15:05:34 +00:00
dependabot[bot]
fa9fb26952 build: bump unicode-xid from 0.2.2 to 0.2.3
Bumps [unicode-xid](https://github.com/unicode-rs/unicode-xid) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/unicode-rs/unicode-xid/releases)
- [Commits](https://github.com/unicode-rs/unicode-xid/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 14:20:11 +00:00
dependabot[bot]
938b0bfcec build: bump serde_json from 1.0.79 to 1.0.80
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.79 to 1.0.80.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.79...v1.0.80)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 13:13:26 +00:00
Sebastien Boeuf
a5a2e591c9 vmm: Remove FsConfig from VmConfig when unplugging fs device
All hotpluggable devices were properly removed from the VmConfig when a
remove-device command was issued, except for the "fs" type. Fix this
lack of support as it is causing the integration tests to fail with the
recent addition of verifying that identifiers are unique.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-02 13:26:15 +02:00
Sebastien Boeuf
677c8831af vmm: Ensure uniqueness of generated identifiers
The device identifiers generated from the DeviceManager were not
guaranteed to be unique since they were not taking the list of
identifiers provided through the configuration.

By returning the list of unique identifiers from the configuration, and
by providing it to the DeviceManager, the generation of new identifiers
can rely both on the DeviceTree and the list of IDs from the
configuration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-02 13:26:15 +02:00
Sebastien Boeuf
634c53ea50 vmm: config: Validate provided identifiers are unique
A valid configuration means we can only accept unique identifiers from
the user.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-05-02 13:26:15 +02:00
dependabot[bot]
657660e5c2 build: bump clap from 3.1.13 to 3.1.14
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.13 to 3.1.14.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.13...v3.1.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 10:44:46 +00:00
dependabot[bot]
b60e6f7cb1 build: bump thiserror from 1.0.30 to 1.0.31
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.30 to 1.0.31.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.30...1.0.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 09:53:42 +00:00
dependabot[bot]
4a7c858fdc build: bump remain from 0.2.2 to 0.2.3
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.2...0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-30 22:43:27 +00:00
dependabot[bot]
85a72efed7 build: bump clap from 3.1.12 to 3.1.13
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.12 to 3.1.13.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.12...v3.1.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-30 21:59:36 +00:00
dependabot[bot]
8afdcb98d4 build: bump syn from 1.0.91 to 1.0.92
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.91 to 1.0.92.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.91...1.0.92)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-30 21:12:59 +00:00
dependabot[bot]
6c36c60330 build: bump syn from 1.0.91 to 1.0.92 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.91 to 1.0.92.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.91...1.0.92)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-30 00:40:22 +00:00
dependabot[bot]
6239b8ad7a build: bump libc from 0.2.124 to 0.2.125 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.124 to 0.2.125.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.124...0.2.125)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-29 23:51:25 +00:00
Rob Bradford
4fed2d4ed7 tests: Use different API sockets when restoring
This prevents a conflict since the old API socket will not have been
cleaned up (due to the use of SIGKILL.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 18:40:49 +01:00
LiHui
ec0c1b01c4 vmm: api: Do not delete the API socket on API server creation
The socket will safely deleted on shutdown and so it is not necessary to
delete the API socket when starting the HTTP server.

Fixes: #4026

Signed-off-by: LiHui <andrewli@kubesphere.io>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 18:40:49 +01:00
Anatol Belski
f77ea5a2ce doc: Initial add releases.md
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-04-29 11:19:45 +01:00
Rob Bradford
f17aa3755f vmm: Add clarifying comment about Vm::entry_point()
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
744a049007 vmm: Parallelise functionality with kernel loading
Move fuctionality earlier in the boot so as to run in parallel with the
loading of the kernel.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
e70bd069b3 vmm: Load kernel asynchronously
Start loading the kernel as possible in the VM in a separate thread.
Whilst it is loading other work can be carried out such as initialising
the devices.

The biggest performance improvement is seen with a more complex set of
devices. If using e.g. four virtio-net devices then the time to start the
kernel improves by 20-30ms. With the simplest configuration the
improvement was of the order of 2-3ms.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
bfeb3120f5 vmm: Refactor kernel loading to decouple from Vm struct
This will allow the kernel to be loaded from another thread.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
ce6d88d187 vmm: Merge aarch64 use statements
These were in their own block and not organised lexically.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
56fe4c61af vmm: Duplicate Vm::entry_point() across architectures
These will have very different implementations when asynchronously
loading the kernel.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
1d1a087fc5 vmm: Refactor kernel command line generation
This allows the same code for generating the kernel command line to be
used on both aarch64 and x86_64 when the latter starts loading the
kernel in asynchronously.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
f1276c58d2 vmm: Commandline inject from devices is aarch64 specific
This is not required for x86_64 and maintains a tight coupling between
kernel loading and the DeviceManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Rob Bradford
da33eb5e8c vmm: device_manager: Remove extra whitespace lines
These originated from the removal of the acpi feature gate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-29 11:03:38 +01:00
Fabiano Fidêncio
fdeb4f7c46 Revert "vmm, openapi: Token Bucket fields should be uint64"
This reverts commit 87eed369cd.

The reason we're reverting this is that OpenAPI Specification[0] doesn't
know how to deal with unsigned types. :-/

Right now the best to do is keep it as it's, as an int64, and try to fix
OpenAPI, or even switch to swagger, as the latter knows how to properly
deal with those.  However, switching to swagger is far from being an 1:1
transition and will require time to experiment, thus reverting this for
now seems the best approach.

[0]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#data-types

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-04-28 09:26:38 +02:00
dependabot[bot]
7388f71228 build: bump libz-sys from 1.1.5 to 1.1.6
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.5 to 1.1.6.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.5...1.1.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-27 23:53:24 +00:00
Bo Chen
eebf4f10e3 tests: Cover 'virtio-balloon' for live migration and live upgrade
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-27 12:27:49 -07:00
Bo Chen
3d1b2eb4e5 tests: Cover 'virtio-watchdog' for live migration and live upgrade
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-27 12:27:49 -07:00
Bo Chen
16740b4fcd tests: Refactor 'test_watchdog' for reusing
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-27 12:27:49 -07:00
Bo Chen
e97fe7a43e tests: Cover 'virtio-pmem' for live migration and live upgrade
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-27 12:27:49 -07:00
Fabiano Fidêncio
87eed369cd vmm, openapi: Token Bucket fields should be uint64
The Token Bucket fields are, on the Cloud Hypervisor side, u64.
However, we expose those as int64 in the OpenAPI YAML file.

With that in mind, let's adjust the yaml file to expose those as uint64.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-04-27 13:16:02 +02:00
Rob Bradford
79f4c2db01 vmm: Enable virtio-iommu in VmConfig::validate()
This means that the automatic enabling of the virtio-iommu will also be
applied to VMs creates via the API as well as the CLI.

Fixes: #4016

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-26 12:27:00 +01:00
Sebastien Boeuf
6df8f0bbf3 virtio-devices: iommu: Report request error back to guest
Improve the request parsing/handling code by allowing an error status to
be returned back to the guest driver before we return an error
internally.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Sebastien Boeuf
bbd0667b98 virtio-devices: iommu: Add bypass mode for domains
Extend the Domain structure to store the information about each domain
being in bypass mode or not. Based on this new information, the address
translation of the virtio devices is performed according to the bypass
mode of each domain. And both MAP/UNMAP requests are generating errors
in case the domain has been previously set to bypass mode.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Sebastien Boeuf
b40633f92c virtio-devices: iommu: Clarify naming around domains
In anticipation for associating more than mappings with a domain, we
factorize the list of mappings associated with a domain behind a
dedicated Domain structure. We also update the field name so that it
reads better in the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Sebastien Boeuf
2f47bea809 tests: Re-enable aarch64_acpi::test_virtio_iommu
Now that virtio-iommu has been fixed, the test can be enabled again.

Fixes #3941

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Sebastien Boeuf
f38360deb6 virtio-devices: iommu: Support global bypass mode for virtio devices
Exposing the VIRTIO_IOMMU_F_BYPASS_CONFIG feature to the guest, which
allows to update the bypass global knob through virtio configuration.

Based on the value of this global knob, the address translations for
endpoints that have not been added to a domain is allowed with a simple
identity mapping.

By default, we enable the bypass mode for all endpoints that are not
attached to any domain.

Fixes #3987

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Sebastien Boeuf
fc8facddee virtio-devices: iommu: Support multiple endpoints per domain
Based on the VIRTIO specification, we must be able to support multiple
endpoints per domain. This is fixed along with the introduction of some
simplification regarding how we can retrieve the external mapping
directly based on the endpoint.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-26 13:07:32 +02:00
Rob Bradford
bf9f79081a vmm: Only create ACPI memory manager DSDT when resizable
If using the ACPI based hotplug only memory can be added so if the
hotplug RAM size is the same as the boot RAM size then do not include
the memory manager DSDT entries.

Also: this change simplifies the code marginally by making the
HotplugMethod enum Copyable.

This was identified from the following perf output:

     1.78%     0.00%  vmm              cloud-hypervisor      [.] <vmm::memory_manager::MemorySlots as acpi_tables::aml::Aml>::append_aml_bytes
            |
            ---<vmm::memory_manager::MemorySlots as acpi_tables::aml::Aml>::append_aml_bytes
               <vmm::memory_manager::MemorySlot as acpi_tables::aml::Aml>::append_aml_bytes
               acpi_tables::aml::Name::new
               <acpi_tables::aml::Path as acpi_tables::aml::Aml>::append_aml_bytes
               __libc_malloc

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-26 13:07:19 +02:00
dependabot[bot]
ec1679406e build: bump clap from 3.1.10 to 3.1.12
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.10 to 3.1.12.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.10...v3.1.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-23 20:13:14 +01:00
dependabot[bot]
17107c59ac build: bump clap from 3.1.10 to 3.1.12 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.10 to 3.1.12.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.1.10...v3.1.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-23 20:12:58 +01:00
Rob Bradford
62f17ccf8c vmm: Improve error handling for vmm::vm::Error
In particular implement thiserror::Error, cleanup wording and remove
unused errors.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-22 17:46:41 +01:00
Rob Bradford
cb03540ffd vmm: config: Derive thiserror::Error
No further changes are necessary that adding a #[derive(Error)] as there
is a manual implementation of Display.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-22 17:46:41 +01:00
Rob Bradford
0270d697ab vmm: cpu: Improve Error reporting
Remove unused enum members, improve error messages and implement
thiserror::Error.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-22 17:46:41 +01:00
Rob Bradford
47529796d0 arch: Improve arch::Error
Remove unused error enum entries, improve wording and derive
thiserror::Error.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-22 17:46:41 +01:00
Rob Bradford
1c786610b7 vmm: api: Don't use clashing struct name for Error
Import vmm::Error as VmmError to allow the use of thiserror::Error to
avoid clashing names.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-22 17:46:41 +01:00
Sebastien Boeuf
4a99d3dbaf pci: Move VfioWrapper to VfioCommon
Extend VfioCommon to simplify the overall code, and also in preparation
for supporting the restore code path.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-22 16:16:48 +02:00
Sebastien Boeuf
e6aa792c01 pci: Store legacy interrupt manager in VfioCommon
Extend VfioCommon structure to own the legacy interrupt manager. This
will be useful for implementing the restore code path.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-22 16:16:48 +02:00
Sebastien Boeuf
eb6daa2fc3 pci: Store MSI interrupt manager in VfioCommon
Extend VfioCommon structure to own the MSI interrupt manager. This will
be useful for implementing the restore code path.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-22 16:16:48 +02:00
Sebastien Boeuf
f767e97fa5 pci: vfio: Split PCI capability parsing functions
We need to split the parsing functions into one function dedicated to
the actual parsing and a second function for initializing the interrupt
type. This will be useful on the restore path as the parsing won't be
needed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-22 16:16:48 +02:00
Sebastien Boeuf
f076819d81 pci: msi: Implement Snapshot for MsiConfig
Adding support for snapshot and restore to the MsiConfig structure, as
it will be needed part of VFIO migration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-22 16:16:48 +02:00
dependabot[bot]
3c8e280bf1 build: bump anyhow from 1.0.56 to 1.0.57
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.56...1.0.57)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-22 00:11:48 +00:00
dependabot[bot]
c1ecfd23be build: bump anyhow from 1.0.56 to 1.0.57 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.56...1.0.57)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-21 23:41:04 +00:00
Rob Bradford
80de77a6e6 tests: Add integration test for --platform serial_number
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 17:17:08 +02:00
Rob Bradford
adb3dcdc13 vmm: openapi: Add serial_number to PlatformConfig
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 17:17:08 +02:00
Rob Bradford
e972eb7c74 arch, vmm: Expose platform serial_number via SMBIOS
Fixes: #4002

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 17:17:08 +02:00
Rob Bradford
203dfdc156 vmm: config: Add "serial_number" option to "--platform"
This carries a string that is exposed via DMI/SMBIOS and is particularly
useful for cloud-init initialisation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 17:17:08 +02:00
Rob Bradford
6ccf037972 option_parser: Support having "=" inside option values
This is particularly helpful as the cloud-init DMI serial number
encoding scheme uses "=" and ";" for key value pairs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 17:17:08 +02:00
Rob Bradford
4a04d1f8f2 vmm: seccomp: Allow SYS_rseq as required by newer glibc
glibc 2.35 as shipped by Fedora 36 now uses the rseq syscall.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 13:02:51 +01:00
Rob Bradford
c274ce4d49 virtio-devices: mem: Reject resize if device not activated by guest
If the guest has not activated the virtio-mem device then reject an
attempt to resize using it.

Fixes: #4001

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-21 10:36:23 +01:00
dependabot[bot]
047432a81b build: bump mshv-bindings from 75cf309 to e2c7657
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `75cf309` to `e2c7657`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](75cf309d56...e2c765737c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 23:40:54 +00:00
dependabot[bot]
8358d100cc build: bump uuid from 0.8.2 to 1.0.0 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 0.8.2 to 1.0.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/0.8.2...1.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 23:38:32 +00:00
Bo Chen
82aa0e1222 tests: Disable live upgrade tests
Live upgrade is currently not guaranteed during this development cycle
and we will try to enable these tests after the next release.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-20 11:51:50 -07:00
Bo Chen
edca82c4bd scripts, tests: Add live upgrade tests
By augmenting existing set of tests, this patch added a set of
tests for live-upgrade that covers use cases with NUMA,
vhost-user (OVS-DPDK), and local-migration.

Fixes: #3949

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-20 11:51:50 -07:00
Bo Chen
7e9c61ab18 tests: Add `test_live_migration_numa_local'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-20 11:51:50 -07:00
Bo Chen
f81220ae2d test_infra: Allow to create a GuestCommand with input binary path
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-20 11:51:50 -07:00
Rob Bradford
4ca066f077 vmm: api: Simplify error reporting from HTTP to internal API calls
Use a single enum member for representing errors from the internal API.
This avoids the ugly duplication of the API call name in the error
message:

e.g.

$ target/debug/ch-remote --api-socket /tmp/api resize --cpus 2
Error running command: Server responded with an error: InternalServerError: VmResize(VmResize(CpuManager(DesiredVCpuCountExceedsMax)))

Becomes:

$ target/debug/ch-remote --api-socket /tmp/api resize --cpus 2
Error running command: Server responded with an error: InternalServerError: ApiError(VmResize(CpuManager(DesiredVCpuCountExceedsMax)))

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-20 19:39:05 +01:00
Vincent Batts
88ed85247e scripts: dev_cli.sh: add option to specify container runtime
For example:

```shell
./scripts/dev_cli.sh build --release --libc musl --runtime "sudo nerdctl"
```

works. And presumably podman as well.

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2022-04-20 17:57:16 +01:00
dependabot[bot]
de1af55e22 build: bump libc from 0.2.123 to 0.2.124
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.123 to 0.2.124.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.123...0.2.124)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 10:43:52 +00:00
dependabot[bot]
bf059914a6 build: bump uuid from 0.8.2 to 1.0.0
Bumps [uuid](https://github.com/uuid-rs/uuid) from 0.8.2 to 1.0.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/0.8.2...1.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 09:41:22 +00:00
dependabot[bot]
3952cc6629 build: bump clap from 3.1.9 to 3.1.10
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.9 to 3.1.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/v3.1.9...v3.1.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 08:45:42 +00:00
dependabot[bot]
e15cac55aa build: bump libc from 0.2.123 to 0.2.124 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.123 to 0.2.124.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.123...0.2.124)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-20 00:08:00 +00:00
dependabot[bot]
824c0c962d build: bump clap from 3.1.9 to 3.1.10 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.9 to 3.1.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/v3.1.9...v3.1.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-19 23:40:29 +00:00
Sebastien Boeuf
37521ddff7 pci: vfio: Restore BARs in a more straightforward way
In case a list of resources is provided to allocate_bars(), it directly
means we're restoring some existing BARs. That's why we shouldn't share
the codepath that creates BARs from scratch as we don't need to interact
with the device to retrieve the information.

Whenever resources are provided, we simply iterate over the list of
possible BAR indexes and create the BARs if the resource could be found.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-19 12:54:09 -07:00
Sebastien Boeuf
11e9f43305 vmm: Use new Resource type PciBar
Instead of defining some very generic resources as PioAddressRange or
MmioAddressRange for each PCI BAR, let's move to the new Resource type
PciBar in order to make things clearer. This allows the code for being
more readable, but also removes the need for hard assumptions about the
MMIO and PIO ranges. PioAddressRange and MmioAddressRange types can be
used to describe everything except PCI BARs. BARs are very special as
they can be relocated and have special information we want to carry
along with them.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-19 12:54:09 -07:00
Sebastien Boeuf
89218b6d1e pci: Replace BAR tuple with PciBarConfiguration
In order to make the code more consistent and easier to read, we remove
the former tuple that was used to describe a BAR, replacing it with the
existing structure PciBarConfiguration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-19 12:54:09 -07:00
Sebastien Boeuf
da95c0d784 pci: Clarify register index and BAR index
The code was quite unclear regarding the type of index that was being
used regarding a BAR. This is improved by differenciating register
indexes and BAR indexes more clearly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-19 12:54:09 -07:00
Sebastien Boeuf
1795afadb8 vmm: Factorize algorithm finding HOB memory resources
By factorizing the algorithm untangling TDVF sections from guest RAM
into a dedicated function, we can write some unit tests to validate it
properly achieves what we expect.

Adding the "tdx" feature to the unit tests, otherwise it wouldn't get
tested.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-19 15:23:12 +02:00
Fabiano Fidêncio
a87d1bbaa1 docs: Fix the name of the I/O operations knobs
The I/O operations knobs are prefixed `ops_` rather than `bw_`, as `bw_`
refers to the "bandwidth" knobs.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-04-19 13:51:33 +01:00
Wei Liu
babece08c6 github: use --locked in cargo invocations
Cargo comes with a --locked option that makes sure Cargo.lock is not
changed.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-04-19 13:44:24 +01:00
dependabot[bot]
5a9779f88c build: bump clap from 3.1.8 to 3.1.9 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.8 to 3.1.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/v3.1.8...v3.1.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-16 00:03:28 +00:00
dependabot[bot]
45d3db48cf build: bump clap from 3.1.8 to 3.1.9
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.8 to 3.1.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/v3.1.8...v3.1.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-15 23:33:32 +00:00
Rob Bradford
f03258bb2a README: Update recommended version of Rust Hypervisor Firmware
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-14 15:37:39 +01:00
Sebastien Boeuf
5264d545dd pci, vmm: Extend PciDevice trait to support BAR relocation
By adding a new method id() to the PciDevice trait, we allow the caller
to retrieve a unique identifier. This is used in the context of BAR
relocation to identify the device being relocated, so that we can update
the DeviceTree resources for all PCI devices (and not only
VirtioPciDevice).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
Sebastien Boeuf
6175cc0977 pci: vfio: Restore BARs at expected addresses
Relying on the list of resources, VfioCommon is now able to allocate the
BARs at specific addresses. This will be useful for restoring VFIO and
vfio-user devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
Sebastien Boeuf
0c34846ef6 vmm: Return new PCI resources from add_pci_device()
By returning the new PCI resources from add_pci_device(), we allow the
factorization of the code translating the BARs into resources. This
allows VIRTIO, VFIO and vfio-user to add the resources to the DeviceTree
node.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
Sebastien Boeuf
4f172ae4b6 vmm: Retrieve PCI resources for VFIO and vfio-user devices
Relying on the function introduced recently to get the PCI resources and
handle the restore case, both VFIO and vfio-user device creation paths
now have access to PCI resources, which can be provided to the function
add_pci_device().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
Sebastien Boeuf
0f12fe9b3b vmm: Factorize retrieval of PCI resources
Create a dedicated function for getting the PCI segment, b/d/f and
optional resources. This is meant for handling the potential case of a
restore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
Sebastien Boeuf
6e084572d4 pci, virtio: Make virtio-pci BAR restoration more generic
Updating the way of restoring BAR addresses for virtio-pci by providing
a more generic approach that will be reused for other PciDevice
implementations (i.e VfioPcidevice and VfioUserPciDevice).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-14 12:11:37 +02:00
147 changed files with 7332 additions and 4487 deletions

View File

@@ -13,7 +13,7 @@ jobs:
- stable
- beta
- nightly
- 1.56
- "1.60"
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
@@ -39,25 +39,28 @@ jobs:
git checkout $GITHUB_SHA
- name: Build (default features)
run: cargo rustc --bin cloud-hypervisor -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor -- -D warnings
- name: Build (common + kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "common,kvm" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "common,kvm" -- -D warnings
- name: Build (default features + tdx)
run: cargo rustc --bin cloud-hypervisor --features "tdx" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --features "tdx" -- -D warnings
- name: Build (default features + amx)
run: cargo rustc --bin cloud-hypervisor --features "amx" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --features "amx" -- -D warnings
- name: Build (default features + gdb)
run: cargo rustc --bin cloud-hypervisor --features "gdb" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --features "gdb" -- -D warnings
- name: Build (default features + guest_debug)
run: cargo rustc --locked --bin cloud-hypervisor --features "guest_debug" -- -D warnings
- name: Build (common + mshv)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "common,mshv" -- -D warnings
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "common,mshv" -- -D warnings
- name: Release Build (default features)
run: cargo build --all --release --target=${{ matrix.target }}
run: cargo build --locked --all --release --target=${{ matrix.target }}
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"

View File

@@ -34,19 +34,22 @@ jobs:
run: cargo fmt -- --check
- name: Clippy (common + kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,kvm" -- -D warnings
run: cargo clippy --locked --all --all-targets --no-default-features --tests --features "common,kvm" -- -D warnings
- name: Clippy (default features)
run: cargo clippy --all --all-targets --tests -- -D warnings
run: cargo clippy --locked --all --all-targets --tests -- -D warnings
- name: Clippy (default features + amx)
run: cargo clippy --all --all-targets --tests --features "amx" -- -D warnings
run: cargo clippy --locked --all --all-targets --tests --features "amx" -- -D warnings
- name: Clippy (default features + gdb)
run: cargo clippy --all --all-targets --tests --features "gdb" -- -D warnings
run: cargo clippy --locked --all --all-targets --tests --features "gdb" -- -D warnings
- name: Clippy (default features + guest_debug)
run: cargo clippy --locked --all --all-targets --tests --features "guest_debug" -- -D warnings
- name: Clippy (common + mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,mshv" -- -D warnings
run: cargo clippy --locked --all --all-targets --no-default-features --tests --features "common,mshv" -- -D warnings
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"

View File

@@ -16,23 +16,23 @@ jobs:
- name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1
with:
toolchain: 1.58
toolchain: "1.62"
target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: 1.58
toolchain: "1.62"
target: x86_64-unknown-linux-musl
- name: Build
uses: actions-rs/cargo@v1
with:
toolchain: 1.58
toolchain: "1.62"
command: build
args: --all --release --target=x86_64-unknown-linux-gnu
- name: Static Build
uses: actions-rs/cargo@v1
with:
toolchain: 1.58
toolchain: "1.62"
command: build
args: --all --release --target=x86_64-unknown-linux-musl
- name: Strip cloud-hypervisor binaries
@@ -40,7 +40,7 @@ jobs:
- name: Install Rust toolchain (aarch64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: 1.58
toolchain: "1.62"
target: aarch64-unknown-linux-musl
override: true
- name: Static Build (AArch64)

1
.gitignore vendored
View File

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

2
CODEOWNERS Normal file
View File

@@ -0,0 +1,2 @@
# Add the list of code owners here (using their GitHub username)
* @cloud-hypervisor/cloud-hypervisor-reviewers

View File

@@ -2,12 +2,14 @@
Cloud Hypervisor is an open source project licensed under the [Apache v2
License](https://opensource.org/licenses/Apache-2.0) and the [BSD 3
Clause](https://opensource.org/licenses/BSD-3-Clause) license. Contributions
can be made under either license or both. Individual files contain details of
their licensing and changes to that file are under the same license unless the
contribution changes the license of the file. When importing code from a third
party project (e.g. Firecracker or CrosVM) please respect the license of those
projects.
Clause](https://opensource.org/licenses/BSD-3-Clause) license. Individual files
contain details of their licensing and changes to that file are under the same
license unless the contribution changes the license of the file. When importing
code from a third party project (e.g. Firecracker or CrosVM) please respect the
license of those projects.
New code should be under the [Apache v2
License](https://opensource.org/licenses/Apache-2.0).
## Coding Style
@@ -63,11 +65,9 @@ you want to merge your changes to `cloud-hypervisor`:
2. Within your fork, create a branch for your contribution.
3. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
against the main branch of the Cloud Hypervisor repository.
4. Add reviewers to your pull request and then work with your reviewers to address
any comments and obtain minimum of 2 [maintainers](MAINTAINERS.md) approvals.
To update your pull request amend existing commits whenever applicable and
4. To update your pull request amend existing commits whenever applicable and
then push the new changes to your pull request branch.
5. Once the pull request is approved, one of the maintainers will merge it.
5. Once the pull request is approved it can be integrated.
## Issue tracking

268
Cargo.lock generated
View File

@@ -20,9 +20,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.56"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
[[package]]
name = "api_client"
@@ -50,7 +50,6 @@ dependencies = [
"linux-loader",
"log",
"serde",
"serde_derive",
"thiserror",
"versionize",
"versionize_derive",
@@ -131,24 +130,33 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.1.8"
version = "3.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"lazy_static",
"os_str_bytes",
"once_cell",
"strsim",
"termcolor",
"terminal_size",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "cloud-hypervisor"
version = "23.0.0"
version = "25.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -157,10 +165,10 @@ dependencies = [
"epoll",
"event_monitor",
"hypervisor",
"lazy_static",
"libc",
"log",
"net_util",
"once_cell",
"option_parser",
"seccompiler",
"serde_json",
@@ -198,6 +206,7 @@ dependencies = [
"bitflags",
"byteorder",
"epoll",
"hypervisor",
"libc",
"log",
"versionize",
@@ -257,7 +266,6 @@ version = "0.1.0"
dependencies = [
"libc",
"serde",
"serde_derive",
"serde_json",
]
@@ -269,9 +277,9 @@ checksum = "b643857cf70949306b81d7e92cb9d47add673868edac9863c4a49c42feaf3f1e"
[[package]]
name = "gdbstub"
version = "0.6.1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa2ca5d6b045de372cef3991f873389b421b4cabcfbe52f7787fae8b8b37906"
checksum = "1c1f9371c87c11642ee94dcf92cb48b1484ba250b8e8bff3df71c28651f3f4e7"
dependencies = [
"bitflags",
"cfg-if",
@@ -283,9 +291,9 @@ dependencies = [
[[package]]
name = "gdbstub_arch"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51dc4b5718ac76d21e8605c0966dd32d80273b89b11e6cfef467b04e45934d37"
checksum = "c24f469ba9556c5a063d6df35a8a338025fccf96ecae44f330a156b686f7a268"
dependencies = [
"gdbstub",
"num-traits",
@@ -293,9 +301,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
@@ -310,9 +318,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hashbrown"
version = "0.11.2"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
[[package]]
name = "hermit-abi"
@@ -344,7 +352,6 @@ dependencies = [
"mshv-bindings",
"mshv-ioctls",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vm-memory",
@@ -363,9 +370,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.1"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
@@ -392,18 +399,18 @@ dependencies = [
[[package]]
name = "ipnetwork"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355"
checksum = "1f84f1612606f3753f205a4e9a2efd6fe5b4c573a6269b2cc6c3003d44a0d127"
dependencies = [
"serde",
]
[[package]]
name = "itoa"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "kvm-bindings"
@@ -418,7 +425,7 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.11.0"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#1e03e29cdfbb0cb108a98de7a78045a5a517f18e"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#ccf0bda07485b2433616de998c000aa5f04ce806"
dependencies = [
"kvm-bindings",
"libc",
@@ -433,9 +440,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.123"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libssh2-sys"
@@ -453,9 +460,9 @@ dependencies = [
[[package]]
name = "libz-sys"
version = "1.1.5"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859"
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
dependencies = [
"cc",
"libc",
@@ -484,9 +491,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.16"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
@@ -499,14 +506,14 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#a730d86940081ad044cdfbc1285c1db6d3048392"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#863b0370ba7e57f7df5b908ada9e5b44809ccae9"
dependencies = [
"libc",
"vmm-sys-util",
@@ -515,7 +522,7 @@ dependencies = [
[[package]]
name = "mshv-bindings"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#75cf309d566c3d9ba91e81582a7864032ecc5bbb"
source = "git+https://github.com/rust-vmm/mshv?branch=main#7ac1b80bff7220171c9a626b23b51620ca774468"
dependencies = [
"libc",
"serde",
@@ -527,7 +534,7 @@ dependencies = [
[[package]]
name = "mshv-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#75cf309d566c3d9ba91e81582a7864032ecc5bbb"
source = "git+https://github.com/rust-vmm/mshv?branch=main#7ac1b80bff7220171c9a626b23b51620ca774468"
dependencies = [
"libc",
"mshv-bindings",
@@ -547,11 +554,12 @@ version = "0.1.0"
dependencies = [
"epoll",
"getrandom",
"lazy_static",
"libc",
"log",
"net_gen",
"once_cell",
"pnet",
"pnet_datalink",
"rate_limiter",
"serde",
"serde_json",
@@ -565,28 +573,40 @@ dependencies = [
]
[[package]]
name = "num-traits"
version = "0.2.14"
name = "no-std-net"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "openssl-src"
version = "111.18.0+1.1.1n"
name = "once_cell"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7897a926e1e8d00219127dc020130eca4292e5ca666dd592480d72c3eca2ff6c"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "openssl-src"
version = "111.22.0+1.1.1q"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f31f0d509d1c1ae9cada2f9539ff8f37933831fd5098879e482aa687d659853"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.72"
version = "0.9.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1"
dependencies = [
"autocfg",
"cc",
@@ -602,12 +622,9 @@ version = "0.1.0"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "parking_lot"
@@ -650,7 +667,6 @@ dependencies = [
"libc",
"log",
"serde",
"serde_derive",
"thiserror",
"versionize",
"versionize_derive",
@@ -671,7 +687,6 @@ dependencies = [
"clap",
"dirs",
"serde",
"serde_derive",
"serde_json",
"test_infra",
"thiserror",
@@ -686,29 +701,30 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "pnet"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8750e073f82219c01e771133c64718d7685aef922da8a0d430a46aed05b6341a"
checksum = "0caaf5b11fd907ff15cf14a4477bfabca4b37ab9e447a4f8dead969a59cdafad"
dependencies = [
"ipnetwork",
"pnet_base",
"pnet_datalink",
"pnet_packet",
"pnet_sys",
"pnet_transport",
]
[[package]]
name = "pnet_base"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8205fe084bd43a3af79b3155c19feddd62e733640498842e631a2ffe107d1538"
checksum = "f9d3a993d49e5fd5d4d854d6999d4addca1f72d86c65adf224a36757161c02b6"
dependencies = [
"no-std-net",
]
[[package]]
name = "pnet_datalink"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f85aef5e52e22ff06b1b11f2eb6d52959a9e0ecad3cb3f5cc2d78cadc077f0e"
checksum = "e466faf03a98ad27f6e15cd27a2b7cc89e73e640a43527742977bc503c37f8aa"
dependencies = [
"ipnetwork",
"libc",
@@ -719,9 +735,9 @@ dependencies = [
[[package]]
name = "pnet_macros"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc3af95fed6dc318dfede3e81320f96ad5e237c6f7c4688108b19c8e67432d"
checksum = "48dd52a5211fac27e7acb14cfc9f30ae16ae0e956b7b779c8214c74559cef4c3"
dependencies = [
"proc-macro2",
"quote",
@@ -731,18 +747,18 @@ dependencies = [
[[package]]
name = "pnet_macros_support"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feaba58ba96abb218ec584d6caf0d3ff48922df05dbbeb1560553c197091b29e"
checksum = "89de095dc7739349559913aed1ef6a11e73ceade4897dadc77c5e09de6740750"
dependencies = [
"pnet_base",
]
[[package]]
name = "pnet_packet"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f246edaaf1aaf82072d4cd38ee18bcc5dfc0464093f9ca39e4ac5962d68cf9d4"
checksum = "bc3b5111e697c39c8b9795b9fdccbc301ab696699e88b9ea5a4e4628978f495f"
dependencies = [
"glob",
"pnet_base",
@@ -752,9 +768,9 @@ dependencies = [
[[package]]
name = "pnet_sys"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "028c87a5e3a48fc07df099a2025f2ef16add5993712e1494ba69a6707ee7ed06"
checksum = "328e231f0add6d247d82421bf3790b4b33b39c8930637f428eef24c4c6a90805"
dependencies = [
"libc",
"winapi",
@@ -762,9 +778,9 @@ dependencies = [
[[package]]
name = "pnet_transport"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "950f2a7961e19d22e19e84ff0a6e0955013185fe149673499662633d02b41b7a"
checksum = "ff597185e6f1f5671b3122e4dba892a1c73e17c17e723d7669bd9299cbe7f124"
dependencies = [
"libc",
"pnet_base",
@@ -774,11 +790,11 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.37"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
@@ -794,9 +810,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.18"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@@ -832,9 +848,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.5.5"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
@@ -843,15 +859,15 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.25"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "remain"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
checksum = "0c35270ea384ac1762895831cc8acb96f171468e52cec82ed9186f9416209fa4"
dependencies = [
"proc-macro2",
"quote",
@@ -869,9 +885,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "scopeguard"
@@ -890,21 +906,24 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.7"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
dependencies = [
"proc-macro2",
"quote",
@@ -913,9 +932,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.79"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
dependencies = [
"itoa",
"ryu",
@@ -924,9 +943,9 @@ dependencies = [
[[package]]
name = "signal-hook"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
dependencies = [
"libc",
"signal-hook-registry",
@@ -943,9 +962,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "ssh2"
@@ -973,13 +992,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.91"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
@@ -1019,8 +1038,8 @@ version = "0.1.0"
dependencies = [
"dirs",
"epoll",
"lazy_static",
"libc",
"once_cell",
"ssh2",
"vmm-sys-util",
"wait-timeout",
@@ -1037,18 +1056,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
@@ -1056,16 +1075,22 @@ dependencies = [
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-xid"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "uuid"
version = "0.8.2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
dependencies = [
"getrandom",
]
@@ -1115,7 +1140,7 @@ dependencies = [
[[package]]
name = "vfio-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#f75a77c1ab6349c105bc1462a65508726b4c2e0f"
source = "git+https://github.com/rust-vmm/vfio?branch=main#38272d3f06bbc0b4b3cfa3f5da07fd1c1c89e4d1"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -1174,9 +1199,9 @@ dependencies = [
[[package]]
name = "vhost-user-backend"
version = "0.3.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1490f2028d4f119b2292efe218b5f8cfc6471f039b53b6a6eb5d9513e964facc"
checksum = "3eeb6723bbee20dbc2db95c575941922fb96e77eb41786ecd1c8c03348709c4c"
dependencies = [
"libc",
"log",
@@ -1249,7 +1274,6 @@ dependencies = [
"rate_limiter",
"seccompiler",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
@@ -1267,9 +1291,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.2.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3785325315e6496fa88673842ee6cd198b9658e88e8b0e1ad48a5dc818b221dc"
checksum = "519c0a333c871650269cba303bc108075d52a0c0d64f9b91fae61829b53725af"
dependencies = [
"log",
"vm-memory",
@@ -1290,8 +1314,8 @@ name = "vm-device"
version = "0.1.0"
dependencies = [
"anyhow",
"hypervisor",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vfio-ioctls",
@@ -1306,9 +1330,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#ca35d96191f8232bd7a
[[package]]
name = "vm-memory"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339d4349c126fdcd87e034631d7274370cf19eb0e87b33166bcd956589fc72c5"
checksum = "767ed8aaebbff902e02e6d3749dc2baef55e46565f8a6414a065e5baee4b4a81"
dependencies = [
"arc-swap",
"libc",
@@ -1321,7 +1345,6 @@ version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
@@ -1356,18 +1379,17 @@ dependencies = [
"gdbstub",
"gdbstub_arch",
"hypervisor",
"lazy_static",
"libc",
"linux-loader",
"log",
"micro_http",
"net_util",
"once_cell",
"option_parser",
"pci",
"qcow",
"seccompiler",
"serde",
"serde_derive",
"serde_json",
"signal-hook",
"thiserror",
@@ -1410,9 +1432,9 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "23.0.0"
version = "25.0.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -10,31 +10,31 @@ description = "Open source Virtual Machine Monitor (VMM) that runs on top of KVM
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
# Minimum buildable version:
# Keep in sync with version in .github/workflows/build.yaml
rust-version = "1.56"
rust-version = "1.60"
[profile.release]
lto = true
[dependencies]
anyhow = "1.0.56"
anyhow = "1.0.58"
api_client = { path = "api_client" }
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
clap = { version = "3.2.8", features = ["wrap_help","cargo"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.123"
log = { version = "0.4.16", features = ["std"] }
libc = "0.2.126"
log = { version = "0.4.17", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.2.0"
serde_json = "1.0.79"
signal-hook = "0.3.13"
thiserror = "1.0.30"
serde_json = "1.0.82"
signal-hook = "0.3.14"
thiserror = "1.0.31"
vmm = { path = "vmm" }
vmm-sys-util = "0.9.0"
vm-memory = "0.7.0"
vm-memory = "0.8.0"
[build-dependencies]
clap = { version = "3.1.8", features = ["cargo"] }
clap = { version = "3.2.8", features = ["cargo"] }
# List of patched crates
[patch.crates-io]
@@ -44,9 +44,9 @@ versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_deri
[dev-dependencies]
dirs = "4.0.0"
lazy_static= "1.4.0"
net_util = { path = "net_util" }
serde_json = "1.0.79"
once_cell = "1.13.0"
serde_json = "1.0.82"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
@@ -58,6 +58,7 @@ amx = ["vmm/amx"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
gdb = ["vmm/gdb"]
guest_debug = ["vmm/guest_debug"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
tdx = ["vmm/tdx"]

24
Jenkinsfile vendored
View File

@@ -23,6 +23,19 @@ pipeline{
}
}
}
stage ('Check for fuzzer cargo files only changes') {
when {
expression {
return fuzzCargoFileOnly()
}
}
steps {
script {
runWorkers = false
echo "Fuzzer cargo files only changes, no need to run the CI"
}
}
}
stage ('Check for RFC/WIP builds') {
when {
changeRequest comparator: 'REGEXP', title: '.*(rfc|RFC|wip|WIP).*'
@@ -402,3 +415,14 @@ def boolean docsFileOnly() {
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v '\\.md'"
) != 0
}
def boolean fuzzCargoFileOnly() {
if (env.CHANGE_TARGET == null) {
return false;
}
return sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v -E 'fuzz\\/Cargo.(toml|lock)'"
) != 0
}

View File

@@ -88,12 +88,10 @@ Hypervisor. Here, all the steps are based on Ubuntu, for other Linux
distributions please replace the package manager and package name.
```shell
# Install git
$ sudo apt install git
# Install build-essential, git, and qemu-img
$ sudo apt install git build-essential qemu-img
# Install rust tool chain
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install build-essential
$ sudo apt install build-essential
# If you want to build statically linked binary please add musl target
$ rustup target add x86_64-unknown-linux-musl
```
@@ -168,7 +166,7 @@ cloud image. Here we will use a Ubuntu image:
$ pushd $CLOUDH
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.3.2/hypervisor-fw
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.4.0/hypervisor-fw
$ popd
```
@@ -291,6 +289,8 @@ As of 2022-04-05, the following cloud images are supported:
Direct kernel boot to userspace should work with a rootfs from most
distributions.
Further details can be found in the [release documentation](docs/releases.md).
## Hot Plug
Cloud Hypervisor supports hotplug of CPUs, passthrough devices (VFIO),

View File

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

View File

@@ -68,7 +68,7 @@ impl Aml for Path {
};
for part in self.name_parts.clone().iter_mut() {
bytes.extend_from_slice(&part.to_vec());
bytes.extend_from_slice(part.as_ref());
}
}
}

View File

@@ -10,18 +10,17 @@ tdx = []
[dependencies]
acpi_tables = { path = "../acpi_tables" }
anyhow = "1.0.56"
anyhow = "1.0.58"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.123"
libc = "0.2.126"
linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.16"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
thiserror = "1.0.30"
log = "0.4.17"
serde = { version = "1.0.138", features = ["rc", "derive"] }
thiserror = "1.0.31"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-bitmap"] }
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.9.0", features = ["with-serde"] }

View File

@@ -8,17 +8,18 @@
use crate::{NumaNodes, PciSpaceInfo};
use byteorder::{BigEndian, ByteOrder};
use hypervisor::arch::aarch64::gic::Vgic;
use std::cmp;
use std::collections::HashMap;
use std::ffi::CStr;
use std::fmt::Debug;
use std::result;
use std::str;
use std::sync::{Arc, Mutex};
use super::super::DeviceType;
use super::super::GuestMemoryMmap;
use super::super::InitramfsConfig;
use super::gic::GicDevice;
use super::layout::{
IRQ_BASE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START,
PCI_HIGH_BASE, PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
@@ -90,7 +91,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
vcpu_mpidr: Vec<u64>,
vcpu_topology: Option<(u8, u8, u8)>,
device_info: &HashMap<(DeviceType, String), T, S>,
gic_device: &dyn GicDevice,
gic_device: &Arc<Mutex<dyn Vgic>>,
initrd: &Option<InitramfsConfig>,
pci_space_info: &[PciSpaceInfo],
numa_nodes: &NumaNodes,
@@ -315,18 +316,18 @@ fn create_chosen_node(
Ok(())
}
fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn GicDevice) -> FdtWriterResult<()> {
let gic_reg_prop = gic_device.device_properties();
fn create_gic_node(fdt: &mut FdtWriter, gic_device: &Arc<Mutex<dyn Vgic>>) -> FdtWriterResult<()> {
let gic_reg_prop = gic_device.lock().unwrap().device_properties();
let intc_node = fdt.begin_node("intc")?;
fdt.property_string("compatible", gic_device.fdt_compatibility())?;
fdt.property_string("compatible", gic_device.lock().unwrap().fdt_compatibility())?;
fdt.property_null("interrupt-controller")?;
// "interrupt-cells" field specifies the number of cells needed to encode an
// interrupt source. The type shall be a <u32> and the value shall be 3 if no PPI affinity description
// is required.
fdt.property_u32("#interrupt-cells", 3)?;
fdt.property_array_u64("reg", gic_reg_prop)?;
fdt.property_array_u64("reg", &gic_reg_prop)?;
fdt.property_u32("phandle", GIC_PHANDLE)?;
fdt.property_u32("#address-cells", 2)?;
fdt.property_u32("#size-cells", 2)?;
@@ -334,18 +335,18 @@ fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn GicDevice) -> FdtWriter
let gic_intr_prop = [
GIC_FDT_IRQ_TYPE_PPI,
gic_device.fdt_maint_irq(),
gic_device.lock().unwrap().fdt_maint_irq(),
IRQ_TYPE_LEVEL_HI,
];
fdt.property_array_u32("interrupts", &gic_intr_prop)?;
if gic_device.msi_compatible() {
if gic_device.lock().unwrap().msi_compatible() {
let msic_node = fdt.begin_node("msic")?;
fdt.property_string("compatible", gic_device.msi_compatibility())?;
fdt.property_string("compatible", gic_device.lock().unwrap().msi_compatibility())?;
fdt.property_null("msi-controller")?;
fdt.property_u32("phandle", MSI_PHANDLE)?;
let msi_reg_prop = gic_device.msi_properties();
fdt.property_array_u64("reg", msi_reg_prop)?;
let msi_reg_prop = gic_device.lock().unwrap().msi_properties();
fdt.property_array_u64("reg", &msi_reg_prop)?;
fdt.end_node(msic_node)?;
}

View File

@@ -1,262 +0,0 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// This file implements the GicV3 device.
pub mod kvm {
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
use crate::aarch64::gic::icc_regs::{get_icc_regs, set_icc_regs};
use crate::aarch64::gic::kvm::{save_pending_tables, KvmGicDevice};
use crate::aarch64::gic::redist_regs::{
construct_gicr_typers, get_redist_regs, set_redist_regs,
};
use crate::aarch64::gic::GicDevice;
use crate::layout;
use anyhow::anyhow;
use hypervisor::kvm::kvm_bindings;
use hypervisor::CpuState;
use std::any::Any;
use std::convert::TryInto;
use std::sync::Arc;
use std::{boxed::Box, result};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use vm_memory::Address;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable,
VersionMapped,
};
/// Errors thrown while saving/restoring the GICv3.
#[derive(Debug)]
pub enum Error {
/// Error in saving RDIST pending tables into guest RAM.
SavePendingTables(crate::aarch64::gic::Error),
/// Error in saving GIC distributor registers.
SaveDistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor registers.
RestoreDistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC distributor control registers.
SaveDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor control registers.
RestoreDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC redistributor registers.
SaveRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC redistributor registers.
RestoreRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC CPU interface registers.
SaveIccRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC CPU interface registers.
RestoreIccRegisters(crate::aarch64::gic::Error),
}
type Result<T> = result::Result<T, Error>;
pub struct KvmGicV3 {
/// The hypervisor agnostic device for the GicV3
device: Arc<dyn hypervisor::Device>,
/// Vector holding values of GICR_TYPER for each vCPU
gicr_typers: Vec<u64>,
/// GIC device properties, to be used for setting up the fdt entry
properties: [u64; 4],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
#[derive(Versionize)]
pub struct Gicv3State {
dist: Vec<u32>,
rdist: Vec<u32>,
icc: Vec<u32>,
// special register that enables interrupts and affinity routing
gicd_ctlr: u32,
}
impl VersionMapped for Gicv3State {}
impl KvmGicV3 {
// Device trees specific constants
pub const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
/// Get the address of the GIC distributor.
pub fn get_dist_addr() -> u64 {
layout::GIC_V3_DIST_START.raw_value()
}
/// Get the size of the GIC distributor.
pub fn get_dist_size() -> u64 {
layout::GIC_V3_DIST_SIZE
}
/// Get the address of the GIC redistributors.
pub fn get_redists_addr(vcpu_count: u64) -> u64 {
KvmGicV3::get_dist_addr() - KvmGicV3::get_redists_size(vcpu_count)
}
/// Get the size of the GIC redistributors.
pub fn get_redists_size(vcpu_count: u64) -> u64 {
vcpu_count * layout::GIC_V3_REDIST_SIZE
}
/// Save the state of GIC.
fn state(&self, gicr_typers: &[u64]) -> Result<Gicv3State> {
let gicd_ctlr =
read_ctlr(self.device()).map_err(Error::SaveDistributorCtrlRegisters)?;
let dist_state =
get_dist_regs(self.device()).map_err(Error::SaveDistributorRegisters)?;
let rdist_state = get_redist_regs(self.device(), gicr_typers)
.map_err(Error::SaveRedistributorRegisters)?;
let icc_state =
get_icc_regs(self.device(), gicr_typers).map_err(Error::SaveIccRegisters)?;
Ok(Gicv3State {
dist: dist_state,
rdist: rdist_state,
icc: icc_state,
gicd_ctlr,
})
}
/// Restore the state of GIC.
fn set_state(&mut self, gicr_typers: &[u64], state: &Gicv3State) -> Result<()> {
write_ctlr(self.device(), state.gicd_ctlr)
.map_err(Error::RestoreDistributorCtrlRegisters)?;
set_dist_regs(self.device(), &state.dist)
.map_err(Error::RestoreDistributorRegisters)?;
set_redist_regs(self.device(), gicr_typers, &state.rdist)
.map_err(Error::RestoreRedistributorRegisters)?;
set_icc_regs(self.device(), gicr_typers, &state.icc)
.map_err(Error::RestoreIccRegisters)?;
Ok(())
}
}
impl GicDevice for KvmGicV3 {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
}
fn device_properties(&self) -> &[u64] {
&self.properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
fn set_its_device(&mut self, _its_device: Option<Arc<dyn hypervisor::Device>>) {}
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let gicr_typers = construct_gicr_typers(vcpu_states);
self.gicr_typers = gicr_typers;
}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
self
}
}
impl KvmGicDevice for KvmGicV3 {
fn version() -> u32 {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice> {
Box::new(KvmGicV3 {
device,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
properties: [
KvmGicV3::get_dist_addr(),
KvmGicV3::get_dist_size(),
KvmGicV3::get_redists_addr(vcpu_count),
KvmGicV3::get_redists_size(vcpu_count),
],
vcpu_count,
})
}
fn init_device_attributes(
_vm: &Arc<dyn hypervisor::Vm>,
gic_device: &mut dyn GicDevice,
) -> crate::aarch64::gic::Result<()> {
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
&KvmGicV3::get_dist_addr() as *const u64 as u64,
0,
)?;
/* Setting up the redistributors' attribute.
We are calculating here the start of the redistributors address. We have one per CPU.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
&KvmGicV3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64,
0,
)?;
Ok(())
}
}
pub const GIC_V3_SNAPSHOT_ID: &str = "gic-v3";
impl Snapshottable for KvmGicV3 {
fn id(&self) -> String {
GIC_V3_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let gicr_typers = self.gicr_typers.clone();
Snapshot::new_from_versioned_state(&self.id(), &self.state(&gicr_typers).unwrap())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
let gicr_typers = self.gicr_typers.clone();
self.set_state(&gicr_typers, &snapshot.to_versioned_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3 state {:?}", e))
})
}
}
impl Pausable for KvmGicV3 {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(self.device()).map_err(|e| {
MigratableError::Pause(anyhow!("Could not save GICv3 GIC pending tables {:?}", e))
})?;
Ok(())
}
}
impl Transportable for KvmGicV3 {}
impl Migratable for KvmGicV3 {}
}

View File

@@ -1,514 +0,0 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// This file implements the GicV3 device with ITS (Virtual Interrupt Translation Service).
pub mod kvm {
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
use crate::aarch64::gic::icc_regs::{get_icc_regs, set_icc_regs};
use crate::aarch64::gic::redist_regs::{
construct_gicr_typers, get_redist_regs, set_redist_regs,
};
use crate::aarch64::gic::gicv3::kvm::KvmGicV3;
use crate::aarch64::gic::kvm::{save_pending_tables, KvmGicDevice};
use crate::aarch64::gic::GicDevice;
use crate::layout;
use anyhow::anyhow;
use hypervisor::kvm::kvm_bindings;
use hypervisor::CpuState;
use std::any::Any;
use std::convert::TryInto;
use std::sync::Arc;
use std::{boxed::Box, result};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable,
VersionMapped,
};
const GITS_CTLR: u32 = 0x0000;
const GITS_IIDR: u32 = 0x0004;
const GITS_CBASER: u32 = 0x0080;
const GITS_CWRITER: u32 = 0x0088;
const GITS_CREADR: u32 = 0x0090;
const GITS_BASER: u32 = 0x0100;
/// Errors thrown while saving/restoring the GICv3ITS.
#[derive(Debug)]
pub enum Error {
/// Error in saving RDIST pending tables into guest RAM.
SavePendingTables(crate::aarch64::gic::Error),
/// Error in saving GIC distributor registers.
SaveDistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor registers.
RestoreDistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC distributor control registers.
SaveDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor control registers.
RestoreDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC redistributor registers.
SaveRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC redistributor registers.
RestoreRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC CPU interface registers.
SaveIccRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC CPU interface registers.
RestoreIccRegisters(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS IIDR register.
SaveITSIIDR(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS IIDR register.
RestoreITSIIDR(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS CBASER register.
SaveITSCBASER(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS CBASER register.
RestoreITSCBASER(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS CREADR register.
SaveITSCREADR(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS CREADR register.
RestoreITSCREADR(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS CWRITER register.
SaveITSCWRITER(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS CWRITER register.
RestoreITSCWRITER(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS BASER register.
SaveITSBASER(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS BASER register.
RestoreITSBASER(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS CTLR register.
SaveITSCTLR(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS CTLR register.
RestoreITSCTLR(crate::aarch64::gic::Error),
/// Error in saving GICv3ITS restore tables.
SaveITSTables(crate::aarch64::gic::Error),
/// Error in restoring GICv3ITS restore tables.
RestoreITSTables(crate::aarch64::gic::Error),
}
type Result<T> = result::Result<T, Error>;
/// Access an ITS device attribute.
///
/// This is a helper function to get/set the ITS device attribute depending
/// the bool parameter `set` provided.
pub fn gicv3_its_attr_access(
its_device: &Arc<dyn hypervisor::Device>,
group: u32,
attr: u32,
val: &u64,
set: bool,
) -> crate::aarch64::gic::Result<()> {
let mut gicv3_its_attr = kvm_bindings::kvm_device_attr {
group,
attr: attr as u64,
addr: val as *const u64 as u64,
flags: 0,
};
if set {
its_device
.set_device_attr(&gicv3_its_attr)
.map_err(crate::aarch64::gic::Error::SetDeviceAttribute)?;
} else {
its_device
.get_device_attr(&mut gicv3_its_attr)
.map_err(crate::aarch64::gic::Error::GetDeviceAttribute)?;
}
Ok(())
}
/// Function that saves/restores ITS tables into guest RAM.
///
/// The tables get flushed to guest RAM whenever the VM gets stopped.
pub fn gicv3_its_tables_access(
its_device: &Arc<dyn hypervisor::Device>,
save: bool,
) -> crate::aarch64::gic::Result<()> {
let attr = if save {
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_SAVE_TABLES)
} else {
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_RESTORE_TABLES)
};
let init_gic_attr = kvm_bindings::kvm_device_attr {
group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
attr,
addr: 0,
flags: 0,
};
its_device
.set_device_attr(&init_gic_attr)
.map_err(crate::aarch64::gic::Error::SetDeviceAttribute)
}
pub struct KvmGicV3Its {
/// The hypervisor agnostic device for the GicV3
device: Arc<dyn hypervisor::Device>,
/// The hypervisor agnostic device for the Its device
its_device: Option<Arc<dyn hypervisor::Device>>,
/// Vector holding values of GICR_TYPER for each vCPU
gicr_typers: Vec<u64>,
/// GIC device properties, to be used for setting up the fdt entry
gic_properties: [u64; 4],
/// MSI device properties, to be used for setting up the fdt entry
msi_properties: [u64; 2],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
#[derive(Versionize)]
pub struct Gicv3ItsState {
dist: Vec<u32>,
rdist: Vec<u32>,
icc: Vec<u32>,
// special register that enables interrupts and affinity routing
gicd_ctlr: u32,
its_ctlr: u64,
its_iidr: u64,
its_cbaser: u64,
its_cwriter: u64,
its_creadr: u64,
its_baser: [u64; 8],
}
impl VersionMapped for Gicv3ItsState {}
impl KvmGicV3Its {
fn get_msi_size() -> u64 {
layout::GIC_V3_ITS_SIZE
}
fn get_msi_addr(vcpu_count: u64) -> u64 {
KvmGicV3::get_redists_addr(vcpu_count) - KvmGicV3Its::get_msi_size()
}
/// Save the state of GICv3ITS.
fn state(&self, gicr_typers: &[u64]) -> Result<Gicv3ItsState> {
let gicd_ctlr =
read_ctlr(self.device()).map_err(Error::SaveDistributorCtrlRegisters)?;
let dist_state =
get_dist_regs(self.device()).map_err(Error::SaveDistributorRegisters)?;
let rdist_state = get_redist_regs(self.device(), gicr_typers)
.map_err(Error::SaveRedistributorRegisters)?;
let icc_state =
get_icc_regs(self.device(), gicr_typers).map_err(Error::SaveIccRegisters)?;
let its_baser_state: [u64; 8] = [0; 8];
for i in 0..8 {
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_BASER + i * 8,
&its_baser_state[i as usize],
false,
)
.map_err(Error::SaveITSBASER)?;
}
let its_ctlr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR,
&its_ctlr_state,
false,
)
.map_err(Error::SaveITSCTLR)?;
let its_cbaser_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CBASER,
&its_cbaser_state,
false,
)
.map_err(Error::SaveITSCBASER)?;
let its_creadr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CREADR,
&its_creadr_state,
false,
)
.map_err(Error::SaveITSCREADR)?;
let its_cwriter_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CWRITER,
&its_cwriter_state,
false,
)
.map_err(Error::SaveITSCWRITER)?;
let its_iidr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_IIDR,
&its_iidr_state,
false,
)
.map_err(Error::SaveITSIIDR)?;
Ok(Gicv3ItsState {
dist: dist_state,
rdist: rdist_state,
icc: icc_state,
gicd_ctlr,
its_ctlr: its_ctlr_state,
its_iidr: its_iidr_state,
its_cbaser: its_cbaser_state,
its_cwriter: its_cwriter_state,
its_creadr: its_creadr_state,
its_baser: its_baser_state,
})
}
/// Restore the state of GICv3ITS.
fn set_state(&mut self, gicr_typers: &[u64], state: &Gicv3ItsState) -> Result<()> {
write_ctlr(self.device(), state.gicd_ctlr)
.map_err(Error::RestoreDistributorCtrlRegisters)?;
set_dist_regs(self.device(), &state.dist)
.map_err(Error::RestoreDistributorRegisters)?;
set_redist_regs(self.device(), gicr_typers, &state.rdist)
.map_err(Error::RestoreRedistributorRegisters)?;
set_icc_regs(self.device(), gicr_typers, &state.icc)
.map_err(Error::RestoreIccRegisters)?;
//Restore GICv3ITS registers
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_IIDR,
&state.its_iidr,
true,
)
.map_err(Error::RestoreITSIIDR)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CBASER,
&state.its_cbaser,
true,
)
.map_err(Error::RestoreITSCBASER)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CREADR,
&state.its_creadr,
true,
)
.map_err(Error::RestoreITSCREADR)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CWRITER,
&state.its_cwriter,
true,
)
.map_err(Error::RestoreITSCWRITER)?;
for i in 0..8 {
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_BASER + i * 8,
&state.its_baser[i as usize],
true,
)
.map_err(Error::RestoreITSBASER)?;
}
// Restore ITS tables
gicv3_its_tables_access(self.its_device().unwrap(), false)
.map_err(Error::RestoreITSTables)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR,
&state.its_ctlr,
true,
)
.map_err(Error::RestoreITSCTLR)?;
Ok(())
}
}
impl GicDevice for KvmGicV3Its {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn its_device(&self) -> Option<&Arc<dyn hypervisor::Device>> {
self.its_device.as_ref()
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn msi_compatible(&self) -> bool {
true
}
fn msi_compatibility(&self) -> &str {
"arm,gic-v3-its"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
}
fn msi_properties(&self) -> &[u64] {
&self.msi_properties
}
fn device_properties(&self) -> &[u64] {
&self.gic_properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
fn set_its_device(&mut self, its_device: Option<Arc<dyn hypervisor::Device>>) {
self.its_device = its_device;
}
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let gicr_typers = construct_gicr_typers(vcpu_states);
self.gicr_typers = gicr_typers;
}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
self
}
}
impl KvmGicDevice for KvmGicV3Its {
fn version() -> u32 {
KvmGicV3::version()
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice> {
Box::new(KvmGicV3Its {
device,
its_device: None,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
gic_properties: [
KvmGicV3::get_dist_addr(),
KvmGicV3::get_dist_size(),
KvmGicV3::get_redists_addr(vcpu_count),
KvmGicV3::get_redists_size(vcpu_count),
],
msi_properties: [
KvmGicV3Its::get_msi_addr(vcpu_count),
KvmGicV3Its::get_msi_size(),
],
vcpu_count,
})
}
fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>,
gic_device: &mut dyn GicDevice,
) -> crate::aarch64::gic::Result<()> {
KvmGicV3::init_device_attributes(vm, gic_device)?;
let mut its_device = kvm_bindings::kvm_create_device {
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
fd: 0,
flags: 0,
};
let its_fd = vm
.create_device(&mut its_device)
.map_err(crate::aarch64::gic::Error::CreateGic)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
&KvmGicV3Its::get_msi_addr(gic_device.vcpu_count()) as *const u64 as u64,
0,
)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
gic_device.set_its_device(Some(its_fd));
Ok(())
}
}
pub const GIC_V3_ITS_SNAPSHOT_ID: &str = "gic-v3-its";
impl Snapshottable for KvmGicV3Its {
fn id(&self) -> String {
GIC_V3_ITS_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let gicr_typers = self.gicr_typers.clone();
Snapshot::new_from_versioned_state(&self.id(), &self.state(&gicr_typers).unwrap())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
let gicr_typers = self.gicr_typers.clone();
self.set_state(&gicr_typers, &snapshot.to_versioned_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3ITS state {:?}", e))
})
}
}
impl Pausable for KvmGicV3Its {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(self.device()).map_err(|e| {
MigratableError::Pause(anyhow!(
"Could not save GICv3ITS GIC pending tables {:?}",
e
))
})?;
// Flush ITS tables to guest RAM.
gicv3_its_tables_access(self.its_device().unwrap(), true).map_err(|e| {
MigratableError::Pause(anyhow!("Could not save GICv3ITS ITS tables {:?}", e))
})?;
Ok(())
}
}
impl Transportable for KvmGicV3Its {}
impl Migratable for KvmGicV3Its {}
}

View File

@@ -1,220 +0,0 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
pub mod dist_regs;
pub mod gicv3;
pub mod gicv3_its;
pub mod icc_regs;
pub mod redist_regs;
pub use self::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
pub use self::icc_regs::{get_icc_regs, set_icc_regs};
pub use self::redist_regs::{get_redist_regs, set_redist_regs};
use hypervisor::CpuState;
use std::any::Any;
use std::result;
use std::sync::Arc;
/// Errors thrown while setting up the GIC.
#[derive(Debug)]
pub enum Error {
/// Error while calling KVM ioctl for setting up the global interrupt controller.
CreateGic(hypervisor::HypervisorVmError),
/// Error while setting device attributes for the GIC.
SetDeviceAttribute(hypervisor::HypervisorDeviceError),
/// Error while getting device attributes for the GIC.
GetDeviceAttribute(hypervisor::HypervisorDeviceError),
}
type Result<T> = result::Result<T, Error>;
pub trait GicDevice: Send {
/// Returns the hypervisor agnostic Device of the GIC device
fn device(&self) -> &Arc<dyn hypervisor::Device>;
/// Returns the hypervisor agnostic Device of the ITS device
fn its_device(&self) -> Option<&Arc<dyn hypervisor::Device>> {
None
}
/// Returns the fdt compatibility property of the device
fn fdt_compatibility(&self) -> &str;
/// Returns the maint_irq fdt property of the device
fn fdt_maint_irq(&self) -> u32;
/// Returns an array with GIC device properties
fn device_properties(&self) -> &[u64];
/// Returns the number of vCPUs this GIC handles
fn vcpu_count(&self) -> u64;
/// Returns whether the GIC device is MSI compatible or not
fn msi_compatible(&self) -> bool {
false
}
/// Returns the MSI compatibility property of the device
fn msi_compatibility(&self) -> &str {
""
}
/// Returns the MSI reg property of the device
fn msi_properties(&self) -> &[u64] {
&[]
}
fn set_its_device(&mut self, its_device: Option<Arc<dyn hypervisor::Device>>);
/// Get the values of GICR_TYPER for each vCPU.
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]);
/// Downcast the trait object to its concrete type.
fn as_any_concrete_mut(&mut self) -> &mut dyn Any;
}
pub mod kvm {
use super::GicDevice;
use super::Result;
use crate::aarch64::gic::gicv3_its::kvm::KvmGicV3Its;
use crate::layout;
use hypervisor::kvm::kvm_bindings;
use std::boxed::Box;
use std::sync::Arc;
/// Trait for GIC devices.
pub trait KvmGicDevice: Send + Sync + GicDevice {
/// Returns the GIC version of the device
fn version() -> u32;
/// Create the GIC device object
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice>;
/// Setup the device-specific attributes
fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>,
gic_device: &mut dyn GicDevice,
) -> Result<()>;
/// Initialize a GIC device
fn init_device(vm: &Arc<dyn hypervisor::Vm>) -> Result<Arc<dyn hypervisor::Device>> {
let mut gic_device = kvm_bindings::kvm_create_device {
type_: Self::version(),
fd: 0,
flags: 0,
};
vm.create_device(&mut gic_device)
.map_err(super::Error::CreateGic)
}
/// Set a GIC device attribute
fn set_device_attribute(
device: &Arc<dyn hypervisor::Device>,
group: u32,
attr: u64,
addr: u64,
flags: u32,
) -> Result<()> {
let attr = kvm_bindings::kvm_device_attr {
flags,
group,
attr,
addr,
};
device
.set_device_attr(&attr)
.map_err(super::Error::SetDeviceAttribute)?;
Ok(())
}
/// Get a GIC device attribute
fn get_device_attribute(
device: &Arc<dyn hypervisor::Device>,
group: u32,
attr: u64,
addr: u64,
flags: u32,
) -> Result<()> {
let mut attr = kvm_bindings::kvm_device_attr {
flags,
group,
attr,
addr,
};
device
.get_device_attr(&mut attr)
.map_err(super::Error::GetDeviceAttribute)?;
Ok(())
}
/// Finalize the setup of a GIC device
fn finalize_device(gic_device: &dyn GicDevice) -> Result<()> {
/* We need to tell the kernel how many irqs to support with this vgic.
* See the `layout` module for details.
*/
let nr_irqs: u32 = layout::IRQ_NUM;
let nr_irqs_ptr = &nr_irqs as *const u32;
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0,
nr_irqs_ptr as u64,
0,
)?;
/* Finalize the GIC.
* See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
Ok(())
}
/// Method to initialize the GIC device
#[allow(clippy::new_ret_no_self)]
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> {
let vgic_fd = Self::init_device(vm)?;
let mut device = Self::create_device(vgic_fd, vcpu_count);
Self::init_device_attributes(vm, &mut *device)?;
Self::finalize_device(&*device)?;
Ok(device)
}
}
/// Create a GICv3-ITS device.
///
pub fn create_gic(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> {
debug!("creating a GICv3-ITS");
KvmGicV3Its::new(vm, vcpu_count)
}
/// Function that saves RDIST pending tables into guest RAM.
///
/// The tables get flushed to guest RAM whenever the VM gets stopped.
pub fn save_pending_tables(gic: &Arc<dyn hypervisor::Device>) -> Result<()> {
let init_gic_attr = kvm_bindings::kvm_device_attr {
group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
attr: u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES),
addr: 0,
flags: 0,
};
gic.set_device_attr(&init_gic_attr)
.map_err(super::Error::SetDeviceAttribute)
}
}

View File

@@ -4,23 +4,19 @@
/// Module for the flattened device tree.
pub mod fdt;
/// Module for the global interrupt controller configuration.
pub mod gic;
/// Layout for this aarch64 system.
pub mod layout;
/// Logic for configuring aarch64 registers.
pub mod regs;
/// Module for loading UEFI binary.
pub mod uefi;
pub use self::fdt::DeviceInfoForFdt;
use crate::{DeviceType, GuestMemoryMmap, NumaNodes, PciSpaceInfo, RegionType};
use gic::GicDevice;
use hypervisor::arch::aarch64::gic::Vgic;
use log::{log_enabled, Level};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt::Debug;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestUsize};
/// Errors thrown while configuring aarch64 system.
@@ -33,13 +29,13 @@ pub enum Error {
WriteFdtToMemory(fdt::Error),
/// Failed to create a GIC.
SetupGic(gic::Error),
SetupGic,
/// Failed to compute the initramfs address.
InitramfsAddress,
/// Error configuring the general purpose registers
RegsConfiguration(regs::Error),
RegsConfiguration(hypervisor::HypervisorCpuError),
/// Error configuring the MPIDR register
VcpuRegMpidr(hypervisor::HypervisorCpuError),
@@ -50,7 +46,7 @@ pub enum Error {
impl From<Error> for super::Error {
fn from(e: Error) -> super::Error {
super::Error::AArch64Setup(e)
super::Error::PlatformSpecific(e)
}
}
@@ -64,16 +60,20 @@ pub struct EntryPoint {
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
fd: &Arc<dyn hypervisor::Vcpu>,
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
) -> super::Result<u64> {
if let Some(kernel_entry_point) = kernel_entry_point {
regs::setup_regs(fd, id, kernel_entry_point.entry_addr.raw_value())
.map_err(Error::RegsConfiguration)?;
vcpu.setup_regs(
id,
kernel_entry_point.entry_addr.raw_value(),
super::layout::FDT_START.raw_value(),
)
.map_err(Error::RegsConfiguration)?;
}
let mpidr = fd.read_mpidr().map_err(Error::VcpuRegMpidr)?;
let mpidr = vcpu.read_mpidr().map_err(Error::VcpuRegMpidr)?;
Ok(mpidr)
}
@@ -143,7 +143,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
initrd: &Option<super::InitramfsConfig>,
pci_space_info: &[PciSpaceInfo],
virtio_iommu_bdf: Option<u32>,
gic_device: &dyn GicDevice,
gic_device: &Arc<Mutex<dyn Vgic>>,
numa_nodes: &NumaNodes,
pmu_supported: bool,
) -> super::Result<()> {
@@ -185,10 +185,10 @@ pub fn initramfs_load_addr(
if guest_mem.address_in_range(offset) {
Ok(offset.raw_value())
} else {
Err(super::Error::AArch64Setup(Error::InitramfsAddress))
Err(super::Error::PlatformSpecific(Error::InitramfsAddress))
}
}
None => Err(super::Error::AArch64Setup(Error::InitramfsAddress)),
None => Err(super::Error::PlatformSpecific(Error::InitramfsAddress)),
}
}

View File

@@ -1,75 +0,0 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use hypervisor::kvm::kvm_bindings::{
kvm_regs, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
};
use hypervisor::{arm64_core_reg_id, offset__of};
use std::sync::Arc;
use std::{mem, result};
use vm_memory::Address;
/// Errors thrown while setting aarch64 registers.
#[derive(Debug)]
pub enum Error {
/// Failed to set core register (PC, PSTATE or general purpose ones).
SetCoreRegister(hypervisor::HypervisorCpuError),
/// Failed to get a system register.
GetSysRegister(hypervisor::HypervisorCpuError),
}
type Result<T> = result::Result<T, Error>;
#[allow(non_upper_case_globals)]
// PSR (Processor State Register) bits.
// Taken from arch/arm64/include/uapi/asm/ptrace.h.
const PSR_MODE_EL1h: u64 = 0x0000_0005;
const PSR_F_BIT: u64 = 0x0000_0040;
const PSR_I_BIT: u64 = 0x0000_0080;
const PSR_A_BIT: u64 = 0x0000_0100;
const PSR_D_BIT: u64 = 0x0000_0200;
// Taken from arch/arm64/kvm/inject_fault.c.
const PSTATE_FAULT_BITS_64: u64 = PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT;
/// Configure core registers for a given CPU.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
/// * `cpu_id` - Index of current vcpu.
/// * `boot_ip` - Starting instruction pointer.
/// * `mem` - Reserved DRAM for current VM.
pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, cpu_id: u8, boot_ip: u64) -> Result<()> {
let kreg_off = offset__of!(kvm_regs, regs);
// Get the register index of the PSTATE (Processor State) register.
let pstate = offset__of!(user_pt_regs, pstate) + kreg_off;
vcpu.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate),
PSTATE_FAULT_BITS_64,
)
.map_err(Error::SetCoreRegister)?;
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
vcpu.set_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip as u64)
.map_err(Error::SetCoreRegister)?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
vcpu.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0),
super::layout::FDT_START.raw_value(),
)
.map_err(Error::SetCoreRegister)?;
}
Ok(())
}

View File

@@ -9,15 +9,15 @@
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::SgxEpcSection;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;
use std::result;
use std::sync::Arc;
use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeError, VersionizeResult};
use versionize_derive::Versionize;
use vm_migration::VersionMapped;
@@ -26,31 +26,27 @@ type GuestMemoryMmap = vm_memory::GuestMemoryMmap<vm_memory::bitmap::AtomicBitma
type GuestRegionMmap = vm_memory::GuestRegionMmap<vm_memory::bitmap::AtomicBitmap>;
/// Type for returning error code.
#[derive(Debug)]
#[derive(Debug, Error)]
pub enum Error {
#[cfg(target_arch = "x86_64")]
/// X86_64 specific error triggered during system configuration.
X86_64Setup(x86_64::Error),
#[error("Platform specific error (x86_64): {0:?}")]
PlatformSpecific(x86_64::Error),
#[cfg(target_arch = "aarch64")]
/// AArch64 specific error triggered during system configuration.
AArch64Setup(aarch64::Error),
/// The zero page extends past the end of guest_mem.
ZeroPagePastRamEnd,
/// Error writing the zero page of guest memory.
ZeroPageSetup(vm_memory::GuestMemoryError),
/// The memory map table extends past the end of guest memory.
#[error("Platform specific error (aarch64): {0:?}")]
PlatformSpecific(aarch64::Error),
#[error("The memory map table extends past the end of guest memory")]
MemmapTablePastRamEnd,
/// Error writing memory map table to guest memory.
#[error("Error writing memory map table to guest memory")]
MemmapTableSetup,
/// The hvm_start_info structure extends past the end of guest memory.
#[error("The hvm_start_info structure extends past the end of guest memory")]
StartInfoPastRamEnd,
/// Error writing hvm_start_info to guest memory.
#[error("Error writing hvm_start_info to guest memory")]
StartInfoSetup,
/// Failed to compute initramfs address.
#[error("Failed to compute initramfs address")]
InitramfsAddress,
/// Error writing module entry to guest memory.
ModlistSetup(vm_memory::GuestMemoryError),
/// RSDP Beyond Guest Memory
#[error("Error writing module entry to guest memory: {0}")]
ModlistSetup(#[source] vm_memory::GuestMemoryError),
#[error("RSDP extends past the end of guest memory")]
RsdpPastRamEnd,
}
@@ -58,7 +54,7 @@ pub enum Error {
pub type Result<T> = result::Result<T, Error>;
/// Type for memory region types.
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize, Versionize)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize, Versionize)]
pub enum RegionType {
/// RAM type
Ram,

View File

@@ -15,7 +15,8 @@ pub mod regs;
use crate::GuestMemoryMmap;
use crate::InitramfsConfig;
use crate::RegionType;
use hypervisor::{CpuId, CpuIdEntry, HypervisorError, CPUID_FLAG_VALID_INDEX};
use hypervisor::x86_64::{CpuId, CpuIdEntry, CPUID_FLAG_VALID_INDEX};
use hypervisor::HypervisorError;
use linux_loader::loader::bootparam::boot_params;
use linux_loader::loader::elf::start_info::{
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
@@ -197,7 +198,7 @@ pub enum Error {
impl From<Error> for super::Error {
fn from(e: Error) -> super::Error {
super::Error::X86_64Setup(e)
super::Error::PlatformSpecific(e)
}
}
@@ -743,7 +744,7 @@ pub fn generate_common_cpuid(
}
pub fn configure_vcpu(
fd: &Arc<dyn hypervisor::Vcpu>,
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
@@ -755,23 +756,23 @@ pub fn configure_vcpu(
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));
fd.set_cpuid2(&cpuid)
vcpu.set_cpuid2(&cpuid)
.map_err(|e| Error::SetSupportedCpusFailed(e.into()))?;
if kvm_hyperv {
fd.enable_hyperv_synic().unwrap();
vcpu.enable_hyperv_synic().unwrap();
}
regs::setup_msrs(fd).map_err(Error::MsrsConfiguration)?;
regs::setup_msrs(vcpu).map_err(Error::MsrsConfiguration)?;
if let Some(kernel_entry_point) = kernel_entry_point {
if let Some(entry_addr) = kernel_entry_point.entry_addr {
// Safe to unwrap because this method is called after the VM is configured
regs::setup_regs(fd, entry_addr.raw_value()).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(fd).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&vm_memory.memory(), fd).map_err(Error::SregsConfiguration)?;
regs::setup_regs(vcpu, entry_addr.raw_value()).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&vm_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
}
}
interrupts::set_lint(fd).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
interrupts::set_lint(vcpu).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
Ok(())
}
@@ -838,13 +839,14 @@ pub fn configure_system(
_num_cpus: u8,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
serial_number: Option<&str>,
) -> super::Result<()> {
// Write EBDA address to location where ACPICA expects to find it
guest_mem
.write_obj((layout::EBDA_START.0 >> 4) as u16, layout::EBDA_POINTER)
.map_err(Error::EbdaSetup)?;
let size = smbios::setup_smbios(guest_mem).map_err(Error::SmbiosSetup)?;
let size = smbios::setup_smbios(guest_mem, serial_number).map_err(Error::SmbiosSetup)?;
// Place the MP table after the SMIOS table aligned to 16 bytes
let offset = GuestAddress(layout::SMBIOS_START).unchecked_add(size);
@@ -1193,6 +1195,7 @@ mod tests {
1,
Some(layout::RSDP_POINTER),
None,
None,
);
assert!(config_err.is_err());
@@ -1206,7 +1209,7 @@ mod tests {
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap();
// Now assigning some memory that is equal to the start of the 32bit memory hole.
let mem_size = 3328 << 20;
@@ -1217,9 +1220,9 @@ mod tests {
.map(|r| (r.0, r.1))
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap();
// Now assigning some memory that falls after the 32bit memory hole.
let mem_size = 3330 << 20;
@@ -1230,9 +1233,9 @@ mod tests {
.map(|r| (r.0, r.1))
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap();
configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap();
}
#[test]

View File

@@ -9,7 +9,7 @@
use crate::layout::{BOOT_GDT_START, BOOT_IDT_START, PVH_INFO_START};
use crate::GuestMemoryMmap;
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
use hypervisor::arch::x86::regs::*;
use hypervisor::arch::x86::regs::CR0_PE;
use hypervisor::x86_64::{FpuState, SpecialRegisters, StandardRegisters};
use std::sync::Arc;
use std::{mem, result};

View File

@@ -162,7 +162,7 @@ fn write_string(
Ok(curptr)
}
pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<u64> {
pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Result<u64> {
let physptr = GuestAddress(SMBIOS_START)
.checked_add(mem::size_of::<Smbios30Entrypoint>() as u64)
.ok_or(Error::NotEnoughMemory)?;
@@ -195,11 +195,15 @@ pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<u64> {
handle,
manufacturer: 1, // First string written in this section
product_name: 2, // Second string written in this section
serial_number: serial_number.map(|_| 3).unwrap_or_default(), // 3rd string
..Default::default()
};
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
curptr = write_string(mem, "Cloud Hypervisor", curptr)?;
curptr = write_string(mem, "cloud-hypervisor", curptr)?;
if let Some(serial_number) = serial_number {
curptr = write_string(mem, serial_number, curptr)?;
}
curptr = write_and_incr(mem, 0u8, curptr)?;
}
@@ -263,7 +267,7 @@ mod tests {
fn entrypoint_checksum() {
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(SMBIOS_START), 4096)]).unwrap();
setup_smbios(&mem).unwrap();
setup_smbios(&mem, None).unwrap();
let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();

View File

@@ -9,16 +9,16 @@ default = []
[dependencies]
io-uring = "0.5.2"
libc = "0.2.123"
log = "0.4.16"
libc = "0.2.126"
log = "0.4.17"
qcow = { path = "../qcow" }
thiserror = "1.0.30"
thiserror = "1.0.31"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vhdx = { path = "../vhdx" }
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.2.0"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.4.0"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"

View File

@@ -104,7 +104,7 @@ impl DiskTopology {
pub type DiskFileResult<T> = std::result::Result<T, DiskFileError>;
pub trait DiskFile: Send + Sync {
pub trait DiskFile: Send {
fn size(&mut self) -> DiskFileResult<u64>;
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>>;
fn topology(&mut self) -> DiskTopology {
@@ -127,7 +127,7 @@ pub enum AsyncIoError {
pub type AsyncIoResult<T> = std::result::Result<T, AsyncIoError>;
pub trait AsyncIo: Send + Sync {
pub trait AsyncIo: Send {
fn notifier(&self) -> &EventFd;
fn read_vectored(
&mut self,

View File

@@ -138,7 +138,7 @@ impl ExecuteError {
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RequestType {
In,
Out,

View File

@@ -6,17 +6,18 @@ edition = "2021"
[dependencies]
acpi_tables = { path = "../acpi_tables" }
anyhow = "1.0.56"
anyhow = "1.0.58"
arch = { path = "../arch" }
bitflags = "1.3.2"
byteorder = "1.4.3"
epoll = "4.3.1"
libc = "0.2.123"
log = "0.4.16"
hypervisor = { path = "../hypervisor" }
libc = "0.2.126"
log = "0.4.17"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-device = { path = "../vm-device" }
vm-memory = "0.7.0"
vm-memory = "0.8.0"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = "0.9.0"

View File

@@ -4,30 +4,34 @@
use super::interrupt_controller::{Error, InterruptController};
extern crate arch;
use arch::aarch64::gic::GicDevice;
use anyhow::anyhow;
use arch::layout;
use hypervisor::{arch::aarch64::gic::Vgic, CpuState};
use std::result;
use std::sync::{Arc, Mutex};
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup,
LegacyIrqSourceConfig, MsiIrqGroupConfig,
};
use vm_memory::Address;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
type Result<T> = result::Result<T, Error>;
// Reserve 32 IRQs for legacy device.
pub const IRQ_LEGACY_BASE: usize = arch::layout::IRQ_BASE as usize;
// Reserve 32 IRQs for legacy devices.
pub const IRQ_LEGACY_BASE: usize = layout::IRQ_BASE as usize;
pub const IRQ_LEGACY_COUNT: usize = 32;
// This Gic struct implements InterruptController to provide interrupt delivery service.
// The Gic source files in arch/ folder maintain the Aarch64 specific Gic device.
// The 2 Gic instances could be merged together.
// Leave this refactoring to future. Two options may be considered:
// 1. Move Gic*.rs from arch/ folder here.
// 2. Move this file and ioapic.rs to arch/, as they are architecture specific.
// Gic (Generic Interupt Controller) struct provides all the functionality of a
// GIC device. It wraps a hypervisor-emulated GIC device (Vgic) provided by the
// `hypervisor` crate.
// Gic struct also implements InterruptController to provide interrupt delivery
// service.
pub struct Gic {
interrupt_source_group: Arc<dyn InterruptSourceGroup>,
gic_device: Option<Arc<Mutex<Box<dyn GicDevice>>>>,
// The hypervisor agnostic virtual GIC
vgic: Option<Arc<Mutex<dyn Vgic>>>,
}
impl Gic {
@@ -44,16 +48,32 @@ impl Gic {
Ok(Gic {
interrupt_source_group,
gic_device: None,
vgic: None,
})
}
pub fn set_gic_device(&mut self, gic_device: Arc<Mutex<Box<dyn GicDevice>>>) {
self.gic_device = Some(gic_device);
pub fn create_vgic(
&mut self,
vm: &Arc<dyn hypervisor::Vm>,
vcpu_count: u64,
) -> Result<Arc<Mutex<dyn Vgic>>> {
let vgic = vm
.create_vgic(
vcpu_count,
layout::GIC_V3_DIST_START.raw_value(),
layout::GIC_V3_DIST_SIZE,
layout::GIC_V3_REDIST_SIZE,
layout::GIC_V3_ITS_SIZE,
layout::IRQ_NUM,
)
.map_err(Error::CreateGic)?;
self.vgic = Some(vgic.clone());
Ok(vgic.clone())
}
pub fn get_gic_device(&self) -> Option<&Arc<Mutex<Box<dyn GicDevice>>>> {
self.gic_device.as_ref()
pub fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock().unwrap().set_gicr_typers(vcpu_states);
}
}
@@ -97,3 +117,43 @@ impl InterruptController for Gic {
self.interrupt_source_group.notifier(irq as InterruptIndex)
}
}
pub const GIC_V3_ITS_SNAPSHOT_ID: &str = "gic-v3-its";
impl Snapshottable for Gic {
fn id(&self) -> String {
GIC_V3_ITS_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let vgic = self.vgic.as_ref().unwrap().clone();
let state = vgic.lock().unwrap().state().unwrap();
Snapshot::new_from_state(&self.id(), &state)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock()
.unwrap()
.set_state(&snapshot.to_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3ITS state {:?}", e))
})?;
Ok(())
}
}
impl Pausable for Gic {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// Flush tables to guest RAM
let vgic = self.vgic.as_ref().unwrap().clone();
vgic.lock().unwrap().save_data_tables().map_err(|e| {
MigratableError::Pause(anyhow!(
"Could not save GICv3ITS GIC pending tables {:?}",
e
))
})?;
Ok(())
}
}
impl Transportable for Gic {}
impl Migratable for Gic {}

View File

@@ -24,6 +24,8 @@ pub enum Error {
UpdateInterrupt(io::Error),
/// Failed enabling the interrupt.
EnableInterrupt(io::Error),
/// Failed creating GIC device.
CreateGic(hypervisor::HypervisorVmError),
}
type Result<T> = result::Result<T, Error>;

View File

@@ -0,0 +1,86 @@
// Copyright © 2022 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use std::fmt;
use std::time::Instant;
use vm_device::BusDevice;
/// Debug I/O port, see:
/// https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html
///
/// Since we're not a physical platform, we can freely assign code ranges for
/// debugging specific parts of our virtual platform.
pub enum DebugIoPortRange {
Firmware,
Bootloader,
Kernel,
Userspace,
Custom,
}
#[cfg(target_arch = "x86_64")]
const DEBUG_IOPORT_PREFIX: &str = "Debug I/O port";
#[cfg(target_arch = "x86_64")]
impl DebugIoPortRange {
fn from_u8(value: u8) -> DebugIoPortRange {
match value {
0x00..=0x1f => DebugIoPortRange::Firmware,
0x20..=0x3f => DebugIoPortRange::Bootloader,
0x40..=0x5f => DebugIoPortRange::Kernel,
0x60..=0x7f => DebugIoPortRange::Userspace,
_ => DebugIoPortRange::Custom,
}
}
}
#[cfg(target_arch = "x86_64")]
impl fmt::Display for DebugIoPortRange {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DebugIoPortRange::Firmware => write!(f, "{}: Firmware", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Bootloader => write!(f, "{}: Bootloader", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Kernel => write!(f, "{}: Kernel", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Userspace => write!(f, "{}: Userspace", DEBUG_IOPORT_PREFIX),
DebugIoPortRange::Custom => write!(f, "{}: Custom", DEBUG_IOPORT_PREFIX),
}
}
}
pub struct DebugPort {
timestamp: Instant,
}
impl DebugPort {
pub fn new(timestamp: Instant) -> Self {
Self { timestamp }
}
}
impl BusDevice for DebugPort {
fn read(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {
error!("Invalid read to debug port")
}
fn write(
&mut self,
_base: u64,
_offset: u64,
data: &[u8],
) -> Option<std::sync::Arc<std::sync::Barrier>> {
let elapsed = self.timestamp.elapsed();
let code = data[0];
warn!(
"[{} code 0x{:x}] {}.{:>06} seconds",
DebugIoPortRange::from_u8(code),
code,
elapsed.as_secs(),
elapsed.as_micros()
);
None
}
}

View File

@@ -6,6 +6,8 @@
// found in the LICENSE-BSD-3-Clause file.
mod cmos;
#[cfg(target_arch = "x86_64")]
mod debug_port;
#[cfg(feature = "fwdebug")]
mod fwdebug;
#[cfg(target_arch = "aarch64")]
@@ -18,6 +20,8 @@ mod serial;
mod uart_pl011;
pub use self::cmos::Cmos;
#[cfg(target_arch = "x86_64")]
pub use self::debug_port::DebugPort;
#[cfg(feature = "fwdebug")]
pub use self::fwdebug::FwDebugDevice;
pub use self::i8042::I8042Device;

View File

@@ -10,6 +10,7 @@ use crate::{read_le_u32, write_le_u32};
use std::collections::VecDeque;
use std::fmt;
use std::sync::{Arc, Barrier};
use std::time::Instant;
use std::{io, result};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
@@ -120,6 +121,7 @@ impl Pl011 {
id: String,
irq: Arc<dyn InterruptSourceGroup>,
out: Option<Box<dyn io::Write + Send>>,
timestamp: Instant,
) -> Self {
Self {
id,
@@ -140,7 +142,7 @@ impl Pl011 {
read_trigger: 1u32,
irq,
out,
timestamp: std::time::Instant::now(),
timestamp,
}
}
@@ -495,6 +497,7 @@ mod tests {
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Some(Box::new(pl011_out.clone())),
Instant::now(),
);
pl011.write(0, UARTDR as u64, &[b'x', b'y']);
@@ -515,6 +518,7 @@ mod tests {
String::from(SERIAL_NAME),
Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
Some(Box::new(pl011_out)),
Instant::now(),
);
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd

View File

@@ -89,6 +89,7 @@ Trigger power button of the VM | `/vm.power-button` | N/A
Pause the VM | `/vm.pause` | N/A | N/A | The VM is booted
Resume the VM | `/vm.resume` | N/A | N/A | The VM is paused
Task a snapshot of the VM | `/vm.snapshot` | `/schemas/VmSnapshotConfig`| N/A | The VM is paused
Perform a coredump of the VM | `/vm.coredump` | `/schemas/VmCoredumpData` | N/A | The VM is paused
Restore the VM from a snapshot | `/vm.restore` | `/schemas/RestoreConfig` | N/A | The VM is created but not booted
Add/remove CPUs to/from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted
Add/remove memory from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted

View File

@@ -6,22 +6,22 @@ This document describes the device model supported by `cloud-hypervisor`.
| Device | Build configurable | Enabled by default | Runtime configurable |
| :----: | :----: | :----: | :----: |
| Serial port | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| RTC/CMOS | :heavy_check_mark: | :heavy_check_mark: | :negative_squared_cross_mark: |
| I/O APIC | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| i8042 shutdown/reboot | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :negative_squared_cross_mark: |
| ACPI shutdown/reboot | :negative_squared_cross_mark: | :heavy_check_mark: | :negative_squared_cross_mark: |
| virtio-blk | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-console | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-iommu | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-net | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-pmem | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-rng | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-vsock | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-blk | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-fs | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-net | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| VFIO | :heavy_check_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| Serial port | :x: | :x: | :heavy_check_mark: |
| RTC/CMOS | :heavy_check_mark: | :heavy_check_mark: | :x: |
| I/O APIC | :x: | :x: | :heavy_check_mark: |
| i8042 shutdown/reboot | :x: | :x: | :x: |
| ACPI shutdown/reboot | :x: | :heavy_check_mark: | :x: |
| virtio-blk | :x: | :x: | :heavy_check_mark: |
| virtio-console | :x: | :x: | :heavy_check_mark: |
| virtio-iommu | :x: | :x: | :heavy_check_mark: |
| virtio-net | :x: | :x: | :heavy_check_mark: |
| virtio-pmem | :x: | :x: | :heavy_check_mark: |
| virtio-rng | :x: | :x: | :heavy_check_mark: |
| virtio-vsock | :x: | :x: | :heavy_check_mark: |
| vhost-user-blk | :x: | :x: | :heavy_check_mark: |
| vhost-user-fs | :x: | :x: | :heavy_check_mark: |
| vhost-user-net | :x: | :x: | :heavy_check_mark: |
| VFIO | :heavy_check_mark: | :x: | :heavy_check_mark: |
## Legacy devices

View File

@@ -24,8 +24,8 @@ bucket is unbounded in speed which allows for bursts bound in size by
the amount of tokens available. Once the token bucket is empty,
consumption speed is bound by the "refill-rate". Similarly, Cloud
Hypervisor provides another three options for limiting I/O operations,
i.e., `ops_size` (I/O operations), `bw_one_time_burst` (I/O operations),
and `bw_refill_time` (ms).
i.e., `ops_size` (I/O operations), `ops_one_time_burst` (I/O operations),
and `ops_refill_time` (ms).
One caveat in the I/O throttling is that every-time the bucket gets
empty, it will stop I/O operations for a fixed amount of time

View File

@@ -43,3 +43,22 @@ $ perf report -g
```
If profiling with a network device attached either the TAP device must be already created and configured or the profiling must be done as root so that the TAP device can be created.
## Userspace only profiling with LBR
The use of LBR (Last Branch Record; available since Haswell) offers lower
overhead if only userspace profiling is required. This lower overhead can allow
a higher frequency of sampling. This also removes the requirement to compile
with custom `RUSTFLAGS` however debug symbols should still be included:
e.g.
```
$ perf record --call-graph lbr --all-user --user-callchains -g target/release/cloud-hypervisor \
--kernel ~/src/linux/vmlinux \
--pmem file=~/workloads/focal.raw \
--cpus boot=1 --memory size=1G \
--cmdline "root=/dev/pmem0p1 console=ttyS0" \
--serial tty --console off \
--api-socket=/tmp/api1
```

103
docs/releases.md Executable file
View File

@@ -0,0 +1,103 @@
# Release Documentation
## Abstract
This document provides guidance to users, downstream maintainers and
any other consumers of the Cloud Hypervisor project, this document
describes the release process, release cadence, stability expectations and
related topics.
## Basic Terms
### Stability
For Cloud Hypervisor the following areas are subject to stability guarantees:
- [REST API](api.md#rest-api)
- [Command line options](api.md#command-line-interface)
- [Device Model](device_model.md)
- Device tree, device list, ACPI, Hyper-V enlightenments and any other
features exposed to guest
- KVM compatibility
- Rust edition compatibility
This list is incomplete but this document serves as a best effort guide to stability
across releases.
### Experimental features
Experimental features are under active development and no guarantees are made about their stability.
List of experimental features:
- TDX
- vfio-user
- vDPA
### Security
Security fixes should be included in a new point release.
For security issues an advisory will be published via the GitHub security advisory process along with the release. Watching the project on GitHub will notify you of those issues.
## Releases
### Versioning
The versioning scheme uses `MAJOR.POINT` pattern:
- `MAJOR` can introduce incompatible changes along with support for new features. Changes to the [API](api.md#rest-api),
[CLI options](api.md#command-line-interface) and [device model](device_model.md)
require a notice at least 2 releases in advance for the actual change to take
place.
- `POINT` contains bug fixes and/or security fixes.
### Major Release Cadence
Cloud Hypervisor is under active development. A new major release is issued approximately
every 6 weeks. Point releases are issued on demand, when important bug fixes are in
the queue. A major release would receive bug fixes for the next two cycles (~12 weeks)
and then be considered EOL.
```
+ - Active release support
E - EOL
2021 2022 2023
| | | | | | | | |
18.0 | | | ++++++++E
19.0 | | | |++++++++E
20.0 | | | | ++++++++E
21.0 | | | | | ++++++++E
22.0 | | | | | +++++++++E
23.0 | | | | | | +++++++++E
```
### Major Release Stability Considerations
Snapshot/restore support is not compatible across `MAJOR` versions.
Live migration support is not compatible across `MAJOR` versions.
### LTS Release Cadence
A regular release is promoted to LTS every 12 months. An LTS release is supported for 18 months. This gives a 6 months window for users to move to the new LTS.
```
+ - Active release support
E - EOL
2022 2023 2024 2025 2026
| | | | | | | | | | | | | | | | |
23.0 | |+++++++++++++++++++++++++++++E
43.0 | | | | | |+++++++++++++++++++++++++++++E
63.0 | | | | | | | | | |+++++++++++++++++++++++++++++E
```
### LTS Stablity Considerations
An LTS release is just a `MAJOR` release for which point releases are made for
longer following the same rules for what can be backported to a `POINT` release.
The focus lays on critical and security bug fixes which are pulled at the
maintainer's discretion.

View File

@@ -75,8 +75,7 @@ Here is an example how to create a bridge and add two DPDK ports to it
ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev
# create two DPDK ports and add them to the bridge
ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser
ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2
type=dpdkvhostuser
ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser
# set the number of rx queues
ovs-vsctl set Interface vhost-user1 options:n_rxq=2
ovs-vsctl set Interface vhost-user2 options:n_rxq=2

View File

@@ -5,7 +5,6 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
libc = "0.2.123"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
serde_json = "1.0.79"
libc = "0.2.126"
serde = { version = "1.0.138", features = ["rc", "derive"] }
serde_json = "1.0.82"

View File

@@ -3,12 +3,11 @@
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use]
extern crate serde_derive;
use serde::Serialize;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::File;
use std::io::Write;
use std::os::unix::io::AsRawFd;
use std::time::{Duration, Instant};
@@ -50,6 +49,9 @@ pub fn event_log(source: &str, event: &str, properties: Option<&HashMap<Cow<str>
properties,
};
serde_json::to_writer_pretty(file, &e).ok();
let mut file = file;
file.write_all(b"\n\n").ok();
}
}

204
fuzz/Cargo.lock generated
View File

@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.56"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
[[package]]
name = "api_client"
@@ -24,9 +24,9 @@ dependencies = [
[[package]]
name = "arbitrary"
version = "1.1.0"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c38b6b6b79f671c25e1a3e785b7b82d7562ffc9cd3efdc98627e5668a2472490"
checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60"
[[package]]
name = "arc-swap"
@@ -47,7 +47,6 @@ dependencies = [
"linux-loader",
"log",
"serde",
"serde_derive",
"thiserror",
"versionize",
"versionize_derive",
@@ -128,24 +127,33 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.1.8"
version = "3.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"lazy_static",
"os_str_bytes",
"once_cell",
"strsim",
"termcolor",
"terminal_size",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "cloud-hypervisor"
version = "22.0.0"
version = "24.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -208,6 +216,7 @@ dependencies = [
"bitflags",
"byteorder",
"epoll",
"hypervisor",
"libc",
"log",
"versionize",
@@ -234,7 +243,6 @@ version = "0.1.0"
dependencies = [
"libc",
"serde",
"serde_derive",
"serde_json",
]
@@ -244,35 +252,11 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b643857cf70949306b81d7e92cb9d47add673868edac9863c4a49c42feaf3f1e"
[[package]]
name = "gdbstub"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa2ca5d6b045de372cef3991f873389b421b4cabcfbe52f7787fae8b8b37906"
dependencies = [
"bitflags",
"cfg-if",
"log",
"managed",
"num-traits",
"paste",
]
[[package]]
name = "gdbstub_arch"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51dc4b5718ac76d21e8605c0966dd32d80273b89b11e6cfef467b04e45934d37"
dependencies = [
"gdbstub",
"num-traits",
]
[[package]]
name = "getrandom"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
@@ -281,9 +265,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.11.2"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
[[package]]
name = "hermit-abi"
@@ -306,7 +290,6 @@ dependencies = [
"libc",
"log",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vm-memory",
@@ -325,9 +308,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.1"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
@@ -345,9 +328,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "kvm-bindings"
@@ -377,9 +360,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.123"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libfuzzer-sys"
@@ -403,25 +386,13 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.16"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "managed"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "micro_http"
version = "0.1.0"
@@ -458,20 +429,11 @@ dependencies = [
"vmm-sys-util",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.10.0"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "option_parser"
@@ -479,18 +441,9 @@ version = "0.1.0"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]]
name = "paste"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "pci"
@@ -502,7 +455,6 @@ dependencies = [
"libc",
"log",
"serde",
"serde_derive",
"thiserror",
"versionize",
"versionize_derive",
@@ -518,11 +470,11 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.37"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
@@ -538,9 +490,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.18"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@@ -556,9 +508,9 @@ dependencies = [
[[package]]
name = "remain"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
checksum = "0c35270ea384ac1762895831cc8acb96f171468e52cec82ed9186f9416209fa4"
dependencies = [
"proc-macro2",
"quote",
@@ -576,9 +528,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "seccompiler"
@@ -591,21 +543,24 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.7"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
dependencies = [
"proc-macro2",
"quote",
@@ -614,9 +569,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.79"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
dependencies = [
"itoa",
"ryu",
@@ -625,9 +580,9 @@ dependencies = [
[[package]]
name = "signal-hook"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
dependencies = [
"libc",
"signal-hook-registry",
@@ -656,13 +611,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.91"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
@@ -695,18 +650,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
@@ -714,16 +669,16 @@ dependencies = [
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "uuid"
version = "0.8.2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
dependencies = [
"getrandom",
]
@@ -847,7 +802,6 @@ dependencies = [
"rate_limiter",
"seccompiler",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
@@ -865,9 +819,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3785325315e6496fa88673842ee6cd198b9658e88e8b0e1ad48a5dc818b221dc"
checksum = "88f2d73c184c18f8acc32dab77fcb6e3af92d53262538d3a68aa474810d6863c"
dependencies = [
"log",
"vm-memory",
@@ -888,8 +842,8 @@ name = "vm-device"
version = "0.1.0"
dependencies = [
"anyhow",
"hypervisor",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vfio-ioctls",
@@ -904,9 +858,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#720e48e435b791ec6cb
[[package]]
name = "vm-memory"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339d4349c126fdcd87e034631d7274370cf19eb0e87b33166bcd956589fc72c5"
checksum = "767ed8aaebbff902e02e6d3749dc2baef55e46565f8a6414a065e5baee4b4a81"
dependencies = [
"arc-swap",
"libc",
@@ -919,7 +873,6 @@ version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
@@ -951,21 +904,18 @@ dependencies = [
"devices",
"epoll",
"event_monitor",
"gdbstub",
"gdbstub_arch",
"hypervisor",
"lazy_static",
"libc",
"linux-loader",
"log",
"micro_http",
"net_util",
"once_cell",
"option_parser",
"pci",
"qcow",
"seccompiler",
"serde",
"serde_derive",
"serde_json",
"signal-hook",
"thiserror",
@@ -999,9 +949,9 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"

View File

@@ -10,16 +10,16 @@ cargo-fuzz = true
[dependencies]
block_util = { path = "../block_util" }
libc = "0.2.123"
libc = "0.2.126"
libfuzzer-sys = "0.4.3"
qcow = { path = "../qcow" }
seccompiler = "0.2.0"
vhdx = { path = "../vhdx" }
virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.2.0"
virtio-queue = "0.4.0"
vmm-sys-util = "0.9.0"
vm-virtio = { path = "../vm-virtio" }
vm-memory = "0.7.0"
vm-memory = "0.8.0"
[dependencies.cloud-hypervisor]
path = ".."

View File

@@ -11,19 +11,18 @@ mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.56"
anyhow = "1.0.58"
epoll = "4.3.1"
thiserror = "1.0.30"
libc = "0.2.123"
log = "0.4.16"
thiserror = "1.0.31"
libc = "0.2.126"
log = "0.4.17"
kvm-ioctls = { version = "0.11.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0-tdx", features = ["with-serde", "fam-wrappers"], optional = true }
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}
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
serde_json = "1.0.79"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic"] }
serde = { version = "1.0.138", features = ["rc", "derive"] }
serde_json = "1.0.82"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.9.0", features = ["with-serde"] }
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]

View File

@@ -0,0 +1,59 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
use crate::{CpuState, Device, GicState, HypervisorDeviceError, HypervisorVmError};
use std::any::Any;
use std::result;
use std::sync::Arc;
/// Errors thrown while setting up the VGIC.
#[derive(Debug)]
pub enum Error {
/// Error while calling KVM ioctl for setting up the global interrupt controller.
CreateGic(HypervisorVmError),
/// Error while setting device attributes for the GIC.
SetDeviceAttribute(HypervisorDeviceError),
/// Error while getting device attributes for the GIC.
GetDeviceAttribute(HypervisorDeviceError),
}
pub type Result<T> = result::Result<T, Error>;
/// Hypervisor agnostic interface for a virtualized GIC
pub trait Vgic: Send + Sync {
/// Returns the fdt compatibility property of the device
fn fdt_compatibility(&self) -> &str;
/// Returns the maint_irq fdt property of the device
fn fdt_maint_irq(&self) -> u32;
/// Returns an array with GIC device properties
fn device_properties(&self) -> [u64; 4];
/// Returns the number of vCPUs this GIC handles
fn vcpu_count(&self) -> u64;
/// Returns whether the GIC device is MSI compatible or not
fn msi_compatible(&self) -> bool;
/// Returns the MSI compatibility property of the device
fn msi_compatibility(&self) -> &str;
/// Returns the MSI reg property of the device
fn msi_properties(&self) -> [u64; 2];
fn set_its_device(&mut self, its_device: Option<Arc<dyn Device>>);
/// Get the values of GICR_TYPER for each vCPU.
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]);
/// Downcast the trait object to its concrete type.
fn as_any_concrete_mut(&mut self) -> &mut dyn Any;
/// Save the state of GICv3ITS.
fn state(&self) -> Result<GicState>;
/// Restore the state of GICv3ITS.
fn set_state(&mut self, state: &GicState) -> Result<()>;
/// Saves GIC internal data tables into RAM.
fn save_data_tables(&self) -> Result<()>;
}

View File

@@ -0,0 +1,3 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
pub mod gic;

View File

@@ -99,7 +99,7 @@ pub enum EmulationError<T: Debug> {
/// A CpuState is an architecture specific type, representing a CPU state.
/// The emulator and its instruction handlers modify a given CPU state and
/// eventually ask the platform to commit it back through `set_cpu_state`.
pub trait PlatformEmulator: Send + Sync {
pub trait PlatformEmulator {
type CpuState: Clone;
/// Read guest memory into a u8 slice.

View File

@@ -10,9 +10,14 @@
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
//
pub mod emulator;
#[cfg(target_arch = "x86_64")]
#[macro_use]
pub mod x86;
#[cfg(target_arch = "aarch64")]
pub mod aarch64;

View File

@@ -28,14 +28,11 @@ fn get_op<T: CpuStateManager>(
)));
}
match op_size {
1 | 2 | 4 | 8 => {}
_ => {
return Err(PlatformError::InvalidOperand(anyhow!(
"Invalid operand size {:?}",
op_size
)))
}
if !matches!(op_size, 1 | 2 | 4 | 8) {
return Err(PlatformError::InvalidOperand(anyhow!(
"Invalid operand size {:?}",
op_size
)));
}
let value = match insn
@@ -81,14 +78,11 @@ fn set_op<T: CpuStateManager>(
)));
}
match op_size {
1 | 2 | 4 | 8 => {}
_ => {
return Err(PlatformError::InvalidOperand(anyhow!(
"Invalid operand size {:?}",
op_size
)))
}
if !matches!(op_size, 1 | 2 | 4 | 8) {
return Err(PlatformError::InvalidOperand(anyhow!(
"Invalid operand size {:?}",
op_size
)));
}
match insn

View File

@@ -6,9 +6,8 @@
use crate::arch::emulator::{EmulationError, EmulationResult, PlatformEmulator, PlatformError};
use crate::arch::x86::emulator::instructions::*;
use crate::arch::x86::regs::*;
use crate::arch::x86::*;
use crate::arch::x86::{Exception, SegmentRegisterOps};
use crate::arch::x86::regs::{CR0_PE, EFER_LMA};
use crate::arch::x86::{segment_type_expand_down, segment_type_ro, Exception, SegmentRegisterOps};
use crate::x86_64::{SegmentRegister, SpecialRegisters, StandardRegisters};
use anyhow::Context;
use iced_x86::*;
@@ -17,7 +16,7 @@ use iced_x86::*;
mod instructions;
/// x86 CPU modes
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Eq)]
pub enum CpuMode {
/// Real mode
Real,

View File

@@ -12,6 +12,12 @@
use crate::aarch64::VcpuInit;
#[cfg(target_arch = "aarch64")]
use crate::aarch64::{RegList, Register, StandardRegisters};
#[cfg(feature = "tdx")]
use crate::kvm::{TdxExitDetails, TdxExitStatus};
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
use crate::x86_64::SuspendRegisters;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::Xsave;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::{CpuId, LapicState};
#[cfg(target_arch = "x86_64")]
@@ -23,12 +29,6 @@ use crate::CpuState;
use crate::DeviceAttr;
#[cfg(feature = "kvm")]
use crate::MpState;
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
use crate::SuspendRegisters;
#[cfg(target_arch = "x86_64")]
use crate::Xsave;
#[cfg(feature = "tdx")]
use crate::{TdxExitDetails, TdxExitStatus};
use thiserror::Error;
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
use vm_memory::GuestAddress;
@@ -453,6 +453,11 @@ pub trait Vcpu: Send + Sync {
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn read_mpidr(&self) -> Result<u64>;
///
/// Configure core registers for a given CPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> Result<()>;
///
/// Retrieve the vCPU state.
/// This function is necessary to snapshot the VM
///

View File

@@ -7,13 +7,13 @@
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
#[cfg(feature = "tdx")]
use crate::kvm::TdxCapabilities;
use crate::vm::Vm;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::CpuId;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::MsrList;
#[cfg(feature = "tdx")]
use crate::TdxCapabilities;
use std::sync::Arc;
use thiserror::Error;
@@ -66,6 +66,11 @@ pub enum HypervisorError {
///
#[error("Failed to retrieve TDX capabilities:{0}")]
TdxCapabilities(#[source] anyhow::Error),
///
/// Failed to set partition property
///
#[error("Failed to set partition property:{0}")]
SetPartitionProperty(#[source] anyhow::Error),
}
///

View File

@@ -1,11 +1,11 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use crate::layout::IRQ_BASE;
use hypervisor::kvm::kvm_bindings::{
use crate::arch::aarch64::gic::{Error, Result};
use crate::kvm::kvm_bindings::{
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
};
use crate::Device;
use std::sync::Arc;
/*
@@ -77,12 +77,7 @@ static VGIC_DIST_REGS: &[DistReg] = &[
VGIC_DIST_REG!(GICD_IPRIORITYR, 8, 0),
];
fn dist_attr_access(
gic: &Arc<dyn hypervisor::Device>,
offset: u32,
val: &u32,
set: bool,
) -> Result<()> {
fn dist_attr_access(gic: &Arc<dyn Device>, offset: u32, val: &u32, set: bool) -> Result<()> {
let mut gic_dist_attr = kvm_device_attr {
group: KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
attr: offset as u64,
@@ -100,18 +95,18 @@ fn dist_attr_access(
}
/// Get the distributor control register.
pub fn read_ctlr(gic: &Arc<dyn hypervisor::Device>) -> Result<u32> {
pub fn read_ctlr(gic: &Arc<dyn Device>) -> Result<u32> {
let val: u32 = 0;
dist_attr_access(gic, GICD_CTLR, &val, false)?;
Ok(val)
}
/// Set the distributor control register.
pub fn write_ctlr(gic: &Arc<dyn hypervisor::Device>, val: u32) -> Result<()> {
pub fn write_ctlr(gic: &Arc<dyn Device>, val: u32) -> Result<()> {
dist_attr_access(gic, GICD_CTLR, &val, true)
}
fn get_interrupts_num(gic: &Arc<dyn hypervisor::Device>) -> Result<u32> {
fn get_interrupts_num(gic: &Arc<dyn Device>) -> Result<u32> {
let num_irq = 0;
let mut nr_irqs_attr = kvm_device_attr {
@@ -125,7 +120,12 @@ fn get_interrupts_num(gic: &Arc<dyn hypervisor::Device>) -> Result<u32> {
Ok(num_irq)
}
fn compute_reg_len(gic: &Arc<dyn hypervisor::Device>, reg: &DistReg, base: u32) -> Result<u32> {
fn compute_reg_len(gic: &Arc<dyn Device>, reg: &DistReg, base: u32) -> Result<u32> {
// FIXME:
// Redefine some GIC constants to avoid the dependency on `layout` crate.
// This is temporary solution, will be fixed in future refactoring.
const LAYOUT_IRQ_BASE: u32 = 32;
let mut end = base;
let num_irq = get_interrupts_num(gic)?;
if reg.length > 0 {
@@ -138,8 +138,8 @@ fn compute_reg_len(gic: &Arc<dyn hypervisor::Device>, reg: &DistReg, base: u32)
// This is the type of register that takes into account the number of interrupts
// that the model has. It is also the type of register where
// a register relates to multiple interrupts.
end = base + (reg.bpi as u32 * (num_irq - IRQ_BASE) / 8);
if reg.bpi as u32 * (num_irq - IRQ_BASE) % 8 > 0 {
end = base + (reg.bpi as u32 * (num_irq - LAYOUT_IRQ_BASE) / 8);
if reg.bpi as u32 * (num_irq - LAYOUT_IRQ_BASE) % 8 > 0 {
end += REG_SIZE as u32;
}
}
@@ -147,7 +147,7 @@ fn compute_reg_len(gic: &Arc<dyn hypervisor::Device>, reg: &DistReg, base: u32)
}
/// Set distributor registers of the GIC.
pub fn set_dist_regs(gic: &Arc<dyn hypervisor::Device>, state: &[u32]) -> Result<()> {
pub fn set_dist_regs(gic: &Arc<dyn Device>, state: &[u32]) -> Result<()> {
let mut idx = 0;
for dreg in VGIC_DIST_REGS {
@@ -164,7 +164,7 @@ pub fn set_dist_regs(gic: &Arc<dyn hypervisor::Device>, state: &[u32]) -> Result
Ok(())
}
/// Get distributor registers of the GIC.
pub fn get_dist_regs(gic: &Arc<dyn hypervisor::Device>) -> Result<Vec<u32>> {
pub fn get_dist_regs(gic: &Arc<dyn Device>) -> Result<Vec<u32>> {
let mut state = Vec::new();
for dreg in VGIC_DIST_REGS {

View File

@@ -1,13 +1,15 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use hypervisor::kvm::kvm_bindings::{
use crate::arch::aarch64::gic::{Error, Result};
use crate::kvm::kvm_bindings::{
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, KVM_REG_ARM64_SYSREG_CRM_MASK,
KVM_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_SHIFT,
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP1_MASK,
KVM_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT,
};
use crate::Device;
use std::sync::Arc;
const KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT: u32 = 32;
@@ -78,7 +80,7 @@ static VGIC_ICC_REGS: &[u64] = &[
];
fn icc_attr_access(
gic: &Arc<dyn hypervisor::Device>,
gic: &Arc<dyn Device>,
offset: u64,
typer: u64,
val: &u32,
@@ -101,7 +103,7 @@ fn icc_attr_access(
}
/// Get ICC registers.
pub fn get_icc_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
pub fn get_icc_regs(gic: &Arc<dyn Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
let mut state: Vec<u32> = Vec::new();
// We need this for the ICC_AP<m>R<n>_EL1 registers.
let mut num_priority_bits = 0;
@@ -154,11 +156,7 @@ pub fn get_icc_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) -> Re
}
/// Set ICC registers.
pub fn set_icc_regs(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &[u32],
) -> Result<()> {
pub fn set_icc_regs(gic: &Arc<dyn Device>, gicr_typer: &[u64], state: &[u32]) -> Result<()> {
let mut num_priority_bits = 0;
let mut idx = 0;
for ix in gicr_typer {

View File

@@ -0,0 +1,615 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
mod dist_regs;
mod icc_regs;
mod redist_regs;
use crate::arch::aarch64::gic::{Error, Result, Vgic};
use crate::kvm::kvm_bindings;
use crate::{CpuState, Device, Vm};
use dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
use icc_regs::{get_icc_regs, set_icc_regs};
use redist_regs::{construct_gicr_typers, get_redist_regs, set_redist_regs};
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::convert::TryInto;
use std::sync::Arc;
const GITS_CTLR: u32 = 0x0000;
const GITS_IIDR: u32 = 0x0004;
const GITS_CBASER: u32 = 0x0080;
const GITS_CWRITER: u32 = 0x0088;
const GITS_CREADR: u32 = 0x0090;
const GITS_BASER: u32 = 0x0100;
/// Access an ITS device attribute.
///
/// This is a helper function to get/set the ITS device attribute depending
/// the bool parameter `set` provided.
pub fn gicv3_its_attr_access(
its_device: &Arc<dyn Device>,
group: u32,
attr: u32,
val: &u64,
set: bool,
) -> Result<()> {
let mut gicv3_its_attr = kvm_bindings::kvm_device_attr {
group,
attr: attr as u64,
addr: val as *const u64 as u64,
flags: 0,
};
if set {
its_device
.set_device_attr(&gicv3_its_attr)
.map_err(Error::SetDeviceAttribute)
} else {
its_device
.get_device_attr(&mut gicv3_its_attr)
.map_err(Error::GetDeviceAttribute)
}
}
/// Function that saves/restores ITS tables into guest RAM.
///
/// The tables get flushed to guest RAM whenever the VM gets stopped.
pub fn gicv3_its_tables_access(its_device: &Arc<dyn Device>, save: bool) -> Result<()> {
let attr = if save {
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_SAVE_TABLES)
} else {
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_RESTORE_TABLES)
};
let init_gic_attr = kvm_bindings::kvm_device_attr {
group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
attr,
addr: 0,
flags: 0,
};
its_device
.set_device_attr(&init_gic_attr)
.map_err(Error::SetDeviceAttribute)
}
pub struct KvmGicV3Its {
/// The hypervisor agnostic device for the GicV3
device: Arc<dyn Device>,
/// The hypervisor agnostic device for the Its device
its_device: Option<Arc<dyn Device>>,
/// Vector holding values of GICR_TYPER for each vCPU
gicr_typers: Vec<u64>,
/// GIC distributor address
dist_addr: u64,
/// GIC distributor size
dist_size: u64,
/// GIC distributors address
redists_addr: u64,
/// GIC distributors size
redists_size: u64,
/// GIC MSI address
msi_addr: u64,
/// GIC MSI size
msi_size: u64,
/// Number of CPUs handled by the device
vcpu_count: u64,
}
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct Gicv3ItsState {
dist: Vec<u32>,
rdist: Vec<u32>,
icc: Vec<u32>,
// special register that enables interrupts and affinity routing
gicd_ctlr: u32,
its_ctlr: u64,
its_iidr: u64,
its_cbaser: u64,
its_cwriter: u64,
its_creadr: u64,
its_baser: [u64; 8],
}
impl KvmGicV3Its {
/// Device trees specific constants
pub const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
/// Returns the GIC version of the device
fn version() -> u32 {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
}
fn device(&self) -> &Arc<dyn Device> {
&self.device
}
fn its_device(&self) -> Option<&Arc<dyn Device>> {
self.its_device.as_ref()
}
/// Setup the device-specific attributes
fn init_device_attributes(&mut self, vm: &dyn Vm, nr_irqs: u32) -> Result<()> {
// GicV3 part attributes
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor.
*/
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
&self.dist_addr as *const u64 as u64,
0,
)?;
/* Setting up the redistributors' attribute.
We are calculating here the start of the redistributors address. We have one per CPU.
*/
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
&self.redists_addr as *const u64 as u64,
0,
)?;
// ITS part attributes
let mut its_device = kvm_bindings::kvm_create_device {
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
fd: 0,
flags: 0,
};
let its_fd = vm
.create_device(&mut its_device)
.map_err(Error::CreateGic)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
&self.msi_addr as *const u64 as u64,
0,
)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
self.set_its_device(Some(its_fd));
/* We need to tell the kernel how many irqs to support with this vgic.
* See the `layout` module for details.
*/
let nr_irqs_ptr = &nr_irqs as *const u32;
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0,
nr_irqs_ptr as u64,
0,
)?;
/* Finalize the GIC.
* See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211.
*/
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)
}
/// Create a KVM Vgic device
fn create_device(vm: &dyn Vm) -> Result<Arc<dyn Device>> {
let mut gic_device = kvm_bindings::kvm_create_device {
type_: Self::version(),
fd: 0,
flags: 0,
};
vm.create_device(&mut gic_device).map_err(Error::CreateGic)
}
/// Set a GIC device attribute
fn set_device_attribute(
device: &Arc<dyn Device>,
group: u32,
attr: u64,
addr: u64,
flags: u32,
) -> Result<()> {
let attr = kvm_bindings::kvm_device_attr {
flags,
group,
attr,
addr,
};
device
.set_device_attr(&attr)
.map_err(Error::SetDeviceAttribute)
}
/// Method to initialize the GIC device
#[allow(clippy::new_ret_no_self)]
pub fn new(
vm: &dyn Vm,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> Result<KvmGicV3Its> {
let vgic = Self::create_device(vm)?;
let redists_size: u64 = redist_size * vcpu_count;
let redists_addr: u64 = dist_addr - redists_size;
let msi_addr: u64 = redists_addr - msi_size;
let mut gic_device = KvmGicV3Its {
device: vgic,
its_device: None,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
dist_addr,
dist_size,
redists_addr,
redists_size,
msi_addr,
msi_size,
vcpu_count,
};
gic_device.init_device_attributes(vm, nr_irqs)?;
Ok(gic_device)
}
}
impl Vgic for KvmGicV3Its {
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn msi_compatible(&self) -> bool {
true
}
fn msi_compatibility(&self) -> &str {
"arm,gic-v3-its"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGicV3Its::ARCH_GIC_V3_MAINT_IRQ
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
fn device_properties(&self) -> [u64; 4] {
[
self.dist_addr,
self.dist_size,
self.redists_addr,
self.redists_size,
]
}
fn msi_properties(&self) -> [u64; 2] {
[self.msi_addr, self.msi_size]
}
fn set_its_device(&mut self, its_device: Option<Arc<dyn Device>>) {
self.its_device = its_device;
}
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let gicr_typers = construct_gicr_typers(vcpu_states);
self.gicr_typers = gicr_typers;
}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
self
}
/// Save the state of GICv3ITS.
fn state(&self) -> Result<Gicv3ItsState> {
let gicr_typers = self.gicr_typers.clone();
let gicd_ctlr = read_ctlr(self.device())?;
let dist_state = get_dist_regs(self.device())?;
let rdist_state = get_redist_regs(self.device(), &gicr_typers)?;
let icc_state = get_icc_regs(self.device(), &gicr_typers)?;
let its_baser_state: [u64; 8] = [0; 8];
for i in 0..8 {
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_BASER + i * 8,
&its_baser_state[i as usize],
false,
)?;
}
let its_ctlr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR,
&its_ctlr_state,
false,
)?;
let its_cbaser_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CBASER,
&its_cbaser_state,
false,
)?;
let its_creadr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CREADR,
&its_creadr_state,
false,
)?;
let its_cwriter_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CWRITER,
&its_cwriter_state,
false,
)?;
let its_iidr_state: u64 = 0;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_IIDR,
&its_iidr_state,
false,
)?;
Ok(Gicv3ItsState {
dist: dist_state,
rdist: rdist_state,
icc: icc_state,
gicd_ctlr,
its_ctlr: its_ctlr_state,
its_iidr: its_iidr_state,
its_cbaser: its_cbaser_state,
its_cwriter: its_cwriter_state,
its_creadr: its_creadr_state,
its_baser: its_baser_state,
})
}
/// Restore the state of GICv3ITS.
fn set_state(&mut self, state: &Gicv3ItsState) -> Result<()> {
let gicr_typers = self.gicr_typers.clone();
write_ctlr(self.device(), state.gicd_ctlr)?;
set_dist_regs(self.device(), &state.dist)?;
set_redist_regs(self.device(), &gicr_typers, &state.rdist)?;
set_icc_regs(self.device(), &gicr_typers, &state.icc)?;
//Restore GICv3ITS registers
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_IIDR,
&state.its_iidr,
true,
)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CBASER,
&state.its_cbaser,
true,
)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CREADR,
&state.its_creadr,
true,
)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CWRITER,
&state.its_cwriter,
true,
)?;
for i in 0..8 {
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_BASER + i * 8,
&state.its_baser[i as usize],
true,
)?;
}
// Restore ITS tables
gicv3_its_tables_access(self.its_device().unwrap(), false)?;
gicv3_its_attr_access(
self.its_device().unwrap(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR,
&state.its_ctlr,
true,
)
}
/// Saves GIC internal data tables into RAM, including:
/// - RDIST pending tables
/// - ITS tables into guest RAM.
fn save_data_tables(&self) -> Result<()> {
// Flash RDIST pending tables
let init_gic_attr = kvm_bindings::kvm_device_attr {
group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
attr: u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES),
addr: 0,
flags: 0,
};
self.device()
.set_device_attr(&init_gic_attr)
.map_err(Error::SetDeviceAttribute)?;
// Flush ITS tables to guest RAM.
gicv3_its_tables_access(self.its_device().unwrap(), true)
}
}
#[cfg(test)]
mod tests {
use crate::aarch64::gic::{
get_dist_regs, get_icc_regs, get_redist_regs, set_dist_regs, set_icc_regs, set_redist_regs,
};
use crate::kvm::KvmGicV3Its;
#[test]
fn test_create_gic() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
assert!(KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256
)
.is_ok());
}
#[test]
fn test_get_set_dist_regs() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let res = get_dist_regs(gic.device());
assert!(res.is_ok());
let state = res.unwrap();
assert_eq!(state.len(), 568);
let res = set_dist_regs(gic.device(), &state);
assert!(res.is_ok());
}
#[test]
fn test_get_set_redist_regs() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let gicr_typer = vec![123];
let res = get_redist_regs(gic.device(), &gicr_typer);
assert!(res.is_ok());
let state = res.unwrap();
println!("{}", state.len());
assert!(state.len() == 24);
assert!(set_redist_regs(gic.device(), &gicr_typer, &state).is_ok());
}
#[test]
fn test_get_set_icc_regs() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = KvmGicV3Its::new(
&*vm,
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
let gicr_typer = vec![123];
let res = get_icc_regs(gic.device(), &gicr_typer);
assert!(res.is_ok());
let state = res.unwrap();
println!("{}", state.len());
assert!(state.len() == 9);
assert!(set_icc_regs(gic.device(), &gicr_typer, &state).is_ok());
}
#[test]
fn test_save_data_tables() {
let hv = crate::new().unwrap();
let vm = hv.create_vm().unwrap();
let _ = vm.create_vcpu(0, None).unwrap();
let gic = vm
.create_vgic(
1,
0x0900_0000 - 0x01_0000,
0x01_0000,
0x02_0000,
0x02_0000,
256,
)
.expect("Cannot create gic");
assert!(gic.lock().unwrap().save_data_tables().is_ok());
}
}

View File

@@ -1,9 +1,10 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use hypervisor::kvm::kvm_bindings::{kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS};
use hypervisor::CpuState;
use crate::arch::aarch64::gic::{Error, Result};
use crate::kvm::kvm_bindings::{kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS};
use crate::{CpuState, Device};
use std::sync::Arc;
// Relevant redistributor registers that we want to save/restore.
@@ -83,7 +84,7 @@ static VGIC_SGI_REGS: &[RdistReg] = &[
];
fn redist_attr_access(
gic: &Arc<dyn hypervisor::Device>,
gic: &Arc<dyn Device>,
offset: u32,
typer: u64,
val: &u32,
@@ -106,7 +107,7 @@ fn redist_attr_access(
}
fn access_redists_aux(
gic: &Arc<dyn hypervisor::Device>,
gic: &Arc<dyn Device>,
gicr_typer: &[u64],
state: &mut Vec<u32>,
reg_list: &[RdistReg],
@@ -136,7 +137,7 @@ fn access_redists_aux(
}
/// Get redistributor registers.
pub fn get_redist_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
pub fn get_redist_regs(gic: &Arc<dyn Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
let mut state = Vec::new();
let mut idx: usize = 0;
access_redists_aux(
@@ -153,11 +154,7 @@ pub fn get_redist_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) ->
}
/// Set redistributor registers.
pub fn set_redist_regs(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &[u32],
) -> Result<()> {
pub fn set_redist_regs(gic: &Arc<dyn Device>, gicr_typer: &[u64], state: &[u32]) -> Result<()> {
let mut idx: usize = 0;
let mut mut_state = state.to_owned();
access_redists_aux(

View File

@@ -8,9 +8,8 @@
//
//
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
///
pub mod gic;
use crate::kvm::{KvmError, KvmResult};
use kvm_bindings::{
kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG,
@@ -23,7 +22,7 @@ use kvm_bindings::{
pub use kvm_bindings::{
kvm_one_reg as Register, kvm_regs as StandardRegisters, kvm_vcpu_init as VcpuInit, RegList,
};
use serde_derive::{Deserialize, Serialize};
use serde::{Deserialize, Serialize};
pub use {kvm_ioctls::Cap, kvm_ioctls::Kvm};
// This macro gets the offset of a structure (i.e `str`) member (i.e `field`) without having

View File

@@ -8,20 +8,24 @@
//
//
#[cfg(target_arch = "aarch64")]
use crate::aarch64::gic::KvmGicV3Its;
#[cfg(target_arch = "aarch64")]
pub use crate::aarch64::{
check_required_kvm_extensions, is_system_register, VcpuInit, VcpuKvmState as CpuState,
MPIDR_EL1,
check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuInit,
VcpuKvmState as CpuState, MPIDR_EL1,
};
#[cfg(target_arch = "aarch64")]
use crate::arch::aarch64::gic::Vgic;
use crate::cpu;
use crate::device;
use crate::hypervisor;
use crate::vec_with_array_field;
use crate::vm::{self, VmmOps};
use crate::vm::{self, InterruptSourceConfig, VmOps};
#[cfg(target_arch = "aarch64")]
use crate::{arm64_core_reg_id, offset__of};
use kvm_ioctls::{NoDatamatch, VcpuFd, VmFd};
use serde_derive::{Deserialize, Serialize};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[cfg(target_arch = "aarch64")]
use std::convert::TryInto;
@@ -31,6 +35,8 @@ use std::os::unix::io::{AsRawFd, RawFd};
use std::result;
#[cfg(target_arch = "x86_64")]
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(target_arch = "aarch64")]
use std::sync::Mutex;
use std::sync::{Arc, RwLock};
use vmm_sys_util::eventfd::EventFd;
// x86_64 dependencies
@@ -154,7 +160,7 @@ pub struct TdxCapabilities {
pub cpuid_configs: [TdxCpuidConfig; TDX_MAX_NR_CPUID_CONFIGS],
}
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct KvmVmState {}
pub use KvmVmState as VmState;
@@ -234,7 +240,7 @@ impl vm::Vm for KvmVm {
fn create_vcpu(
&self,
id: u8,
vmmops: Option<Arc<dyn VmmOps>>,
vm_ops: Option<Arc<dyn VmOps>>,
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
let vc = self
.fd
@@ -244,12 +250,37 @@ impl vm::Vm for KvmVm {
fd: vc,
#[cfg(target_arch = "x86_64")]
msrs: self.msrs.clone(),
vmmops,
vm_ops,
#[cfg(target_arch = "x86_64")]
hyperv_synic: AtomicBool::new(false),
};
Ok(Arc::new(vcpu))
}
#[cfg(target_arch = "aarch64")]
///
/// Creates a virtual GIC device.
///
fn create_vgic(
&self,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> vm::Result<Arc<Mutex<dyn Vgic>>> {
let gic_device = KvmGicV3Its::new(
self,
vcpu_count,
dist_addr,
dist_size,
redist_size,
msi_size,
nr_irqs,
)
.map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?;
Ok(Arc::new(Mutex::new(gic_device)))
}
///
/// Registers an event to be signaled whenever a certain address is written to.
///
@@ -284,6 +315,64 @@ impl vm::Vm for KvmVm {
.unregister_ioevent(fd, addr, NoDatamatch)
.map_err(|e| vm::HypervisorVmError::UnregisterIoEvent(e.into()))
}
///
/// Constructs a routing entry
///
fn make_routing_entry(
&self,
gsi: u32,
config: &InterruptSourceConfig,
) -> kvm_irq_routing_entry {
match &config {
InterruptSourceConfig::MsiIrq(cfg) => {
let mut kvm_route = kvm_irq_routing_entry {
gsi,
type_: KVM_IRQ_ROUTING_MSI,
..Default::default()
};
kvm_route.u.msi.address_lo = cfg.low_addr;
kvm_route.u.msi.address_hi = cfg.high_addr;
kvm_route.u.msi.data = cfg.data;
if self.check_extension(crate::kvm::Cap::MsiDevid) {
// On AArch64, there is limitation on the range of the 'devid',
// it can not be greater than 65536 (the max of u16).
//
// BDF can not be used directly, because 'segment' is in high
// 16 bits. The layout of the u32 BDF is:
// |---- 16 bits ----|-- 8 bits --|-- 5 bits --|-- 3 bits --|
// | segment | bus | device | function |
//
// Now that we support 1 bus only in a segment, we can build a
// 'devid' by replacing the 'bus' bits with the low 8 bits of
// 'segment' data.
// This way we can resolve the range checking problem and give
// different `devid` to all the devices. Limitation is that at
// most 256 segments can be supported.
//
let modified_devid = (cfg.devid & 0x00ff_0000) >> 8 | cfg.devid & 0xff;
kvm_route.flags = KVM_MSI_VALID_DEVID;
kvm_route.u.msi.__bindgen_anon_1.devid = modified_devid;
}
kvm_route
}
InterruptSourceConfig::LegacyIrq(cfg) => {
let mut kvm_route = kvm_irq_routing_entry {
gsi,
type_: KVM_IRQ_ROUTING_IRQCHIP,
..Default::default()
};
kvm_route.u.irqchip.irqchip = cfg.irqchip;
kvm_route.u.irqchip.pin = cfg.pin;
kvm_route
}
}
}
///
/// Sets the GSI routing table entries, overwriting any previously set
/// entries, as per the `KVM_SET_GSI_ROUTING` ioctl.
@@ -816,7 +905,7 @@ pub struct KvmVcpu {
fd: VcpuFd,
#[cfg(target_arch = "x86_64")]
msrs: MsrEntries,
vmmops: Option<Arc<dyn vm::VmmOps>>,
vm_ops: Option<Arc<dyn vm::VmOps>>,
#[cfg(target_arch = "x86_64")]
hyperv_synic: AtomicBool,
}
@@ -1056,8 +1145,8 @@ impl cpu::Vcpu for KvmVcpu {
Ok(run) => match run {
#[cfg(target_arch = "x86_64")]
VcpuExit::IoIn(addr, data) => {
if let Some(vmmops) = &self.vmmops {
return vmmops
if let Some(vm_ops) = &self.vm_ops {
return vm_ops
.pio_read(addr.into(), data)
.map(|_| cpu::VmExit::Ignore)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()));
@@ -1067,8 +1156,8 @@ impl cpu::Vcpu for KvmVcpu {
}
#[cfg(target_arch = "x86_64")]
VcpuExit::IoOut(addr, data) => {
if let Some(vmmops) = &self.vmmops {
return vmmops
if let Some(vm_ops) = &self.vm_ops {
return vm_ops
.pio_write(addr.into(), data)
.map(|_| cpu::VmExit::Ignore)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()));
@@ -1100,8 +1189,8 @@ impl cpu::Vcpu for KvmVcpu {
}
VcpuExit::MmioRead(addr, data) => {
if let Some(vmmops) = &self.vmmops {
return vmmops
if let Some(vm_ops) = &self.vm_ops {
return vm_ops
.mmio_read(addr, data)
.map(|_| cpu::VmExit::Ignore)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()));
@@ -1110,8 +1199,8 @@ impl cpu::Vcpu for KvmVcpu {
Ok(cpu::VmExit::MmioRead(addr, data))
}
VcpuExit::MmioWrite(addr, data) => {
if let Some(vmmops) = &self.vmmops {
return vmmops
if let Some(vm_ops) = &self.vm_ops {
return vm_ops
.mmio_write(addr, data)
.map(|_| cpu::VmExit::Ignore)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()));
@@ -1477,6 +1566,51 @@ impl cpu::Vcpu for KvmVcpu {
.get_one_reg(MPIDR_EL1)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))
}
///
/// Configure core registers for a given CPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
#[allow(non_upper_case_globals)]
// PSR (Processor State Register) bits.
// Taken from arch/arm64/include/uapi/asm/ptrace.h.
const PSR_MODE_EL1h: u64 = 0x0000_0005;
const PSR_F_BIT: u64 = 0x0000_0040;
const PSR_I_BIT: u64 = 0x0000_0080;
const PSR_A_BIT: u64 = 0x0000_0100;
const PSR_D_BIT: u64 = 0x0000_0200;
// Taken from arch/arm64/kvm/inject_fault.c.
const PSTATE_FAULT_BITS_64: u64 =
PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT;
let kreg_off = offset__of!(kvm_regs, regs);
// Get the register index of the PSTATE (Processor State) register.
let pstate = offset__of!(user_pt_regs, pstate) + kreg_off;
self.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate),
PSTATE_FAULT_BITS_64,
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
self.set_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip as u64)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
self.set_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0), fdt_start)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
}
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// Get the current CPU state

View File

@@ -10,7 +10,7 @@
use crate::arch::x86::{msr_index, SegmentRegisterOps, MTRR_ENABLE, MTRR_MEM_TYPE_WB};
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
use serde_derive::{Deserialize, Serialize};
use serde::{Deserialize, Serialize};
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms

View File

@@ -18,6 +18,8 @@
//! - arm64
//!
#![allow(clippy::significant_drop_in_scrutinee)]
#[macro_use]
extern crate anyhow;
#[cfg(target_arch = "x86_64")]
@@ -37,10 +39,10 @@ pub mod kvm;
pub mod mshv;
/// Hypevisor related module
pub mod hypervisor;
mod hypervisor;
/// Vm related module
pub mod vm;
mod vm;
/// CPU related module
mod cpu;
@@ -48,18 +50,32 @@ mod cpu;
/// Device related module
mod device;
pub use crate::hypervisor::{Hypervisor, HypervisorError};
pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
pub use device::{Device, HypervisorDeviceError};
#[cfg(feature = "tdx")]
pub use kvm::TdxCapabilities;
pub use hypervisor::{Hypervisor, HypervisorError};
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
pub use kvm::x86_64;
#[cfg(all(feature = "kvm", target_arch = "aarch64"))]
pub use kvm::{aarch64, GicState};
// Aliased types exposed from both hypervisors
#[cfg(feature = "kvm")]
pub use kvm::*;
pub use kvm::{
ClockData, CpuState, CreateDevice, DeviceAttr, DeviceFd, IoEventAddress, IrqRoutingEntry,
MemoryRegion, MpState, VcpuEvents, VcpuExit, VmState,
};
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
pub use mshv::*;
pub use vm::{DataMatch, HypervisorVmError, Vm};
pub use mshv::x86_64;
// Aliased types exposed from both hypervisors
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
pub use mshv::{
CpuState, CreateDevice, DeviceAttr, DeviceFd, IoEventAddress, IrqRoutingEntry, MemoryRegion,
MpState, VcpuEvents, VcpuExit, VmState,
};
use std::sync::Arc;
pub use vm::{
DataMatch, HypervisorVmError, InterruptSourceConfig, LegacyIrqSourceConfig, MsiIrqSourceConfig,
Vm, VmOps,
};
pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> {
#[cfg(feature = "kvm")]

View File

@@ -11,11 +11,11 @@ use crate::cpu;
use crate::cpu::Vcpu;
use crate::hypervisor;
use crate::vec_with_array_field;
use crate::vm::{self, VmmOps};
use crate::vm::{self, InterruptSourceConfig, VmOps};
pub use mshv_bindings::*;
pub use mshv_ioctls::IoEventAddress;
use mshv_ioctls::{set_registers_64, Mshv, NoDatamatch, VcpuFd, VmFd};
use serde_derive::{Deserialize, Serialize};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use vm::DataMatch;
@@ -108,6 +108,17 @@ impl hypervisor::Hypervisor for MshvHypervisor {
break;
}
// Default Microsoft Hypervisor behavior for unimplemented MSR is to
// 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
// writes from the guest and return zero in attempt to read unimplemented
// MSR.
fd.set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION,
hv_unimplemented_msr_action_HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO as u64,
)
.map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?;
let msr_list = self.get_msr_list()?;
let num_msrs = msr_list.as_fam_struct_ref().nmsrs as usize;
let mut msrs = MsrEntries::new(num_msrs).unwrap();
@@ -122,7 +133,7 @@ impl hypervisor::Hypervisor for MshvHypervisor {
fd: vm_fd,
msrs,
hv_state: hv_state_init(),
vmmops: None,
vm_ops: None,
dirty_log_slots: Arc::new(RwLock::new(HashMap::new())),
}))
}
@@ -151,7 +162,7 @@ pub struct MshvVcpu {
cpuid: CpuId,
msrs: MsrEntries,
hv_state: Arc<RwLock<HvState>>, // Mshv State
vmmops: Option<Arc<dyn vm::VmmOps>>,
vm_ops: Option<Arc<dyn vm::VmOps>>,
}
/// Implementation of Vcpu trait for Microsoft Hypervisor
@@ -355,14 +366,14 @@ impl cpu::Vcpu for MshvVcpu {
if is_write {
let data = (info.rax as u32).to_le_bytes();
if let Some(vmmops) = &self.vmmops {
vmmops
if let Some(vm_ops) = &self.vm_ops {
vm_ops
.pio_write(port.into(), &data[0..len])
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
}
} else {
if let Some(vmmops) = &self.vmmops {
vmmops
if let Some(vm_ops) = &self.vm_ops {
vm_ops
.pio_read(port.into(), &mut data[0..len])
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
}
@@ -655,9 +666,9 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
gpa
);
if let Some(vmmops) = &self.vcpu.vmmops {
if vmmops.guest_mem_read(gpa, data).is_err() {
vmmops
if let Some(vm_ops) = &self.vcpu.vm_ops {
if vm_ops.guest_mem_read(gpa, data).is_err() {
vm_ops
.mmio_read(gpa, data)
.map_err(|e| PlatformError::MemoryReadFailure(e.into()))?;
}
@@ -675,9 +686,9 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
gpa
);
if let Some(vmmops) = &self.vcpu.vmmops {
if vmmops.guest_mem_write(gpa, data).is_err() {
vmmops
if let Some(vm_ops) = &self.vcpu.vm_ops {
if vm_ops.guest_mem_write(gpa, data).is_err() {
vm_ops
.mmio_write(gpa, data)
.map_err(|e| PlatformError::MemoryWriteFailure(e.into()))?;
}
@@ -746,7 +757,7 @@ pub struct MshvVm {
msrs: MsrEntries,
// Hypervisor State
hv_state: Arc<RwLock<HvState>>,
vmmops: Option<Arc<dyn vm::VmmOps>>,
vm_ops: Option<Arc<dyn vm::VmOps>>,
dirty_log_slots: Arc<RwLock<HashMap<u64, MshvDirtyLogSlot>>>,
}
@@ -816,7 +827,7 @@ impl vm::Vm for MshvVm {
fn create_vcpu(
&self,
id: u8,
vmmops: Option<Arc<dyn VmmOps>>,
vm_ops: Option<Arc<dyn VmOps>>,
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
let vcpu_fd = self
.fd
@@ -828,7 +839,7 @@ impl vm::Vm for MshvVm {
cpuid: CpuId::new(1).unwrap(),
msrs: self.msrs.clone(),
hv_state: self.hv_state.clone(),
vmmops,
vm_ops,
};
Ok(Arc::new(vcpu))
}
@@ -957,6 +968,27 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::CreatePassthroughDevice(e.into()))
}
///
/// Constructs a routing entry
///
fn make_routing_entry(
&self,
gsi: u32,
config: &InterruptSourceConfig,
) -> mshv_msi_routing_entry {
match config {
InterruptSourceConfig::MsiIrq(cfg) => mshv_msi_routing_entry {
gsi,
address_lo: cfg.low_addr,
address_hi: cfg.high_addr,
data: cfg.data,
},
_ => {
unreachable!()
}
}
}
fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> vm::Result<()> {
let mut msi_routing =
vec_with_array_field::<mshv_msi_routing, mshv_msi_routing_entry>(entries.len());
@@ -1027,6 +1059,3 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::GetDirtyLog(e.into()))
}
}
pub use hv_cpuid_entry as CpuIdEntry;
pub const CPUID_FLAG_VALID_INDEX: u32 = 0;

View File

@@ -8,13 +8,14 @@
//
//
use crate::arch::x86::{msr_index, SegmentRegisterOps, MTRR_ENABLE, MTRR_MEM_TYPE_WB};
use serde_derive::{Deserialize, Serialize};
use serde::{Deserialize, Serialize};
use std::fmt;
///
/// Export generically-named wrappers of mshv_bindings for Unix-based platforms
///
pub use {
mshv_bindings::hv_cpuid_entry as CpuIdEntry,
mshv_bindings::mshv_user_mem_region as MemoryRegion, mshv_bindings::msr_entry as MsrEntry,
mshv_bindings::CpuId, mshv_bindings::DebugRegisters,
mshv_bindings::FloatingPointUnit as FpuState, mshv_bindings::LapicState,
@@ -25,6 +26,8 @@ pub use {
mshv_bindings::Xcrs as ExtendedControlRegisters,
};
pub const CPUID_FLAG_VALID_INDEX: u32 = 0;
#[derive(Clone, Serialize, Deserialize)]
pub struct VcpuMshvState {
pub msrs: MsrEntries,

View File

@@ -10,23 +10,27 @@
#[cfg(target_arch = "aarch64")]
use crate::aarch64::VcpuInit;
#[cfg(target_arch = "aarch64")]
use crate::arch::aarch64::gic::Vgic;
use crate::cpu::Vcpu;
use crate::device::Device;
#[cfg(feature = "kvm")]
use crate::kvm::KvmVmState as VmState;
#[cfg(feature = "mshv")]
use crate::mshv::HvState as VmState;
#[cfg(feature = "tdx")]
use crate::x86_64::CpuId;
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
use crate::ClockData;
use crate::CreateDevice;
#[cfg(feature = "mshv")]
use crate::HvState as VmState;
#[cfg(feature = "kvm")]
use crate::KvmVmState as VmState;
use crate::{IoEventAddress, IrqRoutingEntry, MemoryRegion};
#[cfg(feature = "kvm")]
use kvm_ioctls::Cap;
#[cfg(target_arch = "x86_64")]
use std::fs::File;
use std::sync::Arc;
#[cfg(target_arch = "aarch64")]
use std::sync::Mutex;
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
@@ -210,12 +214,50 @@ pub enum HypervisorVmError {
///
#[error("Failed to initialize memory region TDX: {0}")]
InitMemRegionTdx(#[source] std::io::Error),
///
/// Create Vgic error
///
#[error("Failed to create Vgic: {0}")]
CreateVgic(#[source] anyhow::Error),
}
///
/// Result type for returning from a function
///
pub type Result<T> = std::result::Result<T, HypervisorVmError>;
/// Configuration data for legacy interrupts.
///
/// On x86 platforms, legacy interrupts means those interrupts routed through PICs or IOAPICs.
#[derive(Copy, Clone, Debug)]
pub struct LegacyIrqSourceConfig {
pub irqchip: u32,
pub pin: u32,
}
/// Configuration data for MSI/MSI-X interrupts.
///
/// On x86 platforms, these interrupts are vectors delivered directly to the LAPIC.
#[derive(Copy, Clone, Debug, Default)]
pub struct MsiIrqSourceConfig {
/// High address to delivery message signaled interrupt.
pub high_addr: u32,
/// Low address to delivery message signaled interrupt.
pub low_addr: u32,
/// Data to write to delivery message signaled interrupt.
pub data: u32,
/// Unique ID of the device to delivery message signaled interrupt.
pub devid: u32,
}
/// Configuration data for an interrupt source.
#[derive(Copy, Clone, Debug)]
pub enum InterruptSourceConfig {
/// Configuration data for Legacy interrupts.
LegacyIrq(LegacyIrqSourceConfig),
/// Configuration data for PciMsi, PciMsix and generic MSI interrupts.
MsiIrq(MsiIrqSourceConfig),
}
///
/// Trait to represent a Vm
///
@@ -235,7 +277,18 @@ pub trait Vm: Send + Sync {
/// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
fn create_vcpu(&self, id: u8, vmmops: Option<Arc<dyn VmmOps>>) -> Result<Arc<dyn Vcpu>>;
fn create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>;
#[cfg(target_arch = "aarch64")]
fn create_vgic(
&self,
vcpu_count: u64,
dist_addr: u64,
dist_size: u64,
redist_size: u64,
msi_size: u64,
nr_irqs: u32,
) -> Result<Arc<Mutex<dyn Vgic>>>;
/// Registers an event to be signaled whenever a certain address is written to.
fn register_ioevent(
&self,
@@ -245,6 +298,8 @@ pub trait Vm: Send + Sync {
) -> Result<()>;
/// Unregister an event from a certain address it has been previously registered to.
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>;
// Construct a routing entry
fn make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry;
/// Sets the GSI routing table entries, overwriting any previously set
fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> Result<()>;
/// Creates a memory region structure that can be used with {create/remove}_user_memory_region
@@ -309,7 +364,7 @@ pub trait Vm: Send + Sync {
) -> Result<()>;
}
pub trait VmmOps: Send + Sync {
pub trait VmOps: Send + Sync {
fn guest_mem_write(&self, gpa: u64, buf: &[u8]) -> Result<usize>;
fn guest_mem_read(&self, gpa: u64, buf: &mut [u8]) -> Result<usize>;
fn mmio_read(&self, gpa: u64, data: &mut [u8]) -> Result<()>;

View File

@@ -7,20 +7,21 @@ edition = "2021"
[dependencies]
epoll = "4.3.1"
getrandom = "0.2"
libc = "0.2.123"
log = "0.4.16"
libc = "0.2.126"
log = "0.4.17"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.136"
serde = "1.0.138"
versionize = "0.1.6"
versionize_derive = "0.1.4"
virtio-bindings = "0.1.0"
virtio-queue = "0.2.0"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.4.0"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"
[dev-dependencies]
lazy_static = "1.4.0"
pnet = "0.29.0"
serde_json = "1.0.79"
once_cell = "1.13.0"
pnet = "0.31.0"
pnet_datalink = "0.31.0"
serde_json = "1.0.82"

View File

@@ -5,11 +5,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
// This is only used by the tests module from tap.rs, but we cannot use #[macro_use] unless the
// reference to lazy_static is declared at the root level of the importing crate.
#[cfg(test)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

View File

@@ -15,7 +15,7 @@ use serde::ser::{Serialize, Serializer};
pub const MAC_ADDR_LEN: usize = 6;
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MacAddr {
bytes: [u8; MAC_ADDR_LEN],
}

View File

@@ -321,15 +321,13 @@ impl Tap {
// If TAP device is already up don't try and enable it
let ifru_flags = unsafe { ifreq.ifr_ifru.ifru_flags };
if ifru_flags
& (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16
== (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16
if ifru_flags & net_gen::net_device_flags_IFF_UP as i16
== net_gen::net_device_flags_IFF_UP as i16
{
return Ok(());
}
ifreq.ifr_ifru.ifru_flags =
(net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16;
ifreq.ifr_ifru.ifru_flags = net_gen::net_device_flags_IFF_UP as i16;
// ioctl is safe. Called with a valid sock fd, and we check the return.
let ret =
@@ -395,38 +393,35 @@ impl AsRawFd for Tap {
#[cfg(test)]
mod tests {
extern crate pnet;
use std::net::Ipv4Addr;
use std::str;
use std::sync::{mpsc, Mutex};
use std::thread;
use std::time::Duration;
use self::pnet::datalink::Channel::Ethernet;
use self::pnet::datalink::{self, DataLinkReceiver, DataLinkSender, NetworkInterface};
use self::pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
use self::pnet::packet::ip::IpNextHeaderProtocols;
use self::pnet::packet::ipv4::{Ipv4Packet, MutableIpv4Packet};
use self::pnet::packet::udp::{MutableUdpPacket, UdpPacket};
use self::pnet::packet::{MutablePacket, Packet};
use self::pnet::util::MacAddr;
use once_cell::sync::Lazy;
use pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
use pnet::packet::ip::IpNextHeaderProtocols;
use pnet::packet::ipv4::{Ipv4Packet, MutableIpv4Packet};
use pnet::packet::udp::{MutableUdpPacket, UdpPacket};
use pnet::packet::{MutablePacket, Packet};
use pnet::util::MacAddr;
use pnet_datalink::Channel::Ethernet;
use pnet_datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface};
use super::*;
static DATA_STRING: &str = "test for tap";
static SUBNET_MASK: &str = "255.255.255.0";
// We needed to have a mutex as a global variable, so we used the crate that provides the
// lazy_static! macro for testing. The main potential problem, caused by tests being run in
// parallel by cargo, is creating different TAPs and trying to associate the same address,
// so we hide the IP address &str behind this mutex, more as a convention to remember to lock
// it at the very beginning of each function susceptible to this issue. Another variant is
// to use a different IP address per function, but we must remember to pick an unique one
// each time.
lazy_static! {
static ref TAP_IP_LOCK: Mutex<&'static str> = Mutex::new("192.168.241.1");
}
// We needed to have a mutex as a global variable, so we used once_cell for testing. The main
// potential problem, caused by tests being run in parallel by cargo, is creating different
// TAPs and trying to associate the same address, so we hide the IP address &str behind this
// mutex, more as a convention to remember to lock it at the very beginning of each function
// susceptible to this issue. Another variant is to use a different IP address per function,
// but we must remember to pick an unique one each time.
static TAP_IP_LOCK: Lazy<Mutex<&'static str>> = Lazy::new(|| Mutex::new("192.168.241.1"));
// Describes the outcomes we are currently interested in when parsing a packet (we use
// an UDP packet for testing).
@@ -543,10 +538,10 @@ mod tests {
let interface_name_matches = |iface: &NetworkInterface| iface.name == ifname;
// Find the network interface with the provided name.
let interfaces = datalink::interfaces();
let interfaces = pnet_datalink::interfaces();
let interface = interfaces.into_iter().find(interface_name_matches).unwrap();
if let Ok(Ethernet(tx, rx)) = datalink::channel(&interface, Default::default()) {
if let Ok(Ethernet(tx, rx)) = pnet_datalink::channel(&interface, Default::default()) {
(interface.mac.unwrap(), tx, rx)
} else {
panic!("datalink channel error or unhandled channel type");

View File

@@ -77,7 +77,7 @@ impl OptionParser {
}
for option in split_commas_outside_brackets(input)?.iter() {
let parts: Vec<&str> = option.split('=').collect();
let parts: Vec<&str> = option.splitn(2, '=').collect();
match self.options.get_mut(parts[0]) {
None => return Err(OptionParserError::UnknownOption(parts[0].to_owned())),

View File

@@ -10,22 +10,21 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.56"
anyhow = "1.0.58"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vfio_user = { path = "../vfio_user" }
vmm-sys-util = "0.9.0"
libc = "0.2.123"
log = "0.4.16"
serde = "1.0.136"
serde_derive = "1.0.136"
thiserror = "1.0.30"
libc = "0.2.126"
log = "0.4.17"
serde = { version="1.0.138", features=["derive"] }
thiserror = "1.0.31"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = "0.7.0"
vm-memory = "0.8.0"
vm-migration = { path = "../vm-migration" }
[dependencies.vfio-bindings]

View File

@@ -6,13 +6,13 @@ use crate::configuration::{
PciBarRegionType, PciBridgeSubclass, PciClassCode, PciConfiguration, PciHeaderType,
};
use crate::device::{DeviceRelocation, Error as PciDeviceError, PciDevice};
use crate::PciBarConfiguration;
use byteorder::{ByteOrder, LittleEndian};
use std::any::Any;
use std::collections::HashMap;
use std::ops::DerefMut;
use std::sync::{Arc, Barrier, Mutex};
use vm_device::{Bus, BusDevice};
use vm_memory::{Address, GuestAddress, GuestUsize};
const VENDOR_ID_INTEL: u16 = 0x8086;
const DEVICE_ID_INTEL_VIRT_PCIE_HOST: u16 = 0x0d57;
@@ -88,6 +88,10 @@ impl PciDevice for PciRoot {
fn as_any(&mut self) -> &mut dyn Any {
self
}
fn id(&self) -> Option<String> {
None
}
}
pub struct PciBus {
@@ -118,21 +122,21 @@ impl PciBus {
dev: Arc<Mutex<dyn BusDevice>>,
#[cfg(target_arch = "x86_64")] io_bus: &Bus,
mmio_bus: &Bus,
bars: Vec<(GuestAddress, GuestUsize, PciBarRegionType)>,
bars: Vec<PciBarConfiguration>,
) -> Result<()> {
for (address, size, type_) in bars {
match type_ {
for bar in bars {
match bar.region_type() {
PciBarRegionType::IoRegion => {
#[cfg(target_arch = "x86_64")]
io_bus
.insert(dev.clone(), address.raw_value(), size)
.insert(dev.clone(), bar.addr(), bar.size())
.map_err(PciRootError::PioInsert)?;
#[cfg(target_arch = "aarch64")]
error!("I/O region is not supported");
}
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
mmio_bus
.insert(dev.clone(), address.raw_value(), size)
.insert(dev.clone(), bar.addr(), bar.size())
.map_err(PciRootError::MmioInsert)?;
}
}

View File

@@ -9,6 +9,7 @@ use std::fmt::{self, Display};
use std::sync::{Arc, Mutex};
use versionize::{VersionMap, Versionize, VersionizeError, VersionizeResult};
use versionize_derive::Versionize;
use vm_device::PciBarType;
use vm_migration::{MigratableError, Pausable, Snapshot, Snapshottable, VersionMapped};
// The number of 32bit registers in the config space, 4096 bytes.
@@ -18,6 +19,7 @@ const STATUS_REG: usize = 1;
const STATUS_REG_CAPABILITIES_USED_MASK: u32 = 0x0010_0000;
const BAR0_REG: usize = 4;
const ROM_BAR_REG: usize = 12;
const ROM_BAR_IDX: usize = 6;
const BAR_IO_ADDR_MASK: u32 = 0xffff_fffc;
const BAR_MEM_ADDR_MASK: u32 = 0xffff_fff0;
const ROM_BAR_ADDR_MASK: u32 = 0xffff_f800;
@@ -185,7 +187,7 @@ pub trait PciProgrammingInterface {
}
/// Types of PCI capabilities.
#[derive(PartialEq, Copy, Clone)]
#[derive(PartialEq, Eq, Copy, Clone)]
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[repr(C)]
@@ -319,24 +321,55 @@ pub struct PciConfiguration {
}
/// See pci_regs.h in kernel
#[derive(Copy, Clone, PartialEq, Versionize, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Versionize, Debug)]
pub enum PciBarRegionType {
Memory32BitRegion = 0,
IoRegion = 0x01,
Memory64BitRegion = 0x04,
}
impl From<PciBarType> for PciBarRegionType {
fn from(type_: PciBarType) -> Self {
match type_ {
PciBarType::Io => PciBarRegionType::IoRegion,
PciBarType::Mmio32 => PciBarRegionType::Memory32BitRegion,
PciBarType::Mmio64 => PciBarRegionType::Memory64BitRegion,
}
}
}
#[allow(clippy::from_over_into)]
impl Into<PciBarType> for PciBarRegionType {
fn into(self) -> PciBarType {
match self {
PciBarRegionType::IoRegion => PciBarType::Io,
PciBarRegionType::Memory32BitRegion => PciBarType::Mmio32,
PciBarRegionType::Memory64BitRegion => PciBarType::Mmio64,
}
}
}
#[derive(Copy, Clone)]
pub enum PciBarPrefetchable {
NotPrefetchable = 0,
Prefetchable = 0x08,
}
#[allow(clippy::from_over_into)]
impl Into<bool> for PciBarPrefetchable {
fn into(self) -> bool {
match self {
PciBarPrefetchable::NotPrefetchable => false,
PciBarPrefetchable::Prefetchable => true,
}
}
}
#[derive(Copy, Clone)]
pub struct PciBarConfiguration {
addr: u64,
size: u64,
reg_idx: usize,
idx: usize,
region_type: PciBarRegionType,
prefetchable: PciBarPrefetchable,
}
@@ -556,22 +589,23 @@ impl PciConfiguration {
/// Adds a region specified by `config`. Configures the specified BAR(s) to
/// report this region and size to the guest kernel. Enforces a few constraints
/// (i.e, region size must be power of two, register not already used). Returns 'None' on
/// failure all, `Some(BarIndex)` on success.
pub fn add_pci_bar(&mut self, config: &PciBarConfiguration) -> Result<usize> {
if self.bars[config.reg_idx].used {
return Err(Error::BarInUse(config.reg_idx));
/// (i.e, region size must be power of two, register not already used).
pub fn add_pci_bar(&mut self, config: &PciBarConfiguration) -> Result<()> {
let bar_idx = config.idx;
let reg_idx = BAR0_REG + bar_idx;
if self.bars[bar_idx].used {
return Err(Error::BarInUse(bar_idx));
}
if config.size.count_ones() != 1 {
return Err(Error::BarSizeInvalid(config.size));
}
if config.reg_idx >= NUM_BAR_REGS {
return Err(Error::BarInvalid(config.reg_idx));
if bar_idx >= NUM_BAR_REGS {
return Err(Error::BarInvalid(bar_idx));
}
let bar_idx = BAR0_REG + config.reg_idx;
let end_addr = config
.addr
.checked_add(config.size - 1)
@@ -584,20 +618,20 @@ impl PciConfiguration {
// Encode the BAR size as expected by the software running in
// the guest.
self.bars[config.reg_idx].size =
self.bars[bar_idx].size =
encode_32_bits_bar_size(config.size as u32).ok_or(Error::Encode32BarSize)?;
}
PciBarRegionType::Memory64BitRegion => {
if config.reg_idx + 1 >= NUM_BAR_REGS {
return Err(Error::BarInvalid64(config.reg_idx));
if bar_idx + 1 >= NUM_BAR_REGS {
return Err(Error::BarInvalid64(bar_idx));
}
if end_addr > u64::max_value() {
return Err(Error::BarAddressInvalid(config.addr, config.size));
}
if self.bars[config.reg_idx + 1].used {
return Err(Error::BarInUse64(config.reg_idx));
if self.bars[bar_idx + 1].used {
return Err(Error::BarInUse64(bar_idx));
}
// Encode the BAR size as expected by the software running in
@@ -605,12 +639,12 @@ impl PciConfiguration {
let (bar_size_hi, bar_size_lo) =
encode_64_bits_bar_size(config.size).ok_or(Error::Encode64BarSize)?;
self.registers[bar_idx + 1] = (config.addr >> 32) as u32;
self.writable_bits[bar_idx + 1] = 0xffff_ffff;
self.bars[config.reg_idx + 1].addr = self.registers[bar_idx + 1];
self.bars[config.reg_idx].size = bar_size_lo;
self.bars[config.reg_idx + 1].size = bar_size_hi;
self.bars[config.reg_idx + 1].used = true;
self.registers[reg_idx + 1] = (config.addr >> 32) as u32;
self.writable_bits[reg_idx + 1] = 0xffff_ffff;
self.bars[bar_idx + 1].addr = self.registers[reg_idx + 1];
self.bars[bar_idx].size = bar_size_lo;
self.bars[bar_idx + 1].size = bar_size_hi;
self.bars[bar_idx + 1].used = true;
}
}
@@ -622,26 +656,30 @@ impl PciConfiguration {
PciBarRegionType::IoRegion => (BAR_IO_ADDR_MASK, config.region_type as u32),
};
self.registers[bar_idx] = ((config.addr as u32) & mask) | lower_bits;
self.writable_bits[bar_idx] = mask;
self.bars[config.reg_idx].addr = self.registers[bar_idx];
self.bars[config.reg_idx].used = true;
self.bars[config.reg_idx].r#type = Some(config.region_type);
Ok(config.reg_idx)
self.registers[reg_idx] = ((config.addr as u32) & mask) | lower_bits;
self.writable_bits[reg_idx] = mask;
self.bars[bar_idx].addr = self.registers[reg_idx];
self.bars[bar_idx].used = true;
self.bars[bar_idx].r#type = Some(config.region_type);
Ok(())
}
/// Adds rom expansion BAR.
pub fn add_pci_rom_bar(&mut self, config: &PciBarConfiguration, active: u32) -> Result<usize> {
pub fn add_pci_rom_bar(&mut self, config: &PciBarConfiguration, active: u32) -> Result<()> {
let bar_idx = config.idx;
let reg_idx = ROM_BAR_REG;
if self.rom_bar_used {
return Err(Error::RomBarInUse(config.reg_idx));
return Err(Error::RomBarInUse(bar_idx));
}
if config.size.count_ones() != 1 {
return Err(Error::RomBarSizeInvalid(config.size));
}
if config.reg_idx != ROM_BAR_REG {
return Err(Error::RomBarInvalid(config.reg_idx));
if bar_idx != ROM_BAR_IDX {
return Err(Error::RomBarInvalid(bar_idx));
}
let end_addr = config
@@ -653,13 +691,14 @@ impl PciConfiguration {
return Err(Error::RomBarAddressInvalid(config.addr, config.size));
}
self.registers[config.reg_idx] = (config.addr as u32) | active;
self.writable_bits[config.reg_idx] = ROM_BAR_ADDR_MASK;
self.rom_bar_addr = self.registers[config.reg_idx];
self.registers[reg_idx] = (config.addr as u32) | active;
self.writable_bits[reg_idx] = ROM_BAR_ADDR_MASK;
self.rom_bar_addr = self.registers[reg_idx];
self.rom_bar_size =
encode_32_bits_bar_size(config.size as u32).ok_or(Error::Encode32BarSize)?;
self.rom_bar_used = true;
Ok(config.reg_idx)
Ok(())
}
/// Returns the address of the given BAR region.
@@ -911,7 +950,7 @@ impl Snapshottable for PciConfiguration {
impl Default for PciBarConfiguration {
fn default() -> Self {
PciBarConfiguration {
reg_idx: 0,
idx: 0,
addr: 0,
size: 0,
region_type: PciBarRegionType::Memory64BitRegion,
@@ -922,13 +961,13 @@ impl Default for PciBarConfiguration {
impl PciBarConfiguration {
pub fn new(
reg_idx: usize,
idx: usize,
size: u64,
region_type: PciBarRegionType,
prefetchable: PciBarPrefetchable,
) -> Self {
PciBarConfiguration {
reg_idx,
idx,
addr: 0,
size,
region_type,
@@ -937,8 +976,8 @@ impl PciBarConfiguration {
}
#[must_use]
pub fn set_register_index(mut self, reg_idx: usize) -> Self {
self.reg_idx = reg_idx;
pub fn set_index(mut self, idx: usize) -> Self {
self.idx = idx;
self
}
@@ -954,15 +993,31 @@ impl PciBarConfiguration {
self
}
pub fn get_size(&self) -> u64 {
self.size
}
#[must_use]
pub fn set_region_type(mut self, region_type: PciBarRegionType) -> Self {
self.region_type = region_type;
self
}
pub fn idx(&self) -> usize {
self.idx
}
pub fn addr(&self) -> u64 {
self.addr
}
pub fn size(&self) -> u64 {
self.size
}
pub fn region_type(&self) -> PciBarRegionType {
self.region_type
}
pub fn prefetchable(&self) -> PciBarPrefetchable {
self.prefetchable
}
}
#[cfg(test)]

View File

@@ -3,13 +3,13 @@
// found in the LICENSE-BSD-3-Clause file.
use crate::configuration::{self, PciBarRegionType};
use crate::PciBarConfiguration;
use std::any::Any;
use std::fmt::{self, Display};
use std::sync::{Arc, Barrier, Mutex};
use std::{self, io, result};
use vm_allocator::{AddressAllocator, SystemAllocator};
use vm_device::BusDevice;
use vm_memory::{GuestAddress, GuestUsize};
use vm_device::{BusDevice, Resource};
#[derive(Debug)]
pub enum Error {
@@ -19,6 +19,8 @@ pub enum Error {
IoAllocationFailed(u64),
/// Registering an IO BAR failed.
IoRegistrationFailed(u64, configuration::Error),
/// Expected resource not found.
MissingResource,
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -34,6 +36,7 @@ impl Display for Error {
IoRegistrationFailed(addr, e) => {
write!(f, "failed to register an IO BAR, addr={} err={}", addr, e)
}
MissingResource => write!(f, "failed to find expected resource"),
}
}
}
@@ -53,7 +56,8 @@ pub trait PciDevice: BusDevice {
&mut self,
_allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
_resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>> {
Ok(Vec::new())
}
@@ -103,6 +107,9 @@ pub trait PciDevice: BusDevice {
/// Provides a mutable reference to the Any trait. This is useful to let
/// the caller have access to the underlying type behind the trait.
fn as_any(&mut self) -> &mut dyn Any;
/// Optionally returns a unique identifier.
fn id(&self) -> Option<String>;
}
/// This trait defines a set of functions which can be triggered whenever a

View File

@@ -52,7 +52,7 @@ pub const PCI_CONFIG_IO_PORT: u64 = 0xcf8;
#[cfg(target_arch = "x86_64")]
pub const PCI_CONFIG_IO_PORT_SIZE: u64 = 0x8;
#[derive(Clone, Copy, PartialEq, PartialOrd)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd)]
pub struct PciBdf(u32);
struct PciBdfVisitor;

View File

@@ -3,11 +3,17 @@
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
use std::io;
use std::sync::Arc;
use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use vm_device::interrupt::{
InterruptIndex, InterruptSourceConfig, InterruptSourceGroup, MsiIrqSourceConfig,
};
use vm_migration::{MigratableError, Pausable, Snapshot, Snapshottable, VersionMapped};
// MSI control masks
const MSI_CTL_ENABLE: u16 = 0x1;
@@ -32,7 +38,15 @@ pub fn msi_num_enabled_vectors(msg_ctl: u16) -> usize {
1 << field
}
#[derive(Clone, Copy, Default)]
#[derive(Error, Debug)]
enum Error {
#[error("Failed enabling the interrupt route: {0}")]
EnableInterruptRoute(io::Error),
#[error("Failed updating the interrupt route: {0}")]
UpdateInterruptRoute(io::Error),
}
#[derive(Clone, Copy, Default, Versionize)]
pub struct MsiCap {
// Message Control Register
// 0: MSI enable.
@@ -157,8 +171,15 @@ impl MsiCap {
}
}
pub struct MsiConfig {
#[derive(Versionize)]
struct MsiConfigState {
cap: MsiCap,
}
impl VersionMapped for MsiConfigState {}
pub struct MsiConfig {
pub cap: MsiCap,
interrupt_source_group: Arc<dyn InterruptSourceGroup>,
}
@@ -175,6 +196,39 @@ impl MsiConfig {
}
}
fn state(&self) -> MsiConfigState {
MsiConfigState { cap: self.cap }
}
fn set_state(&mut self, state: &MsiConfigState) -> Result<(), Error> {
self.cap = state.cap;
if self.enabled() {
for idx in 0..self.num_enabled_vectors() {
let config = MsiIrqSourceConfig {
high_addr: self.cap.msg_addr_hi,
low_addr: self.cap.msg_addr_lo,
data: self.cap.msg_data as u32,
devid: 0,
};
self.interrupt_source_group
.update(
idx as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
self.cap.vector_masked(idx),
)
.map_err(Error::UpdateInterruptRoute)?;
}
self.interrupt_source_group
.enable()
.map_err(Error::EnableInterruptRoute)?;
}
Ok(())
}
pub fn enabled(&self) -> bool {
self.cap.enabled()
}
@@ -222,3 +276,26 @@ impl MsiConfig {
}
}
}
impl Pausable for MsiConfig {}
impl Snapshottable for MsiConfig {
fn id(&self) -> String {
String::from("msi_config")
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id(), &self.state())
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.set_state(&snapshot.to_versioned_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!(
"Could not restore state for {}: {:?}",
self.id(),
e
))
})
}
}

View File

@@ -441,7 +441,7 @@ impl Snapshottable for MsixConfig {
#[allow(dead_code)]
#[repr(packed)]
#[derive(Clone, Copy, Default)]
#[derive(Clone, Copy, Default, Versionize)]
pub struct MsixCap {
// Message Control Register
// 10-0: MSI-X Table size

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,12 @@
// SPDX-License-Identifier: Apache-2.0
//
use crate::vfio::{Interrupt, Vfio, VfioCommon, VfioError};
use crate::{BarReprogrammingParams, PciBarRegionType, VfioPciError};
use crate::vfio::{Interrupt, UserMemoryRegion, Vfio, VfioCommon, VfioError};
use crate::{BarReprogrammingParams, PciBarConfiguration, VfioPciError};
use crate::{
PciBdf, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciSubclass,
};
use anyhow::anyhow;
use hypervisor::HypervisorVmError;
use std::any::Any;
use std::os::unix::prelude::AsRawFd;
@@ -21,19 +22,20 @@ use vfio_user::{Client, Error as VfioUserError};
use vm_allocator::{AddressAllocator, SystemAllocator};
use vm_device::dma_mapping::ExternalDmaMapping;
use vm_device::interrupt::{InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig};
use vm_device::BusDevice;
use vm_device::{BusDevice, Resource};
use vm_memory::bitmap::AtomicBitmap;
use vm_memory::{
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryRegion, GuestRegionMmap,
GuestUsize,
};
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
pub struct VfioUserPciDevice {
id: String,
vm: Arc<dyn hypervisor::Vm>,
client: Arc<Mutex<Client>>,
vfio_wrapper: VfioUserClientWrapper,
common: VfioCommon,
memory_slot: Arc<dyn Fn() -> u32 + Send + Sync>,
}
#[derive(Error, Debug)]
@@ -62,12 +64,16 @@ impl PciSubclass for PciVfioUserSubclass {
}
impl VfioUserPciDevice {
#[allow(clippy::too_many_arguments)]
pub fn new(
id: String,
vm: &Arc<dyn hypervisor::Vm>,
client: Arc<Mutex<Client>>,
msi_interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>,
bdf: PciBdf,
restoring: bool,
memory_slot: Arc<dyn Fn() -> u32 + Send + Sync>,
) -> Result<Self, VfioUserPciDeviceError> {
// This is used for the BAR and capabilities only
let configuration = PciConfiguration::new(
@@ -103,29 +109,31 @@ impl VfioUserPciDevice {
msi: None,
msix: None,
},
msi_interrupt_manager,
legacy_interrupt_group,
vfio_wrapper: Arc::new(vfio_wrapper) as Arc<dyn Vfio>,
};
common.parse_capabilities(msi_interrupt_manager, &vfio_wrapper, bdf);
common
.initialize_legacy_interrupt(legacy_interrupt_group, &vfio_wrapper)
.map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?;
// No need to parse capabilities from the device if on the restore path.
// The initialization will be performed later when restore() will be
// called.
if !restoring {
common.parse_capabilities(bdf);
common
.initialize_legacy_interrupt()
.map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?;
}
Ok(Self {
id,
vm: vm.clone(),
client,
vfio_wrapper,
common,
memory_slot,
})
}
pub fn map_mmio_regions<F>(
&mut self,
vm: &Arc<dyn hypervisor::Vm>,
mem_slot: F,
) -> Result<(), VfioUserPciDeviceError>
where
F: Fn() -> u32,
{
pub fn map_mmio_regions(&mut self) -> Result<(), VfioUserPciDeviceError> {
for mmio_region in &mut self.common.mmio_regions {
let region_flags = self
.client
@@ -143,6 +151,15 @@ impl VfioUserPciDevice {
.file_offset
.clone();
let sparse_areas = self
.client
.lock()
.unwrap()
.region(mmio_region.index)
.unwrap()
.sparse_areas
.clone();
if region_flags & VFIO_REGION_INFO_FLAG_MMAP != 0 {
let mut prot = 0;
if region_flags & VFIO_REGION_INFO_FLAG_READ != 0 {
@@ -152,41 +169,58 @@ impl VfioUserPciDevice {
prot |= libc::PROT_WRITE;
}
let host_addr = unsafe {
libc::mmap(
null_mut(),
mmio_region.length as usize,
prot,
libc::MAP_SHARED,
file_offset.as_ref().unwrap().file().as_raw_fd(),
file_offset.as_ref().unwrap().start() as libc::off_t,
)
let mmaps = if sparse_areas.is_empty() {
vec![vfio_region_sparse_mmap_area {
offset: 0,
size: mmio_region.length,
}]
} else {
sparse_areas
};
if host_addr == libc::MAP_FAILED {
error!(
"Could not mmap regions, error:{}",
std::io::Error::last_os_error()
for s in mmaps.iter() {
let host_addr = unsafe {
libc::mmap(
null_mut(),
s.size as usize,
prot,
libc::MAP_SHARED,
file_offset.as_ref().unwrap().file().as_raw_fd(),
file_offset.as_ref().unwrap().start() as libc::off_t
+ s.offset as libc::off_t,
)
};
if host_addr == libc::MAP_FAILED {
error!(
"Could not mmap regions, error:{}",
std::io::Error::last_os_error()
);
continue;
}
let user_memory_region = UserMemoryRegion {
slot: (self.memory_slot)(),
start: mmio_region.start.0 + s.offset,
size: s.size,
host_addr: host_addr as u64,
};
mmio_region.user_memory_regions.push(user_memory_region);
let mem_region = self.vm.make_user_memory_region(
user_memory_region.slot,
user_memory_region.start,
user_memory_region.size,
user_memory_region.host_addr,
false,
false,
);
continue;
self.vm
.create_user_memory_region(mem_region)
.map_err(VfioUserPciDeviceError::MapRegionGuest)?;
}
let slot = mem_slot();
let mem_region = vm.make_user_memory_region(
slot,
mmio_region.start.0,
mmio_region.length as u64,
host_addr as u64,
false,
false,
);
vm.create_user_memory_region(mem_region)
.map_err(VfioUserPciDeviceError::MapRegionGuest)?;
mmio_region.mem_slot = Some(slot);
mmio_region.host_addr = Some(host_addr as u64);
mmio_region.mmap_size = Some(mmio_region.length as usize);
}
}
@@ -195,17 +229,13 @@ impl VfioUserPciDevice {
pub fn unmap_mmio_regions(&mut self) {
for mmio_region in self.common.mmio_regions.iter() {
if let (Some(host_addr), Some(mmap_size), Some(mem_slot)) = (
mmio_region.host_addr,
mmio_region.mmap_size,
mmio_region.mem_slot,
) {
for user_memory_region in mmio_region.user_memory_regions.iter() {
// Remove region
let r = self.vm.make_user_memory_region(
mem_slot,
mmio_region.start.raw_value(),
mmap_size as u64,
host_addr as u64,
user_memory_region.slot,
user_memory_region.start,
user_memory_region.size,
user_memory_region.host_addr,
false,
false,
);
@@ -214,7 +244,13 @@ impl VfioUserPciDevice {
error!("Could not remove the userspace memory region: {}", e);
}
let ret = unsafe { libc::munmap(host_addr as *mut libc::c_void, mmap_size) };
// Remove mmaps
let ret = unsafe {
libc::munmap(
user_memory_region.host_addr as *mut libc::c_void,
user_memory_region.size as usize,
)
};
if ret != 0 {
error!(
"Could not unmap region {}, error:{}",
@@ -392,9 +428,10 @@ impl PciDevice for VfioUserPciDevice {
&mut self,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> {
resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common
.allocate_bars(allocator, mmio_allocator, &self.vfio_wrapper)
.allocate_bars(allocator, mmio_allocator, resources)
}
fn free_bars(
@@ -425,22 +462,19 @@ impl PciDevice for VfioUserPciDevice {
offset: u64,
data: &[u8],
) -> Option<Arc<Barrier>> {
self.common
.write_config_register(reg_idx, offset, data, &self.vfio_wrapper)
self.common.write_config_register(reg_idx, offset, data)
}
fn read_config_register(&mut self, reg_idx: usize) -> u32 {
self.common
.read_config_register(reg_idx, &self.vfio_wrapper)
self.common.read_config_register(reg_idx)
}
fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) {
self.common.read_bar(base, offset, data, &self.vfio_wrapper)
self.common.read_bar(base, offset, data)
}
fn write_bar(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
self.common
.write_bar(base, offset, data, &self.vfio_wrapper)
self.common.write_bar(base, offset, data)
}
fn move_bar(&mut self, old_base: u64, new_base: u64) -> Result<(), std::io::Error> {
@@ -449,35 +483,41 @@ impl PciDevice for VfioUserPciDevice {
if mmio_region.start.raw_value() == old_base {
mmio_region.start = GuestAddress(new_base);
if let Some(mem_slot) = mmio_region.mem_slot {
if let Some(host_addr) = mmio_region.host_addr {
// Remove original region
let old_region = self.vm.make_user_memory_region(
mem_slot,
old_base,
mmio_region.length as u64,
host_addr as u64,
false,
false,
);
for user_memory_region in mmio_region.user_memory_regions.iter_mut() {
// Remove old region
let old_region = self.vm.make_user_memory_region(
user_memory_region.slot,
user_memory_region.start,
user_memory_region.size,
user_memory_region.host_addr,
false,
false,
);
self.vm
.remove_user_memory_region(old_region)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
self.vm
.remove_user_memory_region(old_region)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
let new_region = self.vm.make_user_memory_region(
mem_slot,
new_base,
mmio_region.length as u64,
host_addr as u64,
false,
false,
);
self.vm
.create_user_memory_region(new_region)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
// Update the user memory region with the correct start address.
if new_base > old_base {
user_memory_region.start += new_base - old_base;
} else {
user_memory_region.start -= old_base - new_base;
}
// Insert new region
let new_region = self.vm.make_user_memory_region(
user_memory_region.slot,
user_memory_region.start,
user_memory_region.size,
user_memory_region.host_addr,
false,
false,
);
self.vm
.create_user_memory_region(new_region)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
}
info!("Moved bar 0x{:x} -> 0x{:x}", old_base, new_base);
}
@@ -485,6 +525,10 @@ impl PciDevice for VfioUserPciDevice {
Ok(())
}
fn id(&self) -> Option<String> {
Some(self.id.clone())
}
}
impl Drop for VfioUserPciDevice {
@@ -493,18 +537,18 @@ impl Drop for VfioUserPciDevice {
if let Some(msix) = &self.common.interrupt.msix {
if msix.bar.enabled() {
self.common.disable_msix(&self.vfio_wrapper);
self.common.disable_msix();
}
}
if let Some(msi) = &self.common.interrupt.msi {
if msi.cfg.enabled() {
self.common.disable_msi(&self.vfio_wrapper)
self.common.disable_msi()
}
}
if self.common.interrupt.intx_in_use() {
self.common.disable_intx(&self.vfio_wrapper);
self.common.disable_intx();
}
if let Err(e) = self.client.lock().unwrap().shutdown() {
@@ -513,6 +557,40 @@ impl Drop for VfioUserPciDevice {
}
}
impl Pausable for VfioUserPciDevice {}
impl Snapshottable for VfioUserPciDevice {
fn id(&self) -> String {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let mut vfio_pci_dev_snapshot = Snapshot::new(&self.id);
// Snapshot VfioCommon
vfio_pci_dev_snapshot.add_snapshot(self.common.snapshot()?);
Ok(vfio_pci_dev_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
// Restore VfioCommon
if let Some(vfio_common_snapshot) = snapshot.snapshots.get(&self.common.id()) {
self.common.restore(*vfio_common_snapshot.clone())?;
self.map_mmio_regions().map_err(|e| {
MigratableError::Restore(anyhow!(
"Could not map MMIO regions for VfioUserPciDevice on restore {:?}",
e
))
})?;
}
Ok(())
}
}
impl Transportable for VfioUserPciDevice {}
impl Migratable for VfioUserPciDevice {}
pub struct VfioUserDmaMapping<M: GuestAddressSpace> {
client: Arc<Mutex<Client>>,
memory: Arc<M>,
@@ -546,10 +624,10 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioUserDmaMappi
)
})
} else {
return Err(std::io::Error::new(
Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Region not found for 0x{:x}", gpa),
));
))
}
}

View File

@@ -6,14 +6,13 @@ edition = "2021"
build = "build.rs"
[dependencies]
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
clap = { version = "3.2.8", features = ["wrap_help","cargo"] }
dirs = "4.0.0"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
serde_json = "1.0.78"
serde = { version = "1.0.138", features = ["rc", "derive"] }
serde_json = "1.0.82"
test_infra = { path = "../test_infra" }
thiserror = "1.0.30"
thiserror = "1.0.31"
wait-timeout = "0.2.0"
[build-dependencies]
clap = { version = "3.1.8", features = ["cargo"] }
clap = { version = "3.2.8", features = ["cargo"] }

View File

@@ -12,8 +12,14 @@ mod performance_tests;
use clap::{Arg, Command as ClapCommand};
use performance_tests::*;
use serde_derive::{Deserialize, Serialize};
use std::{env, fmt, process::Command, sync::mpsc::channel, thread, time::Duration};
use serde::{Deserialize, Serialize};
use std::{
env, fmt,
process::Command,
sync::{mpsc::channel, Arc},
thread,
time::Duration,
};
use thiserror::Error;
#[derive(Error, Debug)]
@@ -47,18 +53,30 @@ impl Default for MetricsReport {
let mut git_human_readable = "".to_string();
if let Ok(git_out) = Command::new("git").args(&["describe", "--dirty"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
git_human_readable = git_out_str.trim().to_string();
}
git_human_readable = String::from_utf8(git_out.stdout)
.unwrap()
.trim()
.to_string();
} else {
eprintln!(
"Error generating human readable git reference: {}",
String::from_utf8(git_out.stderr).unwrap()
);
}
}
let mut git_revision = "".to_string();
if let Ok(git_out) = Command::new("git").args(&["rev-parse", "HEAD"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
git_revision = git_out_str.trim().to_string();
}
git_revision = String::from_utf8(git_out.stdout)
.unwrap()
.trim()
.to_string();
} else {
eprintln!(
"Error generating git reference: {}",
String::from_utf8(git_out.stderr).unwrap()
);
}
}
@@ -68,9 +86,15 @@ impl Default for MetricsReport {
.output()
{
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
git_commit_date = git_out_str.trim().to_string();
}
git_commit_date = String::from_utf8(git_out.stdout)
.unwrap()
.trim()
.to_string();
} else {
eprintln!(
"Error generating git commit date: {}",
String::from_utf8(git_out.stderr).unwrap()
);
}
}
@@ -84,6 +108,21 @@ impl Default for MetricsReport {
}
}
#[derive(Default)]
pub struct PerformanceTestOverrides {
test_iterations: Option<u32>,
}
impl fmt::Display for PerformanceTestOverrides {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(test_iterations) = self.test_iterations {
write!(f, "test_iterations = {}", test_iterations)?;
}
Ok(())
}
}
pub struct PerformanceTestControl {
test_timeout: u32,
test_iterations: u32,
@@ -91,6 +130,7 @@ pub struct PerformanceTestControl {
queue_size: Option<u32>,
net_rx: Option<bool>,
fio_ops: Option<FioOps>,
num_boot_vcpus: Option<u8>,
}
impl fmt::Display for PerformanceTestControl {
@@ -125,6 +165,7 @@ impl PerformanceTestControl {
queue_size: None,
net_rx: None,
fio_ops: None,
num_boot_vcpus: Some(1),
}
}
}
@@ -140,9 +181,12 @@ struct PerformanceTest {
}
impl PerformanceTest {
pub fn run(&self) -> PerformanceTestResult {
pub fn run(&self, overrides: &PerformanceTestOverrides) -> PerformanceTestResult {
let mut metrics = Vec::new();
for _ in 0..self.control.test_iterations {
for _ in 0..overrides
.test_iterations
.unwrap_or(self.control.test_iterations)
{
metrics.push((self.func_ptr)(&self.control));
}
@@ -162,8 +206,9 @@ impl PerformanceTest {
// Calculate the timeout for each test
// Note: To cover the setup/cleanup time, 20s is added for each iteration of the test
pub fn calc_timeout(&self) -> u64 {
((self.control.test_timeout + 20) * self.control.test_iterations) as u64
pub fn calc_timeout(&self, test_iterations: &Option<u32>) -> u64 {
((self.control.test_timeout + 20) * test_iterations.unwrap_or(self.control.test_iterations))
as u64
}
}
@@ -216,7 +261,7 @@ mod adjuster {
}
}
const TEST_LIST: [PerformanceTest; 15] = [
const TEST_LIST: [PerformanceTest; 17] = [
PerformanceTest {
name: "boot_time_ms",
func_ptr: performance_boot_time,
@@ -237,6 +282,28 @@ const TEST_LIST: [PerformanceTest; 15] = [
},
unit_adjuster: adjuster::s_to_ms,
},
PerformanceTest {
name: "boot_time_16_vcpus_ms",
func_ptr: performance_boot_time,
control: PerformanceTestControl {
test_timeout: 2,
test_iterations: 10,
num_boot_vcpus: Some(16),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::s_to_ms,
},
PerformanceTest {
name: "boot_time_16_vcpus_pmem_ms",
func_ptr: performance_boot_time_pmem,
control: PerformanceTestControl {
test_timeout: 2,
test_iterations: 10,
num_boot_vcpus: Some(16),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::s_to_ms,
},
PerformanceTest {
name: "virtio_net_latency_us",
func_ptr: performance_net_latency,
@@ -381,12 +448,20 @@ const TEST_LIST: [PerformanceTest; 15] = [
},
];
fn run_test_with_timeout(test: &'static PerformanceTest) -> Result<PerformanceTestResult, Error> {
fn run_test_with_timeout(
test: &'static PerformanceTest,
overrides: &Arc<PerformanceTestOverrides>,
) -> Result<PerformanceTestResult, Error> {
let (sender, receiver) = channel::<Result<PerformanceTestResult, Error>>();
let test_iterations = overrides.test_iterations;
let overrides = overrides.clone();
thread::spawn(move || {
println!("Test '{}' running .. ({})", test.name, test.control);
println!(
"Test '{}' running .. (control: {}, overrides: {})",
test.name, test.control, overrides
);
let output = match std::panic::catch_unwind(|| test.run()) {
let output = match std::panic::catch_unwind(|| test.run(&overrides)) {
Ok(test_result) => {
println!(
"Test '{}' .. ok: mean = {}, std_dev = {}",
@@ -401,7 +476,7 @@ fn run_test_with_timeout(test: &'static PerformanceTest) -> Result<PerformanceTe
});
// Todo: Need to cleanup/kill all hanging child processes
let test_timeout = test.calc_timeout();
let test_timeout = test.calc_timeout(&test_iterations);
receiver
.recv_timeout(Duration::from_secs(test_timeout))
.map_err(|_| {
@@ -445,6 +520,12 @@ fn main() {
.help("Report file. Standard error is used if not specified")
.takes_value(true),
)
.arg(
Arg::new("iterations")
.long("iterations")
.help("Override number of test iterations")
.takes_value(true),
)
.get_matches();
// It seems that the tool (ethr) used for testing the virtio-net latency
@@ -473,9 +554,17 @@ fn main() {
init_tests();
let overrides = Arc::new(PerformanceTestOverrides {
test_iterations: cmd_arguments
.value_of("iterations")
.map(|s| s.parse())
.transpose()
.unwrap_or_default(),
});
for test in test_list.iter() {
if test_filter.is_empty() || test_filter.iter().any(|&s| test.name.contains(s)) {
match run_test_with_timeout(test) {
match run_test_with_timeout(test, &overrides) {
Ok(r) => {
metrics_report.results.push(r);
}

View File

@@ -238,6 +238,7 @@ pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 {
.default_disks()
.args(&["--net", net_params.as_str()])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
.spawn()
.unwrap();
@@ -367,6 +368,7 @@ pub fn performance_net_latency(control: &PerformanceTestControl) -> f64 {
.default_disks()
.args(&["--net", net_params.as_str()])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
.spawn()
.unwrap();
@@ -472,7 +474,12 @@ fn parse_boot_time_output(output: &[u8]) -> Result<f64, Error> {
}
fn measure_boot_time(cmd: &mut GuestCommand, test_timeout: u32) -> Result<f64, Error> {
let mut child = cmd.capture_output().set_print_cmd(false).spawn().unwrap();
let mut child = cmd
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
.spawn()
.unwrap();
thread::sleep(Duration::new(test_timeout as u64, 0));
let _ = child.kill();
@@ -499,6 +506,10 @@ pub fn performance_boot_time(control: &PerformanceTestControl) -> f64 {
let mut cmd = GuestCommand::new(&guest);
let c = cmd
.args(&[
"--cpus",
&format!("boot={}", control.num_boot_vcpus.unwrap_or(1)),
])
.args(&["--memory", "size=1G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
@@ -522,6 +533,10 @@ pub fn performance_boot_time_pmem(control: &PerformanceTestControl) -> f64 {
let guest = performance_test_new_guest(Box::new(focal));
let mut cmd = GuestCommand::new(&guest);
let c = cmd
.args(&[
"--cpus",
&format!("boot={}", control.num_boot_vcpus.unwrap_or(1)),
])
.args(&["--memory", "size=1G,hugepages=on"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", "root=/dev/pmem0p1 console=ttyS0 quiet rw"])
@@ -655,6 +670,7 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
.default_net()
.args(&["--api-socket", &api_socket])
.capture_output()
.verbosity(VerbosityLevel::Warn)
.set_print_cmd(false)
.spawn()
.unwrap();

View File

@@ -10,7 +10,7 @@ path = "src/qcow.rs"
[dependencies]
byteorder = "1.4.3"
libc = "0.2.123"
log = "0.4.16"
remain = "0.2.2"
libc = "0.2.126"
log = "0.4.17"
remain = "0.2.3"
vmm-sys-util = "0.9.0"

View File

@@ -516,6 +516,19 @@ impl QcowFile {
let l2_entries = cluster_size / size_of::<u64>() as u64;
// Check for compressed blocks
for l2_addr_disk in l1_table.get_values() {
if *l2_addr_disk != 0 {
if let Err(e) = Self::read_l2_cluster(&mut raw_file, *l2_addr_disk) {
if let Some(os_error) = e.raw_os_error() {
if os_error == ENOTSUP {
return Err(Error::CompressedBlocksNotSupported);
}
}
}
}
}
let mut qcow = QcowFile {
raw_file,
header,

View File

@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libc = "0.2.123"
log = "0.4.16"
libc = "0.2.126"
log = "0.4.17"
vmm-sys-util = "0.9.0"

View File

@@ -91,7 +91,7 @@ pub enum BucketReduction {
/// TokenBucket provides a lower level interface to rate limiting with a
/// configurable capacity, refill-rate and initial burst.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TokenBucket {
// Bucket defining traits.
size: u64,

View File

@@ -1,11 +1,28 @@
- [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements)
- [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Removals](#removals)
- [Contributors](#contributors)
- [v24.0](#v240)
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
- [Sparse Mmap support](#sparse-mmap-support)
- [Expose Platform Serial Number](#expose-platform-serial-number)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations)
- [New on the Website](#new-on-the-website)
- [Contributors](#contributors-1)
- [v23.1](#v231)
- [v23.0](#v230)
- [vDPA Support](#vdpa-support)
- [Updated OS Support list](#updated-os-support-list)
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
- [`AMX` Support](#amx-support)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Deprecations](#deprecations)
- [Contributors](#contributors)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-2)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -16,13 +33,13 @@
- [PMU Support for AArch64](#pmu-support-for-aarch64)
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [v21.0](#v210)
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
- [Notable Bug fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [Notable Bug fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -31,8 +48,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [Notable bug fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [v19.0](#v190)
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
- [PCI boot time optimisations](#pci-boot-time-optimisations)
@@ -40,8 +57,8 @@
- [Live migration enhancements](#live-migration-enhancements)
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
- [Notable bug fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [Notable bug fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [v18.0](#v180)
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
@@ -51,31 +68,31 @@
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
- [Power button support on AArch64](#power-button-support-on-aarch64)
- [Notable bug fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [Notable bug fixes](#notable-bug-fixes-7)
- [Contributors](#contributors-7)
- [v17.0](#v170)
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
- [Improved SGX support](#improved-sgx-support)
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
- [Notable bug fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [Notable bug fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-8)
- [v16.0](#v160)
- [Improved live migration support](#improved-live-migration-support)
- [Improved `vhost-user` support](#improved-vhost-user-support)
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
- [Notable bug fixes](#notable-bug-fixes-7)
- [Notable bug fixes](#notable-bug-fixes-9)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-7)
- [Contributors](#contributors-9)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
- [Support for runtime control of `virtio-net` guest offload](#support-for-runtime-control-of-virtio-net-guest-offload)
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-8)
- [Deprecations](#deprecations-2)
- [Contributors](#contributors-10)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -84,8 +101,8 @@
- [Updated hotplug documentation](#updated-hotplug-documentation)
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
- [Block device rate limiting](#block-device-rate-limiting)
- [Deprecations](#deprecations-2)
- [Contributors](#contributors-9)
- [Deprecations](#deprecations-3)
- [Contributors](#contributors-11)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -93,13 +110,13 @@
- [VHD disk image support](#vhd-disk-image-support)
- [Improved Virtio device threading](#improved-virtio-device-threading)
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
- [Contributors](#contributors-10)
- [Contributors](#contributors-12)
- [v0.12.0](#v0120)
- [ARM64 enhancements](#arm64-enhancements)
- [Removal of `vhost-user-net` and `vhost-user-block` self spawning](#removal-of-vhost-user-net-and-vhost-user-block-self-spawning)
- [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend)
- [Enhanced "info" API](#enhanced-info-api)
- [Contributors](#contributors-11)
- [Contributors](#contributors-13)
- [v0.11.0](#v0110)
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
- [Windows Guest Support](#windows-guest-support)
@@ -111,15 +128,15 @@
- [Default Log Level Changed](#default-log-level-changed)
- [New `--balloon` Parameter Added](#new---balloon-parameter-added)
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-12)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Contributors](#contributors-14)
- [v0.10.0](#v0100)
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
- [Memory Zones](#memory-zones)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Contributors](#contributors-13)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Contributors](#contributors-15)
- [v0.9.0](#v090)
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
- [Block and Network Device Statistics](#block-and-network-device-statistics)
@@ -132,17 +149,17 @@
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
- [Intel SGX Support](#intel-sgx-support)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Contributors](#contributors-14)
- [Notable Bug Fixes](#notable-bug-fixes-12)
- [Contributors](#contributors-16)
- [v0.8.0](#v080)
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
- [Experimental ARM64 Support](#experimental-arm64-support)
- [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests)
- [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices)
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Notable Bug Fixes](#notable-bug-fixes-13)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-15)
- [Contributors](#contributors-17)
- [v0.7.0](#v070)
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
- [Alternative `libc` Support](#alternative-libc-support)
@@ -152,14 +169,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-16)
- [Contributors](#contributors-18)
- [v0.6.0](#v060)
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
- [Shared Filesystem Improvements](#shared-filesystem-improvements)
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
- [Command Line Interface](#command-line-interface)
- [PVH Boot](#pvh-boot)
- [Contributors](#contributors-17)
- [Contributors](#contributors-19)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -167,7 +184,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-18)
- [Contributors](#contributors-20)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -176,7 +193,7 @@
- [Userspace IOAPIC by default](#userspace-ioapic-by-default)
- [PCI BAR reprogramming](#pci-bar-reprogramming)
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
- [Contributors](#contributors-19)
- [Contributors](#contributors-21)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -203,6 +220,140 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v25.0
This release has been tracked through the [v25.0
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/29).
### `ch-remote` Improvements
The `ch-remote` command has gained support for creating the VM from a JSON
config and support for booting and deleting the VM from the VMM.
### VM "Coredump" Support
Under the `guest_debug` feature flag it is now possible to extract the memory
of the guest for use in debugging with e.g. the `crash` utility. (#4012)
### Notable Bug Fixes
* Always restore console mode on exit (#4249, #4248)
* Restore vCPUs in numerical order which fixes aarch64 snapshot/restore (#4244)
* Don't try and configure `IFF_RUNNING` on TAP devices (#4279)
* Propagate configured queue size through to vhost-user backend (#4286)
* Always Program vCPU CPUID before running the vCPU to fix running on Linux
5.16 (#4156)
* Enable ACPI MADT "Online Capable" flag for hotpluggable vCPUs to fix newer
Linux guest
### Removals
The following functionality has been removed:
* The `mergeable` option from the `virtio-pmem` support has been removed
(#3968)
* The `dax` option from the `virtio-fs` support has been removed (#3889)
### Contributors
Many thanks to everyone who has contributed to our release:
* Dylan Bargatze <dbargatz@users.noreply.github.com>
* Jinank Jain <jinankjain@microsoft.com>
* Michael Zhao <michael.zhao@arm.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <wang.yi59@zte.com.cn>
# v24.0
This release has been tracked through the [v24.0
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/28).
### Bypass Mode for `virtio-iommu`
`virtio-iommu` specification describes how a device can be attached by default
to a bypass domain. This feature is particularly helpful for booting a VM with
guest software which doesn't support `virtio-iommu` but still need to access
the device. Now that Cloud Hypervisor supports this feature, it can boot a VM
with Rust Hypervisor Firmware or OVMF even if the `virtio-block` device exposing
the disk image is placed behind a virtual IOMMU.
### Ensure Identifiers Uniqueness
Multiple checks have been added to the code to prevent devices with identical
identifiers from being created, and therefore avoid unexpected behaviors at boot
or whenever a device was hot plugged into the VM.
### Sparse Mmap support
Sparse mmap support has been added to both VFIO and vfio-user devices. This
allows the device regions that are not fully mappable to be partially mapped.
And the more a device region can be mapped into the guest address space, the
fewer VM exits will be generated when this device is accessed. This directly
impacts the performance related to this device.
### Expose Platform Serial Number
A new `serial_number` option has been added to `--platform`, allowing a user to
set a specific serial number for the platform. This number is exposed to the
guest through the SMBIOS.
### Notable Bug Fixes
* Fix loading RAW firmware (#4072)
* Reject compressed QCOW images (#4055)
* Reject virtio-mem resize if device is not activated (#4003)
* Fix potential mmap leaks from VFIO/vfio-user MMIO regions (#4069)
* Fix algorithm finding HOB memory resources (#3983)
### Notable Improvements
* Refactor interrupt handling (#4083)
* Load kernel asynchronously (#4022)
* Only create ACPI memory manager DSDT when resizable (#4013)
### Deprecations
Deprecated features will be removed in a subsequent release and users should
plan to use alternatives
* The `mergeable` option from the `virtio-pmem` support has been deprecated
(#3968)
* The `dax` option from the `virtio-fs` support has been deprecated (#3889)
### New on the Website
A new blog post [Achieving Bare Metal Performance Within a Virtual
Machine](https://www.cloudhypervisor.org/blog/achieving-bare-metal-performance-within-a-virtual-machine)
has been added to the Cloud Hypervisor website.
### Contributors
Many thanks to everyone who has contributed to our release:
* Anatol Belski <anbelski@linux.microsoft.com>
* Bo Chen <chen.bo@intel.com>
* Fabiano Fidêncio <fabiano.fidencio@intel.com>
* LiHui <andrewli@kubesphere.io>
* Maksym Pavlenko <pavlenko.maksym@gmail.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Steven Dake <steven.dake@gmail.com>
* Vincent Batts <vbatts@hashbangbash.com>
* Wei Liu <liuwe@microsoft.com>
# v23.1
This is a bug fix release. The following issues have been addressed:
* Add some missing seccomp rules
* Remove `virtio-fs` filesystem entries from config on removal
* Do not delete API socket on API server start (#4026)
* Reject `virtio-mem` resize if the guest doesn't activate the device
* Fix OpenAPI naming of I/O throttling knobs
# v23.0
This release has been tracked through the [v23.0

View File

@@ -4,7 +4,7 @@
FROM ubuntu:20.04 as dev
ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.59.0"
ARG RUST_TOOLCHAIN="1.62.0"
ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"

View File

@@ -1,25 +1,32 @@
# This spec file assumes you're building on an environment where:
# * You have access to the internet during the build
# * You have rustup installed on your system
# * You have both x86_64-unknown-linux-gnu and x86_64-unknown-linux-musl
# targets installed.
# If this flag is set to 1, rustup installation needs to exist on the system and
# <arch>-unknown-linux-gnu target is required.
# If this flag is set to 0, distro specific Rust packages will be pulled into the build environment.
%define using_rustup 1
# If this flag is set to 1, <arch>-unknown-linux-musl target is required.
%define using_musl_libc 1
# If this flag is set to 1, the vendored crates archive and cargo.toml need to be prepared and
# offline build is implied. Attached script update_src can be used for the vendorization.
# If this flag is set to 0, access to the internet is required during the build.
%define using_vendored_crates 0
Name: cloud-hypervisor
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
Version: 23.0
Version: 25.0
Release: 0%{?dist}
License: ASL 2.0 or BSD-3-clause
Group: Applications/System
Source0: https://github.com/cloud-hypervisor/cloud-hypervisor/archive/v%{version}.tar.gz
ExclusiveArch: x86_64
%if 0%{?using_vendored_crates}
Source1: vendor.tar.gz
Source2: config.toml
%endif
ExclusiveArch: x86_64 aarch64
BuildRequires: gcc
BuildRequires: glibc-devel
BuildRequires: binutils
BuildRequires: git
BuildRequires: openssl-devel
%if ! 0%{?using_rustup}
BuildRequires: rust
@@ -31,29 +38,51 @@ Requires: glibc
Requires: libgcc
Requires: libcap
%ifarch x86_64
%define rust_def_target x86_64-unknown-linux-gnu
%if 0%{?using_musl_libc}
%define rust_musl_target x86_64-unknown-linux-musl
%endif
%endif
%ifarch aarch64
%define rust_def_target aarch64-unknown-linux-gnu
%if 0%{?using_musl_libc}
%define rust_musl_target aarch64-unknown-linux-musl
%endif
%endif
%if 0%{?using_vendored_crates}
%define cargo_offline --offline
%endif
%description
Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM. The project focuses on exclusively running modern, cloud workloads, on top of a limited set of hardware architectures and platforms. Cloud workloads refers to those that are usually run by customers inside a cloud provider. For our purposes this means modern Linux* distributions with most I/O handled by paravirtualised devices (i.e. virtio), no requirement for legacy devices and recent CPUs and KVM.
%prep
%setup -q
%if 0%{?using_vendored_crates}
tar xf %{SOURCE1}
mkdir -p .cargo
cp %{SOURCE2} .cargo/
%endif
%install
rm -rf %{buildroot}
install -d %{buildroot}%{_bindir}
install -D -m755 ./target/x86_64-unknown-linux-gnu/release/cloud-hypervisor %{buildroot}%{_bindir}
install -D -m755 ./target/x86_64-unknown-linux-gnu/release/ch-remote %{buildroot}%{_bindir}
install -D -m755 ./target/%{rust_def_target}/release/cloud-hypervisor %{buildroot}%{_bindir}
install -D -m755 ./target/%{rust_def_target}/release/ch-remote %{buildroot}%{_bindir}
install -d %{buildroot}%{_libdir}
install -d %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/x86_64-unknown-linux-gnu/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/x86_64-unknown-linux-gnu/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/%{rust_def_target}/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor
install -D -m755 target/%{rust_def_target}/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor
%if 0%{?using_musl_libc}
install -d %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/x86_64-unknown-linux-musl/release/cloud-hypervisor %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/x86_64-unknown-linux-musl/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/x86_64-unknown-linux-musl/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/x86_64-unknown-linux-musl/release/ch-remote %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/cloud-hypervisor %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/vhost_user_block %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/vhost_user_net %{buildroot}%{_libdir}/cloud-hypervisor/static
install -D -m755 target/%{rust_musl_target}/release/ch-remote %{buildroot}%{_libdir}/cloud-hypervisor/static
%endif
@@ -74,21 +103,25 @@ fi
echo ${cargo_version}
%if 0%{?using_rustup}
rustup target list --installed | grep x86_64-unknown-linux-gnu
rustup target list --installed | grep -e "%{rust_def_target}"
if [[ $? -ne 0 ]]; then
echo "Target x86_64-unknown-linux-gnu not found, please install(#rustup target add x86_64-unknown-linux-gnu). exiting"
echo "Target %{rust_def_target} not found, please install(#rustup target add %{rust_def_target}). exiting"
fi
%if 0%{?using_musl_libc}
rustup target list --installed | grep x86_64-unknown-linux-musl
rustup target list --installed | grep -e "%{rust_musl_target}"
if [[ $? -ne 0 ]]; then
echo "Target x86_64-unknown-linux-musl not found, please install(#rustup target add x86_64-unknown-linux-musl). exiting"
echo "Target %{rust_musl_target} not found, please install(#rustup target add %{rust_musl_target}). exiting"
fi
%endif
%endif
cargo build --release --target=x86_64-unknown-linux-gnu --all
%if 0%{?using_vendored_crates}
# For vendored build, prepend this so openssl-sys doesn't trigger full OpenSSL build
export OPENSSL_NO_VENDOR=1
%endif
cargo build --release --target=%{rust_def_target} --all %{cargo_offline}
%if 0%{?using_musl_libc}
cargo build --release --target=x86_64-unknown-linux-musl --all
cargo build --release --target=%{rust_musl_target} --all %{cargo_offline}
%endif
@@ -112,6 +145,18 @@ rm -rf %{buildroot}
%changelog
* Thu Jul 07 2022 Rob Bradford <robert.bradford@intel.com> 25.0-0
- Update to 25.0
* Wed May 25 2022 Sebastien Boeuf <sebastien.boeuf@intel.com> 24.0-0
- Update to 24.0
* Tue May 18 2022 Anatol Belski <anbelski@linux.microsoft.com> - 23.1-0
- Update to 23.1
- Add support for aarch64 build
- Add offline build configuration using vendored crates
- Fix dependency for openssl-sys
* Thu Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
- Update to 23.0

36
rpm/update_src Normal file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
set -e
CH_VER=$1
CH_SPEC_DIR=$(pwd)
CH_TMP_DIR=$CH_SPEC_DIR/ch_tmp
CH_SRC_DIR=$CH_SPEC_DIR/SOURCES
if [ -z $CH_VER ]; then
echo "Replace sources with the given <version>"
echo "Usage: $0 <version>"
exit 1
fi
rm -rf $CH_TMP_DIR
if [ ! -d $CH_SRC_DIR ]; then
mkdir $CH_SRC_DIR
fi
rm -f $CH_SRC_DIR/v*.tar.gz $CH_SRC_DIR/config.toml $CH_SRC_DIR/vendor.tar.gz
wget https://github.com/cloud-hypervisor/cloud-hypervisor/archive/v${CH_VER}.tar.gz -O $CH_SRC_DIR/v${CH_VER}.tar.gz
mkdir $CH_TMP_DIR
tar xf $CH_SRC_DIR/v${CH_VER}.tar.gz -C $CH_TMP_DIR --strip-components=1
pushd $CH_TMP_DIR
cargo vendor > $CH_SRC_DIR/config.toml
tar czvf $CH_SRC_DIR/vendor.tar.gz vendor
popd
rm -rf $CH_TMP_DIR

View File

@@ -7,7 +7,7 @@
CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="cloudhypervisor/dev"
CTR_IMAGE_VERSION="20220405-0"
CTR_IMAGE_VERSION="20220705-0"
CTR_IMAGE="${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}"
DOCKER_RUNTIME="docker"
@@ -226,6 +226,11 @@ cmd_build() {
} ;;
"--debug") { build="debug"; } ;;
"--release") { build="release"; } ;;
"--runtime")
shift
DOCKER_RUNTIME="$1"
export DOCKER_RUNTIME
;;
"--libc")
shift
[[ "$1" =~ ^(musl|gnu)$ ]] ||

View File

@@ -192,6 +192,15 @@ update_workloads() {
fi
popd
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v23.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64"
CH_RELEASE_NAME="cloud-hypervisor-static-aarch64"
pushd $WORKLOADS_DIR
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1
chmod +x $CH_RELEASE_NAME
popd
# Build custom kernel for guest VMs
build_custom_linux

View File

@@ -45,6 +45,15 @@ if [ $? -ne 0 ]; then
fi
popd
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v23.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static"
CH_RELEASE_NAME="cloud-hypervisor-static"
pushd $WORKLOADS_DIR
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1
chmod +x $CH_RELEASE_NAME
popd
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"

View File

@@ -113,6 +113,9 @@ if [ -n "$test_filter" ]; then
test_binary_args+=("--test-filter $test_filter")
fi
# Ensure that git commands can be run in this directory (for metrics report)
git config --global --add safe.directory $PWD
export RUST_BACKTRACE=1
time target/$BUILD_TARGET/release/performance-metrics ${test_binary_args[*]}
RES=$?

View File

@@ -11,6 +11,8 @@ cargo_args=("")
if [[ $hypervisor = "mshv" ]]; then
cargo_args+=("--no-default-features")
cargo_args+=("--features common,$hypervisor")
elif [[ $(uname -m) = "x86_64" ]]; then
cargo_args+=("--features tdx")
fi
if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then

View File

@@ -12,6 +12,7 @@ use api_client::Error as ApiClientError;
use clap::{Arg, ArgMatches, Command};
use option_parser::{ByteSized, ByteSizedParseError};
use std::fmt;
use std::io::Read;
use std::os::unix::net::UnixStream;
use std::process;
@@ -31,6 +32,8 @@ enum Error {
AddVdpaConfig(vmm::config::Error),
AddVsockConfig(vmm::config::Error),
Restore(vmm::config::Error),
ReadingStdin(std::io::Error),
ReadingFile(std::io::Error),
}
impl fmt::Display for Error {
@@ -51,6 +54,8 @@ impl fmt::Display for Error {
AddVdpaConfig(e) => write!(f, "Error parsing vDPA device syntax: {}", e),
AddVsockConfig(e) => write!(f, "Error parsing vsock syntax: {}", e),
Restore(e) => write!(f, "Error parsing restore syntax: {}", e),
ReadingStdin(e) => write!(f, "Error reading from stdin: {}", e),
ReadingFile(e) => write!(f, "Error reading from file: {}", e),
}
}
}
@@ -264,6 +269,20 @@ fn restore_api_command(socket: &mut UnixStream, config: &str) -> Result<(), Erro
.map_err(Error::ApiClient)
}
fn coredump_api_command(socket: &mut UnixStream, destination_url: &str) -> Result<(), Error> {
let coredump_config = vmm::api::VmCoredumpData {
destination_url: String::from(destination_url),
};
simple_api_command(
socket,
"PUT",
"coredump",
Some(&serde_json::to_string(&coredump_config).unwrap()),
)
.map_err(Error::ApiClient)
}
fn receive_migration_api_command(socket: &mut UnixStream, url: &str) -> Result<(), Error> {
let receive_migration_data = vmm::api::VmReceiveMigrationData {
receiver_url: url.to_owned(),
@@ -295,6 +314,19 @@ fn send_migration_api_command(
.map_err(Error::ApiClient)
}
fn create_api_command(socket: &mut UnixStream, path: &str) -> Result<(), Error> {
let mut data = String::default();
if path == "-" {
std::io::stdin()
.read_to_string(&mut data)
.map_err(Error::ReadingStdin)?;
} else {
data = std::fs::read_to_string(path).map_err(Error::ReadingFile)?;
}
simple_api_command(socket, "PUT", "create", Some(&data)).map_err(Error::ApiClient)
}
fn do_command(matches: &ArgMatches) -> Result<(), Error> {
let mut socket =
UnixStream::connect(matches.value_of("api-socket").unwrap()).map_err(Error::Connect)?;
@@ -422,6 +454,14 @@ fn do_command(matches: &ArgMatches) -> Result<(), Error> {
.value_of("restore_config")
.unwrap(),
),
Some("coredump") => coredump_api_command(
&mut socket,
matches
.subcommand_matches("coredump")
.unwrap()
.value_of("coredump_config")
.unwrap(),
),
Some("send-migration") => send_migration_api_command(
&mut socket,
matches
@@ -442,6 +482,14 @@ fn do_command(matches: &ArgMatches) -> Result<(), Error> {
.value_of("receive_migration_config")
.unwrap(),
),
Some("create") => create_api_command(
&mut socket,
matches
.subcommand_matches("create")
.unwrap()
.value_of("path")
.unwrap(),
),
Some(c) => simple_api_command(&mut socket, "PUT", c, None).map_err(Error::ApiClient),
None => unreachable!(),
}
@@ -576,6 +624,8 @@ fn main() {
),
)
.subcommand(Command::new("resume").about("Resume the VM"))
.subcommand(Command::new("boot").about("Boot a created VM"))
.subcommand(Command::new("delete").about("Delete a VM"))
.subcommand(Command::new("shutdown").about("Shutdown the VM"))
.subcommand(
Command::new("snapshot")
@@ -595,6 +645,11 @@ fn main() {
.help(vmm::config::RestoreConfig::SYNTAX),
),
)
.subcommand(
Command::new("coredump")
.about("Create a coredump from VM")
.arg(Arg::new("coredump_config").index(1).help("<file_path>")),
)
.subcommand(
Command::new("send-migration")
.about("Initiate a VM migration")
@@ -617,6 +672,11 @@ fn main() {
.index(1)
.help("<receiver_url>"),
),
)
.subcommand(
Command::new("create")
.about("Create VM from a JSON configuration")
.arg(Arg::new("path").index(1).default_value("-")),
);
let matches = app.get_matches();

View File

@@ -23,6 +23,7 @@ use thiserror::Error;
use vmm::config;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::signal::block_signal;
use vmm_sys_util::terminal::Terminal;
#[derive(Error, Debug)]
enum Error {
@@ -161,7 +162,7 @@ fn create_app<'a>(
Arg::new("platform")
.long("platform")
.help(
"num_pci_segments=<num pci segments>,iommu_segments=<list_of_segments>",
"num_pci_segments=<num pci segments>,iommu_segments=<list_of_segments>,serial_number=<(DMI) device serial number>",
)
.takes_value(true)
.group("vm-config"),
@@ -623,6 +624,13 @@ fn main() {
}
};
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
if on_tty {
// Don't forget to set the terminal in canonical mode
// before to exit.
std::io::stdin().lock().set_canon_mode().unwrap();
}
std::process::exit(exit_code);
}
@@ -1323,40 +1331,6 @@ mod unit_tests {
}"#,
false,
),
#[cfg(target_arch = "x86_64")]
(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem",
"file=/path/to/img/1,size=1G,mergeable=on",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "mergeable": true}
]
}"#,
true,
),
#[cfg(target_arch = "x86_64")]
(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem",
"file=/path/to/img/1,size=1G,mergeable=off",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "mergeable": false}
]
}"#,
true,
),
]
.iter()
.for_each(|(cli, openapi, equal)| {

View File

@@ -7,8 +7,8 @@ edition = "2021"
[dependencies]
dirs = "4.0.0"
epoll = "4.3.1"
lazy_static = "1.4.0"
libc = "0.2.123"
libc = "0.2.126"
once_cell = "1.13.0"
ssh2 = { version = "0.9.1", features = ["vendored-openssl"]}
vmm-sys-util = "0.9.0"
wait-timeout = "0.2.0"

View File

@@ -3,12 +3,11 @@
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use]
extern crate lazy_static;
use once_cell::sync::Lazy;
use ssh2::Session;
use std::env;
use std::ffi::OsStr;
use std::fmt::Debug;
use std::fs;
use std::io;
use std::io::{Read, Write};
@@ -51,7 +50,7 @@ pub struct GuestNetworkConfig {
pub const DEFAULT_TCP_LISTENER_MESSAGE: &str = "booted";
pub const DEFAULT_TCP_LISTENER_PORT: u16 = 8000;
pub const DEFAULT_TCP_LISTENER_TIMEOUT: i32 = 80;
pub const DEFAULT_TCP_LISTENER_TIMEOUT: i32 = 120;
#[derive(Debug)]
pub enum WaitForBootError {
@@ -721,9 +720,7 @@ pub fn exec_host_command_output(command: &str) -> Output {
pub const PIPE_SIZE: i32 = 32 << 20;
lazy_static! {
static ref NEXT_VM_ID: Mutex<u8> = Mutex::new(1);
}
static NEXT_VM_ID: Lazy<Mutex<u8>> = Lazy::new(|| Mutex::new(1));
pub struct Guest {
pub tmp_dir: TempDir,
@@ -831,30 +828,12 @@ impl Guest {
)
}
pub fn api_create_body(
&self,
cpu_count: u8,
_fw_path: &str,
_kernel_path: &str,
_kernel_cmd: &str,
) -> String {
#[cfg(all(target_arch = "x86_64", not(feature = "mshv")))]
format! {"{{\"cpus\":{{\"boot_vcpus\":{},\"max_vcpus\":{}}},\"kernel\":{{\"path\":\"{}\"}},\"cmdline\":{{\"args\": \"\"}},\"net\":[{{\"ip\":\"{}\", \"mask\":\"255.255.255.0\", \"mac\":\"{}\"}}], \"disks\":[{{\"path\":\"{}\"}}, {{\"path\":\"{}\"}}]}}",
cpu_count,
cpu_count,
_fw_path,
self.network.host_ip,
self.network.guest_mac,
self.disk_config.disk(DiskType::OperatingSystem).unwrap().as_str(),
self.disk_config.disk(DiskType::CloudInit).unwrap().as_str(),
}
#[cfg(any(target_arch = "aarch64", feature = "mshv"))]
pub fn api_create_body(&self, cpu_count: u8, kernel_path: &str, kernel_cmd: &str) -> String {
format! {"{{\"cpus\":{{\"boot_vcpus\":{},\"max_vcpus\":{}}},\"kernel\":{{\"path\":\"{}\"}},\"cmdline\":{{\"args\": \"{}\"}},\"net\":[{{\"ip\":\"{}\", \"mask\":\"255.255.255.0\", \"mac\":\"{}\"}}], \"disks\":[{{\"path\":\"{}\"}}, {{\"path\":\"{}\"}}]}}",
cpu_count,
cpu_count,
_kernel_path,
_kernel_cmd,
kernel_path,
kernel_cmd,
self.network.host_ip,
self.network.guest_mac,
self.disk_config.disk(DiskType::OperatingSystem).unwrap().as_str(),
@@ -984,13 +963,6 @@ impl Guest {
Ok(())
}
pub fn get_entropy(&self) -> Result<u32, Error> {
self.ssh_command("cat /proc/sys/kernel/random/entropy_avail")?
.trim()
.parse()
.map_err(Error::Parsing)
}
pub fn get_pci_bridge_class(&self) -> Result<String, Error> {
Ok(self
.ssh_command("cat /sys/bus/pci/devices/0000:00:00.0/class")?
@@ -1036,50 +1008,6 @@ impl Guest {
Ok(false)
}
pub fn valid_virtio_fs_cache_size(
&self,
dax: bool,
cache_size: Option<u64>,
) -> Result<bool, Error> {
// SHM region is called different things depending on kernel
let shm_region = self
.ssh_command("sudo grep 'virtio[0-9]\\|virtio-pci-shm' /proc/iomem || true")?
.trim()
.to_string();
if shm_region.is_empty() {
return Ok(!dax);
}
// From this point, the region is not empty, hence it is an error
// if DAX is off.
if !dax {
return Ok(false);
}
let cache = if let Some(cache) = cache_size {
cache
} else {
// 8Gib by default
0x0002_0000_0000
};
let args: Vec<&str> = shm_region.split(':').collect();
if args.is_empty() {
return Ok(false);
}
let args: Vec<&str> = args[0].trim().split('-').collect();
if args.len() != 2 {
return Ok(false);
}
let start_addr = u64::from_str_radix(args[0], 16).map_err(Error::Parsing)?;
let end_addr = u64::from_str_radix(args[1], 16).map_err(Error::Parsing)?;
Ok(cache == (end_addr - start_addr + 1))
}
pub fn check_vsock(&self, socket: &str) {
// Listen from guest on vsock CID=3 PORT=16
// SOCKET-LISTEN:<domain>:<protocol>:<local-address>
@@ -1159,7 +1087,12 @@ impl Guest {
.unwrap();
}
pub fn check_devices_common(&self, socket: Option<&String>, console_text: Option<&String>) {
pub fn check_devices_common(
&self,
socket: Option<&String>,
console_text: Option<&String>,
pmem_path: Option<&String>,
) {
// Check block devices are readable
self.ssh_command("sudo dd if=/dev/vda of=/dev/null bs=1M iflag=direct count=1024")
.unwrap();
@@ -1178,6 +1111,63 @@ impl Guest {
self.ssh_command(&console_cmd).unwrap();
}
// The net device is 'automatically' exercised through the above 'ssh' commands
// Check if the pmem device is usable
if let Some(pmem_path) = pmem_path {
assert_eq!(
self.ssh_command(&format!("ls {}", pmem_path))
.unwrap()
.trim(),
pmem_path
);
assert_eq!(
self.ssh_command(&format!("sudo mount {} /mnt", pmem_path))
.unwrap(),
""
);
assert_eq!(self.ssh_command("ls /mnt").unwrap(), "lost+found\n");
self.ssh_command("echo test123 | sudo tee /mnt/test")
.unwrap();
assert_eq!(self.ssh_command("sudo umount /mnt").unwrap(), "");
assert_eq!(self.ssh_command("ls /mnt").unwrap(), "");
assert_eq!(
self.ssh_command(&format!("sudo mount {} /mnt", pmem_path))
.unwrap(),
""
);
assert_eq!(
self.ssh_command("sudo cat /mnt/test || true")
.unwrap()
.trim(),
"test123"
);
self.ssh_command("sudo rm /mnt/test").unwrap();
assert_eq!(self.ssh_command("sudo umount /mnt").unwrap(), "");
}
}
}
pub enum VerbosityLevel {
Warn,
Info,
Debug,
}
impl Default for VerbosityLevel {
fn default() -> Self {
Self::Warn
}
}
impl ToString for VerbosityLevel {
fn to_string(&self) -> String {
use VerbosityLevel::*;
match self {
Warn => "".to_string(),
Info => "-v".to_string(),
Debug => "-vv".to_string(),
}
}
}
@@ -1186,22 +1176,29 @@ pub struct GuestCommand<'a> {
guest: &'a Guest,
capture_output: bool,
print_cmd: bool,
verbosity: VerbosityLevel,
}
impl<'a> GuestCommand<'a> {
pub fn new(guest: &'a Guest) -> Self {
Self::new_with_binary_name(guest, "cloud-hypervisor")
Self::new_with_binary_path(guest, &clh_command("cloud-hypervisor"))
}
pub fn new_with_binary_name(guest: &'a Guest, binary_name: &str) -> Self {
pub fn new_with_binary_path(guest: &'a Guest, binary_path: &str) -> Self {
Self {
command: Command::new(clh_command(binary_name)),
command: Command::new(binary_path),
guest,
capture_output: false,
print_cmd: true,
verbosity: VerbosityLevel::Info,
}
}
pub fn verbosity(&mut self, verbosity: VerbosityLevel) -> &mut Self {
self.verbosity = verbosity;
self
}
pub fn capture_output(&mut self) -> &mut Self {
self.capture_output = true;
self
@@ -1213,6 +1210,17 @@ impl<'a> GuestCommand<'a> {
}
pub fn spawn(&mut self) -> io::Result<Child> {
use VerbosityLevel::*;
match &self.verbosity {
Warn => {}
Info => {
self.command.arg("-v");
}
Debug => {
self.command.arg("-vv");
}
};
if self.print_cmd {
println!(
"\n\n==== Start cloud-hypervisor command-line ====\n\n\
@@ -1225,7 +1233,6 @@ impl<'a> GuestCommand<'a> {
if self.capture_output {
let child = self
.command
.arg("-v")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
@@ -1245,7 +1252,7 @@ impl<'a> GuestCommand<'a> {
))
}
} else {
self.command.arg("-v").spawn()
self.command.spawn()
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,14 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
anyhow = "1.0.56"
libc = "0.2.123"
log = "0.4.16"
anyhow = "1.0.58"
libc = "0.2.126"
log = "0.4.17"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
thiserror = "1.0.30"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic"] }
thiserror = "1.0.31"
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = ">=0.3.1"
[dependencies.vfio-bindings]

View File

@@ -4,7 +4,9 @@
//
use std::ffi::CString;
use std::fs::File;
use std::io::{IoSlice, Read, Write};
use std::mem::size_of;
use std::num::Wrapping;
use std::os::unix::net::UnixStream;
use std::os::unix::prelude::RawFd;
@@ -49,7 +51,7 @@ impl Default for Command {
#[allow(dead_code)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum HeaderFlags {
Command = 0,
Reply = 1,
@@ -234,6 +236,7 @@ pub struct Region {
pub index: u32,
pub size: u64,
pub file_offset: Option<FileOffset>,
pub sparse_areas: Vec<vfio_region_sparse_mmap_area>,
}
#[derive(Debug)]
@@ -294,7 +297,7 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::Version,
flags: HeaderFlags::Command as u32,
message_size: (std::mem::size_of::<Version>() + version_data.len() + 1) as u32,
message_size: (size_of::<Version>() + version_data.len() + 1) as u32,
..Default::default()
},
major: 0,
@@ -330,7 +333,7 @@ impl Client {
let mut server_version_data = Vec::new();
server_version_data.resize(
server_version.header.message_size as usize - std::mem::size_of::<Version>(),
server_version.header.message_size as usize - size_of::<Version>(),
0,
);
self.stream
@@ -361,10 +364,10 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::DmaMap,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DmaMap>() as u32,
message_size: size_of::<DmaMap>() as u32,
..Default::default()
},
argsz: (std::mem::size_of::<DmaMap>() - std::mem::size_of::<Header>()) as u32,
argsz: (size_of::<DmaMap>() - size_of::<Header>()) as u32,
flags: DmaMapFlags::ReadWrite,
offset,
address,
@@ -391,10 +394,10 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::DmaUnmap,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DmaUnmap>() as u32,
message_size: size_of::<DmaUnmap>() as u32,
..Default::default()
},
argsz: (std::mem::size_of::<DmaUnmap>() - std::mem::size_of::<Header>()) as u32,
argsz: (size_of::<DmaUnmap>() - size_of::<Header>()) as u32,
flags: 0,
address,
size,
@@ -420,7 +423,7 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::DeviceReset,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DeviceReset>() as u32,
message_size: size_of::<DeviceReset>() as u32,
..Default::default()
},
};
@@ -445,10 +448,10 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::DeviceGetInfo,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DeviceGetInfo>() as u32,
message_size: size_of::<DeviceGetInfo>() as u32,
..Default::default()
},
argsz: std::mem::size_of::<DeviceGetInfo>() as u32,
argsz: size_of::<DeviceGetInfo>() as u32,
..Default::default()
};
debug!("Command: {:?}", get_info);
@@ -474,20 +477,62 @@ impl Client {
let num_regions = reply.num_regions;
let mut regions = Vec::new();
for index in 0..num_regions {
let get_region_info = DeviceGetRegionInfo {
header: Header {
message_id: self.next_message_id.0,
command: Command::DeviceGetRegionInfo,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DeviceGetRegionInfo>() as u32,
..Default::default()
},
region_info: vfio_region_info {
argsz: 1024, // Arbitrary max size
index,
..Default::default()
},
};
let (region_info, fd, sparse_areas) = self.get_region_info(index)?;
regions.push(Region {
flags: region_info.flags,
index: region_info.index,
size: region_info.size,
file_offset: fd.map(|fd| FileOffset::new(fd, region_info.offset)),
sparse_areas,
});
}
Ok(regions)
}
fn get_region_info(
&mut self,
index: u32,
) -> Result<
(
vfio_region_info,
Option<File>,
Vec<vfio_region_sparse_mmap_area>,
),
Error,
> {
// Retrieve the region info without capability
let mut get_region_info = DeviceGetRegionInfo {
header: Header {
message_id: self.next_message_id.0,
command: Command::DeviceGetRegionInfo,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<DeviceGetRegionInfo>() as u32,
..Default::default()
},
region_info: vfio_region_info {
argsz: size_of::<vfio_region_info>() as u32,
index,
..Default::default()
},
};
debug!("Command: {:?}", get_region_info);
self.next_message_id += Wrapping(1);
self.stream
.write_all(get_region_info.as_slice())
.map_err(Error::StreamWrite)?;
let mut reply = DeviceGetRegionInfo::default();
let (_, fd) = self
.stream
.recv_with_fd(reply.as_mut_slice())
.map_err(Error::ReceiveWithFd)?;
debug!("Reply: {:?}", reply);
// Retrieve the region info again with capabilities if needed
if reply.region_info.argsz > std::mem::size_of::<vfio_region_info>() as u32 {
get_region_info.region_info.argsz = reply.region_info.argsz;
debug!("Command: {:?}", get_region_info);
self.next_message_id += Wrapping(1);
@@ -502,24 +547,94 @@ impl Client {
.map_err(Error::ReceiveWithFd)?;
debug!("Reply: {:?}", reply);
regions.push(Region {
flags: reply.region_info.flags,
index: reply.region_info.index,
size: reply.region_info.size,
file_offset: fd.map(|fd| FileOffset::new(fd, reply.region_info.offset)),
});
// TODO: Handle region with capabilities
let mut _cap_data = Vec::with_capacity(
reply.header.message_size as usize - std::mem::size_of::<DeviceGetRegionInfo>(),
let cap_size = reply.region_info.argsz - std::mem::size_of::<vfio_region_info>() as u32;
assert_eq!(
cap_size,
reply.header.message_size - size_of::<DeviceGetRegionInfo>() as u32
);
_cap_data.resize(_cap_data.capacity(), 0u8);
let mut cap_data = Vec::with_capacity(cap_size as usize);
cap_data.resize(cap_data.capacity(), 0u8);
self.stream
.read_exact(_cap_data.as_mut_slice())
.read_exact(cap_data.as_mut_slice())
.map_err(Error::StreamRead)?;
let sparse_areas = Self::parse_region_caps(&cap_data, &reply.region_info)?;
Ok((reply.region_info, fd, sparse_areas))
} else {
Ok((reply.region_info, fd, Vec::new()))
}
}
fn parse_region_caps(
cap_data: &[u8],
region_info: &vfio_region_info,
) -> Result<Vec<vfio_region_sparse_mmap_area>, Error> {
let mut sparse_areas: Vec<vfio_region_sparse_mmap_area> = Vec::new();
let cap_size = cap_data.len() as u32;
let cap_header_size = size_of::<vfio_info_cap_header>() as u32;
let mmap_cap_size = size_of::<vfio_region_info_cap_sparse_mmap>() as u32;
let mmap_area_size = size_of::<vfio_region_sparse_mmap_area>() as u32;
let cap_data_ptr = cap_data.as_ptr() as *const u8;
let mut region_info_offset = region_info.cap_offset;
while region_info_offset != 0 {
// calculate the offset from the begining of the cap_data based on the offset
// that is relative to the begining of the VFIO region info structure
let cap_offset = region_info_offset - size_of::<vfio_region_info>() as u32;
if cap_offset + cap_header_size > cap_size {
warn!(
"Unexpected end of cap data: 'cap_offset + cap_header_size > cap_size' \
cap_offset = {}, cap_header_size = {}, cap_size = {}",
cap_offset, cap_header_size, cap_size
);
break;
}
// Safe because the `cap_data_ptr` is valid and the `cap_offset` is checked above
let cap_ptr = unsafe { cap_data_ptr.offset(cap_offset as isize) };
let cap_header = unsafe { &*(cap_ptr as *const vfio_info_cap_header) };
match cap_header.id as u32 {
VFIO_REGION_INFO_CAP_SPARSE_MMAP => {
if cap_offset + mmap_cap_size > cap_size {
warn!(
"Unexpected end of cap data: 'cap_offset + mmap_cap_size > cap_size' \
cap_offset = {}, mmap_cap_size = {}, cap_size = {}",
cap_offset, mmap_cap_size, cap_size
);
break;
}
// Safe because the `cap_ptr` is valid and its size is also checked above
let sparse_mmap = unsafe {
&*(cap_ptr as *mut u8 as *const vfio_region_info_cap_sparse_mmap)
};
let area_num = sparse_mmap.nr_areas;
if cap_offset + mmap_cap_size + area_num * mmap_area_size > cap_size {
warn!("Unexpected end of cap data: 'cap_offset + mmap_cap_size + area_num * mmap_area_size > cap_size' \
cap_offset = {}, mmap_cap_size = {}, area_num = {}, mmap_area_size = {}, cap_size = {}",
cap_offset, mmap_cap_size, area_num, mmap_area_size, cap_size);
break;
}
// Safe because the `sparse_mmap` is valid and its size is also checked above
let areas =
unsafe { sparse_mmap.areas.as_slice(sparse_mmap.nr_areas as usize) };
for area in areas.iter() {
sparse_areas.push(*area);
}
}
_ => {
warn!(
"Ignoring unsupported vfio region capability (id = '{}')",
cap_header.id
);
}
}
region_info_offset = cap_header.next;
}
Ok(regions)
Ok(sparse_areas)
}
pub fn region_read(&mut self, region: u32, offset: u64, data: &mut [u8]) -> Result<(), Error> {
@@ -528,7 +643,7 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::RegionRead,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<RegionAccess>() as u32,
message_size: size_of::<RegionAccess>() as u32,
..Default::default()
},
offset,
@@ -556,7 +671,7 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::RegionWrite,
flags: HeaderFlags::Command as u32,
message_size: (std::mem::size_of::<RegionAccess>() + data.len()) as u32,
message_size: (size_of::<RegionAccess>() + data.len()) as u32,
..Default::default()
},
offset,
@@ -588,10 +703,10 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::GetIrqInfo,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<GetIrqInfo>() as u32,
message_size: size_of::<GetIrqInfo>() as u32,
..Default::default()
},
argsz: (std::mem::size_of::<GetIrqInfo>() - std::mem::size_of::<Header>()) as u32,
argsz: (size_of::<GetIrqInfo>() - size_of::<Header>()) as u32,
flags: 0,
index,
count: 0,
@@ -629,10 +744,10 @@ impl Client {
message_id: self.next_message_id.0,
command: Command::SetIrqs,
flags: HeaderFlags::Command as u32,
message_size: std::mem::size_of::<SetIrqs>() as u32,
message_size: size_of::<SetIrqs>() as u32,
..Default::default()
},
argsz: (std::mem::size_of::<SetIrqs>() - std::mem::size_of::<Header>()) as u32,
argsz: (size_of::<SetIrqs>() - size_of::<Header>()) as u32,
flags,
start,
index,

View File

@@ -8,9 +8,9 @@ license = "Apache-2.0"
[dependencies]
byteorder = "1.4.3"
crc32c = "0.6.3"
libc = "0.2.123"
log = "0.4.16"
remain = "0.2.2"
libc = "0.2.126"
log = "0.4.17"
remain = "0.2.3"
thiserror = "1.0"
uuid = { version = "0.8.2", features = ["v4"] }
uuid = { version = "1.1.2", features = ["v4"] }
vmm-sys-util = ">=0.3.1"

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