Compare commits

...

212 Commits

Author SHA1 Message Date
Rob Bradford
e01933c8ea build: Release v21.1 (bug fix release)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Rob Bradford
c6307865eb 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>
(cherry picked from commit 223d0cf787)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Yi Wang
6275d4f87e 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>
(cherry picked from commit 5375b84e3b)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Yi Wang
4dfe1ff77a 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>
(cherry picked from commit db9e5e5a87)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Rob Bradford
bbda07c388 pci: Support DWORD/4-byte writes to the MSI-X control register
The PCI spec does not specify that the access has to be of a specific
size.

Fixes: #3714

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 9c6e7c4a4b)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Rob Bradford
366223c9f4 vmm: Ensure that PIO and MMIO exits complete before pausing
As per this kernel documentation:

      For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_PAPR, KVM_EXIT_XEN,
      KVM_EXIT_EPR, KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR the corresponding
      operations are complete (and guest state is consistent) only after userspace
      has re-entered the kernel with KVM_RUN.  The kernel side will first finish
      incomplete operations and then check for pending signals.

      The pending state of the operation is not preserved in state which is
      visible to userspace, thus userspace should ensure that the operation is
      completed before performing a live migration.  Userspace can re-enter the
      guest with an unmasked signal pending or with the immediate_exit field set
      to complete pending operations without allowing any further instructions
      to be executed.

Since we capture the state as part of the pause and override it as part
of the resume we must ensure the state is consistent otherwise we will
lose the results of the MMIO or PIO operation that caused the exit from
which we paused.

Fixes: #3658

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 507912385a)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Rob Bradford
375356a097 virtio-devices: Add openat() syscall to seccomp filter
When freeing memory sometimes glibc will attempt to read
"/proc/sys/vm/overcommit_memory" to find out how it should release the
blocks. This happens sporadically with Cloud Hypervisor but has been
seen in use. It is not necessary to add the read() syscall to the list
as it is already included in the virtio devices common set. Similarly
the vCPU and vmm threads already have both these in the allowed list.

Fixes: #3609

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 53caa565bb)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-03-11 08:44:05 +00:00
Rob Bradford
95ca79974a build: Release v21.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-20 14:48:11 +00:00
Sebastien Boeuf
eb5c5f2c7f tests: Add integration test for O_DIRECT
Both OVMF and RHF firmwares triggered an error when O_DIRECT was used
because they didn't align the buffers to the block sector size.

In order to prevent regressions, we're adding a new test validating the
VM can properly boot when the OS disk is opened with O_DIRECT and booted
from the rust-hypervisor-fw.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-20 11:49:02 +00:00
Sebastien Boeuf
85bbf75fe8 block_util: Align buffers for O_DIRECT
Whenever the backing file of our virtio-block device is opened with
O_DIRECT, there's a requirement about the buffer address and size to be
aligned to the sector size.

We know virtio-block requests are sector aligned in terms of size, but
we must still check if the buffer address is. In case it's not, we
create an intermediate buffer that will be passed through the system
call. In case of a write operation, the content of the non-aligned
buffer must be copied beforehand, and in case of a read operation, the
content of the aligned buffer must be copied to the non-aligned one
after the operation has been completed.

Fixes #3587

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-20 11:49:02 +00:00
Henry Wang
b4566b9eab tests: ignore the result from test_vfio_user
As it is currently unstable.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-20 11:40:30 +00:00
Anatol Belski
e2a8a1483f acpi: aarch64: Implement DBG2 table
This table is listed as required in the ARM Base Boot Requirements
document. The particular need arises to make the serial debugging of
Windows guest functional.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2022-01-20 09:11:21 +08:00
Rob Bradford
ea60d48853 resources: Update Rust version in container to 1.58
Update to the latest stable release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-19 09:53:42 -08:00
Rob Bradford
658658e76c hypervisor: kvm: Ignore -EINVAL from KVM_KVMCLOCK_CTRL ioctl()
If the guest hasn't initialised a PV clock then the KVM_KVMCLOCK_CTRL
ioctl will return -EINVAL. Therefore if running in the firmware or an OS
that doesn't use the PV clock then we should ignore that error

Tested by migrating a VM that has not yet booted into the Linux kernel
(just in firmware) by specifying no disk image:

e.g. target/debug/cloud-hypervisor --kernel ~/workloads/hypervisor-fw --api-socket /tmp/api --serial tty --console off

Fixes: #3586

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-19 10:12:57 +01:00
Henry Wang
b7b3b45364 tests: Enable test_vfio_user for AArch64
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-18 18:00:00 -08:00
Henry Wang
d5b4d0d951 resources: AArch64: Enable Device Mapper and NVME Multipath in config
From 15358ef79d: Device Mapper Multipath
config can avoid systemd errors related to Device Mapper multipath while
guest booting.

From 46672c384c: CONFIG_NVME_MULTIPATH is
needed to fix the observed guest hanging issue cased by systemd crash
while booting.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-18 18:00:00 -08:00
Henry Wang
1c18d124dc scripts: Add more huge pages for AArch64 integration test
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-18 18:00:00 -08:00
Henry Wang
7a42ce9310 scripts: AArch64: Build SPDK NVMe before running integration tests
The SPDK-NVMe is needed for the integration test for vfio_user.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-18 18:00:00 -08:00
Michael Zhao
1db7718589 pci, vmm: Pass PCI BDF to vfio and vfio_user
On AArch64, PCI BDF is used for devId in MSI-X routing entry.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-01-18 18:00:00 -08:00
Henry Wang
cf68f03ab6 pci: vfio: Skip IOBAR allocation on AArch64
AArch64 does not use IOBAR, and current code of panics the whole VMM if
we need to allocate the IOBAR.

This commit checks if IOBAR is enabled before the arch conditional code
of IOBAR allocation and if the IOBAR is not enabled, we can just skip
the IOBAR allocation and do nothing.

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

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-18 18:00:00 -08:00
Rob Bradford
4ecc778efe vmm: Avoid deadlock between virtio device activation and vcpu pausing
Ensure all pending virtio activations (as triggered by MMIO write on the
vCPU threads leading to a barrier wait) are completed before pausing the
vCPUs as otherwise there will a deadlock with the VMM waiting for the
vCPU to acknowledge it's pause and the vCPU waiting for the VMM to
activate the device and release the barrier.

Fixes: #3585

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 17:30:06 -08:00
Wei Liu
48ba999bd9 net_util: drop unneeded clippy::cast_lossless
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
ef05354c81 memory_manager: drop unneeded clippy suppressions
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
277cfd07ba device_manager: use if let to drop single match
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
4f05b8463c virtio-devices: fix clippy::needless_range_loop
Use iterator instead.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
c9983ff4ad arch: drop allow(clippy::transmute_ptr_to_ptr)
It is not needed.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
714b529bb2 arch: aarch64: drop unnecessary static lifetime
This also has the side effect for making access_redists_aux function
strictly more useful.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
Wei Liu
99bcebad74 arch: aarch64: do not unnecessarily add mut keyword
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 17:23:27 -08:00
dependabot[bot]
22d86fb6d2 build: bump clap from 3.0.8 to 3.0.10
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.8 to 3.0.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.0.8...v3.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-19 00:09:18 +00:00
dependabot[bot]
2eed24b4b2 build: bump serde_json from 1.0.74 to 1.0.75
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.74 to 1.0.75.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.74...v1.0.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 23:41:56 +00:00
dependabot[bot]
be7829b752 build: bump clap from 3.0.8 to 3.0.10 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.8 to 3.0.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.0.8...v3.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 23:35:44 +00:00
Wei Liu
ea2685e928 block_util: rewrite code and drop allow(clippy::ptr_arg)
The code can be written in a better form and the clippy warning
suppression can be dropped.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-18 16:22:21 +01:00
Henry Wang
14ba3f68d3 vmm: cpu: Remove unused import in unit tests
These are the leftovers from the commit 8155be2:
arch: aarch64: vm_memory is not required when configuring vcpu

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2022-01-18 20:34:50 +08:00
Sebastien Boeuf
779bc1a53a edk2: Rely on latest OVMF based on CloudHvX64 target
Update documentation and CI to rely on the new CLOUDHV.fd firmware built
from the newly introduced target CloudHvX64.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-18 11:58:26 +01:00
Rob Bradford
8b8daf571a README: Ensure kernel build includes the ELF PVH note
See: #3222

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 10:32:08 +01:00
Sebastien Boeuf
482e1ca435 scripts: Pin OVMF EDK2 version
By pinning the OVMF version, we will be able to update the EDK2 fork
with a new version without potentially breaking our Cloud Hypervisor CI.

Once the new version is ready on the EDK2 fork, we'll be able to update
Cloud Hypervisor codebase, replacing the fixed version with the latest,
as well as replacing OVMF.fd with CLOUDHV.fd. This is because we'll
start building from the new target CloudHvX64.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-18 10:21:51 +01:00
Rob Bradford
a61302f73f docs: Update Live migration documentation for local migration
Use new --local for efficient live migration when migrating locally for
live upgrade.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
33fd0af8b3 vm-migration: Update protocol for FD based live migration
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
cb243571de tests: Add test_live_migration_local() test
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
70f7f64e23 vmm: api: Add "local" option to OpenAPI YAML file
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
88952cc500 vmm: Send FDs across unix socket for migration when in local mode
When in local migration mode send the FDs for the guest memory over the
socket along with the slot that the FD is associated with. This removes
the requirement for copying the guest RAM and gives significantly faster
live migration performance (of the order of 3s to 60ms).

Fixes: #3566

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
715a7d9065 vmm: Add convenience API for getting slots to FDs mapping
This will be used for sending those file descriptors for local
migration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
1676fffaad vmm: Check shared memory is enabled for local migration
This is required so that the receiving process can access the existing
process's memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
1daef5e8c9 vmm: Propagate the set of memory slots to FDs received in migration
Create the VM using the FDs (wrapped in Files) that have been received
during the migration process.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
735658a49d vm-migration: Add MemoryFd command for setting FDs for memory
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
b95e46565c vmm: Support using existing files for memory slots
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
eeba1d3ad8 vmm: Support using an existing FD for memory
If this FD (wrapped in a File) is supplied when the RAM region is being
created use that over creating a new one.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
271e17bd79 vmm: Extract code for opening a file for memory
This function is used to open an FD (wrapped in a File) that points to
guest memory from memfd_create() or backed on the filesystem.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
Rob Bradford
b9c260c0de vmm, ch-remote: Add "local" option to send-migration API
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-18 09:07:47 +00:00
dependabot[bot]
6e78ac1837 build: bump clap from 3.0.7 to 3.0.8
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.7 to 3.0.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.0.7...v3.0.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-01-18 00:28:25 +00:00
dependabot[bot]
dad5af612b build: bump serde_json from 1.0.74 to 1.0.75 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.74 to 1.0.75.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.74...v1.0.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 00:00:49 +00:00
dependabot[bot]
101d403a6b build: bump mshv-ioctls from f27b7a4 to b8b69b6
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `f27b7a4` to `b8b69b6`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](f27b7a423b...b8b69b6553)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 00:00:26 +00:00
dependabot[bot]
29e3fefc3d build: bump clap from 3.0.7 to 3.0.8 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.7 to 3.0.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.0.7...v3.0.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 23:32:14 +00:00
Liang Zhou
859f72b5a5 docs: update hotplug.md
Currently cloud-hypervisor supports hotplug of CPUs, passthrough devices, virtio devices and memory resizing,
but in hotplug.md it still mentiones: "Currently Cloud Hypervisor only supports hot plugging of CPU devices."
We need to remove the incorrect information from hotplug.md to reflect the true situation.

Fixes: #3504

Signed-off-by: Liang Zhou <zhoul110@chinatelecom.cn>
2022-01-17 09:43:22 +00:00
Wei Liu
8155be2e6b arch: aarch64: vm_memory is not required when configuring vcpu
Drop the unused parameter throughout the code base.

Also take the chance to drop a needless clone.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-14 16:03:12 -08:00
dependabot[bot]
4577e5050b build: bump smallvec from 1.7.0 to 1.8.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.7.0...v1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 23:44:20 +00:00
dependabot[bot]
1952405f69 build: bump getrandom from 0.2.3 to 0.2.4 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.3 to 0.2.4.
- [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.3...v0.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 15:14:21 +00:00
Rob Bradford
1dc913427c devices: legacy: Fix beta clippy issues
error: unneeded late initalization
Error:    --> devices/src/legacy/rtc_pl031.rs:294:9
    |
294 |         let v;
    |         ^^^^^^
    |
    = note: `-D clippy::needless-late-init` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `v` here
    |
297 |         let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) {
    |         +++++++
help: remove the assignments from the branches
    |
299 ~             u32::from(PL031_ID[index])
300 |         } else {
301 ~             match offset {
302 |                 RTCDR => self.get_time(),
303 |                 RTCMR => {
304 |                     // Even though we are not implementing RTC alarm we return the last value
  ...
help: add a semicolon after the `if` expression
    |
317 |         };
    |          +

error: unneeded late initalization
Error:    --> devices/src/legacy/uart_pl011.rs:297:9
    |
297 |         let v;
    |         ^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `v` here
    |
299 |         let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) {
    |         +++++++
help: remove the assignments from the branches
    |
301 ~             u32::from(PL011_ID[index])
302 |         } else {
303 ~             match offset >> 2 {
304 |                 UARTDR => {
305 |                     let c: u32;
306 |                     let r: u32;
  ...
help: add a semicolon after the `if` expression
    |
340 |         };
    |          +

error: unneeded late initalization
Error:    --> devices/src/legacy/uart_pl011.rs:305:21
    |
305 |                     let c: u32;
    |                     ^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `c` here
    |
309 |                     let c: u32 = self.read_fifo.pop_front().unwrap_or_default().into();
    |                     ~~~~~~~~~~

error: unneeded late initalization
Error:    --> devices/src/legacy/uart_pl011.rs:306:21
    |
306 |                     let r: u32;
    |                     ^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `r` here
    |
320 |                     let r: u32 = c;
    |                     ~~~~~~~~~~

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-14 14:33:18 +00:00
Rob Bradford
0a97b76c52 hypervisor: mshv: Fix beta clippy issue
error: this boolean expression can be simplified
   --> hypervisor/src/mshv/mod.rs:348:25
    |
348 |                         !(unsafe { access_info.__bindgen_anon_1.string_op() } == 1),
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { access_info.__bindgen_anon_1.string_op() } != 1`
    |
    = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool

error: this boolean expression can be simplified
   --> hypervisor/src/mshv/mod.rs:352:25
    |
352 |                         !(unsafe { access_info.__bindgen_anon_1.rep_prefix() } == 1),
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { access_info.__bindgen_anon_1.rep_prefix() } != 1`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-14 14:33:18 +00:00
Rob Bradford
b204f43aae tests: Fix beta clippy issues
error: this boolean expression can be simplified
    --> tests/integration.rs:3755:33
     |
3755 |                         assert!(!(empty > 5), "No login on pty");
     |                                 ^^^^^^^^^^^^ help: try: `empty <= 5`
     |
     = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool

error: unneeded late initalization
    --> tests/integration.rs:7619:13
     |
7619 |             let mut success;
     |             ^^^^^^^^^^^^^^^^
     |
     = note: `-D clippy::needless-late-init` implied by `-D warnings`
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `success` here
     |
7621 |             let mut success = if let Some(status) = send_migration
     |             +++++++++++++++++
help: remove the assignments from the branches
     |
7625 ~                 status.success()
7626 |             } else {
7627 ~                 false
     |
help: add a semicolon after the `if` expression
     |
7628 |             };
     |              +

error: unneeded late initalization
    --> tests/integration.rs:7838:13
     |
7838 |             let mut success;
     |             ^^^^^^^^^^^^^^^^
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `success` here
     |
7840 |             let mut success = if let Some(status) = send_migration
     |             +++++++++++++++++
help: remove the assignments from the branches
     |
7844 ~                 status.success()
7845 |             } else {
7846 ~                 false
     |
help: add a semicolon after the `if` expression
     |
7847 |             };
     |              +

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-14 14:33:18 +00:00
Rob Bradford
ade8d71264 arch: aarch64: Fix beta clippy issue
error: unneeded late initalization
Error:    --> arch/src/aarch64/gic/gicv3_its.rs:127:9
    |
127 |         let attr: u64;
    |         ^^^^^^^^^^^^^^
    |
    = note: `-D clippy::needless-late-init` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `attr` here
    |
128 |         let attr: u64 = if save {
    |         +++++++++++++++
help: remove the assignments from the branches
    |
129 ~             u64::from(kvm_bindings::KVM_DEV_ARM_ITS_SAVE_TABLES)
130 |         } else {
131 ~             u64::from(kvm_bindings::KVM_DEV_ARM_ITS_RESTORE_TABLES)
    |
help: add a semicolon after the `if` expression
    |
132 |         };
    |          +

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-14 14:33:18 +00:00
dependabot[bot]
92b8bdf474 build: bump pnet from 0.28.0 to 0.29.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.28.0 to 0.29.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.28.0...v0.29.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 05:45:07 +00:00
dependabot[bot]
84e2f6c1da build: bump getrandom from 0.2.3 to 0.2.4
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.3 to 0.2.4.
- [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.3...v0.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 05:45:04 +00:00
Michael Zhao
e02f5c9699 resources: Update kernel config on AArch64
Adapted the kernel config on AArch64 to 5.15.12.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2022-01-13 15:39:18 +08:00
dependabot[bot]
2f492fbe36 build: bump clap from 3.0.6 to 3.0.7
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.6 to 3.0.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.0.6...v3.0.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-01-13 00:28:13 +00:00
dependabot[bot]
c47cb868ec build: bump clap from 3.0.6 to 3.0.7 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.6 to 3.0.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.0.6...v3.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-12 23:43:18 +00:00
Fabiano Fidêncio
fb1755d85d vmm: openapi: Fix "fds" field name for NetConfig
We've been currently using "fd" as the field name, but it should be
called "fds" since  6664e5a6e7 introduced
the name change on the structure field.

Fixes: #3560

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-01-12 16:44:51 +01:00
Rob Bradford
5e1e523a90 vmm: Don't check for presence of tdx parameter when not built with tdx
Passing no boot related parameters (e.g. no --kernel) is used for e.g.
receiving a live migration or an API based boot.

marvin:~/src/cloud-hypervisor (2022-01-11-live-migration-with-fds *)$ target/debug/cloud-hypervisor --api-socket /tmp/api2
thread 'main' panicked at '`tdx` is not a name of an argument or a group.
Make sure you're using the name of the argument itself and not the name of short or long flags.', /home/rob/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.0.6/src/parse/matches/arg_matches.rs:598:14
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panicking.rs:107:14
   2: clap::parse::matches::arg_matches::ArgMatches::get_arg
             at /home/rob/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.0.6/src/parse/matches/arg_matches.rs:1052:17
   3: clap::parse::matches::arg_matches::ArgMatches::is_present
             at /home/rob/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-3.0.6/src/parse/matches/arg_matches.rs:598:9
   4: cloud_hypervisor::start_vmm
             at ./src/main.rs:530:46
   5: cloud_hypervisor::main
             at ./src/main.rs:566:27
   6: core::ops::function::FnOnce::call_once
             at /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-11 22:54:33 +01:00
dependabot[bot]
685ca03e67 build: bump clap from 3.0.5 to 3.0.6
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.5 to 3.0.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.0.5...v3.0.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-01-11 00:02:29 +00:00
dependabot[bot]
b80feb3d96 build: bump clap from 3.0.5 to 3.0.6 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.5 to 3.0.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.0.5...v3.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-10 23:33:41 +00:00
Fabiano Fidêncio
cb15ae5462 vmm: openapi: Fix default value for tap
`tap` has its default value set to `None`, but in the openapi yaml file
we've been setting it to `""`.

When using this code on the Kata Containers side we'd be hit by a non
expected behaviour of cloud-hypervisor, as even when using a different
method to initialise the `tuntap` device the code would be treated as if
using `--net tap` (which is a valid use-case).

Related: #3554

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
2022-01-10 13:11:33 +00:00
Bo Chen
6738e45b37 tests: Add crate-level attribute to silence "dead-code" warnings
When enabling the `mshv` feature, we skip quite some tests and
hence have known dead-code. This annotation silences dead-code
related warnings for our quality workflow to pass.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
Bo Chen
c2f133990d github: Remove use of "integration_tests" feature gate
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
Bo Chen
a926bc139b build: Remove "integration_tests" from the feature list
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
Bo Chen
5b05e0cdcd scripts: Remove use of "integration_tests" feature
Given integration tests don't have special annotations, all our
integration test scripts do not need to carry special flags when running
`cargo test`. This commit also removed the "test::" prefix for
pattern-matching different set of integration tests.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
Bo Chen
e7a2a715e0 tests: Remove unnecessary annotations integration_tests and test
Given integration tests are placed in a dedicate directory, they don't
need annotations (e.g. `#[cfg(integration_test)]` and `#[cfg(test)]`) or
defining `test mod` to exclude themselves from the common compilation
process.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
Bo Chen
430f72f96c scripts: Use cargo build-in options to run unit tests only
In this way, we don't need to rely on feature gates to exclude
integration tests from running.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-01-10 10:29:07 +01:00
dependabot[bot]
901f65388a build: bump indexmap from 1.7.0 to 1.8.0 in /fuzz
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.7.0 to 1.8.0.
- [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.7.0...1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-08 01:48:09 +00:00
dependabot[bot]
68e95d5841 build: bump mshv-bindings from 8770516 to f27b7a4
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `8770516` to `f27b7a4`.
- [Release notes](https://github.com/rust-vmm/mshv/releases)
- [Commits](8770516859...f27b7a423b)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-08 01:20:06 +00:00
dependabot[bot]
c5f20c45a0 build: bump indexmap from 1.7.0 to 1.8.0
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.7.0 to 1.8.0.
- [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.7.0...1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 23:34:14 +00:00
Rob Bradford
c7d1cfbd88 net_util: Error out if the virtio-net descriptor chain is malformed
Do not silently ignore descriptors that are not of the expected form for
the RX and TX queues.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 17:07:47 +00:00
Rob Bradford
9c8f291b60 main: Fix clippy (needless_late_init) issue
warning: unneeded late initalization
   --> src/main.rs:134:5
    |
134 |     let mut app: App;
    |     ^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(clippy::needless_late_init)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `app` here
    |
138 |     let mut app: App = App::new("cloud-hypervisor")
    |     ~~~~~~~~~~~~~~~~

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
70af81d755 vmm: config: Fix clippy (unnecessary_to_owned) issue
warning: unnecessary use of `to_string`
    --> vmm/src/config.rs:2199:38
     |
2199 | ...                   .get(&memory_zone.to_string())
     |                            ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `memory_zone`
     |
     = note: `#[warn(clippy::unnecessary_to_owned)]` on by default
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
8fa3864ae8 vmm: acpi: Fix clippy (needless_late_init) issue
warning: unneeded late initalization
   --> vmm/src/acpi.rs:525:5
    |
525 |     let mut prev_tbl_len: u64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(clippy::needless_late_init)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `prev_tbl_len` here
    |
552 |     let mut prev_tbl_len: u64 = madt.len() as u64;
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~

warning: unneeded late initalization
   --> vmm/src/acpi.rs:526:5
    |
526 |     let mut prev_tbl_off: GuestAddress;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `prev_tbl_off` here
    |
553 |     let mut prev_tbl_off: GuestAddress = madt_offset;
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
221c1f1bdc pci: Fix clippy (return_self_not_must_use) issue
warning: missing `#[must_use]` attribute on a method returning `Self`
   --> pci/src/configuration.rs:925:5
    |
925 | /     pub fn set_register_index(mut self, reg_idx: usize) -> Self {
926 | |         self.reg_idx = reg_idx;
927 | |         self
928 | |     }
    | |_____^
    |
    = note: `#[warn(clippy::return_self_not_must_use)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use

warning: missing `#[must_use]` attribute on a method returning `Self`
   --> pci/src/configuration.rs:930:5
    |
930 | /     pub fn set_address(mut self, addr: u64) -> Self {
931 | |         self.addr = addr;
932 | |         self
933 | |     }
    | |_____^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use

warning: missing `#[must_use]` attribute on a method returning `Self`
   --> pci/src/configuration.rs:935:5
    |
935 | /     pub fn set_size(mut self, size: u64) -> Self {
936 | |         self.size = size;
937 | |         self
938 | |     }
    | |_____^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use

warning: missing `#[must_use]` attribute on a method returning `Self`
   --> pci/src/configuration.rs:944:5
    |
944 | /     pub fn set_region_type(mut self, region_type: PciBarRegionType) -> Self {
945 | |         self.region_type = region_type;
946 | |         self
947 | |     }
    | |_____^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
3baebc1af0 arch: x86_64: Fix clippy (needless_late_init) issue
warning: unneeded late initalization
   --> arch/src/x86_64/mod.rs:318:17
    |
318 |                 let reg_val: u32;
    |                 ^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(clippy::needless_late_init)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `reg_val` here
    |
319 |                 let reg_val: u32 = match reg {
    |                 ++++++++++++++++++
help: remove the assignments from the `match` arms
    |
321 ~                         entry.eax
322 |                     }
323 |                     CpuidReg::EBX => {
324 ~                         entry.ebx
325 |                     }
326 |                     CpuidReg::ECX => {
  ...
help: add a semicolon after the `match` expression
    |
332 |                 };
    |                  +

warning: unneeded late initalization
   --> arch/src/x86_64/mod.rs:525:13
    |
525 |             let entry_compatible;
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `entry_compatible` here
    |
526 |             let entry_compatible = match entry.compatible_check {
    |             ++++++++++++++++++++++
help: remove the assignments from the `match` arms
    |
530 ~                     src_vm_feature_bits_only == 0
531 |                 }
532 |                 CpuidCompatibleCheck::Equal => {
533 ~                     src_vm_feature == dest_vm_feature
534 |                 }
535 |                 CpuidCompatibleCheck::NumNotGreater => {

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
2563b08ff0 virtio-queue: Fix clippy (needless_late_init) issue
warning: unneeded late initalization
   --> virtio-queue/src/chain.rs:381:13
    |
381 |             let desc: Descriptor;
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(clippy::needless_late_init)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
help: declare `desc` here
    |
382 |             let desc: Descriptor = if i < 3 {
    |             ++++++++++++++++++++++
help: remove the assignments from the branches
    |
383 ~                 Descriptor::new(0x1000 * i as u64, 0x1000, VIRTQ_DESC_F_NEXT, i + 1)
384 |             } else {
385 ~                 Descriptor::new(0x1000 * i as u64, 0x1000, 0, 0)
    |
help: add a semicolon after the `if` expression
    |
386 |             };
    |              +

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
Rob Bradford
f6333a39a5 acpi_tables: Fix clippy (unnecessary_to_owned) issues
warning: unnecessary use of `to_vec`
    --> acpi_tables/src/aml.rs:1395:38
     |
1395 |         assert_eq!(create_pkg_length(&[0u8; 62].to_vec(), true), vec![63]);
     |                                      ^^^^^^^^^^^^^^^^^^^ help: use: `[0u8; 62].as_ref()`
     |
     = note: `#[warn(clippy::unnecessary_to_owned)]` on by default
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

warning: unnecessary use of `to_vec`
    --> acpi_tables/src/aml.rs:1397:31
     |
1397 |             create_pkg_length(&[0u8; 64].to_vec(), true),
     |                               ^^^^^^^^^^^^^^^^^^^ help: use: `[0u8; 64].as_ref()`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

warning: unnecessary use of `to_vec`
    --> acpi_tables/src/aml.rs:1401:31
     |
1401 |             create_pkg_length(&[0u8; 4096].to_vec(), true),
     |                               ^^^^^^^^^^^^^^^^^^^^^ help: use: `[0u8; 4096].as_ref()`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-07 08:16:26 -08:00
dependabot[bot]
936237d4d6 build: bump syn from 1.0.84 to 1.0.85
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.84 to 1.0.85.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.84...1.0.85)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 00:40:08 +00:00
dependabot[bot]
6408e8629e build: bump syn from 1.0.84 to 1.0.85 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.84 to 1.0.85.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.84...1.0.85)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-06 23:34:42 +00:00
Muminul Islam
617b568f71 README: Remove --rng option from command to launch a guest
Current command to run cloud-hypervisor binary has
wrong --rng argument in the README file.
This commit fixes all the references of --rng argument
by removing the --rng option to use default.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2022-01-06 09:53:20 -08:00
Rob Bradford
0fcbcea275 vmm: seccomp: Remove set_tid_address syscall from seccomp filter
The origins of the requirement for this syscall in the seccomp filter
list are unknown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:52:39 -08:00
Rob Bradford
10d1922393 vmm: seccomp: Remove arch_prctl syscall from seccomp filter
The origins of the requirement for this syscall in the seccomp filter
list are unknown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:52:24 -08:00
Sebastien Boeuf
0162d73ed8 virtio-queue: Update crate based on latest rust-vmm/vm-virtio
This crate contains up to date definition of the Queue, AvailIter,
DescriptorChain and Descriptor structures forked from the upstream
crate rust-vmm/vm-virtio 27b18af01ee2d9564626e084a758a2b496d2c618.

The following patches have been applied on top of this base in order to
make it work correctly with Cloud Hypervisor requirements:

- Add MSI vector field to the Queue

  In order to help with MSI/MSI-X support, it is convenient to store the
  value of the interrupt vector inside the Queue directly.

- Handle address translations

  For devices with access to data in memory being translated, we add to
  the Queue the ability to translate the address stored in the
  descriptor.
  It is very helpful as it performs the translation right after the
  untranslated address is read from memory, avoiding any errors from
  happening from the consumer's crate perspective. It also allows the
  consumer to reduce greatly the amount of duplicated code for applying
  the translation in many different places.

- Add helpers for Queue structure

  They are meant to help crate's consumers getting/setting information
  about the Queue.

These patches can be found on the 'ch' branch from the Cloud Hypervisor
fork: https://github.com/cloud-hypervisor/vm-virtio.git

This patch takes care of updating the Cloud Hypervisor code in
virtio-devices and vm-virtio to build correctly with the latest version
of virtio-queue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-06 10:02:40 +00:00
Rob Bradford
d57c49664f vmm: Fix potential deadlock in CpuManager
Remove requirement for CpuManager to lock the Vcpu when starting the
vCPU as the numerical id corresponds to the index in the the vector.
This avoids a potential lock inversion between the Vcpu and CpuManager.

WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=30497)
  Cycle in lock order graph: M48 (0x7b0c00001aa0) => M121 (0x7b0c000022b0) => M48

  Mutex M121 acquired here while holding mutex M48 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662ff4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915de)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h14cfa3c8f5ba878a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36ca3b)
    #4 vmm::cpu::CpuManager::start_vcpu::h290fdbb4b7124ec5 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:710:22 (cloud-hypervisor+0x375023)
    #5 vmm::cpu::CpuManager::activate_vcpus::h2eab380826588391 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:902:13 (cloud-hypervisor+0x376b7b)
    #6 vmm::cpu::CpuManager::start_boot_vcpus::hd80cafe6aa4e8279 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:937:9 (cloud-hypervisor+0x3773af)
    #7 vmm::vm::Vm::boot::hc2ca6b16f996267b /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:2063:9 (cloud-hypervisor+0x343d57)
    #8 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:397:13 (cloud-hypervisor+0x2e5f45)
    #9 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #10 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1ddae0)
    #11 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65926a)
    #12 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x440a3e)
    #13 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd0fe)
    #14 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2d71)
    #15 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #16 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1af9)
    #17 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b75e)
    #18 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f343)
    #19 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cef45)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #21 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #22 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d692)

  Mutex M48 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662ff4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915de)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hecf671add5fe1762 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36d1cb)
    #4 vmm::vm::Vm::boot::hc2ca6b16f996267b /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:2063:9 (cloud-hypervisor+0x343cd1)
    #5 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:397:13 (cloud-hypervisor+0x2e5f45)
    #6 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #7 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1ddae0)
    #8 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65926a)
    #9 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x440a3e)
    #10 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd0fe)
    #11 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2d71)
    #12 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #13 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1af9)
    #14 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b75e)
    #15 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f343)
    #16 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cef45)
    #17 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #18 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #19 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d692)

  Mutex M48 acquired here while holding mutex M121 in thread T4:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::h967991d72ceb6eb0 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0xd94df4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::h8779639163126a21 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0xd90cce)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hd85239d207beb12f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0xd6e9ba)
    #4 vm_device::bus::Bus::write::hf20f991e71af3199 /home/rob/src/cloud-hypervisor/vm-device/src/bus.rs:235:16 (cloud-hypervisor+0xd8dd2d)
    #5 _$LT$vmm..vm..VmOps$u20$as$u20$hypervisor..vm..VmmOps$GT$::mmio_write::hc759194aaebc7399 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:424:15 (cloud-hypervisor+0x32db5f)
    #6 _$LT$hypervisor..kvm..KvmVcpu$u20$as$u20$hypervisor..cpu..Vcpu$GT$::run::h94762dfba6642fb2 /home/rob/src/cloud-hypervisor/hypervisor/src/kvm/mod.rs:1003:32 (cloud-hypervisor+0xcc3ed8)
    #7 vmm::cpu::Vcpu::run::hd5cf042157f95bea /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:327:9 (cloud-hypervisor+0x370234)
    #8 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h37e4dd8619b3a5e5 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:813:35 (cloud-hypervisor+0x47785b)
    #9 std::panicking::try::do_call::h093e4d1434150d77 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2aea)
    #10 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #11 std::panicking::try::hee9535cb997282b4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d268f)
    #12 std::panic::catch_unwind::he3908c4d08a8a028 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57baf9)
    #13 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::h29472aaa3a600231 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:782:21 (cloud-hypervisor+0x477156)
    #14 std::sys_common::backtrace::__rust_begin_short_backtrace::hcfc2f02361c98808 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65932b)
    #15 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h08b82db41d7af2f2 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x4408ef)
    #16 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h7ebad9d94e64fa5f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd1df)
    #17 std::panicking::try::do_call::h121fafbdf5cf84af /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2b81)
    #18 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #19 std::panicking::try::h79e25f019cd90522 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1e1f)
    #20 std::panic::catch_unwind::h5a0619a53bbd611d /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b8ff)
    #21 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h1cfd689c9d362e48 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43fafb)
    #22 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h6642b1b3a2289640 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3ced55)
    #23 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #24 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #25 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d692)

  Mutex M121 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662ff4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915de)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h14cfa3c8f5ba878a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36ca3b)
    #4 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h37e4dd8619b3a5e5 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:813:35 (cloud-hypervisor+0x4777c9)
    #5 std::panicking::try::do_call::h093e4d1434150d77 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2aea)
    #6 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #7 std::panicking::try::hee9535cb997282b4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d268f)
    #8 std::panic::catch_unwind::he3908c4d08a8a028 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57baf9)
    #9 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::h29472aaa3a600231 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:782:21 (cloud-hypervisor+0x477156)
    #10 std::sys_common::backtrace::__rust_begin_short_backtrace::hcfc2f02361c98808 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65932b)
    #11 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h08b82db41d7af2f2 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x4408ef)
    #12 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h7ebad9d94e64fa5f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd1df)
    #13 std::panicking::try::do_call::h121fafbdf5cf84af /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2b81)
    #14 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3db8)
    #15 std::panicking::try::h79e25f019cd90522 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1e1f)
    #16 std::panic::catch_unwind::h5a0619a53bbd611d /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b8ff)
    #17 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h1cfd689c9d362e48 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43fafb)
    #18 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h6642b1b3a2289640 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3ced55)
    #19 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d692)
    #21 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d692)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:59:36 +01:00
Rob Bradford
2f46647ecc vmm: Fix potential deadlock in CpuManager
Delay creating the mutex on the Vcpu until later preventing a potential
lock inversion between CpuManager and the Vcpu.

WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=28799)
  Cycle in lock order graph: M48 (0x7b0c00001aa0) => M117 (0x7b0c00002280) => M48

  Mutex M117 acquired here while holding mutex M48 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662fc4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915ae)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h14cfa3c8f5ba878a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36c82b)
    #4 vmm::cpu::CpuManager::create_vcpu::hd5878da6efae8d68 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:665:13 (cloud-hypervisor+0x3743de)
    #5 vmm::cpu::CpuManager::create_vcpus::h3c747553a1d5bc4e /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:704:13 (cloud-hypervisor+0x374d87)
    #6 vmm::cpu::CpuManager::create_boot_vcpus::he8eeca10785067c1 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:938:9 (cloud-hypervisor+0x377305)
    #7 vmm::vm::Vm::boot::hc2ca6b16f996267b /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:1986:9 (cloud-hypervisor+0x3432d3)
    #8 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:397:13 (cloud-hypervisor+0x2e5d35)
    #9 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f42d0)
    #10 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dd8d0)
    #11 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65923a)
    #12 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x440a0e)
    #13 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd0ce)
    #14 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2d41)
    #15 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #16 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1ac9)
    #17 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b72e)
    #18 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f313)
    #19 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cef15)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #21 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #22 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d662)

  Mutex M48 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662fc4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915ae)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hecf671add5fe1762 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36cfbb)
    #4 vmm::vm::Vm::boot::hc2ca6b16f996267b /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:1986:9 (cloud-hypervisor+0x343237)
    #5 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:397:13 (cloud-hypervisor+0x2e5d35)
    #6 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f42d0)
    #7 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dd8d0)
    #8 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x65923a)
    #9 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x440a0e)
    #10 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd0ce)
    #11 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2d41)
    #12 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #13 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1ac9)
    #14 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b72e)
    #15 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f313)
    #16 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cef15)
    #17 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #18 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #19 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d662)

  Mutex M48 acquired here while holding mutex M117 in thread T3:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::h967991d72ceb6eb0 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0xd94dc4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::h8779639163126a21 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0xd90c9e)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hd85239d207beb12f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0xd6e98a)
    #4 vm_device::bus::Bus::write::hf20f991e71af3199 /home/rob/src/cloud-hypervisor/vm-device/src/bus.rs:235:16 (cloud-hypervisor+0xd8dcfd)
    #5 _$LT$vmm..vm..VmOps$u20$as$u20$hypervisor..vm..VmmOps$GT$::mmio_write::hc759194aaebc7399 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:424:15 (cloud-hypervisor+0x32d94f)
    #6 _$LT$hypervisor..kvm..KvmVcpu$u20$as$u20$hypervisor..cpu..Vcpu$GT$::run::h94762dfba6642fb2 /home/rob/src/cloud-hypervisor/hypervisor/src/kvm/mod.rs:1003:32 (cloud-hypervisor+0xcc3ea8)
    #7 vmm::cpu::Vcpu::run::hd5cf042157f95bea /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:327:9 (cloud-hypervisor+0x3700c4)
    #8 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h37e4dd8619b3a5e5 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:819:35 (cloud-hypervisor+0x47782b)
    #9 std::panicking::try::do_call::h093e4d1434150d77 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2aba)
    #10 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #11 std::panicking::try::hee9535cb997282b4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d265f)
    #12 std::panic::catch_unwind::he3908c4d08a8a028 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bac9)
    #13 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::h29472aaa3a600231 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:788:21 (cloud-hypervisor+0x477126)
    #14 std::sys_common::backtrace::__rust_begin_short_backtrace::hcfc2f02361c98808 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x6592fb)
    #15 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h08b82db41d7af2f2 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x4408bf)
    #16 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h7ebad9d94e64fa5f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd1af)
    #17 std::panicking::try::do_call::h121fafbdf5cf84af /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2b51)
    #18 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #19 std::panicking::try::h79e25f019cd90522 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1def)
    #20 std::panic::catch_unwind::h5a0619a53bbd611d /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b8cf)
    #21 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h1cfd689c9d362e48 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43facb)
    #22 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h6642b1b3a2289640 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3ced25)
    #23 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #24 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #25 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d662)

  Mutex M117 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x662fc4)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x4915ae)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h14cfa3c8f5ba878a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36c82b)
    #4 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h37e4dd8619b3a5e5 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:819:35 (cloud-hypervisor+0x477799)
    #5 std::panicking::try::do_call::h093e4d1434150d77 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2aba)
    #6 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #7 std::panicking::try::hee9535cb997282b4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d265f)
    #8 std::panic::catch_unwind::he3908c4d08a8a028 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bac9)
    #9 vmm::cpu::CpuManager::start_vcpu::_$u7b$$u7b$closure$u7d$$u7d$::h29472aaa3a600231 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:788:21 (cloud-hypervisor+0x477126)
    #10 std::sys_common::backtrace::__rust_begin_short_backtrace::hcfc2f02361c98808 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x6592fb)
    #11 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h08b82db41d7af2f2 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x4408bf)
    #12 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h7ebad9d94e64fa5f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dd1af)
    #13 std::panicking::try::do_call::h121fafbdf5cf84af /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d2b51)
    #14 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d3d88)
    #15 std::panicking::try::h79e25f019cd90522 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d1def)
    #16 std::panic::catch_unwind::h5a0619a53bbd611d /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57b8cf)
    #17 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h1cfd689c9d362e48 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43facb)
    #18 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h6642b1b3a2289640 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3ced25)
    #19 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d662)
    #21 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d662)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:59:36 +01:00
Rob Bradford
9ef1187f4a vmm, pci: Fix potential deadlock in PCI BAR allocation
The allocator is locked by both the BAR allocation code and the
interrupt allocation code. Resulting in a potential lock inversion
error.

WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=26318)
  Cycle in lock order graph: M87 (0x7b0c00001e30) => M28 (0x7b0c00001830) => M87

  Mutex M28 acquired here while holding mutex M87 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663954)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bae)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hc61622e5536f5b72 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36d07b)
    #4 _$LT$vmm..interrupt..MsiInterruptManager$LT$kvm_bindings..x86..bindings..kvm_irq_routing_entry$GT$$u20$as$u20$vm_device..interrupt..InterruptManager$GT$::create_group::hd412b5e1e8eeacc2 /home/rob/src/cloud-hypervisor/vmm/src/interrupt.rs:310:29 (cloud-hypervisor+0x6d1403)
    #5 virtio_devices::transport::pci_device::VirtioPciDevice::new::h3af603c3f00f4b3d /home/rob/src/cloud-hypervisor/virtio-devices/src/transport/pci_device.rs:376:38 (cloud-hypervisor+0x8e6137)
    #6 vmm::device_manager::DeviceManager::add_virtio_pci_device::h23608151d7668a1c /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3333:37 (cloud-hypervisor+0x3b6339)
    #7 vmm::device_manager::DeviceManager::add_pci_devices::h136cc20cbeb6b977 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1236:30 (cloud-hypervisor+0x390aad)
    #8 vmm::device_manager::DeviceManager::create_devices::h29fc5b8a20e1aea5 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1155:9 (cloud-hypervisor+0x38f48c)
    #9 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:799:9 (cloud-hypervisor+0x334641)
    #10 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #11 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #12 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #13 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bca)
    #14 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44100e)
    #15 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda5e)
    #16 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d36d1)
    #17 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4718)
    #18 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2459)
    #19 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdce)
    #20 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f913)
    #21 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf3f5)
    #22 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #23 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #24 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d492)

  Mutex M87 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::h9a2d3e97e05c6430 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x9ea344)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::h8abb3b5cf55c0264 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x96face)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hecec128d40c6dd44 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x97120a)
    #4 virtio_devices::transport::pci_device::VirtioPciDevice::new::h3af603c3f00f4b3d /home/rob/src/cloud-hypervisor/virtio-devices/src/transport/pci_device.rs:356:29 (cloud-hypervisor+0x8e5c0e)
    #5 vmm::device_manager::DeviceManager::add_virtio_pci_device::h23608151d7668a1c /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3333:37 (cloud-hypervisor+0x3b6339)
    #6 vmm::device_manager::DeviceManager::add_pci_devices::h136cc20cbeb6b977 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1236:30 (cloud-hypervisor+0x390aad)
    #7 vmm::device_manager::DeviceManager::create_devices::h29fc5b8a20e1aea5 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1155:9 (cloud-hypervisor+0x38f48c)
    #8 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:799:9 (cloud-hypervisor+0x334641)
    #9 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #10 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #11 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #12 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bca)
    #13 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44100e)
    #14 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda5e)
    #15 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d36d1)
    #16 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4718)
    #17 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2459)
    #18 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdce)
    #19 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f913)
    #20 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf3f5)
    #21 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #22 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #23 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d492)

  Mutex M87 acquired here while holding mutex M28 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::h9a2d3e97e05c6430 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x9ea344)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::h8abb3b5cf55c0264 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x96face)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hecec128d40c6dd44 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x97120a)
    #4 _$LT$virtio_devices..transport..pci_device..VirtioPciDevice$u20$as$u20$pci..device..PciDevice$GT$::allocate_bars::h39dc42b48fc8264c /home/rob/src/cloud-hypervisor/virtio-devices/src/transport/pci_device.rs:850:22 (cloud-hypervisor+0x8eb1a4)
    #5 vmm::device_manager::DeviceManager::add_pci_device::h561f6c8ed61db117 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3087:20 (cloud-hypervisor+0x3b0c62)
    #6 vmm::device_manager::DeviceManager::add_virtio_pci_device::h23608151d7668a1c /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3359:20 (cloud-hypervisor+0x3b6707)
    #7 vmm::device_manager::DeviceManager::add_pci_devices::h136cc20cbeb6b977 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1236:30 (cloud-hypervisor+0x390aad)
    #8 vmm::device_manager::DeviceManager::create_devices::h29fc5b8a20e1aea5 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1155:9 (cloud-hypervisor+0x38f48c)
    #9 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:799:9 (cloud-hypervisor+0x334641)
    #10 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #11 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #12 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #13 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bca)
    #14 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44100e)
    #15 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda5e)
    #16 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d36d1)
    #17 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4718)
    #18 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2459)
    #19 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdce)
    #20 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f913)
    #21 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf3f5)
    #22 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #23 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #24 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d492)

  Mutex M28 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663954)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bae)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::hc61622e5536f5b72 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36d07b)
    #4 vmm::device_manager::DeviceManager::add_pci_device::h561f6c8ed61db117 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3091:22 (cloud-hypervisor+0x3b0a95)
    #5 vmm::device_manager::DeviceManager::add_virtio_pci_device::h23608151d7668a1c /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:3359:20 (cloud-hypervisor+0x3b6707)
    #6 vmm::device_manager::DeviceManager::add_pci_devices::h136cc20cbeb6b977 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1236:30 (cloud-hypervisor+0x390aad)
    #7 vmm::device_manager::DeviceManager::create_devices::h29fc5b8a20e1aea5 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1155:9 (cloud-hypervisor+0x38f48c)
    #8 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:799:9 (cloud-hypervisor+0x334641)
    #9 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #10 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #11 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #12 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bca)
    #13 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44100e)
    #14 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda5e)
    #15 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d36d1)
    #16 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4718)
    #17 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2459)
    #18 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdce)
    #19 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f913)
    #20 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf3f5)
    #21 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #22 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d492)
    #23 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d492)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:59:36 +01:00
Rob Bradford
e7db354c27 vmm: Fix potential deadlock in CpuManager
The lock on the config should not be held whilst calling into
CpuManager::new().

WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=24176)
  Cycle in lock order graph: M13 (0x7b0c000001e0) => M43 (0x7b0c00001a70) => M13

  Mutex M43 acquired here while holding mutex M13 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663984)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bde)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h8a843a6e74b34c4a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36cd8b)
    #4 vmm::cpu::CpuManager::new::h1cc88224a2a50d87 /home/rob/src/cloud-hypervisor/vmm/src/cpu.rs:575:30 (cloud-hypervisor+0x372e16)
    #5 vmm::vm::Vm::new_from_memory_manager::ha2a4467be260e93c /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:592:27 (cloud-hypervisor+0x330b86)
    #6 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:784:22 (cloud-hypervisor+0x3343df)
    #7 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #8 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #9 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #10 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bfa)
    #11 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44103e)
    #12 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda8e)
    #13 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d3701)
    #14 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4748)
    #15 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2489)
    #16 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdfe)
    #17 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f943)
    #18 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf425)
    #19 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #21 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d4c2)

  Mutex M13 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663984)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bde)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::ha29f58bbf496356a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36d03b)
    #4 vmm::vm::Vm::new_from_memory_manager::ha2a4467be260e93c /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:593:14 (cloud-hypervisor+0x3307ee)
    #5 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:784:22 (cloud-hypervisor+0x3343df)
    #6 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #7 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #8 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #9 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bfa)
    #10 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44103e)
    #11 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda8e)
    #12 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d3701)
    #13 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4748)
    #14 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2489)
    #15 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdfe)
    #16 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f943)
    #17 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf425)
    #18 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #19 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #20 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d4c2)

  Mutex M13 acquired here while holding mutex M43 in thread T1:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663984)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bde)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::ha29f58bbf496356a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36d03b)
    #4 vmm::device_manager::DeviceManager::add_console_device::h1d2b419feef80564 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1839:29 (cloud-hypervisor+0x3972f4)
    #5 vmm::device_manager::DeviceManager::create_devices::h29fc5b8a20e1aea5 /home/rob/src/cloud-hypervisor/vmm/src/device_manager.rs:1143:24 (cloud-hypervisor+0x38f068)
    #6 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:798:9 (cloud-hypervisor+0x334671)
    #7 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #8 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #9 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #10 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bfa)
    #11 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44103e)
    #12 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda8e)
    #13 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d3701)
    #14 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4748)
    #15 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2489)
    #16 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdfe)
    #17 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f943)
    #18 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf425)
    #19 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #20 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #21 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d4c2)

  Mutex M43 previously acquired by the same thread here:
    #0 pthread_mutex_lock /rustc/llvm/src/llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:4249:3 (cloud-hypervisor+0x9c368)
    #1 std::sys::unix::mutex::Mutex::lock::hcd1b9aa06ff775d3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/mutex.rs:63:17 (cloud-hypervisor+0x663984)
    #2 std::sys_common::mutex::MovableMutex::raw_lock::hff98d0b036469bca /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/mutex.rs:76:18 (cloud-hypervisor+0x491bde)
    #3 std::sync::mutex::Mutex$LT$T$GT$::lock::h8a843a6e74b34c4a /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sync/mutex.rs:267:13 (cloud-hypervisor+0x36cd8b)
    #4 vmm::vm::Vm::new::h43efe7c6cd97ede5 /home/rob/src/cloud-hypervisor/vmm/src/vm.rs:798:9 (cloud-hypervisor+0x334537)
    #5 vmm::Vmm::vm_boot::h06bdf54b95d5e14f /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:379:26 (cloud-hypervisor+0x2e5ba8)
    #6 vmm::Vmm::control_loop::h40c9b48c7b800bed /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:1299:48 (cloud-hypervisor+0x2f44e0)
    #7 vmm::start_vmm_thread::_$u7b$$u7b$closure$u7d$$u7d$::h016d2f7cff698175 /home/rob/src/cloud-hypervisor/vmm/src/lib.rs:263:17 (cloud-hypervisor+0x1dda20)
    #8 std::sys_common::backtrace::__rust_begin_short_backtrace::h7fd2df3e7cfba503 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys_common/backtrace.rs:123:18 (cloud-hypervisor+0x659bfa)
    #9 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h89880b05fe892d7e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:477:17 (cloud-hypervisor+0x44103e)
    #10 _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h487382524d80571f /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/panic/unwind_safe.rs:271:9 (cloud-hypervisor+0x6dda8e)
    #11 std::panicking::try::do_call::h1d9c2ccdc39f3322 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:406:40 (cloud-hypervisor+0x6d3701)
    #12 __rust_try 3hkmq3dzyyv5ejsx (cloud-hypervisor+0x6d4748)
    #13 std::panicking::try::h251306df23d21913 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panicking.rs:370:19 (cloud-hypervisor+0x6d2489)
    #14 std::panic::catch_unwind::h2a9ac2fb12c3c64e /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/panic.rs:133:14 (cloud-hypervisor+0x57bdfe)
    #15 std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::h10f4c340611b55e4 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/thread/mod.rs:476:30 (cloud-hypervisor+0x43f943)
    #16 core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::hdd9b37241caf97b3 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/core/src/ops/function.rs:227:5 (cloud-hypervisor+0x3cf425)
    #17 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::ha5022a6bb7833f62 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #18 _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h481697829cbc6746 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/alloc/src/boxed.rs:1854:9 (cloud-hypervisor+0x119d4c2)
    #19 std::sys::unix::thread::Thread::new::thread_start::h6fad62c4c393bbe7 /rustc/7d6f948173ccb18822bab13d548c65632db5f0aa/library/std/src/sys/unix/thread.rs:108:17 (cloud-hypervisor+0x119d4c2)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-06 09:59:36 +01:00
dependabot[bot]
6ba5b0a83a build: bump crc32c from 0.6.0 to 0.6.1
Bumps [crc32c](https://github.com/zowens/crc32c) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/zowens/crc32c/releases)
- [Commits](https://github.com/zowens/crc32c/commits/v0.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-06 01:53:15 +00:00
dependabot[bot]
2c59702e4a build: bump clap from 3.0.4 to 3.0.5
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.0.4...v3.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-06 00:52:46 +00:00
dependabot[bot]
98ba347956 build: bump clap from 3.0.4 to 3.0.5 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v3.0.4...v3.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 23:54:35 +00:00
dependabot[bot]
cd0aca4bcd build: bump crc32c from 0.6.0 to 0.6.1 in /fuzz
Bumps [crc32c](https://github.com/zowens/crc32c) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/zowens/crc32c/releases)
- [Commits](https://github.com/zowens/crc32c/commits/v0.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 23:45:32 +00:00
Wei Liu
f27cbb9caf gitignore: ignore .cargo directory
This allows developers to have their local Cargo configurations for
Cloud Hypervisor.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-01-05 16:08:42 +00:00
Rob Bradford
e4763b47f1 vmm, build: Remove use of "credibility" from unit tests
This crate was used in the integration tests to allow the tests to
continue and clean up after a failure. This isn't necessary in the unit
tests and adds a large build dependency chain including an unmaintained
crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-05 12:35:50 +01:00
Muhammad Falak R Wani
7cc1643782 scripts: create-cloud-init: use rm -f instead of rm
Ignore non-existing file instead of bailing out.

Signed-off-by: Muhammad Falak R Wani <falakreyaz@gmail.com>
2022-01-05 11:02:20 +01:00
dependabot[bot]
58501ed0a6 build: bump clap from 3.0.1 to 3.0.4 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.1 to 3.0.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.0.1...v3.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 02:51:00 +00:00
dependabot[bot]
b72136ddb3 build: bump clap from 3.0.1 to 3.0.4
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.1 to 3.0.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.0.1...v3.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 23:35:21 +00:00
Rob Bradford
07756aa8fb tests, README: Bump kernel fork to 5.15.12
This updated tree now includes a fix for virtio-net regression that was
present in 5.14:

commit 732b74d647048668f0f8dc0c848f0746c69e2e2f
Author: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Date:   Sat Oct 9 05:17:53 2021 -0400

    virtio-net: fix for skb_over_panic inside big mode

    commit 126285651b7f ("Merge ra.kernel.org:/pub/scm/linux/kernel/git/netdev/net")
    accidentally reverted the effect of
    commit 1a8024239da ("virtio-net: fix for skb_over_panic inside big mode")
    on drivers/net/virtio_net.c

    As a result, users of crosvm (which is using large packet mode)
    are experiencing crashes with 5.14-rc1 and above that do not
    occur with 5.13.

    Crash trace:

    [   61.346677] skbuff: skb_over_panic: text:ffffffff881ae2c7 len:3762 put:3762 head:ffff8a5ec8c22000 data:ffff8a5ec8c22010 tail:0xec2 end:0xec0 dev:<NULL>
    [   61.369192] kernel BUG at net/core/skbuff.c:111!
    [   61.372840] invalid opcode: 0000 [#1] SMP PTI
    [   61.374892] CPU: 5 PID: 0 Comm: swapper/5 Not tainted 5.14.0-rc1 linux-v5.14-rc1-for-mesa-ci.tar.bz2 #1
    [   61.376450] Hardware name: ChromiumOS crosvm, BIOS 0

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-04 18:07:35 +01:00
Sebastien Boeuf
c47ab55e99 virtio-devices: Forward correct evset in vsock muxer
When forwarding an epoll event from the unix muxer to the
targeted connection event handler, the eventset the connection
registered is forwarded instead of the actual epoll
operation (IN/OUT).

For example, if the connection was registered for EPOLLIN,
and receives an EPOLLOUT, the connection will actually handle
an EPOLLOUT.

This is the root cause of previous bug, which caused the
introduction of some workarounds (i.e: handling ewouldblock
when reading after receiving EPOLLIN, which should never happen).

When matching the connection, we retrieve and use the evset of
the connection instead of the one passed as a parameter.
The compiler does not complain for an unused variable because
it was first logged in a debug! statement.

This is an unfortunate naming mistake that caused a lot of problems.

Fixes #3497

Signed-off-by: Eduard Kyvenko <eduard.kyvenko@gmail.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-04 12:05:01 +00:00
Rob Bradford
a749063c8a vmm: Don't assume that resize_pipe is initialised
If the underlying kernel is old PTY resize is disabled and this is
represented by the use of None in the provided Option<File> type. In the
virtio-console PTY path don't blindly unwrap() the value that will be
preserved across a reboot.

Fixes: #3496

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-01-04 12:04:50 +00:00
dependabot[bot]
cf2abd35d0 build: bump serde_derive from 1.0.132 to 1.0.133
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 03:58:23 +00:00
dependabot[bot]
0dbff2a81d build: bump serde from 1.0.132 to 1.0.133
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 03:26:00 +00:00
dependabot[bot]
e355bb9fd4 build: bump serde_json from 1.0.73 to 1.0.74
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.73 to 1.0.74.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.73...v1.0.74)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 02:42:16 +00:00
dependabot[bot]
aeaf432784 build: bump serde_derive from 1.0.132 to 1.0.133 in /fuzz
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 01:31:24 +00:00
dependabot[bot]
ccc9308ec1 build: bump clap from 3.0.0 to 3.0.1
Bumps [clap](https://github.com/clap-rs/clap) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.0.0...clap_complete-v3.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 01:31:14 +00:00
dependabot[bot]
129f708df7 build: bump serde_json from 1.0.73 to 1.0.74 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.73 to 1.0.74.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.73...v1.0.74)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 00:47:17 +00:00
dependabot[bot]
542f05ebfa build: bump serde from 1.0.132 to 1.0.133 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 00:23:07 +00:00
dependabot[bot]
8e89a10db7 build: bump strsim from 0.8.0 to 0.10.0 in /fuzz
Bumps [strsim](https://github.com/dguo/strsim-rs) from 0.8.0 to 0.10.0.
- [Release notes](https://github.com/dguo/strsim-rs/releases)
- [Changelog](https://github.com/dguo/strsim-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dguo/strsim-rs/compare/0.8.0...0.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 23:35:39 +00:00
dependabot[bot]
5283cb38db build: bump quote from 1.0.10 to 1.0.14
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.10 to 1.0.14.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.10...1.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 12:43:46 +00:00
dependabot[bot]
346bee48ad build: bump clap from 2.34.0 to 3.0.0
Bumps [clap](https://github.com/clap-rs/clap) from 2.34.0 to 3.0.0.
- [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/v2.34.0...clap_complete-v3.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-03 12:28:17 +00:00
Sebastien Boeuf
210a29f05c tests: Disable test_vfio_user
The test test_vfio_user is flaky, let's disable it until we find the
right way to fix it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-03 12:59:23 +01:00
Sebastien Boeuf
21a21ce51a tests: Disable test_virtio_block_topology for aarch64
The test test_virtio_block_topology is flaky on aarch64, let's disable
it until we find the right way to fix it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-03 12:59:23 +01:00
Henry Wang
877a537bf7 docs/arm64: Document the hardware constraints
There is a corner case of using the Cloud Hypervisor on AArch64:
If the VM is started on a device where RAM is limited, and if the user
allocates nearly as much memory for the guest as is still free on the
host, we need to enable the swap memory.

This commit documented this corner case with explanation.

Also, this commit corrects the hardware requirement of the GIC interrupt
controller for running the Cloud Hypervisor on AArch64, accroding to
[1].

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

Signed-off-by: Henry Wang <Henry.Wang@arm.com>

[1] https://www.kernel.org/doc/html/latest/virt/kvm/devices/arm-vgic-its.html
2021-12-28 21:00:43 +08:00
dependabot[bot]
5a1e9c9bff build: bump proc-macro2 from 1.0.34 to 1.0.36
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.34 to 1.0.36.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.34...1.0.36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 07:37:35 +00:00
dependabot[bot]
a45939fb40 build: bump quote from 1.0.10 to 1.0.14 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.10 to 1.0.14.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.10...1.0.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 06:07:54 +00:00
dependabot[bot]
b85d29780f build: bump syn from 1.0.83 to 1.0.84
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.83 to 1.0.84.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.83...1.0.84)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 04:59:48 +00:00
dependabot[bot]
b3351e11b3 build: bump proc-macro2 from 1.0.34 to 1.0.36 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.34 to 1.0.36.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.34...1.0.36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 04:30:48 +00:00
dependabot[bot]
05720dbf25 build: bump syn from 1.0.83 to 1.0.84 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.83 to 1.0.84.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.83...1.0.84)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 03:40:51 +00:00
dependabot[bot]
d7ba8ad1fa build: bump syn from 1.0.82 to 1.0.83 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.82 to 1.0.83.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.82...1.0.83)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-24 00:49:52 +00:00
dependabot[bot]
748611752d build: bump anyhow from 1.0.51 to 1.0.52
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-24 00:22:38 +00:00
dependabot[bot]
9c5636204d build: bump syn from 1.0.82 to 1.0.83
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.82 to 1.0.83.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.82...1.0.83)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 23:58:22 +00:00
dependabot[bot]
fbbbd04ddf build: bump anyhow from 1.0.51 to 1.0.52 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 23:39:08 +00:00
Sebastien Boeuf
89af7dcb2b deps: Bump vm-memory to 0.7.0
Updating Cloud Hypervisor to rely on vm-memory version 0.7.0.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-21 13:51:31 +01:00
dependabot[bot]
8737ca4d45 build: bump vfio-bindings from 0.2.0 to 0.3.1 in /fuzz
Bumps [vfio-bindings](https://github.com/rust-vmm/vfio) from 0.2.0 to 0.3.1.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](https://github.com/rust-vmm/vfio/commits/vfio-bindings-v0.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 12:33:52 +01:00
dependabot[bot]
d186297dba build: bump vhost from 0.2.0 to 0.3.0 in /fuzz
Bumps [vhost](https://github.com/rust-vmm/vhost) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/rust-vmm/vhost/releases)
- [Changelog](https://github.com/rust-vmm/vhost/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vhost/compare/v0.2.0...v0.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 12:29:34 +01:00
dependabot[bot]
09d6cdb185 build: bump vhost from 0.2.0 to 0.3.0
Bumps [vhost](https://github.com/rust-vmm/vhost) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/rust-vmm/vhost/releases)
- [Changelog](https://github.com/rust-vmm/vhost/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vhost/compare/v0.2.0...v0.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 07:57:33 +00:00
dependabot[bot]
c40c1778e5 build: bump vfio-bindings from 0.2.0 to 0.3.1
Bumps [vfio-bindings](https://github.com/rust-vmm/vfio) from 0.2.0 to 0.3.1.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](https://github.com/rust-vmm/vfio/commits/vfio-bindings-v0.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 07:37:44 +00:00
dependabot[bot]
58a2abbba2 build: bump signal-hook from 0.3.12 to 0.3.13 in /fuzz
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.12...v0.3.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 00:31:07 +00:00
dependabot[bot]
b6159217b6 build: bump signal-hook from 0.3.12 to 0.3.13
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.12...v0.3.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 00:00:11 +00:00
Rob Bradford
7bb828ecf2 build: Remove io_uring feature flag
This has been part of the default features for a long time and is widely
tested.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 13:34:17 +01:00
Sebastien Boeuf
4a47cdcebd vmm: tdx: Make sure a TDX enabled binary can be used for non-TDX
It's important to maintain the ability to run in a non-TDX environment
a Cloud Hypervisor binary with the 'tdx' feature enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-17 12:52:40 +01:00
Rob Bradford
8813456aef block_util: Move block device detection into it's own function
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
6c8bd1f476 block_util: Remove duplicated logic for block size ioctls
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
6a76a6772d tests: Add integration test for virtio-block topology
This test relies on using losetup with a block size to create a block
device from a file that has a specific block size for the topology
detection code to pick up and passthrough to the guest.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
cbc388c7e2 vmm: Add ioctls to seccomp filter for block topology detection
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
4773e23c77 virtio-devices: block: Expose device topology
If the disk is backed by a block device on the host a non-default
topology will be available and that topology can be advertised by virtio
block.

Fixes: #3262

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
3b0d278ba3 block_util: Implement DiskFile::topology() for raw file types
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
443b64b04f block_util: Implement DiskTopology::probe()
This method detects the underlying block topology if the disk is backed
by a block device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
Rob Bradford
ccccc94c8a block_util: Add ability to get block topology from a DiskFile
For simplicity this trait implements a default version that has a
topology with 512 byte (i.e. sector) recommended sizes.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-17 12:42:10 +01:00
dependabot[bot]
3f0a33a50f build: bump serde_derive from 1.0.131 to 1.0.132
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 02:15:44 +00:00
dependabot[bot]
32aedddb0a build: bump serde from 1.0.131 to 1.0.132
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 01:44:29 +00:00
dependabot[bot]
fa15cf6ac3 build: bump serde_derive from 1.0.131 to 1.0.132 in /fuzz
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 00:58:47 +00:00
dependabot[bot]
5c12c15f26 build: bump serde from 1.0.131 to 1.0.132 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 00:11:21 +00:00
Rob Bradford
bde81405a8 vmm: seccomp: Remove fork & evecve syscalls
These were use for the self spawning vhost-user device feature that has
been removed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-16 20:56:50 +01:00
dependabot[bot]
9742fa5c7c build: bump proc-macro2 from 1.0.33 to 1.0.34 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.33...1.0.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-15 00:43:13 +00:00
dependabot[bot]
3806afdc43 build: bump once_cell from 1.8.0 to 1.9.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.8.0 to 1.9.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.8.0...v1.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-15 00:02:08 +00:00
dependabot[bot]
c6ba188586 build: bump proc-macro2 from 1.0.33 to 1.0.34
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.33...1.0.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 23:48:09 +00:00
Rob Bradford
afe386bc13 vmm: Only warn on error when setting up SIGWINCH handler
Setting up the SIGWINCH handler requires at least Linux 5.7. However
this functionality is not required for basic PTY operation.

Fixes: #3456

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-14 13:05:09 +01:00
Bo Chen
df21e15148 Dockerfile: Update version of SPDK in container
This patch also removes the workaround of building SPDK with meson
0.59.2 as the bug has been fixed [1].

[1] https://review.spdk.io/gerrit/c/spdk/dpdk/+/10044

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-12-14 08:26:28 +01:00
dependabot[bot]
2883c71911 build: bump ryu from 1.0.6 to 1.0.9 in /fuzz
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.6 to 1.0.9.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.6...1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 03:27:41 +00:00
dependabot[bot]
07a78842b5 build: bump libc from 0.2.109 to 0.2.112
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.109 to 0.2.112.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.109...0.2.112)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 02:30:54 +00:00
dependabot[bot]
91c7590ba6 build: bump ryu from 1.0.6 to 1.0.9
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.6 to 1.0.9.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.6...1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 02:16:52 +00:00
dependabot[bot]
e1b0630b79 build: bump openssl-sys from 0.9.71 to 0.9.72
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.71 to 0.9.72.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.71...openssl-sys-v0.9.72)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 01:26:08 +00:00
dependabot[bot]
2a2cea1658 build: bump serde_json from 1.0.72 to 1.0.73
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.72...v1.0.73)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 01:12:53 +00:00
dependabot[bot]
3cd02403db build: bump libc from 0.2.109 to 0.2.112 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.109 to 0.2.112.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.109...0.2.112)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-14 00:01:31 +00:00
dependabot[bot]
a9f5021005 build: bump pkg-config from 0.3.23 to 0.3.24
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.23 to 0.3.24.
- [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/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 23:45:25 +00:00
dependabot[bot]
f14d0d0191 build: bump serde_json from 1.0.72 to 1.0.73 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.72...v1.0.73)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 23:41:16 +00:00
Rob Bradford
4959434219 Revert "virtio-devices: net: Improve throughput with virtio features"
This reverts commit 58d25b3ccc.

This change introduced a regression when running iperf with the guest
running as the server:

marvin:~/src/cloud-hypervisor ((58d25b3c...))$ iperf  -c 192.168.249.2
------------------------------------------------------------
Client connecting to 192.168.249.2, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[  1] local 192.168.249.1 port 47078 connected with 192.168.249.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-10.40 sec  14.0 MBytes  11.3 Mbits/sec
marvin:~/src/cloud-hypervisor ((58d25b3c...))$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[  1] local 192.168.249.1 port 5001 connected with 192.168.249.2 port 42866
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-10.01 sec  51.2 GBytes  44.0 Gbits/sec

Fixes: #3450

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-13 08:33:27 +00:00
Rob Bradford
7444c3a0c5 pci: vfio_user: Batch IRQ enabling into batches of 16
The sendmsg() syscall is limited in the number of fds it can handle.
This number matches that used by the vfio-user library and is
conservative (since we've seen it work with 64 fds.)

Fixes: #3401

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-12 18:14:51 +00:00
Rob Bradford
35d3c1f611 build: Switch base to hirsute as an experiment
As an experiment switch back to hirsute to see if the CI failure /
timeout rate decreases.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-12 11:09:32 +00:00
dependabot[bot]
be5fd7c572 build: bump hermit-abi from 0.1.19 to 0.1.20
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.19 to 0.1.20.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.19...hermit-abi-0.1.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 17:15:28 +01:00
dependabot[bot]
39172f8b54 build: bump serde_derive from 1.0.130 to 1.0.131
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 15:25:54 +00:00
dependabot[bot]
2bcf718028 build: bump serde_derive from 1.0.130 to 1.0.131 in /fuzz
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 14:27:29 +00:00
dependabot[bot]
6d047bdec6 build: bump serde from 1.0.130 to 1.0.131 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 11:33:23 +01:00
dependabot[bot]
c6e534baf7 build: bump hermit-abi from 0.1.19 to 0.1.20 in /fuzz
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.19 to 0.1.20.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.19...hermit-abi-0.1.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 09:45:25 +01:00
dependabot[bot]
fb2b633ada build: bump serde from 1.0.130 to 1.0.131
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 09:44:23 +01:00
Bo Chen
8fb64859cc vmm: openapi: Add receive/send-migration endpoints
Fixes: #3426

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-12-09 08:49:19 -08:00
dependabot[bot]
254d648bb7 build: bump signal-hook from 0.3.11 to 0.3.12
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.11 to 0.3.12.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.11...v0.3.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-09 08:46:01 +00:00
dependabot[bot]
21b0ab106c build: bump signal-hook from 0.3.11 to 0.3.12 in /fuzz
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.11 to 0.3.12.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.11...v0.3.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-09 08:45:50 +00:00
Sebastien Boeuf
7bce72dff3 tests: Re-enable vfio_user integration test
This time we use the Rust Hypervisor Firmware for test_vfio_user() in
order to fix the systemd issues we've seen so far.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-08 14:38:30 +00:00
Rob Bradford
50f5f43ae3 vmm: acpi: Make MBRD _CRS multi-segment aware
Advertise the PCI MMIO config spaces here so that the MMIO config space
is correctly recognised.

Tested by: --platform num_pci_segments=1 or 16 hotplug NVMe vfio-user device
works correctly with hypervisor-fw & OVMF and direct kernel boot.

Fixes: #3432

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-08 14:38:30 +00:00
dependabot[bot]
fd3cf761be build: bump signal-hook from 0.3.10 to 0.3.11
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.10 to 0.3.11.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.10...v0.3.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-08 13:43:52 +01:00
dependabot[bot]
0a04c7206d build: bump signal-hook from 0.3.10 to 0.3.11 in /fuzz
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.10 to 0.3.11.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.10...v0.3.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-08 09:40:57 +00:00
Rob Bradford
58d3d4c34e build: Include static ch-remote binary in release
Fixes: #3425

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-07 11:17:29 +01:00
Rob Bradford
eea2907daf build: Use OVMF binary released from edk2 repo
Fixes: #3415

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-07 10:34:05 +01:00
dependabot[bot]
7b5e8a3ca8 build: bump libc from 0.2.108 to 0.2.109 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.108 to 0.2.109.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.108...0.2.109)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 09:29:45 +00:00
dependabot[bot]
616d01aca2 build: bump libc from 0.2.108 to 0.2.109
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.108 to 0.2.109.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.108...0.2.109)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 09:29:45 +00:00
dependabot[bot]
637dc53a48 build: bump proc-macro2 from 1.0.32 to 1.0.33
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.32...1.0.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 01:12:09 +00:00
dependabot[bot]
4b9b52fc6f build: bump proc-macro2 from 1.0.32 to 1.0.33 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.32...1.0.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 00:34:50 +00:00
dependabot[bot]
3d1cfd4d55 build: bump pkg-config from 0.3.22 to 0.3.23
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.22 to 0.3.23.
- [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.22...0.3.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 00:27:29 +00:00
Rob Bradford
e1c09b66ba vmm: Replace device tree value when restoring DeviceManager
When restoring replace the internal value of the device tree rather than
replacing the Arc<Mutex<DeviceTree>> itself. This is fixes an issue
where the AddressManager has a copy of the the original
Arc<Mutex<DeviceTree>> from when the DeviceManager was created. The
original restore path only replaced the DeviceManager's version of the
Arc<Mutex<DeviceTree>>. Instead replace the contents of the
Arc<Mutex<DeviceTree>> so all users see the updated version.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-06 15:58:37 +00:00
Wei Liu
af770c814b block_util: provide and use AsyncAdaptor trait
The observation is that the code in question was used to bridge
synchronized and asynchronized code.

We can group the functions for that purpose under an adaptor trait. To
limit the scope of locking, the users of the trait are required to
implement a method to return a MutexGuard for the underlying file.

This then allows us to use concrete types (QcowFile and Vhdx) in code,
which is easier to read than a bunch of traits.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-12-06 15:20:29 +01:00
Rob Bradford
a29e53e436 vmm: Move KVM clock saving to common Vm::restore() method
Saving the KVM clock and restoring it is key for correct behaviour of
the VM when doing snapshot/restore or live migration. The clock is
restored to the KVM state as part of the Vm::resume() method prior to
that it must be extracted from the state object and stored for later use
by this method. This change simplifies the extraction and storage part
so that it is done in the same way for both snapshot/restore and live
migration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-06 11:23:16 +00:00
Henry Wang
00bb1ea1d5 tests: Enhance test for multiple PCI segments
This commit enhances the integration test for multiple PCI segments
by:

(1) Enables the `test_virtio_fs_multi_segment` on AArch64.

(2) Adds a new integration test case for both x86_64 and AArch64 using
the direct kernel boot to test virtio-disk multiple PCI segments.
The test case does:
- Start a VM using direct kernel boot with 16 PCI segments and assign
the last PCI segment with a virtio-disk device.
- Check if the number of PCI host bridges equals to 16 after VM boots.
- Mount the virtio-disk device on the last PCI segment to the rootfs
and write/read data to the virtio-disk device.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Henry Wang
bb6c93d5df docs: device_model: Document how to assign device to PCI segment
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Henry Wang
90df54a245 aarch64: fdt: Create MSI mapping for PCI nodes
Each PCI device under a root complex is uniquely identified by its
Requester ID (AKA RID). A Requester ID is a triplet of a Bus number,
Device number, and Function number.

MSIs may be distinguished in part through the use of sideband data
accompanying writes. In the case of PCI devices, this sideband data
may be derived from the Requester ID. A mechanism is required to
associate a device with both the MSI controllers it can address,
and the sideband data that will be associated with its writes to
those controllers.

This commit adds the `msi-map` property for PCI nodes, therefore
creating MSI mapping for each PCI device.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Henry Wang
ca9a42ece8 aarch64: fdt: Create multiple PCI nodes based on PciSpaceInfo
This commit rewrites the `create_pci_node` in the FDT creator to
create multiple PCI nodes based on the vector of `PciSpaceInfo`,
and each PCI node in FDT reflects a PCI segment.

- The PCI MMIO config space, 32 bits PCI device space and 64 bits
PCI device space is re-calculated based on the `PciSpaceInfo` for
each PCI segment.
- A new FDT property `linux,pci-domain` is added.
- The virtio-iommu node is only created for the first PCI segment.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Henry Wang
2f8540da70 vmm: Rename PCI_MMIO_CONFIG_SIZE and move it to arch
The constant `PCI_MMIO_CONFIG_SIZE` defined in `vmm/pci_segment.rs`
describes the MMIO configuation size for each PCI segment. However,
this name conflicts with the `PCI_MMCONFIG_SIZE` defined in `layout.rs`
in the `arch` crate, which describes the memory size of the PCI MMIO
configuration region.

Therefore, this commit renames the `PCI_MMIO_CONFIG_SIZE` to
`PCI_MMIO_CONFIG_SIZE_PER_SEGMENT` and moves this constant from `vmm`
crate to `arch` crate.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Henry Wang
07bef815cc aarch64: Introduce struct PciSpaceInfo for FDT
Currently, a tuple containing PCI space start address and PCI space
size is used to pass the PCI space information to the FDT creator.
In order to support the multiple PCI segment for FDT, more information
such as the PCI segment ID should be passed to the FDT creator. If we
still use a tuple to store these information, the code flexibility and
readablity will be harmed.

To address this issue, this commit replaces the tuple containing the
PCI space information to a structure `PciSpaceInfo` and uses a vector
of `PciSpaceInfo` to store PCI space information for each segment, so
that multiple PCI segment information can be passed to the FDT together.

Note that the scope of this commit will only contain the refactor of
original code, the actual multiple PCI segments support will be in
following series, and for now `--platform num_pci_segments` should only
be 1.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-06 09:29:49 +00:00
Wei Liu
e1151482fc block_util: handle synchronized read/write/fsync idiomatically
Previously mutex (semaphore) and file were separated. The code needed to
create artificial scopes to use mutex to protect file.

Rewrite the code to be idiomatic. The file itself is turned into a trait
object and placed inside the mutex. This requires providing a new
ReadWriteSeekFile trait to unify all helper functions.

The rewrite further simplified vhdx_sync code. The original code
contained two mutex'es for no apparent reason.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-12-06 09:23:51 +00:00
Wei Liu
3e536f91eb block_util: drop disk_size
It is only used by qcow_sync code. Merge it to its caller.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-12-06 09:23:51 +00:00
Sebastien Boeuf
cab0b3446f tests: Test OVMF with Linux guest
Extending the test_simple_launch() integration test to validate Cloud
Hypervisor boots correctly with both rust-hypervisor-fw and OVMF on
x86_64 platforms.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 23:04:32 +01:00
Sebastien Boeuf
7bb343dce8 vmm: Improve logging related to memory management
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 23:04:32 +01:00
Sebastien Boeuf
9b0fe505ca ci: Update the OVMF version the tests rely on
Bumping the OVMF binary version along with UEFI documentation to
reflect the latest set of patches on top of tianocore/edk2 'master'
branch, which can be found on the Cloud Hypervisor fork on 'ch' branch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 23:04:32 +01:00
Sebastien Boeuf
03a606c7ec arch, vmm: Place KVM identity map region after TSS region
In order to avoid the identity map region to conflict with a possible
firmware being placed in the last 4MiB of the 4GiB range, we must set
the address to a chosen location. And it makes the most sense to have
this region placed right after the TSS region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 19:33:34 +00:00
Sebastien Boeuf
c452471c4e hypervisor: Add support for setting KVM identity map
Extending the Vm trait with set_identity_map_address() in order to
expose this ioctl to the VMM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 19:33:34 +00:00
Sebastien Boeuf
882cdda995 deps: Patch kvm-ioctls to rely on latest from rust-vmm upstream
This brings the support for KVM_SET_IDENTITY_MAP_ADDR ioctl.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-12-04 19:33:34 +00:00
Henry Wang
788d77aee5 tests: Update the virtiofsd-rs cmdline
Commit ac25172176 bumps the rust
version of virtiofsd named `virtiofsd-rs`, which causes a warning
```
warning: use of deprecated parameter '--socket':
Please use the '--socket-path' option instead.
```

This commit updates the cmdline parameter accordingly.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-12-04 13:45:50 +01:00
Barret Rhoden
e08c747638 vmm: fix HANDLED_SIGNALS build error
The error was:

	borrow the array with `&` or call `.iter()` on it to iterate
	over it

Fixes #3348
Signed-off-by: Barret Rhoden <brho@google.com>
2021-12-04 13:45:02 +01:00
Rob Bradford
b519975fc8 build: Use Ubuntu impish (21.10) for workers
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-03 17:45:39 +01:00
Rob Bradford
348def9dfb arch, hypervisor, vmm: Explicitly place the TSS in the 32-bit space
Place the 3 page TSS at an explicit location in the 32-bit address space
to avoid conflicting with the loaded raw firmware.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-12-03 16:53:56 +01:00
Ziye Yang
b09cbb8493 vmm: Add constant SGX_PAGE_SIZE in memory_manager.rs
Purpose: Do not directly use 0x1000 but use predefined constant value.

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
2021-12-03 10:06:15 +00:00
124 changed files with 13192 additions and 10005 deletions

View File

@@ -55,7 +55,7 @@ jobs:
run: cargo clippy --all --all-targets --no-default-features --tests --features "mshv" -- -D warnings
- name: Clippy (integration tests)
run: cargo clippy --all --all-targets --tests --features "integration_tests" -- -D warnings
run: cargo clippy --all --all-targets --tests -- -D warnings
- name: Check build did not modify any files
run: test -z "$(git status --porcelain)"

View File

@@ -99,6 +99,16 @@ jobs:
asset_path: target/x86_64-unknown-linux-gnu/release/ch-remote
asset_name: ch-remote
asset_content_type: application/octet-stream
- name: Upload static-ch-remote
id: upload-release-static-ch-remote
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: target/x86_64-unknown-linux-musl/release/ch-remote
asset_name: ch-remote-static
asset_content_type: application/octet-stream
- name: Upload static AArch64 cloud-hypervisor
id: upload-release-static-aarch64-cloud-hypervisor
uses: actions/upload-release-asset@v1

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
/build
/.cargo
/target
**/*.rs.bk
**/Cargo.lock

335
Cargo.lock generated
View File

@@ -9,21 +9,6 @@ dependencies = [
"vm-memory",
]
[[package]]
name = "addr2line"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
@@ -33,20 +18,11 @@ dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.51"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
[[package]]
name = "api_client"
@@ -101,21 +77,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bincode"
version = "1.3.3"
@@ -170,28 +131,28 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim",
"term_size",
"termcolor",
"terminal_size",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "cloud-hypervisor"
version = "20.0.0"
version = "21.1.0"
dependencies = [
"anyhow",
"api_client",
"clap",
"credibility",
"dirs 4.0.0",
"epoll",
"event_monitor",
@@ -214,9 +175,9 @@ dependencies = [
[[package]]
name = "crc32c"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210cdf933e6a81212bfabf90cd8762f471b5922e5f6b709547673ad8e04b9448"
checksum = "ee6b9c9389584bcba988bd0836086789b7f87ad91892d6a83d5291dbb24524b5"
dependencies = [
"rustc_version",
]
@@ -227,16 +188,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910"
[[package]]
name = "credibility"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fae7a162fd5b462bc49704873a89950a655d44161add4be07e00e64c4c83a5bf"
dependencies = [
"failure",
"failure_derive",
]
[[package]]
name = "devices"
version = "0.1.0"
@@ -319,28 +270,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "fdt"
version = "0.1.3"
@@ -349,21 +278,15 @@ checksum = "b643857cf70949306b81d7e92cb9d47add673868edac9863c4a49c42feaf3f1e"
[[package]]
name = "getrandom"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "glob"
version = "0.3.0"
@@ -371,10 +294,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.19"
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7a30908dbce072eca83216eab939d2290080e00ca71611b96a09e5cdce5f3fa"
dependencies = [
"libc",
]
@@ -417,6 +346,16 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "indexmap"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.12"
@@ -447,9 +386,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "0.4.8"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "kvm-bindings"
@@ -464,8 +403,7 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97422ba48d7ffb66fd4d18130f72ab66f9bbbf791fb7a87b9291cdcfec437593"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#d22ef1f51852dfb055da38004e1a4fed81246f81"
dependencies = [
"kvm-bindings",
"libc",
@@ -480,9 +418,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.108"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "libssh2-sys"
@@ -543,6 +481,15 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "micro_http"
version = "0.1.0"
@@ -552,20 +499,10 @@ dependencies = [
"vmm-sys-util",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "mshv-bindings"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#8770516859e7d05193c496b77ac5ddad3ca5943a"
source = "git+https://github.com/rust-vmm/mshv?branch=main#b8b69b655337292037219ab765d2c94c565a076e"
dependencies = [
"libc",
"serde",
@@ -577,7 +514,7 @@ dependencies = [
[[package]]
name = "mshv-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/mshv?branch=main#8770516859e7d05193c496b77ac5ddad3ca5943a"
source = "git+https://github.com/rust-vmm/mshv?branch=main#b8b69b655337292037219ab765d2c94c565a076e"
dependencies = [
"libc",
"mshv-bindings",
@@ -614,20 +551,11 @@ dependencies = [
"vmm-sys-util",
]
[[package]]
name = "object"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
dependencies = [
"memchr",
]
[[package]]
name = "openssl-sys"
version = "0.9.71"
version = "0.9.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
dependencies = [
"autocfg",
"cc",
@@ -640,6 +568,15 @@ dependencies = [
name = "option_parser"
version = "0.1.0"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]]
name = "parking_lot"
version = "0.11.2"
@@ -689,15 +626,15 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.22"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]]
name = "pnet"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b6d2a0409666964722368ef5fb74b9f93fac11c18bef3308693c16c6733f103"
checksum = "8750e073f82219c01e771133c64718d7685aef922da8a0d430a46aed05b6341a"
dependencies = [
"ipnetwork",
"pnet_base",
@@ -709,15 +646,15 @@ dependencies = [
[[package]]
name = "pnet_base"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25488cd551a753dcaaa6fffc9f69a7610a412dd8954425bf7ffad5f7d1156fb8"
checksum = "8205fe084bd43a3af79b3155c19feddd62e733640498842e631a2ffe107d1538"
[[package]]
name = "pnet_datalink"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d1f8ab1ef6c914cf51dc5dfe0be64088ea5f3b08bbf5a31abc70356d271198"
checksum = "6f85aef5e52e22ff06b1b11f2eb6d52959a9e0ecad3cb3f5cc2d78cadc077f0e"
dependencies = [
"ipnetwork",
"libc",
@@ -728,9 +665,9 @@ dependencies = [
[[package]]
name = "pnet_macros"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30490e0852e58402b8fae0d39897b08a24f493023a4d6cf56b2e30f31ed57548"
checksum = "98cc3af95fed6dc318dfede3e81320f96ad5e237c6f7c4688108b19c8e67432d"
dependencies = [
"proc-macro2",
"quote",
@@ -740,18 +677,18 @@ dependencies = [
[[package]]
name = "pnet_macros_support"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4714e10f30cab023005adce048f2d30dd4ac4f093662abf2220855655ef8f90"
checksum = "feaba58ba96abb218ec584d6caf0d3ff48922df05dbbeb1560553c197091b29e"
dependencies = [
"pnet_base",
]
[[package]]
name = "pnet_packet"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8588067671d03c9f4254b2e66fecb4d8b93b5d3e703195b84f311cd137e32130"
checksum = "f246edaaf1aaf82072d4cd38ee18bcc5dfc0464093f9ca39e4ac5962d68cf9d4"
dependencies = [
"glob",
"pnet_base",
@@ -761,9 +698,9 @@ dependencies = [
[[package]]
name = "pnet_sys"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a3f32b0df45515befd19eed04616f6b56a488da92afc61164ef455e955f07f"
checksum = "028c87a5e3a48fc07df099a2025f2ef16add5993712e1494ba69a6707ee7ed06"
dependencies = [
"libc",
"winapi",
@@ -771,9 +708,9 @@ dependencies = [
[[package]]
name = "pnet_transport"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "932b2916d693bcc5fa18443dc99142e0a6fd31a6ce75a511868f7174c17e2bce"
checksum = "950f2a7961e19d22e19e84ff0a6e0955013185fe149673499662633d02b41b7a"
dependencies = [
"libc",
"pnet_base",
@@ -783,9 +720,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.32"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
@@ -803,9 +740,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.10"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [
"proc-macro2",
]
@@ -866,26 +803,20 @@ dependencies = [
"syn",
]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustc_version"
version = "0.2.3"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.6"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "scopeguard"
@@ -904,30 +835,21 @@ dependencies = [
[[package]]
name = "semver"
version = "0.9.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]]
name = "serde"
version = "1.0.130"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
[[package]]
name = "serde_derive"
version = "1.0.130"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
dependencies = [
"proc-macro2",
"quote",
@@ -936,9 +858,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.72"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
dependencies = [
"itoa",
"ryu",
@@ -947,9 +869,9 @@ dependencies = [
[[package]]
name = "signal-hook"
version = "0.3.10"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
dependencies = [
"libc",
"signal-hook-registry",
@@ -966,9 +888,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.7.0"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "ssh2"
@@ -990,15 +912,15 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
dependencies = [
"proc-macro2",
"quote",
@@ -1017,16 +939,6 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.2"
@@ -1036,6 +948,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "test_infra"
version = "0.1.0"
@@ -1050,12 +972,11 @@ dependencies = [
[[package]]
name = "textwrap"
version = "0.11.0"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
dependencies = [
"term_size",
"unicode-width",
"terminal_size",
]
[[package]]
@@ -1078,12 +999,6 @@ dependencies = [
"syn",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
@@ -1105,12 +1020,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "versionize"
version = "0.1.6"
@@ -1140,9 +1049,9 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a21f546f2bda37f5a8cfb138c87f95b8e34d2d78d6a7a92ba3785f4e08604a7"
checksum = "43449b404c488f70507dca193debd4bea361fe8089869b947adc19720e464bce"
dependencies = [
"vmm-sys-util",
]
@@ -1197,9 +1106,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d23ddeb452fb4f837526c6298cc8a2f4948e5595b0328a3d61b5eebe51874d7"
checksum = "3b56bf8f178fc500fe14505fca8b00dec76fc38f2304f461c8d9d7547982311d"
dependencies = [
"bitflags",
"libc",
@@ -1304,6 +1213,7 @@ name = "virtio-queue"
version = "0.1.0"
dependencies = [
"log",
"memoffset",
"vm-memory",
"vmm-sys-util",
]
@@ -1338,9 +1248,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#9cfa0c8d7c3032f7958
[[package]]
name = "vm-memory"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8ebcb86ca457f9d6e14cf97009f679952eba42f0113de5db596e514cd0e43b"
checksum = "339d4349c126fdcd87e034631d7274370cf19eb0e87b33166bcd956589fc72c5"
dependencies = [
"arc-swap",
"libc",
@@ -1382,7 +1292,6 @@ dependencies = [
"bitflags",
"block_util",
"clap",
"credibility",
"devices",
"epoll",
"event_monitor",

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "20.0.0"
version = "21.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
default-run = "cloud-hypervisor"
@@ -13,55 +13,51 @@ homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
lto = true
[dependencies]
anyhow = "1.0.51"
anyhow = "1.0.52"
api_client = { path = "api_client" }
clap = { version = "2.34.0", features = ["wrap_help"] }
clap = { version = "3.0.10", features = ["wrap_help","cargo"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.108"
libc = "0.2.112"
log = { version = "0.4.14", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.2.0"
serde_json = "1.0.72"
signal-hook = "0.3.10"
serde_json = "1.0.75"
signal-hook = "0.3.13"
thiserror = "1.0.30"
vmm = { path = "vmm" }
vmm-sys-util = "0.9.0"
vm-memory = "0.6.0"
vm-memory = "0.7.0"
[build-dependencies]
clap = { version = "2.34.0", features = ["wrap_help"] }
clap = { version = "3.0.10", features = ["wrap_help"] }
# List of patched crates
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0", features = ["with-serde", "fam-wrappers"] }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
[dev-dependencies]
credibility = "0.1.3"
dirs = "4.0.0"
lazy_static= "1.4.0"
net_util = { path = "net_util" }
serde_json = "1.0.72"
serde_json = "1.0.75"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
[features]
default = ["common", "kvm"]
# Common features for all hypervisors
common = ["acpi", "cmos", "fwdebug", "io_uring"]
common = ["acpi", "cmos", "fwdebug"]
acpi = ["vmm/acpi"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
io_uring = ["vmm/io_uring"]
tdx = ["vmm/tdx"]
# Integration tests require a special environment to run in
integration_tests = []
[workspace]
members = [
"acpi_tables",

25
Jenkinsfile vendored
View File

@@ -22,15 +22,19 @@ pipeline{
}
}
stage ('Build') {
parallel {
parallel {
stage ('Worker build') {
agent { node { label 'hirsute' } }
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run OpenAPI tests') {
steps {
sh "scripts/run_openapi_tests.sh"
@@ -84,12 +88,16 @@ pipeline{
}
stage ('Worker build (musl)') {
agent { node { label 'hirsute' } }
environment {
AZURE_CONNECTION_STRING = credentials('46b4e7d6-315f-4cc1-8333-b58780863b9b')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run unit tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --unit --libc musl"
@@ -189,11 +197,14 @@ pipeline{
checkout scm
}
}
stage ('Install azure-cli') {
steps {
installAzureCli()
}
}
stage ('Download assets') {
steps {
sh "sudo apt install -y azure-cli"
sh "mkdir ${env.HOME}/workloads"
sh 'az storage blob download --container-name private-images --file "$HOME/workloads/OVMF-4b47d0c6c8.fd" --name OVMF-4b47d0c6c8.fd --connection-string "$AZURE_CONNECTION_STRING"'
sh 'az storage blob download --container-name private-images --file "$HOME/workloads/windows-server-2019.raw" --name windows-server-2019.raw --connection-string "$AZURE_CONNECTION_STRING"'
}
}
@@ -278,3 +289,11 @@ 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 "sudo apt update"
sh "sudo apt install -y azure-cli"
}

View File

@@ -4,6 +4,7 @@
- [Architectures](#architectures)
- [Guest OS](#guest-os)
- [2. Getting Started](#2-getting-started)
- [Preparation](#preparation)
- [Install prerequisites](#install-prerequisites)
- [Clone and build](#clone-and-build)
- [Containerized builds and tests](#containerized-builds-and-tests)
@@ -167,8 +168,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
--net "tap=,mac=,ip=,mask="
$ popd
```
@@ -186,12 +186,12 @@ To build the kernel:
# Clone the Cloud Hypervisor Linux branch
$ pushd $CLOUDH
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-5.14 linux-cloud-hypervisor
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-5.15.12 linux-cloud-hypervisor
$ pushd linux-cloud-hypervisor
# Use the cloud-hypervisor kernel config to build your kernel
$ cp $CLOUDH/cloud-hypervisor/resources/linux-config-x86_64 .config
$ make bzImage -j `nproc`
$ KCFLAGS="-Wa,-mx86-used-note=no" make bzImage -j `nproc`
$ popd
```
@@ -222,8 +222,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
--net "tap=,mac=,ip=,mask="
```
The above example use the `virtio-console` device as the guest console, and this
@@ -242,8 +241,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--cmdline "console=ttyS0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
--net "tap=,mac=,ip=,mask="
```
# 3. Status

View File

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

View File

@@ -1392,13 +1392,13 @@ mod tests {
#[test]
fn test_pkg_length() {
assert_eq!(create_pkg_length(&[0u8; 62].to_vec(), true), vec![63]);
assert_eq!(create_pkg_length(&[0u8; 62], true), vec![63]);
assert_eq!(
create_pkg_length(&[0u8; 64].to_vec(), true),
create_pkg_length(&[0u8; 64], true),
vec![1 << 6 | (66 & 0xf), 66 >> 4]
);
assert_eq!(
create_pkg_length(&[0u8; 4096].to_vec(), true),
create_pkg_length(&[0u8; 4096], true),
vec![
2 << 6 | (4099 & 0xf) as u8,
(4099 >> 4) as u8,

View File

@@ -11,18 +11,18 @@ tdx = []
[dependencies]
acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0.51"
anyhow = "1.0.52"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.108"
libc = "0.2.112"
linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.14"
serde = { version = "1.0.130", features = ["rc"] }
serde_derive = "1.0.130"
serde = { version = "1.0.133", features = ["rc"] }
serde_derive = "1.0.133"
thiserror = "1.0.30"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-bitmap"] }
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.9.0", features = ["with-serde"] }

View File

@@ -6,7 +6,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use crate::NumaNodes;
use crate::{NumaNodes, PciSpaceInfo};
use byteorder::{BigEndian, ByteOrder};
use std::cmp;
use std::collections::HashMap;
@@ -22,7 +22,7 @@ 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_MMCONFIG_SIZE, PCI_MMCONFIG_START,
PCI_HIGH_BASE, PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
};
use vm_fdt::{FdtWriter, FdtWriterResult};
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryRegion};
@@ -88,7 +88,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
device_info: &HashMap<(DeviceType, String), T, S>,
gic_device: &dyn GicDevice,
initrd: &Option<InitramfsConfig>,
pci_space_address: &(u64, u64),
pci_space_info: &[PciSpaceInfo],
numa_nodes: &NumaNodes,
virtio_iommu_bdf: Option<u32>,
) -> FdtWriterResult<Vec<u8>> {
@@ -117,12 +117,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
create_clock_node(&mut fdt)?;
create_psci_node(&mut fdt)?;
create_devices_node(&mut fdt, device_info)?;
create_pci_nodes(
&mut fdt,
pci_space_address.0,
pci_space_address.1,
virtio_iommu_bdf,
)?;
create_pci_nodes(&mut fdt, pci_space_info, virtio_iommu_bdf)?;
if numa_nodes.len() > 1 {
create_distance_map_node(&mut fdt, numa_nodes)?;
}
@@ -547,108 +542,145 @@ fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Buil
fn create_pci_nodes(
fdt: &mut FdtWriter,
pci_device_base: u64,
pci_device_size: u64,
pci_device_info: &[PciSpaceInfo],
virtio_iommu_bdf: Option<u32>,
) -> FdtWriterResult<()> {
// Add node for PCIe controller.
// See Documentation/devicetree/bindings/pci/host-generic-pci.txt in the kernel
// and https://elinux.org/Device_Tree_Usage.
// In multiple PCI segments setup, each PCI segment needs a PCI node.
for pci_device_info_elem in pci_device_info.iter() {
// EDK2 requires the PCIe high space above 4G address.
// The actual space in CLH follows the RAM. If the RAM space is small, the PCIe high space
// 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,
)
};
// 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 =
MEM_32BIT_DEVICES_SIZE / ((1 << 12) * pci_device_info.len() as u64) * (1 << 12);
let pci_device_base_32bit: u64 = MEM_32BIT_DEVICES_START.0
+ pci_device_size_32bit * pci_device_info_elem.pci_segment_id as u64;
// EDK2 requires the PCIe high space above 4G address.
// The actual space in CLH follows the RAM. If the RAM space is small, the PCIe high space
// could fall bellow 4G.
// Here we put it above 512G in FDT to workaround the EDK2 check.
// But the address written in ACPI is not impacted.
let pci_device_base_64bit: u64 = if cfg!(feature = "acpi") {
pci_device_base + PCI_HIGH_BASE
} else {
pci_device_base
};
let pci_device_size_64bit: u64 = if cfg!(feature = "acpi") {
pci_device_size - PCI_HIGH_BASE
} else {
pci_device_size
};
let ranges = [
// io addresses
0x1000000,
0_u32,
0_u32,
(MEM_PCI_IO_START.0 >> 32) as u32,
MEM_PCI_IO_START.0 as u32,
(MEM_PCI_IO_SIZE >> 32) as u32,
MEM_PCI_IO_SIZE as u32,
// mmio addresses
0x2000000, // (ss = 10: 32-bit memory space)
(MEM_32BIT_DEVICES_START.0 >> 32) as u32, // PCI address
MEM_32BIT_DEVICES_START.0 as u32,
(MEM_32BIT_DEVICES_START.0 >> 32) as u32, // CPU address
MEM_32BIT_DEVICES_START.0 as u32,
(MEM_32BIT_DEVICES_SIZE >> 32) as u32, // size
MEM_32BIT_DEVICES_SIZE as u32,
// device addresses
0x3000000, // (ss = 11: 64-bit memory space)
(pci_device_base_64bit >> 32) as u32, // PCI address
pci_device_base_64bit as u32,
(pci_device_base_64bit >> 32) as u32, // CPU address
pci_device_base_64bit as u32,
(pci_device_size_64bit >> 32) as u32, // size
pci_device_size_64bit as u32,
];
let bus_range = [0, 0]; // Only bus 0
let reg = [PCI_MMCONFIG_START.0, PCI_MMCONFIG_SIZE];
let pci_node = fdt.begin_node("pci")?;
fdt.property_string("compatible", "pci-host-ecam-generic")?;
fdt.property_string("device_type", "pci")?;
fdt.property_array_u32("ranges", &ranges)?;
fdt.property_array_u32("bus-range", &bus_range)?;
fdt.property_u32("#address-cells", 3)?;
fdt.property_u32("#size-cells", 2)?;
fdt.property_array_u64("reg", &reg)?;
fdt.property_u32("#interrupt-cells", 1)?;
fdt.property_null("interrupt-map")?;
fdt.property_null("interrupt-map-mask")?;
fdt.property_null("dma-coherent")?;
fdt.property_u32("msi-parent", MSI_PHANDLE)?;
if let Some(virtio_iommu_bdf) = virtio_iommu_bdf {
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
// for 'iommu-map' attribute setting.
let iommu_map = [
let ranges = [
// io addresses. Since AArch64 will not use IO address,
// we can set the same IO address range for every segment.
0x1000000,
0_u32,
VIRTIO_IOMMU_PHANDLE,
0_u32,
virtio_iommu_bdf,
virtio_iommu_bdf + 1,
VIRTIO_IOMMU_PHANDLE,
virtio_iommu_bdf + 1,
0xffff - virtio_iommu_bdf,
(MEM_PCI_IO_START.0 >> 32) as u32,
MEM_PCI_IO_START.0 as u32,
(MEM_PCI_IO_SIZE >> 32) as u32,
MEM_PCI_IO_SIZE as u32,
// mmio addresses
0x2000000, // (ss = 10: 32-bit memory space)
(pci_device_base_32bit >> 32) as u32, // PCI address
pci_device_base_32bit as u32,
(pci_device_base_32bit >> 32) as u32, // CPU address
pci_device_base_32bit as u32,
(pci_device_size_32bit >> 32) as u32, // size
pci_device_size_32bit as u32,
// device addresses
0x3000000, // (ss = 11: 64-bit memory space)
(pci_device_base_64bit >> 32) as u32, // PCI address
pci_device_base_64bit as u32,
(pci_device_base_64bit >> 32) as u32, // CPU address
pci_device_base_64bit as u32,
(pci_device_size_64bit >> 32) as u32, // size
pci_device_size_64bit as u32,
];
let bus_range = [0, 0]; // Only bus 0
let reg = [
pci_device_info_elem.mmio_config_address,
PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
];
// See kernel document Documentation/devicetree/bindings/pci/pci-msi.txt
let msi_map = [
// rid-base: A single cell describing the first RID matched by the entry.
0x0,
// msi-controller: A single phandle to an MSI controller.
MSI_PHANDLE,
// msi-base: An msi-specifier describing the msi-specifier produced for the
// first RID matched by the entry.
(pci_device_info_elem.pci_segment_id as u32) << 8,
// length: A single cell describing how many consecutive RIDs are matched
// following the rid-base.
0x100,
];
fdt.property_array_u32("iommu-map", &iommu_map)?;
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
// for virtio-iommu node settings.
let virtio_iommu_node_name = format!("virtio_iommu@{:x}", virtio_iommu_bdf);
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
fdt.property_u32("#iommu-cells", 1)?;
fdt.property_string("compatible", "virtio,pci-iommu")?;
let pci_node_name = format!("pci@{:x}", pci_device_info_elem.mmio_config_address);
let pci_node = fdt.begin_node(&pci_node_name)?;
// 'reg' is a five-cell address encoded as
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
// should be zero.
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
fdt.property_array_u32("reg", &reg)?;
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
fdt.property_string("compatible", "pci-host-ecam-generic")?;
fdt.property_string("device_type", "pci")?;
fdt.property_array_u32("ranges", &ranges)?;
fdt.property_array_u32("bus-range", &bus_range)?;
fdt.property_u32(
"linux,pci-domain",
pci_device_info_elem.pci_segment_id as u32,
)?;
fdt.property_u32("#address-cells", 3)?;
fdt.property_u32("#size-cells", 2)?;
fdt.property_array_u64("reg", &reg)?;
fdt.property_u32("#interrupt-cells", 1)?;
fdt.property_null("interrupt-map")?;
fdt.property_null("interrupt-map-mask")?;
fdt.property_null("dma-coherent")?;
fdt.property_array_u32("msi-map", &msi_map)?;
fdt.property_u32("msi-parent", MSI_PHANDLE)?;
fdt.end_node(virtio_iommu_node)?;
if pci_device_info_elem.pci_segment_id == 0 {
if let Some(virtio_iommu_bdf) = virtio_iommu_bdf {
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
// for 'iommu-map' attribute setting.
let iommu_map = [
0_u32,
VIRTIO_IOMMU_PHANDLE,
0_u32,
virtio_iommu_bdf,
virtio_iommu_bdf + 1,
VIRTIO_IOMMU_PHANDLE,
virtio_iommu_bdf + 1,
0xffff - virtio_iommu_bdf,
];
fdt.property_array_u32("iommu-map", &iommu_map)?;
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
// for virtio-iommu node settings.
let virtio_iommu_node_name = format!("virtio_iommu@{:x}", virtio_iommu_bdf);
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
fdt.property_u32("#iommu-cells", 1)?;
fdt.property_string("compatible", "virtio,pci-iommu")?;
// 'reg' is a five-cell address encoded as
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
// should be zero.
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
fdt.property_array_u32("reg", &reg)?;
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
fdt.end_node(virtio_iommu_node)?;
}
}
fdt.end_node(pci_node)?;
}
fdt.end_node(pci_node)?;
Ok(())
}

View File

@@ -63,7 +63,7 @@ macro_rules! VGIC_DIST_REG {
// List with relevant distributor registers that we will be restoring.
// Order is taken from qemu.
static VGIC_DIST_REGS: &'static [DistReg] = &[
static VGIC_DIST_REGS: &[DistReg] = &[
VGIC_DIST_REG!(GICD_STATUSR, 0, 4),
VGIC_DIST_REG!(GICD_ICENABLER, 1, 0),
VGIC_DIST_REG!(GICD_ISENABLER, 1, 0),

View File

@@ -124,12 +124,11 @@ pub mod kvm {
its_device: &Arc<dyn hypervisor::Device>,
save: bool,
) -> crate::aarch64::gic::Result<()> {
let attr: u64;
if save {
attr = u64::from(kvm_bindings::KVM_DEV_ARM_ITS_SAVE_TABLES);
let attr = if save {
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_SAVE_TABLES)
} else {
attr = u64::from(kvm_bindings::KVM_DEV_ARM_ITS_RESTORE_TABLES);
}
u64::from(kvm_bindings::KVM_DEV_ARM_ITS_RESTORE_TABLES)
};
let init_gic_attr = kvm_bindings::kvm_device_attr {
group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,

View File

@@ -59,7 +59,7 @@ SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R1_EL1, 1);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R2_EL1, 2);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R3_EL1, 3);
static VGIC_ICC_REGS: &'static [u64] = &[
static VGIC_ICC_REGS: &[u64] = &[
SYS_ICC_SRE_EL1,
SYS_ICC_CTLR_EL1,
SYS_ICC_IGRPEN0_EL1,
@@ -91,8 +91,7 @@ fn icc_attr_access(
flags: 0,
};
if set {
#[allow(clippy::unnecessary_mut_passed)]
gic.set_device_attr(&mut gic_icc_attr)
gic.set_device_attr(&gic_icc_attr)
.map_err(Error::SetDeviceAttribute)?;
} else {
gic.get_device_attr(&mut gic_icc_attr)

View File

@@ -61,7 +61,7 @@ macro_rules! VGIC_RDIST_REG {
}
// List with relevant distributor registers that we will be restoring.
static VGIC_RDIST_REGS: &'static [RdistReg] = &[
static VGIC_RDIST_REGS: &[RdistReg] = &[
VGIC_RDIST_REG!(GICR_STATUSR, 4),
VGIC_RDIST_REG!(GICR_WAKER, 4),
VGIC_RDIST_REG!(GICR_PROPBASER, 8),
@@ -70,7 +70,7 @@ static VGIC_RDIST_REGS: &'static [RdistReg] = &[
];
// List with relevant distributor registers that we will be restoring.
static VGIC_SGI_REGS: &'static [RdistReg] = &[
static VGIC_SGI_REGS: &[RdistReg] = &[
VGIC_RDIST_REG!(GICR_IGROUPR0, 4),
VGIC_RDIST_REG!(GICR_ICENABLER0, 4),
VGIC_RDIST_REG!(GICR_ISENABLER0, 4),
@@ -96,8 +96,7 @@ fn redist_attr_access(
flags: 0,
};
if set {
#[allow(clippy::unnecessary_mut_passed)]
gic.set_device_attr(&mut gic_dist_attr)
gic.set_device_attr(&gic_dist_attr)
.map_err(Error::SetDeviceAttribute)?;
} else {
gic.get_device_attr(&mut gic_dist_attr)
@@ -110,7 +109,7 @@ fn access_redists_aux(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &mut Vec<u32>,
reg_list: &'static [RdistReg],
reg_list: &[RdistReg],
idx: &mut usize,
set: bool,
) -> Result<()> {

View File

@@ -82,6 +82,8 @@ pub const MEM_32BIT_DEVICES_SIZE: u64 = 0x2000_0000;
/// PCI MMCONFIG space (start: after the device space at 1 GiB, length: 256MiB)
pub const PCI_MMCONFIG_START: GuestAddress = GuestAddress(0x3000_0000);
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;
@@ -104,7 +106,7 @@ pub const RSDP_POINTER: GuestAddress = GuestAddress(ACPI_START);
pub const KERNEL_START: u64 = ACPI_START + ACPI_MAX_SIZE as u64;
/// Pci high memory base
pub const PCI_HIGH_BASE: u64 = 0x80_0000_0000_u64;
pub const PCI_HIGH_BASE: u64 = 0x2_0000_0000_u64;
// As per virt/kvm/arm/vgic/vgic-kvm-device.c we need
// the number of interrupts our GIC will support to be:

View File

@@ -14,16 +14,14 @@ pub mod regs;
pub mod uefi;
pub use self::fdt::DeviceInfoForFdt;
use crate::{DeviceType, GuestMemoryMmap, NumaNodes, RegionType};
use crate::{DeviceType, GuestMemoryMmap, NumaNodes, PciSpaceInfo, RegionType};
use gic::GicDevice;
use log::{log_enabled, Level};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt::Debug;
use std::sync::Arc;
use vm_memory::{
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestUsize,
};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestUsize};
/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
@@ -66,16 +64,10 @@ pub fn configure_vcpu(
fd: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
) -> super::Result<u64> {
if let Some(kernel_entry_point) = kernel_entry_point {
regs::setup_regs(
fd,
id,
kernel_entry_point.entry_addr.raw_value(),
&vm_memory.memory(),
)
.map_err(Error::RegsConfiguration)?;
regs::setup_regs(fd, id, kernel_entry_point.entry_addr.raw_value())
.map_err(Error::RegsConfiguration)?;
}
let mpidr = fd.read_mpidr().map_err(Error::VcpuRegMpidr)?;
@@ -140,7 +132,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
vcpu_topology: Option<(u8, u8, u8)>,
device_info: &HashMap<(DeviceType, String), T, S>,
initrd: &Option<super::InitramfsConfig>,
pci_space_address: &(u64, u64),
pci_space_info: &[PciSpaceInfo],
virtio_iommu_bdf: Option<u32>,
gic_device: &dyn GicDevice,
numa_nodes: &NumaNodes,
@@ -153,7 +145,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
device_info,
gic_device,
initrd,
pci_space_address,
pci_space_info,
numa_nodes,
virtio_iommu_bdf,
)

View File

@@ -6,7 +6,6 @@
// found in the THIRD-PARTY file.
use super::get_fdt_addr;
use crate::GuestMemoryMmap;
use hypervisor::kvm::kvm_bindings::{
kvm_regs, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
};
@@ -43,12 +42,7 @@ const PSTATE_FAULT_BITS_64: u64 = PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_
/// * `cpu_id` - Index of current vcpu.
/// * `boot_ip` - Starting instruction pointer.
/// * `mem` - Reserved DRAM for current VM.
pub fn setup_regs(
vcpu: &Arc<dyn hypervisor::Vcpu>,
cpu_id: u8,
boot_ip: u64,
_mem: &GuestMemoryMmap,
) -> Result<()> {
pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, cpu_id: u8, boot_ip: u64) -> Result<()> {
let kreg_off = offset__of!(kvm_regs, regs);
// Get the register index of the PSTATE (Processor State) register.

View File

@@ -6,7 +6,6 @@
//! Implements platform specific functionality.
//! Supported platforms: x86_64, aarch64.
#![allow(clippy::transmute_ptr_to_ptr, clippy::redundant_static_lifetimes)]
#[macro_use]
extern crate log;
@@ -162,6 +161,16 @@ pub struct MmioDeviceInfo {
pub irq: u32,
}
/// Structure to describe PCI space information
#[derive(Clone, Debug)]
#[cfg(target_arch = "aarch64")]
pub struct PciSpaceInfo {
pub pci_segment_id: u16,
pub mmio_config_address: u64,
pub pci_device_space_start: u64,
pub pci_device_space_size: u64,
}
#[cfg(target_arch = "aarch64")]
impl DeviceInfoForFdt for MmioDeviceInfo {
fn addr(&self) -> u64 {

View File

@@ -93,6 +93,16 @@ pub const MEM_32BIT_DEVICES_SIZE: u64 = 640 << 20;
pub const PCI_MMCONFIG_START: GuestAddress =
GuestAddress(MEM_32BIT_DEVICES_START.0 + MEM_32BIT_DEVICES_SIZE);
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;
// TSS is 3 pages after the PCI MMCONFIG space
pub const KVM_TSS_START: GuestAddress = GuestAddress(PCI_MMCONFIG_START.0 + PCI_MMCONFIG_SIZE);
pub const KVM_TSS_SIZE: u64 = (3 * 4) << 10;
// Identity map is a one page region after the TSS
pub const KVM_IDENTITY_MAP_START: GuestAddress = GuestAddress(KVM_TSS_START.0 + KVM_TSS_SIZE);
pub const KVM_IDENTITY_MAP_SIZE: u64 = 4 << 10;
// IOAPIC
pub const IOAPIC_START: GuestAddress = GuestAddress(0xfec0_0000);
@@ -101,9 +111,6 @@ pub const IOAPIC_SIZE: u64 = 0x20;
// APIC
pub const APIC_START: GuestAddress = GuestAddress(0xfee0_0000);
/// Address for the TSS setup.
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffb_d000);
// == End of "32-bit reserved" range. ==
// ** 64-bit RAM start (start: 4GiB, length: varies) **

View File

@@ -315,21 +315,12 @@ impl CpuidPatch {
for entry in entries.iter() {
if entry.function == function && entry.index == index {
let reg_val: u32;
match reg {
CpuidReg::EAX => {
reg_val = entry.eax;
}
CpuidReg::EBX => {
reg_val = entry.ebx;
}
CpuidReg::ECX => {
reg_val = entry.ecx;
}
CpuidReg::EDX => {
reg_val = entry.edx;
}
}
let reg_val = match reg {
CpuidReg::EAX => entry.eax,
CpuidReg::EBX => entry.ebx,
CpuidReg::ECX => entry.ecx,
CpuidReg::EDX => entry.edx,
};
return (reg_val & mask) == mask;
}
@@ -522,19 +513,14 @@ impl CpuidFeatureEntry {
.enumerate()
{
let entry = &feature_entry_list[i];
let entry_compatible;
match entry.compatible_check {
let entry_compatible = match entry.compatible_check {
CpuidCompatibleCheck::BitwiseSubset => {
let different_feature_bits = src_vm_feature ^ dest_vm_feature;
let src_vm_feature_bits_only = different_feature_bits & src_vm_feature;
entry_compatible = src_vm_feature_bits_only == 0;
}
CpuidCompatibleCheck::Equal => {
entry_compatible = src_vm_feature == dest_vm_feature;
}
CpuidCompatibleCheck::NumNotGreater => {
entry_compatible = src_vm_feature <= dest_vm_feature;
src_vm_feature_bits_only == 0
}
CpuidCompatibleCheck::Equal => src_vm_feature == dest_vm_feature,
CpuidCompatibleCheck::NumNotGreater => src_vm_feature <= dest_vm_feature,
};
if !entry_compatible {
error!(

View File

@@ -6,11 +6,10 @@ edition = "2018"
[features]
default = []
io_uring = []
[dependencies]
io-uring = "0.5.2"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
qcow = { path = "../qcow" }
thiserror = "1.0.30"
@@ -19,7 +18,7 @@ versionize_derive = "0.1.4"
vhdx = { path = "../vhdx" }
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
virtio-queue = { path = "../virtio-queue" }
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
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

@@ -2,8 +2,13 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use libc::{ioctl, S_IFBLK, S_IFMT};
use std::convert::TryInto;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::{ioctl_expr, ioctl_io_nr, ioctl_ioc_nr};
#[derive(Error, Debug)]
pub enum DiskFileError {
@@ -15,11 +20,96 @@ pub enum DiskFileError {
NewAsyncIo(#[source] std::io::Error),
}
#[derive(Debug)]
pub struct DiskTopology {
pub logical_block_size: u64,
pub physical_block_size: u64,
pub minimum_io_size: u64,
pub optimal_io_size: u64,
}
impl Default for DiskTopology {
fn default() -> Self {
Self {
logical_block_size: 512,
physical_block_size: 512,
minimum_io_size: 512,
optimal_io_size: 0,
}
}
}
ioctl_io_nr!(BLKSSZGET, 0x12, 104);
ioctl_io_nr!(BLKPBSZGET, 0x12, 123);
ioctl_io_nr!(BLKIOMIN, 0x12, 120);
ioctl_io_nr!(BLKIOOPT, 0x12, 121);
enum BlockSize {
LogicalBlock,
PhysicalBlock,
MinimumIo,
OptimalIo,
}
impl DiskTopology {
fn is_block_device(f: &mut File) -> std::io::Result<bool> {
let mut stat = std::mem::MaybeUninit::<libc::stat>::uninit();
let ret = unsafe { libc::fstat(f.as_raw_fd(), stat.as_mut_ptr()) };
if ret != 0 {
return Err(std::io::Error::last_os_error());
}
let is_block = unsafe { (*stat.as_ptr()).st_mode & S_IFMT == S_IFBLK };
Ok(is_block)
}
// libc::ioctl() takes different types on different architectures
#[allow(clippy::useless_conversion)]
fn query_block_size(f: &mut File, block_size_type: BlockSize) -> std::io::Result<u64> {
let mut block_size = 0;
let ret = unsafe {
ioctl(
f.as_raw_fd(),
match block_size_type {
BlockSize::LogicalBlock => BLKSSZGET(),
BlockSize::PhysicalBlock => BLKPBSZGET(),
BlockSize::MinimumIo => BLKIOMIN(),
BlockSize::OptimalIo => BLKIOOPT(),
}
.try_into()
.unwrap(),
&mut block_size,
)
};
if ret != 0 {
return Err(std::io::Error::last_os_error());
};
Ok(block_size)
}
pub fn probe(f: &mut File) -> std::io::Result<Self> {
if !Self::is_block_device(f)? {
return Ok(DiskTopology::default());
}
Ok(DiskTopology {
logical_block_size: Self::query_block_size(f, BlockSize::LogicalBlock)?,
physical_block_size: Self::query_block_size(f, BlockSize::PhysicalBlock)?,
minimum_io_size: Self::query_block_size(f, BlockSize::MinimumIo)?,
optimal_io_size: Self::query_block_size(f, BlockSize::OptimalIo)?,
})
}
}
pub type DiskFileResult<T> = std::result::Result<T, DiskFileError>;
pub trait DiskFile: Send + Sync {
fn size(&mut self) -> DiskFileResult<u64>;
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>>;
fn topology(&mut self) -> DiskTopology {
DiskTopology::default()
}
}
#[derive(Error, Debug)]

View File

@@ -20,9 +20,9 @@ pub mod raw_sync;
pub mod vhd;
pub mod vhdx_sync;
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, DiskFileError, DiskFileResult};
#[cfg(feature = "io_uring")]
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
use io_uring::{opcode, IoUring, Probe};
use std::alloc::{alloc_zeroed, dealloc, Layout};
use std::cmp;
use std::convert::TryInto;
use std::fs::File;
@@ -30,14 +30,14 @@ use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use std::os::linux::fs::MetadataExt;
use std::path::Path;
use std::result;
use std::sync::{Arc, Mutex};
use std::sync::MutexGuard;
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_bindings::bindings::virtio_blk::*;
use virtio_queue::DescriptorChain;
use vm_memory::{
bitmap::AtomicBitmap, bitmap::Bitmap, ByteValued, Bytes, GuestAddress, GuestMemory,
GuestMemoryAtomic, GuestMemoryError,
GuestMemoryError, GuestMemoryLoadGuard,
};
use vmm_sys_util::eventfd::EventFd;
@@ -113,6 +113,8 @@ pub enum ExecuteError {
AsyncRead(AsyncIoError),
AsyncWrite(AsyncIoError),
AsyncFlush(AsyncIoError),
/// Failed allocating a temporary buffer.
TemporaryBufferAllocation(io::Error),
}
impl ExecuteError {
@@ -129,6 +131,7 @@ impl ExecuteError {
ExecuteError::AsyncRead(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::AsyncWrite(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::AsyncFlush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::TemporaryBufferAllocation(_) => VIRTIO_BLK_S_IOERR,
}
}
}
@@ -166,6 +169,14 @@ fn sector(mem: &GuestMemoryMmap, desc_addr: GuestAddress) -> result::Result<u64,
mem.read_obj(addr).map_err(Error::GuestMemory)
}
#[derive(Debug)]
pub struct AlignedOperation {
origin_ptr: u64,
aligned_ptr: u64,
size: usize,
layout: Layout,
}
#[derive(Debug)]
pub struct Request {
pub request_type: RequestType,
@@ -173,11 +184,12 @@ pub struct Request {
pub data_descriptors: Vec<(GuestAddress, u32)>,
pub status_addr: GuestAddress,
pub writeback: bool,
pub aligned_operations: Vec<AlignedOperation>,
}
impl Request {
pub fn parse(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
) -> result::Result<Request, Error> {
let hdr_desc = desc_chain
.next()
@@ -198,6 +210,7 @@ impl Request {
data_descriptors: Vec::new(),
status_addr: GuestAddress(0),
writeback: true,
aligned_operations: Vec::new(),
};
let status_desc;
@@ -253,13 +266,12 @@ impl Request {
Ok(req)
}
#[allow(clippy::ptr_arg)]
pub fn execute<T: Seek + Read + Write>(
&self,
disk: &mut T,
disk_nsectors: u64,
mem: &GuestMemoryMmap,
disk_id: &Vec<u8>,
disk_id: &[u8],
) -> result::Result<u32, ExecuteError> {
disk.seek(SeekFrom::Start(self.sector << SECTOR_SHIFT))
.map_err(ExecuteError::Seek)?;
@@ -294,7 +306,7 @@ impl Request {
if (*data_len as usize) < disk_id.len() {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
mem.write_slice(disk_id.as_slice(), *data_addr)
mem.write_slice(disk_id, *data_addr)
.map_err(ExecuteError::Write)?;
}
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
@@ -304,7 +316,7 @@ impl Request {
}
pub fn execute_async(
&self,
&mut self,
mem: &GuestMemoryMmap,
disk_nsectors: u64,
disk_image: &mut dyn AsyncIo,
@@ -317,6 +329,9 @@ impl Request {
let mut iovecs = Vec::new();
for (data_addr, data_len) in &self.data_descriptors {
if *data_len == 0 {
continue;
}
let mut top: u64 = u64::from(*data_len) / SECTOR_SIZE;
if u64::from(*data_len) % SECTOR_SIZE != 0 {
top += 1;
@@ -328,12 +343,52 @@ impl Request {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
let buf = mem
let origin_ptr = mem
.get_slice(*data_addr, *data_len as usize)
.map_err(ExecuteError::GetHostAddress)?
.as_ptr();
// Verify the buffer alignment.
// In case it's not properly aligned, an intermediate buffer is
// created with the correct alignment, and a copy from/to the
// origin buffer is performed, depending on the type of operation.
let iov_base = if (origin_ptr as u64) % SECTOR_SIZE != 0 {
let layout =
Layout::from_size_align(*data_len as usize, SECTOR_SIZE as usize).unwrap();
// Safe because layout has non-zero size
let aligned_ptr = unsafe { alloc_zeroed(layout) };
if aligned_ptr.is_null() {
return Err(ExecuteError::TemporaryBufferAllocation(
io::Error::last_os_error(),
));
}
// We need to perform the copy beforehand in case we're writing
// data out.
if request_type == RequestType::Out {
// Safe because destination buffer has been allocated with
// the proper size.
unsafe {
std::ptr::copy(origin_ptr as *const u8, aligned_ptr, *data_len as usize)
};
}
// Store both origin and aligned pointers for complete_async()
// to process them.
self.aligned_operations.push(AlignedOperation {
origin_ptr: origin_ptr as u64,
aligned_ptr: aligned_ptr as u64,
size: *data_len as usize,
layout,
});
aligned_ptr as *mut libc::c_void
} else {
origin_ptr as *mut libc::c_void
};
let iovec = libc::iovec {
iov_base: buf as *mut libc::c_void,
iov_base,
iov_len: *data_len as libc::size_t,
};
iovecs.push(iovec);
@@ -381,6 +436,36 @@ impl Request {
Ok(true)
}
pub fn complete_async(&mut self) -> result::Result<(), Error> {
for aligned_operation in self.aligned_operations.drain(..) {
// We need to perform the copy after the data has been read inside
// the aligned buffer in case we're reading data in.
if self.request_type == RequestType::In {
// Safe because origin buffer has been allocated with the
// proper size.
unsafe {
std::ptr::copy(
aligned_operation.aligned_ptr as *const u8,
aligned_operation.origin_ptr as *mut u8,
aligned_operation.size,
)
};
}
// Free the temporary aligned buffer.
// Safe because aligned_ptr was allocated by alloc_zeroed with the same
// layout
unsafe {
dealloc(
aligned_operation.aligned_ptr as *mut u8,
aligned_operation.layout,
)
};
}
Ok(())
}
pub fn set_writeback(&mut self, writeback: bool) {
self.writeback = writeback
}
@@ -423,7 +508,6 @@ unsafe impl ByteValued for VirtioBlockGeometry {}
/// Check if io_uring for block device can be used on the current system, as
/// it correctly supports the expected io_uring features.
#[cfg(feature = "io_uring")]
pub fn block_io_uring_is_supported() -> bool {
let error_msg = "io_uring not supported:";
@@ -471,119 +555,98 @@ pub fn block_io_uring_is_supported() -> bool {
true
}
#[cfg(not(feature = "io_uring"))]
pub fn block_io_uring_is_supported() -> bool {
false
}
pub trait AsyncAdaptor<F>
where
F: Read + Write + Seek,
{
fn read_vectored_sync(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSliceMut
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSliceMut::new(unsafe { std::mem::transmute(*iovec) }));
}
pub fn disk_size(file: &mut dyn Seek, semaphore: &mut Arc<Mutex<()>>) -> DiskFileResult<u64> {
// Take the semaphore to ensure other threads are not interacting with
// the underlying file.
let _lock = semaphore.lock().unwrap();
let result = {
let mut file = self.file();
Ok(file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)? as u64)
}
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?;
pub trait ReadSeekFile: Read + Seek {}
impl<F: Read + Seek> ReadSeekFile for F {}
// Read vectored
file.read_vectored(slices.as_mut_slice())
.map_err(AsyncIoError::ReadVectored)?
};
pub fn read_vectored_sync(
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
file: &mut dyn ReadSeekFile,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSliceMut
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSliceMut::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?;
// Read vectored
file.read_vectored(slices.as_mut_slice())
.map_err(AsyncIoError::ReadVectored)?
};
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
pub trait WriteSeekFile: Write + Seek {}
impl<F: Write + Seek> WriteSeekFile for F {}
pub fn write_vectored_sync(
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
file: &mut dyn WriteSeekFile,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSlice
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSlice::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?;
// Write vectored
file.write_vectored(slices.as_slice())
.map_err(AsyncIoError::WriteVectored)?
};
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
pub fn fsync_sync(
user_data: Option<u64>,
file: &mut dyn Write,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
let result: i32 = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Flush
file.flush().map_err(AsyncIoError::Fsync)?;
0
};
if let Some(user_data) = user_data {
completion_list.push((user_data, result));
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
Ok(())
fn write_vectored_sync(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSlice
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSlice::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
let mut file = self.file();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?;
// Write vectored
file.write_vectored(slices.as_slice())
.map_err(AsyncIoError::WriteVectored)?
};
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
fn fsync_sync(
&mut self,
user_data: Option<u64>,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
) -> AsyncIoResult<()> {
let result: i32 = {
let mut file = self.file();
// Flush
file.flush().map_err(AsyncIoError::Fsync)?;
0
};
if let Some(user_data) = user_data {
completion_list.push((user_data, result));
eventfd.write(1).unwrap();
}
Ok(())
}
fn file(&mut self) -> MutexGuard<F>;
}
pub enum ImageType {

View File

@@ -2,59 +2,61 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileResult};
use crate::{disk_size, fsync_sync, read_vectored_sync, write_vectored_sync};
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult};
use crate::AsyncAdaptor;
use qcow::{QcowFile, RawFile, Result as QcowResult};
use std::fs::File;
use std::sync::{Arc, Mutex};
use std::io::{Seek, SeekFrom};
use std::sync::{Arc, Mutex, MutexGuard};
use vmm_sys_util::eventfd::EventFd;
pub struct QcowDiskSync {
qcow_file: QcowFile,
semaphore: Arc<Mutex<()>>,
qcow_file: Arc<Mutex<QcowFile>>,
}
impl QcowDiskSync {
pub fn new(file: File, direct_io: bool) -> QcowResult<Self> {
Ok(QcowDiskSync {
qcow_file: QcowFile::from(RawFile::new(file, direct_io))?,
semaphore: Arc::new(Mutex::new(())),
qcow_file: Arc::new(Mutex::new(QcowFile::from(RawFile::new(file, direct_io))?)),
})
}
}
impl DiskFile for QcowDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
disk_size(&mut self.qcow_file, &mut self.semaphore)
let mut file = self.qcow_file.lock().unwrap();
Ok(file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)? as u64)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(QcowSync::new(
self.qcow_file.clone(),
self.semaphore.clone(),
)) as Box<dyn AsyncIo>)
Ok(Box::new(QcowSync::new(self.qcow_file.clone())) as Box<dyn AsyncIo>)
}
}
pub struct QcowSync {
qcow_file: QcowFile,
qcow_file: Arc<Mutex<QcowFile>>,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
semaphore: Arc<Mutex<()>>,
}
impl QcowSync {
pub fn new(qcow_file: QcowFile, semaphore: Arc<Mutex<()>>) -> Self {
pub fn new(qcow_file: Arc<Mutex<QcowFile>>) -> Self {
QcowSync {
qcow_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)
.expect("Failed creating EventFd for QcowSync"),
completion_list: Vec::new(),
semaphore,
}
}
}
impl AsyncAdaptor<QcowFile> for Arc<Mutex<QcowFile>> {
fn file(&mut self) -> MutexGuard<QcowFile> {
self.lock().unwrap()
}
}
impl AsyncIo for QcowSync {
fn notifier(&self) -> &EventFd {
&self.eventfd
@@ -66,14 +68,12 @@ impl AsyncIo for QcowSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
read_vectored_sync(
self.qcow_file.read_vectored_sync(
offset,
iovecs,
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
@@ -83,25 +83,18 @@ impl AsyncIo for QcowSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
write_vectored_sync(
self.qcow_file.write_vectored_sync(
offset,
iovecs,
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
fsync_sync(
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
self.qcow_file
.fsync_sync(user_data, &self.eventfd, &mut self.completion_list)
}
fn complete(&mut self) -> Vec<(u64, i32)> {

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, DiskTopology,
};
use io_uring::{opcode, squeue, types, IoUring};
use std::fs::File;
@@ -35,6 +35,15 @@ impl DiskFile for RawFileDisk {
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
fn topology(&mut self) -> DiskTopology {
if let Ok(topology) = DiskTopology::probe(&mut self.file) {
topology
} else {
warn!("Unable to get device topology. Using default topology");
DiskTopology::default()
}
}
}
pub struct RawFileAsync {

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, DiskTopology,
};
use std::fs::File;
use std::io::{Seek, SeekFrom};
@@ -31,6 +31,15 @@ impl DiskFile for RawFileDiskSync {
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(RawFileSync::new(self.file.as_raw_fd())) as Box<dyn AsyncIo>)
}
fn topology(&mut self) -> DiskTopology {
if let Ok(topology) = DiskTopology::probe(&mut self.file) {
topology
} else {
warn!("Unable to get device topology. Using default topology");
DiskTopology::default()
}
}
}
pub struct RawFileSync {

View File

@@ -3,26 +3,20 @@
// SPDX-License-Identifier: Apache-2.0
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult};
use crate::{fsync_sync, read_vectored_sync, write_vectored_sync};
use crate::AsyncAdaptor;
use std::fs::File;
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};
use std::sync::{Arc, Mutex, MutexGuard};
use vhdx::vhdx::{Result as VhdxResult, Vhdx};
use vmm_sys_util::eventfd::EventFd;
pub struct VhdxDiskSync {
vhdx_file: Arc<Mutex<Vhdx>>,
semaphore: Arc<Mutex<()>>,
}
impl VhdxDiskSync {
pub fn new(f: File) -> VhdxResult<Self> {
let vhdx = Vhdx::new(f)?;
let vhdx_file = Arc::new(Mutex::new(vhdx));
Ok(VhdxDiskSync {
vhdx_file,
semaphore: Arc::new(Mutex::new(())),
vhdx_file: Arc::new(Mutex::new(Vhdx::new(f)?)),
})
}
}
@@ -33,10 +27,10 @@ impl DiskFile for VhdxDiskSync {
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
VhdxSync::new(self.vhdx_file.clone(), self.semaphore.clone())
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
Ok(
Box::new(VhdxSync::new(self.vhdx_file.clone()).map_err(DiskFileError::NewAsyncIo)?)
as Box<dyn AsyncIo>,
)
}
}
@@ -44,20 +38,24 @@ pub struct VhdxSync {
vhdx_file: Arc<Mutex<Vhdx>>,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
semaphore: Arc<Mutex<()>>,
}
impl VhdxSync {
pub fn new(vhdx_file: Arc<Mutex<Vhdx>>, semaphore: Arc<Mutex<()>>) -> std::io::Result<Self> {
pub fn new(vhdx_file: Arc<Mutex<Vhdx>>) -> std::io::Result<Self> {
Ok(VhdxSync {
vhdx_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)?,
completion_list: Vec::new(),
semaphore,
})
}
}
impl AsyncAdaptor<Vhdx> for Arc<Mutex<Vhdx>> {
fn file(&mut self) -> MutexGuard<Vhdx> {
self.lock().unwrap()
}
}
impl AsyncIo for VhdxSync {
fn notifier(&self) -> &EventFd {
&self.eventfd
@@ -69,14 +67,12 @@ impl AsyncIo for VhdxSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
read_vectored_sync(
self.vhdx_file.read_vectored_sync(
offset,
iovecs,
user_data,
self.vhdx_file.lock().unwrap().deref_mut(),
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
@@ -86,25 +82,18 @@ impl AsyncIo for VhdxSync {
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
write_vectored_sync(
self.vhdx_file.write_vectored_sync(
offset,
iovecs,
user_data,
self.vhdx_file.lock().unwrap().deref_mut(),
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
fsync_sync(
user_data,
self.vhdx_file.lock().unwrap().deref_mut(),
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
self.vhdx_file
.fsync_sync(user_data, &self.eventfd, &mut self.completion_list)
}
fn complete(&mut self) -> Vec<(u64, i32)> {

View File

@@ -6,17 +6,17 @@ edition = "2018"
[dependencies]
acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0.51"
anyhow = "1.0.52"
arch = { path = "../arch" }
bitflags = "1.3.2"
byteorder = "1.4.3"
epoll = "4.3.1"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-device = { path = "../vm-device" }
vm-memory = "0.6.0"
vm-memory = "0.7.0"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = "0.9.0"

View File

@@ -291,14 +291,13 @@ impl Rtc {
impl BusDevice for Rtc {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let v;
let mut read_ok = true;
if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) {
let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) {
let index = ((offset - AMBA_ID_LOW) >> 2) as usize;
v = u32::from(PL031_ID[index]);
u32::from(PL031_ID[index])
} else {
v = match offset {
match offset {
RTCDR => self.get_time(),
RTCMR => {
// Even though we are not implementing RTC alarm we return the last value
@@ -313,8 +312,8 @@ impl BusDevice for Rtc {
read_ok = false;
0
}
};
}
}
};
if read_ok && data.len() <= 4 {
write_le_u32(data, v);
} else {

View File

@@ -294,19 +294,15 @@ impl Pl011 {
impl BusDevice for Pl011 {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let v;
let mut read_ok = true;
if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) {
let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) {
let index = ((offset - 0xfe0) >> 2) as usize;
v = u32::from(PL011_ID[index]);
u32::from(PL011_ID[index])
} else {
v = match offset >> 2 {
match offset >> 2 {
UARTDR => {
let c: u32;
let r: u32;
self.flags &= !PL011_FLAG_RXFF;
c = self.read_fifo.pop_front().unwrap_or_default().into();
let c: u32 = self.read_fifo.pop_front().unwrap_or_default().into();
if self.read_count > 0 {
self.read_count -= 1;
}
@@ -317,8 +313,7 @@ impl BusDevice for Pl011 {
self.int_level &= !PL011_INT_RX;
}
self.rsr = c >> 8;
r = c;
r
c
}
UARTRSR_UARTECR => self.rsr,
UARTFR => self.flags,
@@ -337,7 +332,7 @@ impl BusDevice for Pl011 {
0
}
}
}
};
if read_ok && data.len() <= 4 {
write_le_u32(data, v);

View File

@@ -1,17 +1,28 @@
# How to build and test Cloud Hypervisor on AArch64
This document introduces how to build and test Cloud Hypervisor on AArch64
servers. Currently Cloud Hypervisor cannot be tested on Raspberry PI. Because
on AArch64, Cloud Hypervisor requires GICv3-ITS device for PCIe MSI interrupt
handling. But GICv3-ITS has not been equipped on any Raspberry PI product so
far.
Now Cloud Hypervisor supports 2 ways of booting on AArch64: UEFI booting and
direct-kernel booting. The document covers both of the ways.
This document introduces how to build and test Cloud Hypervisor on AArch64.
Currently, Cloud Hypervisor supports 2 methods of booting on AArch64: UEFI
booting and direct-kernel booting. The document covers both methods.
All the steps are based on Ubuntu. We use the Ubuntu cloud image for guest VM
disk.
## Hardware requirements
- AArch64 servers (recommended) or development boards equipped with the GICv3
interrupt controller.
- On development boards that have constrained RAM resources, if the creation of
a VM consumes a large portion of the free memory on the host, it may be required
to enable swap. For example, this was required on a board with 3 GB of RAM
booting a 2 GB VM at a point in time when 2.8 GB were free. Without enabling
swap the `cloud-hypervisor` process was terminated by the OOM killer. In this
situation memory was allocated for the virtual machine using memfd while the
page cache was filled, leading to a situation where the kernel could not even
drop caches. Making a small section of swap available (observably, 1 to 15 MB),
this situation can be resolved and the resulting memory footprint of
`cloud-hypervisor` is as expected.
## Getting started
We create a folder to build and run Cloud Hypervisor at `$HOME/cloud-hypervisor`

View File

@@ -89,7 +89,9 @@ feature is enabled by default.
## Virtio devices
For all virtio devices listed below, only `virtio-pci` transport layer is
supported.
supported. Cloud Hypervisor supports multiple PCI segments, and users can
append `,pci_segment=<PCI_segment_number>` to the device flag in the Cloud
Hypervisor command line to assign devices to a specific PCI segment.
### virtio-block

View File

@@ -1,6 +1,6 @@
# Cloud Hypervisor Hot Plug
Currently Cloud Hypervisor only supports hot plugging of CPU devices.
Currently Cloud Hypervisor supports hot plugging of CPUs devices (x86 only), PCI devices and memory resizing.
## Kernel support

View File

@@ -8,13 +8,13 @@ support in Cloud Hypervisor:
1. nested-vm migration - migrating between two nested VMs whose host VMs
are running on the same machine.
## Local Migration
## Local Migration (Suitable for Live Upgrade of VMM)
Launch the source VM (on the host machine):
```bash
$ target/release/cloud-hypervisor
--kernel ~/workloads/vmlinux \
--disk path=~/workloads/focal.raw \
--cpus boot=1 --memory size=1G \
--cpus boot=1 --memory size=1G,shared=on \
--cmdline "root=/dev/vda1 console=ttyS0" \
--serial tty --console off --api-socket=/tmp/api1
```
@@ -31,7 +31,7 @@ $ target/release/ch-remote --api-socket=/tmp/api2 receive-migration unix:/tmp/so
Start to send migration for the source VM (on the host machine):
```bash
$ target/release/ch-remote --api-socket=/tmp/api1 send-migration unix:/tmp/sock
$ target/release/ch-remote --api-socket=/tmp/api1 send-migration --local unix:/tmp/sock
```
When the above commands completed, the source VM should be successfully

View File

@@ -17,7 +17,7 @@ cd edk2
. edksetup.sh
git submodule update --init
echo "ACTIVE_PLATFORM=OvmfPkg/OvmfCh.dsc" >> Conf/target.txt
echo "ACTIVE_PLATFORM=OvmfPkg/CloudHv/CloudHvX64.dsc" >> Conf/target.txt
echo "TARGET_ARCH=X64" >> Conf/target.txt
echo "TOOL_CHAIN_TAG=GCC5" >> Conf/target.txt
@@ -25,49 +25,16 @@ make -C ./BaseTools
build
```
After the successful build, the resulting firmware binaries are available under `Build/OvmfCh/DEBUG_GCC5/FV` underneath the edk2 checkout.
After the successful build, the resulting firmware binaries are available under `Build/CloudHvX64/DEBUG_GCC5/FV` underneath the edk2 checkout.
## Using OVMF Binaries
Any UEFI capable image can be booted using the Cloud Hypervisor specific firmware. Windows guests under Cloud Hypervisor only support UEFI boot, therefore OVMF is mandatory there.
To make Cloud Hypervisor use UEFI boot, pass the `OVMF.fd` file path as an argument to the `--kernel` option. The firmware file will be opened in read only mode.
To make Cloud Hypervisor use UEFI boot, pass the `CLOUDHV.fd` file path as an argument to the `--kernel` option. The firmware file will be opened in read only mode.
The same firmware can be used with Cloud Hypervisor or with QEMU. This is particularly useful if using QEMU for the preparation phase.
## Building UEFI Firmware with Compatibility Support Module (CSM)
CSM is a module that allows to boot legacy operating systems using the OVMF firmware. OVMF can embed a CSM build of SeaBIOS. To build the SeaBIOS with CSM support, add `CONFIG_CSM=y` to `.config` before the build. The outcome `out/Csm16.bin` is to be moved into `OvmfPkg/Csm/Csm16/Csm16.bin` before OVMF is built. Then, the OVMF build will have to be passed the `-D CSM_ENABLE` option in order to generate a legacy aware UEFI firmware. At the current stage, all the necessary patches are included in the Cloud Hypervisor specific [SeaBIOS branch](https://github.com/cloud-hypervisor/seabios/tree/ch). Taking into account the previous instructions, the modified command sequence to compile an OVMF binary with CSM support is the following one:
```shell
sudo apt-get update
sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git libncurses-dev
git clone https://github.com/cloud-hypervisor/seabios -b ch
cd seabios
make menuconfig
# Enable `CONFIG_CSM` and `CONFIG_QEMU_HARDWARE`
# Please make sure `python` is in your path
make CONFIG_CSM=y CONFIG_QEMU_HARDWARE=y
cd ..
git clone https://github.com/cloud-hypervisor/edk2 -b ch
cd edk2
. edksetup.sh
git submodule update --init --recursive
cp ../seabios/out/Csm16.bin OvmfPkg/Csm/Csm16/
echo "ACTIVE_PLATFORM=OvmfPkg/OvmfCh.dsc" >> Conf/target.txt
echo "TARGET_ARCH=X64" >> Conf/target.txt
echo "TOOL_CHAIN_TAG=GCC5" >> Conf/target.txt
make -C ./BaseTools
build -DCSM_ENABLE
```
Please note, that the CSM support has currently only been tested with Linux guests. There are no plans to provide legacy support for other OSes (e.g. Windows).
# Links
- [OVMF wiki](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)

View File

@@ -67,7 +67,7 @@ The basic command to boot a Windows image. The configuration section should be c
```shell
cloud-hypervisor \
--kernel ./$OVMF_DIR/OVMF.fd \
--kernel ./$OVMF_DIR/CLOUDHV.fd \
--disk path=./$IMG_FILE \
--cpus boot=1,kvm_hyperv=on \
--memory size=4G \

View File

@@ -5,7 +5,7 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[dependencies]
libc = "0.2.108"
serde = { version = "1.0.130", features = ["rc"] }
serde_derive = "1.0.130"
serde_json = "1.0.72"
libc = "0.2.112"
serde = { version = "1.0.133", features = ["rc"] }
serde_derive = "1.0.133"
serde_json = "1.0.75"

202
fuzz/Cargo.lock generated
View File

@@ -9,20 +9,11 @@ dependencies = [
"vm-memory",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.51"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
[[package]]
name = "api_client"
@@ -77,6 +68,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bincode"
version = "1.3.3"
@@ -131,23 +128,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim",
"term_size",
"termcolor",
"terminal_size",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "cloud-hypervisor"
version = "19.0.0"
version = "20.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -187,9 +185,9 @@ dependencies = [
[[package]]
name = "crc32c"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210cdf933e6a81212bfabf90cd8762f471b5922e5f6b709547673ad8e04b9448"
checksum = "ee6b9c9389584bcba988bd0836086789b7f87ad91892d6a83d5291dbb24524b5"
dependencies = [
"rustc_version",
]
@@ -248,9 +246,9 @@ checksum = "b643857cf70949306b81d7e92cb9d47add673868edac9863c4a49c42feaf3f1e"
[[package]]
name = "getrandom"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
dependencies = [
"cfg-if",
"libc",
@@ -258,10 +256,16 @@ dependencies = [
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7a30908dbce072eca83216eab939d2290080e00ca71611b96a09e5cdce5f3fa"
dependencies = [
"libc",
]
@@ -295,6 +299,16 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "indexmap"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "io-uring"
version = "0.5.2"
@@ -307,9 +321,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "0.4.8"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "kvm-bindings"
@@ -324,8 +338,7 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97422ba48d7ffb66fd4d18130f72ab66f9bbbf791fb7a87b9291cdcfec437593"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#d22ef1f51852dfb055da38004e1a4fed81246f81"
dependencies = [
"kvm-bindings",
"libc",
@@ -340,9 +353,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.108"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "libfuzzer-sys"
@@ -373,6 +386,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "micro_http"
version = "0.1.0"
@@ -411,14 +430,23 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "option_parser"
version = "0.1.0"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]]
name = "pci"
version = "0.1.0"
@@ -443,9 +471,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.32"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
@@ -463,9 +491,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.10"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [
"proc-macro2",
]
@@ -492,18 +520,18 @@ dependencies = [
[[package]]
name = "rustc_version"
version = "0.2.3"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.6"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "seccompiler"
@@ -516,30 +544,21 @@ dependencies = [
[[package]]
name = "semver"
version = "0.9.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]]
name = "serde"
version = "1.0.130"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
[[package]]
name = "serde_derive"
version = "1.0.130"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
dependencies = [
"proc-macro2",
"quote",
@@ -548,9 +567,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.72"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
dependencies = [
"itoa",
"ryu",
@@ -559,9 +578,9 @@ dependencies = [
[[package]]
name = "signal-hook"
version = "0.3.10"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
dependencies = [
"libc",
"signal-hook-registry",
@@ -584,15 +603,15 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
dependencies = [
"proc-macro2",
"quote",
@@ -600,10 +619,19 @@ dependencies = [
]
[[package]]
name = "term_size"
version = "0.3.2"
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
@@ -611,12 +639,11 @@ dependencies = [
[[package]]
name = "textwrap"
version = "0.11.0"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
dependencies = [
"term_size",
"unicode-width",
"terminal_size",
]
[[package]]
@@ -639,12 +666,6 @@ dependencies = [
"syn",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
@@ -660,12 +681,6 @@ dependencies = [
"getrandom",
]
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "versionize"
version = "0.1.6"
@@ -695,9 +710,9 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a21f546f2bda37f5a8cfb138c87f95b8e34d2d78d6a7a92ba3785f4e08604a7"
checksum = "43449b404c488f70507dca193debd4bea361fe8089869b947adc19720e464bce"
dependencies = [
"vmm-sys-util",
]
@@ -748,9 +763,9 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d23ddeb452fb4f837526c6298cc8a2f4948e5595b0328a3d61b5eebe51874d7"
checksum = "3b56bf8f178fc500fe14505fca8b00dec76fc38f2304f461c8d9d7547982311d"
dependencies = [
"bitflags",
"libc",
@@ -837,9 +852,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#720e48e435b791ec6cb
[[package]]
name = "vm-memory"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8ebcb86ca457f9d6e14cf97009f679952eba42f0113de5db596e514cd0e43b"
checksum = "339d4349c126fdcd87e034631d7274370cf19eb0e87b33166bcd956589fc72c5"
dependencies = [
"arc-swap",
"libc",
@@ -950,6 +965,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"

View File

@@ -10,7 +10,7 @@ cargo-fuzz = true
[dependencies]
block_util = { path = "../block_util" }
libc = "0.2.108"
libc = "0.2.112"
libfuzzer-sys = "0.4.2"
qcow = { path = "../qcow" }
seccompiler = "0.2.0"
@@ -19,13 +19,14 @@ virtio-devices = { path = "../virtio-devices" }
virtio-queue = { path = "../virtio-queue" }
vmm-sys-util = "0.9.0"
vm-virtio = { path = "../vm-virtio" }
vm-memory = "0.6.0"
vm-memory = "0.7.0"
[dependencies.cloud-hypervisor]
path = ".."
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0", features = ["with-serde", "fam-wrappers"] }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
# Prevent this from interfering with workspaces

View File

@@ -79,7 +79,7 @@ fuzz_target!(|bytes| {
let mut q = Queue::<
GuestMemoryAtomic<GuestMemoryMmap>,
QueueState<GuestMemoryAtomic<GuestMemoryMmap>>,
QueueState,
>::new(guest_memory.clone(), QUEUE_SIZE);
q.state.ready = true;
q.state.size = QUEUE_SIZE / 2;

View File

@@ -11,19 +11,19 @@ mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.51"
anyhow = "1.0.52"
epoll = "4.3.1"
thiserror = "1.0.30"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
kvm-ioctls = { version = "0.11.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.5.0", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-bindings = {git = "https://github.com/rust-vmm/mshv", branch = "main", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", branch = "main", optional = true}
serde = { version = "1.0.130", features = ["rc"] }
serde_derive = "1.0.130"
serde_json = "1.0.72"
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic"] }
serde = { version = "1.0.133", features = ["rc"] }
serde_derive = "1.0.133"
serde_json = "1.0.75"
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.9.0", features = ["with-serde"] }
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]

View File

@@ -443,4 +443,9 @@ pub trait Vcpu: Send + Sync {
/// Return suspend registers(explicit and intercept suspend registers)
///
fn get_suspend_regs(&self) -> Result<SuspendRegisters>;
#[cfg(feature = "kvm")]
///
/// Set the "immediate_exit" state
///
fn set_immediate_exit(&self, exit: bool);
}

View File

@@ -32,8 +32,6 @@ use std::result;
#[cfg(target_arch = "x86_64")]
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock};
#[cfg(target_arch = "x86_64")]
use vm_memory::Address;
use vmm_sys_util::eventfd::EventFd;
// x86_64 dependencies
#[cfg(target_arch = "x86_64")]
@@ -47,9 +45,7 @@ use kvm_bindings::{
kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP,
};
#[cfg(target_arch = "x86_64")]
use x86_64::{
check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters, KVM_TSS_ADDRESS,
};
use x86_64::{check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters};
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
CpuId, CpuIdEntry, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState as CpuState,
@@ -139,6 +135,15 @@ pub struct KvmVm {
/// vm.set/get().unwrap()
///
impl vm::Vm for KvmVm {
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the one-page region in the VM's address space.
///
fn set_identity_map_address(&self, address: u64) -> vm::Result<()> {
self.fd
.set_identity_map_address(address)
.map_err(|e| vm::HypervisorVmError::SetIdentityMapAddress(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the three-page region in the VM's address space.
@@ -353,10 +358,6 @@ impl vm::Vm for KvmVm {
}
#[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> vm::Result<()> {
// Set TSS
self.fd
.set_tss_address(KVM_TSS_ADDRESS.raw_value() as usize)
.map_err(|e| vm::HypervisorVmError::EnableSplitIrq(e.into()))?;
// Create split irqchip
// Only the local APIC is emulated in kernel, both PICs and IOAPIC
// are not.
@@ -1050,9 +1051,16 @@ impl cpu::Vcpu for KvmVcpu {
/// potential soft lockups when being resumed.
///
fn notify_guest_clock_paused(&self) -> cpu::Result<()> {
self.fd
.kvmclock_ctrl()
.map_err(|e| cpu::HypervisorCpuError::NotifyGuestClockPaused(e.into()))
if let Err(e) = self.fd.kvmclock_ctrl() {
// Linux kernel returns -EINVAL if the PV clock isn't yet initialised
// which could be because we're still in firmware or the guest doesn't
// use KVM clock.
if e.errno() != libc::EINVAL {
return Err(cpu::HypervisorCpuError::NotifyGuestClockPaused(e.into()));
}
}
Ok(())
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
@@ -1566,6 +1574,13 @@ impl cpu::Vcpu for KvmVcpu {
tdx_command(&self.fd.as_raw_fd(), TdxCommand::InitVcpu, 0, hob_address)
.map_err(cpu::HypervisorCpuError::InitializeTdx)
}
///
/// Set the "immediate_exit" state
///
fn set_immediate_exit(&self, exit: bool) {
self.fd.set_kvm_immediate_exit(exit.into());
}
}
/// Device struct for KVM

View File

@@ -11,7 +11,6 @@
use crate::arch::x86::{msr_index, SegmentRegisterOps, MTRR_ENABLE, MTRR_MEM_TYPE_WB};
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
use serde_derive::{Deserialize, Serialize};
use vm_memory::GuestAddress;
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
@@ -92,8 +91,6 @@ impl SegmentRegisterOps for SegmentRegister {
}
}
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffb_d000);
pub fn boot_msr_entries() -> MsrEntries {
MsrEntries::from_entries(&[
msr!(msr_index::MSR_IA32_SYSENTER_CS),
@@ -127,6 +124,15 @@ pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> {
if !kvm.check_extension(Cap::SplitIrqchip) {
return Err(KvmError::CapabilityMissing(Cap::SplitIrqchip));
}
if !kvm.check_extension(Cap::SetIdentityMapAddr) {
return Err(KvmError::CapabilityMissing(Cap::SetIdentityMapAddr));
}
if !kvm.check_extension(Cap::SetTssAddr) {
return Err(KvmError::CapabilityMissing(Cap::SetTssAddr));
}
if !kvm.check_extension(Cap::ImmediateExit) {
return Err(KvmError::CapabilityMissing(Cap::ImmediateExit));
}
Ok(())
}
#[derive(Clone, Serialize, Deserialize)]

View File

@@ -345,11 +345,11 @@ impl cpu::Vcpu for MshvVcpu {
// SAFETY: access_info is valid, otherwise we won't be here
assert!(
!(unsafe { access_info.__bindgen_anon_1.string_op() } == 1),
(unsafe { access_info.__bindgen_anon_1.string_op() } != 1),
"String IN/OUT not supported"
);
assert!(
!(unsafe { access_info.__bindgen_anon_1.rep_prefix() } == 1),
(unsafe { access_info.__bindgen_anon_1.rep_prefix() } != 1),
"Rep IN/OUT not supported"
);
@@ -764,6 +764,13 @@ fn hv_state_init() -> Arc<RwLock<HvState>> {
/// vm.set/get().unwrap()
///
impl vm::Vm for MshvVm {
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the one-page region in the VM's address space.
///
fn set_identity_map_address(&self, _address: u64) -> vm::Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the three-page region in the VM's address space.

View File

@@ -58,6 +58,11 @@ pub enum HypervisorVmError {
#[error("Failed to create Vcpu: {0}")]
CreateVcpu(#[source] anyhow::Error),
///
/// Identity map address error
///
#[error("Failed to set identity map address: {0}")]
SetIdentityMapAddress(#[source] anyhow::Error),
///
/// TSS address error
///
#[error("Failed to set TSS address: {0}")]
@@ -217,6 +222,9 @@ pub type Result<T> = std::result::Result<T, HypervisorVmError>;
/// This crate provides a hypervisor-agnostic interfaces for Vm
///
pub trait Vm: Send + Sync {
#[cfg(target_arch = "x86_64")]
/// Sets the address of the one-page region in the VM's address space.
fn set_identity_map_address(&self, address: u64) -> Result<()>;
#[cfg(target_arch = "x86_64")]
/// Sets the address of the three-page region in the VM's address space.
fn set_tss_address(&self, offset: usize) -> Result<()>;

View File

@@ -7,20 +7,20 @@ edition = "2018"
[dependencies]
epoll = "4.3.1"
getrandom = "0.2"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.130"
serde = "1.0.133"
versionize = "0.1.6"
versionize_derive = "0.1.4"
virtio-bindings = "0.1.0"
virtio-queue = { path = "../virtio-queue" }
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"
[dev-dependencies]
lazy_static = "1.4.0"
pnet = "0.28.0"
serde_json = "1.0.72"
pnet = "0.29.0"
serde_json = "1.0.75"

View File

@@ -69,6 +69,14 @@ impl TxVirtio {
iov_len: desc.len() as libc::size_t,
};
iovecs.push(iovec);
} else {
error!(
"Invalid descriptor chain: address = 0x{:x} length = {} write_only = {}",
desc.addr().0,
desc.len(),
desc.is_write_only()
);
return Err(NetQueuePairError::DescriptorChainInvalid);
}
next_desc = desc_chain.next();
}
@@ -189,6 +197,14 @@ impl RxVirtio {
iov_len: desc.len() as libc::size_t,
};
iovecs.push(iovec);
} else {
error!(
"Invalid descriptor chain: address = 0x{:x} length = {} write_only = {}",
desc.addr().0,
desc.len(),
desc.is_write_only()
);
return Err(NetQueuePairError::DescriptorChainInvalid);
}
next_desc = desc_chain.next();
}
@@ -282,6 +298,8 @@ pub enum NetQueuePairError {
QueueIteratorFailed(virtio_queue::Error),
/// Descriptor chain is too short
DescriptorChainTooShort,
/// Descriptor chain does not contain valid descriptors
DescriptorChainInvalid,
/// Failed to determine if queue needed notification
QueueNeedsNotification(virtio_queue::Error),
/// Failed to enable notification on the queue

View File

@@ -204,7 +204,6 @@ impl Tap {
ifreq.ifr_ifru.ifru_addr = addr;
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFADDR as c_ulong, &ifreq) };
if ret < 0 {
@@ -230,7 +229,6 @@ impl Tap {
let mut ifreq = self.get_ifreq();
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFHWADDR as c_ulong, &ifreq) };
if ret < 0 {
@@ -245,7 +243,6 @@ impl Tap {
}
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFHWADDR as c_ulong, &ifreq) };
if ret < 0 {
@@ -262,7 +259,6 @@ impl Tap {
let ifreq = self.get_ifreq();
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFHWADDR as c_ulong, &ifreq) };
if ret < 0 {
@@ -287,7 +283,6 @@ impl Tap {
ifreq.ifr_ifru.ifru_addr = addr;
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFNETMASK as c_ulong, &ifreq) };
if ret < 0 {
@@ -300,7 +295,6 @@ impl Tap {
/// Set the offload flags for the tap interface.
pub fn set_offload(&self, flags: c_uint) -> Result<()> {
// ioctl is safe. Called with a valid tap fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_val(&self.tap_file, net_gen::TUNSETOFFLOAD(), flags as c_ulong) };
if ret < 0 {
@@ -316,7 +310,6 @@ impl Tap {
let mut ifreq = self.get_ifreq();
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCGIFFLAGS as c_ulong, &ifreq) };
if ret < 0 {
@@ -336,7 +329,6 @@ impl Tap {
(net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16;
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFFLAGS as c_ulong, &ifreq) };
if ret < 0 {

View File

@@ -10,22 +10,22 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.51"
anyhow = "1.0.52"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio-ioctls", branch = "main", default-features = false }
vfio_user = { path = "../vfio_user" }
vmm-sys-util = "0.9.0"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
thiserror = "1.0.30"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = "0.6.0"
vm-memory = "0.7.0"
vm-migration = { path = "../vm-migration" }
[dependencies.vfio-bindings]
version = "0.2.0"
version = "0.3.1"
features = ["fam-wrappers"]

View File

@@ -740,6 +740,11 @@ impl PciConfiguration {
.lock()
.unwrap()
.set_msg_ctl(LittleEndian::read_u16(data));
} else if msix_cap_reg_idx == reg_idx && offset == 0 && data.len() == 4 {
msix_config
.lock()
.unwrap()
.set_msg_ctl((LittleEndian::read_u32(data) >> 16) as u16);
}
}
}
@@ -922,16 +927,19 @@ impl PciBarConfiguration {
}
}
#[must_use]
pub fn set_register_index(mut self, reg_idx: usize) -> Self {
self.reg_idx = reg_idx;
self
}
#[must_use]
pub fn set_address(mut self, addr: u64) -> Self {
self.addr = addr;
self
}
#[must_use]
pub fn set_size(mut self, size: u64) -> Self {
self.size = size;
self
@@ -941,6 +949,7 @@ impl PciBarConfiguration {
self.size
}
#[must_use]
pub fn set_region_type(mut self, region_type: PciBarRegionType) -> Self {
self.region_type = region_type;
self

View File

@@ -5,7 +5,7 @@
use crate::configuration::{self, PciBarRegionType};
use std::any::Any;
use std::fmt::{self, Display};
use std::sync::{Arc, Barrier};
use std::sync::{Arc, Barrier, Mutex};
use std::{self, io, result};
use vm_allocator::{AddressAllocator, SystemAllocator};
use vm_device::BusDevice;
@@ -51,7 +51,7 @@ pub trait PciDevice: BusDevice {
/// returns an address. Returns a Vec of (GuestAddress, GuestUsize) tuples.
fn allocate_bars(
&mut self,
_allocator: &mut SystemAllocator,
_allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
Ok(Vec::new())

View File

@@ -5,7 +5,7 @@
use crate::{
msi_num_enabled_vectors, BarReprogrammingParams, MsiConfig, MsixCap, MsixConfig,
PciBarConfiguration, PciBarRegionType, PciCapabilityId, PciClassCode, PciConfiguration,
PciBarConfiguration, PciBarRegionType, PciBdf, PciCapabilityId, PciClassCode, PciConfiguration,
PciDevice, PciDeviceError, PciHeaderType, PciSubclass, MSIX_TABLE_ENTRY_SIZE,
};
use byteorder::{ByteOrder, LittleEndian};
@@ -15,7 +15,7 @@ use std::collections::BTreeMap;
use std::io;
use std::os::unix::io::AsRawFd;
use std::ptr::null_mut;
use std::sync::{Arc, Barrier};
use std::sync::{Arc, Barrier, Mutex};
use thiserror::Error;
use vfio_bindings::bindings::vfio::*;
use vfio_ioctls::{VfioContainer, VfioDevice, VfioIrq, VfioRegionInfoCap};
@@ -360,7 +360,7 @@ pub(crate) struct VfioCommon {
impl VfioCommon {
pub(crate) fn allocate_bars(
&mut self,
allocator: &mut SystemAllocator,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
vfio_wrapper: &dyn Vfio,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> {
@@ -411,25 +411,27 @@ impl VfioCommon {
let mut lower = vfio_wrapper.read_config_dword(bar_offset);
if io_bar {
// Mask flag bits (lowest 2 for I/O bars)
lower &= !0b11;
// BAR is not enabled
if lower == 0 {
bar_id += 1;
continue;
}
#[cfg(target_arch = "x86_64")]
{
// IO BAR
region_type = PciBarRegionType::IoRegion;
// Mask flag bits (lowest 2 for I/O bars)
lower &= !0b11;
// BAR is not enabled
if lower == 0 {
bar_id += 1;
continue;
}
// Invert bits and add 1 to calculate size
region_size = (!lower + 1) as u64;
// The address needs to be 4 bytes aligned.
bar_addr = allocator
.lock()
.unwrap()
.allocate_io_addresses(None, region_size, Some(0x4))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
}
@@ -476,6 +478,8 @@ impl VfioCommon {
// BAR allocation must be naturally aligned
bar_addr = allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(None, region_size, Some(region_size))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
}
@@ -553,6 +557,7 @@ impl VfioCommon {
cap: u8,
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vfio_wrapper: &dyn Vfio,
bdf: PciBdf,
) {
let msg_ctl = vfio_wrapper.read_config_word((cap + 2).into());
@@ -573,7 +578,11 @@ impl VfioCommon {
})
.unwrap();
let msix_config = MsixConfig::new(msix_cap.table_size(), interrupt_source_group.clone(), 0);
let msix_config = MsixConfig::new(
msix_cap.table_size(),
interrupt_source_group.clone(),
bdf.into(),
);
self.interrupt.msix = Some(VfioMsix {
bar: msix_config,
@@ -611,6 +620,7 @@ impl VfioCommon {
&mut self,
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vfio_wrapper: &dyn Vfio,
bdf: PciBdf,
) {
let mut cap_next = vfio_wrapper.read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET);
@@ -632,7 +642,12 @@ impl VfioCommon {
if irq_info.count > 0 {
// Parse capability only if the VFIO device
// supports MSI-X.
self.parse_msix_capabilities(cap_next, interrupt_manager, vfio_wrapper);
self.parse_msix_capabilities(
cap_next,
interrupt_manager,
vfio_wrapper,
bdf,
);
}
}
}
@@ -964,6 +979,7 @@ impl VfioPciDevice {
msi_interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>,
iommu_attached: bool,
bdf: PciBdf,
) -> Result<Self, VfioPciError> {
let device = Arc::new(device);
device.reset();
@@ -993,7 +1009,7 @@ impl VfioPciDevice {
},
};
common.parse_capabilities(msi_interrupt_manager, &vfio_wrapper);
common.parse_capabilities(msi_interrupt_manager, &vfio_wrapper, bdf);
common.initialize_legacy_interrupt(legacy_interrupt_group, &vfio_wrapper)?;
let vfio_pci_device = VfioPciDevice {
@@ -1308,7 +1324,7 @@ const PCI_ROM_EXP_BAR_INDEX: usize = 12;
impl PciDevice for VfioPciDevice {
fn allocate_bars(
&mut self,
allocator: &mut SystemAllocator,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> {
self.common

View File

@@ -6,7 +6,7 @@
use crate::vfio::{Interrupt, Vfio, VfioCommon, VfioError};
use crate::{BarReprogrammingParams, PciBarRegionType, VfioPciError};
use crate::{
PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciSubclass,
PciBdf, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciSubclass,
};
use hypervisor::HypervisorVmError;
use std::any::Any;
@@ -67,6 +67,7 @@ impl VfioUserPciDevice {
client: Arc<Mutex<Client>>,
msi_interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>,
bdf: PciBdf,
) -> Result<Self, VfioUserPciDeviceError> {
// This is used for the BAR and capabilities only
let configuration = PciConfiguration::new(
@@ -104,7 +105,7 @@ impl VfioUserPciDevice {
},
};
common.parse_capabilities(msi_interrupt_manager, &vfio_wrapper);
common.parse_capabilities(msi_interrupt_manager, &vfio_wrapper, bdf);
common
.initialize_legacy_interrupt(legacy_interrupt_group, &vfio_wrapper)
.map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?;
@@ -326,17 +327,33 @@ impl Vfio for VfioUserClientWrapper {
);
let fds: Vec<i32> = event_fds.iter().map(|e| e.as_raw_fd()).collect();
self.client
.lock()
.unwrap()
.set_irqs(
irq_index,
VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
0,
event_fds.len() as u32,
&fds,
)
.map_err(VfioError::VfioUser)
// Batch into blocks of 16 fds as sendmsg() has a size limit
let mut sent_fds = 0;
let num_fds = event_fds.len() as u32;
while sent_fds < num_fds {
let remaining_fds = num_fds - sent_fds;
let count = if remaining_fds > 16 {
16
} else {
remaining_fds
};
self.client
.lock()
.unwrap()
.set_irqs(
irq_index,
VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
sent_fds,
count,
&fds[sent_fds as usize..(sent_fds + count) as usize],
)
.map_err(VfioError::VfioUser)?;
sent_fds += count;
}
Ok(())
}
fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> {
@@ -373,7 +390,7 @@ impl Vfio for VfioUserClientWrapper {
impl PciDevice for VfioUserPciDevice {
fn allocate_bars(
&mut self,
allocator: &mut SystemAllocator,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> {
self.common

View File

@@ -10,7 +10,7 @@ path = "src/qcow.rs"
[dependencies]
byteorder = "1.4.3"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
remain = "0.2.2"
vmm-sys-util = "0.9.0"

View File

@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2018"
[dependencies]
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
vmm-sys-util = "0.9.0"

View File

@@ -1,11 +1,19 @@
- [v21.1](#v211)
- [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)
- [Contributors](#contributors)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
- [Multiple PCI segments support](#multiple-pci-segments-support)
- [CPU pinning](#cpu-pinning)
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [Notable bug fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [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)
@@ -13,8 +21,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-1)
- [Contributors](#contributors-1)
- [Notable bug fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [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)
@@ -24,23 +32,23 @@
- [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-2)
- [Contributors](#contributors-2)
- [Notable bug fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [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-3)
- [Contributors](#contributors-3)
- [Notable bug fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [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-4)
- [Notable bug fixes](#notable-bug-fixes-5)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-4)
- [Contributors](#contributors-5)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
@@ -48,7 +56,7 @@
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations)
- [Contributors](#contributors-5)
- [Contributors](#contributors-6)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -58,7 +66,7 @@
- [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-6)
- [Contributors](#contributors-7)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -66,13 +74,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-7)
- [Contributors](#contributors-8)
- [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-8)
- [Contributors](#contributors-9)
- [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)
@@ -84,15 +92,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-5)
- [Contributors](#contributors-9)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-10)
- [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-6)
- [Contributors](#contributors-10)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Contributors](#contributors-11)
- [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)
@@ -105,17 +113,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-7)
- [Contributors](#contributors-11)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-12)
- [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-8)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-12)
- [Contributors](#contributors-13)
- [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)
@@ -125,14 +133,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-13)
- [Contributors](#contributors-14)
- [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-14)
- [Contributors](#contributors-15)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -140,7 +148,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-15)
- [Contributors](#contributors-16)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -149,7 +157,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-16)
- [Contributors](#contributors-17)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -176,6 +184,76 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v21.1
This is a bug fix release. The following issues have been addressed:
* Missing `openat()` syscall from seccomp filter (#3609)
* Ensure MMIO/PIO exits complete before pausing (#3658)
* Support DWORD writes to MSI-X control register (#3714)
* VFIO ioctl reordering to fix MSI on AMD platforms (#3827)
* Fix `virtio-net` control queue (#3829)
# v21.0
This release has been tracked through the [v21.0
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/24).
### Efficient Local Live Migration (for Live Upgrade)
In order to support fast live upgrade of the VMM an optimised path has been added in which the memory for the VM is not compared from source to destination. This is activated by passing `--local` to the `ch-remote send-migration` command. This means that the live upgrade can complete in the order of 50ms vs 3s. (#3566)
### Recommended Kernel is Now 5.15
Due to an issue in the `virtio-net` code in 5.14 the recommended Linux kernel is now 5.15. (#3530)
### Notable Bug fixes
* Multiple fixes were made to the OpenAPI YAML file to match the implementaion (#3555,#3562)
* Avoid live migration deadlock when triggered during the kernel boot (#3585)
* Support live migration within firmware (#3586)
* Validate the `virtio-net` desciptor chain (#3548)
* `direct=on` (`O_DIRECT`) can now be used with a guest that makes unaligned accesses (e.g. firmware) (#3587)
### Contributors
Many thanks to everyone who has contributed to our release:
* Anatol Belski <anbelski@linux.microsoft.com>
* Barret Rhoden <brho@google.com>
* Bo Chen <chen.bo@intel.com>
* Fabiano Fidêncio <fabiano.fidencio@intel.com>
* Henry Wang <Henry.Wang@arm.com>
* Liang Zhou <zhoul110@chinatelecom.cn>
* Michael Zhao <michael.zhao@arm.com>
* Muhammad Falak R Wani <falakreyaz@gmail.com>
* Muminul Islam <muislam@microsoft.com>
* Rob Bradford <robert.bradford@intel.com>
* Sebastien Boeuf <sebastien.boeuf@intel.com>
* Wei Liu <liuwe@microsoft.com>
* Ziye Yang <ziye.yang@intel.com>
# v20.2
This is a bug fix release. The following issues have been addressed:
* Don't error out when setting up the SIGWINCH handler (for console resize)
when this fails due to older kernel (#3456)
* Seccomp rules were refined to remove syscalls that are now unused
* Fix reboot on older host kernels when SIGWINCH handler was not initialised
(#3496)
* Fix virtio-vsock blocking issue (#3497)
# v20.1
This is a bug fix release. The following issues have been addressed:
* Networking performance regression with `virtio-net` (#3450)
* Limit file descriptors sent in `vfio-user` support (#3401)
* Fully advertise PCI MMIO config regions in ACPI tables (#3432)
* Set the TSS and KVM identity maps so they don't overlap with firmware RAM
* Correctly update the `DeviceTree` on restore
# v20.0
This release has been tracked through the [v20.0

View File

@@ -1,7 +1,7 @@
FROM ubuntu:20.04 as dev
ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.56.1"
ARG RUST_TOOLCHAIN="1.58.0"
ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"
@@ -115,10 +115,8 @@ RUN git clone --depth 1 https://gitlab.com/virtio-fs/qemu.git -b qemu5.0-virtiof
RUN if [ "$TARGETARCH" = "amd64" ]; then \
git clone https://github.com/spdk/spdk \
&& cd spdk \
&& git checkout a827fd7eeca67209d4c0aaad9a3ed55692e7e36e \
&& git checkout 59f3cdacb13bd2a19c4a86be04792b0ee4491172 \
&& git submodule update --init \
&& sed -i 's/pip3 install meson/pip3 install meson==0.59.2/g' scripts/pkgdep/ubuntu.sh \
&& sed -i 's/meson/meson==0.59.2/g' scripts/pkgdep/requirements.txt \
&& apt-get update \
&& ./scripts/pkgdep.sh \
&& ./configure --with-vfio-user \

View File

@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 5.14.0 Kernel Configuration
# Linux/arm64 5.15.12 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
CONFIG_CC_IS_GCC=y
@@ -25,6 +25,7 @@ CONFIG_THREAD_INFO_IN_TASK=y
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
@@ -133,6 +134,7 @@ CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_LOG_BUF_SHIFT=21
CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
# CONFIG_PRINTK_INDEX is not set
CONFIG_GENERIC_SCHED_CLOCK=y
#
@@ -202,7 +204,6 @@ CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
@@ -265,7 +266,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
@@ -431,8 +431,10 @@ CONFIG_ARM64_CNP=y
#
CONFIG_ARM64_PTR_AUTH=y
CONFIG_ARM64_PTR_AUTH_KERNEL=y
CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y
CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y
CONFIG_AS_HAS_PAC=y
CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y
# end of ARMv8.3 architectural features
#
@@ -446,9 +448,13 @@ CONFIG_ARM64_TLB_RANGE=y
#
# ARMv8.5 architectural features
#
CONFIG_AS_HAS_ARMV8_5=y
CONFIG_ARM64_BTI=y
CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y
CONFIG_ARM64_E0PD=y
CONFIG_ARCH_RANDOM=y
CONFIG_ARM64_AS_HAS_MTE=y
CONFIG_ARM64_MTE=y
# end of ARMv8.5 architectural features
#
@@ -462,6 +468,8 @@ CONFIG_ARM64_SVE=y
CONFIG_RELOCATABLE=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_STACKPROTECTOR_PER_TASK=y
# end of Kernel Features
#
@@ -543,49 +551,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# end of CPU Frequency scaling
# end of CPU Power Management
#
# Firmware Drivers
#
# CONFIG_ARM_SCMI_PROTOCOL is not set
# CONFIG_ARM_SCPI_PROTOCOL is not set
# CONFIG_ARM_SDE_INTERFACE is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
# CONFIG_FW_CFG_SYSFS is not set
# CONFIG_ARM_FFA_TRANSPORT is not set
# CONFIG_GOOGLE_FIRMWARE is not set
#
# EFI (Extensible Firmware Interface) Support
#
CONFIG_EFI_ESRT=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB=y
CONFIG_EFI_ARMSTUB_DTB_LOADER=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
# CONFIG_RESET_ATTACK_MITIGATION is not set
# CONFIG_EFI_DISABLE_PCI_DMA is not set
# end of EFI (Extensible Firmware Interface) Support
CONFIG_EFI_EARLYCON=y
# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
CONFIG_ARM_PSCI_FW=y
# CONFIG_ARM_PSCI_CHECKER is not set
CONFIG_HAVE_ARM_SMCCC=y
CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y
# CONFIG_ARM_SMCCC_SOC_ID is not set
#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers
CONFIG_ARCH_SUPPORTS_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_GENERIC_GSI=y
@@ -640,6 +605,8 @@ CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_HAVE_KVM_IRQ_BYPASS=y
CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y
CONFIG_KVM_XFER_TO_GUEST_WORK=y
# CONFIG_NVHE_EL2_DEBUG is not set
# CONFIG_ARM64_CRYPTO is not set
#
@@ -654,6 +621,7 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
@@ -738,15 +706,14 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLK_SCSI_REQUEST=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_INTEGRITY_T10=y
# CONFIG_BLK_DEV_ZONED is not set
CONFIG_BLK_DEV_THROTTLING=y
# CONFIG_BLK_DEV_THROTTLING_LOW is not set
CONFIG_BLK_CMDLINE_PARSER=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
# CONFIG_BLK_CGROUP_IOLATENCY is not set
@@ -936,11 +903,18 @@ CONFIG_ZONE_DMA32=y
CONFIG_ZONE_DEVICE=y
CONFIG_DEV_PAGEMAP_OPS=y
# CONFIG_DEVICE_PRIVATE is not set
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
CONFIG_PERCPU_STATS=y
# CONFIG_GUP_TEST is not set
# CONFIG_READ_ONLY_THP_FOR_FS is not set
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_SECRETMEM=y
#
# Data Access Monitoring
#
# CONFIG_DAMON is not set
# end of Data Access Monitoring
# end of Memory Management options
CONFIG_NET=y
@@ -953,6 +927,7 @@ CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_SCM=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=y
CONFIG_TLS=y
# CONFIG_TLS_DEVICE is not set
@@ -1056,6 +1031,7 @@ CONFIG_NET_FLOW_LIMIT=y
# CONFIG_AF_RXRPC is not set
# CONFIG_AF_KCM is not set
CONFIG_STREAM_PARSER=y
# CONFIG_MCTP is not set
# CONFIG_WIRELESS is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -1202,13 +1178,64 @@ CONFIG_GENERIC_ARCH_NUMA=y
# Bus devices
#
# CONFIG_BRCMSTB_GISB_ARB is not set
# CONFIG_SIMPLE_PM_BUS is not set
# CONFIG_VEXPRESS_CONFIG is not set
# CONFIG_MHI_BUS is not set
# end of Bus devices
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
#
# Firmware Drivers
#
#
# ARM System Control and Management Interface Protocol
#
# CONFIG_ARM_SCMI_PROTOCOL is not set
# end of ARM System Control and Management Interface Protocol
# CONFIG_ARM_SCPI_PROTOCOL is not set
# CONFIG_ARM_SDE_INTERFACE is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
# CONFIG_FW_CFG_SYSFS is not set
CONFIG_SYSFB=y
# CONFIG_SYSFB_SIMPLEFB is not set
# CONFIG_ARM_FFA_TRANSPORT is not set
# CONFIG_GOOGLE_FIRMWARE is not set
#
# EFI (Extensible Firmware Interface) Support
#
CONFIG_EFI_ESRT=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB=y
CONFIG_EFI_ARMSTUB_DTB_LOADER=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
# CONFIG_RESET_ATTACK_MITIGATION is not set
# CONFIG_EFI_DISABLE_PCI_DMA is not set
# end of EFI (Extensible Firmware Interface) Support
CONFIG_EFI_EARLYCON=y
# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
CONFIG_ARM_PSCI_FW=y
# CONFIG_ARM_PSCI_CHECKER is not set
CONFIG_HAVE_ARM_SMCCC=y
CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y
# CONFIG_ARM_SMCCC_SOC_ID is not set
#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers
# CONFIG_GNSS is not set
# CONFIG_MTD is not set
CONFIG_DTC=y
@@ -1258,7 +1285,9 @@ CONFIG_VIRTIO_BLK=y
#
# NVME Support
#
# CONFIG_BLK_DEV_NVME is not set
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_NVME_MULTIPATH=y
# CONFIG_NVME_FC is not set
# CONFIG_NVME_TCP is not set
# CONFIG_NVME_TARGET is not set
@@ -1315,7 +1344,38 @@ CONFIG_SCSI_MOD=y
CONFIG_HAVE_PATA_PLATFORM=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BCACHE is not set
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
# CONFIG_DM_UNSTRIPED is not set
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_THIN_PROVISIONING is not set
# CONFIG_DM_CACHE is not set
# CONFIG_DM_WRITECACHE is not set
# CONFIG_DM_EBS is not set
# CONFIG_DM_ERA is not set
# CONFIG_DM_CLONE is not set
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_RAID is not set
# CONFIG_DM_ZERO is not set
CONFIG_DM_MULTIPATH=y
# CONFIG_DM_MULTIPATH_QL is not set
# CONFIG_DM_MULTIPATH_ST is not set
# CONFIG_DM_MULTIPATH_HST is not set
# CONFIG_DM_MULTIPATH_IOA is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_DUST is not set
# CONFIG_DM_INIT is not set
# CONFIG_DM_UEVENT is not set
# CONFIG_DM_FLAKEY is not set
# CONFIG_DM_VERITY is not set
# CONFIG_DM_SWITCH is not set
# CONFIG_DM_LOG_WRITES is not set
# CONFIG_DM_INTEGRITY is not set
# CONFIG_TARGET_CORE is not set
# CONFIG_FUSION is not set
@@ -1379,7 +1439,6 @@ CONFIG_VIRTIO_NET=y
# CONFIG_NETDEVSIM is not set
CONFIG_NET_FAILOVER=y
# CONFIG_ISDN is not set
# CONFIG_NVM is not set
#
# Input device support
@@ -1523,15 +1582,15 @@ CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_HW_RANDOM_CAVIUM=y
# CONFIG_HW_RANDOM_CCTRNG is not set
# CONFIG_HW_RANDOM_XIPHERA is not set
CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y
# CONFIG_APPLICOM is not set
CONFIG_DEVMEM=y
CONFIG_DEVPORT=y
# CONFIG_TCG_TPM is not set
# CONFIG_XILLYBUS is not set
# end of Character devices
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices
#
# I2C support
@@ -1561,12 +1620,12 @@ CONFIG_PPS_CLIENT_GPIO=y
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_PTP_1588_CLOCK_KVM=y
# CONFIG_PTP_1588_CLOCK_OCP is not set
# end of PTP clock support
# CONFIG_PINCTRL is not set
@@ -1620,6 +1679,7 @@ CONFIG_GPIO_PL061=y
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_MOCKUP is not set
# CONFIG_GPIO_VIRTIO is not set
# end of Virtual GPIO drivers
# CONFIG_W1 is not set
@@ -1838,7 +1898,6 @@ CONFIG_HID_GENERIC=y
# CONFIG_HID_AUREAL is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_COUGAR is not set
# CONFIG_HID_MACALLY is not set
# CONFIG_HID_CMEDIA is not set
@@ -1879,7 +1938,6 @@ CONFIG_HID_REDRAGON=y
# CONFIG_HID_PLAYSTATION is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SEMITEK is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEAM is not set
@@ -2011,8 +2069,6 @@ CONFIG_DMA_OF=y
# DMABUF options
#
# CONFIG_SYNC_FILE is not set
# CONFIG_DMABUF_MOVE_NOTIFY is not set
# CONFIG_DMABUF_DEBUG is not set
# CONFIG_DMABUF_HEAPS is not set
# end of DMABUF options
@@ -2027,13 +2083,14 @@ CONFIG_UIO_DMEM_GENIRQ=y
# CONFIG_UIO_NETX is not set
# CONFIG_UIO_PRUSS is not set
# CONFIG_UIO_MF624 is not set
CONFIG_VFIO=y
CONFIG_VFIO_IOMMU_TYPE1=y
CONFIG_VFIO_VIRQFD=y
CONFIG_VFIO=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_PCI=y
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_MMAP=y
CONFIG_VFIO_PCI_INTX=y
CONFIG_VFIO_PCI=y
# CONFIG_VFIO_PLATFORM is not set
# CONFIG_VFIO_MDEV is not set
# CONFIG_VIRT_DRIVERS is not set
@@ -2057,6 +2114,7 @@ CONFIG_VHOST_MENU=y
#
# Microsoft Hyper-V guest support
#
# CONFIG_HYPERV is not set
# end of Microsoft Hyper-V guest support
# CONFIG_GREYBUS is not set
@@ -2118,6 +2176,8 @@ CONFIG_IOMMU_SUPPORT=y
# end of Generic IOMMU Pagetable Support
# CONFIG_IOMMU_DEBUGFS is not set
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
@@ -2320,7 +2380,6 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
# CONFIG_EXPORTFS_BLOCK_OPS is not set
CONFIG_FILE_LOCKING=y
CONFIG_MANDATORY_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
# CONFIG_FS_VERITY is not set
@@ -2349,12 +2408,9 @@ CONFIG_NETFS_SUPPORT=y
# CONFIG_NETFS_STATS is not set
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
# CONFIG_FSCACHE_HISTOGRAM is not set
# CONFIG_FSCACHE_DEBUG is not set
# CONFIG_FSCACHE_OBJECT_LIST is not set
CONFIG_CACHEFILES=y
# CONFIG_CACHEFILES_DEBUG is not set
# CONFIG_CACHEFILES_HISTOGRAM is not set
# end of Caches
#
@@ -2375,6 +2431,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
# CONFIG_FAT_DEFAULT_UTF8 is not set
# CONFIG_EXFAT_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS3_FS is not set
# end of DOS/FAT/EXFAT/NT Filesystems
#
@@ -2772,6 +2829,7 @@ CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y
CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
CONFIG_SWIOTLB=y
# CONFIG_DMA_RESTRICTED_POOL is not set
CONFIG_DMA_NONCOHERENT_MMAP=y
CONFIG_DMA_COHERENT_POOL=y
CONFIG_DMA_REMAP=y
@@ -2884,8 +2942,11 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y
CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# CONFIG_KASAN is not set
CONFIG_HAVE_ARCH_KFENCE=y
# CONFIG_KFENCE is not set
# end of Memory Debugging
@@ -2962,12 +3023,12 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=59
# end of RCU Debugging
# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
# CONFIG_LATENCYTOP is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
@@ -2996,7 +3057,6 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y
CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_LKDTM is not set
# CONFIG_TEST_MIN_HEAP is not set
# CONFIG_TEST_SORT is not set
# CONFIG_TEST_DIV64 is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set

View File

@@ -1,19 +1,19 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 5.14.0 Kernel Configuration
# Linux/x86 5.15.12 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0"
CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7)"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=100300
CONFIG_GCC_VERSION=110201
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23500
CONFIG_AS_VERSION=23700
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23500
CONFIG_LD_VERSION=23700
CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_IRQ_WORK=y
@@ -25,6 +25,7 @@ CONFIG_THREAD_INFO_IN_TASK=y
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
@@ -154,6 +155,7 @@ CONFIG_BUILD_BIN2C=y
CONFIG_LOG_BUF_SHIFT=21
CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
# CONFIG_PRINTK_INDEX is not set
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
#
@@ -226,7 +228,6 @@ CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
@@ -299,6 +300,7 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_NR_GPIO=1024
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_AUDIT_ARCH=y
@@ -380,13 +382,13 @@ CONFIG_PERF_EVENTS_INTEL_UNCORE=y
CONFIG_PERF_EVENTS_INTEL_RAPL=y
CONFIG_PERF_EVENTS_INTEL_CSTATE=y
# CONFIG_PERF_EVENTS_AMD_POWER is not set
CONFIG_PERF_EVENTS_AMD_UNCORE=y
# end of Performance monitoring
CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_X86_VSYSCALL_EMULATION=y
# CONFIG_X86_IOPL_IOPERM is not set
# CONFIG_I8K is not set
# CONFIG_MICROCODE is not set
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
@@ -585,7 +587,6 @@ CONFIG_MMCONF_FAM10H=y
# CONFIG_ISA_BUS is not set
# CONFIG_ISA_DMA_API is not set
CONFIG_AMD_NB=y
# CONFIG_X86_SYSFB is not set
# end of Bus options (PCI etc.)
#
@@ -595,44 +596,6 @@ CONFIG_AMD_NB=y
# CONFIG_X86_X32 is not set
# end of Binary Emulations
#
# Firmware Drivers
#
# CONFIG_EDD is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_FW_CFG_SYSFS is not set
# CONFIG_GOOGLE_FIRMWARE is not set
#
# EFI (Extensible Firmware Interface) Support
#
# CONFIG_EFI_VARS is not set
CONFIG_EFI_ESRT=y
CONFIG_EFI_RUNTIME_MAP=y
# CONFIG_EFI_FAKE_MEMMAP is not set
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
# CONFIG_APPLE_PROPERTIES is not set
# CONFIG_RESET_ATTACK_MITIGATION is not set
# CONFIG_EFI_RCI2_TABLE is not set
# CONFIG_EFI_DISABLE_PCI_DMA is not set
# end of EFI (Extensible Firmware Interface) Support
CONFIG_EFI_EARLYCON=y
# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers
CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQFD=y
@@ -679,6 +642,7 @@ CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
@@ -753,12 +717,14 @@ CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
CONFIG_ARCH_USE_MEMREMAP_PROT=y
# CONFIG_LOCK_EVENT_COUNTS is not set
CONFIG_ARCH_HAS_MEM_ENCRYPT=y
CONFIG_ARCH_HAS_CC_PLATFORM=y
CONFIG_HAVE_STATIC_CALL=y
CONFIG_HAVE_STATIC_CALL_INLINE=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_HAS_ELFCORE_COMPAT=y
CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
#
# GCOV-based kernel profiling
@@ -775,16 +741,14 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLK_SCSI_REQUEST=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_INTEGRITY_T10=y
# CONFIG_BLK_DEV_ZONED is not set
CONFIG_BLK_DEV_THROTTLING=y
# CONFIG_BLK_DEV_THROTTLING_LOW is not set
CONFIG_BLK_CMDLINE_PARSER=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
# CONFIG_BLK_CGROUP_IOLATENCY is not set
@@ -818,6 +782,7 @@ CONFIG_EFI_PARTITION=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BLOCK_HOLDER_DEPRECATED=y
#
# IO Schedulers
@@ -934,6 +899,12 @@ CONFIG_PERCPU_STATS=y
# CONFIG_READ_ONLY_THP_FOR_FS is not set
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_SECRETMEM=y
#
# Data Access Monitoring
#
# CONFIG_DAMON is not set
# end of Data Access Monitoring
# end of Memory Management options
CONFIG_NET=y
@@ -946,6 +917,7 @@ CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_SCM=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=y
CONFIG_TLS=y
# CONFIG_TLS_DEVICE is not set
@@ -1050,6 +1022,7 @@ CONFIG_NET_FLOW_LIMIT=y
# CONFIG_AF_RXRPC is not set
# CONFIG_AF_KCM is not set
CONFIG_STREAM_PARSER=y
# CONFIG_MCTP is not set
# CONFIG_WIRELESS is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -1186,6 +1159,53 @@ CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
#
# Firmware Drivers
#
#
# ARM System Control and Management Interface Protocol
#
# end of ARM System Control and Management Interface Protocol
# CONFIG_EDD is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_FW_CFG_SYSFS is not set
CONFIG_SYSFB=y
# CONFIG_SYSFB_SIMPLEFB is not set
# CONFIG_GOOGLE_FIRMWARE is not set
#
# EFI (Extensible Firmware Interface) Support
#
# CONFIG_EFI_VARS is not set
CONFIG_EFI_ESRT=y
CONFIG_EFI_RUNTIME_MAP=y
# CONFIG_EFI_FAKE_MEMMAP is not set
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
# CONFIG_APPLE_PROPERTIES is not set
# CONFIG_RESET_ATTACK_MITIGATION is not set
# CONFIG_EFI_RCI2_TABLE is not set
# CONFIG_EFI_DISABLE_PCI_DMA is not set
# end of EFI (Extensible Firmware Interface) Support
CONFIG_EFI_EARLYCON=y
# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers
# CONFIG_GNSS is not set
# CONFIG_MTD is not set
# CONFIG_OF is not set
@@ -1385,7 +1405,6 @@ CONFIG_VIRTIO_NET=y
# CONFIG_NETDEVSIM is not set
CONFIG_NET_FAILOVER=y
# CONFIG_ISDN is not set
# CONFIG_NVM is not set
#
# Input device support
@@ -1534,10 +1553,9 @@ CONFIG_HANGCHECK_TIMER=y
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
# CONFIG_XILLYBUS is not set
# end of Character devices
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices
#
# I2C support
@@ -1567,13 +1585,13 @@ CONFIG_PPS=y
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_PTP_1588_CLOCK_KVM=y
# CONFIG_PTP_1588_CLOCK_VMW is not set
# CONFIG_PTP_1588_CLOCK_OCP is not set
# end of PTP clock support
# CONFIG_PINCTRL is not set
@@ -1629,6 +1647,7 @@ CONFIG_GPIO_PCI_IDIO_16=y
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_MOCKUP is not set
# CONFIG_GPIO_VIRTIO is not set
# end of Virtual GPIO drivers
# CONFIG_W1 is not set
@@ -1665,6 +1684,7 @@ CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_INTEL_PCH_THERMAL is not set
# CONFIG_INTEL_TCC_COOLING is not set
# CONFIG_INTEL_MENLOW is not set
# end of Intel thermal drivers
CONFIG_WATCHDOG=y
@@ -1884,7 +1904,6 @@ CONFIG_HID_GENERIC=y
# CONFIG_HID_AUREAL is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_COUGAR is not set
# CONFIG_HID_MACALLY is not set
# CONFIG_HID_CMEDIA is not set
@@ -1925,7 +1944,6 @@ CONFIG_HID_REDRAGON=y
# CONFIG_HID_PLAYSTATION is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SEMITEK is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEAM is not set
@@ -1982,9 +2000,10 @@ CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMA_ACPI=y
# CONFIG_ALTERA_MSGDMA is not set
# CONFIG_INTEL_IDMA64 is not set
# CONFIG_INTEL_IDXD is not set
# CONFIG_INTEL_IDXD_COMPAT is not set
# CONFIG_INTEL_IOATDMA is not set
# CONFIG_PLX_DMA is not set
# CONFIG_AMD_PTDMA is not set
# CONFIG_QCOM_HIDMA_MGMT is not set
# CONFIG_QCOM_HIDMA is not set
CONFIG_DW_DMAC_CORE=y
@@ -2006,8 +2025,6 @@ CONFIG_HSU_DMA=y
# DMABUF options
#
# CONFIG_SYNC_FILE is not set
# CONFIG_DMABUF_MOVE_NOTIFY is not set
# CONFIG_DMABUF_DEBUG is not set
# CONFIG_DMABUF_HEAPS is not set
# end of DMABUF options
@@ -2023,14 +2040,15 @@ CONFIG_UIO_DMEM_GENIRQ=y
# CONFIG_UIO_PRUSS is not set
# CONFIG_UIO_MF624 is not set
# CONFIG_UIO_HV_GENERIC is not set
CONFIG_VFIO=y
CONFIG_VFIO_IOMMU_TYPE1=y
CONFIG_VFIO_VIRQFD=y
CONFIG_VFIO=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_PCI=y
# CONFIG_VFIO_PCI_VGA is not set
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_MMAP=y
CONFIG_VFIO_PCI_INTX=y
CONFIG_VFIO_PCI=y
# CONFIG_VFIO_PCI_VGA is not set
# CONFIG_VFIO_PCI_IGD is not set
# CONFIG_VFIO_MDEV is not set
CONFIG_IRQ_BYPASS_MANAGER=y
@@ -2102,6 +2120,8 @@ CONFIG_IOMMU_SUPPORT=y
# end of Generic IOMMU Pagetable Support
# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_IOMMU_DMA=y
# CONFIG_AMD_IOMMU is not set
@@ -2272,7 +2292,6 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
# CONFIG_EXPORTFS_BLOCK_OPS is not set
CONFIG_FILE_LOCKING=y
CONFIG_MANDATORY_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
# CONFIG_FS_VERITY is not set
@@ -2301,12 +2320,9 @@ CONFIG_NETFS_SUPPORT=y
# CONFIG_NETFS_STATS is not set
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
# CONFIG_FSCACHE_HISTOGRAM is not set
# CONFIG_FSCACHE_DEBUG is not set
# CONFIG_FSCACHE_OBJECT_LIST is not set
CONFIG_CACHEFILES=y
# CONFIG_CACHEFILES_DEBUG is not set
# CONFIG_CACHEFILES_HISTOGRAM is not set
# end of Caches
#
@@ -2327,6 +2343,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
# CONFIG_FAT_DEFAULT_UTF8 is not set
# CONFIG_EXFAT_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS3_FS is not set
# end of DOS/FAT/EXFAT/NT Filesystems
#
@@ -2442,6 +2459,8 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity"
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
# CONFIG_ZERO_CALL_USED_REGS is not set
# end of Memory initialization
# end of Kernel hardening options
# end of Security options
@@ -2587,6 +2606,8 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set
# CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set
# CONFIG_CRYPTO_SM4 is not set
# CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64 is not set
# CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64 is not set
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_X86_64=y
@@ -2792,6 +2813,8 @@ CONFIG_HAVE_ARCH_KGDB=y
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
# CONFIG_UBSAN is not set
CONFIG_HAVE_ARCH_KCSAN=y
CONFIG_HAVE_KCSAN_COMPILER=y
# CONFIG_KCSAN is not set
# end of Generic Kernel Debugging Instruments
CONFIG_DEBUG_KERNEL=y
@@ -2908,7 +2931,6 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=59
# end of RCU Debugging
# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
# CONFIG_LATENCYTOP is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
@@ -2934,7 +2956,6 @@ CONFIG_STRICT_DEVMEM=y
#
# x86 Debugging
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
@@ -2971,7 +2992,6 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y
CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_LKDTM is not set
# CONFIG_TEST_MIN_HEAP is not set
# CONFIG_TEST_SORT is not set
# CONFIG_TEST_DIV64 is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set

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: 20.0
Version: 21.1
Release: 0%{?dist}
License: ASL 2.0 or BSD-3-clause
Group: Applications/System
@@ -112,6 +112,12 @@ rm -rf %{buildroot}
%changelog
* Thu Mar 10 2022 Rob Bradford <robert.bradford@intel.com> 21.1-0
- Update to 21.1
* Thu Jan 20 2022 Rob Bradford <robert.bradford@intel.com> 21.0-0
- Update to 21.0
* Thu Dec 02 2021 Sebastien Boeuf <sebastien.boeuf@intel.com> 20.0-0
- Update to 20.0

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -x
rm /tmp/ubuntu-cloudinit.img
rm -f /tmp/ubuntu-cloudinit.img
mkdosfs -n cidata -C /tmp/ubuntu-cloudinit.img 8192
mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/user-data ::
mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/meta-data ::

View File

@@ -54,7 +54,7 @@ checkout_repo() {
build_custom_linux() {
SRCDIR=$PWD
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
LINUX_CUSTOM_BRANCH="ch-5.14"
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"
@@ -102,6 +102,25 @@ build_edk2() {
popd
}
build_spdk_nvme() {
SPDK_DIR="$WORKLOADS_DIR/spdk"
SPDK_REPO="https://github.com/spdk/spdk.git"
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "f9c496b8e21a8f499df268818bf8b5d8e2b19f04"
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
}
update_workloads() {
cp scripts/sha1sums-aarch64 $WORKLOADS_DIR
@@ -233,6 +252,9 @@ update_workloads() {
echo "bar" > "$SHARED_DIR/file3" || exit 1
fi
# checkout and build SPDK NVMe
build_spdk_nvme
# Check and build EDK2 binary
build_edk2
}
@@ -245,8 +267,8 @@ if [[ "$hypervisor" = "mshv" ]]; then
exit 1
fi
features_build=""
features_test="--features integration_tests"
# For now these values are deafult for kvm
features=""
# lock the workloads folder to avoid parallel updating by different containers
(
@@ -273,7 +295,7 @@ fi
export RUST_BACKTRACE=1
# Test without ACPI
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
strip target/$BUILD_TARGET/release/vhost_user_net
strip target/$BUILD_TARGET/release/ch-remote
@@ -284,17 +306,18 @@ 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"
# Setup huge-pages for ovs-dpdk
echo 2048 | sudo tee /proc/sys/vm/nr_hugepages
# Both test_vfio and ovs-dpdk rely on hugepages
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Run all direct kernel boot (Device Tree) test cases in mod `parallel`
time cargo test $features_test "tests::parallel::$test_filter"
time cargo test $features "parallel::$test_filter"
RES=$?
# Run some tests in sequence since the result could be affected by other tests
# running in parallel.
if [ $RES -eq 0 ]; then
time cargo test $features_test "tests::sequential::$test_filter" -- --test-threads=1
time cargo test $features "sequential::$test_filter" -- --test-threads=1
RES=$?
else
exit $RES
@@ -302,7 +325,7 @@ fi
# Run all ACPI test cases
if [ $RES -eq 0 ]; then
time cargo test $features_test "tests::aarch64_acpi::$test_filter"
time cargo test $features "aarch64_acpi::$test_filter"
RES=$?
else
exit $RES
@@ -310,7 +333,7 @@ fi
# Run all test cases related to live migration
if [ $RES -eq 0 ]; then
time cargo test $features_test "tests::live_migration::$test_filter" -- --test-threads=1
time cargo test $features "live_migration::$test_filter" -- --test-threads=1
RES=$?
else
exit $RES

View File

@@ -11,13 +11,11 @@ mkdir -p "$WORKLOADS_DIR"
process_common_args "$@"
# For now these values are deafult for kvm
features_build=""
features_test="--features integration_tests"
# For now these values are default for kvm
features=""
if [ "$hypervisor" = "mshv" ] ; then
features_build="--no-default-features --features mshv,common"
features_test="--no-default-features --features mshv,common,integration_tests"
features="--no-default-features --features mshv,common"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
@@ -55,7 +53,7 @@ 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.14" $LINUX_CUSTOM_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
@@ -79,7 +77,7 @@ if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
strip target/$BUILD_TARGET/release/vhost_user_net
strip target/$BUILD_TARGET/release/ch-remote
@@ -89,7 +87,7 @@ echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1
time cargo test $features_test "tests::live_migration::$test_filter" -- --test-threads=1
time cargo test $features "live_migration::$test_filter" -- --test-threads=1
RES=$?
exit $RES

View File

@@ -11,9 +11,8 @@ if [[ "$hypervisor" = "mshv" ]]; then
exit 1
fi
# For now these values are deafult for kvm
features_build=""
features_test="--features integration_tests"
# For now these values are default for kvm
features=""
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
@@ -23,12 +22,12 @@ TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
export RUST_BACKTRACE=1
time cargo test $features_test "tests::sgx::$test_filter"
time cargo test $features "sgx::$test_filter"
RES=$?
exit $RES

View File

@@ -5,9 +5,8 @@ source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
process_common_args "$@"
# For now these values are deafult for kvm
features_build=""
features_test="--features integration_tests"
# For now these values are default for kvm
features=""
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
@@ -17,12 +16,12 @@ TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
export RUST_BACKTRACE=1
time cargo test $features_test "tests::vfio::$test_filter" -- --test-threads=1
time cargo test $features "vfio::$test_filter" -- --test-threads=1
RES=$?
exit $RES

View File

@@ -5,16 +5,23 @@ source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
process_common_args "$@"
# For now these values are deafult for kvm
features_build=""
features_test="--features integration_tests"
# For now these values are default for kvm
features=""
if [ "$hypervisor" = "mshv" ] ; then
features_build="--no-default-features --features mshv,common"
features_test="--no-default-features --features mshv,common,integration_tests"
features="--no-default-features --features mshv,common"
fi
WIN_IMAGE_FILE="/root/workloads/windows-server-2019.raw"
OVMF_FW_FILE="/root/workloads/OVMF-4b47d0c6c8.fd"
WORKLOADS_DIR="/root/workloads"
OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
if [ ! -f "$OVMF_FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $OVMF_FW_URL || exit 1
popd
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""
TARGET_CC=""
@@ -24,7 +31,7 @@ CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
# Check if the images are present
if [[ ! -f ${WIN_IMAGE_FILE} || ! -f ${OVMF_FW_FILE} ]]; then
if [[ ! -f ${WIN_IMAGE_FILE} || ! -f ${OVMF_FW} ]]; then
echo "Windows image/firmware not present in the host"
exit 1
fi
@@ -37,14 +44,14 @@ dmsetup mknodes
dmsetup create windows-snapshot-base --table "0 $img_blk_size snapshot-origin /dev/mapper/windows-base"
dmsetup mknodes
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
export RUST_BACKTRACE=1
# Only run with 1 thread to avoid tests interfering with one another because
# Windows has a static IP configured
time cargo test $features_test "tests::windows::$test_filter"
time cargo test $features "windows::$test_filter"
RES=$?
dmsetup remove_all -f

View File

@@ -11,13 +11,11 @@ mkdir -p "$WORKLOADS_DIR"
process_common_args "$@"
# For now these values are deafult for kvm
features_build=""
features_test="--features integration_tests"
# For now these values are default for kvm
features=""
if [ "$hypervisor" = "mshv" ] ; then
features_build="--no-default-features --features mshv,common"
features_test="--no-default-features --features mshv,common,integration_tests"
features="--no-default-features --features mshv,common"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
@@ -30,6 +28,14 @@ if [ ! -f "$FW" ]; then
popd
fi
OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
if [ ! -f "$OVMF_FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $OVMF_FW_URL || exit 1
popd
fi
BIONIC_OS_IMAGE_NAME="bionic-server-cloudimg-amd64.qcow2"
BIONIC_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$BIONIC_OS_IMAGE_NAME"
BIONIC_OS_IMAGE="$WORKLOADS_DIR/$BIONIC_OS_IMAGE_NAME"
@@ -107,7 +113,7 @@ 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.14" $LINUX_CUSTOM_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
@@ -175,7 +181,7 @@ TARGET_CC="musl-gcc"
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --all --release $features_build --target $BUILD_TARGET
cargo build --all --release $features --target $BUILD_TARGET
strip target/$BUILD_TARGET/release/cloud-hypervisor
strip target/$BUILD_TARGET/release/vhost_user_net
strip target/$BUILD_TARGET/release/ch-remote
@@ -195,14 +201,14 @@ echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1
time cargo test $features_test "tests::parallel::$test_filter"
time cargo test $features "parallel::$test_filter"
RES=$?
# Run some tests in sequence since the result could be affected by other tests
# running in parallel.
if [ $RES -eq 0 ]; then
export RUST_BACKTRACE=1
time cargo test $features_test "tests::sequential::$test_filter" -- --test-threads=1
time cargo test $features "sequential::$test_filter" -- --test-threads=1
RES=$?
fi

View File

@@ -13,4 +13,4 @@ if [[ $(uname -m) = "aarch64" || $hypervisor = "mshv" ]]; then
cargo_args+=("--features $hypervisor")
fi
export RUST_BACKTRACE=1
cargo test --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1;
cargo test --lib --bins --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1;

View File

@@ -9,7 +9,7 @@ extern crate clap;
use api_client::simple_api_command;
use api_client::simple_api_command_with_fds;
use api_client::Error as ApiClientError;
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use clap::{App, AppSettings, Arg, ArgMatches};
use option_parser::{ByteSized, ByteSizedParseError};
use std::fmt;
use std::os::unix::net::UnixStream;
@@ -263,9 +263,14 @@ fn receive_migration_api_command(socket: &mut UnixStream, url: &str) -> Result<(
.map_err(Error::ApiClient)
}
fn send_migration_api_command(socket: &mut UnixStream, url: &str) -> Result<(), Error> {
fn send_migration_api_command(
socket: &mut UnixStream,
url: &str,
local: bool,
) -> Result<(), Error> {
let send_migration_data = vmm::api::VmSendMigrationData {
destination_url: url.to_owned(),
local,
};
simple_api_command(
socket,
@@ -402,6 +407,10 @@ fn do_command(matches: &ArgMatches) -> Result<(), Error> {
.unwrap()
.value_of("send_migration_config")
.unwrap(),
matches
.subcommand_matches("send-migration")
.unwrap()
.is_present("send_migration_local"),
),
Some("receive-migration") => receive_migration_api_command(
&mut socket,
@@ -422,7 +431,7 @@ fn main() {
.setting(AppSettings::SubcommandRequired)
.about("Remotely control a cloud-hypervisor VMM.")
.arg(
Arg::with_name("api-socket")
Arg::new("api-socket")
.long("api-socket")
.help("HTTP API socket path (UNIX domain socket).")
.takes_value(true)
@@ -430,97 +439,89 @@ fn main() {
.required(true),
)
.subcommand(
SubCommand::with_name("add-device")
.about("Add VFIO device")
.arg(
Arg::with_name("device_config")
.index(1)
.help(vmm::config::DeviceConfig::SYNTAX),
),
App::new("add-device").about("Add VFIO device").arg(
Arg::new("device_config")
.index(1)
.help(vmm::config::DeviceConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-disk")
.about("Add block device")
.arg(
Arg::with_name("disk_config")
.index(1)
.help(vmm::config::DiskConfig::SYNTAX),
),
App::new("add-disk").about("Add block device").arg(
Arg::new("disk_config")
.index(1)
.help(vmm::config::DiskConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-fs")
App::new("add-fs")
.about("Add virtio-fs backed fs device")
.arg(
Arg::with_name("fs_config")
Arg::new("fs_config")
.index(1)
.help(vmm::config::FsConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-pmem")
App::new("add-pmem")
.about("Add persistent memory device")
.arg(
Arg::with_name("pmem_config")
Arg::new("pmem_config")
.index(1)
.help(vmm::config::PmemConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-net")
.about("Add network device")
.arg(
Arg::with_name("net_config")
.index(1)
.help(vmm::config::NetConfig::SYNTAX),
),
App::new("add-net").about("Add network device").arg(
Arg::new("net_config")
.index(1)
.help(vmm::config::NetConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-user-device")
App::new("add-user-device")
.about("Add userspace device")
.arg(
Arg::with_name("device_config")
Arg::new("device_config")
.index(1)
.help(vmm::config::UserDeviceConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("add-vsock")
.about("Add vsock device")
.arg(
Arg::with_name("vsock_config")
.index(1)
.help(vmm::config::VsockConfig::SYNTAX),
),
App::new("add-vsock").about("Add vsock device").arg(
Arg::new("vsock_config")
.index(1)
.help(vmm::config::VsockConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("remove-device")
App::new("remove-device")
.about("Remove VFIO device")
.arg(Arg::with_name("id").index(1).help("<device_id>")),
.arg(Arg::new("id").index(1).help("<device_id>")),
)
.subcommand(SubCommand::with_name("info").about("Info on the VM"))
.subcommand(SubCommand::with_name("counters").about("Counters from the VM"))
.subcommand(SubCommand::with_name("pause").about("Pause the VM"))
.subcommand(SubCommand::with_name("reboot").about("Reboot the VM"))
.subcommand(SubCommand::with_name("power-button").about("Trigger a power button in the VM"))
.subcommand(App::new("info").about("Info on the VM"))
.subcommand(App::new("counters").about("Counters from the VM"))
.subcommand(App::new("pause").about("Pause the VM"))
.subcommand(App::new("reboot").about("Reboot the VM"))
.subcommand(App::new("power-button").about("Trigger a power button in the VM"))
.subcommand(
SubCommand::with_name("resize")
App::new("resize")
.about("Resize the VM")
.arg(
Arg::with_name("cpus")
Arg::new("cpus")
.long("cpus")
.help("New vCPUs count")
.takes_value(true)
.number_of_values(1),
)
.arg(
Arg::with_name("memory")
Arg::new("memory")
.long("memory")
.help("New memory size in bytes (supports K/M/G suffix)")
.takes_value(true)
.number_of_values(1),
)
.arg(
Arg::with_name("balloon")
Arg::new("balloon")
.long("balloon")
.help("New balloon size in bytes (supports K/M/G suffix)")
.takes_value(true)
@@ -528,57 +529,58 @@ fn main() {
),
)
.subcommand(
SubCommand::with_name("resize-zone")
App::new("resize-zone")
.about("Resize a memory zone")
.arg(
Arg::with_name("id")
Arg::new("id")
.long("id")
.help("Memory zone identifier")
.takes_value(true)
.number_of_values(1),
)
.arg(
Arg::with_name("size")
Arg::new("size")
.long("size")
.help("New memory zone size in bytes (supports K/M/G suffix)")
.takes_value(true)
.number_of_values(1),
),
)
.subcommand(SubCommand::with_name("resume").about("Resume the VM"))
.subcommand(SubCommand::with_name("shutdown").about("Shutdown the VM"))
.subcommand(App::new("resume").about("Resume the VM"))
.subcommand(App::new("shutdown").about("Shutdown the VM"))
.subcommand(
SubCommand::with_name("snapshot")
.about("Create a snapshot from VM")
.arg(
Arg::with_name("snapshot_config")
.index(1)
.help("<destination_url>"),
),
App::new("snapshot").about("Create a snapshot from VM").arg(
Arg::new("snapshot_config")
.index(1)
.help("<destination_url>"),
),
)
.subcommand(
SubCommand::with_name("restore")
.about("Restore VM from a snapshot")
.arg(
Arg::with_name("restore_config")
.index(1)
.help(vmm::config::RestoreConfig::SYNTAX),
),
App::new("restore").about("Restore VM from a snapshot").arg(
Arg::new("restore_config")
.index(1)
.help(vmm::config::RestoreConfig::SYNTAX),
),
)
.subcommand(
SubCommand::with_name("send-migration")
App::new("send-migration")
.about("Initiate a VM migration")
.arg(
Arg::with_name("send_migration_config")
Arg::new("send_migration_config")
.index(1)
.help("<destination_url>"),
)
.arg(
Arg::new("send_migration_local")
.long("local")
.takes_value(false),
),
)
.subcommand(
SubCommand::with_name("receive-migration")
App::new("receive-migration")
.about("Receive a VM migration")
.arg(
Arg::with_name("receive_migration_config")
Arg::new("receive_migration_config")
.index(1)
.help("<receiver_url>"),
),

View File

@@ -125,27 +125,22 @@ fn prepare_default_values() -> (String, String, String) {
(default_vcpus, default_memory, default_rng)
}
fn create_app<'a, 'b>(
fn create_app<'a>(
default_vcpus: &'a str,
default_memory: &'a str,
default_rng: &'a str,
) -> App<'a, 'b> {
#[cfg(target_arch = "x86_64")]
let mut app: App;
#[cfg(target_arch = "aarch64")]
let app: App;
app = App::new("cloud-hypervisor")
) -> App<'a> {
let app = App::new("cloud-hypervisor")
// 'BUILT_VERSION' is set by the build script 'build.rs' at
// compile time
.version(env!("BUILT_VERSION"))
.author(crate_authors!())
.about("Launch a cloud-hypervisor VMM.")
.group(ArgGroup::with_name("vm-config").multiple(true))
.group(ArgGroup::with_name("vmm-config").multiple(true))
.group(ArgGroup::with_name("logging").multiple(true))
.group(ArgGroup::new("vm-config").multiple(true))
.group(ArgGroup::new("vmm-config").multiple(true))
.group(ArgGroup::new("logging").multiple(true))
.arg(
Arg::with_name("cpus")
Arg::new("cpus")
.long("cpus")
.help(
"boot=<boot_vcpus>,max=<max_vcpus>,\
@@ -157,7 +152,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("platform")
Arg::new("platform")
.long("platform")
.help(
"num_pci_segments=<num pci segments>",
@@ -166,7 +161,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("memory")
Arg::new("memory")
.long("memory")
.help(
"Memory parameters \
@@ -181,7 +176,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("memory-zone")
Arg::new("memory-zone")
.long("memory-zone")
.help(
"User defined memory zone parameters \
@@ -198,7 +193,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("kernel")
Arg::new("kernel")
.long("kernel")
.help(
"Path to loaded kernel. This may be a kernel or firmware that supports a PVH \
@@ -208,21 +203,21 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("initramfs")
Arg::new("initramfs")
.long("initramfs")
.help("Path to initramfs image")
.takes_value(true)
.group("vm-config"),
)
.arg(
Arg::with_name("cmdline")
Arg::new("cmdline")
.long("cmdline")
.help("Kernel command line")
.takes_value(true)
.group("vm-config"),
)
.arg(
Arg::with_name("disk")
Arg::new("disk")
.long("disk")
.help(config::DiskConfig::SYNTAX)
.takes_value(true)
@@ -230,7 +225,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("net")
Arg::new("net")
.long("net")
.help(config::NetConfig::SYNTAX)
.takes_value(true)
@@ -238,7 +233,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("rng")
Arg::new("rng")
.long("rng")
.help(
"Random number generator parameters \"src=<entropy_source_path>,iommu=on|off\"",
@@ -247,14 +242,14 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("balloon")
Arg::new("balloon")
.long("balloon")
.help(config::BalloonConfig::SYNTAX)
.takes_value(true)
.group("vm-config"),
)
.arg(
Arg::with_name("fs")
Arg::new("fs")
.long("fs")
.help(config::FsConfig::SYNTAX)
.takes_value(true)
@@ -262,7 +257,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("pmem")
Arg::new("pmem")
.long("pmem")
.help(config::PmemConfig::SYNTAX)
.takes_value(true)
@@ -270,14 +265,14 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("serial")
Arg::new("serial")
.long("serial")
.help("Control serial port: off|null|pty|tty|file=/path/to/a/file")
.default_value("null")
.group("vm-config"),
)
.arg(
Arg::with_name("console")
Arg::new("console")
.long("console")
.help(
"Control (virtio) console: \"off|null|pty|tty|file=/path/to/a/file,iommu=on|off\"",
@@ -286,7 +281,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("device")
Arg::new("device")
.long("device")
.help(config::DeviceConfig::SYNTAX)
.takes_value(true)
@@ -294,7 +289,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("user-device")
Arg::new("user-device")
.long("user-device")
.help(config::UserDeviceConfig::SYNTAX)
.takes_value(true)
@@ -302,7 +297,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("vsock")
Arg::new("vsock")
.long("vsock")
.help(config::VsockConfig::SYNTAX)
.takes_value(true)
@@ -310,7 +305,7 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("numa")
Arg::new("numa")
.long("numa")
.help(config::NumaConfig::SYNTAX)
.takes_value(true)
@@ -318,21 +313,21 @@ fn create_app<'a, 'b>(
.group("vm-config"),
)
.arg(
Arg::with_name("watchdog")
Arg::new("watchdog")
.long("watchdog")
.help("Enable virtio-watchdog")
.takes_value(false)
.group("vm-config"),
)
.arg(
Arg::with_name("v")
.short("v")
.multiple(true)
Arg::new("v")
.short('v')
.multiple_occurrences(true)
.help("Sets the level of debugging output")
.group("logging"),
)
.arg(
Arg::with_name("log-file")
Arg::new("log-file")
.long("log-file")
.help("Log file. Standard error is used if not specified")
.takes_value(true)
@@ -340,7 +335,7 @@ fn create_app<'a, 'b>(
.group("logging"),
)
.arg(
Arg::with_name("api-socket")
Arg::new("api-socket")
.long("api-socket")
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
.takes_value(true)
@@ -348,7 +343,7 @@ fn create_app<'a, 'b>(
.group("vmm-config"),
)
.arg(
Arg::with_name("event-monitor")
Arg::new("event-monitor")
.long("event-monitor")
.help("File to report events on: path=</path/to/a/file> or fd=<fd>")
.takes_value(true)
@@ -356,7 +351,7 @@ fn create_app<'a, 'b>(
.group("vmm-config"),
)
.arg(
Arg::with_name("restore")
Arg::new("restore")
.long("restore")
.help(config::RestoreConfig::SYNTAX)
.takes_value(true)
@@ -364,7 +359,7 @@ fn create_app<'a, 'b>(
.group("vmm-config"),
)
.arg(
Arg::with_name("seccomp")
Arg::new("seccomp")
.long("seccomp")
.takes_value(true)
.possible_values(&["true", "false", "log"])
@@ -372,27 +367,23 @@ fn create_app<'a, 'b>(
);
#[cfg(target_arch = "x86_64")]
{
app = app.arg(
Arg::with_name("sgx-epc")
.long("sgx-epc")
.help(config::SgxEpcConfig::SYNTAX)
.takes_value(true)
.min_values(1)
.group("vm-config"),
);
}
let app = app.arg(
Arg::new("sgx-epc")
.long("sgx-epc")
.help(config::SgxEpcConfig::SYNTAX)
.takes_value(true)
.min_values(1)
.group("vm-config"),
);
#[cfg(feature = "tdx")]
{
app = app.arg(
Arg::with_name("tdx")
.long("tdx")
.help("TDX Support: firmware=<tdvf path>")
.takes_value(true)
.group("vm-config"),
);
}
let app = app.arg(
Arg::new("tdx")
.long("tdx")
.help("TDX Support: firmware=<tdvf path>")
.takes_value(true)
.group("vm-config"),
);
app
}
@@ -513,8 +504,8 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
// Before we start any threads, mask the signals we'll be
// installing handlers for, to make sure they only ever run on the
// dedicated signal handling thread we'll start in a bit.
for sig in vmm::vm::HANDLED_SIGNALS {
if let Err(e) = block_signal(sig) {
for sig in &vmm::vm::HANDLED_SIGNALS {
if let Err(e) = block_signal(*sig) {
eprintln!("Error blocking signals: {}", e);
}
}
@@ -534,9 +525,16 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
)
.map_err(Error::StartVmmThread)?;
// Can't test for "vm-config" group as some have default values. The kernel
// Can't test for "vm-config" group as some have default values. The kernel (or tdx if enabled)
// is the only required option for booting the VM.
if cmd_arguments.is_present("kernel") || cmd_arguments.is_present("tdx") {
#[cfg(feature = "tdx")]
let tdx_or_kernel_present =
cmd_arguments.is_present("kernel") || cmd_arguments.is_present("tdx");
#[cfg(not(feature = "tdx"))]
let tdx_or_kernel_present = cmd_arguments.is_present("kernel");
if tdx_or_kernel_present {
let vm_params = config::VmParams::from_arg_matches(&cmd_arguments);
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
@@ -586,10 +584,6 @@ fn main() {
std::process::exit(exit_code);
}
#[cfg(test)]
#[macro_use]
extern crate credibility;
#[cfg(test)]
mod unit_tests {
use crate::config::HotplugMethod;
@@ -618,15 +612,11 @@ mod unit_tests {
let cli_vm_config = get_vm_config_from_vec(cli);
let openapi_vm_config: VmConfig = serde_json::from_str(openapi).unwrap();
test_block!(tb, "", {
if equal {
aver_eq!(tb, cli_vm_config, openapi_vm_config);
} else {
aver_ne!(tb, cli_vm_config, openapi_vm_config);
}
Ok(())
});
if equal {
assert_eq!(cli_vm_config, openapi_vm_config);
} else {
assert_ne!(cli_vm_config, openapi_vm_config);
}
(cli_vm_config, openapi_vm_config)
}
@@ -640,70 +630,67 @@ mod unit_tests {
let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true);
// As a second step, we validate all the default values.
test_block!(tb, "", {
let expected_vm_config = VmConfig {
cpus: CpusConfig {
boot_vcpus: 1,
max_vcpus: 1,
topology: None,
kvm_hyperv: false,
max_phys_bits: 46,
affinity: None,
},
memory: MemoryConfig {
size: 536_870_912,
mergeable: false,
hotplug_method: HotplugMethod::Acpi,
hotplug_size: None,
hotplugged_size: None,
shared: false,
hugepages: false,
hugepage_size: None,
prefault: false,
zones: None,
},
kernel: Some(KernelConfig {
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None,
cmdline: CmdlineConfig {
args: String::from(""),
},
disks: None,
net: None,
rng: RngConfig {
src: PathBuf::from("/dev/urandom"),
iommu: false,
},
balloon: None,
fs: None,
pmem: None,
serial: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Null,
iommu: false,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
},
devices: None,
user_devices: None,
vsock: None,
let expected_vm_config = VmConfig {
cpus: CpusConfig {
boot_vcpus: 1,
max_vcpus: 1,
topology: None,
kvm_hyperv: false,
max_phys_bits: 46,
affinity: None,
},
memory: MemoryConfig {
size: 536_870_912,
mergeable: false,
hotplug_method: HotplugMethod::Acpi,
hotplug_size: None,
hotplugged_size: None,
shared: false,
hugepages: false,
hugepage_size: None,
prefault: false,
zones: None,
},
kernel: Some(KernelConfig {
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None,
cmdline: CmdlineConfig {
args: String::from(""),
},
disks: None,
net: None,
rng: RngConfig {
src: PathBuf::from("/dev/urandom"),
iommu: false,
#[cfg(target_arch = "x86_64")]
sgx_epc: None,
numa: None,
watchdog: false,
#[cfg(feature = "tdx")]
tdx: None,
platform: None,
};
},
balloon: None,
fs: None,
pmem: None,
serial: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Null,
iommu: false,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
},
devices: None,
user_devices: None,
vsock: None,
iommu: false,
#[cfg(target_arch = "x86_64")]
sgx_epc: None,
numa: None,
watchdog: false,
#[cfg(feature = "tdx")]
tdx: None,
platform: None,
};
aver_eq!(tb, expected_vm_config, result_vm_config);
Ok(())
})
assert_eq!(expected_vm_config, result_vm_config);
}
#[test]

View File

@@ -138,6 +138,7 @@ pub trait DiskConfig {
fn disk(&self, disk_type: DiskType) -> Option<String>;
}
#[derive(Clone)]
pub struct UbuntuDiskConfig {
osdisk_path: String,
cloudinit_path: String,

File diff suppressed because it is too large Load Diff

View File

@@ -5,16 +5,16 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[dependencies]
anyhow = "1.0.51"
libc = "0.2.108"
anyhow = "1.0.52"
libc = "0.2.112"
log = "0.4.14"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
thiserror = "1.0.30"
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic"] }
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = ">=0.3.1"
[dependencies.vfio-bindings]
version = "0.2.0"
version = "0.3.1"
features = ["fam-wrappers"]

View File

@@ -7,8 +7,8 @@ license = "Apache-2.0"
[dependencies]
byteorder = "1.4.3"
crc32c = "0.6.0"
libc = "0.2.108"
crc32c = "0.6.1"
libc = "0.2.112"
log = "0.4.14"
remain = "0.2.2"
thiserror = "1.0"

View File

@@ -9,11 +9,11 @@ default = []
[dependencies]
epoll = "4.3.1"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
virtio-bindings = "0.1.0"
virtio-queue = { path = "../virtio-queue" }
vm-memory = { version = "0.6.0", features = ["backend-bitmap"] }
vm-memory = { version = "0.7.0", features = ["backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"
vhost = { version = "0.2.0", features = ["vhost-user-slave"] }
vhost = { version = "0.3.0", features = ["vhost-user-slave"] }

View File

@@ -6,15 +6,15 @@ edition = "2018"
[dependencies]
block_util = { path = "../block_util" }
clap = { version = "2.34.0", features = ["wrap_help"] }
clap = { version = "3.0.10", features = ["wrap_help"] }
env_logger = "0.9.0"
epoll = "4.3.1"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
option_parser = { path = "../option_parser" }
qcow = { path = "../qcow" }
vhost_user_backend = { path = "../vhost_user_backend" }
vhost = { version = "0.2.0", features = ["vhost-user-slave"] }
vhost = { version = "0.3.0", features = ["vhost-user-slave"] }
virtio-bindings = "0.1.0"
vm-memory = "0.6.0"
vm-memory = "0.7.0"
vmm-sys-util = "0.9.0"

View File

@@ -23,7 +23,7 @@ fn main() {
.author(crate_authors!())
.about("Launch a vhost-user-blk backend.")
.arg(
Arg::with_name("block-backend")
Arg::new("block-backend")
.long("block-backend")
.help(vhost_user_block::SYNTAX)
.takes_value(true)

View File

@@ -5,15 +5,15 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[dependencies]
clap = { version = "2.34.0", features = ["wrap_help"] }
clap = { version = "3.0.10", features = ["wrap_help"] }
env_logger = "0.9.0"
epoll = "4.3.1"
libc = "0.2.108"
libc = "0.2.112"
log = "0.4.14"
net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" }
vhost_user_backend = { path = "../vhost_user_backend" }
vhost = { version = "0.2.0", features = ["vhost-user-slave"] }
vhost = { version = "0.3.0", features = ["vhost-user-slave"] }
virtio-bindings = "0.1.0"
vm-memory = "0.6.0"
vm-memory = "0.7.0"
vmm-sys-util = "0.9.0"

View File

@@ -20,7 +20,7 @@ fn main() {
.author(crate_authors!())
.about("Launch a vhost-user-net backend.")
.arg(
Arg::with_name("net-backend")
Arg::new("net-backend")
.long("net-backend")
.help(vhost_user_net::SYNTAX)
.takes_value(true)

View File

@@ -6,35 +6,34 @@ edition = "2018"
[features]
default = []
io_uring = ["block_util/io_uring"]
mshv = []
[dependencies]
anyhow = "1.0.51"
anyhow = "1.0.52"
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.108"
libc = "0.2.112"
log = "0.4.14"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci" }
rate_limiter = { path = "../rate_limiter" }
seccompiler = "0.2.0"
serde = "1.0.130"
serde_derive = "1.0.130"
serde_json = "1.0.72"
serde = "1.0.133"
serde_derive = "1.0.133"
serde_json = "1.0.75"
versionize = "0.1.6"
versionize_derive = "0.1.4"
vhost = { version = "0.2.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern"] }
vhost = { version = "0.3.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern"] }
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
virtio-queue = { path = "../virtio-queue" }
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.9.0"

View File

@@ -57,6 +57,8 @@ pub enum Error {
RequestParsing(block_util::Error),
/// Failed to execute the request.
RequestExecuting(block_util::ExecuteError),
/// Failed to complete the request.
RequestCompleting(block_util::Error),
/// Missing the expected entry in the list of requests.
MissingEntryRequestList,
/// The asynchronous request returned with failure.
@@ -188,10 +190,11 @@ impl BlockEpollHandler {
let completion_list = self.disk_image.complete();
for (user_data, result) in completion_list {
let desc_index = user_data as u16;
let request = self
let mut request = self
.request_list
.remove(&desc_index)
.ok_or(Error::MissingEntryRequestList)?;
request.complete_async().map_err(Error::RequestCompleting)?;
let (status, len) = if result >= 0 {
match request.request_type {
@@ -422,7 +425,9 @@ impl Block {
let mut avail_features = (1u64 << VIRTIO_F_VERSION_1)
| (1u64 << VIRTIO_BLK_F_FLUSH)
| (1u64 << VIRTIO_BLK_F_CONFIG_WCE);
| (1u64 << VIRTIO_BLK_F_CONFIG_WCE)
| (1u64 << VIRTIO_BLK_F_BLK_SIZE)
| (1u64 << VIRTIO_BLK_F_TOPOLOGY);
if iommu {
avail_features |= 1u64 << VIRTIO_F_IOMMU_PLATFORM;
@@ -432,10 +437,31 @@ impl Block {
avail_features |= 1u64 << VIRTIO_BLK_F_RO;
}
let topology = disk_image.topology();
info!("Disk topology: {:?}", topology);
let logical_block_size = if topology.logical_block_size > 512 {
topology.logical_block_size
} else {
512
};
// Calculate the exponent that maps physical block to logical block
let mut physical_block_exp = 0;
let mut size = logical_block_size;
while size < topology.physical_block_size {
physical_block_exp += 1;
size <<= 1;
}
let disk_nsectors = disk_size / SECTOR_SIZE;
let mut config = VirtioBlockConfig {
capacity: disk_nsectors,
writeback: 1,
blk_size: topology.logical_block_size as u32,
physical_block_exp,
min_io_size: (topology.minimum_io_size / logical_block_size) as u16,
opt_io_size: (topology.optimal_io_size / logical_block_size) as u32,
..Default::default()
};

View File

@@ -25,7 +25,10 @@ use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_queue::{AccessPlatform, DescriptorChain, Queue};
use vm_device::dma_mapping::ExternalDmaMapping;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError,
GuestMemoryLoadGuard,
};
use vm_migration::VersionMapped;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
@@ -339,7 +342,7 @@ impl Request {
// is created based on the information provided from the guest driver for
// virtio-iommu (giving the link device_id <=> domain).
fn parse(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
mapping: &Arc<IommuMapping>,
ext_mapping: &BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
ext_domain_mapping: &mut BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,

View File

@@ -38,7 +38,7 @@ use virtio_queue::{DescriptorChain, Queue};
use vm_device::dma_mapping::ExternalDmaMapping;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError,
GuestMemoryRegion,
GuestMemoryLoadGuard, GuestMemoryRegion,
};
use vm_migration::protocol::MemoryRangeTable;
use vm_migration::{
@@ -277,7 +277,7 @@ struct Request {
impl Request {
fn parse(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
) -> result::Result<Request, Error> {
let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
// The descriptor contains the request type which MUST be readable.

View File

@@ -34,9 +34,7 @@ use std::{collections::HashMap, convert::TryInto};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_bindings::bindings::virtio_net::*;
use virtio_bindings::bindings::virtio_ring::{
VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC,
};
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_queue::Queue;
use vm_memory::{ByteValued, GuestMemoryAtomic};
use vm_migration::VersionMapped;
@@ -400,9 +398,7 @@ impl Net {
| 1 << VIRTIO_NET_F_HOST_TSO4
| 1 << VIRTIO_NET_F_HOST_TSO6
| 1 << VIRTIO_NET_F_HOST_UFO
| 1 << VIRTIO_NET_F_MRG_RXBUF
| 1 << VIRTIO_RING_F_EVENT_IDX
| 1 << VIRTIO_RING_F_INDIRECT_DESC
| 1 << VIRTIO_F_VERSION_1;
if iommu {
@@ -567,10 +563,13 @@ impl VirtioDevice for Net {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
let queue_num = 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()) && queue_num % 2 != 0 {
let cvq_queue = queues.remove(queue_num - 1);
let mut cvq_queue = queues.remove(queue_num - 1);
let cvq_queue_evt = queue_evts.remove(queue_num - 1);
cvq_queue.set_event_idx(event_idx);
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let mut ctrl_handler = NetCtrlEpollHandler {
kill_evt,
@@ -603,8 +602,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

@@ -28,7 +28,10 @@ use std::sync::{Arc, Barrier};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_queue::{DescriptorChain, Queue};
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError,
GuestMemoryLoadGuard,
};
use vm_migration::VersionMapped;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
@@ -114,7 +117,7 @@ struct Request {
impl Request {
fn parse(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
) -> result::Result<Request, Error> {
let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
// The descriptor contains the request type which MUST be readable.

View File

@@ -90,7 +90,6 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_io_uring_enter, vec![]),
(libc::SYS_lseek, vec![]),
(libc::SYS_mprotect, vec![]),
(libc::SYS_openat, vec![]),
(libc::SYS_prctl, vec![]),
(libc::SYS_pread64, vec![]),
(libc::SYS_preadv, vec![]),
@@ -130,7 +129,6 @@ fn virtio_mem_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_openat, vec![]),
(libc::SYS_readv, vec![]),
(libc::SYS_timerfd_settime, vec![]),
(libc::SYS_writev, vec![]),
@@ -258,6 +256,7 @@ fn virtio_thread_common() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_madvise, vec![]),
(libc::SYS_mmap, vec![]),
(libc::SYS_munmap, vec![]),
(libc::SYS_openat, vec![]),
(libc::SYS_read, vec![]),
(libc::SYS_rt_sigprocmask, vec![]),
(libc::SYS_sigaltstack, vec![]),

View File

@@ -362,10 +362,11 @@ impl VirtioPciDevice {
.queue_max_sizes()
.iter()
.map(|&s| {
let mut queue = Queue::<
GuestMemoryAtomic<GuestMemoryMmap>,
virtio_queue::QueueState<GuestMemoryAtomic<GuestMemoryMmap>>,
>::new(memory.clone(), s);
let mut queue =
Queue::<GuestMemoryAtomic<GuestMemoryMmap>, virtio_queue::QueueState>::new(
memory.clone(),
s,
);
queue.state.access_platform = access_platform.clone();
queue
})
@@ -841,7 +842,7 @@ impl PciDevice for VirtioPciDevice {
fn allocate_bars(
&mut self,
allocator: &mut SystemAllocator,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError>
{
@@ -865,6 +866,8 @@ impl PciDevice for VirtioPciDevice {
} else {
let region_type = PciBarRegionType::Memory32BitRegion;
let addr = allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(
self.settings_bar_addr,
CAPABILITY_BAR_SIZE,

View File

@@ -173,7 +173,7 @@ impl VhostUserHandle {
// at early stage.
for (queue_index, queue) in queues.iter().enumerate() {
self.vu
.set_vring_num(queue_index, queue.actual_size())
.set_vring_num(queue_index, queue.max_size())
.map_err(Error::VhostUserSetVringNum)?;
}
@@ -184,7 +184,7 @@ impl VhostUserHandle {
mmap_size: 0,
mmap_offset: 0,
num_queues: queues.len() as u16,
queue_size: queues[0].actual_size(),
queue_size: queues[0].max_size(),
};
let (info, fd) = self
.vu
@@ -203,11 +203,11 @@ impl VhostUserHandle {
let mut vrings_info = Vec::new();
for (queue_index, queue) in queues.into_iter().enumerate() {
let actual_size: usize = queue.actual_size().try_into().unwrap();
let actual_size: usize = queue.max_size().try_into().unwrap();
let config_data = VringConfigData {
queue_max_size: queue.max_size(),
queue_size: queue.actual_size(),
queue_size: queue.max_size(),
flags: 0u32,
desc_table_addr: get_host_address_range(
mem,

View File

@@ -21,7 +21,7 @@ use super::defs;
use super::{Result, VsockError};
use crate::{get_host_address_range, GuestMemoryMmap};
use virtio_queue::DescriptorChain;
use vm_memory::GuestMemoryAtomic;
use vm_memory::GuestMemoryLoadGuard;
// The vsock packet header is defined by the C struct:
//
@@ -106,7 +106,7 @@ impl VsockPacket {
/// creating the wrapper.
///
pub fn from_tx_virtq_head(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
) -> Result<Self> {
let head = desc_chain.next().ok_or(VsockError::HdrDescMissing)?;
@@ -168,7 +168,7 @@ impl VsockPacket {
/// descriptor. Bounds and pointer checks are performed when creating the wrapper.
///
pub fn from_rx_virtq_head(
desc_chain: &mut DescriptorChain<GuestMemoryAtomic<GuestMemoryMmap>>,
desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>,
) -> Result<Self> {
let head = desc_chain.next().ok_or(VsockError::HdrDescMissing)?;

View File

@@ -295,14 +295,13 @@ impl VsockEpollListener for VsockMuxer {
'epoll: loop {
match epoll::wait(self.epoll_file.as_raw_fd(), 0, epoll_events.as_mut_slice()) {
Ok(ev_cnt) => {
#[allow(clippy::needless_range_loop)]
for i in 0..ev_cnt {
for evt in epoll_events.iter().take(ev_cnt) {
self.handle_event(
epoll_events[i].data as RawFd,
// It's ok to unwrap here, since the `epoll_events[i].events` is filled
evt.data as RawFd,
// It's ok to unwrap here, since the `evt.events` is filled
// in by `epoll::wait()`, and therefore contains only valid epoll
// flags.
epoll::Events::from_bits(epoll_events[i].events).unwrap(),
epoll::Events::from_bits(evt.events).unwrap(),
);
}
}
@@ -362,25 +361,24 @@ impl VsockMuxer {
/// Handle/dispatch an epoll event to its listener.
///
fn handle_event(&mut self, fd: RawFd, evset: epoll::Events) {
fn handle_event(&mut self, fd: RawFd, event_set: epoll::Events) {
debug!(
"vsock: muxer processing event: fd={}, evset={:?}",
fd, evset
"vsock: muxer processing event: fd={}, event_set={:?}",
fd, event_set
);
match self.listener_map.get_mut(&fd) {
// This event needs to be forwarded to a `MuxerConnection` that is listening for
// it.
//
Some(EpollListener::Connection { key, evset }) => {
Some(EpollListener::Connection { key, evset: _ }) => {
let key_copy = *key;
let evset_copy = *evset;
// The handling of this event will most probably mutate the state of the
// receiving connection. We'll need to check for new pending RX, event set
// mutation, and all that, so we're wrapping the event delivery inside those
// checks.
self.apply_conn_mutation(key_copy, |conn| {
conn.notify(evset_copy);
conn.notify(event_set);
});
}
@@ -443,7 +441,10 @@ impl VsockMuxer {
}
_ => {
info!("vsock: unexpected event: fd={:?}, evset={:?}", fd, evset);
info!(
"vsock: unexpected event: fd={:?}, event_set={:?}",
fd, event_set
);
}
}
}

View File

@@ -6,13 +6,14 @@ description = "virtio queue implementation"
repository = "https://github.com/rust-vmm/vm-virtio"
keywords = ["virtio"]
readme = "README.md"
license = "Apache-2.0 OR MIT"
license = "Apache-2.0 OR BSD-3-Clause"
edition = "2018"
[features]
test-utils = []
[dependencies]
vm-memory = "0.6.0"
vm-memory = "0.7.0"
vmm-sys-util = ">=0.8.0"
log = ">=0.4.6"
log = ">=0.4.6"
[dev-dependencies]
vm-memory = { version = "0.7.0", features = ["backend-mmap", "backend-atomic"] }
memoffset = "~0"

490
virtio-queue/src/chain.rs Normal file
View File

@@ -0,0 +1,490 @@
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Copyright © 2019 Intel Corporation
//
// Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::convert::TryFrom;
use std::fmt::{self, Debug};
use std::mem::size_of;
use std::ops::Deref;
use std::sync::Arc;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory};
use crate::defs::VIRTQ_DESCRIPTOR_SIZE;
use crate::{AccessPlatform, Descriptor, Error};
/// A virtio descriptor chain.
#[derive(Clone, Debug)]
pub struct DescriptorChain<M> {
mem: M,
desc_table: GuestAddress,
queue_size: u16,
head_index: u16,
next_index: u16,
ttl: u16,
is_indirect: bool,
access_platform: Option<Arc<dyn AccessPlatform>>,
}
impl<M> DescriptorChain<M>
where
M: Deref,
M::Target: GuestMemory,
{
fn with_ttl(
mem: M,
desc_table: GuestAddress,
queue_size: u16,
ttl: u16,
head_index: u16,
access_platform: Option<Arc<dyn AccessPlatform>>,
) -> Self {
DescriptorChain {
mem,
desc_table,
queue_size,
head_index,
next_index: head_index,
ttl,
is_indirect: false,
access_platform,
}
}
/// Create a new `DescriptorChain` instance.
///
/// # Arguments
/// * `mem` - the `GuestMemory` object that can be used to access the buffers pointed to by the
/// descriptor chain.
/// * `desc_table` - the address of the descriptor table.
/// * `queue_size` - the size of the queue, which is also the maximum size of a descriptor
/// chain.
/// * `head_index` - the descriptor index of the chain head.
pub(crate) fn new(
mem: M,
desc_table: GuestAddress,
queue_size: u16,
head_index: u16,
access_platform: Option<Arc<dyn AccessPlatform>>,
) -> Self {
Self::with_ttl(
mem,
desc_table,
queue_size,
queue_size,
head_index,
access_platform,
)
}
/// Get the descriptor index of the chain head.
pub fn head_index(&self) -> u16 {
self.head_index
}
/// Return a `GuestMemory` object that can be used to access the buffers pointed to by the
/// descriptor chain.
pub fn memory(&self) -> &M::Target {
self.mem.deref()
}
/// Return an iterator that only yields the readable descriptors in the chain.
pub fn readable(self) -> DescriptorChainRwIter<M> {
DescriptorChainRwIter {
chain: self,
writable: false,
}
}
/// Return an iterator that only yields the writable descriptors in the chain.
pub fn writable(self) -> DescriptorChainRwIter<M> {
DescriptorChainRwIter {
chain: self,
writable: true,
}
}
// Alters the internal state of the `DescriptorChain` to switch iterating over an
// indirect descriptor table defined by `desc`.
fn switch_to_indirect_table(&mut self, desc: Descriptor) -> Result<(), Error> {
// Check the VIRTQ_DESC_F_INDIRECT flag (i.e., is_indirect) is not set inside
// an indirect descriptor.
// (see VIRTIO Spec, Section 2.6.5.3.1 Driver Requirements: Indirect Descriptors)
if self.is_indirect {
return Err(Error::InvalidIndirectDescriptor);
}
// Check the target indirect descriptor table is correctly aligned.
if desc.addr().raw_value() & (VIRTQ_DESCRIPTOR_SIZE as u64 - 1) != 0
|| desc.len() & (VIRTQ_DESCRIPTOR_SIZE as u32 - 1) != 0
{
return Err(Error::InvalidIndirectDescriptorTable);
}
// It is safe to do a plain division since we checked above that desc.len() is a multiple of
// VIRTQ_DESCRIPTOR_SIZE, and VIRTQ_DESCRIPTOR_SIZE is != 0.
let table_len = (desc.len() as usize) / VIRTQ_DESCRIPTOR_SIZE;
if table_len > usize::from(u16::MAX) {
return Err(Error::InvalidIndirectDescriptorTable);
}
self.desc_table = desc.addr();
// try_from cannot fail as we've checked table_len above
self.queue_size = u16::try_from(table_len).expect("invalid table_len");
self.next_index = 0;
self.ttl = self.queue_size;
self.is_indirect = true;
Ok(())
}
}
impl<M> Iterator for DescriptorChain<M>
where
M: Deref,
M::Target: GuestMemory,
{
type Item = Descriptor;
/// Return the next descriptor in this descriptor chain, if there is one.
///
/// Note that this is distinct from the next descriptor chain returned by
/// [`AvailIter`](struct.AvailIter.html), which is the head of the next
/// _available_ descriptor chain.
fn next(&mut self) -> Option<Self::Item> {
if self.ttl == 0 || self.next_index >= self.queue_size {
return None;
}
let desc_addr = self
.desc_table
// The multiplication can not overflow an u64 since we are multiplying an u16 with a
// small number.
.checked_add(self.next_index as u64 * size_of::<Descriptor>() as u64)?;
// The guest device driver should not touch the descriptor once submitted, so it's safe
// to use read_obj() here.
let mut desc = self.mem.read_obj::<Descriptor>(desc_addr).ok()?;
// When needed, it's very important to translate the decriptor address
// before returning the Descriptor to the consumer.
if let Some(access_platform) = &self.access_platform {
desc.set_addr(
access_platform
.translate(desc.addr().0, u64::from(desc.len()))
.ok()?,
);
}
if desc.refers_to_indirect_table() {
self.switch_to_indirect_table(desc).ok()?;
return self.next();
}
if desc.has_next() {
self.next_index = desc.next();
// It's ok to decrement `self.ttl` here because we check at the start of the method
// that it's greater than 0.
self.ttl -= 1;
} else {
self.ttl = 0;
}
Some(desc)
}
}
/// An iterator for readable or writable descriptors.
#[derive(Clone)]
pub struct DescriptorChainRwIter<M> {
chain: DescriptorChain<M>,
writable: bool,
}
impl<M> Iterator for DescriptorChainRwIter<M>
where
M: Deref,
M::Target: GuestMemory,
{
type Item = Descriptor;
/// Return the next readable/writeable descriptor (depending on the `writable` value) in this
/// descriptor chain, if there is one.
///
/// Note that this is distinct from the next descriptor chain returned by
/// [`AvailIter`](struct.AvailIter.html), which is the head of the next
/// _available_ descriptor chain.
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.chain.next() {
Some(v) => {
if v.is_write_only() == self.writable {
return Some(v);
}
}
None => return None,
}
}
}
}
// We can't derive Debug, because rustc doesn't generate the `M::T: Debug` constraint
impl<M> Debug for DescriptorChainRwIter<M>
where
M: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DescriptorChainRwIter")
.field("chain", &self.chain)
.field("writable", &self.writable)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::defs::{VIRTQ_DESC_F_INDIRECT, VIRTQ_DESC_F_NEXT};
use crate::mock::{DescriptorTable, MockSplitQueue};
use vm_memory::GuestMemoryMmap;
#[test]
fn test_checked_new_descriptor_chain() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
assert!(vq.end().0 < 0x1000);
// index >= queue_size
assert!(
DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), 16, 16, None)
.next()
.is_none()
);
// desc_table address is way off
assert!(DescriptorChain::<&GuestMemoryMmap>::new(
m,
GuestAddress(0x00ff_ffff_ffff),
16,
0,
None
)
.next()
.is_none());
{
// the first desc has a normal len, and the next_descriptor flag is set
// but the the index of the next descriptor is too large
let desc = Descriptor::new(0x1000, 0x1000, VIRTQ_DESC_F_NEXT, 16);
vq.desc_table().store(0, desc);
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), 16, 0, None);
c.next().unwrap();
assert!(c.next().is_none());
}
// finally, let's test an ok chain
{
let desc = Descriptor::new(0x1000, 0x1000, VIRTQ_DESC_F_NEXT, 1);
vq.desc_table().store(0, desc);
let desc = Descriptor::new(0x2000, 0x1000, 0, 0);
vq.desc_table().store(1, desc);
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), 16, 0, None);
assert_eq!(
c.memory() as *const GuestMemoryMmap,
m as *const GuestMemoryMmap
);
assert_eq!(c.desc_table, vq.start());
assert_eq!(c.queue_size, 16);
assert_eq!(c.ttl, c.queue_size);
let desc = c.next().unwrap();
assert_eq!(desc.addr(), GuestAddress(0x1000));
assert_eq!(desc.len(), 0x1000);
assert_eq!(desc.flags(), VIRTQ_DESC_F_NEXT);
assert_eq!(desc.next(), 1);
assert_eq!(c.ttl, c.queue_size - 1);
assert!(c.next().is_some());
// The descriptor above was the last from the chain, so `ttl` should be 0 now.
assert_eq!(c.ttl, 0);
assert!(c.next().is_none());
assert_eq!(c.ttl, 0);
}
}
#[test]
fn test_ttl_wrap_around() {
const QUEUE_SIZE: u16 = 16;
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x100000)]).unwrap();
let vq = MockSplitQueue::new(m, QUEUE_SIZE);
// Populate the entire descriptor table with entries. Only the last one should not have the
// VIRTQ_DESC_F_NEXT set.
for i in 0..QUEUE_SIZE - 1 {
let desc = Descriptor::new(0x1000 * (i + 1) as u64, 0x1000, VIRTQ_DESC_F_NEXT, i + 1);
vq.desc_table().store(i, desc);
}
let desc = Descriptor::new((0x1000 * 16) as u64, 0x1000, 0, 0);
vq.desc_table().store(QUEUE_SIZE - 1, desc);
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), QUEUE_SIZE, 0, None);
assert_eq!(c.ttl, c.queue_size);
// Validate that `ttl` wraps around even when the entire descriptor table is populated.
for i in 0..QUEUE_SIZE {
let _desc = c.next().unwrap();
assert_eq!(c.ttl, c.queue_size - i - 1);
}
assert!(c.next().is_none());
}
#[test]
fn test_new_from_indirect_descriptor() {
// This is testing that chaining an indirect table works as expected. It is also a negative
// test for the following requirement from the spec:
// `A driver MUST NOT set both VIRTQ_DESC_F_INDIRECT and VIRTQ_DESC_F_NEXT in flags.`. In
// case the driver is setting both of these flags, we check that the device doesn't panic.
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let dtable = vq.desc_table();
// Create a chain with one normal descriptor and one pointing to an indirect table.
let desc = Descriptor::new(0x6000, 0x1000, VIRTQ_DESC_F_NEXT, 1);
dtable.store(0, desc);
// The spec forbids setting both VIRTQ_DESC_F_INDIRECT and VIRTQ_DESC_F_NEXT in flags. We do
// not currently enforce this rule, we just ignore the VIRTQ_DESC_F_NEXT flag.
let desc = Descriptor::new(0x7000, 0x1000, VIRTQ_DESC_F_INDIRECT | VIRTQ_DESC_F_NEXT, 2);
dtable.store(1, desc);
let desc = Descriptor::new(0x8000, 0x1000, 0, 0);
dtable.store(2, desc);
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
// create an indirect table with 4 chained descriptors
let idtable = DescriptorTable::new(m, GuestAddress(0x7000), 4);
for i in 0..4u16 {
let desc = if i < 3 {
Descriptor::new(0x1000 * i as u64, 0x1000, VIRTQ_DESC_F_NEXT, i + 1)
} else {
Descriptor::new(0x1000 * i as u64, 0x1000, 0, 0)
};
idtable.store(i, desc);
}
assert_eq!(c.head_index(), 0);
// Consume the first descriptor.
c.next().unwrap();
// The chain logic hasn't parsed the indirect descriptor yet.
assert!(!c.is_indirect);
// Try to iterate through the indirect descriptor chain.
for i in 0..4 {
let desc = c.next().unwrap();
assert!(c.is_indirect);
if i < 3 {
assert_eq!(desc.flags(), VIRTQ_DESC_F_NEXT);
assert_eq!(desc.next(), i + 1);
}
}
// Even though we added a new descriptor after the one that is pointing to the indirect
// table, this descriptor won't be available when parsing the chain.
assert!(c.next().is_none());
}
#[test]
fn test_indirect_descriptor_err() {
// We are testing here different misconfigurations of the indirect table. For these error
// case scenarios, the iterator over the descriptor chain won't return a new descriptor.
{
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
// Create a chain with a descriptor pointing to an invalid indirect table: addr not a
// multiple of descriptor size.
let desc = Descriptor::new(0x1001, 0x1000, VIRTQ_DESC_F_INDIRECT, 0);
vq.desc_table().store(0, desc);
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
assert!(c.next().is_none());
}
{
let m = &GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
// Create a chain with a descriptor pointing to an invalid indirect table: len not a
// multiple of descriptor size.
let desc = Descriptor::new(0x1000, 0x1001, VIRTQ_DESC_F_INDIRECT, 0);
vq.desc_table().store(0, desc);
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
assert!(c.next().is_none());
}
{
let m = &GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
// Create a chain with a descriptor pointing to an invalid indirect table: table len >
// u16::MAX.
let desc = Descriptor::new(
0x1000,
(u16::MAX as u32 + 1) * VIRTQ_DESCRIPTOR_SIZE as u32,
VIRTQ_DESC_F_INDIRECT,
0,
);
vq.desc_table().store(0, desc);
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
assert!(c.next().is_none());
}
{
let m = &GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
// Create a chain with a descriptor pointing to an indirect table.
let desc = Descriptor::new(0x1000, 0x1000, VIRTQ_DESC_F_INDIRECT, 0);
vq.desc_table().store(0, desc);
// It's ok for an indirect descriptor to have flags = 0.
let desc = Descriptor::new(0x3000, 0x1000, 0, 0);
m.write_obj(desc, GuestAddress(0x1000)).unwrap();
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
assert!(c.next().is_some());
// But it's not allowed to have an indirect descriptor that points to another indirect
// table.
let desc = Descriptor::new(0x3000, 0x1000, VIRTQ_DESC_F_INDIRECT, 0);
m.write_obj(desc, GuestAddress(0x1000)).unwrap();
let mut c: DescriptorChain<&GuestMemoryMmap> =
DescriptorChain::new(m, vq.start(), 16, 0, None);
assert!(c.next().is_none());
}
}
}

View File

@@ -10,37 +10,50 @@ pub const VIRTQ_DESC_F_NEXT: u16 = 0x1;
/// Marks a buffer as device write-only.
pub const VIRTQ_DESC_F_WRITE: u16 = 0x2;
/// Shows that the buffer contains a list of buffer descriptors.
/// Marks a buffer as containing a list of buffer descriptors.
pub const VIRTQ_DESC_F_INDIRECT: u16 = 0x4;
/// Used flags
/// Flag to disable guest notification for used descriptors.
pub const VIRTQ_USED_F_NO_NOTIFY: u16 = 0x1;
/// This is the size of one element in the used ring, id (le32) + len (le32).
/// Size of one element in the used ring, id (le32) + len (le32).
pub(crate) const VIRTQ_USED_ELEMENT_SIZE: u64 = 8;
/// Used ring header: flags (u16) + idx (u16)
/// Size of used ring header: flags (u16) + idx (u16)
pub(crate) const VIRTQ_USED_RING_HEADER_SIZE: u64 = 4;
/// This is the size of the used ring metadata: header + avail_event (le16).
/// Size of the used ring metadata: header + avail_event (le16).
///
/// The total size of the used ring is:
/// VIRTQ_USED_RING_HMETA_SIZE + VIRTQ_USED_ELEMENT_SIZE * queue_size
/// VIRTQ_USED_RING_META_SIZE + VIRTQ_USED_ELEMENT_SIZE * queue_size.
pub(crate) const VIRTQ_USED_RING_META_SIZE: u64 = VIRTQ_USED_RING_HEADER_SIZE + 2;
/// This is the size of one element in the available ring (le16).
/// Size of one element in the available ring (le16).
pub(crate) const VIRTQ_AVAIL_ELEMENT_SIZE: u64 = 2;
/// Avail ring header: flags(u16) + idx(u16)
/// Size of available ring header: flags(u16) + idx(u16)
pub(crate) const VIRTQ_AVAIL_RING_HEADER_SIZE: u64 = 4;
/// This is the size of the available ring metadata: header + used_event (le16).
/// Size of the available ring metadata: header + used_event (le16).
///
/// The total size of the available ring is:
/// VIRTQ_AVAIL_RING_META_SIZE + VIRTQ_AVAIL_ELEMENT_SIZE * queue_size
/// VIRTQ_AVAIL_RING_META_SIZE + VIRTQ_AVAIL_ELEMENT_SIZE * queue_size.
pub(crate) const VIRTQ_AVAIL_RING_META_SIZE: u64 = VIRTQ_AVAIL_RING_HEADER_SIZE + 2;
/// Size of virtio descriptor.
///
/// The Virtio Spec 1.0 defines the alignment of VirtIO descriptor is 16 bytes,
/// which fulfills the explicit constraint of GuestMemory::read_obj().
pub(crate) const VIRTQ_DESCRIPTOR_SIZE: usize = 16;
/// Default guest physical address for descriptor table.
pub(crate) const DEFAULT_DESC_TABLE_ADDR: u64 = 0x0;
/// Default guest physical address for available ring.
pub(crate) const DEFAULT_AVAIL_RING_ADDR: u64 = 0x0;
/// Default guest physical address for used ring.
pub(crate) const DEFAULT_USED_RING_ADDR: u64 = 0x0;
/// Vector value used to disable MSI for a queue.
pub const VIRTQ_MSI_NO_VECTOR: u16 = 0xffff;

View File

@@ -0,0 +1,270 @@
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Copyright © 2019 Intel Corporation
//
// Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use vm_memory::{ByteValued, GuestAddress, Le16, Le32, Le64};
use crate::defs::{VIRTQ_DESC_F_INDIRECT, VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
/// A virtio descriptor constraints with C representation.
///
/// # Example
///
/// ```rust
/// # use virtio_queue::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
/// # use virtio_queue::mock::MockSplitQueue;
/// use virtio_queue::{Descriptor, Queue};
/// use vm_memory::{GuestAddress, GuestMemoryMmap};
///
/// # fn populate_queue(m: &GuestMemoryMmap) -> Queue<&GuestMemoryMmap> {
/// # let vq = MockSplitQueue::new(m, 16);
/// # let mut q = vq.create_queue(m);
/// #
/// # // We have only one chain: (0, 1).
/// # let desc = Descriptor::new(0x1000, 0x1000, VIRTQ_DESC_F_NEXT, 1);
/// # vq.desc_table().store(0, desc);
/// # let desc = Descriptor::new(0x2000, 0x1000, VIRTQ_DESC_F_WRITE, 0);
/// # vq.desc_table().store(1, desc);
/// #
/// # vq.avail().ring().ref_at(0).store(u16::to_le(0));
/// # vq.avail().idx().store(u16::to_le(1));
/// # q
/// # }
/// let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
/// // Populate the queue with descriptor chains and update the available ring accordingly.
/// let mut queue = populate_queue(m);
/// let mut i = queue.iter().unwrap();
/// let mut c = i.next().unwrap();
///
/// // Get the first descriptor and access its fields.
/// let desc = c.next().unwrap();
/// let _addr = desc.addr();
/// let _len = desc.len();
/// let _flags = desc.flags();
/// let _next = desc.next();
/// let _is_write_only = desc.is_write_only();
/// let _has_next = desc.has_next();
/// let _refers_to_ind_table = desc.refers_to_indirect_table();
/// ```
// Note that the `ByteValued` implementation of this structure expects the `Descriptor` to store
// only plain old data types.
#[repr(C)]
#[derive(Default, Clone, Copy, Debug)]
pub struct Descriptor {
/// Guest physical address of device specific data.
addr: Le64,
/// Length of device specific data.
len: Le32,
/// Includes next, write, and indirect bits.
flags: Le16,
/// Index into the descriptor table of the next descriptor if flags has the `next` bit set.
next: Le16,
}
#[allow(clippy::len_without_is_empty)]
impl Descriptor {
/// Return the guest physical address of the descriptor buffer.
pub fn addr(&self) -> GuestAddress {
GuestAddress(self.addr.into())
}
/// Return the length of the descriptor buffer.
pub fn len(&self) -> u32 {
self.len.into()
}
/// Return the flags for this descriptor, including next, write and indirect bits.
pub fn flags(&self) -> u16 {
self.flags.into()
}
/// Return the value stored in the `next` field of the descriptor.
pub fn next(&self) -> u16 {
self.next.into()
}
/// Check whether this descriptor refers to a buffer containing an indirect descriptor table.
pub fn refers_to_indirect_table(&self) -> bool {
self.flags() & VIRTQ_DESC_F_INDIRECT != 0
}
/// Check whether the `VIRTQ_DESC_F_NEXT` is set for the descriptor.
pub fn has_next(&self) -> bool {
self.flags() & VIRTQ_DESC_F_NEXT != 0
}
/// Check if the driver designated this as a write only descriptor.
///
/// If this is false, this descriptor is read only.
/// Write only means the the emulated device can write and the driver can read.
pub fn is_write_only(&self) -> bool {
self.flags() & VIRTQ_DESC_F_WRITE != 0
}
/// Set the guest physical address of the descriptor buffer.
pub fn set_addr(&mut self, addr: u64) {
self.addr = addr.into();
}
}
impl Descriptor {
/// Create a new descriptor.
///
/// # Arguments
/// * `addr` - the guest physical address of the descriptor buffer.
/// * `len` - the length of the descriptor buffer.
/// * `flags` - the `flags` for the descriptor.
/// * `next` - the `next` field of the descriptor.
pub fn new(addr: u64, len: u32, flags: u16, next: u16) -> Self {
Descriptor {
addr: addr.into(),
len: len.into(),
flags: flags.into(),
next: next.into(),
}
}
/// Set the length of the descriptor buffer.
pub fn set_len(&mut self, len: u32) {
self.len = len.into();
}
/// Set the flags for this descriptor.
pub fn set_flags(&mut self, flags: u16) {
self.flags = flags.into();
}
/// Set the value stored in the `next` field of the descriptor.
pub fn set_next(&mut self, next: u16) {
self.next = next.into();
}
}
// This is safe because `Descriptor` contains only wrappers over POD types and all accesses through
// safe `vm-memory` API will validate any garbage that could be included in there.
unsafe impl ByteValued for Descriptor {}
/// Represents the contents of an element from the used virtqueue ring.
// Note that the `ByteValued` implementation of this structure expects the `VirtqUsedElem` to store
// only plain old data types.
#[repr(C)]
#[derive(Clone, Copy, Default, Debug)]
pub struct VirtqUsedElem {
id: Le32,
len: Le32,
}
impl VirtqUsedElem {
/// Create a new `VirtqUsedElem` instance.
///
/// # Arguments
/// * `id` - the index of the used descriptor chain.
/// * `len` - the total length of the descriptor chain which was used (written to).
pub(crate) fn new(id: u32, len: u32) -> Self {
VirtqUsedElem {
id: id.into(),
len: len.into(),
}
}
}
#[allow(clippy::len_without_is_empty)]
impl VirtqUsedElem {
/// Get the index of the used descriptor chain.
pub fn id(&self) -> u32 {
self.id.into()
}
/// Get `length` field of the used ring entry.
pub fn len(&self) -> u32 {
self.len.into()
}
}
// This is safe because `VirtqUsedElem` contains only wrappers over POD types and all accesses
// through safe `vm-memory` API will validate any garbage that could be included in there.
unsafe impl ByteValued for VirtqUsedElem {}
#[cfg(test)]
mod tests {
use super::*;
use memoffset::offset_of;
use std::mem::{align_of, size_of};
#[test]
fn test_descriptor_offset() {
assert_eq!(size_of::<Descriptor>(), 16);
assert_eq!(offset_of!(Descriptor, addr), 0);
assert_eq!(offset_of!(Descriptor, len), 8);
assert_eq!(offset_of!(Descriptor, flags), 12);
assert_eq!(offset_of!(Descriptor, next), 14);
assert!(align_of::<Descriptor>() <= 16);
}
#[test]
fn test_descriptor_getter_setter() {
let mut desc = Descriptor::new(0, 0, 0, 0);
desc.set_addr(0x1000);
assert_eq!(desc.addr(), GuestAddress(0x1000));
desc.set_len(0x2000);
assert_eq!(desc.len(), 0x2000);
desc.set_flags(VIRTQ_DESC_F_NEXT);
assert_eq!(desc.flags(), VIRTQ_DESC_F_NEXT);
assert!(desc.has_next());
assert!(!desc.is_write_only());
assert!(!desc.refers_to_indirect_table());
desc.set_flags(VIRTQ_DESC_F_WRITE);
assert_eq!(desc.flags(), VIRTQ_DESC_F_WRITE);
assert!(!desc.has_next());
assert!(desc.is_write_only());
assert!(!desc.refers_to_indirect_table());
desc.set_flags(VIRTQ_DESC_F_INDIRECT);
assert_eq!(desc.flags(), VIRTQ_DESC_F_INDIRECT);
assert!(!desc.has_next());
assert!(!desc.is_write_only());
assert!(desc.refers_to_indirect_table());
desc.set_next(3);
assert_eq!(desc.next(), 3);
}
#[test]
fn test_descriptor_copy() {
let e1 = Descriptor::new(1, 2, VIRTQ_DESC_F_NEXT, 3);
let mut e2 = Descriptor::default();
e2.as_mut_slice().copy_from_slice(e1.as_slice());
assert_eq!(e1.addr(), e2.addr());
assert_eq!(e1.len(), e2.len());
assert_eq!(e1.flags(), e2.flags());
assert_eq!(e1.next(), e2.next());
}
#[test]
fn test_used_elem_offset() {
assert_eq!(offset_of!(VirtqUsedElem, id), 0);
assert_eq!(offset_of!(VirtqUsedElem, len), 4);
assert_eq!(size_of::<VirtqUsedElem>(), 8);
}
#[test]
fn test_used_elem_copy() {
let e1 = VirtqUsedElem::new(3, 15);
let mut e2 = VirtqUsedElem::new(0, 0);
e2.as_mut_slice().copy_from_slice(e1.as_slice());
assert_eq!(e1.id, e2.id);
assert_eq!(e1.len, e2.len);
}
}

View File

@@ -0,0 +1,323 @@
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Copyright © 2019 Intel Corporation
//
// Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::num::Wrapping;
use std::ops::Deref;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory};
use crate::defs::{VIRTQ_AVAIL_ELEMENT_SIZE, VIRTQ_AVAIL_RING_HEADER_SIZE};
use crate::{error, AccessPlatform, DescriptorChain, QueueState};
/// Consuming iterator over all available descriptor chain heads in the queue.
///
/// # Example
///
/// ```rust
/// # use virtio_queue::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
/// # use virtio_queue::mock::MockSplitQueue;
/// use virtio_queue::{Descriptor, Queue};
/// use vm_memory::{GuestAddress, GuestMemoryMmap};
///
/// # fn populate_queue(m: &GuestMemoryMmap) -> Queue<&GuestMemoryMmap> {
/// # let vq = MockSplitQueue::new(m, 16);
/// # let mut q = vq.create_queue(m);
/// #
/// # // The chains are (0, 1), (2, 3, 4) and (5, 6).
/// # for i in 0..7 {
/// # let flags = match i {
/// # 1 | 6 => 0,
/// # 2 | 5 => VIRTQ_DESC_F_NEXT | VIRTQ_DESC_F_WRITE,
/// # 4 => VIRTQ_DESC_F_WRITE,
/// # _ => VIRTQ_DESC_F_NEXT,
/// # };
/// #
/// # let desc = Descriptor::new((0x1000 * (i + 1)) as u64, 0x1000, flags, i + 1);
/// # vq.desc_table().store(i, desc);
/// # }
/// #
/// # vq.avail().ring().ref_at(0).store(u16::to_le(0));
/// # vq.avail().ring().ref_at(1).store(u16::to_le(2));
/// # vq.avail().ring().ref_at(2).store(u16::to_le(5));
/// # vq.avail().idx().store(u16::to_le(3));
/// # q
/// # }
/// let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
/// // Populate the queue with descriptor chains and update the available ring accordingly.
/// let mut queue = populate_queue(m);
/// let mut i = queue.iter().unwrap();
///
/// {
/// let mut c = i.next().unwrap();
/// let _first_head_index = c.head_index();
/// // We should have two descriptors in the first chain.
/// let _desc1 = c.next().unwrap();
/// let _desc2 = c.next().unwrap();
/// }
///
/// {
/// let c = i.next().unwrap();
/// let _second_head_index = c.head_index();
///
/// let mut iter = c.writable();
/// // We should have two writable descriptors in the second chain.
/// let _desc1 = iter.next().unwrap();
/// let _desc2 = iter.next().unwrap();
/// }
///
/// {
/// let c = i.next().unwrap();
/// let _third_head_index = c.head_index();
///
/// let mut iter = c.readable();
/// // We should have one readable descriptor in the third chain.
/// let _desc1 = iter.next().unwrap();
/// }
/// // Let's go back one position in the available ring.
/// i.go_to_previous_position();
/// // We should be able to access again the third descriptor chain.
/// let c = i.next().unwrap();
/// let _third_head_index = c.head_index();
/// ```
#[derive(Debug)]
pub struct AvailIter<'b, M> {
mem: M,
desc_table: GuestAddress,
avail_ring: GuestAddress,
queue_size: u16,
last_index: Wrapping<u16>,
next_avail: &'b mut Wrapping<u16>,
access_platform: &'b Option<Arc<dyn AccessPlatform>>,
}
impl<'b, M> AvailIter<'b, M>
where
M: Deref,
M::Target: GuestMemory + Sized,
{
/// Create a new instance of `AvailInter`.
///
/// # Arguments
/// * `mem` - the `GuestMemory` object that can be used to access the queue buffers.
/// * `idx` - the index of the available ring entry where the driver would put the next
/// available descriptor chain.
/// * `state` - the `QueueState` object from which the needed data to create the `AvailIter` can
/// be retrieved.
pub(crate) fn new(mem: M, idx: Wrapping<u16>, state: &'b mut QueueState) -> Self {
AvailIter {
mem,
desc_table: state.desc_table,
avail_ring: state.avail_ring,
queue_size: state.size,
last_index: idx,
next_avail: &mut state.next_avail,
access_platform: &state.access_platform,
}
}
/// Goes back one position in the available descriptor chain offered by the driver.
///
/// Rust does not support bidirectional iterators. This is the only way to revert the effect
/// of an iterator increment on the queue.
///
/// Note: this method assumes there's only one thread manipulating the queue, so it should only
/// be invoked in single-threaded context.
pub fn go_to_previous_position(&mut self) {
*self.next_avail -= Wrapping(1);
}
}
impl<'b, M> Iterator for AvailIter<'b, M>
where
M: Clone + Deref,
M::Target: GuestMemory,
{
type Item = DescriptorChain<M>;
fn next(&mut self) -> Option<Self::Item> {
if *self.next_avail == self.last_index {
return None;
}
// These two operations can not overflow an u64 since they're working with relatively small
// numbers compared to u64::MAX.
let elem_off = u64::from(self.next_avail.0 % self.queue_size) * VIRTQ_AVAIL_ELEMENT_SIZE;
let offset = VIRTQ_AVAIL_RING_HEADER_SIZE + elem_off;
let addr = self.avail_ring.checked_add(offset)?;
let head_index: u16 = self
.mem
.load(addr, Ordering::Acquire)
.map(u16::from_le)
.map_err(|_| error!("Failed to read from memory {:x}", addr.raw_value()))
.ok()?;
*self.next_avail += Wrapping(1);
Some(DescriptorChain::new(
self.mem.clone(),
self.desc_table,
self.queue_size,
head_index,
self.access_platform.clone(),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
use crate::mock::MockSplitQueue;
use crate::Descriptor;
use vm_memory::GuestMemoryMmap;
#[test]
fn test_descriptor_and_iterator() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
// q is currently valid
assert!(q.is_valid());
// the chains are (0, 1), (2, 3, 4) and (5, 6)
for j in 0..7 {
let flags = match j {
1 | 6 => 0,
2 | 5 => VIRTQ_DESC_F_NEXT | VIRTQ_DESC_F_WRITE,
4 => VIRTQ_DESC_F_WRITE,
_ => VIRTQ_DESC_F_NEXT,
};
let desc = Descriptor::new((0x1000 * (j + 1)) as u64, 0x1000, flags, j + 1);
vq.desc_table().store(j, desc);
}
vq.avail().ring().ref_at(0).store(u16::to_le(0));
vq.avail().ring().ref_at(1).store(u16::to_le(2));
vq.avail().ring().ref_at(2).store(u16::to_le(5));
vq.avail().idx().store(u16::to_le(3));
let mut i = q.iter().unwrap();
{
let c = i.next().unwrap();
assert_eq!(c.head_index(), 0);
let mut iter = c;
assert!(iter.next().is_some());
assert!(iter.next().is_some());
assert!(iter.next().is_none());
assert!(iter.next().is_none());
}
{
let c = i.next().unwrap();
assert_eq!(c.head_index(), 2);
let mut iter = c.writable();
assert!(iter.next().is_some());
assert!(iter.next().is_some());
assert!(iter.next().is_none());
assert!(iter.next().is_none());
}
{
let c = i.next().unwrap();
assert_eq!(c.head_index(), 5);
let mut iter = c.readable();
assert!(iter.next().is_some());
assert!(iter.next().is_none());
assert!(iter.next().is_none());
}
}
#[test]
fn test_iterator() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
q.state.size = q.state.max_size;
q.state.desc_table = vq.desc_table_addr();
q.state.avail_ring = vq.avail_addr();
q.state.used_ring = vq.used_addr();
assert!(q.is_valid());
{
// an invalid queue should return an iterator with no next
q.state.ready = false;
let mut i = q.iter().unwrap();
assert!(i.next().is_none());
}
q.state.ready = true;
// now let's create two simple descriptor chains
// the chains are (0, 1) and (2, 3, 4)
{
for j in 0..5u16 {
let flags = match j {
1 | 4 => 0,
_ => VIRTQ_DESC_F_NEXT,
};
let desc = Descriptor::new((0x1000 * (j + 1)) as u64, 0x1000, flags, j + 1);
vq.desc_table().store(j, desc);
}
vq.avail().ring().ref_at(0).store(u16::to_le(0));
vq.avail().ring().ref_at(1).store(u16::to_le(2));
vq.avail().idx().store(u16::to_le(2));
let mut i = q.iter().unwrap();
{
let mut c = i.next().unwrap();
assert_eq!(c.head_index(), 0);
c.next().unwrap();
assert!(c.next().is_some());
assert!(c.next().is_none());
assert_eq!(c.head_index(), 0);
}
{
let mut c = i.next().unwrap();
assert_eq!(c.head_index(), 2);
c.next().unwrap();
c.next().unwrap();
c.next().unwrap();
assert!(c.next().is_none());
assert_eq!(c.head_index(), 2);
}
// also test go_to_previous_position() works as expected
{
assert!(i.next().is_none());
i.go_to_previous_position();
let mut c = q.iter().unwrap().next().unwrap();
c.next().unwrap();
c.next().unwrap();
c.next().unwrap();
assert!(c.next().is_none());
}
}
}
}

File diff suppressed because it is too large Load Diff

370
virtio-queue/src/mock.rs Normal file
View File

@@ -0,0 +1,370 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//! Utilities used by unit tests and benchmarks for mocking the driver side
//! of the virtio protocol.
use std::marker::PhantomData;
use std::mem::size_of;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestUsize,
};
use crate::defs::{VIRTQ_DESC_F_INDIRECT, VIRTQ_DESC_F_NEXT};
use crate::{Descriptor, Queue, QueueState, VirtqUsedElem};
/// Wrapper struct used for accessing a particular address of a GuestMemory area.
pub struct Ref<'a, M, T> {
mem: &'a M,
addr: GuestAddress,
phantom: PhantomData<*const T>,
}
impl<'a, M: GuestMemory, T: ByteValued> Ref<'a, M, T> {
fn new(mem: &'a M, addr: GuestAddress) -> Self {
Ref {
mem,
addr,
phantom: PhantomData,
}
}
/// Read an object of type T from the underlying memory found at self.addr.
pub fn load(&self) -> T {
self.mem.read_obj(self.addr).unwrap()
}
/// Write an object of type T from the underlying memory found at self.addr.
pub fn store(&self, val: T) {
self.mem.write_obj(val, self.addr).unwrap()
}
}
/// Wrapper struct used for accessing a subregion of a GuestMemory area.
pub struct ArrayRef<'a, M, T> {
mem: &'a M,
addr: GuestAddress,
len: usize,
phantom: PhantomData<*const T>,
}
impl<'a, M: GuestMemory, T: ByteValued> ArrayRef<'a, M, T> {
fn new(mem: &'a M, addr: GuestAddress, len: usize) -> Self {
ArrayRef {
mem,
addr,
len,
phantom: PhantomData,
}
}
/// Return a `Ref` object pointing to an address defined by a particular
/// index offset in the region.
pub fn ref_at(&self, index: usize) -> Ref<'a, M, T> {
// TODO: add better error handling to the mock logic.
assert!(index < self.len);
let addr = self
.addr
.checked_add((index * size_of::<T>()) as u64)
.unwrap();
Ref::new(self.mem, addr)
}
}
/// Represents a virtio queue ring. The only difference between the used and available rings,
/// is the ring element type.
pub struct SplitQueueRing<'a, M, T: ByteValued> {
flags: Ref<'a, M, u16>,
// The value stored here should more precisely be a `Wrapping<u16>`, but that would require a
// `ByteValued` impl for this type, which is not provided in vm-memory. Implementing the trait
// here would require defining a wrapper for `Wrapping<u16>` and that would be too much for a
// mock framework that is only used in tests.
idx: Ref<'a, M, u16>,
ring: ArrayRef<'a, M, T>,
// `used_event` for `AvailRing`, `avail_event` for `UsedRing`.
event: Ref<'a, M, u16>,
}
impl<'a, M: GuestMemory, T: ByteValued> SplitQueueRing<'a, M, T> {
/// Create a new `SplitQueueRing` instance
pub fn new(mem: &'a M, base: GuestAddress, len: u16) -> Self {
let event_addr = base
.checked_add(4)
.and_then(|a| a.checked_add((size_of::<u16>() * len as usize) as u64))
.unwrap();
let split_queue_ring = SplitQueueRing {
flags: Ref::new(mem, base),
idx: Ref::new(mem, base.checked_add(2).unwrap()),
ring: ArrayRef::new(mem, base.checked_add(4).unwrap(), len as usize),
event: Ref::new(mem, event_addr),
};
split_queue_ring.flags.store(0);
split_queue_ring.idx.store(0);
split_queue_ring.event.store(0);
split_queue_ring
}
/// Return the starting address of the `SplitQueueRing`.
pub fn start(&self) -> GuestAddress {
self.ring.addr
}
/// Return the end address of the `SplitQueueRing`.
pub fn end(&self) -> GuestAddress {
self.start()
.checked_add(self.ring.len as GuestUsize)
.unwrap()
}
/// Return a reference to the idx field.
pub fn idx(&self) -> &Ref<'a, M, u16> {
&self.idx
}
/// Return a reference to the ring field.
pub fn ring(&self) -> &ArrayRef<'a, M, T> {
&self.ring
}
}
/// The available ring is used by the driver to offer buffers to the device.
pub type AvailRing<'a, M> = SplitQueueRing<'a, M, u16>;
/// The used ring is where the device returns buffers once it is done with them.
pub type UsedRing<'a, M> = SplitQueueRing<'a, M, VirtqUsedElem>;
/// Refers to the buffers the driver is using for the device.
pub struct DescriptorTable<'a, M> {
table: ArrayRef<'a, M, Descriptor>,
len: u16,
free_descriptors: Vec<u16>,
}
impl<'a, M: GuestMemory> DescriptorTable<'a, M> {
/// Create a new `DescriptorTable` instance
pub fn new(mem: &'a M, addr: GuestAddress, len: u16) -> Self {
let table = ArrayRef::new(mem, addr, len as usize);
let free_descriptors = (0..len).rev().collect();
DescriptorTable {
table,
len,
free_descriptors,
}
}
/// Read one descriptor from the specified index.
pub fn load(&self, index: u16) -> Descriptor {
self.table.ref_at(index as usize).load()
}
/// Write one descriptor at the specified index.
pub fn store(&self, index: u16, value: Descriptor) {
self.table.ref_at(index as usize).store(value)
}
/// Return the total size of the DescriptorTable in bytes.
pub fn total_size(&self) -> u64 {
(self.len as usize * size_of::<Descriptor>()) as u64
}
/// Create a chain of descriptors.
pub fn build_chain(&mut self, len: u16) -> u16 {
let indices = self
.free_descriptors
.iter()
.copied()
.rev()
.take(usize::from(len))
.collect::<Vec<_>>();
assert_eq!(indices.len(), len as usize);
for (pos, index_value) in indices.iter().copied().enumerate() {
// Addresses and lens constant for now.
let mut desc = Descriptor::new(0x1000, 0x1000, 0, 0);
// It's not the last descriptor in the chain.
if pos < indices.len() - 1 {
desc.set_flags(VIRTQ_DESC_F_NEXT);
desc.set_next(indices[pos + 1]);
} else {
desc.set_flags(0);
}
self.store(index_value, desc);
}
indices[0]
}
}
trait GuestAddressExt {
fn align_up(&self, x: GuestUsize) -> GuestAddress;
}
impl GuestAddressExt for GuestAddress {
fn align_up(&self, x: GuestUsize) -> GuestAddress {
Self((self.0 + (x - 1)) & !(x - 1))
}
}
/// A mock version of the virtio queue implemented from the perspective of the driver.
pub struct MockSplitQueue<'a, M> {
mem: &'a M,
len: u16,
desc_table_addr: GuestAddress,
desc_table: DescriptorTable<'a, M>,
avail_addr: GuestAddress,
avail: AvailRing<'a, M>,
used_addr: GuestAddress,
used: UsedRing<'a, M>,
indirect_addr: GuestAddress,
}
impl<'a, M: GuestMemory> MockSplitQueue<'a, M> {
/// Create a new `MockSplitQueue` instance with 0 as the default guest
/// physical starting address.
pub fn new(mem: &'a M, len: u16) -> Self {
Self::create(mem, GuestAddress(0), len)
}
/// Create a new `MockSplitQueue` instance.
pub fn create(mem: &'a M, start: GuestAddress, len: u16) -> Self {
const AVAIL_ALIGN: GuestUsize = 2;
const USED_ALIGN: GuestUsize = 4;
let desc_table_addr = start;
let desc_table = DescriptorTable::new(mem, desc_table_addr, len);
let avail_addr = start
.checked_add(16 * len as GuestUsize)
.unwrap()
.align_up(AVAIL_ALIGN);
let avail = AvailRing::new(mem, avail_addr, len);
let used_addr = avail.end().align_up(USED_ALIGN);
let used = UsedRing::new(mem, used_addr, len);
let indirect_addr = GuestAddress(0x3000_0000);
MockSplitQueue {
mem,
len,
desc_table_addr,
desc_table,
avail_addr,
avail,
used_addr,
used,
indirect_addr,
}
}
/// Return the starting address of the queue.
pub fn start(&self) -> GuestAddress {
self.desc_table_addr
}
/// Return the end address of the queue.
pub fn end(&self) -> GuestAddress {
self.used.end()
}
/// Descriptor table accessor.
pub fn desc_table(&self) -> &DescriptorTable<'a, M> {
&self.desc_table
}
/// Available ring accessor.
pub fn avail(&self) -> &AvailRing<M> {
&self.avail
}
/// Used ring accessor.
pub fn used(&self) -> &UsedRing<M> {
&self.used
}
/// Return the starting address of the descriptor table.
pub fn desc_table_addr(&self) -> GuestAddress {
self.desc_table_addr
}
/// Return the starting address of the available ring.
pub fn avail_addr(&self) -> GuestAddress {
self.avail_addr
}
/// Return the starting address of the used ring.
pub fn used_addr(&self) -> GuestAddress {
self.used_addr
}
fn update_avail_idx(&mut self, value: u16) {
let avail_idx = self.avail.idx.load();
self.avail.ring.ref_at(avail_idx as usize).store(value);
self.avail.idx.store(avail_idx.wrapping_add(1));
}
fn alloc_indirect_chain(&mut self, len: u16) -> GuestAddress {
// To simplify things for now, we round up the table len as a multiple of 16. When this is
// no longer the case, we should make sure the starting address of the descriptor table
// we're creating below is properly aligned.
let table_len = if len % 16 == 0 {
len
} else {
16 * (len / 16 + 1)
};
let mut table = DescriptorTable::new(self.mem, self.indirect_addr, table_len);
let head_decriptor_index = table.build_chain(len);
// When building indirect descriptor tables, the descriptor at index 0 is supposed to be
// first in the resulting chain. Just making sure our logic actually makes that happen.
assert_eq!(head_decriptor_index, 0);
let table_addr = self.indirect_addr;
self.indirect_addr = self.indirect_addr.checked_add(table.total_size()).unwrap();
table_addr
}
/// Add a descriptor chain to the table.
pub fn add_chain(&mut self, len: u16) {
let head_idx = self.desc_table.build_chain(len);
self.update_avail_idx(head_idx);
}
/// Add an indirect descriptor chain to the table.
pub fn add_indirect_chain(&mut self, len: u16) {
let head_idx = self.desc_table.build_chain(1);
// We just allocate the indirect table and forget about it for now.
let indirect_addr = self.alloc_indirect_chain(len);
let mut desc = self.desc_table.load(head_idx);
desc.set_flags(VIRTQ_DESC_F_INDIRECT);
desc.set_addr(indirect_addr.raw_value());
desc.set_len(u32::from(len) * size_of::<Descriptor>() as u32);
self.desc_table.store(head_idx, desc);
self.update_avail_idx(head_idx);
}
/// Creates a new `Queue`, using the underlying memory regions represented
/// by the `MockSplitQueue`.
pub fn create_queue<A: GuestAddressSpace>(&self, a: A) -> Queue<A, QueueState> {
let mut q = Queue::<A, QueueState>::new(a, self.len);
q.state.size = self.len;
q.state.ready = true;
q.state.desc_table = self.desc_table_addr;
q.state.avail_ring = self.avail_addr;
q.state.used_ring = self.used_addr;
q
}
}

683
virtio-queue/src/queue.rs Normal file
View File

@@ -0,0 +1,683 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright © 2019 Intel Corporation
//
// Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::num::Wrapping;
use std::ops::Deref;
use std::sync::atomic::Ordering;
use vm_memory::GuestAddressSpace;
use crate::{AvailIter, Error, QueueGuard, QueueState, QueueStateGuard, QueueStateT};
/// A convenient wrapper struct for a virtio queue, with associated `GuestMemory` object.
///
/// # Example
///
/// ```rust
/// use virtio_queue::{Queue, QueueState};
/// use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
///
/// let m = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
/// let mut queue = Queue::<&GuestMemoryMmap, QueueState>::new(&m, 1024);
///
/// // First, the driver sets up the queue; this set up is done via writes on the bus (PCI, MMIO).
/// queue.set_size(8);
/// queue.set_desc_table_address(Some(0x1000), None);
/// queue.set_avail_ring_address(Some(0x2000), None);
/// queue.set_used_ring_address(Some(0x3000), None);
/// queue.set_event_idx(true);
/// queue.set_ready(true);
/// // The user should check if the queue is valid before starting to use it.
/// assert!(queue.is_valid());
///
/// // Here the driver would add entries in the available ring and then update the `idx` field of
/// // the available ring (address = 0x2000 + 2).
/// m.write_obj(3, GuestAddress(0x2002));
///
/// loop {
/// queue.disable_notification().unwrap();
///
/// // Consume entries from the available ring.
/// while let Some(chain) = queue.iter().unwrap().next() {
/// // Process the descriptor chain, and then add an entry in the used ring and optionally
/// // notify the driver.
/// queue.add_used(chain.head_index(), 0x100).unwrap();
///
/// if queue.needs_notification().unwrap() {
/// // Here we would notify the driver it has new entries in the used ring to consume.
/// }
/// }
/// if !queue.enable_notification().unwrap() {
/// break;
/// }
/// }
///
/// // We can reset the queue at some point.
/// queue.reset();
/// // The queue should not be ready after reset.
/// assert!(!queue.ready());
/// ```
#[derive(Clone, Debug)]
pub struct Queue<M: GuestAddressSpace, S: QueueStateT = QueueState> {
/// Guest memory object associated with the queue.
pub mem: M,
/// Virtio queue state.
pub state: S,
}
impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
/// Construct an empty virtio queue with the given `max_size`.
///
/// # Arguments
/// * `mem` - the guest memory object that can be used to access the queue buffers.
/// * `max_size` - the maximum size (and the default one) of the queue.
pub fn new(mem: M, max_size: u16) -> Self {
Queue {
mem,
state: S::new(max_size),
}
}
/// Check whether the queue configuration is valid.
pub fn is_valid(&self) -> bool {
self.state.is_valid(self.mem.memory().deref())
}
/// Reset the queue to the initial state.
pub fn reset(&mut self) {
self.state.reset()
}
/// Get an exclusive reference to the underlying `QueueState` object.
///
/// Logically this method will acquire the underlying lock protecting the `QueueState` Object.
/// The lock will be released when the returned object gets dropped.
pub fn lock(&mut self) -> <S as QueueStateGuard>::G {
self.state.lock()
}
/// Get an exclusive reference to the underlying `QueueState` object with an associated
/// `GuestMemory` object.
///
/// Logically this method will acquire the underlying lock protecting the `QueueState` Object.
/// The lock will be released when the returned object gets dropped.
pub fn lock_with_memory(
&mut self,
) -> QueueGuard<<M as GuestAddressSpace>::T, <S as QueueStateGuard>::G> {
QueueGuard::new(self.state.lock(), self.mem.memory())
}
/// Get the maximum size of the virtio queue.
pub fn max_size(&self) -> u16 {
self.state.max_size()
}
/// Configure the queue size for the virtio queue.
///
/// # Arguments
/// * `size` - the queue size; it should be a power of two, different than 0 and less than or
/// equal to the value reported by `max_size()`, otherwise the queue size remains the
/// default one (which is the maximum one).
pub fn set_size(&mut self, size: u16) {
self.state.set_size(size);
}
/// Check whether the queue is ready to be processed.
pub fn ready(&self) -> bool {
self.state.ready()
}
/// Configure the queue to the `ready for processing` state.
///
/// # Arguments
/// * `ready` - a boolean to indicate whether the queue is ready to be used or not.
pub fn set_ready(&mut self, ready: bool) {
self.state.set_ready(ready)
}
/// Set the descriptor table address for the queue.
///
/// The descriptor table address is 64-bit, the corresponding part will be updated if 'low'
/// and/or `high` is `Some` and valid.
///
/// # Arguments
/// * `low` - an optional value for the lowest 32 bits of the address.
/// * `high` - an optional value for the highest 32 bits of the address.
pub fn set_desc_table_address(&mut self, low: Option<u32>, high: Option<u32>) {
self.state.set_desc_table_address(low, high);
}
/// Set the available ring address for the queue.
///
/// The available ring address is 64-bit, the corresponding part will be updated if 'low'
/// and/or `high` is `Some` and valid.
///
/// # Arguments
/// * `low` - an optional value for the lowest 32 bits of the address.
/// * `high` - an optional value for the highest 32 bits of the address.
pub fn set_avail_ring_address(&mut self, low: Option<u32>, high: Option<u32>) {
self.state.set_avail_ring_address(low, high);
}
/// Set the used ring address for the queue.
///
/// The used ring address is 64-bit, the corresponding part will be updated if 'low'
/// and/or `high` is `Some` and valid.
///
/// # Arguments
/// * `low` - an optional value for the lowest 32 bits of the address.
/// * `high` - an optional value for the highest 32 bits of the address.
pub fn set_used_ring_address(&mut self, low: Option<u32>, high: Option<u32>) {
self.state.set_used_ring_address(low, high);
}
/// Enable/disable the VIRTIO_F_RING_EVENT_IDX feature for interrupt coalescing.
///
/// # Arguments
/// * `enabled` - a boolean to indicate whether the VIRTIO_F_RING_EVENT_IDX feature was
/// successfully negotiated or not.
pub fn set_event_idx(&mut self, enabled: bool) {
self.state.set_event_idx(enabled)
}
/// Read the `idx` field from the available ring.
///
/// # Arguments
/// * `order` - the memory ordering used to access the `idx` field from memory.
pub fn avail_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error> {
self.state.avail_idx(self.mem.memory().deref(), order)
}
/// Reads the `idx` field from the used ring.
///
/// # Arguments
/// * `order` - the memory ordering used to access the `idx` field from memory.
pub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error> {
self.state.used_idx(self.mem.memory().deref(), order)
}
/// Put a used descriptor head into the used ring.
///
/// # Arguments
/// * `head_index` - the index of the used descriptor chain.
/// * `len` - the total length of the descriptor chain which was used (written to).
pub fn add_used(&mut self, head_index: u16, len: u32) -> Result<(), Error> {
self.state
.add_used(self.mem.memory().deref(), head_index, len)
}
/// Enable notification events from the guest driver.
///
/// Return true if one or more descriptors can be consumed from the available ring after
/// notifications were enabled (and thus it's possible there will be no corresponding
/// notification).
pub fn enable_notification(&mut self) -> Result<bool, Error> {
self.state.enable_notification(self.mem.memory().deref())
}
/// Disable notification events from the guest driver.
pub fn disable_notification(&mut self) -> Result<(), Error> {
self.state.disable_notification(self.mem.memory().deref())
}
/// Check whether a notification to the guest is needed.
///
/// Please note this method has side effects: once it returns `true`, it considers the
/// driver will actually be notified, remember the associated index in the used ring, and
/// won't return `true` again until the driver updates `used_event` and/or the notification
/// conditions hold once more.
pub fn needs_notification(&mut self) -> Result<bool, Error> {
self.state.needs_notification(self.mem.memory().deref())
}
/// Return the index of the next entry in the available ring.
pub fn next_avail(&self) -> u16 {
self.state.next_avail()
}
/// Returns the index for the next descriptor in the used ring.
pub fn next_used(&self) -> u16 {
self.state.next_used()
}
/// Set the index of the next entry in the available ring.
///
/// # Arguments
/// * `next_avail` - the index of the next available ring entry.
pub fn set_next_avail(&mut self, next_avail: u16) {
self.state.set_next_avail(next_avail);
}
/// Sets the index for the next descriptor in the used ring.
///
/// # Arguments
/// * `next_used` - the index of the next used ring entry.
pub fn set_next_used(&mut self, next_used: u16) {
self.state.set_next_used(next_used);
}
}
impl<M: GuestAddressSpace> Queue<M, QueueState> {
/// A consuming iterator over all available descriptor chain heads offered by the driver.
pub fn iter(&mut self) -> Result<AvailIter<'_, M::T>, Error> {
self.state.iter(self.mem.memory())
}
/// Set the queue to "ready", and update desc_table, avail_ring and
/// used_ring addresses based on the AccessPlatform handler.
pub fn enable(&mut self, set: bool) {
self.state.enable(set)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::defs::{
DEFAULT_AVAIL_RING_ADDR, DEFAULT_DESC_TABLE_ADDR, DEFAULT_USED_RING_ADDR,
VIRTQ_DESC_F_NEXT, VIRTQ_USED_F_NO_NOTIFY,
};
use crate::mock::MockSplitQueue;
use crate::Descriptor;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemoryMmap};
#[test]
fn test_queue_is_valid() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
// q is currently valid
assert!(q.is_valid());
// shouldn't be valid when not marked as ready
q.set_ready(false);
assert!(!q.ready());
assert!(!q.is_valid());
q.set_ready(true);
// shouldn't be allowed to set a size > max_size
q.set_size(q.max_size() << 1);
assert_eq!(q.state.size, q.max_size());
// or set the size to 0
q.set_size(0);
assert_eq!(q.state.size, q.max_size());
// or set a size which is not a power of 2
q.set_size(11);
assert_eq!(q.state.size, q.max_size());
// but should be allowed to set a size if 0 < size <= max_size and size is a power of two
q.set_size(4);
assert_eq!(q.state.size, 4);
q.state.size = q.max_size();
// shouldn't be allowed to set an address that breaks the alignment constraint
q.set_desc_table_address(Some(0xf), None);
assert_eq!(q.state.desc_table.0, vq.desc_table_addr().0);
// should be allowed to set an aligned out of bounds address
q.set_desc_table_address(Some(0xffff_fff0), None);
assert_eq!(q.state.desc_table.0, 0xffff_fff0);
// but shouldn't be valid
assert!(!q.is_valid());
// but should be allowed to set a valid description table address
q.set_desc_table_address(Some(0x10), None);
assert_eq!(q.state.desc_table.0, 0x10);
assert!(q.is_valid());
let addr = vq.desc_table_addr().0;
q.set_desc_table_address(Some(addr as u32), Some((addr >> 32) as u32));
// shouldn't be allowed to set an address that breaks the alignment constraint
q.set_avail_ring_address(Some(0x1), None);
assert_eq!(q.state.avail_ring.0, vq.avail_addr().0);
// should be allowed to set an aligned out of bounds address
q.set_avail_ring_address(Some(0xffff_fffe), None);
assert_eq!(q.state.avail_ring.0, 0xffff_fffe);
// but shouldn't be valid
assert!(!q.is_valid());
// but should be allowed to set a valid available ring address
q.set_avail_ring_address(Some(0x2), None);
assert_eq!(q.state.avail_ring.0, 0x2);
assert!(q.is_valid());
let addr = vq.avail_addr().0;
q.set_avail_ring_address(Some(addr as u32), Some((addr >> 32) as u32));
// shouldn't be allowed to set an address that breaks the alignment constraint
q.set_used_ring_address(Some(0x3), None);
assert_eq!(q.state.used_ring.0, vq.used_addr().0);
// should be allowed to set an aligned out of bounds address
q.set_used_ring_address(Some(0xffff_fffc), None);
assert_eq!(q.state.used_ring.0, 0xffff_fffc);
// but shouldn't be valid
assert!(!q.is_valid());
// but should be allowed to set a valid used ring address
q.set_used_ring_address(Some(0x4), None);
assert_eq!(q.state.used_ring.0, 0x4);
let addr = vq.used_addr().0;
q.set_used_ring_address(Some(addr as u32), Some((addr >> 32) as u32));
assert!(q.is_valid());
}
#[test]
fn test_add_used() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
assert_eq!(u16::from_le(vq.used().idx().load()), 0);
// index too large
assert!(q.add_used(16, 0x1000).is_err());
assert_eq!(u16::from_le(vq.used().idx().load()), 0);
// should be ok
q.add_used(1, 0x1000).unwrap();
assert_eq!(q.state.next_used, Wrapping(1));
assert_eq!(u16::from_le(vq.used().idx().load()), 1);
let x = vq.used().ring().ref_at(0).load();
assert_eq!(x.id(), 1);
assert_eq!(x.len(), 0x1000);
}
#[test]
fn test_reset_queue() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
q.set_size(8);
// The address set by `MockSplitQueue` for the descriptor table is DEFAULT_DESC_TABLE_ADDR,
// so let's change it for testing the reset.
q.set_desc_table_address(Some(0x5000), None);
// Same for `event_idx_enabled`, `next_avail` `next_used` and `signalled_used`.
q.set_event_idx(true);
q.set_next_avail(2);
q.add_used(1, 200).unwrap();
q.state.signalled_used = Some(Wrapping(15));
assert_eq!(q.state.size, 8);
// `create_queue` also marks the queue as ready.
assert!(q.state.ready);
assert_ne!(q.state.desc_table, GuestAddress(DEFAULT_DESC_TABLE_ADDR));
assert_ne!(q.state.avail_ring, GuestAddress(DEFAULT_AVAIL_RING_ADDR));
assert_ne!(q.state.used_ring, GuestAddress(DEFAULT_USED_RING_ADDR));
assert_ne!(q.state.next_avail, Wrapping(0));
assert_ne!(q.state.next_used, Wrapping(0));
assert_ne!(q.state.signalled_used, None);
assert!(q.state.event_idx_enabled);
q.reset();
assert_eq!(q.state.size, 16);
assert!(!q.state.ready);
assert_eq!(q.state.desc_table, GuestAddress(DEFAULT_DESC_TABLE_ADDR));
assert_eq!(q.state.avail_ring, GuestAddress(DEFAULT_AVAIL_RING_ADDR));
assert_eq!(q.state.used_ring, GuestAddress(DEFAULT_USED_RING_ADDR));
assert_eq!(q.state.next_avail, Wrapping(0));
assert_eq!(q.state.next_used, Wrapping(0));
assert_eq!(q.state.signalled_used, None);
assert!(!q.state.event_idx_enabled);
}
#[test]
fn test_needs_notification() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let qsize = 16;
let vq = MockSplitQueue::new(m, qsize);
let mut q = vq.create_queue(m);
let avail_addr = vq.avail_addr();
// It should always return true when EVENT_IDX isn't enabled.
for i in 0..qsize {
q.state.next_used = Wrapping(i);
assert!(q.needs_notification().unwrap());
}
m.write_obj::<u16>(
u16::to_le(4),
avail_addr.unchecked_add(4 + qsize as u64 * 2),
)
.unwrap();
q.state.set_event_idx(true);
// Incrementing up to this value causes an `u16` to wrap back to 0.
let wrap = u32::from(u16::MAX) + 1;
for i in 0..wrap + 12 {
q.state.next_used = Wrapping(i as u16);
// Let's test wrapping around the maximum index value as well.
let expected = i == 5 || i == (5 + wrap) || q.state.signalled_used.is_none();
assert_eq!(q.needs_notification().unwrap(), expected);
}
m.write_obj::<u16>(8, avail_addr.unchecked_add(4 + qsize as u64 * 2))
.unwrap();
// Returns `false` because `signalled_used` already passed this value.
assert!(!q.needs_notification().unwrap());
m.write_obj::<u16>(15, avail_addr.unchecked_add(4 + qsize as u64 * 2))
.unwrap();
assert!(!q.needs_notification().unwrap());
q.state.next_used = Wrapping(15);
assert!(!q.needs_notification().unwrap());
q.state.next_used = Wrapping(0);
assert!(q.needs_notification().unwrap());
assert!(!q.needs_notification().unwrap());
m.write_obj::<u16>(u16::MAX - 3, avail_addr.unchecked_add(4 + qsize as u64 * 2))
.unwrap();
q.state.next_used = Wrapping(u16::MAX - 2);
// Returns `true` because the value we wrote in the `used_event` < the next used value and
// the last `signalled_used` is 0.
assert!(q.needs_notification().unwrap());
}
#[test]
fn test_enable_disable_notification() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
let used_addr = vq.used_addr();
assert!(!q.state.event_idx_enabled);
q.enable_notification().unwrap();
let v = m.read_obj::<u16>(used_addr).map(u16::from_le).unwrap();
assert_eq!(v, 0);
q.disable_notification().unwrap();
let v = m.read_obj::<u16>(used_addr).map(u16::from_le).unwrap();
assert_eq!(v, VIRTQ_USED_F_NO_NOTIFY);
q.enable_notification().unwrap();
let v = m.read_obj::<u16>(used_addr).map(u16::from_le).unwrap();
assert_eq!(v, 0);
q.set_event_idx(true);
let avail_addr = vq.avail_addr();
m.write_obj::<u16>(u16::to_le(2), avail_addr.unchecked_add(2))
.unwrap();
assert!(q.enable_notification().unwrap());
q.state.next_avail = Wrapping(2);
assert!(!q.enable_notification().unwrap());
m.write_obj::<u16>(u16::to_le(8), avail_addr.unchecked_add(2))
.unwrap();
assert!(q.enable_notification().unwrap());
q.state.next_avail = Wrapping(8);
assert!(!q.enable_notification().unwrap());
}
#[test]
fn test_consume_chains_with_notif() {
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
// q is currently valid.
assert!(q.is_valid());
// The chains are (0, 1), (2, 3, 4), (5, 6), (7, 8), (9, 10, 11, 12).
for i in 0..13 {
let flags = match i {
1 | 4 | 6 | 8 | 12 => 0,
_ => VIRTQ_DESC_F_NEXT,
};
let desc = Descriptor::new((0x1000 * (i + 1)) as u64, 0x1000, flags, i + 1);
vq.desc_table().store(i, desc);
}
vq.avail().ring().ref_at(0).store(u16::to_le(0));
vq.avail().ring().ref_at(1).store(u16::to_le(2));
vq.avail().ring().ref_at(2).store(u16::to_le(5));
vq.avail().ring().ref_at(3).store(u16::to_le(7));
vq.avail().ring().ref_at(4).store(u16::to_le(9));
// Let the device know it can consume chains with the index < 2.
vq.avail().idx().store(u16::to_le(2));
// No descriptor chains are consumed at this point.
assert_eq!(q.next_avail(), 0);
let mut i = 0;
loop {
i += 1;
q.disable_notification().unwrap();
while let Some(_chain) = q.iter().unwrap().next() {
// Here the device would consume entries from the available ring, add an entry in
// the used ring and optionally notify the driver. For the purpose of this test, we
// don't need to do anything with the chain, only consume it.
}
if !q.enable_notification().unwrap() {
break;
}
}
// The chains should be consumed in a single loop iteration because there's nothing updating
// the `idx` field of the available ring in the meantime.
assert_eq!(i, 1);
// The next chain that can be consumed should have index 2.
assert_eq!(q.next_avail(), 2);
// Let the device know it can consume one more chain.
vq.avail().idx().store(u16::to_le(3));
i = 0;
loop {
i += 1;
q.disable_notification().unwrap();
while let Some(_chain) = q.iter().unwrap().next() {
// In a real use case, we would do something with the chain here.
}
// For the simplicity of the test we are updating here the `idx` value of the available
// ring. Ideally this should be done on a separate thread.
// Because of this update, the loop should be iterated again to consume the new
// available descriptor chains.
vq.avail().idx().store(u16::to_le(4));
if !q.enable_notification().unwrap() {
break;
}
}
assert_eq!(i, 2);
// The next chain that can be consumed should have index 4.
assert_eq!(q.next_avail(), 4);
// Set an `idx` that is bigger than the number of entries added in the ring.
// This is an allowed scenario, but the indexes of the chain will have unexpected values.
vq.avail().idx().store(u16::to_le(7));
loop {
q.disable_notification().unwrap();
while let Some(_chain) = q.iter().unwrap().next() {
// In a real use case, we would do something with the chain here.
}
if !q.enable_notification().unwrap() {
break;
}
}
assert_eq!(q.next_avail(), 7);
}
#[test]
fn test_invalid_avail_idx() {
// This is a negative test for the following MUST from the spec: `A driver MUST NOT
// decrement the available idx on a virtqueue (ie. there is no way to “unexpose” buffers).`.
// We validate that for this misconfiguration, the device does not panic.
let m = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let vq = MockSplitQueue::new(m, 16);
let mut q = vq.create_queue(m);
// q is currently valid.
assert!(q.is_valid());
// The chains are (0, 1), (2, 3, 4), (5, 6).
for i in 0..7 {
let flags = match i {
1 | 4 | 6 => 0,
_ => VIRTQ_DESC_F_NEXT,
};
let desc = Descriptor::new((0x1000 * (i + 1)) as u64, 0x1000, flags, i + 1);
vq.desc_table().store(i, desc);
}
vq.avail().ring().ref_at(0).store(u16::to_le(0));
vq.avail().ring().ref_at(1).store(u16::to_le(2));
vq.avail().ring().ref_at(2).store(u16::to_le(5));
// Let the device know it can consume chains with the index < 2.
vq.avail().idx().store(u16::to_le(3));
// No descriptor chains are consumed at this point.
assert_eq!(q.next_avail(), 0);
loop {
q.disable_notification().unwrap();
while let Some(_chain) = q.iter().unwrap().next() {
// Here the device would consume entries from the available ring, add an entry in
// the used ring and optionally notify the driver. For the purpose of this test, we
// don't need to do anything with the chain, only consume it.
}
if !q.enable_notification().unwrap() {
break;
}
}
// The next chain that can be consumed should have index 3.
assert_eq!(q.next_avail(), 3);
assert_eq!(q.avail_idx(Ordering::Acquire).unwrap(), Wrapping(3));
assert!(q.lock().ready());
// Decrement `idx` which should be forbidden. We don't enforce this thing, but we should
// test that we don't panic in case the driver decrements it.
vq.avail().idx().store(u16::to_le(1));
loop {
q.disable_notification().unwrap();
while let Some(_chain) = q.iter().unwrap().next() {
// In a real use case, we would do something with the chain here.
}
if !q.enable_notification().unwrap() {
break;
}
}
}
}

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