Compare commits

..

217 Commits
v22.0 ... v23.1

Author SHA1 Message Date
Rob Bradford
479fef1b8e build: Release v23.1 (bug fix release)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Bo Chen
fc8f867879 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>
(cherry picked from commit 42c19e14c5)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Sebastien Boeuf
e2eb59bcc8 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>
(cherry picked from commit a5a2e591c9)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
LiHui
1e557fdb3c 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>
(cherry picked from commit ec0c1b01c4)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
10ce348aa6 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>
(cherry picked from commit 4fed2d4ed7)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
63130d0f92 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>
(cherry picked from commit 4a04d1f8f2)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
e6cc364703 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>
(cherry picked from commit c274ce4d49)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Fabiano Fidêncio
a861918f06 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>
(cherry picked from commit a87d1bbaa1)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
0c9c56f5a6 build: Release v23.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-14 09:21:00 +01:00
Rob Bradford
cd2b167b33 .github: Use correct toolchain version for release builds
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-13 10:21:05 -07:00
Rob Bradford
a63d526423 .github: Test building of tests on each commit
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-13 13:54:06 +01:00
Rob Bradford
735457f0e1 .github: Run clippy checks over tests on aarch64
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-13 13:54:06 +01:00
Rob Bradford
719c9b8233 tests: Fix aarch64 clippy issues in integration tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-13 13:54:06 +01:00
dependabot[bot]
4338486c6f build: bump crc32c from 0.6.1 to 0.6.3
Bumps [crc32c](https://github.com/zowens/crc32c) from 0.6.1 to 0.6.3.
- [Release notes](https://github.com/zowens/crc32c/releases)
- [Commits](https://github.com/zowens/crc32c/compare/v0.6.1...v0.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-13 11:58:53 +01:00
dependabot[bot]
a784d9a649 build: bump crc32c from 0.6.1 to 0.6.3 in /fuzz
Bumps [crc32c](https://github.com/zowens/crc32c) from 0.6.1 to 0.6.3.
- [Release notes](https://github.com/zowens/crc32c/releases)
- [Commits](https://github.com/zowens/crc32c/compare/v0.6.1...v0.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-13 11:04:19 +01:00
dependabot[bot]
ee3f9ef334 build: bump libc from 0.2.122 to 0.2.123 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.122 to 0.2.123.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.122...0.2.123)

---
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-13 10:13:41 +01:00
dependabot[bot]
f8201bc151 build: bump libc from 0.2.122 to 0.2.123
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.122 to 0.2.123.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.122...0.2.123)

---
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-13 10:13:32 +01:00
Rob Bradford
b212f2823d vmm: Deprecate mergeable option from virtio-pmem
KSM would never merge the file backed pages so this option has no
effect.

See: #3968

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-12 07:12:25 -07:00
dependabot[bot]
6bf6d95c55 build: bump quote from 1.0.17 to 1.0.18 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.17...1.0.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-12 00:21:16 +00:00
dependabot[bot]
e591385a67 build: bump quote from 1.0.17 to 1.0.18
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.17...1.0.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 23:51:19 +00:00
Rob Bradford
ed87e42e6f vm-device, pci, devices: Remove InterruptSourceGroup::{un}mask
The calls to these functions are always preceded by a call to
InterruptSourceGroup::update(). By adding a masked boolean to that
function call it possible to remove 50% of the calls to the
KVM_SET_GSI_ROUTING ioctl as the the update will correctly handle the
masked or unmasked case.

This causes the ioctl to disappear from the perf report for a boot of
the VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-11 22:56:48 +01:00
Rob Bradford
6a099257e8 .github: Fix Rust version for release to 1.58
Unfortunately Rust 1.59 produces binaries that segfault when compiled
with musl-gcc wrappers. Which is exactly how we produce out aarch64 and
musl binaries for the release.

See: https://github.com/rust-lang/rust/issues/95926

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-11 22:53:34 +01:00
Bo Chen
85c068f769 vhost_user_block/net: Fix build from the target folder
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-11 22:52:47 +01:00
Wei Liu
65716f1376 build: fix performance-metrics build
It suffered from the same issue like the main program after switching to
Rust 2021 edition, but the issue was not caught by the CI.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-04-11 16:33:08 +01:00
Michael Zhao
d1b2a3fca9 aarch64: Add a memory-simulated flash for UEFI
EDK2 execution requires a flash device at address 0.

The new added device is not a fully functional flash. It doesn't
implement any spec of a flash device. Instead, a piece of memory is used
to simulate the flash simply.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-11 09:51:34 +01:00
Michael Zhao
9dd107bb03 tests: Revert the impact for the hidden 4MiB RAM
We modified a test case to workaround the RAM calculation error caused
by hidding 4MiB memory for UEFI. Now change it back to normal.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-11 09:51:34 +01:00
Michael Zhao
6e562eb1e7 aarch64: Return the hidden RAM for UEFI
Size of `memory` node in FDT was reduced by 4MiB. Now it is returned.
In memory regions, a `Ram` region of 4MiB was created at address 0. Now
it is removed.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-11 09:51:34 +01:00
Wei Liu
7d7bfb2034 build: migrate to Rust 2021 edition
Rust 2021 edition has a few improvements over the 2018 edition. Migrate
the project to 2021 edition by following recommended migration steps.
Luckily, the code itself doesn't require fixing.

Bump MSRV to 1.56 as it is required by the 2021 edition. Also fix the
clap build dependency to make Cloud Hypervisor build again.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-04-11 09:51:12 +01:00
Michael Zhao
298a5580a9 aarch64: Remove unnecessary function definitions
This is a refactoring commit to simplify source code.
Removed some functions that only return a layout const.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-08 11:08:43 -07:00
Michael Zhao
656425a328 aarch64: Align the data types in layout
Some addresses defined in `layout.rs` were of type `GuestAddress`, and
are `u64`. Now align the types of all the `*_START` definitions to
`GuestAddress`.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-08 11:08:43 -07:00
dependabot[bot]
d10bfd5aa4 build: bump mshv-ioctls from ef7d561 to 75cf309
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `ef7d561` to `75cf309`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](ef7d56169c...75cf309d56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-08 00:07:30 +00:00
dependabot[bot]
4e0f89359b build: bump syn from 1.0.90 to 1.0.91 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.90 to 1.0.91.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.90...1.0.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-07 09:23:47 +00:00
dependabot[bot]
6ea7dc21eb build: bump libc from 0.2.121 to 0.2.122 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.121 to 0.2.122.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.121...0.2.122)

---
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-07 08:42:50 +00:00
dependabot[bot]
b75b3db232 build: bump proc-macro2 from 1.0.36 to 1.0.37 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.36...1.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-07 01:22:30 +00:00
dependabot[bot]
fe87812b34 build: bump libc from 0.2.121 to 0.2.122
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.121 to 0.2.122.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.121...0.2.122)

---
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-07 01:12:12 +00:00
dependabot[bot]
9d0987ed97 build: bump syn from 1.0.90 to 1.0.91
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.90 to 1.0.91.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.90...1.0.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-07 00:22:39 +00:00
dependabot[bot]
48f1a8ef38 build: bump proc-macro2 from 1.0.36 to 1.0.37
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.36...1.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-06 23:41:07 +00:00
Sebastien Boeuf
bf7daa8ade tests: Disable aarch64_acpi::test_virtio_iommu
Now that address translations performed by virtio-iommu can error out if
the address can't be translated, we uncovered an issue in integration
test aarch64_acpi::test_virtio_iommu.

We disable the test until we can investigate and fix the root cause.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-06 11:21:46 +02:00
Sebastien Boeuf
26006974e8 virtio-devices: iommu: Error out if couldn't translate address
It doesn't matter if we're trying to translate a GVA or a GPA address,
but in both cases we must error out if the address couldn't be
translated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-06 11:21:46 +02:00
Rob Bradford
76b1a009e4 README: Update OS list and clarify release stability
Remove EOLed distributions and clarify the stability guarantees and what
the experimental features are.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-04-05 20:35:33 +01:00
Bo Chen
044b57c927 scripts: Bump container version and SPDK version for aarch64
In this way, CI jobs on both `x86_64` and `aarch64` will start to use
the latest version of SPDK.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-05 13:04:12 +01:00
Bo Chen
0ad3d5196f Dockerfile: Update to build the latest upstream SPDK
The latest upstream SPDK contains the live-migration support for the
NVMe backend.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-04-05 13:04:12 +01:00
Michael Zhao
261e39d8ab tests: Improve test_live_migration_numa
Set various initial memory node sizes in test case
`test_live_migration_numa`.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
9069cc889f aarch64: Update NUMA node in FDT for memory hole
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
96ed1327f8 aarch64: Update FDT for the new memory layout
If the RAM is across the hole, 2 `memory` nodes are needed in FDT.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
d60d6713fa aarch64: Unit test for new memory layout
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
848d88c122 aarch64: Reserve a hole in 32-bit space
The reserved space is for devices.
Some devices (like TPM) require arbitrary addresses close to 4GiB.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
a3dbc3b415 aarch64: Change RAM_START type GuestAddress
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
Michael Zhao
ef9f37cd5f aarch64: Rename RAM_64BIT_START in layout
`RAM_64BIT_START` was set to 1 GiB, not a real 64-bit address. Now
rename it `RAM_START` to avoid confusion.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-04-05 11:04:52 +08:00
dependabot[bot]
c035e5a836 build: bump mshv-bindings from d241ffc to ef7d561
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `d241ffc` to `ef7d561`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](d241ffcacd...ef7d56169c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 23:39:24 +00:00
Sebastien Boeuf
a2acc02f50 tests: Update test_vdpa_block to include vIOMMU testing
The extra vDPA device in the test is hotplugged behind the vIOMMU, which
covers the use case of placing a vDPA device behind a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
590361aeb6 virtio-devices: Translate queue addresses back to GVA if needed
Whenever a virtio device is placed behind a vIOMMU, we have some code in
pci_common_config.rs to translate the queue addresses (descriptor table,
available ring and used ring) from GVA to GPA, so that they can be used
correctly.

But in case of vDPA, we also need to provide the queue addresses to the
vhost backend. And since the vhost backend deals with consistent IOVAs,
all addresses being provided should be GVAs if the device is placed
being a vIOMMU. For that reason, we perform a translation of the queue
addresses back from GPA to GVA if necessary, and only to be provided to
the vhost backend.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
b3d7ad0b91 virtio-devices: vdpa: Add extra debug!() logs
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
e76a5969e8 vmm: Add iommu parameter to VdpaConfig
Add a new iommu parameter to VdpaConfig in order to place the vDPA
device behind a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
e9b1ad9558 virtio-devices: iommu: Fix list of external mappings
In case an external mapping would have been added after the virtio-iommu
device has been activated, it would have simply be ignored because the
code wasn't using a shared object between the vmm thread and the iommu
thread. This behavior is only triggered on the hotplug codepath, and
only if the hotplugged device is placed behind the virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
1cdf8b232d virtio-devices: Introduce new function translating GPAs into GVAs
In anticipation for the vDPA need to translate a GPA back into a GVA, we
extend the existing trait DmaRemapping and AccessPlatform to perform
such operation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
059e787cb5 virtio-devices: Rename address translation function for more clarity
Renaming translate() to translate_gva() to clarify we want to translate
a GVA address into a GPA.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
dependabot[bot]
16c525b2c0 build: bump clap from 3.1.7 to 3.1.8
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.7 to 3.1.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.1.7...v3.1.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-04-02 00:04:16 +00:00
dependabot[bot]
cd599c9e64 build: bump clap from 3.1.7 to 3.1.8 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.7 to 3.1.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.1.7...v3.1.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-01 23:35:45 +00:00
Sebastien Boeuf
2963e5c954 docs: Update TDX documentation
According to latest official images based on latest TDX guest kernel, we
update the documentation to reflect the change regarding serial support.

New guest kernels have been updated to disable usage of serial ports,
meaning adding console=ttyS0 to the kernel boot parameters will have no
effect.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-01 18:24:32 +01:00
Sebastien Boeuf
00ce8277aa vmm: tdx: Fix the logic for generating HOB memory resources
The list of memory resources provided through the HOB wasn't accurate
because of the broken logic. The fix provides correct ranges to the
firmware.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-01 18:24:32 +01:00
Sebastien Boeuf
70222ffc1a vmm: tdx: Only report TempMem as reserved memory
Based on latest QEMU patches from branch tdx-qemu-2022.03.29-v7.0.0-rc1
we should only report as memory resources the TempMem sections from TDVF
sections.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-01 18:24:32 +01:00
Sebastien Boeuf
dae77d8d43 arch: x86_64: tdx: Update EFI HOB attribute
Based on latest QEMU patches from branch tdx-qemu-2022.03.29-v7.0.0-rc1
we don't need EFI_RESOURCE_ATTRIBUTE_ENCRYPTED as part of the attributes
we must enable with EFI_RESOURCE_SYSTEM_MEMORY and
EFI_RESOURCE_MEMORY_RESERVED resource types.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-01 18:24:32 +01:00
dependabot[bot]
a575fd70ec build: bump clap from 3.1.6 to 3.1.7
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.6 to 3.1.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.1.6...v3.1.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-04-01 13:52:38 +00:00
dependabot[bot]
28b56521f5 build: bump pkg-config from 0.3.24 to 0.3.25
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.24 to 0.3.25.
- [Release notes](https://github.com/rust-lang/pkg-config-rs/releases)
- [Changelog](https://github.com/rust-lang/pkg-config-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/pkg-config-rs/compare/0.3.24...0.3.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-01 13:18:40 +00:00
dependabot[bot]
11d0e7aaf1 build: bump clap from 3.1.6 to 3.1.7 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.6 to 3.1.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.1.6...v3.1.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-01 13:59:28 +01:00
Rob Bradford
7fd76eff05 vmm: Don't error if live resizing is not possible
The introduction of a error if live resizing is not possible is a
regression compared to the original behaviour where the new size would
be stored in the config and reflected in the next boot. This behaviour
was also inconsistent with the effect of resizing with no VM booted.

Instead of generating an error allow the code to go ahead and update the
config so that the new size will be available upon the reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-31 17:04:53 +01:00
Bo Chen
4af04d8f49 tests: Enable 'test_vfio_user' using Jammy on 'aarch64'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
eed2a0d06b vmm: Add 'libc::SYS_shutdown' to vmm 'seccomp' filter list
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
d49363a5af tests: Enable guest console log for test_vfio_user
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
0e2cb9fd06 tests: Move to use Jammy guest image for test_vfio_user
Fixes: #3495

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
661e5eb084 scripts: Use the same spdk version from dev container for aarch64
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
cec035c6e0 tests: Increase timeout after vfio-user device hotplug
As reported by the periodic CI runs, it may take more time for the NVMe
device to present in the guest after being hotplugged as a VFIO user
device on `aarch64` (especially under high load). Let's increase the
timeout after device hotplug from `1s` to `10s` to increase the test
stability.

Fixes: #3495

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
Bo Chen
3679be3721 tests: Enable hugepages for test_vfio_user
This is will fix a warning reported from the SPDK/NVMe backend when the
memory address is not 2M aligned.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-31 09:22:07 +01:00
dependabot[bot]
67727deb0a build: bump redox_syscall from 0.2.12 to 0.2.13
Bumps redox_syscall from 0.2.12 to 0.2.13.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-31 00:50:41 +00:00
dependabot[bot]
caa15c5c02 build: bump lock_api from 0.4.6 to 0.4.7
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.4.6 to 0.4.7.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.6...lock_api-0.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-31 00:23:33 +00:00
dependabot[bot]
d1312c3143 build: bump redox_users from 0.4.2 to 0.4.3
Bumps redox_users from 0.4.2 to 0.4.3.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-30 23:44:27 +00:00
Fabiano Fidêncio
f049867cd9 vmm,memory_manager: Deny resizing only if the ram amount has changed
Similarly to the previous commit restricting the cpu resizing error only
to the situations where the vcpu amount has changed, let's do the same
with the memory and be consistent throughout our code base.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-03-30 21:29:08 +01:00
Fabiano Fidêncio
2c8045343c vmm,cpu: Deny resizing only if the vcpu amount has changed
188078467d made clear that resize should
only happen when dealing with a "dynamic" CpuManager.  Although this is
very much correct, it causes a regression on Kata Containers (and on any
other consumer of Cloud Hypervisor) in cases where a resize would be
triggered but the vCPUs values wouldn't be changed.

There's no doubt Kata Containers could do better and do not call a
resize in such situations, and that's something that should **also** be
solved there.  However, we should also work this around on Cloud
Hypervisor side as it introduces a regression with the current Kata
Containers code.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-03-30 21:29:08 +01:00
Sebastien Boeuf
db06c31305 arch: x86_64: Patch CPUID based on TDX capabilities
Based on the XFAM masks retrieved from the TDX capabilities, the CPUID
must be patched.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-30 14:57:23 +01:00
Sebastien Boeuf
b0077f0b5e hypervisor: Implement retrieval of TDX capabilities
Extend the Hypervisor API in order to retrieve the TDX capabilities from
the underlying hypervisor.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-30 14:57:23 +01:00
Sebastien Boeuf
f310dc0916 hypervisor: Don't enable TDX debug
This might not be correctly supported, therefore best to keep it
disabled by default.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-30 14:57:23 +01:00
Sebastien Boeuf
3c973fa7ce virtio-devices: vhost-user: Add support for TDX
By enabling the VIRTIO feature VIRTIO_F_IOMMU_PLATFORM for all
vhost-user devices when needed, we force the guest to use the DMA API,
making these devices compatible with TDX. By using DMA API, the guest
triggers the TDX codepath to share some of the guest memory, in
particular the virtqueues and associated buffers so that the VMM and
vhost-user backends/processes can access this memory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-30 10:32:23 +02:00
dependabot[bot]
d310abed44 build: bump indexmap from 1.8.0 to 1.8.1
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.rst)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.0...1.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-30 00:32:21 +00:00
dependabot[bot]
a9b9251756 build: bump indexmap from 1.8.0 to 1.8.1 in /fuzz
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.rst)
- [Commits](https://github.com/bluss/indexmap/compare/1.8.0...1.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 23:46:58 +00:00
Rob Bradford
c66be2e974 tests: Split test_simple_launch() into separate tests
This will make it much easier identify which tests are failing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-29 15:20:58 +01:00
Rob Bradford
ca68b9e7a9 build: Remove "cmos" feature gate
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-29 15:20:58 +01:00
Rob Bradford
e0d3efec6e devices: cmos: Implement CMOS based reset
If EFI reset fails on the Linux kernel then it will fallthrough to CMOS
reset. Implement this as one of our reset solutions.

Fixes: #3912

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-29 15:20:58 +01:00
dependabot[bot]
4529bd8d0e build: bump semver from 1.0.6 to 1.0.7
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.6...1.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 10:20:55 +00:00
dependabot[bot]
b8d0fee17f build: bump syn from 1.0.89 to 1.0.90
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.89 to 1.0.90.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.89...1.0.90)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 09:41:42 +00:00
dependabot[bot]
43179bb44e build: bump getrandom from 0.2.5 to 0.2.6
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.5 to 0.2.6.
- [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.5...v0.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 00:33:44 +00:00
dependabot[bot]
fa8af3421a build: bump paste from 1.0.6 to 1.0.7
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.6...1.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 23:43:10 +00:00
dependabot[bot]
ac9335d111 build: bump syn from 1.0.89 to 1.0.90 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.89 to 1.0.90.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.89...1.0.90)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 23:35:31 +00:00
Rob Bradford
7c0cf8cc23 arch, devices, vmm: Remove "acpi" feature gate
Compile this feature in by default as it's well supported on both
aarch64 and x86_64 and we only officially support using it (no non-acpi
binaries are available.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-28 09:18:29 -07:00
Rob Bradford
fa7487629f scripts: Fix feature build for aarch64 and mshv builds
These were erroneously skipping features for the unit tests and the
"build" target for dev_cli.sh

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-28 09:18:29 -07:00
Rob Bradford
6eb47bdb03 scripts: Remove unused "cargo" testing script
These are never run by the CI and is inconsistent with the way we build
test which is specified inside the .github workflows.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-28 09:18:29 -07:00
Rob Bradford
3c9e97ce00 .github: Add build testing of "gdb" build feature
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-28 09:18:29 -07:00
Rob Bradford
a9fdaa6734 .github: Simplify feature testing in workflows
This includes the removal of testing without the "acpi" feature. The
command have been reordered to reduce the amount of recompilation
required.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-28 09:18:29 -07:00
dependabot[bot]
41e8f1db73 build: bump getrandom from 0.2.5 to 0.2.6 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.5 to 0.2.6.
- [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.5...v0.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 13:51:35 +00:00
dependabot[bot]
b08d0b5551 build: bump paste from 1.0.6 to 1.0.7 in /fuzz
Bumps [paste](https://github.com/dtolnay/paste) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/paste/releases)
- [Commits](https://github.com/dtolnay/paste/compare/1.0.6...1.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 13:24:01 +00:00
dependabot[bot]
d3dc453cb0 build: bump semver from 1.0.6 to 1.0.7 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.6...1.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 12:18:25 +00:00
Sebastien Boeuf
2ef201e43f tests: Simplify test_vdpa_block() to increase stability
It seems the vdpa_sim_block isn't behaving properly after the vhost
device is closed, as it sometimes returns EBUSY when we try to open it
again. The easiest way to deal with this issue is by simplifying the
integration test, avoid to plug the same device after it's been
unplugged.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-28 13:09:01 +01:00
dependabot[bot]
acd914f02d build: bump quote from 1.0.16 to 1.0.17 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.16 to 1.0.17.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.16...1.0.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 12:37:08 +01:00
dependabot[bot]
0cf100c180 build: bump quote from 1.0.16 to 1.0.17
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.16 to 1.0.17.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.16...1.0.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 09:48:55 +00:00
Henry Wang
26351a81b2 scripts: Use the same linux kernel build function everywhere
This commit unifies the custom linux kernel build in x86, Arm, and
performance metrics to the same function. Therefore, when bumping
the kernel version, we can make sure we only need to make the change
in one place.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-28 10:20:14 +01:00
William Douglas
c8d07f66d1 build: Add amx workflows
With the addition of the amx feature, add a new build workflow to
enable the feature and a clippy quality check.

Signed-off-by: William Douglas <william.douglas@intel.com>
2022-03-25 14:11:54 -07:00
William Douglas
6b0df31e5d vmm: Add support for enabling AMX in vm guests
AMX is an x86 extension adding hardware units for matrix
operations (int and float dot products). The goal of the extension is
to provide performance enhancements for these common operations.

On Linux, AMX requires requesting the permission from the kernel prior
to use. Guests wanting to make use of the feature need to have the
request made prior to starting the vm.

This change then adds the first --cpus features option amx that when
passed will enable AMX usage for guests (needs a 5.17+ kernel) or
exits with failure.

The activation is done in the CpuManager of the VMM thread as it
allows migration and snapshot/restore to work fairly painlessly for
AMX enabled workloads.

Signed-off-by: William Douglas <william.douglas@intel.com>
2022-03-25 14:11:54 -07:00
dependabot[bot]
96e2bedc10 build: bump redox_syscall from 0.2.11 to 0.2.12
Bumps redox_syscall from 0.2.11 to 0.2.12.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 19:06:43 +00:00
dependabot[bot]
86a54a2658 build: bump log from 0.4.14 to 0.4.16
Bumps [log](https://github.com/rust-lang/log) from 0.4.14 to 0.4.16.
- [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)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 18:26:18 +00:00
Rob Bradford
648b61d1cc virtio-devices: Add missing syscalls to virtio common list
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-25 17:56:49 +00:00
Sebastien Boeuf
0685cd8aae virtio-devices: vdpa: Remove get_iova_range() workaround
Now that we rely on vhost v0.4.0, which contains the fix for
get_iova_range(), we don't need the workaround anymore, and we can
actually call into the dedicated function.

Fixes #3861

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-25 17:37:08 +00:00
Sebastien Boeuf
8586c5497b deps: Update vhost and vhost-user-backend dependencies
Rely on newly released versions of the vhost and vhost-user-backend
crates from rust-vmm.

The new vhost version includes the fixes needed for vDPA.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-25 17:51:07 +01:00
Henry Wang
90805dd131 scripts: run_metrics: Always build the custom linux kernel
This commit makes sure that the custom linux kernel is always
rebuilt when running the performance metrics tests, and therefore
changes to the kernel config file is always caught.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-25 17:01:55 +01:00
Sebastien Boeuf
888a465232 docs: Add documentation for vDPA
Explain the reason why using vDPA might be interesting and how to use it
with Cloud Hypervisor.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-25 15:30:20 +01:00
Bo Chen
639a7dd73a vmm: Improve 'test_config_validation' with precise Err assertions
Fixed: #3879

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-25 09:17:05 +00:00
Sebastien Boeuf
afd9f17b73 virtio-fs: Deprecate the DAX feature
Disable the DAX feature from the virtio-fs implementation as the feature
is still not stable. The feature is deprecated, meaning the 'dax'
parameter will be removed in about 2 releases cycles.

In the meantime, the parameter value is ignored and forced to be
disabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-24 10:39:11 -07:00
Sebastien Boeuf
fd40aceabb tests: Fix flakiness in test_vdpa_block()
The test is sporadically failing whenever we try to hotplug the vDPA
device we've just unplugged. This is causing the kernel to complain with
EBUSY because the device hasn't been released yet. This is happening
because the CI system is under very high load, therefore taking quite
some time to the host to update the state of this device.

The easy way to fix such issue is by increasing the sleep time between
the unplug and the replug.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-24 15:15:51 +01:00
Rob Bradford
7a8061818e vmm: Don't expose MemoryManager ACPI functionality unless required
When running non-dynamic or with virtio-mem for hotplug the ACPI
functionality should not be included on the DSDT nor does the
MemoryManager need to be placed on the MMIO bus.

Fixes: #3883

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-24 13:17:51 +00:00
Rob Bradford
f6dfb42a64 vmm: cpu: Don't place CpuManager on MMIO bus when non-dynamic
This is now consistent with not supplying the _CRS for the device when
CpuManager is not dynamic.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-24 13:17:39 +00:00
Sebastien Boeuf
bc90fe4c71 virtio-devices: vhost-user: fs: Don't close file descriptor
The file descriptor provided to fs_slave_map() and fs_slave_io() is
passed as a AsRawFd trait, meaning the caller owns it. For that reason,
there's no need for these functions to close the file descriptor as it
will be closed later on anyway.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-24 11:27:38 +00:00
Rob Bradford
bbf7fd5372 vmm: Reject memory resizing on TDX
This is similar to the dynamic concept used in CpuManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-23 23:15:20 +00:00
Henry Wang
8dda052c7d performance-metrics: disable net latency test on AArch64
As ethr is not stable on AArch64, disable it until we find other tool.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-23 18:25:48 +08:00
Jianyong Wu
1b494fb061 performance-metrics: enable fio test on AArch64
fio test depends on hot-add disk which needs uefi on AArch64, that
will lead to lots of performance issues. So, it's better to use
cold-plug disk.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-23 18:25:48 +08:00
Henry Wang
4335e5f84c scripts: aarch64: Build fio from source for performance metrics
On Arm64, the fio binary that comes from ubuntu distribution cannot
support io_uring, which is a required engine for the block
performance tests in performance metrics. Therefore this commit
build the fio from a relatively new version, and replace the native
ubuntu fio with the newly build one.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-23 18:25:48 +08:00
Jianyong Wu
30025d7676 performance-metrics: prepare image and toolchain for AArch64
Prepare disk image, kernel image and toolchain for AArch64 before run
performance-metrics tests.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2022-03-23 18:25:48 +08:00
Jianyong Wu
6dbc13627a devices: Emulate debug I/O based on pl011
To emulate debug I/O port on arm64, we need trap from guest to VMM.
Generally, there are 3 ways to go:
1) execute a privilege intruction like "wfi";
2) access a system register;
3) access device MMIO region;
However, 1) and 2) often handled in kvm, thus 3) it's the choice.

There maybe lots of repeated work and enlarge the size of clh to develop
a new device, so it's better to reuse the current device. Luckily, I
find that pl011 is the eariest device initialized in kernel and, there
is reserved region in it which we can reuse for emulating debug I/O.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2022-03-23 18:25:48 +08:00
dependabot[bot]
7566f89229 build: bump log from 0.4.14 to 0.4.16 in /fuzz
Bumps [log](https://github.com/rust-lang/log) from 0.4.14 to 0.4.16.
- [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)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-22 23:45:03 +00:00
Rob Bradford
3120260ed6 docs: Add hotplug behind IOMMU segment to documentation
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-22 11:13:20 +00:00
Rob Bradford
1756b23aea vmm: device_manager: Check IOMMU placed device hotplug
Rather than just printing a message return an error back through the API
if the user attempts to hotplug a device that supports being behind an
IOMMU where that device isn't placed on an IOMMU segment.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-22 11:13:20 +00:00
Rob Bradford
0834eca8d4 vmm: config: Validate IOMMU configuration
Ensure devices that are specified to be on a PCI segment that is behind
the IOMMU are IOMMU enabled if possible or error out for those devices
that do not support it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-22 11:13:20 +00:00
Rob Bradford
6d2224f1ba vmm: device_manager: Create IOMMU mapping for hotplugged virtio devices
Previously it was not possible to enable vIOMMU for a virtio device.
However with the ability to place an entire PCI segment behind the
IOMMU the IOMMU mapping needs to be setup for the virtio device if it is
behind the IOMMU.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-22 11:13:20 +00:00
Rob Bradford
54b65107b1 vmm: config: Validate vDPA devices in configuration
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-22 11:13:20 +00:00
Rob Bradford
3b8a017257 vmm: acpi: Print total size of ACPI tables
This can already be calculated by the summing the tables reported by the
Linux kernel but this is more convenient.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-21 14:41:46 +00:00
Henry Wang
d4192abce1 scripts: aarch64: Revert the "Reduce source code build" for linux
Changes in commit "scripts: aarch64: Reduce source code build in CI"
for the Linux kernel will lead to the kernel cannot be rebuilt if
the config file is changed. Therefore should be reverted.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-21 14:41:36 +00:00
Henry Wang
0fa71ddf7e scripts: aarch64: Reduce source code build in CI
As Linux kernel, edk2, virtiofd, SPDK are all build from source, we
need to find a way to reduce the number of source code build.

To address this issue, this commit adds a stage that touching a
".built" file to each repo of the source code after a successfully
build. By checking if the ".built" file exists, we can determine
if there is already an old build. Since the source code repo will
be removed and cloned again when we bump the repo hash, the CI will
rebuild the repo.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-03-21 14:05:59 +08:00
dependabot[bot]
823a860250 build: bump libc from 0.2.120 to 0.2.121 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.120 to 0.2.121.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.120...0.2.121)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-20 13:54:04 +00:00
dependabot[bot]
f05a408a8d build: bump libc from 0.2.120 to 0.2.121
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.120 to 0.2.121.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.120...0.2.121)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-20 12:25:30 +00:00
Wei Liu
0c4b28488c hypervisor: mshv: fix a comment
It should have said MSHV in the comment.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-03-20 11:37:13 +00:00
Sebastien Boeuf
028961ac9f vfio_user: Shutdown the communication with the backend
Whenever a vfio-user device is dropped, the communication between the
VMM and the backend should be shutdown.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:45:26 +01:00
Sebastien Boeuf
9c95109a6b vmm: Streamline reboot code path
Separate the destruction and cleanup of original VM and the creation of
the new one. In particular have a clear hand off point for resources
(e.g. reset EventFd) used by the new VM from the original. In the
situation where vm.shutdown() generates an error this also avoids the
Vmm reference to the Vm (self.vm) from being maintained.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:50 +01:00
Sebastien Boeuf
03014e2e7f tests: Add integration tests for vDPA
Adding two new integration tests for vDPA, relying on both block and net
simulators from the host kernel.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
78fb98a609 Jenkinsfile: Prepare CI environment for vDPA
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
d1d55f1686 scripts: Add a script for preparing environment for vDPA
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
6dcc5572c1 ch-remote: Add support for add-vdpa
Adding the wrapping layer to be able to hotplug a vDPA device from the
ch-remote tool.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
3fea5f5396 vmm: Add support for hotplugging a vDPA device
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
c73c6039c3 vmm: Enable vDPA support
Based on the newly added Vdpa device along with the new vdpa parameter,
this patch enables the support for vDPA devices.

It's important to note this the only virtio device for which we provide
an ExternalDmaMapping instance. This will allow for the right DMA ranges
to be mapped/unmapped.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
72169686fe vmm: Add a vDPA device parameter
Introduce a new --vdpa parameter associated with a VdpaConfig for the
future creation of a Vdpa device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
be7c389120 virtio-devices: Add Vdpa device
vDPA is a kernel framework introduced fairly recently in order to handle
devices complying with virtio specification on their datapath, while the
control path is vendor specific. For the datapath, that means the
virtqueues are handled through DMA directly between the hardware and the
guest, while the control path goes through the vDPA framework,
eventually exposed through a vhost-vdpa device.

vDPA, like VFIO, aims at achieving baremetal performance for devices
that are passed into a VM. But unlike VFIO, it provides a simpler/better
framework for achieving migration. Because the DMA accesses between the
device and the guest are going through virtio queues, migration can be
achieved way more easily, and doesn't require each device driver to
implement the migration support. In the VFIO case, each vendor is
expected to provide an implementation of the VFIO migration framework,
which makes things harder as it must be done for each and every device.

So to summarize the point is to support migration for hardware devices
through which we can achieve baremetal performances.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 12:28:40 +01:00
Sebastien Boeuf
2dc9cfaf01 docs: Update virtio-fs documentation
Update the content of the documentation to clarify how the cache option
from virtiofsd has an impact on the host page cache, while the dax
option for the filesystem in the guest has an impact on the guest page
cache.

The document is also updated to not have lines exceeding 80 characters.

Fixes #3826

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-18 11:25:10 +01:00
dependabot[bot]
86f8fb1c70 build: bump quote from 1.0.15 to 1.0.16
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.15...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-18 01:58:28 +00:00
dependabot[bot]
c0f2991e33 build: bump dirs-sys from 0.3.6 to 0.3.7
Bumps [dirs-sys](https://github.com/dirs-dev/dirs-sys-rs) from 0.3.6 to 0.3.7.
- [Release notes](https://github.com/dirs-dev/dirs-sys-rs/releases)
- [Commits](https://github.com/dirs-dev/dirs-sys-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-18 01:12:58 +00:00
dependabot[bot]
3a1db02212 build: bump redox_users from 0.4.0 to 0.4.2
Bumps redox_users from 0.4.0 to 0.4.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-18 00:14:33 +00:00
dependabot[bot]
13514e1951 build: bump quote from 1.0.15 to 1.0.16 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.15...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-17 23:44:32 +00:00
Sebastien Boeuf
cfc6e6e8eb docs: Add balloon documentation
Document the reason why someone might need to use the balloon device and
detail the different parameters associated with it.

Fixes #3807

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-17 17:01:07 +01:00
Rob Bradford
7324b0e514 vmm: cpu: Only include hotplug/unplug related AML code if dynamic
This will significantly reduce the size of the DSDT and the effort
required to parse them if there is no requirement to support
hotplug/unplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-17 13:46:21 +00:00
Rob Bradford
188078467d vmm: cpu: Deny resizing if CpuManager is not dynamic
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-17 13:46:21 +00:00
Rob Bradford
e5cb13588b vmm: cpu: Add concept of making CpuManager dynamic
If the CpuManager is dynamic it devices CPUs can be
hotplugged/unplugged.

Since TDX does not support CPU hotplug this is currently the only
determinator as to whether the CpuManager is dynamic.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-17 13:46:21 +00:00
Yi Wang
9bfbc93044 docs: api: Add documentation for vm.snapshot/restore
vm.snapshot/restore is missed, add this part.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-03-17 11:44:07 +00:00
dependabot[bot]
c5c0795854 build: bump openssl-src from 111.17.0+1.1.1m to 111.18.0+1.1.1n
Bumps [openssl-src](https://github.com/alexcrichton/openssl-src-rs) from 111.17.0+1.1.1m to 111.18.0+1.1.1n.
- [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-03-17 07:08:03 +00:00
dependabot[bot]
86430bfb3d build: bump syn from 1.0.88 to 1.0.89
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.88 to 1.0.89.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.88...1.0.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-17 00:29:16 +00:00
dependabot[bot]
33ec61345e build: bump syn from 1.0.88 to 1.0.89 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.88 to 1.0.89.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.88...1.0.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-16 23:42:56 +00:00
Rob Bradford
65bebabd70 build: Move Jenkins workers to focal
hirsute is EOLed and focal is receiving kernel updates on Azure.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-16 14:15:18 +01:00
dependabot[bot]
bf7f7f515e build: bump syn from 1.0.87 to 1.0.88
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.87 to 1.0.88.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.87...1.0.88)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-16 00:10:01 +00:00
dependabot[bot]
c42742a58f build: bump syn from 1.0.87 to 1.0.88 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.87 to 1.0.88.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.87...1.0.88)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-15 23:37:25 +00:00
Rob Bradford
b9aeaf6634 net_util: Remove unnecessary return value from CtrlQueue::process()
Since the code has been adapted to support VIRTIO_F_EVENT_IDX we use
Queue::needs_notification() to determine whether to signal the guest so
it is no longer necessary to check if there are any used descriptors. If
the feature is not negotiated then Queue::needs_notification() will
return true triggering an interrupt of the guest. Theoretically this
could be a spurious interrupt of the guest if there were no used used
descriptors but this is unlikely as we only generate used descriptors
for the control queue as a result of an interrupt of the VMM by the
guest.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
aa3ef70ea6 virtio-devices: Use NetCtrlEpollHandler in vhost-user-net
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
21a9ae3459 virtio-devices: net: Signal control queue was used if necessary
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
c5afea5b85 virtio-devices: net: Be more consistent with error messages
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
1fc3fef642 net_util: Use value returned from Queue::enable_notification()
This indicates if anything has been added to the available queue since
it was last iterated through. If it returns true then it is necessary to
iterate through the queue again otherwise it is appropriate to break out
from the loop.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
2ed0338da8 virtio-devices: net: Use consistent nomenclature for control queue
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
b4eddce090 virtio-devices: net: Use "num_queues" for number of queues
This improves consistency with other parts of the code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:08:29 +00:00
Rob Bradford
bbcf69c58c virtio-devices: seccomp: Add pread64/pwrite64 sycalls for virtio-fs
These syscalls are explicitly used in the code:

3593055e77/virtio-devices/src/vhost_user/fs.rs (L237)

Fixes: #3843

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-15 16:58:15 +01:00
dependabot[bot]
18f1306d0c build: bump syn from 1.0.86 to 1.0.87
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.86 to 1.0.87.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.86...1.0.87)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-15 01:05:48 +00:00
dependabot[bot]
9c3f8cf2f5 build: bump libc from 0.2.119 to 0.2.120
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.119 to 0.2.120.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.119...0.2.120)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-15 00:21:58 +00:00
dependabot[bot]
673121b828 build: bump syn from 1.0.86 to 1.0.87 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.86 to 1.0.87.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.86...1.0.87)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-15 00:07:48 +00:00
dependabot[bot]
b762fe4c2e build: bump libc from 0.2.119 to 0.2.120 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.119 to 0.2.120.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.119...0.2.120)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 23:36:07 +00:00
Rob Bradford
c922bf23f6 performance-metrics: Use non-zero exit code on report file issues
This removes the need to wrap an error that is never used.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
f99c09fab7 performance-metrics: Successful output should be on stdout not stderr
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
a6d86b9496 performance-metrics: Use Write::write_all() for report
Write::write() is not guaranteed to write all the contents.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
1004f870e1 performance-metrics: Refactor report file opening code
It should be closer to the use of the opened file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
d3be855b4b performance-metrics: Exit binary with non-zero exit code on test failure
This ensures that partial reports are not generated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
0cbdbc8122 performance-metrics: Remove unnecessary prelude on --list-tests
The user knows they have requested the list of tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
959be92189 performance-metrics: Fix typo in function name
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Rob Bradford
5934319953 performance-metrics: Remove obsolete TODO
We upload from the file written to disk.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-14 16:53:49 +01:00
Bo Chen
8bef32d389 docs: Add a documentation for performance metrics
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-14 09:41:51 +00:00
LiHui
b0be5ff8ad API: fix http hang for vmm.ping/vm.create/vm.info/vmm.shutdown
vmm.ping/vm.info will hang for PUT method, vm.create/vmm.shutdonw hang for GET method.
Because these four APIs do not write the response body when the HTTP method does not match.

Signed-off-by: LiHui <andrewli@kubesphere.io>
2022-03-11 11:56:14 +00:00
Sebastien Boeuf
9d46890dc0 vmm: device_manager: Make virtio DMA mapping conditional on vIOMMU
In case the virtio device which requires DMA mapping is placed behind a
virtual IOMMU, we shouldn't map/unmap any region manually. Instead, we
provide the DMA handler to the virtio-iommu device so that it can
trigger the proper mappings.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Sebastien Boeuf
a4f742277b vmm: device_manager: Handle DMA mapping for virtio devices
If a virtio device is associated with a DMA handler, the DMA mapping and
unmapping is performed from the device manager through the handler.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Sebastien Boeuf
86bc313f38 virtio-devices, vmm: Register a DMA handler to VirtioPciDevice
Given that some virtio device might need some DMA handling, we provide a
way to store this through the VirtioPciDevice layer, so that it can be
accessed when the PCI device is removed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Sebastien Boeuf
54d63e774c vmm: device_manager: Extend MetaVirtioDevice with a DMA handler
In anticipation for handling potential DMA mapping/unmapping operations for a
virtio device, we extend the MetaVirtioDevice with an additional field
that holds an optional DMA handler.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Sebastien Boeuf
f801b0fc72 vmm: device_manager: Factorize virtio device tuple into structure
The tuple of information related to each virtio device is too big, and
it's better to factorize it through a dedicated structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Sebastien Boeuf
80296b9497 vmm: device_manager: Remove typedef VirtioDeviceArc
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-11 12:37:17 +01:00
Rob Bradford
71d911b3aa tests: Add test for virtio-net control queue
Use ethtool to trigger an event on the control queue.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-10 11:27:35 +00:00
Rob Bradford
223d0cf787 virtio-devices: Enable F_EVENT_IDX on control queue if negotiated
With the VIRTIO_F_EVENT_IDX handling now conducted inside the
virtio-queue crate it is necessary to activate the functionality on
every queue if it is negotiatated. Otherwise this leads to a failure of
the guest to signal to the host that there is something in the available
queue as the queue's internal state has not been configured correctly.

Fixes: #3829

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-10 11:27:35 +00:00
Yi Wang
5375b84e3b vmm: interrupt: fix msi mask irq causing kernel panic on AMD
When mask a msi irq, we set the entry.masked to be true, so kvm
hypervisor will not pass the gsi to kernel through KVM_SET_GSI_ROUTING
ioctl which update kvm->irq_routing. This will trigger kernel
panic on AMD platform when the gsi is the largest one in kernel
kvm->irqfds.items:

crash> bt
PID: 22218  TASK: ffff951a6ad74980  CPU: 73  COMMAND: "vcpu8"
 #0 [ffffb1ba6707fa40] machine_kexec at ffffffff8565b397
 #1 [ffffb1ba6707fa90] __crash_kexec at ffffffff85788a6d
 #2 [ffffb1ba6707fb58] crash_kexec at ffffffff8578995d
 #3 [ffffb1ba6707fb70] oops_end at ffffffff85623c0d
 #4 [ffffb1ba6707fb90] no_context at ffffffff856692c9
 #5 [ffffb1ba6707fbf8] exc_page_fault at ffffffff85f95b51
 #6 [ffffb1ba6707fc50] asm_exc_page_fault at ffffffff86000ace
    [exception RIP: svm_update_pi_irte+227]
    RIP: ffffffffc0761b53  RSP: ffffb1ba6707fd08  RFLAGS: 00010086
    RAX: ffffb1ba6707fd78  RBX: ffffb1ba66d91000  RCX: 0000000000000001
    RDX: 00003c803f63f1c0  RSI: 000000000000019a  RDI: ffffb1ba66db2ab8
    RBP: 000000000000019a   R8: 0000000000000040   R9: ffff94ca41b82200
    R10: ffffffffffffffcf  R11: 0000000000000001  R12: 0000000000000001
    R13: 0000000000000001  R14: ffffffffffffffcf  R15: 000000000000005f
    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
 #7 [ffffb1ba6707fdb8] kvm_irq_routing_update at ffffffffc09f19a1 [kvm]
 #8 [ffffb1ba6707fde0] kvm_set_irq_routing at ffffffffc09f2133 [kvm]
 #9 [ffffb1ba6707fe18] kvm_vm_ioctl at ffffffffc09ef544 [kvm]
    RIP: 00007f143c36488b  RSP: 00007f143a4e04b8  RFLAGS: 00000246
    RAX: ffffffffffffffda  RBX: 00007f05780041d0  RCX: 00007f143c36488b
    RDX: 00007f05780041d0  RSI: 000000004008ae6a  RDI: 0000000000000020
    RBP: 00000000000004e8   R8: 0000000000000008   R9: 00007f05780041e0
    R10: 00007f0578004560  R11: 0000000000000246  R12: 00000000000004e0
    R13: 000000000000001a  R14: 00007f1424001c60  R15: 00007f0578003bc0
    ORIG_RAX: 0000000000000010  CS: 0033  SS: 002b

To solve this problem, move route.disable() before set_gsi_routes() to
remove the gsi from irqfds.items first.

This problem only exists on AMD platform, 'cause on Intel platform
kernel just return when update irte while it only prints a warning on
AMD.

Also, this patch adjusts the order of enable() and set_gsi_routes() in
unmask(), which should do no harm.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-03-10 09:27:50 +01:00
Yi Wang
db9e5e5a87 vmm: interrupt: fix msi mask irq causing kernel panic on AMD
When mask a msi irq, we set the entry.masked to be true, so kvm
hypervisor will not pass the gsi to kernel through KVM_SET_GSI_ROUTING
ioctl which update kvm->irq_routing. This will trigger kernel
panic on AMD platform when the gsi is the largest one in kernel
kvm->irqfds.items:

crash> bt
PID: 22218  TASK: ffff951a6ad74980  CPU: 73  COMMAND: "vcpu8"
 #0 [ffffb1ba6707fa40] machine_kexec at ffffffff8565b397
 #1 [ffffb1ba6707fa90] __crash_kexec at ffffffff85788a6d
 #2 [ffffb1ba6707fb58] crash_kexec at ffffffff8578995d
 #3 [ffffb1ba6707fb70] oops_end at ffffffff85623c0d
 #4 [ffffb1ba6707fb90] no_context at ffffffff856692c9
 #5 [ffffb1ba6707fbf8] exc_page_fault at ffffffff85f95b51
 #6 [ffffb1ba6707fc50] asm_exc_page_fault at ffffffff86000ace
    [exception RIP: svm_update_pi_irte+227]
    RIP: ffffffffc0761b53  RSP: ffffb1ba6707fd08  RFLAGS: 00010086
    RAX: ffffb1ba6707fd78  RBX: ffffb1ba66d91000  RCX: 0000000000000001
    RDX: 00003c803f63f1c0  RSI: 000000000000019a  RDI: ffffb1ba66db2ab8
    RBP: 000000000000019a   R8: 0000000000000040   R9: ffff94ca41b82200
    R10: ffffffffffffffcf  R11: 0000000000000001  R12: 0000000000000001
    R13: 0000000000000001  R14: ffffffffffffffcf  R15: 000000000000005f
    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
 #7 [ffffb1ba6707fdb8] kvm_irq_routing_update at ffffffffc09f19a1 [kvm]
 #8 [ffffb1ba6707fde0] kvm_set_irq_routing at ffffffffc09f2133 [kvm]
 #9 [ffffb1ba6707fe18] kvm_vm_ioctl at ffffffffc09ef544 [kvm]
    RIP: 00007f143c36488b  RSP: 00007f143a4e04b8  RFLAGS: 00000246
    RAX: ffffffffffffffda  RBX: 00007f05780041d0  RCX: 00007f143c36488b
    RDX: 00007f05780041d0  RSI: 000000004008ae6a  RDI: 0000000000000020
    RBP: 00000000000004e8   R8: 0000000000000008   R9: 00007f05780041e0
    R10: 00007f0578004560  R11: 0000000000000246  R12: 00000000000004e0
    R13: 000000000000001a  R14: 00007f1424001c60  R15: 00007f0578003bc0
    ORIG_RAX: 0000000000000010  CS: 0033  SS: 002b

To solve this problem, move route.disable() before set_gsi_routes() to
remove the gsi from irqfds.items first.

This problem only exists on AMD platform, 'cause on Intel platform
kernel just return when update irte while it only prints a warning on
AMD.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
2022-03-10 09:27:50 +01:00
Rob Bradford
64b32841a3 arch: x86_64: Write EBDA address to BIOS data area
This allows ACPICA to find the EBDA and load the ACPI tables when
scanning for them.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-09 15:47:01 +01:00
dependabot[bot]
cf388b160b build: bump libz-sys from 1.1.4 to 1.1.5
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.4 to 1.1.5.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.4...1.1.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 16:20:34 +00:00
dependabot[bot]
16d9cb4c98 build: bump regex from 1.5.4 to 1.5.5
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 15:49:47 +00:00
Rob Bradford
55a4803a4a .github: Avoid excessive rebase & rebuilds from dependabot
Reduce the number of open pull requests dependabot will create to avoid
excessive rebase and rebuilds of PRs. This avoids a situation with a 2nd
PR being rebased after a 1st is merged resulting in a wasteful rebuild.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-08 15:16:12 +00:00
dependabot[bot]
08f4375177 build: bump clap from 3.1.5 to 3.1.6
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.5 to 3.1.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.1.5...v3.1.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-03-08 01:52:09 +00:00
dependabot[bot]
f48aa66ccb build: bump anyhow from 1.0.55 to 1.0.56
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.55 to 1.0.56.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.55...1.0.56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 00:48:22 +00:00
dependabot[bot]
1f430fe3ff build: bump libz-sys from 1.1.3 to 1.1.4
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.3...1.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 00:18:36 +00:00
dependabot[bot]
8fd630a19d build: bump clap from 3.1.5 to 3.1.6 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.1.5 to 3.1.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.1.5...v3.1.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 00:02:38 +00:00
dependabot[bot]
09c6b84352 build: bump anyhow from 1.0.55 to 1.0.56 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.55 to 1.0.56.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.55...1.0.56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 23:48:14 +00:00
Rob Bradford
1f077e7871 scripts: Propagate "--test-filter" metrics test
Populate iff the the parameter is passed.

Following combinations tested:

scripts/dev_cli.sh tests --metrics -- --test-filter boot_time
scripts/dev_cli.sh tests --metrics -- --test-filter boot_time -- --report-file /root/workloads/metrics.json
scripts/dev_cli.sh tests --metrics
scripts/dev_cli.sh tests --metrics --  -- --report-file /root/workloads/metrics.json

Fixes: #3787

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-07 14:34:57 +00:00
Sebastien Boeuf
885dce4082 deps: Move to latest vm-virtio and vhost-user-backend releases
Move to release version v0.2.0 for both vm-virtio and vhost-user-backend
crates rather than relying on their main branch, as they might be
subject to breaking changes.

Fixes #3800

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-03-07 13:30:42 +00:00
Rob Bradford
7e146a2057 Revert "scripts: Pass-through '--test-filter' option to performance-metrics"
This reverts commit 0be2d09778.

See: #3813

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-07 11:31:52 +00:00
Rob Bradford
37ea979e56 main: Use non-threaded signal handler for SIGSYS
Replace the thread for handling SIGSYS with a simple signal handler.
This resolves inconsistent delivery of signals to the SIGSYS thread due
to other threads manipulating the signals.

Tested by removing key syscalls from vCPU and virtio device filters and
observing correct notice.

Fixes: #3811

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-07 11:31:19 +00:00
dependabot[bot]
8b1e6140d2 build: bump virtio-queue from bbb22d4 to c1c4c03 in /fuzz
Bumps [virtio-queue](https://github.com/rust-vmm/vm-virtio) from `bbb22d4` to `c1c4c03`.
- [Release notes](https://github.com/rust-vmm/vm-virtio/releases)
- [Commits](bbb22d4355...c1c4c03978)

---
updated-dependencies:
- dependency-name: virtio-queue
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 23:52:25 +00:00
Bo Chen
0be2d09778 scripts: Pass-through '--test-filter' option to performance-metrics
To be consistently with the integration scripts, we now pass through the
`--test-filter` option of the test scripts to the `performance-metrics`
binary. Now the following two commands achieve the same results:

`$./scripts/dev_cli.sh tests --metrics -- --test-filter boot_time_ -- --test-filter latency`
`$./scripts/dev_cli.sh tests --metrics -- -- --test-filter boot_time_ --test-filter latency`

Note that, the test scripts support only single occurrence of the
`--test-filter` option while the `performance-metrics` binary allows
multiple occurrences for filtering based on different keywords.

Fixes: #3787

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-03-04 13:22:56 -08:00
Rob Bradford
a7a8a05c14 build: Add "test_infra" crate to workspace
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-04 17:12:13 +01:00
Wei Liu
4cf22e4ec7 arch: do not hardcode MMIO region length in MmioDeviceInfo
Add a field for its length and fix up users.

Things work just because all hardcoded values agree with each other.
This is prone to breakage.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-03-04 15:21:48 +08:00
dependabot[bot]
288a1c2dd1 build: bump vhost-user-backend from bbc892b to 6e66d2c
Bumps [vhost-user-backend](https://github.com/rust-vmm/vhost-user-backend) from `bbc892b` to `6e66d2c`.
- [Release notes](https://github.com/rust-vmm/vhost-user-backend/releases)
- [Commits](bbc892ba45...6e66d2c1a4)

---
updated-dependencies:
- dependency-name: vhost-user-backend
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-03 23:57:35 +00:00
dependabot[bot]
ec9df5c64a build: bump once_cell from 1.9.0 to 1.10.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.9.0 to 1.10.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.9.0...v1.10.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-03-03 23:54:09 +00:00
dependabot[bot]
5f3afaf282 build: bump libfuzzer-sys from 0.4.2 to 0.4.3 in /fuzz
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.4.2 to 0.4.3.
- [Release notes](https://github.com/rust-fuzz/libfuzzer/releases)
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.2...0.4.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-03 23:37:06 +00:00
Rob Bradford
638c4a5781 performance-metrics: Use friendlier metric units
* Boot time in ms
* Network throughput in Gbps
* Block throughput in MiBps

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-03 11:39:55 -08:00
128 changed files with 4498 additions and 2086 deletions

View File

@@ -4,7 +4,7 @@ updates:
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 3
open-pull-requests-limit: 1
allow:
- dependency-type: direct
- dependency-type: indirect
@@ -12,7 +12,7 @@ updates:
directory: "/fuzz"
schedule:
interval: daily
open-pull-requests-limit: 3
open-pull-requests-limit: 1
allow:
- dependency-type: direct
- dependency-type: indirect

View File

@@ -13,7 +13,7 @@ jobs:
- stable
- beta
- nightly
- 1.54
- 1.56
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
@@ -35,24 +35,27 @@ jobs:
- name: Debug Check (default features)
run: |
git rev-list origin/main..$GITHUB_SHA | xargs -t -I % sh -c 'git checkout %; cargo check --all --target=${{ matrix.target }}'
git rev-list origin/main..$GITHUB_SHA | xargs -t -I % sh -c 'git checkout %; cargo check --tests --all --target=${{ matrix.target }}'
git checkout $GITHUB_SHA
- name: Build (default + tdx)
- name: Build (default features)
run: cargo rustc --bin cloud-hypervisor -- -D warnings
- name: Build (common + kvm)
run: cargo rustc --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
- name: Build (acpi,kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "acpi,kvm" -- -D warnings
- name: Build (default features + amx)
run: cargo rustc --bin cloud-hypervisor --features "amx" -- -D warnings
- name: Build (kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "kvm" -- -D warnings
- name: Build (default features + gdb)
run: cargo rustc --bin cloud-hypervisor --features "gdb" -- -D warnings
- name: Build (acpi,mshv)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "acpi,mshv" -- -D warnings
- name: Build (common + mshv)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "common,mshv" -- -D warnings
- name: Build (mshv)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "mshv" -- -D warnings
- name: Release Build (default features)
run: cargo build --all --release --target=${{ matrix.target }}

View File

@@ -32,30 +32,16 @@ jobs:
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (kvm)
- name: Clippy (common + kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --all --no-default-features --features "kvm" -- -D warnings
args: --target=${{ matrix.target }} --tests --all --no-default-features --features "common,kvm" -- -D warnings
- name: Clippy (kvm,acpi)
- name: Clippy (default features)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --all --no-default-features --features "kvm,acpi" -- -D warnings
- name: Clippy (all features,kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --all --no-default-features --features "common,kvm" -- -D warnings
- name: Clippy (default)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --all -- -D warnings
args: --target=${{ matrix.target }} --tests --all -- -D warnings

View File

@@ -33,29 +33,20 @@ jobs:
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (all features,kvm)
- name: Clippy (common + kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,kvm" -- -D warnings
- name: Clippy (all features,mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,mshv" -- -D warnings
- name: Clippy (acpi,kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,kvm" -- -D warnings
- name: Clippy (acpi,kvm,tdx)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,kvm,tdx" -- -D warnings
- name: Clippy (kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "kvm" -- -D warnings
- name: Clippy (acpi,mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,mshv" -- -D warnings
- name: Clippy (mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "mshv" -- -D warnings
- name: Clippy (integration tests)
- name: Clippy (default features)
run: cargo clippy --all --all-targets --tests -- -D warnings
- name: Clippy (default features + amx)
run: cargo clippy --all --all-targets --tests --features "amx" -- -D warnings
- name: Clippy (default features + gdb)
run: cargo clippy --all --all-targets --tests --features "gdb" -- -D warnings
- name: Clippy (common + mshv)
run: cargo clippy --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,31 @@ jobs:
- name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.58
target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.58
target: x86_64-unknown-linux-musl
- name: Build
run: cargo build --all --release --target=x86_64-unknown-linux-gnu
uses: actions-rs/cargo@v1
with:
toolchain: 1.58
command: build
args: --all --release --target=x86_64-unknown-linux-gnu
- name: Static Build
run: cargo build --all --release --target=x86_64-unknown-linux-musl
uses: actions-rs/cargo@v1
with:
toolchain: 1.58
command: build
args: --all --release --target=x86_64-unknown-linux-musl
- name: Strip cloud-hypervisor binaries
run: strip target/*/release/cloud-hypervisor
- name: Install Rust toolchain (aarch64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.58
target: aarch64-unknown-linux-musl
override: true
- name: Static Build (AArch64)

View File

@@ -1 +1 @@
edition = "2018"
edition = "2021"

103
Cargo.lock generated
View File

@@ -20,9 +20,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.55"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd"
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
[[package]]
name = "api_client"
@@ -131,9 +131,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.1.5"
version = "3.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312"
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
dependencies = [
"atty",
"bitflags",
@@ -148,7 +148,7 @@ dependencies = [
[[package]]
name = "cloud-hypervisor"
version = "22.0.0"
version = "23.1.0"
dependencies = [
"anyhow",
"api_client",
@@ -175,9 +175,9 @@ dependencies = [
[[package]]
name = "crc32c"
version = "0.6.1"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee6b9c9389584bcba988bd0836086789b7f87ad91892d6a83d5291dbb24524b5"
checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e"
dependencies = [
"rustc_version",
]
@@ -219,9 +219,9 @@ dependencies = [
[[package]]
name = "dirs-sys"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
@@ -293,9 +293,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
@@ -363,9 +363,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
@@ -433,9 +433,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd"
[[package]]
name = "libssh2-sys"
@@ -453,9 +453,9 @@ dependencies = [
[[package]]
name = "libz-sys"
version = "1.1.3"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859"
dependencies = [
"cc",
"libc",
@@ -474,18 +474,19 @@ dependencies = [
[[package]]
name = "lock_api"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [
"cfg-if",
]
@@ -514,7 +515,7 @@ dependencies = [
[[package]]
name = "mshv-bindings"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#d241ffcacdfa4240b4a1d34b44af89dc7b113986"
source = "git+https://github.com/rust-vmm/mshv?branch=main#75cf309d566c3d9ba91e81582a7864032ecc5bbb"
dependencies = [
"libc",
"serde",
@@ -526,7 +527,7 @@ dependencies = [
[[package]]
name = "mshv-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#d241ffcacdfa4240b4a1d34b44af89dc7b113986"
source = "git+https://github.com/rust-vmm/mshv?branch=main#75cf309d566c3d9ba91e81582a7864032ecc5bbb"
dependencies = [
"libc",
"mshv-bindings",
@@ -574,9 +575,9 @@ dependencies = [
[[package]]
name = "openssl-src"
version = "111.17.0+1.1.1m"
version = "111.18.0+1.1.1n"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d6a336abd10814198f66e2a91ccd7336611f30334119ca8ce300536666fcf4"
checksum = "7897a926e1e8d00219127dc020130eca4292e5ca666dd592480d72c3eca2ff6c"
dependencies = [
"cc",
]
@@ -635,9 +636,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
[[package]]
name = "pci"
@@ -679,9 +680,9 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.24"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "pnet"
@@ -773,9 +774,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.36"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
dependencies = [
"unicode-xid",
]
@@ -793,9 +794,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.15"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
@@ -811,28 +812,29 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.2.11"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall",
"thiserror",
]
[[package]]
name = "regex"
version = "1.5.4"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
@@ -888,9 +890,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
[[package]]
name = "serde"
@@ -971,9 +973,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.86"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
dependencies = [
"proc-macro2",
"quote",
@@ -1160,9 +1162,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b56bf8f178fc500fe14505fca8b00dec76fc38f2304f461c8d9d7547982311d"
checksum = "53567fd9ab820e4f3cc156f24146882fee3c365194c3e1dea74723265f27fc88"
dependencies = [
"bitflags",
"libc",
@@ -1172,8 +1174,9 @@ dependencies = [
[[package]]
name = "vhost-user-backend"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vhost-user-backend?branch=main#bbc892ba4526bdf8101252f7aa51832d1f2eeabd"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1490f2028d4f119b2292efe218b5f8cfc6471f039b53b6a6eb5d9513e964facc"
dependencies = [
"libc",
"log",
@@ -1248,6 +1251,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
"versionize_derive",
"vhost",
@@ -1263,8 +1267,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vm-virtio?branch=main#bbb22d43558a76cc7cc9c262c4be870a9e682a86"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3785325315e6496fa88673842ee6cd198b9658e88e8b0e1ad48a5dc818b221dc"
dependencies = [
"log",
"vm-memory",

View File

@@ -1,8 +1,8 @@
[package]
name = "cloud-hypervisor"
version = "22.0.0"
version = "23.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
default-run = "cloud-hypervisor"
build = "build.rs"
license = "LICENSE-APACHE & LICENSE-BSD-3-Clause"
@@ -10,20 +10,20 @@ 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.54"
rust-version = "1.56"
[profile.release]
lto = true
[dependencies]
anyhow = "1.0.55"
anyhow = "1.0.56"
api_client = { path = "api_client" }
clap = { version = "3.1.5", features = ["wrap_help","cargo"] }
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.119"
log = { version = "0.4.14", features = ["std"] }
libc = "0.2.123"
log = { version = "0.4.16", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.2.0"
serde_json = "1.0.79"
@@ -34,14 +34,13 @@ vmm-sys-util = "0.9.0"
vm-memory = "0.7.0"
[build-dependencies]
clap = { version = "3.1.5", features = ["wrap_help"] }
clap = { version = "3.1.8", features = ["cargo"] }
# List of patched crates
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0-tdx" }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
virtio-queue = { git = "https://github.com/rust-vmm/vm-virtio", branch = "main" }
[dev-dependencies]
dirs = "4.0.0"
@@ -54,8 +53,8 @@ wait-timeout = "0.2.0"
[features]
default = ["common", "kvm"]
# Common features for all hypervisors
common = ["acpi", "cmos", "fwdebug"]
acpi = ["vmm/acpi"]
common = ["fwdebug"]
amx = ["vmm/amx"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
gdb = ["vmm/gdb"]
@@ -79,6 +78,7 @@ members = [
"performance-metrics",
"qcow",
"rate_limiter",
"test_infra",
"vfio_user",
"vhdx",
"vhost_user_block",

22
Jenkinsfile vendored
View File

@@ -43,7 +43,7 @@ pipeline{
stage ('Build') {
parallel {
stage ('Worker build') {
agent { node { label 'hirsute' } }
agent { node { label 'focal' } }
when {
beforeAgent true
expression {
@@ -56,7 +56,11 @@ pipeline{
checkout scm
}
}
stage ('Prepare environment') {
steps {
sh "scripts/prepare_vdpa.sh"
}
}
stage ('Run OpenAPI tests') {
steps {
sh "scripts/run_openapi_tests.sh"
@@ -115,7 +119,7 @@ pipeline{
}
}
stage ('Worker build (musl)') {
agent { node { label 'hirsute' } }
agent { node { label 'focal' } }
when {
beforeAgent true
expression {
@@ -128,7 +132,11 @@ pipeline{
checkout scm
}
}
stage ('Prepare environment') {
steps {
sh "scripts/prepare_vdpa.sh"
}
}
stage ('Run unit tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --unit --libc musl"
@@ -228,7 +236,7 @@ pipeline{
}
}
stage ('Worker build - Windows guest') {
agent { node { label 'hirsute' } }
agent { node { label 'focal' } }
when {
beforeAgent true
expression {
@@ -274,7 +282,7 @@ pipeline{
}
}
stage ('Worker build - Live Migration') {
agent { node { label 'hirsute-small' } }
agent { node { label 'focal-small' } }
when {
beforeAgent true
expression {
@@ -379,7 +387,7 @@ def cancelPreviousBuilds() {
def installAzureCli() {
sh "sudo apt install -y ca-certificates curl apt-transport-https lsb-release gnupg"
sh "curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null"
sh "echo \"deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ hirsute main\" | sudo tee /etc/apt/sources.list.d/azure-cli.list"
sh "echo \"deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ focal main\" | sudo tee /etc/apt/sources.list.d/azure-cli.list"
sh "sudo apt update"
sh "sudo apt install -y azure-cli"
}

View File

@@ -267,26 +267,26 @@ Cloud Hypervisor is under active development. The following stability guarantees
are currently made:
* The API (including command line options) will not be removed or changed in a
breaking way without a minimum of 2 releases notice. Where possible warnings
will be given about the use of deprecated functionality and the deprecations
will be documented in the release notes.
breaking way without a minimum of 2 major releases notice. Where possible
warnings will be given about the use of deprecated functionality and the
deprecations will be documented in the release notes.
* Point releases will be made between individual releases where there are
substantial bug fixes or security issues that need to be fixed.
substantial bug fixes or security issues that need to be fixed. These point
releases will only include bug fixes.
Currently the following items are **not** guaranteed across updates:
* Snapshot/restore is not supported across different versions
* Live migration is not supported across different versions
* The following features are considered experimental and may change
substantially between releases: TDX, SGX.
substantially between releases: TDX, vfio-user, vDPA.
As of 2021-04-29, the following cloud images are supported:
As of 2022-04-05, the following cloud images are supported:
- [Ubuntu Bionic](https://cloud-images.ubuntu.com/bionic/current/) (cloudimg)
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (cloudimg)
- [Ubuntu Groovy](https://cloud-images.ubuntu.com/groovy/current/) (cloudimg)
- [Ubuntu Hirsute](https://cloud-images.ubuntu.com/hirsute/current/) (cloudimg)
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (cloudimg)
Direct kernel boot to userspace should work with a rootfs from most
distributions.

View File

@@ -2,7 +2,7 @@
name = "acpi_tables"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
vm-memory = "0.7.0"

View File

@@ -2,7 +2,7 @@
name = "api_client"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
vmm-sys-util = "0.9.0"

View File

@@ -2,21 +2,20 @@
name = "arch"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
edition = "2018"
edition = "2021"
[features]
default = []
acpi = ["acpi_tables"]
tdx = []
[dependencies]
acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0.55"
acpi_tables = { path = "../acpi_tables" }
anyhow = "1.0.56"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.119"
libc = "0.2.123"
linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.14"
log = "0.4.16"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
thiserror = "1.0.30"

View File

@@ -18,14 +18,13 @@ use std::str;
use super::super::DeviceType;
use super::super::GuestMemoryMmap;
use super::super::InitramfsConfig;
use super::get_fdt_addr;
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,
};
use vm_fdt::{FdtWriter, FdtWriterResult};
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryRegion};
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion};
// This is a value for uniquely identifying the FDT node declaring the interrupt controller.
const GIC_PHANDLE: u32 = 1;
@@ -141,9 +140,8 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
pub fn write_fdt_to_memory(fdt_final: Vec<u8>, guest_mem: &GuestMemoryMmap) -> Result<()> {
// Write FDT to memory.
let fdt_address = GuestAddress(get_fdt_addr());
guest_mem
.write_slice(fdt_final.as_slice(), fdt_address)
.write_slice(fdt_final.as_slice(), super::layout::FDT_START)
.map_err(Error::WriteFdtToMemory)?;
Ok(())
}
@@ -231,40 +229,67 @@ fn create_memory_node(
guest_mem: &GuestMemoryMmap,
numa_nodes: &NumaNodes,
) -> FdtWriterResult<()> {
// See https://github.com/torvalds/linux/blob/58ae0b51506802713aa0e9956d1853ba4c722c98/Documentation/devicetree/bindings/numa.txt
// for NUMA setting in memory node.
if numa_nodes.len() > 1 {
for numa_node_idx in 0..numa_nodes.len() {
let numa_node = numa_nodes.get(&(numa_node_idx as u32));
let mut mem_reg_prop: Vec<u64> = Vec::new();
let mut node_memory_addr: u64 = 0;
// Each memory zone of numa will have its own memory node, but
// different numa nodes should not share same memory zones.
for memory_region in numa_node.unwrap().memory_regions.iter() {
let memory_region_start_addr: u64 = memory_region.start_addr().raw_value();
let memory_region_size: u64 = memory_region.size() as u64;
let mem_reg_prop = [memory_region_start_addr, memory_region_size];
// With feature `acpi` enabled, RAM at 0-4M is for edk2 only
// and should be hidden to the guest.
#[cfg(feature = "acpi")]
if memory_region_start_addr == 0 {
continue;
mem_reg_prop.push(memory_region_start_addr);
mem_reg_prop.push(memory_region_size);
// Set the node address the first non-zero regison address
if node_memory_addr == 0 {
node_memory_addr = memory_region_start_addr;
}
let memory_node_name = format!("memory@{:x}", memory_region_start_addr);
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
fdt.end_node(memory_node)?;
}
let memory_node_name = format!("memory@{:x}", node_memory_addr);
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
fdt.end_node(memory_node)?;
}
} else {
let mem_size = guest_mem.last_addr().raw_value() - super::layout::RAM_64BIT_START + 1;
// See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L960
// for an explanation of this.
let mem_reg_prop = [super::layout::RAM_64BIT_START as u64, mem_size as u64];
let memory_node = fdt.begin_node("memory")?;
let last_addr = guest_mem.last_addr().raw_value();
if last_addr < super::layout::MEM_32BIT_RESERVED_START.raw_value() {
// Case 1: all RAM is under the hole
let mem_size = last_addr - super::layout::RAM_START.raw_value() + 1;
let mem_reg_prop = [super::layout::RAM_START.raw_value() as u64, mem_size as u64];
let memory_node = fdt.begin_node("memory")?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.end_node(memory_node)?;
} else {
// Case 2: RAM is split by the hole
// Region 1: RAM before the hole
let mem_size = super::layout::MEM_32BIT_RESERVED_START.raw_value()
- super::layout::RAM_START.raw_value();
let mem_reg_prop = [super::layout::RAM_START.raw_value() as u64, mem_size as u64];
let memory_node_name = format!("memory@{:x}", super::layout::RAM_START.raw_value());
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.end_node(memory_node)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.end_node(memory_node)?;
// Region 2: RAM after the hole
let mem_size = last_addr - super::layout::RAM_64BIT_START.raw_value() + 1;
let mem_reg_prop = [
super::layout::RAM_64BIT_START.raw_value() as u64,
mem_size as u64,
];
let memory_node_name =
format!("memory@{:x}", super::layout::RAM_64BIT_START.raw_value());
let memory_node = fdt.begin_node(&memory_node_name)?;
fdt.property_string("device_type", "memory")?;
fdt.property_array_u64("reg", &mem_reg_prop)?;
fdt.end_node(memory_node)?;
}
}
Ok(())
@@ -548,20 +573,19 @@ fn create_pci_nodes(
// could fall bellow 4G.
// Here we cut off PCI device space below 8G in FDT to workaround the EDK2 check.
// But the address written in ACPI is not impacted.
let (pci_device_base_64bit, pci_device_size_64bit) = if cfg!(feature = "acpi")
&& (pci_device_info_elem.pci_device_space_start < PCI_HIGH_BASE)
{
(
PCI_HIGH_BASE,
pci_device_info_elem.pci_device_space_size
- (PCI_HIGH_BASE - pci_device_info_elem.pci_device_space_start),
)
} else {
(
pci_device_info_elem.pci_device_space_start,
pci_device_info_elem.pci_device_space_size,
)
};
let (pci_device_base_64bit, pci_device_size_64bit) =
if pci_device_info_elem.pci_device_space_start < PCI_HIGH_BASE.raw_value() {
(
PCI_HIGH_BASE.raw_value(),
pci_device_info_elem.pci_device_space_size
- (PCI_HIGH_BASE.raw_value() - pci_device_info_elem.pci_device_space_start),
)
} else {
(
pci_device_info_elem.pci_device_space_start,
pci_device_info_elem.pci_device_space_size,
)
};
// There is no specific requirement of the 32bit MMIO range, and
// therefore at least we can make these ranges 4K aligned.
let pci_device_size_32bit: u64 =

View File

@@ -22,6 +22,7 @@ pub mod kvm {
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,
@@ -83,7 +84,7 @@ pub mod kvm {
/// Get the address of the GIC distributor.
pub fn get_dist_addr() -> u64 {
layout::GIC_V3_DIST_START
layout::GIC_V3_DIST_START.raw_value()
}
/// Get the size of the GIC distributor.

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//
// Memory layout of Aarch64 guest:
// Memory layout of AArch64 guest:
//
// Physical +---------------------------------------------------------------+
// address | |
@@ -20,6 +20,13 @@
// | DRAM |
// | |
// | |
// 4GB +---------------------------------------------------------------+
// | 32-bit devices hole |
// 4GB-64M +---------------------------------------------------------------+
// | |
// | |
// | DRAM |
// | |
// | |
// 1GB +---------------------------------------------------------------+
// | |
@@ -35,11 +42,11 @@
// | Legacy devices space |
// | |
// 144 M +---------------------------------------------------------------|
// | |
// | Reserved (now GIC is here) |
// 64 M +---------------------------------------------------------------+
// | |
// | UEFI space |
// | |
// 4 M +---------------------------------------------------------------+
// | UEFI flash |
// 0GB +---------------------------------------------------------------+
//
//
@@ -48,17 +55,16 @@ use vm_memory::GuestAddress;
/// 0x0 ~ 0x40_0000 (4 MiB) is reserved to UEFI
/// UEFI binary size is required less than 3 MiB, reserving 4 MiB is enough.
pub const UEFI_START: u64 = 0x0;
pub const MEM_UEFI_START: GuestAddress = GuestAddress(0);
pub const UEFI_START: GuestAddress = GuestAddress(0);
pub const UEFI_SIZE: u64 = 0x040_0000;
/// Below this address will reside the GIC, above this address will reside the MMIO devices.
pub const MAPPED_IO_START: u64 = 0x0900_0000;
pub const MAPPED_IO_START: GuestAddress = GuestAddress(0x0900_0000);
/// See kernel file arch/arm64/include/uapi/asm/kvm.h for the GIC related definitions.
/// 0x08ff_0000 ~ 0x0900_0000 is reserved for GICv3 Distributor
pub const GIC_V3_DIST_SIZE: u64 = 0x01_0000;
pub const GIC_V3_DIST_START: u64 = MAPPED_IO_START - GIC_V3_DIST_SIZE;
pub const GIC_V3_DIST_START: GuestAddress = GuestAddress(MAPPED_IO_START.0 - GIC_V3_DIST_SIZE);
/// Below 0x08ff_0000 is reserved for GICv3 Redistributor.
/// The size defined here is for each vcpu.
/// The total size is 'number_of_vcpu * GIC_V3_REDIST_SIZE'
@@ -67,9 +73,9 @@ pub const GIC_V3_REDIST_SIZE: u64 = 0x02_0000;
pub const GIC_V3_ITS_SIZE: u64 = 0x02_0000;
/// Space 0x0900_0000 ~ 0x0905_0000 is reserved for legacy devices.
pub const LEGACY_SERIAL_MAPPED_IO_START: u64 = 0x0900_0000;
pub const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000;
pub const LEGACY_GPIO_MAPPED_IO_START: u64 = 0x0902_0000;
pub const LEGACY_SERIAL_MAPPED_IO_START: GuestAddress = GuestAddress(0x0900_0000);
pub const LEGACY_RTC_MAPPED_IO_START: GuestAddress = GuestAddress(0x0901_0000);
pub const LEGACY_GPIO_MAPPED_IO_START: GuestAddress = GuestAddress(0x0902_0000);
/// Space 0x0905_0000 ~ 0x0906_0000 is reserved for pcie io address
pub const MEM_PCI_IO_START: GuestAddress = GuestAddress(0x0905_0000);
@@ -85,8 +91,15 @@ pub const PCI_MMCONFIG_SIZE: u64 = 256 << 20;
// One bus with potentially 256 devices (32 slots x 8 functions).
pub const PCI_MMIO_CONFIG_SIZE_PER_SEGMENT: u64 = 4096 * 256;
/// Start of RAM on 64 bit ARM.
pub const RAM_64BIT_START: u64 = 0x4000_0000;
/// Start of RAM.
pub const RAM_START: GuestAddress = GuestAddress(0x4000_0000);
/// 32-bit reserved area: 64MiB before 4GiB
pub const MEM_32BIT_RESERVED_START: GuestAddress = GuestAddress(0xfc00_0000);
pub const MEM_32BIT_RESERVED_SIZE: u64 = 0x0400_0000;
/// Start of 64-bit RAM.
pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);
/// Kernel command line maximum size.
/// As per `arch/arm64/include/uapi/asm/setup.h`.
@@ -94,19 +107,19 @@ pub const CMDLINE_MAX_SIZE: usize = 2048;
/// FDT is at the beginning of RAM.
/// Maximum size of the device tree blob as specified in https://www.kernel.org/doc/Documentation/arm64/booting.txt.
pub const FDT_START: u64 = RAM_64BIT_START;
pub const FDT_MAX_SIZE: usize = 0x20_0000;
pub const FDT_START: GuestAddress = RAM_START;
pub const FDT_MAX_SIZE: u64 = 0x20_0000;
/// Put ACPI table above dtb
pub const ACPI_START: u64 = RAM_64BIT_START + FDT_MAX_SIZE as u64;
pub const ACPI_MAX_SIZE: usize = 0x20_0000;
pub const RSDP_POINTER: GuestAddress = GuestAddress(ACPI_START);
pub const ACPI_START: GuestAddress = GuestAddress(RAM_START.0 + FDT_MAX_SIZE);
pub const ACPI_MAX_SIZE: u64 = 0x20_0000;
pub const RSDP_POINTER: GuestAddress = ACPI_START;
/// Kernel start after FDT and ACPI
pub const KERNEL_START: u64 = ACPI_START + ACPI_MAX_SIZE as u64;
pub const KERNEL_START: GuestAddress = GuestAddress(ACPI_START.0 + ACPI_MAX_SIZE);
/// Pci high memory base
pub const PCI_HIGH_BASE: u64 = 0x2_0000_0000_u64;
pub const PCI_HIGH_BASE: GuestAddress = GuestAddress(0x2_0000_0000);
// As per virt/kvm/arm/vgic/vgic-kvm-device.c we need
// the number of interrupts our GIC will support to be:

View File

@@ -78,31 +78,11 @@ pub fn configure_vcpu(
}
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> {
// Normally UEFI should be loaded to a flash area at the beginning of memory.
// But now flash memory type is not supported.
// As a workaround, we take 4 MiB memory from the main RAM for UEFI.
// As a result, the RAM that the guest can see is less than what has been
// assigned in command line, when ACPI and UEFI is enabled.
let ram_deduction = if cfg!(feature = "acpi") {
layout::UEFI_SIZE
} else {
0
};
vec![
// 0 ~ 4 MiB: Reserved for UEFI space
#[cfg(feature = "acpi")]
(GuestAddress(0), layout::UEFI_SIZE as usize, RegionType::Ram),
#[cfg(not(feature = "acpi"))]
let mut regions = vec![
// 0 MiB ~ 256 MiB: UEFI, GIC and legacy devices
(
GuestAddress(0),
layout::UEFI_SIZE as usize,
RegionType::Reserved,
),
// 4 MiB ~ 256 MiB: Gic and legacy devices
(
GuestAddress(layout::UEFI_SIZE),
(layout::MEM_32BIT_DEVICES_START.0 - layout::UEFI_SIZE) as usize,
layout::MEM_32BIT_DEVICES_START.0 as usize,
RegionType::Reserved,
),
// 256 MiB ~ 768 MiB: MMIO space
@@ -117,13 +97,39 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
layout::PCI_MMCONFIG_SIZE as usize,
RegionType::Reserved,
),
// 1 GiB ~ : Ram
(
GuestAddress(layout::RAM_64BIT_START),
(size - ram_deduction) as usize,
];
let ram_32bit_space_size =
layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START);
// RAM space
// Case1: guest memory fits before the gap
if size as u64 <= ram_32bit_space_size {
regions.push((layout::RAM_START, size as usize, RegionType::Ram));
// Case2: guest memory extends beyond the gap
} else {
// Push memory before the gap
regions.push((
layout::RAM_START,
ram_32bit_space_size as usize,
RegionType::Ram,
),
]
));
// Other memory is placed after 4GiB
regions.push((
layout::RAM_64BIT_START,
(size - ram_32bit_space_size) as usize,
RegionType::Ram,
));
}
// Add the 32-bit reserved memory hole as a reserved region
regions.push((
layout::MEM_32BIT_RESERVED_START,
layout::MEM_32BIT_RESERVED_SIZE as usize,
RegionType::Reserved,
));
regions
}
/// Configures the system and should be called once per vm before starting vcpu threads.
@@ -186,21 +192,6 @@ pub fn initramfs_load_addr(
}
}
/// Returns the memory address where the kernel could be loaded.
pub fn get_kernel_start() -> u64 {
layout::KERNEL_START
}
///Return guest memory address where the uefi should be loaded.
pub fn get_uefi_start() -> u64 {
layout::UEFI_START
}
// Auxiliary function to get the address where the device tree blob is loaded.
fn get_fdt_addr() -> u64 {
layout::FDT_START
}
pub fn get_host_cpu_phys_bits() -> u8 {
// A dummy hypervisor created only for querying the host IPA size and will
// be freed after the query.
@@ -220,11 +211,26 @@ mod tests {
use super::*;
#[test]
fn test_arch_memory_regions_dram() {
let regions = arch_memory_regions((1usize << 32) as u64); //4GB
fn test_arch_memory_regions_dram_2gb() {
let regions = arch_memory_regions((1usize << 31) as u64); //2GB
assert_eq!(5, regions.len());
assert_eq!(GuestAddress(layout::RAM_64BIT_START), regions[4].0);
assert_eq!(1usize << 32, regions[4].1);
assert_eq!(layout::RAM_START, regions[3].0);
assert_eq!((1usize << 31), regions[3].1);
assert_eq!(RegionType::Ram, regions[3].2);
assert_eq!(RegionType::Reserved, regions[4].2);
}
#[test]
fn test_arch_memory_regions_dram_4gb() {
let regions = arch_memory_regions((1usize << 32) as u64); //4GB
let ram_32bit_space_size =
layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START) as usize;
assert_eq!(6, regions.len());
assert_eq!(layout::RAM_START, regions[3].0);
assert_eq!(ram_32bit_space_size as usize, regions[3].1);
assert_eq!(RegionType::Ram, regions[3].2);
assert_eq!(RegionType::Reserved, regions[5].2);
assert_eq!(RegionType::Ram, regions[4].2);
assert_eq!(((1usize << 32) - ram_32bit_space_size), regions[4].1);
}
}

View File

@@ -5,13 +5,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use super::get_fdt_addr;
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)]
@@ -67,7 +67,7 @@ pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, cpu_id: u8, boot_ip: u64) ->
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
vcpu.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0),
get_fdt_addr() as u64,
super::layout::FDT_START.raw_value(),
)
.map_err(Error::SetCoreRegister)?;
}

View File

@@ -85,8 +85,8 @@ pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt,
get_host_cpu_phys_bits, get_kernel_start, get_uefi_start, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, uefi, EntryPoint,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::IRQ_BASE, uefi, EntryPoint,
};
#[cfg(target_arch = "x86_64")]
@@ -158,6 +158,7 @@ impl fmt::Display for DeviceType {
#[cfg(target_arch = "aarch64")]
pub struct MmioDeviceInfo {
pub addr: u64,
pub len: u64,
pub irq: u32,
}
@@ -180,6 +181,6 @@ impl DeviceInfoForFdt for MmioDeviceInfo {
self.irq
}
fn length(&self) -> u64 {
4096
self.len
}
}

View File

@@ -24,6 +24,9 @@ pub const LOW_RAM_START: GuestAddress = GuestAddress(0x0);
// == Fixed addresses within the "Low RAM" range: ==
// Location of EBDA address
pub const EBDA_POINTER: GuestAddress = GuestAddress(0x40e);
// Initial GDT/IDT needed to boot kernel
pub const BOOT_GDT_START: GuestAddress = GuestAddress(0x500);
pub const BOOT_IDT_START: GuestAddress = GuestAddress(0x520);

View File

@@ -186,6 +186,13 @@ pub enum Error {
/// Error checking CPUID compatibility
CpuidCheckCompatibility,
// Error writing EBDA address
EbdaSetup(vm_memory::GuestMemoryError),
/// Error retrieving TDX capabilities through the hypervisor (kvm/mshv) API
#[cfg(feature = "tdx")]
TdxCapabilities(HypervisorError),
}
impl From<Error> for super::Error {
@@ -597,9 +604,39 @@ pub fn generate_common_cpuid(
update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?;
}
#[cfg(feature = "tdx")]
let tdx_capabilities = if tdx_enabled {
let caps = hypervisor
.tdx_capabilities()
.map_err(Error::TdxCapabilities)?;
info!("TDX capabilities {:#?}", caps);
Some(caps)
} else {
None
};
// Update some existing CPUID
for entry in cpuid.as_mut_slice().iter_mut() {
match entry.function {
0xd =>
{
#[cfg(feature = "tdx")]
if let Some(caps) = &tdx_capabilities {
let xcr0_mask: u64 = 0x82ff;
let xss_mask: u64 = !xcr0_mask;
if entry.index == 0 {
entry.eax &= (caps.xfam_fixed0 as u32) & (xcr0_mask as u32);
entry.eax |= (caps.xfam_fixed1 as u32) & (xcr0_mask as u32);
entry.edx &= ((caps.xfam_fixed0 & xcr0_mask) >> 32) as u32;
entry.edx |= ((caps.xfam_fixed1 & xcr0_mask) >> 32) as u32;
} else if entry.index == 1 {
entry.ecx &= (caps.xfam_fixed0 as u32) & (xss_mask as u32);
entry.ecx |= (caps.xfam_fixed1 as u32) & (xss_mask as u32);
entry.edx &= ((caps.xfam_fixed0 & xss_mask) >> 32) as u32;
entry.edx |= ((caps.xfam_fixed1 & xss_mask) >> 32) as u32;
}
}
}
// Set CPU physical bits
0x8000_0008 => {
entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff);
@@ -802,6 +839,11 @@ pub fn configure_system(
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
) -> 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)?;
// Place the MP table after the SMIOS table aligned to 16 bytes

View File

@@ -324,10 +324,10 @@ impl TdHob {
},
/* TODO:
* QEMU currently fills it in like this:
* EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_ENCRYPTED | EFI_RESOURCE_ATTRIBUTE_TESTED
* EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED
* which differs from the spec (due to TDVF implementation issue?)
*/
0x04000007,
0x7,
)
}

View File

@@ -2,22 +2,22 @@
name = "block_util"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[features]
default = []
[dependencies]
io-uring = "0.5.2"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
qcow = { path = "../qcow" }
thiserror = "1.0.30"
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 = { git = "https://github.com/rust-vmm/vm-virtio", branch = "main" }
virtio-queue = "0.2.0"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"

View File

@@ -209,7 +209,7 @@ impl Request {
let hdr_desc_addr = hdr_desc
.addr()
.translate(access_platform, hdr_desc.len() as usize);
.translate_gva(access_platform, hdr_desc.len() as usize);
let mut req = Request {
request_type: request_type(desc_chain.memory(), hdr_desc_addr)?,
@@ -249,7 +249,8 @@ impl Request {
}
req.data_descriptors.push((
desc.addr().translate(access_platform, desc.len() as usize),
desc.addr()
.translate_gva(access_platform, desc.len() as usize),
desc.len(),
));
desc = desc_chain
@@ -274,7 +275,7 @@ impl Request {
req.status_addr = status_desc
.addr()
.translate(access_platform, status_desc.len() as usize);
.translate_gva(access_platform, status_desc.len() as usize);
Ok(req)
}

View File

@@ -2,17 +2,17 @@
name = "devices"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
edition = "2018"
edition = "2021"
[dependencies]
acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0.55"
acpi_tables = { path = "../acpi_tables" }
anyhow = "1.0.56"
arch = { path = "../arch" }
bitflags = "1.3.2"
byteorder = "1.4.3"
epoll = "4.3.1"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-device = { path = "../vm-device" }
@@ -22,6 +22,5 @@ vmm-sys-util = "0.9.0"
[features]
default = []
acpi = ["acpi_tables"]
cmos = []
fwdebug = []

View File

@@ -102,7 +102,6 @@ impl BusDevice for AcpiGedDevice {
}
}
#[cfg(feature = "acpi")]
impl Aml for AcpiGedDevice {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
aml::Device::new(

View File

@@ -76,6 +76,7 @@ impl InterruptController for Gic {
.update(
i as InterruptIndex,
InterruptSourceConfig::LegacyIrq(config),
false,
)
.map_err(Error::EnableInterrupt)?;
}

View File

@@ -367,19 +367,13 @@ impl Ioapic {
};
self.interrupt_source_group
.update(irq as InterruptIndex, InterruptSourceConfig::MsiIrq(config))
.update(
irq as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
interrupt_mask(entry) == 1,
)
.map_err(Error::UpdateInterrupt)?;
if interrupt_mask(entry) == 1 {
self.interrupt_source_group
.mask(irq as InterruptIndex)
.map_err(Error::MaskInterrupt)?;
} else {
self.interrupt_source_group
.unmask(irq as InterruptIndex)
.map_err(Error::UnmaskInterrupt)?;
}
Ok(())
}
}

View File

@@ -7,6 +7,7 @@ use std::cmp::min;
use std::mem;
use std::sync::{Arc, Barrier};
use vm_device::BusDevice;
use vmm_sys_util::eventfd::EventFd;
// https://github.com/rust-lang/libc/issues/1848
#[cfg_attr(target_env = "musl", allow(deprecated))]
@@ -21,13 +22,14 @@ const DATA_LEN: usize = 128;
pub struct Cmos {
index: u8,
data: [u8; DATA_LEN],
reset_evt: EventFd,
}
impl Cmos {
/// Constructs a CMOS/RTC device with initial data.
/// `mem_below_4g` is the size of memory in bytes below the 32-bit gap.
/// `mem_above_4g` is the size of memory in bytes above the 32-bit gap.
pub fn new(mem_below_4g: u64, mem_above_4g: u64) -> Cmos {
pub fn new(mem_below_4g: u64, mem_above_4g: u64, reset_evt: EventFd) -> Cmos {
let mut data = [0u8; DATA_LEN];
// Extended memory from 16 MB to 4 GB in units of 64 KB
@@ -44,7 +46,11 @@ impl Cmos {
data[0x5c] = (high_mem >> 8) as u8;
data[0x5d] = (high_mem >> 16) as u8;
Cmos { index: 0, data }
Cmos {
index: 0,
data,
reset_evt,
}
}
}
@@ -56,8 +62,15 @@ impl BusDevice for Cmos {
}
match offset {
INDEX_OFFSET => self.index = data[0] & INDEX_MASK,
DATA_OFFSET => self.data[self.index as usize] = data[0],
INDEX_OFFSET => self.index = data[0],
DATA_OFFSET => {
if self.index == 0x8f && data[0] == 0 {
info!("CMOS reset");
self.reset_evt.write(1).unwrap();
} else {
self.data[(self.index & INDEX_MASK) as usize] = data[0]
}
}
o => warn!("bad write offset on CMOS device: {}", o),
};
None

View File

@@ -356,6 +356,7 @@ mod tests {
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
_masked: bool,
) -> result::Result<(), std::io::Error> {
Ok(())
}

View File

@@ -5,7 +5,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
#[cfg(feature = "cmos")]
mod cmos;
#[cfg(feature = "fwdebug")]
mod fwdebug;
@@ -18,7 +17,6 @@ mod serial;
#[cfg(target_arch = "aarch64")]
mod uart_pl011;
#[cfg(feature = "cmos")]
pub use self::cmos::Cmos;
#[cfg(feature = "fwdebug")]
pub use self::fwdebug::FwDebugDevice;

View File

@@ -430,6 +430,7 @@ mod tests {
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
_masked: bool,
) -> result::Result<(), std::io::Error> {
Ok(())
}

View File

@@ -339,6 +339,7 @@ mod tests {
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
_masked: bool,
) -> result::Result<(), std::io::Error> {
Ok(())
}

View File

@@ -34,6 +34,7 @@ const UARTRIS: u64 = 15;
const UARTMIS: u64 = 16;
const UARTICR: u64 = 17;
const UARTDMACR: u64 = 18;
const UARTDEBUG: u64 = 0x3c0;
const PL011_INT_TX: u32 = 0x20;
const PL011_INT_RX: u32 = 0x10;
@@ -77,6 +78,7 @@ pub struct Pl011 {
rsr: u32,
cr: u32,
dmacr: u32,
debug: u32,
int_enabled: u32,
int_level: u32,
read_fifo: VecDeque<u8>,
@@ -88,6 +90,7 @@ pub struct Pl011 {
read_trigger: u32,
irq: Arc<dyn InterruptSourceGroup>,
out: Option<Box<dyn io::Write + Send>>,
timestamp: std::time::Instant,
}
#[derive(Versionize)]
@@ -97,6 +100,7 @@ pub struct Pl011State {
rsr: u32,
cr: u32,
dmacr: u32,
debug: u32,
int_enabled: u32,
int_level: u32,
read_fifo: Vec<u8>,
@@ -124,6 +128,7 @@ impl Pl011 {
rsr: 0u32,
cr: 0x300u32,
dmacr: 0u32,
debug: 0u32,
int_enabled: 0u32,
int_level: 0u32,
read_fifo: VecDeque::new(),
@@ -135,6 +140,7 @@ impl Pl011 {
read_trigger: 1u32,
irq,
out,
timestamp: std::time::Instant::now(),
}
}
@@ -149,6 +155,7 @@ impl Pl011 {
rsr: self.rsr,
cr: self.cr,
dmacr: self.dmacr,
debug: self.debug,
int_enabled: self.int_enabled,
int_level: self.int_level,
read_fifo: self.read_fifo.clone().into(),
@@ -167,6 +174,7 @@ impl Pl011 {
self.rsr = state.rsr;
self.cr = state.cr;
self.dmacr = state.dmacr;
self.debug = state.debug;
self.int_enabled = state.int_enabled;
self.int_level = state.int_level;
self.read_fifo = state.read_fifo.clone().into();
@@ -280,13 +288,50 @@ impl Pl011 {
return Err(Error::DmaNotImplemented);
}
}
UARTDEBUG => {
self.debug = val;
self.handle_debug();
}
off => {
debug!("PL011: Bad write offset, offset: {}", off);
return Err(Error::BadWriteOffset(off));
}
}
Ok(())
}
fn handle_debug(&self) {
let elapsed = self.timestamp.elapsed();
match self.debug {
0x00..=0x1f => info!(
"[Debug I/O port: Firmware code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x20..=0x3f => info!(
"[Debug I/O port: Bootloader code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x40..=0x5f => info!(
"[Debug I/O port: Kernel code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
0x60..=0x7f => info!(
"[Debug I/O port: Userspace code: 0x{:x}] {}.{:>06} seconds",
self.debug,
elapsed.as_secs(),
elapsed.as_micros()
),
_ => {}
}
}
fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> {
self.irq.trigger(0)
}
@@ -327,6 +372,7 @@ impl BusDevice for Pl011 {
UARTRIS => self.int_level,
UARTMIS => (self.int_level & self.int_enabled),
UARTDMACR => self.dmacr,
UARTDEBUG => self.debug,
_ => {
read_ok = false;
0
@@ -404,6 +450,7 @@ mod tests {
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
_masked: bool,
) -> result::Result<(), std::io::Error> {
Ok(())
}

View File

@@ -12,7 +12,6 @@ extern crate bitflags;
#[macro_use]
extern crate log;
#[cfg(feature = "acpi")]
pub mod acpi;
#[cfg(target_arch = "aarch64")]
pub mod gic;
@@ -21,7 +20,6 @@ pub mod interrupt_controller;
pub mod ioapic;
pub mod legacy;
#[cfg(feature = "acpi")]
pub use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice};
bitflags! {

View File

@@ -88,6 +88,8 @@ Reboot the VM | `/vm.reboot` | N/A
Trigger power button of the VM | `/vm.power-button` | N/A | N/A | The VM is booted
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
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
Add/remove memory from a zone | `/vm.resize-zone` | `/schemas/VmResizeZone` | N/A | The VM is booted
@@ -98,6 +100,7 @@ Add fs device to the VM | `/vm.add-fs` | `/schemas/FsConfig`
Add pmem device to the VM | `/vm.add-pmem` | `/schemas/PmemConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add network device to the VM | `/vm.add-net` | `/schemas/NetConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add userspace PCI device to the VM | `/vm.add-user-device`| `/schemas/VmAddUserDevice`| `/schemas/PciDeviceInfo` | The VM is booted
Add vdpa device to the VM | `/vm.add-vdpa` | `/schemas/VdpaConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add vsock device to the VM | `/vm.add-vsock` | `/schemas/VsockConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Remove device from the VM | `/vm.remove-device` | `/schemas/VmRemoveDevice` | N/A | The VM is booted
Dump the VM counters | `/vm.counters` | N/A | `/schemas/VmCounters` | The VM is booted

76
docs/balloon.md Normal file
View File

@@ -0,0 +1,76 @@
# Balloon
Cloud Hypervisor implements a balloon device based on the VIRTIO specification.
Its main purpose is to provide the host a way to reclaim memory by controlling
the amount of memory visible to the guest. But it also provides some interesting
features related to guest memory management.
## Parameters
`BalloonConfig` (known as `--balloon` from the CLI perspective) contains the
list of parameters available for the balloon device.
```rust
struct BalloonConfig {
pub size: u64,
pub deflate_on_oom: bool,
pub free_page_reporting: bool,
}
```
```
--balloon <balloon> Balloon parameters "size=<balloon_size>,deflate_on_oom=on|off,free_page_reporting=on|off"
```
### `size`
Size of the balloon device. It is subtracted from the VM's total size. For
instance, if creating a VM with 4GiB of RAM, along with a balloon of 1GiB, the
guest will be able to use 3GiB of accessible memory. The guest sees all the RAM
and unless it is balloon enlightened is entitled to all of it.
This parameter is mandatory.
Value is an unsigned integer of 64 bits corresponding to the balloon size in
bytes.
_Example_
```
--balloon size=1G
```
### `deflate_on_oom`
Allow the guest to deflate the balloon if running Out Of Memory (OOM). Assuming
the balloon size is greater than 0, this means the guest is allowed to reduce
the balloon size all the way down to 0 if this can help recover from the OOM
event.
This parameter is optional.
Value is a boolean set to `off` by default.
_Example_
```
--ballloon size=2G,deflate_on_oom=on
```
### `free_page_reporting`
Allow the guest to report lists of free pages. This feature doesn't require the
balloon to be of any specific size as it doesn't impact the balloon size. The
guest can let the VMM know about pages that are free after they have been used.
Based on this information, the VMM can advise the host that it doesn't need
these pages anymore.
This parameter is optional.
Value is a boolean set to `off` by default.
_Example_
```
--ballloon size=0,free_page_reporting=on
```

View File

@@ -17,11 +17,12 @@ struct CpusConfig {
kvm_hyperv: bool,
max_phys_bits: u8,
affinity: Option<Vec<CpuAffinity>>,
features: CpuFeatures,
}
```
```
--cpus boot=<boot_vcpus>,max=<max_vcpus>,topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,affinity=<list_of_vcpus_with_their_associated_cpuset>
--cpus boot=<boot_vcpus>,max=<max_vcpus>,topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,affinity=<list_of_vcpus_with_their_associated_cpuset>,features=<list_of_features_to_enable>
```
### `boot`
@@ -187,3 +188,24 @@ _Example_
In this example, assuming the host has 4 CPUs, vCPU 0 will run exclusively on
host CPUs 2 and 3, while vCPU 1 will run exclusively on host CPUs 0 and 1.
Because nothing is defined for vCPU 2, it can run on any of the 4 host CPUs.
### `features`
Set of CPU features to enable.
This option allows the user to enable a set of CPU features that are disabled
by default otherwise.
The currently available feature set is: `amx`.
The `amx` feature will enable the x86 extension adding hardware units for
matrix operations (int and float dot products). The goal of the extension is to
provide performance enhancements for these common operations.
_Example_
```
--cpus features=amx
```
In this example the amx CPU feature will be enabled for the VMM.

View File

@@ -1,14 +1,18 @@
# How to use virtio-fs
In the context of virtualization, it is always convenient to be able to share a directory from the host with the guest.
In the context of virtualization, it is always convenient to be able to share a
directory from the host with the guest.
__virtio-fs__, also known as __vhost-user-fs__ is a virtual device defined by the VIRTIO specification which allows any VMM to perform filesystem sharing.
__virtio-fs__, also known as __vhost-user-fs__ is a virtual device defined by
the VIRTIO specification which allows any VMM to perform filesystem sharing.
## Pre-requisites
### The daemon
This virtual device relies on the _vhost-user_ protocol, which assumes the backend (device emulation) is handled by a dedicated process running on the host. This daemon is called __virtiofsd__ and needs to be present on the host.
This virtual device relies on the _vhost-user_ protocol, which assumes the
backend (device emulation) is handled by a dedicated process running on the
host. This daemon is called __virtiofsd__ and needs to be present on the host.
_Build virtiofsd_
```bash
@@ -31,25 +35,35 @@ _Run virtiofsd_
--cache=never
```
The `cache=never` option should be the default when using `virtiofsd` with the __cloud-hypervisor__ VMM. This prevents from using the guest page cache, which reduces the memory footprint of the guest. When running multiple virtual machines on the same host, this will let the host deal with page cache, which will increase the density of virtual machines which can be launched.
The `cache=never` option is the default when using `virtiofsd` with
Cloud Hypervisor. This prevents from using the host page cache, reducing the
overall footprint on host memory. This increases the maximum density of virtual
machines that can be launched on a single host.
The `cache=always` option will allow for the guest page cache to be used, which will increase the memory footprint of the guest. This option should be used only for specific use cases where a single VM is going to be running on a host.
The `cache=always` option will allow the host page cache to be used, which can
result in better performance for the guest's workload at the cost of increasing
the footprint on host memory.
### Kernel support
Modern Linux kernels starting (at least v5.10) have support for virtio-fs. Use
of older kernels, with additional patches, are not supported.
Modern Linux kernels (at least v5.10) have support for virtio-fs. Use of older
kernels, with additional patches, are not supported.
## How to share directories with cloud-hypervisor
### Start the VM
Once the daemon is running, the option `--fs` from __cloud-hypervisor__ needs to be used.
Direct kernel boot is the preferred option, but we can boot from an EFI cloud image if it contains a recent enough kernel.
Once the daemon is running, the option `--fs` from Cloud Hypervisor needs
to be used.
Because _vhost-user_ expects a dedicated process (__virtiofsd__ in this case) to be able to access the guest RAM to communicate through the _virtqueues_ with the driver running in the guest, `--memory` option needs to be slightly modified. It must specify `shared=on` to share the memory pages so that an external process can access them.
Both direct kernel boot and EFI firmware can be used to boot a VM with
virtio-fs, given that the cloud image contains a recent enough kernel.
Assuming you have `focal-server-cloudimg-amd64.raw` and `vmlinux` on your system, here is the __cloud-hypervisor__ command you need to run:
Correct functioning of `--fs` requires `--memory shared=on` to facilitate
interprocess memory sharing.
Assuming you have `focal-server-cloudimg-amd64.raw` and `vmlinux` on your
system, here is the Cloud Hypervisor command you need to run:
```bash
./cloud-hypervisor \
--cpus boot=1 \
@@ -60,26 +74,20 @@ Assuming you have `focal-server-cloudimg-amd64.raw` and `vmlinux` on your system
--fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512
```
By default, DAX is enabled with a cache window of 8GiB. You can specify a custom size (let's say 4GiB for this example) for the cache by explicitly setting DAX and the cache size:
```bash
--fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512,dax=on,cache_size=4G
```
In case you don't want to use a shared window of cache to pass the shared files content, this means you will have to explicitly disable DAX with `dax=off`. Note that in this case, the `cache_size` parameter will be ignored.
```bash
--fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512,dax=off
```
### Mount the shared directory
The last step is to mount the shared directory inside the guest, using the `virtiofs` filesystem type.
The last step is to mount the shared directory inside the guest, using the
`virtiofs` filesystem type.
```bash
mkdir mount_dir
mount -t virtiofs -o dax myfs mount_dir/
mount -t virtiofs myfs mount_dir/
```
The `tag` needs to be consistent with what has been provided through the __cloud-hypervisor__ command line, which happens to be `myfs` in this example.
The `-o dax` option must be removed in case the shared cache region is not enabled from the VMM.
The `tag` needs to be consistent with what has been provided through the
Cloud Hypervisor command line, which happens to be `myfs` in this example.
## DAX feature
Given the DAX feature is not stable yet from a daemon standpoint, it is not
available in Cloud Hypervisor.

View File

@@ -55,9 +55,9 @@ cargo build --features tdx
```
And run a TDX VM by providing the firmware previously built, along with the
guest image containing the TDX enlightened kernel. Assuming the guest kernel
command line contains `console=hvc0` (printing to the `virtio-console` device),
run Cloud Hypervisor as follows:
guest image containing the TDX enlightened kernel. The latest image
`td-guest-rhel8.5.raw` contains `console=hvc0` on the kernel boot parameters,
meaning it will be printing guest kernel logs to the `virtio-console` device.
```bash
./cloud-hypervisor \
@@ -67,8 +67,8 @@ run Cloud Hypervisor as follows:
--disk path=tdx_guest_img
```
And here is the alternative command when looking for debug logs (assuming the
guest kernel command line contains `console=ttyS0`):
And here is the alternative command when looking for debug logs from the
firmware:
```bash
./cloud-hypervisor \
@@ -76,8 +76,8 @@ guest kernel command line contains `console=ttyS0`):
--cpus boot=1 \
--memory size=1G \
--disk path=tdx_guest_img \
--serial tty \
--console off
--serial file=/tmp/ch_serial \
--console tty
```
### TDShim
@@ -97,8 +97,14 @@ option as well.
./cloud-hypervisor \
--tdx firmware=tdshim \
--kernel bzImage \
--cmdline "root=/dev/vda1 console=hvc0 rw tdx_allow_acpi=MCFG"
--cmdline "root=/dev/vda3 console=hvc0 rw"
--cpus boot=1 \
--memory size=1G \
--disk path=tdx_guest_img
```
```
### Guest kernel disables serial ports
The latest guest kernel that can be found in the latest image
`td-guest-rhel8.5.raw` disabled the support for serial ports. This means adding
`console=ttyS0` will have no effect and will not print any log from the guest.

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

@@ -231,3 +231,38 @@ Last thing is to start the L2 guest with the huge pages memory backend.
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--device path=/sys/bus/pci/devices/0000:00:04.0
```
### Dedicated IOMMU PCI segments
To facilitate hotplug of devices that require being behind an IOMMU it is
possible to mark entire PCI segments as behind the IOMMU.
This is accomplished through `--platform
num_pci_segments=<number_of_segments>,iommu_segments=<range of segments>` or
via the equivalents in `PlatformConfig` for the API.
e.g.
```bash
./cloud-hypervisor \
--api-socket=/tmp/api \
--cpus boot=1 \
--memory size=4G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-vmlinux \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--platform num_pci_segments=2,iommu_segments=1
```
This adds a second PCI segment to the platform behind the IOMMU. A VFIO device
requiring the IOMMU then may be hotplugged:
e.g.
```bash
./ch-remote --api-socket=/tmp/api add-device path=/sys/bus/pci/devices/0000:00:04.0,iommu=on,pci_segment=1
```
Devices that cannot be placed behind an IOMMU (e.g. lacking an `iommu=` option)
cannot be placed on the IOMMU segments.

View File

@@ -0,0 +1,29 @@
# Performance Metrics
Cloud Hypervisor provides a [performance metrics](https://github.com/cloud-hypervisor/cloud-hypervisor/tree/main/performance-metrics)
binary for users to generate metrics data from their own
environment. This document describes how to generate metrics data
quickly by using Cloud Hypervisor's development script,
e.g. `dev_cli.sh`. The only prerequisite is [Docker installation](https://docs.docker.com/engine/install/).
Please note that upon its first invocation, this script will pull a
fairly large container image.
To generate metrics data for all available performance tests (including
boot time, block I/O throughput, and network throughput & latency) and
output the result into a json file:
```
$ ./scripts/dev_cli.sh tests --metrics -- -- --report-file /tmp/metrics.json
```
To get a list of available performance tests:
```
$ ./scripts/dev_cli.sh tests --metrics -- -- --list-tests
```
To generate metrics data for selected performance tests, e.g. boot time only:
```
$ ./scripts/dev_cli.sh tests --metrics -- -- --report-file /tmp/metrics.json --test-filter boot_time
```

154
docs/vdpa.md Normal file
View File

@@ -0,0 +1,154 @@
# Virtio Data Path Acceleration
vDPA aims at achieving bare-metal performance for devices passed into a virtual
machine. It is an alternative to VFIO, as it provides a simpler solution for
achieving migration.
It is a kernel framework introduced recently to handle devices complying with
the VIRTIO specification on their data-path, while the control path is vendor
specific. In practice, virtqueues are accessed directly through DMA mechanism
between the hardware and the guest. The control path is accessed through the
vDPA framework, being exposed through the vhost interface as a vhost-vdpa
device.
Because DMA accesses between device and guest are going through virtqueues,
migration can be achieved without requiring device's driver to implement any
specific migration support. In case of VFIO, each vendor is expected to provide
an implementation of the VFIO migration framework, complicating things as it
must be done for each and every device's driver.
The official [website](https://vdpa-dev.gitlab.io/) contains some extensive
documentation on the topic.
## Usage
`VdpaConfig` (known as `--vdpa` from the CLI perspective) contains the list of
parameters available for the vDPA device.
```rust
struct VdpaConfig {
path: PathBuf,
num_queues: usize,
id: Option<String>,
pci_segment: u16,
}
```
```
--vdpa <vdpa> vDPA device "path=<device_path>,num_queues=<number_of_queues>,iommu=on|off,id=<device_id>,pci_segment=<segment_id>"
```
### `path`
Path of the vDPA device. Usually `/dev/vhost-vdpa-X`.
This parameter is mandatory.
Value is a string.
_Example_
```
--vdpa path=/dev/vhost-vdpa-0
```
### `num_queues`
Number of virtqueues supported by the vDPA device.
This parameter is optional.
Value is an unsigned integer set to `1` by default.
_Example_
```
--vdpa path=/dev/vhost-vdpa-0,num_queues=2
```
### `id`
Identifier of the vDPA device.
This parameter is optional. If provided, it must be unique across the entire
virtual machine.
Value is a string.
_Example_
```
--vdpa path=/dev/vhost-vdpa-0,id=vdpa0
```
### `pci_segment`
PCI segment number to which the vDPA device should be attached to.
This parameter is optional.
Value is an unsigned integer of 16 bits set to `0` by default.
_Example_
```
--vdpa path=/dev/vhost-vdpa-0,pci_segment=1
```
## Example with vDPA block simulator
The vDPA framework provides a simulator with both `virtio-block` and
`virtio-net` implementations. This is very useful for testing vDPA when we
don't have access to the specific hardware.
Given the host kernel has the appropriate modules available, let's load them
all:
```
sudo modprobe vdpa
sudo modprobe vhost_vdpa
sudo modprobe vdpa_sim
sudo modprobe vdpa_sim_blk
```
Given you have the `iproute2/vdpa` tool installed, let's now create the
`virtio-block` vDPA device:
```sh
sudo vdpa dev add name vdpa-blk1 mgmtdev vdpasim_blk
sudo chown $USER:$USER /dev/vhost-vdpa-0
sudo chmod 660 /dev/vhost-vdpa-0
```
Increase the maximum locked memory to ensure setting up IOMMU mappings will
succeed:
```sh
ulimit -l unlimited
```
Start Cloud Hypervisor:
```sh
cloud-hypervisor \
--cpus boot=1 \
--memory size=1G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel vmlinux \
--cmdline "root=/dev/vda1 console=hvc0" \
--vdpa path=/dev/vhost-vdpa-0,num_queues=1
```
The `virtio-block` device backed by the vDPA simulator can be found as
`/dev/vdb` in the guest:
```
cloud@cloud:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nullb0 252:0 0 250G 0 disk
vda 254:0 0 2.2G 0 disk
├─vda1 254:1 0 2.1G 0 part /
├─vda14 254:14 0 4M 0 part
└─vda15 254:15 0 106M 0 part /boot/efi
vdb 254:16 0 128M 0 disk
```

View File

@@ -2,10 +2,10 @@
name = "event_monitor"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
libc = "0.2.119"
libc = "0.2.123"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
serde_json = "1.0.79"

68
fuzz/Cargo.lock generated
View File

@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.55"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd"
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
[[package]]
name = "api_client"
@@ -128,9 +128,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.1.5"
version = "3.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312"
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
dependencies = [
"atty",
"bitflags",
@@ -145,7 +145,7 @@ dependencies = [
[[package]]
name = "cloud-hypervisor"
version = "21.0.0"
version = "22.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -185,9 +185,9 @@ dependencies = [
[[package]]
name = "crc32c"
version = "0.6.1"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee6b9c9389584bcba988bd0836086789b7f87ad91892d6a83d5291dbb24524b5"
checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e"
dependencies = [
"rustc_version",
]
@@ -270,9 +270,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
@@ -325,9 +325,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
@@ -377,15 +377,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd"
[[package]]
name = "libfuzzer-sys"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3"
checksum = "336244aaeab6a12df46480dc585802aa743a72d66b11937844c61bbca84c991d"
dependencies = [
"arbitrary",
"cc",
@@ -403,9 +403,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.14"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [
"cfg-if",
]
@@ -469,9 +469,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "option_parser"
@@ -488,9 +488,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
[[package]]
name = "pci"
@@ -518,9 +518,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.36"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
dependencies = [
"unicode-xid",
]
@@ -538,9 +538,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.15"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
@@ -591,9 +591,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
[[package]]
name = "serde"
@@ -656,9 +656,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.86"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
dependencies = [
"proc-macro2",
"quote",
@@ -812,9 +812,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b56bf8f178fc500fe14505fca8b00dec76fc38f2304f461c8d9d7547982311d"
checksum = "53567fd9ab820e4f3cc156f24146882fee3c365194c3e1dea74723265f27fc88"
dependencies = [
"bitflags",
"libc",
@@ -849,6 +849,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"thiserror",
"versionize",
"versionize_derive",
"vhost",
@@ -864,8 +865,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vm-virtio?branch=main#bbb22d43558a76cc7cc9c262c4be870a9e682a86"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3785325315e6496fa88673842ee6cd198b9658e88e8b0e1ad48a5dc818b221dc"
dependencies = [
"log",
"vm-memory",

View File

@@ -3,20 +3,20 @@ name = "cloud-hypervisor-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"
edition = "2021"
[package.metadata]
cargo-fuzz = true
[dependencies]
block_util = { path = "../block_util" }
libc = "0.2.119"
libfuzzer-sys = "0.4.2"
libc = "0.2.123"
libfuzzer-sys = "0.4.3"
qcow = { path = "../qcow" }
seccompiler = "0.2.0"
vhdx = { path = "../vhdx" }
virtio-devices = { path = "../virtio-devices" }
virtio-queue = { git = "https://github.com/rust-vmm/vm-virtio", branch = "main" }
virtio-queue = "0.2.0"
vmm-sys-util = "0.9.0"
vm-virtio = { path = "../vm-virtio" }
vm-memory = "0.7.0"

View File

@@ -2,7 +2,7 @@
name = "hypervisor"
version = "0.1.0"
authors = ["Microsoft Authors"]
edition = "2018"
edition = "2021"
license = "Apache-2.0 OR BSD-3-Clause"
[features]
@@ -11,11 +11,11 @@ mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.55"
anyhow = "1.0.56"
epoll = "4.3.1"
thiserror = "1.0.30"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
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 }

View File

@@ -12,6 +12,8 @@ use crate::vm::Vm;
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;
@@ -59,6 +61,11 @@ pub enum HypervisorError {
///
#[error("Checking extensions:{0}")]
CheckExtensions(#[source] anyhow::Error),
///
/// Failed to retrieve TDX capabilities
///
#[error("Failed to retrieve TDX capabilities:{0}")]
TdxCapabilities(#[source] anyhow::Error),
}
///
@@ -105,4 +112,9 @@ pub trait Hypervisor: Send + Sync {
/// Retrieve AArch64 host maximum IPA size supported by KVM.
///
fn get_host_ipa_limit(&self) -> i32;
///
/// Retrieve TDX capabilities
///
#[cfg(feature = "tdx")]
fn tdx_capabilities(&self) -> Result<TdxCapabilities>;
}

View File

@@ -107,7 +107,6 @@ ioctl_iowr_nr!(KVM_MEMORY_ENCRYPT_OP, KVMIO, 0xba, std::os::raw::c_ulong);
#[cfg(feature = "tdx")]
#[repr(u32)]
enum TdxCommand {
#[allow(dead_code)]
Capabilities = 0,
InitVm,
InitVcpu,
@@ -127,6 +126,34 @@ pub enum TdxExitStatus {
InvalidOperand,
}
#[cfg(feature = "tdx")]
const TDX_MAX_NR_CPUID_CONFIGS: usize = 6;
#[cfg(feature = "tdx")]
#[repr(C)]
#[derive(Debug, Default)]
pub struct TdxCpuidConfig {
pub leaf: u32,
pub sub_leaf: u32,
pub eax: u32,
pub ebx: u32,
pub ecx: u32,
pub edx: u32,
}
#[cfg(feature = "tdx")]
#[repr(C)]
#[derive(Debug, Default)]
pub struct TdxCapabilities {
pub attrs_fixed0: u64,
pub attrs_fixed1: u64,
pub xfam_fixed0: u64,
pub xfam_fixed1: u64,
pub nr_cpuid_configs: u32,
pub padding: u32,
pub cpuid_configs: [TdxCpuidConfig; TDX_MAX_NR_CPUID_CONFIGS],
}
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
pub struct KvmVmState {}
@@ -525,7 +552,7 @@ impl vm::Vm for KvmVm {
let data = TdxInitVm {
max_vcpus,
tsc_khz: 0,
attributes: 1, // TDX1_TD_ATTRIBUTE_DEBUG,
attributes: 0,
cpuid: cpuid.as_fam_struct_ptr() as u64,
mrconfigid: [0; 6],
mrowner: [0; 6],
@@ -762,6 +789,27 @@ impl hypervisor::Hypervisor for KvmHypervisor {
fn get_host_ipa_limit(&self) -> i32 {
self.kvm.get_host_ipa_limit()
}
///
/// Retrieve TDX capabilities
///
#[cfg(feature = "tdx")]
fn tdx_capabilities(&self) -> hypervisor::Result<TdxCapabilities> {
let data = TdxCapabilities {
nr_cpuid_configs: TDX_MAX_NR_CPUID_CONFIGS as u32,
..Default::default()
};
tdx_command(
&self.kvm.as_raw_fd(),
TdxCommand::Capabilities,
0,
&data as *const _ as u64,
)
.map_err(|e| hypervisor::HypervisorError::TdxCapabilities(e.into()))?;
Ok(data)
}
}
/// Vcpu struct for KVM
pub struct KvmVcpu {

View File

@@ -51,6 +51,8 @@ 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;
#[cfg(feature = "kvm")]
pub use kvm::*;
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]

View File

@@ -134,7 +134,7 @@ impl hypervisor::Hypervisor for MshvHypervisor {
}
#[cfg(target_arch = "x86_64")]
///
/// Retrieve the list of MSRs supported by KVM.
/// Retrieve the list of MSRs supported by MSHV.
///
fn get_msr_list(&self) -> hypervisor::Result<MsrList> {
self.mshv

View File

@@ -2,7 +2,7 @@
name = "net_gen"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
edition = "2018"
edition = "2021"
[dependencies]
vmm-sys-util = "0.9.0"

View File

@@ -2,20 +2,20 @@
name = "net_util"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
edition = "2018"
edition = "2021"
[dependencies]
epoll = "4.3.1"
getrandom = "0.2"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.136"
versionize = "0.1.6"
versionize_derive = "0.1.4"
virtio-bindings = "0.1.0"
virtio-queue = { git = "https://github.com/rust-vmm/vm-virtio", branch = "main" }
virtio-queue = "0.2.0"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"

View File

@@ -60,97 +60,103 @@ impl CtrlQueue {
&mut self,
queue: &mut Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
access_platform: Option<&Arc<dyn AccessPlatform>>,
) -> Result<bool> {
) -> Result<()> {
let mut used_desc_heads = Vec::new();
for mut desc_chain in queue.iter().map_err(Error::QueueIterator)? {
let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?;
loop {
for mut desc_chain in queue.iter().map_err(Error::QueueIterator)? {
let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?;
let ctrl_hdr: ControlHeader = desc_chain
.memory()
.read_obj(
ctrl_desc
.addr()
.translate(access_platform, ctrl_desc.len() as usize),
)
.map_err(Error::GuestMemory)?;
let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?;
let ctrl_hdr: ControlHeader = desc_chain
.memory()
.read_obj(
ctrl_desc
.addr()
.translate_gva(access_platform, ctrl_desc.len() as usize),
)
.map_err(Error::GuestMemory)?;
let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?;
let data_desc_addr = data_desc
.addr()
.translate(access_platform, data_desc.len() as usize);
let data_desc_addr = data_desc
.addr()
.translate_gva(access_platform, data_desc.len() as usize);
let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?;
let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?;
let ok = match u32::from(ctrl_hdr.class) {
VIRTIO_NET_CTRL_MQ => {
let queue_pairs = desc_chain
.memory()
.read_obj::<u16>(data_desc_addr)
.map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else if (queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16)
|| (queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16)
{
warn!("Number of MQ pairs out of range: {}", queue_pairs);
false
} else {
info!("Number of MQ pairs requested: {}", queue_pairs);
true
}
}
VIRTIO_NET_CTRL_GUEST_OFFLOADS => {
let features = desc_chain
.memory()
.read_obj::<u64>(data_desc_addr)
.map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else {
let mut ok = true;
for tap in self.taps.iter_mut() {
info!("Reprogramming tap offload with features: {}", features);
tap.set_offload(virtio_features_to_tap_offload(features))
.map_err(|e| {
error!("Error programming tap offload: {:?}", e);
ok = false
})
.ok();
let ok = match u32::from(ctrl_hdr.class) {
VIRTIO_NET_CTRL_MQ => {
let queue_pairs = desc_chain
.memory()
.read_obj::<u16>(data_desc_addr)
.map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else if (queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16)
|| (queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16)
{
warn!("Number of MQ pairs out of range: {}", queue_pairs);
false
} else {
info!("Number of MQ pairs requested: {}", queue_pairs);
true
}
ok
}
}
_ => {
warn!("Unsupported command {:?}", ctrl_hdr);
false
}
};
VIRTIO_NET_CTRL_GUEST_OFFLOADS => {
let features = desc_chain
.memory()
.read_obj::<u64>(data_desc_addr)
.map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else {
let mut ok = true;
for tap in self.taps.iter_mut() {
info!("Reprogramming tap offload with features: {}", features);
tap.set_offload(virtio_features_to_tap_offload(features))
.map_err(|e| {
error!("Error programming tap offload: {:?}", e);
ok = false
})
.ok();
}
ok
}
}
_ => {
warn!("Unsupported command {:?}", ctrl_hdr);
false
}
};
desc_chain
.memory()
.write_obj(
if ok { VIRTIO_NET_OK } else { VIRTIO_NET_ERR } as u8,
status_desc
.addr()
.translate(access_platform, status_desc.len() as usize),
)
.map_err(Error::GuestMemory)?;
let len = ctrl_desc.len() + data_desc.len() + status_desc.len();
used_desc_heads.push((desc_chain.head_index(), len));
}
desc_chain
.memory()
.write_obj(
if ok { VIRTIO_NET_OK } else { VIRTIO_NET_ERR } as u8,
status_desc
.addr()
.translate_gva(access_platform, status_desc.len() as usize),
)
.map_err(Error::GuestMemory)?;
let len = ctrl_desc.len() + data_desc.len() + status_desc.len();
used_desc_heads.push((desc_chain.head_index(), len));
}
for (desc_index, len) in used_desc_heads.iter() {
queue
.add_used(*desc_index, *len)
.map_err(Error::QueueAddUsed)?;
queue
for (desc_index, len) in used_desc_heads.iter() {
queue
.add_used(*desc_index, *len)
.map_err(Error::QueueAddUsed)?;
}
if !queue
.enable_notification()
.map_err(Error::QueueEnableNotification)?;
.map_err(Error::QueueEnableNotification)?
{
break;
}
}
Ok(!used_desc_heads.is_empty())
Ok(())
}
}

View File

@@ -60,7 +60,9 @@ impl TxVirtio {
let mut iovecs = Vec::new();
while let Some(desc) = next_desc {
let desc_addr = desc.addr().translate(access_platform, desc.len() as usize);
let desc_addr = desc
.addr()
.translate_gva(access_platform, desc.len() as usize);
if !desc.is_write_only() && desc.len() > 0 {
let buf = desc_chain
.memory()
@@ -130,9 +132,12 @@ impl TxVirtio {
queue
.add_used(used_desc_head.0, used_desc_head.1)
.map_err(NetQueuePairError::QueueAddUsed)?;
queue
if !queue
.enable_notification()
.map_err(NetQueuePairError::QueueEnableNotification)?;
.map_err(NetQueuePairError::QueueEnableNotification)?
{
break;
}
}
Ok(retry_write)
@@ -189,7 +194,8 @@ impl RxVirtio {
let num_buffers_addr = desc_chain
.memory()
.checked_offset(
desc.addr().translate(access_platform, desc.len() as usize),
desc.addr()
.translate_gva(access_platform, desc.len() as usize),
10,
)
.unwrap();
@@ -197,7 +203,9 @@ impl RxVirtio {
let mut iovecs = Vec::new();
while let Some(desc) = next_desc {
let desc_addr = desc.addr().translate(access_platform, desc.len() as usize);
let desc_addr = desc
.addr()
.translate_gva(access_platform, desc.len() as usize);
if desc.is_write_only() && desc.len() > 0 {
let buf = desc_chain
.memory()
@@ -275,9 +283,12 @@ impl RxVirtio {
queue
.add_used(used_desc_head.0, used_desc_head.1)
.map_err(NetQueuePairError::QueueAddUsed)?;
queue
if !queue
.enable_notification()
.map_err(NetQueuePairError::QueueEnableNotification)?;
.map_err(NetQueuePairError::QueueEnableNotification)?
{
break;
}
}
Ok(exhausted_descs)

View File

@@ -2,4 +2,4 @@
name = "option_parser"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"

View File

@@ -313,6 +313,7 @@ impl<S: FromStr, T: TupleValue> FromStr for Tuple<S, T> {
}
}
#[derive(Default)]
pub struct StringList(pub Vec<String>);
pub enum StringListParseError {

View File

@@ -2,7 +2,7 @@
name = "pci"
version = "0.1.0"
authors = ["Samuel Ortiz <sameo@linux.intel.com>"]
edition = "2018"
edition = "2021"
[features]
default = []
@@ -10,14 +10,14 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.55"
anyhow = "1.0.56"
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.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
serde = "1.0.136"
serde_derive = "1.0.136"
thiserror = "1.0.30"

View File

@@ -201,20 +201,13 @@ impl MsiConfig {
devid: 0,
};
if let Err(e) = self
.interrupt_source_group
.update(idx as InterruptIndex, InterruptSourceConfig::MsiIrq(config))
{
if let Err(e) = self.interrupt_source_group.update(
idx as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
self.cap.vector_masked(idx),
) {
error!("Failed updating vector: {:?}", e);
}
if self.cap.vector_masked(idx) {
if let Err(e) = self.interrupt_source_group.mask(idx as InterruptIndex) {
error!("Failed masking vector: {:?}", e);
}
} else if let Err(e) = self.interrupt_source_group.unmask(idx as InterruptIndex) {
error!("Failed unmasking vector: {:?}", e);
}
}
if !old_enabled {

View File

@@ -132,7 +132,11 @@ impl MsixConfig {
};
self.interrupt_source_group
.update(idx as InterruptIndex, InterruptSourceConfig::MsiIrq(config))
.update(
idx as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
self.masked,
)
.map_err(Error::UpdateInterruptRoute)?;
self.interrupt_source_group
@@ -171,21 +175,13 @@ impl MsixConfig {
devid: self.devid,
};
if let Err(e) = self
.interrupt_source_group
.update(idx as InterruptIndex, InterruptSourceConfig::MsiIrq(config))
{
if let Err(e) = self.interrupt_source_group.update(
idx as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
table_entry.masked(),
) {
error!("Failed updating vector: {:?}", e);
}
if table_entry.masked() {
if let Err(e) = self.interrupt_source_group.mask(idx as InterruptIndex) {
error!("Failed masking vector: {:?}", e);
}
} else if let Err(e) = self.interrupt_source_group.unmask(idx as InterruptIndex)
{
error!("Failed unmasking vector: {:?}", e);
}
}
} else if old_enabled || !old_masked {
debug!("MSI-X disabled for device 0x{:x}", self.devid);
@@ -314,17 +310,10 @@ impl MsixConfig {
if let Err(e) = self.interrupt_source_group.update(
index as InterruptIndex,
InterruptSourceConfig::MsiIrq(config),
table_entry.masked(),
) {
error!("Failed updating vector: {:?}", e);
}
if table_entry.masked() {
if let Err(e) = self.interrupt_source_group.mask(index as InterruptIndex) {
error!("Failed masking vector: {:?}", e);
}
} else if let Err(e) = self.interrupt_source_group.unmask(index as InterruptIndex) {
error!("Failed unmasking vector: {:?}", e);
}
}
// After the MSI-X table entry has been updated, it is necessary to

View File

@@ -506,6 +506,10 @@ impl Drop for VfioUserPciDevice {
if self.common.interrupt.intx_in_use() {
self.common.disable_intx(&self.vfio_wrapper);
}
if let Err(e) = self.client.lock().unwrap().shutdown() {
error!("Failed shutting down vfio-user client: {}", e);
}
}
}

View File

@@ -2,11 +2,11 @@
name = "performance-metrics"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
build = "build.rs"
[dependencies]
clap = { version = "3.1.5", features = ["wrap_help","cargo"] }
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
dirs = "4.0.0"
serde = { version = "1.0.136", features = ["rc"] }
serde_derive = "1.0.136"
@@ -16,4 +16,4 @@ thiserror = "1.0.30"
wait-timeout = "0.2.0"
[build-dependencies]
clap = { version = "3.1.5", features = ["wrap_help"] }
clap = { version = "3.1.8", features = ["cargo"] }

View File

@@ -22,10 +22,6 @@ enum Error {
TestTimeout,
#[error("Error: test failed")]
TestFailed,
#[error("Error creating log file: {0}")]
ReportFileCreation(std::io::Error),
#[error("Error writing log file: {0}")]
ReportFileWrite(std::io::Error),
}
#[derive(Deserialize, Serialize)]
@@ -140,6 +136,7 @@ struct PerformanceTest {
pub name: &'static str,
pub func_ptr: fn(&PerformanceTestControl) -> f64,
pub control: PerformanceTestControl,
unit_adjuster: fn(f64) -> f64,
}
impl PerformanceTest {
@@ -149,10 +146,10 @@ impl PerformanceTest {
metrics.push((self.func_ptr)(&self.control));
}
let mean = mean(&metrics).unwrap();
let std_dev = std_deviation(&metrics).unwrap();
let max = metrics.clone().into_iter().reduce(f64::max).unwrap();
let min = metrics.clone().into_iter().reduce(f64::min).unwrap();
let mean = (self.unit_adjuster)(mean(&metrics).unwrap());
let std_dev = (self.unit_adjuster)(std_deviation(&metrics).unwrap());
let max = (self.unit_adjuster)(metrics.clone().into_iter().reduce(f64::max).unwrap());
let min = (self.unit_adjuster)(metrics.clone().into_iter().reduce(f64::min).unwrap());
PerformanceTestResult {
name: self.name.to_string(),
@@ -200,24 +197,45 @@ fn std_deviation(data: &[f64]) -> Option<f64> {
}
}
mod adjuster {
pub fn identity(v: f64) -> f64 {
v
}
pub fn s_to_ms(v: f64) -> f64 {
v * 1000.0
}
pub fn bps_to_gbps(v: f64) -> f64 {
v / (1_000_000_000_f64)
}
#[allow(non_snake_case)]
pub fn Bps_to_MiBps(v: f64) -> f64 {
v / (1 << 20) as f64
}
}
const TEST_LIST: [PerformanceTest; 15] = [
PerformanceTest {
name: "boot_time_s",
name: "boot_time_ms",
func_ptr: performance_boot_time,
control: PerformanceTestControl {
test_timeout: 2,
test_iterations: 10,
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::s_to_ms,
},
PerformanceTest {
name: "boot_time_pmem_s",
name: "boot_time_pmem_ms",
func_ptr: performance_boot_time_pmem,
control: PerformanceTestControl {
test_timeout: 2,
test_iterations: 10,
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::s_to_ms,
},
PerformanceTest {
name: "virtio_net_latency_us",
@@ -227,9 +245,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
queue_size: Some(256),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::identity,
},
PerformanceTest {
name: "virtio_net_throughput_single_queue_rx_bps",
name: "virtio_net_throughput_single_queue_rx_gbps",
func_ptr: performance_net_throughput,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -237,9 +256,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
net_rx: Some(true),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::bps_to_gbps,
},
PerformanceTest {
name: "virtio_net_throughput_single_queue_tx_bps",
name: "virtio_net_throughput_single_queue_tx_gbps",
func_ptr: performance_net_throughput,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -247,9 +267,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
net_rx: Some(false),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::bps_to_gbps,
},
PerformanceTest {
name: "virtio_net_throughput_multi_queue_rx_bps",
name: "virtio_net_throughput_multi_queue_rx_gbps",
func_ptr: performance_net_throughput,
control: PerformanceTestControl {
num_queues: Some(4),
@@ -257,9 +278,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
net_rx: Some(true),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::bps_to_gbps,
},
PerformanceTest {
name: "virtio_net_throughput_multi_queue_tx_bps",
name: "virtio_net_throughput_multi_queue_tx_gbps",
func_ptr: performance_net_throughput,
control: PerformanceTestControl {
num_queues: Some(4),
@@ -267,9 +289,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
net_rx: Some(false),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::bps_to_gbps,
},
PerformanceTest {
name: "block_read_Bps",
name: "block_read_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(1),
@@ -277,9 +300,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::Read),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_write_Bps",
name: "block_write_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(1),
@@ -287,9 +311,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::Write),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_random_read_Bps",
name: "block_random_read_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(1),
@@ -297,9 +322,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::RandomRead),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_random_write_Bps",
name: "block_random_write_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(1),
@@ -307,9 +333,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::RandomWrite),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_multi_queue_read_Bps",
name: "block_multi_queue_read_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -317,9 +344,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::Read),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_multi_queue_write_Bps",
name: "block_multi_queue_write_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -327,9 +355,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::Write),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_multi_queue_random_read_Bps",
name: "block_multi_queue_random_read_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -337,9 +366,10 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::RandomRead),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
PerformanceTest {
name: "block_multi_queue_random_write_Bps",
name: "block_multi_queue_random_write_MiBps",
func_ptr: performance_block_io,
control: PerformanceTestControl {
num_queues: Some(2),
@@ -347,10 +377,11 @@ const TEST_LIST: [PerformanceTest; 15] = [
fio_ops: Some(FioOps::RandomWrite),
..PerformanceTestControl::default()
},
unit_adjuster: adjuster::Bps_to_MiBps,
},
];
fn run_test_with_timetout(test: &'static PerformanceTest) -> Result<PerformanceTestResult, Error> {
fn run_test_with_timeout(test: &'static PerformanceTest) -> Result<PerformanceTestResult, Error> {
let (sender, receiver) = channel::<Result<PerformanceTestResult, Error>>();
thread::spawn(move || {
println!("Test '{}' running .. ({})", test.name, test.control);
@@ -416,9 +447,16 @@ fn main() {
)
.get_matches();
// It seems that the tool (ethr) used for testing the virtio-net latency
// is not stable on AArch64, and therefore the latency test is currently
// skipped on AArch64.
let test_list: Vec<&PerformanceTest> = TEST_LIST
.iter()
.filter(|t| !(cfg!(target_arch = "aarch64") && t.name == "virtio_net_latency_us"))
.collect();
if cmd_arguments.is_present("list-tests") {
println!("List of available metrics tests:\n");
for test in TEST_LIST.iter() {
for test in test_list.iter() {
println!("\"{}\" ({})", test.name, test.control);
}
@@ -430,31 +468,20 @@ fn main() {
None => Vec::new(),
};
let mut report_file: Box<dyn std::io::Write + Send> =
if let Some(file) = cmd_arguments.value_of("report-file") {
Box::new(
std::fs::File::create(std::path::Path::new(file))
.map_err(Error::ReportFileCreation)
.unwrap(),
)
} else {
Box::new(std::io::stderr())
};
// Run performance tests sequentially and report results (in both readable/json format)
let mut metrics_report: MetricsReport = Default::default();
init_tests();
for test in TEST_LIST.iter() {
for test in test_list.iter() {
if test_filter.is_empty() || test_filter.iter().any(|&s| test.name.contains(s)) {
match run_test_with_timetout(test) {
match run_test_with_timeout(test) {
Ok(r) => {
metrics_report.results.push(r);
}
Err(e) => {
eprintln!("Aborting test due to error: '{:?}'", e);
break;
std::process::exit(1);
}
};
}
@@ -462,13 +489,29 @@ fn main() {
cleanup_tests();
// Todo: Report/upload to the metrics database
let mut report_file: Box<dyn std::io::Write + Send> =
if let Some(file) = cmd_arguments.value_of("report-file") {
Box::new(
std::fs::File::create(std::path::Path::new(file))
.map_err(|e| {
eprintln!("Error opening report file: {}: {}", file, e);
std::process::exit(1);
})
.unwrap(),
)
} else {
Box::new(std::io::stdout())
};
report_file
.write(
.write_all(
serde_json::to_string_pretty(&metrics_report)
.unwrap()
.as_bytes(),
)
.map_err(Error::ReportFileWrite)
.map_err(|e| {
eprintln!("Error writing report file: {}", e);
std::process::exit(1);
})
.unwrap();
}

View File

@@ -17,7 +17,10 @@ use test_infra::Error as InfraError;
use test_infra::*;
use wait_timeout::ChildExt;
#[cfg(target_arch = "x86_64")]
pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-amd64-custom-20210609-0.raw";
#[cfg(target_arch = "aarch64")]
pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-arm64-custom-20210929-0-update-tool.raw";
#[derive(Debug)]
enum WaitTimeoutError {
@@ -618,7 +621,6 @@ fn parse_fio_output(output: &str, fio_ops: &FioOps, num_jobs: u32) -> Result<f64
pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
let test_timeout = control.test_timeout;
let num_queues = control.num_queues.unwrap();
let queue_size = control.queue_size.unwrap();
let fio_ops = control.fio_ops.as_ref().unwrap();
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
@@ -636,7 +638,20 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
.args(&["--memory", "size=4G"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.args(&[
"--disk",
format!(
"path={}",
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
)
.as_str(),
format!(
"path={}",
guest.disk_config.disk(DiskType::CloudInit).unwrap()
)
.as_str(),
format!("path={}", BLK_IO_TEST_IMG).as_str(),
])
.default_net()
.args(&["--api-socket", &api_socket])
.capture_output()
@@ -647,25 +662,6 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
// Hotplug test disk
assert!(Command::new(clh_command("ch-remote"))
.args(&[&format!("--api-socket={}", api_socket)])
.args(&[
"add-disk",
&format!(
"path={},num_queues={},queue_size={},direct=on",
BLK_IO_TEST_IMG, num_queues, queue_size
)
])
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap()
.wait_timeout(Duration::from_secs(5))
.unwrap()
.expect("Failed to hotplug test disk image")
.success());
let fio_command = format!(
"sudo fio --filename=/dev/vdc --name=test --output-format=json \
--direct=1 --bs=4k --ioengine=io_uring --iodepth=64 \

View File

@@ -2,7 +2,7 @@
name = "qcow"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
edition = "2018"
edition = "2021"
license = "BSD-3-Clause"
[lib]
@@ -10,7 +10,7 @@ path = "src/qcow.rs"
[dependencies]
byteorder = "1.4.3"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
remain = "0.2.2"
vmm-sys-util = "0.9.0"

View File

@@ -1,9 +1,9 @@
[package]
name = "rate_limiter"
version = "0.1.0"
edition = "2018"
edition = "2021"
[dependencies]
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
vmm-sys-util = "0.9.0"

View File

@@ -1,3 +1,13 @@
- [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)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
- [`virtio-iommu` Backed Segments](#virtio-iommu-backed-segments)
@@ -5,15 +15,15 @@
- [`virtio-balloon` Free Page Reporting](#virtio-balloon-free-page-reporting)
- [Support for Direct Kernel Booting with TDX](#support-for-direct-kernel-booting-with-tdx)
- [PMU Support for AArch64](#pmu-support-for-aarch64)
- [Documentation Under CC-BY-4.0 Licese](#documentation-under-cc-by-40-licese)
- [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)
- [Contributors](#contributors)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [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-1)
- [Contributors](#contributors-1)
- [Notable Bug fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -22,8 +32,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [Notable bug fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [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)
@@ -31,8 +41,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-3)
- [Contributors](#contributors-3)
- [Notable bug fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [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)
@@ -42,31 +52,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-4)
- [Contributors](#contributors-4)
- [Notable bug fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [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-5)
- [Contributors](#contributors-5)
- [Notable bug fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [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-6)
- [Notable bug fixes](#notable-bug-fixes-7)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-6)
- [Contributors](#contributors-7)
- [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)
- [Contributors](#contributors-7)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-8)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -75,8 +85,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-1)
- [Contributors](#contributors-8)
- [Deprecations](#deprecations-2)
- [Contributors](#contributors-9)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -84,13 +94,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-9)
- [Contributors](#contributors-10)
- [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-10)
- [Contributors](#contributors-11)
- [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)
@@ -102,15 +112,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-7)
- [Contributors](#contributors-11)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-12)
- [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-8)
- [Contributors](#contributors-12)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Contributors](#contributors-13)
- [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)
@@ -123,17 +133,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-9)
- [Contributors](#contributors-13)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Contributors](#contributors-14)
- [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-10)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-14)
- [Contributors](#contributors-15)
- [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)
@@ -143,14 +153,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-15)
- [Contributors](#contributors-16)
- [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-16)
- [Contributors](#contributors-17)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -158,7 +168,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-17)
- [Contributors](#contributors-18)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -167,7 +177,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-18)
- [Contributors](#contributors-19)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -193,11 +203,91 @@
- [Console over virtio](#console-over-virtio)
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# 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
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/27).
### vDPA Support
A vDPA device has a datapath that complies with the virtio specification but
with a vendor specific control path. The addition of `--vdpa` and the REST API
equivalent allows the use of these devices with Cloud Hypervisor.
### Updated OS Support list
The list of officially supported and tested OS versions has been updated to
include Ubuntu "jammy" 22.04 and EOLed versions removed.
### `AArch64` Memory Map Improvements
The memory map when running on `AArch64` has been improved for the handling of
the UEFI region which means that the booted guest OS now has full access to its
allocated RAM. (#3938)
### `AMX` Support
Under a compile time gate of `amx` it is possible compile in support for the
`AMX` instruction set extension for guest use. This also requires runtime
enabling with `--cpu features=amx`.
### Notable Bug Fixes
* Generate error when incorrect HTTP method used for some API endpoints (#3887)
* CMOS based reset is now available to support rebooting on "jammy" (#3914)
* ACPI tables are not produced for memory hotplug when running with
`virtio-mem` (#3883)
* `virtio-iommu` backed PCI segments are now comprehensively placed behind the
vIOMMU (#3870)
* Seccomp rules have been extended for `virtio-fs` to support direct access
(#3848)
### 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)
### Contributors
Many thanks to everyone who has contributed to our release:
* Bo Chen <chen.bo@intel.com>
* Fabiano Fidêncio <fabiano.fidencio@intel.com>
* Henry Wang <Henry.Wang@arm.com>
* Jianyong Wu <jianyong.wu@arm.com>
* LiHui <andrewli@kubesphere.io>
* Michael Zhao <michael.zhao@arm.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Wei Liu <liuwe@microsoft.com>
* William Douglas <william.douglas@intel.com>
* Yi Wang <wang.yi59@zte.com.cn>
# v22.1
This is a bug fix release. The following issues have been addressed:
* VFIO ioctl reordering to fix MSI on AMD platforms (#3827)
* Fix `virtio-net` control queue (#3829)
# v22.0
This release has been tracked through the [v21.0
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/24).
This release has been tracked through the [v22.0
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/25).
### GDB Debug Stub Support
@@ -206,7 +296,6 @@ by the `gdb` compile time feature and details of how to use it can be found in
the [gdb
documentation](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/main/docs/gdb.md).
### `virtio-iommu` Backed Segments
In order to facilitate hotplug devices that require being behind an IOMMU (e.g.
@@ -218,7 +307,6 @@ will place all the specified segments behind the IOMMU.
It is now possible to change the VM configuration (e.g. add or remove devices,
resize) before the VM is booted.
### `virtio-balloon` Free Page Reporting
If `--balloon free_page_reporting=on` is used then the guest can report pages
@@ -238,7 +326,7 @@ has been updated for this usage.
A PMU is now available on AArch64 for guest performance profiling. This will be
exposed automatically if available from the host.
### Documentation Under CC-BY-4.0 Licese
### Documentation Under CC-BY-4.0 License
The documentation is now licensed under the "Creative Commons Attribution 4.0
International" license which is aligned with the project charter under the

View File

@@ -112,7 +112,7 @@ RUN echo 'source $CARGO_HOME/env' >> $HOME/.bashrc \
RUN if [ "$TARGETARCH" = "amd64" ]; then \
git clone https://github.com/spdk/spdk \
&& cd spdk \
&& git checkout 59f3cdacb13bd2a19c4a86be04792b0ee4491172 \
&& git checkout 6301f8915de32baed10dba1eebed556a6749211a \
&& git submodule update --init \
&& apt-get update \
&& ./scripts/pkgdep.sh \

View File

@@ -9,7 +9,7 @@
Name: cloud-hypervisor
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
Version: 22.0
Version: 23.1
Release: 0%{?dist}
License: ASL 2.0 or BSD-3-clause
Group: Applications/System
@@ -112,6 +112,12 @@ rm -rf %{buildroot}
%changelog
* Mon May 09 2022 Rob Bradford <robert.bradford@intel.com> 23.1-0
- Update to 23.1
* Thu Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
- Update to 23.0
* Thu Mar 03 2022 Rob Bradford <robert.bradford@intel.com> 22.0-0
- Update to 22.0

View File

@@ -7,7 +7,7 @@
CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="cloudhypervisor/dev"
CTR_IMAGE_VERSION="20220303-0"
CTR_IMAGE_VERSION="20220405-0"
CTR_IMAGE="${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}"
DOCKER_RUNTIME="docker"
@@ -183,10 +183,9 @@ cmd_help() {
echo " --volumes Hash separated volumes to be exported. Example --volumes /mnt:/mnt#/myvol:/myvol"
echo " --hypervisor Underlying hypervisor. Options kvm, mshv"
echo ""
echo " tests [--unit|--cargo|--all] [--libc musl|gnu] [-- [<test scripts args>] [-- [<test binary args>]]] "
echo " tests [<test type (see below)>] [--libc musl|gnu] [-- [<test scripts args>] [-- [<test binary args>]]] "
echo " Run the Cloud Hypervisor tests."
echo " --unit Run the unit tests."
echo " --cargo Run the cargo tests."
echo " --integration Run the integration tests."
echo " --integration-sgx Run the SGX integration tests."
echo " --integration-vfio Run the VFIO integration tests."
@@ -271,8 +270,6 @@ cmd_build() {
cargo_args=("$@")
[ $build = "release" ] && cargo_args+=("--release")
cargo_args+=(--target "$target")
[ "$(uname -m)" = "aarch64" ] && cargo_args+=("--no-default-features")
[ "$(uname -m)" = "aarch64" ] && cargo_args+=(--features "$hypervisor")
rustflags=""
target_cc=""
@@ -314,7 +311,6 @@ cmd_clean() {
cmd_tests() {
unit=false
cargo=false
integration=false
integration_sgx=false
integration_vfio=false
@@ -332,7 +328,6 @@ cmd_tests() {
exit 1
} ;;
"--unit") { unit=true; } ;;
"--cargo") { cargo=true; } ;;
"--integration") { integration=true; } ;;
"--integration-sgx") { integration_sgx=true; } ;;
"--integration-vfio") { integration_vfio=true; } ;;
@@ -398,16 +393,6 @@ cmd_tests() {
./scripts/run_unit_tests.sh "$@" || fix_dir_perms $? || exit $?
fi
if [ "$cargo" = true ]; then
say "Running cargo tests..."
$DOCKER_RUNTIME run \
--workdir "$CTR_CLH_ROOT_DIR" \
--rm \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
"$CTR_IMAGE" \
./scripts/run_cargo_tests.sh "$@" || fix_dir_perms $? || exit $?
fi
if [ "$integration" = true ]; then
say "Running integration tests for $target..."
$DOCKER_RUNTIME run \

42
scripts/prepare_vdpa.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
set -x
sudo apt install -y libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf git make dpkg-dev libmnl-dev pkg-config
sudo sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list
sudo apt update
apt-get source linux-image-unsigned-`uname -r`
pushd linux-azure*/drivers/vdpa/vdpa_sim/
cat <<'EOF' > Makefile
# SPDX-License-Identifier: GPL-2.0
obj-m += vdpa_sim.o
obj-m += vdpa_sim_net.o
obj-m += vdpa_sim_blk.o
EOF
make -C /lib/modules/`uname -r`/build M=$PWD
sudo make -C /lib/modules/`uname -r`/build M=$PWD modules_install
popd
sudo depmod -a
sudo modprobe vdpa
sudo modprobe vhost_vdpa
sudo modprobe vdpa_sim
sudo modprobe vdpa_sim_blk
sudo modprobe vdpa_sim_net
# After the Jenkins builder are moved to Ubuntu 22.04, manually building and
# installing iproute2/vdpa won't be required.
# Tracked by: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/3862
git clone https://github.com/shemminger/iproute2.git
pushd iproute2
./configure
make -j
sudo make install
popd
# Create /dev/vhost-vdpa-0
sudo vdpa dev add name vdpa-blk1 mgmtdev vdpasim_blk
# Create /dev/vhost-vdpa-1
sudo vdpa dev add name vdpa-blk2 mgmtdev vdpasim_blk
# Create /dev/vhost-vdpa-2
sudo vdpa dev add name vdpa-net1 mgmtdev vdpasim_net
sudo chmod 660 /dev/vhost-vdpa-0
sudo chmod 660 /dev/vhost-vdpa-1
sudo chmod 660 /dev/vhost-vdpa-2
vdpa dev show -jp

View File

@@ -1,26 +0,0 @@
#!/bin/bash
set -e
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
process_common_args "$@"
# Install cargo components
time rustup component add clippy
time rustup component add rustfmt
time which cargo-audit || cargo install cargo-audit
# Run cargo builds and checks
time cargo clippy --all-targets --all-features -- -D warnings
time cargo rustc --bin cloud-hypervisor -- -D warnings
time cargo rustc -p vhost_user_net --bin vhost_user_net -- -D warnings
time cargo test
time cargo audit
time cargo clippy --all-targets --no-default-features --features "acpi,$hypervisor" -- -D warnings
time cargo rustc --bin cloud-hypervisor --no-default-features --features "acpi,$hypervisor" -- -D warnings
time cargo clippy --all-targets --no-default-features --features "$hypervisor" -- -D warnings
time cargo rustc --bin cloud-hypervisor --no-default-features --features "$hypervisor" -- -D warnings
time cargo fmt -- --check
time cargo build --all --release

View File

@@ -11,63 +11,6 @@ WORKLOADS_LOCK="$WORKLOADS_DIR/integration_test.lock"
mkdir -p "$WORKLOADS_DIR"
# Checkout source code of a GIT repo with specified branch and commit
# Args:
# $1: Target directory
# $2: GIT URL of the repo
# $3: Required branch
# $4: Required commit (optional)
checkout_repo() {
SRC_DIR="$1"
GIT_URL="$2"
GIT_BRANCH="$3"
GIT_COMMIT="$4"
# Check whether the local HEAD commit same as the requested commit or not.
# If commit is not specified, compare local HEAD and remote HEAD.
# Remove the folder if there is difference.
if [ -d "$SRC_DIR" ]; then
pushd $SRC_DIR
git fetch
SRC_LOCAL_COMMIT=$(git rev-parse HEAD)
if [ -z "$GIT_COMMIT" ]; then
GIT_COMMIT=$(git rev-parse remotes/origin/"$GIT_BRANCH")
fi
popd
if [ "$SRC_LOCAL_COMMIT" != "$GIT_COMMIT" ]; then
rm -rf "$SRC_DIR"
fi
fi
# Checkout the specified branch and commit (if required)
if [ ! -d "$SRC_DIR" ]; then
git clone --depth 1 "$GIT_URL" -b "$GIT_BRANCH" "$SRC_DIR"
if [ "$GIT_COMMIT" ]; then
pushd "$SRC_DIR"
git fetch --depth 1 origin "$GIT_COMMIT"
git reset --hard FETCH_HEAD
popd
fi
fi
}
build_custom_linux() {
SRCDIR=$PWD
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
LINUX_CUSTOM_BRANCH="ch-5.15.12"
LINUX_CUSTOM_URL="https://github.com/cloud-hypervisor/linux.git"
checkout_repo "$LINUX_CUSTOM_DIR" "$LINUX_CUSTOM_URL" "$LINUX_CUSTOM_BRANCH"
cp $SRCDIR/resources/linux-config-aarch64 $LINUX_CUSTOM_DIR/.config
pushd $LINUX_CUSTOM_DIR
time make -j `nproc`
cp arch/arm64/boot/Image "$WORKLOADS_DIR/" || exit 1
cp arch/arm64/boot/Image.gz "$WORKLOADS_DIR/" || exit 1
popd
}
build_edk2() {
EDK2_BUILD_DIR="$WORKLOADS_DIR/edk2_build"
EDK2_REPO="https://github.com/tianocore/edk2.git"
@@ -92,33 +35,61 @@ build_edk2() {
checkout_repo "$EDK2_PLAT_DIR" "$EDK2_PLAT_REPO" master "8227e9e9f6a8aefbd772b40138f835121ccb2307"
checkout_repo "$ACPICA_DIR" "$ACPICA_REPO" master "b9c69f81a05c45611c91ea9cbce8756078d76233"
pushd "$EDK2_BUILD_DIR"
# Build
make -C acpica -j `nproc`
source edk2/edksetup.sh
make -C edk2/BaseTools -j `nproc`
build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtCloudHv.dsc -b RELEASE -n 0
cp Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd "$WORKLOADS_DIR"
popd
if [[ ! -f "$EDK2_DIR/.built" || \
! -f "$EDK2_PLAT_DIR/.built" || \
! -f "$ACPICA_DIR/.built" ]]; then
pushd "$EDK2_BUILD_DIR"
# Build
make -C acpica -j `nproc`
source edk2/edksetup.sh
make -C edk2/BaseTools -j `nproc`
build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtCloudHv.dsc -b RELEASE -n 0
cp Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd "$WORKLOADS_DIR"
touch "$EDK2_DIR"/.built
touch "$EDK2_PLAT_DIR"/.built
touch "$ACPICA_DIR"/.built
popd
fi
}
build_spdk_nvme() {
SPDK_DIR="$WORKLOADS_DIR/spdk"
SPDK_REPO="https://github.com/spdk/spdk.git"
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "f9c496b8e21a8f499df268818bf8b5d8e2b19f04"
SPDK_DEPLOY_DIR="/usr/local/bin/spdk-nvme"
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "6301f8915de32baed10dba1eebed556a6749211a"
pushd $SPDK_DIR
git submodule update --init
apt-get update
./scripts/pkgdep.sh
./configure --with-vfio-user
chmod +x /usr/local/lib/python3.8/dist-packages/ninja/data/bin/ninja
make -j `nproc`
mkdir /usr/local/bin/spdk-nvme
cp ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme
cp ./scripts/rpc.py /usr/local/bin/spdk-nvme
cp -r ./scripts/rpc /usr/local/bin/spdk-nvme
popd
if [ ! -f "$SPDK_DIR/.built" ]; then
pushd $SPDK_DIR
git submodule update --init
apt-get update
./scripts/pkgdep.sh
./configure --with-vfio-user
chmod +x /usr/local/lib/python3.8/dist-packages/ninja/data/bin/ninja
make -j `nproc` || exit 1
touch .built
popd
fi
if [ ! -d "/usr/local/bin/spdk-nvme" ]; then
mkdir -p $SPDK_DEPLOY_DIR
fi
cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt
cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py
cp -r "$WORKLOADS_DIR/spdk/scripts/rpc" $SPDK_DEPLOY_DIR/rpc
}
build_virtiofsd() {
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.1.0 "220405d7a2606c92636d31992b5cb3036a41047b"
if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then
pushd $VIRTIOFSD_DIR
time cargo build --release
cp target/release/virtiofsd "$WORKLOADS_DIR/" || exit 1
touch .built
popd
fi
}
update_workloads() {
@@ -169,6 +140,24 @@ update_workloads() {
popd
fi
JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.raw"
JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_RAW_IMAGE_NAME"
JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL || exit 1
popd
fi
JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.qcow2"
JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
if [ ! -f "$JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL || exit 1
popd
fi
ALPINE_MINIROOTFS_URL="http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/aarch64/alpine-minirootfs-3.11.3-aarch64.tar.gz"
ALPINE_MINIROOTFS_TARBALL="$WORKLOADS_DIR/alpine-minirootfs-aarch64.tar.gz"
if [ ! -f "$ALPINE_MINIROOTFS_TARBALL" ]; then
@@ -217,19 +206,7 @@ update_workloads() {
guestunmount "$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR"
# Build virtiofsd
VIRTIOFSD="$WORKLOADS_DIR/virtiofsd"
VIRTIOFSD_DIR="virtiofsd_build"
if [ ! -f "$VIRTIOFSD" ]; then
pushd $WORKLOADS_DIR
git clone "https://gitlab.com/virtio-fs/virtiofsd.git" $VIRTIOFSD_DIR
pushd $VIRTIOFSD_DIR
git checkout v1.1.0
time cargo build --release
cp target/release/virtiofsd $VIRTIOFSD || exit 1
popd
rm -rf $VIRTIOFSD_DIR
popd
fi
build_virtiofsd
BLK_IMAGE="$WORKLOADS_DIR/blk.img"
MNT_DIR="mount_image"
@@ -252,10 +229,10 @@ update_workloads() {
echo "bar" > "$SHARED_DIR/file3" || exit 1
fi
# checkout and build SPDK NVMe
# Checkout and build SPDK NVMe
build_spdk_nvme
# Check and build EDK2 binary
# Checkout and build EDK2
build_edk2
}

View File

@@ -71,6 +71,23 @@ if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
popd
fi
JAMMY_OS_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20220329-0.qcow2"
JAMMY_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_IMAGE_NAME"
JAMMY_OS_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $JAMMY_OS_IMAGE_URL || exit 1
popd
fi
JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20220329-0.raw"
JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
time qemu-img convert -p -f qcow2 -O raw $JAMMY_OS_IMAGE_NAME $JAMMY_OS_RAW_IMAGE_NAME || exit 1
popd
fi
ALPINE_MINIROOTFS_URL="http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-minirootfs-3.11.3-x86_64.tar.gz"
ALPINE_MINIROOTFS_TARBALL="$WORKLOADS_DIR/alpine-minirootfs-x86_64.tar.gz"
if [ ! -f "$ALPINE_MINIROOTFS_TARBALL" ]; then
@@ -107,27 +124,7 @@ popd
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
if [ ! -f "$VMLINUX_IMAGE" ]; then
SRCDIR=$PWD
pushd $WORKLOADS_DIR
time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-5.15.12" $LINUX_CUSTOM_DIR
cp $SRCDIR/resources/linux-config-x86_64 $LINUX_CUSTOM_DIR/.config
popd
fi
if [ ! -f "$VMLINUX_IMAGE" ]; then
pushd $LINUX_CUSTOM_DIR
time make bzImage -j `nproc`
cp vmlinux $VMLINUX_IMAGE || exit 1
popd
fi
if [ -d "$LINUX_CUSTOM_DIR" ]; then
rm -rf $LINUX_CUSTOM_DIR
fi
build_custom_linux
VIRTIOFSD="$WORKLOADS_DIR/virtiofsd"
VIRTIOFSD_DIR="virtiofsd_build"
@@ -190,10 +187,13 @@ sudo bash -c "echo 1000000 > /sys/kernel/mm/ksm/pages_to_scan"
sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs"
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
# Both test_vfio and ovs-dpdk rely on hugepages
# Both test_vfio, ovs-dpdk and vDPA tests rely on hugepages
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Update max locked memory to 'unlimited' to avoid issues with vDPA
ulimit -l unlimited
export RUST_BACKTRACE=1
time cargo test $features "parallel::$test_filter" -- ${test_binary_args[*]}
RES=$?

View File

@@ -4,23 +4,45 @@ set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
export BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
export TEST_ARCH=$(uname -m)
export BUILD_TARGET=${BUILD_TARGET-${TEST_ARCH}-unknown-linux-gnu}
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
build_fio() {
FIO_DIR="$WORKLOADS_DIR/fio_build"
FIO_REPO="https://github.com/axboe/fio.git"
checkout_repo "$FIO_DIR" "$FIO_REPO" master "1953e1adb5a28ed21370e85991d7f5c3cdc699f3"
if [ ! -f "$FIO_DIR/.built" ]; then
pushd $FIO_DIR
./configure
make -j `nproc`
cp fio "$WORKLOADS_DIR/fio"
touch .built
popd
fi
}
process_common_args "$@"
# For now these values are default for kvm
features=""
if [ "$hypervisor" = "mshv" ] ; then
if [ "$hypervisor" = "mshv" ]; then
features="--no-default-features --features mshv,common"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
cp scripts/sha1sums-${TEST_ARCH} $WORKLOADS_DIR
if [ ${TEST_ARCH} == "aarch64" ]; then
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.qcow2"
else
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
fi
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
@@ -29,7 +51,12 @@ if [ ! -f "$FOCAL_OS_IMAGE" ]; then
popd
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
if [ ${TEST_ARCH} == "aarch64" ]; then
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.raw"
else
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
fi
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
@@ -38,43 +65,38 @@ if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
fi
pushd $WORKLOADS_DIR
grep focal sha1sums-x86_64 | sha1sum --check
grep focal sha1sums-${TEST_ARCH} | sha1sum --check
if [ $? -ne 0 ]; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
if [ ${TEST_ARCH} == "aarch64" ]; then
build_fio
# Update the fio in the cloud image to use io_uring on AArch64
FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_NAME="focal-server-cloudimg-arm64-custom-20210929-0-update-tool.raw"
cp "$FOCAL_OS_RAW_IMAGE" "$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_NAME"
FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR="$WORKLOADS_DIR/focal-server-cloudimg-root"
if [ ! -d "$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR" ]; then
mkdir -p "$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR"
fi
# Mount the 'raw' image, replace the fio and umount the working folder
guestmount -a "$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_NAME" -m /dev/sda1 "$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR" || exit 1
cp "$WORKLOADS_DIR"/fio "$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR"/usr/bin/fio
guestunmount "$FOCAL_OS_RAW_IMAGE_UPDATE_TOOL_ROOT_DIR"
fi
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
build_custom_linux
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
if [ ! -f "$VMLINUX_IMAGE" ]; then
SRCDIR=$PWD
pushd $WORKLOADS_DIR
time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-5.15.12" $LINUX_CUSTOM_DIR
cp $SRCDIR/resources/linux-config-x86_64 $LINUX_CUSTOM_DIR/.config
popd
fi
if [ ! -f "$VMLINUX_IMAGE" ]; then
pushd $LINUX_CUSTOM_DIR
time make bzImage -j `nproc`
cp vmlinux $VMLINUX_IMAGE || exit 1
popd
fi
if [ -d "$LINUX_CUSTOM_DIR" ]; then
rm -rf $LINUX_CUSTOM_DIR
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
BUILD_TARGET="${TEST_ARCH}-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
if [[ "${BUILD_TARGET}" == "${TEST_ARCH}-unknown-linux-musl" ]]; then
TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
CFLAGS="-I /usr/include/${TEST_ARCH}-linux-musl/ -idirafter /usr/include/"
fi
cargo build --all --release $features --target $BUILD_TARGET
@@ -87,6 +109,10 @@ strip target/$BUILD_TARGET/release/performance-metrics
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
if [ -n "$test_filter" ]; then
test_binary_args+=("--test-filter $test_filter")
fi
export RUST_BACKTRACE=1
time target/$BUILD_TARGET/release/performance-metrics ${test_binary_args[*]}
RES=$?

View File

@@ -1,16 +1,16 @@
#!/bin/bash
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
source $(dirname "$0")/test-util.sh
process_common_args "$@"
BUILD_TARGET=${BUILD_TARGET-x86_64-unknown-linux-gnu}
cargo_args=("")
if [[ $(uname -m) = "aarch64" || $hypervisor = "mshv" ]]; then
if [[ $hypervisor = "mshv" ]]; then
cargo_args+=("--no-default-features")
cargo_args+=("--features $hypervisor")
cargo_args+=("--features common,$hypervisor")
fi
if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then
@@ -19,4 +19,4 @@ if [[ "${BUILD_TARGET}" == "aarch64-unknown-linux-musl" ]]; then
fi
export RUST_BACKTRACE=1
cargo test --lib --bins --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1;
cargo test --lib --bins --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1

View File

@@ -4,3 +4,5 @@
e4addb6e212a298144f9eb0eb6e36019d013f0e7 alpine-minirootfs-aarch64.tar.gz
25b4f9ac308898d63b73d7db0e0e2d4768853723 focal-server-cloudimg-arm64-custom-20210929-0.qcow2
9953b31bb1923cdd8d91b1b7cc9ad3a9be1e0a59 focal-server-cloudimg-arm64-custom-20210929-0.raw
7118f4d4cad18c8357bc2ad9824a50f9a82a860a jammy-server-cloudimg-arm64-custom-20220329-0.qcow2
1f2b71be43b8f748f01306c4454e5c921343faa4 jammy-server-cloudimg-arm64-custom-20220329-0.raw

View File

@@ -3,3 +3,5 @@
d4a44acc6014d5f83dea1c625c43d677a95fa75f alpine-minirootfs-x86_64.tar.gz
f1eccdc5e1b515dbad294426ab081b47ebfb97c0 focal-server-cloudimg-amd64-custom-20210609-0.qcow2
7f5a8358243a96adf61f5c20139b29f308f2c0e3 focal-server-cloudimg-amd64-custom-20210609-0.raw
272102ac243e544bc5c2303f383eeb217bd2e446 jammy-server-cloudimg-amd64-custom-20220329-0.qcow2
0b5b4816a0976c458f8e8bab061e9d63ebc1b806 jammy-server-cloudimg-amd64-custom-20220329-0.raw

View File

@@ -1,7 +1,68 @@
#!/bin/bash
hypervisor="kvm"
test_filter=""
test_binary_args=()
# Checkout source code of a GIT repo with specified branch and commit
# Args:
# $1: Target directory
# $2: GIT URL of the repo
# $3: Required branch
# $4: Required commit (optional)
checkout_repo() {
SRC_DIR="$1"
GIT_URL="$2"
GIT_BRANCH="$3"
GIT_COMMIT="$4"
# Check whether the local HEAD commit same as the requested commit or not.
# If commit is not specified, compare local HEAD and remote HEAD.
# Remove the folder if there is difference.
if [ -d "$SRC_DIR" ]; then
pushd $SRC_DIR
git fetch
SRC_LOCAL_COMMIT=$(git rev-parse HEAD)
if [ -z "$GIT_COMMIT" ]; then
GIT_COMMIT=$(git rev-parse remotes/origin/"$GIT_BRANCH")
fi
popd
if [ "$SRC_LOCAL_COMMIT" != "$GIT_COMMIT" ]; then
rm -rf "$SRC_DIR"
fi
fi
# Checkout the specified branch and commit (if required)
if [ ! -d "$SRC_DIR" ]; then
git clone --depth 1 "$GIT_URL" -b "$GIT_BRANCH" "$SRC_DIR"
if [ "$GIT_COMMIT" ]; then
pushd "$SRC_DIR"
git fetch --depth 1 origin "$GIT_COMMIT"
git reset --hard FETCH_HEAD
popd
fi
fi
}
build_custom_linux() {
ARCH=$(uname -m)
SRCDIR=$PWD
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
LINUX_CUSTOM_BRANCH="ch-5.15.12"
LINUX_CUSTOM_URL="https://github.com/cloud-hypervisor/linux.git"
checkout_repo "$LINUX_CUSTOM_DIR" "$LINUX_CUSTOM_URL" "$LINUX_CUSTOM_BRANCH"
cp $SRCDIR/resources/linux-config-${ARCH} $LINUX_CUSTOM_DIR/.config
pushd $LINUX_CUSTOM_DIR
make -j `nproc`
if [ ${ARCH} == "x86_64" ]; then
cp vmlinux "$WORKLOADS_DIR/" || exit 1
elif [ ${ARCH} == "aarch64" ]; then
cp arch/arm64/boot/Image "$WORKLOADS_DIR/" || exit 1
cp arch/arm64/boot/Image.gz "$WORKLOADS_DIR/" || exit 1
fi
popd
}
cmd_help() {
echo ""
@@ -44,5 +105,5 @@ process_common_args() {
die "Hypervisor value must be kvm or mshv"
fi
test_binary_args="$@"
test_binary_args=($@)
}

View File

@@ -28,6 +28,7 @@ enum Error {
AddPmemConfig(vmm::config::Error),
AddNetConfig(vmm::config::Error),
AddUserDeviceConfig(vmm::config::Error),
AddVdpaConfig(vmm::config::Error),
AddVsockConfig(vmm::config::Error),
Restore(vmm::config::Error),
}
@@ -47,6 +48,7 @@ impl fmt::Display for Error {
AddPmemConfig(e) => write!(f, "Error parsing persistent memory syntax: {}", e),
AddNetConfig(e) => write!(f, "Error parsing network syntax: {}", e),
AddUserDeviceConfig(e) => write!(f, "Error parsing user device syntax: {}", e),
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),
}
@@ -212,6 +214,18 @@ fn add_net_api_command(socket: &mut UnixStream, config: &str) -> Result<(), Erro
.map_err(Error::ApiClient)
}
fn add_vdpa_api_command(socket: &mut UnixStream, config: &str) -> Result<(), Error> {
let vdpa_config = vmm::config::VdpaConfig::parse(config).map_err(Error::AddVdpaConfig)?;
simple_api_command(
socket,
"PUT",
"add-vdpa",
Some(&serde_json::to_string(&vdpa_config).unwrap()),
)
.map_err(Error::ApiClient)
}
fn add_vsock_api_command(socket: &mut UnixStream, config: &str) -> Result<(), Error> {
let vsock_config = vmm::config::VsockConfig::parse(config).map_err(Error::AddVsockConfig)?;
@@ -376,6 +390,14 @@ fn do_command(matches: &ArgMatches) -> Result<(), Error> {
.value_of("device_config")
.unwrap(),
),
Some("add-vdpa") => add_vdpa_api_command(
&mut socket,
matches
.subcommand_matches("add-vdpa")
.unwrap()
.value_of("vdpa_config")
.unwrap(),
),
Some("add-vsock") => add_vsock_api_command(
&mut socket,
matches
@@ -486,6 +508,13 @@ fn main() {
.help(vmm::config::UserDeviceConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-vdpa").about("Add vDPA device").arg(
Arg::new("vdpa_config")
.index(1)
.help(vmm::config::VdpaConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-vsock").about("Add vsock device").arg(
Arg::new("vsock_config")

View File

@@ -13,16 +13,12 @@ use libc::EFD_NONBLOCK;
use log::LevelFilter;
use option_parser::OptionParser;
use seccompiler::SeccompAction;
use signal_hook::{
consts::SIGSYS,
iterator::{exfiltrator::WithRawSiginfo, SignalsInfo},
};
use signal_hook::consts::SIGSYS;
use std::env;
use std::fs::File;
use std::os::unix::io::{FromRawFd, RawFd};
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
use std::thread;
use thiserror::Error;
use vmm::config;
use vmm_sys_util::eventfd::EventFd;
@@ -155,7 +151,8 @@ fn create_app<'a>(
"boot=<boot_vcpus>,max=<max_vcpus>,\
topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,\
kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,\
affinity=<list_of_vcpus_with_their_associated_cpuset>",
affinity=<list_of_vcpus_with_their_associated_cpuset>,\
features=<list_of_features_to_enable>",
)
.default_value(default_vcpus)
.group("vm-config"),
@@ -305,6 +302,14 @@ fn create_app<'a>(
.min_values(1)
.group("vm-config"),
)
.arg(
Arg::new("vdpa")
.long("vdpa")
.help(config::VdpaConfig::SYNTAX)
.takes_value(true)
.min_values(1)
.group("vm-config"),
)
.arg(
Arg::new("vsock")
.long("vsock")
@@ -495,28 +500,21 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
SeccompAction::Trap
};
// See https://github.com/rust-lang/libc/issues/716 why we can't get the details from siginfo_t
if seccomp_action == SeccompAction::Trap {
thread::Builder::new()
.name("seccomp_signal_handler".to_string())
.spawn(move || {
for si in SignalsInfo::<WithRawSiginfo>::new(&[SIGSYS])
.unwrap()
.forever()
{
/* SYS_SECCOMP */
if si.si_code == 1 {
eprint!(
"\n==== seccomp violation ====\n\
Try running with `strace -ff` to identify the cause and open an issue: \
https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new\n"
);
signal_hook::low_level::emulate_default_handler(SIGSYS).unwrap();
}
}
// SAFETY: We only using signal_hook for managing signals and only execute signal
// handler safe functions (writing to stderr) and manipulating signals.
unsafe {
signal_hook::low_level::register(signal_hook::consts::SIGSYS, || {
eprint!(
"\n==== Possible seccomp violation ====\n\
Try running with `strace -ff` to identify the cause and open an issue: \
https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new\n"
);
signal_hook::low_level::emulate_default_handler(SIGSYS).unwrap();
})
.unwrap();
}
.map_err(|e| eprintln!("Error adding SIGSYS signal handler: {}", e))
.ok();
}
// Before we start any threads, mask the signals we'll be
@@ -634,8 +632,8 @@ mod unit_tests {
use crate::{create_app, prepare_default_values};
use std::path::PathBuf;
use vmm::config::{
CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, KernelConfig, MemoryConfig,
RngConfig, VmConfig, VmParams,
CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, KernelConfig,
MemoryConfig, RngConfig, VmConfig, VmParams,
};
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
@@ -682,6 +680,7 @@ mod unit_tests {
kvm_hyperv: false,
max_phys_bits: 46,
affinity: None,
features: CpuFeatures::default(),
},
memory: MemoryConfig {
size: 536_870_912,
@@ -723,6 +722,7 @@ mod unit_tests {
},
devices: None,
user_devices: None,
vdpa: None,
vsock: None,
iommu: false,
#[cfg(target_arch = "x86_64")]
@@ -1260,125 +1260,6 @@ mod unit_tests {
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true","--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true","--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
}"#,
false,
),
]
.iter()
.for_each(|(cli, openapi, equal)| {
@@ -1680,6 +1561,51 @@ mod unit_tests {
});
}
#[test]
fn test_valid_vm_config_vdpa() {
vec![
(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vdpa",
"path=/path/to/device/1",
"path=/path/to/device/2,num_queues=2",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"vdpa": [
{"path": "/path/to/device/1", "num_queues": 1},
{"path": "/path/to/device/2", "num_queues": 2}
]
}"#,
true,
),
(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vdpa",
"path=/path/to/device/1",
"path=/path/to/device/2",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"vdpa": [
{"path": "/path/to/device/1"}
]
}"#,
false,
),
]
.iter()
.for_each(|(cli, openapi, equal)| {
compare_vm_config_cli_vs_json(cli, openapi, *equal);
});
}
#[test]
fn test_valid_vm_config_vsock() {
vec![

View File

@@ -2,13 +2,13 @@
name = "test_infra"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
dirs = "4.0.0"
epoll = "4.3.1"
lazy_static = "1.4.0"
libc = "0.2.91"
libc = "0.2.123"
ssh2 = { version = "0.9.1", features = ["vendored-openssl"]}
vmm-sys-util = "0.9.0"
wait-timeout = "0.2.0"

View File

@@ -8,6 +8,7 @@
// related warnings for our quality workflow to pass.
#![allow(dead_code)]
#[cfg(target_arch = "x86_64")]
#[macro_use]
extern crate lazy_static;
@@ -43,6 +44,7 @@ mod x86_64 {
pub const FOCAL_IMAGE_NAME_QCOW2: &str = "focal-server-cloudimg-amd64-custom-20210609-0.qcow2";
pub const FOCAL_IMAGE_NAME_VHD: &str = "focal-server-cloudimg-amd64-custom-20210609-0.vhd";
pub const FOCAL_IMAGE_NAME_VHDX: &str = "focal-server-cloudimg-amd64-custom-20210609-0.vhdx";
pub const JAMMY_IMAGE_NAME: &str = "jammy-server-cloudimg-amd64-custom-20220329-0.raw";
pub const WINDOWS_IMAGE_NAME: &str = "windows-server-2019.raw";
pub const OVMF_NAME: &str = "CLOUDHV.fd";
pub const GREP_SERIAL_IRQ_CMD: &str = "grep -c 'IO-APIC.*ttyS0' /proc/interrupts || true";
@@ -60,6 +62,7 @@ mod aarch64 {
pub const FOCAL_IMAGE_NAME_QCOW2: &str = "focal-server-cloudimg-arm64-custom-20210929-0.qcow2";
pub const FOCAL_IMAGE_NAME_VHD: &str = "focal-server-cloudimg-arm64-custom-20210929-0.vhd";
pub const FOCAL_IMAGE_NAME_VHDX: &str = "focal-server-cloudimg-arm64-custom-20210929-0.vhdx";
pub const JAMMY_IMAGE_NAME: &str = "jammy-server-cloudimg-arm64-custom-20220329-0.raw";
pub const GREP_SERIAL_IRQ_CMD: &str = "grep -c 'GICv3.*uart-pl011' /proc/interrupts || true";
pub const GREP_PMU_IRQ_CMD: &str = "grep -c 'GICv3.*arm-pmu' /proc/interrupts || true";
}
@@ -415,7 +418,7 @@ enum FwType {
RustHypervisorFirmware,
}
fn fw_path(fw_type: FwType) -> String {
fn fw_path(_fw_type: FwType) -> String {
let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads");
@@ -424,7 +427,7 @@ fn fw_path(fw_type: FwType) -> String {
fw_path.push("CLOUDHV_EFI.fd");
#[cfg(target_arch = "x86_64")]
{
match fw_type {
match _fw_type {
FwType::Ovmf => fw_path.push(OVMF_NAME),
FwType::RustHypervisorFirmware => fw_path.push("hypervisor-fw"),
}
@@ -744,7 +747,7 @@ fn test_vhost_user_net(
);
// ACPI feature is needed.
#[cfg(all(target_arch = "x86_64", feature = "acpi"))]
#[cfg(target_arch = "x86_64")]
{
guest.enable_memory_hotplug();
@@ -883,7 +886,7 @@ fn test_vhost_user_blk(
);
// ACPI feature is needed.
#[cfg(all(target_arch = "x86_64", feature = "acpi"))]
#[cfg(target_arch = "x86_64")]
{
guest.enable_memory_hotplug();
@@ -1121,7 +1124,7 @@ fn test_virtio_fs(
);
// ACPI feature is needed.
#[cfg(all(target_arch = "x86_64", feature = "acpi"))]
#[cfg(target_arch = "x86_64")]
{
guest.enable_memory_hotplug();
@@ -1754,48 +1757,58 @@ mod parallel {
#[test]
#[cfg(target_arch = "x86_64")]
fn test_simple_launch() {
let bionic = UbuntuDiskConfig::new(BIONIC_IMAGE_NAME.to_string());
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
fn test_bionic_hypervisor_fw() {
test_simple_launch(fw_path(FwType::RustHypervisorFirmware), BIONIC_IMAGE_NAME)
}
vec![Box::new(bionic), Box::new(focal)]
.drain(..)
.for_each(|disk_config| {
vec![
fw_path(FwType::Ovmf),
fw_path(FwType::RustHypervisorFirmware),
]
.drain(..)
.for_each(|fw_path| {
let guest = Guest::new(disk_config.clone());
#[test]
#[cfg(target_arch = "x86_64")]
fn test_focal_hypervisor_fw() {
test_simple_launch(fw_path(FwType::RustHypervisorFirmware), FOCAL_IMAGE_NAME)
}
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", "boot=1"])
.args(&["--memory", "size=512M"])
.args(&["--kernel", fw_path.as_str()])
.default_disks()
.default_net()
.args(&["--serial", "tty", "--console", "off"])
.capture_output()
.spawn()
.unwrap();
#[test]
#[cfg(target_arch = "x86_64")]
fn test_bionic_ovmf() {
test_simple_launch(fw_path(FwType::Ovmf), BIONIC_IMAGE_NAME)
}
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(Some(120)).unwrap();
#[test]
#[cfg(target_arch = "x86_64")]
fn test_focal_ovmf() {
test_simple_launch(fw_path(FwType::Ovmf), FOCAL_IMAGE_NAME)
}
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 1);
assert_eq!(guest.get_initial_apicid().unwrap_or(1), 0);
assert!(guest.get_total_memory().unwrap_or_default() > 480_000);
assert!(guest.get_entropy().unwrap_or_default() >= 900);
assert_eq!(guest.get_pci_bridge_class().unwrap_or_default(), "0x060000");
});
#[cfg(target_arch = "x86_64")]
fn test_simple_launch(fw_path: String, disk_path: &str) {
let disk_config = Box::new(UbuntuDiskConfig::new(disk_path.to_string()));
let guest = Guest::new(disk_config);
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", "boot=1"])
.args(&["--memory", "size=512M"])
.args(&["--kernel", fw_path.as_str()])
.default_disks()
.default_net()
.args(&["--serial", "tty", "--console", "off"])
.capture_output()
.spawn()
.unwrap();
handle_child_output(r, &output);
});
});
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(Some(120)).unwrap();
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 1);
assert_eq!(guest.get_initial_apicid().unwrap_or(1), 0);
assert!(guest.get_total_memory().unwrap_or_default() > 480_000);
assert!(guest.get_entropy().unwrap_or_default() >= 900);
assert_eq!(guest.get_pci_bridge_class().unwrap_or_default(), "0x060000");
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
#[test]
@@ -2130,7 +2143,13 @@ mod parallel {
let (cmd_success, cmd_output) = remote_command_w_output(
&api_socket,
"add-disk",
Some(format!("path={},id=test0,pci_segment=1", test_disk_path.as_str()).as_str()),
Some(
format!(
"path={},id=test0,pci_segment=1,iommu=on",
test_disk_path.as_str()
)
.as_str(),
),
);
assert!(cmd_success);
assert!(String::from_utf8_lossy(&cmd_output)
@@ -2195,6 +2214,46 @@ mod parallel {
handle_child_output(r, &output);
}
#[test]
fn test_virtio_net_ctrl_queue() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let mut cmd = GuestCommand::new(&guest);
cmd.args(&["--cpus", "boot=1"])
.args(&["--memory", "size=512M"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.capture_output()
.default_disks()
.default_net();
let mut child = cmd.spawn().unwrap();
guest.wait_vm_boot(None).unwrap();
#[cfg(target_arch = "aarch64")]
let iface = "enp0s4";
#[cfg(target_arch = "x86_64")]
let iface = "ens4";
let r = std::panic::catch_unwind(|| {
assert_eq!(
guest
.ssh_command(
format!("sudo ethtool -K {} rx-gro-hw off && echo success", iface).as_str()
)
.unwrap()
.trim(),
"success"
);
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_pci_multiple_segments() {
@@ -2751,36 +2810,11 @@ mod parallel {
handle_child_output(r, &output);
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_fs_dax_on_default_cache_size() {
test_virtio_fs(true, None, "never", &prepare_virtiofsd, false, None)
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_fs_dax_on_cache_size_1_gib() {
test_virtio_fs(
true,
Some(0x4000_0000),
"never",
&prepare_virtiofsd,
false,
None,
)
}
#[test]
fn test_virtio_fs_dax_off() {
test_virtio_fs(false, None, "never", &prepare_virtiofsd, false, None)
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_fs_hotplug_dax_on() {
test_virtio_fs(true, None, "never", &prepare_virtiofsd, true, None)
}
#[test]
fn test_virtio_fs_hotplug_dax_off() {
test_virtio_fs(false, None, "never", &prepare_virtiofsd, true, None)
@@ -2789,27 +2823,13 @@ mod parallel {
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_fs_multi_segment_hotplug() {
test_virtio_fs(
true,
Some(0x4000_0000),
"never",
&prepare_virtiofsd,
true,
Some(15),
)
test_virtio_fs(false, None, "never", &prepare_virtiofsd, true, Some(15))
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_fs_multi_segment() {
test_virtio_fs(
true,
Some(0x4000_0000),
"never",
&prepare_virtiofsd,
false,
Some(15),
)
test_virtio_fs(false, None, "never", &prepare_virtiofsd, false, Some(15))
}
#[test]
@@ -3296,7 +3316,6 @@ mod parallel {
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
#[cfg(feature = "acpi")]
assert!(guest
.does_device_vendor_pair_match("0x1043", "0x1af4")
.unwrap_or_default());
@@ -4295,12 +4314,6 @@ mod parallel {
thread::sleep(std::time::Duration::new(20, 0));
let r = std::panic::catch_unwind(|| {
// On AArch64 when acpi is enabled, there is a 4 MiB gap between the RAM
// that the VMM gives and the guest can see.
// This is a temporary solution, will be fixed in future.
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
let guest_memory_size_kb = guest_memory_size_kb - 4 * 1024;
let overhead = get_vmm_overhead(child.id(), guest_memory_size_kb);
eprintln!(
"Guest memory overhead: {} vs {}",
@@ -5045,7 +5058,7 @@ mod parallel {
let guest = Guest::new(Box::new(focal));
let kernel_path = direct_kernel_boot_path();
let api_socket = temp_api_path(&guest.tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&guest.tmp_dir));
let net_id = "net123";
let net_params = format!(
@@ -5061,7 +5074,7 @@ mod parallel {
let socket = temp_vsock_path(&guest.tmp_dir);
let mut child = GuestCommand::new(&guest)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_source])
.args(&["--cpus", "boot=4"])
.args(&[
"--memory",
@@ -5097,11 +5110,11 @@ mod parallel {
// Check the guest RAM
assert!(guest.get_total_memory().unwrap_or_default() > 3_840_000);
// Increase guest RAM with virtio-mem
resize_command(&api_socket, None, Some(6 << 30), None);
resize_command(&api_socket_source, None, Some(6 << 30), None);
thread::sleep(std::time::Duration::new(5, 0));
assert!(guest.get_total_memory().unwrap_or_default() > 5_760_000);
// Use balloon to remove RAM from the VM
resize_command(&api_socket, None, None, Some(1 << 30));
resize_command(&api_socket_source, None, None, Some(1 << 30));
thread::sleep(std::time::Duration::new(5, 0));
let total_memory = guest.get_total_memory().unwrap_or_default();
assert!(total_memory > 4_800_000);
@@ -5118,12 +5131,16 @@ mod parallel {
// AArch64: Device hotplug is currently not supported, skipping here.
#[cfg(target_arch = "x86_64")]
{
assert!(remote_command(&api_socket, "remove-device", Some(net_id),));
assert!(remote_command(
&api_socket_source,
"remove-device",
Some(net_id),
));
thread::sleep(std::time::Duration::new(10, 0));
// Plug the virtio-net device again
assert!(remote_command(
&api_socket,
&api_socket_source,
"add-net",
Some(net_params.as_str()),
));
@@ -5131,11 +5148,11 @@ mod parallel {
}
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -5162,9 +5179,11 @@ mod parallel {
.output()
.unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&guest.tmp_dir));
// Restore the VM from the snapshot
let mut child = GuestCommand::new(&guest)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -5178,7 +5197,7 @@ mod parallel {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
// Perform same checks to validate VM has been properly restored
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 4);
@@ -5186,11 +5205,11 @@ mod parallel {
assert!(total_memory > 4_800_000);
assert!(total_memory < 5_760_000);
// Deflate balloon to restore entire RAM to the VM
resize_command(&api_socket, None, None, Some(0));
resize_command(&api_socket_restored, None, None, Some(0));
thread::sleep(std::time::Duration::new(5, 0));
assert!(guest.get_total_memory().unwrap_or_default() > 5_760_000);
// Decrease guest RAM with virtio-mem
resize_command(&api_socket, None, Some(5 << 30), None);
resize_command(&api_socket_restored, None, Some(5 << 30), None);
thread::sleep(std::time::Duration::new(5, 0));
let total_memory = guest.get_total_memory().unwrap_or_default();
assert!(total_memory > 4_800_000);
@@ -5585,9 +5604,9 @@ mod parallel {
let focal2 = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest2 = Guest::new(Box::new(focal2));
let api_socket = temp_api_path(&guest2.tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&guest2.tmp_dir));
let (mut child1, mut child2) = setup_ovs_dpdk_guests(&guest1, &guest2, &api_socket);
let (mut child1, mut child2) = setup_ovs_dpdk_guests(&guest1, &guest2, &api_socket_source);
// Create the snapshot directory
let snapshot_dir = temp_snapshot_dir_path(&guest2.tmp_dir);
@@ -5621,11 +5640,11 @@ mod parallel {
guest2.ssh_command("nc -vz 172.100.0.1 12345").unwrap();
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -5646,9 +5665,10 @@ mod parallel {
.output()
.unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&guest2.tmp_dir));
// Restore the VM from the snapshot
let mut child2 = GuestCommand::new(&guest2)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -5662,7 +5682,7 @@ mod parallel {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
// Spawn a new netcat listener in the first VM
let guest_ip = guest1.network.guest_ip.clone();
@@ -5748,16 +5768,11 @@ mod parallel {
exec_host_command_status("pkill -f nvmf_tgt");
}
#[ignore]
#[test]
#[cfg(target_arch = "aarch64")]
fn test_vfio_user() {
#[cfg(target_arch = "aarch64")]
let focal_image = FOCAL_IMAGE_UPDATE_KERNEL_NAME.to_string();
#[cfg(target_arch = "x86_64")]
let focal_image = FOCAL_IMAGE_NAME.to_string();
let focal = UbuntuDiskConfig::new(focal_image);
let guest = Guest::new(Box::new(focal));
let jammy_image = JAMMY_IMAGE_NAME.to_string();
let jammy = UbuntuDiskConfig::new(jammy_image);
let guest = Guest::new(Box::new(jammy));
let spdk_nvme_dir = guest.tmp_dir.as_path().join("test-vfio-user");
setup_spdk_nvme(spdk_nvme_dir.as_path());
@@ -5766,8 +5781,9 @@ mod parallel {
let mut child = GuestCommand::new(&guest)
.args(&["--api-socket", &api_socket])
.args(&["--cpus", "boot=1"])
.args(&["--memory", "size=512M,shared=on"])
.args(&["--memory", "size=512M,shared=on,hugepages=on"])
.args(&["--kernel", fw_path(FwType::RustHypervisorFirmware).as_str()])
.args(&["--serial", "tty", "--console", "off"])
.default_disks()
.default_net()
.capture_output()
@@ -5792,9 +5808,9 @@ mod parallel {
);
assert!(cmd_success);
assert!(String::from_utf8_lossy(&cmd_output)
.contains("{\"id\":\"vfio_user0\",\"bdf\":\"0000:00:06.0\"}"));
.contains("{\"id\":\"vfio_user0\",\"bdf\":\"0000:00:05.0\"}"));
thread::sleep(std::time::Duration::new(1, 0));
thread::sleep(std::time::Duration::new(10, 0));
// Check both if /dev/nvme exists and if the block size is 128M.
assert_eq!(
@@ -5837,6 +5853,207 @@ mod parallel {
handle_child_output(r, &output);
}
#[test]
#[cfg(target_arch = "x86_64")]
fn test_vdpa_block() {
// Before trying to run the test, verify the vdpa_sim_blk module is correctly loaded.
if !exec_host_command_status("lsmod | grep vdpa_sim_blk").success() {
return;
}
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let api_socket = temp_api_path(&guest.tmp_dir);
let kernel_path = direct_kernel_boot_path();
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", "boot=2"])
.args(&["--memory", "size=512M,hugepages=on"])
.args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.default_net()
.args(&["--vdpa", "path=/dev/vhost-vdpa-0,num_queues=1"])
.args(&["--platform", "num_pci_segments=2,iommu_segments=1"])
.args(&["--api-socket", &api_socket])
.capture_output()
.spawn()
.unwrap();
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
// Check both if /dev/vdc exists and if the block size is 128M.
assert_eq!(
guest
.ssh_command("lsblk | grep vdc | grep -c 128M")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
1
);
// Check the content of the block device after we wrote to it.
// The vpda-sim-blk should let us read what we previously wrote.
guest
.ssh_command("sudo bash -c 'echo foobar > /dev/vdc'")
.unwrap();
assert_eq!(
guest.ssh_command("sudo head -1 /dev/vdc").unwrap().trim(),
"foobar"
);
// Hotplug an extra vDPA block device behind the vIOMMU
// Add a new vDPA device to the VM
let (cmd_success, cmd_output) = remote_command_w_output(
&api_socket,
"add-vdpa",
Some("id=myvdpa0,path=/dev/vhost-vdpa-1,num_queues=1,pci_segment=1,iommu=on"),
);
assert!(cmd_success);
assert!(String::from_utf8_lossy(&cmd_output)
.contains("{\"id\":\"myvdpa0\",\"bdf\":\"0001:00:01.0\"}"));
thread::sleep(std::time::Duration::new(10, 0));
// Check IOMMU setup
assert!(guest
.does_device_vendor_pair_match("0x1057", "0x1af4")
.unwrap_or_default());
assert_eq!(
guest
.ssh_command("ls /sys/kernel/iommu_groups/0/devices")
.unwrap()
.trim(),
"0001:00:01.0"
);
// Check both if /dev/vdd exists and if the block size is 128M.
assert_eq!(
guest
.ssh_command("lsblk | grep vdd | grep -c 128M")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
1
);
// Write some content to the block device we've just plugged.
guest
.ssh_command("sudo bash -c 'echo foobar > /dev/vdd'")
.unwrap();
// Check we can read the content back.
assert_eq!(
guest.ssh_command("sudo head -1 /dev/vdd").unwrap().trim(),
"foobar"
);
// Unplug the device
let cmd_success = remote_command(&api_socket, "remove-device", Some("myvdpa0"));
assert!(cmd_success);
thread::sleep(std::time::Duration::new(10, 0));
// Check /dev/vdd doesn't exist anymore
assert_eq!(
guest
.ssh_command("lsblk | grep -c vdd || true")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or(1),
0
);
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
#[test]
#[cfg(target_arch = "x86_64")]
fn test_vdpa_net() {
// Before trying to run the test, verify the vdpa_sim_net module is correctly loaded.
if !exec_host_command_status("lsmod | grep vdpa_sim_net").success() {
return;
}
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let kernel_path = direct_kernel_boot_path();
let mut child = GuestCommand::new(&guest)
.args(&["--cpus", "boot=2"])
.args(&["--memory", "size=512M,hugepages=on"])
.args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.default_net()
.args(&["--vdpa", "path=/dev/vhost-vdpa-2,num_queues=2"])
.capture_output()
.spawn()
.unwrap();
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
// Check we can find network interface related to vDPA device
assert_eq!(
guest
.ssh_command("ip -o link | grep -c ens6")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or(0),
1
);
guest
.ssh_command("sudo ip addr add 172.16.1.2/24 dev ens6")
.unwrap();
guest.ssh_command("sudo ip link set up dev ens6").unwrap();
// Check there is no packet yet on both TX/RX of the network interface
assert_eq!(
guest
.ssh_command("ip -j -p -s link show ens6 | grep -c '\"packets\": 0'")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or(0),
2
);
// Send 6 packets with ping command
guest.ssh_command("ping 172.16.1.10 -c 6 || true").unwrap();
// Check we can find 6 packets on both TX/RX of the network interface
assert_eq!(
guest
.ssh_command("ip -j -p -s link show ens6 | grep -c '\"packets\": 6'")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or(0),
2
);
// No need to check for hotplug as we already tested it through
// test_vdpa_block()
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
}
mod sequential {
@@ -6267,10 +6484,10 @@ mod windows {
ovmf_path.push(OVMF_NAME);
let tmp_dir = TempDir::new_with_prefix("/tmp/ch").unwrap();
let api_socket = temp_api_path(&tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&tmp_dir));
let mut child = GuestCommand::new(windows_guest.guest())
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_source])
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=4G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
@@ -6297,11 +6514,11 @@ mod windows {
let snapshot_dir = temp_snapshot_dir_path(&tmp_dir);
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -6312,9 +6529,11 @@ mod windows {
let _ = child.kill();
child.wait().unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&tmp_dir));
// Restore the VM from the snapshot
let mut child = GuestCommand::new(windows_guest.guest())
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -6328,7 +6547,7 @@ mod windows {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
windows_guest.shutdown();
});
@@ -7070,7 +7289,7 @@ mod live_migration {
"--memory-zone",
"id=mem0,size=1G,hotplug_size=32G",
"id=mem1,size=1G,hotplug_size=32G",
"id=mem2,size=1G,hotplug_size=32G",
"id=mem2,size=2G,hotplug_size=32G",
"--numa",
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
@@ -7121,7 +7340,7 @@ mod live_migration {
// virtio-mem regions being used.
if numa {
guest.check_numa_common(
Some(&[960_000, 960_000, 960_000]),
Some(&[960_000, 960_000, 1_920_000]),
Some(&[vec![0, 1, 2], vec![3, 4], vec![5]]),
Some(&["10 15 20", "20 10 25", "25 30 10"]),
);
@@ -7136,7 +7355,7 @@ mod live_migration {
// has been assigned the right amount of memory.
resize_zone_command(&src_api_socket, "mem0", "2G");
resize_zone_command(&src_api_socket, "mem1", "2G");
resize_zone_command(&src_api_socket, "mem2", "2G");
resize_zone_command(&src_api_socket, "mem2", "3G");
thread::sleep(std::time::Duration::new(5, 0));
guest.check_numa_common(Some(&[1_920_000, 1_920_000, 1_920_000]), None, None);
@@ -7292,14 +7511,15 @@ mod live_migration {
let r = std::panic::catch_unwind(|| {
// Perform same checks to validate VM has been properly migrated
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 6);
#[cfg(target_arch = "x86_64")]
if numa {
#[cfg(target_arch = "x86_64")]
assert!(guest.get_total_memory().unwrap_or_default() > 5_760_000);
#[cfg(target_arch = "aarch64")]
assert!(guest.get_total_memory().unwrap_or_default() > 2_880_000);
assert!(guest.get_total_memory().unwrap_or_default() > 6_720_000);
} else {
assert!(guest.get_total_memory().unwrap_or_default() > 3_840_000);
}
#[cfg(target_arch = "aarch64")]
assert!(guest.get_total_memory().unwrap_or_default() > 3_840_000);
guest.check_devices_common(None, Some(&console_text));
// Perform NUMA related checks
@@ -7307,7 +7527,7 @@ mod live_migration {
#[cfg(target_arch = "aarch64")]
{
guest.check_numa_common(
Some(&[960_000, 960_000, 960_000]),
Some(&[960_000, 960_000, 1_920_000]),
Some(&[vec![0, 1, 2], vec![3, 4], vec![5]]),
Some(&["10 15 20", "20 10 25", "25 30 10"]),
);
@@ -7318,7 +7538,7 @@ mod live_migration {
#[cfg(target_arch = "x86_64")]
{
guest.check_numa_common(
Some(&[1_920_000, 1_920_000, 1_920_000]),
Some(&[1_920_000, 1_920_000, 2_880_000]),
Some(&[vec![0, 1, 2], vec![3, 4], vec![5]]),
Some(&["10 15 20", "20 10 25", "25 30 10"]),
);
@@ -7587,7 +7807,7 @@ mod live_migration {
}
}
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
#[cfg(target_arch = "aarch64")]
mod aarch64_acpi {
use crate::*;
@@ -7650,7 +7870,9 @@ mod aarch64_acpi {
_test_power_button(true);
}
// https://github.com/cloud-hypervisor/cloud-hypervisor/issues/3941
#[test]
#[ignore]
fn test_virtio_iommu() {
_test_virtio_iommu(true)
}

View File

@@ -2,12 +2,12 @@
name = "vfio_user"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
anyhow = "1.0.55"
libc = "0.2.119"
log = "0.4.14"
anyhow = "1.0.56"
libc = "0.2.123"
log = "0.4.16"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"

View File

@@ -255,6 +255,8 @@ pub enum Error {
StreamWrite(#[source] std::io::Error),
#[error("Error reading from stream: {0}")]
StreamRead(#[source] std::io::Error),
#[error("Error shutting down stream: {0}")]
StreamShutdown(#[source] std::io::Error),
#[error("Error writing with file descriptors: {0}")]
SendWithFd(#[source] vmm_sys_util::errno::Error),
#[error("Error reading with file descriptors: {0}")]
@@ -665,4 +667,10 @@ impl Client {
pub fn resettable(&self) -> bool {
self.resettable
}
pub fn shutdown(&self) -> Result<(), Error> {
self.stream
.shutdown(std::net::Shutdown::Both)
.map_err(Error::StreamShutdown)
}
}

View File

@@ -2,14 +2,14 @@
name = "vhdx"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
license = "Apache-2.0"
[dependencies]
byteorder = "1.4.3"
crc32c = "0.6.1"
libc = "0.2.119"
log = "0.4.14"
crc32c = "0.6.3"
libc = "0.2.123"
log = "0.4.16"
remain = "0.2.2"
thiserror = "1.0"
uuid = { version = "0.8.2", features = ["v4"] }

View File

@@ -2,19 +2,22 @@
name = "vhost_user_block"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
block_util = { path = "../block_util" }
clap = { version = "3.1.5", features = ["wrap_help"] }
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
env_logger = "0.9.0"
epoll = "4.3.1"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
option_parser = { path = "../option_parser" }
qcow = { path = "../qcow" }
vhost = { version = "0.3.0", features = ["vhost-user-slave"] }
vhost-user-backend = { git = "https://github.com/rust-vmm/vhost-user-backend", branch = "main" }
vhost = { version = "0.4.0", features = ["vhost-user-slave"] }
vhost-user-backend = "0.3.0"
virtio-bindings = "0.1.0"
vm-memory = "0.7.0"
vmm-sys-util = "0.9.0"
[build-dependencies]
clap = { version = "3.1.8", features = ["cargo"] }

View File

@@ -2,18 +2,21 @@
name = "vhost_user_net"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[dependencies]
clap = { version = "3.1.5", features = ["wrap_help"] }
clap = { version = "3.1.8", features = ["wrap_help","cargo"] }
env_logger = "0.9.0"
epoll = "4.3.1"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" }
vhost = { version = "0.3.0", features = ["vhost-user-slave"] }
vhost-user-backend = { git = "https://github.com/rust-vmm/vhost-user-backend", branch = "main" }
vhost = { version = "0.4.0", features = ["vhost-user-slave"] }
vhost-user-backend = "0.3.0"
virtio-bindings = "0.1.0"
vm-memory = "0.7.0"
vmm-sys-util = "0.9.0"
[build-dependencies]
clap = { version = "3.1.8", features = ["cargo"] }

View File

@@ -2,22 +2,22 @@
name = "virtio-devices"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
edition = "2021"
[features]
default = []
mshv = []
[dependencies]
anyhow = "1.0.55"
anyhow = "1.0.56"
arc-swap = "1.5.0"
block_util = { path = "../block_util" }
byteorder = "1.4.3"
epoll = "4.3.1"
event_monitor = { path = "../event_monitor" }
io-uring = "0.5.2"
libc = "0.2.119"
log = "0.4.14"
libc = "0.2.123"
log = "0.4.16"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci" }
@@ -26,11 +26,12 @@ seccompiler = "0.2.0"
serde = "1.0.136"
serde_derive = "1.0.136"
serde_json = "1.0.79"
thiserror = "1.0.30"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vhost = { version = "0.3.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern"] }
vhost = { version = "0.4.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] }
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
virtio-queue = { git = "https://github.com/rust-vmm/vm-virtio", branch = "main" }
virtio-queue = "0.2.0"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }

View File

@@ -151,7 +151,7 @@ impl ConsoleEpollHandler {
if let Err(e) = desc_chain.memory().write_slice(
&source_slice[..],
desc.addr()
.translate(self.access_platform.as_ref(), desc.len() as usize),
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
) {
error!("Failed to write slice: {:?}", e);
avail_iter.go_to_previous_position();
@@ -190,7 +190,7 @@ impl ConsoleEpollHandler {
if let Some(ref mut out) = self.endpoint.out_file() {
let _ = desc_chain.memory().write_to(
desc.addr()
.translate(self.access_platform.as_ref(), desc.len() as usize),
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
out,
desc.len() as usize,
);

View File

@@ -207,7 +207,10 @@ pub trait VirtioDevice: Send {
/// On the other side, the implementation itself should be provided by the code
/// emulating the IOMMU for the guest.
pub trait DmaRemapping: Send + Sync {
fn translate(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
/// Provide a way to translate GVA address ranges into GPAs.
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
/// Provide a way to translate GPA address ranges into GVAs.
fn translate_gpa(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
}
/// Structure to handle device state common to all devices

View File

@@ -20,7 +20,7 @@ use std::ops::Bound::Included;
use std::os::unix::io::AsRawFd;
use std::result;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier, RwLock};
use std::sync::{Arc, Barrier, Mutex, RwLock};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_queue::{DescriptorChain, Queue};
@@ -572,7 +572,7 @@ struct IommuEpollHandler {
kill_evt: EventFd,
pause_evt: EventFd,
mapping: Arc<IommuMapping>,
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
ext_mapping: Arc<Mutex<BTreeMap<u32, Arc<dyn ExternalDmaMapping>>>>,
ext_domain_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
msi_iova_space: (u64, u64),
}
@@ -585,7 +585,7 @@ impl IommuEpollHandler {
let len = match Request::parse(
&mut desc_chain,
&self.mapping,
&self.ext_mapping,
&self.ext_mapping.lock().unwrap(),
&mut self.ext_domain_mapping,
self.msi_iova_space,
) {
@@ -683,8 +683,8 @@ pub struct IommuMapping {
}
impl DmaRemapping for IommuMapping {
fn translate(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
debug!("Translate addr 0x{:x}", addr);
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
debug!("Translate GVA addr 0x{:x}", addr);
if let Some(domain) = self.endpoints.read().unwrap().get(&id) {
if let Some(mapping) = self.mappings.read().unwrap().get(domain) {
let range_start = if VIRTIO_IOMMU_PAGE_SIZE_MASK > addr {
@@ -695,15 +695,37 @@ impl DmaRemapping for IommuMapping {
for (&key, &value) in mapping.range((Included(&range_start), Included(&addr))) {
if addr >= key && addr < key + value.size {
let new_addr = addr - key + value.gpa;
debug!("Into new_addr 0x{:x}", new_addr);
debug!("Into GPA addr 0x{:x}", new_addr);
return Ok(new_addr);
}
}
}
}
debug!("Into same addr...");
Ok(addr)
Err(io::Error::new(
io::ErrorKind::Other,
format!("failed to translate GVA addr 0x{:x}", addr),
))
}
fn translate_gpa(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
debug!("Translate GPA addr 0x{:x}", addr);
if let Some(domain) = self.endpoints.read().unwrap().get(&id) {
if let Some(mapping) = self.mappings.read().unwrap().get(domain) {
for (&key, &value) in mapping.iter() {
if addr >= value.gpa && addr < value.gpa + value.size {
let new_addr = addr - value.gpa + key;
debug!("Into GVA addr 0x{:x}", new_addr);
return Ok(new_addr);
}
}
}
}
Err(io::Error::new(
io::ErrorKind::Other,
format!("failed to translate GPA addr 0x{:x}", addr),
))
}
}
@@ -720,8 +742,11 @@ impl AccessPlatformMapping {
}
impl AccessPlatform for AccessPlatformMapping {
fn translate(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
self.mapping.translate(self.id, base)
fn translate_gva(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
self.mapping.translate_gva(self.id, base)
}
fn translate_gpa(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
self.mapping.translate_gpa(self.id, base)
}
}
@@ -730,7 +755,7 @@ pub struct Iommu {
id: String,
config: VirtioIommuConfig,
mapping: Arc<IommuMapping>,
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
ext_mapping: Arc<Mutex<BTreeMap<u32, Arc<dyn ExternalDmaMapping>>>>,
seccomp_action: SeccompAction,
exit_evt: EventFd,
msi_iova_space: (u64, u64),
@@ -778,7 +803,7 @@ impl Iommu {
},
config,
mapping: mapping.clone(),
ext_mapping: BTreeMap::new(),
ext_mapping: Arc::new(Mutex::new(BTreeMap::new())),
seccomp_action,
exit_evt,
msi_iova_space,
@@ -824,7 +849,7 @@ impl Iommu {
}
pub fn add_external_mapping(&mut self, device_id: u32, mapping: Arc<dyn ExternalDmaMapping>) {
self.ext_mapping.insert(device_id, mapping);
self.ext_mapping.lock().unwrap().insert(device_id, mapping);
}
}

View File

@@ -34,6 +34,7 @@ mod rng;
pub mod seccomp_filters;
mod thread_helper;
pub mod transport;
pub mod vdpa;
pub mod vhost_user;
pub mod vsock;
pub mod watchdog;
@@ -48,6 +49,7 @@ pub use self::mem::*;
pub use self::net::*;
pub use self::pmem::*;
pub use self::rng::*;
pub use self::vdpa::*;
pub use self::vsock::*;
pub use self::watchdog::*;
use vm_memory::{bitmap::AtomicBitmap, GuestAddress, GuestMemory};
@@ -100,6 +102,8 @@ pub enum ActivateError {
CreateSeccompFilter(seccompiler::Error),
/// Cannot create rate limiter
CreateRateLimiter(std::io::Error),
/// Failed activating the vDPA device
ActivateVdpa(vdpa::Error),
}
pub type ActivateResult = std::result::Result<(), ActivateError>;
@@ -110,6 +114,7 @@ pub type DeviceEventT = u16;
pub enum Error {
FailedSignalingUsedQueue(io::Error),
IoError(io::Error),
VdpaUpdateMemory(vdpa::Error),
VhostUserUpdateMemory(vhost_user::Error),
VhostUserAddMemoryRegion(vhost_user::Error),
SetShmRegionsNotSupported,

View File

@@ -137,6 +137,8 @@ pub enum Error {
DmaUnmap(std::io::Error),
// Invalid DMA mapping handler
InvalidDmaMappingHandler,
// Not activated by the guest
NotActivatedByGuest,
}
#[repr(C)]
@@ -327,6 +329,7 @@ impl Request {
pub struct ResizeSender {
hotplugged_size: Arc<AtomicU64>,
activated: Arc<AtomicBool>,
tx: mpsc::Sender<Result<(), Error>>,
evt: EventFd,
}
@@ -345,6 +348,7 @@ impl Clone for ResizeSender {
fn clone(&self) -> Self {
ResizeSender {
hotplugged_size: self.hotplugged_size.clone(),
activated: self.activated.clone(),
tx: self.tx.clone(),
evt: self
.evt
@@ -356,6 +360,7 @@ impl Clone for ResizeSender {
pub struct Resize {
hotplugged_size: Arc<AtomicU64>,
activated: Arc<AtomicBool>,
tx: mpsc::Sender<Result<(), Error>>,
rx: mpsc::Receiver<Result<(), Error>>,
evt: EventFd,
@@ -367,6 +372,7 @@ impl Resize {
Ok(Resize {
hotplugged_size: Arc::new(AtomicU64::new(hotplugged_size)),
activated: Arc::new(AtomicBool::default()),
tx,
rx,
evt: EventFd::new(EFD_NONBLOCK)?,
@@ -376,12 +382,17 @@ impl Resize {
pub fn new_resize_sender(&self) -> Result<ResizeSender, Error> {
Ok(ResizeSender {
hotplugged_size: self.hotplugged_size.clone(),
activated: self.activated.clone(),
tx: self.tx.clone(),
evt: self.evt.try_clone().map_err(Error::EventFdTryCloneFail)?,
})
}
pub fn work(&self, desired_size: u64) -> Result<(), Error> {
if !self.activated.load(Ordering::Acquire) {
return Err(Error::NotActivatedByGuest);
}
self.hotplugged_size.store(desired_size, Ordering::Release);
self.evt.write(1).map_err(Error::EventFdWriteFail)?;
self.rx.recv().map_err(Error::MpscRecvFail)?
@@ -1046,11 +1057,14 @@ impl VirtioDevice for Mem {
)?;
self.common.epoll_threads = Some(epoll_threads);
self.resize.activated.store(true, Ordering::Release);
event!("virtio-device", "activated", "id", &self.id);
Ok(())
}
fn reset(&mut self) -> Option<Arc<dyn VirtioInterrupt>> {
self.resize.activated.store(false, Ordering::Release);
let result = self.common.reset();
event!("virtio-device", "reset", "id", &self.id);
result

View File

@@ -53,9 +53,20 @@ pub struct NetCtrlEpollHandler {
pub queue_evt: EventFd,
pub queue: Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
pub access_platform: Option<Arc<dyn AccessPlatform>>,
pub interrupt_cb: Arc<dyn VirtioInterrupt>,
pub queue_index: u16,
}
impl NetCtrlEpollHandler {
fn signal_used_queue(&self, queue_index: u16) -> result::Result<(), DeviceError> {
self.interrupt_cb
.trigger(VirtioInterruptType::Queue(queue_index))
.map_err(|e| {
error!("Failed to signal used queue: {:?}", e);
DeviceError::FailedSignalingUsedQueue(e)
})
}
pub fn run_ctrl(
&mut self,
paused: Arc<AtomicBool>,
@@ -75,19 +86,33 @@ impl EpollHelperHandler for NetCtrlEpollHandler {
match ev_type {
CTRL_QUEUE_EVENT => {
if let Err(e) = self.queue_evt.read() {
error!("failed to get ctl queue event: {:?}", e);
error!("Failed to get control queue event: {:?}", e);
return true;
}
if let Err(e) = self
.ctrl_q
.process(&mut self.queue, self.access_platform.as_ref())
{
error!("failed to process ctrl queue: {:?}", e);
error!("Failed to process control queue: {:?}", e);
return true;
} else {
match self.queue.needs_notification() {
Ok(true) => {
if let Err(e) = self.signal_used_queue(self.queue_index) {
error!("Error signalling that control queue was used: {:?}", e);
return true;
}
}
Ok(false) => {}
Err(e) => {
error!("Error getting notification state of control queue: {}", e);
return true;
}
}
}
}
_ => {
error!("Unknown event for virtio-net");
error!("Unknown event for virtio-net control queue");
return true;
}
}
@@ -565,19 +590,25 @@ impl VirtioDevice for Net {
) -> ActivateResult {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
let queue_num = queues.len();
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && queue_num % 2 != 0 {
let cvq_queue = queues.remove(queue_num - 1);
let cvq_queue_evt = queue_evts.remove(queue_num - 1);
let num_queues = queues.len();
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 {
let ctrl_queue_index = num_queues - 1;
let mut ctrl_queue = queues.remove(ctrl_queue_index);
let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index);
ctrl_queue.set_event_idx(event_idx);
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let mut ctrl_handler = NetCtrlEpollHandler {
kill_evt,
pause_evt,
ctrl_q: CtrlQueue::new(self.taps.clone()),
queue: cvq_queue,
queue_evt: cvq_queue_evt,
queue: ctrl_queue,
queue_evt: ctrl_queue_evt,
access_platform: self.common.access_platform.clone(),
queue_index: ctrl_queue_index as u16,
interrupt_cb: interrupt_cb.clone(),
};
let paused = self.common.paused.clone();
@@ -603,8 +634,6 @@ impl VirtioDevice for Net {
self.ctrl_queue_epoll_thread = Some(epoll_threads.remove(0));
}
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
let mut epoll_threads = Vec::new();
let mut taps = self.taps.clone();
for i in 0..queues.len() / 2 {

View File

@@ -133,7 +133,10 @@ impl Request {
let request: VirtioPmemReq = desc_chain
.memory()
.read_obj(desc.addr().translate(access_platform, desc.len() as usize))
.read_obj(
desc.addr()
.translate_gva(access_platform, desc.len() as usize),
)
.map_err(Error::GuestMemory)?;
let request_type = match request.type_ {
@@ -156,7 +159,7 @@ impl Request {
type_: request_type,
status_addr: status_desc
.addr()
.translate(access_platform, status_desc.len() as usize),
.translate_gva(access_platform, status_desc.len() as usize),
})
}
}

View File

@@ -61,7 +61,7 @@ impl RngEpollHandler {
.memory()
.read_from(
desc.addr()
.translate(self.access_platform.as_ref(), desc.len() as usize),
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
&mut self.random_file,
desc.len() as usize,
)

View File

@@ -160,6 +160,8 @@ fn virtio_vhost_fs_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_connect, vec![]),
(libc::SYS_nanosleep, vec![]),
(libc::SYS_pread64, vec![]),
(libc::SYS_pwrite64, vec![]),
(libc::SYS_recvmsg, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_sendto, vec![]),
@@ -178,7 +180,6 @@ fn virtio_vhost_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_getcwd, vec![]),
(libc::SYS_listen, vec![]),
(libc::SYS_recvmsg, vec![]),
(libc::SYS_rt_sigreturn, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_sendto, vec![]),
(libc::SYS_socket, vec![]),
@@ -242,7 +243,6 @@ fn get_seccomp_rules(thread_type: Thread) -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_thread_common() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_brk, vec![]),
#[cfg(feature = "mshv")]
(libc::SYS_clock_gettime, vec![]),
(libc::SYS_close, vec![]),
(libc::SYS_dup, vec![]),
@@ -259,6 +259,7 @@ fn virtio_thread_common() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_openat, vec![]),
(libc::SYS_read, vec![]),
(libc::SYS_rt_sigprocmask, vec![]),
(libc::SYS_rt_sigreturn, vec![]),
(libc::SYS_sigaltstack, vec![]),
(libc::SYS_write, vec![]),
]

View File

@@ -204,11 +204,15 @@ impl VirtioPciCommonConfig {
// Translate address of descriptor table and vrings.
if let Some(access_platform) = &self.access_platform {
if ready {
let desc_table =
access_platform.translate(q.state.desc_table.0, 0).unwrap();
let avail_ring =
access_platform.translate(q.state.avail_ring.0, 0).unwrap();
let used_ring = access_platform.translate(q.state.used_ring.0, 0).unwrap();
let desc_table = access_platform
.translate_gva(q.state.desc_table.0, 0)
.unwrap();
let avail_ring = access_platform
.translate_gva(q.state.avail_ring.0, 0)
.unwrap();
let used_ring = access_platform
.translate_gva(q.state.used_ring.0, 0)
.unwrap();
q.set_desc_table_address(
Some((desc_table & 0xffff_ffff) as u32),
Some((desc_table >> 32) as u32),

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