Compare commits

...

2306 Commits

Author SHA1 Message Date
Rob Bradford
198bd55122 build, release-notes.md: Document 0.10.0 release
Update release notes and version number for the new release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 14:06:10 +01:00
Sebastien Boeuf
555c5c5d9c vmm: Add missing syscalls to signal thread
When the VMM is terminated by receiving a SIGTERM signal, the signal
handler thread must be able to invoke ioctl(TCGETS) and ioctl(TCSETS)
without error.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-18 13:40:10 +01:00
Rob Bradford
41a9b1adef vmm: Add missing syscall to vCPU thread
Fixes: #1717

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 13:40:10 +01:00
Rob Bradford
036c2e5e45 Jenkinsfile: Remove "Build" steps from Jenkinsfile
Build testing of changes happens on GitHub actions and the integration
tests will build the binary (with different feature flags) again. So
these earlier build operations are just wasted time on the critical
path.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 12:48:30 +01:00
Rob Bradford
66352b100f README: Reference the aarch64 tracking issue.
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
8589d3f985 README: Fix missing punctuation
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
5d535853f4 README: Update table of contents
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
98bce5e044 README: Standardise project nomenclature
Only use `cloud-hypervisor` when referring to the binary itself and
prefer Cloud Hypervisor when referring to the project.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
ce6353818f README: Update status section
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
ea44d0a433 README: Include bzImage as a supported direct kernel boot method
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
6d0b05c6b3 README: Update operating system and architecture support statements
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
ab80789747 README: Configurable hotplug is no longer an objective
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
5506908199 README: Remove KVM exclusivity
With our hypervisor crate we are no aiming to be KVM exclusive.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
b666d40f9d README: Remove security reporting guidelines
These guidelines are no longer correct remove them as they are
unhelpful.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Rob Bradford
f0fae3e8b6 README: Remove pre-production disclaimer
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-18 10:25:04 +01:00
Sebastien Boeuf
b8bbe244b7 block_util: Ensure all io_uring operations are asynchronous
Some operations complete directly after they have been submitted, which
means they are not submitted asynchronously and therefore they don't
generate any ioevent. This is the reason why we are not processing some
of the completed operations, which leads to some unpredictable
behaviors.

Forcing all io_uring operations submitted to the SQE to be asynchronous
helps simplifying the code as it ensures the completion of every
operation will generate an ioevent, therefore no operation is missed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-17 23:16:27 +02:00
dependabot-preview[bot]
144f0839ae build(deps): bump cc from 1.0.59 to 1.0.60
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.59 to 1.0.60.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.59...1.0.60)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-17 07:43:00 +00:00
Sebastien Boeuf
5a3d54fa19 ci: Extend virtio-mem integration test with reboot
Now that virtio-mem supports reboot, we extend the existing integration
tests to validate the amount of RAM after reboot is the same as before
the reboot, but also that we can still resize down the VM or the memory
zone after the reboot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
46d972e402 virtio-devices: mem: Add missing syscall to seccomp filters
The missing syscall rt_sigprocmask(2) was triggered for the musl build
upon rebooting the VM, and was causing the VM to be killed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
87bb041101 resources: x86_64: Enable auto onlining of memory blocks
In order to facilitate the memory hotplug for our users, let's enable
the automatic memory onlining in our guest kernel by activating the
kernel config option 'CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE'.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
1e1a50ef70 vmm: Update memory configuration upon virtio-mem resizing
Based on all the preparatory work achieved through previous commits,
this patch updates the 'hotplugged_size' field for both MemoryConfig and
MemoryZoneConfig structures when either the whole memory is resized, or
simply when a memory zone is resized.

This fixes the lack of support for rebooting a VM with the right amount
of memory plugged in.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
de2b917f55 vmm: Add hotplugged_size to VirtioMemZone
Adding a new field to VirtioMemZone structure, as it lets us associate
with a particular virtio-mem region the amount of memory that should be
plugged in at boot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
3faf8605f3 vmm: Group virtio-mem fields under a dedicated structure
This patch simplifies the code as we have one single Option for the
VirtioMemZone. This also prepares for storing additional information
related to the virtio-mem region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
4e1b78e1ff vmm: Add 'hotplugged_size' to memory parameters
Add the new option 'hotplugged_size' to both --memory-zone and --memory
parameters so that we can let the user specify a certain amount of
memory being plugged at boot.

This is also part of making sure we can store the virtio-mem size over a
reboot of the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Hui Zhu
33a1e37c35 virtio-devices: mem: Allow for an initial size
This commit gives the possibility to create a virtio-mem device with
some memory already plugged into it. This is preliminary work to be
able to reboot a VM with the virtio-mem region being already resized.

Signed-off-by: Hui Zhu <teawater@antfin.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
8b5202aa5a vmm: Always add virtio-mem region upon VM creation
Now that e820 tables are created from the 'boot_guest_memory', we can
simplify the memory manager code by adding the virtio-mem regions when
they are created. There's no need to wait for the first hotplug to
insert these regions.

This also anticipates the need for starting a VM with some memory
already plugged into the virtio-mem region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
66fc557015 vmm: Store boot guest memory and use it for boot sequence
In order to differentiate the 'boot' memory regions from the virtio-mem
regions, we store what we call 'boot_guest_memory'. This is useful to
provide the adequate list of regions to the configure_system() function
as it expects only the list of regions that should be exposed through
the e820 table.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
9d8672afc6 ci: Extend guest NUMA integration test with memory zone resizing
Extend the existing test to validate that each NUMA node gets assigned
the right amount of memory after each memory zone has been resized.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
5823c12eab ci: Extend memory zone integration test with 'resize-zone'
Now that we can resize each memory zone independently, this commit
extends the memory zone related test by validating 'vm.resize-zone'
works correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
1798ed8194 vmm: virtio-mem: Enforce alignment and size requirements
The virtio-mem driver is generating some warnings regarding both size
and alignment of the virtio-mem region if not based on 128MiB:

The alignment of the physical start address can make some memory
unusable.
The alignment of the physical end address can make some memory
unusable.

For these reasons, the current patch enforces virtio-mem regions to be
128MiB aligned and checks the size provided by the user is a multiple of
128MiB.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
eb7b923e22 vmm: Create virtio-mem device with appropriate NUMA node
Now that virtio-mem device accept a guest NUMA node as parameter, we
retrieve this information from the list of NUMA nodes. Based on the
memory zone associated with the virtio-mem device, we obtain the NUMA
node identifier, which we provide to the virtio-mem device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
dcedd4cded virtio-devices: virtio-mem: Add NUMA support
Implement support for associating a virtio-mem device with a specific
guest NUMA node, based on the ACPI proximity domain identifier.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
0658559880 vmm: memory_manager: Rename 'use_zones' with 'user_provided_zones'
This brings more clarity on the meaning of this boolean.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
775f3346e3 vmm: Rename 'virtiomem' to 'virtio_mem'
For more consistency and help reading the code better, this commit
renames all 'virtiomem*' variables into 'virtio_mem*'.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
bc1bbb6dc4 virtio-devices: virtio-mem: Add missing syscalls
By testing manually the memory resizing through virtio-mem, several
missing syscalls have been identified.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
015c78411e vmm: Add a 'resize-zone' action to the API actions
Implement a new VM action called 'resize-zone' allowing the user to
resize one specific memory zone at a time. This relies on all the
preliminary work from the previous commits to resize each virtio-mem
device independently from each others.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
141df701dd vmm: memory_manager: Make virtiomem_resize function generic
By adding a new parameter 'id' to the virtiomem_resize() function, we
prepare this function to be usable for both global memory resizing and
memory zone resizing.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
34331d3e72 vmm: memory_manager: Fix virtio-mem resize
It's important to return the region covered by virtio-mem the first time
it is inserted as the device manager must update all devices with this
information.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
adc59a6f15 vmm: memory_manager: Create one virtio-mem per memory zone
Based on the previous code changes, we can now update the MemoryManager
code to create one virtio-mem region and resizing handler per memory
zone. This will naturally create one virtio-mem device per memory zone
from the DeviceManager's code which has been previously updated as well.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
c645a72c17 vmm: Add 'hotplug_size' to memory zones
In anticipation for resizing support of an individual memory zone,
this commit introduces a new option 'hotplug_size' to '--memory-zone'
parameter. This defines the amount of memory that can be added through
each specific memory zone.

Because memory zone resize is tied to virtio-mem, make sure the user
selects 'virtio-mem' hotplug method, otherwise return an error.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
30ff7e108f vmm: Prepare code to accept multiple virtio-mem devices
Both MemoryManager and DeviceManager are updated through this commit to
handle the creation of multiple virtio-mem devices if needed. For now,
only the framework is in place, but the behavior remains the same, which
means only the memory zone created from '--memory' generates a
virtio-mem region that can be used for resize.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Sebastien Boeuf
b173b6c5b4 vmm: Create a MemoryZone structure
In order to anticipate the need for storing memory regions along with
virtio-mem information for each memory zone, we create a new structure
MemoryZone that will replace Vec<Arc<GuestRegionMmap>> in the hash map
MemoryZones.

This makes thing more logical as MemoryZones becomes a list of
MemoryZone sorted by their identifier.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 19:20:04 +02:00
Rob Bradford
27c28fa3b0 vmm, arch: Enable KVM HyperV support
Inject CPUID leaves for advertising KVM HyperV support when the
"kvm_hyperv" toggle is enabled. Currently we only enable a selection of
features required to boot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-16 16:08:01 +01:00
Rob Bradford
da642fcf7f hypervisor: Add "HyperV" exit to list of KVM exits
Currently we don't need to do anything to service these exits but when
the synthetic interrupt controller is active an exit will be triggered
to notify the VMM of details of the synthetic interrupt page.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-16 16:08:01 +01:00
Rob Bradford
9b48ee38cb hypervisor: Support enabling HyperV synthetic interrupt controller
This adds a KVM HyperV synthetic interrupt controller in place of the
emulated PIC.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-16 16:08:01 +01:00
Rob Bradford
5495ab7415 vmm: Add "kvm_hyperv" toggle to "--cpus"
This turns on the KVM HyperV emulation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-16 16:08:01 +01:00
Rob Bradford
c03dbe8cc7 virtio-devices: block: Support multiple data descriptors
The Windows virtio block driver puts multiple data descriptors between
the header and the status footer. To handle this when parsing iterate
over the descriptor chain until the end is reached accumulating the
address and length pairs in a vector. For execution iterate over the
vector and make sequential reads from the disk for each data descriptor.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 16:13:24 +02:00
Sebastien Boeuf
5f6432830c block_util: io_uring: Move to vectored I/O
In anticipation for supporting multiple virtio descriptors, let's make
sure the read/write operations are performed with vectored I/O.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 16:13:24 +02:00
Sebastien Boeuf
b3435d51d9 vmm: cpu: Add missing io_uring syscalls to vCPU threads
Some of the io_uring setup happens upon activation of the virtio-blk
device, which is initially triggered through an MMIO VM exit. That's why
the vCPU threads must authorize io_uring related syscalls.

This commit ensures the virtio-blk io_uring implementation can be used
along with the seccomp filters enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-16 11:59:47 +02:00
dependabot-preview[bot]
3d7e7d3869 build(deps): bump kvm-ioctls from f5312ea to 6442739
Bumps [kvm-ioctls](https://github.com/cloud-hypervisor/kvm-ioctls) from `f5312ea` to `6442739`.
- [Release notes](https://github.com/cloud-hypervisor/kvm-ioctls/releases)
- [Commits](f5312ea173...64427395b6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-15 16:47:55 +00:00
dependabot-preview[bot]
ae35967f02 build(deps): bump syn from 1.0.40 to 1.0.41
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.40 to 1.0.41.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.40...1.0.41)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-14 17:16:43 +00:00
dependabot-preview[bot]
1ab12c47b6 build(deps): bump serde from 1.0.115 to 1.0.116
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.115 to 1.0.116.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.115...v1.0.116)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-14 06:52:01 +00:00
dependabot-preview[bot]
701f3ae475 build(deps): bump miniz_oxide from 0.4.1 to 0.4.2
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/Frommi/miniz_oxide/releases)
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/compare/0.4.1...0.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-14 05:54:50 +00:00
dependabot-preview[bot]
a3bf981b94 build(deps): bump serde_derive from 1.0.115 to 1.0.116
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.115 to 1.0.116.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.115...v1.0.116)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-14 05:54:33 +00:00
Rob Bradford
bd463324f3 build: Move to rust-vmm vhost crate
There is no need to point at our forked version any longer.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-11 13:43:57 +02:00
Bo Chen
b4f6db5f31 virtio-devices: vsock: Add 'brk' to the seccomp list
We observed CI instability for the past couple of days. This
instability is confirmed to be a result of incomplete seccomp
filters. Given the filter on 'virtio_vsock' is recently added and
is missing 'brk', it is likely to be the root cause of the
instability.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-11 07:56:52 +02:00
Bo Chen
9682d74763 vmm: seccomp: Add seccomp filters for signal_handler worker thread
This patch covers the last worker thread with dedicated secomp filters.

Fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-11 07:42:31 +02:00
Bo Chen
2612a6df29 vmm: seccomp: Add seccomp filters for the vcpu worker thread
Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-11 07:42:31 +02:00
Rob Bradford
d793cc4da3 vmm: device_manager: Extract common PCI code
Extract common code for adding devices to the PCI bus into its own
function from the VFIO and VIRTIO code paths.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-11 07:33:18 +02:00
dependabot-preview[bot]
cd8c38384e build(deps): bump getrandom from 0.1.14 to 0.1.15
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.1.14 to 0.1.15.
- [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.1.14...v0.1.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-10 11:53:56 +00:00
Rob Bradford
15025d71b1 devices, vm-device: Move BusDevice and Bus into vm-device
This removes the dependency of the pci crate on the devices crate which
now only contains the device implementations themselves.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-10 09:35:38 +01:00
dependabot-preview[bot]
f24a12913a build(deps): bump libc from 0.2.76 to 0.2.77
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.76 to 0.2.77.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.76...0.2.77)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-10 06:45:09 +00:00
dependabot-preview[bot]
7fddb9aa4f build(deps): bump proc-macro2 from 1.0.20 to 1.0.21
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.20...1.0.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-09 22:28:52 +01:00
Bo Chen
3c923f0727 virtio-devices: seccomp: Add seccomp filters for virtio_vsock thread
This patch enables the seccomp filters for the virtio_vsock worker
thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-09 17:04:39 +01:00
Bo Chen
1175fa2bc7 virtio-devices: seccomp: Add seccomp filters for blk_io_uring thread
This patch enables the seccomp filters for the block_io_uring worker
thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-09 17:04:39 +01:00
Sebastien Boeuf
56b0c85578 ci: Introduce SGX integration testing
Extending the Cloud-Hypervisor CI to allow for testing SGX on a
dedicated machine where special image and kernels are ready.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-09 15:33:49 +02:00
Rob Bradford
a86a2711f8 ch-remote: Support using unit suffices for "resize"
Remove the requirement for the user to calculate the size they want in
bytes.

Fixes: #1596

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-08 22:27:34 +02:00
Rob Bradford
42de27b215 virtio-devices: Remove virtio_pausable! macros
These are no longer needed as virtio device pausing is handledby
VirtioCommon.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-07 17:39:30 +02:00
Rob Bradford
a641f8930f virtio-devices: virtio-vsock: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-07 17:39:30 +02:00
Rob Bradford
12f90569e2 virtio-devices: vhost-user-net: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-07 17:39:30 +02:00
Rob Bradford
d33a1a5313 virtio-devices: vhost-user-fs: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-07 17:39:30 +02:00
Rob Bradford
1e4b612d39 virtio-devices: vhost-user-block: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-07 17:39:30 +02:00
Wei Liu
53f4fed516 hypervisor: drop get_api_version from Hypervisor trait
The new function already checks if the API version is compatible. There
is no need to expose the get_api_version function to code outside
hypervisor crate.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-09-07 11:59:08 +01:00
Wei Liu
d73971e407 hypervisor: kvm: check API compatibility
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-09-07 11:59:08 +01:00
Bo Chen
559d1840d8 build: Use the crate version when the 'git describe' command failed
In our build-script (build.rs), we won't set the environment variable
'BUILD_VERSION' when the 'git describe' command failed (e.g. when the
current source tree does not contain git information). This patch added
a fall back path where the default value of 'BUILD_VERSION' is based on
the 'cloud-hypervisor' crate version.

Fixes: #1669

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-07 12:03:57 +02:00
dependabot-preview[bot]
318ad83509 build(deps): bump syn from 1.0.39 to 1.0.40
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.39 to 1.0.40.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.39...1.0.40)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-07 05:39:02 +00:00
Sebastien Boeuf
e15dba2925 vmm: Rename NUMA option 'id' into 'guest_numa_id'
The goal of this commit is to rename the existing NUMA option 'id' with
'guest_numa_id'. This is done without any modification to the way this
option behaves.

The reason for the rename is caused by the observation that all other
parameters with an option called 'id' expect a string to be provided.

Because in this particular case we expect a u32 representing a proximity
domain from the ACPI specification, it's better to name it with a more
explicit name.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
55e9827e00 docs: Update memory documentation
Based on the recent changes regarding how to describe NUMA nodes to the
guest, the documentation related to memory zones and NUMA has been
updated accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
bf5e028016 ci: Update memory zone and NUMA integration tests
Since both --memory-zone and --numa parameters have been updated with
addition and removal of multiple options, this commit updates the
related integration tests to ensure they are still valid.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
1970ee89da main, vmm: Remove guest_numa_node option from memory zones
The way to describe guest NUMA nodes has been updated through previous
commits, letting the user describe the full NUMA topology through the
--numa parameter (or NumaConfig).

That's why we can remove the deprecated and unused 'guest_numa_node'
option.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
f21c04166a vmm: Move NUMA node list creation to Vm structure
Based on the previous changes introducing new options for both memory
zones and NUMA configuration, this patch changes the behavior of the
NUMA node definition. Instead of relying on the memory zones to define
the guest NUMA nodes, everything goes through the --numa parameter. This
allows for defining NUMA nodes without associating any particular memory
range to it. And in case one wants to associate one or multiple memory
ranges to it, the expectation is to describe a list of memory zone
through the --numa parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
dc42324351 vmm: Add 'memory_zones' option to NumaConfig
This new option provides a new way to describe the memory associated
with a NUMA node. This is the first step before we can remove the
'guest_numa_node' option from the --memory-zone parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
5d7215915f vmm: memory_manager: Store a list of memory zones
Now that we have an identifier per memory zone, and in order to keep
track of the memory regions associated with the memory zones, we create
and store a map referencing list of memory regions per memory zone ID.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Sebastien Boeuf
3ff82b4b65 main, vmm: Add mandatory id to memory zones
In anticipation for allowing memory zones to be removed, but also in
anticipation for refactoring NUMA parameter, we introduce a mandatory
'id' option to the --memory-zone parameter.

This forces the user to provide a unique identifier for each memory zone
so that we can refer to these.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-07 07:37:14 +02:00
Rob Bradford
c37fb5b602 virtio-devices: rng: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
d5d0b8566b virtio-devices: pmem: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
30f4f2b9ab virtio-devices: net: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
df8a55ab11 virtio-devices: mem: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
376babb21e virtio-devices: iommu: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
f6b75c683f virtio-devices: console: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
360d6702b6 virtio-devices: block_io_uring: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
3c6fd5634d virtio-devices: balloon: Port to VirtioCommon
Use VirtioCommon to handle activate() preparation, reset() and Pausable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
3487524950 virtio-device: block, common: Split out common code
Split the block device implementation into code that be used in common
between multiple different virtio device implementations.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
a9a138460b virtio-devices: Use Default::default() for transitioning to VirtioCommon
In order to simplify the transition to VirtioCommon and to avoid needing
to set empty fields derive Default for VirtioCommon.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
008cf4a5ae virtio-devices: block: Rearrange activate() to match other devices
Rearrange the code to match other devices which makes it easier to prep
for sharing this between other devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
56f03db69c virtio-devices: net: Simplify activate function
Move the if-let for the taps later which makes the earlier activation
code identical to other devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Rob Bradford
31d7712878 virtio-devices: block: Remove duplicated block
The same block of code seems to copied twice into the block activation
function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-05 10:06:39 +01:00
Samuel Ortiz
e5ce6dc43c vmm: cpu: Warn if the guest is trying to access unregistered IO ranges
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-09-04 14:39:58 +02:00
dependabot-preview[bot]
7f2ee1f984 build(deps): bump libz-sys from 1.1.1 to 1.1.2
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.1.1...1.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-04 05:41:22 +00:00
dependabot-preview[bot]
4870b5099a build(deps): bump proc-macro2 from 1.0.19 to 1.0.20
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.19...1.0.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-04 05:41:03 +00:00
Bo Chen
4392a1484c tests: Port test_bzimage_reboot to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Bo Chen
ded376c6e1 tests: Port test_console_file to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Bo Chen
a4abb7f8e5 tests: Port test_virtio_console to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Bo Chen
aac0cba0d1 tests: Port test_serial_file to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Bo Chen
9686aef2c9 tests: Port test_serial_tty to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Bo Chen
4e0e3d6221 tests: Port test_serial_null to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 17:47:14 +01:00
Rob Bradford
4bb00224b4 virtio-devices: balloon: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
dc9f1e4cdf virtio-devices: block_io_uring: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
e3abcdbff8 virtio-devices: console: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
9fc8b6d242 virtio-devices: iommu: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
d63dcae233 virtio-devices: mem: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
47c165e08a virtio-devices: net: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
84b4aef87a virtio-devices: pmem: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
37e99bbbb0 virtio-devices: rng: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
edb7ac5922 virtio-devices: vhost-user-block: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
8c42dd3811 virtio-devices: vhost-user-fs: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
9d0ebf8d25 virtio-devices: vhost-user-net: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
684b47013a virtio-devices: vsock: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
be945b3bc8 virtio-devices: block: Port to VirtioCommon for feature handling
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Rob Bradford
081c897989 virtio-devices: Introduce VirtioCommon for shared functionality
Introduce VirtioCommon to help remove duplicated functionality and state
between implementations of VirtioDevice. Initially it is only handling
feature acknowledgement and testing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-03 17:00:32 +02:00
Bo Chen
9e7e64d2a3 tests: Port various integration tests to new methodology
This patch ported many tests to the new methodology, where the guest log
will be printed only when the test is failing.

Things to finish in follow-up PRs:

1. Special tests not ported yet include: test_reboot,
test_bzimage_reboot, test_serial_null(), test_serial_tty(),
test_serial_file(), test_virtio_console(), test_console_file(),
and test_simple_launch.

2. Few direct calls to 'Command::new(clh_command("cloud-hypervisor"))',
which is still printing the guest console

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-03 08:13:20 +02:00
Rob Bradford
c266e56a02 hypervisor: Fix copy and pasted error enum entries
Remove unused GetNrVcpus error and fix duplicated error message for
GetCpuId.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-02 10:24:48 -07:00
Sebastien Boeuf
239169ad1d docs: Add documentation about memory in Cloud-Hypervisor
Writing some new documentation to help users understand how the guest
memory can be described through Cloud-Hypervisor parameters.

Fixes #1659

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-02 13:46:28 +02:00
Rob Bradford
dac600305b vm-virtio: queue: Clear all queue fields on reset
Some of the fields on the queue were not being cleared up on device
reset.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-02 11:48:44 +01:00
Sebastien Boeuf
5d80bc2339 ci: Add distance validation to NUMA integration test
By extending the existing NUMA integration test, this commit validates
the proper distances between NUMA nodes are exposed to the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 18:09:01 +02:00
Sebastien Boeuf
c0d0d23932 vmm: acpi: Introduce SLIT for NUMA nodes distances
By introducing the SLIT (System Locality Distance Information Table), we
provide the guest with the distance between each node. This lets the
user describe the NUMA topology with a lot of details so that slower
memory backing the VM can be exposed as being further away from other
nodes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 18:09:01 +02:00
Sebastien Boeuf
9548e7e857 vmm: Update NUMA node distances internally
Based on the NumaConfig which now provides distance information, we can
internally update the list of NUMA nodes with the exact distances they
should be located from other nodes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 18:09:01 +02:00
Sebastien Boeuf
a5a29134ca vmm: Extend --numa parameter with NUMA node distances
By introducing 'distances' option, we let the user describe a list of
destination NUMA nodes with their associated distances compared to the
current node (defined through 'id').

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 18:09:01 +02:00
Sebastien Boeuf
d6fc18da9e ci: Add CPUs validation to the NUMA integration test
Extend the existing NUMA integration to validate that specifying CPUs
for each NUMA node gets propagated to the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 15:25:00 +02:00
Sebastien Boeuf
629befdb4a vmm: acpi: Add CPUs to NUMA nodes
Based on the list of CPUs related to each NUMA node, Processor Local
x2APIC Affinity structures are created and included into the SRAT table.

This describes which CPUs are part of each node.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 15:25:00 +02:00
Sebastien Boeuf
db28db8567 vmm: Update NUMA nodes based on NumaConfig
Relying on the list of CPUs defined through the NumaConfig, this patch
will update the internal list of CPUs attached to each NUMA node.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 15:25:00 +02:00
Sebastien Boeuf
42f963d6f2 main, vmm: Add new --numa parameter
Through this new parameter, we give users the opportunity to specify a
set of CPUs attached to a NUMA node that has been previously created
from the --memory-zone parameter.

This parameter will be extended in the future to describe the distance
between multiple nodes.

For instance, if a user wants to attach CPUs 0, 1, 2 and 6 to a NUMA
node, here are two different ways of doing so:
Either
	./cloud-hypervisor ... --numa id=0,cpus=0-2:6
Or
	./cloud-hypervisor ... --numa id=0,cpus=0:1:2:6

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 15:25:00 +02:00
Sebastien Boeuf
36171caba9 ci: Add integration test for defining NUMA nodes in the guest
This new test validates the guest OS can find the NUMA nodes which have
been defined by the user through the CLI, and that the right amount of
memory is associated with each node.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 14:11:49 +02:00
Sebastien Boeuf
65a23c6fc6 vmm: acpi: Create the SRAT table
The SRAT table (System Resource Affinity Table) is needed to describe
NUMA nodes and how memory ranges and CPUs are attached to them.

For now it simply attaches a list of Memory Affinity structures based on
the list of NUMA nodes created from the VMM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 14:11:49 +02:00
Sebastien Boeuf
cf81254a8d vmm: memory_manager: Create a NUMA node list
Based on the 'guest_numa_node' option, we create and store a list of
NUMA nodes in the MemoryManager. The point being to associate a list of
memory regions to each node, so that we can later create the ACPI tables
with the proper memory range information.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 14:11:49 +02:00
Sebastien Boeuf
768dbd1fb0 vmm: Add 'guest_numa_node' option to 'memory-zone'
With the introduction of this new option, the user will be able to
describe if a particular memory zone should belong to a specific NUMA
node from a guest perspective.

For instance, using '--memory-zone size=1G,guest_numa_node=2' would let
the user describe that a memory zone of 1G in the guest should be
exposed as being associated with the NUMA node 2.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 14:11:49 +02:00
Sebastien Boeuf
274c001eab vmm: Use u32 instead of u64 for host_numa_node option
Given that ACPI uses u32 as the type for the Proximity Domain, we can
use u32 instead of u64 as the type for 'host_numa_node' option.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-01 13:29:42 +02:00
dependabot-preview[bot]
4c6a250383 build(deps): bump kvm-ioctls from 37953e9 to f5312ea
Bumps [kvm-ioctls](https://github.com/cloud-hypervisor/kvm-ioctls) from `37953e9` to `f5312ea`.
- [Release notes](https://github.com/cloud-hypervisor/kvm-ioctls/releases)
- [Commits](37953e968b...f5312ea173)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-31 06:21:24 +00:00
dependabot-preview[bot]
42bfea5d5a build(deps): bump libz-sys from 1.1.0 to 1.1.1
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/commits/1.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-31 06:21:07 +00:00
Michael Zhao
a1c4c77cd8 tests: Enable test cases checking PCI MSI on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-31 08:20:42 +02:00
Michael Zhao
2b8e08bd36 tests: Enable test_multi_cpu case on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-31 08:20:42 +02:00
Michael Zhao
85c9bd0f47 tests: Enable vhost-user-net self-spawned test cases
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-31 08:19:23 +02:00
Michael Zhao
23e5a726ec virtio-devices: Add seccomp rules for vhost-user backend
The missing rules caused failures when guest powered off.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-31 08:19:23 +02:00
Michael Zhao
a95b6bbd8b vmm: Add seccomp rules for starting vhost-user-net backend on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-31 08:19:23 +02:00
Hui Zhu
f7b3581645 cloud-hypervisor.yaml: MemoryConfig: Add balloon_size
"struct MemoryConfig" has balloon_size but not in MemoryConfig
of cloud-hypervisor.yaml.
This commit adds it.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-08-28 09:58:39 +02:00
Hui Zhu
9c257a7e8c aarch64: fdt.rs: create_devices_node: Change sort_by to sort_by_key
Change sort_by to sort_by_key in create_devices_node.

Fixes: #1646

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-08-28 08:02:54 +02:00
Sebastien Boeuf
a8a9e61c3d vmm: memory_manager: Allow host NUMA for RAM backed files
Let's narrow down the limitation related to mbind() by allowing shared
mappings backed by a file backed by RAM. This leaves the restriction on
only for mappings backed by a regular file.

With this patch, host NUMA node can be specified even if using
vhost-user devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-27 08:39:38 -07:00
Sebastien Boeuf
1b4591aecc vmm: memory_manager: Apply NUMA policy to memory zones
Relying on the new option 'host_numa_node' from the 'memory-zone'
parameter, the user can now define which NUMA node from the host
should be used to back the current memory zone.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-27 08:39:38 -07:00
Sebastien Boeuf
e6f585a31c vmm: Add 'host_numa_nodes' option to memory zones
Since memory zones have been introduced, it is now possible for a user
to specify multiple backends for the guest RAM. By adding a new option
'host_numa_node' to the 'memory-zone' parameter, we allow the guest RAM
to be backed by memory that might come from a specific NUMA node on the
host.

The option expects a node identifier, specifying which NUMA node should
be used to allocate the memory associated with a specific memory zone.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-27 08:39:38 -07:00
Sebastien Boeuf
ad5d0e4713 vmm: Remove 'mergeable' from memory zones
The flag 'mergeable' should only apply to the entire guest RAM, which is
why it is removed from the MemoryZoneConfig as it is defined as a global
parameter at the MemoryConfig level.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-27 07:26:49 +02:00
dependabot-preview[bot]
be8f40f2b6 build(deps): bump redox_users from 0.3.4 to 0.3.5
Bumps redox_users from 0.3.4 to 0.3.5.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-26 21:22:08 +00:00
Sebastien Boeuf
89e7774b96 vmm: openapi: Don't expect cmdline to always be there
The 'cmdline' parameter should not be required as it is not needed when
the 'kernel' parameter is the rust-hypervisor-fw, which means the kernel
and the associated command line will be found from the EFI partition.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:49:05 +02:00
Sebastien Boeuf
e8149380b7 vmm: memory_manager: Factorize memory regions creation
Factorize the codepath between simple memory and multiple memory zones.
This simplifies the way regions are memory mapped, as everything relies
on the same codepath. This is performed by creating a memory zone on the
fly for the specific use case where --memory is used with size being
different from 0. Internally, the code can rely on memory zones to
create the memory regions forming the guest memory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
c58dd761f4 vmm: Remove 'file' option from MemoryConfig
After the introduction of user defined memory zones, we can now remove
the deprecated 'file' option from --memory parameter. This makes this
parameter simpler, letting more advanced users define their own custom
memory zones through the dedicated parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
5bf7113768 vmm: memory_manager: Remove restrictions about snapshot/restore
User defined memory regions can now support being snapshot and restored,
therefore this commit removes the restrictions that were applied through
earlier commit.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
2583d572fc vmm: memory_manager: Simplify how to restore memory regions
By factorizing a lot of code into create_ram_region(), this commit
achieves the simplification of the restore codepath. Additionally, it
makes user defined memory zones compatible with snapshot/restore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
b14c861c6f vmm: memory_manager: Store memory regions content only when necessary
First thing, this patch introduces a new function to identify if a file
descriptor is linked to any hard link on the system. This can let the
VMM know if the file can be accessed by the user, or if the file will
be destroyed as soon as the VMM releases the file descriptor.

Based on this information, and associated with the knowledge about the
region being MAP_SHARED or not, the VMM can now decide to skip the copy
of the memory region content. If the user has access to the file from
the filesystem, and if the file has been mapped as MAP_SHARED, we can
consider the guest memory region content to be present in this file at
any point in time. That's why in this specific case, there's no need for
performing the copy of the memory region content into a dedicated file.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
d1ce52f3a8 vmm: memory_manager: Make backing file from snapshot optional
Let's not assume that a backing file is going to be the result from
a snapshot for each memory region. These regions might be backed by
a file on the host filesystem (not a temporary file in host RAM), which
means they don't need to be copied and stored into dedicated files.

That's why this commit prepares for further changes by introducing an
optional PathBuf associated with the snapshot of each memory region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
871138d5cc vm-migration: Make snapshot() mutable
There will be some cases where the implementation of the snapshot()
function from the Snapshottable trait will require to modify some
internal data, therefore we make this possible by updating the trait
definition with snapshot(&mut self).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
7b898285d5 ci: Extend integration tests with user defined memory zones
Adding a small test to validate that user defined memory zones work as
expected when using --memory-zone option.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
c13721fdbd vmm: memory_manager: Handle user defined memory zones
In case the memory size is 0, this means the user defined memory
zones are used as a way to specify how to back the guest memory.

This is the first step in supporting complex use cases where the user
can define exactly which type of memory from the host should back the
memory from the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
7cd3867e2c vmm: memory_manager: Provide file offset through create_ram_region()
In anticipation for the need to map part of a file with the function
create_ram_region(), it is extended to accept a file offset as argument.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
59d4a56ab7 vmm: memory_manager: Don't truncate backing file
In case the provided backing file is an actual file and not a directory,
we should not truncate it, as we expect the file to already be the right
size.

This change will be important once we try to map the same file through
multiple memory mappings. We can't let the file be truncated as the
second mapping wouldn't work properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
be475ddc22 main, vmm: Let the user define distincts memory zones
Introducing a new CLI option --memory-zone letting the user specify
custom memory zones. When this option is present, the --memory size
must be explicitly set to 0.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Sebastien Boeuf
d25ec66bb6 vmm: memory_manager: Simplify start_addr()
Small simplification for the function calculating the start address.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-25 16:43:10 +02:00
Anatol Belski
12212d2966 pci: device_manager: Remove hardcoded I/O port assignment
It is otherwise seems to be able to cause resource conflicts with
Windows APCI_HAL. The OS might do a better job on assigning resources
to this device, withouth them to be requested explicitly. 0xcf8 and
0xcfc are only what is certainly needed for the PCI device enumeration.

Signed-off-by: Anatol Belski <anatol.belski@microsoft.com>
2020-08-25 09:00:06 +02:00
Michael Zhao
a4222afd7c scripts: Remove the workaround for "with-serde" in unit tests on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-24 10:59:08 +02:00
Michael Zhao
afc98a5ec9 vmm: Fix AArch64 clippy warnings of vmm and other crates
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-24 10:59:08 +02:00
Michael Zhao
46b8f38987 arch: Fix AArch64 clippy warnings of arch crate
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-24 10:59:08 +02:00
Michael Zhao
527e8e7b1d build: Add quality checks workflow for AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-24 10:59:08 +02:00
Amey Narkhede
dc9c12518e docs/iommu: Update cpu and memory option parameters
Use of backing file is deprecated hence use the `hugepages` field.
Also use the `boot` field for specifying number of cpus

Signed-off-by: Amey Narkhede <ameynarkhede02@gmail.com>
2020-08-24 08:49:47 +02:00
dependabot-preview[bot]
0c33bf0044 build(deps): bump syn from 1.0.38 to 1.0.39
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.38 to 1.0.39.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.38...1.0.39)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-24 06:48:33 +00:00
Muminul Islam
92b4499c1e vmm, hypervisor: Add vmstate to snapshot and restore path
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-08-24 08:48:15 +02:00
Muminul Islam
77e901a602 hypervisor: Introduce VM state to Vm hypervisor trait
We may need to store hypervisor speciific data to the VM. This support is
needed for Microsoft hyperv implementations. This patch introduces two
new definitions to Vm trait and implements for KVM.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-08-24 08:48:15 +02:00
dependabot-preview[bot]
8962e25268 build(deps): bump miniz_oxide from 0.4.0 to 0.4.1
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/Frommi/miniz_oxide/releases)
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/compare/0.4.0...0.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-24 04:00:04 +00:00
Wei Liu
47e8f5475e pci/msix: remove reference to KVM from a comment
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-08-21 16:23:41 +02:00
Wei Liu
e6849699d2 vfio: remove KVM-ism from comments and error messages
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-08-21 16:23:41 +02:00
Wei Liu
571c368528 vfio: fix comment for map_mmio_regions
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-08-21 16:23:41 +02:00
dependabot-preview[bot]
57ff608be9 build(deps): bump libc from 0.2.74 to 0.2.76
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.74 to 0.2.76.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.74...0.2.76)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-21 07:08:35 +00:00
dependabot-preview[bot]
da72d30f53 build(deps): bump ppv-lite86 from 0.2.8 to 0.2.9
Bumps [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) from 0.2.8 to 0.2.9.
- [Release notes](https://github.com/cryptocorrosion/cryptocorrosion/releases)
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/compare/ppv-lite86-0.2.8...ppv-lite86-0.2.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-21 06:17:47 +00:00
dependabot-preview[bot]
1c9c0fa0e5 build(deps): bump linux-loader from 726360b to 3cf96c5
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `726360b` to `3cf96c5`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](726360bb2c...3cf96c53ed)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-21 06:17:35 +00:00
dependabot-preview[bot]
421f1c9d8b build(deps): bump autocfg from 1.0.0 to 1.0.1
Bumps [autocfg](https://github.com/cuviper/autocfg) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/cuviper/autocfg/releases)
- [Commits](https://github.com/cuviper/autocfg/compare/1.0.0...1.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-21 04:14:36 +00:00
Sebastien Boeuf
d751f419de Jenkinsfile: Force the cleanup after stages are aborted
Problem with the previous solution was that Cleanup stage was not
executed when previous stages failed. We fix this by adding a post
section that executes always after the Aarch64 build completed, no
matter if it has failed, succeeded or been aborted.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-19 09:26:36 -07:00
Michael Zhao
cd0b8ed8f8 virtio-devices: Allowing SYS_write syscall for virtio-net-ctl thread
"debug!" marco is used in virtio-devices/src/epoll_helper.rs. When"-vvv"
and "--log-file" option was specified, the missing "SYS_write" rule
caused a "bad system call" crash.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-19 14:26:07 +02:00
Sebastien Boeuf
bcbc098c66 Jenkinsfile: Add a cleanup stage
Cleanup of the Aarch64 machine can't be done as part of the parallel
stage as this is often skipped. When the build is aborted because
another parallel stage failed, the post actions are simply not
performed. That's why we need a dedicated stage, out of the parallel
ones, to cleanup the Aarch64 machine.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-19 11:23:06 +02:00
Amey Narkhede
9304b92219 docs/virtio-fs: Update --memory option parameters
Use updated --memory option parameters. The field `size` needs
M/G suffix. Without the suffix cloud-hypervisor panics at
src/main.rs:353
Also the use of backing file is deprecated so use `shared` field

Signed-off-by: Amey Narkhede <ameynarkhede02@gmail.com>
2020-08-19 10:43:04 +02:00
Bo Chen
02d87833f0 virtio-devices: seccomp: Add seccomp filters for vhost_blk thread
This patch enables the seccomp filters for the vhost_blk worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
Bo Chen
4e0ea15075 virtio-devices: seccomp: Add seccomp filter for vhost_net thread
This patch enables the seccomp filters for the vhost_net worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
Bo Chen
896b9a1d4b virtio-devices: seccomp: Add seccomp filter for vhost_net_ctl thread
This patch enables the seccomp filters for the vhost_net_ctl worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
Bo Chen
02d63149fe virtio-devices: seccomp: Add seccomp filters for vhost_fs thread
This patch enables the seccomp filters for the vhost_fs worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
Bo Chen
c82ded8afa virtio-devices: seccomp: Add seccomp filters for balloon thread
This patch enables the seccomp filters for the balloon worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
Bo Chen
c460178723 virtio-devices: seccomp: Add seccomp filters for mem thread
This patch enables the seccomp filters for the mem worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-19 08:33:58 +02:00
dependabot-preview[bot]
c30ff62a7a build(deps): bump libssh2-sys from 0.2.18 to 0.2.19
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.18 to 0.2.19.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.18...libssh2-sys-0.2.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-19 06:24:42 +00:00
dependabot-preview[bot]
58d0aec510 build(deps): bump cc from 1.0.58 to 1.0.59
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.58 to 1.0.59.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.58...1.0.59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-19 06:24:29 +00:00
Michael Zhao
24fb5c8387 tests: Enable test case test_counters on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-18 08:10:04 +02:00
Bo Chen
de3b17d948 virtio-devices: Print out worker thread errors
As we never join the spawned virtio-devices worker threads, the error
returned from each worker thread is lost. For now, we simply print out
the error from each worker thread.

Fixes: #1551

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-18 07:57:11 +02:00
dependabot-preview[bot]
df30b23f0c build(deps): bump once_cell from 1.4.0 to 1.4.1
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.4.0...v1.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-18 05:55:55 +00:00
dependabot-preview[bot]
4cde183783 build(deps): bump tinyvec from 0.3.3 to 0.3.4
Bumps [tinyvec](https://github.com/Lokathor/tinyvec) from 0.3.3 to 0.3.4.
- [Release notes](https://github.com/Lokathor/tinyvec/releases)
- [Commits](https://github.com/Lokathor/tinyvec/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-18 05:55:43 +00:00
dependabot-preview[bot]
f02a5d0915 build(deps): bump libz-sys from 1.0.27 to 1.1.0
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.0.27 to 1.1.0.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-18 05:55:31 +00:00
Bo Chen
aaa02a0d78 virtio-devices: seccomp: Add 'brk' syscall to all worker threads
To prevent potential failures, this patch adds 'brk' syscall to all
virtio-devices worker threads.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
c90a71e329 virtio-devices: seccomp: Add 'brk' syscall to the rng thread
From the experiments of running integration tests on my local machine,
auditd occationally reported the 'brk' syscall is needed for the
'virtio-rng' worker thread.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
c70ad27247 virtio-devices: Add seccomp filter list for net worker thread
This patch adds the seccomp filter list for the virtio_net thread, while
the list was already added for the virtio_net_ctl thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
3d6d9ca4de virtio-devices: Print out error message from the net worker thread
Partially fixes: #1551

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
1bf7817c40 virtio-devices: seccomp: Distinguish viritio-net-ctl from virtio-net
The current seccomp filter for virtio-net is actually for the worker
thread 'virtio_net_ctl' (not the actual worker thread
'virtio_net'). This patch introduces changes to distinguish those two
worker threads and seccomp filters.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
4539236690 virtio-devices: seccomp: Add seccomp filters for iommu thread
This patch enables the seccomp filters for the iommu worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
Bo Chen
dc6c62af09 virtio-devices: Print out error message from the iommu worker thread
Partially fixes: #1551

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-17 21:08:49 +02:00
dependabot-preview[bot]
d71142277c build(deps): bump libz-sys from 1.0.25 to 1.0.27
Bumps [libz-sys](https://github.com/rust-lang/libz-sys) from 1.0.25 to 1.0.27.
- [Release notes](https://github.com/rust-lang/libz-sys/releases)
- [Commits](https://github.com/rust-lang/libz-sys/compare/1.0.25...1.0.27)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-17 07:14:15 +00:00
Sebastien Boeuf
17a0733527 Jenkinsfile: Don't retry integration tests on failure
We recently added the ability for the gnu and musl workers to retry if
integration test were not passing, relying on some simple Jenkins
options. Unfortunately, this is not working as expected as the retries
never pass either. The suspected reason is the machine itself, which
might be scheduled on some specific hardware, which makes our VMs more
error prone.

Bottom line, on a faulty machine, the tests will always fail, therefore
there is no added value in retrying on the same machine.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-14 16:44:35 +02:00
Anatol Belski
eba42c392f devices: acpi: Add UID to devices with common HID
Some OS might check for duplicates and bail out, if it can't create a
distinct mapping. According to ACPI 5.0 section 6.1.12, while _UID is
optional, it becomes required when there are multiple devices with the
same _HID.

Signed-off-by: Anatol Belski <ab@php.net>
2020-08-14 08:52:02 +02:00
dependabot-preview[bot]
ebe61de0d1 build(deps): bump clap from 2.33.2 to 2.33.3
Bumps [clap](https://github.com/clap-rs/clap) from 2.33.2 to 2.33.3.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-14 06:18:55 +00:00
Rob Bradford
01b1412914 Jenkinsfile: Move OpenAPI validation to worker
Remove this work from the Jenkins master.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:53:16 +01:00
Rob Bradford
cf1a1ac6cf Jenkinsfile: Stop running "cargo" checks on master
These checks are now handled via GitHub actions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:09:24 +02:00
Rob Bradford
bf4051665c build: Run cargo-audit from a GitHub action
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:09:24 +02:00
Rob Bradford
6b40f2dbc5 virtio-devices: vsock: Fix clippy error
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:09:24 +02:00
Rob Bradford
1a01f2d82a qcow: raw_file: Fix clippy warning
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:09:24 +02:00
Rob Bradford
a4b67c2226 build: Use GitHub actions for clippy/build/rustfmt tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 16:09:24 +02:00
Sebastien Boeuf
aa57762c4f virtio-devices: Acknowledge a device being paused
Using the Rust Barrier mechanism, this patch forces each virtio device
to acknowledge they've been correctly paused before going further.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-13 14:52:18 +02:00
Rob Bradford
fd48779a0d tests: Port test_initramfs to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 13:03:22 +02:00
Rob Bradford
dd39aedde1 tests: Port test_memory_mergeable to new methodology
As a compromise we only print out the first child's output.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 13:03:22 +02:00
Rob Bradford
9dd4625fb4 tests: Port test_virtio_vsock to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 13:03:22 +02:00
Rob Bradford
4983e5c322 tests: Port test_virtio_pmem to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 13:03:22 +02:00
Rob Bradford
7b621bde4f Jenkinsfile: chown the workspace before cleaning up
If the build was aborted then the dev_cli.sh code that is responsible
for changing the file ownership will not get run. This results in the
failure to delete some of the files in the workspace.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-13 09:10:46 +01:00
dependabot-preview[bot]
b9fbcd469c build(deps): bump linux-loader from b13674a to 726360b
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `b13674a` to `726360b`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](b13674ab87...726360bb2c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-12 16:29:45 +00:00
Sebastien Boeuf
fca46fd00e virtio-devices: net: Add dup syscall to seccomp filters
The seccomp filters specific to the virtio-net threads must contain
dup() syscall now that we ported the epoll code to the EpollHelper.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-12 17:34:02 +02:00
Sebastien Boeuf
a502cb282e virtio-devices: net_ctrlq: Port to EpollHelper
Migrate virtio-net and vhost-user-net control queue to EpollHelper so
as to remove code duplication.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-12 17:34:02 +02:00
Rob Bradford
32b70e354c tests: Port virtiofs tests to new methodology
This required a bit of rearranging as it is not possible to call
prepare_daemon() inside a catch_unwind{} block.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 14:53:02 +01:00
Rob Bradford
23174800ca tests: Port vhost_user_block tests to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 14:53:02 +01:00
Rob Bradford
8f4e1382a9 tests: Port vhost_user_net tests to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 14:53:02 +01:00
Rob Bradford
effff460d4 tests: Port test_cpu_topology to new test methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 14:53:02 +01:00
Sebastien Boeuf
821cf3add9 virtio-devices: vhost-user: Port to EpollHelper
Migrate all vhost-user devices to EpollHelper so as to remove code that
is duplicated between multiple virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-12 14:39:54 +02:00
Rob Bradford
d749aa2e6b tests: Port test_vfio to new test methodology
Now the testing aspects are run inside a panic handler block rather than
inside a credibility TestBlock. If the test fails then the output from
the cloud-hypervisor binary is then presented.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 12:19:34 +02:00
Rob Bradford
4ef702ea76 tests: Use a disk image for test_vfio rather than virtio-fs
This reduces the complexity of the test slightly. The PCI BDFs in the L1
needed changing as the block devices come before the network ones.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-12 12:19:34 +02:00
Sebastien Boeuf
8fbc4b4004 virtio-devices: vsock: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-12 10:07:57 +01:00
Sebastien Boeuf
01e7bd7276 virtio-devices: Make EpollHandler more generic
Instead of passing only the event type through the handle_event()
callback, we make the trait slightly more generic by providing the
epoll event to each virtio device implementation.

This is particularly useful for vsock as it will need the event set.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-12 10:07:57 +01:00
dependabot-preview[bot]
1e0b516a84 build(deps): bump linux-loader from b309c9d to b13674a
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `b309c9d` to `b13674a`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](b309c9df17...b13674ab87)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-12 07:52:10 +00:00
dependabot-preview[bot]
31031b43b6 build(deps): bump smallvec from 1.4.1 to 1.4.2
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.4.1...v1.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-12 06:41:42 +00:00
Sebastien Boeuf
e7ed037351 virtio-devices: balloon: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-11 19:58:10 +01:00
Alyssa Ross
17ad86afe3 docs: use shared memory with vhost-user
Not doing this is an error.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2020-08-11 19:37:31 +02:00
Sebastien Boeuf
e8f0bdb6f2 virtio-devices: console: Add dup syscall to seccomp filters
The seccomp filters specific to the virtio-console thread must contain
dup syscall now that we ported the epoll code to the EpollHelper.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-11 19:17:50 +02:00
Sebastien Boeuf
d9992b5b5f virtio-devices: console: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-11 19:17:50 +02:00
Sebastien Boeuf
bdef54ead6 vmm: Add brk syscall to the API thread
The brk syscall is not always called as the system might not need it.
But when it's needed from the API thread, this causes the thread to
terminate as it is not part of the authorized list of syscalls.

This should fix some sporadic failures on the CI with the musl build.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-11 15:04:21 +01:00
Alyssa Ross
cb96afaa2f vhost_user_net: don't claim to impl all features
Even if the vhost-user-net device did implement all currently-defined
features, it would be very short-sighted to use ::all(), because if a
new feature was defined later, the device would start claiming to
implement it even though it didn't.

More practically, claiming to implement all features breaks using QEMU
with the cloud-hypervisor vhost-user-net backend, because QEMU will
negotiate VHOST_USER_PROTOCOL_F_SLAVE_REQ, and then break when the
communication channel isn't actually set up.

I wasn't sure exactly which features the backend should claim to
implement, though.  Definitely MQ, and I'm fairly certain none of the
features I've ommitted are implemented.  But I'm not sure about
REPLY_ACK.  As far as I can tell it should be implemented entirely by
the vhost crate, with no cooperation required from the vhost-user-net
backend itself, so there should be no reason to let a frontend use it
if it wants to.  But despite this, neither vhost-user-fs nor
vhost-user-blk claims to implement it.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2020-08-11 12:58:26 +02:00
Rob Bradford
070f47246c tests: Port test_snapshot_restore to new methodology
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-11 12:57:18 +02:00
Rob Bradford
6cd31e7a4d tests: Introduce new test methodology
Rather than using a credible TestBlock to capture the test assertions
instead use a catch_unwind block to catch the panic and turn
it into a Result<>.

If block panicked or the child binary had non-zero exit then, and only
then, print out the child output.

This results in a clearer test output with no interleaving.

Currently only test_counters is ported to this methodology to
demonstrate its use.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-11 12:57:18 +02:00
Rob Bradford
5da55f0f2e tests: Remove "--nocapture" from tests
`cargo test` runs every test in its own process and by default will
collect the output from the test and only print it if the test fails.
`--nocapture` instead prints any output from the test immediately and
does not collate it - this leads to interleaving.

`--nocapture` might be useful for local test debugging but is not
something that is helpful, and is instead unhelpful for our CI as a
whole.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-11 12:57:18 +02:00
dependabot-preview[bot]
bfacf50d90 build(deps): bump serde_derive from 1.0.114 to 1.0.115
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.114 to 1.0.115.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.114...v1.0.115)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-11 05:47:30 +00:00
dependabot-preview[bot]
6812a63fca build(deps): bump serde from 1.0.114 to 1.0.115
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.114 to 1.0.115.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.114...v1.0.115)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-11 05:14:51 +00:00
Rob Bradford
c5a03d5ad4 build: Remove job directory on ARM64 build
This prevents the builder from running out of disk space.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-10 14:55:50 +01:00
Sebastien Boeuf
05c6136790 io-uring: Move to the crates.io 0.4.0 version
Now that io-uring crate has been stabilized, let's move to the latest
release 0.4.0 from crates.io.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-10 08:40:51 +01:00
Rob Bradford
66efe3cf53 virtio-devices: mem: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-10 08:46:35 +02:00
Anatol Belski
d4754e18f9 Cargo.toml: add missing [package] entries
These are required by some tools, but also by crates.io one day.

Signed-off-by: Anatol Belski <ab@php.net>
2020-08-10 08:44:09 +02:00
dependabot-preview[bot]
3bbed83e8e build(deps): bump io-uring from c00d968 to 445fbc4
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from `c00d968` to `445fbc4`.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [Commits](c00d968b03...445fbc4ae4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-09 17:01:24 +00:00
Rob Bradford
1c4e8ac5ce Revert "build: Temporarily disable ARM64 builds"
This reverts commit 743ebe2fa6.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-07 10:35:50 +01:00
Rob Bradford
d714cf8131 build, release-notes.md: Document 0.9.0 release
Update release notes and version number for the new release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-06 14:31:36 +01:00
Rob Bradford
8286b316c1 build: Bump vm-memory dependency
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-06 14:26:47 +01:00
Muminul Islam
96caf6b03b rpm: Add spec file for packaging cloud-hypervisor
Packaging the cloud-hyperviosr binary is useful for enterprise use.
This patch adds the spec file for x86_64. Aarch64 support is not added
yet.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-08-06 09:29:36 +01:00
Sebastien Boeuf
20cd778c5b ci: Retry integration tests if failing
Both gnu and musl workers will retry integration tests up to 3 times if
they fail. This should give us a better pass rate, without having to
restart the entire build every time a single glitch happens.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-06 08:29:50 +01:00
dependabot-preview[bot]
7529a9ac05 build(deps): bump seccomp from v0.21.2 to v0.22.0
Bumps [seccomp](https://github.com/firecracker-microvm/firecracker) from v0.21.2 to v0.22.0.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Changelog](cc5387637c/CHANGELOG.md)
- [Commits](a06d358b2e...cc5387637c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-06 07:25:30 +00:00
Bo Chen
f65372ea4a dev_cli: Remove the use of undefined '$libc' for the 'shell' command
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-06 08:30:40 +02:00
dependabot-preview[bot]
8e8ec74b2a build(deps): bump clap from 2.33.1 to 2.33.2
Bumps [clap](https://github.com/clap-rs/clap) from 2.33.1 to 2.33.2.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 20:36:12 +00:00
dependabot-preview[bot]
1ac6ccb300 build(deps): bump signal-hook-registry from 1.2.0 to 1.2.1
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.2.0 to 1.2.1.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 20:35:55 +00:00
Jose Carlos Venegas Munoz
90acb01bad vmm: seccomp: add mprotect to API thread filter
Add mprotect to API thread rules. Prevent the VMM is
killed when it is used.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-08-05 21:35:21 +01:00
Rob Bradford
743ebe2fa6 build: Temporarily disable ARM64 builds
The builder is not currently responding to pings.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 17:51:20 +01:00
Anatol Belski
4f33ea89cf pci: use vfio-bindings from crates.io
This fixes `cargo vendor` throwing an error

```
$ cargo vendor
error: failed to sync

Caused by:
  found duplicate version of package `vfio-bindings v0.2.0` vendored from two sources:

	source 1: https://github.com/rust-vmm/vfio-bindings#f08cbcbf
	source 2: registry `https://github.com/rust-lang/crates.io-index`
```

Both sources are indeed same, the conflict is only cause by the
different URLs.

Signed-off-by: Anatol Belski <ab@php.net>
2020-08-05 17:50:45 +01:00
Sebastien Boeuf
0f1ab38ded hypervisor: kvm: Make MSRs set/get more flexible
Based on the way KVM_GET_MSRS and KVM_SET_MSRS work, both function are
very unlikely to fail, as they simply stop looping through the list of
MSRs as soon as getting or setting one fails. This is causing some
issues with the snapshot/restore feature, as on some platforms, we only
save a subset of the list of MSRs, leading to unproper way of saving the
VM.

The way to address this issue is by checking the number of MSRs get/set
matches the expected amount from the list. In case it does not match, we
simply ignore the failing MSR and continue getting/setting the rest of
the list. By doing this by iterations, we end up getting/setting as many
MSRs as the platform can support.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-05 14:52:35 +01:00
Rob Bradford
44cf97e2fd build: Fix Jenkinsfile syntax
Turns out that "when" blocks are permitted but not effectual in "post"
sections so instead use a script behaviour to make the message
conditional on build change.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 14:49:33 +01:00
Rob Bradford
b5d64be479 virtio-devices: iommu: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 13:15:23 +02:00
Rob Bradford
2e98208af5 build: Alert on Slack when master build regresses or is fixed
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 13:14:20 +02:00
Rob Bradford
55c16fecbf virtio-devices: seccomp: Add missing dup() syscalls
The refactoring to use EpollHelper added a requirement on this system
call.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 11:32:31 +02:00
Rob Bradford
0e335a709d virtio-devices: Print out worker error messages
Currently any messages generated during the worker thread are not
shown anywhere as the thread is never join()ed on. Instead output the
error immediately.

For now only cover the subset where the work to port to EpollHandler
clashed with the seccomp filtering for virtio devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 11:32:31 +02:00
dependabot-preview[bot]
ec9de259ba build(deps): bump seccomp from v0.21.1 to v0.21.2
Bumps [seccomp](https://github.com/firecracker-microvm/firecracker) from v0.21.1 to v0.21.2.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Changelog](a06d358b2e/CHANGELOG.md)
- [Commits](047a379eb0...a06d358b2e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 07:34:44 +00:00
Michael Zhao
fc2d9c6e31 ci: Remove unused image in sha1sums-aarch64
We no longer download focal-server-cloudimg-arm64.img, checking it
lead to a failure if "work_loads" folder is new.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-05 08:15:18 +01:00
Michael Zhao
f2db346127 tests: Enable more integration test cases on AArch64
Enabled 3 test cases:
- test_large_vm
- test_huge_memory
- test_serial_null

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-08-05 08:15:18 +01:00
Bo Chen
dc71d2765a virtio-devices: seccomp: Add seccomp filters for pmem thread
This patch enables the seccomp filters for the pmem worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-05 08:13:31 +01:00
Bo Chen
d77977536d virtio-devices: seccomp: Add seccomp filters for net thread
This patch enables the seccomp filters for the net worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-05 08:13:31 +01:00
Bo Chen
276df6b71c virtio-devices: seccomp: Add seccomp filters for console thread
This patch enables the seccomp filters for the console worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-05 08:13:31 +01:00
Bo Chen
a426221167 virtio-devices: seccomp: Add seccomp filters for rng thread
This patch enables the seccomp filters for the rng worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-05 08:13:31 +01:00
Bo Chen
6a26789222 virtio-devices: seccomp: Fix typos in the block module
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-05 08:13:31 +01:00
dependabot-preview[bot]
3eeee63189 build(deps): bump syn from 1.0.37 to 1.0.38
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.37...1.0.38)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 06:43:20 +00:00
Rob Bradford
ce65093f8d virtio-devices: pmem: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 08:43:01 +02:00
Rob Bradford
e093f0e83e virtio-devices: rng: Port to EpollHelper
Migrate to EpollHelper so as to remove code that is duplicated between
multiple virtio devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-05 08:42:06 +02:00
Ricardo Koller
358b3c0b89 Dummy change to start the tests
Signed-off-by: Ricardo Koller <ricarkol@gmail.com>
2020-08-05 08:38:58 +02:00
Ricardo Koller
7589f1b3bf vhost_user_fs: increase RLIMIT_NOFILE
Increase the number of open files limit for the sandboxed process to the
maximum allowed in the system. The maximum is obtained by reading the
/proc/sys/fs/nr_open sysctl file, and the setting is done using the setrlimit
syscall. Failure to read or parse the nr_open file, or to set the rlimit
results in a panic.

Signed-off-by: Ricardo Koller <ricarkol@gmail.com>
2020-08-05 08:38:58 +02:00
Rob Bradford
8f39b5ef84 build: Update Cargo.lock for kvm-bindings
Point to the non-merge commit.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-08-04 16:50:06 +01:00
Henry Wang
a47da51539 ci: AArch64: Enable basic virtio_vsock test case for AArch64
This commit enables the test case for testing the basic function
of virtio_vsock (i.e. without the hotplug).

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-08-04 13:16:14 +01:00
Bo Chen
704edd544c virtio-devices: seccomp: Add seccomp_filter module
This patch added the seccomp_filter module to the virtio-devices crate
by taking reference code from the vmm crate. This patch also adds
allowed-list for the virtio-block worker thread.

Partially fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-04 11:40:49 +02:00
Bo Chen
ff7ed8f628 vmm: Propagate the SeccompAction value to the Vm struct constructor
This patch propagates the SeccompAction value from main to the
Vm struct constructor (i.e. Vm::new_from_memory_manager), so that we can
use it to construct the DeviceManager and CpuManager struct for
controlling the behavior of the seccomp filters for vcpu/virtio-device
worker threads.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-04 11:40:49 +02:00
Bo Chen
8e74637ebb main, vmm: seccomp: Add the '--seccomp log' option
This patch extends the CLI option '--seccomp' to accept the 'log'
parameter in addition 'true/false'. It also refactors the
vmm::seccomp_filters module to support both "SeccompAction::Trap" and
"SeccompAction::Log".

Fixes: #1180

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-04 11:40:49 +02:00
Bo Chen
b41884a406 main, vmm: seccomp: Use SeccompAction instead of SeccompLevel
This patch replaces the usage of 'SeccompLevel' with 'SeccompAction',
which is the first step to support the 'log' action over system
calls that are not on the allowed list of seccomp filters.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-08-04 11:40:49 +02:00
dependabot-preview[bot]
bfc37bc8d3 build(deps): bump syn from 1.0.36 to 1.0.37
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.36...1.0.37)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-04 06:44:59 +00:00
Henry Wang
61c093f724 ci: AArch64: Enable api_create_boot for AArch64
This commit enables the `api_create_boot` case in the integration
test as the test for the Cloud Hypervisor API server functionality.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-08-03 14:15:14 +01:00
Sebastien Boeuf
8f0bf82648 io_uring: Add new feature gate
By adding a new io_uring feature gate, we let the user the possibility
to choose if he wants to enable the io_uring improvements or not.
Since the io_uring feature depends on the availability on recent host
kernels, it's better if we leave it off for now.

As soon as our CI will have support for a kernel 5.6 with all the
features needed from io_uring, we'll enable this feature gate
permanently.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-03 14:15:01 +01:00
Sebastien Boeuf
a85304196e virtio-devices: Improve error handling for virtio-blk io_uring
Instead of just logging error messages but continue the processing of
the queues, this patch returns errors right away. This allows for a
quicker detection of an error happening on the virtqueue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-03 14:15:01 +01:00
Sebastien Boeuf
917027c55b vmm: Rely on virtio-blk io_uring when possible
In case the host supports io_uring and the specific io_uring options
needed, the VMM will choose the asynchronous version of virtio-blk.
This will enable better I/O performances compared to the default
synchronous version.

This is also important to note the VMM won't be able to use the
asynchronous version if the backend image is in QCOW format.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-03 14:15:01 +01:00
Sebastien Boeuf
64283726e7 virtio-devices: Add an asynchronous virtio-blk device
This introduces a new version of virtio-blk device. The default
virtio-blk provides synchronous processing of the queues, while this
new version relies on io_uring from the host kernel to provide an
asynchronous processing of the queues.

This new asynchronous version provides a huge performance improvement
compared to the default synchronous version.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-03 14:15:01 +01:00
Sebastien Boeuf
49a6500185 block_util: Add utilities to support io_uring
Creates a dedicated function relying on io_uring crate to execute
io_uring specific requests.

Also creates a function for checking io_uring support on the host.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-08-03 14:15:01 +01:00
Henry Wang
5807a91f33 scripts: AArch64: Fix abnormal integration script behaviour
PR#1511 introduced a `flock` command in order to let AArch64 CI
can be executed with multiple executors. However the command
```
(
    echo "try to lock $WORKLOADS_DIR folder and update"
    flock -x 12 && update_workloads
)
```
will introduce an abnormal behavior: If any error happened in
function `updated_workloads`, the sub-shell opened by the pair of
parentheses will be killed instead of the main shell, which is not
right.

This commit fixes this abnormal execution behaviour.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-31 14:08:15 +02:00
Henry Wang
d5863caa4d ci: AArch64: Enable virtio-fs integration test
This commit enables the virtio-fs related integration test cases
for AArch64.

Note that to run virtio-fs cases, the host kernel should be
newer than v5.5.

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

Signed-off-by: Henry Wang <henry.wang@arm.com>
2020-07-31 14:06:55 +02:00
Henry Wang
77ba041362 ci: AArch64: Update custom linux kernel to v5.8-rc4
This commit updates the AArch64 kernel config file and integration
test script to v5.8-rc4, and this update keeps the aarch64 guest
kernel in sync with the x86_64 one.

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

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-31 14:06:55 +02:00
Michael Zhao
44eccbe1af scripts: Remove the workaround for "with-serde" build error on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-31 12:35:17 +01:00
Praveen Paladugu
afa8ecc90c vmm: add validation for network parameters
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
2020-07-31 09:07:12 +02:00
Wei Liu
a52b614a61 vmm: device_manager: console input should be only consumed by one device
Cloud Hypervisor allows either the serial or virtio console to output to
TTY, but TTY input is pushed to both.

This is not correct. When Linux guest is configured to spawn TTYs on
both ttyS0 and hvc0, the user effectively issues the same commands twice
in different TTYs.

Fix this by only direct input to the one choice that is using host side
TTY.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-30 18:05:01 +02:00
Wei Liu
5ed794a44c vmm: device_manager: rename console_input to virtio_console_input
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-30 18:05:01 +02:00
Michael Zhao
fec54f71b0 tests: Enable PCI integration test cases on AArch64
Enabled a minimum set of PCI test case.
More cases are to be adapted or debugged.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-30 09:52:12 +02:00
Michael Zhao
8e520d2415 resource: Enable PCI controller driver in AArch64 kernel config
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-30 09:52:12 +02:00
Wei Liu
3e68867bb7 vmm: device_manager: eliminate KvmMsiInterruptManager from the new function
The logic to create an MSI interrupt manager is applicable to Hyper-V as
well.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-30 08:00:33 +02:00
Michael Zhao
cf1b5156f4 scripts: Change AArch64 container network type BRIDGE
Changed the container network type to BRIDGE to seprate the networking
of parallel containers.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-29 18:32:44 +01:00
Michael Zhao
7e3cbf04de scripts: Improve AArch64 CI for parallel executors
Lock "work_loads" folder when one job is syncing files. If another job
arrives, wait until the lock is released.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-29 18:32:44 +01:00
dependabot-preview[bot]
12c5b7668a build(deps): bump libc from 0.2.73 to 0.2.74
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.73 to 0.2.74.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.73...0.2.74)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-28 20:46:37 +00:00
Muminul Islam
d49059a31b README: Fix copy command when using config from Cloud-hypervisor
The command which is mentioned in the README is wrong. We have two
cofigs one for x86_64 and another for aarh64. Previously it was a single
config. After adding the configs the read me was not modified. This
patch fixes the issue.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-07-28 21:09:22 +01:00
Wei Liu
218ec563fc vmm: fix warnings when KVM is not enabled
Some imports are only used by KVM. Some variables and code become dead
or unused when KVM is not enabled.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-28 21:08:39 +01:00
Howard Zhang
15bf61c6aa doc: AArch64: align rootfs name in arm64.md
Signed-off-by: Howard Zhang <howard.zhang@arm.com>
2020-07-28 10:38:13 +08:00
dependabot-preview[bot]
58f1051278 build(deps): bump pin-project from 0.4.22 to 0.4.23
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.22 to 0.4.23.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.22...v0.4.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-27 14:22:17 +00:00
dependabot-preview[bot]
35578f766a build(deps): bump proc-macro-hack from 0.5.16 to 0.5.18
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.16 to 0.5.18.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.16...0.5.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-27 13:08:25 +00:00
Sebastien Boeuf
8ad0e4d715 ci: Move to latest virtiofsd version
In order to follow the virtio-fs development, we rely on the latest
development branch regarding the virtio-fs daemon. It will be now build
from virtio-fs-dev branch from the virtio-fs maintainers repository.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-27 14:03:05 +01:00
Sebastien Boeuf
8dc0f49ba5 deps: Update vhost dependency
Move to latest vhost version, as it contains the updated list of
vhost-user protocol features along with the updated list of virtio-fs
slave commands.

This will allow Cloud-Hypervisor to work with latest virtiofsd binary.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-27 14:03:05 +01:00
dependabot-preview[bot]
6bf0d381e1 build(deps): bump serde_json from 1.0.56 to 1.0.57
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.56...v1.0.57)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-27 12:12:14 +00:00
Jianyong Wu
d24b110519 seccomp: AArch64: Add SYS_unlinkat to seccomp whitelist
This commit fixes an "Bad syscall" error when shutting down the VM
on AArch64 by adding the SYS_unlinkat syscall to the seccomp
whitelist.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2020-07-27 07:25:07 +00:00
dependabot-preview[bot]
948cd20bfa build(deps): bump syn from 1.0.35 to 1.0.36
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.35 to 1.0.36.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.35...1.0.36)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-27 06:21:51 +00:00
dependabot-preview[bot]
9eb6d45c40 build(deps): bump anyhow from 1.0.31 to 1.0.32
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.31 to 1.0.32.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.31...1.0.32)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-25 08:59:42 +00:00
Rob Bradford
56bfe2700d virtio-devices, net_util: Migrate virtio-net to EpollHelper
EpollHelper allows the removal of much duplicated loop handling code and
instead the device specific even handling is delegated via an
implementation of EpollHelperHandler.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-24 13:50:37 +02:00
Rob Bradford
d66fa942be virtio-devices: Implement AsRawFd for EpollHelper
This is required for implementing virtio-net as the epoll RawFd must be
assigned into the NetQueuePair.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-24 13:50:37 +02:00
Rob Bradford
1dcf1b11e4 virtio-devices: Reserve first 16 events for the EpollHelper
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-24 13:50:37 +02:00
dependabot-preview[bot]
609f34fa43 build(deps): bump micro_http from c9ffb90 to 40309b7
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `c9ffb90` to `40309b7`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](c9ffb90aeb...40309b72ee)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-24 06:42:53 +00:00
Rob Bradford
9ae44aeada vmm: acpi_tables: Fix PM timer I/O port width
Ensure that the width of the I/O port is correctly set to 32-bits in the
generic address used for the X_PM_TMR_BLK. Do this by type
parameterising GenericAddress::io_port_address() fuction.

TEST=Boot with clocksource=acpi_pm and observe no errors in the dmesg.

Fixes: #1496

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-23 17:48:22 +02:00
Rob Bradford
5cad2334dd virtio-block: Port to EpollHelper
Port virtio-block device to the new EpollHelper. This required moving
the queue EventFd ownership to BlockEpollHandler.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-23 13:10:34 +01:00
Rob Bradford
7d9dc4013e virtio-devices: Introduce EpollHelper
This is a helper for implementing the worker thread for virtio devices
and in particular handles special behaviour for pause and kill events.

The device specific event handling (for the queues themselves) is
delegated to a method invoked on a new EpollHelperHandler trait. This
method is passed the event as well as the EpollHelper so that it can
operate on the handler in order to manage events itself (required for
virtio-net.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-23 13:10:34 +01:00
Rob Bradford
aae5d988e1 devices: vmm: Add ACPI PM timer
This is a counter exposed via an I/O port that runs at 3.579545MHz. Here
we use a hardcoded I/O and expose the details through the FADT table.

TEST=Boot Linux kernel and see the following in dmesg:

[    0.506198] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-23 13:10:21 +01:00
Sebastien Boeuf
4fc7eb3daa docs: Add snapshot/restore documentation
Add some documentation regarding the snapshot/restore feature which was
introduced earlier, explaining how the feature works and how to use it
properly.

Fixes #1490

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-22 12:49:34 +01:00
Rob Bradford
08288305ef devices: cmos: Populate Update in Progress bit (UIP)
This bit should be set for the last 224us of each second. To be able to
fill this bit we need to use clock_gettime() to get the nanoseconds.
Also set the frequency bit to indicate we update at 32kHz.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-22 09:57:46 +02:00
Wei Liu
f03afea0d6 device_manager: document unsafe block in add_vfio_device
It is not immediately obvious why the conversion is safe. Document the
safety guarantee.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-21 17:13:10 +01:00
Samuel Ortiz
be51ea250d device_manager: Simplify the passthrough internal API
We store the device passthrough handler, so we should use it through our
internal API and only carry the passed through device configuration.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-21 17:20:25 +02:00
Michael Zhao
f57d970451 arch: Code cleanup after refactoring aarch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-21 16:22:02 +02:00
Michael Zhao
ddf1b76906 hypervisor: Refactor create_passthrough_device() for generic type
Changed the return type of create_passthrough_device() to generic type
hypervisor::Device.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-21 16:22:02 +02:00
Michael Zhao
6c8749adf2 arch: Switch to hypervisor crate
Removed the dependency on kvm-bindings and kvm-ioctls, use hypervisor
crate instead.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-21 16:22:02 +02:00
Michael Zhao
e7288888cf hypervisor: Extend hypervisor crate with Device trait
Added Device trait and KvmDevice struct for KVM-emulated devices.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-21 16:22:02 +02:00
Michael Zhao
e3e771727a arch: Refactor GIC code to seperate KVM specific code
Shrink GICDevice trait to contain hypervisor agnostic API's only, which
are used in generating FDT.
Move all KVM specific logic into KvmGICDevice trait.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-21 16:22:02 +02:00
Rob Bradford
6e8c8991d9 fuzz: qcow: Remove unnecessary "use libc"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-20 20:22:47 +02:00
Rob Bradford
191f64028a fuzz: Add a fuzzer for virtio-devices::Block
This is based on the block fuzzer from crosvm and ported to Cloud
Hypervisor.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-20 20:22:47 +02:00
dependabot-preview[bot]
d922986d78 build(deps): bump syn from 1.0.34 to 1.0.35
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.34 to 1.0.35.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.34...1.0.35)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-20 17:38:11 +00:00
Michael Zhao
b363d1c706 tests: Enable integration test for initramfs on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-20 14:20:53 +01:00
Michael Zhao
3e051e7b2c arch, vmm: Enable initramfs on AArch64
Ported Firecracker commit 144b6c.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-20 14:20:53 +01:00
Henry Wang
f449aec78e ci: AArch64: Enable AArch64 mmio-related integration test cases
This commit enables some mmio-related integration test cases on
AArch64, including:
* some vhost_user test cases
* virtio-blk test cases
* pmem test cases

Also this commit contains a bug fix in creating virtio-blk device.
Previously, when creating the FDT, the virtio-blk device was
labeled in the reverse order of address allocation.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-20 11:45:47 +01:00
dependabot-preview[bot]
07b6026f45 build(deps): bump proc-macro2 from 1.0.18 to 1.0.19
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.18...1.0.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-20 08:06:29 +00:00
Sebastien Boeuf
840445096a docs: Add Intel SGX documentation
Adding a few notes and links about how to enable and use SGX through
Cloud-Hypervisor.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-20 09:06:06 +01:00
Wei Liu
e1af251c9f vmm, hypervisor: adjust set_gsi_routing / set_gsi_routes
Make set_gsi_routing take a list of IrqRoutingEntry. The construction of
hypervisor specific structure is left to set_gsi_routing.

Now set_gsi_routes, which is part of the interrupt module, is only
responsible for constructing a list of routing entries.

This further splits hypervisor specific code from hypervisor agnostic
code.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-20 07:32:32 +02:00
dependabot-preview[bot]
12b37ef13b build(deps): bump libc from 0.2.72 to 0.2.73
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.72 to 0.2.73.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.72...0.2.73)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-20 05:15:24 +00:00
Wei Liu
d484a3383c vmm: device_manager: introduce add_passthrough_device
It calls add_vfio_device on KVM or returns an error when not running on
KVM.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-17 20:21:39 +02:00
Wei Liu
821892419c vmm: device_manager: use generic names for passthrough device
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-17 20:21:39 +02:00
Wei Liu
ff8d7bfe83 hypervisor: add create_passthrough_device call to Vm trait
That function is going to return a handle for passthrough related
operations.

Move create_kvm_device code there.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-17 20:21:39 +02:00
Samuel Ortiz
7bfe87b7af README: Refer to the community repository
We now have a defined governance model.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-17 12:56:37 +02:00
Rob Bradford
4d878418e5 fuzz: Add fuzzing infrastructure and QCOW fuzzer
Add the basic infrastructure for fuzzing along with a qcow fuzzer ported
from crosvm and adapted to our code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-17 08:49:35 +02:00
dependabot-preview[bot]
9267628e7c build(deps): bump vfio-ioctls from 195d6c6 to 49cc362
Bumps [vfio-ioctls](https://github.com/cloud-hypervisor/vfio-ioctls) from `195d6c6` to `49cc362`.
- [Release notes](https://github.com/cloud-hypervisor/vfio-ioctls/releases)
- [Commits](195d6c6eb0...49cc3626f6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-17 06:45:58 +00:00
Wei Liu
c08d2b2c70 device_manager: avoid manipulating MemoryRegion fields directly
Hyper-V may have different field names. Use make_user_memory_region
instead.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-16 15:56:03 +02:00
Rob Bradford
dfd6f3471d virtio-devices: vhost_user: block: Only change mutable field in write_config()
The only driver writable field in the virtio-block specification is the
writeback one. Check that the offset being written to is for that field
and update it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
eabcd618ba virtio-devices: block: Only change mutable field in write_config()
The only driver writable field in the virtio-block specification is the
writeback one. Check that the offset being written to is for that field
and update it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
751a302050 virtio-devices: Port devices over to new read_config_from_slice() helper
Using this helper removes lots of duplicated code across the devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
d262540857 virtio-devices: Introduce helper for implementing read_config()
Add a helper function to share code between implementations that can use
a slice accessible data structure for configuration data.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
5d67338b29 virtio-devices: Remove warning generating read_config() implementation
The version in VirtioDevice can be used instead.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
676322c3cc virtio-devices: vsock: Remove write_config() implementation
This warning generating implementation can be handled by the version in
VirtioDevice.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
580739f776 virtio-devices: vhost_user: fs: Remove write_config() implementation
All the configuration fields for virtio-fs are read only for the driver.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
15d5cc62ff virtio-devices: vhost_user: net: Remove write_config implementation
The spec specifies that all fields are read-only from the driver.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
f1e940df8d virtio-devices: net: Remove write_config implementation
The spec specifies that all fields are read-only from the driver.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
e3dc620146 virtio-devices: Remove write_config implementations
Remove the write_config() implementations that only generate a warning
as that is now done at the VirtioDevice level.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Rob Bradford
6ba1c4318e virtio-devices: Add default implementations for {read,write}_config
Not every virtio device has any config fields that can be read and most
have none that can be written to.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-16 13:17:22 +02:00
Michael Zhao
f1419d116d docs: Update AArch64 doc to use KVM feature
Updated the build instructions to adapt to new added KVM feature.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-16 11:00:32 +02:00
Michael Zhao
2de4f73275 arch: Add log messages in GIC creation
The retry order to create virtual GIC is GICv3-ITS, GICv3 and GICv2.
But there was not log message to show what was finally created.
The log messages also mute the warning for unused "log" crate.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-16 11:00:32 +02:00
Bo Chen
48966b4535 docs: Update API documentation about '/vm.remove-device'
With recent changes (#1030 #1084), the '/vm.remove-device' API is no
longer restricted to remove VFIO PCI devices. It now supports (almost)
all hotpluggable devices, e.g. disk/net/pmem/fs/vsock.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-07-16 07:35:26 +02:00
Muminul Islam
053ea5dcd3 vfio: Make vfio to use MemoryRegion instead of kvm_userspace_memory_region
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-07-16 07:34:27 +02:00
dependabot-preview[bot]
cc57467d10 build(deps): bump log from 0.4.8 to 0.4.11
Bumps [log](https://github.com/rust-lang/log) from 0.4.8 to 0.4.11.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.8...0.4.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-16 05:33:44 +00:00
Wei Liu
d80e383dbb arch: move test cases to vmm crate
This saves us from adding a "kvm" feature to arch crate merely for the
purpose of running tests.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-15 17:21:07 +02:00
Wei Liu
598eaf9f86 vmm: use hypervisor::new in test_vm
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-15 17:21:07 +02:00
Wei Liu
11ffc83365 arch: use hypervsisor::new in test cases
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-15 17:21:07 +02:00
Wei Liu
085d165f8a bin: switch to hypervisor::new
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-15 17:21:07 +02:00
Wei Liu
a83bd97e0d hypervisor: introduce a new function
It returns an hypervisor object depending on which hypervisor is
configured.  Currently it only supports KVM.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-15 17:21:07 +02:00
Sebastien Boeuf
a5c4f0fc6f arch, vmm: Add e820 entry related to SGX EPC region
SGX expects the EPC region to be reported as "reserved" from the e820
table. This patch adds a new entry to the table if SGX is enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Sebastien Boeuf
e10d9b13d4 arch, hypervisor, vmm: Patch CPUID subleaves to expose EPC sections
The support for SGX is exposed to the guest through CPUID 0x12. KVM
passes static subleaves 0 and 1 from the host to the guest, without
needing any modification from the VMM itself.

But SGX also relies on dynamic subleaves 2 through N, used for
describing each EPC section. This is not handled by KVM, which means
the VMM is in charge of setting each subleaf starting from index 2
up to index N, depending on the number of EPC sections.

These subleaves 2 through N are not listed as part of the supported
CPUID entries from KVM. But it's important to set them as long as index
0 and 1 are present and indicate that SGX is supported.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Sebastien Boeuf
1603786374 vmm: Pass MemoryManager through CpuManager creation
Instead of passing the GuestMemoryMmap directly to the CpuManager upon
its creation, it's better to pass a reference to the MemoryManager. This
way we will be able to know if SGX EPC region along with one or multiple
sections are present.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Sebastien Boeuf
2b06ce0ed4 vmm: Add EPC device to ACPI tables
The SGX EPC region must be exposed through the ACPI tables so that the
guest can detect its presence. The guest only get the full range from
ACPI, as the specific EPC sections are directly described through the
CPUID of each vCPU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Sebastien Boeuf
84cf12d86a arch, vmm: Create SGX virtual EPC sections from MemoryManager
Based on the presence of one or multiple SGX EPC sections from the VM
configuration, the MemoryManager will allocate a contiguous block of
guest address space to hold the entire EPC region. Within this EPC
region, each EPC section is memory mapped.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Sebastien Boeuf
d9244e9f4c vmm: Add option for enabling SGX EPC regions
Introducing the new CLI option --sgx-epc along with the OpenAPI
structure SgxEpcConfig, so that a user can now enable one or multiple
SGX Enclave Page Cache sections within a contiguous region from the
guest address space.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-15 15:08:56 +02:00
Rob Bradford
1842865823 build: Add missing "hypervisor" crate from workspace
Also rearrange the workspace members so they are in alphabetical order.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-15 13:09:21 +02:00
Rob Bradford
9c867edc35 vhost_user_block, virtio-devices, block_util: Extract common block code
Extract the code that is used by vhost_user_block from the
virtio-devices crate to remove the dependencies on unrequired
functionality such as the virtio transports.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-15 10:17:11 +01:00
dependabot-preview[bot]
ce79482ec4 build(deps): bump linux-loader from ec930d7 to b309c9d
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `ec930d7` to `b309c9d`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](ec930d700f...b309c9df17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-15 07:03:06 +00:00
Henry Wang
5a2ff98917 ci: AArch64: Add a build stage for musl toolchain
This commit adds required environment configurations to the
`dev_cli.sh` and a Jenkins stage to enable AArch64 binary
building using musl toolchain.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-15 08:19:15 +02:00
Henry Wang
e81402e76e ci: AArch64: Refactor custom linux kernel building strategy
As the current AArch64 integration test builds kernel every time,
which would take unnecessary time in CI and therefore not ideal.

This commit refactors the AArch64 kernel building strategy to:
1. Keep the Linux kernel source code directory instead of deleting
it everytime after the kernel is built.

2. In integration test script, check if the Linux kernel source
code directory exists. If so use `git fetch && git checkout -f` to
keep the source code always updated, else run `git clone` to get
the source code.

3. Copy config file in and then compile the kernel.

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

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-15 08:10:20 +02:00
Rob Bradford
dc55e45977 pci: Introduce and use PciBar struct
This simplies some of the handling for PCI BARs particularly with
respect to snapshot and restore. No attempt has been made to handle the
64-bit bar handling in a different manner to that which was used before.

Fixes: #1153

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-15 07:59:33 +02:00
Michael Zhao
cbb1f4cc2d docs: Add document for using PCI on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
Michael Zhao
cce6237536 pci: Enable GSI routing (MSI type) for AArch64
In this commit we saved the BDF of a PCI device and set it to "devid"
in GSI routing entry, because this field is mandatory for GICv3-ITS.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
Michael Zhao
82a0e29c7a hypervisor: Export check_extension() API from hypervisor::Vm
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
Michael Zhao
f2e484750a arch: aarch64: Add PCIe node in FDT for AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
Michael Zhao
598bcf1459 arch: aarch64: Add GICv3-ITS on AArch64
GICv3-ITS is needed for MSI handling.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
Michael Zhao
17057a0dd9 vmm: Fix build errors with "pci" feature on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-14 14:34:54 +01:00
dependabot-preview[bot]
9ec4aa4019 build(deps): bump vfio-ioctls from 4c56812 to 195d6c6
Bumps [vfio-ioctls](https://github.com/cloud-hypervisor/vfio-ioctls) from `4c56812` to `195d6c6`.
- [Release notes](https://github.com/cloud-hypervisor/vfio-ioctls/releases)
- [Commits](4c568127fe...195d6c6eb0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 16:53:05 +00:00
Wei Liu
e5552a53d8 arch, pci: rename vm_fd to vm
The type is now hypervisor::Vm. Switch from KVM specific name vm_fd to a
generic name just like 8186a8eee6 ("vmm: interrupt: Rename vm_fd").

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-13 16:08:00 +01:00
Sebastien Boeuf
8be80aca80 ci: Give some time to the disk hotplug
Under high load, the VM might take some time to hotplug the disk after
the hotplug command has been issued. For this reason, let's put a 10s
sleep before checking for the presence of the new disk.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-13 12:19:24 +02:00
Sebastien Boeuf
802f02532a ci: Extend test_vfio time before VM is ready
We want to give the time to the nested VM to be fully ready before we
check it's correctly setup. This involves 3 layers of virtualization
when running the CI on Azure, which added to the high load happening
because of the parallelization, adds up to the start up time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-13 12:19:24 +02:00
Hui Zhu
165568e98b virtio-mem: Update VirtioMemConfig according to Linux kernel
Types of block_size and padding is updated in
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=544fc7dbbf920a3e64d109c416ee229e8e1763c5.
Update VirtioMemConfig according to it.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-13 12:19:24 +02:00
Sebastien Boeuf
3cc8ca4ea5 virtio-devices: Update virtio-iommu to follow 5.8-rc4 kernel
The virtio configuration structures have been slightly modified between
5.6-rc4 and 5.8-rc4, forcing the virtio-iommu device to be updated
accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-13 12:19:24 +02:00
Sebastien Boeuf
2721a7004f ci: Update guest kernel to v5.8-rc4
Updating the kernel from 5.6-rc4 to 5.8-rc4 allows us to remove the
dependency on both virtio-vsock and virtio-mem patches as they are now
part of the upstream kernel. We're still carrying virtio-iommu and
virtio-fs patches.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-13 12:19:24 +02:00
Rob Bradford
81ce8f505c tests: Enable virtio-mmio tests for virtio-console
This is useful to ensure that virtio-console support is covered.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-13 10:16:03 +02:00
dependabot-preview[bot]
3800acd347 build(deps): bump adler from 0.2.2 to 0.2.3
Bumps [adler](https://github.com/jonas-schievink/adler) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/jonas-schievink/adler/releases)
- [Changelog](https://github.com/jonas-schievink/adler/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jonas-schievink/adler/compare/v0.2.2...v0.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 05:31:14 +00:00
dependabot-preview[bot]
cde162c62f build(deps): bump syn from 1.0.33 to 1.0.34
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.33...1.0.34)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 05:06:39 +00:00
dependabot-preview[bot]
8ab11ae87e build(deps): bump pkg-config from 0.3.17 to 0.3.18
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.17 to 0.3.18.
- [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.17...0.3.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 05:05:29 +00:00
dependabot-preview[bot]
dda4cd8eb7 build(deps): bump redox_syscall from 0.1.56 to 0.1.57
Bumps redox_syscall from 0.1.56 to 0.1.57.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 05:04:16 +00:00
Rob Bradford
4963e37dc8 qcow, virtio-devices: Break cyclic dependency
Move the definition of RawFile from virtio-devices crate into qcow
crate. All the code that consumes RawFile also already depends on the
qcow crate for image file type detection so this change breaks the
need for the qcow crate to depend on the very large virtio-devices
crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-10 17:47:31 +02:00
Rob Bradford
6161d3bef8 tests: Enable virtio-vsock testing with virtio-mmio transport
As compiling without acpi (implied by mmio) means that the VM will
terminate on i8042 reset we cannot test the reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-10 07:22:37 +02:00
Rob Bradford
bb6b738c0d tests: Enable test_multiple_network_interfaces with virtio-mmio
Ensure that multiple network interfaces function correctly when using
virtio-mmio.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-09 09:53:30 +02:00
Rob Bradford
730f3884f4 tests: Enable test_virtio_blk with virtio-mmio transport
This test makes use of MQ support in virtio-block so it is advisable to
test with virtio-mmio.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-09 09:53:13 +02:00
Rob Bradford
d725c2cbfb tests: Enable virtio-mem testing with virtio-mmio
Try and enable virtio-mem testing when using the virtio-mmio transport.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-09 09:52:56 +02:00
dependabot-preview[bot]
96274a33ca build(deps): bump cc from 1.0.57 to 1.0.58
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.57...1.0.58)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-08 15:12:19 +00:00
Rob Bradford
f47f221f24 build: Remove obsolete feature differentiated vhost_user_net builds
Now that vhost_user_net crate does not depend on the virtio-devices
crate it is no longer compiled differently based on the mmio or pci
features.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
17766fcea4 net_util, vhost_user_net, virtio-devices: Move NetQueuePair
Move NetQueuePair and the related NetCounters into the net_util crate.
This means that the vhost_user_net crate now no longer depends on
virtio-devices and so does not depend on the pci, qcow or other similar
crates. This significantly simplifies the build chain for this backend.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
1237784a8f net_util, virtio-devices: Move TAP register/unregister helpers
Move these helper functions into net_util so that they can be used from
code inside there.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
7f3e40e0cf net_util: Consolidate vnet_hdr_len() functions
As a result of refactoring this function was duplicated so consolidate
into the top level.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
48faf3abac net_util, virtio-devices, vhost_user_net: Relocate {Rx,Tx}Virtio
By moving the code for opening the two RX and TX queues into a shared
location we are starting to remove the requirement for the
vhost-user-net backend to depend on the virtio-devices crate which in of
itself depends on many other crates that are not necessary for the
backend to function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
2efd307c4e net_util: Use two two different enums for MQ error
Rather than use an embedded String inside the MultiQueueSupport error
value use two different values to differentiate the two cases.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
Rob Bradford
3e807a19b7 net_util, virtio-devices, vhost_user_net: Relocate code for opening TAP
By moving the code for opening the TAP device into a shared location we
are starting to remove the requirement for the vhost-user-net backend to
depend on the virtio-devices crate which in of itself depends on many
other crates that are not necessary for the backend to function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-08 16:11:50 +01:00
dependabot-preview[bot]
bb390981a9 build(deps): bump kvm-ioctls from d094064 to 37953e9
Bumps [kvm-ioctls](https://github.com/cloud-hypervisor/kvm-ioctls) from `d094064` to `37953e9`.
- [Release notes](https://github.com/cloud-hypervisor/kvm-ioctls/releases)
- [Commits](d094064fef...37953e968b)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-08 12:53:00 +00:00
Wei Liu
5bfac796b3 build: add a default feature KVM
It gets bubbled all the way up from hypervsior crate to top-level
Cargo.toml.

Cloud Hypervisor can't function without KVM at this point, so make it
a default feature.

Fix all scripts that use --no-default-features.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-08 11:07:15 +01:00
dependabot-preview[bot]
861337cc6f build(deps): bump libc from 0.2.71 to 0.2.72
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.71 to 0.2.72.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.71...0.2.72)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-08 05:11:25 +00:00
Sebastien Boeuf
ef554ba13c ci: Increase time to stabilize memory measurement
Check if increasing the time after the VM is spawned help with getting
more stable numbers for the base PSS.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-07 19:36:12 +02:00
Hui Zhu
b59f231092 tests: Add integration test to test_memory_hotplug for virtio-balloon
Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
Hui Zhu
800220acbb virtio-balloon: Store the balloon size to support reboot
This commit store balloon size to MemoryConfig.
After reboot, virtio-balloon can use this size to inflate back to
the size before reboot.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
Sebastien Boeuf
50da100afd virtio-devices: Fix virtio-balloon device
The implementation of the virtio-balloon was slightly wrong as it was
generating the GPA (Guest Physical Address) from the PFN (Page Frame
Number) which was a u32. That means the GPA was created as a u32, and
later a cast was done to extend it to a u64 type. Unfortunately, by
doing so, the GPA was wrong if the value was supposedly more than 32
bits.

That's why the PFN is casted into a u64 before the GPA is generated,
which creates the GPA on 64 bits directly.

Additionally, this patch simplifies the process_queue() function,
relying on multiple vm-memory helpers.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-07 17:25:13 +01:00
Hui Zhu
8ffbc3d031 vmm: api: ch-remote: Add balloon to VmResizeData
Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
Hui Zhu
f729b25a10 openapi: Add MemoryConfig balloon
Add MemoryConfig balloon to vmm/src/api/openapi/cloud-hypervisor.yaml.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
Hui Zhu
8b6b97b86f vmm: Add virtio-balloon support
This commit adds new option balloon to memory config.
Set it to on will open the balloon function.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
Hui Zhu
0d72aa782f virtio-devices: Add virtio-balloon device
Add virtio-balloon device.
It only supports the basic functions of the virtio-balloon.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-07-07 17:25:13 +01:00
dependabot-preview[bot]
ccc276a222 build(deps): bump backtrace from 0.3.49 to 0.3.50
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.49 to 0.3.50.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.49...0.3.50)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-07 14:40:07 +00:00
Henry Wang
603445e0a5 tests: Add a Jenkins stage for AArch64 integration test
This commit adds a Jenkins stage for AArch64 integration test,
and the test is carried out using the GNU toolchain.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-07 13:55:39 +01:00
Henry Wang
33c5d6bb98 tests: Enable test_aarch64_pe_boot case for AArch64
The compiled AArch64 linux kernel by running `make` is in PE format
instead of vmlinux, vmlinux.pvh and bzImage format. Therefore we
need to add integration test for this case.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-07 13:55:39 +01:00
Henry Wang
2ce231370d tests: Preparation of enabling integration tests for AArch64
This commit adds supporting components and code for enabling the
AArch64 integration tests, including:

1. A Linux kernel config file to build kernel on AArch64 machines.

2. Refactoring the `run_integration_test.sh` to architecture
specific scripts for readability.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-07 13:55:39 +01:00
Rob Bradford
b69f6d4f6c vhost_user_net, vhost_user_block, option_parser: Remove vmm dependency
Remove the vmm dependency from vhost_user_block and vhost_user_net where
it was existing to use config::OptionParser. By moving the OptionParser
to its own crate at the top-level we can remove the very heavy
dependency that these vhost-user backends had.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 18:33:29 +01:00
dependabot-preview[bot]
90261bb9c7 build(deps): bump smallvec from 1.4.0 to 1.4.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.4.0...v1.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 16:38:18 +00:00
Michael Zhao
726e45e0ce vmm: Divide Seccomp KVM IOCTL rules by architecture
Refactored the construction of KVM IOCTL rules for Seccomp.
Separating the rules by architecture can reduce the risk of bugs and
attacks.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-06 13:40:38 +01:00
Wei Liu
a4f484bc5e hypervisor: Define a VM-Exit abstraction
In order to move the hypervisor specific parts of the VM exit handling
path, we're defining a generic, hypervisor agnostic VM exit enum.

This is what the hypervisor's Vcpu run() call should return when the VM
exit can not be completely handled through the hypervisor specific bits.
For KVM based hypervisors, this means directly forwarding the IO related
exits back to the VMM itself. For other hypervisors that e.g. rely on the
VMM to decode and emulate instructions, this means the decoding itself
would happen in the hypervisor crate exclusively, and the rest of the VM
exit handling would be handled through the VMM device model implementation.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Fix test_vm unit test by using the new abstraction and dropping some
dead code.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-06 12:59:43 +01:00
Wei Liu
cfa758fbb1 vmm, hypervisor: introduce and use make_user_memory_region
This removes the last KVM-ism from memory_manager. Also make use of that
method in other places.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-06 12:31:19 +02:00
Wei Liu
8d97d628c3 vmm: drop "kvm" from memory slot code
The code is purely for maintaining an internal counter. It is not really
tied to KVM.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-06 12:31:19 +02:00
Rob Bradford
f19f7490c6 build: Bulk upgrade dependencies
There are several dependencies that need updating so update them
manually rather than relying on dependabot. This will reduce the load on
the CI.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:46:17 +01:00
Rob Bradford
72802b34cd vhost_user_block: Move binary into vhost_user_block crate
The binary is still built in the same location but the source code and
the dependencies for it come from the vhost_user_block crate itself.

The binary will be built with:

`cargo build --all --bin vhost_user_block` or just `cargo build --all`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
6959d27e8c vhost_user_net: Move binary into vhost_user_net crate
The binary is still built in the same location but the source code and
the dependencies for it come from the vhost_user_net crate itself.

The binary will be built with:

`cargo build --all --bin vhost_user_net` or just `cargo build --all`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
7548283feb build: Remove unused dependencies from top-level Cargo.toml
With vhost_user_fs binary moved to its own crate the dependencies in the
top level can be trimmed significantly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
d6a05ceabb vhost_user_fs: Move binary into vhost_user_fs crate
The binary is still built in the same location but the source code and
the dependencies for it come from the vhost_user_fs crate itself.

The binary will be built with:

`cargo build --all --bin vhost_user_fs` or just `cargo build --all`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
b8be6bab16 tests: Prepare for splitting binaries by building all binaries
In preparation for splitting the binaries into their own crates start
building all the binaries in the workspace as part of the integration
testing suite.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
6f59cdbb55 build: dev_cli: Prepare for splitting binaries by building all binaries
In preparation for splitting the binaries into their own crates start
building all the binaries in the workspace when running the build
command inside the container.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
Rob Bradford
1e9956c8cb build: github: Prepare for splitting binaries by building all binaries
In preparation for splitting the binaries into their own crates start
building all the binaries in the workspace when doing a build as part of
the GitHub actions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-06 10:56:10 +02:00
dependabot-preview[bot]
863ea97213 build(deps): bump vfio-ioctls from f6f81ee to 4c56812
Bumps [vfio-ioctls](https://github.com/cloud-hypervisor/vfio-ioctls) from `f6f81ee` to `4c56812`.
- [Release notes](https://github.com/cloud-hypervisor/vfio-ioctls/releases)
- [Commits](f6f81ee865...4c568127fe)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 08:45:57 +00:00
Samuel Ortiz
8186a8eee6 vmm: interrupt: Rename vm_fd
The _fd suffix is KVM specific. But since it now point to an hypervisor
agnostic hypervisor::Vm implementation, we should just rename it vm.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Samuel Ortiz
4cc8853fe4 vmm: device_manager: Rename vm_fd
The _fd suffix is KVM specific. But since it now point to an hypervisor
agnostic hypervisor::Vm implementation, we should just rename it vm.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Samuel Ortiz
2012287611 vmm: memory_manager: Rename fd variable into something more meaningful
The fd naming is quite KVM specific. Since we're now using the
hypervisor crate abstractions, we can rename those into something more
readable and meaningful.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Samuel Ortiz
acfe5eb94f vmm: vm: Rename fd variable into something more meaningful
The fd naming is quite KVM specific. Since we're now using the
hypervisor crate abstractions, we can rename those into something more
readable and meaningful.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Samuel Ortiz
3db4c003a3 vmm: cpu: Rename fd variable into something more meaningful
The fd naming is quite KVM specific. Since we're now using the
hypervisor crate abstractions, we can rename those into something more
readable and meaningful. Like e.g. vcpu or vm.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Samuel Ortiz
618722cdca hypervisor: cpu: Rename state getter and setter
vcpu.{set_}cpu_state() is a stutter.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-07-06 09:35:30 +01:00
Sebastien Boeuf
a3342bdb25 docs: Replace every mention of ClearLinux with Ubuntu
Now that our CI has transitioned from ClearLinux to Ubuntu images
exclusively, let's update the documentation to refer to Ubuntu images
instead of ClearLinux's ones.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-03 14:37:09 +02:00
Sebastien Boeuf
b452e8be00 docs: Update custom image instructions
Now that the project relies on Ubuntu images, the documentation related
to the creation of a custom image has been updated. It's important to
note this procedure could be applied to any other distribution, given
that the package manager's commands would be slightly different.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-03 14:37:09 +02:00
Sebastien Boeuf
bb9174601a ci: Separate parallel vs sequential tests
In order to differentiate tests that can be run in parallel versus
tests that must be run on their own, we move all tests into dedicated
modules.

The point is to avoid glitches in results that can be caused by the fact
that other tests (hence VMs) are running at the same time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-03 13:08:37 +01:00
Rob Bradford
2a6eb31d5b vm-virtio, virtio-devices: Split device implementation from virt queues
Split the generic virtio code (queues and device type) from the
VirtioDevice trait, transport and device implementations.

This also simplifies the feature handling in vhost_user_backend as the
vm-virtio crate is no longer has any features.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-02 17:09:28 +01:00
dependabot-preview[bot]
9a628edfcf build(deps): bump cc from 1.0.56 to 1.0.57
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.56...1.0.57)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-02 14:40:59 +00:00
Wei Liu
44be3af9c8 arch: drop one level of indirection for boot_msr_entries
This makes setup_msrs hypervisor agnostic.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-07-02 13:47:58 +02:00
Sebastien Boeuf
c2920d2b6b ci: Move from Clear Linux to Ubuntu Focal Fossa cloud image
Move the CI to rely entirely on Ubuntu cloud images. It's worth noting
that both QCOW2 and RAW images from Ubuntu Focal Fossa have been
modified to include the tools needed from integration tests.
This means fio, iperf, iperf3, netcat and socat have been added to the
image. The snapd package have been fully removed as it was expecting the
support for squashfs (not present when using our own kernel from direct
kernel boot), which was causing some failures, and was preventing
cloud-init from terminating properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-02 13:47:16 +02:00
Sebastien Boeuf
1f9103bb67 test_data: Update Ubuntu cloud-init to support all integration tests
Updating the cloud-init files related to Ubuntu images is needed to be
able to use Ubuntu images for running all integration tests.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-07-02 13:47:16 +02:00
Rob Bradford
135ee4568e tests: Enhance rate_limited_copy() to also consider free disk space
With QCOW disk images the space needed is greater than the size of the
iamge as any "zero" blocks in the image are allocated when they are
touched making the image bigger.

Here we add a threshold of 6GiB with added debugging messages to ensure
that there is sufficient disk space to run the tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-02 11:52:49 +02:00
Michael Zhao
8820e9e133 vmm: Fix Seccomp filter for AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-07-02 08:46:24 +01:00
Rob Bradford
8e43f886e1 build: Bump kvm-ioctls dependency after rebase
ch branch is now rebased on latest upstream master

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-07-01 18:46:05 +02:00
Henry Wang
b70e254700 resources: Dockerfile: Update Dockerfile for AArch64
This update of Dockerfile will add support to the AArch64
integration tests and musl building, including:

1. Installation of the missing `setcap` binary on AArch64.
On AArch64, `setcap` binary should be installed via `libcap2-bin`.
This binary is needed in the integration test.

2. Related support for the cloud-hypervisor binary building by
musl toolchain.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-07-01 09:51:15 +01:00
Wei Liu
92a62d80e9 README: update hypervisor-fw release
The CI is using 0.2.8.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 21:02:13 +01:00
Rob Bradford
f8a8a5ca68 arch: x86_64: Remove residual debugging from smbios code
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-30 15:50:33 +01:00
Rob Bradford
602f76e4fc arch: x86_64: Use symbolic constant for end of table
The other types use a symbolic constant so do the same for consistency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-30 15:50:33 +01:00
Sebastien Boeuf
514978b54a ci: Improve test_snapshot_restore with multiple vCPUs
Extend the existing integration test test_snapshot_restore by testing
with more than one vCPU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-30 14:03:03 +01:00
Sebastien Boeuf
e35d4c5b28 hypervisor: Store all supported MSRs
On x86 architecture, we need to save a list of MSRs as part of the vCPU
state. By providing the full list of MSRs supported by KVM, this patch
fixes the remaining snapshot/restore issues, as the vCPU is restored
with all its previous states.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-30 14:03:03 +01:00
Sebastien Boeuf
49b4fba283 hypervisor: Retrieve list of supported MSRs
Add a new function to the hypervisor trait so that the caller can
retrieve the list of MSRs supported by this hypervisor.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-30 14:03:03 +01:00
Sebastien Boeuf
e2b5c78dc5 hypervisor: Re-order vCPU state for storing and restoring
Some vCPU states such as MP_STATE can be modified while retrieving
other states. For this reason, it's important to follow a specific
order that will ensure a state won't be modified after it has been
saved. Comments about ordering requirements have been copied over
from Firecracker commit 57f4c7ca14a31c5536f188cacb669d2cad32b9ca.

This patch also set the previously saved VCPU_EVENTS, as this was
missing from the restore codepath.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-30 14:03:03 +01:00
Wei Liu
2b8accf49a vmm: interrupt: put KVM code into a kvm module
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
c31e747005 vmm: interrupt: generify impl InterruptManager for MsiInterruptManager
The logic can be shared among hypervisor implementations.

The 'static bound is used such that we don't need to deal with extra
lifetime parameter everywhere. It should be okay because we know the
entry type E doesn't contain any reference.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
ade904e356 vmm: interrupt: generify impl InterruptSourceGroup for MsiInterruptGroup
At this point we can use the same logic for all hypervisor
implementations.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
2b466ed80c vmm: interrupt: provide MsiInterruptGroupOps trait
Currently it only contains a function named set_gsi_routes.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
b2abead65b vmm: interrupt: provide and use extension trait RoutingEntryExt
This trait contains a function which produces a interrupt routing entry.

Implement that trait for KvmRoutingEntry and rewrite the update
function.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
4dbca81b86 vmm: interrupt: rename set_kvm_gsi_routes to set_gsi_routes
This function will be used to commit routing information to the
hypervisor.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
fd7b42e54d vmm: interrupt: inline mask_kvm_entry
The logic for looking up the correct interrupt can be shared among
hypervisors.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
0ec39da90c vmm: interrupt: generify KvmMsiInterruptManager
The observation is only the route entry is hypervisor dependent.

Keep a definition of KvmMsiInterruptManager to avoid too much code
churn.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
d5149e95cb vmm: interrupt: generify KvmRoutingEntry and KvmMsiInterruptGroup
The observation is that only the route field is hypervisor specific.

Provide a new function in blanket implementation. Also redefine
KvmRoutingEntry with RoutingEntry to avoid code churn.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
637f58bcd9 vmm: interrupt: drop Kvm prefix from KvmLegacyUserspaceInterruptManager
This data structure doesn't contain KVM specific stuff.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
Wei Liu
574cab6990 vmm: interrupt: create GSI hashmap directly
The observation is that the GSI hashmap remains untouched before getting
passed into the MSI interrupt manager. We can create that hashmap
directly in the interrupt manager's new function.

The drops one import from the interrupt module.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-30 12:09:42 +01:00
dependabot-preview[bot]
f3c8f827cc build(deps): bump linux-loader from 2a62f21 to ec930d7
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `2a62f21` to `ec930d7`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](2a62f21b44...ec930d700f)

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-30 07:05:06 +00:00
Rob Bradford
fbbe348447 arch: x86-64: Add missing End of Table entry
The OVMF firmware loops around looking for an entry marking the end of
the table. Without this entry processing the tables is an infinite loop.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-30 08:15:48 +02:00
Rob Bradford
2c3c335de6 arch: x86_64: Add basic SMBIOS support
Taken from crosvm: 44336b913126d73f9f8d6854f57aac92b5db809e and adapted
for Cloud Hypervisor.

This is basic and incomplete support but Linux correctly finds the DMI
data based on this:

root@clr-c6ed47bc1c9d473d9a3a8bddc50ee4cb ~ # dmesg | grep -i dmi
[    0.000000] DMI: Cloud Hypervisor cloud-hypervisor, BIOS 0

root@clr-c6ed47bc1c9d473d9a3a8bddc50ee4cb ~ # dmesg | grep -i smbio
[    0.000000] SMBIOS 3.2.0 present.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-30 08:15:48 +02:00
Wei Liu
24c051c663 vmm: hypervisor: drop duplicate comment
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-29 21:51:59 +01:00
Wei Liu
2518b9e3cd vmm: hypervisor: fix white space issues
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-29 21:51:59 +01:00
dependabot-preview[bot]
5ac3299234 build(deps): bump serde_json from 1.0.55 to 1.0.56
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.55 to 1.0.56.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.55...v1.0.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-29 19:54:47 +00:00
dependabot-preview[bot]
58980067f4 build(deps): bump ssh2 from 0.8.1 to 0.8.2
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.8.1 to 0.8.2.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.8.1...0.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-29 18:02:38 +00:00
dependabot-preview[bot]
d2780a6575 build(deps): bump unicode-width from 0.1.7 to 0.1.8
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/unicode-rs/unicode-width/releases)
- [Commits](https://github.com/unicode-rs/unicode-width/commits/v0.1.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-29 17:37:40 +00:00
Samuel Ortiz
5a6b8d6323 dev_cli: Add a shell command
And drop the caller into a privileged root shell.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-29 18:17:39 +01:00
Henry Wang
d824d55562 unit tests: Fix broken AArch64 unit tests
https://github.com/cloud-hypervisor/cloud-hypervisor/pull/1225
introduces a hypervisor abstraction crate, which breaks some of
the unit test cases on AArch64. This commit fixes related test
cases.

Signed-off-by: Henry Wang <henry.wang@arm.com>
2020-06-29 18:00:42 +01:00
Henry Wang
462c58d58b tests: Enable AArch64 Jenkins CI with unit tests for GNU
This commit enables the AArch64 Jenkins CI with build and running
unit tests for GNU toolchain.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-29 18:00:42 +01:00
dependabot-preview[bot]
ba3f1bcde2 build(deps): bump cc from 1.0.55 to 1.0.56
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.55 to 1.0.56.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.55...1.0.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-29 16:20:33 +00:00
Rob Bradford
6ee9903601 docs: Update API documentation
Update the API documentation to reflect that the hotplug APIs return
data about the device as well as the newly added /vm.counters API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-27 00:07:47 +02:00
Rob Bradford
522d8c8412 vmm: openapi: Add the /vm.counters API entry point
This is a hash table of string to hash tables of u64s. In JSON these
hash tables are object types.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-27 00:07:47 +02:00
Muminul Islam
72ae1577ed hypervisor: Update license to Apache-2.0 OR BSD-3-Clause
Initially the licensing was just Apache-2.0. This patch changes
the licensing to dual license Apache-2.0 OR BSD-3-Clause

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-06-27 00:06:39 +02:00
dependabot-preview[bot]
e1ea06e74a build(deps): bump cc from 1.0.54 to 1.0.55
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.54 to 1.0.55.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.54...1.0.55)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-26 04:55:46 +00:00
dependabot-preview[bot]
19ce0a37a4 build(deps): bump epoll from 4.3.0 to 4.3.1
Bumps [epoll](https://github.com/nathansizemore/epoll) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/commits/4.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-25 14:03:04 +00:00
Sebastien Boeuf
a7f0f9dfea vm-virtio: Ensure pause event is caught by every virtio thread
Each virtio thread was reading/draining the pause_evt pipe when
detecting the associated event. Problem is, when a virtio device has
multiple threads, they all share the same pause_evt pipe, which can
prevent some threads from receiving the event. If the first thread to
catch the event is quickly clearing the pipe, some other threads might
simply miss the event and they will not enter the "paused" state as
expected.

This is a behavior that was spotted with virtio-net as it usually uses
2 threads by default (1 for TX/RX queues and 1 for the control queue).

The way to solve this issue is by letting each thread drain the pipe
during the resume codepath, that is after the thread has been unparked.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-25 12:01:34 +02:00
Sebastien Boeuf
86377127df vmm: Resume devices after vCPUs have been resumed
Because we don't want the guest to miss any event triggered by the
emulation of devices, it is important to resume all vCPUs before we can
resume the DeviceManager with all its associated devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-25 12:01:34 +02:00
Sebastien Boeuf
f6eeba781b vmm: Save and restore vCPU states during pause/resume operations
We need consistency between pause/resume and snapshot/restore
operations. The symmetrical behavior of pausing/snapshotting
and restoring/resuming has been introduced recently, and we must
now ensure that no matter if we're using pause/resume or
snapshot/restore features, the resulting VM should be running in
the exact same way.

That's why the vCPU state is now stored upon VM pausing. The snapshot
operation being a simple serialization of the previously saved state.
The same way, the vCPU state is now restored upon VM resuming. The
restore operation being a simple deserialization of the previously
restored state.

It's interesting to note that this patch ensures time consistency from a
guest perspective, no matter which clocksource is being used. From a
previous patch, the KVM clock was saved/restored upon VM pause/resume.
We now have the same behavior for TSC, as the TSC from the vCPUs are
saved/restored upon VM pause/resume too.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-25 12:01:34 +02:00
Sebastien Boeuf
18e7d7a1f7 vmm: cpu: Resume before shutdown in a specific way
Instead of calling the resume() function from the CpuManager, which
involves more than what is needed from the shutdown codepath, and
potentially ends up with a deadlock, we replace it with a subset.

The full resume operation is reserved for a VM that has been paused.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-25 12:01:34 +02:00
Sebastien Boeuf
65132fb99d vmm: Implement Pausable trait for Vcpu
We want each Vcpu to store the vCPU state upon VM pausing. This is the
reason why we need to explicitly implement the Pausable trait for the
Vcpu structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-25 12:01:34 +02:00
Wei Liu
1741af74ed hypervisor: add safety statement in set_user_memory_region
When set_user_memory_region was moved to hypervisor crate, it was turned
into a safe function that wrapped around an unsafe call. All but one
call site had the safety statements removed. But safety statement was
not moved inside the wrapper function.

Add the safety statement back to help reasoning in the future. Also
remove that one last instance where the safety statement is not needed .

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-25 10:25:13 +02:00
Wei Liu
b27439b6ed arch, hypervisor, vmm: KvmHyperVisor -> KvmHypervisor
"Hypervisor" is one word. The "v" shouldn't be capitalised.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-25 10:25:13 +02:00
Wei Liu
b00171e17d vmm: use MemoryRegion where applicable
That removes one more KVM-ism in VMM crate.

Note that there are more KVM specific code in those files to be split
out, but we're not at that stage yet.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-25 10:25:13 +02:00
Rob Bradford
48a05c4727 tests: Add simple counters integration test
Add a simple test to check that the data from the counters matches what
is expected and that the value of the counters increases after an
operation that will hit all counters.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
980b49da94 vm-virtio: block: Implement counters for block device
Expose counters for read/write bytes/ops from the virtio block device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
d983c0a680 vmm: Expose counters from virtio devices to API
Collate the virtio device counters in DeviceManager for each device that
exposes any and expose it through the recently added HTTP API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
9b7afd4aac bin: ch-remote: Implement "counters" command
This is used to obtain the counters from the VM. The raw JSON data is
presented to the user.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
bca8a19244 vmm: Implement HTTP API for obtaining counters
The counters are a hash of device name to hash of counter name to u64
value. Currently the API is only implemented with a stub that returns an
empty set of counters.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
fd4aba8eae vmm: api: Implement support for GET handlers EndpointHandler
This can be used for simple API requests which return data but do not
require any input.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
80be393b16 vmm: api: Order HTTP entry points in alphabetical order
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
6713a3c859 vm-virtio: net: Expose network counters through VirtioDevice
Through the counters() function on the trait expose the accumulated
counters.

TEST=Observe that the counters from the VM match those from the tap on
the host (RX-TX inverted) and inside the guest (non inverted.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
dd54883a07 vm-virtio: device: Extend the VirtioDevice trait to expose counters
The counters are a hash of counter name to (wrapping) u64 value. The
interpretation layer is responsible for converting this data into a
rate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Rob Bradford
2b4a0358de vm-virtio: net: Implement counters for network traffic
Add counters for RX/TX bytes and RX/TX frames. These are collected on a
per queue basis and then accumulated into an atomic shared value across
the different threads for the device as a whole.

Collecting and accumulating these counters makes minimal difference in
the iperf results. Any difference seen is within what is observed as
natural variation in this test.

e.g.

With counter updates:

$ iperf3 -c 192.168.249.2
Connecting to host 192.168.249.2, port 5201
[  5] local 192.168.249.1 port 52706 connected to 192.168.249.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  6.19 GBytes  53.2 Gbits/sec    0   3.01 MBytes
[  5]   1.00-2.00   sec  6.31 GBytes  54.2 Gbits/sec    0   3.01 MBytes
[  5]   2.00-3.00   sec  6.29 GBytes  54.0 Gbits/sec    0   3.01 MBytes
[  5]   3.00-4.00   sec  6.22 GBytes  53.4 Gbits/sec    0   3.01 MBytes
[  5]   4.00-5.00   sec  6.14 GBytes  52.8 Gbits/sec    0   3.01 MBytes
[  5]   5.00-6.00   sec  6.13 GBytes  52.7 Gbits/sec    0   3.01 MBytes
[  5]   6.00-7.00   sec  6.20 GBytes  53.3 Gbits/sec    0   3.01 MBytes
[  5]   7.00-8.00   sec  6.16 GBytes  52.9 Gbits/sec    0   3.01 MBytes
[  5]   8.00-9.00   sec  6.13 GBytes  52.6 Gbits/sec    0   3.01 MBytes
[  5]   9.00-10.00  sec  6.15 GBytes  52.8 Gbits/sec    0   3.01 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  61.9 GBytes  53.2 Gbits/sec    0             sender
[  5]   0.00-10.00  sec  61.9 GBytes  53.2 Gbits/sec                  receiver

iperf Done.

Without counter updates:

$ iperf3 -c 192.168.249.2
Connecting to host 192.168.249.2, port 5201
[  5] local 192.168.249.1 port 52716 connected to 192.168.249.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  6.29 GBytes  54.1 Gbits/sec    0   3.03 MBytes
[  5]   1.00-2.00   sec  6.18 GBytes  53.1 Gbits/sec    0   3.03 MBytes
[  5]   2.00-3.00   sec  6.26 GBytes  53.8 Gbits/sec    0   3.03 MBytes
[  5]   3.00-4.00   sec  6.24 GBytes  53.6 Gbits/sec    0   3.03 MBytes
[  5]   4.00-5.00   sec  6.27 GBytes  53.9 Gbits/sec    1   3.03 MBytes
[  5]   5.00-6.00   sec  6.31 GBytes  54.2 Gbits/sec    0   3.03 MBytes
[  5]   6.00-7.00   sec  6.29 GBytes  54.1 Gbits/sec    0   3.03 MBytes
[  5]   7.00-8.00   sec  6.16 GBytes  52.9 Gbits/sec    0   3.03 MBytes
[  5]   8.00-9.00   sec  6.13 GBytes  52.6 Gbits/sec    0   3.03 MBytes
[  5]   9.00-10.00  sec  6.25 GBytes  53.7 Gbits/sec    0   3.03 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  62.4 GBytes  53.6 Gbits/sec    1             sender
[  5]   0.00-10.00  sec  62.4 GBytes  53.6 Gbits/sec                  receiver

iperf Done.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-25 07:02:44 +02:00
Dr. David Alan Gilbert
0583ce921b vhost_user_fs: Allow fchmod in seccomp
This corresponds to QEMU's 63659fe74e76f5c52854 commit.
the setattr code uses both fchmod and fchmodat in different cases,
however we only had fchmodat in the whitelist.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2020-06-24 21:56:58 +01:00
Wei Liu
4cc37d7b9a vmm: interrupt: drop a few pub keywords
Those items are not used elsewhere. Restrict their scope.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-24 12:39:42 +02:00
Wei Liu
1661adbbaf vmm: interrupt: add "Kvm" prefix to MsiInterruptGroup
The structure is tightly coupled with KVM. It uses KVM specific
structures and calls. Add Kvm prefix to it.

Microsoft hypervisor will implement its own interrupt group(s) later.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-24 12:39:42 +02:00
Sebastien Boeuf
9f4714c32a vmm: Extend seccomp filters with KVM_KVMCLOCK_CTRL
Now that the VMM uses KVM_KVMCLOCK_CTRL from the KVM API, it must be
added to the seccomp filters list.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-24 12:38:56 +02:00
Sebastien Boeuf
4a81d65f79 vmm: Notify the guest about vCPUs being paused
Through the newly added API notify_guest_clock_paused(), this patch
improves the vCPU pause operation by letting the guest know that each
vCPU is being paused. This is important to avoid soft lockups detection
from the guest that could happen because the VM has been paused for more
than 20 seconds.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-24 12:38:56 +02:00
Sebastien Boeuf
309924eca8 hypervisor: Add guest pause notification
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-24 12:38:56 +02:00
Sebastien Boeuf
9fa8438063 vmm: Fill CpuManager's vCPU list on restore path
It's important that on restore path, the CpuManager's vCPU gets filled
with each new vCPU that is being created. In order to cover both boot
and restore paths, the list is being filled from the common function
create_vcpu().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-24 12:38:56 +02:00
Sebastien Boeuf
0b45f6364e build(deps): Update to latest kvm-ioctls
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-24 12:38:56 +02:00
dependabot-preview[bot]
7f955ff122 build(deps): bump epoll from 4.2.0 to 4.3.0
Bumps [epoll](https://github.com/nathansizemore/epoll) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-24 05:39:26 +00:00
Sebastien Boeuf
f5150aa261 vmm: Extend seccomp filters with KVM_GET_CLOCK and KVM_SET_CLOCK
Now that the VMM uses both KVM_GET_CLOCK and KVM_SET_CLOCK from the KVM
API, they must be added to the seccomp filters list.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 14:36:01 +01:00
Sebastien Boeuf
8038161861 vmm: Get and set clock during pause and resume operations
In order to maintain correct time when doing pause/resume and
snapshot/restore operations, this patch stores the clock value
on pause, and restore it on resume. Because snapshot/restore
expects a VM to be paused before the snapshot and paused after
the restore, this covers the migration use case too.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 14:36:01 +01:00
Sebastien Boeuf
68ec0eb7a8 hypervisor: Add get/set clock API
Add the hypervisor wrappers to expose KVM_GET_CLOCK and KVM_SET_CLOCK
from the KVM API.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 14:36:01 +01:00
Rob Bradford
4b64f2a027 vmm: cpu: Reuse already allocated vCPUs if available
When a request is made to increase the number of vCPUs in the VM attempt
to reuse any previously removed (and hence inactive) vCPUs before
creating new ones.

This ensures that the APIC ID is not reused for a different KVM vCPU
(which is not allowed) and that the APIC IDs are also sequential.

The two key changes to support this are:

* Clearing the "kill" bit on the old vCPU state so that it does not
  immediately exit upon thread recreation.
* Using the length of the vcpus vector (the number of allocated vcpus)
  rather than the number of active vCPUs (.present_vcpus()) to determine
  how many should be created.

This change also introduced some new info!() debugging on the vCPU
creation/removal path to aid further development in the future.

TEST=Expanded test_cpu_hotplug test.

Fixes: #1338

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-23 14:11:14 +01:00
Rob Bradford
9dcd0c37f3 vmm: cpu: Clear the "kill" flag on vCPU to support reuse
After the vCPU has been ejected and the thread shutdown it is useful to
clear the "kill" flag so that if the vCPU is reused it does not
immediately exit upon thread recreation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-23 14:11:14 +01:00
Rob Bradford
b107bfcf2c vmm: cpu: Add info!() level debugging to vCPU handling
These messages are intended to be useful to support debugging related to
vCPU hotplug/unplug issues.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-23 14:11:14 +01:00
dependabot-preview[bot]
3c2bfbdc95 build(deps): bump aho-corasick from 0.7.12 to 0.7.13
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 0.7.12 to 0.7.13.
- [Release notes](https://github.com/BurntSushi/aho-corasick/releases)
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/0.7.12...0.7.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-23 13:03:45 +00:00
Sebastien Boeuf
b5cf150ac3 ci: Update test_snapshot_restore by resuming the VM
Now that snapshot/restore is symmetrical, that is the VM must be paused
before it is snapshot and it must be resumed after it's been restored,
the integration test is updated accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 10:15:03 +02:00
Sebastien Boeuf
e382dc6657 vmm, vm-virtio: Restore DeviceManager's devices in a paused state
The same way the VM and the vCPUs are restored in a paused state, all
devices associated with the device manager must be restored in the same
paused state.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 10:15:03 +02:00
Sebastien Boeuf
8a165b5314 vmm: Restore the VM in "paused" state
Because we need to pause the VM before it is snapshot, it should be
restored in a paused state to keep the sequence symmetrical. That's the
reason why the state machine regarding the valid VM's state transition
needed to be updated accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 10:15:03 +02:00
Sebastien Boeuf
a16414dc87 vmm: Restore vCPUs in "paused" state
To follow a symmetrical model, and avoid potential race conditions, it's
important to restore a previously snapshot VM in a "paused" state.

The snapshot operation being valid only if the VM has been previously
paused.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-23 10:15:03 +02:00
Wei Liu
7552f4db61 vmm: device_manager: restore error handling
When the hypervisor crate was introduced, a few places that handled
errors were commented out in favor of unwrap, but that's bad practice.

Restore proper error handling in those places in this patch.

We cannot use from_raw_os_error anymore because it is wrapped deep under
hypervisor crate. Create new custom errors instead.

Fixes: e4dee57e81 ("arch, pci, vmm: Initial switch to the hypervisor crate")
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-22 22:02:21 +01:00
Muminul Islam
cca59bc52f hypervisor, arch: Fix warnings introduced in hypervisor crate
This commit fixes some warnings introduced in the previous
hyperviosr crate PR.Removed some unused variables from arch/aarch64
module.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-06-22 21:58:45 +01:00
dependabot-preview[bot]
4ce7af08d8 build(deps): bump aho-corasick from 0.7.10 to 0.7.12
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 0.7.10 to 0.7.12.
- [Release notes](https://github.com/BurntSushi/aho-corasick/releases)
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/0.7.10...0.7.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-22 21:57:15 +01:00
Rob Bradford
d714efe6d4 vmm: cpu: Import CpuTopology conditionally on x86_64 only
The aarch64 build has no use for this structure at the moment.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-22 15:00:27 +01:00
Sebastien Boeuf
a998e89375 build(deps): bump signal-hook from 0.1.15 to 0.1.16
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.15
to 0.1.16.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](vorner/signal-hook@v0.1.15...v0.1.16)

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-22 14:09:11 +01:00
Muminul Islam
e4dee57e81 arch, pci, vmm: Initial switch to the hypervisor crate
Start moving the vmm, arch and pci crates to being hypervisor agnostic
by using the hypervisor trait and abstractions. This is not a complete
switch and there are still some remaining KVM dependencies.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
c48d0c1a67 hypervisor: kvm: Implement vCPU state method
Implement the vCPU state getter and setter separately from the initial
KVM Hypervisor trait implementation, mostly for readability purposes.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
72e39a3496 hypervisor: Add KVM implementation
For each of the traits we are defining kvm related structures
and add the trait implementation to the structs. For more information
please see the kvm-ioctls and kvm-bindings crate.

This is a standalone implementation that does not include the switch of
the Cloud-Hypervisor vmm and arch crates to it.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
683210d6e9 hypervisor: Add Hypervisor trait
As the only hypervisor that Cloud-Hypervisor supports is KVM, the
Hypervisor trait accomodates for the upcoming KVM implementation.

This trait will be instanciated at build time through hypervisor
specific features, i.e. it's not aiming at run-time selection of
hypervisors for Cloud-Hypervisor.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
f5afc288d8 hypervisor: Add Vm trait
This VM trait should be implemented by each underlying hypervisor.

Previously created hypervisor object should create the VM based on
already selected hypervisor. This is just the trait definition. For each
of supported hypervisor we need to implement the trait. Later we will
implement this trait for KVM and then Microsoft Hyper-V.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
f9b51a41b5 hypervisor: Add Vcpu trait
This Vcpu trait should be implemented by each underlying hypervisor.

Previously created hypervisor object should create the VM based on
already selected hypervisor and Vm object should create this vcpu
object based on same hyperviosr. Each of this object should be
referenced by trait object i.e <dyn Vcpu>.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-22 15:03:15 +02:00
Muminul Islam
56a1638517 hypervisor: Introduce hypervisor crate
The purpose of this trait is to add support for other hypervisors than
KVM, like e.g. Microsoft Hyper-V.

Further commits will define additional hypervisor related traits like
Vcpu and Vm. Each of the supported hypervisor will need to implement all
traits defined from the hypervisor crate.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-06-22 15:03:15 +02:00
dependabot-preview[bot]
b969d92fe3 build(deps): bump serde from 1.0.113 to 1.0.114
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.113 to 1.0.114.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.113...v1.0.114)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-22 06:03:59 +00:00
dependabot-preview[bot]
30fb6732a2 build(deps): bump serde_derive from 1.0.113 to 1.0.114
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.113 to 1.0.114.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.113...v1.0.114)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-22 05:18:53 +00:00
dependabot-preview[bot]
22fc3bfaaf build(deps): bump syn from 1.0.32 to 1.0.33
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.32...1.0.33)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-22 05:18:24 +00:00
dependabot-preview[bot]
c0d42dc1bf build(deps): bump syn from 1.0.31 to 1.0.32
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.31 to 1.0.32.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.31...1.0.32)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-21 18:09:04 +00:00
dependabot-preview[bot]
3a102c6573 build(deps): bump addr2line from 0.12.1 to 0.12.2
Bumps [addr2line](https://github.com/gimli-rs/addr2line) from 0.12.1 to 0.12.2.
- [Release notes](https://github.com/gimli-rs/addr2line/releases)
- [Changelog](https://github.com/gimli-rs/addr2line/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/addr2line/compare/0.12.1...0.12.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-21 18:08:44 +00:00
dependabot-preview[bot]
62eb66d87e build(deps): bump serde from 1.0.112 to 1.0.113
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.112 to 1.0.113.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.112...v1.0.113)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-20 13:36:11 +01:00
dependabot-preview[bot]
7e8c1ade12 build(deps): bump serde_derive from 1.0.112 to 1.0.113
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.112 to 1.0.113.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.112...v1.0.113)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-20 10:58:57 +01:00
dependabot-preview[bot]
025941ba73 build(deps): bump epoll from 4.1.0 to 4.2.0
Bumps [epoll](https://github.com/nathansizemore/epoll) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-19 06:02:13 +00:00
Rob Bradford
ec246b9702 build: Enable LTO for release build
This results in ~20% reduction of stripped binary size:

Default release build: 8.7M -> stripped: 5.3M
LTO release build: 5.9M -> stripped: 4.3M

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 21:44:21 +01:00
Rob Bradford
798f3f01a9 tests: Add integration tests for CPU topology
Add multiple integration tests with various different CPU topologies and
check that they work as expected.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
Rob Bradford
a74c6fc14f vmm, arch: x86_64: Fill the CPUID leaves with the topology
There are two CPUID leaves for handling CPU topology, 0xb and 0x1f. The
difference between the two is that the 0x1f leaf (Extended Topology
Leaf) supports exposing multiple die packages.

Fixes: #1284

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
Rob Bradford
e19079782d vmm, arch: x86_64: Set the APIC ID on the 0x1f CPUID leaf
The extended topology leaf (0x1f) also needs to have the APIC ID (which
is the KVM cpu ID) set. This mirrors the APIC ID set on the 0xb topology
leaf

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
Rob Bradford
b81bc77390 vmm: cpu: Save CpusConfig into CpuManager
Rather than saving the individual parts into the CpuManager save the
full struct as it now also contains the topology data.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
Rob Bradford
284891b5df main: Populate "--cpus" with appropriate syntax definition
This needed to be updated to include specifying the boot and maxmium
vCPUs as well as the newly added topology for those vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
Rob Bradford
4a0439a993 vmm: config: Extend CpusConfig to add the topology
This allows the user to optionally specify the desired CPU topology. All
parts of the topology must be specified and the product of all parts
must match the maximum vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-17 12:18:09 +02:00
dependabot-preview[bot]
9099b067e1 build(deps): bump linux-loader from f7f2e89 to 2a62f21
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `f7f2e89` to `2a62f21`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](f7f2e890f7...2a62f21b44)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-17 09:34:08 +02:00
dependabot-preview[bot]
1d27416fd1 build(deps): bump unicode-normalization from 0.1.12 to 0.1.13
Bumps [unicode-normalization](https://github.com/unicode-rs/unicode-normalization) from 0.1.12 to 0.1.13.
- [Release notes](https://github.com/unicode-rs/unicode-normalization/releases)
- [Commits](https://github.com/unicode-rs/unicode-normalization/compare/v0.1.12...v0.1.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-16 22:49:54 +02:00
Stefano Garzarella
f756174b9f vsock: add muxer rxq regression test
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 78ca0a942f32140465c67ea4b45d68c52c72d751.

Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
bb3cf7c30c vsock: add handshake regression test
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 6dbe8e021a64ba3742081741a7538cdfd93a102e.

Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
6ab4e247e6 vsock: fixed TX buf flushing
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 78819f35f63f5777a58e3e1e774b3270b32881ed.

The vsock TX buffer flush operation would report inconsistent results,
under specific circumstances.

The flush operation is performed in two steps, since it's dealing with a
ring buffer, an the data to be flushed may wrap around. If the first
step was successful, but the second one failed, the whole flush
operation would report an error, thus causing flow control accounting to
lose track of the bytes that were successfully written by the first
pass.

This commit changes the flush behavior to always report success when
some data has been written to the backing stream.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
aca2baf458 vsock: fixed flow control regression
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 2da612a9cdce85c91fb54ab22d950ec6ccc93b27.

Fixed a bug introduced by a271d08f0b1ba0ee82761cd49244b6a8017bcede,
whereby the flow control accouting would be off by a few bytes, for
host-initiated connections.

The connection ack message ("OK <port_num><CR>") was accounted for as
data sent by the guest, so its length was substracted from the total
amount of data the guest was allowed to send.

This commit changes the way this ack message is sent, so that it
bypasses flow control accouting.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
3ce4bd5ec8 vsock: absorb spurious EPOLLOUT events
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 109e631566350867dafa4b16c3919dfd1533eeea.

This commit changes the vsock connection state machine behavior to absorb
any EWOULDBLOCK errors recevied while handling an EPOLLOUT event. Previously,
this condition would lead to immediate connection termination.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
0530b4e1ed vsock: absorb spurious EPOLLIN events
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 660d18cf7fee5b38c3b1b17a5da6544b9025909d.

Apparently, epoll_wait sometimes yields false EPOLLIN events (i.e. events
follwing which read() would fail with EWOULDBLOCK). This would cause the
vsock connection state machine to terminate connections, since an error
was detected on the underlying Unix socket.

This commit changes the vsock connection state machine code to handle such
erroneous EPOLLIN events by absorbing EWOULDBLOCK read() errors.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
a3f24e5fb9 vsock: flow control fix
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 1cc8b8a678eb28b20f5843556bdb7fbb2dfa6284.

Fixed a logical error in the vsock flow control, that would cause credit
update packets to not be sent at the right time.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
Stefano Garzarella
5fc52a5056 vsock: fixed rxq logic
This patch has been cherry-picked from the Firecracker tree. The
reference commit is d2475773557c82d2abad2fc8bdf69e7d01444109.

Fixed a vsock muxer issue that would cause a connection to be removed
from the RX queue, even though it still had pending RX data.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Gabriel Ionescu <gbi@amazon.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-16 22:02:06 +02:00
dependabot-preview[bot]
69dac2dbb5 build(deps): bump remain from 0.2.1 to 0.2.2
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.1...0.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-16 21:53:01 +02:00
dependabot-preview[bot]
19ab08f239 build(deps): bump itoa from 0.4.5 to 0.4.6
Bumps [itoa](https://github.com/dtolnay/itoa) from 0.4.5 to 0.4.6.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/0.4.5...0.4.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-16 21:52:43 +02:00
dependabot-preview[bot]
a17aaec663 build(deps): bump adler32 from 1.0.4 to 1.1.0
Bumps [adler32](https://github.com/remram44/adler32-rs) from 1.0.4 to 1.1.0.
- [Release notes](https://github.com/remram44/adler32-rs/releases)
- [Commits](https://github.com/remram44/adler32-rs/compare/1.0.4...1.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-16 08:44:15 +02:00
dependabot-preview[bot]
8e5c816c2b build(deps): bump thiserror from 1.0.19 to 1.0.20
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.19...1.0.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-16 08:16:52 +02:00
Stefano Garzarella
096ffe08f2 vm-virtio: vsock: add is_empty method to VsockPacket
This patch adds `is_empty` method to VsockPacket to fix the
following clippy error:

error: item `vsock::packet::VsockPacket` has a public `len` method but no corresponding `is_empty` method
   --> vm-virtio/src/vsock/packet.rs:100:1
    |
100 | / impl VsockPacket {
101 | |     /// Create the packet wrapper from a TX virtq chain head.
102 | |     ///
103 | |     /// The chain head is expected to hold valid packet header data. A following packet buffer
...   |
334 | |     }
335 | | }
    | |_^
    |
    = note: `-D clippy::len-without-is-empty` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-15 18:31:54 +01:00
Stefano Garzarella
b74a855446 vm-virtio: make VsockPacket public
This patch makes VsockPacket public to allow other crates
(e.g. vhost-user-vsock) to use it.

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
2020-06-15 18:31:54 +01:00
dependabot-preview[bot]
8bcd0abbe5 build(deps): bump backtrace from 0.3.48 to 0.3.49
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.48 to 0.3.49.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.48...0.3.49)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-15 17:31:53 +01:00
Henry Wang
99e72be169 unit tests: Fix unit tests and docs for AArch64
Currently, not every feature of the cloud-hypervisor is enabled
on AArch64, which means that on AArch64 machines, the
`run_unit_tests.sh` needs to be tailored and some unit test cases
should be run on x86_64 only.

Also this commit fixes the typo and unifies `Arm64` and `AArch64`
in the AArch64 document.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-15 17:28:05 +01:00
Wei Liu
103cd61bd2 vmm: device_tree: make available remove function unconditionally
Its test case calls remove unconditionally. Instead of making the test
code call remove conditionally, removing the pci_support dependency
simplifies things -- that function is just a wrapper around HashMap's
remove function anyway.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-15 11:41:34 +02:00
dependabot-preview[bot]
66f7d20ee5 build(deps): bump linux-loader from 1af92d2 to f7f2e89
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `1af92d2` to `f7f2e89`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](1af92d21ad...f7f2e890f7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-15 08:56:24 +02:00
LiYa'nan
acc234088f vfio: fix for bug as below:
cloud-hypervisor: 763.978581807s: ERROR:pci/src/vfio.rs:651 -- failed to remove all guest memory regions from iommu table

when poweroff a vm with vfio device, clh will finally remove all guest memory region from iommu table
with the method unset_dma_map, not method setup_dma_map.

Signed-off-by: LiYa'nan <oliverliyn@gmail.com>
2020-06-15 08:51:13 +02:00
Rob Bradford
e080c6e5b0 Revert "build: Temporarily disable nightly builds"
This reverts commit 1a2b3c8f3e.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-15 06:43:27 +02:00
dependabot-preview[bot]
36f6d9da52 build(deps): bump serde from 1.0.111 to 1.0.112
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.111 to 1.0.112.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.111...v1.0.112)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-14 20:26:25 +01:00
dependabot-preview[bot]
9a99ebfd81 build(deps): bump serde_derive from 1.0.111 to 1.0.112
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.111 to 1.0.112.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.111...v1.0.112)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-14 20:26:01 +01:00
dependabot-preview[bot]
cb67372de2 build(deps): bump proc-macro-nested from 0.1.5 to 0.1.6
Bumps [proc-macro-nested](https://github.com/dtolnay/proc-macro-hack) from 0.1.5 to 0.1.6.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-14 13:02:33 +01:00
dependabot-preview[bot]
4171155540 build(deps): bump hermit-abi from 0.1.13 to 0.1.14
Bumps [hermit-abi](https://github.com/hermitcore/libhermit-rs) from 0.1.13 to 0.1.14.
- [Release notes](https://github.com/hermitcore/libhermit-rs/releases)
- [Commits](https://github.com/hermitcore/libhermit-rs/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-14 13:02:25 +01:00
dependabot-preview[bot]
2072145d71 build(deps): bump pin-project from 0.4.20 to 0.4.22
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.20 to 0.4.22.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.20...v0.4.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-14 13:02:14 +01:00
dependabot-preview[bot]
9eaa735ccb build(deps): bump remove_dir_all from 0.5.2 to 0.5.3
Bumps [remove_dir_all](https://github.com/XAMPPRocky/remove_dir_all) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/XAMPPRocky/remove_dir_all/releases)
- [Changelog](https://github.com/XAMPPRocky/remove_dir_all/blob/master/CHANGELOG.md)
- [Commits](https://github.com/XAMPPRocky/remove_dir_all/compare/v0.5.2...remove_dir_all@0.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-12 18:56:34 +01:00
Wei Liu
fb461c820f vmm: vm: enable test_vm test case
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-12 14:46:58 +01:00
Wei Liu
b99b5777bb vmm: vm: move some imports into test_vm
They are only needed there. Not moving them causes rustc to complain
about unused imports.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-12 14:46:58 +01:00
Sebastien Boeuf
4f311b56eb ci: Extend integration tests for checking PCI hotplug response
Upon PCI hotplug, the VMM now returns some information about the device
name and the associated b/d/f. This patch extends the integration tests
so that we validate the response is the one that is expected.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
b62d5d22ff vmm: openapi: Update the OpenAPI definition
Now that PCI device hotplug returns a response, the OpenAPI definition
must reflect it, describing what is expected to be received.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
4fe7347fb9 vmm: Manually implement Serialize for PciDeviceInfo
In order to provide a more comprehensive b/d/f to the user, the
serialization of PciDeviceInfo is implemented manually to control the
formatting.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
83cd9969df vmm: Enable HTTP response for PCI device hotplug
This patch completes the series by connecting the dots between the HTTP
frontend and the device manager backend.

Any request to hotplug a VFIO, disk, fs, pmem, net, or vsock device will
now return a response including the device name and the place of the
device in the PCI topology.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
3316348d4c vmm: vm: Carry information from hotplugged PCI device
Pass from the device manager to the calling code the information about
the PCI device that has just been hotplugged.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
f08e9b6a73 vmm: device_manager: Return PciDeviceInfo from a hotplugged device
In order to provide the device name and PCI b/d/f associated with a
freshly hotplugged device, the hotplugging functions from the device
manager return a new structure called PciDeviceInfo.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
0bc2b08d3a vmm: api: Return an optional response from vm_action()
Any action that relies on vm_action() can now return a response body.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Sebastien Boeuf
038180269e vmm: api: Allow HTTP PUT request to return a response
Adding the codepath to return a response from a PUT request.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-12 13:37:18 +01:00
Rob Bradford
1a2b3c8f3e build: Temporarily disable nightly builds
Rust nightly builds are currently failing due to a crate outside of
our control not meeting the latest cargo requirements.

See XAMPPRocky/remove_dir_all#19

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-12 10:07:00 +01:00
Wei Liu
5ebd02a572 vmm: vm: fix test_vm test case
We should break out from the loop after getting the HLT exit, otherwise
the VM hangs forever.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-06-12 08:38:07 +02:00
Rob Bradford
52b839694d build, release-notes: Document 0.8.0 release
Update the build version and the release notes for the 0.8.0 release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-11 18:31:31 +01:00
Rob Bradford
776f8fc555 build: Update Cargo.lock
An update to the Cargo.lock file was missing from a previous commit.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-11 16:58:35 +02:00
Michael Zhao
3f18f93f40 docs: Add a guide for testing on AArch64
The support of AArch64 is in very early stage. The steps in building and
runing on X86 and AArch64 can not align well yet. Adding AArch64 content
to README.md would produce much divergence.
Adding a guide in docs/ folder could be a better way to start now.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
97a1e5e1d2 vmm: Exit VMM event loop after guest shutdown for AArch64
X86 and AArch64 work in different ways to shutdown a VM.
X86 exit VMM event loop through ACPI device;
AArch64 need to exit from CPU loop of a SystemEvent.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
5cd1730bc4 vmm: Configure VM on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
917219fa92 vmm: Enable VCPU for AArch64
Added MPIDR which is needed in system configuration.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
b5f1c912d6 vmm: Enable memory manager for AArch64
Screened IO space as it is not available on AArch64.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
eeeb45bbb9 vmm: Enable device manager for AArch64
Screened IO bus because it is not for AArch64.
Enabled Serial, RTC and Virtio devices with MMIO transport option.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Michael Zhao
e9488846f1 vm-allocator: Enable vm-allocator for AArch64
Implemented GSI allocator and system allocator for AArch64.
Renamed some layout definitions to align more code between architectures.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-11 15:00:17 +01:00
Anatol Belski
5343b0ac18 net_util: Fix usage of deprecated mac_address method
This fixes the build warning below

warning: use of deprecated item 'tap::tests::pnet::datalink::NetworkInterface::mac_address': Please use NetworkInterface's field 'mac' instead.
   --> net_util/src/tap.rs:530:24
    |
530 |             (interface.mac_address(), tx, rx)
    |                        ^^^^^^^^^^^
    |
    = note: `#[warn(deprecated)]` on by default

Signed-off-by: Anatol Belski <ab@php.net>
2020-06-11 08:23:01 +01:00
Sebastien Boeuf
bf37ebdcb6 arch: x86_64: Add 5th level of paging when needed
For correctness, when the CPUID supports the LA57 feature, the VMM sets
the CR4.LA57 register, which means a fifth level of page table might be
needed. Even if it's not needed because the kernel should not use
addresses over 1GiB, it's better to define this new level anyway.

This patch only applies to the Linux boot codepath, which means it
affects both vmlinux without PVH and bzImage binaries. The bzImage
does not need this since the page tables and CR4 registers are set in
the decompression code from the kernel.

And for vmlinux with PVH, if we follow the PVH specification, the kernel
must be responsible for setting things up, but the implementation is
missing. This means for now that PVH does not support LA57 with 5 levels
of paging.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-11 09:18:52 +02:00
Anatol Belski
abd6204d27 source: Fix file permissions
Rust sources and some data files should not be executable. The perms are
set to 644.

Signed-off-by: Anatol Belski <ab@php.net>
2020-06-10 18:47:27 +01:00
Rob Bradford
02ac1820b1 scripts: Ensure musl-gcc is used by musl build
"cc" is invoked as part of the Cloud Hypervisor Rust build however due
to a copy and paste error the wrong variable was being tested for
overriding the CC and the CFLAGS.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-10 18:22:50 +02:00
Bo Chen
cc85d896a5 tests: Extend test_*_reboot with checks on fd leaking
This revised version of the patch reuses the back-off strategy from
'ssh_command()' to deal with varying booting time.

Fixes: #1209

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-06-10 13:54:18 +01:00
dependabot-preview[bot]
2ae547cf71 build(deps): bump vmm-sys-util from 0.6.0 to 0.6.1
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Changelog](https://github.com/rust-vmm/vmm-sys-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vmm-sys-util/compare/v0.6.0...v0.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-10 13:24:53 +01:00
dependabot-preview[bot]
f3556279d5 build(deps): bump serde_json from 1.0.54 to 1.0.55
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.54 to 1.0.55.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.54...v1.0.55)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-10 11:48:39 +01:00
Rob Bradford
dc034eb3b0 scripts: Only use musl for the Rust components
Don't use the musl toolchain for the virtiofsd build as it does not
work.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-10 10:16:57 +01:00
Rob Bradford
176d671609 build: Run musl builds in parallel to glibc builds
Run these builds against every PR rather than just master.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-10 10:16:57 +01:00
dependabot-preview[bot]
083189e5a1 build(deps): bump vcpkg from 0.2.9 to 0.2.10
Bumps [vcpkg](https://github.com/mcgoo/vcpkg-rs) from 0.2.9 to 0.2.10.
- [Release notes](https://github.com/mcgoo/vcpkg-rs/releases)
- [Changelog](https://github.com/mcgoo/vcpkg-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mcgoo/vcpkg-rs/compare/vcpkg-rs-0.2.9...vcpkg-rs-0.2.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-10 09:21:10 +02:00
dependabot-preview[bot]
2334b521da build(deps): bump syn from 1.0.30 to 1.0.31
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.30 to 1.0.31.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.30...1.0.31)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-10 07:35:29 +02:00
dependabot-preview[bot]
99c99c2476 build(deps): bump serde_json from 1.0.53 to 1.0.54
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.53 to 1.0.54.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.53...v1.0.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-09 21:17:48 +01:00
Sebastien Boeuf
96a5e22bd6 resources: kernel: Enable 5 levels of page table
Some CPUs might support up to 52 bits of addressable space, that's the
reason why we need the guest kernel to support 5 levels of page table.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-09 18:08:09 +01:00
Sebastien Boeuf
653087d7a3 vmm: Reduce MMIO address space by 4KiB
In order to workaround a Linux bug that happens when we place devices at
the end of the physical address space on recent hardware (52 bits limit)
we reduce the MMIO address space by one 4k page. This way, nothing gets
allocated in the last 4k of the address space, which is negligible given
the amount of space in the address space.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-09 18:08:09 +01:00
Sebastien Boeuf
5f0b620148 arch: x86_64: Enable CR4 LA57 feature
In case the host CPU exposes the support for LA57 feature through its
cpuid, the CR4.LA57 bit is enabled accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-06-09 18:08:09 +01:00
Rob Bradford
09fd325963 build: Use fork of vm-memory with less performance impact
Currently released vm-memory uses aligned and volatile copying for all
data. The version in the fork only uses the assured (and slower) path
for data upto the natural data width.

Fixes: #1258

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-09 17:06:35 +02:00
Henry Wang
5f9e079a03 device: Add AArch64 RTC PL031 implementation
This commit adds the implementation for the AArch64 PL031
Real Time Clock (RTC) that provides a long time base counter. This
is achieved by generating an interrupt signal after counting a
programmed number of cycles of a real-time clock input. The AArch64
guest VM of the cloud-hypervisor will use this RTC to sync the time
in itself.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-09 06:27:46 +01:00
Bo Chen
625bab69bd vmm: api: Allow to delete non-booted VMs
The action of "vm.delete" should not report errors on non-booted
VMs. This patch also revised the "docs/api.md" to reflect the right
'Prerequisites' of different API actions, e.g. on "vm.delete" and
"vm.boot".

Fixes: #1110

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-06-09 05:58:32 +01:00
LiYa'nan
313883f6e4 remove duplicated structure InitrdConfig
structure InitrdConfig duplicated with InitramfsConfig

Signed-off-by: LiYa'nan <oliverliyn@gmail.com>
2020-06-09 05:53:37 +01:00
dependabot-preview[bot]
afe60808ac build(deps): bump synstructure from 0.12.3 to 0.12.4
Bumps [synstructure](https://github.com/mystor/synstructure) from 0.12.3 to 0.12.4.
- [Release notes](https://github.com/mystor/synstructure/releases)
- [Commits](https://github.com/mystor/synstructure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 21:05:16 +01:00
Rob Bradford
aa79a92c35 tests: Add integration test for unprivileged network
This tests whether we can have a working network without having
CAP_NET_ADMIN.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-08 17:56:10 +02:00
Rob Bradford
9b71ba20ac vmm, vm-virtio: Stop always autogenerating a host MAC address
This removes the need to use CAP_NET_ADMIN privileges and instead the
host MAC addres is either provided by the user or alternatively it is
retrieved from the kernel.

TEST=Run cloud-hypervisor without CAP_NET_ADMIN permission and a
preconfigured tap device:

sudo ip tuntap add name tap0 mode tap
sudo ifconfig tap0 192.168.249.1 netmask 255.255.255.0 up
cargo clean
cargo build
target/debug/cloud-hypervisor --serial tty --console off --kernel ~/src/rust-hypervisor-firmware/target/target/release/hypervisor-fw --disk path=~/workloads/clear-33190-kvm.img --net tap=tap0

VM was also rebooted to check that works correctly.

Fixes: #1274

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-08 17:56:10 +02:00
Rob Bradford
1f8b6fa947 net_util: Allow retrieving the MAC address from the TAP device
This can be used to preserve the host MAC address as part of the
configuration when the TAP device is precreated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-08 17:56:10 +02:00
Rob Bradford
929d70bc7f net_util: Only try and enable the TAP device if it not already enabled
This allows an existing TAP interface to be used without needing
CAP_NET_ADMIN permissions on the Cloud Hypervisor binary as the ioctl to
bring up the interface is avoided.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-08 17:56:10 +02:00
Bo Chen
eda9bfc7a1 vhost_user_fs: Replace the '--sock' parameter with '--socket'
We are keeping the '--sock' parameter for backward compatibility.

Fixes: #1091

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-06-08 17:41:12 +02:00
Bo Chen
a8cdf2f070 tests,vm-virtio,vmm: Use 'socket' for all CLI/API parameters
This patch unifies the inconsistent uses of 'socket' and 'sock' from our
CLI/API parameters.

Fixes: #1091

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-06-08 17:41:12 +02:00
Rob Bradford
90e7accf8b ch-remote: Show response body from error
If the server returns an error then print out the response body if there
is one present.

Fixes: #1262

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-08 17:35:54 +02:00
Henry Wang
e436bbf3bb build: Install libfdt in github cross-build workflow
In AArch64 prototype, there are code to construct the flattened device
tree, and to make such code compilable we need to install libfdt-dev. In
normal situation, this installation process can be done by either installing
libfdt-dev locally or in the development container.

Before formal AArch64 CI is setup, we use the workaround in this commit
to install libfdt in the github cross-build workflow.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-08 09:59:46 +01:00
Henry Wang
2d13751d7d aarch64: Porting fdt related files from Firecracker
When booting VM on AArch64 machines, we need to construct the
flattened device tree before loading kernel. Hence here we add
the implementation of the flattened device tree for AArch64.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-08 09:59:46 +01:00
Henry Wang
5a18dd36e2 aarch64: Porting AArch64 register implementation from Firecracker
As on AArch64 systems we need register mpidr to create the
flattened device tree, here in this commit we add ported AArch64
register implementation from Firecracker and related changes to
make this commit build.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-08 09:59:46 +01:00
Henry Wang
d605fda3f7 aarch64: Porting GIC source files from Firecracker
This commit adds ported code of Generic Interrupt Controller (GIC)
software implementation for AArch64, including both GICv2 and
GICv3 devices. These GIC devices are actually emulated by the
host kernel through KVM and will be used in the guest VM as the
interrupt controller for AArch64.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-06-08 09:59:46 +01:00
Michael Zhao
ce624a6dee aarch64: Add memory layout for AArch64
This commit adds the memory layout design for AArch64 in
`arch/src/aarch64/layout.rs` and related changes in
`arch/src/lib.rs` to make sure this commit can build.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-08 09:59:46 +01:00
dependabot-preview[bot]
c7d44b880e build(deps): bump quote from 1.0.6 to 1.0.7
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.6...1.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 08:05:11 +02:00
dependabot-preview[bot]
7c91dfaeef build(deps): bump proc-macro-nested from 0.1.4 to 0.1.5
Bumps [proc-macro-nested](https://github.com/dtolnay/proc-macro-hack) from 0.1.4 to 0.1.5.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 08:04:48 +02:00
dependabot-preview[bot]
17c16e5c82 build(deps): bump pin-project from 0.4.19 to 0.4.20
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.19 to 0.4.20.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.19...v0.4.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-07 17:00:42 +01:00
dependabot-preview[bot]
a2398742da build(deps): bump arc-swap from 0.4.6 to 0.4.7
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 0.4.6 to 0.4.7.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v0.4.6...v0.4.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-07 17:00:31 +01:00
dependabot-preview[bot]
b31fe72edc build(deps): bump openssl-sys from 0.9.57 to 0.9.58
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.57 to 0.9.58.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.57...openssl-sys-v0.9.58)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-06 09:50:31 +01:00
dependabot-preview[bot]
9649700420 build(deps): bump dirs-sys from 0.3.4 to 0.3.5
Bumps [dirs-sys](https://github.com/dirs-dev/dirs-sys-rs) from 0.3.4 to 0.3.5.
- [Release notes](https://github.com/dirs-dev/dirs-sys-rs/releases)
- [Commits](https://github.com/dirs-dev/dirs-sys-rs/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-05 19:41:36 +02:00
Rob Bradford
eabf43fbf6 Revert "tests: Extend test_*_reboot with checks on fd leaking"
This reverts commit 7dc4e91303.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-05 14:09:17 +01:00
Bo Chen
7dc4e91303 tests: Extend test_*_reboot with checks on fd leaking
Fixes: #1209

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-06-04 20:48:44 +01:00
dependabot-preview[bot]
601d898f8a build(deps): bump pin-project from 0.4.17 to 0.4.19
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.17 to 0.4.19.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.17...v0.4.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-04 18:44:30 +02:00
Arron Wang
6ff107afe4 vm-device: Switch to use get_host_address_range in vfio-ioctls
The API has change to use generic GuestMemory trait:
pub fn get_host_address_range<M: GuestMemory>(
    mem: &M,
    addr: GuestAddress,
    size: usize,
) -> Option<*mut u8> {

Signed-off-by: Arron Wang <arron.wang@intel.com>
2020-06-04 08:48:55 +02:00
Samuel Ortiz
3336e80192 vfio: Switch to the vfio-ioctls crate ch branch
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-04 08:48:55 +02:00
Samuel Ortiz
d24aa72d3e vfio: Rename to vfio-ioctls
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-04 08:48:55 +02:00
Samuel Ortiz
53ce529875 vfio: Move the PCI implementation to the PCI crate
There is a much stronger PCI dependency from vfio_pci.rs than a VFIO one
from pci/src/vfio.rs. It seems more natural to have the PCI specific
VFIO implementation in the PCI crate rather than the other way around.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-06-04 08:48:55 +02:00
Michael Zhao
8f7dc73562 vmm: Move Vcpu::configure() to arch crate
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-03 11:27:29 +02:00
Michael Zhao
969e5e0b51 vmm: Split configure_system() from load_kernel() for x86_64
Now the flow of both architectures are aligned to:
1. load kernel
2. create VCPU's
3. configure system
4. start VCPU's

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-03 11:27:29 +02:00
Michael Zhao
20cf21cd9d vmm: Change booting process to cover AArch64 requirements
Between X86 and AArch64, there is some difference in booting a VM:
- X86_64 can setup IOAPIC before creating any VCPU.
- AArch64 have to create VCPU's before creating GIC.

The old process is:
1. load_kernel()
    load kernel binary
    configure system
2. activate_vcpus()
    create & start VCPU's

So we need to separate "activate_vcpus" into "create_vcpus" and
"activate_vcpus" (to start vcpus only). Setup GIC and create FDT
between the 2 steps.

The new procedure is:
1. load_kernel()
    load kernel binary
    (X86_64) configure system
2. create VCPU's
3. (AArch64) setup GIC
4. (AArch64) configure system
5. start VCPU's

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-06-03 11:27:29 +02:00
Rob Bradford
61aa4615e2 vhost_user_net: Implement VIRTIO_RING_F_EVENT_IDX
The general handling of VIRTIO_RING_F_EVENT_IDX is in the
vhost_user_backend functionality and the net specific handling is in the
NetQueuePair from virtio-net.

As such enabling for the vhost-user-net backend is just the case of
adding the feature.

Fixes: #789

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-03 08:28:49 +02:00
Rob Bradford
a4d377a066 vm-virtio: net: Implement VIRTIO_RING_F_EVENT_IDX
If VIRTIO_RING_F_EVENT_IDX is negotiated only generate suppress
interrupts if the guest has asked us to do so.

Fixes: #788

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-03 08:28:49 +02:00
Rob Bradford
f06970730b vm-virtio: net: Handle lost interrupts on restore
In some situations it is seen that the first interrupt sent to the guest
is lost upon a restore (due to the tap worker being awake ahead of the
vPUs).

This causes problems with VIRTIO_RING_F_EVENT_IDX interrupt suppression
as the guest will not be interrupted again in order to mitigate this we
always interrupt the guest until the device itself has been signalled by
the guest.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-03 08:28:49 +02:00
Rob Bradford
a5596020b3 vm-virtio: Add some info! level debugging interrupt generation
This was very helpful when debugging interrupt issues and will be useful
for the future.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-03 08:28:49 +02:00
Rob Bradford
cc51fdb8a7 vhost_user_net: Use NetQueuePair from vm-virtio
The logic for handling the networking queues can now be shared between
the version running in vhost-user-net and vm-virtio.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
Rob Bradford
fcc62efc41 vm-virtio: net: Prepare NetQueuePair for use in vhost-user-net
This requires exposing the struct members and also using Option<..>
types for the main epoll fd and the memory as they are initialised later
in vhost-user-net.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
Rob Bradford
2dbd11864e vm-virtio: net: Split network handling
Split handling of behaviour that is independent of the device itself so
that it can be reused in the vhost-user-net device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
Rob Bradford
237cb184b4 vm-virtio: net: Add further missing error reporting
Ensure that errors generated from rx_single_frame are propagated
correctly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
Rob Bradford
36d072e69c vm-virtio: Add error propagation for TAP listener (un)registration
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
Rob Bradford
3151b5d82a vm-virtio: net: Refactor to support code reuse
Split out functions that work just on the TAP device and queues. Whilst
doing so also improve the error handling to return Results rather than
drop errors.

This change also addresses a bug where the TAP event suppression could
ineffectual because it was being enabled immediately after it may have
been disabled:

resume_rx -> rx_single_frame -> unregister_listener -> resume_rx ->
register_listener.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-06-02 13:26:52 +02:00
dependabot-preview[bot]
22be88d3fb build(deps): bump vfio-bindings from 887b3cf to f08cbcb
Bumps [vfio-bindings](https://github.com/rust-vmm/vfio-bindings) from `887b3cf` to `f08cbcb`.
- [Release notes](https://github.com/rust-vmm/vfio-bindings/releases)
- [Commits](887b3cf877...f08cbcbf40)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-02 11:54:09 +01:00
dependabot-preview[bot]
6121f4626b build(deps): bump vfio-bindings from 46ef9d4 to 887b3cf
Bumps [vfio-bindings](https://github.com/rust-vmm/vfio-bindings) from `46ef9d4` to `887b3cf`.
- [Release notes](https://github.com/rust-vmm/vfio-bindings/releases)
- [Commits](46ef9d418e...887b3cf877)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-02 09:22:29 +01:00
dependabot-preview[bot]
b731e63a8c build(deps): bump ryu from 1.0.4 to 1.0.5
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.4...1.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:51:44 +01:00
dependabot-preview[bot]
d2d5ccb163 build(deps): bump proc-macro2 from 1.0.17 to 1.0.18
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.17...1.0.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:51:26 +01:00
dependabot-preview[bot]
a1b9131bc6 build(deps): bump syn from 1.0.29 to 1.0.30
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.29 to 1.0.30.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.29...1.0.30)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:51:12 +01:00
dependabot-preview[bot]
2571b27966 build(deps): bump vcpkg from 0.2.8 to 0.2.9
Bumps [vcpkg](https://github.com/mcgoo/vcpkg-rs) from 0.2.8 to 0.2.9.
- [Release notes](https://github.com/mcgoo/vcpkg-rs/releases)
- [Changelog](https://github.com/mcgoo/vcpkg-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mcgoo/vcpkg-rs/compare/vcpkg-rs-0.2.8...vcpkg-rs-0.2.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:50:55 +01:00
dependabot-preview[bot]
57f477efa1 build(deps): bump syn from 1.0.28 to 1.0.29
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.28 to 1.0.29.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.28...1.0.29)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-31 17:46:29 +01:00
dependabot-preview[bot]
8a08ea466a build(deps): bump serde_derive from 1.0.110 to 1.0.111
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.110 to 1.0.111.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.110...v1.0.111)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-31 17:46:02 +01:00
dependabot-preview[bot]
b8ae30d454 build(deps): bump serde from 1.0.110 to 1.0.111
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.110 to 1.0.111.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.110...v1.0.111)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-31 17:45:42 +01:00
dependabot-preview[bot]
0a0fb2468a build(deps): bump syn from 1.0.27 to 1.0.28
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.27 to 1.0.28.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.27...1.0.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-30 00:51:13 +02:00
dependabot-preview[bot]
bc2921b22c build(deps): bump regex from 1.3.8 to 1.3.9
Bumps [regex](https://github.com/rust-lang/regex) from 1.3.8 to 1.3.9.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.3.8...1.3.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-29 08:17:07 +01:00
dependabot-preview[bot]
917ad53024 build(deps): bump regex from 1.3.7 to 1.3.8
Bumps [regex](https://github.com/rust-lang/regex) from 1.3.7 to 1.3.8.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-1.3.7...1.3.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-28 17:07:31 +01:00
dependabot-preview[bot]
aac87196d6 build(deps): bump vm-memory from 0.2.0 to 0.2.1
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Changelog](https://github.com/rust-vmm/vm-memory/blob/v0.2.1/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vm-memory/compare/v0.2.0...v0.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-28 17:06:48 +01:00
Rob Bradford
4c2e6054c0 build: Update to latest version of container
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-27 19:32:12 +02:00
Rob Bradford
c471ae944c Dockerfile: Update to latest Rust toolchain: 1.43.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-27 19:32:12 +02:00
Rob Bradford
c31ad72ee9 build: Address issues found by 1.43.0 clippy
These are mostly due to use of "bare use" statements and unnecessary vector
creation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-27 19:32:12 +02:00
Bo Chen
fbd1a6c5f1 vmm: api: Return complete error responses in handle_http_request()
Instead of responding only headers with error code, we now return
complete error responses to HTTP requests with errors (e.g. undefined
endpoints and InternalSeverError).

Fixes: #472

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-05-27 18:29:52 +01:00
Rob Bradford
0728bece0c vmm: seccomp: Ensure that umask() can be reprogrammed
When doing self spawning the child will attempt to set the umask() again. Let
it through the seccomp rules so long as it the safe mask again.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-27 16:46:51 +01:00
Rob Bradford
3497eeff49 main: Set the umask to 0077
This ensures that all created filed are only read/write for the current user.

Fixes: #1240

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-27 16:46:51 +01:00
dependabot-preview[bot]
c1d15de7fc build(deps): bump syn from 1.0.25 to 1.0.27
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.25 to 1.0.27.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.25...1.0.27)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-27 09:02:38 +02:00
dependabot-preview[bot]
a4bb96d45c build(deps): bump libc from 0.2.70 to 0.2.71
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.70 to 0.2.71.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.70...0.2.71)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-27 09:02:13 +02:00
dependabot-preview[bot]
bfd52ad85f build(deps): bump linux-loader from bd01b6d to 1af92d2
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `bd01b6d` to `1af92d2`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](bd01b6dd23...1af92d21ad)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-27 09:01:24 +02:00
Michael Zhao
8f1f9d9e6b devices: Implement InterruptController on AArch64
This commit only implements the InterruptController crate on AArch64.
The device specific part for GIC is to be added.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-05-26 11:09:19 +02:00
Michael Zhao
b32d3025f3 devices: Refactor IOAPIC to cover other architectures
IOAPIC, a X86 specific interrupt controller, is referenced by device
manager and CPU manager. To work with more architectures, a common
type for all architectures is needed.
This commit introduces trait InterruptController to provide architecture
agnostic functions. Device manager and CPU manager can use it without
caring what the underlying device is.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-05-26 11:09:19 +02:00
dependabot-preview[bot]
d588418053 build(deps): bump syn from 1.0.24 to 1.0.25
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.24 to 1.0.25.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.24...1.0.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-26 06:36:22 +02:00
dependabot-preview[bot]
83c18de56a build(deps): bump proc-macro-hack from 0.5.15 to 0.5.16
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.15 to 0.5.16.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.15...0.5.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 10:14:07 +02:00
dependabot-preview[bot]
7708b95ec7 build(deps): bump syn from 1.0.23 to 1.0.24
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.23 to 1.0.24.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.23...1.0.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 07:18:56 +02:00
dependabot-preview[bot]
749f2f0314 build(deps): bump proc-macro2 from 1.0.15 to 1.0.17
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.15 to 1.0.17.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.15...1.0.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 07:17:38 +02:00
dependabot-preview[bot]
c98d6fd035 build(deps): bump openssl-sys from 0.9.56 to 0.9.57
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.56 to 0.9.57.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.56...openssl-sys-v0.9.57)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 07:17:03 +02:00
dependabot-preview[bot]
a9ca493b5d build(deps): bump proc-macro2 from 1.0.14 to 1.0.15
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.14 to 1.0.15.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.14...1.0.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-22 22:23:31 +01:00
dependabot-preview[bot]
974c71389c build(deps): bump thiserror from 1.0.18 to 1.0.19
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.18...1.0.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-22 17:26:44 +01:00
dependabot-preview[bot]
321c479b03 build(deps): bump proc-macro2 from 1.0.13 to 1.0.14
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.13 to 1.0.14.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.13...1.0.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-22 17:26:39 +01:00
Michael Zhao
4f5c8be38e build: Added a workflow to cross-build targetting AArch64
The result of the workflow can be seen in Checks tab of a PR.
Two targets have been added:
- stable aarch64-unknown-linux-gnu
- stable aarch64-unknown-linux-musl

Note: a temporary step was added before building. We used "sed" command
to remove "with-serde" feature of kvm-bindings in vmm/Cargo.toml.
This step should be removed in future when kvm-bindings is ready.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-05-21 11:56:26 +01:00
Michael Zhao
1befae872d build: Fixed build errors and warnings on AArch64
This is a preparing commit to build and test CH on AArch64. All building
issues were fixed, but no functionality was introduced.
For X86, the logic of code was not changed at all.
For ARM, the architecture specific part is still empty. And we applied
some tricks to workaround lint warnings. But such code will be replaced
later by other commits with real functionality.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-05-21 11:56:26 +01:00
Michael Zhao
0090ec2dda build: Updated development utilities for AArch64
Updated Dockerfile to work with multiple architectures.
Updated dev_cli.sh to:
1. Build container image before AArch64 image is ready in public.
2. Adjust default feature collection on AArch64.
3. Workaround a build problem with musl on AArch64.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-05-21 11:56:26 +01:00
Rob Bradford
af8292b623 vmm, config, vhost_user_blk: remove "wce" parameter
This config option provided very little value and instead we now enable
this feature (which then lets the guest control the cache mode)
unconditionally.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
9101bdd7a9 vm-virtio: block: Ensure backing file consistency
Correctly implement the virtio specification by setting the writeback
field on the request based on the algorithm in the spec.

TEST=Boot with hypervisor-firmware with CH in verbose mode. See info
level messages saying cache mode is writethrough in firmware (no support
for flush or WCE). Once in the Linux kernel see messages that mode is
writeback.

Fixes: #1216
Fixes: #680

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
dc66eee8f0 vhost_user_block: Ensure backing file consistency
Correctly implement the virtio specification by setting the writeback
field on the request based on the algorithm in the spec.

TEST=Boot with hypervisor-firmware with CH in verbose mode. See info
level messages saying cache mode is writethrough in firmware (no support
for flush or WCE). Once in the Linux kernel see messages that mode is
writeback.

Fixes: #1216

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
10db2131bd vm-virtio: block: Add "writeback" control to Request
When this is set to false the write needs to be followed by a flush on
the underlying disk (leading to a fsync()).

The default behaviour is not changed with this change.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
b94d9a30d3 vhost_user_backend: Allow backends to know features that can be used
Previous to adding a a trait method to inform the backends of the acked
features backends can use features than the guest has not enabled which
could lead to unpredictable results.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
9d88ba7afb vhost_user_block: Use VirtioBlockConfig from vm-virtio
Use the same definition of the struct as vm-virtio.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
Rob Bradford
1fac263263 vm-virtio: Use config name as per spec
The spec calls this field "writeback" which is much clearer than than
"wce".

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-21 08:40:43 +02:00
dependabot-preview[bot]
077a5c367c build(deps): bump syn from 1.0.22 to 1.0.23
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.22 to 1.0.23.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.22...1.0.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-21 07:05:20 +01:00
Rob Bradford
a813b57f59 vm-virtio, vhost_user_{fs,block,backend}: Move EVENT_IDX handling
Move the method that is used to decide whether the guest should be
signalled into the Queue implementation from vm-virtio. This removes
duplicated code between vhost_user_backend and the vm-virtio block
implementation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-20 12:56:25 +02:00
Rob Bradford
8ae7a38da5 build: Use same virtio-bindings version
Consistently use the crates.io 0.1.0 version based on Linux 5.0.0

Fixes: #1192

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-20 12:55:59 +02:00
Rob Bradford
3947809c36 vm-virtio: block: Ensure that VIRTIO_BLK_T_FLUSH requests actually sync
The implementation of this virtio block (and vhost-user block) command
called a function that was a no-op on Linux. Use the same function as
virtio-pmem to ensure that data is not lost when the guest asks for it
to be flused to disk.

Fixes: #399

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-20 12:54:10 +02:00
dependabot-preview[bot]
ca6edafbfe build(deps): bump cc from 1.0.53 to 1.0.54
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.53 to 1.0.54.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.53...1.0.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-20 07:42:00 +02:00
Sebastien Boeuf
a7f236b896 ci: Extend snapshot/restore to validate virtio-vsock
Now that snapshot/restore support has been enabled for virtio-vsock, the
corresponding integration test is expanded with some validation that
virtio-vsock supports to be snapshot and restored.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 18:52:08 +02:00
Sebastien Boeuf
f442c62bc5 vm-virtio: Implement Snapshottable trait for Vsock
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 18:52:08 +02:00
Sebastien Boeuf
f975998875 ci: Extend snapshot/restore test with virtio-iommu
When compiled with pci feature, the integration test now validates that
/dev/vdb can be correctly read while being placed behing a virtual
IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 09:03:41 +01:00
Sebastien Boeuf
646d33fea3 vm-virtio: Set queue fields explicitely during restore
For both virtio-mmio and virtio-pci transport layers, we were setting
every field from the saved snapshot during a restore. This is a problem
when we don't want to override specific fields such as iommu_mapping_cb
because the saved snapshot doesn't contain the appropriate information.

That's why this commit sets only the appropriate field from the saved
snapshot during a restore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 09:03:41 +01:00
Sebastien Boeuf
02cbea546d vm-virtio: Implement Snapshottable trait for Iommu
Provide implementation for both snapshot() and restore() methods from
the Snapshottable trait, so that we can snapshot and restore a VM with
devices attached to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 09:03:41 +01:00
dependabot-preview[bot]
4f89cb050a build(deps): bump linux-loader from 43d1c51 to bd01b6d
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `43d1c51` to `bd01b6d`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](43d1c51c32...bd01b6dd23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-19 09:49:37 +02:00
dependabot-preview[bot]
14db7b0ac0 build(deps): bump addr2line from 0.12.0 to 0.12.1
Bumps [addr2line](https://github.com/gimli-rs/addr2line) from 0.12.0 to 0.12.1.
- [Release notes](https://github.com/gimli-rs/addr2line/releases)
- [Changelog](https://github.com/gimli-rs/addr2line/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/addr2line/compare/0.12.0...0.12.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-19 07:48:46 +00:00
Sebastien Boeuf
9f2eddd9d8 ci: Fix test_serial_off
The integration test validating that --serial off works correctly was
not properly written as it was using the FW, which by default would use
the kernel command line found in the EFI partition. Unfortunately, this
kernel command line was including "console=ttyS0", which causes the
kernel to try to write to the serial port, even if there's no serial
port being emulated.

The problem is, when no emulation of the serial port is provided, the
default value returned on 0x3f8 is 0, which makes the guest kernel think
that some data needs to be read.

The only way to avoid all this is by ensuring we can control the kernel
command line by removing any occurence of "console=ttyS0" from it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-19 09:22:09 +02:00
Bo Chen
7c3e19c65a vhost_user_backend, vmm: Close leaked file descriptors
Explicit call to 'close()' is required on file descriptors allocated
from 'epoll::create()', which is missing for the 'EpollContext' and
'VringWorker'. This patch enforces to close the file descriptors by
reusing the Drop trait of the 'File' struct.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-05-19 09:22:09 +02:00
Bo Chen
35782bd9f8 vm-virtio: Close file descriptors created by epoll::create()
This patch fixes file descriptor leak related to epoll::create() from
various virtio devices.

Fixes: #1124

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-05-19 09:22:09 +02:00
Rob Bradford
039accc139 vhost_user_net, vm-virtio: Interrupt guest when TX queue is updated
According to the virtio spec the guest should always be interrupted when
"used" descriptors are returned from the device to the driver. However
this was not the case for the TX queue in either the virtio-net
implementation or the vhost-user-net implementation.

This would have meant that the guest could end up with a reduced TX
throughput as it would not know that the packets had been dispatched via
the VMM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-18 17:02:53 +02:00
dependabot-preview[bot]
c8a081e459 build(deps): bump pin-project from 0.4.16 to 0.4.17
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.16 to 0.4.17.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.16...v0.4.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 15:02:50 +02:00
dependabot-preview[bot]
b80a7d01c7 build(deps): bump vmm-sys-util from 0.5.0 to 0.6.0
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Changelog](https://github.com/rust-vmm/vmm-sys-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vmm-sys-util/compare/v0.5.0...v0.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 15:02:34 +02:00
Rob Bradford
e6fd6d6360 vhost_user_block: Implement VIRTIO_BLK_F_FLUSH
As the parsing code is reused the flush feature is already implemented
and ready to be used.

Fixes: #1197

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-18 13:11:00 +01:00
dependabot-preview[bot]
95e3eddaf0 build(deps): bump quote from 1.0.5 to 1.0.6
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.5...1.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 05:52:50 +00:00
dependabot-preview[bot]
d760010c9e build(deps): bump ppv-lite86 from 0.2.6 to 0.2.8
Bumps [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) from 0.2.6 to 0.2.8.
- [Release notes](https://github.com/cryptocorrosion/cryptocorrosion/releases)
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/compare/ppv-lite86-0.2.6...ppv-lite86-0.2.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 06:58:10 +02:00
dependabot-preview[bot]
0cde08a78c build(deps): bump hermit-abi from 0.1.12 to 0.1.13
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.12 to 0.1.13.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.12...hermit-sys-0.1.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 06:57:27 +02:00
dependabot-preview[bot]
3adfe3fbb9 build(deps): bump syn from 1.0.21 to 1.0.22
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.21 to 1.0.22.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.21...1.0.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 06:56:51 +02:00
dependabot-preview[bot]
85aadd1585 build(deps): bump proc-macro2 from 1.0.12 to 1.0.13
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.12 to 1.0.13.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.12...1.0.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 06:56:23 +02:00
dependabot-preview[bot]
c764c21273 build(deps): bump thiserror from 1.0.17 to 1.0.18
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.17...1.0.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 06:56:00 +02:00
Rob Bradford
4366dd92ac vm-virtio: block: Add support for VIRTIO_RING_F_EVENT_IDX
Permit the guest to suppress interrupts from the host as an
optimisation.

Fixes: #786

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-15 19:03:41 +02:00
Rob Bradford
5a55fc0737 vhost_user_fs: Fix seccomp filter for musl
Add missing syscall used by the musl build.

TEST=scripts/dev_cli.sh tests --libc musl --integration -- vhost_user_fs_daemon

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-15 16:33:48 +02:00
Rob Bradford
391508f054 tests: Add tests checking for host MAC address setting
Extend the set of tests we have for virtio-net and vhost-user-net to
check for host MAC address setting.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-15 11:45:09 +01:00
Rob Bradford
1b8b5ac179 vhost-user_net, vm-virtio, vmm: Permit host MAC address setting
Add a new "host_mac" parameter to "--net" and "--net-backend" and use
this to set the MAC address on the tap interface. If no address is given
one is randomly assigned and is stored in the config.

Support for vhost-user-net self spawning was also included.

Fixes: #1177

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-15 11:45:09 +01:00
Rob Bradford
11049401ce vmm: seccomp: Add ioctl() commands interface hardware address
This is necessary to support setting the MAC address on the tap
interface on the host.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-15 11:45:09 +01:00
Rob Bradford
59e1361f5e net_util: tap: Add support for setting tap MAC address
Do this by reading the HW address information and then modifying the
HW address to match the desired address. Preserving the rest of the
state including the address type.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-15 11:45:09 +01:00
Sebastien Boeuf
68fc432978 vmm: Update seccomp filters with clock_nanosleep
The clock_nanosleep system call needs to be whitelisted since the commit
12e00c0f45 introduced the use of a sleep()
function. Without this patch, we can see an error when the VM is paused
or killed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-15 12:34:53 +02:00
dependabot-preview[bot]
badf826196 build(deps): bump anyhow from 1.0.30 to 1.0.31
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.30 to 1.0.31.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.30...1.0.31)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-15 09:24:01 +02:00
dependabot-preview[bot]
7b10f7320d build(deps): bump cc from 1.0.52 to 1.0.53
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.52 to 1.0.53.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.52...1.0.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-14 17:21:52 +00:00
Dr. David Alan Gilbert
4120a7dee9 vhost_user_fs: Add seccomp
Implement seccomp; we use one filter for all threads.
The syscall list comes from the C daemon with syscalls added
as I hit them.

The default behaviour is to kill the process, this normally gets
audit logged.

--seccomp none  disables seccomp
          log   Just logs violations but doesn't stop it
          trap  causes a signal to be be sent that can be trapped.

If you suspect you're hitting a seccomp action then you can
check the audit log;  you could also switch to running with 'log'
to collect a bunch of calls to report.
To see where the syscalls are coming from use 'trap' with a debugger
or coredump to backtrace it.

This can be improved for some syscalls to restrict the parameters
to some syscalls to make them more restrictive.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2020-05-14 18:56:19 +02:00
Rob Bradford
6aa29bdb24 vmm: api: Use a common handler for data actions too
Like the actions that don't take data such as "pause" or "resume" use a
common handler implementation to remove duplicated code for handling
simple endpoints like the hotplug ones.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-14 16:55:51 +01:00
Rob Bradford
0fe223f00e vmm: api: Extend VmAction to reduce code duplication
Many of the API requests take a similar form with a single data item
(i.e. config for a device hotplug) expand the VmAction enum to handle
those actions and a single function to dispatch those API events.

For now port the existing helper functions to use this new API. In the
future the HTTP layer can create the VmAction directly avoiding the
extra layer of indirection.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-14 16:55:51 +01:00
Rob Bradford
6ec605a7fb vmm: api: Refactor generic action handler
Rather than save the save a function pointer and use that instead the
underlying action. This is useful for two reasons:

1. We can ensure that we generate HttpErrors in the same way as the
   other endpoints where API error variant should be determined by the
   request being made not the underlying error.
2. It can be extended to handle other generic actions where the function
   prototype differs slightly.

As result of this refactoring it was found that the "vm.delete" endpoint
was not connected so address that issue.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-14 16:55:51 +01:00
Rob Bradford
c652625beb vmm: api: Add a default implementation for simple PUT requests
Extend the EndpointHandler trait to include automatic support for
handling PUT requests. This will allow the removal of lots of duplicated
code in the following commit from the API handling code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-14 16:55:51 +01:00
Rob Bradford
a3e8bea03c vmm: api: Move HttpError enum to http module
Minor rearrangement of code to make it easier to implement refactoring.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-14 16:55:51 +01:00
Sergio Lopez
6aab0a5458 vhost_user_fs: Implement support for optional sandboxing
Implement support for setting up a sandbox for running the
service. The technique for this has been borrowed from virtiofsd, and
consists on switching to new PID, mount and network namespaces, and
then switching root to the directory to be shared.

Future patches will implement additional hardening features like
dropping capabilities and seccomp filters.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-05-14 17:16:23 +02:00
Sergio Lopez
c4bf383fd7 vhost_user_*: Create a vhost::Listener in advance
Changes is vhost crate require VhostUserDaemon users to create and
provide a vhost::Listener in advance. This allows us to adopt
sandboxing strategies in the future, by being able to create the UNIX
socket before switching to a restricted namespace.

Update also the reference to vhost crate in Cargo.lock to point to the
latest commit from the dragonball branch.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-05-14 17:16:23 +02:00
Sergio Lopez
fa844865a5 vhost_user_fs: Allow callers to provide a fd for /proc/self/fd
Allow callers to provide a file descriptor for /proc/self/fd. This is
useful for sandboxing, as we may be running in a namespace that
doesn't have access to /proc.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-05-14 17:16:23 +02:00
Sergio Lopez
831cff3fee vhost_user_fs: Use a fd for /proc/self/fd instead of /proc
Open a file descriptor to /proc/self/fd instead of /proc. We aren't
using any other entries from that directory, and doing this allows us
to keep working even if /proc is no longer present in our
namespace (useful for sandboxing).

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-05-14 17:16:23 +02:00
Sebastien Boeuf
ba4ec7fce2 ci: Extend snapshot_restore_test with hotplug
There's a simple way to trigger PCI BAR reprogramming for a given
device, by removing it and then hotplugging it back. The Linux kernel
will simply choose to place the BARs at different location than the ones
chosen by Cloud-Hypervisor. By doing so, and creating the snapshot after
this hotplug operation, we can manage to validate that the resource are
correctly restored for a given virtio-pci device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-14 11:02:22 +02:00
Sebastien Boeuf
9e165c2c17 ci: Enable snapshot/restore integration test
Now that snapshot/restore feature is stable for both virtio-mmio and
virtio-pci devices, we re-enable the integration test for validating
snapshot/restore does not get broken.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-14 11:02:22 +02:00
dependabot-preview[bot]
c566f1f024 build(deps): bump once_cell from 1.3.1 to 1.4.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.3.1 to 1.4.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.3.1...v1.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-14 09:01:57 +02:00
dependabot-preview[bot]
7ffde29593 build(deps): bump backtrace from 0.3.47 to 0.3.48
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.47 to 0.3.48.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.47...0.3.48)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 23:36:55 +02:00
dependabot-preview[bot]
e9c2dbc866 build(deps): bump anyhow from 1.0.29 to 1.0.30
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.29 to 1.0.30.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.29...1.0.30)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 19:56:23 +02:00
Rob Bradford
9ccc7daa83 build, vmm: Update to latest kvm-ioctls
The ch branch has been rebased to incorporate the latest upstream code
requiring a small change to the unit tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-13 17:14:49 +02:00
Rob Bradford
80aa0a753d tests: Test unplugging virtio-fs
Now that virtio-fs has unplug support try unplugging and readding the
virtio-fs device.

Fixes: #1050

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-13 09:11:50 +01:00
Rob Bradford
88ec93d075 vmm: config: Add missing "id" from FsConfig parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-13 09:11:50 +01:00
dependabot-preview[bot]
0f89f5eca0 build(deps): bump anyhow from 1.0.28 to 1.0.29
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.28 to 1.0.29.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.28...1.0.29)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 09:32:48 +02:00
dependabot-preview[bot]
ab3d374ab7 build(deps): bump syn from 1.0.20 to 1.0.21
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.20...1.0.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 09:32:38 +02:00
dependabot-preview[bot]
35b8992ede build(deps): bump thiserror from 1.0.16 to 1.0.17
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.16 to 1.0.17.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.16...1.0.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:54:23 +02:00
dependabot-preview[bot]
3415b11d79 build(deps): bump quote from 1.0.4 to 1.0.5
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.4...1.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:54:12 +02:00
dependabot-preview[bot]
6989bf054c build(deps): bump backtrace from 0.3.46 to 0.3.47
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.46 to 0.3.47.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.46...0.3.47)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-12 20:27:38 +02:00
dependabot-preview[bot]
2991fd2a48 build(deps): bump libc from 0.2.69 to 0.2.70
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.69 to 0.2.70.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.69...0.2.70)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-12 20:26:43 +02:00
Sebastien Boeuf
c37da600e8 vmm: Update DeviceTree upon PCI BAR reprogramming
By passing a reference of the DeviceTree to the AddressManager, we can
now update the DeviceTree whenever a PCI BAR is reprogrammed. This is
mandatory to maintain the correct resources information related to each
virtio-pci device, which will ensure correct information will be stored
upon VM snapshot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
d0ae9d7ce6 vmm: Share the DeviceTree across threads
We want to be able to share the same DeviceTree across multiple threads,
particularly to handle the use case where PCI BAR reprogramming might
need to update the tree while from another thread a new device is being
added to the tree.

That's why this patch moves the DeviceTree instance into an Arc<Mutex<>>
so that we can later share a reference of the same mutable tree with the
AddressManager responsible for handling PCI BAR reprogramming.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
5e9d254564 vmm: Store and restore virtio-pci BAR resources
By using the vector of resources provided by the DeviceNode, the device
manager can store the information related to PCI BARs from a virtio-pci
device. Based on this, and upon VM restoration, the device manager can
restore the BARs in the expected location in the guest address space.

One thing to note is that we only need to provide the VirtioPciDevice
with the configuration BAR (BAR 0) since the SHaredMemory BAR info comes
from the virtio device directly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
02bd50f6ab vm-virtio: Add helper to set the configuration BAR value
From a VirtioPciDevice perspective, there are two types of BARs, either
the virtio configuration BAR or the SHaredMemory BAR.

The SHaredMemory BAR address comes from the virtio device directly as
the memory region had been previously allocated when the virtio device
has been created. So for this BAR, there's nothing to do when restoring
a VM, since the associated virtio device is already restored with the
appropriate resources, hence the BAR will already be at the right
address.

The remaining configuration BAR is different, as we usually get its
address from the SystemAllocator. This means in case we restore a VM,
we must provide this value, bypassing the allocator. This is what this
commit takes care of, by letting the caller set the base address for the
configuration BAR prior to allocating the BARs.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
8a826ae24c vmm: Store and restore virtio-pci device on right PCI slot
Based on the new field "pci_bdf", a virtio-pci device can be restored at
the same place on the PCI bus it was located before the VM snapshot.

This ensures consistent placement on the PCI bus, based on the stored
information related to each device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
98dac352b8 vmm: Add optional PCI b/d/f to each DeviceNode
We need a way to store the information about where a PCI device was
placed on the PCI bus before the VM was snapshotted. The way to do this
is by adding an extra field to the DeviceNode structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
Sebastien Boeuf
1e0ebb760f pci: Allow specific PCI b/d/f to be reserved
In order to let the PciBus user choose where a device should be placed
on the bus, a new function get_device_id() is introduced. This will be
helpful in the context of snapshot/restore as the caller will be able to
place the PCI devices on the same slot they were placed before the
snapshot was taken.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-12 17:37:31 +01:00
dependabot-preview[bot]
e577b64a58 build(deps): bump syn from 1.0.19 to 1.0.20
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.19 to 1.0.20.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.19...1.0.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-12 10:20:15 +02:00
Rob Bradford
36bffff22a tests: Expand the test_large_memory() test to cover lots of vCPUs
Ensure that there is no regression in our support for a large number of
vCPUS.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 19:34:34 +01:00
Rob Bradford
b9ba81c30d arch, vmm: Don't build mptable when using ACPI
Use the ACPI feature to control whether to build the mptable. This is
necessary as the mptable and ACPI RSDP table can easily overwrite each
other leading to it failing to boot.

TEST=Compile with default features and see that --cpus boot=48 now
works, try with --no-default-features --features "pci" and observe the
--cpus boot=48 also continues to work.

Fixes: #1132

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 19:34:34 +01:00
Rob Bradford
16ac24d8f7 tests: Only test "noacpi" test when we don't build with ACPI
The mmio integration test build currently doesn't use ACPI so piggyback
on that test variation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 19:34:34 +01:00
Rob Bradford
bb8d19bbd6 arch: Check RSDP address does not go past memory
The setup_mptables() call which is not used on ACPI builds has a side
effect of testing whether there was enough RAM which one of the unit
tests was relying on. Add a similar check for the RSDP address.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 19:34:34 +01:00
dependabot-preview[bot]
1c44e917f9 build(deps): bump clap from 2.33.0 to 2.33.1
Bumps [clap](https://github.com/clap-rs/clap) from 2.33.0 to 2.33.1.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v2.33.1/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v2.33.0...v2.33.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 20:15:13 +02:00
dependabot-preview[bot]
4cd2eccf2f build(deps): bump signal-hook from 0.1.14 to 0.1.15
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.14 to 0.1.15.
- [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.1.14...v0.1.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 20:15:03 +02:00
Sebastien Boeuf
308b790cfc vm-virtio: Implement Snapshottable trait for VirtioPciDevice
This gives Cloud-Hypervisor the possibility to snapshot and restore a
VM running with virtio-pci devices attached to it.

The VirtioPciDevice snapshot contains a vector of sub-snapshots to store
and restore information related to MsixConfig, VirtioPciCommonConfig and
PciConfiguration structures, along with snapshot data related to
VirtioPciDevice itself.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-11 11:38:16 +01:00
Sebastien Boeuf
6d59428641 vm-virtio: Implement Snapshottable trait for VirtioPciCommonConfig
This structure contains all the virtio generic information, and as part
of restoring a VM with virtio-pci devices, it is important to restore
these values to ensure the device's proper functioning.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-11 11:38:16 +01:00
Sebastien Boeuf
e1701f11b1 pci: Implement Snapshottable trait for PciConfiguration
The PCI configuration from each PCI device is modified at runtime as we
can expect the guest OS to write to some PCI capability structure, or
move the BAR to a different location in the guest address space.

For all the reasons why such configuration might differ from the initial
configuration, we must store the registers values to be able to restore
them with the right values whenever a PCI device is being restored.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-11 11:38:16 +01:00
Sebastien Boeuf
376db31107 pci: Implement Snapshottable trait for MsixConfig
In order to restore devices relying on MSI-X, the MsixConfig structure
must be restored with the correct values. Additionally, the KVM routes
must be restored so that interrupts can be delivered through KVM the way
they were configured before the snapshot was taken.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-11 11:38:16 +01:00
Rob Bradford
52ac3779df tests: Remove network interface from test_memory_overhead
Continue to try and track down the instability in the numbers generated
by this test by removing the (unused) network interface. It's possible
we are getting broadcast packets into the tap device and generating a
variable size of allocations.

See: #760

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 11:27:19 +02:00
Rob Bradford
b57eeb9628 vhost_user_block: Add "queue_size" to --block-backend
This allows the configuration of the queue size like other backends.

Fixes: #1131

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 09:40:40 +02:00
Rob Bradford
5016fcf8d5 vhost_user_block: Use config::OptionParser to simplify block backend parsing
Switch to using the recently added OptionParser in the code that parses
the block backend.

Fixes: #1092

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 09:40:40 +02:00
Rob Bradford
592de97fbd vhost_user_net: Use config::OptionParser to simplify net backend parsing
Switch to using the recently added OptionParser in the code that parses
the network backend.

Whilst doing this also update the net-backend syntax to use "sock"
rather than socket.

Fixes: #1092
Partially fixes: #1091

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 09:40:40 +02:00
Rob Bradford
f3f398eb44 vhost_user_block: Consolidate the vhost-user-block backend syntax
Rather than repeat syntax for the vhost-user-block backend in multiple
places store it in one place and reference it from the required places.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 09:40:40 +02:00
Rob Bradford
3220292d45 vhost_user_net: Consolidate the vhost-user-net backend syntax
Rather than repeat syntax for the vhost-user-net backend in multiple
places store it in one place and reference it from the required places.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-11 09:40:40 +02:00
dependabot-preview[bot]
0d2be3b6d4 build(deps): bump serde from 1.0.107 to 1.0.110
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.107 to 1.0.110.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.107...v1.0.110)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 06:43:33 +00:00
dependabot-preview[bot]
9d8754c620 build(deps): bump pin-project from 0.4.13 to 0.4.16
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.13 to 0.4.16.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/master/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.13...v0.4.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 08:01:33 +02:00
dependabot-preview[bot]
9bac13deb3 build(deps): bump serde_json from 1.0.52 to 1.0.53
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.52 to 1.0.53.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.52...v1.0.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 08:00:54 +02:00
dependabot-preview[bot]
e8d4a13e7f build(deps): bump serde_derive from 1.0.107 to 1.0.110
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.107 to 1.0.110.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.107...v1.0.110)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 08:00:37 +02:00
dependabot-preview[bot]
d8f181c576 build(deps): bump futures from 0.3.4 to 0.3.5
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.4 to 0.3.5.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.4...0.3.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-09 12:31:12 +01:00
dependabot-preview[bot]
1e44ac515f build(deps): bump serde_derive from 1.0.106 to 1.0.107
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.106 to 1.0.107.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.106...v1.0.107)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-09 12:30:55 +01:00
dependabot-preview[bot]
c197bd6f82 build(deps): bump serde from 1.0.106 to 1.0.107
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.106 to 1.0.107.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.106...v1.0.107)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-09 12:30:30 +01:00
Sebastien Boeuf
475040b29e vm-virtio: Correctly reset the virtqueues
Upon a virtio reset, the driver expects that available and used indexes
will be reset to 0. That's why we need to reset these values from the
VMM for any virtio device that might get reset.

This issue was not detected before because the Vec<Queue> maintained
through VirtioPciDevice or MmioDevice was never updated from the virtio
device thread after the device had been actived. For this reason, upon
reset, both available and used indexes were already at the value 0.

The issue arose when trying to reset a device after the VM was restored.
That's because during the restore, each queue is assigned with the right
available and used indexes before it is passed to the device through the
activate function. And that's why upon reset, each queue was still
assigned with these indexes while it should have been reset to 0.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-08 11:31:50 +01:00
Sebastien Boeuf
d809f2fe09 vm-virtio: Add virtio reset() support to MmioDevice
All our virtio devices support to be reset, but the virtio-mmio
transport layer was not implemented for it. This patch fixes this
lack of support.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-08 11:31:16 +01:00
Rob Bradford
0d720cc3d8 bin: ch-remote: Ensure ch-remote supports syntax it advertises
The ch-remote usage says:

OPTIONS:
        --api-socket <api-socket>    HTTP API socket path (UNIX domain socket).

However it doesn't seem to actually accept that syntax, instead
requiring "--api-socket=". This may be a clap bug however it is resolved
by setting the number of arguments requires to exactly one. Which is
also the actual correct number.

Fixes: #1117
Fixes: #1116

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-08 09:54:50 +01:00
dependabot-preview[bot]
74d88c4c8a build(deps): bump openssl-sys from 0.9.55 to 0.9.56
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.55 to 0.9.56.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.55...openssl-sys-v0.9.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-08 10:13:33 +02:00
Rob Bradford
9adc32a043 tests: Print out details for smaps in test_memory_overhead
To aid the debugging of why the test_memory_overhead sometimes fails
print a details of all the named regions that it uses in its
calculation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 17:53:47 +02:00
Rob Bradford
250f825f58 tests: Check that requesting tap name for virtio-net succeeds
When requesting a specific tap name with virtio-net check that that tap
device is created.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 13:41:00 +02:00
Rob Bradford
006da0405e tests: Check tap name provided is used for vhost_user_net tests
If a preferred tap name is given check that it is created.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 13:41:00 +02:00
Rob Bradford
54b3329f0c tests: Add tests that use (non-existing) named tap
The current tests support giving a tap name but they only test with tap
interfaces that already exist.

Fixes: #871

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 13:41:00 +02:00
Rob Bradford
6fde2d18a6 build: Strip the binaries before using/releasing them
Stripping the release build for glibc shrinks the size considerably:

$ du -h target/release/cloud-hypervisor
8.5M    target/release/cloud-hypervisor
$ strip target/release/cloud-hypervisor
$ du -h target/release/cloud-hypervisor
5.2M    target/release/cloud-hypervisor

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 12:31:01 +01:00
dependabot-preview[bot]
a4d23c3cf3 build(deps): bump syn from 1.0.18 to 1.0.19
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.18...1.0.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-07 08:12:17 +00:00
Rob Bradford
12e00c0f45 vmm: cpu: Retry sending signals if necessary
To avoid a race condition where the signal might "miss" the KVM_RUN
ioctl() instead reapeatedly try sending a signal until the vCPU run is
interrupted (as indicated by setting a new per vCPU atomic.)

It important to also clear this atomic when coming out of a paused
state.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 09:00:14 +02:00
Rob Bradford
31bde4f5da vmm: Unpark the DeviceManager threads in shutdown
To ensure that the DeviceManager threads (such as those used for virtio
devices) are cleaned up it is necessary to unpark them so that they get
cleanly terminated as part of the shutdown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 09:00:14 +02:00
Rob Bradford
801e72ac6d vmm: cpu: Unpause vCPU threads
After setting the kill signal flag for the vCPU thread release the pause
flag and unpark the threads. This ensures that that the vCPU thread will
wake up and check the kill signal flag if the VM is paused.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 09:00:14 +02:00
Rob Bradford
91a4a2581e vmm: cpu: When coming out of the pause event check for a kill signal
Rather than immediately entering the vCPU run() code check if the kill
signal is set. This allows paused VMs to be shutdown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 09:00:14 +02:00
Rob Bradford
cd60de8f7f Revert "vmm: vm: Unpark the threads before shutdown when the current state is paused"
This reverts commit e1a07ce3c4.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-07 09:00:14 +02:00
dependabot-preview[bot]
797cd13dcc build(deps): bump vec_map from 0.8.1 to 0.8.2
Bumps [vec_map](https://github.com/contain-rs/vec-map) from 0.8.1 to 0.8.2.
- [Release notes](https://github.com/contain-rs/vec-map/releases)
- [Commits](https://github.com/contain-rs/vec-map/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-06 15:25:15 +01:00
Sebastien Boeuf
f6a71bec36 vmm: Add unit tests for DeviceTree
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
64e01684f9 vmm: Create new module device_tree
This module will be dedicated to DeviceNode and DeviceTree definitions
along with some dedicated unit tests.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
3b77be903d vmm: Add device_node!() macro to improve code readability
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
83ec716ec4 vmm: Create breadth-first search iterator for the DeviceTree
This iterator will let the VMM enumerate the resources associated
with the DeviceManager, allowing for introspection.

Moreover, by implementing a double ended iterator, we can get the
hierarchy from the leaves to the root of the tree, which is very
helpful in the context of restoring the devices in the right order.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
b91ab1e3a5 vmm: Remove the list of migratable devices
Now that the device tree fully replaced the need for a dedicated list of
migratable devices, this commit cleans up the codebase by removing it
from the DeviceManager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
1be7037229 vmm: Don't use migratable_devices for restore
This commit switches from migratable_devices to device_tree in order to
restore devices exclusively based on the device tree.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
bc6084390f vmm: Add migratable field to the DeviceNode
This commit adds an extra field to the DeviceNode so that the structure
can hold a Migratable device. The long term plan is to be able to remove
the dedicated table of migratable devices, but instead rely only on the
device tree.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
7fec020f53 vmm: Create a dedicated DeviceTree structure
In order to hide the complexity chosen for the device tree stored in
the DeviceManager, we introduce a new DeviceTree structure.

For now, this structure is a simple passthrough of a HashMap, but it can
be extended to handle some DeviceTree specific operations.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
14b379dec5 vmm: Add an identifier field to DeviceNode structure
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
0805d458c4 vmm: Add support for multiple children per DeviceNode
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
daaeba5142 vmm: Change Node into DeviceNode
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
5c7df03efe vmm: Store and restore virtio-pmem resources
This device has a dedicated memory region in the guest address space,
which means in case of snapshot/restore, it must be restored in the
exact same location it was during the snapshot.

That's through the resources that we can describe the location of this
extra memory region, allowing the device for correct restoring.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
2e6895d911 vmm: Store and restore virtio-fs resources
This device has a dedicated memory region in the guest address space,
which means in case of snapshot/restore, it must be restored in the
exact same location it was during the snapshot.

That's through the resources that we can describe the location of this
extra memory region, allowing the device for correct restoring.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
987f82152e vmm: Store and restore virtio-mmio resources
Based on the device tree, retrieve the resources associated with a
virtio-mmio device to restore it at the right location in guest address
space. Also, the IRQ number is correctly restored.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
9cb1e1cc6b vmm: Perform MMIO allocation from virtio-mmio device creation
Instead of splitting the MMIO allocation and the device creation into
separate functions for virtio-mmio devices, it's is easier to move
everything into the same function as we'll be able to gather resources
in the same place for the same device.

These resources will be stored in the device tree in a follow up patch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
adf297066d vmm: Create devices in different path if restoring the VM
In case the VM is created from scratch, the devices should be created
after the DeviceManager has been created. But this should not affect the
restore codepath, as in this case the devices should be created as part
of the restore() function.

It's necessary to perform this differentiation as the restore must go
through the following steps:
- Create the DeviceManager
- Restore the DeviceManager with the right state
- Create the devices based on the restored DeviceManager's device tree
- Restore each device based on the restored DeviceManager's device tree

That's why this patch leverages the recent split of the DeviceManager's
creation to achieve what's needed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
d39f91de02 vmm: Reorganize DeviceManager creation
This commit performs the split of the DeviceManager's creation into two
separate functions by moving anything related to device's creation after
the DeviceManager structure has been initialized.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
89c2a5868c vmm: Restore devices following the device tree
Based on the device tree, we now ensure the restore can be done in the
right order, as it will respect the dependencies between nodes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
52c80cfcf5 vmm: Snapshot and restore DeviceManager state
The DeviceManager itself must be snapshotted in order to store the
information regarding the devices associated with it, which effectively
means we need to store the device tree.

The mechanics to snapshot and restore the DeviceManagerState are added
to the existing snapshot() and restore() implementations.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
5b408eec66 vmm: Create a device tree
The DeviceManager now creates a tree of devices in order to store the
resources associated with each device, but also to track dependencies
between devices.

This is a key part for proper introspection, but also to support
snapshot and restore correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Sebastien Boeuf
a6fde0bb1c vm-device: Define a Resource
Based on rust-vmm code, we copy the Resource structure as it will be
used to define the set of resources associated with a device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-05-05 16:08:42 +02:00
Rob Bradford
b8841d7a82 tests: Validate vsock functionality works across a reboot
Reboot the VM and check that the vsock functionality is preserved.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-05 13:01:38 +02:00
Rob Bradford
fec97e0586 vm-virtio, vmm: Delete unix socket on shutdown
It's not possible to call UnixListener::Bind() on an existing file so
unlink the created socket when shutting down the Vsock device.

This will allow the VM to be rebooted with a vsock device.

Fixes: #1083

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-05 13:01:38 +02:00
Rob Bradford
5109f914eb vmm: config: Reject attempts to use VFIO or IOMMU without PCI
Generate an error during validation if an attempt it made to place a
device behind an IOMMU or using a VFIO device when not using PCI.

Fixes: #751

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-05 11:20:52 +01:00
Rob Bradford
cb220ae184 tests: Add some debugging to test_memory_overhead
This test is flaky. Add some debugging to identify what the bad value
is.

See: #760

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-05-05 11:35:12 +02:00
dependabot-preview[bot]
eb3d9d15bf build(deps): bump ssh2 from 0.8.0 to 0.8.1
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.8.0...0.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 08:20:01 +00:00
dependabot-preview[bot]
59b730342d build(deps): bump failure from 0.1.7 to 0.1.8
Bumps [failure](https://github.com/rust-lang-nursery/failure) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/rust-lang-nursery/failure/releases)
- [Changelog](https://github.com/rust-lang-nursery/failure/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-lang-nursery/failure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 07:26:47 +00:00
dependabot-preview[bot]
dd0791d7c8 build(deps): bump pnet from 0.25.0 to 0.26.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.25.0 to 0.26.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.25.0...v0.26.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 07:26:30 +00:00
dependabot-preview[bot]
7660a104d9 build(deps): bump failure_derive from 0.1.7 to 0.1.8
Bumps [failure_derive](https://github.com/rust-lang-nursery/failure) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/rust-lang-nursery/failure/releases)
- [Changelog](https://github.com/rust-lang-nursery/failure/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-lang-nursery/failure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:00:56 +02:00
Hui Zhu
327d67fadf virtio-mem: Return reize error in MemEpollHandler.run
Return resize error in MemEpollHandler.run.

Fixes: #1081

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-05-03 10:21:49 +01:00
dependabot-preview[bot]
bc318b64e9 build(deps): bump proc-macro2 from 1.0.10 to 1.0.12
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.10 to 1.0.12.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.10...1.0.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-02 19:01:45 +01:00
dependabot-preview[bot]
5571c6af2d build(deps): bump signal-hook from 0.1.13 to 0.1.14
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.13 to 0.1.14.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.1.13...v0.1.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-02 19:01:33 +01:00
dependabot-preview[bot]
af3d080226 build(deps): bump pnet_macros from 0.25.0 to 0.26.0
Bumps [pnet_macros](https://github.com/libpnet/libpnet) from 0.25.0 to 0.26.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.25.0...v0.26.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-02 19:01:13 +01:00
dependabot-preview[bot]
678855e858 build(deps): bump term_size from 0.3.1 to 0.3.2
Bumps [term_size](https://github.com/kbknapp/term_size-rs) from 0.3.1 to 0.3.2.
- [Release notes](https://github.com/kbknapp/term_size-rs/releases)
- [Changelog](https://github.com/clap-rs/term_size-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kbknapp/term_size-rs/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-02 19:01:05 +01:00
dependabot-preview[bot]
2a16ce7e41 build(deps): bump quote from 1.0.3 to 1.0.4
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.3...1.0.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-30 23:03:47 +02:00
dependabot-preview[bot]
99e3a15014 build(deps): bump backtrace-sys from 0.1.36 to 0.1.37
Bumps [backtrace-sys](https://github.com/alexcrichton/backtrace-rs) from 0.1.36 to 0.1.37.
- [Release notes](https://github.com/alexcrichton/backtrace-rs/releases)
- [Commits](https://github.com/alexcrichton/backtrace-rs/compare/backtrace-sys-0.1.36...backtrace-sys-0.1.37)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-30 17:22:02 +01:00
Rob Bradford
96be82296f release: Release v0.7.0
Expand release notes and bump Cargo.toml.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-30 16:26:08 +01:00
Rob Bradford
5115ad6e56 vmm: config: Support on/off/true/false for all booleans
Migrate missing boolean controls over to the Toggle to handle all
values.

Fixes: #936

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-30 15:21:09 +02:00
Rob Bradford
d5bfa2dfc8 vmm, vhost_user_block: Make parameter names match --disk
Make the --block-backend parameters match the --disk parameters.

Fixes: #898

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-30 15:20:55 +02:00
Sebastien Boeuf
2f0bc06bec vmm: Update default devices names as "internal"
Let's put an underscore "_" in front of each device name to identify
when it has been set internally.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
aaba6e777f vmm: Add virtio-console to the list of Migratable devices
The virtio-console was not added to the list of Migratable devices,
which is fixed from this patch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
9ab4bb1ae2 devices: serial: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
06487131f9 vm-virtio: pci: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

It is based off the name from the virtio device attached to this
transport layer.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
eeb7e10d1f vm-virtio: mmio: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

It is based off the name from the virtio device attached to this
transport layer.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
9d84ef5073 vmm: Make the virtio identifier mandatory
Because we know we will need every virtio device to be identified with a
unique id, we can simplify the code by making the identifier mandatory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
14350f5de4 devices: ioapic: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
556871570e vm-virtio: iommu: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
052eff1ca7 vm-virtio: console: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
354c2a4b3d vm-virtio: vhost-user-net: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
46e0b3ff75 vm-virtio: vhost-user-blk: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
bb7fa71fcb vm-virtio: vhost-user-fs: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
ec5ff395cf vm-virtio: vsock: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
9b53044aae vm-virtio: mem: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
1592a9292f vm-virtio: pmem: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
2e91b73881 vm-virtio: rng: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
9eb7413fab vm-virtio: net: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
be946caf4b vm-virtio: blk: Expect an identifier upon device creation
This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
ff9c8b847f vmm: Always generate the next device name
Even in the context of "mmio" feature, we need the next device name to
be generated as we need to identify virtio-mmio devices to support
snapshot and restore functionalities.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
8183141399 vmm: Add an identifier to the ioapic device
This will be later used to identify each device used by the VM in order
to perform introspection and snapshot/restore properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
e4386c8bb7 vmm: Add an identifier to the virtio-iommu device
This will be later used to identify each device used by the VM in order
to perform introspection and snapshot/restore properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
75ddd2a244 vmm: Add an identifier to the --console device
This will be later used to identify each device used by the VM in order
to perform introspection and snapshot/restore properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
eac350c454 vmm: Add an identifier to the virtio-mem device
This will be later used to identify each device used by the VM in order
to perform introspection and snapshot/restore properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
6802ef5406 vmm: Add an identifier to the --rng device
This will be later used to identify each device used by the VM in order
to perform introspection and snapshot/restore properly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
d71d52e9b0 vmm: Fix virtio-console creation with virtual IOMMU
If the virtio-console device is supposed to be placed behind the virtual
IOMMU, this must be explicitly propagated through the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
b08fde5928 vmm: Fix virtio-rng creation with virtual IOMMU
If the virtio-rng device is supposed to be placed behind the virtual
IOMMU, this must be explicitly propagated through the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Sebastien Boeuf
8031ac33c3 vmm: Fix virtio-vsock creation with virtual IOMMU
If the virtio-vsock device is supposed to be placed behind the virtual
IOMMU, this must be explicitly propagated through the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 19:34:31 +01:00
Samuel Ortiz
50134969b9 Jenkins: Run musl unit and integration tests on master branch
And use a bumped up container image for that.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 17:57:01 +01:00
Samuel Ortiz
ce794f7858 ci: Pass target triple to the test scripts
We pass it to the integration and unit tests script through --libc.
Cargo tests are left unmodified.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-29 17:57:01 +01:00
Samuel Ortiz
33b0e15804 resources: Add musl tools and toolchain to the Dockerfile
And fix the libssl install for building it with musl.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-29 17:57:01 +01:00
Samuel Ortiz
ad9374bd68 dev_cli: Add --libc to the build and test commands
We only support musl and gnu, default is gnu.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-29 17:57:01 +01:00
Rob Bradford
8cef35745b vmm: seccomp: Add fork, gettid and pipe2 syscalls to permitted list
This is needed for self spawning with the musl target.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 17:57:01 +01:00
Rob Bradford
ce7678f29f vmm: seccomp: Add tkill syscall to permitted list
This is needed for rebooting on the musl target.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 17:57:01 +01:00
Rob Bradford
12758d7fad vmm: seccomp: Add epoll_pwait syscall to permitted list
This is needed for basic operation on the musl target.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 17:57:01 +01:00
Samuel Ortiz
86fcd19b8a build: Initial musl support
Fix all build failures and add musl to the gihub workflows.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-29 17:57:01 +01:00
Sebastien Boeuf
a5de49558e vmm: Only allow removal of specific types of virtio device
Now that all virtio devices are assigned with identifiers, they could
all be removed from the VM. This is not something that we want to allow
because it does not make sense for some devices. That's why based on the
device type, we remove the device or we return an error to the user.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 13:33:19 +01:00
Sebastien Boeuf
9ed880d74e vmm: Add an identifier to the --fs device
By giving the devices ids this effectively enables the removal of the
device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 13:33:19 +01:00
Sebastien Boeuf
7e0ab6b56d vmm: Fix pmem device creation
The parameters regarding the attachment to the virtio-iommu device was
not propagated correclty, and any modification to the configuration was
not stored back into it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-29 13:33:19 +01:00
Rob Bradford
3012975c17 tests: Enhance vsock integration test to support hotplug
Test basic vsock functionality works with hotplugged vsock device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
6c2bca5f1b bin: ch-remote: Add support for adding vsock devices
Add support for adding a vsock device using the HTTP API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
8de7448d44 vmm: api: Add "add-vsock" API entry point
This allows the hotplugging of vsock devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
bf09a1e695 openapi: Add "id" field to VsockConfig
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
a76cf0865f vmm: vm: Remove vsock device from config
When doing device unplug remove the vsock device from the configuration
if present.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
99422324a7 vmm: vm: Add "add_vsock()"
Add the vsock device to the device manager and patch the config to add
the new vsock device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
1d61c476a1 vmm: device_manager: Add support for hotplugging virtio-vsock devices
Create a new VirtioVsock device and add it to the PCI bus upon hotplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
f8501a3bd3 vmm: config: Move --vsock syntax to VsockConfig
This means it can be reused with ch-remote.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Sebastien Boeuf
6e049e0da1 vmm: Add an identifier to the --vsock device
It's possible to have multiple vsock devices so in preparation for
hotplug/unplug it is important to be able to have a unique identifier
for each device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-29 12:44:49 +01:00
Rob Bradford
10348f73e4 vmm, main: Support only zero or one vsock devices
The Linux kernel does not support multiple virtio-vsock devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-28 20:07:18 +02:00
Rob Bradford
9d1f95a3cc openapi: Add missing "id" field
NetConfig/DiskConfig/PmemConfig/FsConfig were all missing the id field
in the API yaml file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-28 18:27:45 +02:00
dependabot-preview[bot]
30e2e51588 build(deps): bump serde_json from 1.0.51 to 1.0.52
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.51...v1.0.52)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-28 14:09:57 +02:00
dependabot-preview[bot]
dd9d0d0440 build(deps): bump micro_http from 0d87a94 to c9ffb90
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `0d87a94` to `c9ffb90`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](0d87a94c8e...c9ffb90aeb)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-28 10:21:55 +01:00
dependabot-preview[bot]
cdc8493a05 build(deps): bump thiserror from 1.0.15 to 1.0.16
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.15...1.0.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-28 08:01:55 +02:00
dependabot-preview[bot]
f5debc4bc0 build(deps): bump libssh2-sys from 0.2.16 to 0.2.17
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.16 to 0.2.17.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.16...libssh2-sys-0.2.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:10:14 +02:00
dependabot-preview[bot]
37dfb4cbb3 build(deps): bump hermit-abi from 0.1.11 to 0.1.12
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.11 to 0.1.12.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.11...hermit-abi-0.1.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:10:02 +02:00
Muminul Islam
e1a07ce3c4 vmm: vm: Unpark the threads before shutdown when the current state is paused
If the current state is paused that means most of the handles got killed by pthread_kill
We need to unpark those threads to make the shutdown worked. Otherwise
The shutdown API hangs and the API is not responding afterwards. So
before the shutdown call we need to resume the VM make it succeed.

Fixes: #817

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-04-27 09:09:12 +02:00
Rob Bradford
1df38daf74 vmm, tests: Make specifying a size optional for virtio-pmem
If a size is specified use it (in particular this is required if the
destination is a directory) otherwise seek in the file to get the size
of the file.

Add a new check that the size is a multiple of 2MiB otherwise the kernel
will reject it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-24 18:30:05 +01:00
Rob Bradford
7481e4d959 vmm: config: Validate that shared memory is enabled if using vhost-user
Check that if any device using vhost-user (net & disk with
vhost_user=true) or virtio-fs is enabled then check shared memory is
also enabled.

Fixes: #848

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-24 16:01:49 +01:00
Bo Chen
2ac6971a8b vmm: MemoryManager: Cleanup the usage of std::ffi/io/result
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-04-23 21:39:51 +02:00
Bo Chen
3f42f86d81 vmm: Add the 'shared' and 'hugepages' controls to MemoryConfig
The new 'shared' and 'hugepages' controls aim to replace the 'file'
option in MemoryConfig. This patch also updated all related integration
tests to use the new controls (instead of providing explicit paths to
"/dev/shm" or "/dev/hugepages").

Fixes: #1011

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-04-23 21:39:51 +02:00
dependabot-preview[bot]
d6aa717913 build(deps): bump syn from 1.0.17 to 1.0.18
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.17 to 1.0.18.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.17...1.0.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-23 21:32:53 +02:00
Jose Carlos Venegas Munoz
3eaeba4b55 vm-virtio: Fix FS_IO callback for virtio-fs
FS_IO is part of the actions a vhost-user-fs daemon can ask the VMM to
perform on its behalf. It is meant to read/write the content from a file
descriptor directly into a guest memory region. This region can either
be a RAM region or the dedicated cache region for virtio-fs.

The way FS_IO was implemented, it was only expecting the guest physical
address provided through the "cache_offset" field to refer to the cache
region. Unfortunately, this was only implementing FS_IO partially.

This patch extends the existing FS_IO implementation by checking the GPA
against the cache region as a first step, but if it is not part of the
cache region address range, then we fallback onto searching for a RAM
region that could match. If there is a matching RAM region, we retrieve
the corresponding host address to let the VMM read/write from/to it.

Fixes: #1054

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-04-23 15:01:28 +01:00
dependabot-preview[bot]
df14a68e87 build(deps): bump smallvec from 1.3.0 to 1.4.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.3.0...v1.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-23 14:38:39 +02:00
Samuel Ortiz
e685854f16 gh: Separate the build and release jobs
The release one is always skipped for PRs which can be confusing for
e.g. dependabot.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-23 13:45:12 +02:00
Rob Bradford
c790bba905 tests: Migrate from Ubuntu Eoan to Focal
This is the latest LTS release.

Fixes: #989

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-23 13:01:02 +02:00
dependabot-preview[bot]
e525af7a61 build(deps): bump ryu from 1.0.3 to 1.0.4
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.3...1.0.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-23 12:29:14 +02:00
Sebastien Boeuf
3e8a6ba0c0 ci: Ignore test_snapshot_restore
The newly added integration test "test_snapshot_restore" is very
unstable, which causes our CI to fail on most pull requests, which is
not acceptable. That's why we ignore this test until we can fix the
stability issue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-23 11:38:47 +02:00
dependabot-preview[bot]
9ebf052538 build(deps): bump cc from 1.0.51 to 1.0.52
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.51...1.0.52)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-22 22:19:53 +02:00
Sebastien Boeuf
f6b150a34d ci: Add integration test for VM migration
Now that we have multiple virtio devices supporting snapshot and restore
operations, we can add a new integration test to validate the migration
feature works as expected.

The important part is virtio-net as it is used to ssh into the VM to
verify the VM has been restored in the proper state.

This test only works for virtio-mmio for now. Further support for
testing virtio-pci will be added once the virtio-pci transport layer
will support migration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-22 22:19:31 +02:00
dependabot-preview[bot]
9f08f537e0 build(deps): bump pin-utils from 0.1.0-alpha.4 to 0.1.0
Bumps [pin-utils](https://github.com/rust-lang-nursery/pin-utils) from 0.1.0-alpha.4 to 0.1.0.
- [Release notes](https://github.com/rust-lang-nursery/pin-utils/releases)
- [Commits](https://github.com/rust-lang-nursery/pin-utils/compare/0.1.0-alpha.4...0.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-22 20:18:42 +02:00
Yang Zhong
9c7215d620 docs: Add the vhost-user-blk test doc
This doc describe how to use vhost-user-blk in Cloud Hypervisor
with SPDK. With this doc, we can setup simple test environment on
Ubuntu release.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-04-22 20:18:23 +02:00
dependabot-preview[bot]
35744375e0 build(deps): bump cc from 1.0.50 to 1.0.51
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.50 to 1.0.51.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.50...1.0.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-22 17:10:21 +02:00
Yi Sun
4fc75cf2b0 vm-virtio: Implement Snapshottable trait for Console
This patch implements the Snapshottable trait for virtio-console, which
enables migration support for it. A VM with a virtio-console device
attached can be snapshot and then restored without issues.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-22 14:45:16 +02:00
Yi Sun
d41ce909a2 vm-virtio: Implement Snapshottable trait for Pmem
This brings the migration support to virtio-pmem device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-22 14:45:02 +02:00
dependabot-preview[bot]
f626bd60c5 build(deps): bump parking_lot_core from 0.7.1 to 0.7.2
Bumps [parking_lot_core](https://github.com/Amanieu/parking_lot) from 0.7.1 to 0.7.2.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.7.1...core-0.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-22 09:12:08 +02:00
Martin Xu
5a380a6918 vmm: memory_manager: Support non-power-of-2 block sizes
Replace alignment calculation of start address with functionally
equivalent version that does not assume that the block size is a power
of two.

Signed-off-by: Martin Xu <martin.xu@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-22 09:11:51 +02:00
dependabot-preview[bot]
f8ee89a514 build(deps): bump arc-swap from 0.4.5 to 0.4.6
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 0.4.5 to 0.4.6.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v0.4.5...v0.4.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-21 22:08:17 +02:00
Sebastien Boeuf
49322c5ebe vm-virtio: Implement the Snapshottable trait for Net
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-21 21:25:03 +02:00
Sebastien Boeuf
24c2b67aa4 vm-virtio: Improve virtio-net rx queue processing
The frame buffer must be updated depending on the amount read from it,
which depends on the number and depth of descriptors available at the
time of the processing.

This patch handles this buffer update, and allow for large buffers to be
correctly processed in multiple rounds.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 21:25:03 +02:00
Sebastien Boeuf
03dd24978e vm-virtio: Restore queues based on used index
On the restore path, using the available and used indexes read from
memory to fill the Queue structure was a mistake. Indeed, the available
index is written from the guest and it reflects the last available index
in the descriptor table. But the driver might have queued a lot of
buffers which have not yet been used by the device. This leads to a
situation where the next_avail from Queue is completely different from
the one we can read from memory.

Instead, the right way to determine the next_avail index that should be
used by the device is by relying on the used index from the memory. This
index represents the correct information we're looking for as it has
been updated before the snapshot to let the guest know the next index to
process.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 21:25:03 +02:00
Sebastien Boeuf
cf707da1a8 vm-virtio: Extend Queue helpers
First, this modifies the existing helpers on how to get indexes for
available and used rings from memory. Instead of updating the queue
through each helper, they are now used as simple getters.

Based on these new getters, we could create a new helper to determine if
the queue has some available descriptors already queued from the driver
side. This helper is going to be particularly helpful when trying to
determine from a virtio thread if a queue is already loaded with some
available buffers that can be used to send information to the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 21:25:03 +02:00
Sebastien Boeuf
c22fd39170 vmm: Remove virtio device's userspace mapping on hot-unplug
When a virtio device is dynamically removed from the VM through the
hot-unplug mechanism, every mapping associated with it must be properly
removed.

Based on the previous patches letting a VirtioDevice expose the list of
userspace mappings associated with it, this patch can now remove all the
KVM userspace memory regions through the MemoryManager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
Sebastien Boeuf
0a97c25464 vmm: Extend MemoryManager to remove userspace mappings
The same way we added a helper for creating userspace memory mappings
from the MemoryManager, this patch adds a new helper to remove some
previously added mappings.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
Sebastien Boeuf
b2de1cd523 vm-virtio: Implement shutdown() for virtio-fs
Since the virtio-fs device is backed by a vhost-user process, it is
important to implement the proper shutdown() function from the
VirtioDevice trait, as vhost-user-blk and vhost-user-net do.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
Sebastien Boeuf
fbcf3a7a7a vm-virtio: Implement userspace_mappings() for virtio-pmem
When hot-unplugging the virtio-pmem from the VM, we don't remove the
associated userspace mapping. This patch will let us fix this in a
following patch. For now, it simply adapts the code so that the Pmem
device knows about the mapping associated with it. By knowing about it,
it can expose it to the caller through the new userspace_mappings()
function.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
Sebastien Boeuf
b0353992d6 vm-virtio: Implement userspace_mappings() for virtio-fs
This will help when we will implement the hot-unplug of the virtio-fs
device, as we will have to remove correctly the userspace mappings
associated with the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
Sebastien Boeuf
3fb0a02fa2 vm-virtio: Get userspace mappings from VirtioDevice
Introduce new getter function to the VirtioDevice trait, as it will
allow the caller to retrieve the list of userspace mappings associated
with the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-21 10:02:21 +01:00
dependabot-preview[bot]
8b823e5e34 build(deps): bump backtrace-sys from 0.1.35 to 0.1.36
Bumps [backtrace-sys](https://github.com/alexcrichton/backtrace-rs) from 0.1.35 to 0.1.36.
- [Release notes](https://github.com/alexcrichton/backtrace-rs/releases)
- [Commits](https://github.com/alexcrichton/backtrace-rs/compare/backtrace-sys-0.1.35...backtrace-sys-0.1.36)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 21:49:34 +00:00
Sebastien Boeuf
c23b48888d ci: Factorize virtio-fs hotplug integration tests
There is some duplication between regular and hotplug virtio-fs tests
that can be factorized by adding a simple hotplug flag to choose if each
test should run with or without hotplugging the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-20 20:36:26 +02:00
Dean Sheather
f68b08bfdb tests: add integration tests for vm.add-fs route
Adds integration tests with and without dax for the new vm.add-fs route.

Signed-off-by: Dean Sheather <dean@coder.com>
2020-04-20 20:36:26 +02:00
Sebastien Boeuf
18f7789a81 vmm: Add hotplugged virtio devices to the DeviceManager list
The hotplugged virtio devices were not added to the list of virtio
devices from the DeviceManager. This patch fixes it, as it was causing
hotplugged virtio-fs devices from not supporting memory hotplug, since
they were never getting the update as they were not part of the list of
virtio devices held by the DeviceManager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-20 20:36:26 +02:00
Dean Sheather
c2abadc293 vmm: Add ability to add virtio-fs device post-boot
Adds DeviceManager method `make_virtio_fs_device` which creates a single
device, and modifies `make_virtio_fs_devices` to use this method.

Implements the new `vm.add-fs route`.

Signed-off-by: Dean Sheather <dean@coder.com>
2020-04-20 20:36:26 +02:00
Dean Sheather
bb2139a408 vmm/api: Add vm.add-fs route
Currently unimplemented. Once implemented, this API will allow for
creating virtio-fs devices in the VM after it has booted.

Signed-off-by: Dean Sheather <dean@coder.com>
2020-04-20 20:36:26 +02:00
Sebastien Boeuf
d35e775ed9 vmm: Update KVM userspace mapping when PCI BAR remapping
In the context of the shared memory region used by virtio-fs in order to
support DAX feature, the shared region is exposed as a dedicated PCI
BAR, and it is backed by a KVM userspace mapping.

Upon BAR remapping, the BAR is moved to a different location in the
guest address space, and the KVM mapping must be updated accordingly.

Additionally, we need the VirtioDevice to report the updated guest
address through the shared memory region returned by get_shm_regions().
That's why a new setter is added to the VirtioDevice trait, so that
after the mapping has been updated for KVM, we can tell the VirtioDevice
the new guest address the shared region is located at.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-20 16:01:25 +02:00
Sebastien Boeuf
49cc73a4ca vm-virtio: pci: Make sure to return the correct list of BARs
By adding the shared memory regions to the list of BARs, we make sure
the DeviceManager will register it as a BAR on the PCI bus. Without
this, when PCI BAR reprogramming happens, the PCI bus errors since it
does not know about any BAR at the specified address.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-20 16:01:25 +02:00
Yi Sun
187b1eec8b vm-virtio: Implement the Snapshottable trait for Block
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-17 19:29:41 +02:00
Samuel Ortiz
a484aa7be6 vm-virtio: Implement the Snapshottable trait for Rng
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-17 19:29:41 +02:00
Sebastien Boeuf
ac7178ef2a vmm: Keep migratable devices list as a Vec
The order the elements are pushed into the list is important to restore
them in the right order. This is particularly important for MmioDevice
(or VirtioPciDevice) and their VirtioDevice counterpart.

A device must be fully ready before its associated transport layer
management can trigger its restoration, which will end up activating the
device in most cases.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 19:29:41 +02:00
Sebastien Boeuf
b6fdbf7a44 vm-virtio: Implement Snapshottable trait for MmioDevice
Any virtio device relying on the mmio transport layer can be snapshotted
and restored thanks to this new patch. From the MmioDevice perspective,
it is mainly a matter of saving the information about the virtqueues as
the restore path will need them to activate the device (if needed
because it has been activated before being snapshotted).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 19:29:41 +02:00
Sebastien Boeuf
12fec55064 vm-virtio: Add helpers to update queue indexes
In anticipation for adding snapshot/restore support to virtio devices,
this commit introduces two new helpers updating the available and used
indexes of a queue, relying on the guest memory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 19:29:41 +02:00
Samuel Ortiz
fd45e94510 vm-virtio: Add the ability to serialize a Queue
This commit relies on serde to serialize and deserialize the content of
a Queue structure. This will be useful information to store when
implementing snapshot/restore feature for virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-17 19:29:41 +02:00
Sergio Lopez
b7faf4fdc1 vhost_user_fs: Add the WRITE_KILL_PRIV write flag.
Add the WRITE_KILL_PRIV write flag, corresponding to
FUSE_WRITE_KILL_PRIV introduced in 7.31, and use to only remove the
setuid and setgid bits (by switching credentials) conditionally.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
0870028fde vhost_user_fs: Add the IOCTL_COMPAT_32 flag
Add the IOCTL_COMPAT_32 flag, corresponding to FUSE_IOCTL_COMPAT_32
introduced in FUSE 7.30.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
592cfbafb3 vhost_user_fs: Add the EXPLICIT_INVAL_DATA capability flag
Add EXPLICIT_INVAL_DATA capability flag, corresponding to
FUSE_EXPLICIT_INVAL_DATA introduced in FUSE 7.30.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
621ea837fa vhost_user_fs: Add the ZERO_MESSAGE_OPENDIR capability flag
Add ZERO_MESSAGE_OPENDIR capability flag, corresponding to
FUSE_NO_OPENDIR_SUPPORT introduced in FUSE 7.29.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
a2830da7c0 vhost_user_fs: Add the CACHE_SYMLINKS flag
Add the CACHE_SYMLINKS flag, corresponding to FUSE_CACHE_SYMLINKS
introduced in FUSE 7.28.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
926a414b90 vhost_user_fs: Add support for MAX_PAGES
Add support for MAX_PAGES, corresonding to FUSE_MAX_PAGES introduced
in FUSE 7.28.

This allows us to negotiate with the kernel the maximum number of
pages that we support to transfer in a single request.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
747f31d82c vhost_user_fs: Add the ABORT_ERROR flag
Add the ABORT_ERROR flag, corresponding to FUSE_ABORT_ERROR,
introduced in FUSE 7.27.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
5eb903a509 vhost_user_fs: Add support for FOPEN_CACHE_DIR
Add support for FOPEN_CACHE_DIR, a flag that allows us to tell the
guest that it's safe to cache a directory, introduced in FUSE 7.28.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Sergio Lopez
97e2d5d266 vhost_user_fs: Add support for CopyFileRange
Add support for the CopyFileRange request, introduced in FUSE 7.28.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-04-17 15:42:40 +01:00
Rob Bradford
b8cfdab8b6 pci: configuration: Use correct algorithm for BAR size reporting
When reporting the BAR size it is necessary to return a value that is
encoded such that all the bits are set that represent the mask of the
natural alignment of the field.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-17 15:20:50 +02:00
Rob Bradford
9bd5ec8967 pci, vfio, vm-virtio: Specify a PCI revision ID of 1 for virtio-pci
Add support for specifying the PCI revision in the PCI configuration and
populate this with the value of 1 for virtio-pci devices.

The virtio-pci specification is slightly ambiguous only saying that
transitional (i.e. devices that support legacy and virtio 1.0) should
set this to 0. In practice it seems that software expects the revision
to be set to 1 for modern only devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-17 13:46:48 +02:00
Rob Bradford
e7e0e8ac38 vmm, devices: Add firmware debug port device
OVMF and other standard firmwares use I/O port 0x402 as a simple debug
port by writing ASCII characters to it. This is gated under a feature
that is not enabled by default.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-17 12:54:00 +02:00
Sebastien Boeuf
82d0cdff4f vhost_user_net: Simplify match values for handle_event()
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Sebastien Boeuf
a517be4eac vhost_user_blk: Add multithreaded multiqueue support
After all the previous refactoring patches, we can finally create
multiple threads under the same backend. This is directly combined with
multiqueues so that it will create one thread per queue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Sebastien Boeuf
13c8283fbe vhost_user_blk: Make everything private when possible
Doing some cleanup as most of the code does not need to be public.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Sebastien Boeuf
a31f5f8106 vhost_user_blk: Move disk initialization to VhostUserBlkBackend
Anticipating the follow up patches to run multiple threads for the same
backend, we need the initialization of the disk to happen in the high
level structure VhostUserBlkBackend.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Sebastien Boeuf
e78e34b36a vhost_user_blk: Make DiskFile sharable across threads
The DiskFile will need to be shared across multiple threads when running
multiple queues across these threads. That's why it needs to be put
inside an Arc. The reason for the Mutex is because execute() expects a
mutable object implementing Read + Write + Seek. Unfortunately, this
create a contention point as the object needs to be locked from each
thread, reducing the performance gain we will get with multiple threads.

The need for an immutable object would solve this problem, and it will
be addressed later through follow up patches.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Sebastien Boeuf
808586ece7 vhost_user_blk: Simplify the code by removing VringWorker
There is no need for retrieving the VringWorker since we don't need to
register some extra file descriptors to the epoll loop.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-17 12:52:28 +02:00
Rob Bradford
ea82632c70 tests: Enhance test_pmem_hotplug to also unplug device
Ensure that the device is removed and the removed device stays away
after a reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
6389418fa6 tests: Enhance test_disk_hotplug to also unplug device
Ensure that the device is removed and the removed device stays away
after a reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
f9a0445c3d vmm: vm: Remove device from configuration after unplug
This ensures that a device that is removed will not reappear after a
reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
444e5c2a04 vmm: device_manager: Generalise NoAvailableVfioDeviceName
We now support assigning device ids for VFIO and virtio-pci devices so
this error can be generalised.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
5bab9c3894 vmm: device_manager: Assign ids to pmem/net/disk devices if absent
If the id has not been provided by the user generate an incrementing id.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
514491a051 vmm: device_manager: Support unplugging virtio-pci devices
Extend the eject_device() method on DeviceManager to also support
virtio-pci devices being unplugged.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
2fa652aa4c vm-virtio: pci: Add virtio_device() accessor
Add an accessor to return the underlying VirtioDevice. This is useful
for managing the removal of the device from internal datastructures when
handling virtio-pci device unplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
476e4ce24f vmm: device_manager: Add virtio-pci devices into id to BDF map
In order to support hotplugging there is a map of human readable device
id to PCI BDF map.

As the device id is part of the specific device configuration (e.g.
NetConfig) it is necessary to return the id through from the helper
functions that create the devices through to the functions that add
those devices to the bus. This necessitates changing a great deal of
function prototypes but otherwise has little impact.

Currently only if an id is supplied by the user as part of the device
configuration is it populated into this map. A later commit will
populate with an autogenerated name where none is supplied by the user.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
b38470df4b vmm: config: Add "id" parameter to {Net, Disk, Pmem}Config
This id will be used to unplug the device if the user has chosen an id.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
Rob Bradford
1beb62ed2d vmm: vm: Don't panic on kernel load error
Rather than panic()ing when we get a kernel loading error populate the
error upwards.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-16 17:03:25 +02:00
dependabot-preview[bot]
a8ec8f3326 build(deps): bump hermit-abi from 0.1.10 to 0.1.11
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.10 to 0.1.11.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.10...hermit-abi-0.1.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-15 18:27:24 +00:00
dependabot-preview[bot]
6cc8248a37 build(deps): bump num_cpus from 1.12.0 to 1.13.0
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.12.0...v1.13.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-15 18:27:18 +00:00
Rob Bradford
8ff3633782 vm-virtio: pci: Update the BARs used by the VirtioPciDevice
In order to support freeing the memory that is allocated we need to make
sure that we update the internal representation so that free_bars() can
correctly free the memory if the device has its BARs moved.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-15 12:02:19 +02:00
Rob Bradford
56207a0328 pci: Print out details of the BAR moving upon error
In particular include the old and new bases as well as the length.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-15 12:02:19 +02:00
Rob Bradford
a216c2ebd3 vm-virtio: pci: Implement free_bars() for VirtioPciDevice
Implement the free_bars() method from the PciDevice trait which is used
as part of the device removal process. Although there is only one BAR
allocated by VirtioPciDevice simplify the code by using a vector.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-15 12:02:19 +02:00
Rob Bradford
72fdfff15d vmm: device_manager: Remove unused "_mmap_regions" member
Now that ownership of the memory regions used for the virtio-pmem and
vhost-user-fs devices have been moved into those devices it is no longer
necessary to track them inside DeviceManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-14 17:46:11 +01:00
Rob Bradford
70ecd6bab4 vmm, virtio: fs: Move freeing of mappped region into device
Move the release of the managed memory region from the DeviceManager to
the vhost-user-fs device. This ensures that the memory will be freed when
the device is unplugged which will lead to it being Drop()ed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-14 17:46:11 +01:00
Rob Bradford
0c6706a510 vmm, virtio: pmem: Move freeing of mappped region into device
Move the release of the managed memory region from the DeviceManager to
the virtio-pmem device. This ensures that the memory will be freed when
the device is unplugged which will lead to it being Drop()ed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-14 17:46:11 +01:00
Sebastien Boeuf
6565e478e6 vhost_user_net: Enable multithreaded multiqueue support
By implementing queues_per_thread(), this patch fills the last missing
bit to enable multithreaded multiqueue support for the vhost-user-net
backend implementation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
1a0a2c0182 vhost_user_backend: Provide the thread ID to handle_event()
By adding a "thread_id" parameter to handle_event(), the backend crate
can now indicate to the backend implementation which thread triggered
the processing of some events.

This is applied to vhost-user-net backend and allows for simplifying a
lot the code since each thread is identical.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
cfffb7edb0 vhost_user_backend: Allow for one exit_event per thread
By adding the "thread_index" parameter to the function exit_event() from
the VhostUserBackend trait, the backend crate now has the ability to ask
the backend implementation about the exit event related to a specific
thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
b927dceed8 vhost_user_net: Prepare for multithreaded support
In order to prepare for the support of multithreaded multiqueues, the
structure VhostUserNetThread is simplified to hold only one RX queue,
one TX queue, and one TAP interface.

Following this change, VhostUserNetBackend now holds a list of threads
instead of going through each thread to handle multiqueues.

These changes decouple neatly the abstraction between the backend and
each thread. This allows for a lot of simplification since we now know
all threads are identical, hence the handling of events becomes very
straightforward.

One important point is that each thread can be locked when in use,
without causing any contention with other threads since the backend
doesn't need to be locked anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
cd2b03f6ed vhost_user_backend: Return a list of vring workers
Now that multiple worker threads can be run from the backend crate, it
is important that each backend implementation can access every worker
thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
d9eec0de14 vhost_user_backend: Add the ability to start multiple threads
In order to support multiqueues running on multiple threads for
increasing the IO performances, this commit introduces a new function
queues_per_thread() to the VhostUserBackend trait.

This gives each backend implementation the opportunity to define which
queues belong to which thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
40e4dc6339 vhost_user_backend: Change handle_event as immutable
By changing the mutability of this function, after adapting all
backends, we should be able to implement multithreads with
multiqueues support without hitting a bottleneck on the backend
locking.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
8f434df1fb vhost_user: Adapt backends to let handle_event be immutable
Both blk, net and fs backends have been updated to avoid the requirement
of having handle_event(&mut self). This will allow the backend crate to
avoid taking a write lock onto the backend object, which will remove the
potential contention point when multiple threads will be handling
multiqueues.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
Sebastien Boeuf
b1554642e4 vmm: seccomp: Add missing mremap() syscall
While testing self spawned vhost-user backends, it appeared that the
backend was aborting due to a missing system call in the seccomp
filters. mremap() was the culprit and this patch simply adds it to the
whitelist.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-14 14:11:41 +02:00
dependabot-preview[bot]
886c0f9093 build(deps): bump libc from 0.2.68 to 0.2.69
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.68 to 0.2.69.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.68...0.2.69)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-14 09:27:04 +01:00
dependabot-preview[bot]
6c164c761b build(deps): bump thiserror from 1.0.14 to 1.0.15
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.14 to 1.0.15.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.14...1.0.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 08:33:58 +02:00
dependabot-preview[bot]
0071ac8c30 build(deps): bump parking_lot from 0.10.0 to 0.10.2
Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.10.0 to 0.10.2.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.10.0...0.10.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-11 01:25:39 +02:00
dependabot-preview[bot]
2b7fbcb99a build(deps): bump lock_api from 0.3.3 to 0.3.4
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.3.3 to 0.3.4.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.3.3...lock_api-0.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-10 19:20:27 +02:00
dependabot-preview[bot]
d1155c7c7f build(deps): bump parking_lot_core from 0.7.0 to 0.7.1
Bumps [parking_lot_core](https://github.com/Amanieu/parking_lot) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.7.0...0.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-10 19:20:17 +02:00
Rob Bradford
28abfa9de5 vmm: openapi: Mark "initramfs" field nullable
This should make it a pointer in the Go generated code so that it will
be ommitted and thus not populated with an unhelpful default value.

Fixes: #1015

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-09 23:25:18 +02:00
Rob Bradford
c260640fd5 vmm: config: Use Default::default() value for initramfs field
This ensures that the field is filled with None when it is not specified
as part of the deserialisation step.

Fixes: #1015

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-09 17:28:45 +02:00
Alejandro Jimenez
4617aefd60 tests: Test initramfs loading with PVH boot
Add an integration test to verify loading an initramfs using the
PVH boot protocol.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-04-09 17:28:03 +02:00
Alejandro Jimenez
7134f3129f vmm: Allow PVH boot with initramfs
We can now allow guests that specify an initramfs to boot
using the PVH boot protocol.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-04-09 17:28:03 +02:00
Alejandro Jimenez
0fc3936448 arch: Support loading initramfs with PVH boot protocol
Fill and write to guest memory the necessary boot module
structure to allow a guest using the PVH boot protocol
to load an initramfs image.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-04-09 17:28:03 +02:00
dependabot-preview[bot]
b9f193703a build(deps): bump smallvec from 1.2.0 to 1.3.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.2.0 to 1.3.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.2.0...v1.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-09 06:07:36 +00:00
Rob Bradford
2d3f518c72 vmm: config: Error if both socket and path are specified for a disk
This allows the validation of this requirement for both command line
booted VMs and those booted via the API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
eeb7e2529d vmm: config: Move max vCPUs > boot vCPUs check to validate()
This allows the validation of this requirement for both command line
booted VMs and those booted via the API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
12edb24678 vmm: config: Validate that serial/console file mode has a path
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
31928fb103 main: Consistently use eprintln!() for error messages
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
11dd609fa5 main: Only try and parse VM options on VM boot path
As the VmConfig::Parse() also does validation work it only make sense to
parse the VM options on the VM boot path only.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
aaf382eee2 vmm: Move kernel check to VmConfig::validate() method
Replace the existing VmConfig::valid() check with a call into
.validate() as part of earlier config setup or boot API checks.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
3b0da2d895 vmm: vm: Validate configuration on API boot
When performing an API boot validate the configuration. For now only
some very basic validation is performed but in subsequent commits
the validation will be extended.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Rob Bradford
99b2ada4d0 vmm: Start splitting configuration parsing and validation
The configuration comes from a variety of places (commandline, REST API
and restore) however some validation was only happening on the command
line parsing path.  Therefore introduce a new ability to validate the
configuration before proceeding so that this can be used for commandline
and API boots.

For now move just the console and serial output mode validation under
the new validation API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-08 12:06:09 +01:00
Sebastien Boeuf
0ea706faf5 vmm: openapi: Update OpenAPI definition with RestoreConfig
Making sure the OpenAPI definition is up to date with newly added
structure and parameters to support VM restoration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
8d9d22436a vmm: Add "prefault" option when restoring
Now that the restore path uses RestoreConfig structure, we add a new
parameter called "prefault" to it. This will give the user the ability
to populate the pages corresponding to the mapped regions backed by the
snapshotted memory files.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
a517ca23a0 vmm: Move restore parameters into common RestoreConfig structure
The goal here is to move the restore parameters into a dedicated
structure that can be reused from the entire codebase, making the
addition or removal of a parameter easier.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
6712958f23 vmm: memory: Add prefault option when creating region
When CoW can be used, the VM restoration time is reduced, but the pages
are not populated. This can lead to some slowness from the guest when
accessing these pages.

Depending on the use case, we might prefer a slower boot time for better
performances from guest runtime. The way to achieve this is to prefault
the pages in this case, using the MAP_POPULATE flag along with CoW.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
b2cdee80b6 vmm: memory: Restore with Copy-on-Write when possible
This patch extends the previous behavior on the restore codepath.
Instead of copying the memory regions content from the snapshot files
into the new memory regions, the VMM will use the snapshot region files
as the backing files behind each mapped region. This is done in order to
reduce the time for the VM to be restored.

When the source VM has been initially started with a backing file, this
means it has been mapped with the MAP_SHARED flag. For this case, we
cannot use the CoW trick to speed up the VM restore path and we simply
fallback onto the copy of the memory regions content.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
d771223b2f vmm: memory: Extend new() to support external backing files
Whenever a MemoryManager is restored from a snapshot, the memory regions
associated with it might need to directly back the mapped memory for
increased performances. If that's the case, a list of external regions
is provided and the MemoryManager should simply ignore what's coming
from the MemoryConfig.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
ee5a041a0f vmm: memory: Add Copy-on-Write parameter when creating region
Now that we can choose specific mmap flags for the guest RAM, we create
a new parameter "copy_on_write" meaning that the memory mappings backed
by a file should be performed with MAP_PRIVATE instead of MAP_SHARED.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
Sebastien Boeuf
be4e1e8712 vmm: memory: Use fine grained mmap wrapper
In order to anticipate the need for special mmap flags when memory
mapping the guest RAM, we need to switch from from_file() wrapper to
build() wrapper.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-08 10:56:14 +02:00
dependabot-preview[bot]
f0ab002ef1 build(deps): bump openssl-sys from 0.9.54 to 0.9.55
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.54 to 0.9.55.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.54...openssl-sys-v0.9.55)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-08 06:04:24 +00:00
Sebastien Boeuf
b9f9f01fcc vmm: Extend seccomp filters to allow snapshot/restore
A few KVM ioctls were missing in order to perform both snapshot and
restore while keeping seccomp enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-07 12:26:10 +02:00
Sebastien Boeuf
6eb721301c vmm: Enable restore feature
This connects the dots together, making the request from the user reach
the actual implementation for restoring the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-07 12:26:10 +02:00
Sebastien Boeuf
53613319cc vmm: Enable snapshot feature
This connects the dots together, making the request from the user reach
the actual implementation for snapshotting the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
2cd0bc0a2c vmm: Create initial VM from its snapshot
The MemoryManager is somehow a special case, as its restore() function
was not implemented as part of the Snapshottable trait. Instead, and
because restoring memory regions rely both on vm.json and every memory
region snapshot file, the memory manager is restored at creation time.
This makes the restore path slightly different from CpuManager, Vcpu,
DeviceManager and Vm, but achieve the correct restoration of the
MemoryManager along with its memory regions filled with the correct
content.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
b55b83c6e8 vmm: vm: Implement the Transportable trait
This is only implementing the send() function in order to store all Vm
states into a file.

This needs to be extended for live migration, by adding more transport
methods, and also the recv() function must be implemented.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
1ed357cf34 vmm: vm: Implement the Snapshottable trait
By aggregating snapshots from the CpuManager, the MemoryManager and the
DeviceManager, Vm implements the snapshot() function from the
Snapshottable trait.
And by restoring snapshots from the CpuManager, the MemoryManager and
the DeviceManager, Vm implements the restore() function from the
Snapshottable trait.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
20ba271b6c vmm: memory_manager: Implement the Transportable trait
This implements the send() function of the Transportable trait, so that
the guest memory regions can be saved into one file per region.

This will need to be extended for live migration, as it will require
other transport methods and the recv() function will need to be
implemented too.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Yi Sun
e606112cef vmm: memory_manager: Implement the Snapshottable trait
In order to snapshot the content of the guest RAM, the MemoryManager
must implement the Snapshottable trait.

Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-07 12:26:10 +02:00
Yi Sun
50b3f008d1 vmm: cpu: Implement the Snapshottable trait
Implement the Snapshottable trait for Vcpu, and then implements it for
CpuManager. Note that CpuManager goes through the Snapshottable
implementation of Vcpu for every vCPU in order to implement the
Snapshottable trait for itself.

Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Sebastien Boeuf
f787c409c4 vmm: cpu: Factorize vcpu starting code
Anticipating the need for a slightly different function for restoring
vCPUs, this patch factorizes most of the vCPU creation, so that it can
be reused for migration purposes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-07 12:26:10 +02:00
Cathy Zhang
722f9b6628 vmm: cpu: Get and set KVM vCPU state
These two new helpers will be useful to capture a vCPU state and being
able to restore it at a later time.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Cathy Zhang
13756490b5 vmm: cpu: Track all Vcpus through CpuManager
In anticipation for the CpuManager to aggregate all Vcpu snapshots
together, this change makes sure the CpuManager has a handle onto
every vCPU.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
a0d5dbce6c vmm: device_manager: Implement the Snapshottable trait
Based on the list of Migratable devices stored by the DeviceManager, the
DeviceManager can implement the Snapshottable trait by aggregating all
devices snapshots together.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Yi Sun
93d3abfd6e vmm: device_manager: Make serial and ioapic devices migratable
Serial and Ioapic both implement the Migratable trait, hence the
DeviceManager can store them in the list of Migratable devices.

Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-07 12:26:10 +02:00
Samuel Ortiz
12b036a824 Cargo: Update dependencies for the KVM serialization work
We need the project to rely on kvm-bindings and kvm-ioctls branches
which include the serde derive to be able to serialize and deserialize
some KVM structures.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-07 12:26:10 +02:00
Yang Zhong
183529d024 vmm: Cleanup warning from build
Remove unnecessary parentheses from code and this will cleanup
the warning from cargo build.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-04-07 09:45:31 +02:00
Rob Bradford
22958261aa main: Print human readable error for command line error
Fixes: #367

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
c7dfbd8a84 vmm: config: Implement fmt::Display for error
Fixes: #367

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
d8119fda13 vmm: config: Remove unused error entries
These entries are not currently used.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
1a10f16ad0 vmm: config: Consolidate size parsing code
The parse_size helper function can now be consolidated into the
ByteSized FromStr implementation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
f449486b9b vmm: config: Make toggle parsing more tolerant
Support "true" and "false" as well as well as capitalised forms.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
a4e0ce58c7 vmm: config: Consolidate on/off parsing
Now all parsing code makes use of the Toggle and it's FromStr support
move the helper function into the from_str() implementation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
c731a943d4 vmm: config: Port vsock to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
37264cf21b vmm: config: Add unit testing for vsock
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
8665898ff3 vmm: config: Port device parsing to OptionParser
Also make the "path" option required and generate an error if it is not
provided.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
a85e2fa735 vmm: config: Add unit test for VFIO device parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
bed282b801 vmm: config: Add "valueless" options to OptionParser
Valueless options are those like "off" or "tty" as used by the console
options.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
2ae3392d32 vmm: config: Port console parsing to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
143d63c88e vmm: config: Add unit test for console parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
5ab58e743a vmm: config: Port pmem option to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
233ad78b3a vmm: config: Add parsing test for pmem
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
13dc637350 vmm: config: Port filesystem parsing to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
7a071c28db vmm: config: Implement unit testing for virtio-fs parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
e4cd3072d4 vmm: config: Port RNG options to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
708dbb973a vmm: config: Add RNG parsing unit test
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
057e71d266 vmm: config: Accept empty value strings
The integration tests and documentation make use of empty value strings
like "--net tap=" accept them but return None so that the default value
will be used as expected.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
218c780f67 vmm: config: Port network parsing to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
a5747a843e net_util: Implement FromStr for MacAddr
This allows it to be used with str::parse().

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
8754720e2d vmm: config: Add unit test for net parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
224e3ddef4 vmm: config: Switch disk parsing to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
9e10244716 vmm: config: Add unit test for disk parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
e40ae6274b vmm: config: Port memory option parsing to OptionParser
This simplifies the parsing of the option by using OptionParser along
with its automatic conversion behaviour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
be32065aa4 vmm: config: Add "ByteSized" type for simplifying parsing of byte sizes
Byte sizes are quantities ending in "K", "M", "G" and by implementing
this type with a FromStr implementation the values can be converted
using .parse().

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
f01bd7d56d vmm: config: Implement FromStr for HotplugMethod
This allows the use of .parse() to automatically convert the string to
the enum.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
746138039d vmm: config: Add a Toggle type for "on/off" strings
Some of the config parameters take an "on" or "off". Add a way to
neatly parse that.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
929142bc2e vmm: config: Add memory parsing unit test
Before porting over to OptionParser add a unit test to validate the
current memory parsing code. This showed up a bug where the "size=" was
always required. Temporarily resolve this by assigning the string a
default value which will later be replaced when the code is refactored.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
68203ea414 vmm: config: Port CPU parsing to OptionParser
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
9e6a2825ba vmm: config: Add unit test for CPU parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
Rob Bradford
9e7231cd69 vmm: config: Introduce basic OptionParser
This will be used to simplify and consolidate much of the parsing code
used for command line parameters.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-06 10:31:24 +01:00
dependabot-preview[bot]
1e20b5727d build(deps): bump serde_json from 1.0.50 to 1.0.51
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.50 to 1.0.51.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.50...v1.0.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 05:31:07 +00:00
dependabot-preview[bot]
baf4850052 build(deps): bump serde_derive from 1.0.105 to 1.0.106
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.105 to 1.0.106.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.105...v1.0.106)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-04 14:22:07 +00:00
dependabot-preview[bot]
00230905ff build(deps): bump serde from 1.0.105 to 1.0.106
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.105 to 1.0.106.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.105...v1.0.106)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-04 13:58:41 +00:00
Samuel Ortiz
447af8e702 vmm: vm: Factorize the device and cpu managers creation routine
Into a new_from_memory_manager() routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
c73c9b112c vmm: vm: Open kernel and initramfs once all managers are created
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
0646a90626 vmm: cpu: Pass CpusConfig to simplify the new() prototype
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
b584ec3fb3 vmm: memory_manager: Own the system allocator
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
ef2b11ee6c vmm: memory_manager: Pass MemoryConfig to simplify the new() prototype
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
622f3f8fb6 vmm: vm: Avoid ioapic variable creation
For a more readable VM creation routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
164e810069 vmm: cpu: Move CPUID patching to CpuManager
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
1a2c1f9751 vmm: vm: Factorize the KVM setup code
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
3eb11069d0 arch: regs: Rename and export create_msr_entries
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
c3a3490331 arch: regs: Make create_msr_entries more readable
By using simple macros.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Samuel Ortiz
7a50646c02 vmm: device_manager: Convert migratable_devices to a map
We must be able to map a migratable component id to its device.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-03 18:05:18 +01:00
Rob Bradford
8ba37a98a7 .gitignore: Add build directory
This directory contains the source code for crates that we pull in and
should be excluded.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-04-03 15:44:14 +01:00
Yi Sun
b3e4111e1d devices: serial: Implement the Snapshottable trait
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-02 19:02:57 +02:00
Yi Sun
98741573e7 devices: ioapic: Implement the Snapshottable trait
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-02 19:02:57 +02:00
Sebastien Boeuf
3ef1c00cfb ch-remote: Fix snapshot and restore subcommands
So that they are listed and can be used as expected.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 17:55:30 +01:00
Sebastien Boeuf
dc97b67dac main: Fix restore CLI
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 17:55:30 +01:00
Sebastien Boeuf
859a96181f ch-remote: Add --restore option
Introduce restore wrapper to ch-remote.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 13:24:25 +01:00
Sebastien Boeuf
35c0ea6c25 ch-remote: Add --snapshot option
Introduce the snapshot wrapper to ch-remote.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
fe2d884605 main: Support VM restore from the command line
Through the new CLI --restore option.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
8f300bed83 vmm: api: Add a /api/v1/vm.restore endpoint
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
92c73c3b78 vmm: Add a VmRestore command
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
39d4f817f0 vmm: http: Add a /api/v1/vm.snapshot endpoint
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
cf8f8ce93a vmm: api: Add a Snapshot command
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-02 13:24:25 +01:00
Sebastien Boeuf
452475c280 vmm: Add migration helpers
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 13:24:25 +01:00
Samuel Ortiz
1b1a2175ca vm-migration: Define the Snapshottable and Transportable traits
A Snapshottable component can snapshot itself and
provide a MigrationSnapshot payload as a result.

A MigrationSnapshot payload is a map of component IDs to a list of
migration sections (MigrationSection). As component can be made of
several Migratable sub-components (e.g. the DeviceManager and its
device objects), a migration snapshot can be made of multiple snapshot
itself.
A snapshot is a list of migration sections, each section being a
component state snapshot. Having multiple sections allows for easier and
backward compatible migration payload extensions.

Once created, a migratable component snapshot may be transported and this
is what the Transportable trait defines, through 2 methods: send and recv.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2020-04-02 13:24:25 +01:00
Sebastien Boeuf
2d17f4384a vmm: seccomp: Add missing open() syscall
On some systems, the open() system call is used by Cloud-Hypervisor,
that's why it should be part of the seccomp filters whitelist.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-04-02 09:56:48 +02:00
dependabot-preview[bot]
bf135a29f7 build(deps): bump linux-loader from 2adddce to 61d95eb
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `2adddce` to `61d95eb`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](2adddce25b...61d95eb67b)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-02 06:35:44 +00:00
dependabot-preview[bot]
da4aaee778 build(deps): bump vmm-sys-util from 0.4.0 to 0.5.0
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Changelog](https://github.com/rust-vmm/vmm-sys-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vmm-sys-util/compare/v0.4.0...v0.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-01 12:02:19 +00:00
dependabot-preview[bot]
6a934c32ee build(deps): bump proc-macro-hack from 0.5.14 to 0.5.15
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.14 to 0.5.15.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.14...0.5.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-31 15:56:27 +00:00
dependabot-preview[bot]
3b891cd304 build(deps): bump micro_http from e89ed14 to 0d87a94
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `e89ed14` to `0d87a94`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](e89ed14707...0d87a94c8e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-31 07:31:12 +00:00
dependabot-preview[bot]
d5199ad91d build(deps): bump anyhow from 1.0.27 to 1.0.28
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.27 to 1.0.28.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.27...1.0.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-31 06:00:23 +00:00
dependabot-preview[bot]
6a0b4d7a7c build(deps): bump proc-macro2 from 1.0.9 to 1.0.10
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.9...1.0.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 20:59:50 +00:00
dependabot-preview[bot]
31bbe0e509 build(deps): bump hermit-abi from 0.1.9 to 0.1.10
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.9 to 0.1.10.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.9...hermi-abi-0.1.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 06:59:35 +00:00
dependabot-preview[bot]
7f098168ac build(deps): bump hermit-abi from 0.1.8 to 0.1.9
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.8 to 0.1.9.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/compare/hermit-abi-0.1.8...hermit-abi-0.1.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 05:16:35 +00:00
dependabot-preview[bot]
00a1eced55 build(deps): bump thiserror from 1.0.13 to 1.0.14
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.13 to 1.0.14.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.13...1.0.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-29 19:25:57 +00:00
dependabot-preview[bot]
f24b74246d build(deps): bump serde_json from 1.0.48 to 1.0.50
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.48 to 1.0.50.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.48...v1.0.50)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-28 20:33:37 +00:00
Sebastien Boeuf
e4ea8b0bef vmm: Add missing syscalls to the seccomp filters
Both clock_gettime and gettimeofday syscalls where missing when running
Cloud-Hypervisor on a Linux host without vDSO enabled. On a system with
vDSO enabled, the syscalls performed by vDSO were not filtered, that's
why we didn't have to whitelist them.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-27 16:50:52 +00:00
Eryu Guan
33be24bd5a vhost-user-fs: return EINVAL if req is out of range in fs_slave_mmap/unmap/sync
Return libc::EINVAL instead of custom "Wrong offset" error, as mmap(2)
returns EINVAL when offset/len is invalid.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-27 11:27:56 +01:00
Eryu Guan
78b5cbc63a vhost-user-fs: validate fs_slave_map/unmap/sync request
In fs_slave_map/unmap/sync, we only made sure offset < cache_size, but
didn't validate (offset + len). We should ensure [offset, offset+len]
is within cache range as well.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-27 11:27:56 +01:00
Sebastien Boeuf
0c29c2ec49 ci: Extend VFIO test with memory hotplug
One more time, we're extending the VFIO integration test to verify that
a VFIO device passed through a VM is still usable after some new memory
has been hotplugged.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-27 09:35:39 +01:00
Sebastien Boeuf
9e18177654 vmm: Add memory hotplug support to VFIO PCI devices
Extend the update_memory() method from DeviceManager so that VFIO PCI
devices can update their DMA mappings to the physical IOMMU, after a
memory hotplug has been performed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-27 09:35:39 +01:00
Sebastien Boeuf
cc67131ecc vmm: Retrieve new memory region when memory is extended
Whenever the memory is resized, it's important to retrieve the new
region to pass it down to the device manager, this way it can decide
what to do with it.

Also, there's no need to use a boolean as we can instead use an Option
to carry the information about the region. In case of virtio-mem, there
will be no region since the whole memory has been reserved up front by
the VMM at boot. This means only the ACPI hotplug will return a region
and is the only method that requires the memory to be updated from the
device manager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-27 09:35:39 +01:00
Sebastien Boeuf
e4a034aef9 vfio: Add support for memory hotplug
Whenever the guest memory is extended, the IOMMU mappings related to
each VFIO device must be updated. This allows subsequent RAM accesses
to be authorized by the physical IOMMU for the newly added RAM region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-27 09:35:39 +01:00
Samuel Ortiz
8fc7bf2953 vmm: Move to the latest linux-loader
Commit 2adddce2 reorganized the crate for a cleaner multi architecture
(x86_64 and aarch64) support.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-27 08:48:20 +01:00
Sebastien Boeuf
785812d976 vmm: Fallback to legacy boot if PVH is enabled along with initramfs
For now, the codebase does not support booting from initramfs with PVH
boot protocol, therefore we need to fallback to the legacy boot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
5157ba10d1 resources: enable initramfs in kernel config
so that we can use the kernel compiled for the integration tests

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
3b470d4f4b tests: add support for initramfs
the integration test creates an initramfs image based on AlpineLinux mini root filesystem
with a simple /init script that just echoes a string to the console. The string
is passed via the kernel cmdline as an environment variable.

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
6cce7b9560 arch: load initramfs and populate zero page
* load the initramfs File into the guest memory, aligned to page size
* finally setup the initramfs address and its size into the boot params
  (in configure_64bit_boot)

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
1f9bc68c54 openapi: Add initramfs support
added InitramfsConfig property to the REST API spec

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
4db252b418 main, vmm: add --initramfs cli option
currently unused, the initramfs argument is added to the cli,
and stored in vmm::config:VmConfig as an Option(InitramfsConfig(PathBuf))

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Damjan Georgievski
0ce7de3ef5 arch: provide mechanism to get page size
This is a copy of the same code in vm-allocator, until a better place is
found for general use.

Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
2020-03-26 11:59:03 +01:00
Rob Bradford
4b110d5b73 tests: Add integration test for hotplugging network device
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
f3f4d07595 ch-remote: Add support for hotplugging network devices
Call the new HTTP API for hotplugging network devices using the same
syntax as coldplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
c73c31b66e docs: Update API documentation to include "vm.add-net"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
6244beb9d5 openapi: Add "vm.add-net" entry point
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
57c3fa4b1e vmm: Add "add-net" to the API
Add the HTTP and internal API entry points for adding a network device
at runtime.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
f664cddec9 vmm: Add support for adding network devices to the VM
The persistent memory will be hotplugged via DeviceManager and saved in
the config for later use.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
8f323e61d8 vmm: Add support to DeviceManager for hotplugging network devices
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
42a9896fe4 vmm: device_manager: Refactor make_virtio_net_devices
Split it into a method that creates a single device which is called by
the multiple device version so this can be used when dynamically adding
a device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Rob Bradford
9df601a1df bin, vmm: Centralise the net syntax
This will allow the syntax to be reused with cloud-hypervsor binary and
ch-remote.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 17:58:06 +01:00
Samuel Ortiz
41d7b3a387 vmm: memory_manager: Only send the GED notification for the ACPI method
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
15d9ec0149 openapit: Add hotplug_method to MemoryConfig
Add hotplug_method to MemoryConfig in cloud-hypervisor.yaml.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
abbd69abee tests: Add integration test test_virtio_mem
Add integration test test_virtio_mem for virtio-mem.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
4a7a2cff8c tests: Add test for hotplug_size and hotplug_method
Add test for hotplug_size and hotplug_method.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
e63f98182a vmm: device: Add make_virtio_mem_devices
Add make_virtio_mem_devices to add virtio-mem to vmm.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
e6b934a56a vmm: Add support for virtio-mem
This commit adds new option hotplug_method to memory config.
It can set the hotplug method to "acpi" or "virtio-mem".

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Hui Zhu
51d102c708 vm-virtio: Add virtio-mem device
The basic idea of virtio-mem is to provide a flexible, cross-architecture
memory hot plug and hot unplug solution that avoids many limitations
imposed by existing technologies, architectures, and interfaces. More
details can be found in https://lkml.org/lkml/2019/12/12/681.

This commit add virtio-mem device.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-03-25 15:54:16 +01:00
Rob Bradford
8d05fb86e3 tests: Add integration test for hotplugging pmem device
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
0b0510108d ch-remote: Add support for hotplugging persistent memory
Call the new HTTP API for hotplugging persistent memory using the same
syntax as coldplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
44aef8f438 docs: Update API documentation to include "vm.add-pmem"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
75878dd90a openapi: Add "vm.add-pmem" entry point
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
f6f4c68fb4 vmm: Add "add-pmem" to the API
Add the HTTP and internal API entry points for adding persistent memory
at runtime.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
15de30f141 vmm: Add support for adding pmem devices to the VM
The persistent memory will be hotplugged via DeviceManager and saved in
the config for later use.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
f7def621dd vmm: Add support to DeviceManager for hotplugging pmem devices
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
8c3ea8cd76 vmm: device_manager: Refactor make_virtio_pmem_devices
Split it into a method that creates a single device which is called by
the multiple device version so this can be used when dynamically adding
a device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Rob Bradford
a7296bbb52 bin, vmm: Centralise the pmem syntax
This will allow the syntax to be reused with cloud-hypervisor binary and
ch-remote.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 13:18:17 +01:00
Eryu Guan
61e34331c2 virtio-fs: validate request len in fs_slave_io()
We made sure gpa is in cache range, but not the end addr of request,
which is (gpa + len). If the end addr of request is beyond dax cache
window, vmm would corrupt guest memory or crash.

Fix it by making sure end addr of request is within cache range as well.
And while we're at it, return EFAULT if the request is out of range, as
write(2)/read(2) returns EFAULT when buffer is outside accessible
address space.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-25 13:12:26 +01:00
Rob Bradford
4c9d15d44c vmm: Fix copy and paste error message
vm_remove_device was copied from vm_add_device but the error message
wasn't correctly updated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
96d4f1e39e tests: Add integration test for hotplugging disk device
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
05ce2dc820 ch-remote: Add support for hotplugging disks
Call the new HTTP API for hotplugging disks using the same syntax as
disk coldplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
eec1a32d95 docs: Update API documentation to include "vm.add-disk"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
82cad99c0b openapi: Add "vm.add-disk" entry point
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
f2151b2734 vmm: Add "add-disk" to the API
Add the HTTP and internal API entry points for adding disks at runtime.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
164ec2b8e6 vmm: Add support for adding disks to the VM
The disk will be hotplugged via DeviceManager and saved in the config
for later use.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
b3082c1984 vmm: Add support to DeviceManager for hotplugging disks
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
2be703ca92 vmm: device_manager: Refactor make_virtio_block_devices
Split it into a method that creates a single device which is called by
the multiple device version so this can be used when dynamically adding
a device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
Rob Bradford
66da29d8dd bin, vmm: Centralise the disk syntax
This will allow the syntax to be reused with cloud-hypervsor binary and
ch-remote.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-25 09:35:53 +00:00
dependabot-preview[bot]
ede288789a build(deps): bump micro_http from e712d6a to e89ed14
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `e712d6a` to `e89ed14`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](e712d6ae23...e89ed14707)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-25 06:43:09 +00:00
Sebastien Boeuf
c1e6d0022b ci: Add memory resizing use case to vhost-user tests
All vhost-user-blk, vhost-user-net and virtio-fs integration tests are
extended with memory resizing. The point is to validate that we can
hotplug some memory and keep these backends to work as expected.

Just a note that because memory resizing is not supported by mmio, we
limit these extensions to all non-mmio use cases.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
890582b5a2 ci: Factorize kernel command line
The same Clear Linux kernel command line was repeated again and again in
the code. That's why this commit takes care of factorizing it, which
simplifies the code but also simplify maintenance whenever we'd need to
update the block UUID.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
4de258477e ci: Fix mmio tests with direct kernel boot
The hypervisor-fw does not support virtio-blk through mmio transport
layer, therefore we can only run tests with mmio if these tests boot
directly to kernel.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
f2682463a4 ci: Factorize integration tests booting from vhost-user-blk
Remove duplicated code for all boot related tests relying on
vhost-user-blk.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
5a5b3cf23b ci: Factorize vhost-user-blk integration tests
All the non-boot related vhost-user-blk tests are factorized to remove
code duplication.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
dd8debf201 ci: Run vhost-user-blk tests for mmio builds
There's no reason mmio builds cannot support vhost-user-blk, therefore
there's no reason to skip these tests for mmio.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
0c9c72c583 ci: Unify vhost-user-blk integration tests
As a first step towards factorizing as many vhost-user-blk tests as
possible, this patch takes care of unifying their expected output.

It also makes a clear separation between the tests booting from
vhost-user-blk from the ones passing an extra volume.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
c95851f48f ci: Run vhost-user-net tests for mmio transport
No reason to skip vhost-user-net integration tests for the mmio
transport build.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
68293fc0e8 ci: Factorize vhost-user-net one step further
In order to limit code duplication, vhost-user-net integration tests are
further factorized, as they now include the self spawning test.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
d75e7456fc vm-virtio: vhost-user: Send memory update to the backend
In order to keep vhost-user backend to work across guest memory resizing
happening when memory is hot-plugged or hot-unplugged, both blk, net and
fs devices are implementing the notifier to let the backend know.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
7ff82af4b2 vm-virtio: vhost-user: Factorize SET_MEM_TABLE setup
By factorizing the setup of the memory table for vhost-user, we
anticipate the fact that vhost-user devices are going to reuse this
function when the guest memory will be updated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
e54f8ec8a5 vmm: Update memory through DeviceManager
Whenever the VM memory is resized, DeviceManager needs to be notified
so that it can subsequently notify each virtio devices about it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
Sebastien Boeuf
bc874a9b6f vm-virtio: Add update_memory() to VirtioDevice trait
The virtio devices backed by a vhost-user backend must send an update to
the associated backend with the new file descriptors corresponding to
the memory regions.

This patch allows such devices to be notified when such update needs to
happen.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 19:01:15 +00:00
dependabot-preview[bot]
93becca82a build(deps): bump backtrace from 0.3.45 to 0.3.46
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.45 to 0.3.46.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.45...0.3.46)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-24 16:49:27 +00:00
Sebastien Boeuf
feb8d7ae90 vmm: Separate seccomp filters between VMM and API threads
This separates the filters used between the VMM and API threads, so that
we can apply different rules for each thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Sebastien Boeuf
5120c275a2 main: Add seccomp support
This change introduces a new CLI option --seccomp. This allows the user
to enable/disable the seccomp filters when needed. Because the user now
has the possibility to disable the seccomp filters, and because the
Cloud-Hypervisor project wants to enforce the maximum security by
default, the seccomp filters are now applied by default.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Sebastien Boeuf
f1a23d712f vmm: api: Add seccomp to the HTTP API thread
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Sebastien Boeuf
db62cb3f4d vmm: Add seccomp filter to the VMM thread
This commit introduces the application of the seccomp filter to the VMM
thread. The filter is empty for now (SeccompLevel::None).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Sebastien Boeuf
cb98d90097 vmm: Create new seccomp_filter module
Based on the seccomp crate, we create a new vmm module responsible for
creating a seccomp filter that will be applied to the VMM main thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Sebastien Boeuf
708f02dc26 vmm: Pull seccomp crate from Firecracker
The seccomp crate from Firecracker is nicely implemented, documented and
tested, which is a good reason for relying on it to create and apply
seccomp filters.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-24 14:59:57 +01:00
Eryu Guan
18fbd303ab vhost-user-fs: return correct result of fs_slave_io()
Virtio-fs daemon expects fs_slave_io() returns the number of bytes
read/written on success, but we always return 0 and make userspace think
nothing has been read/written.

Fix it by returning the actual bytes read/written. Note that This
depends on the corresponding fix in vhost crate.

Fixes: #949
Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-24 14:55:56 +01:00
Samuel Ortiz
bbc385c3f3 devices: ioapic: Remove unused MsiMessage structure
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-24 12:53:46 +00:00
Samuel Ortiz
2fc86ffea6 dev_cli: Always pull the latest container image
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-23 19:54:40 +01:00
Samuel Ortiz
4b462a54ee Dockerfile: Add cpio and bsdtar to the container image
To be able to build initrd images.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-23 19:54:40 +01:00
Rob Bradford
8acc15a63c build: Bump vm-memory and linux-loader dependencies
linux-loader depends on vm-memory so must be updated at the same time.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-23 14:27:41 +00:00
dependabot-preview[bot]
38ed560d3a build(deps): bump thiserror from 1.0.12 to 1.0.13
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.12 to 1.0.13.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.12...1.0.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-23 07:12:27 +00:00
dependabot-preview[bot]
9f67de4735 build(deps): bump proc-macro-hack from 0.5.12 to 0.5.14
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.12 to 0.5.14.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.12...0.5.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-22 18:40:56 +00:00
dependabot-preview[bot]
ebab8090ee build(deps): bump thiserror from 1.0.11 to 1.0.12
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.11...1.0.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-21 08:38:25 +00:00
dependabot-preview[bot]
c67e407620 build(deps): bump syn from 1.0.16 to 1.0.17
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.16 to 1.0.17.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.16...1.0.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-21 08:38:11 +00:00
Rob Bradford
bdcfe1efbd tests: Add "discard_writes" pmem test
Factorise test_virtio_pmem to test changes are not persisted if file is
readonly.

As virtio-mem is now supported in the upstream kernel we can switch to
using the firmware.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-20 14:46:34 +01:00
Rob Bradford
70986022d8 tests: Make the test_virtio_pmem test use a temporary file
Rather than using a raw OS disk image. This will be useful when the test
is extended to doing I/O on the image.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-20 14:46:34 +01:00
Rob Bradford
f7197e8415 vmm: Add a "discard_writes=" to --pmem
This opens the backing file read-only, makes the pages in the mmap()
read-only and also makes the KVM mapping read-only. The file is also
mapped with MAP_PRIVATE to make the changes local to this process only.

This is functional alternative to having support for making a
virtio-pmem device readonly. Unfortunately there is no concept of
readonly virtio-pmem (or any type of NVDIMM/PMEM) in the Linux kernel so
to be able to have a block device that is appears readonly in the guest
requires significant specification and kernel changes.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-20 14:46:34 +01:00
Rob Bradford
d11a67b0fe vmm: Use more generic MmapRegion constructor
Switch to MmapRegion::build() and fill in the fields appropriately.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-20 14:46:34 +01:00
Rob Bradford
7257e890ef vmm: Add "readonly" parameter MemoryManager::create_userspace_mapping
Use this boolean to turn on the KVM_MEM_READONLY flag to indicate that
this memory mapping should not be writable by the VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-20 14:46:34 +01:00
Samuel Ortiz
03cb26cc70 release: v0.6.0
Expand the release notes and bump Cargo.toml.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-20 12:26:27 +01:00
Samuel Ortiz
3e9a39ca13 github: Upload the ch-remote asset
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-20 12:26:27 +01:00
Qiu Wenbo
c503118d16 vmm: fix a corrupted stack caused by get_win_size
According to `asm-generic/termios.h`, the `struct winsize` should be:

struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;
        unsigned short ws_ypixel;
};

The ioctl of TIOCGWINSZ will trigger a segfault on aarch64.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2020-03-20 07:30:06 +01:00
Rob Bradford
0788600702 build: Remove "pvh_boot" feature flag
This feature is stable and there is no need for this to be behind a
flag. This will also reduce the time needed to run the integration test
as we will not be running them all again under the flag.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-19 13:05:44 +00:00
Rob Bradford
477bc17f18 bin: Share VFIO device syntax between cloud-hypervisor and ch-remote
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-18 23:38:55 +00:00
dependabot-preview[bot]
96be2dbeff build(deps): bump serde_derive from 1.0.104 to 1.0.105
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.104...v1.0.105)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-18 20:49:40 +00:00
dependabot-preview[bot]
5a335fc408 build(deps): bump serde from 1.0.104 to 1.0.105
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.104...v1.0.105)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-18 20:00:16 +00:00
Jose Carlos Venegas Munoz
a31ffef085 openapi: Add hotplug_size for memory hotplug
Add hotplug_size, needed to be defined when hotplug is used.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-03-18 19:06:07 +00:00
Rob Bradford
87990f9e67 vmm: Add virtio-pci device to B/D/F hash table
This table currently contains only all the VFIO devices and it should
really contain all the PCI devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-18 19:05:58 +00:00
Rob Bradford
fb185fa839 vmm: Always return PCI B/D/F from add_virtio_pci_device
Previously this was only returned if the device had an IOMMU mapping and
whether the device should be added to the virtio-iommu. This was already
captured earlier as part of creating the device so use that information
instead.

Always returning the B/D/F is helpful as it facilitates virtio PCI
device hotplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-18 19:05:58 +00:00
dependabot-preview[bot]
462082c52f build(deps): bump arc-swap from 0.4.4 to 0.4.5
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 0.4.4 to 0.4.5.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v0.4.4...v0.4.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-18 19:00:24 +00:00
Sergio Lopez
c821e96e2a vhost_user_fs: Implement support for FUSE_LSEEK
Implement missing support for FUSE_LSEEK, which basically implies
calling to libc::lseek on the file handle. As this operation alters
the file offset, we take a write lock on the File's RwLock.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-18 18:15:28 +00:00
Cathy Zhang
5aa9abca5e docs: Add document for vhost-user-net test with OVS/DPDK
Add a document to illustrate how to test vhost-user-net function with
OpenVSwitch + DPDK as backend.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-03-18 16:43:09 +01:00
Sergio Lopez
6329219749 vm-virtio: queue: Use a SeqCst fence on get_used_event
On x86_64, a hint to the compiler is not enough, we need to issue a
MFENCE instruction. Replace the Acquire fence with a SeqCst one.

Without this, it's still possible to miss an used_event update,
leading to the omission of a notification, possibly stalling the
vring.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-18 13:36:17 +00:00
Samuel Ortiz
63eeed29cc vm: Comment on the VM config update from memory hotplug
I spent a few minutes trying to understand why we were unconditionally
updating the VM config memory size, even if the guest memory resizing
did not happen.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-18 12:48:40 +01:00
dependabot-preview[bot]
0895bcb5dd build(deps): bump proc-macro-hack from 0.5.11 to 0.5.12
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.11 to 0.5.12.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.11...0.5.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-18 08:21:54 +00:00
dependabot-preview[bot]
0541f5aa54 build(deps): bump proc-macro-nested from 0.1.3 to 0.1.4
Bumps [proc-macro-nested](https://github.com/dtolnay/proc-macro-hack) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-17 21:36:51 +00:00
dependabot-preview[bot]
51f51ea17d build(deps): bump libc from 0.2.67 to 0.2.68
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.67 to 0.2.68.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.67...0.2.68)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-17 21:36:38 +00:00
Samuel Ortiz
9cf67d133f arch: x86: Always set the bootloader type
We set it to 0xff, which is for unregistered loaders.
The kernel checks that the bootloader ID is set when e.g. loading
ramdisks, so not setting it when we get a bootparams header from the
loader will prevent the kernel from loading ramdisks.

Fixes: #918

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-17 19:11:38 +01:00
Samuel Ortiz
ad354700c9 arch: x86: Extract common bootparams settings
We're going to add more common settings, so let's avoid duplication
between the 2 branches.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-17 19:11:38 +01:00
Rob Bradford
28a5f9dc19 vmm: acpi: Remove unused IORT related structures
The IORT table for virtio-iommu use was removed and replaced with a
purely virtio based solution. Although the table construction was
removed these structures were left behind.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-17 12:46:26 +00:00
Liu Bo
5c1207c198 vhost-user-fs: handle FS_IO request
Virtiofs's dax window can be used as read/write's source (e.g. mmap a file
on virtiofs), but the dax window area is not shared with vhost-user
backend, i.e. virtiofs daemon.

To make those IO work, addresses of this kind of IO source are routed to
VMM via FS_IO requests to perform a read/write from an fd directly to the
given GPA.

This adds the support of FS_IO request to clh's vhost-user-fs master part.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-03-17 08:23:38 +01:00
dependabot-preview[bot]
f61f78eac6 build(deps): bump anyhow from 1.0.26 to 1.0.27
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.26 to 1.0.27.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.26...1.0.27)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-15 09:03:20 +00:00
Alejandro Jimenez
efb2447801 pvh: Add integration test to validate PVH boot
Add an integration test that builds cloud-hypervisor with
the pvh_boot feature and boots a kernel built with CONFIG_PVH.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
da084fade7 pvh: Add unit tests for initial sregs and control registers
Validate correct GDT entries, initial segment configuration, and control
register bits that are required by PVH boot protocol.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
64941bfcad pvh: Add unit tests for start_info and memory map structures
Expand the unit tests to cover the configure_system() code when
using the PVH boot protocol. Verify the method for adding memory
map table entries in the format specified by PVH boot protocol.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
9e247c4e06 pvh: Introduce "pvh_boot" feature
Use a new feature called "pvh_boot" to enable using the PVH boot
protocol if the guest kernel supports it. The feature can be enabled
by building with:

cargo build [--release] --features "pvh_boot"

Once performance has been evaluated, this can be made part of the
default set of features so that any guest that supports it boots
using PVH as the preferred option as is the case in QEMU.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
a22bc3559f pvh: Write start_info structure to guest memory
Fill the hvm_start_info and related memory map structures as
specified in the PVH boot protocol. Write the data structures
to guest memory at the GPA that will be stored in %rbx when
the guest starts.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
840a9a97ff pvh: Initialize vCPU regs/sregs for PVH boot
Set the initial values of the KVM vCPU registers as specified in
the PVH boot ABI:

https://xenbits.xen.org/docs/unstable/misc/pvh.html

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
24f0e42e6a pvh: Introduce EntryPoint struct
In order to properly initialize the kvm regs/sregs structs for
the guest, the load_kernel() return type must specify which
boot protocol to use with the entry point address it returns.

Make load_kernel() return an EntryPoint struct containing the
required information. This structure will later be used
in the vCPU configuration methods to setup the appropriate
initial conditions for the guest.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Alejandro Jimenez
98b956886e pvh: Add definitions for PVH boot protocol support
Create supporting definitions to use the hvm start info and memory
map table entry struct definitions from the linux-loader crate in
order to enable PVH boot protocol support

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
2020-03-13 18:29:44 +01:00
Rob Bradford
6e6ef8348b build: Fix log dependency
@dependabot bumped the dependency to 0.4.10 but this is no longer a
valid version so downgrade appropriately.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-13 17:27:38 +01:00
dependabot-preview[bot]
291f1cef29 build(deps): bump linux-loader from 0c754f3 to 0ce5bfa
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `0c754f3` to `0ce5bfa`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](0c754f380a...0ce5bfa70d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-13 16:26:50 +00:00
Sergio Lopez
07cc73bddc vhost_user_fs: add a flag to disable extended attributes
Extended attributes (xattr) support has a huge impact on write
performance. The reason for this is that, if enabled, FUSE sends a
setxattr request after each write operation, and due to the inode
locking inside the kernel during said request, the ability to execute
the operations in parallel becomes heavily limited.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-13 15:20:34 +00:00
Sergio Lopez
710520e9a1 vhost_user_fs: Process requests in parallel with a thread pool
This change enables vhost_user_fs to process multiple requests in
parallel by scheduling them into a ThreadPool (from the Futures
crate).

Parallelism on a single file is limited by the nature of the operation
executed on it. A recent commit replaced the Mutex that protects the
File within HandleData with a RwLock, to allow some operations (at
this moment, only "read" and "write") to proceed in parallel by
acquiring a read lock.

A more complex approach was also implemented [1], involving
instrumentation through vhost_user_backend to be able to serialize
completions, reducing the pressure on the vring RwLock. This strategy
improved the performance on some corner cases, while making it worse
on other, more common ones. This fact, in addition to it requiring
wider changes through the source code, prompted me to drop it in favor
of this one.

[1] https://github.com/slp/cloud-hypervisor/tree/vuf_async

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-13 15:20:34 +00:00
Sergio Lopez
90309b5106 vm-virtio: queue: Add methods to switch a descriptor context
"DescriptorChain"s are tied to the lifetime of the referenced
GuestMemoryMmap object (for good reasons), but sometimes (i.e., when
processing descriptors from different contexts) we may need to switch
them to point a different GuestMemoryMmap.

Here we introduce the structure DescriptorHead, which holds the data
needed to rebuild a DescriptorChain, the method "get_head" which
returns the DescriptorHead for a DescriptorChain, and the method
"new_from_head", which allows to create a new DescriptorChain with a
DescriptorHead and a new reference to a GuestMemoryMmap.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-13 15:20:34 +00:00
Sergio Lopez
2294c2d2c9 Add .rustfmt.toml to the project
For rustfmt to accept modern syntax like "async move", a .rustfmt.toml
with "edition = 2018" needs to be created.

https://github.com/rust-lang/rustfmt/issues/3149

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-13 15:20:34 +00:00
Sergio Lopez
48c4885b47 vhost_user_fs: replace HandleData's File Mutex with RwLock
Replace HandleData's File Mutex with a RwLock to have more granularity
on the lock. This allows operations on the same File that are safe to
be run in parallel (at this moment, read and write), to acquire a read
lock to avoid waiting on each other.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-13 15:20:34 +00:00
Samuel Ortiz
134e64c612 arch, qcow: Fix 1.42.0 clippy warnings
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-13 12:26:15 +00:00
Samuel Ortiz
6ea85ca86c resources: Dockerfile: Update Rust toolchain
To the latest stable version: 1.42.0

Fixes: #909

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-13 12:26:15 +00:00
Rob Bradford
4579afa091 vmm: For --disk error if socket and path is specified
This is an error as the path should be specfied by the unmanaged
backend.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-13 11:41:52 +00:00
Rob Bradford
7e599b4450 vmm: Make disk path optional
When using "--disk" with a vhost socket and not using self spawning then
it is not necessary or helpful to specify the path.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-13 11:41:52 +00:00
Samuel Ortiz
477d924528 github: Build from a rust toolchain matrix
So that we can run our builds against several toolchains (beta, stable,
nightly).

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-13 11:41:34 +00:00
Rob Bradford
4f2469e054 main: Remove "--vhost-user-net"
This option was superseded by using "--net" with "vhost_user=true". This
option wasn't being parsed any more but was left over.

Fixes: #806

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-13 11:00:43 +00:00
Sebastien Boeuf
8d785bbd5f pci: Fix the PciBus using HashMap instead of Vec
By using a Vec to hold the list of devices on the PciBus, there's a
problem when we use unplug. Indeed, the vector of devices gets reduced
and if the unplugged device was not the last one from the list, every
other device after this one is shifted on the bus.

To solve this problem, a HashMap is used. This allows to keep track of
the exact place where each device stands on the bus.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-13 10:54:34 +01:00
dependabot-preview[bot]
04f2ccd16d build(deps): bump ryu from 1.0.2 to 1.0.3
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.2 to 1.0.3.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.2...1.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-13 08:44:41 +00:00
dependabot-preview[bot]
02265bb589 build(deps): bump regex-syntax from 0.6.16 to 0.6.17
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.16 to 0.6.17.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-13 08:14:13 +00:00
Jose Carlos Venegas Munoz
40b38a4222 openapi: Make desired_ram int64 format
The option desired_ram is in byte, make larger the amount of memory to
add.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-03-12 23:17:56 +01:00
Rob Bradford
ca3b39c0be bin: Fix wrapping in help strings
Some of the help strings had extra newlines in them or otherwise strange
wrapping. The strings were rewrapped with the nightly version of rustfmt
that supports string formatting.

Fixes: #899

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 18:03:18 +00:00
Rob Bradford
ee1ba56cfe build: Use "wrap_help" feature for clap
This prevents the output being wrapped at 120 characters and giving
strange results.

Fixes: #899

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 18:03:18 +00:00
Sergio Lopez
3957d1ee27 vhost_user_backend: call get_used_event from needs_notification
This change, combined with the compiler hint to inline get_used_event,
shortens the window between the memory read and the actual check by
calling get_used_event from needs_notification.

Without it, when putting enough pressure on the vring, it's possible
that a notification is wrongly omitted, causing the queue to stall.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-12 14:34:21 +00:00
Sergio Lopez
536323d9fb vm-virtio: queue: hint that get_used_event should be inlined
get_used_event is used from vhost_user_backend:needs_notification to
check whether an interrupt must be sent to the guest to notify there
are new items in the queue. Shorten the update window by asking the
the compiler to inline this method, so a write won't slip between the
read of the memory contents and the actual check.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-12 14:34:21 +00:00
Sergio Lopez
401e1d2489 vm-virtio: queue: fix a barrier comment at update_avail_event
The barrier had a comment coming from other context. Adjust it to be
relevant to its own context.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-12 14:34:21 +00:00
Sergio Lopez
e0bdfe826e vm-virtio: queue: add a missing memory barrier in get_used_event
Add a missing memory barrier in get_used_event to make sure we see the
last value written by the guest.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-03-12 14:34:21 +00:00
Sebastien Boeuf
df2570a472 resources: Simplify kernel config filename
Since we only keep one single version of the kernel config file in our
repository, there is no reason to keep the filename complex.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-12 14:07:11 +01:00
Sebastien Boeuf
9ab648b8f7 resources: Enable VIRTIO_MEM support
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-12 14:07:11 +01:00
Sebastien Boeuf
03398532dc ci: Bump to kernel 5.6-rc4
The kernel version is updated from 5.5-rc1 to 5.6-rc4, including the
updated kernel config file.

The kernel branch contains virtio-fs, virtio-iommu and virtio-mem
patches that are not upstream yet. It also contains one fix for
virtio-vsock which will be merged upstream in the next release.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-12 14:07:11 +01:00
Rob Bradford
abccf766ce tests: Use ch-remote to add/remove devices in test_vfio
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 12:56:10 +01:00
Rob Bradford
5c3ce9dd00 tests: Extend ch-remote helper to support optional single argument
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 12:56:10 +01:00
Rob Bradford
9a7d9c9465 ch-remote: Support removing VFIO devices
Add a "remove-device" command that allows removing VFIO devices from the
VM after boot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 12:56:10 +01:00
Rob Bradford
0d53ba4395 ch-remote: Support adding VFIO devices
Add an "add-device" command that allows adding VFIO devices to the VM
after boot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 12:56:10 +01:00
Rob Bradford
babefbd9bf main: Remove spurious second help line for "--device"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-12 12:56:10 +01:00
Samuel Ortiz
63c5d09537 github: Trigger the build job on PRs
And not on pushes only.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-12 11:27:43 +01:00
Samuel Ortiz
8cbb6d0faf github: Replace Travis CI with github actions
We define 1 workflow with 2 jobs: One for the regular build and another
one for creating a release and uploading the corresponding assets.
They both run conditionally, depending on the gihtub event that triggered
the action.

Fixes: #825

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-12 09:18:01 +01:00
Sebastien Boeuf
efba48dddb vmm: Don't put a VFIO device behind the vIOMMU by default
With some of the factorization that happened to be able to support VFIO
hotplug, one mistake was made. In case a vIOMMU is created through a
virtio-iommu device, and no matter the "iommu" option value from the
VFIO device parameter, the VFIO device was always placed behind the
virtual IOMMU.

This commit fixes this wrong behavior by making sure the device
configuration is taken into account to decide if it should be attached
or not to the virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 19:50:31 +01:00
Sebastien Boeuf
34412c9b41 vmm: Add id option to VFIO hotplug
Add a new id option to the VFIO hotplug command so that it matches the
VFIO coldplug semantic.

This is done by refactoring the existing code for VFIO hotplug, where
VmAddDeviceData structure is replaced by DeviceConfig. This structure is
the one used whenever a VFIO device is coldplugged, which is why it
makes sense to reuse it for the hotplug codepath.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 19:50:31 +01:00
Samuel Ortiz
18dc916380 vmm: Switch to the micro-http package
It's been extracted from the Firecracker code base.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-03-11 17:38:01 +01:00
Sebastien Boeuf
9023444ad3 vmm: Add id field to --device through CLI
Add the ability to specify the "id" associated with a device, by adding
an extra option to the parameter --device.

This new option is not mandatory, and by default, the VMM will take care
of finding a unique identifier.

If the identifier provided by the user through this new option is not
unique, an error will be thrown and the VM won't be started.

Fixes #881

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:57 +00:00
Sebastien Boeuf
f4a956a60a vmm: Remove 32 bits MMIO range from correct address space
The 32 bits MMIO address space is handled separately from the 64 bits
one. For this reason, we need to invoke the appropriate freeing function
to remove a range from this address space.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Sebastien Boeuf
432eb5b70a vmm: Free PCI BARs when unplugging PCI device
Now that PciDevice trait has a dedicated function to remove the bars,
the DeviceManager can invoke this function whenever a PCI device is
unplugged from the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Sebastien Boeuf
f0dff8b58c vfio: pci: Remove KVM user memory region when cleaning up
Whenever a VfioPciDevice is dropped, the regions previously mapped are
being unmapped. But there's also a need for removing the region from a
KVM perspective.

This commit extends the existing unmap_mmio_regions() function to take
care of removing the KVM region at the same time the regions are being
unmapped.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Sebastien Boeuf
34d1f435f4 vfio: pci: Implement free_bars() from the PciDevice trait
In order to provide the tools for a complete cleanup whenever a VFIO PCI
device is removed from the VM, the VfioPciDevice implements free_bars()
method from PciDevice trait. This will take care of removing the IO and
MMIO ranges previously reserved through the vm-allocator.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Sebastien Boeuf
b8e1cf2d4e vm-allocator: Add new function to free 32 bits MMIO address space
The allocator already had functions to allocate and free both IO and 64
bits MMIO address spaces, but it only had an allocating function for 32
bits MMIO address space.

With this new function, it will be now possible to remove cleanly some
ranges from the 32 bits MMIO address space.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Sebastien Boeuf
f3dc245c4f pci: Extend PciDevice trait with new free_bars() method
The point of this new method is to let the caller decide when the
implementation of the PciDevice should free the BARs previously
allocated through the other method allocate_bars().

This provides a way to perform proper cleanup for any PCI device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-11 13:10:30 +00:00
Rob Bradford
911a2d61d7 tests: Use ch-remote to resize the VM
Remove manually constructed API request in the integration tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-11 08:22:09 +01:00
Rob Bradford
21160f7490 ch-remote: Add "resize" command
This command lets you change the number of vCPUs and RAM that the VM
has.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-11 08:22:09 +01:00
Rob Bradford
bb2d04b39d ch-remote: Add support for sending a request body
Support sending a request body this will usually be JSON encoded data
representing the details of the request.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-11 08:22:09 +01:00
Rob Bradford
bde4f735ab ch-remote: Refactor HTTP response handling
Extract HTTP response handling into its own function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-11 08:22:09 +01:00
dependabot-preview[bot]
6ed23bb3ab build(deps): bump micro_http from 9bbde4f to 6b3e5f0
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `9bbde4f` to `6b3e5f0`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](9bbde4fb6a...6b3e5f0a18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-11 07:15:40 +00:00
dependabot-preview[bot]
5edd812792 build(deps): bump backtrace-sys from 0.1.33 to 0.1.34
Bumps [backtrace-sys](https://github.com/alexcrichton/backtrace-rs) from 0.1.33 to 0.1.34.
- [Release notes](https://github.com/alexcrichton/backtrace-rs/releases)
- [Commits](https://github.com/alexcrichton/backtrace-rs/compare/backtrace-sys-0.1.33...backtrace-sys-0.1.34)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-11 07:15:28 +00:00
Sebastien Boeuf
f7277140bb ci: Add integration test for VFIO hot-unplug
Extend the existing test_vfio by unplugging the previously hotplugged
device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
b50cbe5064 pci: Give PCI device ID back when removing a device
Upon removal of a PCI device, make sure we don't hold onto the device ID
as it could be reused for another device later.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
df71aaee3f pci: Make the device ID allocation smarter
In order to handle the case where devices are very often plugged and
unplugged from a VM, we need to handle the PCI device ID allocation
better.

Any PCI device could be removed, which means we cannot simply rely on
the vector size to give the next available PCI device ID.

That's why this patch stores in memory the information about the 32
slots availability. Based on this information, whenever a new slot is
needed, the code can correctly provide an available ID, or simply return
an error because all slots are taken.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
e514b124ed vmm: Update VmConfig when removing VFIO device
This commit ensures that when a VFIO device is hot-unplugged from the
VM, it is also removed from the VmConfig. This prevents a potential
reboot from creating the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
81173bf4ab vmm: Add id field to DeviceConfig structure
Add a new field to the DeviceConfig, allowing the VMM to allocate a name
to the VFIO devices.

By identifying a VFIO device with a unique name, we can make sure a user
can properly unplug it at any time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
6cbdb9aa47 vmm: api: Introduce new "remove-device" HTTP endpoint
This commit introduces the new command "remove-device" that will let a
user hot-unplug a VFIO PCI device from an already running VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
991f3bb5da vmm: Remove VFIO device from everywhere it is referenced
This commit implements the eject function so that a VFIO device will be
removed from any bus it might sit on, and from any list it might be
stored in.

The idea is to reach a point where there is no reference of the device
anywhere in the code, so that the Drop implementation will be invoked
and so that the device will be fully removed from the VMM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
6adebbc6a0 vmm: Detect when guest notifies about ejecting PCI device
When the guest OS is done removing a PCI device, it will invoke the _EJ0
method from ACPI, associated with the device. This will trigger a port
IO write to a region known by the VMM. Upon this writing, the VMM will
trap the VM exit and retrieve the written value.

Based on the value, the VMM will invoke its eject_device() method to
finalize the removal of the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
0e21c32c0b devices: Add new method to remove all occurrences of a BusDevice
The same BusDevice can be inserted multiple times on the same bus at
different ranges. This is the case for a PCI device with multiple memory
BARs for example, as each BAR will be inserted at a specific MMIO range.

This new method allows to find and remove every occurence of the same
device so that we can make sure it is fully removed from the bus.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
f8e2008e0e pci: Add a function to remove a PciDevice from the bus
Simple function relying on the retain() method from std::Vec, allowing
to remove every occurence of the same device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
08604ac6a8 vmm: Store PCI devices as Any devices from DeviceManager
As we try to keep track of every PCI device related to the VM, we don't
want to have separate lists depending on the concrete type associated
with the PciDevice trait. Also, we want to be able to cast the actual
type into any trait or concrete type.

The most efficient way to solve all these issues is to store every
device as an Arc<dyn Any + Send + Sync>. This gives the ability to
downcast into the appropriate concrete type, and then to cast back into
any trait that we might need.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
Sebastien Boeuf
0f99d3f7cc vmm: Store VFIO device's name and its PCI b/d/f
Add a new list storing the device names across the entire codebase. VFIO
devices are added to the list whenever a new one is created. By default,
each VFIO device is given a name "vfioX" where X is the first available
integer.

Along with this new list of names, another list is created, grouping PCI
device's name with its associated b/d/f. This will be useful to keep
track of the created devices so that we can implement unplug
functionality.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-10 17:05:06 +00:00
dependabot-preview[bot]
13a61c4784 build(deps): bump rand_chacha from 0.2.1 to 0.2.2
Bumps [rand_chacha](https://github.com/rust-random/rand) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_chacha-0.2.1...rand_chacha-0.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-10 11:20:29 +00:00
dependabot-preview[bot]
fcd605a227 build(deps): bump micro_http from 6d416af to 9bbde4f
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `6d416af` to `9bbde4f`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](6d416afe10...9bbde4fb6a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-10 07:12:00 +00:00
Rob Bradford
30b69549e1 vm-virtio: Consume pause events to prevent infinite epoll_wait calls
When a virtio device is paused an event is written to the appropriate
"pause" EventFd for the device. This will be noticed by the the device's
epoll_wait(), an atomic bool checked an if true then the thread is
parked(). When resuming the bool is reset and the thread is unpark()ed.
However the event triggering the pause is still in the EventFd so the
epoll_wait() will continue to return but because the boolean is not set
the thread will not be park()ed but instead we will busy loop around an
event that is not being consumed.

The solution is to drain the "pause" EventFd when the event is first
received and thus the epoll_wait() will only return for the pause event
once. This resolves the infinite epoll_wait() wake-ups.

Fixes: #869

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-09 19:01:38 +01:00
Rob Bradford
16fd506bb8 tests: Use new ch-remote for pause/resume integration test
Replace the use of a manual curl command with the new ch-remote tool.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-09 15:03:01 +00:00
Rob Bradford
ba8cd4d55a bin: Introduce "ch-remote" for controlling VMM
This commit introduces a basic implementation of a remote control of a
running VMM implementing a subset of the API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-09 15:03:01 +00:00
dependabot-preview[bot]
06cd31cb2e build(deps): bump micro_http from 02def92 to 6d416af
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `02def92` to `6d416af`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](02def92b33...6d416afe10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 11:03:07 +00:00
dependabot-preview[bot]
7e941c9ecd build(deps): bump linux-loader from 8cb7c66 to 0c754f3
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `8cb7c66` to `0c754f3`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](8cb7c6621b...0c754f380a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 07:52:31 +00:00
Jose Carlos Venegas Munoz
df794993f8 net: Do not check multiqueue for new interface
If tun_flags file does not exist, check should not be fatal.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-03-05 19:21:06 +00:00
dependabot-preview[bot]
7d75b1f938 build(deps): bump quote from 1.0.2 to 1.0.3
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.2 to 1.0.3.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.2...1.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 19:05:49 +00:00
dependabot-preview[bot]
841bf89639 build(deps): bump failure from 0.1.6 to 0.1.7
Bumps [failure](https://github.com/rust-lang-nursery/failure) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/rust-lang-nursery/failure/releases)
- [Changelog](https://github.com/rust-lang-nursery/failure/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-lang-nursery/failure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 18:30:35 +00:00
dependabot-preview[bot]
86acdb9a12 build(deps): bump failure_derive from 0.1.6 to 0.1.7
Bumps [failure_derive](https://github.com/rust-lang-nursery/failure) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/rust-lang-nursery/failure/releases)
- [Changelog](https://github.com/rust-lang-nursery/failure/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-lang-nursery/failure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 16:52:13 +00:00
Sebastien Boeuf
4b328631b9 docs: Update api.md for VFIO hotplug
Adding the missing entry for "add-device" in the API documentation.

Fixes #863

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-05 16:41:26 +00:00
Rob Bradford
e518098688 scripts: Make integration tests fail if some important commands fail
As it's not possible to use "set -e" explicitly mark the important
commands with "|| exit 1"

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-05 16:37:52 +01:00
Cathy Zhang
be6f91d0d1 tests: Refactoring vhost_user_net test cases
Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-03-05 15:09:20 +00:00
Cathy Zhang
6341736286 vhost_user_net: Provide tap option for vhost_user_net backend
Provide vhost_user_net backend with the tap option, it allows to
use the existing tap interface.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-03-05 15:09:20 +00:00
Rob Bradford
e0419e988b build: Don't cancel older master builds
If a new build request for master comes in don't cancel the older
builds. Cancelling older builds is very useful for PRs that are being
updated but less so for a build of the master branch that has been
triggered via a merge or a periodic build.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-05 12:08:33 +01:00
Rob Bradford
f0a3e7c4a1 build: Bump linux-loader and vm-memory dependencies
linux-loader now uses the released vm-memory so we must move to that
version at the same time.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-05 11:01:30 +01:00
Jose Carlos Venegas Munoz
6539d4a873 vfio: handle case for missing iommu_group
For cases where IOMMU is not supported, iommu_group will be no present.

This could happened because IOMMU is off at kernel level, bios level or
is not supported at all.

Instead of fail with a generic error handle it as different use case:

Before:
ReadLink(Os { code: 2, kind: NotFound, message: "No such file or directory"})

After:
VfioNoIommuGroup("/sys/bus/pci/devices/0000:03:00.0/iommu_group")

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2020-03-05 09:49:32 +00:00
dependabot-preview[bot]
cfbebd8852 build(deps): bump micro_http from 88011bd to 02def92
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `88011bd` to `02def92`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](88011bd64f...02def92b33)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-05 07:38:35 +00:00
Rob Bradford
42148063ec tests: Remove further use of sudo subshells
Replace sudo invocations of bash creating a subshell with simpler
solutions by running the program directly on the input or using tee.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 20:54:46 +01:00
Rob Bradford
2baf5ab80d tests: Simplfy the shm region check
There is no need to spawn a subshell in this case as grep can open the
file directly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 20:54:46 +01:00
Rob Bradford
97affbebfe tests: Re-enable the virtio-fs tests and make them work with virtio-mmio
As part of bringing the tests up with virtio-mmio the virtio-fs were
wrongly disabled. Re-enable them and remove the cache size check as the
cache does not appear in /proc/iomem on virtio-mmio.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 20:54:46 +01:00
Rob Bradford
7b1d5c1ad9 tests: Remove entropy check from vhost-user-block test
When booting from vhost-user-block the entropy is sometimes lower
triggering a flaky test. We have already use other, more reliable
methods for checking that the VM has booted.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 20:54:46 +01:00
Rob Bradford
a4cca5f60a tests: sha1sums --check can take a list of hashes
There is no need to cat the file in as input and instead the the program
will load from disk.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 20:54:46 +01:00
dependabot-preview[bot]
689415e5ff build(deps): bump libssh2-sys from 0.2.15 to 0.2.16
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.15 to 0.2.16.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.15...libssh2-sys-0.2.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-04 18:42:47 +00:00
Sebastien Boeuf
09829c44b2 vmm: Remove IO bus strong reference from Vm
The Vm structure was used to store a strong reference to the IO bus.
This is not needed anymore since the AddressManager is logically the
one holding this strong reference. This has been made possible by the
introduction of Weak references on the Bus structure itself.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
2dbb376175 vmm: Remove all Weak references from DeviceManager
Now that the BusDevice devices are stored as Weak references by the
IO and MMIO buses, there's no need to use Weak references from the
DeviceManager anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
9e915a0284 vmm: Remove all Weak references from CpuManager
Now that the BusDevice devices are stored as Weak references by the
IO and MMIO buses, there's no need to use Weak references from the
CpuManager anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
49268bff3b pci: Remove all Weak references from PciBus
Now that the BusDevice devices are stored as Weak references by the IO
and MMIO buses, there's no need to use Weak references from the PciBus
anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
ca426cfdf4 devices: Make Bus hold a list of Weak BusDevice references
By storing a list of Weak references to BusDevice devices, the Bus
structure prevents potential cyclic dependencies from happening on
strong references.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
7773812f58 vmm: Store the list of BusDevice devices from DeviceManager
The point is to make sure the DeviceManager holds a strong reference of
each BusDevice inserted on the IO and MMIO buses. This will allow these
buses to hold Weak references onto the BusDevice devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
d0820cc026 vmm: Make add_vfio_device mutable
The method add_vfio_device() from the DeviceManager needs to be mutable
if we want later to be able to update some internal fields from the
DeviceManager from this same function.

This commit simply takes care of making the necessary changes to change
this function as mutable.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
Sebastien Boeuf
948f808da6 vm: Rename DeviceManager field in Vm structure
It's more logical to name the field referring to the DeviceManager as
"device_manager" instead of "devices".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 18:46:44 +01:00
dependabot-preview[bot]
aa638ead42 build(deps): bump backtrace from 0.3.44 to 0.3.45
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.44 to 0.3.45.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.44...0.3.45)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-04 15:33:46 +00:00
Sebastien Boeuf
1152b1a147 ci: Add VFIO hotplug integration test
This commit extends the existing test_vfio by hotplugging an extra
virtio-net device to the L2 VM. The test for validating the hotplug
succeeded is the same as the one to verify the non-hotplugged devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
d47f733e51 vmm: Break the cyclic dependency between DeviceManager and IO bus
By inserting the DeviceManager on the IO bus, we introduced some cyclic
dependency:

  DeviceManager ---> AddressManager ---> Bus ---> BusDevice
        ^                                             |
        |                                             |
        +---------------------------------------------+

This cycle needs to be broken by inserting a Weak reference instead of
an Arc (considered as a strong reference).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
c1af13efeb vmm: Update VmConfig when adding new device
Ensures the configuration is updated after a new device has been
hotplugged. In the event of a reboot, this means the new VM will be
started with the new device that had been previously hotplugged.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
a86f4369a7 vmm: Add VFIO PCI device hotplug support
This commit finalizes the VFIO PCI hotplug support, based on all the
previous commits preparing for it.

One thing to notice, this does not support vIOMMU yet. This means we can
hotplug VFIO PCI devices, but we cannot attach them to an existing or a
new virtio-iommu device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
320fea0eaf vmm: Factorize VFIO PCI device creation
This factorization is very important as it will allow both the standard
codepath and the VFIO PCI hotplug codepath to rely on the same function
to perform the addition of a new VFIO PCI device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
00716f90a0 vmm: Store virtio-iommu device from DeviceManager
Helps with future refactoring of VFIO device creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
5902dfa403 vmm: Store VFIO KVM device from DeviceManager
Helps with future refactoring of VFIO device creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
d9c1b4396e vmm: Store MSI InterruptManager from DeviceManager
Helps with future refactoring of VFIO device creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
02adc4061a vmm: Store PciBus from DeviceManager
Helps with future refactoring of VFIO device creation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
3f396d87ef resources: Enable ACPI PCI hotplug in the kernel config
The PCI hotplug through ACPI was not enabled by default.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
d0218e94a3 vmm: Trigger hotplug notification to the guest
Whenever the user wants to hotplug a new VFIO PCI device, the VMM will
have to trigger a hotplug notification through the GED device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
0e58741a09 vmm: api: Introduce new "add-device" HTTP endpoint
This commit introduces the new command "add-device" that will let a user
hotplug a VFIO PCI device to an already running VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
0f1396acef vmm: Insert PCI device hotplug operation region on IO bus
Through the BusDevice implementation from the DeviceManager, and by
inserting the DeviceManager on the IO bus for a specific IO port range,
the VMM now has the ability to handle PCI device hotplug.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
65774e8a78 vmm: Implement BusDevice for DeviceManager
In anticipation of inserting the DeviceManager on the IO/MMIO buses,
the DeviceManager must implement the BusDevice trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
2eb26d4de4 devices: acpi: Update GED to support PCI devices hotplug
Expands the existing GED device description in the DSDT table. A new
case of hotplug notification is being added to the already existing CPU
and memory hotplug. The third case of hotplug being the addition/removal
of a PCI device, it is identified through the flag 0x4.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
8dbc84318c vmm: acpi: Add PCNT method to invoke DVNT
Create a small method that will perform both hotplug of all the devices
identified by PCIU bitmap, and then perform the hotunplug of all the
devices identified by the PCID bitmap.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
c62db97a81 vmm: acpi: Add _EJ0 to each PCI device slot
The _EJ0 method provides the guest OS a way to notify the VMM that the
device has been properly ejected from the guest OS. Only after this
point, the VMM can fully remove the device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
4dc2a39f3a vmm: acpi: Create PHPR container
This new PHPR device in the DSDT table introduces some specific
operation regions and the associated fields.

PCIU stands for "PCI up", which identifies PCI devices that must be
added.
PCID stands for "PCI down", which identifies PCI devices that must be
removed.
B0EJ stands for "Bus 0 eject", which identifies which device on the bus
has been ejected by the guest OS.

Thanks to these fields, the VMM and the guest OS can communicate while
performing hotplug/hotunplug operations.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
c3a0685e2d vmm: acpi: Add notification method for PCI device slots
Adds the DVNT method to the PCI0 device in the DSDT table. This new
method is responsible for checking each slot and notify the guest OS if
one of the slots is supposed to be added or removed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
Sebastien Boeuf
5a68d5b6a7 vmm: acpi: Create PCI device slots
This commit introduces the ACPI support for describing the 32 device
slots attached to the main PCI host bridge.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 12:06:02 +00:00
dependabot-preview[bot]
ead86bb1e4 build(deps): bump micro_http from 9945928 to 88011bd
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `9945928` to `88011bd`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](9945928e28...88011bd64f)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-04 08:46:55 +00:00
Rob Bradford
22dd49d0b5 tests: Test virtio-fs with virtio-mmio
Now that virtio-mmio transport has support for SHM regions we should be
able to test virtio-fs against it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 09:40:25 +01:00
Rob Bradford
642b890b0f vm-virtio: mmio: Enable reporting of SHM regions via config fields
The details of the SHM regions or the lack of, which is used by
virtio-fs DAX, is communicated through configuration fields on the
virtio-mmio memory region. Implement the necessary fields to return the
SHM entries and in particular return a length of (u64)-1 which is used
by the kernel to indicate there are no SHM regions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-03-04 09:40:25 +01:00
Sebastien Boeuf
0223cf8c2b ci: Update ClearLinux image
A new ClearLinux image has been uploaded to the Azure storage account.
It is based off of the ClearLinux cloudguest image 31310 version, with
three extra bundles added to it.

First bundle is curl, which adds the curl binary to the image, second
bundle is iperf, adding the iperf binary to the image, and third bundle
is sysadmin-basic to include utility like netcat.

The image is 2G in size.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-03-04 07:31:15 +00:00
dependabot-preview[bot]
ed396b4d58 build(deps): bump vm-memory from 2099f41 to a84a7b8
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `2099f41` to `a84a7b8`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](2099f4162f...a84a7b8f53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-03 13:44:47 +00:00
Eryu Guan
81c2294c11 vhost_rs: remove unused crate
As we switched to external vhost_rs crate, delete this internal one.
All vhost changes should go to cloud-hypervisor/vhost.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-03 13:14:45 +00:00
Eryu Guan
5200bf3c59 Cargo: switch vhost_rs to external crate
As cloud-hypervisor/vhost crate (dragonball branch) is ready to be used,
switch vhost_rs from internal crate to the external one.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-03-03 13:14:45 +00:00
Arron Wang
65a38e6f70 vm-virtio: vhost_user: Fix blk device configuration space offset value
Current device configuration space offset value is 0, we need to
update that value to VHOST_USER_CONFIG_OFFSET(0x100) to follow the spec

Fixes #844

Signed-off-by: Arron Wang <arron.wang@intel.com>
2020-03-03 12:27:55 +00:00
Bin Liu
d6e6901957 vmm/api: Fix vm.info response definition
Update cloud-hypervisor.yaml with latest code.

Fixes: #841

Signed-off-by: liubin <liubin0329@gmail.com>
2020-03-03 09:34:25 +01:00
dependabot-preview[bot]
8f3720089f build(deps): bump micro_http from 3eb926c to 9945928
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `3eb926c` to `9945928`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](3eb926ccf4...9945928e28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-03 07:15:28 +00:00
dependabot-preview[bot]
cc2d03d29f build(deps): bump regex-syntax from 0.6.15 to 0.6.16
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.15 to 0.6.16.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-syntax-0.6.15...regex-syntax-0.6.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-03 07:15:15 +00:00
dependabot-preview[bot]
f5b37e3444 build(deps): bump regex-syntax from 0.6.14 to 0.6.15
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.14 to 0.6.15.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/commits/regex-syntax-0.6.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-02 12:59:16 +00:00
dependabot-preview[bot]
009f4d23d0 build(deps): bump micro_http from 8d48e73 to 3eb926c
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `8d48e73` to `3eb926c`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](8d48e730f2...3eb926ccf4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-28 07:51:33 +00:00
Rob Bradford
5ade9d4610 tests: Remove unnecessary sleeps and kill on clean shutdown tests
On tests that expect a clean shutdown there is no need to try and kill
the child after wait() has returned as the process has already exited.
Further there is no need to sleep before wait() as wait will block until
the VM and VMM shutdown is complete.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
c98949bdd3 tests: Wait for VMM to exit in test_serial_file/test_console_file
This should address any flakiness as the VMM process will have
completely terminated and all files closed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
2f58fb8307 tests: Test rebooting works for block self spawn test
Being able to reboot the VM is an important aspect of the self spawning
behaviour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
e817aa6824 tests: Improve VM shutdown behaviour
Many of the tests attempted to SSH into the VM and then run "shutdown"
but don't actually check that the VM has shutdown correctly and proceed
to kill the child process. Remove the associated SSH commands and sleeps
from those tests that are not explicitly checking the shutdown
behaviour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
559b70cf0a tests: Make output capture optional
Only some tests require the output for the tests to be captured so
default to not capturing the output to a pipe and instead make it
controllable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
dae7608b1e tests: Remove duplicated network configuration
Many of the tests use an identical network configuration. Add a
GuestCommand::default_net() to generate this configuration and use it
wherever possible.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
6466ad2112 tests: Remove duplicated disk configuration
Many of the tests use an identical disk configuration. Add a
GuestCommand::default_disks() to generate this configuration and use it
wherever possible.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
9f1ac24bed tests: Make the GuestCommand take a reference to the guest
This will be used fill out default parts of the guest command.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
49e70c6203 tests: Port integration tests over to GuestCommand
Rather than creating the command itself delegate to the GuestCommand.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Rob Bradford
67a5882415 tests: Introduce new GuestCommand to handle launching the guest
This is a thin wrapper over std::process:Command which currently only
specifies the default binary but in future will handle more default
behaviour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-27 17:08:49 +00:00
Sebastien Boeuf
8142c823ed vmm: Move DeviceManager into an Arc<Mutex<>>
In anticipation of the support for device hotplug, this commit moves the
DeviceManager object into an Arc<Mutex<>> when the DeviceManager is
being created. The reason is, we need the DeviceManager to implement the
BusDevice trait and then provide it to the IO bus, so that IO accesses
related to device hotplug can be handled correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-27 11:12:31 +01:00
Sergio Lopez
531f4ff6b0 vhost_user_fs: Remove an unneeded unwrap in handle_event
Remove an unneeded unwrap in handle_event.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-26 12:08:12 +01:00
Sergio Lopez
e52129efb4 vhost_user_fs: Process events from HIPRIO queue
We weren't processing events arriving at the HIPRIO queue, which
implied ignoring FUSE_INTERRUPT, FUSE_FORGET, and FUSE_BATCH_FORGET
requests.

One effect of this issue was that file descriptors weren't closed on
the server, so it eventually hits RLIMIT_NOFILE. Additionally, the
guest OS may hang while attempting to unmount the filesystem.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-26 12:08:12 +01:00
dependabot-preview[bot]
0c5c470247 build(deps): bump micro_http from b85757e to 8d48e73
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `b85757e` to `8d48e73`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](b85757ec00...8d48e730f2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-26 07:06:24 +00:00
Sebastien Boeuf
5b96dd5f70 ci: Don't give special capabilities to Rust vhost-user-fs backend
There is no reason to give some special capabilities to the Rust version
of virtiofsd since it behaves slightly differently and does not require
neither DAC_OVERRIDE nor SYS_ADMIN.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-25 15:05:05 +00:00
Sergio Lopez
d8d790bb7b vhost_rs: Don't check for SLAVE_SEND_FD on SET_SLAVE_REQ_FD
SLAVE_SEND_FD and SLAVE_REQ are different protocol features. Check for
SLAVE_REQ instead.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-25 11:12:50 +00:00
Sergio Lopez
1c5562b656 vhost_user_fs: Add support for EVENT_IDX
Now that Queue supports EVENT_IDX, expose the feature and add support
for it in vhost_user_fs.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-25 11:12:50 +00:00
Sergio Lopez
eae4f1d249 vhost_user_fs: Add support for indirect descriptors
Now that Queue supports indirect descriptors, expose the feature and
support them in vhost_user_fs too.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-25 11:12:50 +00:00
Sergio Lopez
ea0bc240fd vhost_user_fs: Be honest about protocol supported features
vhost_user_fs doesn't really support all vhost protocol features, just
MQ and SLAVE_REQ, so return that in protocol_features().

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-25 11:12:50 +00:00
Sergio Lopez
42937c9754 vm-virtio: Add support for indirect descriptors
Indirect descriptors is a virtio feature that allows the driver to
store a table of descriptors anywhere in memory, pointing to it from a
virtqueue ring's descriptor with a particular flag.

We can't seamlessly transition from an iterator over a conventional
descriptor chain to an indirect chain, so Queue users need to
explicitly support this feature by calling Queue::is_indirect() and
Queue::new_from_indirect().

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-25 11:12:50 +00:00
Rob Bradford
d7b0b9842d tests: Move integration tests to their own directory
Simplify main.rs by moving the integration tests to their own directory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-25 10:42:54 +00:00
Eryu Guan
3cb4513077 vhost_rs: control SlaveFsCacheReq with vhost-user-slave feature
We import slave_fs_cache mod under vhost-user-slave feature control,
but not the self::slave_fs_cache::SlaveFsCacheReq import.

Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
2020-02-25 09:48:04 +00:00
Qiu Wenbo
9de3ace8c7 devices: implement Aml trait for GED device
Fixes: #657

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2020-02-25 08:32:16 +00:00
Sebastien Boeuf
b77fdeba2d msi/msi-x: Prevent from losing masked interrupts
We want to prevent from losing interrupts while they are masked. The
way they can be lost is due to the internals of how they are connected
through KVM. An eventfd is registered to a specific GSI, and then a
route is associated with this same GSI.

The current code adds/removes a route whenever a mask/unmask action
happens. Problem with this approach, KVM will consume the eventfd but
it won't be able to find an associated route and eventually it won't
be able to deliver the interrupt.

That's why this patch introduces a different way of masking/unmasking
the interrupts, simply by registering/unregistering the eventfd with the
GSI. This way, when the vector is masked, the eventfd is going to be
written but nothing will happen because KVM won't consume the event.
Whenever the unmask happens, the eventfd will be registered with a
specific GSI, and if there's some pending events, KVM will trigger them,
based on the route associated with the GSI.

Suggested-by: Liu Jiang <gerry@linux.alibaba.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-25 08:31:14 +00:00
dependabot-preview[bot]
8423c0897a build(deps): bump proc-macro2 from 1.0.8 to 1.0.9
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.8...1.0.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-25 07:51:48 +00:00
dependabot-preview[bot]
6315f16ca7 build(deps): bump syn from 1.0.15 to 1.0.16
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.15...1.0.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-25 07:19:05 +00:00
Qiu Wenbo
4cf89d373d pci: handle extended configuration space properly
This is critical to support extended capabilitiy list.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2020-02-24 17:05:09 +01:00
Qiu Wenbo
f6b9445be7 pci: fix pci MMCONFIG address parsing
We should not assume the offset produced by ECAM is identical to the
CONFIG_ADDRESS register of legacy PCI port io enumeration.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2020-02-24 17:05:09 +01:00
Rob Bradford
77ee331be0 resources: Enable KASLR in kernel config
This option improves the security of the guest by randomising the start
address of the kernel in physical memory. We should turn this on so as
to ensure all our functionality such as memory hotplug and kernel
loading works as this is an option used widely in production.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-24 15:56:37 +00:00
Rob Bradford
bba5ef3a59 vmm: Remove deprecated CPU syntax
Remove the old way of specifying the number of vCPUs to use.

Fixes: #678

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-24 07:26:31 +01:00
Rob Bradford
374ac77c63 main, vmm: Remove deprecated --vhost-user-net
This has been superseded by using --net with vhost_user=true and
socket=<socket>

Fixes: #678

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-24 07:26:31 +01:00
Rob Bradford
ffd816ebfa main, vmm: Remove deprecated --vhost-user-blk
This has been superseded by using --disk with vhost_user=true and
socket=<socket>

Fixes: #678

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-24 07:26:31 +01:00
dependabot-preview[bot]
d04e0dc9e1 build(deps): bump crossbeam-utils from 0.7.0 to 0.7.2
Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.7.0 to 0.7.2.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-utils-0.7.0...crossbeam-0.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 06:25:32 +00:00
dependabot-preview[bot]
7da5b531a0 build(deps): bump ssh2 from 0.7.1 to 0.8.0
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.7.1 to 0.8.0.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.7.1...0.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 06:24:52 +00:00
dependabot-preview[bot]
109c7f731d build(deps): bump hermit-abi from 0.1.7 to 0.1.8
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 06:24:31 +00:00
dependabot-preview[bot]
812a6b97d3 build(deps): bump syn from 1.0.14 to 1.0.15
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.14 to 1.0.15.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.14...1.0.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-22 09:52:59 +00:00
dependabot-preview[bot]
ad307912ab build(deps): bump memchr from 2.3.2 to 2.3.3
Bumps [memchr](https://github.com/BurntSushi/rust-memchr) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/BurntSushi/rust-memchr/releases)
- [Commits](https://github.com/BurntSushi/rust-memchr/compare/2.3.2...2.3.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-22 09:52:49 +00:00
Rob Bradford
94f2fc3308 release-notes: Update for v0.5.1 bug fix release
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-21 14:31:39 +01:00
dependabot-preview[bot]
f190cb05b5 build(deps): bump libc from 0.2.66 to 0.2.67
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.66 to 0.2.67.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.66...0.2.67)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-21 08:03:30 +00:00
dependabot-preview[bot]
299eb28453 build(deps): bump micro_http from 6fd1545 to b85757e
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `6fd1545` to `b85757e`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](6fd1545222...b85757ec00)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-20 17:12:23 +00:00
Sergio Lopez
d2f1749edb vmm: config: Add poll_queue property to DiskConfig
Recently, vhost_user_block gained the ability of actively polling the
queue, a feature that can be disabled with the poll_queue property.

This change adds this property to DiskConfig, so it can be used
through the "disk" argument.

For the moment, it can only be used when vhost_user=true, but this
will change once virtio-block gets the poll_queue feature too.

Fixes: #787

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-20 18:06:54 +01:00
Sergio Lopez
378dd81204 vmm: openapi: Add missing "direct" knob to DiskConfig
Add missing "direct" knob that should be exposed through the REST API.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-20 18:06:54 +01:00
Sergio Lopez
056f5481ac vmm: openapi: Fix "readonly" and "wce" defaults in DiskConfig
Fix "readonly" and "wce" defaults in cloud-hypervisor.yaml to match
their respective defaults in config.rs:DiskConfig.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-20 18:06:54 +01:00
Rob Bradford
4ebf01b344 vhost_user_backend: Don't report out socket broken errors
This is a perfectly acceptable situation as it causes the backend to
exit because the VMM has closed the connection. This addresses the
rather ugly reporting of errors from the backend that appears
interleaved with the output from the VMM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-20 14:30:27 +00:00
Rob Bradford
b5755e9c33 vhost_rs: vhost_user: Return error when connection broken
Return an error wen recvmsg() returns without a message using the
libc::ECONNRESET error so that the upper levels will correctly
interpret this as the connection being broken.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-20 14:30:27 +00:00
Samuel Ortiz
c49e31a6d9 vmm: api: Return a resize error when resize fails
And not a VmCreate one.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-20 12:26:12 +01:00
Samuel Ortiz
ebc6391bea vmm: api: Fix resize command typos
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-20 12:26:12 +01:00
Samuel Ortiz
9de755334d vmm: openapi: Update DiskConfig
It's missing a few knobs (readonly, vhost, wce) that should be exposed
through the rest API.

Fixes: #790

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-20 12:17:50 +01:00
Rob Bradford
ed1e7817cc vmm: Workaround double reboot triggered by the kernel
The kernel does not adhere to the ACPI specification (probably to work
around broken hardware) and rather than busy looping after requesting an
ACPI reset it will attempt to reset by other mechanisms (such as i8042
reset.)

In order to trigger a reset the devices write to an EventFd (called
reset_evt.) This is used by the VMM to identify if a reset is requested
and make the VM reboot. As the reset_evt is part of the VMM and reused
for both the old and new VM it is possible for the newly booted VM to
immediately get reset as there is an old event sitting in the EventFd.

The simplest solution is to "drain" the reset_evt EventFd on reboot to
make sure that there is no spurious events in the EventFd.

Fixes: #783

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-19 18:51:14 +01:00
Sergio Lopez
5c06b7f862 vhost_user_block: Implement optional static polling
Actively polling the virtqueue significantly reduces the latency of
each I/O operation, at the expense of using more CPU time. This
features is specially useful when using low-latency devices (SSD,
NVMe) as the backend.

This change implements static polling. When a request arrives after
being idle, vhost_user_block will keep checking the virtqueue for new
requests, until POLL_QUEUE_US (50us) has passed without finding one.

POLL_QUEUE_US is defined to be 50us, based on the current latency of
enterprise SSDs (< 30us) and the overhead of the emulation.

This feature is enabled by default, and can be disabled by using the
"poll_queue" parameter of "block-backend".

This is a test using null_blk as a backend for the image, with the
following parameters:

 - null_blk gb=20 nr_devices=1 irqmode=2 completion_nsec=0 no_sched=1

With "poll_queue=false":

fio --ioengine=sync --bs=4k --rw randread --name randread --direct=1
--filename=/dev/vdb --time_based --runtime=10

randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1
fio-3.14
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=169MiB/s][r=43.2k IOPS][eta 00m:00s]
randread: (groupid=0, jobs=1): err= 0: pid=433: Tue Feb 18 11:12:59 2020
  read: IOPS=43.2k, BW=169MiB/s (177MB/s)(1688MiB/10001msec)
    clat (usec): min=17, max=836, avg=21.64, stdev= 3.81
     lat (usec): min=17, max=836, avg=21.77, stdev= 3.81
    clat percentiles (nsec):
     |  1.00th=[19328],  5.00th=[19840], 10.00th=[20352], 20.00th=[21120],
     | 30.00th=[21376], 40.00th=[21376], 50.00th=[21376], 60.00th=[21632],
     | 70.00th=[21632], 80.00th=[21888], 90.00th=[22144], 95.00th=[22912],
     | 99.00th=[28544], 99.50th=[30336], 99.90th=[39168], 99.95th=[42752],
     | 99.99th=[71168]
   bw (  KiB/s): min=168440, max=188496, per=100.00%, avg=172912.00, stdev=3975.63, samples=19
   iops        : min=42110, max=47124, avg=43228.00, stdev=993.91, samples=19
  lat (usec)   : 20=5.90%, 50=94.08%, 100=0.02%, 250=0.01%, 500=0.01%
  lat (usec)   : 750=0.01%, 1000=0.01%
  cpu          : usr=10.35%, sys=25.82%, ctx=432417, majf=0, minf=10
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=432220,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=169MiB/s (177MB/s), 169MiB/s-169MiB/s (177MB/s-177MB/s), io=1688MiB (1770MB), run=10001-10001msec

Disk stats (read/write):
  vdb: ios=427867/0, merge=0/0, ticks=7346/0, in_queue=0, util=99.04%

With "poll_queue=true" (default):

fio --ioengine=sync --bs=4k --rw randread --name randread --direct=1
--filename=/dev/vdb --time_based --runtime=10

randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1
fio-3.14
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=260MiB/s][r=66.7k IOPS][eta 00m:00s]
randread: (groupid=0, jobs=1): err= 0: pid=422: Tue Feb 18 11:14:47 2020
  read: IOPS=68.5k, BW=267MiB/s (280MB/s)(2674MiB/10001msec)
    clat (usec): min=10, max=966, avg=13.60, stdev= 3.49
     lat (usec): min=10, max=966, avg=13.70, stdev= 3.50
    clat percentiles (nsec):
     |  1.00th=[11200],  5.00th=[11968], 10.00th=[11968], 20.00th=[12224],
     | 30.00th=[12992], 40.00th=[13504], 50.00th=[13760], 60.00th=[13888],
     | 70.00th=[14016], 80.00th=[14144], 90.00th=[14272], 95.00th=[14656],
     | 99.00th=[20352], 99.50th=[23936], 99.90th=[35072], 99.95th=[36096],
     | 99.99th=[47872]
   bw (  KiB/s): min=265456, max=296456, per=100.00%, avg=274229.05, stdev=13048.14, samples=19
   iops        : min=66364, max=74114, avg=68557.26, stdev=3262.03, samples=19
  lat (usec)   : 20=98.84%, 50=1.15%, 100=0.01%, 250=0.01%, 500=0.01%
  lat (usec)   : 750=0.01%, 1000=0.01%
  cpu          : usr=8.24%, sys=21.15%, ctx=684669, majf=0, minf=10
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=684611,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=267MiB/s (280MB/s), 267MiB/s-267MiB/s (280MB/s-280MB/s), io=2674MiB (2804MB), run=10001-10001msec

Disk stats (read/write):
  vdb: ios=677855/0, merge=0/0, ticks=7026/0, in_queue=0, util=99.04%

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-19 17:13:47 +00:00
Sergio Lopez
0e4e27ea9d vhost_user_block: Make use of the EVENT_IDX feature
Now that vhost_user_backend and vm-virtio do support EVENT_IDX, use it
in vhost_user_block to reduce the number of notifications sent between
the driver and the device.

This is specially useful when using active polling on the virtqueue,
as it'll be implemented by a future patch.

This is a snapshot of kvm_stat while generating ~60K IOPS with fio on
the guest without EVENT_IDX:

 Event                                         Total %Total CurAvg/s
 kvm_entry                                    393454   20.3    62494
 kvm_exit                                     393446   20.3    62494
 kvm_apic_accept_irq                          378146   19.5    60268
 kvm_msi_set_irq                              369720   19.0    58881
 kvm_fast_mmio                                370497   19.1    58817
 kvm_hv_timer_state                            10197    0.5     1715
 kvm_msr                                        8770    0.5     1443
 kvm_wait_lapic_expire                          7018    0.4     1118
 kvm_apic                                       2768    0.1      538
 kvm_pv_tlb_flush                               2028    0.1      360
 kvm_vcpu_wakeup                                1453    0.1      278
 kvm_apic_ipi                                   1384    0.1      269
 kvm_fpu                                        1148    0.1      164
 kvm_pio                                         574    0.0	  82
 kvm_userspace_exit                              574    0.0	  82
 kvm_halt_poll_ns                                 24    0.0	   3

And this is the snapshot while doing the same thing with EVENT_IDX:

 Event                                         Total %Total CurAvg/s
 kvm_entry                                     35506   26.0     3873
 kvm_exit                                      35499   26.0     3873
 kvm_hv_timer_state                            14740   10.8     1672
 kvm_apic_accept_irq                           13017    9.5     1438
 kvm_msr                                       12845    9.4     1421
 kvm_wait_lapic_expire                         10422    7.6     1118
 kvm_apic                                       3788    2.8      502
 kvm_pv_tlb_flush                               2708    2.0      340
 kvm_vcpu_wakeup                                1992    1.5      258
 kvm_apic_ipi                                   1894    1.4      251
 kvm_fpu                                        1476    1.1      164
 kvm_pio                                         738    0.5       82
 kvm_userspace_exit                              738    0.5	  82
 kvm_msi_set_irq                                 701    0.5	  69
 kvm_fast_mmio                                   238    0.2        4
 kvm_halt_poll_ns                                 50    0.0        1
 kvm_ple_window_update                            28    0.0        0
 kvm_page_fault                                    4    0.0        0

It can be clearly appreciated how the number of vm exits per second,
specially the ones related to notifications (kvm_fast_mmio and
kvm_msi_set_irq) is drastically lower.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-19 17:13:47 +00:00
Sergio Lopez
1ef6996207 vhost_user_backend: Add helpers for EVENT_IDX
Add helpers to Vring and VhostUserSlaveReqHandler for EVENT_IDX, so
consumers of this crate can make use of this feature.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-19 17:13:47 +00:00
Sergio Lopez
d17fa784bc vm-virtio: Implement support for EVENT_IDX
VIRTIO_RING_F_EVENT_IDX is a virtio feature that allows to avoid
device <-> driver notifications under some circunstances, most
notably when actively polling the queue.

This commit implements support for in in the vm-virtio
crate. Consumers of this crate will also need to add support for it by
exposing the feature and calling using update_avail_event() and
get_used_event() accordingly.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-02-19 17:13:47 +00:00
Sebastien Boeuf
793d4e7b8d vmm: Move codebase to GuestMemoryAtomic from vm-memory
Relying on the latest vm-memory version, including the freshly
introduced structure GuestMemoryAtomic, this patch replaces every
occurrence of Arc<ArcSwap<GuestMemoryMmap> with
GuestMemoryAtomic<GuestMemoryMmap>.

The point is to rely on the common RCU-like implementation from
vm-memory so that we don't have to do it from Cloud-Hypervisor.

Fixes #735

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-19 13:48:19 +00:00
Sebastien Boeuf
ddf6caf955 ci: Improve test_memory_mergeable_on stability
The integration test test_memory_mergeable_on has been fairly unstable
for quite some time now. Because it can take some time for the VM to be
spawned and to be able to perform a correct measure of the PSS, this
commit simply increases the time before such measure is done.
This should return more accurate PSS results, which should help
stabilize the test.

Fixes #781

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-19 12:36:28 +00:00
dependabot-preview[bot]
af621be509 build(deps): bump micro_http from 57ac9df to 6fd1545
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `57ac9df` to `6fd1545`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](57ac9df0ad...6fd1545222)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-19 07:53:09 +00:00
Liu Bo
4970e2f703 vhost-user-fs: add dax tests for vhost_user_fs rust daemon
Now that vhost_user_fs rust daemon supports virtiofs's dax mode, this adds
the two dax tests accordingly.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-02-19 07:52:50 +00:00
Liu Bo
59958f0a61 vhost_user_fs: add the ability to set slave req fd
This adds the missing part of supporting virtiofs dax on the slave end,
that is, receiving a socket pair fd from the master end to set up a
communication channel for sending setupmapping & removemapping messages.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-02-19 07:52:50 +00:00
Liu Bo
3f09eff6c5 vhost_user_fs: add fs cache request operations
This introduces setupmapping and removemapping methods to server.rs,
passthrough.rs and filesystem.rs in order to support virtiofs dax mode
inside guest.

Since we don't really want the server.rs to know that it is dealing with
vhost-user specifically, this is making it more generic by adding a new
trait which has three functions map()/unmap()/sync() corresponding to
fs_slave_{map, unmap, sync}, server.rs will take anything that implements
the trait.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-02-19 07:52:50 +00:00
Liu Bo
956a84f73a vhost_user_fs: add necessary structs for map/unmap requests
This is adding some structures with which we will talk with guest kernel on
map/unmap requests.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-02-19 07:52:50 +00:00
Liu Bo
269d660b0a vhost_user_fs: add SlaveFsCacheReq to handle map/unmap
This introduces SlaveFsCacheReq which implements
VhostUserMasterReqHandler to handle map/unmap requests.

Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
2020-02-19 07:52:50 +00:00
Sebastien Boeuf
be78c6da49 vhost_rs: Fix unit test race condition
The unit tests are run from cargo test through multiple threads of the
same process. For this reason, all these threads share their file
descriptors (because that's how this works on Linux), which means that
any of them can close a file descriptor opened from another thread.

In the context of create_listener() and accept_connection() tests, they
can run concurrently and this generates some failure when the file
descriptor create_listener() is binding to is being closed from the
accept_connection() test.

In order to avoid such race condition, this patch simply removes the
part of the unit test performing an explicit and unsafe file descriptor
closure.

Fixes #759

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-18 16:59:13 +01:00
Rob Bradford
f7378bc092 tests: Add self spawning vhost-user-block test
Also rename the net self spawning test to differentiate it from the the
block one.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-18 08:43:47 +00:00
Rob Bradford
1f6cbad01a vmm: Add support for spawning vhost-user-block backend
If no socket is supplied when enabling "vhost_user=true" on "--disk"
follow the "exe" path in the /proc entry for this process and launch the
network backend (via the vmm_path field.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-18 08:43:47 +00:00
Rob Bradford
4d60ef59bc vm-virtio: vhost_user: block: On shutdown() drop the socket
This causes the vhost-user-block backend to shutdown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-18 08:43:47 +00:00
Sebastien Boeuf
7fabca3548 ci: Don't run unit tests in a privileged container
The unit tests require some specific Linux capabilities and also to have
access to /dev/kvm device. This commit makes sure we enable only what's
necessary instead of blindly enable full priviliges with --privileged
option.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-18 08:53:03 +01:00
dependabot-preview[bot]
27247164b5 build(deps): bump micro_http from 4827569 to 57ac9df
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `4827569` to `57ac9df`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](482756925c...57ac9df0ad)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-18 06:42:39 +00:00
Rob Bradford
08a68f2f0f build: Run unit tests on worker node
The unit tests require higher privileges so for safety run on the worker
nodes.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-17 15:41:06 +00:00
Samuel Ortiz
f21cd31b94 scripts: dev_cli: Add more privileges for the integration tests
We need the host IPC for sharing eventfds with KVM, and the host network
for VFIO.

We also enforce the no-seccomp setting on the container, to overcome any
potential filtering set by our container's Ubuntu base.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-17 15:06:04 +00:00
Rob Bradford
a94887e051 build: Use dev container for integration tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-17 15:06:04 +00:00
Sebastien Boeuf
3edc2bd6ab vmm: Prevent memory overcommitment through virtio-fs shared regions
When a virtio-fs device is created with a dedicated shared region, by
default the region should be mapped as PROT_NONE so that no pages can be
faulted in.

It's only when the guest performs the mount of the virtiofs filesystem
that we can expect the VMM, on behalf of the backend, to perform some
new mappings in the reserved shared window, using PROT_READ and/or
PROT_WRITE.

Fixes #763

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-17 15:03:47 +01:00
dependabot-preview[bot]
968c90a6ce build(deps): bump hermit-abi from 0.1.6 to 0.1.7
Bumps [hermit-abi](https://github.com/hermitcore/rusty-hermit) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/hermitcore/rusty-hermit/releases)
- [Commits](https://github.com/hermitcore/rusty-hermit/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 11:17:39 +00:00
Rob Bradford
7485a0c1f7 Revert "build: Don't fail build on test_vfio failure"
This reverts commit 014844d0da.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-17 08:23:02 +00:00
dependabot-preview[bot]
cbc0ac3267 build(deps): bump micro_http from 7a23e54 to 4827569
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `7a23e54` to `4827569`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](7a23e54775...482756925c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 07:41:05 +00:00
dependabot-preview[bot]
7fdb5ae4c4 build(deps): bump vm-memory from eb2fc0b to f615b19
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `eb2fc0b` to `f615b19`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](eb2fc0b6d9...f615b19469)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 07:40:49 +00:00
dependabot-preview[bot]
0d748c5c2b build(deps): bump scopeguard from 1.0.0 to 1.1.0
Bumps [scopeguard](https://github.com/bluss/scopeguard) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/bluss/scopeguard/releases)
- [Commits](https://github.com/bluss/scopeguard/compare/1.0.0...v1.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 07:40:24 +00:00
dependabot-preview[bot]
6692fa60e9 build(deps): bump thiserror from 1.0.10 to 1.0.11
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.10 to 1.0.11.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.10...1.0.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-15 11:05:06 +00:00
Rob Bradford
f03602a4c9 tests: Add self spawning vhost-user-net test
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
bc75c1b4e1 vmm: Add support for spawning vhost-user-net backend
If no socket is supplied when enabling "vhost_user=true" on "--net"
follow the "exe" path in the /proc entry for this process and launch the
network backend (via the vmm_path field.)

Currently this only supports creating a new tap interface as the network
backend also only supports that.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
d054dddcb3 vm-virtio: Retry connections to vhost-user backends
If the connection to the backend fails, sleep and retry up to a count.
This failure could happen because the backend is not yet ready to handle
the connection which is a common case when working with a spawned
backend.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
b04eb4770b vmm: Follow the "exe" symlink from the PID directory in /proc
It is necessary to do this at the start of the VMM execution rather than
later as it must be done in the main thread in order to satisfy the
checks required by PTRACE_MODE_READ_FSCREDS (see proc(5) and
ptrace(2))

The alternative is to run as CAP_SYS_PTRACE but that has its
disadvantages.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
503887843f vm-virtio: vhost_user: net: On shutdown() drop the socket
This causes the vhost-user-net backend to shutdown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
7c9e8b103f vmm: device_manager: Shutdown all virtio devices
When the DeviceManager is dropped explicitly shutdown() all virtio
devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Rob Bradford
545ea9ea33 vm-virtio: Add shutdown method to VirtioDevice trait
This allows the VMM to explicitly shutdown devices as part of the VM
shutdown ahead of what Drop::drop() would do.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-14 17:32:49 +00:00
Bo Chen
ebd83699dc main: Display git commit hash with the '--version' option
Add a build-script to propagate the git commit hash to other crates at
compile time through environment variables, and display the hash along
with the '--version' option.

Fixes #729

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-02-14 10:00:14 +01:00
dependabot-preview[bot]
bdb92f9ace build(deps): bump micro_http from 7fb2e46 to 7a23e54
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `7fb2e46` to `7a23e54`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](7fb2e4658a...7a23e54775)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-14 07:27:28 +00:00
Rob Bradford
2061f0d8b4 tests: Always create shared VFIO directory from scratch
This ensures that any changes to the contents will not affect subsequent
tests runs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-13 17:55:21 +01:00
Rob Bradford
e8e4f43d52 tests: Use hugepages for test_vfio
Using hugepages with VFIO and virtiofs can improve the performance of
the test_vfio test.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-13 17:55:21 +01:00
Samuel Ortiz
296ada9441 scripts: dev_cli: Fix post build permissions for the whole tree
Fixes: #752

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-13 17:52:30 +01:00
Rob Bradford
287897d702 tests: Run test_vfio with PCI binary
The placement of the explicit run of "test_vfio" meant it was run with
MMIO rather than PCI which meant it always failed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-13 13:37:58 +00:00
dependabot-preview[bot]
16614447eb build(deps): bump serde_json from 1.0.47 to 1.0.48
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.47 to 1.0.48.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.47...v1.0.48)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-13 09:03:24 +00:00
dependabot-preview[bot]
96479dabe6 build(deps): bump vm-memory from f3d1c27 to eb2fc0b
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `f3d1c27` to `eb2fc0b`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](f3d1c2775c...eb2fc0b6d9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-13 07:20:51 +00:00
dependabot-preview[bot]
88c1683029 build(deps): bump memchr from 2.3.1 to 2.3.2
Bumps [memchr](https://github.com/BurntSushi/rust-memchr) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/BurntSushi/rust-memchr/releases)
- [Commits](https://github.com/BurntSushi/rust-memchr/compare/2.3.1...2.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-13 07:20:34 +00:00
dependabot-preview[bot]
8d3e4f989d build(deps): bump micro_http from c9e900c to 7fb2e46
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `c9e900c` to `7fb2e46`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](c9e900c181...7fb2e4658a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-12 18:12:43 +00:00
Sebastien Boeuf
53481aabe5 docs: Update documentation related to multiqueue network
Just updating the documentation regarding the pre-creation of a tap
interface supporting multiqueue, by adding what the cloud-hypervisor
--net parameter should look like.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-12 18:05:42 +00:00
Sebastien Boeuf
4dd16c2686 vm-virtio: Detect if a tap interface supports multiqueue
By detecting if an existing tap interface supports multiqueue, we now
have the information to determine if the command line parameters
regarding the number of queues is correct.

Fixes #738

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-12 18:05:42 +00:00
Sebastien Boeuf
8627656f55 net_util: Provide more accurate error messages
In order to identify better the problem whenever an existing TAP is
provided, this patch enhances the error returned for an easier
diagnosis of the problem.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-12 18:05:42 +00:00
dependabot-preview[bot]
6e5338d28f build(deps): bump memchr from 2.3.0 to 2.3.1
Bumps [memchr](https://github.com/BurntSushi/rust-memchr) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/BurntSushi/rust-memchr/releases)
- [Commits](https://github.com/BurntSushi/rust-memchr/compare/2.3.0...2.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-12 17:29:03 +00:00
Rob Bradford
014844d0da build: Don't fail build on test_vfio failure
test_vfio has been failing consistently on the CI so mark it with
a "#[ignore]" and then forceably build it again but ignore the build
result.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-12 15:37:47 +00:00
dependabot-preview[bot]
779cbfe8bd build(deps): bump backtrace from 0.3.43 to 0.3.44
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.43 to 0.3.44.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.43...0.3.44)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-11 18:10:45 +00:00
Rob Bradford
700df9eb16 vhost_user_net: Port to new exit event strategy
Implement the exit_event() method on the VhostUserBackend trait. It is
necessary to specify a custom exit event id in this case as the loop is
also used for handling activity on the tap file descriptors.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-11 15:21:07 +01:00
Rob Bradford
c33c38bd96 vhost_user_block: Port to new exit event strategy
Implement the newly added exit_event() method on the VhostUserBackend
trait to allow the backend to provide an EventFD for triggering an exit
of the worker thread.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-11 15:21:07 +01:00
Rob Bradford
da7f31d4bc bin: vhost_user_fs: Port to new exit event strategy
Rather than handling the KILL_EVENT in the event handler itself use the
newly added support in VhostUserBackend for providing a kill event
framework.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-11 15:21:07 +01:00
Rob Bradford
759a0be6cd vhost_user_backend: Add support for handling exiting of worker thread
All backends currently provide their own implementation for triggering
the worker thread to exit via an EventFd. Modify the VhostUserBackend
trait to allow a common implementation strategy that backends can use to
provide an EventFd (and optional id) that can be used to trigger the
worker to exit.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-11 15:21:07 +01:00
dependabot-preview[bot]
b17bafb530 build(deps): bump micro_http from 1de6f32 to c9e900c
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `1de6f32` to `c9e900c`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](1de6f32610...c9e900c181)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-11 07:16:11 +00:00
Rob Bradford
7ca691fc2f vhost_user_block: Implement and use worker shutdown
Add a kill EventFD and use this to shutdown the worker thread when the
backend terminates.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
e619fe6b01 vhost_user_net: Remove "Clone" implementation
There is no need for this and it could lead to inadvertent issues in the
future.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
613f254908 vhost_user_backend: Wait on the worker thread
Check the return value from the worker thread by saving the thread
handle and waiting for it to return.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
97ab767a2f vhost_user_net: Shutdown worker thread on exit
This will ensure a clean shutdown of the backend

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
7f032c8bb3 bin: vhost_user_fs: Shutdown worker thread on exit
This will ensure a clean shutdown of the backend

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
99cb8dc0a4 bin: vhost_user_fs use error! macro logging for consistency
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
710394b872 vhost_user_block: Forward the error from unexpected event
This is consistent with vhost-user-net and vhost-user-fs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
4f4c3d3ebe vhost_user_block: Make Error behave like net and fs versions
Make the Error struct behave more like the net and fs equivalents.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
f1e19d6c96 vhost_user_backend: Forward the error from main thread
The main thread returns a Result with any errors from it. Although the
error from the join itself was being returned the real error from the
thread was being ignored so ensure that it is forwarded.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Rob Bradford
80c9dc2e0c Revert "vhost-user-backend: Correct error handling in run"
This reverts commit 4a1af7f63c.

This change erroneously ignored the return value for the result which
meant that requests to break out of the loop due to a kill event were
lost.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-10 09:16:49 +01:00
Samuel Ortiz
c706ca1522 scripts: dev_cli: Simplify the build command exit path
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-10 09:11:17 +01:00
Samuel Ortiz
0a1d6e1cb3 scripts: dev_cli: Fix build directory permisions
All our tests must be run as root and thus the build directory is owned
by root after we run any of them.

Start another container to fix all permissions whenever we're done with
our tests.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-10 09:11:17 +01:00
Samuel Ortiz
c8fa8092c5 scripts: dev_cli: Run unprivileged containers as the host user
By default we will run as root inside the container, which means all the
build artifacts will be owned by root. That prevents us from properly
cleaning our build from an unprivileged host user.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-10 09:11:17 +01:00
dependabot-preview[bot]
26d8caedb6 build(deps): bump micro_http from ae15e75 to 1de6f32
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `ae15e75` to `1de6f32`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](ae15e75eb7...1de6f32610)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 07:22:59 +00:00
dependabot-preview[bot]
572aaa7231 build(deps): bump serde_json from 1.0.46 to 1.0.47
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.46 to 1.0.47.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.46...v1.0.47)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-08 00:27:55 +00:00
Rob Bradford
04cb35e3f4 scripts: Make dev_cli.sh exit on test error
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-07 17:24:32 +00:00
Rob Bradford
9bf100c91c build: Run worker and master build in parallel
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-07 17:24:32 +00:00
Rob Bradford
bfbca596ea scripts: Don't use interactive & terminal mode for docker
When running the docker container there is no interactivity needed so
don't pass "-ti" to "docker run"

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-07 17:24:32 +00:00
Rob Bradford
6e6eb5b55e build: Do cargo tests, unit tests and OpenAPI check on master
Rather than on the CI nodes.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-07 17:24:32 +00:00
Samuel Ortiz
a5b053f81d scripts: dev_cli: Use a tmpfs mount for /tmp
To mitigate Azure slow disk IO, we mount /tmp on tmpfs.
This is a reproduction of our CI environment, as setup by the
Jenkinsfile.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-07 17:33:30 +01:00
Samuel Ortiz
2f395e60a0 release: v0.5.0
Expand the release notes and bump Cargo.toml.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-07 16:17:06 +01:00
dependabot-preview[bot]
d46c61c5d4 build(deps): bump byteorder from 1.3.2 to 1.3.4
Bumps [byteorder](https://github.com/BurntSushi/byteorder) from 1.3.2 to 1.3.4.
- [Release notes](https://github.com/BurntSushi/byteorder/releases)
- [Changelog](https://github.com/BurntSushi/byteorder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/byteorder/compare/1.3.2...1.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-07 14:18:07 +00:00
Samuel Ortiz
0cd3325a06 docs: Cloud Hypervisor API documentation
We document both the internal and external APIs, and how they relate to
each others.

Fixes: #318

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-07 11:26:41 +01:00
Cathy Zhang
14eddf72b4 vm-virtio: Simplify virtio feature handling
Remove duplicated code across the different devices by handling
the virtio feature pages in VirtioDevice itself rather than
in the backends. This works as no virtio devices use feature
bits beyond 64-bits.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-02-07 08:32:21 +00:00
dependabot-preview[bot]
411e2b43ba build(deps): bump micro_http from 10d1f4a to ae15e75
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `10d1f4a` to `ae15e75`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](10d1f4aa59...ae15e75eb7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-07 08:24:12 +00:00
Bo Chen
3bf46d4c80 README: Fix a typo for using cli_dev
Fix the typo for the instructions of using cli_dev to run unit tests.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-02-06 18:02:21 +01:00
Sebastien Boeuf
3447e226d9 dependencies: bump vm-memory from 4237db3 to f3d1c27
This commit updates Cloud-Hypervisor to rely on the latest version of
the vm-memory crate.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-06 11:40:45 +01:00
dependabot-preview[bot]
ae87455242 build(deps): bump micro_http from ab44474 to 10d1f4a
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `ab44474` to `10d1f4a`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](ab44474a08...10d1f4aa59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-06 06:35:35 +00:00
Sebastien Boeuf
62ccccc303 vmm: Make sure to retry creating the VM on EINTR
If the ioctl syscall KVM_CREATE_VM gets interrupted while creating the
VM, it is expected that we should retry since EINTR should not be
considered a standard error.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-05 12:06:21 +01:00
dependabot-preview[bot]
671b49ba23 build(deps): bump vm-memory from d6229fc to 4237db3
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `d6229fc` to `4237db3`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](d6229fc5bd...4237db35e8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-05 07:28:33 +00:00
dependabot-preview[bot]
e5b7fff990 build(deps): bump micro_http from 1eb80f8 to ab44474
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `1eb80f8` to `ab44474`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](1eb80f8d1b...ab44474a08)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-05 07:28:22 +00:00
Samuel Ortiz
da2b3c92d3 vm-device: interrupt: Remove InterruptType dependencies and definitions
Having the InterruptManager trait depend on an InterruptType forces
implementations into supporting potentially very different kind of
interrupts from the same code base. What we're defining through the
current, interrupt type based create_group() method is a need for having
different interrupt managers for different kind of interrupts.

By associating the InterruptManager trait to an interrupt group
configuration type, we create a cleaner design to support that need as
we're basically saying that one interrupt manager should have the single
responsibility of supporting one kind of interrupt (defined through its
configuration).

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-04 19:32:45 +01:00
Samuel Ortiz
84fc807bc6 interrupt: Interrupt manager split
We create 2 different interrupt managers for separately handling
creation of legacy and MSI interrupt groups.
Doing so allows us to have a cleaner interrupt manager and IOAPIC
initialization path. It also prepares for an InterruptManager trait
design improvement where we remove the interrupt source type dependency
by associating an interrupt configuration type to the trait.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-04 19:32:45 +01:00
Sebastien Boeuf
56d7c04226 vm-virtio: vsock: Don't return error when epoll_wait is interrupted
The existing code taking care of the epoll loop was too restrictive as
it was considering all errors the same. But in case the error is EINTR,
this means the syscall has been interrupted while waiting, and it should
be resumed to wait again.

This patch enforces the parsing of the returned error and prevent the
code from assuming EINTR should be handled as all other errors.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-02-04 18:16:37 +01:00
Rob Bradford
6e6b2b84fe scripts: Check the Rust formatting is valid
Check the rust formatting rather than just reformatting code on the CI
agent.

Also fix a formatting error that slipped in whilst the cargo fmt check
was not working correctly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-04 16:47:05 +01:00
Samuel Ortiz
705f27151d scripts: dev_cli: Pass unit and integration test args to cargo test
In order, among other things, to use the development CLI to run specific
integration tests. For example, to run only the memory_overhead
integration test:

./scripts/dev_cli.sh tests --integration -- memory_overhead

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-04 15:31:58 +01:00
Rob Bradford
bc053f1b13 main: Ignore error on log writing
A previous version of this change attempted to avoid panicking by not
using .expect() when handling an error when attempting to write to the
log file. Unfortunately the macro eprintln!() that was used to replace
the .expect() also has the behaviour of panicking if stderr cannot be
used. Instead swallow the error completely as if writing to the log has
failed at logging time it is almost certainly the case that any message
about the log would also not be seen.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-04 12:22:23 +00:00
Yang Zhong
91739be120 main: Add help info for block-backend
Since the vhost-user-blk binary will be removed and the newer
release will integrate this block backend into cloud-hypervisor
binary. The block backend code has been added num_queues cmdline
support, we need update multiple queues help info for this
block-backend in the cloud-hypervisor.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-02-04 11:06:17 +00:00
Samuel Ortiz
ae6cf4c922 tests: integration: Add memory overhead test
We measure the memory overhead that the VMM process adds to the guest VM
and compare it with a maximum acceptable limit. The test is run against
a simple VM, running 1 vCPU and 512MB of RAM. Although this is not by
any mean a comprehensive VMM overhead measurement, it will allow us to
detect when and if any PR makes our code cross an arbitrary memory
overhead threshold.

Fixes: #64

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-02-04 09:23:56 +00:00
Rob Bradford
7cb61d3960 main: Don't panic (by calling .expect()) if writing to the log fails
As this can happen during the running of the VMM we should be very
careful not to panic() as that can lead to a thread being used by the VM
disappearing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 19:08:08 +01:00
Rob Bradford
880a57c920 vmm: Remove VmInfo struct
After refactoring the VmInfo struct is no longer needed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
07bc292fa5 vmm: device_manager: Get VmFd from AddressManager
A reference to the VmFd is stored on the AddressManager so it is not
necessary to pass in the VmInfo into all methods that need it as it can
be obtained from the AddressManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
6411c3ae42 vmm: device_manager: Use MemoryManager to get guest memory
The DeviceManager has a reference to the MemoryManager so use that to
get the GuestMemoryMmap rather than the version stored in the VmInfo
struct.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
066fc6c0d1 vmm: device_manager: Get VM config from the struct member
Remove the use of vm_info in methods to get the config and instead use
the config stored on the DeviceManager itself.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
77ae3de4f3 vmm: device_manager: Make legacy device addition a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
599275b610 vmm: device_manager: Make ACPI device creation a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
b8c1b2e174 vmm: device_manager: Make console creation a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
b5440e2d0a vmm: device_manager: Make virtio device creation functions methods
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter. This prepares the way to more easily store state on
the DeviceManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
e90c6f3c44 vmm: device_manager: Make make_virtio_devices a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter. A follow-up commit will change the callee functions
that create the devices themselves.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
dbc09ad0ef vmm: device_manager: Make add_vfio_devices a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
d9e1c2cd22 vmm: device_manager: Make add_virtio_pci_device a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
aaa5e2e9ea vmm: device_manager: Make add_virtio_mmio_device a method
Remove some in/out parameters and instead rely on them as members of the
&mut self parameter.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
2987476e0a vmm: device_manager: Make add_pci_devices and add_mmio_devices methods
Modify these functions to take an &mut self and become methods on
DeviceManager. This allows the removal of some in/out parameters and
leads the way to further refactoring and simplification.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
3dbae423bb vmm: device_manager: Only add MemoryManager to I/O bus on ACPI builds
The MemoryManager should only be included on the I/O bus when doing ACPI
builds as that is the only time it will be interrogated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Rob Bradford
68fa97eb0e vmm: device_manager: Always embed MemoryManager in the struct
Currently the MemoryManager is only used on the ACPI code paths after
the DeviceManager has been created. This will change in a future commit
as part of the refactoring so for now always include it but name it with
underscore prefix to indicate it might not always be used.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-02-03 12:28:30 +00:00
Yang Zhong
789a39a2d5 ci: Add MQ support in the test cases
The CI need to add MQ support, and the vcpu number should
be bigger than or equal to queue number.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-02-03 09:49:27 +01:00
Yang Zhong
99da1dff90 vhost-user-blk: Add MQ support in backend
Adding the num_queues parameter for vhost-user-blk backend, which
can enable MQ support in the backend.

This patch has enabled the MQ support from handle_event, and the
vhost-user-backend crate will enable multiple threads to call this
handle_event to handle read/write operations.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-02-03 09:49:27 +01:00
Yang Zhong
1038a07dd6 vhost-user-blk: Device support multiple queues
The previous code only support one queue, and we need
to support MQ in vhost user block device. This patch
can work with SPDK with MQ setting.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2020-02-03 09:49:27 +01:00
dependabot-preview[bot]
839f3a74ff build(deps): bump serde_json from 1.0.45 to 1.0.46
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.45 to 1.0.46.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.45...v1.0.46)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 07:07:34 +00:00
Samuel Ortiz
652b60320d vfio: Use the vfio-binding FAM wrappers
It's less unsafe and makes the code more readable.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-31 15:09:11 +01:00
Samuel Ortiz
275cb5c92f scripts: dev_cli: Add clean command support
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-31 11:42:20 +00:00
Samuel Ortiz
8676759c38 README: Basic dev_cli documentation
Document it as an alternative way of building the Cloud Hypervisor
binaries.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-31 11:42:20 +00:00
Samuel Ortiz
76087f1235 script: cargo: Improve the cargo tests
We don't need to force the cargo-audit install, we can check if it's
already available instead and install if it's not.

Also, since we now have workspaces properly setup, we can call directly
into cargo fmt and avoid calling into find magic incantation.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-31 11:42:20 +00:00
Samuel Ortiz
db6f894e5e scripts: Add container based development script
The script is a development tool that runs all commands in a dedicated
container. This allows for containerized, isolated and reproducible
builds and CI runs.

The script supports the following command:

* build: Build Cloud Hypervisor binaries (debug and release)
* build-container: Build the container used by the script
* tests: Run unit, cargo and integration tests

$ ./scripts/dev_cli.sh help

Cloud Hypervisor dev_cli.sh
Usage: dev_cli.sh <command> [<command args>]

Available commands:

    build [--debug|--release] [-- [<cargo args>]]
        Build the Cloud Hypervisor binaries.
        --debug               Build the debug binaries. This is the default.
        --release             Build the release binaries.

    tests [--unit|--cargo|--all]
        Run the Cloud Hypervisor tests.
        --unit               Run the unit tests.
        --cargo              Run the cargo tests.
	--integration        Run the integration tests.
        --all                Run all tests.

    build-container [--type]
        Build the Cloud Hypervisor container.
        --dev                Build dev container. This is the default.

    help
        Display this help message.

Fixes: #682
Fixes: #684

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-31 11:42:20 +00:00
dependabot-preview[bot]
31c3685117 build(deps): bump micro_http from e5ef374 to 1eb80f8
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `e5ef374` to `1eb80f8`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](e5ef374c8e...1eb80f8d1b)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-31 07:55:08 +00:00
dependabot-preview[bot]
8dfb79e077 build(deps): bump vm-memory from df6207f to d6229fc
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `df6207f` to `d6229fc`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](df6207f1c0...d6229fc5bd)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-31 07:54:31 +00:00
dependabot-preview[bot]
e99b64097a build(deps): bump regex-syntax from 0.6.13 to 0.6.14
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.13 to 0.6.14.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-31 00:03:28 +00:00
dependabot-preview[bot]
92b3764553 build(deps): bump openssl-sys from 0.9.53 to 0.9.54
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.53 to 0.9.54.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.53...openssl-sys-v0.9.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-30 17:20:30 +00:00
dependabot-preview[bot]
de91c30cd3 build(deps): bump micro_http from 9e68aa4 to e5ef374
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `9e68aa4` to `e5ef374`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](9e68aa4d9d...e5ef374c8e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-30 17:01:33 +00:00
Sebastien Boeuf
aa4efdd7ec ci: Update kernel related to virtio-iommu
Because of the new set of patches related to virtio-iommu allowing only
for the topology to be described through virtio configuration, this
patch updates the kernel branch and the kernel configuration our CI
relies on.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 10:37:40 +01:00
Sebastien Boeuf
ac01ceddbb vmm: Cleanup list of PCI IDs related to virtual IOMMU
Now that devices attached to the virtual IOMMU are described through
virtio configuration, there is no need for the DeviceManager to store
the list of IDs for all these devices. Instead, things are handled
locally when PCI devices are being added.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 10:37:40 +01:00
Sebastien Boeuf
097cff2d85 vmm: Use virtio topology for virtio-iommu
Instead of relying on the ACPI tables to describe the devices attached
to the virtual IOMMU, let's use the virtio topology, as the ACPI support
is getting deprecated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 10:37:40 +01:00
Sebastien Boeuf
bac0d1e689 iommu: Implement virtio topology configuration
Based on the new structures previously introduced, the new topology
feature is being fully implemented through this commit. This allows
the description of the devices attached to the virtual IOMMU, which
is why a new function attach_devices() has been introduced. It gives
the virtual IOMMU device the full list of devices which must be attached
to it, letting the device share this information through its virtio
configuration.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 10:37:40 +01:00
Sebastien Boeuf
0c73ff8129 iommu: Add topology structures
The virtio-iommu device defines a new virtio feature allowing the
topology to be discovered fully through virtio configuration.

By topology, it means describing the devices attached to the virtual
IOMMU. This is currently managed through ACPI with IORT and VIOT table,
but this is another way of describing it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 10:37:40 +01:00
Sebastien Boeuf
db42caef42 vm-virtio: Handle special virtio-pci capability CAP_PCI_CFG
The virtio capability VIRTIO_PCI_CAP_PCI_CFG is exposed through the
device's PCI config space the same way other virtio-pci capabilities
are exposed.

The main and important difference is that this specific capability is
designed as a way for the guest to access virtio capabilities without
mapping the PCI BAR. This is very rarely used, but it can be useful when
it is too early for the guest to be able to map the BARs.

One thing to note, this special feature MUST be implemented, based on
the virtio specification.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 09:25:52 +01:00
Sebastien Boeuf
db9f9b7820 pci: Make self mutable when reading from PCI config space
In order to anticipate the need to support more features related to the
access of a device's PCI config space, this commits changes the self
reference in the function read_config_register() to be mutable.

This also brings some more flexibility for any implementation of the
PciDevice trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-30 09:25:52 +01:00
dependabot-preview[bot]
655d9cdb0d build(deps): bump smallvec from 1.1.0 to 1.2.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.1.0...v1.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-30 01:54:42 +00:00
dependabot-preview[bot]
74ab468bb4 build(deps): bump backtrace from 0.3.42 to 0.3.43
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.42 to 0.3.43.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.42...0.3.43)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-29 22:59:26 +00:00
dependabot-preview[bot]
1651cc3953 build(deps): bump kvm-ioctls from 0.4.0 to 0.5.0
Bumps [kvm-ioctls](https://github.com/rust-vmm/kvm-ioctls) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/rust-vmm/kvm-ioctls/releases)
- [Changelog](https://github.com/rust-vmm/kvm-ioctls/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/kvm-ioctls/compare/v0.4.0...v0.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-29 10:22:51 +00:00
Rob Bradford
b4d04bdff6 tests: Add CLI <-> API validation test for --disk changes
Check that the CLI generates the JSON data as expected.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
Rob Bradford
3c8cf0988d docs: Update device model to clarify how to enable vhost-user-block
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
Rob Bradford
75e6762897 vmm: Give deprecation warning for "--vhost-user-blk" syntax
This will be removed in a future release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
Rob Bradford
969b5ee4e8 vmm: config: Add warning about specifying "wce" without "vhost-user"
Currently configuring WCE is only supported when using vhost-user.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
Rob Bradford
12f4cd951a tests: Use "--disks" for vhost-user-block testing
Use newly unified command line options for testing vhost-user based
block support.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
Rob Bradford
aeeae661fc vmm: Support vhost-user-block via "--disks"
Add a socket and vhost_user parameter to this option so that the same
configuration option can be used for both virtio-block and
vhost-user-block.  For now it is necessary to specify both vhost_user
and socket parameters as auto activation is not yet implemented. The wce
parameter for supporting "Write Cache Enabling" is also added to the
disk configuration.

The original command line parameter is still supported for now and will
be removed in a future release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-29 08:06:37 +00:00
dependabot-preview[bot]
362942fa6e build(deps): bump micro_http from 53cf1ba to 9e68aa4
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `53cf1ba` to `9e68aa4`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](53cf1bacad...9e68aa4d9d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-29 07:06:52 +00:00
dependabot-preview[bot]
b5992fe90b build(deps): bump thiserror from 1.0.9 to 1.0.10
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.9...1.0.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 20:42:12 +00:00
Rob Bradford
2c6f528c23 vmm: Give deprecation warning for "--vhost-user-net" syntax
This will be removed in a future release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-28 12:39:26 +00:00
Rob Bradford
f322e924ad docs: Update device model to clarify how to enable vhost-user-net
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-28 12:39:26 +00:00
Rob Bradford
4888dd2e01 tests: Add CLI <-> API validation test for --net changes
Check that the CLI generates the JSON data as expected.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-28 12:39:26 +00:00
Rob Bradford
8f096b8be5 tests: Use "--net" parameter for vhost-user-net setup
Use the newly unified parameter for setting up vhost-user-net based
networking.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-28 12:39:26 +00:00
Rob Bradford
a831aa214c vmm: Support vhost-user-net via "--net"
Add a socket and vhost_user parameter to this option so that the same
configuration option can be used for both virtio-net and vhost-user-net.
For now it is necessary to specify both vhost_user and socket parameters
as auto activation is not yet implemented. The original command line
parameter is still supported for now.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-28 12:39:26 +00:00
Sebastien Boeuf
e155e3690c vm-virtio: Simplify virtio-fs configuration
This commit introduces a clear definition of the virtio-fs
configuration structure, allowing vhost-user-fs device to
rely on it.

This makes the code more readable for developers.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 10:28:14 +00:00
Sebastien Boeuf
8e48fc445f vm-virtio: Simplify virtio-blk configuration
This commit reuses the clear definition of the virtio-blk
configuration structure, allowing both vhost-user-blk and
virtio-blk devices to rely on it.

This makes the code more readable for developers.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 10:28:14 +00:00
Sebastien Boeuf
8946a09afd vm-virtio: Simplify virtio-net configuration
This commit introduces a clear definition of the virtio-net
configuration structure, allowing both vhost-user-net and
virtio-net devices to rely on it.

This makes the code more readable for developers.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 10:28:14 +00:00
Sebastien Boeuf
9efaff73fa ci: Consolidate virtio-blk integration tests
In order to reduce the amount of times VMs are being started through
integration tests, this commit consolidates very similar tests related
to virtio-blk into a single one.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 09:26:53 +01:00
Sebastien Boeuf
a33e8342ee ci: Add integration test for virtio-blk multiqueue support
Just add a new integration test to verify that multiqueue support is
correctly supported and that we can find the right amount of queues in
the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 09:26:53 +01:00
Sebastien Boeuf
f5b53ae4be vm-virtio: Implement multiqueue/multithread support for virtio-blk
This commit improves the existing virtio-blk implementation, allowing
for better I/O performance. The cost for the end user is to accept
allocating more vCPUs to the virtual machine, so that multiple I/O
threads can run in parallel.

One thing to notice, the amount of vCPUs must be egal or superior to the
amount of queues dedicated to the virtio-blk device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 09:26:53 +01:00
Sebastien Boeuf
08e47ebd4b vmm: Add num_queues and queue_size parameters to virtio-blk
The number of queues and the size of each queue were not configurable.
In anticipation for adding multiqueue support, this commit introduces
some new parameters to let the user decide about the number of queues
and the queue size.

Note that the default values for each of these parameters are identical
to the default values used for vhost-user-blk, that is 1 for the number
of queues and 128 for the queue size.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-28 09:26:53 +01:00
Samuel Ortiz
c4b3ed7223 vm-virtio: Further factorization
The trait bound and non trait bound virtio devices can use the same
inner implementation.
Also, the virtio pausable trait definiton can also be factorized.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
Samuel Ortiz
bce76271c5 vm-virtio: Define a separate macro alias for ctrl queue devices
Now that we have factorized the common virtio pausable implementation,
it's cleaner to have a dedicated macro for control queue devices rather
than overload the macro prototype.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
Samuel Ortiz
2e2b1e4230 vm-virtio: Remove the multiqueue argument from the pausable macro
We only need the ctrl queue one.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
Samuel Ortiz
2cb7ec04a4 vm-virtio: Pausable macro factorization improvements
By adding an internal layer of abstraction (the hidden VirtioPausable
trait), we can factorize the virtio common code.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
Samuel Ortiz
c06a827cbb vm-virtio: Rename epoll_thread to epoll_threads
Now that we unified epoll_thread to potentially be a vector of threads,
it makes sense to make it a plural field.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
Samuel Ortiz
f648f2856d vm-virtio: Make all virtio devices potentially multi-threaded
Although only the block and net virtio devices can actually be multi
threaded (for now), handling them as special cases makes the code more
complex.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-28 07:51:13 +01:00
dependabot-preview[bot]
ac8e4b9cb6 build(deps): bump vm-memory from 8a606cd to df6207f
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `8a606cd` to `df6207f`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](8a606cd838...df6207f1c0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 06:49:55 +00:00
dependabot-preview[bot]
45d43f9441 build(deps): bump micro_http from af25399 to 53cf1ba
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `af25399` to `53cf1ba`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](af25399667...53cf1bacad)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 06:49:37 +00:00
dependabot-preview[bot]
91747094ae build(deps): bump arrayref from 0.3.5 to 0.3.6
Bumps [arrayref](https://github.com/droundy/arrayref) from 0.3.5 to 0.3.6.
- [Release notes](https://github.com/droundy/arrayref/releases)
- [Commits](https://github.com/droundy/arrayref/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 08:56:17 +00:00
dependabot-preview[bot]
90810a9691 build(deps): bump micro_http from 1f931c6 to af25399
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `1f931c6` to `af25399`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](1f931c6649...af25399667)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 08:07:15 +00:00
dependabot-preview[bot]
16af54e583 build(deps): bump signal-hook from 0.1.12 to 0.1.13
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.12 to 0.1.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.1.12...v0.1.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-26 13:29:47 +00:00
dependabot-preview[bot]
4ff972c329 build(deps): bump ssh2 from 0.6.0 to 0.7.1
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.6.0 to 0.7.1.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.6.0...0.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-26 01:55:04 +00:00
dependabot-preview[bot]
3508440684 build(deps): bump itoa from 0.4.4 to 0.4.5
Bumps [itoa](https://github.com/dtolnay/itoa) from 0.4.4 to 0.4.5.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/0.4.4...0.4.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-25 00:14:23 +00:00
Sebastien Boeuf
0fa1e2c241 vmm: Handle mapping from devices regions through vm-memory
Devices like virtio-pmem and virtio-fs require some dedicated memory
region to be mapped. The memory mapping from the DeviceManager is being
replaced by the usage of MmapRegion from the vm-memory crate.

The unmap will happen automatically when the MmapRegion will be dropped,
which should happen when the DeviceManager gets dropped.

Fixes #240

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 17:56:49 +01:00
Sebastien Boeuf
694da82691 ci: Make the integration tests fail if images are not valid
When the CI runs in a brand new VM, there's no problem with the validity
of the images as they just got downloaded from the Azure bucket.

In case of a user who runs the CI locally, while doing some debug, he
might provision the images with cloudinit at some point, and later try
to run the CI based on these same images. What happens is that the CI
might randomly fail because the provisioning will not happen again as
it already happened.

This patch ensures the CI to fail early and show an error message to
notify the user about the validity of the images, based on their
sha1sum.

Fixes #112

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 14:02:35 +01:00
dependabot-preview[bot]
0ea6406d5b build(deps): bump vm-memory from beaf215 to 8a606cd
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `beaf215` to `8a606cd`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](beaf215905...8a606cd838)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-24 12:32:16 +00:00
Sebastien Boeuf
148a9ed5ce vmm: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
0a7bcc9a7d vm-virtio: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
4587cc7ffa vhost_user_net: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
f444ef6ccf vfio: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
aa5ae7616e src: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
cf25bd74b0 qcow: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
06396593c9 net_util: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Sebastien Boeuf
f5a52eda2b arch: Fix map_err losing the inner error
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-24 12:42:09 +01:00
Rob Bradford
a34893a402 Revert "vmm: Move MemoryManager from I/O ports to MMIO region"
This reverts commit 03108fb88b.
2020-01-24 12:08:31 +01:00
Rob Bradford
57ed006992 Revert "devices, vmm: Move GED device to MMIO region"
This reverts commit 5e3c62dc6a.
2020-01-24 12:08:31 +01:00
Rob Bradford
6120d0fb1b Revert "vmm: Move CpuManager device to MMIO region"
This reverts commit 980e03fa0a.
2020-01-24 12:08:31 +01:00
dependabot-preview[bot]
6475052692 build(deps): bump micro_http from 1db1bbd to 1f931c6
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `1db1bbd` to `1f931c6`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](1db1bbd40d...1f931c6649)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-24 06:47:58 +00:00
Rob Bradford
980e03fa0a vmm: Move CpuManager device to MMIO region
Move the CpuManager device from the I/O bus to living in an MMIO region.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 16:04:58 +00:00
Rob Bradford
5e3c62dc6a devices, vmm: Move GED device to MMIO region
Move GED device reporting of required device type to scan into an MMIO
region rather than an I/O port.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 16:04:58 +00:00
Rob Bradford
03108fb88b vmm: Move MemoryManager from I/O ports to MMIO region
Rather than have the MemoryManager device sit on the I/O bus allocate
space for MMIO and add it to the MMIO bus.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 16:04:58 +00:00
Sebastien Boeuf
3202e8ac7a vfio: Fix 64bits BAR size reading
The way to get the BAR size is by writing all 1's to the BAR register in
the PCI config space. The mechanism was in place but the parameters were
swapped. The data buffer was provided with the actual offset, while the
offset was provided with the actual all 1's dword. We were effectively
trying to write the real offset at the offset 0xffffffff, which was
failing and resulting in the size being wrong.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-23 13:07:43 +01:00
Rob Bradford
d5d4053795 README.md: Update kernel instructions to use branch
Update the kernel build instructions to use the configuration and branch
that we test and develop against.

Fixes: #521

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 12:56:52 +01:00
Sebastien Boeuf
0042f1de75 ioapic: Rely fully on the InterruptSourceGroup to manage interrupts
This commit relies on the interrupt manager and the resulting interrupt
source group to abstract the knowledge about KVM and how interrupts are
updated and delivered.

This allows the entire "devices" crate to be freed from kvm_ioctls and
kvm_bindings dependencies.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-23 11:20:08 +00:00
Sebastien Boeuf
2dca959084 ioapic: Create the InterruptSourceGroup from InterruptManager
The interrupt manager is passed to the IOAPIC creation, and the IOAPIC
now creates an InterruptSourceGroup for MSI interrupts based on it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-23 11:20:08 +00:00
Sebastien Boeuf
52800a871a vmm: Create an InterruptManager dedicated to IOAPIC
By introducing a new InterruptManager dedicated to the IOAPIC, we don't
have to solve the chicken and eggs problem about which of the
InterruptManager or the Ioapic should be created first. It's also
totally fine to have two interrupt manager instances as they both share
the same list of GSI routes and the same allocator.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-23 11:20:08 +00:00
Sebastien Boeuf
29e668c302 cargo: Update Cargo.lock
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-23 11:20:08 +00:00
Rob Bradford
cafab9e981 main: Add some command line argument conflicts
Add explicit exclusions with --net-backend from --block-backend (and
vice-versa.) And also with "--kernel" as this is the option for "VM boot" that is never optional.

Ideally we would conflcit the backend arguments against the "vm-group"
however this does not work as it includes some arguments that have a
default value set and thus clap thinks those arguments are always
provided. Conflicting with "--kernel" is thus a reasonable compromise.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
611d13ed1b main: Move logging arguments to their own group
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
8aabb9012d main: Add "--vhost-user-blk" to the "vm-config" group
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
bdb0ad98c4 tests: Use cloud-hypervisor binary for "--{net,block}-backend"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
45fb9187c5 main: Allow main binary to be used as net or block backend
Use newly factorised out function to start the block or net
vhost-user-backend.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
7f73eebbdb vhost_user_block: Split launching backend into its own function
Split the basic launching functionality into its own function in the
newly added vhost_user_block crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
9fd187c9fe vhost_user_net: Split launching backend into its own function
Split the basic launching functionality into its own function in the
newly added vhost_user_net crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
b851887738 main: Split current VMM running code into it's own function
This prepaees the main binary to start running vhost-user backends.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
1dd2451895 vhost_user_block: Refactor vhost_user_block backend code into a new crate
Extract the majority of the code that provides the vhost-user-block
backend into its own crate and port the binary to use it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
fb763c4043 vhost_user_net: Refactor vhost_user_net backend code into a new crate
Extract the majority of the code that provides the vhost-user-net
backend into its own crate and port the binary to use it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
dd82064aba main: Delay converting command line to VM params
Generate the VM params until after the logging has been enabled. This
will make it possible to reuse the logging for vhost backends.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
e12179a3e6 bin: vhost_user_net: Rename "--backend" to "--net-backend"
This will prevent it from conflicting when it is aggregated into the
cloud-hypervisor binary.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
Rob Bradford
3ede2dc53a bin: vhost_user_blk: Rename "--backend" to "--block-backend"
This will prevent it from conflicting when it is aggregated into the
cloud-hypervisor binary.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-23 10:30:06 +00:00
dependabot-preview[bot]
032b8e4c1d build(deps): bump micro_http from ebc15f2 to 1db1bbd
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `ebc15f2` to `1db1bbd`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](ebc15f2eac...1db1bbd40d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-23 06:44:46 +00:00
dependabot-preview[bot]
204f05fdf1 build(deps): bump serde_json from 1.0.44 to 1.0.45
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.44 to 1.0.45.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.44...v1.0.45)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-23 06:14:06 +00:00
dependabot-preview[bot]
7ee9ecaaf4 build(deps): bump vmm-sys-util from 0.3.1 to 0.4.0
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.3.1 to 0.4.0.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Changelog](https://github.com/rust-vmm/vmm-sys-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vmm-sys-util/compare/v0.3.1...v0.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-22 14:10:19 +00:00
Qiu Wenbo
2034fc2d84 vmm: Fix LENGTH_OFFSET_HIGH of MemoryManager
Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2020-01-22 12:33:38 +00:00
dependabot-preview[bot]
503e047c3a build(deps): bump redox_users from 0.3.3 to 0.3.4
Bumps redox_users from 0.3.3 to 0.3.4.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-22 07:39:39 +00:00
Sergio Lopez
605fa8307b ci: Add integration test for virtio-blk with 'direct=on'
Previous commit added 'direct' support for virtio-blk to be able to
open files backing disk images with O_DIRECT, so add an integration
test for this new feature.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-21 13:39:45 +00:00
Sergio Lopez
925c862f98 vmm: device_manager: Add 'direct' support for virtio-blk
vhost_user_blk already has it, so it's only fair to give it to
virtio-blk too. Extend DiskConfig with a 'direct' property, honor
it while opening the file backing the disk image, and pass it to
vm_virtio::RawFile.

Fixes #631

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-21 13:39:45 +00:00
Sergio Lopez
2bd90d9263 ci: Add integration test for virtio-blk with 'readonly=on'
Previous commit added 'readonly' support for virtio-blk to be able to
configure read-only devices, so add an integration test for this new
feature.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-21 13:39:45 +00:00
Sergio Lopez
fb79e75afc vmm: device_manager: Add read-only support for virtio-blk
vhost_user_blk already has it, so it's only fair to give it to
virtio-blk too. Extend DiskConfig with a 'readonly' properly, and pass
it to vm_virtio::Block.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-21 13:39:45 +00:00
Sebastien Boeuf
9ac06bf613 ci: Run clippy for each specific feature
The build is run against "--all-features", "pci,acpi", "pci" and "mmio"
separately. The clippy validation must be run against the same set of
features in order to validate the code is correct.

Because of these new checks, this commit includes multiple fixes
related to the errors generated when manually running the checks.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 11:44:40 +01:00
Sebastien Boeuf
e91638e6c5 pci: Cleanup the crate from unneeded types
Both InterruptDelivery and InterruptParameters can be removed from the
pci crate as they are not used anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
99f39291fd pci: Simplify PciDevice trait
There's no need for assign_irq() or assign_msix() functions from the
PciDevice trait, as we can see it's never used anywhere in the codebase.
That's why it's better to remove these methods from the trait, and
slightly adapt the existing code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
a20b383be8 vmm: Always use a reference for InterruptManager
Since the InterruptManager is never stored into any structure, it should
be passed as a reference instead of being cloned.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
bb8cd9eb24 vmm: Use LegacyUserspaceInterruptGroup for acpi device
This commit replaces the way legacy interrupts were handled with the
brand new implementation of the legacy InterruptSourceGroup for KVM.

Additionally, since it removes the last bit relying on the Interrupt
trait, the trait and its implementation can be removed from the
codebase.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
75e22ff34e vmm: Use LegacyUserspaceInterruptGroup for serial device
This commit replaces the way legacy interrupts were handled with the
brand new implementation of the legacy InterruptSourceGroup for KVM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
8d7c4ea334 vmm: Use LegacyUserspaceInterruptGroup for mmio devices
This commit replaces the way legacy interrupts were handled with the
brand new implementation of the legacy InterruptSourceGroup for KVM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
12657ef59f vmm: Fully implement LegacyUserspaceInterruptGroup
Relying on the previous commits, the legacy interrupt implementation can
be completed. The IOAPIC handler is used to deliver the interrupt that
will be triggered through the trigger() method.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
f70c9937fb vmm: Add ioapic to KvmInterruptManager
By having a reference to the IOAPIC, the KvmInterruptManager is going
to be able to initialize properly the legacy interrupt source group.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
c9ea235a0e vmm: Add LegacyUserspaceInterruptGroup skeleton for legacy interrupts
In order to be able to use the InterruptManager abstraction with
virtio-mmio devices, this commit introduces InterruptSourceGroup's
skeleton for legacy interrupts.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
2aabf58bf5 vmm: Move irq_routes creation to specific MSI use case
When KvmInterruptManager initializes a new InterruptSourceGroup, it's
only for PCI_MSI_IRQ case that it needs to allocate the GSI and create a
new InterruptRoute. That's why this commit moves the general code into
the specific use case.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
d34f31fe7b vmm: Fix KvmInterruptManager when base is different from 0
When the base InterruptIndex is different from 0, the loop allocating
GSI and HashMap entries won't work as expected. The for loop needs to
start from base, but the limit must be base+count so that we allocate
a number of "count" entries.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
Sebastien Boeuf
e73cb1ff80 vmm: Initialize InterruptManager sooner
In order to let the InterruptManager be shared across both PCI and MMIO
devices, this commit moves the initialization earlier in the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-21 10:44:48 +01:00
dependabot-preview[bot]
9fab9bc645 build(deps): bump micro_http from f77960b to ebc15f2
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `f77960b` to `ebc15f2`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](f77960b81e...ebc15f2eac)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-21 06:54:50 +00:00
dependabot-preview[bot]
9fe6ece262 build(deps): bump redox_users from 0.3.1 to 0.3.3
Bumps redox_users from 0.3.1 to 0.3.3.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 21:47:15 +00:00
dependabot-preview[bot]
c27be842e4 build(deps): bump syn from 1.0.13 to 1.0.14
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.13 to 1.0.14.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.13...1.0.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 10:21:53 +00:00
dependabot-preview[bot]
9731be1126 build(deps): bump remain from 0.2.0 to 0.2.1
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.0...0.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 08:52:00 +00:00
dependabot-preview[bot]
eedfb36c66 build(deps): bump micro_http from 6327290 to f77960b
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `6327290` to `f77960b`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](6327290424...f77960b81e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 07:10:42 +00:00
Rob Bradford
3901a1dd7d vmm: Log an error if VM resize fails
As well as returing an error to the API caller.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-17 23:44:21 +01:00
Rob Bradford
76d9bf2792 vmm: Start memory slots at zero
After refactoring a common function is used to setup these slots and
that function takes care of allocating a new slot so it is not necessary
to reserve the initial region slots.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-17 23:44:21 +01:00
Rob Bradford
0ab22fea2c vmm: Only generate GED event when new DIMM added
Avoid the ACPI scan in the guest OS when no new DIMM is hotplugged.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-17 23:44:21 +01:00
Rob Bradford
211786ab42 vmm: Only generate GED interrupt when the number of vCPUs has changed
Avoid activity in the the guest OS if the number of vCPUs has not
changed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-17 23:44:21 +01:00
Sebastien Boeuf
8049666eff vm-virtio: Cleanup from kvm_iotcls and kvm_bindings dependencies
Now that KVM specific interrupts are handled through InterruptManager
trait implementation, the vm-virtio crate does not need to rely on
kvm_ioctls and kvm_bindings crates.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
50a4c16d34 pci: Cleanup the crate from kvm_iotcls and kvm_bindings dependencies
Now that KVM specific interrupts are handled through InterruptManager
trait implementation, the pci crate does not need to rely on kvm_ioctls
and kvm_bindings crates.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
4bb12a2d8d interrupt: Reorganize all interrupt management with InterruptManager
Based on all the previous changes, we can at this point replace the
entire interrupt management with the implementation of InterruptManager
and InterruptSourceGroup traits.

By using KvmInterruptManager from the DeviceManager, we can provide both
VirtioPciDevice and VfioPciDevice a way to pick the kind of
InterruptSourceGroup they want to create. Because they choose the type
of interrupt to be MSI/MSI-X, they will be given a MsiInterruptGroup.

Both MsixConfig and MsiConfig are responsible for the update of the GSI
routes, which is why, by passing the MsiInterruptGroup to them, they can
still perform the GSI route management without knowing implementation
details. That's where the InterruptSourceGroup is powerful, as it
provides a generic way to manage interrupt, no matter the type of
interrupt and no matter which hypervisor might be in use.

Once the full replacement has been achieved, both SystemAllocator and
KVM specific dependencies can be removed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
92082ad439 vmm: Fully implement interrupt traits
After the skeleton of InterruptManager and InterruptSourceGroup traits
have been implemented, this new commit takes care of fully implementing
the content of KvmInterruptManager (InterruptManager trait) and
MsiInterruptGroup (InterruptSourceGroup).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
0f727127d5 vmm: Implement InterruptSourceGroup and InterruptManager skeleton
This commit introduces an empty implementation of both InterruptManager
and InterruptSourceGroup traits, as a proper basis for further
implementation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
11d4d57c06 vm-device: Introduce InterruptManager and InterruptSourceGroup traits
These new traits are meant to abstract the knowledge about the
hypervisor and the type of interrupt being used from the perspective
of the devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
be421dccea vm-virtio: Optimize vhost-user interrupt notification
Thanks to the recently introduced function notifier() in the
VirtioInterrupt trait, all vhost-user devices can now bypass
listening onto an intermediate event fd as they can provide the
actual fd responsible for triggering the interrupt directly to
the vhost-user backend.

In case the notifier does not provide the event fd, the code falls
back onto the creation of an intermediate event fd it needs to listen
to, so that it can trigger the interrupt on behalf of the backend.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
1f029dd2dc vm-virtio: Add notifier to VirtioInterrupt trait
The point is to be able to retrieve directly the event fd related to
the interrupt, as this might optimize the way VirtioDevice devices are
implemented.

For instance, this can be used by vhost-user devices to provide
vhost-user backends directly with the event fd triggering the
interrupt related to a virtqueue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
c396baca46 vm-virtio: Modify VirtioInterrupt callback into a trait
Callbacks are not the most Rust idiomatic way of programming. The right
way is to use a Trait to provide multiple implementation of the same
interface.

Additionally, a Trait will allow for multiple functions to be defined
while using callbacks means that a new callback must be introduced for
each new function we want to add.

For these two reasons, the current commit modifies the existing
VirtioInterrupt callback into a Trait of the same name.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
ef7d889a79 vfio: Remove unused GSI routing functions
At this point, both MSI and MSI-X handle the KVM GSI routing update,
which means the vfio crate does not have to deal with it anymore.
Therefore, several functions can be removed from the vfio-pci code, as
they are not needed anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
1a4b5ecc75 msi: Set KVM routes from MsiConfig instead of VFIO
Now that MsiConfig has access to both KVM VmFd and the list of GSI
routes, the update of the KVM GSI routes can be directly done from
MsiConfig instead of specifically from the vfio-pci implementation.

By moving the KVM GSI routes update at the MsiConfig level, any PCI
device such as vfio-pci, virtio-pci, or any other emulated PCI device
can benefit from it, without having to implement it on their own.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
f3c3870159 msi: Create MsiConfig to embed MsiCap
The same way we have MsixConfig in charge of managing whatever relates
to MSI-X vectors, we need a MsiConfig structure to manage MSI vectors.
The MsiCap structure is still needed as a low level API, but it is now
part of the MsiConfig which oversees anything related to MSI.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
1e5e02801f msix: Perform interrupt enabling/disabling
In order to factorize one step further, we let MsixConfig perform the
interrupt enabling/disabling. This is done by registering/unregistering
the KVM irq_fds of all GSI routes related to this device.

And now that MsixConfig is in charge of the irq_fds, vfio-pci must rely
on it to retrieve them and provide them to the vfio driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
19aeac40c9 msix: Remove the need for interrupt callback
Now that MsixConfig has access to the irq_fd descriptors associated with
each vector, it can directly write to it anytime it needs to trigger an
interrupt.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
3fe362e3bd msix: Set KVM routes from MsixConfig instead of VFIO
Now that MsixConfig has access to both KVM VmFd and the list of GSI
routes, the update of the KVM GSI routes can be directly done from
MsixConfig instead of specifically from the vfio-pci implementation.

By moving the KVM GSI routes update at the MsixConfig level, both
vfio-pci and virtio-pci (or any other emulated PCI device) can benefit
from it, without having to implement it on their own.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
2381f32ae0 msix: Add gsi_msi_routes to MsixConfig
Because MsixConfig will be responsible for updating KVM GSI routes at
some point, it is necessary that it can access the list of routes
contained by gsi_msi_routes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
9b60fcdc39 msix: Add VmFd to MsixConfig
Because MsixConfig will be responsible for updating the KVM GSI routes
at some point, it must have access to the VmFd to invoke the KVM ioctl
KVM_SET_GSI_ROUTING.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
86c760a0d9 msix: Add SystemAllocator to MsixConfig
The point here is to let MsixConfig take care of the GSI allocation,
which means the SystemAllocator must be passed from the vmm crate all
the way down to the pci crate.

Once this is done, the GSI allocation and irq_fd creation is performed
by MsixConfig directly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
f77d2c2d16 pci: Add some KVM and interrupt utilities to the crate
In order to anticipate the need for both msi.rs and msix.rs to rely on
some KVM utils and InterruptRoute structure to handle the update of the
KVM GSI routes, this commit adds these utilities directly to the pci
crate. So far, these were exclusively used by the vfio crate, which is
why there were located there.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sebastien Boeuf
f5704d32b3 vmm: Move gsi_msi_routes creation to be shared across all PCI devices
Because we will need to share the same list of GSI routes across
multiple PCI devices (virtio-pci, VFIO), this commit moves the creation
of such list to a higher level location in the code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-17 23:43:45 +01:00
Sergio Lopez
ed5459f268 ci: Add integration test for vhost_user_blk with 'direct'
This test is a variant of test_boot_vhost_user_blk(), named
test_boot_vhost_user_blk_direct(), that instances the vhost-user-blk
daemon with 'direct=true', to test this recently introduced feature
for opening files with O_DIRECT.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-17 17:28:44 +00:00
Sergio Lopez
e0a8da2f46 vhost_user_blk: Add missing WCE property support
Add missing WCE (write-cache enable) property support. This not only
an enhancement, but also a fix for a bug.

Right now, when vhost_user_blk uses a qcow2 image, it doesn't write
the QCOW2 metadata until the guest explicitly requests a flush. In
practice, this is equivalent to the write back semantic.

Without WCE, the guest assumes write through for the virtio_blk
device, and doesn't send those flush requests. Adding support for WCE,
and enabling it by default, we ensure the guest does send said
requests.

Supporting "WCE = false" would require updating our qcow2
implementation to ensure that, when required, it honors the write
through semantics by not deferring the updates to QCOW2 metadata.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-17 17:28:44 +00:00
Sergio Lopez
c7e9056c1e vhost_user_blk: implement support for direct (O_DIRECT) mode
Add support for opening the disk images with O_DIRECT. This allows
bypassing the host's file system cache, which is useful to avoid
polluting its cache and for better data integrity.

This mode of operation can be enabled by adding the "direct=<bool>"
parameter to the "backend" argument:

./target/debug/vhost_user_blk --backend image=test.raw,sock=/tmp/vhostblk,direct=true

The "direct" parameter defaults to "false", to preserve the original
behavior.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-17 17:28:44 +00:00
Sergio Lopez
a14aee9213 qcow: Use RawFile as backend instead of File
Use RawFile as backend instead of File. This allows us to abstract
the access to the actual image with a specialized layer, so we have a
place where we can deal with the low-level peculiarities.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-17 17:28:44 +00:00
Sergio Lopez
c5a656c9dc vm-virtio: block: Add support for alignment restrictions
Doing I/O on an image opened with O_DIRECT requires to adhere to
certain restrictions, requiring the following elements to be aligned:

 - Address of the source/destination memory buffer.
 - File offset.
 - Length of the data to be read/written.

The actual alignment value depends on various elements, and according
to open(2) "(...) there is currently no filesystem-independent
interface for an application to discover these restrictions (...)".

To discover such value, we iterate through a list of alignments
(currently, 512 and 4096) calling pread() with each one and checking
if the operation succeeded.

We also extend RawFile so it can be used as a backend for QcowFile,
so the later can be easily adapted to support O_DIRECT too.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2020-01-17 17:28:44 +00:00
Cathy Zhang
e483cde1bb docs: Update networking.md with multiple queue support
Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
973eb16ae9 src: Add multiple queue checking in vhost-user-net integration test
Update queue number with 4 to verify if vhost-user-net device
and backend could work well with multiple queue.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
4885dc0ed4 src: Update test_valid_vm_config_net with new option for virtio-net
There are two new options num_queues and queue_size defined for
virtio-net, add them in test_valid_vm_config_net which is used
to validate that both the CLI and the OpenAPI will generate the
same configuration.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
652e7b9b8a vm-virtio: Implement multiple queue support for net devices
Update the common part in net_util.rs under vm-virtio to add mq
support, meanwhile enable mq for virtio-net device, vhost-user-net
device and vhost-user-net backend. Multiple threads will be created,
one thread will be responsible to handle one queue pair separately.
To gain the better performance, it requires to have the same amount
of vcpus as queue pair numbers defined for the net device, due to
the cpu affinity.

Multiple thread support is not added for vhost-user-net backend
currently, it will be added in future.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
404316eea1 vmm: Add multiple queue option and update config for virtio-net device
Add num_queues and queue_size for virtio-net device to make them configurable,
while add the associated options in command line.

Update cloud-hypervisor.yaml with the new options for NetConfig.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
4ab88a8173 net_util: Add multiple queue support for tap
Add support to allow VMMs to open the same tap device many times, it will
create multiple file descriptors meanwhile.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
cf7e0cdf95 vm-virtio: Add multiple queue handling with control queue
Current guest kernel will check the oneline cpu count, in principle,
if the online cpu count is not smaller than the number of queue pairs
VMM reported, the net packets could be put/get to all the virtqueues,
otherwise, only the number of queue pairs that match the oneline cpu
count will have packets work with. guest kernel will send command
through control queue to tell VMMs the actual queue pair numbers which
it could currently play with. Add mq process in control queue handling
to get the queue pair number, VMM will verify if it is in a valid range,
nothing else but this.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
709f7fe607 vm-virtio: Implement control queue support for net devices
While feature VIRTIO_NET_F_CTRL_VQ is negotiated, control queue
will exits besides the Tx/Rx virtqueues, an epoll handler should
be started to monitor and handle the control queue event.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
d38787c578 vm-virtio: Add control queue support in net_util.rs
As virtio spec 1.1 said, the driver uses the control queue
to send commands to manipulate various features of the devices,
such as VIRTIO_NET_F_MQ which is required by multiple queue
support. Here add the control queue handling process.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
1ae7deb393 vm-virtio: Implement refactor for net devices and backend
Since the common parts are put into net_util.rs under vm-virtio,
refactoring code for virtio-net device, vhost-user-net device
and backend to shrink the code size and improve readability
meanwhile.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
6ae2597d19 vm-virtio: Create new module to abstract common parts for net devices
There are some common logic shared among virtio-net device, vhost-user-net
device and vhost-user-net backend, abstract those parts into net_util.rs
to improve code maintainability and readability.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
Cathy Zhang
3485e89080 vm-virtio: Stop delivering interrupt while NO_VECTOR
According to virtio spec, for used buffer notifications, if
MSI-X capability is enabled, and queue msix vector is
VIRTIO_MSI_NO_VECTOR 0xffff, the device must not deliver an
interrupt for that virtqueue.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2020-01-17 12:06:19 +01:00
dependabot-preview[bot]
1324aa451f build(deps): bump proc-macro2 from 1.0.7 to 1.0.8
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.7...1.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-17 06:58:27 +00:00
dependabot-preview[bot]
dcb6d02b98 build(deps): bump micro_http from db75e88 to 6327290
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `db75e88` to `6327290`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](db75e88e9e...6327290424)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-17 06:58:10 +00:00
dependabot-preview[bot]
cde2c4449b build(deps): bump backtrace from 0.3.41 to 0.3.42
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.41 to 0.3.42.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.41...0.3.42)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-16 10:59:19 +00:00
dependabot-preview[bot]
d8adf6a6d7 build(deps): bump micro_http from 52e21d0 to db75e88
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `52e21d0` to `db75e88`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](52e21d0f9e...db75e88e9e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-16 06:38:18 +00:00
Rob Bradford
14041e97e7 docs: Add memory resizing documentation
Add documentation for memory resizing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
32506dadfc docs: Document CPU unplug
This newly added feature wasn't yet documented.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
8b500d7873 deps: Bump vm-memory and linux-loader version
The function GuestMemory::end_addr() has been renamed to last_addr()

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
7310ab6fa7 devices, vmm: Use a bit field for ACPI GED interrupt type
Use independent bits for storing whether there is a CPU or memory device
changed when reporting changes via ACPI GED interrupt. This prevents a
later notification squashing an earlier one and ensure that hotplugging
both CPU and memory at the same time succeeds.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
d2d1248342 tests: Add test combining memory and vCPU hotplug
Test resizing with both optional parameters set in the VmResize API
works.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
2073007214 tests: Add integration test for RAM hotplug
Reuse the existing infrastructure for CPU hotplug and add a new test for
memory hotplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
351058ab0f resources: Add memory hotplug support to the kernel configuration
Add the config option for enabling memory hotplug to our recommended
kenrel configuration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
28c6652e57 vmm: Upon VmResize attempt to hotplug the memory
If a new amount of RAM is requested in the VmResize command try and
hotplug if it an increase (MemoryManager::Resize() silently ignores
decreases.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
4e414f0d84 vmm: device_manager: Scan memory devices upon GED interrupt
If there is a GED interrupt and the field indicates that the memory
device has changed triggers a scan of the memory devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
284d5e011a vmm: Add memory hotplug ACPI entries to DSDT
Generate and expose the DSDT table entries required to support memory
hotplug. The AML methods call into the MemoryManager via I/O ports
exposed as fields.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
8ecf736982 vmm: device_manager: Add the MemoryManager to the I/O bus
Now that the MemoryManager has I/O port functionality it needs to be
exposed on the I/O bus.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
1218765df2 vmm: memory_manager: Expose the slots details via an I/O port
Expose the details of hotplug RAM slots via an I/O port. This will be
consumed by the ACPI DSDT tables to report the hotplug memory details to
the guest.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
9880a2aba9 vmm: memory_manger: Add support for adding new memory to the VM
Add a "resize()" method on MemoryManager which will create a new memory
allocation based on the difference between the desired RAM amount and
the amount already in use. After allocating the added RAM using the same
backing method as the boot RAM store the details in a vector and update
the KVM map and create a new GuestMemoryMmap and replace all the users.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
82fce5a4e2 vmm: Add support for resizing the memory used by the VM
For now the new memory size is only used after a reboot but support for
hotplugging memory will be added in a later commit.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
78dcb1862c vmm: device_manager: Store the type of notification in a local value
When the value is read from the I/O port via the ACPI AML functions to
determine what has been triggered the notifiction value is reset
preventing a second read from exposing the value. If we need support
multiple types of GED notification (such as memory hotplug) then we
should avoid reading the value multiple times.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
5da7c63127 acpi_tables: aml: Add support for creating fields
These fields allow you to expose the component part of an existing
buffer, such as a resource template as a new field which is required to
expose the memory CRS details.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
f5137e84bb vmm, main: Add optional "hotplug_size" to --mem
This specifies how much address space should be reserved for hotplugging
of RAM. This space is reserved by adding move the start of the device
area by the desired amount.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
f1b6657833 vmm: Make desired vCPUs optional in resize command
In order to be able to support resizing either vCPUs or memory or both
make the fields in the resize command optional.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
72b9e920a3 vmm: memory_manager: Further refactor memory region allocation
This allows the memory regions to be allocated later which is necessary
for hotplug memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
Rob Bradford
1af11a7c92 vmm: memory_manager: Refactor GuestMemoryMmap construction
Make the GuestMemoryMmap from a Vec<Arc<GuestRegionMmap>> by using this
method we can persist a set of regions in the MemoryManager and then
extend this set with a newly created region. Ultimately that will allow
the hotplug of memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-15 20:21:22 +01:00
dependabot-preview[bot]
281b99af0a build(deps): bump micro_http from 803c8fa to 52e21d0
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `803c8fa` to `52e21d0`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](803c8fae14...52e21d0f9e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-15 07:26:59 +00:00
dependabot-preview[bot]
0acabcdd27 build(deps): bump libssh2-sys from 0.2.13 to 0.2.14
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.13 to 0.2.14.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.13...libssh2-sys-0.2.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-15 07:26:40 +00:00
dependabot-preview[bot]
85f43c7026 build(deps): bump micro_http from edbff4c to 803c8fa
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `edbff4c` to `803c8fa`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](edbff4ce62...803c8fae14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-14 06:42:28 +00:00
Samuel Ortiz
5788d36583 vmm: Do not create virtio devices when missing a transport
If neither PCI or MMIO are built in, we should not bother creating any
virtio devices at all.
When building a minimal VMM made of a kernel with an initramfs and a
serial console, the RNG virtio device is still created even though there
is no way it can ever get probed.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-14 07:42:09 +01:00
dependabot-preview[bot]
41895d7df1 build(deps): bump rand from 0.7.2 to 0.7.3
Bumps [rand](https://github.com/rust-random/rand) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 16:24:25 +00:00
dependabot-preview[bot]
85d155543e build(deps): bump micro_http from 0987cdc to edbff4c
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `0987cdc` to `edbff4c`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](0987cdc52b...edbff4ce62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 16:24:25 +00:00
dependabot-preview[bot]
3430e20f64 build(deps): bump memchr from 2.2.1 to 2.3.0
Bumps [memchr](https://github.com/BurntSushi/rust-memchr) from 2.2.1 to 2.3.0.
- [Release notes](https://github.com/BurntSushi/rust-memchr/releases)
- [Commits](https://github.com/BurntSushi/rust-memchr/compare/2.2.1...2.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 16:24:25 +00:00
dependabot-preview[bot]
7d853241ad build(deps): bump constant_time_eq from 0.1.4 to 0.1.5
Bumps [constant_time_eq](https://github.com/cesarb/constant_time_eq) from 0.1.4 to 0.1.5.
- [Release notes](https://github.com/cesarb/constant_time_eq/releases)
- [Commits](https://github.com/cesarb/constant_time_eq/compare/0.1.4...0.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 16:24:25 +00:00
dependabot-preview[bot]
fc8bfe07f3 build(deps): bump backtrace from 0.3.40 to 0.3.41
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.40 to 0.3.41.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.40...0.3.41)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 16:24:25 +00:00
Sebastien Boeuf
fa34fae55f ci: Move to personal branch for virtiofsd
The current virtio-fs-dev branch from the official repo is breaking the
build on our Azure VMs because the glibc wrapper for renameat2() syscall
does not exist. This branch fixes the problem while the maintainers are
fixing the issue upstream.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-13 15:55:34 +00:00
Sebastien Boeuf
f427d94422 virtio-fs: Update virtiofs daemon parameters
With the latest version of virtiofsd, some changes have been made
to the socket path parameter. This needs to be updated in the cloud
hypervisor codebase, so that our CI keeps running correctly.

Fixes #611

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-13 15:55:34 +00:00
dependabot-preview[bot]
345c922cb9 build(deps): bump micro_http from 0bfaf39 to 0987cdc
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `0bfaf39` to `0987cdc`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](0bfaf39af1...0987cdc52b)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-10 07:18:48 +00:00
dependabot-preview[bot]
b38beb606f build(deps): bump regex-syntax from 0.6.12 to 0.6.13
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.12 to 0.6.13.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-syntax-0.6.12...regex-syntax-0.6.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 20:55:02 +00:00
Samuel Ortiz
c2f6dfce88 vm-virtio: Fix VirtioDeviceType traits
The From and Display traits were not handling some of the enum
definitions. We no longer have a default case for Display so any future
misses will fail at build time.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-01-09 15:29:09 +01:00
dependabot-preview[bot]
9d775a140f build(deps): bump pnet from 0.23.0 to 0.25.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.23.0 to 0.25.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 08:07:19 +00:00
dependabot-preview[bot]
70d80cc064 build(deps): bump pnet_sys from 0.23.0 to 0.23.1
Bumps [pnet_sys](https://github.com/libpnet/libpnet) from 0.23.0 to 0.23.1.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 07:33:18 +00:00
dependabot-preview[bot]
f493d434ba build(deps): bump vm-memory from 467eda6 to 218afdd
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `467eda6` to `218afdd`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](467eda62ae...218afddd4f)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 07:08:08 +00:00
dependabot-preview[bot]
2500d0aaac build(deps): bump micro_http from 2953365 to 0bfaf39
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `2953365` to `0bfaf39`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](29533658e5...0bfaf39af1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 07:07:55 +00:00
dependabot-preview[bot]
279c4f91a3 build(deps): bump pnet_macros from 0.23.0 to 0.25.0
Bumps [pnet_macros](https://github.com/libpnet/libpnet) from 0.23.0 to 0.25.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 07:05:53 +00:00
Sebastien Boeuf
24cf15d2b2 vfio: Don't throw an error if a region cannot be found
Everytime we use VFIO with cloud-hypervisor, we get the following error:

ERROR:vfio/src/vfio_device.rs:440 -- Could not get region #8 info

But this is not an error per se, and should be considered as a simple
warning.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-09 08:05:35 +01:00
Sebastien Boeuf
c2ae380503 pci: Refine detection of BAR reprogramming
The current code was always considering 0xffffffff being written to the
register as a sign it was expecting to get the size, hence the BAR
reprogramming detection was stating this case was not a reprogramming
case.

Problem is, if the value 0xffffffff is directed at a 64bits BAR, this
might be the high or low part of a 64bits address which is meant to be
the new address of the BAR, which means we would miss the detection of
the BAR being reprogrammed here.

This commit improves the code using finer granularity checks in order to
detect this corner case correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-09 08:05:35 +01:00
Sebastien Boeuf
07bad79fd7 pci: Fix detection of expansion ROM BAR reprogramming
The expansion ROM BAR reprogramming was being triggered for the wrong
reason and was causing the following error to be reported:

ERROR:pci/src/bus.rs:207 -- Failed moving device BAR: failed allocating
new 32 bits MMIO range

Following the PCI specification, here is what is defined:

Device independent configuration software can determine how much address
space the device requires by writing a value of all 1's to the address
portion of the register and then reading the value back.

This means we cannot expect 0xffffffff to be written, as the address
portion corresponds to the bits 31-11. That's why whenever the size of
this special BAR is being asked for, the value being written is
0xfffff800.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-09 08:05:35 +01:00
dependabot-preview[bot]
0d2e38db25 build(deps): bump cc from 1.0.49 to 1.0.50
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.49 to 1.0.50.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.49...1.0.50)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-08 17:00:07 +00:00
Sebastien Boeuf
38468d3d9b vm-virtio: Improve virtio-console input processing
The way the code is currently implemented, only by writing to STDIN a
user can trigger some input to reach the VM through virtio-console. But
in case, there were not enough virtio descriptors to process what was
retrieved from STDIN, the remaining bits would be transferred only if
STDIN was triggered again. The missing part is that when some
descriptors are made available from the guest, the virtio-console device
should try to send any possible remaining bits.

By triggering the function process_input_queue() whenever the guest
notifies the host that some new descriptors are ready for the receive
queue, this patch allows to fill the implementation void that was left.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 15:37:02 +01:00
Sebastien Boeuf
e4c3401a33 vm-virtio: Don't waste a descriptor if not filled
In case the virtio descriptor is pulled out of the Queue iterator, it
is important to fill it and tag it as used. This is already done from
the successful code path, but in case there's an error during the
filling, we should make sure to put the descriptor back in the list of
available descriptors. This way, when the error occurs, we don't loose
a descriptor, and it could be used later.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 15:37:02 +01:00
Sebastien Boeuf
7a3e6caca4 vm-virtio: Simplify virtio-console input processing
The existing code was a bit too complex and it was introducing a bug
when trying to paste long lines directly to the console. By simplifying
the code, and by doing proper usage of the drain() function, the bug is
fixed by this commit.

Here is the similar output one could have gotten from time to time, when
pasting important amounts of bytes:

ERROR:vm-virtio/src/console.rs:104 -- Failed to write slice:
InvalidGuestAddress(GuestAddress(1040617472))

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 15:37:02 +01:00
Sebastien Boeuf
ad223f2b50 fs: Use cache=none by default
The cache= option from the virtiofsd backend is meant to be used
depending on how the user wants to use the guest page cache. For most
use cases, we want to bypass the guest page cache to reduce the guest
memory footprint, which is why "cache=none" should be the default.

"cache=always" is the other option when the user wants to do something
specific by using the guest page cache, but should not be the default
anymore.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
84445aae93 vm-virtio: Implement multi-mapping for virtio-fs
The virtio-fs messages coming from the slave can contain multiple
mappings (up to 8) through one single request. By implementing such
feature, the virtio-fs implementation of cloud-hypervisor is optimal and
fully functional as it resolves a bug that was seen when running fio
testing without this patch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
143471b739 fs: Update mount command to mount virtiofs filesystem
With latest kernel, virtio-fs mount command has been simplified, and
this needs to be applied everywhere in our tests and documentation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
e1822cfdad vm-virtio: Implement VIRTIO_IOMMU_F_PROBE feature
By implementing this virtio feature, we let the virtio-iommu driver call
the device backend so that it can probe each device that gets attached.

Through this probing, the device provides a range of reserved memory
related to MSI. This is mandatory for x86 architecture as we want to
avoid the default MSI range assigned by the virtio-iommu driver if no
range is provided at all. The default range is 0x8000000-0x80FFFFF but
it only makes sense for ARM architectures.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
ae6f27277b acpi: Introduce VIOT to support latest virtio-iommu implementation
Because virtio-iommu is still evolving (as it's only partly upstream),
some pieces like the ACPI declaration of the different nodes and devices
attached to the virtual IOMMU are changing.

This patch introduces a new ACPI table called VIOT, standing as the high
level table overseeing the IORT table and associated subtables.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
4dbb33a1fa resources: Update kernel config
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
Sebastien Boeuf
c56af8daeb ci: Use a temporary kernel branch before we override the current one
In order to validate the newly created virtio-fs-virtio-iommu-5.5-rc1
branch is not breaking anything in our CI, we must try it as a temporary
branch before we can override virtio-fs-virtio-iommu.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-01-08 09:27:07 +01:00
dependabot-preview[bot]
d756844096 build(deps): bump getrandom from 0.1.13 to 0.1.14
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.1.13 to 0.1.14.
- [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.1.13...v0.1.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 13:54:27 +00:00
dependabot-preview[bot]
9d3f656572 build(deps): bump cc from 1.0.48 to 1.0.49
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.48 to 1.0.49.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.48...1.0.49)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 08:14:13 +00:00
dependabot-preview[bot]
f59665e8aa build(deps): bump epoll from 4.0.1 to 4.1.0
Bumps [epoll](https://github.com/nathansizemore/epoll) from 4.0.1 to 4.1.0.
- [Release notes](https://github.com/nathansizemore/epoll/releases)
- [Commits](https://github.com/nathansizemore/epoll/compare/4.0.1...4.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 07:39:59 +00:00
dependabot-preview[bot]
9482ded365 build(deps): bump micro_http from aec25f9 to 2953365
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `aec25f9` to `2953365`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](aec25f9e5a...29533658e5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 07:08:03 +00:00
dependabot-preview[bot]
e4ea60dd96 build(deps): bump rand from 0.7.0 to 0.7.2
Bumps [rand](https://github.com/rust-random/rand) from 0.7.0 to 0.7.2.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.7.0...0.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 08:32:44 +00:00
dependabot-preview[bot]
44dd056647 build(deps): bump remain from 0.1.5 to 0.2.0
Bumps [remain](https://github.com/dtolnay/remain) from 0.1.5 to 0.2.0.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.1.5...0.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 08:26:02 +00:00
dependabot-preview[bot]
091c9d9f93 build(deps): bump pnet from 0.22.0 to 0.23.0
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.22.0 to 0.23.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/commits/v0.23.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:53:56 +00:00
dependabot-preview[bot]
d8c3912a18 build(deps): bump micro_http from be97831 to aec25f9
Bumps [micro_http](https://github.com/firecracker-microvm/firecracker) from `be97831` to `aec25f9`.
- [Release notes](https://github.com/firecracker-microvm/firecracker/releases)
- [Commits](be978312ea...aec25f9e5a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:26:24 +00:00
dependabot-preview[bot]
1a28f64d5d build(deps): bump atty from 0.2.13 to 0.2.14
Bumps [atty](https://github.com/softprops/atty) from 0.2.13 to 0.2.14.
- [Release notes](https://github.com/softprops/atty/releases)
- [Changelog](https://github.com/softprops/atty/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/atty/compare/0.2.13...0.2.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:26:09 +00:00
dependabot-preview[bot]
8f6cbf849a build(deps): bump vm-memory from 291dc2e to 467eda6
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `291dc2e` to `467eda6`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](291dc2e236...467eda62ae)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:25:53 +00:00
dependabot-preview[bot]
5a0d01ca13 build(deps): bump blake2b_simd from 0.5.9 to 0.5.10
Bumps [blake2b_simd](https://github.com/oconnor663/blake2_simd) from 0.5.9 to 0.5.10.
- [Release notes](https://github.com/oconnor663/blake2_simd/releases)
- [Commits](https://github.com/oconnor663/blake2_simd/compare/0.5.9...0.5.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-05 09:03:50 +00:00
dependabot-preview[bot]
38c0d328c2 build(deps): bump syn from 1.0.12 to 1.0.13
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.12 to 1.0.13.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.12...1.0.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-03 17:50:44 +00:00
Rob Bradford
134bcd84e6 tests: Use the workspace to unit test all the crates
Make all the crates members of the workspace so that "cargo test
--workspace" will find them all and test them with the features enabled
that we use.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-03 10:20:53 +01:00
Rob Bradford
b6f6772df4 vhost_rs: Fix compile failure in tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-03 10:20:53 +01:00
Rob Bradford
cf1983c70e vhost_rs: Mark some broken tests ignored
If we use the workspace based testing methodology then we start testing
some code inside vhost_rs that is broken.

See #576

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-03 10:20:53 +01:00
Rob Bradford
32a39f9b95 vm-virtio: Fix broken write_base_regs() unit test
The following commit broke this unit test:

"""
vmm: Convert virtio devices to Arc<Mutex<T>>

Migratable devices can be virtio or legacy devices.
In any case, they can potentially be tracked through one of the IO bus
as an Arc<Mutex<dyn BusDevice>>. In order for the DeviceManager to also
keep track of such devices as Migratable trait objects, they must be
shared as mutable atomic references, i.e. Arc<Mutex<T>>. That forces all
Migratable objects to be tracked as Arc<Mutex<dyn Migratable>>.

Virtio devices are typically migratable, and thus for them to be
referenced by the DeviceManager, they now should be built as
Arc<Mutex<VirtioDevice>>.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
"""

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-03 10:20:53 +01:00
Rob Bradford
b2589d4f3f vm-virtio, vmm, vfio: Store GuestMemoryMmap in an Arc<ArcSwap<T>>
This allows us to change the memory map that is being used by the
devices via an atomic swap (by replacing the map with another one). The
ArcSwap provides the mechanism for atomically swapping from to another
whilst still giving good read performace. It is inside an Arc so that we
can use a single ArcSwap for all users.

Not covered by this change is replacing the GuestMemoryMmap itself.

This change also removes some vertical whitespace from use blocks in the
files that this commit also changed. Vertical whitespace was being used
inconsistently and broke rustfmt's behaviour of ordering the imports as
it would only do it within the block.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-01-02 13:20:11 +00:00
dependabot-preview[bot]
5c0bb38a65 build(deps): bump vm-memory from 09c119f to 291dc2e
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `09c119f` to `291dc2e`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](09c119f742...291dc2e236)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-02 08:03:05 +00:00
dependabot-preview[bot]
b9971302be build(deps): bump syn from 1.0.11 to 1.0.12
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.11...1.0.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-02 08:02:34 +00:00
dependabot-preview[bot]
fda8a04ec2 build(deps): bump vm-memory from 3ef06be to 09c119f
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `3ef06be` to `09c119f`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](3ef06beaea...09c119f742)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-26 07:07:41 +00:00
dependabot-preview[bot]
34e35c9ae0 build(deps): bump anyhow from 1.0.25 to 1.0.26
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.25 to 1.0.26.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.25...1.0.26)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-24 07:00:35 +00:00
dependabot-preview[bot]
95352db1e5 build(deps): bump vm-memory from ec69de9 to 3ef06be
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `ec69de9` to `3ef06be`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](ec69de9c07...3ef06beaea)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-24 07:00:00 +00:00
Rob Bradford
a551398135 vmm: device_manager: Use MemoryManager to create KVM mapping
Use the newly exported funtionality to reduce the amount of duplicated
code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-23 10:25:40 +00:00
Rob Bradford
962dec2913 vmm: memory_manager: Refactor KVM userspace mapping creation
This function will be useful for other parts of the VMM that also
estabilish their own mappings.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-23 10:25:40 +00:00
Rob Bradford
7df88793a0 vmm: device_manager: Get device range from MemoryManager
This removes the duplication of these values.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-23 10:25:40 +00:00
Rob Bradford
61cfe3e72d vmm: Obtain sequential KVM memory slot numbers from MemoryManager
This removes the need to handle a mutable integer and also centralises
the allocation of these slot numbers.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-23 10:25:40 +00:00
Rob Bradford
260cebb8cf vmm: Introduce MemoryManager
The memory manager is responsible for setting up the guest memory and in
the long term will also handle addition of guest memory.

In this commit move code for creating the backing memory and populating
the allocator into the new implementation trying to make as minimal
changes to other code as possible.

Follow on commits will further reduce some of the duplicated code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-23 10:25:40 +00:00
dependabot-preview[bot]
bcfe546ea2 build(deps): bump vm-memory from bb29ec8 to ec69de9
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `bb29ec8` to `ec69de9`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](bb29ec8713...ec69de9c07)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 07:11:13 +00:00
Sebastien Boeuf
f668603694 ci: Fix flaky test_memory_mergeable_on test
Because we don't always reach the expected footprint improvements with
KSM, let's review the numbers. By reducing the expectations and
increasing the amount of pages to scan, this should stabilize the CI.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-20 13:44:22 +00:00
Rob Bradford
1e3fd2f6a5 tests: Remove many redundant clones
As found by updated clippy:

e.g:

error: redundant clone
    --> src/main.rs:1590:57
     |
1590 |             let mut osdisk_raw_base_path = workload_path.clone();
     |                                                         ^^^^^^^^ help: remove this
     |
     = note: `-D clippy::redundant-clone` implied by `-D warnings`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Rob Bradford
d5682cd306 vmm: device_manager: Rewrite if chain using match
To reflect updated clippy rules:

error: `if` chain can be rewritten with `match`
    --> vmm/src/device_manager.rs:1508:25
     |
1508 | /                         if ret > 0 {
1509 | |                             debug!("MSI message successfully delivered");
1510 | |                         } else if ret == 0 {
1511 | |                             warn!("failed to deliver MSI message, blocked by guest");
1512 | |                         }
     | |_________________________^
     |
     = note: `-D clippy::comparison-chain` implied by `-D warnings`
     = help: Consider rewriting the `if` chain to use `cmp` and `match`.
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Rob Bradford
21b88c3ea0 vmm: cpu: Rewrite if chain using match
Address updated clippy error:

error: `if` chain can be rewritten with `match`
   --> vmm/src/cpu.rs:668:9
    |
668 | /         if desired_vcpus > self.present_vcpus() {
669 | |             self.activate_vcpus(desired_vcpus, None)?;
670 | |         } else if desired_vcpus < self.present_vcpus() {
671 | |             self.mark_vcpus_for_removal(desired_vcpus)?;
672 | |         }
    | |_________^
    |
    = note: `-D clippy::comparison-chain` implied by `-D warnings`
    = help: Consider rewriting the `if` chain to use `cmp` and `match`.
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Rob Bradford
e25a47b32c vmm: device_manager: Remove redundant clones
Address updated clippy errors:

error: redundant clone
   --> vmm/src/device_manager.rs:699:32
    |
699 |             .insert(acpi_device.clone(), 0x3c0, 0x4)
    |                                ^^^^^^^^ help: remove this
    |
    = note: `-D clippy::redundant-clone` implied by `-D warnings`
note: this value is dropped without further use
   --> vmm/src/device_manager.rs:699:21
    |
699 |             .insert(acpi_device.clone(), 0x3c0, 0x4)
    |                     ^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone

error: redundant clone
   --> vmm/src/device_manager.rs:737:26
    |
737 |             .insert(i8042.clone(), 0x61, 0x4)
    |                          ^^^^^^^^ help: remove this
    |
note: this value is dropped without further use
   --> vmm/src/device_manager.rs:737:21
    |
737 |             .insert(i8042.clone(), 0x61, 0x4)
    |                     ^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone

error: redundant clone
   --> vmm/src/device_manager.rs:754:29
    |
754 |                 .insert(cmos.clone(), 0x70, 0x2)
    |                             ^^^^^^^^ help: remove this
    |
note: this value is dropped without further use
   --> vmm/src/device_manager.rs:754:25
    |
754 |                 .insert(cmos.clone(), 0x70, 0x2)
    |                         ^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Rob Bradford
9fb1c46cd1 vm-virtio: Remove unnecessary cloning
Found by updated clippy:

error: redundant clone
   --> vm-virtio/src/block.rs:182:5
    |
182 |     .to_owned();
    |     ^^^^^^^^^^^ help: remove this
    |
    = note: `-D clippy::redundant-clone` implied by `-D warnings`
note: this value is dropped without further use
   --> vm-virtio/src/block.rs:176:21
    |
176 |       let device_id = format!(
    |  _____________________^
177 | |         "{}{}{}",
178 | |         blk_metadata.st_dev(),
179 | |         blk_metadata.st_rdev(),
180 | |         blk_metadata.st_ino()
181 | |     )
182 | |     .to_owned();
    | |____^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Rob Bradford
deb3cbd501 arch_gen: Remove unused bootparam module
We use the version that's included in the linux-loader crate. This old
version was also generating build errors after updating to the new
clippy:

e.g.:

error: unsafe function's docs miss `# Safety` section
  --> arch_gen/src/x86/bootparam.rs:23:5
   |
23 | /     pub unsafe fn as_ptr(&self) -> *const T {
24 | |         ::std::mem::transmute(self)
25 | |     }
   | |_____^
   |
   = note: `-D clippy::missing-safety-doc` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-20 00:52:03 +01:00
Sebastien Boeuf
9701fde209 vm-virtio: Add connection handshake to vsock
This patch has been cherry-picked from the Firecracker tree. The
reference commit is 1db04ccc69862f30b7814f30024d112d1b86b80e.

Changed the host-initiated vsock connection protocol to include a
trivial handshake.

The new protocol looks like this:
- [host] CONNECT <port><LF>
- [guest/success] OK <assigned_host_port><LF>

On connection failure, the host host connection is reset without any
accompanying message, as before.

This allows host software to more easily detect connection failures, for
instance when attempting to connect to a guest server that may have not
yet started listening for client connections.

Signed-off-by: Dan Horobeanu <dhr@amazon.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-19 09:48:17 +01:00
Yang Zhong
5c4e1726f8 ci: test the vhost-user-blk readonly function
This patch is to check if block device is readonly
when backend set readonly=true.

The lsblk command can show the RO value in the guest.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-12-18 09:45:11 +01:00
Yang Zhong
cee01edb97 vhost-user-blk backend: add readonly support
The current backend only support rw, and we also need
add readonly support.

The new command:
vhost_user_blk \
  --backend "image=/home/test.img, \
            sock=/home/path/vhost.socket, \
            readonly=true"

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-12-18 09:45:11 +01:00
Rob Bradford
91549ddd71 tests: Add integration test for CPU unplug
Enhance the CPU hotplug test to also unplug the CPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-18 08:23:53 +00:00
Rob Bradford
a6878accd5 vmm: cpu: Implement CPU removal
When the running OS has been told that a CPU should be removed it will
shutdown the CPU and then signal to the hypervisor via the "_EJ0" method
on the device that ultimately writes into an I/O port than the vCPU
should be shutdown. Upon notification the hypervisor signals to the
individual thread that it should shutdown and waits for that thread to
end.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-18 08:23:53 +00:00
Rob Bradford
7b3fc72aea vmm: cpu: Notify guest OS that it should offline vCPUs
Allow the resizing of the number of vCPUs to less than the current
active vCPUs. This does not currently remove them from the system but
the kernel will take them offline.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-18 08:23:53 +00:00
Rob Bradford
7e81b0ded7 vmm: cpu: Create vCPU state for all possible vCPUs
This will make it more straightforward when we attempt to remove vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-18 08:23:53 +00:00
Rob Bradford
156ea392a2 vmm: cpu: Only do ACPI notify on newly added vCPUs
When we add a vCPU set an "inserting" boolean that is exposed as an ACPI
field that will be checked for and reset when the ACPI GED notification
for CPU devices happens.

This change is a precursor for CPU unplug.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-16 23:57:14 +01:00
Rob Bradford
e8313e3e69 vmm: acpi: Refactor ACPI CPU notification
Continue to notify on all vCPUs but instead separate the notification
functionality into two methods, CSCN that walks through all the CPUs
and CTFY which notifies based on the numerical CPU id. This is an
interim step towards only notifying on changed CPUs and ultimately CPU
removal.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-16 23:57:14 +01:00
Sebastien Boeuf
43d2e09e1f ci: Add unit tests to compare CLI and OpenAPI
The goal here is to ensure that CLI and OpenAPI both behave as closely
as possible, and also that they behave as expected.

Leveraging the reorganization of the code, we can now compare two
VmConfig structures generated from one CLI entry on one side, and from
an OpenAPI entry (JSON payload) on the other side.

Fixes #535

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
Sebastien Boeuf
d1390906c8 vmm: config: Derive Debug and PartialEq for configuration structures
In anticipation for the writing of unit tests comparing two VmConfig
structures, this commit derives the PartialEq trait for VmConfig and
all embedded structures.

This patch also derives the Debug trait for the same set of structures
so that we can print them to facilitate debugging.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
Sebastien Boeuf
93f5f6ed45 vmm: config: Provide a default empty command line through OpenAPI
The OpenAPI should not have to provide a command line since the CLI
considers the command line as an empty string if nothing is provided.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
Sebastien Boeuf
43bd0e53c4 main: Move VmParams creation into a dedicated function
This brings more modularity to the code, which will be helpful when we
will later test the CLI and OpenAPI generate the same VmConfig output.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
Sebastien Boeuf
17a167dbb6 main: Move default values preparation into a dedicated function
This brings more modularity to the code, which will be helpful when we
will later test the CLI and OpenAPI generate the same VmConfig output.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
Sebastien Boeuf
9c3a7ddcc9 main: Move clap::App creation into a dedicated function
This brings more modularity to the code, which will be helpful when we
will later test the CLI and OpenAPI generate the same VmConfig output.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-16 16:48:59 +01:00
dependabot-preview[bot]
11750efb78 build(deps): bump log from 0.4.8 to 0.4.10
Bumps [log](https://github.com/rust-lang/log) from 0.4.8 to 0.4.10.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.8...0.4.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 14:46:05 +00:00
dependabot-preview[bot]
dea5776fb9 build(deps): bump serde from 1.0.103 to 1.0.104
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.103 to 1.0.104.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.103...v1.0.104)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 08:15:47 +00:00
dependabot-preview[bot]
7909f7a8c9 build(deps): bump serde_derive from 1.0.103 to 1.0.104
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.103 to 1.0.104.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.103...v1.0.104)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:05:03 +00:00
Rob Bradford
23150f8647 tests: Throttle tests based on disk space
On our CI the /tmp filesystem is mounted as tmpfs and this is the
location where the test disk images are located. When the CI worker
nodes have less memory and fewer CPUs the tmpfs fills up as the tests
run in parallel.

Introduce a mechanism to reduce the parallelism of the tests based on
starvation of the tmpfs disk availability.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-13 16:42:59 +01:00
Rob Bradford
d59fe4eee7 ci: Add some time measurements to CI scripts
Add some use of "time" to measure the wallclock time for various items
within our CI scripts.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-13 13:42:52 +00:00
Samuel Ortiz
fa0fdc6500 cargo: Update Cargo.lock for the 0.4.0 release
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-13 12:21:13 +01:00
Samuel Ortiz
cec884e863 release: v0.4.0
Expand release notes and bump Cargo.toml.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-13 11:42:59 +01:00
Rob Bradford
6444e29b04 docs: Add CPU hot plug documentation
Add details of how to add vCPUs to the running VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-13 10:34:41 +00:00
dependabot-preview[bot]
a002093a55 build(deps): bump anyhow from 1.0.23 to 1.0.25
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.23 to 1.0.25.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.23...1.0.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-13 08:29:30 +01:00
dependabot-preview[bot]
43f0478fa8 build(deps): bump thiserror from 1.0.6 to 1.0.9
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.6 to 1.0.9.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.6...1.0.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-13 06:38:08 +00:00
Samuel Ortiz
664431ff14 vsock: vhost_user: vfio: Fix potential host memory overflow
The vsock packets that we're building are resolving guest addresses to
host ones and use the latter as raw pointers.
If the corresponding guest mapped buffer spans across several regions in
the guest, they will do so in the host as well. Since we have no
guarantees that host regions are contiguous, it may lead the VMM into
trying to access memory outside of its memory space.

For now we fix that by ensuring that the guest buffers do not span
across several regions. If they do, we error out.
Ideally, we should enhance the rust-vmm memory model to support safe
acces across host regions.

Fixes CVE-2019-18960

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 22:15:50 +01:00
Rob Bradford
1e97d1413e README: Update for newer distribution support
Highlight that we support Ubuntu Bionic and Eoan as well as Clear Linux
and update the Clear Linux versions referenced.

Also update the firmware URL to point to the latest version.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-12 13:36:28 +01:00
Samuel Ortiz
e8e21aeb7e README: Update the --cpus command line examples
We recommend to specify the boot cpus, even though the old syntax is still
supported.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 11:55:37 +00:00
Sebastien Boeuf
a40a70ad86 ci: Rely on latest virtiofsd version
Virtio-fs maintainers recently updated the virtiofsd daemon through
their official branch on Gitlab. It includes fixes that were needed for
cloud-hypervisor to work correctly with it.

Jenkinsfile needs to be updated since the virtiofsd build requires both
libseccomp and libcap-ng to be present on the system.

One thing to notice, because the latest branch introduced a change
regarding libfuse behavior, the counterpart patch has been added to the
custom kernel branch "virtio-fs-virtio-iommu".

Fixes #536

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-12 11:09:36 +01:00
Samuel Ortiz
f0b7412495 vmm: device_manager: Add all virtio devices to the migratable list
We want to track all migratable devices through the DeviceManager.

Fixes: #341

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
37557c8b35 vmm: vm: Implement the Pausable trait
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
9756fc2dd0 vmm: cpu_manager: Implement the Pausable trait
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
35dd1523c9 vmm: device_manager: Implement the Pausable trait
Since the Snapshotable placeholder and Migratable traits are provided as
well, the DeviceManager object and all its objects are now Migratable.

All Migratable devices are tracked as Arc<Mutex<dyn Migratable>>
references.

Keeping track of all migratable devices allows for implementing the
Migratable trait for the DeviceManager structure, making the whole
device model potentially migratable.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
a122da4bef vm-virtio: vhost: Implement the Pausable trait for all vhost-user devices
Due to the amount of code currently duplicated across vhost-user devices,
the stats for this commit is on the large side but it's mostly more
duplicated code, unfortunately.

Migratable and Snapshotable placeholder implementations are provided as
well, making all vhost-user devices Migratable.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
dae0b2ef72 vm-virtio: Implement the Pausable trait for all virtio devices
Due to the amount of code currently duplicated across virtio devices,
the stats for this commit is on the large side but it's mostly more
duplicated code, unfortunately.

Migratable and Snapshotable placeholder implementations are provided as
well, making all virtio devices Migratable.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
35d7721683 vmm: Convert virtio devices to Arc<Mutex<T>>
Migratable devices can be virtio or legacy devices.
In any case, they can potentially be tracked through one of the IO bus
as an Arc<Mutex<dyn BusDevice>>. In order for the DeviceManager to also
keep track of such devices as Migratable trait objects, they must be
shared as mutable atomic references, i.e. Arc<Mutex<T>>. That forces all
Migratable objects to be tracked as Arc<Mutex<dyn Migratable>>.

Virtio devices are typically migratable, and thus for them to be
referenced by the DeviceManager, they now should be built as
Arc<Mutex<VirtioDevice>>.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
5450de0f5e cargo: Do not run fmt on anyhow's build code
The anyhow crate generates some incorrectly indented code from its
build.rs code. We don't want to run cargo fmt on this code.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Samuel Ortiz
0361df4ae0 vm-device: Initial Migratable trait
The Migratable trait groups all expected capabilities of devices and
components that can be migrated.

For a component to be migrated, it must be able to pause and resume.
Once paused, it should be able to provide a snapshot of itself. It
should also be able to restore itself from a snaphot.

As a consequence, the Migratable trait will be split between the
Pausable and the Snapshotable traits. This commit only adds the
Pausable one.

All migratable devices will be tracked from the DeviceManager.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-12-12 08:50:36 +01:00
Rob Bradford
36daf9c0b0 ci: Skip testing RFC or WIP PRs
To alleviate load on the CI only test PRs that are not marked as RFC or
WIP.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-11 18:22:12 +01:00
Sebastien Boeuf
64c5e3d8cb vmm: api: Adjust FsConfig for OpenAPI
The FsConfig structure has been recently adjusted so that the default
value matches between OpenAPI and CLI. Unfortunately, with the current
description, there is no way from the OpenAPI to describe a cache_size
value "None", so that DAX does not get enabled. Usually, using a Rust
"Option" works because the default value is None. But in this case, the
default value is Some(8G), which means we cannot describe a None.

This commit tackles the problem, introducing an explicit parameter
"dax", and leaving "cache_size" as a simple u64 integer.

This way, the default value is dax=true and cache_size=8G, but it lets
the opportunity to disable DAX entirely with dax=false, which will
simply ignore the cache_size value.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
4bfd51cc42 vmm: api: Match VhostUserBlkConfig defaults between CLI and HTTP API
In order to let the CLI and the HTTP API behave the same regarding the
VhostUserBlkConfig structure, this patch defines some default values
for num_queues, queue_size and wce.

num_queues is 1, queue_size is 128 and wce is true.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
1c2587f8cb vmm: api: Match VhostUserNetConfig defaults between CLI and HTTP API
In order to let the CLI and the HTTP API behave the same regarding the
VhostUserNetConfig structure, this patch defines some default values
for num_queues, queue_size and mac.

num_queues is 2 since that's a pair of TX/RX queues, queue_size is 256
and mac is a randomly generated value.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
5e0bbf9c3b vmm: Don't factorize vhost-user configurations
We want to set different default configurations for vhost-user-net and
vhost-user-blk, which is the reason why the common part corresponding to
the number of queues and the queue size cannot be embedded.

This prepares for the following commit, matching API and CLI behaviors.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
793327cff8 vmm: api: Make ConsoleConfig default match between CLI and HTTP API
A simple patch making sure the field "file" is provisioned with the same
default value through CLI and OpenAPI.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
cc08c44cb9 vmm: api: Make MemoryConfig default match between CLI and HTTP API
Just making sure we have a serde default for the field "file" since it
is not a required field in the OpenAPI definition.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
5a72225856 vmm: api: Update CpuConfig name to match the internal name
All structures match between the OpenAPI definition and the internal
configuration code, that's why CpuConfig is being renamed into
CpusConfig.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Sebastien Boeuf
f7c215d92d cli: Fix default CPU argument
By default, and in order to avoid falling into the legacy CLI usage, the
CPU argument should at least include "boot=" to define the number of
CPUs.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 15:50:24 +00:00
Rob Bradford
59ae01ff71 ci: Cancel older builders on Jenkins
When a new build is triggered cancel any older builds to conserve
resources.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-11 15:50:01 +00:00
Rob Bradford
c61104df47 vmm: Port to latest vmm-sys-util
The signal handling for vCPU signals has changed in the latest release
so switch to the new API.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-11 14:11:11 +00:00
Sebastien Boeuf
4c92f89f0f ci: Add OpenAPI validation
We need to validate that OpenAPI YAML definition is not broken by each
and every pull request. The easiest way is to rely on the Docker image
provided by OpenAPITools, as it allows us to validate the definition
with one simple command.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 12:53:31 +00:00
Sebastien Boeuf
93bd88e681 ci: Simplify travis.yml
Now that Cargo tests are being run on the worker node directly, we can
leave the bare minimum in Travis, which is taking care of the release
deployment.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 12:53:31 +00:00
Sebastien Boeuf
d42ef186a1 ci: Offload cargo tests to the worker node VM
Because the resources on the amount of worker nodes we can have access
to through Travis is limited, we offload the burden of running all tests
related to Cargo inside the Azure VM directly.

This will have the positive effect of stopping the build very early in
case something goes wrong during the Cargo testing.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-11 12:53:31 +00:00
Sebastien Boeuf
ee528ae808 vmm: api: Make FsConfig defaults match between CLI and HTTP API
In order to let the CLI and the HTTP API behave the same regarding the
FsConfig structure, this patch defines some default values for
num_queues, queue_size and the cache_size.

num_queues is set to 1, queue_size is set to 1024, and cache_size is set
to Some(8G) which means that DAX is enabled by default with a shared
region of 8GiB.

Fixes #508

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-09 23:42:23 -08:00
Sebastien Boeuf
befd342da4 vmm: api: Make NetConfig defaults match between CLI and HTTP API
In order to let the CLI and the HTTP API behave the same regarding the
NetConfig structure, this patch defines some default values for tap, ip,
mask, mac and iommu.

tap is None, ip is 192.168.249.1, mask is 255.255.255.0, mac is a
randomly generated value, and iommu is false.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-09 23:19:24 -08:00
Sebastien Boeuf
eff78f746a resources: Prevent kernel config interactive shell from showing up
Following the recent addition of CONFIG_EXPERT=y, the kernel config now
asks for several options through interactive shell. This is not
convenient when locally running the integration tests script as the
shell asks for input.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-10 06:24:11 +01:00
Jose Carlos Venegas Munoz
99e608c240 openapi: Fix schema
Fix openapi schema to be a valid yaml.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-12-09 14:30:15 -08:00
Rob Bradford
f994665610 vmm: Reduce the minimum IRQ constant
Now that the GED device does not use a hardcoded IRQ number the starting
IRQ number can be restored (needed for the hardcoded serial port IRQ.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-09 16:58:00 +00:00
Rob Bradford
ba59c62044 vmm, devices: Remove hardcoded IRQ number for GED device
Remove the previously hardcoded IRQ number used for the GED device.
Instead allocate the IRQ using the allocator and use that value in the
definition in the ACPI device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-09 16:58:00 +00:00
Qiu Wenbo
ce1bd9c7ff resources: turn on CONFIG_ACPI_REDUCED_HARDWARE_ONLY
We need turn on CONFIG_ACPI_REDUCED_HARDWARE_ONLY to support cpu hotplug
feature.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2019-12-09 10:49:17 +01:00
dependabot-preview[bot]
0374c3dc71 build(deps): bump ssh2 from 0.5.0 to 0.6.0
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.5.0...0.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 05:53:30 +00:00
Sebastien Boeuf
aa94e9b8f3 Revert "vmm: api: Modify FsConfig to be OpenAPI friendly"
This reverts commit defc5dcd9c.
2019-12-06 18:08:10 +00:00
Rob Bradford
9b1ba14f2d vmm: Delegate device related ACPI DSDT table work to DeviceManager
Move the code for handling the creation of the DSDT entries for devices
into the DeviceManager.

This will make it easier to handle device hotplug and also in the future
remove some hardcoded ACPI constants.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 17:44:00 +00:00
Rob Bradford
60e6609011 vmm: Delegate CPU related ACPI tables to CpuManager
Move the code for generating the MADT (APIC) table and the DSDT
generation for CPU related functionality into the CpuManager.

There is no functional change just code rearrangement.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 17:44:00 +00:00
Sebastien Boeuf
defc5dcd9c vmm: api: Modify FsConfig to be OpenAPI friendly
When consumer of the HTTP API try to interact with cloud-hypervisor,
they have to provide the equivalent of the config structure related to
each component they need. Problem is, the Rust enum type "Option" cannot
be obtained from the OpenAPI YAML definition.

This patch intends to fix this inconsistency between what is possible
through the CLI and what's possible through the HTTP API by using simple
types bool and int64 instead of Option<u64>.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-06 06:38:48 -08:00
Sebastien Boeuf
66e00ce710 ci: Extend VFIO integration test
In order to validate that multiple devices can be passed through and
they are still fully functional, this patch extends the existing VFIO
test to pass a second virtio-net device, and verifies that both
interfaces are functional by ssh'ing into each network interface.

Fixes #503

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-06 12:53:09 +01:00
Rob Bradford
59d01712ad vmm: Remove kernel based IOAPIC handling from the device manager
Previously the device setup code assumed that if no IOAPIC was passed in
then the device should be added to the kernel irqchip. As an earlier
change meant that there was always a userspace IOAPIC this kernel based
code can be removed.

The accessor still returns an Option type to leave scope for
implementing a situation without an IOAPIC (no serial or GED device).
This change does not add support no-IOAPIC mode as the original code did
not either.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 12:34:06 +01:00
Rob Bradford
afea6a10a2 vmm: Stop initialising kernel based IOAPIC/PIC
Now that we require the modern capabilities we can stop creating a
kernel base irqchip.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 12:34:06 +01:00
Rob Bradford
9b1cb9621f vmm: Remove pin based interrupt setup for virtio devices
With MSI now required remove pin based interrupt support from all the
virtio PCI device setup.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 12:34:06 +01:00
Rob Bradford
72fb687e3f vmm: Check for required capabilities
We now require CAP_SIGNAL_MSI, CAP_TSC_DEADLINE_TIMER and
CAP_SPLIT_IRQCHIP.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-06 12:34:06 +01:00
dependabot-preview[bot]
904b1ea599 build(deps): bump unicode-width from 0.1.6 to 0.1.7
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/unicode-rs/unicode-width/releases)
- [Commits](https://github.com/unicode-rs/unicode-width/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-05 23:19:28 +00:00
Rob Bradford
fcf92d86b5 tests: Add rebooting to the CPU hotplug test
Check that the added vCPUs are still there after a reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-05 16:39:19 +00:00
Rob Bradford
f98b16f308 vmm: Update the configuration to preserve hot-plug CPUs after reboot
Update the configuration after a resize to ensure that after a reboot
the added vCPUs are preserved.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-05 16:39:19 +00:00
Rob Bradford
1722708612 vmm: Switch to storing VmConfig inside an Arc<Mutex<>>
This permits the runtime reconfiguration of the VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-05 16:39:19 +00:00
Rob Bradford
c063bb8d30 vmm: acpi: Make GED interrupt edge triggered
This was causing issues when the kernel was trying to reset the
interrupt and making the reboot fail.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-05 16:39:19 +00:00
Qiu Wenbo
e1af17d93a vmm: Restore tty to canonical mode when SIGTERM or SIGINT received
The tty mode remains raw mode when cloud-hypervisor is terminted by
SIGTERM or SIGINT. The terminal is unusable due to echoing is
disabled which is really annoying.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2019-12-05 01:29:26 -08:00
dependabot-preview[bot]
44d026bfb1 build(deps): bump serde_json from 1.0.43 to 1.0.44
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.43 to 1.0.44.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.43...v1.0.44)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 22:53:40 +00:00
dependabot-preview[bot]
a1285ea57d build(deps): bump cc from 1.0.47 to 1.0.48
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.47 to 1.0.48.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.47...1.0.48)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 16:57:32 +00:00
Sebastien Boeuf
23929f41a7 vfio: Don't override MSI Enable bit through VFIO ioctl
This commit ensures device's PCI config space is being written after
MSI/MSI-X interrupts have been enabled/disabled. In case of MSI, when
the interrupts are enabled through VFIO (using VFIO_DEVICE_SET_IRQS),
the MSI Enable bit in the MSI capability structure found in the PCI
config space is disabled by default. That's why when the guest is
enabling this bit, we first need to enable the MSI interrupts with
VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write
to the device region to update the MSI Enable bit.

Fixes #460

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-04 14:47:06 +00:00
Wu Zongyong
1dfd60b609 vfio: use correct flags to disable interrupts
The comments of vfio kernel module said that individual subindex
interrupts can be disabled using the -1 value for DATA_EVENTFD or
the index can be disabled as a whole with:
    flags = (DATA_NONE|ACTION_TRIGGER), count = 0.

Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com>
CC: Liu Jiang <gerry@linux.alibaba.com>
2019-12-04 14:47:06 +00:00
Qiu Wenbo
5208ff86c8 vmm: Detect and handle AMD SME (Secure Memory Encryption)
Some physical address bits may become reserved in page table when SME
is enabled on AMD platform. Guest will trigger a reserved bit
violation page fault in this case due to write these reserved bits to 1
in page table. We need reduce the reserved bits to get the right
physical address range.

Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2019-12-04 14:46:44 +00:00
dependabot-preview[bot]
dcfd6ffd4b build(deps): bump serde_json from 1.0.42 to 1.0.43
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.42 to 1.0.43.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.42...v1.0.43)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 11:31:05 +00:00
Sebastien Boeuf
08258d5dad vfio: pci: Allow multiple devices to be passed through
The KVM_SET_GSI_ROUTING ioctl is very simple, it overrides the previous
routes configuration with the new ones being applied. This means the
caller, in this case cloud-hypervisor, needs to maintain the list of all
interrupts which needs to be active at all times. This allows to
correctly support multiple devices to be passed through the VM and being
functional at the same time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-04 08:48:17 +01:00
Sebastien Boeuf
4115fa8a87 vfio: pci: Update irqfd registration
In order to improve the existing VFIO code, this patch registers the
eventfds used to trigger KVM interrupts only when the interrupts are
enabled, and unregisters them when interrupts are disabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-04 08:48:17 +01:00
Sebastien Boeuf
1379abb94b pci: msi: Fix MSG_CTL update through 32 bits write
If the MSG_CTL is being written from a 32 bits write access, the offset
won't be 0x2, but 0x0 instead. That's simply because 32 bits access have
to be aligned on each double word.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-04 08:48:17 +01:00
Sebastien Boeuf
c81e808e98 docs: Update instructions regarding virtiofsd
The documentation was out of date since the URL to download virtiofsd
binary was not valid anymore. Instead, the updated documentation now
describe how to build virtiofsd from source.

Fixes #491

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-12-03 12:16:43 +00:00
Rob Bradford
17badfbff5 vmm: cpu: Call vcpu configure() on the vCPU thread
The function that programs the vCPUs is expected to be run from within
each vCPU thread.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-03 03:22:15 -08:00
Rob Bradford
13503061e6 api: Fix OpenAPI specification entries
Some renames from "cpu_count" were missing.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-03 03:28:06 +01:00
Rob Bradford
e1ff142392 tests: Remove MSI only test from test_serial_off
Now we have a GED device we are not MSI only when the serial port is
turned off.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
e0830640b7 tests: Add integration test for hotplugging vCPUs
Resize the VM to increase the number of vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
66a31c19e8 vmm: acpi: Upon GED interrupt notify on all vCPUs
Call the "CTFY" method that will itself call Notify() on the CPU objects
in the ACPI namespace.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
48bf141364 vmm: Trigger a hotplug device notification when resizing
When adjusting the number of vCPUs generate a hotplug notification.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
b629727901 vmm: acpi: Add a CTFY method to notify on all CPU objects
This method calls Notify() on all the vCPU objects in the ACPI
namespace.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
ae9359c859 vmm: acpi: Create the CPU entries in the DSDT for all vCPUs
CPU entries need to be created for every potential vCPU in the system.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
791ca3388f vmm: device_manager: Add ability to notify via GED device
Add ability to notify via the GED device that there is some new hotplug
activity. This will be used by the CpuManager (and later DeviceManager
itself) to notify of new hotplug activity.

Currently it has a hardcoded IRQ of 5 as the ACPI tables also need to
refer to this IRQ and the IRQ allocation does not permit the allocation
of specific IRQs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
623755cc70 devices: Add ACPI GED device
This device provides the ability to notify the kernel via interrupt that
there is some new hotplug activity. The type is determined by reading
from the I/O port.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
7ad68d499a vmm: device_manager: Allocate I/O port for ACPI shutdown device
The refactoring in ce1765c8af dropped the
code to allocate the I/O port.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
86339b4cb4 vmm: Add HTTP API to resize the VM
Currently only increasing the number of vCPUs is supported but in the
future it will be extended.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
e7d4eae527 vmm: cpu: Add support for starting more vCPU threads
Add support for starting vCPU threads after the initial boot ones.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
0ef999978c vmm: cpu: Support only partially configuring the vCPU
When configuring a processor after boot as a hotplug CPU we only
configure a subset of the CPU state. In particular we should not
configure the FPU, segment registers (or reconfigure the paging which is
a side-effect of that) nor the main registers. Achieve this by making
the function take an Option type for the start address.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
c8b3041e62 vmm: openapi: Update OpenAPI for CpuConfig struct
This struct has changed in order to support differentiating between boot
and max vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
b6801e355e vmm: cpu: Refactor vCPU thread starting
Refactor the vCPU thread starting so that there is the possibility to
bring on extra vCPU threads.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
66d5163ee7 vmm: cpu: Encapsulate vCPU state into its own struct
Currently this just holds the thread handle but will be enlarged to
encompass details such as whether the vCPU is currently being inserted
or ejected.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
ea19bb026f tests: Add a test to check that the boot vs max cpus work
The easiest way to detect if the kernel is willing to accept hotplug
vCPUs is to check the dmesg output.

Switch the test to bionic as the Clear Cloud image lacks "dmesg."

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
1bbe48b24c vmm: acpi: Mark non-boot vCPUs as disabled in the MADT table
The MADT table contains the details of all the potential vCPUs and
whether they are present at boot (as indicated by the flags field.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
4bc8635c59 tests: Use new "--cpus" syntax for integration tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
82bc07cce4 vmm: Add boot and max vCPU handling to command line parser
Also retain support (with a warning for the old behaviour.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
7543e00a07 vmm: Use new CpuManager accessor to get boot vCPUs
When initialising the ACPI tables and configuring the VM use the new
accessor on the CpuManager to get the number of boot vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Rob Bradford
df0907845a vmm: cpu: Introduce concept of maximum vs boot vCPUs in CpuManager
For now the max vCPUs is the same as the boot vCPUs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-12-02 13:49:04 +00:00
Sergio Lopez
669d9a8ae8 vhost_user_backend: fix memory region offsetting
The way in which offsets are currently use in memory regions is
derived from QEMU's contrib/libvhost-user, but while this one works
mainly by translating vmm va's to local va's, vm-memory expects us to
use proper guest addresses and thus, define memory regions that
actually match the guest's memory disposition.

With this change, we create the memory regions with the proper length
and offsets, extend AddrMapping to store the guest physical address,
and use the latter instead of offset in vmm_va_to_gpa().

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-12-02 01:57:25 -08:00
dependabot-preview[bot]
d378da64ee build(deps): bump vcpkg from 0.2.7 to 0.2.8
Bumps [vcpkg](https://github.com/mcgoo/vcpkg-rs) from 0.2.7 to 0.2.8.
- [Release notes](https://github.com/mcgoo/vcpkg-rs/releases)
- [Changelog](https://github.com/mcgoo/vcpkg-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mcgoo/vcpkg-rs/compare/vcpkg-rs-0.2.7...vcpkg-rs-0.2.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-02 07:50:00 +00:00
dependabot-preview[bot]
b1cfdc761a build(deps): bump syn from 1.0.9 to 1.0.11
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.9 to 1.0.11.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.9...1.0.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-01 11:33:30 +00:00
Samuel Ortiz
0f21781fbe cargo: Bump the kvm and vmm-sys-util crates
Since the kvm crates now depend on vmm-sys-util, the bump must be
atomic.
The kvm-bindings and ioctls 0.2.0 and 0.4.0 crates come with a few API
changes, one of them being the use of a kvm_ioctls specific error type.
Porting our code to that type makes for a fairly large diff stat.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-29 17:48:02 +00:00
dependabot-preview[bot]
ca97385da5 build(deps): bump libc from 0.2.65 to 0.2.66
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.65 to 0.2.66.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.65...0.2.66)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-29 13:00:02 +00:00
dependabot-preview[bot]
f7dace151c build(deps): bump syn from 1.0.8 to 1.0.9
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.8...1.0.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-29 08:48:13 +00:00
Qiu Wenbo
861d902c21 acpi_tables: aml: Add support for binary operators
Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
2019-11-29 08:47:58 +00:00
Rob Bradford
f787139805 build: Reorder travis build commands to reuse build assets
Reorder the build commands so that more build assets in the target/
build directory can be reused. This will reduce the build time.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-28 14:29:38 +01:00
Rob Bradford
338beebc83 misc: Update locations to point to new kernel fork
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-28 14:28:12 +01:00
Wu Zongyong
4de04e84b5 vfio-pci: unmap regions when dropping VfioGroup
Introduce method unmap_mmio_regions to unmap all regions mapped to host.
This patch eliminate the error message "Could not unset container".

Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com>
2019-11-27 07:44:02 -08:00
Jose Carlos Venegas Munoz
62fa595ac6 cargo: set cloud-hypervisor as default crate
cloud-hypervisor is the main crate, useful to do cargo run.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-26 10:33:48 +01:00
Jose Carlos Venegas Munoz
ab16af2941 openapi: make context ID vsock int64
context ID on vsock man defines a 32-bits value, openapi default integer
is a signed 32-bits value.

This could lead to miss one bit during castings for typed client
implmentations. Lets increase the range of valid values by requesting an
int64.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-26 08:38:59 +01:00
dependabot-preview[bot]
9fd5ea4951 build(deps): bump signal-hook from 0.1.11 to 0.1.12
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.11 to 0.1.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.1.11...v0.1.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 21:09:19 +00:00
dependabot-preview[bot]
d6d1074ca3 build(deps): bump serde_derive from 1.0.102 to 1.0.103
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.102 to 1.0.103.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.102...v1.0.103)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 20:32:53 +00:00
dependabot-preview[bot]
4cff045cc6 build(deps): bump serde_json from 1.0.41 to 1.0.42
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.41 to 1.0.42.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.41...v1.0.42)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 19:54:16 +00:00
dependabot-preview[bot]
0ae9610e09 build(deps): bump serde from 1.0.102 to 1.0.103
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.102 to 1.0.103.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.102...v1.0.103)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 18:52:45 +00:00
dependabot-preview[bot]
0274b7923b build(deps): bump signal-hook-registry from 1.1.1 to 1.2.0
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.1.1 to 1.2.0.
- [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/registry-v1.1.1...registry-v1.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 17:15:16 +00:00
dependabot-preview[bot]
edd59a0f97 build(deps): bump remain from 0.1.4 to 0.1.5
Bumps [remain](https://github.com/dtolnay/remain) from 0.1.4 to 0.1.5.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.1.4...0.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 17:11:41 +00:00
dependabot-preview[bot]
c718225c5f build(deps): bump openssl-sys from 0.9.52 to 0.9.53
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.52 to 0.9.53.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.52...openssl-sys-v0.9.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 17:06:23 +00:00
Sebastien Boeuf
360f0639f4 Revert "vfio: use correct flags to disable interrupts"
This reverts commit 66fde245b3.

The commit broke the VFIO support for MSI. Issue needs to be
investigated but in the meantime, it is safer to fix the codebase.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-24 12:43:06 +01:00
Rob Bradford
8fe5a43d9d tests: Only setcap on test binary
The setcap tool is unusual in its behaviour in that it will process each
parameter separately and abort if one of the parameters is invalid (e.g.
after a symlink.) But any previous parameters will be correctly
processed. This means that depending on the generated test binary name
an invalid entry might occur before it and thus abort the setcap.

Fix to only setcap on the test binary by excluding the other files.
Because the binary name is based on a hash the PR that introduced this
version worked but once merged the hash changed and broke the build.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-23 21:15:56 +00:00
Sebastien Boeuf
f1c7f0c0b8 ci: Add integration test for vhost_user_fs daemon
In order to validate the new virtio-fs daemon written in Rust is
behaving correctly, a new integration test has been added. Important to
note that for now, only a test with cache=none and dax=off can be added
since the daemon does not support shared memory region yet.

The long term goal being to replace virtiofsd with vhost_user_daemon
once it will reach parity regarding the supported features.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
50b0e58c88 vhost_user_fs: Allow specific shared directory to be specified
Because the vhost_user_backend crate needs some changes to support
moving the process to a different mount namespace and perform a pivot
root, it is not possible to change '/' to the given shared directory.

This commit, as a temporary measure, let the code point at the given
shared directory.

The long term solution is to perform the mount namespace change and the
pivot root as this will provide greater security.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
ba17758ac0 src: Add vhost-user-fs daemon
This patch implements a vhost-user-fs daemon based on Rust. It only
supports communicating through the virtqueues. The support for the
shared memory region associated with DAX will be added later.

It relies on all the code copied over from the crosvm repository, based
on the commit 961461350c0b6824e5f20655031bf6c6bf6b7c30.

It also relies on the vhost_user_backend crate, limiting the amount of
code needed to get this daemon up and running.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
5c128023da vhost_user_fs: Add Server structure to consume FileSystem implementation
Add a Server type that links the FUSE protocol with the virtio
transport. It parses messages sent on the virtio queue and then
calls the appropriate method of the Filesystem trait.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

One small modification has been applied to the original code. Because
cloud-hypervisor didn't have the macro used by crosvm, the match
statement in the function handle_message() has been updated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
e1fccc3615 vhost_user_fs: Add virtio descriptor helper traits
Introduce helpers to split a virtio descriptor into its readable part on
one side, and into its writable part on the other side. This is useful
to separate the request from the reply.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Two important modifications have been applied to the original code:
- GuestMemory is replaced by GuestMemoryMmap from the vm-memory crate,
  which comes with different ways of accessing the memory regions.
- VolatileSlice has different methods, which means the code has been
  updated accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
5f7935f8e0 vhost_user_fs: Add file traits to handle writing volatile memory
The vm_memory implementation for VolatileSlice is able to read and write
to a source or destination which implements a Read or Write trait.

Unfortunately, this is not enough for this specific use case as we need
to be able to write to a file at a specific offset, which is not
provided by the Read or Write trait.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
e33ccb0c95 vhost_user_fs: Implement FileSystem trait for Passthrough
Add a "passthrough" file system implementation that just forwards its
requests to the appropriate system call.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
1b76c0a183 vhost_user_fs: Add FileSystem trait
Add the `Filesystem` trait, which is the main interface between the
transport and the actual file system implementation.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
1e65bda0a7 vhost_user_fs: Add multikey module
The multikey module provides a BTreeMap implementation that can use one
of 2 different kinds of keys to look up a value. This is needed by the
virtio-fs server since it needs to be able to look up keys either by
u64 or by a (ino_t, dev_t) pair.

This code has been ported over from crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
cd1684bd2e vhost_user_fs: Add FUSE definitions
To be able to deal with FUSE requests, this commit introduces FUSE
definitions, copied over from the crosvm commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
03361a6c29 vhost_user_fs: Add new crate
This new crate will be dedicated to vhost_user_fs specific code that can
be used as a library from the vhost-user-fs daemon.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Sebastien Boeuf
8845326aa2 vm-virtio: Introduce DescriptorChain iterator
In order to iterate over a chain of descriptor chains, this code has
been ported over from crosvm, based on the commit
961461350c0b6824e5f20655031bf6c6bf6b7c30.

The main modification compared to the original code is the way the
sorting between readable and writable descriptors happens.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 22:17:47 +01:00
Rob Bradford
3d6b5459ef ci: Make the integration test binary run with same caps
By giving the same caps to both cloud-hypervisor and the test binary, we
can access information under /proc related to the VM PID.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-22 15:28:10 +00:00
Rob Bradford
ac118c9924 ci: Parse the smaps file with Rust
Instead of using bash and awk, using Rust allows us to retrieve
information about a VM process with the right permissions as we are not
forced to spawn a new child process.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-22 15:28:10 +00:00
Sebastien Boeuf
bdb7bcdbe3 ci: Add integration test for mergeable memory
The test validates that when the mergeable option is enabled, the
resulting PSS for two instances of cloud-hypervisor is lower than two
instances not using the mergeable flag.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 15:28:10 +00:00
Sebastien Boeuf
f979380620 vmm: Mark guest persistent memory pages as mergeable
In case the VM is started with the flag "--pmem mergeable=on", it means
the user expects the guest persistent memory pages to be marked as
mergeable. This commit relies on the madvise(MADV_MERGEABLE) system call
to inform the host kernel about these pages.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 15:28:10 +00:00
Sebastien Boeuf
0f9afc3017 vmm: Add mergeable=on|off option to --pmem flag
In order to let the user indicate if the persistent memory pages should
be marked as mergeable or not, a new option is being introduced.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 15:28:10 +00:00
Sebastien Boeuf
e4e8062dda vmm: Mark guest RAM pages as mergeable
In case the VM is started with the flag "--memory mergeable=on", it
means the user expects the guest RAM pages to be marked as mergeable.
This commit relies on the madvise(MADV_MERGEABLE) system call to inform
the host kernel about these pages.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 15:28:10 +00:00
Sebastien Boeuf
880f62bab8 vmm: Add mergeable=on|off option to --memory flag
In order to let the user indicate if the guest RAM pages should be
marked as mergeable or not, a new option is being introduced.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-22 15:28:10 +00:00
Rob Bradford
0213177027 Jenkinsfile: Add timeout for build
In order to conserve CI resources limit build execution to one hour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-22 06:52:21 -08:00
Rob Bradford
d642060378 Jenkinsfile: Switch to pipeline (declarative format)
Switch the Jenkinsfile from the scripted format over to the declarative
format.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-22 06:52:21 -08:00
Jose Carlos Venegas Munoz
1d852e9ce5 vmm: Provide vmm version to start_vmm_thread
When vmm.ping give a response, we expect get the version from
the VMM not the vmm create

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-21 15:04:11 -08:00
Jose Carlos Venegas Munoz
a518651402 http: api: implement vmm.ping
vmm.ping will help to check if http API server is up and
running.

This also removes the vmm.info endpoint.

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-21 15:04:11 -08:00
Rob Bradford
348a1bc30e vmm: cpu: Allocate I/O port for the CPU manager
The CPU manager uses an I/O port and to prevent potential clashes with
assignment for PCI devices ensure that it is allocated by the allocator.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
07cdb37dda vmm: cpu & acpi: Query CPU manager for CPU status
Rather than hardcode the CPU status for all the CPUs instead query from
the CPU manager via the I/O port that is is on via the ACPI tables.

Each CPU device has a _STA method that calls into the CSTA method which
reads and writes the I/O ports via the PRST field which exposes the I/O
port through and OpRegion.

As we only support boot CPUS report that all the CPUs are enabled for
now.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
5faf8b756c vmm: acpi: Add an _MAT for the CPU devices containing a LAPIC
The Linux kernel expects all CPUs, whether they be enabled or disabled
to have an _MAT entry containing the LAPIC details for this CPU with the
enabled bit set to 1 (in the flags.)

In the MADT table the same bit is used to determine if the CPU is
present at boot vs available later.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
e51ebe045f acpi_tables: Add support for Buffer objects
These are necessary to populate "_MAT" entries for CPU devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
1da0ff395d vmm: cpu: Add the CpuManager onto the IO bus
This allows the kernel (via ACPI based controls) to query and control
the CPU state.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
39a1b8f4db acpi_tables: aml: Add support for calling methods
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
d5bb0781e4 acpi_tables: aml: Add support for while loops
Which also requires adding support for addition.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
89f0db2173 acpi_tables: aml: Add support for device notification
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
d6696e1bdd acpi_tables: aml: Add support for mutexes
And add support for operations on them.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
3d70ce9ad1 acpi_tables: aml: Add "if" with local variables and arguments
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
d06623fb97 acpi_tables: aml: Add support for OpRegion
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
93ee6f5e62 acpi_tables: aml: Add support for field definitions
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
4b5ce23d97 acpi_tables: Add PkgLength variant that does not include itself
This is necessary as adding support for NamedFields requires a PkgLength
calculation that does not include the length itself.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
50c8335d3d vmm: device_manager: Expose the SystemAllocator
This allows other code to allocate I/O ports for use on the (already)
exposed IO bus.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Rob Bradford
1ac1231292 vmm: Encase CpuManager within an Arc<Mutex<>>
This is necessary to be able to add the CpuManager onto the IO bus.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 09:17:15 -08:00
Wu Zongyong
d7dc1a9226 pci: don't cleanup msi/msix interrupts repeatedly
We disabled msi/msix twice inside Drop trait for VfioPciDevice,
which resulted in error message "Could not disable MSI-X". Eliminating
this error by check whether the msi/msix capability is enabled.

Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com>
CC: Liu Jiang <gerry@linux.alibaba.com>
2019-11-21 06:38:36 -08:00
Wu Zongyong
66fde245b3 vfio: use correct flags to disable interrupts
The comments of vfio kernel module said that individual subindex
interrupts can be disabled using the -1 value for DATA_EVENTFD or
the index can be disabled as a whole with:
    flags = (DATA_NONE|ACTION_TRIGGER), count = 0.

Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com>
CC: Liu Jiang <gerry@linux.alibaba.com>
2019-11-21 06:38:36 -08:00
Rob Bradford
8ec89bc884 misc: Update to new repository locations
Update all references to the new repository locations. Many of these will
redirect however the one used for the hypervisor-fw binary does not so
this is required to allow the builds to pass.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-21 11:39:11 +00:00
Sebastien Boeuf
64305dab16 docs: device_model: Fix formatting error
Fix the summary table format.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-19 15:45:52 -08:00
Sebastien Boeuf
b55d75ea62 docs: Add device model
This commit introduces a dedicated document describing the device model
supported by cloud-hypervisor VMM.

It needs to be updated anytime a new device will be added in the future.

Fixes #437

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-19 14:10:36 -08:00
Samuel Ortiz
f0e618431d vmm: device_manager: Use consistent naming when adding devices
When adding devices to the guest, and populating the device model, we
should prefix the routines with add_. When we're just creating the
device objects but not yet adding them we use make_.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
a2ee681665 vmm: device_manager: Add an MMIO devices creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
MMIO devices creation code into its own routine.

Fixes: #441

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
79b8f8e477 vmm: device_manager: Add a PCI devices creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
PCI devices creation code into its own routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
5087f633f6 vmm: device_manager: Add an IOAPIC creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
ACPI device creation code into its own routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
ce1765c8af vmm: device_manager: Add an ACPI device creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
ACPI device creation code into its own routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
cfca2759fc vmm: device_manager: Add a legacy devices creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
legacy devices creation code into its own routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
Samuel Ortiz
4b469b98cf vmm: device_manager: Add a console creation routine
In order to reduce the DeviceManager's new() complexity, we can move the
console creation code into its own routine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-19 13:36:21 -08:00
dependabot-preview[bot]
e1281b5488 build(deps): bump cast from 0.2.2 to 0.2.3
Bumps [cast](https://github.com/japaric/cast.rs) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/japaric/cast.rs/releases)
- [Changelog](https://github.com/japaric/cast.rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/japaric/cast.rs/compare/v0.2.2...v0.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 08:43:57 +00:00
dependabot-preview[bot]
fa0d573fef build(deps): bump arc-swap from 0.4.3 to 0.4.4
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v0.4.3...v0.4.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 08:43:17 +00:00
Sebastien Boeuf
d9695a0fd9 docs: fs: Update virtio-fs documentation
The cloud-hypervisor supports the DAX shared region for better virtio-fs
performances, but it was not updated in the documentation. This commit
takes care of this and also update the mount command since it changed
with virtio-fs v0.3.

Fixes #433

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-11-15 10:51:31 -08:00
dependabot-preview[bot]
4d0872df5f build(deps): bump vm-memory from 8d6ca35 to bb29ec8
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `8d6ca35` to `bb29ec8`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](8d6ca3553c...bb29ec8713)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-15 06:35:41 +00:00
Emin Ghuliev
c204d5404b docs: networking: Fix typo in hyperlink
An extra double quote was introduced by mistake in one of the hyperlink.

Signed-off-by: Emin Ghuliev drmint80@gmail.com
2019-11-13 13:18:26 +01:00
Samuel Ortiz
b930b3fb41 vmm: api: Specify which integers are 64 bit wide
By default, client will assume 32-bits for OpenAPI interger types.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-12 08:39:05 -08:00
Samuel Ortiz
6af2f57644 vmm: api: Fix the vm.info response payload
We are returning a state and a config.

Fixes: #431

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-12 08:39:05 -08:00
dependabot-preview[bot]
2dcd36f2f0 build(deps): bump synstructure from 0.12.2 to 0.12.3
Bumps [synstructure](https://github.com/mystor/synstructure) from 0.12.2 to 0.12.3.
- [Release notes](https://github.com/mystor/synstructure/releases)
- [Commits](https://github.com/mystor/synstructure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-11 19:29:20 +00:00
Rob Bradford
6958ec4922 vmm: Move CPU management code to its own module
Move CpuManager, Vcpu and related functionality to its own module (and
file) inside the VMM crate

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-11 15:46:24 +00:00
dependabot-preview[bot]
7b77189c80 build(deps): bump vm-memory from 366a907 to 8d6ca35
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `366a907` to `8d6ca35`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](366a907660...8d6ca3553c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-11 12:43:48 +00:00
Samuel Ortiz
3dde848c8f vmm: api: Update our OpenAPI document
In most cases we return a 204 (No Content) and not a 201.
In those cases, we do not send any HTTP body back at all.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-10 14:51:55 +01:00
Samuel Ortiz
96aa2441ad vmm: http: Convert to micro_http HttpServer
The new micro_http package provides a built-in HttpServer wrapper for
running a more robust HTTP server based on the package HTTP API.

Switching to this implementation allows us to, among other things,
handle HTTP requests that are larger than 1024 bytes.

Fixes: #423

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-10 14:51:55 +01:00
Samuel Ortiz
f34ace7673 vmm: http_endpoint: Do not sent 200 status code when our body is empty
Otherwise HTTP client will not close the connection and wait for a
pending body.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-11-10 14:51:55 +01:00
Jose Carlos Venegas Munoz
ede262684d API: HTTP: change response content type to JSON
The HTTP API responses are encoded in json

Suggested-by:  Samuel Ortiz <sameo@linux.intel.com>
Tested-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-08 22:49:08 +01:00
Jose Carlos Venegas Munoz
7498647e3f cargo: Update micro_http
Update micro_http create to allow set content type.

Suggested-by:  Samuel Ortiz <sameo@linux.intel.com>
Tested-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-11-08 22:49:08 +01:00
dependabot-preview[bot]
fa94635282 build(deps): bump syn from 1.0.7 to 1.0.8
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.7...1.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-08 21:18:37 +00:00
Rob Bradford
ff36fa99e6 vm-virtio: Replace use of deprecated std::mem::uninitialized
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-08 20:43:52 +00:00
Rob Bradford
3c715daa9d vmm: Fix rustfmt failure by removing extra ";"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-08 20:43:52 +00:00
Rob Bradford
73b4668bd9 acpi_tables: Fix rustfmt failure by removing extra ";"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-08 20:43:52 +00:00
Rob Bradford
a1a5fe0c93 vmm: Split CPU management into it's own struct
Pull details of vCPU management (booting, pausing, resuming, shutdown)
into it's own structure. This will ultimately enable this to be moved to
its own file and encapsulate all the vCPU handling for the VMM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-08 11:59:21 +01:00
Rob Bradford
0319a4a09a arch: vmm: Move ACPI tables creation to vmm crate
Remove ACPI table creation from arch crate to the vmm crate simplifying
arch::configure_system()

GuestAddress(0) is used to mean no RSDP table rather than adding
complexity with a conditional argument or an Option type as it will
evaluate to a zero value which would be the default anyway.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-07 14:02:27 +00:00
Sergio Lopez
c3eaa41b77 ci: use the new vhost-user-blk backend for integration tests
Use the new vhost-user-blk backend for the integration tests,
eliminating the need for building vubd using the implementation in
QEMU.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
Sergio Lopez
ceafd4cee7 vhost_user_backend: remove ownership check in set_features()
set_features() fails with InvalidOperation if !self.owned. I don't see
this as a requirement in the specification and, in fact, vm-virtio
implementation for resetting the device calls SET_FEATURES just after
RESET_OWNER.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
Sergio Lopez
5870452d25 src: add vhost-user-blk backend
Create a vhost-user-blk backend using vhost-user-backend and following
the conventions established by the existing vhost-user-net
implementation.

This backend is based on https://github.com/slp/vhost-user-backend,
but a bit simplified, making it closer to the original implementation
in Firecracker. The main features missing are EVENT_IDX, support for
asynchronous I/O and multiqueue, but it's still fully functional and
provides a good starting point for evolving it into a more complete
implementation.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
Sergio Lopez
3a3dd0096c vm-virtio: export block::Request and related funcs/structs
Export block::Request and related functions and structs so the code
can be shared with vhost-user-blk.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
Sergio Lopez
08bebaae4f vhost_user_backend: move protocol_features to the backend
Extend VhostUserBackend trait with protocol_features(), so device
backend implementations can freely define which protocol features they
want to support.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
Sergio Lopez
85e936d4bd vhost_rs: fix VhostUserConfig payload management
The VhostUserConfig carries a message with a payload, the contents of
which depend on the kind of device being emulated.

With this change, we calculate the offset of the payload within the
message, check its size corresponds to the expected one, and pass it
to the backend as a reference to a slice adjusted to the payload
dimensions.

The backend will be responsible of validating the payload, as it's the
one aware of its expected contents.

Signed-off-by: Sergio Lopez <slp@redhat.com>
2019-11-07 10:36:30 +00:00
dependabot-preview[bot]
2cc723f77b build(deps): bump blake2b_simd from 0.5.8 to 0.5.9
Bumps [blake2b_simd](https://github.com/oconnor663/blake2_simd) from 0.5.8 to 0.5.9.
- [Release notes](https://github.com/oconnor663/blake2_simd/releases)
- [Commits](https://github.com/oconnor663/blake2_simd/compare/0.5.8...0.5.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-07 07:40:51 +00:00
dependabot-preview[bot]
d1f03bae84 build(deps): bump pnet_macros from 0.22.0 to 0.23.0
Bumps [pnet_macros](https://github.com/libpnet/libpnet) from 0.22.0 to 0.23.0.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-06 14:35:29 +00:00
dependabot-preview[bot]
ae5e8c47ae build(deps): bump cc from 1.0.46 to 1.0.47
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.46 to 1.0.47.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.46...1.0.47)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-05 23:58:36 +00:00
dependabot-preview[bot]
8cd45e4ade build(deps): bump synstructure from 0.12.1 to 0.12.2
Bumps [synstructure](https://github.com/mystor/synstructure) from 0.12.1 to 0.12.2.
- [Release notes](https://github.com/mystor/synstructure/releases)
- [Commits](https://github.com/mystor/synstructure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-05 23:58:17 +00:00
Rob Bradford
c999ea6471 arch: x86_64: acpi: Add basic processor details
Add basic processor details to the DSDT table. The code has to be
slightly convoluted (with the second pass over the cpu_devices vector)
in order to keep the objects alive long enough in order to be able to
take their reference.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-05 14:45:21 +01:00
Rob Bradford
64368a195a acpi_tables: aml: Add support for Method and Return
This allows the implementation of simple methods that return a constant
value.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-05 14:45:21 +01:00
Rob Bradford
08d6386482 acpi_tables: aml: Add support for strings
Support strings from both static strings (&'static str) and String.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-05 14:45:21 +01:00
Cathy Zhang
5cd4f5daeb vmm: Release the old vm before build a new one
In vm_reboot, while build the new vm, the old one pointed by self.vm
is not released, that is, the tap opened by self.vm is not closed
either. As a result, the associated dev name slot in host kernel is
still in use state, which prevents the new build from picking it up as
the new opened tap's name, but to use the name in next slot finally.
Call self.vm_shutdown instead here since it has call take() on vm reference,
which could ensure the old vm is destructed before the new vm build.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-11-05 14:40:43 +01:00
Rob Bradford
b3388c343d vmm: device_manager: Ensure I/O ports are allocated
Ensure that we tell the allocator about all the I/O ports that we are
using for I/O bus attached devices (serial, i8042, ACPI device.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-11-05 10:13:01 +00:00
dependabot-preview[bot]
2d25862477 build(deps): bump pkg-config from 0.3.16 to 0.3.17
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.16 to 0.3.17.
- [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.16...0.3.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-02 16:10:00 +00:00
Rob Bradford
ce386ba4c6 tests: Use release build for integration tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-31 10:07:37 -07:00
dependabot-preview[bot]
87e9ce6960 build(deps): bump num_cpus from 1.10.1 to 1.11.0
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.10.1 to 1.11.0.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.10.1...v1.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-31 14:03:37 +00:00
Sebastien Boeuf
5694ac2b1e vm-virtio: Create new VirtioTransport trait to abstract ioeventfds
In order to group together some functions that can be shared across
virtio transport layers, this commit introduces a new trait called
VirtioTransport.

The first function of this trait being ioeventfds() as it is needed from
both virtio-mmio and virtio-pci devices, represented by MmioDevice and
VirtioPciDevice structures respectively.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-31 09:30:59 +01:00
Sebastien Boeuf
3fa5df4161 vmm: Unregister old ioeventfds when reprogramming PCI BAR
Now that kvm-ioctls has been updated, the function unregister_ioevent()
can be used to remove eventfd previously associated with some specific
PIO or MMIO guest address. Particularly, it is useful for the PCI BAR
reprogramming case, as we want to ensure the eventfd will only get
triggered by the new BAR address, and not the old one.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-31 09:30:59 +01:00
Sebastien Boeuf
587a420429 cargo: Update to the latest kvm-ioctls version
We need to rely on the latest kvm-ioctls version to benefit from the
recent addition of unregister_ioevent(), allowing us to detach a
previously registered eventfd to a PIO or MMIO guest address.

Because of this update, we had to modify the current constraint we had
on the vmm-sys-util crate, using ">= 0.1.1" instead of being strictly
tied to "0.2.0".

Once the dependency conflict resolved, this commit took care of fixing
build issues caused by recent modification of kvm-ioctls relying on
EventFd reference instead of RawFd.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-31 09:30:59 +01:00
Sebastien Boeuf
c7cabc88b4 vmm: Conditionally update ioeventfds for virtio PCI device
The specific part of PCI BAR reprogramming that happens for a virtio PCI
device is the update of the ioeventfds addresses KVM should listen to.
This should not be triggered for every BAR reprogramming associated with
the virtio device since a virtio PCI device might have multiple BARs.

The update of the ioeventfds addresses should only happen when the BAR
related to those addresses is being moved.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-31 09:30:59 +01:00
Sebastien Boeuf
de21c9ba4f pci: Remove ioeventfds() from PciDevice trait
The PciDevice trait is supposed to describe only functions related to
PCI. The specific method ioeventfds() has nothing to do with PCI, but
instead would be more specific to virtio transport devices.

This commit removes the ioeventfds() method from the PciDevice trait,
adding some convenient helper as_any() to retrieve the Any trait from
the structure behing the PciDevice trait. This is the only way to keep
calling into ioeventfds() function from VirtioPciDevice, so that we can
still properly reprogram the PCI BAR.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-31 09:30:59 +01:00
Samuel Ortiz
3be95dbf93 pci: Remove KVM dependency
The PCI crate should not depend on the KVM crates.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-29 20:09:04 -07:00
Sebastien Boeuf
296f2e1182 ci: Add integration test for PCI BAR reprogramming
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
d6c68e4738 pci: Add error propagation to PCI BAR reprogramming
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
3e819ac797 pci: Use a weak reference to the AddressManager
Storing a strong reference to the AddressManager behind the
DeviceRelocation trait results in a cyclic reference count.
Use a weak reference to break that dependency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
149b61b213 pci: Detect BAR reprogramming
Based on the value being written to the BAR, the implementation can
now detect if the BAR is being moved to another address. If that is the
case, it invokes move_bar() function from the DeviceRelocation trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
04a449d3f3 pci: Pass DeviceRelocation to PciBus
In order to trigger the PCI BAR reprogramming from PciConfigIo and
PciConfigMmmio, we need the PciBus to have a hold onto the trait
implementation of DeviceRelocation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
e93467a96c vmm: Implement DeviceRelocation trait
By implementing the DeviceRelocation trait for the AddressManager
structure, we now have a way to let the PCI BAR reprogramming happen.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
4f8054fa82 pci: Store the type of BAR to return correct address
Based on the type of BAR, we can now provide the correct address related
to a BAR index provided by the caller.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
b51a9e1ef1 pci: Make PciBarRegionType implement PartialEq
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
8746c16593 vmm: Create AddressManager to own SystemAllocator
In order to reuse the SystemAllocator later at runtime, it is moved into
the new structure AddressManager. The goal is to have a hold onto the
SystemAllocator and both IO and MMIO buses so that we can use them
later.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
1870eb4295 devices: Lock the BtreeMap inside to avoid deadlocks
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
733e636f02 devices: Allow for bus range removal and update
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
e536f88012 vfio: Implement move_bar() from PciDevice trait
Everytime a PCI BAR is moved, the KVM regions need to be updated.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
c865f93c9b pci: Extend PciDevice trait with move_bar() function
In order to support PCI BAR reprogramming, the PciDevice trait defines a
new method move_bar() dedicated for taking appropriate action when a BAR
is moved to a different guest address.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
3e37f59933 pci: Add new DeviceRelocation trait
This new trait will allow the VMM to implement the mechanism following a
BAR modification regarding its location in the guest address space.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Sebastien Boeuf
5cc1e73e52 Fix Cargo.lock
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-29 16:48:02 +01:00
Rob Bradford
05eb567a7c build: Ensure there is a release build artifact for travis to upload
After some of the build changes there was no longer a release artifact
left to be used for the release builds.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-29 15:23:31 +00:00
Samuel Ortiz
75bf240b83 cargo: Move to 0.3.0
Our most recent release.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-28 21:32:30 +01:00
dependabot-preview[bot]
be6a1975d2 build(deps): bump serde_derive from 1.0.101 to 1.0.102
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.101 to 1.0.102.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.101...v1.0.102)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 07:34:31 +00:00
dependabot-preview[bot]
f27893f822 build(deps): bump vm-memory from 8669369 to 366a907
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from `8669369` to `366a907`.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Commits](8669369d17...366a907660)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 07:17:32 +00:00
dependabot-preview[bot]
696f6cae47 build(deps): bump signal-hook from 0.1.10 to 0.1.11
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.1.10 to 0.1.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.1.10...v0.1.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 06:59:16 +00:00
dependabot-preview[bot]
1f7f484f61 build(deps): bump serde from 1.0.101 to 1.0.102
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.101 to 1.0.102.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.101...v1.0.102)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 06:28:18 +00:00
dependabot-preview[bot]
4e0b5e8a63 build(deps): bump syn from 1.0.6 to 1.0.7
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.6...1.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 06:27:34 +00:00
dependabot-preview[bot]
c159515e91 build(deps): bump syn from 1.0.5 to 1.0.6
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.5...1.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-27 09:21:34 +00:00
dependabot-preview[bot]
26336363cc build(deps): bump getrandom from 0.1.12 to 0.1.13
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.1.12 to 0.1.13.
- [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.1.12...v0.1.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-25 13:03:06 +00:00
Rob Bradford
7c2c4fb3fc acpi_tables: aml: Rename to_bytes() to to_aml_bytes()
To avoid a clash with to_bytes() for the unsigned integer types that is
coming in a future release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
ad60fe110b arch: x86_64: acpi: Mark 64-bit device area uncacheable
This region was erroneously marked as cacheable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
025f1f9d9b arch: x86_64: acpi: Remove 16-bit PCI range
We don't use this range and it shouldn't be included in our DSDT.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
555ac68ea5 arch: x86_64: acpi: Generate DSDT programatically
This was verified by comparing the ASL from disassembling the DSDT
before and after. All the individual AML components themselves are also
unit tested.

Fixes: #352

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
dd539df633 acpi_tables: sdt: Add ability to add to the table from a slice
The generic version does not work in this case as it the size of the the
&[u8] is not the size of the slice's contents but how much memory the
slice object itself takes up.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
c76fd6df21 acpi_tables: aml: Implement AML Zero, One, Ones
These are special encodings for representing zero, one or all ones in a
single byte.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
9269e40ba5 acpi_tables: aml: Add support for device and scope
These both group a set of AML objects together.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
e1e0ac2ee3 acpi_tables: aml: Add support for creating IO and interrupt resources
As per ACPI spec: "6.4.2.5 I/O Port Descriptor" and "6.4.3.6 Extended
Interrupt Descriptor"

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
08aff4ed5a acpi_tables: aml: Add support for address spaces
Add support for Word/DWord/QWord address spaces for I/O, memory and
buses. Using sensible defaults for infrequently set flags.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
c4c3540a1d acpi_tables: aml: Add resource templates and Memory32Fixed
Add support for generating resource templates (a kind of buffer) along
with generating Memory32Fixed to go into it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
03d8cdc4f2 acpi_tables: aml: Generate EISA name IDs
EISA names (of the the form UUUNNNN) are encoded into a 32-bit integer.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
3cb73b3a45 acpi_tables: aml: Add Package support
Packages are a way of grouping values together and as such they require
an explicit length which is a variable length encoding calculated with
create_pkg_length().

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
bf0d0d9f9b acpi_tables: aml: Add support for named definitions
Named definitions use op code 0x08 and are used to name some more
complex object.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
5a7076442c acpi_tables: aml: Implement numbers
Add support for the numerical types. By using type aliases the
generation can be very ergonomic as From<T> is implemented.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Rob Bradford
a4ce596f7b acpi_tables: aml: Add support for generating AML name paths
Root ("\"), single, dual and multi-part names are supported. "^" is not
supported (not widely used.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-24 10:55:02 +01:00
Samuel Ortiz
1387ac5571 ci: Add cargo audit to the travis pipeline
cargo audit audits Cargo.lock for crates with security vulnerabvilities
reported by the RustSec Advisory Database.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-23 13:06:29 +03:00
Samuel Ortiz
de9eb3e0fa Bump vmm-sys-utils to 0.2.0
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-23 11:35:11 +03:00
dependabot-preview[bot]
dc951af167 build(deps): bump c2-chacha from 0.2.2 to 0.2.3
Bumps [c2-chacha](https://github.com/cryptocorrosion/cryptocorrosion) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/cryptocorrosion/cryptocorrosion/releases)
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/compare/c2-chacha-0.2.2...c2-chacha-0.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-21 17:44:17 +00:00
dependabot-preview[bot]
3dff551399 build(deps): bump ppv-lite86 from 0.2.5 to 0.2.6
Bumps [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) from 0.2.5 to 0.2.6.
- [Release notes](https://github.com/cryptocorrosion/cryptocorrosion/releases)
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/compare/ppv-lite86-0.2.5...ppv-lite86-0.2.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-21 17:10:47 +00:00
dependabot-preview[bot]
4783fe7402 build(deps): bump autocfg from 0.1.6 to 0.1.7
Bumps [autocfg](https://github.com/cuviper/autocfg) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/cuviper/autocfg/releases)
- [Commits](https://github.com/cuviper/autocfg/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-21 04:26:47 +00:00
dependabot-preview[bot]
e10413b96c build(deps): bump proc-macro2 from 1.0.5 to 1.0.6
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.5...1.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-20 14:30:54 +00:00
dependabot-preview[bot]
317d754946 build(deps): bump ssh2 from 0.4.0 to 0.5.0
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.4.0...0.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-20 14:30:18 +00:00
dependabot-preview[bot]
eff1ece368 build(deps): bump openssl-sys from 0.9.51 to 0.9.52
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.51 to 0.9.52.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.51...openssl-sys-v0.9.52)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-20 14:30:02 +00:00
Sebastien Boeuf
05c7130f06 ci: Update ClearLinux image
A new ClearLinux image has been uploaded to the Azure storage account.
It is based off of the ClearLinux cloudguest image 31310 version, with
two extra bundles added to it.

First bundle is sysadmin-basic to include utility like netcat, and the
second bundle is iperf, adding the iperf binary to the image.

The image is 2G in size.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-18 16:49:46 +01:00
Samuel Ortiz
8e8a7b6d07 release-notes: v0.3.0 release
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-18 11:55:13 +02:00
dependabot-preview[bot]
2d7bfdd920 build(deps): bump libc from 0.2.64 to 0.2.65
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.64 to 0.2.65.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.64...0.2.65)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 08:53:20 +00:00
Sebastien Boeuf
5822969afa docs: Update instructions to create custom ClearLinux image
Based on recent update of the cloudguest image used by Cloud Hypervisor,
we identified some missing or incorrect details in the instructions.
This patch is here to fix those.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-18 08:10:06 +02:00
Sebastien Boeuf
defc33927f docs: iommu: Improve VM boot time and performance
This patch extends the existing virtual IOMMU documentation, explaining
how the use of huge pages can drastically improve the VM boot time.

Particularly, how in case of nested VFIO, the impact is significant and
the rationales behind it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-18 07:21:40 +02:00
Sebastien Boeuf
efbafdf9ed vm-virtio: Allow 2MiB mappings
In order to speed up the boot time and reduce the amount of mappings,
this patch exposes the virtio-iommu device as supporting both 2M and 4k
page sizes.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-18 07:21:40 +02:00
dependabot-preview[bot]
2b60452195 build(deps): bump backtrace from 0.3.39 to 0.3.40
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.39 to 0.3.40.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.39...0.3.40)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-17 22:53:26 +00:00
dependabot-preview[bot]
e8a25c22f6 build(deps): bump backtrace from 0.3.38 to 0.3.39
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.38 to 0.3.39.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.38...0.3.39)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-17 19:14:34 +00:00
dependabot-preview[bot]
b8be1dc24a build(deps): bump backtrace-sys from 0.1.31 to 0.1.32
Bumps [backtrace-sys](https://github.com/alexcrichton/backtrace-rs) from 0.1.31 to 0.1.32.
- [Release notes](https://github.com/alexcrichton/backtrace-rs/releases)
- [Commits](https://github.com/alexcrichton/backtrace-rs/compare/backtrace-sys-0.1.31...backtrace-sys-0.1.32)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-17 18:40:05 +00:00
dependabot-preview[bot]
83631599a3 build(deps): bump cc from 1.0.45 to 1.0.46
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.45 to 1.0.46.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.45...1.0.46)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-17 06:37:13 +00:00
Jose Carlos Venegas Munoz
78e2f7a99a api: http: handle cpu according to openapi
openapi definition defines an object for cpus not an integer

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-10-17 07:39:56 +02:00
Jose Carlos Venegas Munoz
205b8c1cd5 api: http: make consistent api and implementation
vsocks: vsocks is implemented as an array

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-10-17 07:39:56 +02:00
Sebastien Boeuf
3acf9dfcf3 vfio: Don't map guest memory for VFIO devices attached to vIOMMU
In case a VFIO devices is being attached behind a virtual IOMMU, we
should not automatically map the entire guest memory for the specific
device.

A VFIO device attached to the virtual IOMMU will be driven with IOVAs,
hence we should simply wait for the requests coming from the virtual
IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
63c30a6e79 vmm: Build and set the list of external mappings for VFIO
When VFIO devices are created and if the device is attached to the
virtual IOMMU, the ExternalDmaMapping trait implementation is created
and associated with the device. The idea is to build a hash map of
device IDs with their associated trait implementation.

This hash map is provided to the virtual IOMMU device so that it knows
how to properly trigger external mappings associated with VFIO devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
c65ead5de8 vm-virtio: Trigger external map/unmap from virtio-iommu
This patch relies on the trait implementation provided for each device
which requires some sort of external update based on a map or unmap.

Whenever a MAP or UNMAP request comes through the virtqueues, it
triggers a call to the external mapping trait with map()/unmap()
functions being invoked.

Those external mappings are meant to be used from VFIO and vhost-user
devices as they need to update their own mappings. In case of VFIO, the
goal is to update the DMAR table in the physical IOMMU, while vhost-user
devices needs to update their internal representation of the virtqueues.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
837bcbc6ba vfio: Create VFIO implementation of ExternalDmaMapping
With this implementation of the trait ExternalDmaMapping, we now have
the tool to provide to the virtual IOMMU to trigger the map/unmap on
behalf of the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
3598e603d5 vfio: Add a public function to retrive VFIO container
The VFIO container is the object needed to update the VFIO mapping
associated with a VFIO device. This patch allows the device manager
to have access to the VFIO container.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
34bb31791b vm-device: Add new crate for virtio and VFIO agnostic traits
The new crate vm-device is created here to host the definitions of
traits not meant to be tied to virtio of VFIO specifically. We need to
add a new trait to update external DMA mappings for devices, which is
why the vm-device crate is the right fit for this.

We can expect this crate to be extended later once the design gets
approved from a rust-vmm perspective.

In this specific use case, we can have some devices like VFIO or
vhost-user ones requiring to be notified about mapping updates. This
new trait ExternalDmaMapping will allow such devices to implement their
own way to handle such event.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
9085a39c7d vmm: Attach VFIO devices to IORT table
This patch attaches VFIO devices to the virtual IOMMU if they are
identified as they should be, based on the option "iommu=on". This
simply takes care of adding the PCI device ID to the ACPI IORT table.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
Sebastien Boeuf
5fc3f37c9b vmm: Add iommu=on|off option for --device
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a VFIO device should be attached to the virtual
IOMMU or not. That's why we introduce an extra option "iommu" with the
value "on" or "off". By default, the device is not attached, which means
"iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-16 07:27:06 +02:00
dependabot-preview[bot]
3bb51d4d5e build(deps): bump libc from 0.2.62 to 0.2.64
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.62 to 0.2.64.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.62...0.2.64)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-15 19:46:54 +00:00
Rob Bradford
cc72ed1cc9 vhost_user_net: Propagate errors correctly
Clean up the error handling and ensure that where possible errors are
propagated. Make use of std::convert::From in order to translate error
types.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-15 09:27:01 -07:00
Rob Bradford
8663b429b3 vhost_user_net: Remove unnecessary checks for unconfigured memory
Simplify the check for the unusual situation where the memory is not
configured by using .ok_or() on the option to convert it to a result.
This cleans up a bunch of extra indentation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-15 09:27:01 -07:00
Rob Bradford
df336ade57 vhost_user_net: Remove debugging println! messages
Remove messages that are left over from the development of the project
that represent normal operation for the backend. This cleans up the
console output and improves performance.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-15 09:27:01 -07:00
dependabot-preview[bot]
9e78c2e686 build(deps): bump ryu from 1.0.1 to 1.0.2
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.1...1.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-15 05:16:47 +00:00
Jose Carlos Venegas Munoz
786e33931f api: http: Fix openpi schema.
Fix invalid type for version:

- VmInfo.version.type string

Change Null value from enum as it has problems to build clients with
openapi tools.

- ConsoleConfig.mode.enum Null -> Nil

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-10-15 07:16:24 +02:00
dependabot-preview[bot]
90d1083bda build(deps): bump syn from 1.0.3 to 1.0.5
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.3 to 1.0.5.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.3...1.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-14 11:25:01 +02:00
dependabot-preview[bot]
5ca068a068 build(deps): bump proc-macro2 from 1.0.1 to 1.0.5
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.1 to 1.0.5.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.1...1.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-14 09:23:47 +00:00
Samuel Ortiz
2a0ba7aef8 vmm: vm: Add state validation unit test
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-14 06:35:36 +02:00
Samuel Ortiz
097b30669f vmm: vm: Verify that state transitions are valid
We should return an explicit error when the transition from on VM state
to another is invalid.
The valid_transition() routine for the VmState enum essentially
describes the VM state machine.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-14 06:35:36 +02:00
dependabot-preview[bot]
ef090cf37d build(deps): bump ryu from 1.0.0 to 1.0.1
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.0...1.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-12 09:33:07 +01:00
dependabot-preview[bot]
db3ece8ef2 build(deps): bump failure from 0.1.5 to 0.1.6
Bumps [failure](https://github.com/rust-lang-nursery/failure) from 0.1.5 to 0.1.6.
- [Release notes](https://github.com/rust-lang-nursery/failure/releases)
- [Changelog](https://github.com/rust-lang-nursery/failure/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-lang-nursery/failure/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-12 08:32:38 +00:00
Samuel Ortiz
af41d6fc88 main: Add VM pause/resume test
We pause a VM from the API, then SSH'ing into it should fail.
After resuming, SSH'ing should work again.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 17:13:44 -07:00
Samuel Ortiz
d2d3abb13c vmm: Rename Booted vm state to Running
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 17:13:44 -07:00
Samuel Ortiz
dbbd04a4cf vmm: Implement VM resume
To resume a VM, we unpark all its vCPU threads.

Fixes: #333

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 17:13:44 -07:00
Samuel Ortiz
4ac0cb9cff vmm: Implement VM pause
In order to pause a VM, we signal all the vCPU threads to get them out
of vmx non-root. Once out, the vCPU thread will check for a an atomic
pause boolean. If it's set to true, then the thread will park until
being resumed.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 17:13:44 -07:00
Sebastien Boeuf
80c3fd922a ci: Allow enough time for L2 VM to boot
Because the L2 VM running in the VFIO integration test is actually
running as L3 (since the CI runs in a VM), it can take quite some
time for this VM to boot.

The way to solve this issue is to extend the sleep time before to try
communicating with the L2 VM, but also to speed up the boot time by
using virtio-console instead of serial. We suspect the use of serial,
implying PIO VM exits for each character on the serial port is quite
expensive compared to the paravirtualized console.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-11 01:40:11 +02:00
Sebastien Boeuf
37a7000fdd ci: Make sure VFIO test don't conflict with Azure private IP
Azure virtual machines can have private IPs in the 172.16.x.x range,
causing some issues with the VFIO test. By using 172.17.x.x for this
test, we avoid IP conflicts.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-10 11:29:17 -07:00
Sebastien Boeuf
6e9e24ec0f ci: Extend virtio-iommu integration test
Now that our custom kernel includes all the patches for the full support
of virtio-iommu, we can go one step further by attaching the virtio-net
device to the virtual IOMMU and use it to SSH some commands validating
both disks and the network card are isolated into their own IOMMU group.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-10 16:07:50 +02:00
Sebastien Boeuf
1fc8ee945a ci: Remove QEMU dependency for nested VFIO test
Now that cloud-hypervisor can expose a virtual IOMMU to its guest VM,
the integration test validating the VFIO support with virtio-net can be
updated to use cloud-hypervisor exclusively.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-10 16:07:50 +02:00
Sebastien Boeuf
cb59f826ad scripts: Use virtio-fs-virtio-iommu branch as custom kernel
Because we want both early support for virtio-fs and virtio-iommu, our
custom kernel is now based on the kernel branch virtio-fs-virtio-iommu.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-10 16:07:50 +02:00
Sebastien Boeuf
688ec0eb2d resources: Update kernel config
In order to support nested virtualization and nested device passthrough
from our CI tests, we need some extra kernel configuration options to be
enabled.

CONFIG_KVM and CONFIG_VIRTUALIZATION for nested virtualization.
CONFIG_VFIO for nested device passthrough.
CONFIG_VIRTIO_IOMMU and CONFIG_ACPI_IORT for virtio-iommu support.

With all these new options applied, we can leverage virtio-iommu to
attach some VFIO devices to it and pass them through a second layer of
virtualization.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-10 16:07:50 +02:00
Samuel Ortiz
8e018d6feb vfio: Move vfio-bindings to crates.io
And remove our local vfio-bindings code.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 10:32:40 +02:00
Samuel Ortiz
c446b9d510 Cargo: Move virtio-bindings to crates.io
v0.1.0 was just published.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-10 10:32:40 +02:00
dependabot-preview[bot]
6df7cd0e4b build(deps): bump openssl-sys from 0.9.50 to 0.9.51
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.50 to 0.9.51.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.50...openssl-sys-v0.9.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-10 07:44:14 +00:00
dependabot-preview[bot]
3a04db5936 build(deps): bump arrayvec from 0.4.11 to 0.4.12
Bumps [arrayvec](https://github.com/bluss/arrayvec) from 0.4.11 to 0.4.12.
- [Release notes](https://github.com/bluss/arrayvec/releases)
- [Commits](https://github.com/bluss/arrayvec/compare/0.4.11...0.4.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-10 01:04:35 +00:00
dependabot-preview[bot]
ad7d02cd74 build(deps): bump nodrop from 0.1.13 to 0.1.14
Bumps [nodrop](https://github.com/bluss/arrayvec) from 0.1.13 to 0.1.14.
- [Release notes](https://github.com/bluss/arrayvec/releases)
- [Commits](https://github.com/bluss/arrayvec/compare/nodrop-0.1.13...nodrop-0.1.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-09 15:12:04 +00:00
Samuel Ortiz
1298b508bf vmm: Manage the exit and reset behaviours from the control loop
So that we don't need to forward an ExitBehaviour up to the VMM thread.
This simplifies the control loop and the VMM thread even further.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-08 18:03:27 -07:00
Samuel Ortiz
a95fa1c4e8 vmm: api: Add a VMM shutdown command
This shuts the current VM down, if any, and then exits the VMM process.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-08 18:03:27 -07:00
Samuel Ortiz
228adebc32 vmm: Unreference the VM when shutting down
This way, we are forced to re-create the VM object when moving from
shutdown to boot.

Fixes: #321

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-08 17:24:05 +02:00
Samuel Ortiz
14eb071b29 Cargo: Move to crates.io vmm-sys-util
Use the newly published 0.1.1 version.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-08 07:28:53 -07:00
Sebastien Boeuf
5652cc7a05 README: Remove wrong statement about the firmware
The firmware has been recently updated to find the EFI partition, no
matter if the disk is not the first one of the list.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
2c50c963f5 docs: Explain how to use the virtual IOMMU
This patch introduces a specific documentation for the virtual IOMMU
device. This is important to understand what the use cases are for this
new device and how to properly use it with virtio devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
46848fdc43 ci: Add integration test for virtio-iommu
Simply test the guest can find the PCI device corresponding to the
virtio-iommu device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
b918220b49 vmm: Support virtio-pci devices attached to a virtual IOMMU
This commit is the glue between the virtio-pci devices attached to the
vIOMMU, and the IORT ACPI table exposing them to the guest as sitting
behind this vIOMMU.

An important thing is the trait implementation provided to the virtio
vrings for each device attached to the vIOMMU, as they need to perform
proper address translation before they can access the buffers.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
278ab05cbc vmm: Add iommu=on|off option for --vsock
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-vsock device should be attached to this
virtual IOMMU or not. That's why we introduce an extra option "iommu"
with the value "on" or "off". By default, the device is not attached,
which means "iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
32d07e40cc vmm: Add iommu=on|off option for --console
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-console device should be attached to
this virtual IOMMU or not. That's why we introduce an extra option
"iommu" with the value "on" or "off". By default, the device is not
attached, which means "iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
63869bde75 vmm: Add iommu=on|off option for --pmem
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-pmem device should be attached to this
virtual IOMMU or not. That's why we introduce an extra option "iommu"
with the value "on" or "off". By default, the device is not attached,
which means "iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
fb4769388b vmm: Add iommu=on|off option for --rng
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-rng device should be attached to this
virtual IOMMU or not. That's why we introduce an extra option "iommu"
with the value "on" or "off". By default, the device is not attached,
which means "iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
20c4ed829a vmm: Add iommu=on|off option for --net
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-net device should be attached to this
virtual IOMMU or not. That's why we introduce an extra option "iommu"
with the value "on" or "off". By default, the device is not attached,
which means "iommu=off".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
4b8d7e718d vmm: Add iommu=on|off option for --disk
Having the virtual IOMMU created with --iommu is one thing, but we also
need a way to decide if a virtio-blk device should be attached to this
virtual IOMMU or not. That's why we introduce an extra option "iommu"
with the value "on" or "off". By default, the device is not attached,
which means "iommu=off".

One side effect of this new option is that we had to introduce a new
option for the disk path, simply called "path=".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
6e0aa56f06 vmm: Add iommu field to the VmConfig
Adding a simple iommu boolean field to the VmConfig structure so that we
can later use it to create a virtio-iommu device for the current VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
03352f45f9 arch: Create ACPI IORT table
The virtual IOMMU exposed through virtio-iommu device has a dependency
on ACPI. It needs to expose the device ID of the virtio-iommu device,
and all the other devices attached to this virtual IOMMU. The IDs are
expressed from a PCI bus perspective, based on segment, bus, device and
function.

The guest relies on the topology description provided by the IORT table
to attach devices to the virtio-iommu device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
f40adff2a1 vm-virtio: Add virtio-iommu support
This patch introduces the first implementation of the virtio-iommu
device. This device emulates an IOMMU for the guest, which allows
special use cases like nesting passed through devices, or even using
IOVAs from the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
0acb1e329d vm-virtio: Translate addresses for devices attached to IOMMU
In case some virtio devices are attached to the virtual IOMMU, their
vring addresses need to be translated from IOVA into GPA. Otherwise it
makes no sense to try to access them, and they would cause out of range
errors.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
6566c739e1 vm-virtio: Add IOMMU support to virtio-vsock
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
9ab00dcb75 vm-virtio: Add IOMMU support to virtio-rng
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
ee1899c6f6 vm-virtio: Add IOMMU support to virtio-pmem
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
392f1ec155 vm-virtio: Add IOMMU support to virtio-console
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
9fad680db1 vm-virtio: Add IOMMU support to virtio-net
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
9ebb1a55bc vm-virtio: Add IOMMU support to virtio-blk
Adding virtio feature VIRTIO_F_IOMMU_PLATFORM when explicitly asked by
the user. The need for this feature is to be able to attach the virtio
device to a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
85e1865cb5 vm-virtio: Implement reset() for vhost-user-fs
The virtio specification defines a device can be reset, which was not
supported by this vhost-user-fs implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind it
to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
4b1328a29c vm-virtio: Implement reset() for vhost-user-net
The virtio specification defines a device can be reset, which was not
supported by this vhost-user-net implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind it
to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
8225d4cd6e vm-virtio: Implement reset() for virtio-console
The virtio specification defines a device can be reset, which was not
supported by this virtio-console implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind it
to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
dac7737919 vm-virtio: Implement reset() for virtio-vsock
The virtio specification defines a device can be reset, which was not
supported by this virtio-vsock implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind
it to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
3e750de43f vm-virtio: Implement reset() for virtio-pmem
The virtio specification defines a device can be reset, which was not
supported by this virtio-pmem implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind
it to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
eb91bc812b vm-virtio: Implement reset() for virtio-rng
The virtio specification defines a device can be reset, which was not
supported by this virtio-rng implementation. The reason it is needed
is to support unbinding this device from the guest driver, and rebind
it to vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Sebastien Boeuf
59b4aaba87 vm-virtio: Implement reset() for virtio-net
The virtio specification defines a device can be reset, which was not
supported by this virtio-net implementation. The reason it is needed is
to support unbinding this device from the guest driver, and rebind it to
vfio-pci driver.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-10-07 10:12:07 +02:00
Samuel Ortiz
8288cb2ac8 micro_http: Use Firecracker version
As of commit 2b94334a, Firecracker includes all the changes we need.
We can now switch to using it instead of carrying a copy.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 06:52:34 -07:00
Samuel Ortiz
2a466132a0 vmm: api: Set the HTTP response header Server field
To "Cloud Hypervisor API" and not "Firecracker API".

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
fc5c210498 micro_http: Set the response headers Server value
And implement the Default trait for ResponseHeaders, falling back to
Firecracker API.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
8dbb16df4d main: Add a simple HTTP API integration test
For now we test that we can create and boot a guest from the HTTP API.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
7abbad0a62 vmm: Be more idiomatic when calling into the VMM API
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
7328ecdb3b vmm: Implement the /api/v1/vm.delete endpoint
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
f9daf2e247 vmm: Factorize the vm boot and shutdown code
So that the API handling state machine is cleaner and easier to read.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
43b3642955 vmm: Clean Error handling up
We used to have errors definitions spread across vmm, vm, api,
and http.

We now have a cleaner separation: All API routines only return an
ApiResult. All VM operations, including the VMM wrappers, return a
VmResult. This makes it easier to carry errors up to the HTTP caller.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
42758244a0 vmm: Implement the /api/v1/vm.info endpoint
This, for now, returns the VM config and its state.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
27af983ec9 vmm: Track the VM state
We will expose it through the api/v1/vm.info endpoint.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
b70344158b vmm: Handle the missing VM error
When trying to boot or shut a VM down, return an error if the VM was not
previously created.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
7e0cb078ed vmm: Only build a new VM when booting it
In order to support further use cases where a VM configuration could be
modified through the HTTP API, we only store the passed VM config when
being asked to create a VM. The actual creation will happen when booting
a new config for the first time.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
9a93f4f0a6 micro_http: Fix clippy warning
Use a more idiomatic "let Ok(foo) = result" construct for:

105 |           if try_numeric.is_ok() {
    |              ------------------- the check is happening here
106 |              self.content_length = try_numeric.unwrap();
    |                                   ^^^^^^^^^^^^^^^^^^^^

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
c505cfae2b vmm: Implement the VM HTTP endpoint handlers
Implement the vm.create, vm.boot, vm.shutdown and vm.reboot HTTP endpoint
handlers.

Fixes: #244

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
8a5e47f989 vmm: Implement the shutdown and reboot API
We factorize some of the code for both the API helpers and the VMM
thread.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
46cde1a38e vmm: Rename the VM start and stop operations to boot and shutdown
To match the OpenAPI description. And also to map the real life
terminology.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
ce0b475ef7 vmm: Move the VM creation and startup helpers to the api module
They're API wrappers, not VMM ones.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
f674019ea1 vmm: {De}serialize VmConfig
We use the serde crate to serialize and deserialize the VmVConfig
structure. This structure will be passed from the HTTP API caller as a
JSON payload and we need to deserialize it into a VmConfig.

For a convenient use of the HTTP API, we also provide Default traits
implementations for some of the VmConfig fields (vCPUs, memory, etc...).

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
f2de4d0315 vmm: config: Make the cmdline config serializable
The linux_loader crate Cmdline struct is not serializable.
Instead of forcing the upstream create to carry a serde dependency, we
simply use a String for the passed command line and build the actual
CmdLine when we need it (in vm::new()).
Also, the cmdline offset is not a configuration knob, so we remove it.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
6a722e5c0b vmm: config: Make VhostUser configs serializable
They point to a vm_virtio structure (VhostUserConfig) and in order to
make the whole config serializable (through the serde crate for
example), we'd have to add a serde dependency to the vm_virtio crate.

Instead we use a local, serializable structure and convert it to
VhostUserConfig from the DeviceManager code.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
aa31748781 vmm: Start the HTTP server thread
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
b14fd37db9 vmm: Make --kernel optional
The kernel path was the only mandatory command line option.
With the addition of the --api-socket option, we can run without a
kernel path and get it later through the API.

Since we can end up with VM configurations that are no longer valid by
default, we need to provide a validation check for it. For now, if the
kernel path is not defined, the VM configuration is invalid.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
f27aa21e3f main: Add API socket option
The API server will unconditionally run through a UNIX domain socket
which default path is /run/user/<uid>/cloud-hypervisor.<pid>.

The --api-socket command line option allows to override that default
value with some custom socket path.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
fe5561df50 main: Group cli options logically
With the API server socket option, we will be able to support a model
where the user can start cloud-hypervisor with no options or an
alternative API server socket path. In this case, we don't want to try
to start a new guest VM, and for that we need to know if the user has
set any VM configuration at all. Grouping all VM configuration specific
options together is one way to be able to know about it.

If the user has not set any VM configuration, we only start the API
server. If it has set anything, we will verify that the overall
configuration is valid and will implicitly convert that configuration
into a request to the API server.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
2371325f9c vmm: api: Add HTTP server
The Cloud Hyper HTTP server runs a synchronous, multi-threaded
loop that receives HTTP requests and tries to call the corresponding
endpoint handlers for the requests URIs.

An endpoint handler will parse the HTTP request and potentially
translate it into and IPC request. The handler holds an notifier and an
mspc Sender for respectively notifying and sending the IPC payload to
the VMM API server. The handler then waits for an API server response
and translate it back into an HTTP response.
The HTTP server is responsible for sending the reponse back to the
caller.

The HTTP server uses a static routes hash table that maps URIs to
endpoint handlers.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
e50f4418a2 micro_http: Import Firecracker HTTP 1.x implementation
Based on Firecracker commit 58edf03b.

We're going to use the micro_http crate to serve the cloud-hypervisor
HTTP API.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
Samuel Ortiz
8916dad2da vmm: api: Add cloud-hypervisor OpenAPI documentation
The cloud-hypervisor API uses HTTP as a transport and is accessible
through a local UNIX socket.

The API root path is /api/v1 and is a collection of RPC-style methods.
All methods are static, unlike typical REST APIs. Variable (e.g. device
IDs) are passed through the request body.

Fixes: #244

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-04 09:36:33 +02:00
dependabot-preview[bot]
1b66a2fa60 build(deps): bump serde_json from 1.0.40 to 1.0.41
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.40 to 1.0.41.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.40...v1.0.41)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-03 22:06:24 +00:00
Rob Bradford
8ea4145f98 devices, vmm: Add legacy CMOS device
Based off of crosvm revision b5237bbcf074eb30cf368a138c0835081e747d71
add a CMOS device. This environments that can't use KVM clock to get the
current time (e.g. Windows and EFI.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-03 14:57:49 +01:00
dependabot-preview[bot]
47367eb61b build(deps): bump openssl-sys from 0.9.49 to 0.9.50
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.49 to 0.9.50.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.49...openssl-sys-v0.9.50)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-03 09:06:31 +00:00
Rob Bradford
df3e5c874f tests: Add support for integration testing Ubuntu "eoan"
Refactor the Ubuntu testing infrastructure to support testing different
versions.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-10-02 13:59:48 +01:00
Samuel Ortiz
8ec6cda0c5 ci: Do not look for vubridge to decide if qemu must be built
We no longer build vubridge, so we end up cloning qemu and building
virtiofs and the block backend all the time.

Fixes: #312

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-10-02 09:39:55 +02:00
Cathy Zhang
8c33eb3069 src: Add integration test for vhost-user-net backend
An integration test relying on the new vhost-user-net backend now
replaces the previous test using the QEMU test backend. This allows
us to avoid building the QEMU backend, and we now really exercise the
vhost-user-net implementation as it is used for the ssh communication
in this test.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 13:06:00 -07:00
Cathy Zhang
f6d1a9d9b8 src: Add vhost-user-net backend
Create vhost-user-net backend with Tap interface, to offload network
transaction from cloud-hypervisor. The goal is to provide flexibility
about the backend being in use, but also more security as it will allow
users to isolate the backend with different security profiles since it
will run as a dedicated process on the host.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 13:06:00 -07:00
Cathy Zhang
d724511a91 vm-virtio: Add set_protocol_features in vhost-user-net
While implement vhost-user-net backend with Tap interface, it keeps
failed to enable the tx vring, since there is a checking in
slave_req_handler.rs to require acked_protocol_features to be setup
as a pre-requirement, which is filled by set_protocol_features call.
Add this call in vhost-user-net device implementation to address the issue.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-09-30 13:06:00 -07:00
Sebastien Boeuf
9ff42060e0 vhost_user_backend: Fix clippy issues
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 13:06:00 -07:00
Cathy Zhang
db151819f1 Cargo.toml: Add workspace config changes
Remove workspace from vhost_user_backend/Cargo.toml to have
vhost-user-backend compiled in cloud-hypervisor. Add workspace in
Cargo.toml to have vhost-user-backend consumed by vhost-user-net.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-09-30 13:06:00 -07:00
Rob Bradford
9356af80c6 arch: Mark the PCI MMCONFIG region as reserved in the E820 tables
The PCI Express Firmware specification says that the region may
be included in the E820 tables (but it must always be in the ACPI
tables.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Rob Bradford
6a4a931b9e arch: acpi: Reserve the PCI MMCONFIG region
The PCI Express Firmware spec says that the region to be used for PCI
MMCONFIG should be reserved as part of the motherboard's resources in
the ACPI tables.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Rob Bradford
038f198129 arch: acpi: Fix off-by-one error in size of PCI device region
When comparing offsets it is necessry to increment by one to give the
appropriate size.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Rob Bradford
833a3d456c pci, vmm: Expose the PCI bus for configuration via MMIO
Refactor the PCI datastructures to move the device ownership to a PciBus
struct. This PciBus struct can then be used by both a PciConfigIo and
PciConfigMmio in order to expose the configuration space via both IO
port and also via MMIO for PCI MMCONFIG.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Rob Bradford
c0ca3b6b8e arch: acpi, layout: Correctly calculate and expose PCI MMCONFIG area
The PCI MMCONFIG area must be below 4GiB and must not be part of the
device space. Shrink the device area and put the PCI MMCONFIG region
above it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Rob Bradford
a9eb352aea arch: acpi: Patch the 32-bit PCI device area in the APCI table
Patch the table with the currently used constants. This will be relevant
when we want to adjust the size of the PCI device area to accomodate the
PCI MMCONFIG region.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-30 18:00:31 +01:00
Sebastien Boeuf
09392f0530 vhost_user_backend: Fix remaining issues
This commit fixes all the remaining issues that were found as part of
the integration with vhost-user-net.

It fixes the way to notify that a vring is used, by using the proper
EventFd.

It removes the process_queue() function from the trait, since the
complexity it was introducing was leading to deadlocks with mutexes.

It moves the register/unregister functions for registering custom events
from the backend, from the VringEpollHandler to the VringWorker. This
allows for a lot of simplification and solve a deadlock issue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Cathy Zhang
527dd68ce1 vhost_user_backend: Update vmm_va_to_gpa with adding offset
The original logic does not has any problem without offset, since the
current offset is zero. However, if offset is not zero, while convert
vmm address to backend process address, it needs to consider the
offset.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-09-30 09:26:11 -07:00
Cathy Zhang
4a1af7f63c vhost-user-backend: Correct error handling in run
The error handling here to trigger break epoll seems not correct,
epoll will be ended once one event is handled, no matter successfully
or failed. Fix it.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-09-30 09:26:11 -07:00
Cathy Zhang
c4309515c9 vhost-user-backend: Remove one checking from set_features
The vhost-user protocol does not indicate set_features could not
be issued more than once, the checking is not needed at all, and
prevent communication between master and slave. Remove it to
fix the issue.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
347611b0c7 vhost_user_backend: Pass a backend that can be modified
This patch modifies the library so that a consumer can update the
backend after it's been passed to the daemon.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
f14ab872ec vhost_user_backend: Give access to the EpollVringHandler
By letting the consumer of this crate getting access to the vring
handler, we will be able to let it perform several actions without
producing a deadlock.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
cfc8c39446 vhost_user_backend: Provide some default trait implementations
We cannot expect every backend to support GET_CONFIG and SET_CONFIG
commands. That's why this patch adds some default implementations for
the trait VhostUserBackend regarding both get_config() and set_config()
functions.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
1aab372a06 vhost_user_backend: Make the backend a server
The code needs to initialize a listener to accept connection from the
VMM being the client in this case.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
c1b26b1fab vhost_user_backend: Don't process disabled queues
Every time an event is triggered, it needs to be read, but only based on
the status of the vring (enabled or not) will decide if the queue needs
to be processed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
d80ac43ef1 vhost_user_backend: Remove useless started field
The Queue structure already contains a field "ready" that can be used to
track the status of the vrings.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
5f076923d3 vhost_user_backend: Allow for proper error propagation
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
36de390caf vhost_user_backend: Make some trait functions as mutable
Let's be realistic, the trait VhostUserBackend will need to have mutable
self for some functions like handle_event, process_queue and set_config,
which is the reason why this commit needs to introduce a RwLock on the
backend instance that was passed around as a simple Arc.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
d4f7f73bc8 vhost_user_backend: Move to a per-queue RwLock
Instead of locking every queues whenever something needs to be updated,
this patch modifies the code design to lock each Vring independently.
This allows for much finer granularity, and will allow multiple queues
to be handled at the same time.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
4ed81894aa vhost_user_backend: Replace Mutex with RwLock when possible
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Sebastien Boeuf
2e2cad91ae vhost_user_backend: Add new crate
The purpose of this new crate is to provide a common library to all
vhost-user backend implementations. The more is handled by this library,
the less duplication will need to happen in each vhost-user daemon.

This crate relies a lot on vhost_rs, vm-memory and vm-virtio crates.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-30 09:26:11 -07:00
Rob Bradford
b5ee9212c1 vmm, devices: Use APIC address constant
In order to avoid introducing a dependency on arch in the devices crate
pass the constant in to the IOAPIC device creation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
162791b571 vmm, arch: Use IOAPIC constants from layout in DeviceManager
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
8207b2e97d arch: Move addresses for GDT and IDT tables to layout module
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
a0455167d0 vmm: Use layout constant for kernel command line
Remove the unnecessary field on CmdlineConfig and switch to using the
common offset.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
1bc47507b7 arch: Move initial page table addresses to layout module
These are part of RAM and are used as the initial page table entries for
booting the OS and firmware (identity mapping.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
5ba61f6d5e arch: Move address of MPTABLE to layout module
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
6d6e290000 arch: Move APIC and IOAPIC addresses into layout
Move the addresses used for the APIC and IOAPIC into our new memory
layout module.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 11:48:30 -07:00
Rob Bradford
0e7a1fc923 arch, vmm: Start documenting major regions of RAM and reserved memory
Using the existing layout module start documenting the major regions of
RAM and those areas that are reserved. Some of the constants have also
been renamed to be more consistent and some functions that returned
constant variables have been replaced.

Future commits will move more constants into this file to make it the
canonical source of information about the memory layout.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 08:55:47 -07:00
Rob Bradford
f63cb85f93 net_util: Implement fmt::Display for MacAddr
Updated clippy does not like the declaration of a "to_string()" function
and instead requires fmt::Display to be implemented.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 08:05:56 -07:00
Rob Bradford
ff1cb11946 arch: Use if-let notation
To keep updated clippy happy.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 08:05:56 -07:00
Rob Bradford
df2516f229 vhost_rs: Add clippy override
clippy wants us to use "if let Some(fd) = fd {}" but to combine that
with && is an experimental feature.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 08:05:56 -07:00
Rob Bradford
2ae3919181 vm-virtio: Fix formatting
With the 1.38.0 toolchain rustfmt is even stricter about formatting now

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-27 08:05:56 -07:00
Samuel Ortiz
8188074300 main: Start the VMM thread
We now start the main VMM thread, which will be listening for VM and IPC
related events.
In order to start the configured VM, we no longer directly call the VM
API but we use the IPC instead, to first create and then start a VM.

Fixes: #303

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
e235c6de4f vmm: Add VM creation and startup helpers
Based on the newly defined Cloud Hypervisor IPC, those helpers send
VmCreate and VmStart requests respectively. This will be used by the
main thread to create and start a VM based on the CLI parameters.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
151f96e454 vmm: Add a VMM thread startup routine
This starts the main, single VMM thread, which:

1. Creates the VMM instance
2. Starts the VMM control loop
3. Manages the VMM control loop exits for handling resets and shutdowns.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
2f1ff23066 vmm: (Re-)Introduce a VMM structure
Unlike the Vmm structure we removed with commit bdfd1a3f, this new one
is really meant to represent the VM monitoring/management object.
For that, we implement a control loop that will replace the one that's
currently embedded within the Vm structure itself.
This will allow us to decouple the VM lifecycle management from the VM
object itself, by having a constantly running VMM control loop.

Besides the VM specific events (exit, reset, stdin for now), the VMM
control loop also handles all the Cloud Hypervisor IPC requests.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
4671a5831f vmm: Move the EpollContext implementation to lib
The VMM thread and control loop will be the sole consumer of the
EpollContext and EpollDispatch API, so let's move it to lib.rs.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
03ab6839c1 vmm: Introduce Cloud Hypervisor IPC
Cloud Hypervisor IPC is a simple, mpsc based protocol for threads to
send command to the furture VMM thread. This patch adds the API
definition for that IPC, which will be used by both the main thread
to e.g. start a new VM based on the CLI arguments and the future HTTP
server to relay external requests received from a local Unix domain
socket.
We are moving it to its own "api" module because this is where the
external API (HTTP based) will also be implemented.

The VMM thread will be listening for IPC requests from an mpsc receiver,
process them and send a response back through another mpsc channel.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
6710a39b5a vmm: Pass the exit and reset fds to the vm creation method
As we're going to move the control loop to the VMM thread, the exit and
reset EventFds are no longer going to be owned by the VM.
We pass a copy of them when creating the Vm instead.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
feb1c33084 vmm: Add a VM config getter
We will need it from the VMM thread, when trying to reboot a VM.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
47167a658e vmm: Add a VM console handling method
In order to handle the VM STDIN stream from a separate VMM thread
without having to export the DeviceManager, we simply add a console
handling method to the Vm structure.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
ea7abc6c80 vmm: Add a VM stop method
In order to transfer the control loop to a separate VMM thread, we want
to shrink the VM control loop to a bare minimum.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
e6ef9ece2c vmm: Move the tty setting to the VM start routine
We want to shrink the control loop to a bare minimal.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
2e9d815701 vmm: Use a reference counted VmConfig when creating a new VM
Once passed to the VM creation routine, a VmConfig structure is
immutable. We can simply carry a Arc of it instead of a reference.
This also allows us to remove any lifetime bound from our VM.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-26 16:21:14 +02:00
Samuel Ortiz
2e0f1c2afe README: Update Slack invitation link
The current one is no longer valid.
The new one does not expire.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-25 13:25:00 +01:00
dependabot-preview[bot]
e869283b4e build(deps): bump cfg-if from 0.1.9 to 0.1.10
Bumps [cfg-if](https://github.com/alexcrichton/cfg-if) from 0.1.9 to 0.1.10.
- [Release notes](https://github.com/alexcrichton/cfg-if/releases)
- [Commits](https://github.com/alexcrichton/cfg-if/compare/0.1.9...0.1.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-24 20:30:43 +00:00
Samuel Ortiz
bdfd1a3f38 vmm: Remove the Vmm structure
The Vmm structure is just a placeholder for the KVM instance. We can
create it directly from the VM creation routine instead.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 10:12:04 +02:00
Samuel Ortiz
9c5135da7a vmm: Simplify the VM start flow
We can integrate the kernel loading into the VM start method.
The VM start flow is then: Vm::new() -> vm.start(), which feels more
natural.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 10:12:04 +02:00
Samuel Ortiz
b79c1f7722 vmm: Derive the clone trait for VmConfig
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
acc60b0ad5 vmm: Make VsockConfig owned
Convert Path to PathBuf and remove the associated lifetime.
Now we can remove the VmConfig associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
3dc7aff00e vmm: Make vhost-user configuration owned
Convert Path to PathBuf, &str to String and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
5f8a62f3d0 vmm: Make DeviceConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
36137232f0 vmm: Make ConsoleConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
79a02f9171 vmm: Make PmemConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
00674cd850 vmm: Make FsConfig owned
Convert Path to PathBuf, &str to String and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
5323da031c vmm: Make RngConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
0688bec298 vmm: Make NetConfig owned
Convert str to String and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
675e46355c vmm: Make DiskConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
036890e5be vmm: Make KernelConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
Samuel Ortiz
9c5bfb8e13 vmm: Make MemoryConfig owned
Convert Path to PathBuf and remove the associated lifetime.

Fixes #298

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-24 08:39:39 +01:00
dependabot-preview[bot]
dbff0e94b8 build(deps): bump backtrace from 0.3.37 to 0.3.38
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.37 to 0.3.38.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.37...0.3.38)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-23 20:08:09 +00:00
Sebastien Boeuf
0c8f9d2768 ci: Boot from vhost-user-blk with hypervisor-fw
Now that vhost-user has been fixed regarding size of the virtqueues,
booting a VM with the firmware from a vhost-user-blk backend actually
works. That's why this commit updates the previously introduced
integration test to make it use the firmware instead of direct kernel
boot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-23 17:29:38 +01:00
Sebastien Boeuf
f06b2aaaa7 vm-virtio: vhost-user: Set the right vring size
The vhost-user implementation was always passing the maximum size
supported by the virtqueues to the backend, but this is obviously wrong
as it must pass the size being set by the driver running in the guest.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-23 17:29:38 +01:00
dependabot-preview[bot]
a2f3da3488 build(deps): bump arc-swap from 0.4.2 to 0.4.3
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 0.4.2 to 0.4.3.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v0.4.2...v0.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-21 08:11:43 +00:00
Sebastien Boeuf
2cd406ba50 vm-virtio: Fix virtio-pci BAR type
The 32 or 64 bits type for the memory BAR was not set correctly. This
patch ensure the right type is applied to the BAR.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-21 09:11:30 +01:00
Sebastien Boeuf
29b3848ffb ci: Add a test to validate the VM can be booted from vhost-user-blk
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-20 15:56:51 +02:00
Sebastien Boeuf
d723b7dae8 vm-virtio: vhost-user-blk: Add support for reset
If we expect the vhost-user-blk device to be used for booting a VMM
along with the firmware, then need the device to support being reset.

In the vhost-user context, this means the backend needs to be informed
the vrings are disabled and stopped, and the owner needs to be reset
too.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-20 15:56:51 +02:00
Sebastien Boeuf
0a229ef4f5 ci: Extend vhost-user-blk test to validate the content
This commit extends the existing integration test related to
vhost-user-blk by validating the block image contains one file
"foo" containing "bar".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
6b06cec611 ci: add test case for vhost-user-blk
Currently we need use backend device from Qemu to test vhost-user-blk
device. Once the rust backend is ready, we will replace it.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
360980d93c vhost-user-blk: enable write_config for WCE
In vhost-user-blk, only WCE value can be set back to device in
guest kernel like
echo "write through" > /sys/block/vda/cache_type

So write_config() will only set WCE value from guest kernel to
vhost user side.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
39083d705b vhost-user-blk: make read_config work
Since config space in vhost-user-blk are mostly from backend
device, this change will get config space info from backend
by vhost-user protocol.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
a949ab21f7 main: add arguments entry for vhost-user-blk
To add vhost-user-blk support, it requires to add arguments
passed for it.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
4164853ec6 vmm: add vhost-user-blk support
Update vm configuration and device initial process to add
vhost-user-blk support.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
c7559bb7a4 config: make error definition common
Since vhost-user-blk use same error definition with vhost-user-net,
those errors need define to common usage.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
397d388710 vm-virtio: Add vhost-user-blk implementation
vhost-user-blk has better performance than virtio-blk, so we need
add vhost-user-blk support with SPDK in Rust-based VMMs.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
b232de9963 vhost_rs: Add INFLIGHT_SHMFD protocol feature
Add to the vhost_rs crate the INFLIGHT_SHMFD protocol feature that was
missing from the list. The feature has been recently introduced in
vhost-user specification, which is the reason why it was missing.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
2019-09-20 15:56:51 +02:00
Sebastien Boeuf
927148dd3c vhost_rs: Fix GET_CONFIG command
Following the vhost-user specification that can be found at
https://github.com/qemu/qemu/blob/master/docs/interop/vhost-user.rst#virtio-device-config-space
this patch fixes the GET_CONFIG command.

This command is very specific as it needs to provide a body and a
payload corresponding to the content of the configuration structure as
an array of bytes. As a reply, it receives the body and payload provided
by the slave.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-20 15:56:51 +02:00
Yang Zhong
c347f84d74 Revert "vhost_rs: add config messge support"
This reverts commit 3e99098bf3 because we
realized there was no need for those extra functions to be introduced as
the existing one from the vhost crate are sufficient for the vhost-user
configuration use case.
2019-09-20 15:56:51 +02:00
Sebastien Boeuf
0a0c7358a2 virtio-bindings: Rely on the upstream crate from rust-vmm
Now that virtio-bindings is a crate part of the rust-vmm project, we
want to rely on this one instead of the local one we had so far.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-19 07:13:54 -07:00
Rob Bradford
5f0337c21d tests: Add a "huge" memory test
Now that we have expanded our address space we should add automated
testing to try VMs that use a large amount of RAM.

As the hypervisor does an anonymous mmap() for the backing of memory and
during a typical test boot the guest will not touch it all it should be
possible to test large RAM VMs even if that exceeds the RAM of the host
machine.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 05:23:15 -07:00
Rob Bradford
b488d4859b arch: x86_64: Fix E820 table for RAM
The last byte was missing from the E820 RAM area. This was due to the
function using the last address relative to the first address in the
range to calculate the size. This incorrectly calculated the size by
one. This produced incorrect E820 tables like this:

[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000001ffffffe] usable

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 10:43:55 +01:00
Rob Bradford
5b3ca78dac vmm: Use the full host physical address range
Probe for the size of the host physical address range and use that to
establish the address range for the VM. This removes the limitation on
the size of the VM RAM and gives more space for the devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 10:43:55 +01:00
Rob Bradford
180e6d1e78 vm-virtio: Allocate BARs for virtio-block devices in 32-bit hole
Currently all devices and guest memory share the same 64GiB
allocation. With guest memory working upwards and devices working
downwards. This creates issues if you want to either have a VM with a
large amount of memory or want to have devices with a large allocation
(e.g. virtio-pmem.)

As it is possible for the hypervisor to place devices anywhere in its
address range it is required for simplistic users like the firmware to
set up an identity page table mapping across the full range. Currently
the hypervisor sets up an identify mapping of 1GiB which the firmware
extends to 64GiB to match the current address space size of the
hypervisor.

A simpler solution is to place the device needed for booting with the
firmware (virtio-block) inside the 32-bit memory hole. This allows the
firmware to easily access the block device and paves the way for
increasing the address space beyond the current 64GiB limit.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 10:43:55 +01:00
Rob Bradford
f0360c92d9 arch: acpi: Set the upper device range based on RAM levels
After the 32-bit gap the memory is shared between the devices and the
RAM. Ensure that the ACPI tables correctly indicate where the RAM ends
and the device area starts by patching the precompiled tables. We get
the following valid output now from the PCI bus probing (8GiB guest)

[    0.317757] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
[    0.319035] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
[    0.320215] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
[    0.321431] pci_bus 0000:00: resource 7 [mem 0xc0000000-0xfebfffff window]
[    0.322613] pci_bus 0000:00: resource 8 [mem 0x240000000-0xfffffffff window]

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 10:43:55 +01:00
Rob Bradford
f9b0875a60 arch: acpi: Correct range for the 32-bit device hole
There was an off-by-error in the result making the hole one byte too
big and ending at an address too high.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-19 10:43:55 +01:00
dependabot-preview[bot]
bf4f3db6c4 build(deps): bump vmm-sys-util from 07ef2e2 to 27e7ff1
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from `07ef2e2` to `27e7ff1`.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Commits](07ef2e280e...27e7ff14d6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-18 11:48:09 +00:00
Rob Bradford
eb60106159 arch: acpi: Correct starting length of MCFG table
The starting length of the MCFG table was too long resulting in the
kernel trying to get extra MCFG entries from the table that weren't
there resulting in the following error message from the kernel:

PCI: no memory for MCFG entries

The MCFG table also has an 8 bytes of padding at the start before the
table begins.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-18 06:27:59 +02:00
dependabot-preview[bot]
67ef4f0d74 build(deps): bump linux-loader from b270081 to 6cf23a8
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `b270081` to `6cf23a8`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](b2700818ad...6cf23a8bca)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-17 07:50:59 +00:00
Rob Bradford
f622a76597 build: Build test all supported build configurations on Travis
Treat warnings as errors for these test builds.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 08:55:35 -07:00
Rob Bradford
3bc11a4a2e vmm: Make the "mmio" only build generate no errors
Rerrange "use" statements and make rename variables and fields to
indicate they might be unused.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 08:55:35 -07:00
Rob Bradford
4df5ebea12 vmm: Add devices to IO/MMIO bus closer to creation
This removes the register_devices() function with all that functionality
spread across the places where the devices are created.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 08:55:35 -07:00
Rob Bradford
0739c2c7fd vm-virtio: Fix compilation warning from "mmio" feature only build
Use the correct constant for the newly initialised device state.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 08:55:35 -07:00
Rob Bradford
7358144f09 vmm: Cleanup warning from "pci" feature only build
Mark exit_evt with an underscore it may be unused (it is ignored if the
"acpi" feature is not turned on.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 08:55:35 -07:00
Rob Bradford
3567206059 build, tests: Update to ssh2 0.4.0
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-16 13:21:48 +01:00
dependabot-preview[bot]
ea7f4d7f0b build(deps): bump serde from 1.0.100 to 1.0.101
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.100 to 1.0.101.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.100...v1.0.101)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-16 11:47:24 +00:00
dependabot-preview[bot]
c0fede0774 build(deps): bump libssh2-sys from 0.2.11 to 0.2.12
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.11 to 0.2.12.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.11...libssh2-sys-0.2.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-16 11:47:12 +00:00
Rob Bradford
1097afbaff tests: Run MMIO supported integration tests
Run these tests after the normal tests and only if those have succeeded.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
ccb83282e9 tests: Add integration testing for MMIO based virtio
Label tests that definitely can't function with virtio-mmio (because
they use the firmware) and within those that can be used mark individual
assertions that will no longer hold (around PCI.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
3ad4b8486f tests: Remove unused "kernel_path" variable
tests_virtio_vsock uses a firmware based boot

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
1099f0726b vmm: Add MMIO support
Add (non-default) support for using MMIO for virtio devices. This can be
tested by:

cargo build --no-default-features --features "mmio"

All necessary options will be included injected into the kernel
commandline.

Fixes: #243

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
26974c7625 vm-virtio: Add MMIO transport
Derived from the crosvm code at 5656c124af2bb956dba19e409a269ca588c685e3
and adapted to work within cloud-hypervisor:

Main differences:

* Interrupt handling is done via a VirtioInterrupt turned into a
devices::Interrupt
* GuestMemory -> GuestMemoryMmap
* Differences in read/write for BusDevice
* Different crates for EventFd and GuestAddress

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
c042483953 build: make PCI (virtio and vfio) disableable at build time
Although included by default it is now possible to build without PCI
support.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
6d27ac9dfc vmm: Allow the DeviceManager to inject extra kernel commandline entries
This is useful for virtio-mmio to be able to provide the commandline
entries for the devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Rob Bradford
3df1680888 devices: Require Interrupt trait implementations to support Sync
This is necesary to be able easily translate an Interrupt to a
VirtioInterrupt which is already Sync.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-13 12:30:13 +01:00
Sebastien Boeuf
f5a44ea1ad docs: Explain how to create a custom Clear Linux cloud image
This is a quick guide on how to create a custom Clear Linux image based
on the official tooling provided by Clear Linux. If for any reason, the
image we are using is missing some interesting bundles that are packaged
by Clear Linux, this documentation will be the guide on how to proceed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-11 19:13:29 +02:00
Sebastien Boeuf
e950aa6b9a ci: Reduce integration testing time
By relying on a decompressed image, this patch assumes that downloading
the image will always be faster than decompressing it from the worker
VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-11 06:41:01 +02:00
Rob Bradford
05b5115e67 vmm: Call DeviceManager's register_devices() on creation
Rather than calling it at the very start of the VM execution (i.e. when
the VCPUs are created) do it as part of the DeviceManager creation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-10 20:04:00 +02:00
Rob Bradford
7edc46f492 vmm: Make virtio device creation independent of PCI
Create the virtio devices independently of adding them to the PCI bus.
Instead accrue the devices in a vector and add them to the bus en-masse.
This will allow the virtio device creation to be used independently of
PCI based transport.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-10 09:41:53 -07:00
Sebastien Boeuf
7c6ef7fd63 ci: Add integration test for virtio-vsock
This patch extends the current set of integration tests to correctly
validate that virtio-vsock is functional. It establishes a communication
between host and guest relying on the newly integrated vsock device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-10 17:57:49 +02:00
Sebastien Boeuf
bf37b960ec ci: Rely on custom Clear Linux cloud image
Rely on the newly generated Clear Linux image for the integration
testing of cloud-hypervisor. The image has been generated using the
Clear Linux clr-installer tooling, which means it is in compliance with
the Clear Linux licensing.

This new image contains one more bundle that was not part of the default
cloudguest image. This bundle is basic-sysadmin, and contains both nc
and socat utilities.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-10 17:57:49 +02:00
Sebastien Boeuf
4d86359a09 ci: Install socat on the host VM
In order to interact between host and guest through socket connection,
socat is a useful utility needed for integration testing.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-10 17:57:49 +02:00
Sebastien Boeuf
5e5c2f2c48 ci: Allow tests to print some useful information with println
In order to make the tests more verbose and help identify more quickly
where a test might be failing, this patch adds the ability for the unit
tests to print useful information with println.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-10 16:33:12 +01:00
Sebastien Boeuf
a9b2207bcf ci: Allow threads to send ssh commands
The goal here is to decouple the Guest instance from the ssh connection
to send some commands to the guest. The reason being to allow ssh
commands to be issued from a different thread, which can be useful to
wait for the end of a command with a thread.join().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-10 17:29:23 +02:00
Samuel Ortiz
40fc6c3f0f README: Update rust-hypervisor-firmware link
We should use the 0.2.0 firmware.

Fixes: #258

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-09-10 08:39:50 +01:00
Rob Bradford
389f9e3779 tests: Check that the test binary cleanly terminated
As part of the reboot test check that the binary cleanly terminated
after the subsequent shutdown.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-09 08:24:34 -07:00
Rob Bradford
8f37dec498 vmm: "close" the SIGWINCH signal handler
Rather than sending a signal to the signal handler used for handling
SIGWINCH calls instead use the crate provided termination method. This
also unregisters the signal handler which also means that there won't be
a leaked signal handler remaining.

This leaked signal handler is what was causing a failure to cleanup up
the thread on subsequent requests breaking two reboots in a row.

Fixes: #252

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-09 15:42:26 +02:00
dependabot-preview[bot]
c00b58de9b build(deps): bump pkg-config from 0.3.15 to 0.3.16
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.15 to 0.3.16.
- [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.15...0.3.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 12:48:05 +00:00
dependabot-preview[bot]
5f752dade7 build(deps): bump serde from 1.0.99 to 1.0.100
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.99 to 1.0.100.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.99...v1.0.100)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 08:17:00 +00:00
dependabot-preview[bot]
8e7d67fcfe build(deps): bump vmm-sys-util from 8703cfd to 07ef2e2
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from `8703cfd` to `07ef2e2`.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Commits](8703cfd427...07ef2e280e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 08:16:31 +00:00
dependabot-preview[bot]
b515d48eca build(deps): bump cc from 1.0.42 to 1.0.45
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.42 to 1.0.45.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.42...1.0.45)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 08:15:49 +00:00
Rob Bradford
eb46aa2b22 vmm: If acpi feature is disabled make "reboot" shutdown
With ACPI disabled there is no way to support both reset and shutdown so
make the VMM exit if the VM is rebootet (via i8042 or triple-fault
reset.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-06 11:03:44 -07:00
Sebastien Boeuf
7975394901 vm-virtio: vsock: Port unit testing from Firecracker
This unit testing porting effort is based off of Firecracker commit
1e1cb6f8f8003e0bdce11d265f0feb23249a03f6

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
5a3472847d vm-virtio: vsock: Implement VsockEpollHandler
This is the last step connecting the dots between the virtio-vsock
device and the bulk of the logic hosted in the unix and csm modules.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
475e487ac3 vmm: Create vsock backend
This commit relies on the new vsock::unix module to create the backend
that will be used from the virtio-vsock device.

The concept of backend is interesting here as it would allow for a vhost
kernel backend to be plugged if that was needed someday.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
434a5d0edf vm-virtio: vsock: Port submodule unix from Firecracker
This code porting is based off of Firecracker commit
1e1cb6f8f8003e0bdce11d265f0feb23249a03f6

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
df61a8fea2 vm-virtio: vsock: Port submodule csm and packet from Firecracker
This code porting is based off of Firecracker commit
1e1cb6f8f8003e0bdce11d265f0feb23249a03f6

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
22f91ab3a2 vm-virtio: Move vsock to its own module
There is a lot of code related to this virtio-vsock hybrid
implementation, that's why it's better to keep it under its
own module.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
4ccc81fdf9 vmm: Create virtio-vsock device
Based on previous patch introducing the new flag "--vsock", this commit
creates a new virtio-vsock device based on the presence of this flag.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
11e7ece9f5 vmm: Add new flag "--vsock"
The new flag vsock is meant to be used in order to create a VM with a
virtio-vsock device attached to it. Two parameters are needed with this
device, "cid" representing the guest context ID, and "sock" representing
the UNIX socket path which can be accessed from the host.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
c48ca61417 vm-virtio: Add virtio-vsock skeleton
This is the first commit introducing the support for virtio-vsock.

This is based off of Firecracker commit
1e1cb6f8f8003e0bdce11d265f0feb23249a03f6

Fixes #102

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Sebastien Boeuf
69e27288a2 vmm: Allocate enough MSI-X vectors for multiqueue virtio devices
The default number of MSI-X vector allocated was 2, which is the minimum
defined by the virtio specification. The reason for this minimum is that
virtio needs at least one interrupt to signal that configuration changed
and at least one to specify something happened regarding the virtqueues.

But this current implementation is not optimal because our VMM supports
as many MSI-X vectors as allowed by the MSI-X specification (2048 max).
For that reason, the current patch relies on the number of virtqueues
needed by the virtio device to determine the right amount of MSI-X
vectors needed. It's important not to forget the dedicated vector for
any configuration change too.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2019-09-06 10:51:25 -07:00
Rob Bradford
d2db34edf2 vmm: Hide underlying console setup from VM
Refactor the underlying console details into the DeviceManager and
abstract away.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-06 09:26:37 -07:00
Rob Bradford
d089ee4e25 vmm: Move ownership of the exit/reset EventFd to Vm structure
It makes more sense there as it is used by more than just the
DeviceManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-06 09:26:37 -07:00
Rob Bradford
2f4de81175 vmm: Access ioapic/io_bus/mmio_bus from DeviceManager via accessor
This paves the way for introducing a trait for the DeviceManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-06 09:26:37 -07:00
Rob Bradford
9ac967e3d8 vmm: Split DeviceManager into it's own file
Refactor out DeviceManager into it's own file. This is part of a bigger
effort to reduce complexity in the vm.rs file but will also allow future
separation to allow making PCI support optional.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-06 09:26:37 -07:00
dependabot-preview[bot]
f740a3568d build(deps): bump getrandom from 0.1.11 to 0.1.12
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.1.11 to 0.1.12.
- [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.1.11...v0.1.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-06 14:07:55 +00:00
dependabot-preview[bot]
e21bc972b0 build(deps): bump vmm-sys-util from fd4dcd1 to 8703cfd
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from `fd4dcd1` to `8703cfd`.
- [Release notes](https://github.com/rust-vmm/vmm-sys-util/releases)
- [Commits](fd4dcd172e...8703cfd427)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-06 06:37:14 +00:00
dependabot-preview[bot]
d446a8217a build(deps): bump blake2b_simd from 0.5.7 to 0.5.8
Bumps [blake2b_simd](https://github.com/oconnor663/blake2_simd) from 0.5.7 to 0.5.8.
- [Release notes](https://github.com/oconnor663/blake2_simd/releases)
- [Commits](https://github.com/oconnor663/blake2_simd/compare/0.5.7...0.5.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-05 18:41:53 +00:00
dependabot-preview[bot]
2432ad07ea build(deps): bump cc from 1.0.41 to 1.0.42
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.41 to 1.0.42.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.41...1.0.42)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-05 16:41:42 +00:00
Rob Bradford
9661e8da5d build: Really make the acpi feature disableable
The command "cargo build --no-default-features" does not recursively
disable the default features across the workspace. Instead add an acpi
feature at the top-level, making it default, and then make that feature
conditional on all the crate acpi features.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2019-09-05 08:58:47 -07:00
263 changed files with 68840 additions and 26550 deletions

15
.github/workflows/audit.yaml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Cloud Hypervisor Dependency Audit
on:
pull_request:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
jobs:
security_audit:
name: Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}

41
.github/workflows/build.yaml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Cloud Hypervisor Build
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
- nightly
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- name: Debug Build (default features)
run: cargo build --all --target=${{ matrix.target }}
- name: Build (pci,acpi,kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "pci,acpi,kvm" -- -D warnings
- name: Build (pci,kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "pci,kvm" -- -D warnings
- name: Build (mmio,kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "mmio,kvm" -- -D warnings
- name: Release Build (default features)
run: cargo build --all --release --target=${{ matrix.target }}

32
.github/workflows/cross-build.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Cloud Hypervisor Cross Build
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
target:
- aarch64-unknown-linux-gnu
- aarch64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- name: Install arm64 libfdt
run: wget http://ftp.us.debian.org/debian/pool/main/d/device-tree-compiler/libfdt-dev_1.6.0-1_arm64.deb && dpkg-deb -xv libfdt-dev_1.6.0-1_arm64.deb ./tlibfdtdev && sudo mkdir /tmmmp && mkdir target && mkdir target/debug && mkdir target/debug/deps && sudo cp ./tlibfdtdev/usr/lib/aarch64-linux-gnu/libfdt.a target/debug/deps/libfdt.a && echo "libfdt installed"
- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --target=${{ matrix.target }} --no-default-features --features "mmio,kvm"

40
.github/workflows/quality-aarch64.yaml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Cloud Hypervisor Quality Checks
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Quality (clippy, rustfmt)
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
target:
- aarch64-unknown-linux-gnu
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
components: rustfmt, clippy
- name: Install arm64 libfdt
run: wget http://ftp.us.debian.org/debian/pool/main/d/device-tree-compiler/libfdt-dev_1.6.0-1_arm64.deb && dpkg-deb -xv libfdt-dev_1.6.0-1_arm64.deb ./tlibfdtdev && sudo mkdir /tmmmp && mkdir target && mkdir target/debug && mkdir target/debug/deps && sudo cp ./tlibfdtdev/usr/lib/aarch64-linux-gnu/libfdt.a target/debug/deps/libfdt.a && echo "libfdt installed"
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (mmio,kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --no-default-features --features "mmio,kvm" -- -D warnings
- name: Clippy (pci,kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --no-default-features --features "pci,kvm" -- -D warnings

39
.github/workflows/quality.yaml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Cloud Hypervisor Quality Checks
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Quality (clippy, rustfmt)
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
target:
- x86_64-unknown-linux-gnu
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
components: rustfmt, clippy
- name: Formatting (rustfmt)
run: cargo fmt -- --check
- name: Clippy (all features)
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Clippy (pci,acpi,kvm)
run: cargo clippy --all-targets --no-default-features --features "pci,acpi,kvm" -- -D warnings
- name: Clippy (pci,kvm)
run: cargo clippy --all-targets --no-default-features --features "pci,kvm" -- -D warnings
- name: Clippy (mmio,kvm)
run: cargo clippy --all-targets --no-default-features --features "mmio,kvm" -- -D warnings

67
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: Cloud Hypervisor Release
on: [create]
jobs:
release:
if: github.event_name == 'create' && github.event.ref_type == 'tag'
name: Release
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-musl
- name: Build
run: cargo build --all --release --target=x86_64-unknown-linux-gnu
- name: Static Build
run: cargo build --all --release --target=x86_64-unknown-linux-musl
- name: Strip cloud-hypervisor binaries
run: strip target/*/release/cloud-hypervisor
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: true
prerelease: true
- name: Upload cloud-hypervisor
id: upload-release-cloud-hypervisor
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-gnu/release/cloud-hypervisor
asset_name: cloud-hypervisor
asset_content_type: application/octet-stream
- name: Upload static cloud-hypervisor
id: upload-release-static-cloud-hypervisor
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/cloud-hypervisor
asset_name: cloud-hypervisor-static
asset_content_type: application/octet-stream
- name: Upload ch-remote
id: upload-release-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-gnu/release/ch-remote
asset_name: ch-remote
asset_content_type: application/octet-stream

1
.gitignore vendored
View File

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

1
.rustfmt.toml Normal file
View File

@@ -0,0 +1 @@
edition = "2018"

View File

@@ -1,24 +0,0 @@
language: rust
rust:
- stable
before_script:
- rustup component add clippy
- rustup component add rustfmt
script:
- cargo build --release
- cargo build --release --no-default-features
- cargo test
- cargo clippy --all-targets --all-features -- -D warnings
- find . -name "*.rs" | xargs rustfmt --check
deploy:
provider: releases
api_key: $GITHUB_OAUTH_TOKEN
file: target/release/cloud-hypervisor
skip_cleanup: true
draft: true
on:
tags: true

View File

@@ -51,7 +51,7 @@ Signed-off-by: Rob Bradford <robert.bradford@intel.com>
Cloud Hypervisor uses the “fork-and-pull” development model. Follow these steps if
you want to merge your changes to `cloud-hypervisor`:
1. Fork the [cloud-hypervisor](https://github.com/intel/cloud-hypervisor) project
1. Fork the [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor) project
into your github organization.
2. Within your fork, create a branch for your contribution.
3. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
@@ -65,7 +65,7 @@ you want to merge your changes to `cloud-hypervisor`:
## Issue tracking
If you have a problem, please let us know. We recommend using
[github issues](https://github.com/intel/cloud-hypervisor/issues/new) for formally
[github issues](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new) for formally
reporting and documenting them.
To quickly and informally bring something up to us, you can also reach out on [Slack](https://cloud-hypervisor.slack.com).

1624
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,80 @@
[package]
name = "cloud-hypervisor"
version = "0.1.0"
version = "0.10.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
default-run = "cloud-hypervisor"
build = "build.rs"
license = "LICENSE-APACHE & LICENSE-BSD-3-Clause"
description = "Open source Virtual Machine Monitor (VMM) that runs on top of KVM"
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
[profile.release]
lto = true
[dependencies]
clap = "2.33.0"
lazy_static = "1.4.0"
log = { version = "0.4.8", features = ["std"] }
clap = { version = "2.33.3", features = ["wrap_help"] }
hypervisor = { path = "hypervisor" }
libc = "0.2.77"
log = { version = "0.4.11", features = ["std"] }
option_parser = { path = "option_parser" }
seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" }
serde_json = "1.0.57"
vhost_user_block = { path = "vhost_user_block"}
vhost_user_net = { path = "vhost_user_net"}
vmm = { path = "vmm" }
vmm-sys-util = "0.6.1"
[build-dependencies]
clap = { version = "2.33.3", features = ["wrap_help"] }
[patch.crates-io]
vm-memory = { git = "https://github.com/cloud-hypervisor/vm-memory", branch = "ch" }
[dev-dependencies]
ssh2 = "0.3.3"
dirs = "2.0.2"
ssh2 = "0.8.2"
dirs = "3.0.1"
credibility = "0.1.3"
tempdir= "0.3.7"
tempdir = "0.3.7"
lazy_static= "1.4.0"
tempfile = "3.1.0"
serde_json = "1.0.57"
net_util = { path = "net_util" }
[features]
default = []
default = ["acpi", "pci", "cmos", "kvm"]
acpi = ["vmm/acpi"]
pci = ["vmm/pci_support"]
mmio = ["vmm/mmio_support"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
kvm = ["vmm/kvm"]
io_uring = ["vmm/io_uring"]
# Integration tests require a special environment to run in
integration_tests = []
[workspace]
members = [
"acpi_tables",
"arch",
"arch_gen",
"block_util",
"devices",
"hypervisor",
"net_gen",
"net_util",
"option_parser",
"pci",
"qcow",
"vhost_user_backend",
"vhost_user_block",
"vhost_user_fs",
"vhost_user_net",
"virtio-devices",
"vmm",
"vm-allocator",
"vm-device",
"vm-migration",
"vm-virtio"
]

179
Jenkinsfile vendored
View File

@@ -1,22 +1,171 @@
stage ("Builds") {
node ('bionic') {
stage ('Checkout') {
checkout scm
pipeline{
agent none
stages {
stage ('Early checks') {
agent { node { label 'master' } }
stages {
stage ('Check for RFC/WIP builds') {
when {
changeRequest comparator: 'REGEXP', title: '.*(rfc|RFC|wip|WIP).*'
beforeAgent true
}
steps {
error("Failing as this is marked as a WIP or RFC PR.")
}
}
stage ('Cancel older builds') {
when { not { branch 'master' } }
steps {
cancelPreviousBuilds()
}
}
}
}
stage ('Install system packages') {
sh "sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq build-essential mtools libssl-dev pkg-config"
sh "sudo apt-get install -yq flex bison libelf-dev qemu-utils qemu-system libglib2.0-dev libpixman-1-dev libseccomp-dev"
stage ('Build') {
failFast true
parallel {
stage ('Worker build') {
agent { node { label 'bionic' } }
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run OpenAPI tests') {
steps {
sh "scripts/run_openapi_tests.sh"
}
}
stage ('Run unit tests') {
steps {
sh "scripts/dev_cli.sh tests --unit"
}
}
stage ('Run integration tests') {
steps {
sh "scripts/dev_cli.sh tests --integration"
}
}
}
}
stage ('AArch64 worker build') {
agent { node { label 'bionic-arm64' } }
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run unit tests') {
steps {
sh "scripts/dev_cli.sh tests --unit"
}
}
stage ('Run integration tests') {
steps {
sh "scripts/dev_cli.sh tests --integration"
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage ('Worker build (musl)') {
agent { node { label 'bionic' } }
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run unit tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --unit --libc musl"
}
}
stage ('Run integration tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --integration --libc musl"
}
}
}
}
stage ('Worker build SGX') {
agent { node { label 'bionic-sgx' } }
options {
timeout(time: 1, unit: 'HOURS')
}
when { branch 'master' }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run SGX integration tests') {
steps {
sh "scripts/dev_cli.sh tests --integration-sgx"
}
}
stage ('Run SGX integration tests for musl') {
steps {
sh "scripts/dev_cli.sh tests --integration-sgx --libc musl"
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
}
}
stage ('Install Rust') {
sh "nohup curl https://sh.rustup.rs -sSf | sh -s -- -y"
}
post {
regression {
script {
if (env.BRANCH_NAME == 'master') {
slackSend (color: '#ff0000', message: '"master" branch build is now failing')
}
}
}
stage ('Run unit tests') {
sh "scripts/run_unit_tests.sh"
}
stage ('Run integration tests') {
sh "sudo mount -t tmpfs tmpfs /tmp"
sh "scripts/run_integration_tests.sh"
fixed {
script {
if (env.BRANCH_NAME == 'master') {
slackSend (color: '#00ff00', message: '"master" branch build is now fixed')
}
}
}
}
}
def cancelPreviousBuilds() {
// Check for other instances of this particular build, cancel any that are older than the current one
def jobName = env.JOB_NAME
def currentBuildNumber = env.BUILD_NUMBER.toInteger()
def currentJob = Jenkins.instance.getItemByFullName(jobName)
// Loop through all instances of this particular job/branch
for (def build : currentJob.builds) {
if (build.isBuilding() && (build.number.toInteger() < currentBuildNumber)) {
echo "Older build still queued. Sending kill signal to build number: ${build.number}"
build.doStop()
}
}
}

211
README.md
View File

@@ -1,34 +1,34 @@
[![Build Status](https://travis-ci.com/intel/cloud-hypervisor.svg?branch=master)](https://travis-ci.com/intel/cloud-hypervisor)
[![Build Status](https://travis-ci.com/cloud-hypervisor/cloud-hypervisor.svg?branch=master)](https://travis-ci.com/cloud-hypervisor/cloud-hypervisor)
1. [What is Cloud Hypervisor?](#1-what-is-cloud-hypervisor)
* [Requirements](#requirements)
+ [High Level](#high-level)
+ [Architectures](#architectures)
+ [Guest OS](#guest-os)
2. [Getting Started](#2-getting-started)
* [Clone and build](#clone-and-build)
* [Run](#run)
+ [Cloud image](#cloud-image)
+ [Custom kernel and disk image](#custom-kernel-and-disk-image)
- [Building your kernel](#building-your-kernel)
- [Disk image](#disk-image)
- [Booting the guest VM](#booting-the-guest-vm)
3. [Status](#2-status)
* [TODO](#todo)
4. [rust-vmm dependency](#4-rust-vmm-dependency)
* [Firecracker and crosvm](#firecracker-and-crosvm)
5. [Community](#5-community)
* [Join us](#join-us)
6. [Security](#6-security)
- [1. What is Cloud Hypervisor?](#1-what-is-cloud-hypervisor)
- [Objectives](#objectives)
- [High Level](#high-level)
- [Architectures](#architectures)
- [Guest OS](#guest-os)
- [2. Getting Started](#2-getting-started)
- [Clone and build](#clone-and-build)
- [Containerized builds and tests](#containerized-builds-and-tests)
- [Run](#run)
- [Cloud image](#cloud-image)
- [Custom kernel and disk image](#custom-kernel-and-disk-image)
- [Building your kernel](#building-your-kernel)
- [Disk image](#disk-image)
- [Booting the guest VM](#booting-the-guest-vm)
- [3. Status](#3-status)
- [Hot Plug](#hot-plug)
- [Device Model](#device-model)
- [TODO](#todo)
- [4. `rust-vmm` project dependency](#4-rust-vmm-project-dependency)
- [Firecracker and crosvm](#firecracker-and-crosvm)
- [5. Community](#5-community)
- [Contribute](#contribute)
- [Join us](#join-us)
# 1. What is Cloud Hypervisor?
**This project is an experiment and should not be used with production workloads.**
Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of [KVM](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt).
The project focuses on exclusively running modern, cloud workloads, on top of a limited set of hardware architectures and platforms.
Cloud workloads refers to those that are usually run by customers inside a cloud provider. For our purposes this means modern
Linux* distributions with most I/O handled by paravirtualised devices (i.e. virtio), no requirement for legacy devices and recent CPUs and KVM.
Cloud workloads refers to those that are usually run by customers inside a cloud provider. For our purposes this means modern operating systems with most I/O handled by paravirtualised devices (i.e. virtio), no requirement for legacy devices, and 64-bit CPUs.
Cloud Hypervisor is implemented in [Rust](https://www.rust-lang.org/) and is based on the [rust-vmm](https://github.com/rust-vmm) crates.
@@ -36,7 +36,7 @@ Cloud Hypervisor is implemented in [Rust](https://www.rust-lang.org/) and is bas
### High Level
* KVM and KVM only based
* KVM based
* Minimal emulation
* Low latency
* Low memory footprint
@@ -44,19 +44,16 @@ Cloud Hypervisor is implemented in [Rust](https://www.rust-lang.org/) and is bas
* High performance
* Small attack surface
* 64-bit support only
* Build time configurable CPU, memory, PCI and NVDIMM hotplug
* CPU, memory, PCI hotplug
* Machine to machine migration
### Architectures
`cloud-hypervisor` only supports the `x86-64` CPU architecture for now.
We're planning to add support for the `AArch64` architecture in the future.
Cloud Hypervisor supports the `x86-64` and `AArch64` architecture. There are some small differences in functionality between the two architecture (see #1125).
### Guest OS
* `64-bit Linux`
Support for *modern* 64-bit Windows guest is being evaluated.
Cloud Hypervisor supports `64-bit Linux` with support for *modern* 64-bit Windows guests currently under development.
# 2. Getting Started
@@ -73,7 +70,7 @@ First you need to clone and build the cloud-hypervisor repo:
```shell
$ pushd $CLOUDH
$ git clone https://github.com/intel/cloud-hypervisor.git
$ git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
$ cd cloud-hypervisor
$ cargo build --release
@@ -85,26 +82,54 @@ $ popd
This will build a `cloud-hypervisor` binary under `$CLOUDH/cloud-hypervisor/target/release/cloud-hypervisor`.
### Containerized builds and tests
If you want to build and test Cloud Hypervisor without having to install all the
required dependencies (The rust toolchain, cargo tools, etc), you can also use
Cloud Hypervisor's development script: `dev_cli.sh`. Please note that upon its
first invocation, this script will pull a fairly large container image.
For example, to build the Cloud Hypervisor release binary:
```shell
$ pushd $CLOUDH
$ cd cloud-hypervisor
$ ./scripts/dev_cli.sh build --release
```
With `dev_cli.sh`, one can also run the Cloud Hypervisor CI locally. This can be
very convenient for debugging CI errors without having to fully rely on the
Cloud Hypervisor CI infrastructure.
For example, to run the Cloud Hypervisor unit tests:
```shell
$ ./scripts/dev_cli.sh tests --unit
```
Run the `./scripts/dev_cli.sh --help` command to view all the supported
development script commands and their related options.
## Run
You can run a guest VM by either using an existing cloud image or booting into your own kernel and disk image.
### Cloud image
`cloud-hypervisor` supports booting disk images containing all needed
Cloud Hypervisor supports booting disk images containing all needed
components to run cloud workloads, a.k.a. cloud images. To do that we rely on
the [Rust Hypervisor
Firmware](https://github.com/intel/rust-hypervisor-firmware) project to provide
Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware) project to provide
an ELF
formatted KVM firmware for `cloud-hypervisor` to directly boot into.
We need to get the latest `rust-hypervisor-firmware` release and also a working cloud image. Here we will use a Clear Linux image:
We need to get the latest `rust-hypervisor-firmware` release and also a working cloud image. Here we will use a Ubuntu image:
```shell
$ pushd $CLOUDH
$ wget https://download.clearlinux.org/releases/29160/clear/clear-29160-kvm.img.xz
$ unxz clear-29160-kvm.img.xz
$ wget https://github.com/intel/rust-hypervisor-firmware/releases/download/0.1.0/hypervisor-fw
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.2.8/hypervisor-fw
$ popd
```
@@ -113,33 +138,33 @@ $ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk ./clear-29160-kvm.img \
--cpus 4 \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
$ popd
```
Multiple arguments can be given to the `--disk` parameter, currently the firmware requires that the bootable image is on the first disk.
Multiple arguments can be given to the `--disk` parameter.
### Custom kernel and disk image
#### Building your kernel
`cloud-hypervisor` also supports direct kernel boot into a `vmlinux` ELF kernel
image. You want to build such an image first:
Cloud Hypervisor also supports direct kernel boot into a `vmlinux` ELF kernel or `bzImage`. In order to support virtio-fs and virtio-iommu we have our own development branch. You are of course able to use your own kernel but these instructions will continue with the version that we develop and test against.
To build the kernel:
```shell
# Clone a 5.0 Linux kernel
# Clone the Cloud Hypervisor Linux branch
$ pushd $CLOUDH
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux-cloud-hypervisor
$ cd linux-cloud-hypervisor
$ git reset --hard v5.0
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b virtio-fs-virtio-iommu-virtio-mem-5.6-rc4 linux-cloud-hypervisor
$ pushd linux-cloud-hypervisor
# Use the cloud-hypervisor kernel config to build your kernel
$ cp $CLOUDH/cloud-hypervisor/resources/linux-5.0-config .config
$ cp $CLOUDH/cloud-hypervisor/resources/linux-config-x86_64 .config
$ make bzImage -j `nproc`
$ popd
```
@@ -148,18 +173,18 @@ The `vmlinux` kernel image will then be located at `linux-cloud-hypervisor/arch/
#### Disk image
For the disk image, we will use a Clear Linux cloud image that contains a root partition:
For the disk image, we will use a Ubuntu cloud image that contains a root partition:
```shell
$ pushd $CLOUDH
$ wget https://download.clearlinux.org/releases/29160/clear/clear-29160-kvm.img.xz
$ unxz clear-29160-kvm.img.xz
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
$ qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
$ popd
```
#### Booting the guest VM
Now we can directly boot into our custom kernel and make it use the Clear Linux root partition.
Now we can directly boot into our custom kernel and make it use the Ubuntu root partition.
If we want to have 4 vCPUs and 512 MBytes of memory:
```shell
@@ -167,9 +192,9 @@ $ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--disk ./clear-29160-kvm.img \
--cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--cpus 4 \
--disk path=focal-server-cloudimg-amd64.raw \
--cmdline "console=hvc0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
@@ -187,51 +212,61 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \
--serial tty \
--disk ./clear-29160-kvm.img \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--cpus 4 \
--disk path=focal-server-cloudimg-amd64.raw \
--cmdline "console=ttyS0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng
```
# 3. Status
`cloud-hypervisor` is in a very early, pre-alpha stage. Use at your own risk!
Cloud Hypervisor is under active development. No API or feature stability is guaranteed.
As of 2019/05/12, booting cloud images has only been tested with [Clear Linux images](https://download.clearlinux.org/current/).
Direct kernel boot to userspace should work with most rootfs and it's been tested with
Clear Linux root partitions, and also basic initrd/initramfs images.
As of 2020-07-02, the following cloud images are supported:
* [Ubuntu Bionic](https://cloud-images.ubuntu.com/bionic/current/) (cloudimg)
* [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (cloudimg)
Direct kernel boot to userspace should work with a rootfs from most distributions.
## Hot Plug
Cloud Hypervisor supports hotplug of CPUs, passthrough devices (VFIO), `virtio-{net,block,pmem,fs,vsock}` and memory resizing. This [document](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/hotplug.md) details how to add devices to
a running VM.
## Device Model
Details of the device model can be found in this [documentation](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/device_model.md).
## TODO
We are not tracking the `cloud-hypervisor` TODO list from a specific git tracked file but through
[github issues](https://github.com/intel/cloud-hypervisor/issues/new) instead.
We are not tracking the Cloud Hypervisor TODO list from a specific git tracked file but through
[github issues](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new) instead.
# 4. `rust-vmm` project dependency
In order to satisfy the design goal of having a high-performance, security-focused hypervisor the decision
was made to use the [Rust](https://www.rust-lang.org/) programming language.
The language's strong focus on memory and thread safety makes it an ideal candidate for implementing VMMs
The language's strong focus on memory and thread safety makes it an ideal candidate for implementing VMMs.
Instead of implementing the VMM components from scratch, `cloud-hypervisor` is importing the [rust-vmm](https://github.com/rust-vmm)
Instead of implementing the VMM components from scratch, Cloud Hypervisor is importing the [rust-vmm](https://github.com/rust-vmm)
crates, and sharing code and architecture together with other VMMs like e.g. Amazon's [Firecracker](https://firecracker-microvm.github.io/)
and Google's [crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm/).
`cloud-hypervisor` embraces the rust-vmm project goals, which is to be able to share and re-use
as many virtualization crates as possible. As such, the `cloud-hypervisor` relationship with the rust-vmm
Cloud Hypervisor embraces the rust-vmm project goals, which is to be able to share and re-use
as many virtualization crates as possible. As such, the Cloud Hypervisor relationship with the rust-vmm
project is twofold:
1. It will use as much of the rust-vmm code as possible. Any new rust-vmm crate that's relevant to the project
goals will be integrated as soon as possible.
2. As it is likely that the rust-vmm project will lack some of the features that `cloud-hypervisor` needs (e.g. ACPI,
VFIO, vhost-user, etc), we will be using the `cloud-hypervisor` VMM to implement and test them, and contribute them
2. As it is likely that the rust-vmm project will lack some of the features that Cloud Hypervisor needs (e.g. ACPI,
VFIO, vhost-user, etc), we will be using the Cloud Hypervisor VMM to implement and test them, and contribute them
back to the rust-vmm project.
## Firecracker and crosvm
A large part of the `cloud-hypervisor` code is based on either the Firecracker or the crosvm projects implementations.
A large part of the Cloud Hypervisor code is based on either the Firecracker or the crosvm projects implementations.
Both of these are VMMs written in Rust with a focus on safety and security, like Cloud Hypervisor.
However we want to emphasize that the Cloud Hypervisor project is neither a fork nor a reimplementation of any of those
@@ -246,6 +281,11 @@ crates as possible.
# 5. Community
The Cloud Hypervisor project follows the governance, and community guidelines described in
the [Community](https://github.com/cloud-hypervisor/community) repository.
## Contribute
We are working on building a global, diverse and collaborative community around the Cloud Hypervisor project.
Anyone who is interested in [contributing](CONTRIBUTING.md) to the project is welcome to participate.
@@ -255,29 +295,6 @@ etc, are all equal and welcome means of contribution. See the [CONTRIBUTING](CON
## Join us
Get an [invite to our Slack channel](https://join.slack.com/t/cloud-hypervisor/shared_invite/enQtNjY3MTE3MDkwNDQ4LTc0YzlmYzQxZDkxNDVhYzZjZjA5MTkxMGY3NTI3YzMzYTFkM2IyY2E0YTIxMzkyYTEwYzdlMzBhMWYxYzVmNDI)
Get an [invite to our Slack channel](https://join.slack.com/t/cloud-hypervisor/shared_invite/enQtNjY3MTE3MDkwNDQ4LWQ1MTA1ZDVmODkwMWQ1MTRhYzk4ZGNlN2UwNTI3ZmFlODU0OTcwOWZjMTkwZDExYWE3YjFmNzgzY2FmNDAyMjI)
and [join us on Slack](https://cloud-hypervisor.slack.com/).
# 6. Security
**Reporting a Potential Security Vulnerability**: If you have discovered
potential security vulnerability in this project, please send an e-mail to
secure@intel.com. For issues related to Intel Products, please visit
https://security-center.intel.com.
It is important to include the following details:
- The projects and versions affected
- Detailed description of the vulnerability
- Information on known exploits
Vulnerability information is extremely sensitive. Please encrypt all security
vulnerability reports using our *PGP key*
A member of the Intel Product Security Team will review your e-mail and
contact you to to collaborate on resolving the issue. For more information on
how Intel works to resolve security issues, see: *Vulnerability Handling
Guidelines*
PGP Key: https://www.intel.com/content/www/us/en/security-center/pgp-public-key.html
Vulnerability Handling Guidelines: https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html

View File

@@ -5,5 +5,5 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[dependencies]
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
vm-memory = "0.2.1"

1988
acpi_tables/src/aml.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//
pub mod aml;
pub mod rsdp;
pub mod sdt;

View File

@@ -36,7 +36,7 @@ impl RSDP {
};
rsdp.checksum = super::generate_checksum(&rsdp.as_slice()[0..19]);
rsdp.extended_checksum = super::generate_checksum(&rsdp.as_slice());;
rsdp.extended_checksum = super::generate_checksum(&rsdp.as_slice());
rsdp
}

View File

@@ -13,12 +13,12 @@ pub struct GenericAddress {
}
impl GenericAddress {
pub fn io_port_address(address: u16) -> Self {
pub fn io_port_address<T>(address: u16) -> Self {
GenericAddress {
address_space_id: 1,
register_bit_width: 8,
register_bit_width: 8 * std::mem::size_of::<T>() as u8,
register_bit_offset: 0,
access_size: 1,
access_size: std::mem::size_of::<T>() as u8,
address: u64::from(address),
}
}
@@ -77,6 +77,14 @@ impl SDT {
self.write(orig_length, value);
}
pub fn append_slice(&mut self, data: &[u8]) {
let orig_length = self.data.len();
let new_length = orig_length + data.len();
self.write_u32(4, new_length as u32);
self.data.extend_from_slice(data);
self.update_checksum();
}
/// Write a value at the given offset
pub fn write<T>(&mut self, offset: usize, value: T) {
assert!((offset + (std::mem::size_of::<T>() - 1)) < self.data.len());

View File

@@ -4,25 +4,22 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[features]
default = ["acpi"]
default = []
acpi = ["acpi_tables"]
[dependencies]
byteorder = "1.3.2"
kvm-bindings = "0.1.1"
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "master" }
libc = "0.2.60"
anyhow = "1.0"
byteorder = "1.3.4"
hypervisor = { path = "../hypervisor" }
libc = "0.2.77"
log = "0.4.11"
vm-memory = { version = "0.2.1", features = ["backend-mmap"] }
acpi_tables = { path = "../acpi_tables", optional = true }
arch_gen = { path = "../arch_gen" }
[dependencies.vm-memory]
git = "https://github.com/rust-vmm/vm-memory"
features = ["backend-mmap"]
[dependencies.linux-loader]
git = "https://github.com/rust-vmm/linux-loader"
features = ["elf", "bzimage"]
[dev-dependencies]
rand = "0.7.0"
rand = "0.7.3"

595
arch/src/aarch64/fdt.rs Normal file
View File

@@ -0,0 +1,595 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use libc::{c_char, c_int, c_void};
use std::collections::HashMap;
use std::ffi::{CStr, CString, NulError};
use std::fmt::Debug;
use std::ptr::null;
use std::{io, result};
use super::super::DeviceType;
use super::super::InitramfsConfig;
use super::get_fdt_addr;
use super::gic::GICDevice;
use super::layout::{
FDT_MAX_SIZE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, PCI_MMCONFIG_SIZE,
PCI_MMCONFIG_START,
};
use crate::aarch64::fdt::Error::CstringFDTTransform;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
// This is a value for uniquely identifying the FDT node declaring the interrupt controller.
const GIC_PHANDLE: u32 = 1;
// This is a value for uniquely identifying the FDT node declaring the MSI controller.
const MSI_PHANDLE: u32 = 2;
// This is a value for uniquely identifying the FDT node containing the clock definition.
const CLOCK_PHANDLE: u32 = 3;
// Read the documentation specified when appending the root node to the FDT.
const ADDRESS_CELLS: u32 = 0x2;
const SIZE_CELLS: u32 = 0x2;
// As per kvm tool and
// https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.txt
// Look for "The 1st cell..."
const GIC_FDT_IRQ_TYPE_SPI: u32 = 0;
const GIC_FDT_IRQ_TYPE_PPI: u32 = 1;
// From https://elixir.bootlin.com/linux/v4.9.62/source/include/dt-bindings/interrupt-controller/irq.h#L17
const IRQ_TYPE_EDGE_RISING: u32 = 1;
const IRQ_TYPE_LEVEL_HI: u32 = 4;
// This links to libfdt which handles the creation of the binary blob
// flattened device tree (fdt) that is passed to the kernel and indicates
// the hardware configuration of the machine.
#[link(name = "fdt")]
extern "C" {
fn fdt_create(buf: *mut c_void, bufsize: c_int) -> c_int;
fn fdt_finish_reservemap(fdt: *mut c_void) -> c_int;
fn fdt_begin_node(fdt: *mut c_void, name: *const c_char) -> c_int;
fn fdt_property(fdt: *mut c_void, name: *const c_char, val: *const c_void, len: c_int)
-> c_int;
fn fdt_end_node(fdt: *mut c_void) -> c_int;
fn fdt_open_into(fdt: *const c_void, buf: *mut c_void, bufsize: c_int) -> c_int;
fn fdt_finish(fdt: *const c_void) -> c_int;
fn fdt_pack(fdt: *mut c_void) -> c_int;
}
/// Trait for devices to be added to the Flattened Device Tree.
pub trait DeviceInfoForFDT {
/// Returns the address where this device will be loaded.
fn addr(&self) -> u64;
/// Returns the associated interrupt for this device.
fn irq(&self) -> u32;
/// Returns the amount of memory that needs to be reserved for this device.
fn length(&self) -> u64;
}
/// Errors thrown while configuring the Flattened Device Tree for aarch64.
#[derive(Debug)]
pub enum Error {
/// Failed to append node to the FDT.
AppendFDTNode(io::Error),
/// Failed to append a property to the FDT.
AppendFDTProperty(io::Error),
/// Syscall for creating FDT failed.
CreateFDT(io::Error),
/// Failed to obtain a C style string.
CstringFDTTransform(NulError),
/// Failure in calling syscall for terminating this FDT.
FinishFDTReserveMap(io::Error),
/// Failure in writing FDT in memory.
WriteFDTToMemory(GuestMemoryError),
}
type Result<T> = result::Result<T, Error>;
/// Creates the flattened device tree for this aarch64 VM.
pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
guest_mem: &GuestMemoryMmap,
cmdline: &CStr,
vcpu_mpidr: Vec<u64>,
device_info: &HashMap<(DeviceType, String), T, S>,
gic_device: &dyn GICDevice,
initrd: &Option<InitramfsConfig>,
pci_space_address: &Option<(u64, u64)>,
) -> Result<Vec<u8>> {
// Alocate stuff necessary for the holding the blob.
let mut fdt = vec![0; FDT_MAX_SIZE];
allocate_fdt(&mut fdt)?;
// For an explanation why these nodes were introduced in the blob take a look at
// https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L845
// Look for "Required nodes and properties".
// Header or the root node as per above mentioned documentation.
append_begin_node(&mut fdt, "")?;
append_property_string(&mut fdt, "compatible", "linux,dummy-virt")?;
// For info on #address-cells and size-cells read "Note about cells and address representation"
// from the above mentioned txt file.
append_property_u32(&mut fdt, "#address-cells", ADDRESS_CELLS)?;
append_property_u32(&mut fdt, "#size-cells", SIZE_CELLS)?;
// This is not mandatory but we use it to point the root node to the node
// containing description of the interrupt controller for this VM.
append_property_u32(&mut fdt, "interrupt-parent", GIC_PHANDLE)?;
create_cpu_nodes(&mut fdt, &vcpu_mpidr)?;
create_memory_node(&mut fdt, guest_mem)?;
create_chosen_node(&mut fdt, cmdline, initrd)?;
create_gic_node(&mut fdt, gic_device)?;
create_timer_node(&mut fdt)?;
create_clock_node(&mut fdt)?;
create_psci_node(&mut fdt)?;
create_devices_node(&mut fdt, device_info)?;
if let Some((pci_device_base, pci_device_size)) = pci_space_address {
create_pci_nodes(&mut fdt, *pci_device_base, *pci_device_size)?;
}
// End Header node.
append_end_node(&mut fdt)?;
// Allocate another buffer so we can format and then write fdt to guest.
let mut fdt_final = vec![0; FDT_MAX_SIZE];
finish_fdt(&mut fdt, &mut fdt_final)?;
// Write FDT to memory.
let fdt_address = GuestAddress(get_fdt_addr(&guest_mem));
guest_mem
.write_slice(fdt_final.as_slice(), fdt_address)
.map_err(Error::WriteFDTToMemory)?;
Ok(fdt_final)
}
// Following are auxiliary functions for allocating and finishing the FDT.
fn allocate_fdt(fdt: &mut Vec<u8>) -> Result<()> {
// Safe since we allocated this array with FDT_MAX_SIZE.
let mut fdt_ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, FDT_MAX_SIZE as c_int) };
if fdt_ret != 0 {
return Err(Error::CreateFDT(io::Error::last_os_error()));
}
// The flattened device trees created with fdt_create() contains a list of
// reserved memory areas. We need to call `fdt_finish_reservemap` so as to make sure that there is a
// terminator in the reservemap list and whatever happened to be at the
// start of the FDT data section would end up being interpreted as
// reservemap entries.
// Safe since we previously allocated this array.
fdt_ret = unsafe { fdt_finish_reservemap(fdt.as_mut_ptr() as *mut c_void) };
if fdt_ret != 0 {
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
}
Ok(())
}
fn finish_fdt(from_fdt: &mut Vec<u8>, to_fdt: &mut Vec<u8>) -> Result<()> {
// Safe since we allocated `fdt_final` and previously passed in its size.
let mut fdt_ret = unsafe { fdt_finish(from_fdt.as_mut_ptr() as *mut c_void) };
if fdt_ret != 0 {
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
}
// Safe because we allocated both arrays with the correct size.
fdt_ret = unsafe {
fdt_open_into(
from_fdt.as_mut_ptr() as *mut c_void,
to_fdt.as_mut_ptr() as *mut c_void,
FDT_MAX_SIZE as i32,
)
};
if fdt_ret != 0 {
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
}
// Safe since we allocated `to_fdt`.
fdt_ret = unsafe { fdt_pack(to_fdt.as_mut_ptr() as *mut c_void) };
if fdt_ret != 0 {
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
}
Ok(())
}
// Following are auxiliary functions for appending nodes to FDT.
fn append_begin_node(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
// Safe because we allocated fdt and converted name to a CString
let fdt_ret = unsafe { fdt_begin_node(fdt.as_mut_ptr() as *mut c_void, cstr_name.as_ptr()) };
if fdt_ret != 0 {
return Err(Error::AppendFDTNode(io::Error::last_os_error()));
}
Ok(())
}
fn append_end_node(fdt: &mut Vec<u8>) -> Result<()> {
// Safe because we allocated fdt.
let fdt_ret = unsafe { fdt_end_node(fdt.as_mut_ptr() as *mut c_void) };
if fdt_ret != 0 {
return Err(Error::AppendFDTNode(io::Error::last_os_error()));
}
Ok(())
}
// Following are auxiliary functions for appending property nodes to the nodes of the FDT.
fn append_property_u32(fdt: &mut Vec<u8>, name: &str, val: u32) -> Result<()> {
append_property(fdt, name, &to_be32(val))
}
fn append_property_u64(fdt: &mut Vec<u8>, name: &str, val: u64) -> Result<()> {
append_property(fdt, name, &to_be64(val))
}
fn append_property_string(fdt: &mut Vec<u8>, name: &str, value: &str) -> Result<()> {
let cstr_value = CString::new(value).map_err(CstringFDTTransform)?;
append_property_cstring(fdt, name, &cstr_value)
}
fn append_property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Result<()> {
let value_bytes = cstr_value.to_bytes_with_nul();
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
// Safe because we allocated fdt, converted name and value to CStrings
let fdt_ret = unsafe {
fdt_property(
fdt.as_mut_ptr() as *mut c_void,
cstr_name.as_ptr(),
value_bytes.as_ptr() as *mut c_void,
value_bytes.len() as i32,
)
};
if fdt_ret != 0 {
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
}
Ok(())
}
fn append_property_null(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
// Safe because we allocated fdt, converted name to a CString
let fdt_ret = unsafe {
fdt_property(
fdt.as_mut_ptr() as *mut c_void,
cstr_name.as_ptr(),
null(),
0,
)
};
if fdt_ret != 0 {
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
}
Ok(())
}
fn append_property(fdt: &mut Vec<u8>, name: &str, val: &[u8]) -> Result<()> {
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
let val_ptr = val.as_ptr() as *const c_void;
// Safe because we allocated fdt and converted name to a CString
let fdt_ret = unsafe {
fdt_property(
fdt.as_mut_ptr() as *mut c_void,
cstr_name.as_ptr(),
val_ptr,
val.len() as i32,
)
};
if fdt_ret != 0 {
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
}
Ok(())
}
// Auxiliary functions for writing u32/u64 numbers in big endian order.
fn to_be32(input: u32) -> [u8; 4] {
u32::to_be_bytes(input)
}
fn to_be64(input: u64) -> [u8; 8] {
u64::to_be_bytes(input)
}
// Helper functions for generating a properly formatted byte vector using 32-bit/64-bit cells.
fn generate_prop32(cells: &[u32]) -> Vec<u8> {
let mut ret: Vec<u8> = Vec::new();
for &e in cells {
ret.extend(to_be32(e).iter());
}
ret
}
fn generate_prop64(cells: &[u64]) -> Vec<u8> {
let mut ret: Vec<u8> = Vec::new();
for &e in cells {
ret.extend(to_be64(e).iter());
}
ret
}
// Following are the auxiliary function for creating the different nodes that we append to our FDT.
fn create_cpu_nodes(fdt: &mut Vec<u8>, vcpu_mpidr: &[u64]) -> Result<()> {
// See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/arm/cpus.yaml.
append_begin_node(fdt, "cpus")?;
// As per documentation, on ARM v8 64-bit systems value should be set to 2.
append_property_u32(fdt, "#address-cells", 0x02)?;
append_property_u32(fdt, "#size-cells", 0x0)?;
let num_cpus = vcpu_mpidr.len();
for (cpu_index, mpidr) in vcpu_mpidr.iter().enumerate().take(num_cpus) {
let cpu_name = format!("cpu@{:x}", cpu_index);
append_begin_node(fdt, &cpu_name)?;
append_property_string(fdt, "device_type", "cpu")?;
append_property_string(fdt, "compatible", "arm,arm-v8")?;
if num_cpus > 1 {
// This is required on armv8 64-bit. See aforementioned documentation.
append_property_string(fdt, "enable-method", "psci")?;
}
// Set the field to first 24 bits of the MPIDR - Multiprocessor Affinity Register.
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488c/BABHBJCI.html.
append_property_u64(fdt, "reg", mpidr & 0x7FFFFF)?;
append_end_node(fdt)?;
}
append_end_node(fdt)?;
Ok(())
}
fn create_memory_node(fdt: &mut Vec<u8>, guest_mem: &GuestMemoryMmap) -> Result<()> {
let mem_size = guest_mem.last_addr().raw_value() - super::layout::RAM_64BIT_START + 1;
// See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L960
// for an explanation of this.
let mem_reg_prop = generate_prop64(&[super::layout::RAM_64BIT_START as u64, mem_size as u64]);
append_begin_node(fdt, "memory")?;
append_property_string(fdt, "device_type", "memory")?;
append_property(fdt, "reg", &mem_reg_prop)?;
append_end_node(fdt)?;
Ok(())
}
fn create_chosen_node(
fdt: &mut Vec<u8>,
cmdline: &CStr,
initrd: &Option<InitramfsConfig>,
) -> Result<()> {
append_begin_node(fdt, "chosen")?;
append_property_cstring(fdt, "bootargs", cmdline)?;
if let Some(initrd_config) = initrd {
append_property_u64(
fdt,
"linux,initrd-start",
initrd_config.address.raw_value() as u64,
)?;
append_property_u64(
fdt,
"linux,initrd-end",
initrd_config.address.raw_value() + initrd_config.size as u64,
)?;
}
append_end_node(fdt)?;
Ok(())
}
fn create_gic_node(fdt: &mut Vec<u8>, gic_device: &dyn GICDevice) -> Result<()> {
let gic_reg_prop = generate_prop64(gic_device.device_properties());
append_begin_node(fdt, "intc")?;
append_property_string(fdt, "compatible", gic_device.fdt_compatibility())?;
append_property_null(fdt, "interrupt-controller")?;
// "interrupt-cells" field specifies the number of cells needed to encode an
// interrupt source. The type shall be a <u32> and the value shall be 3 if no PPI affinity description
// is required.
append_property_u32(fdt, "#interrupt-cells", 3)?;
append_property(fdt, "reg", &gic_reg_prop)?;
append_property_u32(fdt, "phandle", GIC_PHANDLE)?;
append_property_u32(fdt, "#address-cells", 2)?;
append_property_u32(fdt, "#size-cells", 2)?;
append_property_null(fdt, "ranges")?;
let gic_intr = [
GIC_FDT_IRQ_TYPE_PPI,
gic_device.fdt_maint_irq(),
IRQ_TYPE_LEVEL_HI,
];
let gic_intr_prop = generate_prop32(&gic_intr);
append_property(fdt, "interrupts", &gic_intr_prop)?;
if gic_device.msi_compatible() {
append_begin_node(fdt, "msic")?;
append_property_string(fdt, "compatible", gic_device.msi_compatiblility())?;
append_property_null(fdt, "msi-controller")?;
append_property_u32(fdt, "phandle", MSI_PHANDLE)?;
let msi_reg_prop = generate_prop64(gic_device.msi_properties());
append_property(fdt, "reg", &msi_reg_prop)?;
append_end_node(fdt)?;
}
append_end_node(fdt)?;
Ok(())
}
fn create_clock_node(fdt: &mut Vec<u8>) -> Result<()> {
// The Advanced Peripheral Bus (APB) is part of the Advanced Microcontroller Bus Architecture
// (AMBA) protocol family. It defines a low-cost interface that is optimized for minimal power
// consumption and reduced interface complexity.
// PCLK is the clock source and this node defines exactly the clock for the APB.
append_begin_node(fdt, "apb-pclk")?;
append_property_string(fdt, "compatible", "fixed-clock")?;
append_property_u32(fdt, "#clock-cells", 0x0)?;
append_property_u32(fdt, "clock-frequency", 24000000)?;
append_property_string(fdt, "clock-output-names", "clk24mhz")?;
append_property_u32(fdt, "phandle", CLOCK_PHANDLE)?;
append_end_node(fdt)?;
Ok(())
}
fn create_timer_node(fdt: &mut Vec<u8>) -> Result<()> {
// See
// https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/interrupt-controller/arch_timer.txt
// These are fixed interrupt numbers for the timer device.
let irqs = [13, 14, 11, 10];
let compatible = "arm,armv8-timer";
let mut timer_reg_cells: Vec<u32> = Vec::new();
for &irq in irqs.iter() {
timer_reg_cells.push(GIC_FDT_IRQ_TYPE_PPI);
timer_reg_cells.push(irq);
timer_reg_cells.push(IRQ_TYPE_LEVEL_HI);
}
let timer_reg_prop = generate_prop32(timer_reg_cells.as_slice());
append_begin_node(fdt, "timer")?;
append_property_string(fdt, "compatible", compatible)?;
append_property_null(fdt, "always-on")?;
append_property(fdt, "interrupts", &timer_reg_prop)?;
append_end_node(fdt)?;
Ok(())
}
fn create_psci_node(fdt: &mut Vec<u8>) -> Result<()> {
let compatible = "arm,psci-0.2";
append_begin_node(fdt, "psci")?;
append_property_string(fdt, "compatible", compatible)?;
// Two methods available: hvc and smc.
// As per documentation, PSCI calls between a guest and hypervisor may use the HVC conduit instead of SMC.
// So, since we are using kvm, we need to use hvc.
append_property_string(fdt, "method", "hvc")?;
append_end_node(fdt)?;
Ok(())
}
fn create_virtio_node<T: DeviceInfoForFDT + Clone + Debug>(
fdt: &mut Vec<u8>,
dev_info: &T,
) -> Result<()> {
let device_reg_prop = generate_prop64(&[dev_info.addr(), dev_info.length()]);
let irq = generate_prop32(&[GIC_FDT_IRQ_TYPE_SPI, dev_info.irq(), IRQ_TYPE_EDGE_RISING]);
append_begin_node(fdt, &format!("virtio_mmio@{:x}", dev_info.addr()))?;
append_property_string(fdt, "compatible", "virtio,mmio")?;
append_property(fdt, "reg", &device_reg_prop)?;
append_property(fdt, "interrupts", &irq)?;
append_property_u32(fdt, "interrupt-parent", GIC_PHANDLE)?;
append_end_node(fdt)?;
Ok(())
}
fn create_serial_node<T: DeviceInfoForFDT + Clone + Debug>(
fdt: &mut Vec<u8>,
dev_info: &T,
) -> Result<()> {
let serial_reg_prop = generate_prop64(&[dev_info.addr(), dev_info.length()]);
let irq = generate_prop32(&[GIC_FDT_IRQ_TYPE_SPI, dev_info.irq(), IRQ_TYPE_EDGE_RISING]);
append_begin_node(fdt, &format!("uart@{:x}", dev_info.addr()))?;
append_property_string(fdt, "compatible", "ns16550a")?;
append_property(fdt, "reg", &serial_reg_prop)?;
append_property_u32(fdt, "clocks", CLOCK_PHANDLE)?;
append_property_string(fdt, "clock-names", "apb_pclk")?;
append_property(fdt, "interrupts", &irq)?;
append_end_node(fdt)?;
Ok(())
}
fn create_rtc_node<T: DeviceInfoForFDT + Clone + Debug>(
fdt: &mut Vec<u8>,
dev_info: &T,
) -> Result<()> {
let compatible = b"arm,pl031\0arm,primecell\0";
let rtc_reg_prop = generate_prop64(&[dev_info.addr(), dev_info.length()]);
let irq = generate_prop32(&[GIC_FDT_IRQ_TYPE_SPI, dev_info.irq(), IRQ_TYPE_LEVEL_HI]);
append_begin_node(fdt, &format!("rtc@{:x}", dev_info.addr()))?;
append_property(fdt, "compatible", compatible)?;
append_property(fdt, "reg", &rtc_reg_prop)?;
append_property(fdt, "interrupts", &irq)?;
append_property_u32(fdt, "clocks", CLOCK_PHANDLE)?;
append_property_string(fdt, "clock-names", "apb_pclk")?;
append_end_node(fdt)?;
Ok(())
}
fn create_devices_node<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
fdt: &mut Vec<u8>,
dev_info: &HashMap<(DeviceType, String), T, S>,
) -> Result<()> {
// Create one temp Vec to store all virtio devices
let mut ordered_virtio_device: Vec<&T> = Vec::new();
for ((device_type, _device_id), info) in dev_info {
match device_type {
DeviceType::RTC => create_rtc_node(fdt, info)?,
DeviceType::Serial => create_serial_node(fdt, info)?,
DeviceType::Virtio(_) => {
ordered_virtio_device.push(info);
}
}
}
// Sort out virtio devices by address from low to high and insert them into fdt table.
ordered_virtio_device.sort_by_key(|&a| a.addr());
// Current address allocation strategy in cloud-hypervisor is: the first created device
// will be allocated to higher address. Here we reverse the vector to make sure that
// the older created device will appear in front of the newer created device in FDT.
ordered_virtio_device.reverse();
for ordered_device_info in ordered_virtio_device.drain(..) {
create_virtio_node(fdt, ordered_device_info)?;
}
Ok(())
}
fn create_pci_nodes(fdt: &mut Vec<u8>, pci_device_base: u64, pci_device_size: u64) -> Result<()> {
// Add node for PCIe controller.
// See Documentation/devicetree/bindings/pci/host-generic-pci.txt in the kernel
// and https://elinux.org/Device_Tree_Usage.
let ranges = generate_prop32(&[
// 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 >> 32) as u32, // PCI address
pci_device_base as u32,
(pci_device_base >> 32) as u32, // CPU address
pci_device_base as u32,
(pci_device_size >> 32) as u32, // size
pci_device_size as u32,
]);
let bus_range = generate_prop32(&[0, 0]); // Only bus 0
let reg = generate_prop64(&[PCI_MMCONFIG_START.0, PCI_MMCONFIG_SIZE]);
append_begin_node(fdt, "pci")?;
append_property_string(fdt, "compatible", "pci-host-ecam-generic")?;
append_property_string(fdt, "device_type", "pci")?;
append_property(fdt, "ranges", &ranges)?;
append_property(fdt, "bus-range", &bus_range)?;
append_property_u32(fdt, "#address-cells", 3)?;
append_property_u32(fdt, "#size-cells", 2)?;
append_property(fdt, "reg", &reg)?;
append_property_u32(fdt, "#interrupt-cells", 1)?;
append_property_null(fdt, "interrupt-map")?;
append_property_null(fdt, "interrupt-map-mask")?;
append_property_null(fdt, "dma-coherent")?;
append_property_u32(fdt, "msi-parent", MSI_PHANDLE)?;
append_end_node(fdt)?;
Ok(())
}

174
arch/src/aarch64/gic.rs Normal file
View File

@@ -0,0 +1,174 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use std::result;
use std::sync::Arc;
/// Errors thrown while setting up the GIC.
#[derive(Debug)]
pub enum Error {
/// Error while calling KVM ioctl for setting up the global interrupt controller.
CreateGIC(hypervisor::HypervisorVmError),
/// Error while setting device attributes for the GIC.
SetDeviceAttribute(hypervisor::HypervisorDeviceError),
}
type Result<T> = result::Result<T, Error>;
pub trait GICDevice {
/// Returns the hypervisor agnostic Device of the GIC device
fn device(&self) -> &Arc<dyn hypervisor::Device>;
/// Returns the fdt compatibility property of the device
fn fdt_compatibility(&self) -> &str;
/// Returns the maint_irq fdt property of the device
fn fdt_maint_irq(&self) -> u32;
/// Returns an array with GIC device properties
fn device_properties(&self) -> &[u64];
/// Returns the number of vCPUs this GIC handles
fn vcpu_count(&self) -> u64;
/// Returns whether the GIC device is MSI compatible or not
fn msi_compatible(&self) -> bool {
false
}
/// Returns the MSI compatibility property of the device
fn msi_compatiblility(&self) -> &str {
""
}
/// Returns the MSI reg property of the device
fn msi_properties(&self) -> &[u64] {
&[]
}
}
pub mod kvm {
use super::GICDevice;
use super::Result;
use crate::aarch64::gicv2::kvm::KvmGICv2;
use crate::aarch64::gicv3::kvm::KvmGICv3;
use crate::aarch64::gicv3_its::kvm::KvmGICv3ITS;
use crate::layout;
use hypervisor::kvm::kvm_bindings;
use std::boxed::Box;
use std::sync::Arc;
/// Trait for GIC devices.
pub trait KvmGICDevice: Send + Sync + GICDevice {
/// Returns the GIC version of the device
fn version() -> u32;
/// Create the GIC device object
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GICDevice>;
/// Setup the device-specific attributes
fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GICDevice,
) -> Result<()>;
/// Initialize a GIC device
fn init_device(vm: &Arc<dyn hypervisor::Vm>) -> Result<Arc<dyn hypervisor::Device>> {
let mut gic_device = kvm_bindings::kvm_create_device {
type_: Self::version(),
fd: 0,
flags: 0,
};
vm.create_device(&mut gic_device)
.map_err(super::Error::CreateGIC)
}
/// Set a GIC device attribute
fn set_device_attribute(
device: &Arc<dyn hypervisor::Device>,
group: u32,
attr: u64,
addr: u64,
flags: u32,
) -> Result<()> {
let attr = kvm_bindings::kvm_device_attr {
group,
attr,
addr,
flags,
};
device
.set_device_attr(&attr)
.map_err(super::Error::SetDeviceAttribute)?;
Ok(())
}
/// Finalize the setup of a GIC device
fn finalize_device(gic_device: &dyn GICDevice) -> Result<()> {
/* We need to tell the kernel how many irqs to support with this vgic.
* See the `layout` module for details.
*/
let nr_irqs: u32 = layout::IRQ_MAX - layout::IRQ_BASE + 1;
let nr_irqs_ptr = &nr_irqs as *const u32;
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0,
nr_irqs_ptr as u64,
0,
)?;
/* Finalize the GIC.
* See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
Ok(())
}
/// Method to initialize the GIC device
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GICDevice>> {
let vgic_fd = Self::init_device(vm)?;
let device = Self::create_device(vgic_fd, vcpu_count);
Self::init_device_attributes(vm, &*device)?;
Self::finalize_device(&*device)?;
Ok(device)
}
}
/// Create a GIC device.
///
/// It will try to create by default a GICv3 device. If that fails it will try
/// to fall-back to a GICv2 device.
pub fn create_gic(
vm: &Arc<dyn hypervisor::Vm>,
vcpu_count: u64,
its_required: bool,
) -> Result<Box<dyn GICDevice>> {
if its_required {
KvmGICv3ITS::new(vm, vcpu_count)
} else {
KvmGICv3ITS::new(vm, vcpu_count).or_else(|_| {
debug!("Failed to create GICv3-ITS, will try GICv3 instead.");
KvmGICv3::new(vm, vcpu_count).or_else(|_| {
debug!("Failed to create GICv3, will try GICv2 instead.");
KvmGICv2::new(vm, vcpu_count)
})
})
}
}
}

124
arch/src/aarch64/gicv2.rs Normal file
View File

@@ -0,0 +1,124 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
pub mod kvm {
use crate::aarch64::gic::kvm::KvmGICDevice;
use crate::aarch64::gic::{Error, GICDevice};
use std::{boxed::Box, result};
type Result<T> = result::Result<T, Error>;
use crate::layout;
use hypervisor::kvm::kvm_bindings;
use std::sync::Arc;
/// Represent a GIC v2 device
pub struct KvmGICv2 {
/// The hypervisor agnostic device
device: Arc<dyn hypervisor::Device>,
/// GIC device properties, to be used for setting up the fdt entry
properties: [u64; 4],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
impl KvmGICv2 {
// Unfortunately bindgen omits defines that are based on other defines.
// See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel.
const KVM_VGIC_V2_DIST_SIZE: u64 = 0x1000;
const KVM_VGIC_V2_CPU_SIZE: u64 = 0x2000;
// Device trees specific constants
const ARCH_GIC_V2_MAINT_IRQ: u32 = 8;
/// Get the address of the GICv2 distributor.
const fn get_dist_addr() -> u64 {
layout::MAPPED_IO_START - KvmGICv2::KVM_VGIC_V2_DIST_SIZE
}
/// Get the size of the GIC_v2 distributor.
const fn get_dist_size() -> u64 {
KvmGICv2::KVM_VGIC_V2_DIST_SIZE
}
/// Get the address of the GIC_v2 CPU.
const fn get_cpu_addr() -> u64 {
KvmGICv2::get_dist_addr() - KvmGICv2::KVM_VGIC_V2_CPU_SIZE
}
/// Get the size of the GIC_v2 CPU.
const fn get_cpu_size() -> u64 {
KvmGICv2::KVM_VGIC_V2_CPU_SIZE
}
}
impl GICDevice for KvmGICv2 {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn device_properties(&self) -> &[u64] {
&self.properties
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-400"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGICv2::ARCH_GIC_V2_MAINT_IRQ
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
}
impl KvmGICDevice for KvmGICv2 {
fn version() -> u32 {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GICDevice> {
Box::new(KvmGICv2 {
device,
properties: [
KvmGICv2::get_dist_addr(),
KvmGICv2::get_dist_size(),
KvmGICv2::get_cpu_addr(),
KvmGICv2::get_cpu_size(),
],
vcpu_count,
})
}
fn init_device_attributes(
_vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GICDevice,
) -> Result<()> {
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor. */
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V2_ADDR_TYPE_DIST),
&KvmGICv2::get_dist_addr() as *const u64 as u64,
0,
)?;
/* Setting up the CPU attribute. */
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V2_ADDR_TYPE_CPU),
&KvmGICv2::get_cpu_addr() as *const u64 as u64,
0,
)?;
Ok(())
}
}
}

127
arch/src/aarch64/gicv3.rs Normal file
View File

@@ -0,0 +1,127 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
pub mod kvm {
use crate::aarch64::gic::kvm::KvmGICDevice;
use crate::aarch64::gic::{Error, GICDevice};
use crate::layout;
use hypervisor::kvm::kvm_bindings;
use std::sync::Arc;
use std::{boxed::Box, result};
type Result<T> = result::Result<T, Error>;
pub struct KvmGICv3 {
/// The hypervisor agnostic device
device: Arc<dyn hypervisor::Device>,
/// GIC device properties, to be used for setting up the fdt entry
properties: [u64; 4],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
impl KvmGICv3 {
// Unfortunately bindgen omits defines that are based on other defines.
// See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel.
pub const SZ_64K: u64 = 0x0001_0000;
const KVM_VGIC_V3_DIST_SIZE: u64 = KvmGICv3::SZ_64K;
const KVM_VGIC_V3_REDIST_SIZE: u64 = (2 * KvmGICv3::SZ_64K);
// Device trees specific constants
pub const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
/// Get the address of the GIC distributor.
pub fn get_dist_addr() -> u64 {
layout::MAPPED_IO_START - KvmGICv3::KVM_VGIC_V3_DIST_SIZE
}
/// Get the size of the GIC distributor.
pub fn get_dist_size() -> u64 {
KvmGICv3::KVM_VGIC_V3_DIST_SIZE
}
/// Get the address of the GIC redistributors.
pub fn get_redists_addr(vcpu_count: u64) -> u64 {
KvmGICv3::get_dist_addr() - KvmGICv3::get_redists_size(vcpu_count)
}
/// Get the size of the GIC redistributors.
pub fn get_redists_size(vcpu_count: u64) -> u64 {
vcpu_count * KvmGICv3::KVM_VGIC_V3_REDIST_SIZE
}
}
impl GICDevice for KvmGICv3 {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGICv3::ARCH_GIC_V3_MAINT_IRQ
}
fn device_properties(&self) -> &[u64] {
&self.properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
}
impl KvmGICDevice for KvmGICv3 {
fn version() -> u32 {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GICDevice> {
Box::new(KvmGICv3 {
device,
properties: [
KvmGICv3::get_dist_addr(),
KvmGICv3::get_dist_size(),
KvmGICv3::get_redists_addr(vcpu_count),
KvmGICv3::get_redists_size(vcpu_count),
],
vcpu_count,
})
}
fn init_device_attributes(
_vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GICDevice,
) -> Result<()> {
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
&KvmGICv3::get_dist_addr() as *const u64 as u64,
0,
)?;
/* Setting up the redistributors' attribute.
We are calculating here the start of the redistributors address. We have one per CPU.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
&KvmGICv3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64,
0,
)?;
Ok(())
}
}
}

View File

@@ -0,0 +1,133 @@
// Copyright 2020 ARM Limited
// SPDX-License-Identifier: Apache-2.0
pub mod kvm {
use std::sync::Arc;
use std::{boxed::Box, result};
type Result<T> = result::Result<T, Error>;
use crate::aarch64::gic::kvm::KvmGICDevice;
use crate::aarch64::gic::{Error, GICDevice};
use crate::aarch64::gicv3::kvm::KvmGICv3;
use hypervisor::kvm::kvm_bindings;
pub struct KvmGICv3ITS {
/// The hypervisor agnostic device
device: Arc<dyn hypervisor::Device>,
/// GIC device properties, to be used for setting up the fdt entry
gic_properties: [u64; 4],
/// MSI device properties, to be used for setting up the fdt entry
msi_properties: [u64; 2],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
impl KvmGICv3ITS {
const KVM_VGIC_V3_ITS_SIZE: u64 = (2 * KvmGICv3::SZ_64K);
fn get_msi_size() -> u64 {
KvmGICv3ITS::KVM_VGIC_V3_ITS_SIZE
}
fn get_msi_addr(vcpu_count: u64) -> u64 {
KvmGICv3::get_redists_addr(vcpu_count) - KvmGICv3ITS::get_msi_size()
}
}
impl GICDevice for KvmGICv3ITS {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn msi_compatible(&self) -> bool {
true
}
fn msi_compatiblility(&self) -> &str {
"arm,gic-v3-its"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGICv3::ARCH_GIC_V3_MAINT_IRQ
}
fn msi_properties(&self) -> &[u64] {
&self.msi_properties
}
fn device_properties(&self) -> &[u64] {
&self.gic_properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
}
impl KvmGICDevice for KvmGICv3ITS {
fn version() -> u32 {
KvmGICv3::version()
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GICDevice> {
Box::new(KvmGICv3ITS {
device,
gic_properties: [
KvmGICv3::get_dist_addr(),
KvmGICv3::get_dist_size(),
KvmGICv3::get_redists_addr(vcpu_count),
KvmGICv3::get_redists_size(vcpu_count),
],
msi_properties: [
KvmGICv3ITS::get_msi_addr(vcpu_count),
KvmGICv3ITS::get_msi_size(),
],
vcpu_count,
})
}
fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GICDevice,
) -> Result<()> {
KvmGICv3::init_device_attributes(vm, gic_device)?;
let mut its_device = kvm_bindings::kvm_create_device {
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
fd: 0,
flags: 0,
};
let its_fd = vm
.create_device(&mut its_device)
.map_err(Error::CreateGIC)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
&KvmGICv3ITS::get_msi_addr(gic_device.vcpu_count()) as *const u64 as u64,
0,
)?;
Self::set_device_attribute(
&its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
Ok(())
}
}
}

View File

@@ -1,7 +1,86 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/// Kernel command line start address.
pub const CMDLINE_START: usize = 0x0;
/// Kernel command line start address maximum size.
pub const CMDLINE_MAX_SIZE: usize = 0x0;
//
// Memory layout of Aarch64 guest:
//
// Physical +---------------------------------------------------------------+
// address | |
// end | |
// ~ ~ ~ ~
// | |
// | Highmem PCI MMIO space |
// | |
// RAM end +---------------------------------------------------------------+
// (dynamic, | |
// including | |
// hotplug ~ ~ ~ ~
// memory) | |
// | DRAM |
// | |
// 2GB +---------------------------------------------------------------+
// | |
// | Reserved |
// | |
// 1G+256M +---------------------------------------------------------------+
// | |
// | PCI MMCONFIG space |
// | |
// 1GB +---------------------------------------------------------------+
// | |
// | PCI MMIO space |
// | |
// 256 M +---------------------------------------------------------------|
// | |
// | Legacy devices space |
// | |
// 144 M +---------------------------------------------------------------|
// | |
// | Reserverd (now GIC is here) |
// | |
// 0GB +---------------------------------------------------------------+
//
//
use vm_memory::{GuestAddress, GuestUsize};
/// Below this address will reside the GIC, above this address will reside the MMIO devices.
pub const MAPPED_IO_START: u64 = 0x0900_0000;
/// Space 0x0900_0000 ~ 0x1000_0000 is reserved for legacy devices.
pub const LEGACY_SERIAL_MAPPED_IO_START: u64 = 0x0900_0000;
pub const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000;
/// Legacy space will be allocated at once whiling setting up legacy devices.
pub const LEGACY_DEVICES_MAPPED_IO_SIZE: u64 = 0x0700_0000;
/// Starting from 0x1000_0000 (256MiB), the 768MiB (ends at 1 GiB) is used for PCIE MMIO
pub const MEM_32BIT_DEVICES_START: GuestAddress = GuestAddress(0x1000_0000);
pub const MEM_32BIT_DEVICES_SIZE: u64 = 0x3000_0000;
/// PCI MMCONFIG space (start: after the device space at 1 GiB, length: 256MiB)
pub const PCI_MMCONFIG_START: GuestAddress = GuestAddress(0x4000_0000);
pub const PCI_MMCONFIG_SIZE: GuestUsize = 256 << 20;
/// Start of RAM on 64 bit ARM.
pub const RAM_64BIT_START: u64 = 0x8000_0000;
/// Kernel command line maximum size.
/// As per `arch/arm64/include/uapi/asm/setup.h`.
pub const CMDLINE_MAX_SIZE: usize = 2048;
/// Maximum size of the device tree blob as specified in https://www.kernel.org/doc/Documentation/arm64/booting.txt.
pub const FDT_MAX_SIZE: usize = 0x20_0000;
// As per virt/kvm/arm/vgic/vgic-kvm-device.c we need
// the number of interrupts our GIC will support to be:
// * bigger than 32
// * less than 1023 and
// * a multiple of 32.
// We are setting up our interrupt controller to support a maximum of 128 interrupts.
/// First usable interrupt on aarch64.
pub const IRQ_BASE: u32 = 32;
/// Last usable interrupt on aarch64.
pub const IRQ_MAX: u32 = 159;

View File

@@ -1,27 +1,270 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/// Module for the flattened device tree.
pub mod fdt;
/// Module for the global interrupt controller configuration.
pub mod gic;
mod gicv2;
mod gicv3;
mod gicv3_its;
/// Layout for this aarch64 system.
pub mod layout;
/// Logic for configuring aarch64 registers.
pub mod regs;
use memory_model::{GuestAddress, GuestMemory};
pub use self::fdt::DeviceInfoForFDT;
use crate::DeviceType;
use crate::RegionType;
use hypervisor::kvm::kvm_bindings;
use std::collections::HashMap;
use std::ffi::CStr;
use std::fmt::Debug;
use std::sync::Arc;
use vm_memory::{
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap,
GuestUsize,
};
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize, RegionType)> {
vec![(GuestAddress(0), size, RegionType::Ram)]
/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
pub enum Error {
/// Failed to create a FDT.
SetupFDT(fdt::Error),
/// Failed to create a GIC.
SetupGIC(gic::Error),
/// Failed to compute the initramfs address.
InitramfsAddress,
/// Error configuring the general purpose registers
REGSConfiguration(regs::Error),
/// Error fetching prefered target
VcpuArmPreferredTarget(hypervisor::HypervisorVmError),
/// Error doing Vcpu Init on Arm.
VcpuArmInit(hypervisor::HypervisorCpuError),
}
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn configure_system(
_guest_mem: &GuestMemory,
_cmdline_addr: GuestAddress,
_cmdline_size: usize,
_num_cpus: u8,
_serial_enabled: bool,
impl From<Error> for super::Error {
fn from(e: Error) -> super::Error {
super::Error::AArch64Setup(e)
}
}
#[derive(Debug, Copy, Clone)]
/// Specifies the entry point address where the guest must start
/// executing code.
pub struct EntryPoint {
/// Address in guest memory where the guest must start execution
pub entry_addr: GuestAddress,
}
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
fd: &Arc<dyn hypervisor::Vcpu>,
id: u8,
vm: &Arc<dyn hypervisor::Vm>,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
) -> super::Result<u64> {
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
// This reads back the kernel's preferred target type.
vm.get_preferred_target(&mut kvi)
.map_err(Error::VcpuArmPreferredTarget)?;
// We already checked that the capability is supported.
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
// Non-boot cpus are powered off initially.
if id > 0 {
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
}
fd.vcpu_init(&kvi).map_err(Error::VcpuArmInit)?;
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)?;
}
let mpidr = regs::read_mpidr(fd).map_err(Error::REGSConfiguration)?;
Ok(mpidr)
}
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> {
let mut regions = Vec::new();
// 0 ~ 256 MiB: Reserved
regions.push((
GuestAddress(0),
layout::MEM_32BIT_DEVICES_START.0 as usize,
RegionType::Reserved,
));
// 256 MiB ~ 1 G: MMIO space
regions.push((
layout::MEM_32BIT_DEVICES_START,
layout::MEM_32BIT_DEVICES_SIZE as usize,
RegionType::SubRegion,
));
// 1G ~ 2G: reserved. The leading 256M for PCIe MMCONFIG space
regions.push((
layout::PCI_MMCONFIG_START,
(layout::RAM_64BIT_START - layout::PCI_MMCONFIG_START.0) as usize,
RegionType::Reserved,
));
regions.push((
GuestAddress(layout::RAM_64BIT_START),
size as usize,
RegionType::Ram,
));
regions
}
/// Configures the system and should be called once per vm before starting vcpu threads.
///
/// # Arguments
///
/// * `guest_mem` - The memory to be used by the guest.
/// * `num_cpus` - Number of virtual CPUs the guest will have.
#[allow(clippy::too_many_arguments)]
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
vm: &Arc<dyn hypervisor::Vm>,
guest_mem: &GuestMemoryMmap,
cmdline_cstring: &CStr,
vcpu_count: u64,
vcpu_mpidr: Vec<u64>,
device_info: &HashMap<(DeviceType, String), T, S>,
initrd: &Option<super::InitramfsConfig>,
pci_space_address: &Option<(u64, u64)>,
) -> super::Result<()> {
// If pci_space_address is present, it means PCI devices are used ("pci" feature enabled).
// Then GITv3-ITS is required for MSI messaging.
// Otherwise ("mmio" feature enabled), any version of GIC is OK.
let gic_device = gic::kvm::create_gic(vm, vcpu_count, pci_space_address.is_some())
.map_err(Error::SetupGIC)?;
fdt::create_fdt(
guest_mem,
cmdline_cstring,
vcpu_mpidr,
device_info,
&*gic_device,
initrd,
pci_space_address,
)
.map_err(Error::SetupFDT)?;
Ok(())
}
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn get_reserved_mem_addr() -> usize {
0
/// Returns the memory address where the initramfs could be loaded.
pub fn initramfs_load_addr(
guest_mem: &GuestMemoryMmap,
initramfs_size: usize,
) -> super::Result<u64> {
let round_to_pagesize = |size| (size + (super::PAGE_SIZE - 1)) & !(super::PAGE_SIZE - 1);
match GuestAddress(get_fdt_addr(&guest_mem))
.checked_sub(round_to_pagesize(initramfs_size) as u64)
{
Some(offset) => {
if guest_mem.address_in_range(offset) {
Ok(offset.raw_value())
} else {
Err(super::Error::AArch64Setup(Error::InitramfsAddress))
}
}
None => Err(super::Error::AArch64Setup(Error::InitramfsAddress)),
}
}
/// Returns the memory address where the kernel could be loaded.
pub fn get_kernel_start() -> u64 {
layout::RAM_64BIT_START
}
// Auxiliary function to get the address where the device tree blob is loaded.
fn get_fdt_addr(mem: &GuestMemoryMmap) -> u64 {
// If the memory allocated is smaller than the size allocated for the FDT,
// we return the start of the DRAM so that
// we allow the code to try and load the FDT.
if let Some(addr) = mem.last_addr().checked_sub(layout::FDT_MAX_SIZE as u64 - 1) {
if mem.address_in_range(addr) {
return addr.raw_value();
}
}
layout::RAM_64BIT_START
}
pub fn get_host_cpu_phys_bits() -> u8 {
// The value returned here is used to determine the physical address space size
// for a VM (IPA size).
// In recent kernel versions, the maxium IPA size supported by the host can be
// known by querying cap KVM_CAP_ARM_VM_IPA_SIZE. And the IPA size for a
// guest can be configured smaller.
// But in Cloud-Hypervisor we simply use the maxium value for the VM.
// Reference https://lwn.net/Articles/766767/.
//
// The correct way to query KVM_CAP_ARM_VM_IPA_SIZE is via rust-vmm/kvm-ioctls,
// which wraps all IOCTL's and provides easy interface to user hypervisors.
// For now the cap hasn't been supported. A separate patch will be submitted to
// rust-vmm to add it.
// So a hardcoded value is used here as a temporary solution.
// It will be replace once rust-vmm/kvm-ioctls is ready.
//
40
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_arch_memory_regions_dram() {
let regions = arch_memory_regions((1usize << 32) as u64); //4GB
assert_eq!(4, regions.len());
assert_eq!(GuestAddress(layout::RAM_64BIT_START), regions[3].0);
assert_eq!(1usize << 32, regions[3].1);
assert_eq!(RegionType::Ram, regions[3].2);
}
#[test]
fn test_get_fdt_addr() {
let mut regions = Vec::new();
regions.push((
GuestAddress(layout::RAM_64BIT_START),
(layout::FDT_MAX_SIZE - 0x1000) as usize,
));
let mem = GuestMemoryMmap::from_ranges(&regions).expect("Cannot initialize memory");
assert_eq!(get_fdt_addr(&mem), layout::RAM_64BIT_START);
regions.clear();
regions.push((
GuestAddress(layout::RAM_64BIT_START),
(layout::FDT_MAX_SIZE) as usize,
));
let mem = GuestMemoryMmap::from_ranges(&regions).expect("Cannot initialize memory");
assert_eq!(get_fdt_addr(&mem), layout::RAM_64BIT_START);
regions.clear();
regions.push((
GuestAddress(layout::RAM_64BIT_START),
(layout::FDT_MAX_SIZE + 0x1000) as usize,
));
let mem = GuestMemoryMmap::from_ranges(&regions).expect("Cannot initialize memory");
assert_eq!(get_fdt_addr(&mem), 0x1000 + layout::RAM_64BIT_START);
regions.clear();
}
}

156
arch/src/aarch64/regs.rs Normal file
View File

@@ -0,0 +1,156 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use super::get_fdt_addr;
use hypervisor::kvm::kvm_bindings::{
user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK,
KVM_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_SHIFT,
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP1_MASK,
KVM_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT,
KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
};
use std::sync::Arc;
use std::{mem, result};
use vm_memory::GuestMemoryMmap;
/// Errors thrown while setting aarch64 registers.
#[derive(Debug)]
pub enum Error {
/// Failed to set core register (PC, PSTATE or general purpose ones).
SetCoreRegister(hypervisor::HypervisorCpuError),
/// Failed to get a system register.
GetSysRegister(hypervisor::HypervisorCpuError),
}
type Result<T> = result::Result<T, Error>;
#[allow(non_upper_case_globals)]
// PSR (Processor State Register) bits.
// Taken from arch/arm64/include/uapi/asm/ptrace.h.
const PSR_MODE_EL1h: u64 = 0x0000_0005;
const PSR_F_BIT: u64 = 0x0000_0040;
const PSR_I_BIT: u64 = 0x0000_0080;
const PSR_A_BIT: u64 = 0x0000_0100;
const PSR_D_BIT: u64 = 0x0000_0200;
// Taken from arch/arm64/kvm/inject_fault.c.
const PSTATE_FAULT_BITS_64: u64 = PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT;
// Following are macros that help with getting the ID of a aarch64 core register.
// The core register are represented by the user_pt_regs structure. Look for it in
// arch/arm64/include/uapi/asm/ptrace.h.
// This macro gets the offset of a structure (i.e `str`) member (i.e `field`) without having
// an instance of that structure.
// It uses a null pointer to retrieve the offset to the field.
// Inspired by C solution: `#define offsetof(str, f) ((size_t)(&((str *)0)->f))`.
// Doing `offset__of!(user_pt_regs, pstate)` in our rust code will trigger the following:
// unsafe { &(*(0 as *const user_pt_regs)).pstate as *const _ as usize }
// The dereference expression produces an lvalue, but that lvalue is not actually read from,
// we're just doing pointer math on it, so in theory, it should safe.
macro_rules! offset__of {
($str:ty, $field:ident) => {
unsafe { &(*std::ptr::null::<user_pt_regs>()).$field as *const _ as usize }
};
}
macro_rules! arm64_core_reg {
($reg: tt) => {
// As per `kvm_arm_copy_reg_indices`, the id of a core register can be obtained like this:
// `const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE | i`, where i is obtained with:
// `for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {`
// We are using here `user_pt_regs` since this structure contains the core register and it is at
// the start of `kvm_regs`.
// struct kvm_regs {
// struct user_pt_regs regs; /* sp = sp_el0 */
//
// __u64 sp_el1;
// __u64 elr_el1;
//
// __u64 spsr[KVM_NR_SPSR];
//
// struct user_fpsimd_state fp_regs;
//};
// struct user_pt_regs {
// __u64 regs[31];
// __u64 sp;
// __u64 pc;
// __u64 pstate;
//};
// In our implementation we need: pc, pstate and user_pt_regs->regs[0].
KVM_REG_ARM64 as u64
| KVM_REG_SIZE_U64 as u64
| u64::from(KVM_REG_ARM_CORE)
| ((offset__of!(user_pt_regs, $reg) / mem::size_of::<u32>()) as u64)
};
}
// This macro computes the ID of a specific ARM64 system register similar to how
// the kernel C macro does.
// https://elixir.bootlin.com/linux/v4.20.17/source/arch/arm64/include/uapi/asm/kvm.h#L203
macro_rules! arm64_sys_reg {
($name: tt, $op0: tt, $op1: tt, $crn: tt, $crm: tt, $op2: tt) => {
const $name: u64 = KVM_REG_ARM64 as u64
| KVM_REG_SIZE_U64 as u64
| KVM_REG_ARM64_SYSREG as u64
| ((($op0 as u64) << KVM_REG_ARM64_SYSREG_OP0_SHIFT)
& KVM_REG_ARM64_SYSREG_OP0_MASK as u64)
| ((($op1 as u64) << KVM_REG_ARM64_SYSREG_OP1_SHIFT)
& KVM_REG_ARM64_SYSREG_OP1_MASK as u64)
| ((($crn as u64) << KVM_REG_ARM64_SYSREG_CRN_SHIFT)
& KVM_REG_ARM64_SYSREG_CRN_MASK as u64)
| ((($crm as u64) << KVM_REG_ARM64_SYSREG_CRM_SHIFT)
& KVM_REG_ARM64_SYSREG_CRM_MASK as u64)
| ((($op2 as u64) << KVM_REG_ARM64_SYSREG_OP2_SHIFT)
& KVM_REG_ARM64_SYSREG_OP2_MASK as u64);
};
}
// Constant imported from the Linux kernel:
// https://elixir.bootlin.com/linux/v4.20.17/source/arch/arm64/include/asm/sysreg.h#L135
arm64_sys_reg!(MPIDR_EL1, 3, 0, 0, 0, 5);
/// Configure core registers for a given CPU.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
/// * `cpu_id` - Index of current vcpu.
/// * `boot_ip` - Starting instruction pointer.
/// * `mem` - Reserved DRAM for current VM.
pub fn setup_regs(
vcpu: &Arc<dyn hypervisor::Vcpu>,
cpu_id: u8,
boot_ip: u64,
mem: &GuestMemoryMmap,
) -> Result<()> {
// Get the register index of the PSTATE (Processor State) register.
vcpu.set_one_reg(arm64_core_reg!(pstate), PSTATE_FAULT_BITS_64)
.map_err(Error::SetCoreRegister)?;
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
vcpu.set_one_reg(arm64_core_reg!(pc), boot_ip)
.map_err(Error::SetCoreRegister)?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
vcpu.set_one_reg(arm64_core_reg!(regs), get_fdt_addr(mem) as u64)
.map_err(Error::SetCoreRegister)?;
}
Ok(())
}
/// Read the MPIDR - Multiprocessor Affinity Register.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn read_mpidr(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<u64> {
vcpu.get_one_reg(MPIDR_EL1).map_err(Error::GetSysRegister)
}

View File

@@ -1,6 +1,11 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
// Copyright © 2020, Oracle and/or its affiliates.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//! Implements platform specific functionality.
//! Supported platforms: x86_64, aarch64.
#![allow(
clippy::unreadable_literal,
clippy::redundant_static_lifetimes,
@@ -10,31 +15,53 @@
)]
extern crate byteorder;
extern crate kvm_bindings;
extern crate hypervisor;
extern crate libc;
#[macro_use]
extern crate log;
#[cfg(feature = "acpi")]
extern crate acpi_tables;
extern crate arch_gen;
extern crate kvm_ioctls;
extern crate linux_loader;
extern crate vm_memory;
use std::fmt;
use std::result;
use vm_memory::GuestAddress;
#[derive(Debug, PartialEq)]
/// Type for returning error code.
#[derive(Debug)]
pub enum Error {
#[cfg(target_arch = "x86_64")]
/// X86_64 specific error triggered during system configuration.
X86_64Setup(x86_64::Error),
#[cfg(target_arch = "aarch64")]
/// AArch64 specific error triggered during system configuration.
AArch64Setup(aarch64::Error),
/// The zero page extends past the end of guest_mem.
ZeroPagePastRamEnd,
/// Error writing the zero page of guest memory.
ZeroPageSetup,
ZeroPageSetup(vm_memory::GuestMemoryError),
/// The memory map table extends past the end of guest memory.
MemmapTablePastRamEnd,
/// Error writing memory map table to guest memory.
MemmapTableSetup,
/// The hvm_start_info structure extends past the end of guest memory.
StartInfoPastRamEnd,
/// Error writing hvm_start_info to guest memory.
StartInfoSetup,
/// Failed to compute initramfs address.
InitramfsAddress,
/// Error writing module entry to guest memory.
ModlistSetup(vm_memory::GuestMemoryError),
/// RSDP Beyond Guest Memory
RSDPPastRamEnd,
}
/// Type for returning public functions outcome.
pub type Result<T> = result::Result<T, Error>;
#[derive(PartialEq)]
/// Type for memory region types.
#[derive(PartialEq, Debug)]
pub enum RegionType {
/// RAM type
Ram,
@@ -52,16 +79,15 @@ pub enum RegionType {
Reserved,
}
// 1MB. We don't put anything above here except the kernel itself.
pub const HIMEM_START: GuestAddress = GuestAddress(0x100000);
/// Module for aarch64 related functionality.
#[cfg(target_arch = "aarch64")]
pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE,
layout::CMDLINE_START,
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT,
get_host_cpu_phys_bits, get_kernel_start, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint,
};
#[cfg(target_arch = "x86_64")]
@@ -69,6 +95,66 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, get_32bit_gap_start as get_reserved_mem_addr,
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START,
arch_memory_regions, configure_system, configure_vcpu, get_host_cpu_phys_bits,
initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs,
BootProtocol, CpuidPatch, CpuidReg, EntryPoint,
};
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
#[cfg(target_arch = "x86_64")]
#[inline(always)]
fn pagesize() -> usize {
// Trivially safe
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
}
/// Type for passing information about the initramfs in the guest memory.
pub struct InitramfsConfig {
/// Load address of initramfs in guest memory
pub address: vm_memory::GuestAddress,
/// Size of initramfs in guest memory
pub size: usize,
}
/// Types of devices that can get attached to this platform.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)]
pub enum DeviceType {
/// Device Type: Virtio.
Virtio(u32),
/// Device Type: Serial.
#[cfg(target_arch = "aarch64")]
Serial,
/// Device Type: RTC.
#[cfg(target_arch = "aarch64")]
RTC,
}
/// Default (smallest) memory page size for the supported architectures.
pub const PAGE_SIZE: usize = 4096;
impl fmt::Display for DeviceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
/// Structure to describe MMIO device information
#[derive(Clone, Debug)]
#[cfg(target_arch = "aarch64")]
pub struct MMIODeviceInfo {
pub addr: u64,
pub irq: u32,
}
#[cfg(target_arch = "aarch64")]
impl DeviceInfoForFDT for MMIODeviceInfo {
fn addr(&self) -> u64 {
self.addr
}
fn irq(&self) -> u32 {
self.irq
}
fn length(&self) -> u64 {
4096 as u64
}
}

View File

@@ -1,315 +0,0 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use acpi_tables::{
rsdp::RSDP,
sdt::{GenericAddress, SDT},
};
use vm_memory::{GuestAddress, GuestMemoryMmap};
use vm_memory::{Address, ByteValued, Bytes};
#[repr(packed)]
struct LocalAPIC {
pub r#type: u8,
pub length: u8,
pub processor_id: u8,
pub apic_id: u8,
pub flags: u32,
}
#[repr(packed)]
#[derive(Default)]
struct IOAPIC {
pub r#type: u8,
pub length: u8,
pub ioapic_id: u8,
_reserved: u8,
pub apic_address: u32,
pub gsi_base: u32,
}
#[repr(packed)]
#[derive(Default)]
struct InterruptSourceOverride {
pub r#type: u8,
pub length: u8,
pub bus: u8,
pub source: u8,
pub gsi: u32,
pub flags: u16,
}
#[repr(packed)]
#[derive(Default)]
struct PCIRangeEntry {
pub base_address: u64,
pub segment: u16,
pub start: u8,
pub end: u8,
_reserved: u32,
}
pub fn create_dsdt_table(serial_enabled: bool) -> SDT {
/*
The hex tables in this file are generated from the ASL below with:
"iasl -tc <dsdt.asl>"
As the output contains a table header that is not required the first 40 bytes
should be disregarded.
*/
/*
Device (_SB.PCI0)
{
Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
Name (_ADR, Zero) // _ADR: Address
Name (_SEG, Zero) // _SEG: PCI Segment
Name (_UID, Zero) // _UID: Unique ID
Name (SUPP, Zero)
}
Scope (_SB.PCI0)
{
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, // Granularity
0x0000, // Range Minimum
0x00FF, // Range Maximum
0x0000, // Translation Offset
0x0100, // Length
,, )
IO (Decode16,
0x0CF8, // Range Minimum
0x0CF8, // Range Maximum
0x01, // Alignment
0x08, // Length
)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, // Granularity
0x0000, // Range Minimum
0x0CF7, // Range Maximum
0x0000, // Translation Offset
0x0CF8, // Length
,, , TypeStatic, DenseTranslation)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, // Granularity
0x0D00, // Range Minimum
0xFFFF, // Range Maximum
0x0000, // Translation Offset
0xF300, // Length
,, , TypeStatic, DenseTranslation)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, // Granularity
0x000A0000, // Range Minimum
0x000BFFFF, // Range Maximum
0x00000000, // Translation Offset
0x00020000, // Length
,, , AddressRangeMemory, TypeStatic)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x00000000, // Granularity
0xC0000000, // Range Minimum
0xFEC00000, // Range Maximum
0x00000000, // Translation Offset
0x3EC00001, // Length
,, , AddressRangeMemory, TypeStatic)
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x0000000000000000, // Granularity
0x0000000800000000, // Range Minimum
0x0000000FFFFFFFFF, // Range Maximum
0x0000000000000000, // Translation Offset
0x0000000800000000, // Length
,, , AddressRangeMemory, TypeStatic)
})
}
*/
let pci_dsdt_data = [
0x5Bu8, 0x82, 0x36, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x08, 0x5F, 0x48,
0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x08, 0x08, 0x5F, 0x43, 0x49, 0x44, 0x0C, 0x41, 0xD0,
0x0A, 0x03, 0x08, 0x5F, 0x41, 0x44, 0x52, 0x00, 0x08, 0x5F, 0x53, 0x45, 0x47, 0x00, 0x08,
0x5F, 0x55, 0x49, 0x44, 0x00, 0x08, 0x53, 0x55, 0x50, 0x50, 0x00, 0x10, 0x41, 0x0B, 0x2E,
0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x40,
0x0A, 0x0A, 0x9C, 0x88, 0x0D, 0x00, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x01, 0x47, 0x01, 0xF8, 0x0C, 0xF8, 0x0C, 0x01, 0x08, 0x88, 0x0D, 0x00,
0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C, 0x88, 0x0D,
0x00, 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3, 0x87,
0x17, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x87, 0x17, 0x00, 0x00, 0x0C,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0xC0, 0x3E, 0x8A, 0x2B, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x79, 0x00,
];
/*
Device (_SB.COM1)
{
Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */) // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
{
0x00000004,
}
IO (Decode16,
0x03F8, // Range Minimum
0x03F8, // Range Maximum
0x00, // Alignment
0x08, // Length
)
})
}
*/
let com1_dsdt_data = [
0x5Bu8, 0x82, 0x36, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31, 0x08, 0x5F, 0x48,
0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01, 0x08, 0x5F, 0x55, 0x49, 0x44, 0x00, 0x08, 0x5F,
0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01, 0x04, 0x00, 0x00,
0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
];
/*
Name (\_S5, Package (0x01) // _S5_: S5 System State
{
0x05
})
*/
let s5_sleep_data = [0x08u8, 0x5F, 0x53, 0x35, 0x5F, 0x12, 0x04, 0x01, 0x0A, 0x05];
// DSDT
let mut dsdt = SDT::new(*b"DSDT", 36, 6, *b"CLOUDH", *b"CHDSDT ", 1);
dsdt.append(pci_dsdt_data);
if serial_enabled {
dsdt.append(com1_dsdt_data);
}
dsdt.append(s5_sleep_data);
dsdt
}
pub fn create_acpi_tables(
guest_mem: &GuestMemoryMmap,
num_cpus: u8,
serial_enabled: bool,
) -> GuestAddress {
// RSDP is at the EBDA
let rsdp_offset = super::EBDA_START;
let mut tables: Vec<u64> = Vec::new();
// DSDT
let dsdt = create_dsdt_table(serial_enabled);
let dsdt_offset = rsdp_offset.checked_add(RSDP::len() as u64).unwrap();
guest_mem
.write_slice(dsdt.as_slice(), dsdt_offset)
.expect("Error writing DSDT table");
// FACP aka FADT
// Revision 6 of the ACPI FADT table is 276 bytes long
let mut facp = SDT::new(*b"FACP", 276, 6, *b"CLOUDH", *b"CHFACP ", 1);
// HW_REDUCED_ACPI and RESET_REG_SUP
let fadt_flags: u32 = 1 << 20 | 1 << 10;
facp.write(112, fadt_flags);
// RESET_REG
facp.write(116, GenericAddress::io_port_address(0x3c0));
// RESET_VALUE
facp.write(128, 1u8);
facp.write(131, 3u8); // FADT minor version
facp.write(140, dsdt_offset.0); // X_DSDT
// SLEEP_CONTROL_REG
facp.write(244, GenericAddress::io_port_address(0x3c0));
// SLEEP_STATUS_REG
facp.write(256, GenericAddress::io_port_address(0x3c0));
facp.write(268, b"CLOUDHYP"); // Hypervisor Vendor Identity
facp.update_checksum();
let facp_offset = dsdt_offset.checked_add(dsdt.len() as u64).unwrap();
guest_mem
.write_slice(facp.as_slice(), facp_offset)
.expect("Error writing FACP table");
tables.push(facp_offset.0);
// MADT
let mut madt = SDT::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1);
madt.write(36, super::mptable::APIC_DEFAULT_PHYS_BASE);
for cpu in 0..num_cpus {
let lapic = LocalAPIC {
r#type: 0,
length: 8,
processor_id: cpu,
apic_id: cpu,
flags: 1,
};
madt.append(lapic);
}
madt.append(IOAPIC {
r#type: 1,
length: 12,
ioapic_id: 0,
apic_address: super::mptable::IO_APIC_DEFAULT_PHYS_BASE,
gsi_base: 0,
..Default::default()
});
madt.append(InterruptSourceOverride {
r#type: 2,
length: 10,
bus: 0,
source: 4,
gsi: 4,
flags: 0,
});
let madt_offset = facp_offset.checked_add(facp.len() as u64).unwrap();
guest_mem
.write_slice(madt.as_slice(), madt_offset)
.expect("Error writing MADT table");
tables.push(madt_offset.0);
// MCFG
let mut mcfg = SDT::new(*b"MCFG", 60, 1, *b"CLOUDH", *b"CHMCFG ", 1);
// 32-bit PCI enhanced configuration mechanism
mcfg.append(PCIRangeEntry {
base_address: super::MEM_32BIT_DEVICES_GAP_SIZE,
segment: 0,
start: 0,
end: 0xff,
..Default::default()
});
let mcfg_offset = madt_offset.checked_add(madt.len() as u64).unwrap();
guest_mem
.write_slice(mcfg.as_slice(), mcfg_offset)
.expect("Error writing MCFG table");
tables.push(mcfg_offset.0);
// XSDT
let mut xsdt = SDT::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1);
for table in tables {
xsdt.append(table);
}
xsdt.update_checksum();
let xsdt_offset = mcfg_offset.checked_add(mcfg.len() as u64).unwrap();
guest_mem
.write_slice(xsdt.as_slice(), xsdt_offset)
.expect("Error writing XSDT table");
// RSDP
let rsdp = RSDP::new(*b"CLOUDH", xsdt_offset.0);
guest_mem
.write_slice(rsdp.as_slice(), rsdp_offset)
.expect("Error writing RSDP");
rsdp_offset
}

View File

@@ -1,3 +1,5 @@
// Copyright © 2020, Oracle and/or its affiliates.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
@@ -6,26 +8,51 @@
// found in the LICENSE-BSD-3-Clause file.
// For GDT details see arch/x86/include/asm/segment.h
use kvm_bindings::kvm_segment;
use hypervisor::x86_64::SegmentRegister;
/// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h.
pub fn gdt_entry(flags: u16, base: u32, limit: u32) -> u64 {
((((base as u64) & 0xff000000u64) << (56 - 24))
(((base as u64) & 0xff000000u64) << (56 - 24))
| (((flags as u64) & 0x0000f0ffu64) << 40)
| (((limit as u64) & 0x000f0000u64) << (48 - 16))
| (((base as u64) & 0x00ffffffu64) << 16)
| ((limit as u64) & 0x0000ffffu64))
| ((limit as u64) & 0x0000ffffu64)
}
fn get_base(entry: u64) -> u64 {
((((entry) & 0xFF00000000000000) >> 32)
(((entry) & 0xFF00000000000000) >> 32)
| (((entry) & 0x000000FF00000000) >> 16)
| (((entry) & 0x00000000FFFF0000) >> 16))
| (((entry) & 0x00000000FFFF0000) >> 16)
}
// Extract the segment limit from the GDT segment descriptor.
//
// In a segment descriptor, the limit field is 20 bits, so it can directly describe
// a range from 0 to 0xFFFFF (1MByte). When G flag is set (4-KByte page granularity) it
// scales the value in the limit field by a factor of 2^12 (4Kbytes), making the effective
// limit range from 0xFFF (4 KBytes) to 0xFFFF_FFFF (4 GBytes).
//
// However, the limit field in the VMCS definition is a 32 bit field, and the limit value is not
// automatically scaled using the G flag. This means that for a desired range of 4GB for a
// given segment, its limit must be specified as 0xFFFF_FFFF. Therefore the method of obtaining
// the limit from the GDT entry is not sufficient, since it only provides 20 bits when 32 bits
// are necessary. Fortunately, we can check if the G flag is set when extracting the limit since
// the full GDT entry is passed as an argument, and perform the scaling of the limit value to
// return the full 32 bit value.
//
// The scaling mentioned above is required when using PVH boot, since the guest boots in protected
// (32-bit) mode and must be able to access the entire 32-bit address space. It does not cause issues
// for the case of direct boot to 64-bit (long) mode, since in 64-bit mode the processor does not
// perform runtime limit checking on code or data segments.
fn get_limit(entry: u64) -> u32 {
((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32
let limit: u32 =
((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32;
// Perform manual limit scaling if G flag is set
match get_g(entry) {
0 => limit,
_ => ((limit << 12) | 0xFFF), // G flag is either 0 or 1
}
}
fn get_g(entry: u64) -> u8 {
@@ -60,14 +87,14 @@ fn get_type(entry: u64) -> u8 {
((entry & 0x00000F0000000000) >> 40) as u8
}
/// Automatically build the kvm struct for SET_SREGS from the kernel bit fields.
/// Automatically build the struct for SET_SREGS from the kernel bit fields.
///
/// # Arguments
///
/// * `entry` - The gdt entry.
/// * `table_index` - Index of the entry in the gdt table.
pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment {
kvm_segment {
pub fn segment_from_gdt(entry: u64, table_index: u8) -> SegmentRegister {
SegmentRegister {
base: get_base(entry),
limit: get_limit(entry),
selector: (table_index * 8) as u16,
@@ -94,7 +121,7 @@ mod tests {
#[test]
fn field_parse() {
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
let seg = kvm_segment_from_gdt(gdt, 0);
let seg = segment_from_gdt(gdt, 0);
// 0xA09B
// 'A'
assert_eq!(0x1, seg.g);
@@ -109,7 +136,7 @@ mod tests {
assert_eq!(0xB, seg.type_);
// base and limit
assert_eq!(0x100000, seg.base);
assert_eq!(0xfffff, seg.limit);
assert_eq!(0xffffffff, seg.limit);
assert_eq!(0x0, seg.unusable);
}
}

View File

@@ -5,30 +5,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use std::io::{self, Cursor};
use std::io::Cursor;
use std::mem;
use std::result;
use std::sync::Arc;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use kvm_bindings::kvm_lapic_state;
use kvm_ioctls;
use hypervisor::x86_64::LapicState;
#[derive(Debug)]
pub enum Error {
GetLapic(io::Error),
SetLapic(io::Error),
GetLapic(anyhow::Error),
SetLapic(anyhow::Error),
}
pub type Result<T> = result::Result<T, Error>;
pub type Result<T> = result::Result<T, hypervisor::HypervisorCpuError>;
// Defines poached from apicdef.h kernel header.
const APIC_LVT0: usize = 0x350;
const APIC_LVT1: usize = 0x360;
const APIC_MODE_NMI: u32 = 0x4;
const APIC_MODE_EXTINT: u32 = 0x7;
pub const APIC_LVT0: usize = 0x350;
pub const APIC_LVT1: usize = 0x360;
pub const APIC_MODE_NMI: u32 = 0x4;
pub const APIC_MODE_EXTINT: u32 = 0x7;
fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 {
pub fn get_klapic_reg(klapic: &LapicState, reg_offset: usize) -> u32 {
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
@@ -41,7 +41,7 @@ fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 {
.expect("Failed to read klapic register")
}
fn set_klapic_reg(klapic: &mut kvm_lapic_state, reg_offset: usize, value: u32) {
pub fn set_klapic_reg(klapic: &mut LapicState, reg_offset: usize, value: u32) {
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
@@ -54,16 +54,16 @@ fn set_klapic_reg(klapic: &mut kvm_lapic_state, reg_offset: usize, value: u32) {
.expect("Failed to write klapic register")
}
fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
(((reg) & !0x700) | ((mode) << 8))
pub fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
((reg) & !0x700) | ((mode) << 8)
}
/// Configures LAPICs. LAPIC0 is set for external interrupts, LAPIC1 is set for NMI.
///
/// # Arguments
/// * `vcpu` - The VCPU object to configure.
pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> {
let mut klapic = vcpu.get_lapic().map_err(Error::GetLapic)?;
pub fn set_lint(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
let mut klapic = vcpu.get_lapic()?;
let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0);
set_klapic_reg(
@@ -78,24 +78,23 @@ pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> {
set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI),
);
vcpu.set_lapic(&klapic).map_err(Error::SetLapic)
vcpu.set_lapic(&klapic)
}
#[cfg(test)]
mod tests {
extern crate kvm_ioctls;
extern crate rand;
use self::rand::Rng;
use super::*;
use kvm_ioctls::Kvm;
const KVM_APIC_REG_SIZE: usize = 0x400;
#[test]
fn test_set_and_get_klapic_reg() {
let reg_offset = 0x340;
let mut klapic = kvm_lapic_state::default();
let mut klapic = LapicState::default();
set_klapic_reg(&mut klapic, reg_offset, 3);
let value = get_klapic_reg(&klapic, reg_offset);
assert_eq!(value, 3);
@@ -105,7 +104,7 @@ mod tests {
#[should_panic]
fn test_set_and_get_klapic_out_of_bounds() {
let reg_offset = KVM_APIC_REG_SIZE + 10;
let mut klapic = kvm_lapic_state::default();
let mut klapic = LapicState::default();
set_klapic_reg(&mut klapic, reg_offset, 3);
}
@@ -119,40 +118,4 @@ mod tests {
let after: Vec<u32> = v.iter().map(|x| ((*x & !0x700) | ((2) << 8))).collect();
assert_eq!(v, after);
}
#[test]
fn test_setlint() {
let kvm = kvm_ioctls::Kvm::new().unwrap();
assert!(kvm.check_extension(kvm_ioctls::Cap::Irqchip));
let vm = kvm.create_vm().unwrap();
//the get_lapic ioctl will fail if there is no irqchip created beforehand.
assert!(vm.create_irq_chip().is_ok());
let vcpu = vm.create_vcpu(0).unwrap();
let klapic_before: kvm_lapic_state = vcpu.get_lapic().unwrap();
// Compute the value that is expected to represent LVT0 and LVT1.
let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0);
let lint1 = get_klapic_reg(&klapic_before, APIC_LVT1);
let lint0_mode_expected = set_apic_delivery_mode(lint0, APIC_MODE_EXTINT);
let lint1_mode_expected = set_apic_delivery_mode(lint1, APIC_MODE_NMI);
set_lint(&vcpu).unwrap();
// Compute the value that represents LVT0 and LVT1 after set_lint.
let klapic_actual: kvm_lapic_state = vcpu.get_lapic().unwrap();
let lint0_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT0);
let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1);
assert_eq!(lint0_mode_expected, lint0_mode_actual);
assert_eq!(lint1_mode_expected, lint1_mode_actual);
}
#[test]
fn test_setlint_fails() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// 'get_lapic' ioctl triggered by the 'set_lint' function will fail if there is no
// irqchip created beforehand.
assert!(set_lint(&vcpu).is_err());
}
}

View File

@@ -1,3 +1,5 @@
// Copyright © 2020, Oracle and/or its affiliates.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
@@ -5,21 +7,104 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use vm_memory::GuestAddress;
use vm_memory::{GuestAddress, GuestUsize};
/// Magic addresses externally used to lay out x86_64 VMs.
/*
Memory layout documentation and constants
~~~~~~ ~~~~~~ ~~~~~~~~~~~~~ ~~~ ~~~~~~~~~
Constants are in order and grouped by range. Take care to update all references
when making changes and keep them in order.
*/
// ** Low RAM (start: 0, length: 640KiB) **
pub const LOW_RAM_START: GuestAddress = GuestAddress(0x0);
// == Fixed addresses within the "Low RAM" range: ==
// Initial GDT/IDT needed to boot kernel
pub const BOOT_GDT_START: GuestAddress = GuestAddress(0x500);
pub const BOOT_IDT_START: GuestAddress = GuestAddress(0x520);
/// Address for the hvm_start_info struct used in PVH boot
pub const PVH_INFO_START: GuestAddress = GuestAddress(0x6000);
/// Starting address of array of modules of hvm_modlist_entry type.
/// Used to enable initrd support using the PVH boot ABI.
pub const MODLIST_START: GuestAddress = GuestAddress(0x6040);
/// Address of memory map table used in PVH boot. Can overlap
/// with the zero page address since they are mutually exclusive.
pub const MEMMAP_START: GuestAddress = GuestAddress(0x7000);
/// The 'zero page', a.k.a linux kernel bootparams.
pub const ZERO_PAGE_START: GuestAddress = GuestAddress(0x7000);
/// Initial stack for the boot CPU.
pub const BOOT_STACK_START: GuestAddress = GuestAddress(0x8000);
pub const BOOT_STACK_POINTER: GuestAddress = GuestAddress(0x8ff0);
// Initial pagetables.
pub const PML5_START: GuestAddress = GuestAddress(0x9000);
pub const PML4_START: GuestAddress = GuestAddress(0xa000);
pub const PDPTE_START: GuestAddress = GuestAddress(0xb000);
pub const PDE_START: GuestAddress = GuestAddress(0xc000);
/// Kernel command line start address.
pub const CMDLINE_START: GuestAddress = GuestAddress(0x20000);
/// Kernel command line start address maximum size.
pub const CMDLINE_MAX_SIZE: usize = 0x10000;
/// Address for the TSS setup.
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffbd000);
// MPTABLE, describing VCPUS.
pub const MPTABLE_START: GuestAddress = GuestAddress(0x9fc00);
/// The 'zero page', a.k.a linux kernel bootparams.
pub const ZERO_PAGE_START: GuestAddress = GuestAddress(0x7000);
// == End of "Low RAM" range. ==
// ** EBDA reserved area (start: 640KiB, length: 384KiB) **
pub const EBDA_START: GuestAddress = GuestAddress(0xa0000);
// == Fixed constants within the "EBDA" range ==
// ACPI RSDP table
pub const RSDP_POINTER: GuestAddress = EBDA_START;
pub const SMBIOS_START: u64 = 0xf0000; // First possible location per the spec.
// == End of "EBDA" range ==
// ** High RAM (start: 1MiB, length: 3071MiB) **
pub const HIGH_RAM_START: GuestAddress = GuestAddress(0x100000);
// == No fixed addresses in the "High RAM" range ==
// ** 32-bit reserved area (start: 3GiB, length: 1GiB) **
pub const MEM_32BIT_RESERVED_START: GuestAddress = GuestAddress(0xc000_0000);
pub const MEM_32BIT_RESERVED_SIZE: GuestUsize = 1024 << 20;
// == Fixed constants within the "32-bit reserved" range ==
// Sub range: 32-bit PCI devices (start: 3GiB, length: 640Mib)
pub const MEM_32BIT_DEVICES_START: GuestAddress = MEM_32BIT_RESERVED_START;
pub const MEM_32BIT_DEVICES_SIZE: GuestUsize = 640 << 20;
// PCI MMCONFIG space (start: after the device space, length: 256MiB)
pub const PCI_MMCONFIG_START: GuestAddress =
GuestAddress(MEM_32BIT_DEVICES_START.0 + MEM_32BIT_DEVICES_SIZE);
pub const PCI_MMCONFIG_SIZE: GuestUsize = 256 << 20;
// IOAPIC
pub const IOAPIC_START: GuestAddress = GuestAddress(0xfec0_0000);
pub const IOAPIC_SIZE: GuestUsize = 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) **
pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,8 @@ use std::slice;
use libc::c_char;
use arch_gen::x86::mpspec;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
use layout::{APIC_START, IOAPIC_START, MPTABLE_START};
use vm_memory::{Address, ByteValued, Bytes, GuestMemory, GuestMemoryError, GuestMemoryMmap};
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `ByteValued`) where:
@@ -44,33 +45,30 @@ unsafe impl ByteValued for MpcTableWrapper {}
unsafe impl ByteValued for MpcLintsrcWrapper {}
unsafe impl ByteValued for MpfIntelWrapper {}
// MPTABLE, describing VCPUS.
const MPTABLE_START: GuestAddress = GuestAddress(0x9fc00);
#[derive(Debug, PartialEq)]
#[derive(Debug)]
pub enum Error {
/// There was too little guest memory to store the entire MP table.
NotEnoughMemory,
/// The MP table has too little address space to be stored.
AddressOverflow,
/// Failure while zeroing out the memory for the MP table.
Clear,
Clear(GuestMemoryError),
/// Number of CPUs exceeds the maximum supported CPUs
TooManyCpus,
/// Failure to write the MP floating pointer.
WriteMpfIntel,
WriteMpfIntel(GuestMemoryError),
/// Failure to write MP CPU entry.
WriteMpcCpu,
WriteMpcCpu(GuestMemoryError),
/// Failure to write MP ioapic entry.
WriteMpcIoapic,
WriteMpcIoapic(GuestMemoryError),
/// Failure to write MP bus entry.
WriteMpcBus,
WriteMpcBus(GuestMemoryError),
/// Failure to write MP interrupt source entry.
WriteMpcIntsrc,
WriteMpcIntsrc(GuestMemoryError),
/// Failure to write MP local interrupt source entry.
WriteMpcLintsrc,
WriteMpcLintsrc(GuestMemoryError),
/// Failure to write MP table header.
WriteMpcTable,
WriteMpcTable(GuestMemoryError),
}
pub type Result<T> = result::Result<T, Error>;
@@ -92,8 +90,6 @@ const MPC_SPEC: i8 = 4;
const MPC_OEM: [c_char; 8] = char_array!(c_char; 'F', 'C', ' ', ' ', ' ', ' ', ' ', ' ');
const MPC_PRODUCT_ID: [c_char; 12] = ['0' as c_char; 12];
const BUS_TYPE_ISA: [u8; 6] = char_array!(u8; 'I', 'S', 'A', ' ', ' ', ' ');
pub const IO_APIC_DEFAULT_PHYS_BASE: u32 = 0xfec00000; // source: linux/arch/x86/include/asm/apicdef.h
pub const APIC_DEFAULT_PHYS_BASE: u32 = 0xfee00000; // source: linux/arch/x86/include/asm/apicdef.h
const APIC_VERSION: u8 = 0x14;
const CPU_STEPPING: u32 = 0x600;
const CPU_FEATURE_APIC: u32 = 0x200;
@@ -149,7 +145,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
}
mem.read_exact_from(base_mp, &mut io::repeat(0), mp_size)
.map_err(|_| Error::Clear)?;
.map_err(Error::Clear)?;
{
let mut mpf_intel = MpfIntelWrapper(mpspec::mpf_intel::default());
@@ -160,7 +156,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpf_intel.0.physptr = (base_mp.raw_value() + size) as u32;
mpf_intel.0.checksum = mpf_intel_compute_checksum(&mpf_intel.0);
mem.write_obj(mpf_intel, base_mp)
.map_err(|_| Error::WriteMpfIntel)?;
.map_err(Error::WriteMpfIntel)?;
base_mp = base_mp.unchecked_add(size);
}
@@ -185,7 +181,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_cpu.0.cpufeature = CPU_STEPPING;
mpc_cpu.0.featureflag = CPU_FEATURE_APIC | CPU_FEATURE_FPU;
mem.write_obj(mpc_cpu, base_mp)
.map_err(|_| Error::WriteMpcCpu)?;
.map_err(Error::WriteMpcCpu)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_cpu.0));
}
@@ -197,7 +193,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_bus.0.busid = 0;
mpc_bus.0.bustype = BUS_TYPE_ISA;
mem.write_obj(mpc_bus, base_mp)
.map_err(|_| Error::WriteMpcBus)?;
.map_err(Error::WriteMpcBus)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_bus.0));
}
@@ -208,9 +204,9 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_ioapic.0.apicid = ioapicid;
mpc_ioapic.0.apicver = APIC_VERSION;
mpc_ioapic.0.flags = mpspec::MPC_APIC_USABLE as u8;
mpc_ioapic.0.apicaddr = IO_APIC_DEFAULT_PHYS_BASE;
mpc_ioapic.0.apicaddr = IOAPIC_START.0 as u32;
mem.write_obj(mpc_ioapic, base_mp)
.map_err(|_| Error::WriteMpcIoapic)?;
.map_err(Error::WriteMpcIoapic)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_ioapic.0));
}
@@ -226,7 +222,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_intsrc.0.dstapic = ioapicid;
mpc_intsrc.0.dstirq = i;
mem.write_obj(mpc_intsrc, base_mp)
.map_err(|_| Error::WriteMpcIntsrc)?;
.map_err(Error::WriteMpcIntsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_intsrc.0));
}
@@ -241,7 +237,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_lintsrc.0.destapic = 0;
mpc_lintsrc.0.destapiclint = 0;
mem.write_obj(mpc_lintsrc, base_mp)
.map_err(|_| Error::WriteMpcLintsrc)?;
.map_err(Error::WriteMpcLintsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
}
@@ -256,7 +252,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_lintsrc.0.destapic = 0xFF; /* to all local APICs */
mpc_lintsrc.0.destapiclint = 1;
mem.write_obj(mpc_lintsrc, base_mp)
.map_err(|_| Error::WriteMpcLintsrc)?;
.map_err(Error::WriteMpcLintsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
}
@@ -271,11 +267,11 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
mpc_table.0.spec = MPC_SPEC;
mpc_table.0.oem = MPC_OEM;
mpc_table.0.productid = MPC_PRODUCT_ID;
mpc_table.0.lapic = APIC_DEFAULT_PHYS_BASE;
mpc_table.0.lapic = APIC_START.0 as u32;
checksum = checksum.wrapping_add(compute_checksum(&mpc_table.0));
mpc_table.0.checksum = (!checksum).wrapping_add(1) as i8;
mem.write_obj(mpc_table, table_base)
.map_err(|_| Error::WriteMpcTable)?;
.map_err(Error::WriteMpcTable)?;
}
Ok(())
@@ -284,7 +280,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use vm_memory::GuestUsize;
use vm_memory::{GuestAddress, GuestUsize};
fn table_entry_size(type_: u8) -> usize {
match type_ as u32 {
@@ -300,7 +296,8 @@ mod tests {
#[test]
fn bounds_check() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
}
@@ -308,7 +305,8 @@ mod tests {
#[test]
fn bounds_check_fails() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)]).unwrap();
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)])
.unwrap();
assert!(setup_mptable(&mem, num_cpus).is_err());
}
@@ -316,7 +314,8 @@ mod tests {
#[test]
fn mpf_intel_checksum() {
let num_cpus = 1;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
@@ -331,7 +330,8 @@ mod tests {
#[test]
fn mpc_table_checksum() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
@@ -360,9 +360,11 @@ mod tests {
#[test]
fn cpu_entry_count() {
let mem =
GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(MAX_SUPPORTED_CPUS as u8))])
.unwrap();
let mem = GuestMemoryMmap::from_ranges(&[(
MPTABLE_START,
compute_mp_size(MAX_SUPPORTED_CPUS as u8),
)])
.unwrap();
for i in 0..MAX_SUPPORTED_CPUS as u8 {
setup_mptable(&mem, i).unwrap();
@@ -395,9 +397,10 @@ mod tests {
#[test]
fn cpu_entry_count_max() {
let cpus = MAX_SUPPORTED_CPUS + 1;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let result = setup_mptable(&mem, cpus as u8).unwrap_err();
assert_eq!(result, Error::TooManyCpus);
let result = setup_mptable(&mem, cpus as u8);
assert!(result.is_err());
}
}

View File

@@ -1,49 +1,48 @@
// Copyright © 2020, Oracle and/or its affiliates.
//
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use std::sync::Arc;
use std::{mem, result};
use std::{io, mem, result};
use super::gdt::{gdt_entry, kvm_segment_from_gdt};
use arch_gen::x86::msr_index;
use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_msrs, kvm_regs, kvm_sregs};
use kvm_ioctls::VcpuFd;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
// Initial pagetables.
const PML4_START: GuestAddress = GuestAddress(0x9000);
const PDPTE_START: GuestAddress = GuestAddress(0xa000);
const PDE_START: GuestAddress = GuestAddress(0xb000);
// MTRR constants
const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11
const MTRR_MEM_TYPE_WB: u64 = 0x6;
use super::gdt::{gdt_entry, segment_from_gdt};
use super::BootProtocol;
use hypervisor::x86_64::{FpuState, SpecialRegisters, StandardRegisters};
use layout::{
BOOT_GDT_START, BOOT_IDT_START, PDE_START, PDPTE_START, PML4_START, PML5_START, PVH_INFO_START,
};
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryMmap};
#[derive(Debug)]
pub enum Error {
/// Failed to get SREGs for this CPU.
GetStatusRegisters(io::Error),
GetStatusRegisters(hypervisor::HypervisorCpuError),
/// Failed to set base registers for this CPU.
SetBaseRegisters(io::Error),
SetBaseRegisters(hypervisor::HypervisorCpuError),
/// Failed to configure the FPU.
SetFPURegisters(io::Error),
SetFPURegisters(hypervisor::HypervisorCpuError),
/// Setting up MSRs failed.
SetModelSpecificRegisters(io::Error),
SetModelSpecificRegisters(hypervisor::HypervisorCpuError),
/// Failed to set SREGs for this CPU.
SetStatusRegisters(io::Error),
SetStatusRegisters(hypervisor::HypervisorCpuError),
/// Checking the GDT address failed.
CheckGDTAddr,
/// Writing the GDT to RAM failed.
WriteGDT,
WriteGDT(GuestMemoryError),
/// Writing the IDT to RAM failed.
WriteIDT,
WriteIDT(GuestMemoryError),
/// Writing PDPTE to RAM failed.
WritePDPTEAddress,
WritePDPTEAddress(GuestMemoryError),
/// Writing PDE to RAM failed.
WritePDEAddress,
WritePDEAddress(GuestMemoryError),
/// Writing PML4 to RAM failed.
WritePML4Address,
WritePML4Address(GuestMemoryError),
/// Writing PML5 to RAM failed.
WritePML5Address(GuestMemoryError),
}
pub type Result<T> = result::Result<T, Error>;
@@ -53,8 +52,8 @@ pub type Result<T> = result::Result<T, Error>;
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
let fpu: kvm_fpu = kvm_fpu {
pub fn setup_fpu(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
let fpu: FpuState = FpuState {
fcw: 0x37f,
mxcsr: 0x1f80,
..Default::default()
@@ -68,27 +67,11 @@ pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
let entry_vec = create_msr_entries();
let vec_size_bytes =
mem::size_of::<kvm_msrs>() + (entry_vec.len() * mem::size_of::<kvm_msr_entry>());
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
let msrs: &mut kvm_msrs = unsafe {
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
// vector to size and set the members ensures no out-of-bounds errors below.
&mut *(vec.as_ptr() as *mut kvm_msrs)
};
pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
vcpu.set_msrs(&hypervisor::x86_64::boot_msr_entries())
.map_err(Error::SetModelSpecificRegisters)?;
unsafe {
// Mapping the unsized array to a slice is unsafe because the length isn't known.
// Providing the length used to create the struct guarantees the entire slice is valid.
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(entry_vec.len());
entries.copy_from_slice(&entry_vec);
}
msrs.nmsrs = entry_vec.len() as u32;
vcpu.set_msrs(msrs)
.map_err(Error::SetModelSpecificRegisters)
Ok(())
}
/// Configure base registers for a given CPU.
@@ -99,16 +82,31 @@ pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
/// * `boot_ip` - Starting instruction pointer.
/// * `boot_sp` - Starting stack pointer.
/// * `boot_si` - Must point to zero page address per Linux ABI.
pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64, boot_sp: u64, boot_si: u64) -> Result<()> {
let regs: kvm_regs = kvm_regs {
rflags: 0x0000000000000002u64,
rip: boot_ip,
rsp: boot_sp,
rbp: boot_sp,
rsi: boot_si,
..Default::default()
pub fn setup_regs(
vcpu: &Arc<dyn hypervisor::Vcpu>,
boot_ip: u64,
boot_sp: u64,
boot_si: u64,
boot_prot: BootProtocol,
) -> Result<()> {
let regs: StandardRegisters = match boot_prot {
// Configure regs as required by PVH boot protocol.
BootProtocol::PvhBoot => StandardRegisters {
rflags: 0x0000000000000002u64,
rbx: PVH_INFO_START.raw_value(),
rip: boot_ip,
..Default::default()
},
// Configure regs as required by Linux 64-bit boot protocol.
BootProtocol::LinuxBoot => StandardRegisters {
rflags: 0x0000000000000002u64,
rip: boot_ip,
rsp: boot_sp,
rbp: boot_sp,
rsi: boot_si,
..Default::default()
},
};
vcpu.set_regs(&regs).map_err(Error::SetBaseRegisters)
}
@@ -118,18 +116,22 @@ pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64, boot_sp: u64, boot_si: u64) -> Re
///
/// * `mem` - The memory that will be passed to the guest.
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd) -> Result<()> {
let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
pub fn setup_sregs(
mem: &GuestMemoryMmap,
vcpu: &Arc<dyn hypervisor::Vcpu>,
boot_prot: BootProtocol,
) -> Result<()> {
let mut sregs: SpecialRegisters = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
configure_segments_and_sregs(mem, &mut sregs)?;
setup_page_tables(mem, &mut sregs)?; // TODO(dgreid) - Can this be done once per system instead?
configure_segments_and_sregs(mem, &mut sregs, boot_prot)?;
if let BootProtocol::LinuxBoot = boot_prot {
setup_page_tables(mem, &mut sregs)?; // TODO(dgreid) - Can this be done once per system instead?
}
vcpu.set_sregs(&sregs).map_err(Error::SetStatusRegisters)
}
const BOOT_GDT_OFFSET: GuestAddress = GuestAddress(0x500);
const BOOT_IDT_OFFSET: GuestAddress = GuestAddress(0x520);
const BOOT_GDT_MAX: usize = 4;
const EFER_LMA: u64 = 0x400;
@@ -138,46 +140,63 @@ const EFER_LME: u64 = 0x100;
const X86_CR0_PE: u64 = 0x1;
const X86_CR0_PG: u64 = 0x80000000;
const X86_CR4_PAE: u64 = 0x20;
const X86_CR4_LA57: u64 = 0x1000;
fn write_gdt_table(table: &[u64], guest_mem: &GuestMemoryMmap) -> Result<()> {
let boot_gdt_addr = BOOT_GDT_OFFSET;
let boot_gdt_addr = BOOT_GDT_START;
for (index, entry) in table.iter().enumerate() {
let addr = guest_mem
.checked_offset(boot_gdt_addr, index * mem::size_of::<u64>())
.ok_or(Error::WriteGDT)?;
guest_mem
.write_obj(*entry, addr)
.map_err(|_| Error::WriteGDT)?;
.ok_or(Error::CheckGDTAddr)?;
guest_mem.write_obj(*entry, addr).map_err(Error::WriteGDT)?;
}
Ok(())
}
fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> {
let boot_idt_addr = BOOT_IDT_OFFSET;
let boot_idt_addr = BOOT_IDT_START;
guest_mem
.write_obj(val, boot_idt_addr)
.map_err(|_| Error::WriteIDT)
.map_err(Error::WriteIDT)
}
fn configure_segments_and_sregs(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
let gdt_table: [u64; BOOT_GDT_MAX as usize] = [
gdt_entry(0, 0, 0), // NULL
gdt_entry(0xa09b, 0, 0xfffff), // CODE
gdt_entry(0xc093, 0, 0xfffff), // DATA
gdt_entry(0x808b, 0, 0xfffff), // TSS
];
pub fn configure_segments_and_sregs(
mem: &GuestMemoryMmap,
sregs: &mut SpecialRegisters,
boot_prot: BootProtocol,
) -> Result<()> {
let gdt_table: [u64; BOOT_GDT_MAX as usize] = match boot_prot {
BootProtocol::PvhBoot => {
// Configure GDT entries as specified by PVH boot protocol
[
gdt_entry(0, 0, 0), // NULL
gdt_entry(0xc09b, 0, 0xffffffff), // CODE
gdt_entry(0xc093, 0, 0xffffffff), // DATA
gdt_entry(0x008b, 0, 0x67), // TSS
]
}
BootProtocol::LinuxBoot => {
// Configure GDT entries as specified by Linux 64bit boot protocol
[
gdt_entry(0, 0, 0), // NULL
gdt_entry(0xa09b, 0, 0xfffff), // CODE
gdt_entry(0xc093, 0, 0xfffff), // DATA
gdt_entry(0x808b, 0, 0xfffff), // TSS
]
}
};
let code_seg = kvm_segment_from_gdt(gdt_table[1], 1);
let data_seg = kvm_segment_from_gdt(gdt_table[2], 2);
let tss_seg = kvm_segment_from_gdt(gdt_table[3], 3);
let code_seg = segment_from_gdt(gdt_table[1], 1);
let data_seg = segment_from_gdt(gdt_table[2], 2);
let tss_seg = segment_from_gdt(gdt_table[3], 3);
// Write segments
write_gdt_table(&gdt_table[..], mem)?;
sregs.gdt.base = BOOT_GDT_OFFSET.raw_value();
sregs.gdt.base = BOOT_GDT_START.raw_value();
sregs.gdt.limit = mem::size_of_val(&gdt_table) as u16 - 1;
write_idt_value(0, mem)?;
sregs.idt.base = BOOT_IDT_OFFSET.raw_value();
sregs.idt.base = BOOT_IDT_START.raw_value();
sregs.idt.limit = mem::size_of::<u64>() as u16 - 1;
sregs.cs = code_seg;
@@ -188,111 +207,64 @@ fn configure_segments_and_sregs(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) ->
sregs.ss = data_seg;
sregs.tr = tss_seg;
/* 64-bit protected mode */
sregs.cr0 |= X86_CR0_PE;
sregs.efer |= EFER_LME | EFER_LMA;
match boot_prot {
BootProtocol::PvhBoot => {
sregs.cr0 = X86_CR0_PE;
sregs.cr4 = 0;
}
BootProtocol::LinuxBoot => {
/* 64-bit protected mode */
sregs.cr0 |= X86_CR0_PE;
sregs.efer |= EFER_LME | EFER_LMA;
}
}
Ok(())
}
fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
// Puts PML4 right after zero page but aligned to 4k.
pub fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut SpecialRegisters) -> Result<()> {
// Puts PML5 or PML4 right after zero page but aligned to 4k.
if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 {
// Entry covering VA [0..256TB)
mem.write_obj(PML4_START.raw_value() | 0x03, PML5_START)
.map_err(Error::WritePML5Address)?;
sregs.cr3 = PML5_START.raw_value();
sregs.cr4 |= X86_CR4_LA57;
} else {
sregs.cr3 = PML4_START.raw_value();
}
// Entry covering VA [0..512GB)
mem.write_obj(PDPTE_START.raw_value() | 0x03, PML4_START)
.map_err(|_| Error::WritePML4Address)?;
.map_err(Error::WritePML4Address)?;
// Entry covering VA [0..1GB)
mem.write_obj(PDE_START.raw_value() | 0x03, PDPTE_START)
.map_err(|_| Error::WritePDPTEAddress)?;
.map_err(Error::WritePDPTEAddress)?;
// 512 2MB entries together covering VA [0..1GB). Note we are assuming
// CPU supports 2MB pages (/proc/cpuinfo has 'pse'). All modern CPUs do.
for i in 0..512 {
mem.write_obj((i << 21) + 0x83u64, PDE_START.unchecked_add(i * 8))
.map_err(|_| Error::WritePDEAddress)?;
.map_err(Error::WritePDEAddress)?;
}
sregs.cr3 = PML4_START.raw_value();
sregs.cr4 |= X86_CR4_PAE;
sregs.cr0 |= X86_CR0_PG;
Ok(())
}
fn create_msr_entries() -> Vec<kvm_msr_entry> {
let mut entries = Vec::<kvm_msr_entry>::new();
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_CS,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_ESP,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_EIP,
data: 0x0,
..Default::default()
});
// x86_64 specific msrs, we only run on x86_64 not x86.
entries.push(kvm_msr_entry {
index: msr_index::MSR_STAR,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_CSTAR,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_KERNEL_GS_BASE,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_SYSCALL_MASK,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_LSTAR,
data: 0x0,
..Default::default()
});
// end of x86_64 specific code
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_TSC,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_MISC_ENABLE,
data: msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_MTRRdefType,
data: MTRR_ENABLE | MTRR_MEM_TYPE_WB,
..Default::default()
});
entries
}
#[cfg(test)]
mod tests {
extern crate kvm_ioctls;
extern crate vm_memory;
use super::*;
use kvm_ioctls::Kvm;
use vm_memory::{GuestAddress, GuestMemoryMmap};
fn create_guest_mem() -> GuestMemoryMmap {
GuestMemoryMmap::new(&vec![(GuestAddress(0), 0x10000)]).unwrap()
GuestMemoryMmap::from_ranges(&vec![(GuestAddress(0), 0x10000)]).unwrap()
}
fn read_u64(gm: &GuestMemoryMmap, offset: GuestAddress) -> u64 {
@@ -301,46 +273,79 @@ mod tests {
#[test]
fn segments_and_sregs() {
let mut sregs: kvm_sregs = Default::default();
let mut sregs: SpecialRegisters = Default::default();
let gm = create_guest_mem();
configure_segments_and_sregs(&gm, &mut sregs).unwrap();
configure_segments_and_sregs(&gm, &mut sregs, BootProtocol::LinuxBoot).unwrap();
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_OFFSET));
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_START));
assert_eq!(
0xaf9b000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(8))
read_u64(&gm, BOOT_GDT_START.unchecked_add(8))
);
assert_eq!(
0xcf93000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(16))
read_u64(&gm, BOOT_GDT_START.unchecked_add(16))
);
assert_eq!(
0x8f8b000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(24))
read_u64(&gm, BOOT_GDT_START.unchecked_add(24))
);
assert_eq!(0x0, read_u64(&gm, BOOT_IDT_OFFSET));
assert_eq!(0x0, read_u64(&gm, BOOT_IDT_START));
assert_eq!(0, sregs.cs.base);
assert_eq!(0xfffff, sregs.ds.limit);
assert_eq!(0xffffffff, sregs.ds.limit);
assert_eq!(0x10, sregs.es.selector);
assert_eq!(1, sregs.fs.present);
assert_eq!(1, sregs.gs.g);
assert_eq!(0, sregs.ss.avl);
assert_eq!(0, sregs.tr.base);
assert_eq!(0xfffff, sregs.tr.limit);
assert_eq!(0xffffffff, sregs.tr.limit);
assert_eq!(0, sregs.tr.avl);
assert_eq!(X86_CR0_PE, sregs.cr0);
assert_eq!(EFER_LME | EFER_LMA, sregs.efer);
configure_segments_and_sregs(&gm, &mut sregs, BootProtocol::PvhBoot).unwrap();
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_START));
assert_eq!(
0xcf9b000000ffff,
read_u64(&gm, BOOT_GDT_START.unchecked_add(8))
);
assert_eq!(
0xcf93000000ffff,
read_u64(&gm, BOOT_GDT_START.unchecked_add(16))
);
assert_eq!(
0x8b0000000067,
read_u64(&gm, BOOT_GDT_START.unchecked_add(24))
);
assert_eq!(0x0, read_u64(&gm, BOOT_IDT_START));
assert_eq!(0, sregs.cs.base);
assert_eq!(0xffffffff, sregs.ds.limit);
assert_eq!(0x10, sregs.es.selector);
assert_eq!(1, sregs.fs.present);
assert_eq!(1, sregs.gs.g);
assert_eq!(0, sregs.ss.avl);
assert_eq!(0, sregs.tr.base);
assert_eq!(0, sregs.tr.g);
assert_eq!(0x67, sregs.tr.limit);
assert_eq!(0xb, sregs.tr.type_);
assert_eq!(0, sregs.tr.avl);
assert_eq!(X86_CR0_PE, sregs.cr0);
assert_eq!(0, sregs.cr4);
}
#[test]
fn page_tables() {
let mut sregs: kvm_sregs = Default::default();
let mut sregs: SpecialRegisters = Default::default();
let gm = create_guest_mem();
setup_page_tables(&gm, &mut sregs).unwrap();
assert_eq!(0xa003, read_u64(&gm, PML4_START));
assert_eq!(0xb003, read_u64(&gm, PDPTE_START));
if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 {
assert_eq!(0xa003, read_u64(&gm, PML5_START));
}
assert_eq!(0xb003, read_u64(&gm, PML4_START));
assert_eq!(0xc003, read_u64(&gm, PDPTE_START));
for i in 0..512 {
assert_eq!(
(i << 21) + 0x83u64,
@@ -348,114 +353,12 @@ mod tests {
);
}
assert_eq!(PML4_START.raw_value(), sregs.cr3);
if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 {
assert_eq!(PML5_START.raw_value(), sregs.cr3);
} else {
assert_eq!(PML4_START.raw_value(), sregs.cr3);
}
assert_eq!(X86_CR4_PAE, sregs.cr4);
assert_eq!(X86_CR0_PG, sregs.cr0);
}
#[test]
fn test_setup_fpu() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
setup_fpu(&vcpu).unwrap();
let expected_fpu: kvm_fpu = kvm_fpu {
fcw: 0x37f,
mxcsr: 0x1f80,
..Default::default()
};
let actual_fpu: kvm_fpu = vcpu.get_fpu().unwrap();
// TODO: auto-generate kvm related structures with PartialEq on.
assert_eq!(expected_fpu.fcw, actual_fpu.fcw);
// Setting the mxcsr register from kvm_fpu inside setup_fpu does not influence anything.
// See 'kvm_arch_vcpu_ioctl_set_fpu' from arch/x86/kvm/x86.c.
// The mxcsr will stay 0 and the assert below fails. Decide whether or not we should
// remove it at all.
// assert!(expected_fpu.mxcsr == actual_fpu.mxcsr);
}
#[test]
fn test_setup_msrs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
setup_msrs(&vcpu).unwrap();
// This test will check against the last MSR entry configured (the tenth one).
// See create_msr_entries for details.
let test_kvm_msrs_entry = [kvm_msr_entry {
index: msr_index::MSR_IA32_MISC_ENABLE,
..Default::default()
}];
let vec_size_bytes = mem::size_of::<kvm_msrs>() + mem::size_of::<kvm_msr_entry>();
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
let mut msrs: &mut kvm_msrs = unsafe {
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
// vector to size and set the members ensures no out-of-bounds errors below.
&mut *(vec.as_ptr() as *mut kvm_msrs)
};
unsafe {
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(1);
entries.copy_from_slice(&test_kvm_msrs_entry);
}
msrs.nmsrs = 1;
// get_msrs returns the number of msrs that it succeed in reading. We only want to read 1
// in this test case scenario.
let read_msrs = vcpu.get_msrs(&mut msrs).unwrap();
assert_eq!(read_msrs, 1);
// Official entries that were setup when we did setup_msrs. We need to assert that the
// tenth one (i.e the one with index msr_index::MSR_IA32_MISC_ENABLE has the data we
// expect.
let entry_vec = create_msr_entries();
unsafe {
assert_eq!(entry_vec[9], msrs.entries.as_slice(1)[0]);
}
}
#[test]
fn test_setup_regs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let expected_regs: kvm_regs = kvm_regs {
rflags: 0x0000000000000002u64,
rip: 1,
rsp: 2,
rbp: 2,
rsi: 3,
..Default::default()
};
setup_regs(
&vcpu,
expected_regs.rip,
expected_regs.rsp,
expected_regs.rsi,
)
.unwrap();
let actual_regs: kvm_regs = vcpu.get_regs().unwrap();
assert_eq!(actual_regs, expected_regs);
}
#[test]
fn test_setup_sregs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mut expected_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
let gm = create_guest_mem();
configure_segments_and_sregs(&gm, &mut expected_sregs).unwrap();
setup_page_tables(&gm, &mut expected_sregs).unwrap();
setup_sregs(&gm, &vcpu).unwrap();
let actual_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
assert_eq!(expected_sregs, actual_sregs);
}
}

263
arch/src/x86_64/smbios.rs Normal file
View File

@@ -0,0 +1,263 @@
// Copyright © 2020 Intel Corporation
//
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use layout::SMBIOS_START;
use std::fmt::{self, Display};
use std::mem;
use std::result;
use std::slice;
use vm_memory::ByteValued;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemoryMmap};
#[allow(unused_variables)]
#[derive(Debug)]
pub enum Error {
/// There was too little guest memory to store the entire SMBIOS table.
NotEnoughMemory,
/// The SMBIOS table has too little address space to be stored.
AddressOverflow,
/// Failure while zeroing out the memory for the SMBIOS table.
Clear,
/// Failure to write SMBIOS entrypoint structure
WriteSmbiosEp,
/// Failure to write additional data to memory
WriteData,
}
impl std::error::Error for Error {}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
let description = match self {
NotEnoughMemory => "There was too little guest memory to store the SMBIOS table",
AddressOverflow => "The SMBIOS table has too little address space to be stored",
Clear => "Failure while zeroing out the memory for the SMBIOS table",
WriteSmbiosEp => "Failure to write SMBIOS entrypoint structure",
WriteData => "Failure to write additional data to memory",
};
write!(f, "SMBIOS error: {}", description)
}
}
pub type Result<T> = result::Result<T, Error>;
// Constants sourced from SMBIOS Spec 3.2.0.
const SM3_MAGIC_IDENT: &[u8; 5usize] = b"_SM3_";
const BIOS_INFORMATION: u8 = 0;
const SYSTEM_INFORMATION: u8 = 1;
const END_OF_TABLE: u8 = 127;
const PCI_SUPPORTED: u64 = 1 << 7;
const IS_VIRTUAL_MACHINE: u8 = 1 << 4;
fn compute_checksum<T: Copy>(v: &T) -> u8 {
// Safe because we are only reading the bytes within the size of the `T` reference `v`.
let v_slice = unsafe { slice::from_raw_parts(v as *const T as *const u8, mem::size_of::<T>()) };
let mut checksum: u8 = 0;
for i in v_slice.iter() {
checksum = checksum.wrapping_add(*i);
}
(!checksum).wrapping_add(1)
}
#[repr(packed)]
#[derive(Default, Copy)]
pub struct Smbios30Entrypoint {
pub signature: [u8; 5usize],
pub checksum: u8,
pub length: u8,
pub majorver: u8,
pub minorver: u8,
pub docrev: u8,
pub revision: u8,
pub reserved: u8,
pub max_size: u32,
pub physptr: u64,
}
unsafe impl ByteValued for Smbios30Entrypoint {}
impl Clone for Smbios30Entrypoint {
fn clone(&self) -> Self {
*self
}
}
#[repr(packed)]
#[derive(Default, Copy)]
pub struct SmbiosBiosInfo {
pub typ: u8,
pub length: u8,
pub handle: u16,
pub vendor: u8,
pub version: u8,
pub start_addr: u16,
pub release_date: u8,
pub rom_size: u8,
pub characteristics: u64,
pub characteristics_ext1: u8,
pub characteristics_ext2: u8,
}
impl Clone for SmbiosBiosInfo {
fn clone(&self) -> Self {
*self
}
}
unsafe impl ByteValued for SmbiosBiosInfo {}
#[repr(packed)]
#[derive(Default, Copy)]
pub struct SmbiosSysInfo {
pub typ: u8,
pub length: u8,
pub handle: u16,
pub manufacturer: u8,
pub product_name: u8,
pub version: u8,
pub serial_number: u8,
pub uuid: [u8; 16usize],
pub wake_up_type: u8,
pub sku: u8,
pub family: u8,
}
impl Clone for SmbiosSysInfo {
fn clone(&self) -> Self {
*self
}
}
unsafe impl ByteValued for SmbiosSysInfo {}
fn write_and_incr<T: ByteValued>(
mem: &GuestMemoryMmap,
val: T,
mut curptr: GuestAddress,
) -> Result<GuestAddress> {
mem.write_obj(val, curptr).map_err(|_| Error::WriteData)?;
curptr = curptr
.checked_add(mem::size_of::<T>() as u64)
.ok_or(Error::NotEnoughMemory)?;
Ok(curptr)
}
fn write_string(
mem: &GuestMemoryMmap,
val: &str,
mut curptr: GuestAddress,
) -> Result<GuestAddress> {
for c in val.as_bytes().iter() {
curptr = write_and_incr(mem, *c, curptr)?;
}
curptr = write_and_incr(mem, 0 as u8, curptr)?;
Ok(curptr)
}
pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<()> {
let physptr = GuestAddress(SMBIOS_START)
.checked_add(mem::size_of::<Smbios30Entrypoint>() as u64)
.ok_or(Error::NotEnoughMemory)?;
let mut curptr = physptr;
let mut handle = 0;
{
handle += 1;
let mut smbios_biosinfo = SmbiosBiosInfo::default();
smbios_biosinfo.typ = BIOS_INFORMATION;
smbios_biosinfo.length = mem::size_of::<SmbiosBiosInfo>() as u8;
smbios_biosinfo.handle = handle;
smbios_biosinfo.vendor = 1; // First string written in this section
smbios_biosinfo.version = 2; // Second string written in this section
smbios_biosinfo.characteristics = PCI_SUPPORTED;
smbios_biosinfo.characteristics_ext2 = IS_VIRTUAL_MACHINE;
curptr = write_and_incr(mem, smbios_biosinfo, curptr)?;
curptr = write_string(mem, "cloud-hypervisor", curptr)?;
curptr = write_string(mem, "0", curptr)?;
curptr = write_and_incr(mem, 0 as u8, curptr)?;
}
{
handle += 1;
let mut smbios_sysinfo = SmbiosSysInfo::default();
smbios_sysinfo.typ = SYSTEM_INFORMATION;
smbios_sysinfo.length = mem::size_of::<SmbiosSysInfo>() as u8;
smbios_sysinfo.handle = handle;
smbios_sysinfo.manufacturer = 1; // First string written in this section
smbios_sysinfo.product_name = 2; // Second string written in this section
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
curptr = write_string(mem, "Cloud Hypervisor", curptr)?;
curptr = write_string(mem, "cloud-hypervisor", curptr)?;
curptr = write_and_incr(mem, 0 as u8, curptr)?;
}
{
handle += 1;
let mut smbios_sysinfo = SmbiosSysInfo::default();
smbios_sysinfo.typ = END_OF_TABLE;
smbios_sysinfo.length = mem::size_of::<SmbiosSysInfo>() as u8;
smbios_sysinfo.handle = handle;
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
curptr = write_and_incr(mem, 0 as u8, curptr)?;
}
{
let mut smbios_ep = Smbios30Entrypoint::default();
smbios_ep.signature = *SM3_MAGIC_IDENT;
smbios_ep.length = mem::size_of::<Smbios30Entrypoint>() as u8;
// SMBIOS rev 3.2.0
smbios_ep.majorver = 0x03;
smbios_ep.minorver = 0x02;
smbios_ep.docrev = 0x00;
smbios_ep.revision = 0x01; // SMBIOS 3.0
smbios_ep.max_size = curptr.unchecked_offset_from(physptr) as u32;
smbios_ep.physptr = physptr.0;
smbios_ep.checksum = compute_checksum(&smbios_ep);
mem.write_obj(smbios_ep, GuestAddress(SMBIOS_START))
.map_err(|_| Error::WriteSmbiosEp)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn struct_size() {
assert_eq!(
mem::size_of::<Smbios30Entrypoint>(),
0x18usize,
concat!("Size of: ", stringify!(Smbios30Entrypoint))
);
assert_eq!(
mem::size_of::<SmbiosBiosInfo>(),
0x14usize,
concat!("Size of: ", stringify!(SmbiosBiosInfo))
);
assert_eq!(
mem::size_of::<SmbiosSysInfo>(),
0x1busize,
concat!("Size of: ", stringify!(SmbiosSysInfo))
);
}
#[test]
fn entrypoint_checksum() {
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(SMBIOS_START), 4096)]).unwrap();
setup_smbios(&mem).unwrap();
let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();
assert_eq!(compute_checksum(&smbios_ep), 0);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -16,11 +16,7 @@
clippy::should_implement_trait,
clippy::transmute_ptr_to_ptr
)]
pub mod bootparam;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)]
pub mod mpspec;
#[allow(non_upper_case_globals)]
#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)]
pub mod msr_index;

21
block_util/Cargo.toml Normal file
View File

@@ -0,0 +1,21 @@
[package]
name = "block_util"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[features]
default = []
io_uring = []
[dependencies]
io-uring = ">=0.4.0"
libc = "0.2.77"
log = "0.4.11"
serde = ">=1.0.27"
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]}
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1"

567
block_util/src/lib.rs Normal file
View File

@@ -0,0 +1,567 @@
// 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 © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "io_uring")]
use io_uring::{opcode, squeue, IoUring, Probe};
use serde::ser::{Serialize, SerializeStruct, Serializer};
use std::cmp;
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::os::linux::fs::MetadataExt;
#[cfg(feature = "io_uring")]
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::PathBuf;
use std::result;
use virtio_bindings::bindings::virtio_blk::*;
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
use vm_virtio::DescriptorChain;
#[cfg(feature = "io_uring")]
use vmm_sys_util::eventfd::EventFd;
const SECTOR_SHIFT: u8 = 9;
pub const SECTOR_SIZE: u64 = (0x01 as u64) << SECTOR_SHIFT;
#[derive(Debug)]
pub enum Error {
/// Guest gave us bad memory addresses.
GuestMemory(GuestMemoryError),
/// Guest gave us offsets that would have overflowed a usize.
CheckedOffset(GuestAddress, usize),
/// Guest gave us a write only descriptor that protocol says to read from.
UnexpectedWriteOnlyDescriptor,
/// Guest gave us a read only descriptor that protocol says to write to.
UnexpectedReadOnlyDescriptor,
/// Guest gave us too few descriptors in a descriptor chain.
DescriptorChainTooShort,
/// Guest gave us a descriptor that was too short to use.
DescriptorLengthTooSmall,
/// Getting a block's metadata fails for any reason.
GetFileMetadata,
/// The requested operation would cause a seek beyond disk end.
InvalidOffset,
/// The requested operation does not support multiple descriptors.
TooManyDescriptors,
}
fn build_device_id(disk_path: &PathBuf) -> result::Result<String, Error> {
let blk_metadata = match disk_path.metadata() {
Err(_) => return Err(Error::GetFileMetadata),
Ok(m) => m,
};
// This is how kvmtool does it.
let device_id = format!(
"{}{}{}",
blk_metadata.st_dev(),
blk_metadata.st_rdev(),
blk_metadata.st_ino()
);
Ok(device_id)
}
pub fn build_disk_image_id(disk_path: &PathBuf) -> Vec<u8> {
let mut default_disk_image_id = vec![0; VIRTIO_BLK_ID_BYTES as usize];
match build_device_id(disk_path) {
Err(_) => {
warn!("Could not generate device id. We'll use a default.");
}
Ok(m) => {
// The kernel only knows to read a maximum of VIRTIO_BLK_ID_BYTES.
// This will also zero out any leftover bytes.
let disk_id = m.as_bytes();
let bytes_to_copy = cmp::min(disk_id.len(), VIRTIO_BLK_ID_BYTES as usize);
default_disk_image_id[..bytes_to_copy].clone_from_slice(&disk_id[..bytes_to_copy])
}
}
default_disk_image_id
}
#[derive(Debug)]
pub enum ExecuteError {
BadRequest(Error),
Flush(io::Error),
Read(GuestMemoryError),
Seek(io::Error),
Write(GuestMemoryError),
Unsupported(u32),
SubmitIoUring(io::Error),
GetHostAddress(GuestMemoryError),
}
impl ExecuteError {
pub fn status(&self) -> u32 {
match *self {
ExecuteError::BadRequest(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Seek(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Write(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Unsupported(_) => VIRTIO_BLK_S_UNSUPP,
ExecuteError::SubmitIoUring(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::GetHostAddress(_) => VIRTIO_BLK_S_IOERR,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum RequestType {
In,
Out,
Flush,
GetDeviceID,
Unsupported(u32),
}
pub fn request_type(
mem: &GuestMemoryMmap,
desc_addr: GuestAddress,
) -> result::Result<RequestType, Error> {
let type_ = mem.read_obj(desc_addr).map_err(Error::GuestMemory)?;
match type_ {
VIRTIO_BLK_T_IN => Ok(RequestType::In),
VIRTIO_BLK_T_OUT => Ok(RequestType::Out),
VIRTIO_BLK_T_FLUSH => Ok(RequestType::Flush),
VIRTIO_BLK_T_GET_ID => Ok(RequestType::GetDeviceID),
t => Ok(RequestType::Unsupported(t)),
}
}
fn sector(mem: &GuestMemoryMmap, desc_addr: GuestAddress) -> result::Result<u64, Error> {
const SECTOR_OFFSET: usize = 8;
let addr = match mem.checked_offset(desc_addr, SECTOR_OFFSET) {
Some(v) => v,
None => return Err(Error::CheckedOffset(desc_addr, SECTOR_OFFSET)),
};
mem.read_obj(addr).map_err(Error::GuestMemory)
}
pub struct Request {
pub request_type: RequestType,
pub sector: u64,
pub data_descriptors: Vec<(GuestAddress, u32)>,
pub status_addr: GuestAddress,
pub writeback: bool,
}
impl Request {
pub fn parse(
avail_desc: &DescriptorChain,
mem: &GuestMemoryMmap,
) -> result::Result<Request, Error> {
// The head contains the request type which MUST be readable.
if avail_desc.is_write_only() {
return Err(Error::UnexpectedWriteOnlyDescriptor);
}
let mut req = Request {
request_type: request_type(&mem, avail_desc.addr)?,
sector: sector(&mem, avail_desc.addr)?,
data_descriptors: Vec::new(),
status_addr: GuestAddress(0),
writeback: true,
};
let status_desc;
let mut desc = avail_desc
.next_descriptor()
.ok_or(Error::DescriptorChainTooShort)?;
if !desc.has_next() {
status_desc = desc;
// Only flush requests are allowed to skip the data descriptor.
if req.request_type != RequestType::Flush {
return Err(Error::DescriptorChainTooShort);
}
} else {
while desc.has_next() {
if desc.is_write_only() && req.request_type == RequestType::Out {
return Err(Error::UnexpectedWriteOnlyDescriptor);
}
if !desc.is_write_only() && req.request_type == RequestType::In {
return Err(Error::UnexpectedReadOnlyDescriptor);
}
if !desc.is_write_only() && req.request_type == RequestType::GetDeviceID {
return Err(Error::UnexpectedReadOnlyDescriptor);
}
req.data_descriptors.push((desc.addr, desc.len));
desc = desc
.next_descriptor()
.ok_or(Error::DescriptorChainTooShort)?;
}
status_desc = desc;
}
// The status MUST always be writable.
if !status_desc.is_write_only() {
return Err(Error::UnexpectedReadOnlyDescriptor);
}
if status_desc.len < 1 {
return Err(Error::DescriptorLengthTooSmall);
}
req.status_addr = status_desc.addr;
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>,
) -> result::Result<u32, ExecuteError> {
disk.seek(SeekFrom::Start(self.sector << SECTOR_SHIFT))
.map_err(ExecuteError::Seek)?;
let mut len = 0;
for (data_addr, data_len) in &self.data_descriptors {
let mut top: u64 = u64::from(*data_len) / SECTOR_SIZE;
if u64::from(*data_len) % SECTOR_SIZE != 0 {
top += 1;
}
top = top
.checked_add(self.sector)
.ok_or(ExecuteError::BadRequest(Error::InvalidOffset))?;
if top > disk_nsectors {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
match self.request_type {
RequestType::In => {
mem.read_exact_from(*data_addr, disk, *data_len as usize)
.map_err(ExecuteError::Read)?;
len += data_len;
}
RequestType::Out => {
mem.write_all_to(*data_addr, disk, *data_len as usize)
.map_err(ExecuteError::Write)?;
if !self.writeback {
disk.flush().map_err(ExecuteError::Flush)?;
}
}
RequestType::Flush => disk.flush().map_err(ExecuteError::Flush)?,
RequestType::GetDeviceID => {
if (*data_len as usize) < disk_id.len() {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
mem.write_slice(&disk_id.as_slice(), *data_addr)
.map_err(ExecuteError::Write)?;
}
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
};
}
Ok(len)
}
#[cfg(feature = "io_uring")]
pub fn execute_io_uring(
&self,
mem: &GuestMemoryMmap,
io_uring: &mut IoUring,
disk_nsectors: u64,
disk_image_fd: RawFd,
disk_id: &[u8],
user_data: u64,
) -> result::Result<bool, ExecuteError> {
let sector = self.sector;
let request_type = self.request_type;
let offset = (sector << SECTOR_SHIFT) as libc::off_t;
let (submitter, sq, _) = io_uring.split();
let mut avail_sq = sq.available();
let mut iovecs = Vec::new();
for (data_addr, data_len) in &self.data_descriptors {
let mut top: u64 = u64::from(*data_len) / SECTOR_SIZE;
if u64::from(*data_len) % SECTOR_SIZE != 0 {
top += 1;
}
top = top
.checked_add(sector)
.ok_or(ExecuteError::BadRequest(Error::InvalidOffset))?;
if top > disk_nsectors {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
let buf = mem
.get_slice(*data_addr, *data_len as usize)
.map_err(ExecuteError::GetHostAddress)?
.as_ptr();
let iovec = libc::iovec {
iov_base: buf as *mut libc::c_void,
iov_len: *data_len as libc::size_t,
};
iovecs.push(iovec);
}
// Queue operations expected to be submitted.
match request_type {
RequestType::In => {
// Safe because we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
avail_sq.push(
opcode::Readv::new(
opcode::types::Fd(disk_image_fd),
iovecs.as_ptr(),
iovecs.len() as u32,
)
.offset(offset)
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
}
RequestType::Out => {
// Safe because we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
avail_sq.push(
opcode::Writev::new(
opcode::types::Fd(disk_image_fd),
iovecs.as_ptr(),
iovecs.len() as u32,
)
.offset(offset)
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
}
RequestType::Flush => {
// Safe because we know the file descriptor is valid.
let _ = unsafe {
avail_sq.push(
opcode::Fsync::new(opcode::types::Fd(disk_image_fd))
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
}
RequestType::GetDeviceID => {
let (data_addr, data_len) = if self.data_descriptors.len() == 1 {
(self.data_descriptors[0].0, self.data_descriptors[0].1)
} else {
return Err(ExecuteError::BadRequest(Error::TooManyDescriptors));
};
if (data_len as usize) < disk_id.len() {
return Err(ExecuteError::BadRequest(Error::InvalidOffset));
}
mem.write_slice(disk_id, data_addr)
.map_err(ExecuteError::Write)?;
return Ok(false);
}
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
}
// Update the submission queue and submit new operations to the
// io_uring instance.
avail_sq.sync();
submitter.submit().map_err(ExecuteError::SubmitIoUring)?;
Ok(true)
}
pub fn set_writeback(&mut self, writeback: bool) {
self.writeback = writeback
}
}
#[derive(Copy, Clone, Debug, Default, Deserialize)]
#[repr(C, packed)]
pub struct VirtioBlockConfig {
pub capacity: u64,
pub size_max: u32,
pub seg_max: u32,
pub geometry: VirtioBlockGeometry,
pub blk_size: u32,
pub physical_block_exp: u8,
pub alignment_offset: u8,
pub min_io_size: u16,
pub opt_io_size: u32,
pub writeback: u8,
pub unused: u8,
pub num_queues: u16,
pub max_discard_sectors: u32,
pub max_discard_seg: u32,
pub discard_sector_alignment: u32,
pub max_write_zeroes_sectors: u32,
pub max_write_zeroes_seg: u32,
pub write_zeroes_may_unmap: u8,
pub unused1: [u8; 3],
}
// We must explicitly implement Serialize since the structure is packed and
// it's unsafe to borrow from a packed structure. And by default, if we derive
// Serialize from serde, it will borrow the values from the structure.
// That's why this implementation copies each field separately before it
// serializes the entire structure field by field.
impl Serialize for VirtioBlockConfig {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let capacity = self.capacity;
let size_max = self.size_max;
let seg_max = self.seg_max;
let geometry = self.geometry;
let blk_size = self.blk_size;
let physical_block_exp = self.physical_block_exp;
let alignment_offset = self.alignment_offset;
let min_io_size = self.min_io_size;
let opt_io_size = self.opt_io_size;
let writeback = self.writeback;
let unused = self.unused;
let num_queues = self.num_queues;
let max_discard_sectors = self.max_discard_sectors;
let max_discard_seg = self.max_discard_seg;
let discard_sector_alignment = self.discard_sector_alignment;
let max_write_zeroes_sectors = self.max_write_zeroes_sectors;
let max_write_zeroes_seg = self.max_write_zeroes_seg;
let write_zeroes_may_unmap = self.write_zeroes_may_unmap;
let unused1 = self.unused1;
let mut virtio_block_config = serializer.serialize_struct("VirtioBlockConfig", 60)?;
virtio_block_config.serialize_field("capacity", &capacity)?;
virtio_block_config.serialize_field("size_max", &size_max)?;
virtio_block_config.serialize_field("seg_max", &seg_max)?;
virtio_block_config.serialize_field("geometry", &geometry)?;
virtio_block_config.serialize_field("blk_size", &blk_size)?;
virtio_block_config.serialize_field("physical_block_exp", &physical_block_exp)?;
virtio_block_config.serialize_field("alignment_offset", &alignment_offset)?;
virtio_block_config.serialize_field("min_io_size", &min_io_size)?;
virtio_block_config.serialize_field("opt_io_size", &opt_io_size)?;
virtio_block_config.serialize_field("writeback", &writeback)?;
virtio_block_config.serialize_field("unused", &unused)?;
virtio_block_config.serialize_field("num_queues", &num_queues)?;
virtio_block_config.serialize_field("max_discard_sectors", &max_discard_sectors)?;
virtio_block_config.serialize_field("max_discard_seg", &max_discard_seg)?;
virtio_block_config
.serialize_field("discard_sector_alignment", &discard_sector_alignment)?;
virtio_block_config
.serialize_field("max_write_zeroes_sectors", &max_write_zeroes_sectors)?;
virtio_block_config.serialize_field("max_write_zeroes_seg", &max_write_zeroes_seg)?;
virtio_block_config.serialize_field("write_zeroes_may_unmap", &write_zeroes_may_unmap)?;
virtio_block_config.serialize_field("unused1", &unused1)?;
virtio_block_config.end()
}
}
unsafe impl ByteValued for VirtioBlockConfig {}
#[derive(Copy, Clone, Debug, Default, Deserialize)]
#[repr(C, packed)]
pub struct VirtioBlockGeometry {
pub cylinders: u16,
pub heads: u8,
pub sectors: u8,
}
// We must explicitly implement Serialize since the structure is packed and
// it's unsafe to borrow from a packed structure. And by default, if we derive
// Serialize from serde, it will borrow the values from the structure.
// That's why this implementation copies each field separately before it
// serializes the entire structure field by field.
impl Serialize for VirtioBlockGeometry {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let cylinders = self.cylinders;
let heads = self.heads;
let sectors = self.sectors;
let mut virtio_block_geometry = serializer.serialize_struct("VirtioBlockGeometry", 4)?;
virtio_block_geometry.serialize_field("cylinders", &cylinders)?;
virtio_block_geometry.serialize_field("heads", &heads)?;
virtio_block_geometry.serialize_field("sectors", &sectors)?;
virtio_block_geometry.end()
}
}
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:";
// Check we can create an io_uring instance, which effectively verifies
// that io_uring_setup() syscall is supported.
let io_uring = match IoUring::new(1) {
Ok(io_uring) => io_uring,
Err(e) => {
info!("{} failed to create io_uring instance: {}", error_msg, e);
return false;
}
};
let submitter = io_uring.submitter();
let event_fd = match EventFd::new(libc::EFD_NONBLOCK) {
Ok(fd) => fd,
Err(e) => {
info!("{} failed to create eventfd: {}", error_msg, e);
return false;
}
};
// Check we can register an eventfd as this is going to be needed while
// using io_uring with the virtio block device. This also validates that
// io_uring_register() syscall is supported.
match submitter.register_eventfd(event_fd.as_raw_fd()) {
Ok(_) => {}
Err(e) => {
info!("{} failed to register eventfd: {}", error_msg, e);
return false;
}
}
let mut probe = Probe::new();
// Check we can register a probe to validate supported operations.
match submitter.register_probe(&mut probe) {
Ok(_) => {}
Err(e) => {
info!("{} failed to register a probe: {}", error_msg, e);
return false;
}
}
// Check IORING_OP_FSYNC is supported
if !probe.is_supported(opcode::Fsync::CODE) {
info!("{} IORING_OP_FSYNC operation not supported", error_msg);
return false;
}
// Check IORING_OP_READ is supported
if !probe.is_supported(opcode::Read::CODE) {
info!("{} IORING_OP_READ operation not supported", error_msg);
return false;
}
// Check IORING_OP_WRITE is supported
if !probe.is_supported(opcode::Write::CODE) {
info!("{} IORING_OP_WRITE operation not supported", error_msg);
return false;
}
true
}

27
build.rs Normal file
View File

@@ -0,0 +1,27 @@
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use(crate_version)]
extern crate clap;
use std::process::Command;
fn main() {
let mut version = crate_version!().to_string();
if let Ok(git_out) = Command::new("git").args(&["describe", "--dirty"]).output() {
if git_out.status.success() {
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
version = git_out_str;
}
}
}
// This println!() has a special behavior, as it will set the environment
// variable BUILT_VERSION, so that it can be reused from the binary.
// Particularly, this is used from src/main.rs to display the exact
// version.
println!("cargo:rustc-env=BUILT_VERSION={}", version);
}

View File

@@ -4,18 +4,26 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
byteorder = "1.3.2"
epoll = "4.1.0"
kvm-bindings = "0.1.1"
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "master" }
libc = "0.2.60"
log = "0.4.8"
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
vmm-sys-util = { git = "https://github.com/rust-vmm/vmm-sys-util" }
anyhow = "1.0"
bitflags = ">=1.2.1"
byteorder = "1.3.4"
epoll = ">=4.0.1"
libc = "0.2.77"
log = "0.4.11"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vm-device = { path = "../vm-device" }
acpi_tables = { path = "../acpi_tables", optional = true }
vm-memory = "0.2.1"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = ">=0.3.1"
[dev-dependencies]
tempfile = "3.1.0"
[features]
default = ["acpi"]
acpi = []
default = []
acpi = ["acpi_tables"]
cmos = []
fwdebug = []

View File

@@ -3,8 +3,13 @@
// SPDX-License-Identifier: Apache-2.0
//
use acpi_tables::{aml, aml::Aml};
use std::sync::Arc;
use std::time::Instant;
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vmm_sys_util::eventfd::EventFd;
use BusDevice;
use HotPlugNotificationFlags;
/// A device for handling ACPI shutdown and reboot
pub struct AcpiShutdownDevice {
@@ -44,9 +49,140 @@ impl BusDevice for AcpiShutdownDevice {
const SLEEP_VALUE_BIT: u8 = 2;
if data[0] == (S5_SLEEP_VALUE << SLEEP_VALUE_BIT) | (1 << SLEEP_STATUS_EN_BIT) {
debug!("ACPI Shutdown signalled");
extern crate bitflags;
if let Err(e) = self.exit_evt.write(1) {
error!("Error triggering ACPI shutdown event: {}", e);
}
}
}
}
/// A device for handling ACPI GED event generation
pub struct AcpiGEDDevice {
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
notification_type: HotPlugNotificationFlags,
ged_irq: u32,
}
impl AcpiGEDDevice {
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>, ged_irq: u32) -> AcpiGEDDevice {
AcpiGEDDevice {
interrupt,
notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED,
ged_irq,
}
}
pub fn notify(
&mut self,
notification_type: HotPlugNotificationFlags,
) -> Result<(), std::io::Error> {
self.notification_type |= notification_type;
self.interrupt.trigger(0)
}
pub fn irq(&self) -> u32 {
self.ged_irq
}
}
// I/O port reports what type of notification was made
impl BusDevice for AcpiGEDDevice {
// Spec has all fields as zero
fn read(&mut self, _base: u64, _offset: u64, data: &mut [u8]) {
data[0] = self.notification_type.bits();
self.notification_type = HotPlugNotificationFlags::NO_DEVICES_CHANGED;
}
fn write(&mut self, _base: u64, _offset: u64, _data: &[u8]) {}
}
#[cfg(feature = "acpi")]
impl Aml for AcpiGEDDevice {
fn to_aml_bytes(&self) -> Vec<u8> {
aml::Device::new(
"_SB_.GED_".into(),
vec![
&aml::Name::new("_HID".into(), &"ACPI0013"),
&aml::Name::new("_UID".into(), &aml::ZERO),
&aml::Name::new(
"_CRS".into(),
&aml::ResourceTemplate::new(vec![&aml::Interrupt::new(
true,
true,
false,
false,
self.ged_irq,
)]),
),
&aml::OpRegion::new("GDST".into(), aml::OpRegionSpace::SystemIO, 0xb000, 0x1),
&aml::Field::new(
"GDST".into(),
aml::FieldAccessType::Byte,
aml::FieldUpdateRule::WriteAsZeroes,
vec![aml::FieldEntry::Named(*b"GDAT", 8)],
),
&aml::Method::new(
"_EVT".into(),
1,
true,
vec![
&aml::Store::new(&aml::Local(0), &aml::Path::new("GDAT")),
&aml::And::new(&aml::Local(1), &aml::Local(0), &aml::ONE),
&aml::If::new(
&aml::Equal::new(&aml::Local(1), &aml::ONE),
vec![&aml::MethodCall::new("\\_SB_.CPUS.CSCN".into(), vec![])],
),
&aml::And::new(&aml::Local(1), &aml::Local(0), &2usize),
&aml::If::new(
&aml::Equal::new(&aml::Local(1), &2usize),
vec![&aml::MethodCall::new("\\_SB_.MHPC.MSCN".into(), vec![])],
),
&aml::And::new(&aml::Local(1), &aml::Local(0), &4usize),
&aml::If::new(
&aml::Equal::new(&aml::Local(1), &4usize),
vec![&aml::MethodCall::new("\\_SB_.PCI0.PCNT".into(), vec![])],
),
],
),
],
)
.to_aml_bytes()
}
}
pub struct AcpiPMTimerDevice {
start: Instant,
}
impl AcpiPMTimerDevice {
pub fn new() -> Self {
Self {
start: Instant::now(),
}
}
}
impl Default for AcpiPMTimerDevice {
fn default() -> Self {
Self::new()
}
}
impl BusDevice for AcpiPMTimerDevice {
fn read(&mut self, _base: u64, _offset: u64, data: &mut [u8]) {
let now = Instant::now();
let since = now.duration_since(self.start);
let nanos = since.as_nanos();
const PM_TIMER_FREQUENCY_HZ: u128 = 3_579_545;
const NANOS_PER_SECOND: u128 = 1_000_000_000;
let counter = (nanos * PM_TIMER_FREQUENCY_HZ) / NANOS_PER_SECOND;
let counter: u32 = (counter & 0xffff_ffff) as u32;
data.copy_from_slice(&counter.to_le_bytes());
}
fn write(&mut self, _base: u64, _offset: u64, _data: &[u8]) {}
}

84
devices/src/gic.rs Normal file
View File

@@ -0,0 +1,84 @@
// Copyright 2020, ARM Limited.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use super::interrupt_controller::{Error, InterruptController};
use std::result;
use std::sync::Arc;
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig,
};
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
type Result<T> = result::Result<T, Error>;
// Reserve 32 IRQs (GSI 32 ~ 64) for legacy device.
// GsiAllocator should allocate beyond this: from 64 on
pub const IRQ_LEGACY_COUNT: usize = 32;
pub const IRQ_SPI_OFFSET: usize = 32;
// This Gic struct implements InterruptController to provide interrupt delivery service.
// The Gic source files in arch/ folder maintain the Aarch64 specific Gic device.
// The 2 Gic instances could be merged together.
// Leave this refactoring to future. Two options may be considered:
// 1. Move Gic*.rs from arch/ folder here.
// 2. Move this file and ioapic.rs to arch/, as they are architecture specific.
pub struct Gic {
interrupt_source_group: Arc<Box<dyn InterruptSourceGroup>>,
}
impl Gic {
pub fn new(
_vcpu_count: u8,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
) -> Result<Gic> {
let interrupt_source_group = interrupt_manager
.create_group(MsiIrqGroupConfig {
base: IRQ_SPI_OFFSET as InterruptIndex,
count: IRQ_LEGACY_COUNT as InterruptIndex,
})
.map_err(Error::CreateInterruptSourceGroup)?;
Ok(Gic {
interrupt_source_group,
})
}
}
impl InterruptController for Gic {
fn enable(&self) -> Result<()> {
self.interrupt_source_group
.enable()
.map_err(Error::EnableInterrupt)?;
Ok(())
}
// This should be called anytime an interrupt needs to be injected into the
// running guest.
fn service_irq(&mut self, irq: usize) -> Result<()> {
self.interrupt_source_group
.trigger(irq as InterruptIndex)
.map_err(Error::TriggerInterrupt)?;
Ok(())
}
}
const GIC_SNAPSHOT_ID: &str = "gic";
impl Snapshottable for Gic {
fn id(&self) -> String {
GIC_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
unimplemented!();
}
fn restore(&mut self, _snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
unimplemented!();
}
}
impl Pausable for Gic {}
impl Transportable for Gic {}
impl Migratable for Gic {}

View File

@@ -0,0 +1,61 @@
// Copyright 2020, ARM Limited.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::io;
use std::result;
#[derive(Debug)]
pub enum Error {
/// Invalid destination mode.
InvalidDestinationMode,
/// Invalid trigger mode.
InvalidTriggerMode,
/// Invalid delivery mode.
InvalidDeliveryMode,
/// Failed creating the interrupt source group.
CreateInterruptSourceGroup(io::Error),
/// Failed triggering the interrupt.
TriggerInterrupt(io::Error),
/// Failed masking the interrupt.
MaskInterrupt(io::Error),
/// Failed unmasking the interrupt.
UnmaskInterrupt(io::Error),
/// Failed updating the interrupt.
UpdateInterrupt(io::Error),
/// Failed enabling the interrupt.
EnableInterrupt(io::Error),
}
type Result<T> = result::Result<T, Error>;
pub struct MsiMessage {
// Message Address Register
// 31-20: Base address. Fixed value (0x0FEE)
// 19-12: Destination ID
// 11-4: Reserved
// 3: Redirection Hint indication
// 2: Destination Mode
// 1-0: Reserved
pub addr: u32,
// Message Data Register
// 32-16: Reserved
// 15: Trigger Mode. 0 = Edge, 1 = Level
// 14: Level. 0 = Deassert, 1 = Assert
// 13-11: Reserved
// 10-8: Delivery Mode
// 7-0: Vector
pub data: u32,
}
// Introduce trait InterruptController to uniform the interrupt
// service provided for devices.
// Device manager uses this trait without caring whether it is a
// IOAPIC (X86) or GIC (Arm).
pub trait InterruptController: Send {
fn service_irq(&mut self, irq: usize) -> Result<()>;
#[cfg(target_arch = "aarch64")]
fn enable(&self) -> Result<()>;
#[cfg(target_arch = "x86_64")]
fn end_of_interrupt(&mut self, vec: u8);
}

View File

@@ -9,24 +9,25 @@
// Implementation of an intel 82093AA Input/Output Advanced Programmable Interrupt Controller
// See https://pdos.csail.mit.edu/6.828/2016/readings/ia32/ioapic.pdf for a specification.
use crate::BusDevice;
use super::interrupt_controller::{Error, InterruptController};
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
use kvm_bindings::kvm_msi;
use kvm_ioctls::VmFd;
use std::result;
use std::sync::Arc;
use std::{io, result};
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup,
MsiIrqGroupConfig, MsiIrqSourceConfig,
};
use vm_device::BusDevice;
use vm_memory::GuestAddress;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
#[derive(Debug)]
pub enum Error {
/// Failed to send an interrupt.
InterruptFailed(io::Error),
/// Invalid destination mode.
InvalidDestinationMode,
/// Invalid trigger mode.
InvalidTriggerMode,
/// Invalid delivery mode.
InvalidDeliveryMode,
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "GuestAddress")]
pub struct GuestAddressDef(pub u64);
type Result<T> = result::Result<T, Error>;
@@ -85,25 +86,6 @@ fn set_remote_irr(entry: &mut RedirectionTableEntry, val: u8) {
*entry |= u64::from(val & 0x1) << 14;
}
pub struct MsiMessage {
// Message Address Register
// 31-20: Base address. Fixed value (0x0FEE)
// 19-12: Destination ID
// 11-4: Reserved
// 3: Redirection Hint indication
// 2: Destination Mode
// 1-0: Reserved
pub addr: u32,
// Message Data Register
// 32-16: Reserved
// 15: Trigger Mode. 0 = Edge, 1 = Level
// 14: Level. 0 = Deassert, 1 = Assert
// 13-11: Reserved
// 10-8: Delivery Mode
// 7-0: Vector
pub data: u32,
}
pub const NUM_IOAPIC_PINS: usize = 24;
const IOAPIC_VERSION_ID: u32 = 0x0017_0011;
@@ -152,10 +134,23 @@ fn decode_irq_from_selector(selector: u8) -> (usize, bool) {
}
pub struct Ioapic {
id: u32,
id: String,
id_reg: u32,
reg_sel: u32,
reg_entries: [RedirectionTableEntry; NUM_IOAPIC_PINS],
vm_fd: Arc<VmFd>,
used_entries: [bool; NUM_IOAPIC_PINS],
apic_address: GuestAddress,
interrupt_source_group: Arc<Box<dyn InterruptSourceGroup>>,
}
#[derive(Serialize, Deserialize)]
pub struct IoapicState {
id_reg: u32,
reg_sel: u32,
reg_entries: [RedirectionTableEntry; NUM_IOAPIC_PINS],
used_entries: [bool; NUM_IOAPIC_PINS],
#[serde(with = "GuestAddressDef")]
apic_address: GuestAddress,
}
impl BusDevice for Ioapic {
@@ -194,117 +189,38 @@ impl BusDevice for Ioapic {
}
impl Ioapic {
pub fn new(vm_fd: Arc<VmFd>) -> Ioapic {
Ioapic {
id: 0,
pub fn new(
id: String,
apic_address: GuestAddress,
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
) -> Result<Ioapic> {
let interrupt_source_group = interrupt_manager
.create_group(MsiIrqGroupConfig {
base: 0 as InterruptIndex,
count: NUM_IOAPIC_PINS as InterruptIndex,
})
.map_err(Error::CreateInterruptSourceGroup)?;
interrupt_source_group
.enable()
.map_err(Error::EnableInterrupt)?;
Ok(Ioapic {
id,
id_reg: 0,
reg_sel: 0,
reg_entries: [0; NUM_IOAPIC_PINS],
vm_fd,
}
}
// The ioapic must be informed about EOIs in order to deassert interrupts
// already sent.
pub fn end_of_interrupt(&mut self, vec: u8) {
for i in 0..NUM_IOAPIC_PINS {
let entry = &mut self.reg_entries[i];
// Clear Remote IRR bit
if vector(*entry) == vec && trigger_mode(*entry) == 1 {
set_remote_irr(entry, 0);
}
}
}
// This should be called anytime an interrupt needs to be injected into the
// running guest.
pub fn service_irq(&mut self, irq: usize) -> Result<()> {
let entry = &mut self.reg_entries[irq];
// Don't inject the interrupt if the IRQ is masked
if interrupt_mask(*entry) == 1 {
return Ok(());
}
// Validate Destination Mode value, and retrieve Destination ID
let destination_mode = destination_mode(*entry);
let destination_id: u8 = match destination_mode {
x if x == DestinationMode::Physical as u8 => destination_field_physical(*entry),
x if x == DestinationMode::Logical as u8 => destination_field_logical(*entry),
_ => return Err(Error::InvalidDestinationMode),
};
// When this bit is set, the message is directed to the processor with
// the lowest interrupt priority among processors that can receive the
// interrupt.
let redirection_hint: u8 = 1;
// Generate MSI message address
let address_lo: u32 = 0xfee0_0000
| u32::from(destination_id) << 12
| u32::from(redirection_hint) << 3
| u32::from(destination_mode) << 2;
// Validate Trigger Mode value
let trigger_mode = trigger_mode(*entry);
match trigger_mode {
x if (x == TriggerMode::Edge as u8) || (x == TriggerMode::Level as u8) => {}
_ => return Err(Error::InvalidTriggerMode),
}
// Validate Delivery Mode value
let delivery_mode = delivery_mode(*entry);
match delivery_mode {
x if (x == DeliveryMode::Fixed as u8)
|| (x == DeliveryMode::Lowest as u8)
|| (x == DeliveryMode::SMI as u8)
|| (x == DeliveryMode::RemoteRead as u8)
|| (x == DeliveryMode::NMI as u8)
|| (x == DeliveryMode::Init as u8)
|| (x == DeliveryMode::Startup as u8)
|| (x == DeliveryMode::External as u8) => {}
_ => return Err(Error::InvalidDeliveryMode),
}
// Generate MSI message data
let data: u32 = u32::from(trigger_mode) << 15
| u32::from(remote_irr(*entry)) << 14
| u32::from(delivery_mode) << 8
| u32::from(vector(*entry));
let msi = kvm_msi {
address_lo,
address_hi: 0x0,
data,
flags: 0u32,
devid: 0u32,
pad: [0u8; 12],
};
match self.vm_fd.signal_msi(msi) {
Ok(ret) => {
if ret > 0 {
debug!("MSI message successfully delivered");
// If trigger mode is level sensitive, set the Remote IRR bit.
// It will be cleared when the EOI is received.
if trigger_mode == 1 {
set_remote_irr(entry, 1);
}
// Clear the Delivery Status bit
set_delivery_status(entry, 0);
} else {
warn!("failed to deliver MSI message, blocked by guest");
}
Ok(())
}
Err(e) => Err(Error::InterruptFailed(e)),
}
used_entries: [false; NUM_IOAPIC_PINS],
apic_address,
interrupt_source_group,
})
}
fn ioapic_write(&mut self, val: u32) {
debug!("IOAPIC_W reg 0x{:x}, val 0x{:x}", self.reg_sel, val);
match self.reg_sel as u8 {
IOAPIC_REG_ID => self.id = (val >> 24) & 0xf,
IOAPIC_REG_ID => self.id_reg = (val >> 24) & 0xf,
IOWIN_OFF..=REG_MAX_OFFSET => {
let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8);
if is_high_bits {
@@ -317,6 +233,13 @@ impl Ioapic {
self.reg_entries[index] &= 0xffff_ffff_0000_5000;
self.reg_entries[index] |= u64::from(val) & 0xffff_afff;
}
// The entry must be updated through the interrupt source
// group.
if let Err(e) = self.update_entry(index) {
error!("Failed updating IOAPIC entry: {:?}", e);
}
// Store the information this IRQ is now being used.
self.used_entries[index] = true;
}
_ => error!("IOAPIC: invalid write to register offset"),
}
@@ -327,7 +250,7 @@ impl Ioapic {
match self.reg_sel as u8 {
IOAPIC_REG_VERSION => IOAPIC_VERSION_ID,
IOAPIC_REG_ID | IOAPIC_REG_ARBITRATION_ID => (self.id & 0xf) << 24,
IOAPIC_REG_ID | IOAPIC_REG_ARBITRATION_ID => (self.id_reg & 0xf) << 24,
IOWIN_OFF..=REG_MAX_OFFSET => {
let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8);
if is_high_bits {
@@ -342,4 +265,182 @@ impl Ioapic {
}
}
}
fn state(&self) -> IoapicState {
IoapicState {
id_reg: self.id_reg,
reg_sel: self.reg_sel,
reg_entries: self.reg_entries,
used_entries: self.used_entries,
apic_address: self.apic_address,
}
}
fn set_state(&mut self, state: &IoapicState) -> Result<()> {
self.id_reg = state.id_reg;
self.reg_sel = state.reg_sel;
self.reg_entries = state.reg_entries;
self.used_entries = state.used_entries;
self.apic_address = state.apic_address;
for (irq, entry) in self.used_entries.iter().enumerate() {
if *entry {
self.update_entry(irq)?;
}
}
Ok(())
}
fn update_entry(&self, irq: usize) -> Result<()> {
let entry = self.reg_entries[irq];
// Validate Destination Mode value, and retrieve Destination ID
let destination_mode = destination_mode(entry);
let destination_id: u8 = match destination_mode {
x if x == DestinationMode::Physical as u8 => destination_field_physical(entry),
x if x == DestinationMode::Logical as u8 => destination_field_logical(entry),
_ => return Err(Error::InvalidDestinationMode),
};
// When this bit is set, the message is directed to the processor with
// the lowest interrupt priority among processors that can receive the
// interrupt.
let redirection_hint: u8 = 1;
// Generate MSI message address
let low_addr: u32 = self.apic_address.0 as u32
| u32::from(destination_id) << 12
| u32::from(redirection_hint) << 3
| u32::from(destination_mode) << 2;
// Validate Trigger Mode value
let trigger_mode = trigger_mode(entry);
match trigger_mode {
x if (x == TriggerMode::Edge as u8) || (x == TriggerMode::Level as u8) => {}
_ => return Err(Error::InvalidTriggerMode),
}
// Validate Delivery Mode value
let delivery_mode = delivery_mode(entry);
match delivery_mode {
x if (x == DeliveryMode::Fixed as u8)
|| (x == DeliveryMode::Lowest as u8)
|| (x == DeliveryMode::SMI as u8)
|| (x == DeliveryMode::RemoteRead as u8)
|| (x == DeliveryMode::NMI as u8)
|| (x == DeliveryMode::Init as u8)
|| (x == DeliveryMode::Startup as u8)
|| (x == DeliveryMode::External as u8) => {}
_ => return Err(Error::InvalidDeliveryMode),
}
// Generate MSI message data
let data: u32 = u32::from(trigger_mode) << 15
| u32::from(remote_irr(entry)) << 14
| u32::from(delivery_mode) << 8
| u32::from(vector(entry));
let config = MsiIrqSourceConfig {
high_addr: 0x0,
low_addr,
data,
devid: 0,
};
self.interrupt_source_group
.update(irq as InterruptIndex, InterruptSourceConfig::MsiIrq(config))
.map_err(Error::UpdateInterrupt)?;
if interrupt_mask(entry) == 1 {
self.interrupt_source_group
.mask(irq as InterruptIndex)
.map_err(Error::MaskInterrupt)?;
} else {
self.interrupt_source_group
.unmask(irq as InterruptIndex)
.map_err(Error::UnmaskInterrupt)?;
}
Ok(())
}
}
impl InterruptController for Ioapic {
// The ioapic must be informed about EOIs in order to deassert interrupts
// already sent.
fn end_of_interrupt(&mut self, vec: u8) {
for i in 0..NUM_IOAPIC_PINS {
let entry = &mut self.reg_entries[i];
// Clear Remote IRR bit
if vector(*entry) == vec && trigger_mode(*entry) == 1 {
set_remote_irr(entry, 0);
}
}
}
// This should be called anytime an interrupt needs to be injected into the
// running guest.
fn service_irq(&mut self, irq: usize) -> Result<()> {
let entry = &mut self.reg_entries[irq];
self.interrupt_source_group
.trigger(irq as InterruptIndex)
.map_err(Error::TriggerInterrupt)?;
debug!("Interrupt successfully delivered");
// If trigger mode is level sensitive, set the Remote IRR bit.
// It will be cleared when the EOI is received.
if trigger_mode(*entry) == 1 {
set_remote_irr(entry, 1);
}
// Clear the Delivery Status bit
set_delivery_status(entry, 0);
Ok(())
}
}
impl Snapshottable for Ioapic {
fn id(&self) -> String {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let snapshot =
serde_json::to_vec(&self.state()).map_err(|e| MigratableError::Snapshot(e.into()))?;
let mut ioapic_snapshot = Snapshot::new(self.id.as_str());
ioapic_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id),
snapshot,
});
Ok(ioapic_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(ioapic_section) = snapshot.snapshot_data.get(&format!("{}-section", self.id)) {
let ioapic_state = match serde_json::from_slice(&ioapic_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize IOAPIC {}",
error
)))
}
};
return self.set_state(&ioapic_state).map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore IOAPIC state {:?}", e))
});
}
Err(MigratableError::Restore(anyhow!(
"Could not find IOAPIC snapshot section"
)))
}
}
impl Pausable for Ioapic {}
impl Transportable for Ioapic {}
impl Migratable for Ioapic {}

124
devices/src/legacy/cmos.rs Normal file
View File

@@ -0,0 +1,124 @@
// 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 file.
use libc::{clock_gettime, gmtime_r, time_t, timespec, tm, CLOCK_REALTIME};
use std::cmp::min;
use std::mem;
use vm_device::BusDevice;
const INDEX_MASK: u8 = 0x7f;
const INDEX_OFFSET: u64 = 0x0;
const DATA_OFFSET: u64 = 0x1;
const DATA_LEN: usize = 128;
/// A CMOS/RTC device commonly seen on x86 I/O port 0x70/0x71.
pub struct Cmos {
index: u8,
data: [u8; DATA_LEN],
}
impl Cmos {
/// Constructs a CMOS/RTC device with initial data.
/// `mem_below_4g` is the size of memory in bytes below the 32-bit gap.
/// `mem_above_4g` is the size of memory in bytes above the 32-bit gap.
pub fn new(mem_below_4g: u64, mem_above_4g: u64) -> Cmos {
let mut data = [0u8; DATA_LEN];
// Extended memory from 16 MB to 4 GB in units of 64 KB
let ext_mem = min(
0xFFFF,
mem_below_4g.saturating_sub(16 * 1024 * 1024) / (64 * 1024),
);
data[0x34] = ext_mem as u8;
data[0x35] = (ext_mem >> 8) as u8;
// High memory (> 4GB) in units of 64 KB
let high_mem = min(0x00FF_FFFF, mem_above_4g / (64 * 1024));
data[0x5b] = high_mem as u8;
data[0x5c] = (high_mem >> 8) as u8;
data[0x5d] = (high_mem >> 16) as u8;
Cmos { index: 0, data }
}
}
impl BusDevice for Cmos {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
if data.len() != 1 {
return;
}
match offset {
INDEX_OFFSET => self.index = data[0] & INDEX_MASK,
DATA_OFFSET => self.data[self.index as usize] = data[0],
o => panic!("bad write offset on CMOS device: {}", o),
}
}
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
fn to_bcd(v: u8) -> u8 {
assert!(v < 100);
((v / 10) << 4) | (v % 10)
}
if data.len() != 1 {
return;
}
data[0] = match offset {
INDEX_OFFSET => self.index,
DATA_OFFSET => {
let seconds;
let minutes;
let hours;
let week_day;
let day;
let month;
let year;
// The clock_gettime and gmtime_r calls are safe as long as the structs they are
// given are large enough, and neither of them fail. It is safe to zero initialize
// the tm and timespec struct because it contains only plain data.
let update_in_progress = unsafe {
let mut timespec: timespec = mem::zeroed();
clock_gettime(CLOCK_REALTIME, &mut timespec as *mut _);
let now: time_t = timespec.tv_sec;
let mut tm: tm = mem::zeroed();
gmtime_r(&now, &mut tm as *mut _);
// The following lines of code are safe but depend on tm being in scope.
seconds = tm.tm_sec;
minutes = tm.tm_min;
hours = tm.tm_hour;
week_day = tm.tm_wday + 1;
day = tm.tm_mday;
month = tm.tm_mon + 1;
year = tm.tm_year;
// Update in Progress bit held for last 224us of each second
const NANOSECONDS_PER_SECOND: i64 = 1_000_000_000;
const UIP_HOLD_LENGTH: i64 = 8 * NANOSECONDS_PER_SECOND / 32768;
timespec.tv_nsec >= (NANOSECONDS_PER_SECOND - UIP_HOLD_LENGTH)
};
match self.index {
0x00 => to_bcd(seconds as u8),
0x02 => to_bcd(minutes as u8),
0x04 => to_bcd(hours as u8),
0x06 => to_bcd(week_day as u8),
0x07 => to_bcd(day as u8),
0x08 => to_bcd(month as u8),
0x09 => to_bcd((year % 100) as u8),
// Bit 5 for 32kHz clock. Bit 7 for Update in Progress
0x0a => 1 << 5 | (update_in_progress as u8) << 7,
0x32 => to_bcd(((year + 1900) / 100) as u8),
_ => {
// self.index is always guaranteed to be in range via INDEX_MASK.
self.data[(self.index & INDEX_MASK) as usize]
}
}
}
o => panic!("bad read offset on CMOS device: {}", o),
}
}
}

View File

@@ -0,0 +1,40 @@
// 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 © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//
use vm_device::BusDevice;
/// Provides firmware debug output via I/O port controls
#[derive(Default)]
pub struct FwDebugDevice {}
impl FwDebugDevice {
pub fn new() -> Self {
Self {}
}
}
/// FwDebugDevice sits on the I/O bus as 0x402 and receives ASCII characters
impl BusDevice for FwDebugDevice {
/// Upon read return the magic value to indicate that there is a debug port
fn read(&mut self, _base: u64, _offset: u64, data: &mut [u8]) {
if data.len() == 1 {
data[0] = 0xe9
} else {
error!("Invalid read size on debug port: {}", data.len())
}
}
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) {
if data.len() == 1 {
print!("{}", data[0] as char);
} else {
error!("Invalid write size on debug port: {}", data.len())
}
}
}

View File

@@ -4,7 +4,7 @@
use vmm_sys_util::eventfd::EventFd;
use BusDevice;
use vm_device::BusDevice;
/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
pub struct I8042Device {

View File

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

View File

@@ -0,0 +1,625 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//! ARM PL031 Real Time Clock
//!
//! This module implements a PL031 Real Time Clock (RTC) that provides to provides long time base counter.
//! This is achieved by generating an interrupt signal after counting for a programmed number of cycles of
//! a real-time clock input.
//!
use std::fmt;
use std::sync::Arc;
use std::time::Instant;
use std::{io, result};
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
// As you can see in https://static.docs.arm.com/ddi0224/c/real_time_clock_pl031_r1p3_technical_reference_manual_DDI0224C.pdf
// at section 3.2 Summary of RTC registers, the total size occupied by this device is 0x000 -> 0xFFC + 4 = 0x1000.
// From 0x0 to 0x1C we have following registers:
const RTCDR: u64 = 0x0; // Data Register.
const RTCMR: u64 = 0x4; // Match Register.
const RTCLR: u64 = 0x8; // Load Regiser.
const RTCCR: u64 = 0xc; // Control Register.
const RTCIMSC: u64 = 0x10; // Interrupt Mask Set or Clear Register.
const RTCRIS: u64 = 0x14; // Raw Interrupt Status.
const RTCMIS: u64 = 0x18; // Masked Interrupt Status.
const RTCICR: u64 = 0x1c; // Interrupt Clear Register.
// From 0x020 to 0xFDC => reserved space.
// From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity
// of these devices (i.e look at the `amba_device_try_add` function).
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
const PL031_ID: [u8; 8] = [0x31, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
// We are only interested in the margins.
const AMBA_ID_LOW: u64 = 0xFE0;
const AMBA_ID_HIGH: u64 = 0x1000;
/// Constant to convert seconds to nanoseconds.
pub const NANOS_PER_SECOND: u64 = 1_000_000_000;
#[allow(unused_macros)]
macro_rules! generate_read_fn {
($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => {
#[allow(dead_code)]
pub fn $fn_name(input: &[$byte_type]) -> $data_type {
assert!($type_size == std::mem::size_of::<$data_type>());
let mut array = [0u8; $type_size];
for (byte, read) in array.iter_mut().zip(input.iter().cloned()) {
*byte = read as u8;
}
<$data_type>::$endian_type(array)
}
};
}
#[allow(unused_macros)]
macro_rules! generate_write_fn {
($fn_name: ident, $data_type: ty, $byte_type: ty, $endian_type: ident) => {
#[allow(dead_code)]
pub fn $fn_name(buf: &mut [$byte_type], n: $data_type) {
for (byte, read) in buf
.iter_mut()
.zip(<$data_type>::$endian_type(n).iter().cloned())
{
*byte = read as $byte_type;
}
}
};
}
generate_read_fn!(read_le_u16, u16, u8, 2, from_le_bytes);
generate_read_fn!(read_le_u32, u32, u8, 4, from_le_bytes);
generate_read_fn!(read_le_u64, u64, u8, 8, from_le_bytes);
generate_read_fn!(read_le_i32, i32, i8, 4, from_le_bytes);
generate_read_fn!(read_be_u16, u16, u8, 2, from_be_bytes);
generate_read_fn!(read_be_u32, u32, u8, 4, from_be_bytes);
generate_write_fn!(write_le_u16, u16, u8, to_le_bytes);
generate_write_fn!(write_le_u32, u32, u8, to_le_bytes);
generate_write_fn!(write_le_u64, u64, u8, to_le_bytes);
generate_write_fn!(write_le_i32, i32, i8, to_le_bytes);
generate_write_fn!(write_be_u16, u16, u8, to_be_bytes);
generate_write_fn!(write_be_u32, u32, u8, to_be_bytes);
#[derive(Debug)]
pub enum Error {
BadWriteOffset(u64),
InterruptFailure(io::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
}
}
}
type Result<T> = result::Result<T, Error>;
/// Wrapper over `libc::clockid_t` to specify Linux Kernel clock source.
pub enum ClockType {
/// Equivalent to `libc::CLOCK_MONOTONIC`.
Monotonic,
/// Equivalent to `libc::CLOCK_REALTIME`.
#[allow(dead_code)]
Real,
/// Equivalent to `libc::CLOCK_PROCESS_CPUTIME_ID`.
ProcessCpu,
/// Equivalent to `libc::CLOCK_THREAD_CPUTIME_ID`.
#[allow(dead_code)]
ThreadCpu,
}
impl Into<libc::clockid_t> for ClockType {
fn into(self) -> libc::clockid_t {
match self {
ClockType::Monotonic => libc::CLOCK_MONOTONIC,
ClockType::Real => libc::CLOCK_REALTIME,
ClockType::ProcessCpu => libc::CLOCK_PROCESS_CPUTIME_ID,
ClockType::ThreadCpu => libc::CLOCK_THREAD_CPUTIME_ID,
}
}
}
/// Structure representing the date in local time with nanosecond precision.
pub struct LocalTime {
/// Seconds in current minute.
sec: i32,
/// Minutes in current hour.
min: i32,
/// Hours in current day, 24H format.
hour: i32,
/// Days in current month.
mday: i32,
/// Months in current year.
mon: i32,
/// Years passed since 1900 BC.
year: i32,
/// Nanoseconds in current second.
nsec: i64,
}
impl LocalTime {
/// Returns the [LocalTime](struct.LocalTime.html) structure for the calling moment.
#[allow(dead_code)]
pub fn now() -> LocalTime {
let mut timespec = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
let mut tm: libc::tm = libc::tm {
tm_sec: 0,
tm_min: 0,
tm_hour: 0,
tm_mday: 0,
tm_mon: 0,
tm_year: 0,
tm_wday: 0,
tm_yday: 0,
tm_isdst: 0,
tm_gmtoff: 0,
tm_zone: std::ptr::null(),
};
// Safe because the parameters are valid.
unsafe {
libc::clock_gettime(libc::CLOCK_REALTIME, &mut timespec);
libc::localtime_r(&timespec.tv_sec, &mut tm);
}
LocalTime {
sec: tm.tm_sec,
min: tm.tm_min,
hour: tm.tm_hour,
mday: tm.tm_mday,
mon: tm.tm_mon,
year: tm.tm_year,
nsec: timespec.tv_nsec,
}
}
}
impl fmt::Display for LocalTime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}-{:02}-{:02}T{:02}:{:02}:{:02}.{:09}",
self.year + 1900,
self.mon + 1,
self.mday,
self.hour,
self.min,
self.sec,
self.nsec
)
}
}
/// Holds a micro-second resolution timestamp with both the real time and cpu time.
#[derive(Clone)]
pub struct TimestampUs {
/// Real time in microseconds.
pub time_us: u64,
/// Cpu time in microseconds.
pub cputime_us: u64,
}
impl Default for TimestampUs {
fn default() -> TimestampUs {
TimestampUs {
time_us: get_time(ClockType::Monotonic) / 1000,
cputime_us: get_time(ClockType::ProcessCpu) / 1000,
}
}
}
/// Returns a timestamp in nanoseconds from a monotonic clock.
///
/// Uses `_rdstc` on `x86_64` and [`get_time`](fn.get_time.html) on other architectures.
#[allow(dead_code)]
pub fn timestamp_cycles() -> u64 {
#[cfg(target_arch = "x86_64")]
// Safe because there's nothing that can go wrong with this call.
unsafe {
std::arch::x86_64::_rdtsc() as u64
}
#[cfg(not(target_arch = "x86_64"))]
{
get_time(ClockType::Monotonic)
}
}
/// Returns a timestamp in nanoseconds based on the provided clock type.
///
/// # Arguments
///
/// * `clock_type` - Identifier of the Linux Kernel clock on which to act.
pub fn get_time(clock_type: ClockType) -> u64 {
let mut time_struct = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
// Safe because the parameters are valid.
unsafe { libc::clock_gettime(clock_type.into(), &mut time_struct) };
seconds_to_nanoseconds(time_struct.tv_sec).unwrap() as u64 + (time_struct.tv_nsec as u64)
}
/// Converts a timestamp in seconds to an equivalent one in nanoseconds.
/// Returns `None` if the conversion overflows.
///
/// # Arguments
///
/// * `value` - Timestamp in seconds.
pub fn seconds_to_nanoseconds(value: i64) -> Option<i64> {
value.checked_mul(NANOS_PER_SECOND as i64)
}
/// A RTC device following the PL031 specification..
pub struct RTC {
previous_now: Instant,
tick_offset: i64,
// This is used for implementing the RTC alarm. However, in Firecracker we do not need it.
match_value: u32,
// Writes to this register load an update value into the RTC.
load: u32,
imsc: u32,
ris: u32,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
}
impl RTC {
/// Constructs an AMBA PL031 RTC device.
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> RTC {
RTC {
// This is used only for duration measuring purposes.
previous_now: Instant::now(),
tick_offset: get_time(ClockType::Real) as i64,
match_value: 0,
load: 0,
imsc: 0,
ris: 0,
interrupt,
}
}
fn trigger_interrupt(&mut self) -> Result<()> {
self.interrupt.trigger(0).map_err(Error::InterruptFailure)?;
Ok(())
}
fn get_time(&self) -> u32 {
let ts = (self.tick_offset as i128)
+ (Instant::now().duration_since(self.previous_now).as_nanos() as i128);
(ts / NANOS_PER_SECOND as i128) as u32
}
fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> {
match offset {
RTCMR => {
// The MR register is used for implementing the RTC alarm. A real time clock alarm is
// a feature that can be used to allow a computer to 'wake up' after shut down to execute
// tasks every day or on a certain day. It can sometimes be found in the 'Power Management'
// section of a motherboard's BIOS setup. This is functionality that extends beyond
// Firecracker intended use. However, we increment a metric just in case.
self.match_value = val;
}
RTCLR => {
self.load = val;
self.previous_now = Instant::now();
// If the unwrap fails, then the internal value of the clock has been corrupted and
// we want to terminate the execution of the process.
self.tick_offset = seconds_to_nanoseconds(i64::from(val)).unwrap();
}
RTCIMSC => {
self.imsc = val & 1;
self.trigger_interrupt()?;
}
RTCICR => {
// As per above mentioned doc, the interrupt is cleared by writing any data value to
// the Interrupt Clear Register.
self.ris = 0;
self.trigger_interrupt()?;
}
RTCCR => (), // ignore attempts to turn off the timer.
o => {
return Err(Error::BadWriteOffset(o));
}
}
Ok(())
}
}
impl BusDevice for RTC {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let v;
let mut read_ok = true;
if offset < AMBA_ID_HIGH && offset >= AMBA_ID_LOW {
let index = ((offset - AMBA_ID_LOW) >> 2) as usize;
v = u32::from(PL031_ID[index]);
} else {
v = match offset {
RTCDR => self.get_time(),
RTCMR => {
// Even though we are not implementing RTC alarm we return the last value
self.match_value
}
RTCLR => self.load,
RTCCR => 1, // RTC is always enabled.
RTCIMSC => self.imsc,
RTCRIS => self.ris,
RTCMIS => self.ris & self.imsc,
_ => {
read_ok = false;
0
}
};
}
if read_ok && data.len() <= 4 {
write_le_u32(data, v);
} else {
warn!(
"Invalid RTC PL031 read: offset {}, data length {}",
offset,
data.len()
);
}
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
if data.len() <= 4 {
let v = read_le_u32(&data[..]);
if let Err(e) = self.handle_write(offset, v) {
warn!("Failed to write to RTC PL031 device: {}", e);
}
} else {
warn!(
"Invalid RTC PL031 write: offset {}, data length {}",
offset,
data.len()
);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig};
use vmm_sys_util::eventfd::EventFd;
const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000;
#[test]
fn test_get_time() {
for _ in 0..1000 {
assert!(get_time(ClockType::Monotonic) <= get_time(ClockType::Monotonic));
}
for _ in 0..1000 {
assert!(get_time(ClockType::ProcessCpu) <= get_time(ClockType::ProcessCpu));
}
for _ in 0..1000 {
assert!(get_time(ClockType::ThreadCpu) <= get_time(ClockType::ThreadCpu));
}
assert_ne!(get_time(ClockType::Real), 0);
}
#[test]
fn test_local_time_display() {
let local_time = LocalTime {
sec: 30,
min: 15,
hour: 10,
mday: 4,
mon: 6,
year: 119,
nsec: 123_456_789,
};
assert_eq!(
String::from("2019-07-04T10:15:30.123456789"),
local_time.to_string()
);
let local_time = LocalTime {
sec: 5,
min: 5,
hour: 5,
mday: 23,
mon: 7,
year: 44,
nsec: 123,
};
assert_eq!(
String::from("1944-08-23T05:05:05.000000123"),
local_time.to_string()
);
let local_time = LocalTime::now();
assert!(local_time.mon >= 0 && local_time.mon <= 11);
}
#[test]
fn test_seconds_to_nanoseconds() {
assert_eq!(
seconds_to_nanoseconds(100).unwrap() as u64,
100 * NANOS_PER_SECOND
);
assert!(seconds_to_nanoseconds(9_223_372_037).is_none());
}
struct TestInterrupt {
event_fd: EventFd,
}
impl InterruptSourceGroup for TestInterrupt {
fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> {
self.event_fd.write(1)
}
fn update(
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
) -> result::Result<(), std::io::Error> {
Ok(())
}
fn notifier(&self, _index: InterruptIndex) -> Option<&EventFd> {
Some(&self.event_fd)
}
}
impl TestInterrupt {
fn new(event_fd: EventFd) -> Self {
TestInterrupt { event_fd }
}
}
#[test]
fn test_rtc_read_write_and_event() {
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let mut rtc = RTC::new(Arc::new(Box::new(TestInterrupt::new(
intr_evt.try_clone().unwrap(),
))));
let mut data = [0; 4];
// Read and write to the MR register.
write_le_u32(&mut data, 123);
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCMR, &mut data);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCMR, &mut data);
let v = read_le_u32(&data[..]);
assert_eq!(v, 123);
// Read and write to the LR register.
let v = get_time(ClockType::Real);
write_le_u32(&mut data, (v / NANOS_PER_SECOND) as u32);
let previous_now_before = rtc.previous_now;
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCLR, &mut data);
assert!(rtc.previous_now > previous_now_before);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCLR, &mut data);
let v_read = read_le_u32(&data[..]);
assert_eq!((v / NANOS_PER_SECOND) as u32, v_read);
// Read and write to IMSC register.
// Test with non zero value.
let non_zero = 1;
write_le_u32(&mut data, non_zero);
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
// The interrupt line should be on.
assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() == 1);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
let v = read_le_u32(&data[..]);
assert_eq!(non_zero & 1, v);
// Now test with 0.
write_le_u32(&mut data, 0);
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
let v = read_le_u32(&data[..]);
assert_eq!(0, v);
// Read and write to the ICR register.
write_le_u32(&mut data, 1);
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCICR, &mut data);
// The interrupt line should be on.
assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() > 1);
let v_before = read_le_u32(&data[..]);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCICR, &mut data);
let v = read_le_u32(&data[..]);
// ICR is a write only register. Data received should stay equal to data sent.
assert_eq!(v, v_before);
// Attempts to turn off the RTC should not go through.
write_le_u32(&mut data, 0);
rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCCR, &mut data);
rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCCR, &mut data);
let v = read_le_u32(&data[..]);
assert_eq!(v, 1);
// Attempts to write beyond the writable space. Using here the space used to read
// the CID and PID from.
write_le_u32(&mut data, 0);
rtc.write(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &mut data);
// However, reading from the AMBA_ID_LOW should succeed upon read.
let mut data = [0; 4];
rtc.read(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &mut data);
let index = AMBA_ID_LOW + 3;
assert_eq!(data[0], PL031_ID[((index - AMBA_ID_LOW) >> 2) as usize]);
}
macro_rules! byte_order_test_read_write {
($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr, $data_type: ty) => {
#[test]
fn $test_name() {
#[allow(overflowing_literals)]
let test_cases = [
(
0x0123_4567_89AB_CDEF as u64,
[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef],
),
(
0x0000_0000_0000_0000 as u64,
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
),
(
0x1923_2345_ABF3_CCD4 as u64,
[0x19, 0x23, 0x23, 0x45, 0xAB, 0xF3, 0xCC, 0xD4],
),
(
0x0FF0_0FF0_0FF0_0FF0 as u64,
[0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0],
),
(
0xFFFF_FFFF_FFFF_FFFF as u64,
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
),
(
0x89AB_12D4_C2D2_09BB as u64,
[0x89, 0xAB, 0x12, 0xD4, 0xC2, 0xD2, 0x09, 0xBB],
),
];
let type_size = std::mem::size_of::<$data_type>();
for (test_val, v_arr) in &test_cases {
let v = *test_val as $data_type;
let cmp_iter: Box<dyn Iterator<Item = _>> = if $is_be {
Box::new(v_arr[(8 - type_size)..].iter())
} else {
Box::new(v_arr.iter().rev())
};
// test write
let mut write_arr = vec![Default::default(); type_size];
$write_fn_name(&mut write_arr, v);
for (cmp, cur) in cmp_iter.zip(write_arr.iter()) {
assert_eq!(*cmp, *cur as u8)
}
// test read
let read_val = $read_fn_name(&write_arr);
assert_eq!(v, read_val);
}
}
};
}
byte_order_test_read_write!(test_le_u16, write_le_u16, read_le_u16, false, u16);
byte_order_test_read_write!(test_le_u32, write_le_u32, read_le_u32, false, u32);
byte_order_test_read_write!(test_le_u64, write_le_u64, read_le_u64, false, u64);
byte_order_test_read_write!(test_le_i32, write_le_i32, read_le_i32, false, i32);
byte_order_test_read_write!(test_be_u16, write_be_u16, read_be_u16, true, u16);
byte_order_test_read_write!(test_be_u32, write_be_u32, read_be_u32, true, u32);
}

View File

@@ -5,9 +5,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use crate::{BusDevice, Interrupt};
use anyhow::anyhow;
use std::collections::VecDeque;
use std::sync::Arc;
use std::{io, result};
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
use vmm_sys_util::errno::Result;
const LOOP_SIZE: usize = 0x40;
@@ -53,9 +60,10 @@ const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps
/// This can optionally write the guest's output to a Write trait object. To send input to the
/// guest, use `queue_input_bytes`.
pub struct Serial {
id: String,
interrupt_enable: u8,
interrupt_identification: u8,
interrupt: Box<dyn Interrupt>,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
line_control: u8,
line_status: u8,
modem_control: u8,
@@ -66,9 +74,27 @@ pub struct Serial {
out: Option<Box<dyn io::Write + Send>>,
}
#[derive(Serialize, Deserialize)]
pub struct SerialState {
interrupt_enable: u8,
interrupt_identification: u8,
line_control: u8,
line_status: u8,
modem_control: u8,
modem_status: u8,
scratch: u8,
baud_divisor: u16,
in_buffer: VecDeque<u8>,
}
impl Serial {
pub fn new(interrupt: Box<dyn Interrupt>, out: Option<Box<dyn io::Write + Send>>) -> Serial {
pub fn new(
id: String,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
out: Option<Box<dyn io::Write + Send>>,
) -> Serial {
Serial {
id,
interrupt_enable: 0,
interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION,
interrupt,
@@ -84,13 +110,17 @@ impl Serial {
}
/// Constructs a Serial port ready for output.
pub fn new_out(interrupt: Box<dyn Interrupt>, out: Box<dyn io::Write + Send>) -> Serial {
Self::new(interrupt, Some(out))
pub fn new_out(
id: String,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
out: Box<dyn io::Write + Send>,
) -> Serial {
Self::new(id, interrupt, Some(out))
}
/// Constructs a Serial port with no connected output.
pub fn new_sink(interrupt: Box<dyn Interrupt>) -> Serial {
Self::new(interrupt, None)
pub fn new_sink(id: String, interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> Serial {
Self::new(id, interrupt, None)
}
/// Queues raw bytes for the guest to read and signals the interrupt if the line status would
@@ -149,7 +179,7 @@ impl Serial {
}
fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> {
self.interrupt.deliver()
self.interrupt.trigger(0)
}
fn iir_reset(&mut self) {
@@ -186,6 +216,32 @@ impl Serial {
}
Ok(())
}
fn state(&self) -> SerialState {
SerialState {
interrupt_enable: self.interrupt_enable,
interrupt_identification: self.interrupt_identification,
line_control: self.line_control,
line_status: self.line_status,
modem_control: self.modem_control,
modem_status: self.modem_status,
scratch: self.scratch,
baud_divisor: self.baud_divisor,
in_buffer: self.in_buffer.clone(),
}
}
fn set_state(&mut self, state: &SerialState) {
self.interrupt_enable = state.interrupt_enable;
self.interrupt_identification = state.interrupt_identification;
self.line_control = state.line_control;
self.line_status = state.line_status;
self.modem_control = state.modem_control;
self.modem_status = state.modem_status;
self.scratch = state.scratch;
self.baud_divisor = state.baud_divisor;
self.in_buffer = state.in_buffer.clone();
}
}
impl BusDevice for Serial {
@@ -228,21 +284,76 @@ impl BusDevice for Serial {
}
}
impl Snapshottable for Serial {
fn id(&self) -> String {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let snapshot =
serde_json::to_vec(&self.state()).map_err(|e| MigratableError::Snapshot(e.into()))?;
let mut serial_snapshot = Snapshot::new(self.id.as_str());
serial_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id),
snapshot,
});
Ok(serial_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(serial_section) = snapshot.snapshot_data.get(&format!("{}-section", self.id)) {
let serial_state = match serde_json::from_slice(&serial_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize SERIAL {}",
error
)))
}
};
self.set_state(&serial_state);
return Ok(());
}
Err(MigratableError::Restore(anyhow!(
"Could not find the serial snapshot section"
)))
}
}
impl Pausable for Serial {}
impl Transportable for Serial {}
impl Migratable for Serial {}
#[cfg(test)]
mod tests {
use super::*;
use std::io;
use std::sync::{Arc, Mutex};
use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig};
use vmm_sys_util::eventfd::EventFd;
const SERIAL_NAME: &str = "serial";
struct TestInterrupt {
event_fd: EventFd,
}
impl Interrupt for TestInterrupt {
fn deliver(&self) -> result::Result<(), std::io::Error> {
impl InterruptSourceGroup for TestInterrupt {
fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> {
self.event_fd.write(1)
}
fn update(
&self,
_index: InterruptIndex,
_config: InterruptSourceConfig,
) -> result::Result<(), std::io::Error> {
Ok(())
}
}
impl TestInterrupt {
@@ -278,7 +389,8 @@ mod tests {
let intr_evt = EventFd::new(0).unwrap();
let serial_out = SharedBuffer::new();
let mut serial = Serial::new_out(
Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Box::new(serial_out.clone()),
);
@@ -297,7 +409,8 @@ mod tests {
let intr_evt = EventFd::new(0).unwrap();
let serial_out = SharedBuffer::new();
let mut serial = Serial::new_out(
Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Box::new(serial_out.clone()),
);
@@ -334,8 +447,10 @@ mod tests {
#[test]
fn serial_thr() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial =
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
);
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
// counter doesn't change (for 0 it blocks)
@@ -354,8 +469,10 @@ mod tests {
#[test]
fn serial_dlab() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial =
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
);
serial.write(0, LCR as u64, &[LCR_DLAB_BIT as u8]);
serial.write(0, DLAB_LOW as u64, &[0x12 as u8]);
@@ -373,8 +490,10 @@ mod tests {
#[test]
fn serial_modem() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial =
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
);
serial.write(0, MCR as u64, &[MCR_LOOP_BIT as u8]);
serial.write(0, DATA as u64, &['a' as u8]);
@@ -397,8 +516,10 @@ mod tests {
#[test]
fn serial_scratch() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial =
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
let mut serial = Serial::new_sink(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
);
serial.write(0, SCR as u64, &[0x12 as u8]);

View File

@@ -6,67 +6,42 @@
// found in the LICENSE-BSD-3-Clause file.
//! Emulates virtual and hardware devices.
extern crate anyhow;
#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate epoll;
extern crate kvm_bindings;
extern crate kvm_ioctls;
extern crate libc;
#[macro_use]
extern crate log;
#[cfg(feature = "acpi")]
extern crate acpi_tables;
extern crate serde;
extern crate vm_device;
extern crate vm_memory;
extern crate vm_migration;
extern crate vmm_sys_util;
use std::fs::File;
use std::{io, result};
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[cfg(feature = "acpi")]
mod acpi;
mod bus;
#[cfg(target_arch = "aarch64")]
pub mod gic;
pub mod interrupt_controller;
#[cfg(target_arch = "x86_64")]
pub mod ioapic;
pub mod legacy;
#[cfg(feature = "acpi")]
pub use self::acpi::AcpiShutdownDevice;
pub use self::bus::{Bus, BusDevice, Error as BusError};
pub use self::acpi::{AcpiGEDDevice, AcpiPMTimerDevice, AcpiShutdownDevice};
pub type DeviceEventT = u16;
/// The payload is used to handle events where the internal state of the VirtIO device
/// needs to be changed.
pub enum EpollHandlerPayload {
/// DrivePayload(disk_image)
DrivePayload(File),
/// Events that do not need a payload.
Empty,
}
type Result<T> = std::result::Result<T, Error>;
pub trait EpollHandler: Send {
fn handle_event(
&mut self,
device_event: DeviceEventT,
event_flags: u32,
payload: EpollHandlerPayload,
) -> Result<()>;
}
#[derive(Debug)]
pub enum Error {
FailedReadingQueue {
event_type: &'static str,
underlying: io::Error,
},
FailedReadTap,
FailedSignalingUsedQueue(io::Error),
PayloadExpected,
UnknownEvent {
device: &'static str,
event: DeviceEventT,
},
IoError(io::Error),
}
pub trait Interrupt: Send {
fn deliver(&self) -> result::Result<(), std::io::Error>;
bitflags! {
pub struct HotPlugNotificationFlags: u8 {
const NO_DEVICES_CHANGED = 0;
const CPU_DEVICES_CHANGED = 0b1;
const MEMORY_DEVICES_CHANGED = 0b10;
const PCI_DEVICES_CHANGED = 0b100;
}
}

379
docs/api.md Normal file
View File

@@ -0,0 +1,379 @@
- [Cloud Hypervisor API](#cloud-hypervisor-api)
* [External API](#external-api)
+ [REST API](#rest-api)
- [Location and availability](#location-and-availability)
- [Endpoints](#endpoints)
* [Virtual Machine Manager (VMM) Actions](#virtual-machine-manager-vmm-actions)
* [Virtual Machine (VM) Actions](#virtual-machine-vm-actions)
- [REST API Examples](#rest-api-examples)
* [Create a Virtual Machine](#create-a-virtual-machine)
* [Boot a Virtual Machine](#boot-a-virtual-machine)
* [Dump a Virtual Machine Information](#dump-a-virtual-machine-information)
* [Reboot a Virtual Machine](#reboot-a-virtual-machine)
* [Shut a Virtual Machine Down](#shut-a-virtual-machine-down)
+ [Command Line Interface](#command-line-interface)
+ [REST API and CLI Architecural Relationship](#rest-api-and-cli-architectural-relationship)
* [Internal API](#internal-api)
+ [Goals and Design](#goals-and-design)
* [End to End Example](#end-to-end-example)
# Cloud Hypervisor API
The Cloud Hypervisor API is made of 2 distinct interfaces:
1. **The external API**. This is the user facing API. Users and operators can
control and manage Cloud Hypervisor through either a REST API or a Command
Line Interface (CLI).
1. **The internal API**, based on [rust's Multi-Producer, Single-Consumer (MPSC)](https://doc.rust-lang.org/std/sync/mpsc/)
module. This API is used internally by the Cloud Hypervisor threads to
communicate between each others.
The goal of this document is to describe the Cloud Hypervisor API as a whole,
and to outline how the internal and external APIs are architecturally related.
## External API
### REST API
The Cloud Hypervisor [REST](https://en.wikipedia.org/wiki/Representational_state_transfer)
API triggers VM and VMM specific actions, and as such it is designed as a
collection of RPC-style, static methods.
The API is [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md)
compliant. Please consult the [Cloud Hypervisor API](https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/master/vmm/src/api/openapi/cloud-hypervisor.yaml)
document for more details about the API payloads and responses.
### Location and availability
The REST API is available as soon as the Cloud Hypervisor binary is started,
through a local UNIX socket.
By default, it is located at `/run/user/{user ID}/cloud-hypervisor.{Cloud Hypervisor PID}`.
For example, if you launched Cloud Hypervisor as user ID 1000 and its PID is
123456, the Cloud Hypervisor REST API will be available at `/run/user/1000/cloud-hypervisor.123456`.
The REST API default URL can be overridden through the Cloud Hypervisor
option `--api-socket`:
```
$ ./target/debug/cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
Cloud Hypervisor Guest
API server: /tmp/cloud-hypervisor.sock
vCPUs: 1
Memory: 512 MB
Kernel: None
Kernel cmdline:
Disk(s): None
```
### Endpoints
The Cloud Hypervisor API exposes the following actions through its endpoints:
#### Virtual Machine Manager (VMM) Actions
Action | Endpoint | Request Body | Response Body | Prerequisites
------------------------------------|-----------------|--------------|----------------------------|---------------------------
Check for the REST API availability | `/vmm.ping` | N/A | `/schemas/VmmPingResponse` | N/A
Shut the VMM down | `/vmm.shutdown` | N/A | N/A | The VMM is running
#### Virtual Machine (VM) Actions
Action | Endpoint | Request Body | Response Body | Prerequisites
-----------------------------------|---------------------|---------------------------|--------------------------|---------------------------
Create the VM | `/vm.create` | `/schemas/VmConfig` | N/A | The VM is not created yet
Delete the VM | `/vm.delete` | N/A | N/A | N/A
Boot the VM | `/vm.boot` | N/A | N/A | The VM is created but not booted
Shut the VM down | `/vm.shutdown` | N/A | N/A | The VM is booted
Reboot the VM | `/vm.reboot` | N/A | N/A | The VM is booted
Pause the VM | `/vm.pause` | N/A | N/A | The VM is booted
Resume the VM | `/vm.resume` | N/A | N/A | The VM is paused
Add/remove CPUs to/from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted
Add/remove memory from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted
Add/remove memory from a zone | `/vm.resize-zone` | `/schemas/VmResizeZone` | N/A | The VM is booted
Dump the VM information | `/vm.info` | N/A | `/schemas/VmInfo` | The VM is created
Add VFIO PCI device to the VM | `/vm.add-device` | `/schemas/VmAddDevice` | `/schemas/PciDeviceInfo` | The VM is booted
Add disk device to the VM | `/vm.add-disk` | `/schemas/DiskConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add fs device to the VM | `/vm.add-fs` | `/schemas/FsConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add pmem device to the VM | `/vm.add-pmem` | `/schemas/PmemConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add network device to the VM | `/vm.add-net` | `/schemas/NetConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Add vsock device to the VM | `/vm.add-vsock` | `/schemas/VsockConfig` | `/schemas/PciDeviceInfo` | The VM is booted
Remove device from the VM | `/vm.remove-device` | `/schemas/VmRemoveDevice` | N/A | The VM is booted
Dump the VM counters | `/vm.counters` | N/A | `/schemas/VmCounters` | The VM is booted
### REST API Examples
For the following set of examples, we assume Cloud Hypervisor is started with
the REST API available at `/tmp/cloud-hypervisor.sock`:
```
$ ./target/debug/cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
Cloud Hypervisor Guest
API server: /tmp/cloud-hypervisor.sock
vCPUs: 1
Memory: 512 MB
Kernel: None
Kernel cmdline:
Disk(s): None
```
#### Create a Virtual Machine
We want to create a virtual machine with the following characteristics:
* 4 vCPUs
* 1 GB of RAM
* 1 virtio based networking interface
* Direct kernel boot from a custom 5.6.0-rc4 Linux kernel located at
`/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu`
* Using a Ubuntu image as its root filesystem, located at
`/opt/clh/images/focal-server-cloudimg-amd64.raw`
```shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X PUT 'http://localhost/api/v1/vm.create' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"cpus":{"boot_vcpus": 4, "max_vcpus": 4},
"kernel":{"path":"/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu"},
"cmdline":{"args":"console=ttyS0 console=hvc0 root=/dev/vda1 rw"},
"disks":[{"path":"/opt/clh/images/focal-server-cloudimg-amd64.raw"}],
"rng":{"src":"/dev/urandom"},
"net":[{"ip":"192.168.10.10", "mask":"255.255.255.0", "mac":"12:34:56:78:90:01"}]
}'
```
#### Boot a Virtual Machine
Once the VM is created, we can boot it:
```shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.boot'
```
#### Dump a Virtual Machine Information
We can fetch information about any VM, as soon as it's created:
```shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X GET 'http://localhost/api/v1/vm.info' \
-H 'Accept: application/json'
```
#### Reboot a Virtual Machine
We can reboot a VM that's already booted:
```shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.reboot'
```
#### Shut a Virtual Machine Down
Once booted, we can shut a VM down from the REST API:
```shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.shutdown'
```
### Command Line Interface
The Cloud Hypervisor Command Line Interface (CLI) can only be used for launching
the Cloud Hypervisor binary, i.e. it can not be used for controlling the VMM or
the launched VM once they're up and running.
If you want to inspect the VMM, or control the VM after launching Cloud
Hypervisor from the CLI, you must use the [REST API](#rest-api).
From the CLI, one can either:
1. Create and boot a complete virtual machine by using the CLI options to build
the VM config. Run `cloud-hypervisor --help` for a complete list of CLI
options. As soon as the `cloud-hypervisor` binary is launched, the
[REST API](#rest-api) is available for controlling and managing the VM.
1. Start the [REST API](#rest-api) server only, by not passing any VM
configuration options. The VM can then be asynchronously created and booted
by sending HTTP commands to the [REST API](#rest-api). Check the
[REST API examples](#rest-api-examples) section for more details.
### REST API and CLI Architectural Relationship
The REST API and the CLI both rely on a common, [internal API](#internal-api).
The CLI options are parsed by the
[clap crate](https://docs.rs/clap/2.33.0/clap/) and then translated into
[internal API](#internal-api) commands.
The REST API is processed by an HTTP thread using the
[Firecracker's `micro_http`](https://github.com/firecracker-microvm/firecracker/tree/master/src/micro_http)
crate. As with the CLI, the HTTP requests eventually get translated into
[internal API](#internal-api) commands.
As a summary, the REST API and the CLI are essentially frontends for the
[internal API](#internal-api):
```
+------------------+
REST API | |
+--------->+ micro_http +--------+
| | | |
| +------------------+ |
| | +------------------------+
| | | |
+------------+ | | | |
| | | | | +--------------+ |
| User +---------+ +------> | Internal API | |
| | | | | +--------------+ |
+------------+ | | | |
| | | |
| | +------------------------+
| +----------+ | VMM
| CLI | | |
+----------->+ clap +--------------+
| |
+----------+
```
## Internal API
The Cloud Hypervisor internal API, as its name suggests, is used internally
by the different Cloud Hypervisor threads (VMM, HTTP, control loop, etc) to
send commands and responses to each others.
It is based on [rust's Multi-Producer, Single-Consumer (MPSC)](https://doc.rust-lang.org/std/sync/mpsc/),
and the single consumer (a.k.a. the API receiver) is the Cloud Hypervisor
control loop.
API producers are the HTTP thread handling the [REST API](#rest-api) and the
main thread that initially parses the [CLI](#command-line-interface).
### Goals and Design
The internal API is designed for controlling, managing and inspecting a Cloud
Hypervisor VMM and its guest. It is a backend for handling external, user
visible requests through either the [REST API](#rest-api) or the
[CLI](#command-line-interface) interfaces.
The API follows a command-response scheme that closely maps the [REST API](#rest-api).
Any command must be replied to with a response.
Commands are [MPSC](https://doc.rust-lang.org/std/sync/mpsc/) based messages and
are received and processed by the VMM control loop.
In order for the VMM control loop to respond to any internal API command, it
must be able to send a response back to the MPSC sender. For that purpose, all
internal API command payload carry the [Sender](https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html)
end of an [MPSC](https://doc.rust-lang.org/std/sync/mpsc/) channel.
The sender of any internal API command is therefore responsible for:
1. Creating an [MPSC](https://doc.rust-lang.org/std/sync/mpsc/) response
channel.
1. Passing the [Sender](https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html)
end of the response channel as part of the internal API command payload.
1. Waiting for the internal API command's response on the [Receiver](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html)
end of the response channel.
## End to End Example
In order to further understand how the external and internal Cloud Hypervisor
APIs work together, let's look at a complete VM creation flow, from the
[REST API](#rest-api) call, to the reply the external user will receive:
1. A user or operator sends an HTTP request to the Cloud Hypervisor
[REST API](#rest-api) in order to creates a virtual machine:
```
shell
#!/bin/bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X PUT 'http://localhost/api/v1/vm.create' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"cpus":{"boot_vcpus": 4, "max_vcpus": 4},
"kernel":{"path":"/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu"},
"cmdline":{"args":"console=ttyS0 console=hvc0 root=/dev/vda1 rw"},
"disks":[{"path":"/opt/clh/images/focal-server-cloudimg-amd64.raw"}],
"rng":{"src":"/dev/urandom"},
"net":[{"ip":"192.168.10.10", "mask":"255.255.255.0", "mac":"12:34:56:78:90:01"}]
}'
```
1. The Cloud Hypervisor HTTP thread processes the request and de-serializes the
HTTP request JSON body into an internal `VmConfig` structure.
1. The Cloud Hypervisor HTTP thread creates an
[MPSC](https://doc.rust-lang.org/std/sync/mpsc/) channel for the internal API
server to send its response back.
1. The Cloud Hypervisor HTTP thread prepares an internal API command for creating a
virtual machine. The command's payload is made of the de-serialized
`VmConfig` structure and the response channel:
```Rust
VmCreate(Arc<Mutex<VmConfig>>, Sender<ApiResponse>)
```
1. The Cloud Hypervisor HTTP thread sends the internal API command, and waits
for the response:
```Rust
// Send the VM creation request.
api_sender
.send(ApiRequest::VmCreate(config, response_sender))
.map_err(ApiError::RequestSend)?;
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
response_receiver.recv().map_err(ApiError::ResponseRecv)??;
```
1. The Cloud Hypervisor control loop receives the command, as it listens on the
internal API [MPSC](https://doc.rust-lang.org/std/sync/mpsc/) channel:
```Rust
// Read from the API receiver channel
let api_request = api_receiver.recv().map_err(Error::ApiRequestRecv)?;
```
1. The Cloud Hypervisor control loop matches the received internal API against
the `VmCreate` payload, and extracts both the `VmConfig` structure and the
[Sender](https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html) from the
command payload. It stores the `VmConfig` structure and replies back to the
sender ((The HTTP thread):
```Rust
match api_request {
ApiRequest::VmCreate(config, sender) => {
// We only store the passed VM config.
// The VM will be created when being asked to boot it.
let response = if self.vm_config.is_none() {
self.vm_config = Some(config);
Ok(ApiResponsePayload::Empty)
} else {
Err(ApiError::VmAlreadyCreated)
};
sender.send(response).map_err(Error::ApiResponseSend)?;
}
```
1. The Cloud Hypervisor HTTP thread receives the internal API command response
as the return value from its `VmCreate` HTTP handler. Depending on the
control loop internal API response, it generates the appropriate HTTP
response:
```Rust
// Call vm_create()
match vm_create(api_notifier, api_sender, Arc::new(Mutex::new(vm_config)))
.map_err(HttpError::VmCreate)
{
Ok(_) => Response::new(Version::Http11, StatusCode::NoContent),
Err(e) => error_response(e, StatusCode::InternalServerError),
}
```
1. The Cloud Hypervisor HTTP thread sends the formed HTTP response back to the
user. This is abstracted by the
[micro_http](https://github.com/firecracker-microvm/firecracker/tree/master/src/micro_http)
crate.

68
docs/arm64.md Normal file
View File

@@ -0,0 +1,68 @@
# How to build and run Cloud-hypervisor on AArch64
Cloud-hypervisor is partially enabled on AArch64 architecture.
Although all features are not ready yet, you can begin to test Cloud-hypervisor on a AArch64 host by following this guide.
## Prerequisites
On AArch64 machines, Cloud-hypervisor depends on an external library `libfdt-dev` for generating Flattened Device Tree (FDT).
The long-term plan is to replace `libfdt-dev` with some pure-Rust component to get rid of such dependency.
```bash
sudo apt-get update
sudo apt-get install libfdt-dev
```
## Build
For Virtio devices, you can choose MMIO or PCI as transport option.
### MMIO
```bash
cargo build --no-default-features --features mmio,kvm
```
### PCI
Using PCI devices requires GICv3-ITS for MSI messaging. GICv3-ITS is very common in modern servers, but your machine happen to be old ones with GICv2(M) (like Raspberry Pi 4) or GICv3 without ITS, MMIO can still work.
```bash
cargo build --no-default-features --features pci,kvm
```
## Image
Download kernel binary and rootfs image from AWS.
```bash
wget https://s3.amazonaws.com/spec.ccfc.min/img/aarch64/ubuntu_with_ssh/fsfiles/xenial.rootfs.ext4 -O rootfs.ext4
wget https://s3.amazonaws.com/spec.ccfc.min/img/aarch64/ubuntu_with_ssh/kernel/vmlinux.bin -O kernel.bin
```
## Containerized build
If you want to build and test Cloud Hypervisor without having to install all the required dependencies, you can also turn to the development script: dev_cli.sh.
To build the development container:
```bash
./scripts/dev_cli.sh build-container
```
To build Cloud-hypervisor in the container: (The default option for Virtio transport is MMIO.)
```bash
./scripts/dev_cli.sh build
```
## Run
Assuming you have built Cloud-hypervisor with the development container, a VM can be started with command:
```bash
sudo build/cargo_target/aarch64-unknown-linux-gnu/debug/cloud-hypervisor --kernel kernel.bin --disk path=rootfs.ext4 --cmdline "keep_bootcon console=hvc0 reboot=k panic=1 pci=off root=/dev/vda rw" --cpus boot=4 --memory size=512M --serial file=serial.log --log-file log.log -vvv
```
If the build was done out of the container, replace the binary path with `target/debug/cloud-hypervisor`.

136
docs/custom-image.md Normal file
View File

@@ -0,0 +1,136 @@
# How to create a custom Ubuntu image
In the context of adding more utilities to the Ubuntu cloud image being used
for integration testing, this quick guide details how to achieve the proper
modification of an official Ubuntu cloud image.
## Create the image
Let's go through the steps on how to extend an official Ubuntu image. These
steps can be applied to other distributions (with a few changes regarding
package management).
### Get latest Ubuntu cloud image
```bash
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
```
### Check the file format is QCOW2
```bash
file focal-server-cloudimg-amd64.img
focal-server-cloudimg-amd64.img: QEMU QCOW2 Image (v2), 2361393152 bytes
```
### Convert QCOW2 into RAW
```bash
qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
```
### Identify the Linux partition
The goal is to mount the image rootfs so that it can be modified as needed.
That's why we need to identify where the Linux filesystem partition is located
in the image.
```bash
sudo fdisk -l focal-server-cloudimg-amd64.raw
Disk focal-server-cloudimg-amd64.raw: 2.2 GiB, 2361393152 bytes, 4612096 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: A1171ABA-2BEA-4218-A467-1B2B607E5953
Device Start End Sectors Size Type
focal-server-cloudimg-amd64.raw1 227328 4612062 4384735 2.1G Linux filesystem
focal-server-cloudimg-amd64.raw14 2048 10239 8192 4M BIOS boot
focal-server-cloudimg-amd64.raw15 10240 227327 217088 106M EFI System
Partition table entries are not in disk order.
```
### Mount the Linux partition
```bash
mkdir -p /mnt
sudo mount -o loop,offset=$((227328 * 512)) focal-server-cloudimg-amd64.raw /mnt
```
### Change root directory
Changing the root directory will allow us to install new packages to the rootfs
contained by the cloud image.
```bash
sudo chroot /mnt
mount -t proc proc /proc
mount -t devpts devpts /dev/pts
```
### Install needed packages
In the context Cloud-Hypervisor's integration tests, we need several utilities.
Here is the way to install them for a Ubuntu image. This step is specific to
Ubuntu distributions.
```bash
apt update
apt install fio iperf iperf3 socat
```
### Remove snapd
This prevents snapd from trying to mount squashfs filesystem when the kernel
might not support it. This might be the case when the image is used with direct
kernel boot. This step is specific to Ubuntu distributions.
```bash
apt remove --purge snapd
```
### Cleanup the image
Leave no trace in the image before unmounting its content.
```bash
umount /dev/pts
umount /proc
history -c
exit
umount /mnt
```
### Rename the image
Renaming is important to identify this is a modified image.
```bash
mv focal-server-cloudimg-amd64.raw focal-server-cloudimg-amd64-custom.raw
```
### Create QCOW2 from RAW
Last step is to create the QCOW2 image back from the modified image.
```bash
qemu-img convert -p -f raw -O qcow2 focal-server-cloudimg-amd64-custom.raw focal-server-cloudimg-amd64-custom.qcow2
```
## Switch CI to use the new image
### Upload to Azure storage
The next step is to update both images (QCOW2 and RAW) stored as part of the
Azure storage account, replacing them with the newly created ones. This will
make these new images available from the integration tests. This is usually
achieved through the web interface.
### Update integration tests
Last step is about updating the integration tests to work with this new image.
The key point is to identify where the Linux filesystem partition is located,
as we might need to update the direct kernel boot command line, replacing
`/dev/vda1` with the appropriate partition number.

View File

@@ -43,7 +43,7 @@ to easily grep for the tracing logs (e.g.
```
./target/debug/cloud-hypervisor \
--kernel ~/rust-hypervisor-firmware/target/target/release/hypervisor-fw \
--disk ~/hypervisor/images/clear-30080-kvm.img \
--disk path=~/hypervisor/images/focal-server-cloudimg-amd64.raw \
--cpus 4 \
--memory size=1024M \
--rng \

208
docs/device_model.md Normal file
View File

@@ -0,0 +1,208 @@
# Device Model
This document describes the device model supported by `cloud-hypervisor`.
## Summary
| Device | Build configurable | Enabled by default | Runtime configurable |
| :----: | :----: | :----: | :----: |
| Serial port | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| RTC/CMOS | :heavy_check_mark: | :heavy_check_mark: | :negative_squared_cross_mark: |
| I/O APIC | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| i8042 shutdown/reboot | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :negative_squared_cross_mark: |
| ACPI shutdown/reboot | :negative_squared_cross_mark: | :heavy_check_mark: | :negative_squared_cross_mark: |
| virtio-blk | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-console | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-iommu | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-net | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-pmem | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-rng | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| virtio-vsock | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-blk | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-fs | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| vhost-user-net | :negative_squared_cross_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
| VFIO | :heavy_check_mark: | :negative_squared_cross_mark: | :heavy_check_mark: |
## Legacy devices
### Serial port
Simple emulation of a serial port by reading and writing to specific port I/O
addresses. Used as the default console for Linux when booting with the option
`console=ttyS0`, the serial port can be very useful to gather early logs from
the operating system booted inside the VM.
This device is always built-in, and it is disabled by default. It can be
enabled with the `--serial` option, as long as its parameter is not `off`.
### RTC/CMOS
For environments such as Windows or EFI which cannot rely on KVM clock, the
emulation of this legacy device makes the platform usable.
This device is built-in by default, but it can be compiled out with Rust
features. When compiled in, it is always enabled, and cannot be disabled
from the command line.
### I/O APIC
`cloud-hypervisor` supports a so-called split IRQ chip implementation by
implementing support for the [IOAPIC](https://wiki.osdev.org/IOAPIC).
By moving part of the IRQ chip implementation from kernel space to user space,
the IRQ chip emulation does not always run in a fully privileged mode.
The device is always built-in, and it is enabled depending on the presence of
the serial port. If the serial port is disabled, and because no other device
would require pin based interrupts (INTx), the I/O APIC is disabled.
### i8042
Simplified PS/2 port since it supports only one key to trigger a reboot or
shutdown, depending on the ACPI support.
This device is always built-in, but it is disabled by default. Because ACPI is
enabled by default, the handling of reboot/shutdown goes through the dedicated
ACPI device. In case ACPI is disabled, this device is enabled to bring to the
VM some reboot/shutdown support.
### ACPI device
This is a dedicated device for handling ACPI shutdown and reboot when ACPI is
enabled.
This device is always built-in, and it is enabled by default since the ACPI
feature is enabled by default.
## Virtio devices
For all virtio devices listed below, both `virtio-mmio` and `virtio-pci`
transport layers are supported, `virtio-pci` being the default.
Both `virtio-mmio` and `virtio-pci` can be compiled out. `virtio-pci` is
built-in by default, and enabled by default. If both transport layers were
built at the same time, `virtio-pci` would be the default transport layer.
### virtio-block
The `virtio-blk` device exposes a block device to the guest. This device is
usually used to boot the operating system running in the VM.
This device is always built-in, and it is enabled based on the presence of the
flag `--disk`.
### virtio-console
`cloud-hypervisor` exposes a `virtio-console` device to the guest. Although
using this device as a guest console can potentially cut some early boot
messages, it can reduce the guest boot time and provides a complete console
implementation.
This device is always built-in, and it is enabled by default to provide a guest
console. It can be disabled, switching back to the legacy serial port by
selecting `--serial tty --console off` from the command line.
### virtio-iommu
As we want to improve our nested guests support, we added support for exposing
a [paravirtualized IOMMU](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/iommu.md)
device through virtio. This allows for a safer nested virtio and directly
assigned devices support.
This device is always built-in, and it is enabled based on the presence of the
parameter `iommu=on` in any of the virtio or VFIO devices. If at least one of
these devices needs to be connected to the paravirtualized IOMMU, the
`virtio-iommu` device will be created.
### virtio-net
The `virtio-net` device provides network connectivity for the guest, as it
creates a network interface connected to a TAP interface automatically created
by the `cloud-hypervisor` on the host.
This device is always built-in, and it is enabled based on the presence of the
flag `--net`.
### virtio-pmem
The `virtio-pmem` implementation emulates a virtual persistent memory device
that `cloud-hypervisor` can e.g. boot from. Booting from a `virtio-pmem` device
allows to bypass the guest page cache and improve the guest memory footprint.
This device is always built-in, and it is enabled based on the presence of the
flag `--pmem`.
### virtio-rng
A VM does not generate entropy like a real machine would, which is an issue
when workloads running in the guest need random numbers to be generated. The
`virtio-rng` device provides entropy to the guest by relying on the generator
that can be found on the host. By default, the chosen source of entropy is
`/dev/urandom`.
This device is always built-in, and it is always enabled. The `--rng` flag can
be used to change the source of entropy.
### virtio-vsock
In order to more efficiently and securely communicate between host and guest,
we added a hybrid implementation of the [VSOCK](http://man7.org/linux/man-pages/man7/vsock.7.html)
socket address family over virtio.
Credits go to the [Firecracker](https://github.com/firecracker-microvm/firecracker/blob/master/docs/vsock.md)
project as our implementation is a copy of theirs.
This device is always built-in, and it is enabled based on the presence of the
flag `--vsock`.
## Vhost-user devices
Vhost-user devices are virtio backends running outside of the VMM, as its own
separate process. They are usually used to bring more flexibility and increased
isolation.
### vhost-user-blk
As part of the general effort to offload paravirtualized I/O to external
processes, we added support for vhost-user-blk backends. This enables
`cloud-hypervisor` users to plug a `vhost-user` based block device (e.g. SPDK)
into the VMM as their virtio block backend.
This device is always built-in, and it is enabled when `vhost_user=true` and
`socket` are provided to the `--disk` parameter.
### vhost-user-fs
`cloud-hypervisor` supports the [virtio-fs](https://virtio-fs.gitlab.io/)
shared file system, allowing for an efficient and reliable way of sharing
a filesystem between the host and the cloud-hypervisor guest.
See our [filesystem sharing](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/fs.md)
documentation for more details on how to use virtio-fs with cloud-hypervisor.
This device is always built-in, and it is enabled based on the presence of the
flag `--fs`.
### vhost-user-net
As part of the general effort to offload paravirtualized I/O to external
processes, we added support for [vhost-user-net](https://access.redhat.com/solutions/3394851)
backends. This enables `cloud-hypervisor` users to plug a `vhost-user` based
networking device (e.g. DPDK) into the VMM as their virtio network backend.
This device is always built-in, and it is enabled when `vhost_user=true` and
`socket` are provided to the `--net` parameter.
## VFIO
VFIO (Virtual Function I/O) is a kernel framework that exposes direct device
access to userspace. `cloud-hypervisor` uses VFIO to directly assign host
physical devices into its guest.
See our [VFIO documentation](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/vfio.md)
for more details on how to directly assign host devices to `cloud-hypervisor`
guests.
Because VFIO implies `vfio-pci` in the `cloud-hypervisor` context, the VFIO
support is built-in when the `pci` feature is selected. And because the `pci`
feature is built-in by default, VFIO support is also built-in by default.
When VFIO support is built-in, a physical device can be passed through, using
the flag `--device` in order to enable the VFIO code.

View File

@@ -10,11 +10,12 @@ __virtio-fs__, also known as __vhost-user-fs__ is a virtual device defined by th
This virtual device relies on the _vhost-user_ protocol, which assumes the backend (device emulation) is handled by a dedicated process running on the host. This daemon is called __virtiofsd__ and needs to be present on the host.
_Install virtiofsd_
_Build virtiofsd_
```bash
VIRTIOFSD_URL="$(curl --silent https://api.github.com/repos/intel/nemu/releases/latest | grep "browser_download_url" | grep "virtiofsd-x86_64" | grep -o 'https://.*[^ "]')"
wget --quiet $VIRTIOFSD_URL -O "virtiofsd"
chmod +x "virtiofsd"
git clone --depth 1 "https://github.com/sboeuf/qemu.git" -b "virtio-fs" $VIRTIOFSD_DIR
cd $VIRTIOFSD_DIR
./configure --prefix=$PWD --target-list=x86_64-softmmu
make virtiofsd -j `nproc`
sudo setcap cap_sys_admin+epi "virtiofsd"
```
_Create shared directory_
@@ -25,17 +26,20 @@ _Run virtiofsd_
```bash
./virtiofsd \
-d \
-o vhost_user_socket=/tmp/virtiofs \
--socket-path=/tmp/virtiofs \
-o source=/tmp/shared_dir \
-o cache=none
```
The `cache=none` option here is an important one as it tells the daemon not to try any memory mapping of the files, but instead to use the _virtqueues_ to convey the files content. The support for the memory mapping of the files will be added later.
The `cache=none` option should be the default when using `virtiofsd` with the __cloud-hypervisor__ VMM. This prevents from using the guest page cache, which reduces the memory footprint of the guest. When running multiple virtual machines on the same host, this will let the host deal with page cache, which will increase the density of virtual machines which can be launched.
The `cache=always` option will allow for the guest page cache to be used, which will increase the memory footprint of the guest. This option should be used only for specific use cases where a single VM is going to be running on a host.
### The kernel
In order to leverage __virtio-fs__ support from within the guest, and because the code has not been merged in upstream Linux kernel yet, it is required to build a custom kernel embedding the patches.
The following branch `virtio-pmem_and_virtio-fs` on the repository https://github.com/sboeuf/linux.git includes all the needed patches to support __virtio-fs__.
The following branch `virtio-fs-virtio-iommu` on the repository https://github.com/cloud-hypervisor/linux.git includes all the needed patches to support __virtio-fs__.
Make sure to build a kernel out of this branch that can be then used to boot the VM.
@@ -48,23 +52,37 @@ Direct kernel boot option is preferred since we need to provide the custom kerne
Because _vhost-user_ expects a dedicated process (__virtiofsd__ in this case) to be able to access the guest RAM to communicate through the _virtqueues_ with the driver running in the guest, `--memory` option needs to be slightly modified. It needs to specify a backing file for the memory so that an external process can access it.
Assuming you have `clear-kvm.img` and `custom-vmlinux.bin` on your system, here is the __cloud-hypervisor__ command you need to run:
Assuming you have `focal-server-cloudimg-amd64.raw` and `custom-vmlinux.bin` on your system, here is the __cloud-hypervisor__ command you need to run:
```bash
./cloud-hypervisor \
--cpus 4 \
--memory "size=512,file=/dev/shm" \
--disk clear-kvm.img \
--memory "size=512M,shared=on" \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-vmlinux.bin \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \
--fs tag=virtiofs,sock=/tmp/virtiofs,num_queues=1,queue_size=512
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--fs tag=myfs,socket=/tmp/virtiofs,num_queues=1,queue_size=512
```
By default, DAX is enabled with a cache window of 8GiB. You can specify a custom size (let's say 4GiB for this example) for the cache by explicitly setting DAX and the cache size:
```bash
--fs tag=virtiofs,socket=/tmp/virtiofs,num_queues=1,queue_size=512,dax=on,cache_size=4G
```
In case you don't want to use a shared window of cache to pass the shared files content, this means you will have to explicitly disable DAX with `dax=off`. Note that in this case, the `cache_size` parameter will be ignored.
```bash
--fs tag=virtiofs,socket=/tmp/virtiofs,num_queues=1,queue_size=512,dax=off
```
### Mount the shared directory
The last step is to mount the shared directory inside the guest, using the `virtio_fs` filesystem type.
The last step is to mount the shared directory inside the guest, using the `virtiofs` filesystem type.
```bash
mkdir mount_dir
mount \
-t virtio_fs /dev/null mount_dir/ \
-o tag=virtiofs,rootmode=040000,user_id=0,group_id=0
mount -t virtiofs -o dax myfs mount_dir/
```
The `tag` needs to be consistent with what has been provided through the __cloud-hypervisor__ command line.
The `tag` needs to be consistent with what has been provided through the __cloud-hypervisor__ command line, which happens to be `myfs` in this example.
The `-o dax` option must be removed in case the shared cache region is not enabled from the VMM.

35
docs/fuzzing.md Normal file
View File

@@ -0,0 +1,35 @@
# Fuzzing in Cloud Hypervisor
Cloud Hypervisor uses [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) for fuzzing individual components.
The fuzzers are are in the `fuzz/fuzz_targets` directory
## Preparation
Switch to nightly:
````
rustup override set nightly
````
Install `cargo fuzz`:
```
cargo install cargo-fuzz
```
## Running the fuzzers
e.g. To run the `qcow` fuzzer using all available CPUs:
```
cargo fuzz run qcow -j `nproc`
```
## Adding a new fuzzer
```
cargo fuzz add <new_fuzzer>
```
Inspiration for fuzzers can be found in [crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm/+/refs/heads/master/fuzz/)

113
docs/hotplug.md Normal file
View File

@@ -0,0 +1,113 @@
# Cloud Hypervisor Hot Plug
Currently Cloud Hypervisor only support hot plugging of CPU devices.
## Kernel support
For hotplug on Cloud Hypervisor ACPI GED support is needed. This can either be achieved by turning on `CONFIG_ACPI_REDUCED_HARDWARE_ONLY`
or by using this kernel patch (available in 5.5-rc1 and later): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/drivers/acpi/Makefile?id=ac36d37e943635fc072e9d4f47e40a48fbcdb3f0
## CPU Hot Plug
Extra vCPUs can be added and removed from a running Cloud Hypervisor instance. This is controlled by two mechanisms:
1. Specifying a number of maximum potential vCPUs that is greater than the number of default (boot) vCPUs.
2. Making a HTTP API request to the VMM to ask for the additional vCPUs to be added.
To use CPU hotplug start the VM with the number of max vCPUs greater than the number of boot vCPUs, e.g.
```shell
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel custom-vmlinux.bin \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4,max=8 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--rng \
--api-socket=/tmp/ch-socket
$ popd
```
Notice the addition of `--api-socket=/tmp/ch-socket` and a `max` parameter on `--cpus boot=4.max=8`.
To ask the VMM to add additional vCPUs then use the resize API:
```shell
curl -H "Accept: application/json" -H "Content-Type: application/json" -i -XPUT --unix-socket /tmp/ch-socket -d "{ \"desired_vcpus\":8}" http://localhost/api/v1/vm.resize
```
The extra vCPU threads will be created and advertised to the running kernel. The kernel does not bring up the CPUs immediately and instead the user must "online" them from inside the VM:
```shell
root@ch-guest ~ # lscpu | grep list:
On-line CPU(s) list: 0-3
Off-line CPU(s) list: 4-7
root@ch-guest ~ # echo 1 | tee /sys/devices/system/cpu/cpu[4,5,6,7]/online
1
root@ch-guest ~ # lscpu | grep list:
On-line CPU(s) list: 0-7
```
After a reboot the added CPUs will remain.
Removing CPUs works similarly by reducing the number in the "desired_vcpus" field of the reisze API. The CPUs will be automatically offlined inside the guest so there is no need to run any commands inside the guest:
```shell
curl -H "Accept: application/json" -H "Content-Type: application/json" -i -XPUT --unix-socket /tmp/ch-socket -d "{ \"desired_vcpus\":2}" http://localhost/api/v1/vm.resize
```
As per adding CPUs to the guest, after a reboot the VM will be running with the reduced number of vCPUs.
## Memory Hot Plug
Extra memory can be added from a runing Cloud Hypervisor instance. This is controlled by two mechanisms:
1. Allocating some of the guest physical address space for hotplug memory.
2. Making a HTTP API request to the VMM to ask for a new amount of RAM to be assigned to the VM. In the case of expanding the memory for the VM the new memory will be hotplugged into the running VM, if reducing the size of the memory then change will take effect after the next reboot.
To use memory hotplug start the VM specifying some size RAM in the "hotplug_size" parameter to the memory configuration. Not all the memory specified in this parameter will be available to hotplug as there are spacing and alignment requirements so it is recommended to make it larger than the hotplug RAM needed.
```shell
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel custom-vmlinux.bin \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4,max=8 \
--memory size=1024M,hotplug_size=8192M \
--net "tap=,mac=,ip=,mask=" \
--rng \
--api-socket=/tmp/ch-socket
$ popd
```
Before issuing the API request it is necessary to run the following command inside the VM to make it automatically online the added memory:
```shell
root@ch-guest ~ # echo online | sudo tee /sys/devices/system/memory/auto_online_blocks
```
To ask the VMM to add expand the RAM for the VM (request is in bytes):
```shell
curl -H "Accept: application/json" -H "Content-Type: application/json" -i -XPUT --unix-socket /tmp/ch-socket -d "{ \"desired_vcpus\": 4, \"desired_ram\" : 3221225472}" http://localhost/api/v1/vm.resize
```
The new memory is now available to use inside the VM:
```shell
free -h
total used free shared buff/cache available
Mem: 3.0Gi 71Mi 2.8Gi 0.0Ki 47Mi 2.8Gi
Swap: 32Mi 0B 32Mi
```
Due to guest OS limitations is is necessary to ensure that amount of memory added (between currently assigned RAM and that which is desired) is a multiple of 128MiB.
The same API can also be used to reduce the desired RAM for a VM but the change will not be applied until the VM is rebooted.
Memory and CPU resizing can be combined together into the same HTTP API request.

55
docs/intel_sgx.md Normal file
View File

@@ -0,0 +1,55 @@
# Intel SGX
Intel® Software Guard Extensions (Intel® SGX) is an Intel technology designed
to increase the security of application code and data. Cloud-Hypervisor supports
SGX virtualization through KVM. Because SGX is built on hardware features that
cannot be emulated in software, virtualizing SGX requires support in KVM and in
the host kernel. The required Linux and KVM changes can be found in the
[KVM SGX Tree](https://github.com/intel/kvm-sgx).
Utilizing SGX in the guest requires a kernel/OS with SGX support, e.g. a kernel
buit using the [SGX Linux Development Tree](https://github.com/jsakkine-intel/linux-sgx.git)
or the [KVM SGX Tree](https://github.com/intel/kvm-sgx). Running KVM SGX as the
guest kernel allows nested virtualization of SGX.
For more information about SGX, please refer to the [SGX Homepage](https://software.intel.com/sgx).
For more information about SGX SDK and how to test SGX, please refer to the
following [instructions](https://github.com/intel/linux-sgx).
## Cloud-Hypervisor support
Assuming the host exposes `/dev/sgx/virt_epc`, we can pass SGX enclaves through
the guest.
In order to use SGX enclaves within a Cloud-Hypervisor VM, we must define one
or several Enclave Page Cache (EPC) sections. Here is an example of a VM being
created with 2 EPC sections, the first one being 64MiB with pre-allocated
memory, the second one being 32MiB with no pre-allocated memory.
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=1G \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel bzImage \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--sgx-epc size=64M,prefault=on size=32M,prefault=off
```
Once booted, and assuming your guest kernel contains the patches from the
[KVM SGX Tree](https://github.com/intel/kvm-sgx), you can validate SGX devices
have been correctly created under `/dev/sgx`:
```bash
ls /dev/sgx
enclave provision virt_epc
```
From this point, it is possible to run any SGX application from the guest, as
it will access `/dev/sgx/enclave` device to create dedicated SGX enclaves.
Note: There is only one contiguous SGX EPC region, which contains all SGX EPC
sections. This region is exposed through ACPI and marked as reserved through
the e820 table. It is treated yet as another device, which means it should
appear at the end of the guest address space.

209
docs/iommu.md Normal file
View File

@@ -0,0 +1,209 @@
# Virtual IOMMU
## Rationales
Having the possibility to expose a virtual IOMMU to the guest can be
interesting to support specific use cases. That being said, it is always
important to keep in mind a virtual IOMMU can impact the performance of the
attached devices, which is the reason why one should be careful when enabling
this feature.
### Protect nested virtual machines
The first reason why one might want to expose a virtual IOMMU to the guest is
to increase the security regarding the memory accesses performed by the virtual
devices (VIRTIO devices), on behalf of the guest drivers.
With a virtual IOMMU, the VMM stands between the guest driver and its device
counterpart, validating and translating every address before to try accessing
the guest memory. This is standard interposition that is performed here by the
VMM.
The increased security does not apply for a simple case where we have one VM
per VMM. Because the guest cannot be trusted, as we always consider it could
be malicious and gain unauthorized privileges inside the VM, preventing some
devices from accessing the entire guest memory is pointless.
But let's take the interesting case of nested virtualization, and let's assume
we have a VMM running a first layer VM. This L1 guest is fully trusted as the
user intends to run multiple VMs from this L1. We can end up with multiple L2
VMs running on a single L1 VM. In this particular case, and without exposing a
virtual IOMMU to the L1 guest, it would be possible for any L2 guest to use the
device implementation from the host VMM to access the entire guest L1 memory.
The virtual IOMMU prevents from this kind of trouble as it will validate the
addresses the device is authorized to access.
### Achieve VFIO nested
Another reason for having a virtual IOMMU is to allow passing physical devices
from the host through multiple layers of virtualization. Let's take as example
a system with a physical IOMMU running a VM with a virtual IOMMU. The
implementation of the virtual IOMMU is responsible for updating the physical
DMA Remapping table (DMAR) everytime the DMA mapping changes. This must happen
through the VFIO framework on the host as this is the only userspace interface
to interact with a physical IOMMU.
Relying on this update mechanism, it is possible to attach physical devices to
the virtual IOMMU, which allows these devices to be passed from L1 to another
layer of virtualization.
## Why virtio-iommu?
The Cloud Hypervisor project decided to implement the brand new virtio-iommu
device in order to provide a virtual IOMMU to its users. The reason being the
simplicity brought by the paravirtualization solution. By having one side
handled from the guest itself, it removes the complexity of trapping memory
page accesses and shadowing them. This is why the project will not try to
implement a full emulation of a physical IOMMU.
## Pre-requisites
### Kernel
Since virtio-iommu has landed partially into the version 5.3 of the Linux
kernel, a special branch is needed to get things working with Cloud Hypervisor.
By partially, we are talking about x86 specifically, as it is already fully
functional for ARM architectures.
## Usage
In order to expose a virtual IOMMU to the guest, it is required to create a
virtio-iommu device and expose it through the ACPI IORT table. This can be
simply achieved by attaching at least one device to the virtual IOMMU.
The way to expose to the guest a specific device as sitting behind this IOMMU
is to explicitly tag it from the command line with the option `iommu=on`.
Not all devices support this extra option, and the default value will always
be `off` since we want to avoid the performance impact for most users who don't
need this.
Refer to the command line `--help` to find out which device support to be
attached to the virtual IOMMU.
Below is a simple example exposing the `virtio-blk` device as attached to the
virtual IOMMU:
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=512M \
--disk path=focal-server-cloudimg-amd64.raw,iommu=on \
--kernel custom-bzImage \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
```
From a guest perspective, it is easy to verify if the device is protected by
the virtual IOMMU. Check the directories listed under
`/sys/kernel/iommu_groups`:
```bash
ls /sys/kernel/iommu_groups
0
```
In this case, only one IOMMU group should be created. Under this group, it is
possible to find out the b/d/f of the device(s) part of this group.
```bash
ls /sys/kernel/iommu_groups/0/devices/
0000:00:03.0
```
And you can validate the device is the one we expect running `lspci`:
```bash
lspci
00:00.0 Host bridge: Intel Corporation Device 0d57
00:01.0 Unassigned class [ffff]: Red Hat, Inc. Device 1057
00:02.0 Unassigned class [ffff]: Red Hat, Inc. Virtio console
00:03.0 Mass storage controller: Red Hat, Inc. Virtio block device
00:04.0 Unassigned class [ffff]: Red Hat, Inc. Virtio RNG
```
## Faster mappings
By default, the guest memory is mapped with 4k pages and no huge pages, which
causes the virtual IOMMU device to be asked for 4k mappings only. This
configuration slows down the setup of the physical IOMMU as an important number
of requests need to be issued in order to create large mappings.
One use case is even more impacted by the slowdown, the nested VFIO case. When
passing a device through a L2 guest, the VFIO driver running in L1 will update
the DMAR entries for the specific device. Because VFIO pins the entire guest
memory, this means the entire mapping of the L2 guest need to be stored into
multiple 4k mappings. Obviously, the bigger the L2 guest RAM is, the longer the
update of the mappings will last. There is an additional problem happening in
this case, if the L2 guest RAM is quite large, it will require a large number
of mappings, which might exceed the VFIO limit set on the host. The default
value is 65536, which can simply be reached with a 256MiB sized RAM.
The way to solve both problems, the slowdown and the limit being exceeded, is
to reduce the amount of requests to describe those same large mappings. This
can be achieved by using 2MiB pages, known as huge pages. By seeing the guest
RAM as larger pages, and because the virtual IOMMU device supports it, the
guest will require less mappings, which will prevent the limit from being
exceeded, but also will take less time to process them on the host. That's
how using huge pages as much as possible can speed up VM boot time.
### Basic usage
Let's look at an example of how to run a guest with huge pages.
First, make sure your system has enough pages to cover the entire guest RAM:
```bash
# This example creates 4096 hugepages
echo 4096 > /proc/sys/vm/nr_hugepages
```
Next step is simply to create the VM. Two things are important, first we want
the VM RAM to be mapped on huge pages by backing it with `/dev/hugepages`. And
second thing, we need to create some huge pages in the guest itself so they can
be consumed.
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=8G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw hugepagesz=2M hugepages=2048" \
--net tap=,mac=,iommu=on
```
### Nested usage
Let's now look at the specific example of nested virtualization. In order to
reach optimized performances, the L2 guest also need to be mapped based on
huge pages. Here is how to achieve this, assuming the physical device you are
passing through is `0000:00:01.0`.
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=8G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw kvm-intel.nested=1 vfio_iommu_type1.allow_unsafe_interrupts rw hugepagesz=2M hugepages=2048" \
--device path=/sys/bus/pci/devices/0000:00:01.0,iommu=on
```
Once the L1 VM is running, unbind the device from the default driver in the
guest, and bind it to VFIO (it should appear as `0000:00:04.0`).
```bash
echo 0000:00:04.0 > /sys/bus/pci/devices/0000\:00\:04.0/driver/unbind
echo 8086 1502 > /sys/bus/pci/drivers/vfio-pci/new_id
```
Last thing is to start the L2 guest with the huge pages memory backend.
```bash
./cloud-hypervisor \
--cpus boot=1 \
--memory size=4G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--device path=/sys/bus/pci/devices/0000:00:04.0
```

467
docs/memory.md Normal file
View File

@@ -0,0 +1,467 @@
# Memory
Cloud-Hypervisor has many ways to expose memory to the guest VM. This document
aims to explain what Cloud-Hypervisor is capable of and how it can be used to
meet the needs of very different use cases.
## Basic Parameters
`MemoryConfig` or what is known as `--memory` from the CLI perspective is the
easiest way to get started with Cloud-Hypervisor.
```rust
struct MemoryConfig {
size: u64,
mergeable: bool,
shared: bool,
hugepages: bool,
hotplug_method: HotplugMethod,
hotplug_size: Option<u64>,
hotplugged_size: Option<u64>,
balloon: bool,
balloon_size: u64,
zones: Option<Vec<MemoryZoneConfig>>,
}
```
```
--memory <memory> Memory parameters "size=<guest_memory_size>,mergeable=on|off,shared=on|off,hugepages=on|off,hotplug_method=acpi|virtio-mem,hotplug_size=<hotpluggable_memory_size>,hotplugged_size=<hotplugged_memory_size>,balloon=on|off"
```
### `size`
Size of the RAM in the guest VM.
This option is mandatory when using the `--memory` parameter.
Value is an unsigned integer of 64 bits.
_Example_
```
--memory size=1G
```
### `mergeable`
Specifies if the pages from the guest RAM must be marked as _mergeable_. In
case this option is `true` or `on`, the pages will be marked with `madvise(2)`
to let the host kernel know which pages are eligible for being merged by the
KSM daemon.
This option can be used when trying to reach a higher density of VMs running
on a single host, as it will reduce the amount of memory consumed by each VM.
By default this option is turned off.
_Example_
```
--memory size=1G,mergeable=on
```
### `shared`
Specifies if the memory must be `mmap(2)` with `MAP_SHARED` flag.
By sharing a memory mapping, one can share the guest RAM with other processes
running on the host. One can use this option when running vhost-user devices
as part of the VM device model, as they will be driven by standalone daemons
needing access to the guest RAM content.
By default this option is turned off, which results in performing `mmap(2)`
with `MAP_PRIVATE` flag.
_Example_
```
--memory size=1G,shared=on
```
### `hugepages`
Specifies if the memory must be `mmap(2)` with `MAP_HUGETLB` and `MAP_HUGE_2MB`
flags. This performs a memory mapping relying on 2MiB pages instead of the
default 4kiB pages.
By using hugepages, one can improve the overall performance of the VM, assuming
the guest will allocate hugepages as well. Another interesting use case is VFIO
as it speeds up the VM's boot time since the amount of IOMMU mappings are
reduced.
By default this option is turned off.
_Example_
```
--memory size=1G,hugepages=on
```
### `hotplug_method`
Selects the way of adding and/or removing memory to/from a booted VM.
Possible values are `acpi` and `virtio-mem`. Default value is `acpi`.
_Example_
```
--memory size=1G,hotplug_method=acpi
```
### `hotplug_size`
Amount of memory that can be dynamically added to the VM.
Value is an unsigned integer of 64 bits. A value of 0 is invalid.
_Example_
```
--memory size=1G,hotplug_size=1G
```
### `hotplugged_size`
Amount of memory that will be dynamically added to the VM at boot. This option
allows for starting a VM with a certain amount of memory that can be reduced
during runtime.
This is only valid when the `hotplug_method` is `virtio-mem` as it does not
make sense for the `acpi` use case. When using ACPI, the memory can't be
resized after it has been extended.
This option is only valid when `hotplug_size` is specified, and its value can't
exceed the value of `hotplug_size`.
Value is an unsigned integer of 64 bits. A value of 0 is invalid.
_Example_
```
--memory size=1G,hotplug_method=virtio-mem,hotplug_size=1G,hotplugged_size=512M
```
### `balloon`
Specifies if the `virtio-balloon` device must be activated. This creates a
dedicated virtio device for managing the balloon in the guest, which allows
guest to access more or less memory depending on the balloon size.
By default this option is turned off.
_Example_
```
--memory size=1G,balloon=on
```
## Advanced Parameters
`MemoryZoneConfig` or what is known as `--memory-zone` from the CLI perspective
is a power user parameter. It allows for a full description of the guest RAM,
describing how every memory region is backed and exposed to the guest.
```rust
struct MemoryZoneConfig {
id: String,
size: u64,
file: Option<PathBuf>,
shared: bool,
hugepages: bool,
host_numa_node: Option<u32>,
hotplug_size: Option<u64>,
hotplugged_size: Option<u64>,
}
```
```
--memory-zone <memory-zone> User defined memory zone parameters "size=<guest_memory_region_size>,file=<backing_file>,shared=on|off,hugepages=on|off,host_numa_node=<node_id>,id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,hotplugged_size=<hotplugged_memory_size>"
```
This parameter expects one or more occurences, allowing for a list of memory
zones to be defined. It must be used with `--memory size=0`, clearly indicating
that the memory will be described through advanced parameters.
Each zone is given a list of options which we detail through the following
sections.
### `id`
Memory zone identifier. This identifier must be unique, otherwise an error will
be returned.
This option is useful when referring to a memory zone previously created. In
particular, the `--numa` parameter can associate a memory zone to a specific
NUMA node based on the memory zone identifier.
This option is mandatory when using the `--memory-zone` parameter.
Value is a string.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G
```
### `size`
Size of the memory zone.
This option is mandatory when using the `--memory-zone` parameter.
Value is an unsigned integer of 64 bits.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G
```
### `file`
Path to the file backing the memory zone. This can be either a file or a
directory. In case of a file, it will be opened and used as the backing file
for the `mmap(2)` operation. In case of a directory, a temporary file with no
hard link on the filesystem will be created. This file will be used as the
backing file for the `mmap(2)` operation.
This option can be particularly useful when trying to back a part of the guest
RAM with a well known file. In the context of the snapshot/restore feature, and
if the provided path is a file, the snapshot operation will not perform any
copy of the guest RAM content for this specific memory zone since the user has
access to it and it would duplicate data already stored on the current
filesystem.
Value is a string.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G,file=/foo/bar
```
### `shared`
Specifies if the memory zone must be `mmap(2)` with `MAP_SHARED` flag.
By sharing a memory zone mapping, one can share part of the guest RAM with
other processes running on the host. One can use this option when running
vhost-user devices as part of the VM device model, as they will be driven
by standalone daemons needing access to the guest RAM content.
By default this option is turned off, which result in performing `mmap(2)`
with `MAP_PRIVATE` flag.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G,shared=on
```
### `hugepages`
Specifies if the memory zone must be `mmap(2)` with `MAP_HUGETLB` and
`MAP_HUGE_2MB` flags. This performs a memory zone mapping relying on 2MiB
pages instead of the default 4kiB pages.
By using hugepages, one can improve the overall performance of the VM, assuming
the guest will allocate hugepages as well. Another interesting use case is VFIO
as it speeds up the VM's boot time since the amount of IOMMU mappings are
reduced.
By default this option is turned off.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G,hugepages=on
```
### `host_numa_node`
Node identifier of a node present on the host. This option will let the user
pick a specific NUMA node from which the memory must be allocated. After the
memory zone is `mmap(2)`, the NUMA policy for this memory mapping will be
applied through `mbind(2)`, relying on the provided node identifier. If the
node does not exist on the host, the call to `mbind(2)` will fail.
This option is useful when trying to back a VM memory with a specific type of
memory from the host. Assuming a host has two types of memory, with one slower
than the other, each related to a distinct NUMA node, one could create a VM
with slower memory accesses by backing the entire guest RAM from the furthest
NUMA node on the host.
This option also gives the opportunity to create a VM with non uniform memory
accesses as one could define a first memory zone backed by fast memory, and a
second memory zone backed by slow memory.
Value is an unsigned integer of 32 bits.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G,host_numa_node=0
```
### `hotplug_size`
Amount of memory that can be dynamically added to the memory zone. Since
`virtio-mem` is the only way of resizing a memory zone, one must specify
the `hotplug_method=virtio-mem` to the `--memory` parameter.
Value is an unsigned integer of 64 bits. A value of 0 is invalid.
_Example_
```
--memory size=0,hotplug_method=virtio-mem
--memory-zone id=mem0,size=1G,hotplug_size=1G
```
### `hotplugged_size`
Amount of memory that will be dynamically added to a memory zone at VM's boot.
This option allows for starting a VM with a certain amount of memory that can
be reduced during runtime.
This is only valid when the `hotplug_method` is `virtio-mem` as it does not
make sense for the `acpi` use case. When using ACPI, the memory can't be
resized after it has been extended.
This option is only valid when `hotplug_size` is specified, and its value can't
exceed the value of `hotplug_size`.
Value is an unsigned integer of 64 bits. A value of 0 is invalid.
_Example_
```
--memory size=0,hotplug_method=virtio-mem
--memory-zone id=mem0,size=1G,hotplug_size=1G,hotplugged_size=512M
```
## NUMA settings
`NumaConfig` or what is known as `--numa` from the CLI perspective has been
introduced to define a guest NUMA topology. It allows for a fine description
about the CPUs and memory ranges associated with each NUMA node. Additionally
it allows for specifying the distance between each NUMA node.
```rust
struct NumaConfig {
id: u32,
cpus: Option<Vec<u8>>,
distances: Option<Vec<NumaDistance>>,
memory_zones: Option<Vec<String>>,
}
```
```
--numa <numa> Settings related to a given NUMA node "id=<node_id>,cpus=<cpus_id>,distances=<list_of_distances_to_destination_nodes>,memory_zones=<list_of_memory_zones>"
```
### `guest_numa_id`
Node identifier of a guest NUMA node. This identifier must be unique, otherwise
an error will be returned.
This option is mandatory when using the `--numa` parameter.
Value is an unsigned integer of 32 bits.
_Example_
```
--numa guest_numa_id=0
```
### `cpus`
List of virtual CPUs attached to the guest NUMA node identified by the
`guest_numa_id` option. This allows for describing a list of CPUs which
must be seen by the guest as belonging to the NUMA node `guest_numa_id`.
One can use this option for a fine grained description of the NUMA topology
regarding the CPUs associated with it, which might help the guest run more
efficiently.
Multiple values can be provided to define the list. Each value is an unsigned
integer of 8 bits.
For instance, if one needs to attach all CPUs from 0 to 4 to a specific node,
the syntax using `-` will help define a contiguous range with `cpus=0-4`. The
same example could also be described with `cpus=0:1:2:3:4`.
A combination of both `-` and `:` separators is useful when one might need to
describe a list containing all CPUs from 0 to 99 and the CPU 255, as it could
simply be described with `cpus=0-99:255`.
_Example_
```
--cpus boot=8
--numa guest_numa_id=0,cpus=1-3:7
--numa guest_numa_id=1,cpus=0:4-6
```
### `distances`
List of distances between the current NUMA node referred by `guest_numa_id`
and the destination NUMA nodes listed along with distances. This option let
the user choose the distances between guest NUMA nodes. This is important to
provide an accurate description of the way non uniform memory accesses will
perform in the guest.
One or more tuple of two values must be provided through this option. The first
value is an unsigned integer of 32 bits as it represents the destination NUMA
node. The second value is an unsigned integer of 8 bits as it represents the
distance between the current NUMA node and the destination NUMA node. The two
values are separated by `@` (`value1@value2`), meaning the destination NUMA
node `value1` is located at a distance of `value2`. Each tuple is separated
from the others with `:` separator.
For instance, if one wants to define 3 NUMA nodes, with each node located at
different distances, it can be described with the following example.
_Example_
```
--numa guest_numa_id=0,distances=1@15:2@25
--numa guest_numa_id=1,distances=0@15:2@20
--numa guest_numa_id=2,distances=0@25:1@20
```
### `memory_zones`
List of memory zones attached to the guest NUMA node identified by the
`guest_numa_id` option. This allows for describing a list of memory ranges
which must be seen by the guest as belonging to the NUMA node `guest_numa_id`.
This option can be very useful and powerful when combined with `host_numa_node`
option from `--memory-zone` parameter as it allows for creating a VM with non
uniform memory accesses, and let the guest know about it. It allows for
exposing memory zones through different NUMA nodes, which can help the guest
workload run more efficiently.
Multiple values can be provided to define the list. Each value is a string
referring to an existing memory zone identifier. Values are separated from
each other with the `:` separator.
_Example_
```
--memory size=0
--memory-zone id=mem0,size=1G
--memory-zone id=mem1,size=1G
--memory-zone id=mem2,size=1G
--numa guest_numa_id=0,memory_zones=mem0:mem2
--numa guest_numa_id=1,memory_zones=mem1
```

View File

@@ -1,6 +1,21 @@
# How to use networking
cloud-hypervisor can emulate one or more virtual network interfaces, represented at the hypervisor host by [tap devices](https://www.kernel.org/doc/Documentation/networking/tuntap.txt"). This guide briefly describes, in a manual and distribution neutral way, how to setup and use networking with cloud-hypevisor.
cloud-hypervisor can emulate one or more virtual network interfaces, represented at the hypervisor host by [tap devices](https://www.kernel.org/doc/Documentation/networking/tuntap.txt). This guide briefly describes, in a manual and distribution neutral way, how to setup and use networking with cloud-hypevisor.
## Multiple queue support for net devices ##
While multiple vcpus defined for guest, to gain the benefit of vcpu scalable to improve performance, it suggests to define multiple queue pairs for net devices, one Tx/Rx queue pair per one vcpu, that means the number of queue pairs at least is equal to the vcpu count. In that case, after virtnet driver set cpu affinity for virtqueues in guest kernel, vcpus could handle interrupt from different virtqueue pairs in parallel.
It will gain better performance for guest that has multiple queues defined for net devices while it has multiple net sessions running in userspace.
To enable multiple queue support in cloud-hypervisor, multiple queue pairs will be defined, while multiple tap fds will be opened for the same tap device, it will also have multiple threads started, each thread will monitor and handle the events from each virtqueue pairs and the associated tap fd.
Note:
- Currently, it does not support to use ethtool to change the combined queue numbers in guest.
- Multiple queue is enabled for vhost-user-net backend in cloud-hypervisor, however, multiple thread is not added to handle mq, thus, the performance for vhost-user-net backend is not supposed to be improved. The multiple thread will be added for backend later.
- Performance test for vhost-user-net will be covered once vhost-user-net backend has mulitple thread supported.
- Performance test for virtio-net is done by comparing 2 queue pairs with 1 queue pairs, that to run 2 iperf3 sessions in the same test environments, throughput is improved about 37%.
## Start cloud-hypervisor with net devices
@@ -10,21 +25,37 @@ Use one `--net` command-line argument from cloud-hypervisor to specify the emula
./cloud-hypervisor \
--cpus 4 \
--memory "size=512M" \
--disk my-root-disk.img \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel my-vmlinux.bin \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \
--net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0 \
tap=ich1,mac=a4:a1:c2:00:00:02,ip=10.0.1.2,mask=255.255.255.0
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0,num_queues=2,queue_size=256 \
tap=ich1,mac=a4:a1:c2:00:00:02,ip=10.0.1.2,mask=255.255.255.0,num_queues=2,queue_size=256
```
The `--net` argument takes 1 or more space-separated strings of key value pairs containing the following 4 keys or fields:
| Name | Purpose | Optional |
| -------- |----------------------------| ----------|
| tap | tap device name | Yes |
| mac | vNIC mac address | Yes |
| ip | tap IP IP address | yes |
| mask | tap IP netmask | Yes |
| Name | Purpose | Optional |
| -----------|----------------------------| ----------|
| tap | tap device name | Yes |
| mac | vNIC mac address | Yes |
| ip | tap IP IP address | yes |
| mask | tap IP netmask | Yes |
| num_queues | the number of queues | yes |
| queue_size | the size of each queue | Yes |
num_queues is the total number of tx and rx queues, the default value is 2, and it could be increased by multiples of 2. Additionally, num_queues is suggested to be as 2 times of vcpu count. The default value for queue_size is 256.
If the tap device is pre-created on host before guest boot up. To use multiple queue support for net device in guest, the tap device should be opened like this from host.
```bash
[root@localhost ~]# ip tuntap add name ich0 mode tap multi_queue
```
And the `--net` device should specify support for multiple queues. `num_queues` must be a multiple of 2 starting at least from 4 since multiple queues really means multiple queue pairs. We need at least 2 pairs for this configuration to be correct:
```bash
--net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0,num_queues=4,queue_size=256
```
## Configure the tap devices

112
docs/snapshot_restore.md Normal file
View File

@@ -0,0 +1,112 @@
# Snapshot and Restore
The goal for the snapshot/restore feature is to provide the user with the
ability to take a snapshot of a previously paused virtual machine. This
snapshot can be used as the base for creating new identical virtual machines,
without the need to boot them from scratch. The restore codepath takes the
snapshot and creates the exact same virtual machine, restoring the previously
saved states. The new virtual machine is restored in a paused state, as it was
before the snapshot was performed.
This feature is important for the project as it establishes the first step
towards the support for live migration.
## Snapshot a Cloud-Hypervisor VM
First thing, we must run a Cloud-Hypervisor VM:
```bash
./cloud-hypervisor \
--api-socket /tmp/cloud-hypervisor.sock \
--cpus boot=4 \
--memory size=4G \
--kernel bzImage \
--cmdline "root=/dev/vda1 console=hvc0 rw" \
--disk path=focal-server-cloudimg-amd64.raw
```
At any point in time when the VM is running, one might choose to pause it:
```bash
./ch-remote --api-socket=/tmp/cloud-hypervisor.sock pause
```
Once paused, the VM can be safely snapshot into the specified directory and
using the following command:
```bash
./ch-remote --api-socket=/tmp/cloud-hypervisor.sock snapshot file:///home/foo/snapshot
```
Given the directory was present on the system, the snapshot will succeed and
it should contain the following files:
```bash
ll /home/foo/snapshot/
total 4194536
drwxrwxr-x 2 foo bar 4096 Jul 22 11:50 ./
drwxr-xr-x 47 foo bar 4096 Jul 22 11:47 ../
-rw------- 1 foo bar 3221225472 Jul 22 11:19 memory-region-0
-rw------- 1 foo bar 1073741824 Jul 22 11:19 memory-region-1
-rw------- 1 foo bar 217853 Jul 22 11:19 vm.json
```
In this particular example, we can observe that 2 memory region files were
created. That is explained by the size of the guest RAM, which is 4GiB in this
case. Because it exceeds 3GiB (which is where we can find a ~1GiB memory hole),
Cloud-Hypervisor needs 2 distincts memory regions to be created. Each memory
region's content is stored through a dedicated file, which explains why we end
up with 2 different files, the first one containing the guest RAM range 0-3GiB
and the second one containing the guest RAM range 3-4GiB.
`vm.json` gathers all information related to the virtual machine configuration
and state. The configuration bits are used to create a similar virtual machine
with the correct amount of CPUs, RAM, and other expected devices. The state
bits are used to restore each component in the state it was left before the
snapshot occured.
## Restore a Cloud-Hypervisor VM
Given that one has access to an existing snapshot in `/home/foo/snapshot`,
it is possible to create a new VM based on this snapshot with the following
command:
```bash
./cloud-hypervisor \
--api-socket /tmp/cloud-hypervisor.sock \
--restore source_url=file:///home/foo/snapshot
```
Or using two different commands from two terminals:
```bash
# First terminal
./cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
# Second terminal
./ch-remote --api-socket=/tmp/cloud-hypervisor.sock restore source_url=file:///home/foo/snapshot
```
Remember the VM is restored in a `paused` state, which was the VM's state when
it was snapshot. For this reason, one must explicitly `resume` the VM before to
start using it.
```bash
./ch-remote --api-socket=/tmp/cloud-hypervisor.sock resume
```
At this point, the VM is fully restored and is identical to the VM which was
snapshot earlier.
## Limitations
The support of snapshot/restore feature is still experimental, meaning one
might still find some bugs associated with it.
Additionally, some devices and features don't support to be snapshot and
restored yet:
- `vhost-user` devices
- `virtio-mem`
- Intel SGX
VFIO devices are out of scope.

View File

@@ -66,13 +66,13 @@ takes the device's sysfs path as an argument. In our example it is
```
./target/debug/cloud-hypervisor \
--kernel ~/vmlinux \
--disk ~/clear-29160-kvm.img \
--disk path=~/focal-server-cloudimg-amd64.raw \
--console off \
--serial tty \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--cmdline "console=ttyS0 root=/dev/vda1 rw" \
--cpus 4 \
--memory size=512M \
--device /sys/bus/pci/devices/0000:01:00.0/
--device path=/sys/bus/pci/devices/0000:01:00.0/
```
The guest kernel will then detect the card reader on its PCI bus and provided

View File

@@ -0,0 +1,104 @@
# How to test vhost-user-blk with SPDK
The purpose of this document is to illustrate how to test vhost-user-blk in Cloud Hypervisor with SPDK as the backend.
## Framework
It's a simple test to validate the block read/write between VM and block backend.
```
+----+----------+ +-------------+-----------+
| | | | | |
| |vhost-user|----------| vhost-user | dpdk |
| |blk device| | port 1 | |
| | | | | |
| +----------+ +-------------+-----------+
| | | |
| vm | | spdk |
| | | |
+--+----------------------------------------------------+--+
| | hugepages | |
| +----------------------------------------------------+ |
| |
| host |
| |
+----------------------------------------------------------+
```
## Prerequisites
Prior to running the test, the following steps need to be performed.
- Enable hugepages
- Install SPDK
Here are some good references for detailing them.
- spdk
* https://spdk.io/doc/
## Test environment
The below test environment is based on ubuntu release(16.04.1 LTS), as for other system, please check related document.
The test runs with multiple queue (MQ) support enabled, using 4 queues defined for both SPDK and the virtual machine.
Here are the details on how the test can be run.
### The hugepages settings in host linux
Add "default_hugepagesz=1G hugepagesz=1G hugepages=2" into host linux cmdline.
As for how to change Ubuntu linux cmdline in grub file, please ref below link:
https://www.ostechnix.com/configure-grub-2-boot-loader-settings-ubuntu-16-04/
reboot Ubuntu
sudo mount -t hugetlbfs -o pagesize=1G none /dev/hugepages
### Download the SPDK code
git clone https://github.com/spdk/spdk
cd spdk
git submodule update --init
### Create the build dep
./scripts/pkgdep.sh
### Build spdk
./configure
make
### Set the SPDk environment
sudo HUGEMEM=2048 scripts/setup.sh
sudo ./app/vhost/vhost -S /var/tmp -s 1024 -m 0x3 &
### Create 512M block device
sudo scripts/rpc.py bdev_malloc_create 512 512 -b Malloc0
sudo scripts/rpc.py vhost_create_blk_controller --cpumask 0x1 vhost.1 Malloc0
_Launch the VM_
VMs run in client mode. They connect to the socket created by the `dpdkvhostuser` in the SPDK backend.
```bash
# From the test terminal. We need to create one vhost-user-blk device for the --disk.
./cloud-hypervisor \
--cpus boot=4 \
--memory size=1024M,hugepages=on,shared=true \
--kernel linux/arch/x86/boot/compressed/vmlinux.bin \
--cmdline "console=ttyS0 root=/dev/vda1 rw iommu=off" \
--disk path=images/focal-server-cloudimg-amd64.raw vhost_user=true,socket=/var/tmp/vhost.1,num_queues=4,queue_size=128 \
--console off \
--serial tty \
--rng
```
```bash
# How to test the vhost-user-blk device with SPDK backend
login in guest
# Use lsblk command to find out vhost-user-blk device
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 2.2G 0 disk
├─vda1 252:1 0 2.1G 0 part /
├─vda14 252:14 0 4M 0 part
└─vda15 252:15 0 106M 0 part /boot/efi
vdb 253:16 0 512M 0 disk
The vhost-user-blk device is /dev/vdb
# How to do simple read/write test
dd if=/dev/vdb of=/dev/null bs=2M iflag=direct
dd of=/dev/vdb if=/dev/zero bs=2M oflag=direct count=256
If you want to do fio test, please install fio binary into guest. The detailed info is not listed here.

View File

@@ -0,0 +1,132 @@
# How to test Vhost-user net with OpenVSwitch/DPDK
The purpose of this document is to illustrate how to test vhost-user-net in cloud-hypervisor with OVS/DPDK as the backend.
## Framework
It's a simple test to validate the communication between two virtual machine, connecting them to vhost-user ports respectively provided by `OVS/DPDK`.
```
+----+----------+ +-------------+-----------+-------------+ +----------+----+
| | | | | | | | | |
| |vhost-user|----------| vhost-user | ovs | vhost-user |----------|vhost-user| |
| |net device| | port 1 | | port 2 | |net device| |
| | | | | | | | | |
| +----------+ +-------------+-----------+-------------+ +----------+ |
| | | | | |
|vm1 | | dpdk | | vm2 |
| | | | | |
+--+---------------------------------------------------------------------------------------------+--+
| | hugepages | |
| +---------------------------------------------------------------------------------------------+ |
| |
| host |
| |
+---------------------------------------------------------------------------------------------------+
```
## Prerequisites
Prior to running the test, the following steps need to be performed.
- Enable hugepages
- Install DPDK
- Install OVS
Here are some good references for detailing them.
- Red Hat
* https://wiki.qemu.org/Documentation/vhost-user-ovs-dpdk
- Ubuntu server
* https://help.ubuntu.com/lts/serverguide/DPDK.html
* https://software.intel.com/en-us/articles/set-up-open-vswitch-with-dpdk-on-ubuntu-server
## Test
The test runs with multiple queue (MQ) support enabled, using 2 pairs of TX/RX queues defined for both OVS and the virtual machine. Here are the details on how the test can be run.
_Setup OVS_
`ovs_test.sh` is created to setup and start OVS. OVS will provide the `dpdkvhostuser` backend running in server mode.
```bash
mkdir -p /var/run/openvswitch
modprobe openvswitch
killall ovsdb-server ovs-vswitchd
rm -f /var/run/openvswitch/vhost-user*
rm -f /etc/openvswitch/conf.db
export DB_SOCK=/var/run/openvswitch/db.sock
ovsdb-tool create /etc/openvswitch/conf.db /usr/share/openvswitch/vswitch.ovsschema
ovsdb-server --remote=punix:$DB_SOCK --remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile --detach
ovs-vsctl --no-wait init
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-lcore-mask=0xf
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem=1024
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0xf
ovs-vswitchd unix:$DB_SOCK --pidfile --detach --log-file=/var/log/openvswitch/ovs-vswitchd.log
ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev
ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser
ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser
ovs-vsctl set Interface vhost-user1 options:n_rxq=2
ovs-vsctl set Interface vhost-user2 options:n_rxq=2
```
_Run ovs_test.sh_
```bash
./ovs_test.sh
```
_Launch the VMs_
VMs run in client mode. They connect to the socket created by the `dpdkvhostuser` backend.
```bash
# From one terminal. We need to give the cloud-hypervisor binary the NET_ADMIN capabilities for it to set TAP interfaces up on the host.
./cloud-hypervisor \
--cpus boot=2 \
--memory size=512M,hugepages=on,shared=true \
--kernel vmlinux \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--disk path=focal-server-cloudimg-amd64.raw \
--net mac=52:54:00:02:d9:01,vhost_user=true,socket=/var/run/openvswitch/vhost-user1,num_queues=4
# From another terminal. We need to give the cloud-hypervisor binary the NET_ADMIN capabilities for it to set TAP interfaces up on the host.
./cloud-hypervisor \
--cpus boot=2 \
--memory size=512M,hugepages=on,shared=true \
--kernel vmlinux \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--disk path=focal-server-cloudimg-amd64.raw \
--net "mac=52:54:20:11:C5:02,vhost_user=true,socket=/var/run/openvswitch/vhost-user2,num_queues=4"
```
_Setup VM1_
```bash
# From inside the guest
sudo ip addr add 172.100.0.1/24 dev enp0s3
```
_Setup VM2_
```bash
# From inside the guest
sudo ip addr add 172.100.0.2/24 dev enp0s3
```
_Ping VM1 from VM2_
```bash
# From inside the guest
sudo ping 172.100.0.1
```
_Ping VM2 from VM1_
```bash
# From inside the guest
sudo ping 172.100.0.2
```
__Result:__ At this point, VM1 and VM2 can ping each other successfully. We can now run `iperf3` test.
_Run VM1 as server_
```bash
# From inside the guest
iperf3 -s -p 4444
```
_Run VM2 as client_
```bash
# From inside the guest
iperf3 -c 172.100.0.1 -t 30 -p 4444 &
```

4
fuzz/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
target
corpus
artifacts

41
fuzz/Cargo.toml Normal file
View File

@@ -0,0 +1,41 @@
[package]
name = "cloud-hypervisor-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"
[package.metadata]
cargo-fuzz = true
[dependencies]
libc = "0.2.72"
libfuzzer-sys = "0.3"
qcow = { path = "../qcow" }
virtio-devices = { path = "../virtio-devices" }
vmm-sys-util = ">=0.3.1"
vm-virtio = { path = "../vm-virtio" }
vm-memory = "0.2.1"
[dependencies.cloud-hypervisor]
path = ".."
[patch.crates-io]
vm-memory = { git = "https://github.com/cloud-hypervisor/vm-memory", branch = "ch" }
# Prevent this from interfering with workspaces
[workspace]
members = ["."]
[[bin]]
name = "qcow"
path = "fuzz_targets/qcow.rs"
test = false
doc = false
[[bin]]
name = "block"
path = "fuzz_targets/block.rs"
test = false
doc = false

136
fuzz/fuzz_targets/block.rs Normal file
View File

@@ -0,0 +1,136 @@
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![no_main]
use libfuzzer_sys::fuzz_target;
use std::ffi;
use std::fs::File;
use std::io::{self, Cursor, Read, Seek, SeekFrom};
use std::mem::size_of;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::path::PathBuf;
use std::sync::Arc;
use virtio_devices::{Block, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use vm_memory::{Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryMmap};
use vm_virtio::Queue;
use vmm_sys_util::eventfd::EventFd;
const MEM_SIZE: u64 = 256 * 1024 * 1024;
const DESC_SIZE: u64 = 16; // Bytes in one virtio descriptor.
const QUEUE_SIZE: u16 = 16; // Max entries in the queue.
const CMD_SIZE: usize = 16; // Bytes in the command.
fuzz_target!(|bytes| {
let size_u64 = size_of::<u64>();
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE as usize)]).unwrap();
// The fuzz data is interpreted as:
// starting index 8 bytes
// command location 8 bytes
// command 16 bytes
// descriptors circular buffer 16 bytes * 3
if bytes.len() < 4 * size_u64 {
// Need an index to start.
return;
}
let mut data_image = Cursor::new(bytes);
let first_index = read_u64(&mut data_image);
if first_index > MEM_SIZE / DESC_SIZE {
return;
}
let first_offset = first_index * DESC_SIZE;
if first_offset as usize + size_u64 > bytes.len() {
return;
}
let command_addr = read_u64(&mut data_image);
if command_addr > MEM_SIZE - CMD_SIZE as u64 {
return;
}
if mem
.write_slice(
&bytes[2 * size_u64..(2 * size_u64) + CMD_SIZE],
GuestAddress(command_addr as u64),
)
.is_err()
{
return;
}
data_image.seek(SeekFrom::Start(first_offset)).unwrap();
let desc_table = read_u64(&mut data_image);
if mem
.write_slice(&bytes[32..], GuestAddress(desc_table as u64))
.is_err()
{
return;
}
let mut q = Queue::new(QUEUE_SIZE);
q.ready = true;
q.size = QUEUE_SIZE / 2;
q.max_size = QUEUE_SIZE;
let queue_evts: Vec<EventFd> = vec![EventFd::new(0).unwrap()];
let queue_fd = queue_evts[0].as_raw_fd();
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(queue_fd)) };
let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
let disk_file: File = unsafe { File::from_raw_fd(shm) };
let raw_img = qcow::RawFile::new(disk_file, false);
let mut block = Block::new(
"tmp".to_owned(),
raw_img,
PathBuf::from(""),
false,
false,
2,
256,
)
.unwrap();
block
.activate(
GuestMemoryAtomic::new(mem),
Arc::new(NoopVirtioInterrupt {}),
vec![q],
queue_evts,
)
.ok();
queue_evt.write(77).unwrap(); // Rings the doorbell, any byte will do.
});
fn read_u64<T: Read>(readable: &mut T) -> u64 {
let mut buf = [0u8; size_of::<u64>()];
readable.read_exact(&mut buf[..]).unwrap();
u64::from_le_bytes(buf)
}
fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> {
let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
if res < 0 {
Err(io::Error::last_os_error())
} else {
Ok(res as RawFd)
}
}
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(
&self,
_int_type: &VirtioInterruptType,
_queue: Option<&Queue>,
) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}

49
fuzz/fuzz_targets/qcow.rs Normal file
View File

@@ -0,0 +1,49 @@
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
#![no_main]
use libfuzzer_sys::fuzz_target;
use qcow::{QcowFile, RawFile};
use std::ffi;
use std::fs::File;
use std::io::{self, Cursor, Read, Seek, SeekFrom, Write};
use std::mem::size_of;
use std::os::unix::io::{FromRawFd, RawFd};
// Take the first 64 bits of data as an address and the next 64 bits as data to
// store there. The rest of the data is used as a qcow image.
fuzz_target!(|bytes| {
if bytes.len() < 16 {
// Need an address and data, each are 8 bytes.
return;
}
let mut disk_image = Cursor::new(bytes);
let addr = read_u64(&mut disk_image);
let value = read_u64(&mut disk_image);
let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
let mut disk_file: File = unsafe { File::from_raw_fd(shm) };
disk_file.write_all(&bytes[16..]).unwrap();
disk_file.seek(SeekFrom::Start(0)).unwrap();
if let Ok(mut qcow) = QcowFile::from(RawFile::new(disk_file, false)) {
if qcow.seek(SeekFrom::Start(addr)).is_ok() {
let _ = qcow.write_all(&value.to_le_bytes());
}
}
});
fn read_u64<T: Read>(readable: &mut T) -> u64 {
let mut buf = [0u8; size_of::<u64>()];
readable.read_exact(&mut buf[..]).unwrap();
u64::from_le_bytes(buf)
}
fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> {
let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
if res < 0 {
Err(io::Error::last_os_error())
} else {
Ok(res as RawFd)
}
}

25
hypervisor/Cargo.toml Normal file
View File

@@ -0,0 +1,25 @@
[package]
name = "hypervisor"
version = "0.1.0"
authors = ["Muminul Islam <muislam@microsoft.com>"]
edition = "2018"
[features]
kvm = []
[dependencies]
anyhow = "1.0"
thiserror = "1.0"
libc = "0.2.77"
log = "0.4.11"
kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch", features = ["with-serde", "fam-wrappers"] }
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vm-memory = { version = "0.2.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = ">=0.5.0", features = ["with-serde"] }
[dependencies.linux-loader]
git = "https://github.com/rust-vmm/linux-loader"
features = ["elf", "bzimage"]

View File

@@ -1,15 +1,15 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
#![allow(clippy::all)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
pub mod virtio_blk;
pub mod virtio_net;
pub mod virtio_ring;
#[cfg(target_arch = "x86_64")]
pub mod x86;

View File

@@ -0,0 +1,36 @@
// 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
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[allow(non_upper_case_globals)]
#[allow(unused)]
#[allow(
clippy::unreadable_literal,
clippy::redundant_static_lifetimes,
clippy::trivially_copy_pass_by_ref,
clippy::useless_transmute,
clippy::should_implement_trait,
clippy::transmute_ptr_to_ptr,
clippy::unreadable_literal,
clippy::redundant_static_lifetimes
)]
pub mod msr_index;
// MTRR constants
pub const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11
pub const MTRR_MEM_TYPE_WB: u64 = 0x6;
// IOAPIC pins
pub const NUM_IOAPIC_PINS: usize = 24;

323
hypervisor/src/cpu.rs Normal file
View File

@@ -0,0 +1,323 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
#[cfg(target_arch = "aarch64")]
use crate::aarch64::VcpuInit;
use crate::{CpuState, MpState};
#[cfg(target_arch = "x86_64")]
use crate::x86_64::{
CpuId, ExtendedControlRegisters, FpuState, LapicState, MsrEntries, SpecialRegisters,
StandardRegisters, VcpuEvents, Xsave,
};
use thiserror::Error;
#[derive(Error, Debug)]
///
/// Enum for CPU error
pub enum HypervisorCpuError {
///
/// Setting standard registers error
///
#[error("Failed to set standard register: {0}")]
SetStandardRegs(#[source] anyhow::Error),
///
/// Setting standard registers error
///
#[error("Failed to get standard registers: {0}")]
GetStandardRegs(#[source] anyhow::Error),
///
/// Setting special register error
///
#[error("Failed to set special registers: {0}")]
SetSpecialRegs(#[source] anyhow::Error),
///
/// Getting standard register error
///
#[error("Failed to get special registers: {0}")]
GetSpecialRegs(#[source] anyhow::Error),
///
/// Setting floating point registers error
///
#[error("Failed to set special register: {0}")]
SetFloatingPointRegs(#[source] anyhow::Error),
///
/// Getting floating point register error
///
#[error("Failed to get special register: {0}")]
GetFloatingPointRegs(#[source] anyhow::Error),
///
/// Setting Cpuid error
///
#[error("Failed to set Cpuid: {0}")]
SetCpuid(#[source] anyhow::Error),
///
/// Getting Cpuid error
///
#[error("Failed to get Cpuid: {0}")]
GetCpuid(#[source] anyhow::Error),
///
/// Setting lapic state error
///
#[error("Failed to set Lapic state: {0}")]
SetLapicState(#[source] anyhow::Error),
///
/// Getting Lapic state error
///
#[error("Failed to get Lapic state: {0}")]
GetlapicState(#[source] anyhow::Error),
///
/// Setting MSR entries error
///
#[error("Failed to set Msr entries: {0}")]
SetMsrEntries(#[source] anyhow::Error),
///
/// Getting Msr entries error
///
#[error("Failed to get Msr entries: {0}")]
GetMsrEntries(#[source] anyhow::Error),
///
/// Setting MSR entries error
///
#[error("Failed to set MP state: {0}")]
SetMpState(#[source] anyhow::Error),
///
/// Getting Msr entries error
///
#[error("Failed to get MP state: {0}")]
GetMpState(#[source] anyhow::Error),
///
/// Setting Saved Processor Extended States error
///
#[error("Failed to set Saved Processor Extended States: {0}")]
SetXsaveState(#[source] anyhow::Error),
///
/// Getting Saved Processor Extended States error
///
#[error("Failed to get Saved Processor Extended States: {0}")]
GetXsaveState(#[source] anyhow::Error),
///
/// Setting Extended Control Registers error
///
#[error("Failed to set Extended Control Registers: {0}")]
SetXcsr(#[source] anyhow::Error),
///
/// Getting Extended Control Registers error
///
#[error("Failed to get Extended Control Registers: {0}")]
GetXcsr(#[source] anyhow::Error),
///
/// Running Vcpu error
///
#[error("Failed to run vcpu: {0}")]
RunVcpu(#[source] anyhow::Error),
///
/// Getting Vcpu events error
///
#[error("Failed to get Vcpu events: {0}")]
GetVcpuEvents(#[source] anyhow::Error),
///
/// Setting Vcpu events error
///
#[error("Failed to set Vcpu events: {0}")]
SetVcpuEvents(#[source] anyhow::Error),
///
/// Vcpu Init error
///
#[error("Failed to init vcpu: {0}")]
VcpuInit(#[source] anyhow::Error),
///
/// Setting one reg error
///
#[error("Failed to init vcpu: {0}")]
SetOneReg(#[source] anyhow::Error),
///
/// Getting one reg error
///
#[error("Failed to init vcpu: {0}")]
GetOneReg(#[source] anyhow::Error),
///
/// Getting guest clock paused error
///
#[error("Failed to notify guest its clock was paused: {0}")]
NotifyGuestClockPaused(#[source] anyhow::Error),
///
/// Enabling HyperV SynIC error
///
#[error("Failed to enable HyperV SynIC")]
EnableHyperVSynIC(#[source] anyhow::Error),
}
#[derive(Debug)]
pub enum VmExit<'a> {
#[cfg(target_arch = "x86_64")]
IoOut(u16 /* port */, &'a [u8] /* data */),
#[cfg(target_arch = "x86_64")]
IoIn(u16 /* port */, &'a mut [u8] /* data */),
#[cfg(target_arch = "x86_64")]
IoapicEoi(u8 /* vector */),
MmioRead(u64 /* address */, &'a mut [u8]),
MmioWrite(u64 /* address */, &'a [u8]),
Ignore,
Reset,
Hyperv,
}
///
/// Result type for returning from a function
///
pub type Result<T> = anyhow::Result<T, HypervisorCpuError>;
///
/// Trait to represent a generic Vcpu
///
pub trait Vcpu: Send + Sync {
#[cfg(target_arch = "x86_64")]
///
/// Returns the vCPU general purpose registers.
///
fn get_regs(&self) -> Result<StandardRegisters>;
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU general purpose registers.
///
fn set_regs(&self, regs: &StandardRegisters) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Returns the vCPU special registers.
///
fn get_sregs(&self) -> Result<SpecialRegisters>;
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU special registers
///
fn set_sregs(&self, sregs: &SpecialRegisters) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Returns the floating point state (FPU) from the vCPU.
///
fn get_fpu(&self) -> Result<FpuState>;
#[cfg(target_arch = "x86_64")]
///
/// Set the floating point state (FPU) of a vCPU
///
fn set_fpu(&self, fpu: &FpuState) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to setup the CPUID registers.
///
fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to enable HyperV SynIC
///
fn enable_hyperv_synic(&self) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve the CPUID registers.
///
fn get_cpuid2(&self, num_entries: usize) -> Result<CpuId>;
#[cfg(target_arch = "x86_64")]
///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
///
fn get_lapic(&self) -> Result<LapicState>;
#[cfg(target_arch = "x86_64")]
///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
///
fn set_lapic(&self, lapic: &LapicState) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Returns the model-specific registers (MSR) for this vCPU.
///
fn get_msrs(&self, msrs: &mut MsrEntries) -> Result<usize>;
#[cfg(target_arch = "x86_64")]
///
/// Setup the model-specific registers (MSR) for this vCPU.
///
fn set_msrs(&self, msrs: &MsrEntries) -> Result<usize>;
///
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> Result<MpState>;
///
/// Sets the vcpu's current "multiprocessing state".
///
fn set_mp_state(&self, mp_state: MpState) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xsave struct".
///
fn get_xsave(&self) -> Result<Xsave>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xsave struct".
///
fn set_xsave(&self, xsave: &Xsave) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xcrs".
///
fn get_xcrs(&self) -> Result<ExtendedControlRegisters>;
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xcrs".
///
fn set_xcrs(&self, xcrs: &ExtendedControlRegisters) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related
/// states of the vcpu.
///
fn get_vcpu_events(&self) -> Result<VcpuEvents>;
#[cfg(target_arch = "x86_64")]
///
/// Sets pending exceptions, interrupts, and NMIs as well as related states
/// of the vcpu.
///
fn set_vcpu_events(&self, events: &VcpuEvents) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Let the guest know that it has been paused, which prevents from
/// potential soft lockups when being resumed.
///
fn notify_guest_clock_paused(&self) -> Result<()>;
///
/// Sets the type of CPU to be exposed to the guest and optional features.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>;
///
/// Sets the value of one register for this vCPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn set_one_reg(&self, reg_id: u64, data: u64) -> Result<()>;
///
/// Sets the value of one register for this vCPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn get_one_reg(&self, reg_id: u64) -> Result<u64>;
///
/// Retrieve the vCPU state.
/// This function is necessary to snapshot the VM
///
fn state(&self) -> Result<CpuState>;
///
/// Set the vCPU state.
/// This function is required when restoring the VM
///
fn set_state(&self, state: &CpuState) -> Result<()>;
///
/// Triggers the running of the current virtual CPU returning an exit reason.
///
fn run(&self) -> std::result::Result<VmExit, HypervisorCpuError>;
}

40
hypervisor/src/device.rs Normal file
View File

@@ -0,0 +1,40 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
// Copyright 2020, ARM Limited
//
use crate::DeviceAttr;
use std::os::unix::io::AsRawFd;
use thiserror::Error;
#[derive(Error, Debug)]
///
/// Enum for device error
pub enum HypervisorDeviceError {
///
/// Set device attribute error
///
#[error("Failed to set device attribute: {0}")]
SetDeviceAttribute(#[source] anyhow::Error),
}
///
/// Result type for returning from a function
///
pub type Result<T> = std::result::Result<T, HypervisorDeviceError>;
///
/// Trait to represent a device
///
/// This crate provides a hypervisor-agnostic interfaces for device
///
pub trait Device: Send + Sync + AsRawFd {
/// Set device attribute.
fn set_device_attr(&self, attr: &DeviceAttr) -> Result<()>;
}

View File

@@ -0,0 +1,112 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
use crate::vm::Vm;
#[cfg(target_arch = "x86_64")]
use crate::x86_64::{CpuId, MsrList};
#[cfg(target_arch = "x86_64")]
use kvm_ioctls::Cap;
use std::sync::Arc;
use thiserror::Error;
#[derive(Error, Debug)]
///
///
pub enum HypervisorError {
///
/// Vm creation failure
///
#[error("Failed to create Vm: {0}")]
VmCreate(#[source] anyhow::Error),
///
/// Vm setup failure
///
#[error("Failed to setup Vm: {0}")]
VmSetup(#[source] anyhow::Error),
///
/// API version error
///
#[error("Failed to get API Version: {0}")]
GetApiVersion(#[source] anyhow::Error),
///
/// Vcpu mmap error
///
#[error("Failed to get Vcpu Mmap: {0}")]
GetVcpuMmap(#[source] anyhow::Error),
///
/// Max Vcpu error
///
#[error("Failed to get number of max vcpus: {0}")]
GetMaxVcpu(#[source] anyhow::Error),
///
/// CpuId error
///
#[error("Failed to get cpuid: {0}")]
GetCpuId(#[source] anyhow::Error),
///
/// Failed to retrieve list of MSRs.
///
#[error("Failed to get the list of supported MSRs: {0}")]
GetMsrList(#[source] anyhow::Error),
///
/// API version is not compatible
///
#[error("Incompatible API version")]
IncompatibleApiVersion,
}
///
/// Result type for returning from a function
///
pub type Result<T> = std::result::Result<T, HypervisorError>;
///
/// Trait to represent a Hypervisor
///
/// This crate provides a hypervisor-agnostic interfaces
///
pub trait Hypervisor: Send + Sync {
///
/// Create a Vm using the underlying hypervisor
/// Return a hypervisor-agnostic Vm trait object
///
fn create_vm(&self) -> Result<Arc<dyn Vm>>;
///
/// Returns the size of the memory mapping required to use the vcpu's structures
///
fn get_vcpu_mmap_size(&self) -> Result<usize>;
///
/// Gets the recommended maximum number of VCPUs per VM.
///
fn get_max_vcpus(&self) -> Result<usize>;
///
/// Gets the recommended number of VCPUs per VM.
///
fn get_nr_vcpus(&self) -> Result<usize>;
#[cfg(target_arch = "x86_64")]
///
/// Checks if a particular `Cap` is available.
///
fn check_capability(&self, c: Cap) -> bool;
#[cfg(target_arch = "x86_64")]
///
/// Get the supported CpuID
///
fn get_cpuid(&self) -> Result<CpuId>;
///
/// Check particular extensions if any
///
fn check_required_extensions(&self) -> Result<()>;
#[cfg(target_arch = "x86_64")]
///
/// Retrieve the list of MSRs supported by the hypervisor.
///
fn get_msr_list(&self) -> Result<MsrList>;
}

View File

@@ -0,0 +1,27 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
///
use crate::kvm::{KvmError, KvmResult};
pub use kvm_bindings::kvm_vcpu_init as VcpuInit;
use serde_derive::{Deserialize, Serialize};
pub use {kvm_ioctls::Cap, kvm_ioctls::Kvm};
pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> {
if !kvm.check_extension(Cap::SignalMsi) {
return Err(KvmError::CapabilityMissing(Cap::SignalMsi));
}
Ok(())
}
#[derive(Clone, Serialize, Deserialize)]
pub struct VcpuKvmState {}

989
hypervisor/src/kvm/mod.rs Normal file
View File

@@ -0,0 +1,989 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
#[cfg(target_arch = "aarch64")]
pub use crate::aarch64::{check_required_kvm_extensions, VcpuInit, VcpuKvmState as CpuState};
use crate::cpu;
use crate::device;
use crate::hypervisor;
use crate::vm;
use kvm_ioctls::{NoDatamatch, VcpuFd, VmFd};
use serde_derive::{Deserialize, Serialize};
use std::os::unix::io::{AsRawFd, RawFd};
use std::result;
use std::sync::Arc;
#[cfg(target_arch = "x86_64")]
use vm_memory::Address;
use vmm_sys_util::eventfd::EventFd;
// x86_64 dependencies
#[cfg(target_arch = "x86_64")]
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
use x86_64::{
check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters, KVM_TSS_ADDRESS,
};
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
CpuId, CpuIdEntry, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState as CpuState,
Xsave, CPUID_FLAG_VALID_INDEX,
};
#[cfg(target_arch = "x86_64")]
use kvm_bindings::{kvm_enable_cap, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP};
#[cfg(target_arch = "x86_64")]
use crate::arch::x86::NUM_IOAPIC_PINS;
// aarch64 dependencies
#[cfg(target_arch = "aarch64")]
pub mod aarch64;
pub use kvm_bindings;
pub use kvm_bindings::{
kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO, kvm_irq_routing, kvm_irq_routing_entry,
kvm_userspace_memory_region, KVM_IRQ_ROUTING_MSI, KVM_MEM_READONLY, KVM_MSI_VALID_DEVID,
};
pub use kvm_ioctls;
pub use kvm_ioctls::{Cap, Kvm};
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
///
pub use {
kvm_bindings::kvm_clock_data as ClockData, kvm_bindings::kvm_create_device as CreateDevice,
kvm_bindings::kvm_device_attr as DeviceAttr,
kvm_bindings::kvm_irq_routing_entry as IrqRoutingEntry, kvm_bindings::kvm_mp_state as MpState,
kvm_bindings::kvm_userspace_memory_region as MemoryRegion,
kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_ioctls::DeviceFd, kvm_ioctls::IoEventAddress,
kvm_ioctls::VcpuExit,
};
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
pub struct KvmVmState {}
pub use KvmVmState as VmState;
/// Wrapper over KVM VM ioctls.
pub struct KvmVm {
fd: Arc<VmFd>,
#[cfg(target_arch = "x86_64")]
msrs: MsrEntries,
state: KvmVmState,
}
// Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`.
fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> {
let rounded_size = (size_in_bytes + size_of::<T>() - 1) / size_of::<T>();
let mut v = Vec::with_capacity(rounded_size);
v.resize_with(rounded_size, T::default);
v
}
// The kvm API has many structs that resemble the following `Foo` structure:
//
// ```
// #[repr(C)]
// struct Foo {
// some_data: u32
// entries: __IncompleteArrayField<__u32>,
// }
// ```
//
// In order to allocate such a structure, `size_of::<Foo>()` would be too small because it would not
// include any space for `entries`. To make the allocation large enough while still being aligned
// for `Foo`, a `Vec<Foo>` is created. Only the first element of `Vec<Foo>` would actually be used
// as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be contiguous
// with `Foo`. This function is used to make the `Vec<Foo>` with enough space for `count` entries.
use std::mem::size_of;
fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> {
let element_space = count * size_of::<F>();
let vec_size_bytes = size_of::<T>() + element_space;
vec_with_size_in_bytes(vec_size_bytes)
}
///
/// Implementation of Vm trait for KVM
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// vm.set/get().unwrap()
///
impl vm::Vm for KvmVm {
#[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) -> vm::Result<()> {
self.fd
.set_tss_address(offset)
.map_err(|e| vm::HypervisorVmError::SetTssAddress(e.into()))
}
///
/// Creates an in-kernel interrupt controller.
///
fn create_irq_chip(&self) -> vm::Result<()> {
self.fd
.create_irq_chip()
.map_err(|e| vm::HypervisorVmError::CreateIrq(e.into()))
}
///
/// Registers an event that will, when signaled, trigger the `gsi` IRQ.
///
fn register_irqfd(&self, fd: &EventFd, gsi: u32) -> vm::Result<()> {
self.fd
.register_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::RegisterIrqFd(e.into()))
}
///
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
///
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> vm::Result<()> {
self.fd
.unregister_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::UnregisterIrqFd(e.into()))
}
///
/// Creates a VcpuFd object from a vcpu RawFd.
///
fn create_vcpu(&self, id: u8) -> vm::Result<Arc<dyn cpu::Vcpu>> {
let vc = self
.fd
.create_vcpu(id)
.map_err(|e| vm::HypervisorVmError::CreateVcpu(e.into()))?;
let vcpu = KvmVcpu {
fd: vc,
#[cfg(target_arch = "x86_64")]
msrs: self.msrs.clone(),
};
Ok(Arc::new(vcpu))
}
///
/// Registers an event to be signaled whenever a certain address is written to.
///
fn register_ioevent(
&self,
fd: &EventFd,
addr: &IoEventAddress,
datamatch: Option<vm::DataMatch>,
) -> vm::Result<()> {
if let Some(dm) = datamatch {
match dm {
vm::DataMatch::DataMatch32(kvm_dm32) => self
.fd
.register_ioevent(fd, addr, kvm_dm32)
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())),
vm::DataMatch::DataMatch64(kvm_dm64) => self
.fd
.register_ioevent(fd, addr, kvm_dm64)
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())),
}
} else {
self.fd
.register_ioevent(fd, addr, NoDatamatch)
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into()))
}
}
///
/// Unregisters an event from a certain address it has been previously registered to.
///
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> {
self.fd
.unregister_ioevent(fd, addr, NoDatamatch)
.map_err(|e| vm::HypervisorVmError::UnregisterIoEvent(e.into()))
}
///
/// Sets the GSI routing table entries, overwriting any previously set
/// entries, as per the `KVM_SET_GSI_ROUTING` ioctl.
///
fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> vm::Result<()> {
let mut irq_routing =
vec_with_array_field::<kvm_irq_routing, kvm_irq_routing_entry>(entries.len());
irq_routing[0].nr = entries.len() as u32;
irq_routing[0].flags = 0;
unsafe {
let entries_slice: &mut [kvm_irq_routing_entry] =
irq_routing[0].entries.as_mut_slice(entries.len());
entries_slice.copy_from_slice(&entries);
}
self.fd
.set_gsi_routing(&irq_routing[0])
.map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into()))
}
///
/// Creates a memory region structure that can be used with set_user_memory_region
///
fn make_user_memory_region(
&self,
slot: u32,
guest_phys_addr: u64,
memory_size: u64,
userspace_addr: u64,
readonly: bool,
) -> MemoryRegion {
MemoryRegion {
slot,
guest_phys_addr,
memory_size,
userspace_addr,
flags: if readonly { KVM_MEM_READONLY } else { 0 },
}
}
///
/// Creates/modifies a guest physical memory slot.
///
fn set_user_memory_region(&self, user_memory_region: MemoryRegion) -> vm::Result<()> {
// Safe because guest regions are guaranteed not to overlap.
unsafe {
self.fd
.set_user_memory_region(user_memory_region)
.map_err(|e| vm::HypervisorVmError::SetUserMemory(e.into()))
}
}
///
/// Creates an emulated device in the kernel.
///
/// See the documentation for `KVM_CREATE_DEVICE`.
fn create_device(&self, device: &mut CreateDevice) -> vm::Result<Arc<dyn device::Device>> {
let fd = self
.fd
.create_device(device)
.map_err(|e| vm::HypervisorVmError::CreateDevice(e.into()))?;
let device = KvmDevice { fd };
Ok(Arc::new(device))
}
///
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> vm::Result<()> {
self.fd
.get_preferred_target(kvi)
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))
}
#[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.
let mut cap: kvm_enable_cap = Default::default();
cap.cap = KVM_CAP_SPLIT_IRQCHIP;
cap.args[0] = NUM_IOAPIC_PINS as u64;
self.fd
.enable_cap(&cap)
.map_err(|e| vm::HypervisorVmError::EnableSplitIrq(e.into()))?;
Ok(())
}
/// Retrieve guest clock.
#[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> vm::Result<ClockData> {
self.fd
.get_clock()
.map_err(|e| vm::HypervisorVmError::GetClock(e.into()))
}
/// Set guest clock.
#[cfg(target_arch = "x86_64")]
fn set_clock(&self, data: &ClockData) -> vm::Result<()> {
self.fd
.set_clock(data)
.map_err(|e| vm::HypervisorVmError::SetClock(e.into()))
}
/// Checks if a particular `Cap` is available.
fn check_extension(&self, c: Cap) -> bool {
self.fd.check_extension(c)
}
/// Create a device that is used for passthrough
fn create_passthrough_device(&self) -> vm::Result<Arc<dyn device::Device>> {
let mut vfio_dev = kvm_create_device {
type_: kvm_device_type_KVM_DEV_TYPE_VFIO,
fd: 0,
flags: 0,
};
self.create_device(&mut vfio_dev)
.map_err(|e| vm::HypervisorVmError::CreatePassthroughDevice(e.into()))
}
///
/// Get the Vm state. Return VM specific data
///
fn state(&self) -> vm::Result<VmState> {
Ok(self.state)
}
///
/// Set the VM state
///
fn set_state(&self, _state: &VmState) -> vm::Result<()> {
Ok(())
}
}
/// Wrapper over KVM system ioctls.
pub struct KvmHypervisor {
kvm: Kvm,
}
/// Enum for KVM related error
#[derive(Debug)]
pub enum KvmError {
CapabilityMissing(Cap),
}
pub type KvmResult<T> = result::Result<T, KvmError>;
impl KvmHypervisor {
/// Create a hypervisor based on Kvm
pub fn new() -> hypervisor::Result<KvmHypervisor> {
let kvm_obj = Kvm::new().map_err(|e| hypervisor::HypervisorError::VmCreate(e.into()))?;
let api_version = kvm_obj.get_api_version();
if api_version != kvm_bindings::KVM_API_VERSION as i32 {
return Err(hypervisor::HypervisorError::IncompatibleApiVersion);
}
Ok(KvmHypervisor { kvm: kvm_obj })
}
}
/// Implementation of Hypervisor trait for KVM
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
///
impl hypervisor::Hypervisor for KvmHypervisor {
/// Create a KVM vm object and return the object as Vm trait object
/// Example
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// use hypervisor::KvmVm;
/// let hypervisor = KvmHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap()
///
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
let fd: VmFd;
loop {
match self.kvm.create_vm() {
Ok(res) => fd = res,
Err(e) => {
if e.errno() == libc::EINTR {
// If the error returned is EINTR, which means the
// ioctl has been interrupted, we have to retry as
// this can't be considered as a regular error.
continue;
} else {
return Err(hypervisor::HypervisorError::VmCreate(e.into()));
}
}
}
break;
}
let vm_fd = Arc::new(fd);
#[cfg(target_arch = "x86_64")]
{
let msr_list = self.get_msr_list()?;
let num_msrs = msr_list.as_fam_struct_ref().nmsrs as usize;
let mut msrs = MsrEntries::new(num_msrs);
let indices = msr_list.as_slice();
let msr_entries = msrs.as_mut_slice();
for (pos, index) in indices.iter().enumerate() {
msr_entries[pos].index = *index;
}
Ok(Arc::new(KvmVm {
fd: vm_fd,
msrs,
state: VmState {},
}))
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
{
Ok(Arc::new(KvmVm {
fd: vm_fd,
state: VmState {},
}))
}
}
fn check_required_extensions(&self) -> hypervisor::Result<()> {
check_required_kvm_extensions(&self.kvm).expect("Missing KVM capabilities");
Ok(())
}
///
/// Returns the size of the memory mapping required to use the vcpu's `kvm_run` structure.
///
fn get_vcpu_mmap_size(&self) -> hypervisor::Result<usize> {
self.kvm
.get_vcpu_mmap_size()
.map_err(|e| hypervisor::HypervisorError::GetVcpuMmap(e.into()))
}
///
/// Gets the recommended maximum number of VCPUs per VM.
///
fn get_max_vcpus(&self) -> hypervisor::Result<usize> {
Ok(self.kvm.get_max_vcpus())
}
///
/// Gets the recommended number of VCPUs per VM.
///
fn get_nr_vcpus(&self) -> hypervisor::Result<usize> {
Ok(self.kvm.get_nr_vcpus())
}
#[cfg(target_arch = "x86_64")]
///
/// Checks if a particular `Cap` is available.
///
fn check_capability(&self, c: Cap) -> bool {
self.kvm.check_extension(c)
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to get the system supported CPUID values.
///
fn get_cpuid(&self) -> hypervisor::Result<CpuId> {
self.kvm
.get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES)
.map_err(|e| hypervisor::HypervisorError::GetCpuId(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Retrieve the list of MSRs supported by KVM.
///
fn get_msr_list(&self) -> hypervisor::Result<MsrList> {
self.kvm
.get_msr_index_list()
.map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into()))
}
}
/// Vcpu struct for KVM
pub struct KvmVcpu {
fd: VcpuFd,
#[cfg(target_arch = "x86_64")]
msrs: MsrEntries,
}
/// Implementation of Vcpu trait for KVM
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// let vcpu = vm.create_vcpu(0).unwrap();
/// vcpu.get/set().unwrap()
///
impl cpu::Vcpu for KvmVcpu {
#[cfg(target_arch = "x86_64")]
///
/// Returns the vCPU general purpose registers.
///
fn get_regs(&self) -> cpu::Result<StandardRegisters> {
self.fd
.get_regs()
.map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU general purpose registers using the `KVM_SET_REGS` ioctl.
///
fn set_regs(&self, regs: &StandardRegisters) -> cpu::Result<()> {
self.fd
.set_regs(regs)
.map_err(|e| cpu::HypervisorCpuError::SetStandardRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the vCPU special registers.
///
fn get_sregs(&self) -> cpu::Result<SpecialRegisters> {
self.fd
.get_sregs()
.map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU special registers using the `KVM_SET_SREGS` ioctl.
///
fn set_sregs(&self, sregs: &SpecialRegisters) -> cpu::Result<()> {
self.fd
.set_sregs(sregs)
.map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the floating point state (FPU) from the vCPU.
///
fn get_fpu(&self) -> cpu::Result<FpuState> {
self.fd
.get_fpu()
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct.
///
fn set_fpu(&self, fpu: &FpuState) -> cpu::Result<()> {
self.fd
.set_fpu(fpu)
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to setup the CPUID registers.
///
fn set_cpuid2(&self, cpuid: &CpuId) -> cpu::Result<()> {
self.fd
.set_cpuid2(cpuid)
.map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to enable HyperV SynIC
///
fn enable_hyperv_synic(&self) -> cpu::Result<()> {
let mut cap: kvm_enable_cap = Default::default();
cap.cap = KVM_CAP_HYPERV_SYNIC;
self.fd
.enable_cap(&cap)
.map_err(|e| cpu::HypervisorCpuError::EnableHyperVSynIC(e.into()))
}
///
/// X86 specific call to retrieve the CPUID registers.
///
#[cfg(target_arch = "x86_64")]
fn get_cpuid2(&self, num_entries: usize) -> cpu::Result<CpuId> {
self.fd
.get_cpuid2(num_entries)
.map_err(|e| cpu::HypervisorCpuError::GetCpuid(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
///
fn get_lapic(&self) -> cpu::Result<LapicState> {
self.fd
.get_lapic()
.map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
///
fn set_lapic(&self, klapic: &LapicState) -> cpu::Result<()> {
self.fd
.set_lapic(klapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the model-specific registers (MSR) for this vCPU.
///
fn get_msrs(&self, msrs: &mut MsrEntries) -> cpu::Result<usize> {
self.fd
.get_msrs(msrs)
.map_err(|e| cpu::HypervisorCpuError::GetMsrEntries(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Setup the model-specific registers (MSR) for this vCPU.
/// Returns the number of MSR entries actually written.
///
fn set_msrs(&self, msrs: &MsrEntries) -> cpu::Result<usize> {
self.fd
.set_msrs(msrs)
.map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into()))
}
///
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> cpu::Result<MpState> {
self.fd
.get_mp_state()
.map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))
}
///
/// Sets the vcpu's current "multiprocessing state".
///
fn set_mp_state(&self, mp_state: MpState) -> cpu::Result<()> {
self.fd
.set_mp_state(mp_state)
.map_err(|e| cpu::HypervisorCpuError::SetMpState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xsave struct".
///
fn get_xsave(&self) -> cpu::Result<Xsave> {
self.fd
.get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xsave struct".
///
fn set_xsave(&self, xsave: &Xsave) -> cpu::Result<()> {
self.fd
.set_xsave(xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xcrs".
///
fn get_xcrs(&self) -> cpu::Result<ExtendedControlRegisters> {
self.fd
.get_xcrs()
.map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xcrs".
///
fn set_xcrs(&self, xcrs: &ExtendedControlRegisters) -> cpu::Result<()> {
self.fd
.set_xcrs(&xcrs)
.map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into()))
}
///
/// Triggers the running of the current virtual CPU returning an exit reason.
///
fn run(&self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
match self.fd.run() {
Ok(run) => match run {
#[cfg(target_arch = "x86_64")]
VcpuExit::IoIn(addr, data) => Ok(cpu::VmExit::IoIn(addr, data)),
#[cfg(target_arch = "x86_64")]
VcpuExit::IoOut(addr, data) => Ok(cpu::VmExit::IoOut(addr, data)),
#[cfg(target_arch = "x86_64")]
VcpuExit::IoapicEoi(vector) => Ok(cpu::VmExit::IoapicEoi(vector)),
#[cfg(target_arch = "x86_64")]
VcpuExit::Shutdown | VcpuExit::Hlt => Ok(cpu::VmExit::Reset),
#[cfg(target_arch = "aarch64")]
VcpuExit::SystemEvent(event_type, flags) => {
use kvm_bindings::KVM_SYSTEM_EVENT_SHUTDOWN;
// On Aarch64, when the VM is shutdown, run() returns
// VcpuExit::SystemEvent with reason KVM_SYSTEM_EVENT_SHUTDOWN
if event_type == KVM_SYSTEM_EVENT_SHUTDOWN {
Ok(cpu::VmExit::Reset)
} else {
Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unexpected system event with type 0x{:x}, flags 0x{:x}",
event_type,
flags
)))
}
}
VcpuExit::MmioRead(addr, data) => Ok(cpu::VmExit::MmioRead(addr, data)),
VcpuExit::MmioWrite(addr, data) => Ok(cpu::VmExit::MmioWrite(addr, data)),
VcpuExit::Hyperv => Ok(cpu::VmExit::Hyperv),
r => Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unexpected exit reason on vcpu run: {:?}",
r
))),
},
Err(ref e) => match e.errno() {
libc::EAGAIN | libc::EINTR => Ok(cpu::VmExit::Ignore),
_ => Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"VCPU error {:?}",
e
))),
},
}
}
#[cfg(target_arch = "x86_64")]
///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related
/// states of the vcpu.
///
fn get_vcpu_events(&self) -> cpu::Result<VcpuEvents> {
self.fd
.get_vcpu_events()
.map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets pending exceptions, interrupts, and NMIs as well as related states
/// of the vcpu.
///
fn set_vcpu_events(&self, events: &VcpuEvents) -> cpu::Result<()> {
self.fd
.set_vcpu_events(events)
.map_err(|e| cpu::HypervisorCpuError::SetVcpuEvents(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Let the guest know that it has been paused, which prevents from
/// 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()))
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
self.fd
.vcpu_init(kvi)
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
}
///
/// Sets the value of one register for this vCPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn set_one_reg(&self, reg_id: u64, data: u64) -> cpu::Result<()> {
self.fd
.set_one_reg(reg_id, data)
.map_err(|e| cpu::HypervisorCpuError::SetOneReg(e.into()))
}
///
/// Gets the value of one register for this vCPU.
///
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn get_one_reg(&self, reg_id: u64) -> cpu::Result<u64> {
self.fd
.get_one_reg(reg_id)
.map_err(|e| cpu::HypervisorCpuError::GetOneReg(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Get the current CPU state
///
/// Ordering requirements:
///
/// KVM_GET_MP_STATE calls kvm_apic_accept_events(), which might modify
/// vCPU/LAPIC state. As such, it must be done before most everything
/// else, otherwise we cannot restore everything and expect it to work.
///
/// KVM_GET_VCPU_EVENTS/KVM_SET_VCPU_EVENTS is unsafe if other vCPUs are
/// still running.
///
/// KVM_GET_LAPIC may change state of LAPIC before returning it.
///
/// GET_VCPU_EVENTS should probably be last to save. The code looks as
/// it might as well be affected by internal state modifications of the
/// GET ioctls.
///
/// SREGS saves/restores a pending interrupt, similar to what
/// VCPU_EVENTS also does.
///
/// GET_MSRS requires a pre-populated data structure to do something
/// meaningful. For SET_MSRS it will then contain good data.
///
/// # Example
///
/// ```rust
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hv.create_vm().expect("new VM fd creation failed");
/// vm.enable_split_irq().unwrap();
/// let vcpu = vm.create_vcpu(0).unwrap();
/// let state = vcpu.state().unwrap();
/// ```
fn state(&self) -> cpu::Result<CpuState> {
let mp_state = self.get_mp_state()?;
let regs = self.get_regs()?;
let sregs = self.get_sregs()?;
let xsave = self.get_xsave()?;
let xcrs = self.get_xcrs()?;
let lapic_state = self.get_lapic()?;
let fpu = self.get_fpu()?;
// Try to get all MSRs based on the list previously retrieved from KVM.
// If the number of MSRs obtained from GET_MSRS is different from the
// expected amount, we fallback onto a slower method by getting MSRs
// by chunks. This is the only way to make sure we try to get as many
// MSRs as possible, even if some MSRs are not supported.
let mut msr_entries = self.msrs.clone();
let expected_num_msrs = msr_entries.as_fam_struct_ref().nmsrs as usize;
let num_msrs = self.get_msrs(&mut msr_entries)?;
let msrs = if num_msrs != expected_num_msrs {
let mut faulty_msr_index = num_msrs;
let mut msr_entries_tmp =
MsrEntries::from_entries(&msr_entries.as_slice()[..faulty_msr_index]);
loop {
warn!(
"Detected faulty MSR 0x{:x} while getting MSRs",
msr_entries.as_slice()[faulty_msr_index].index
);
let start_pos = faulty_msr_index + 1;
let mut sub_msr_entries =
MsrEntries::from_entries(&msr_entries.as_slice()[start_pos..]);
let expected_num_msrs = sub_msr_entries.as_fam_struct_ref().nmsrs as usize;
let num_msrs = self.get_msrs(&mut sub_msr_entries)?;
for i in 0..num_msrs {
msr_entries_tmp
.push(sub_msr_entries.as_slice()[i])
.map_err(|e| {
cpu::HypervisorCpuError::GetMsrEntries(anyhow!(
"Failed adding MSR entries: {:?}",
e
))
})?;
}
if num_msrs == expected_num_msrs {
break;
}
faulty_msr_index = start_pos + num_msrs;
}
msr_entries_tmp
} else {
msr_entries
};
let vcpu_events = self.get_vcpu_events()?;
Ok(CpuState {
msrs,
vcpu_events,
regs,
sregs,
fpu,
lapic_state,
xsave,
xcrs,
mp_state,
})
}
#[cfg(target_arch = "aarch64")]
fn state(&self) -> cpu::Result<CpuState> {
unimplemented!();
}
#[cfg(target_arch = "x86_64")]
///
/// Restore the previously saved CPU state
///
/// Ordering requirements:
///
/// KVM_GET_VCPU_EVENTS/KVM_SET_VCPU_EVENTS is unsafe if other vCPUs are
/// still running.
///
/// Some SET ioctls (like set_mp_state) depend on kvm_vcpu_is_bsp(), so
/// if we ever change the BSP, we have to do that before restoring anything.
/// The same seems to be true for CPUID stuff.
///
/// SREGS saves/restores a pending interrupt, similar to what
/// VCPU_EVENTS also does.
///
/// SET_REGS clears pending exceptions unconditionally, thus, it must be
/// done before SET_VCPU_EVENTS, which restores it.
///
/// SET_LAPIC must come after SET_SREGS, because the latter restores
/// the apic base msr.
///
/// SET_LAPIC must come before SET_MSRS, because the TSC deadline MSR
/// only restores successfully, when the LAPIC is correctly configured.
///
/// Arguments: CpuState
/// # Example
///
/// ```rust
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hv.create_vm().expect("new VM fd creation failed");
/// vm.enable_split_irq().unwrap();
/// let vcpu = vm.create_vcpu(0).unwrap();
/// let state = vcpu.state().unwrap();
/// vcpu.set_state(&state).unwrap();
/// ```
fn set_state(&self, state: &CpuState) -> cpu::Result<()> {
self.set_mp_state(state.mp_state)?;
self.set_regs(&state.regs)?;
self.set_sregs(&state.sregs)?;
self.set_xsave(&state.xsave)?;
self.set_xcrs(&state.xcrs)?;
self.set_lapic(&state.lapic_state)?;
self.set_fpu(&state.fpu)?;
// Try to set all MSRs previously stored.
// If the number of MSRs set from SET_MSRS is different from the
// expected amount, we fallback onto a slower method by setting MSRs
// by chunks. This is the only way to make sure we try to set as many
// MSRs as possible, even if some MSRs are not supported.
let expected_num_msrs = state.msrs.as_fam_struct_ref().nmsrs as usize;
let num_msrs = self.set_msrs(&state.msrs)?;
if num_msrs != expected_num_msrs {
let mut faulty_msr_index = num_msrs;
loop {
warn!(
"Detected faulty MSR 0x{:x} while setting MSRs",
state.msrs.as_slice()[faulty_msr_index].index
);
let start_pos = faulty_msr_index + 1;
let sub_msr_entries = MsrEntries::from_entries(&state.msrs.as_slice()[start_pos..]);
let expected_num_msrs = sub_msr_entries.as_fam_struct_ref().nmsrs as usize;
let num_msrs = self.set_msrs(&sub_msr_entries)?;
if num_msrs == expected_num_msrs {
break;
}
faulty_msr_index = start_pos + num_msrs;
}
}
self.set_vcpu_events(&state.vcpu_events)?;
Ok(())
}
#[allow(unused_variables)]
#[cfg(target_arch = "aarch64")]
fn set_state(&self, state: &CpuState) -> cpu::Result<()> {
warn!("CPU state was not restored");
Ok(())
}
}
/// Device struct for KVM
pub struct KvmDevice {
fd: DeviceFd,
}
impl device::Device for KvmDevice {
///
/// Set device attribute
///
fn set_device_attr(&self, attr: &DeviceAttr) -> device::Result<()> {
self.fd
.set_device_attr(attr)
.map_err(|e| device::HypervisorDeviceError::SetDeviceAttribute(e.into()))
}
}
impl AsRawFd for KvmDevice {
fn as_raw_fd(&self) -> RawFd {
self.fd.as_raw_fd()
}
}

View File

@@ -0,0 +1,97 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
use vm_memory::GuestAddress;
use crate::arch::x86::{msr_index, MTRR_ENABLE, MTRR_MEM_TYPE_WB};
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
use serde_derive::{Deserialize, Serialize};
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
///
pub use {
kvm_bindings::kvm_cpuid_entry2 as CpuIdEntry, kvm_bindings::kvm_dtable as DescriptorTable,
kvm_bindings::kvm_fpu as FpuState, kvm_bindings::kvm_lapic_state as LapicState,
kvm_bindings::kvm_mp_state as MpState, kvm_bindings::kvm_msr_entry as MsrEntry,
kvm_bindings::kvm_regs as StandardRegisters, kvm_bindings::kvm_segment as SegmentRegister,
kvm_bindings::kvm_sregs as SpecialRegisters, kvm_bindings::kvm_vcpu_events as VcpuEvents,
kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave as Xsave,
kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries,
kvm_bindings::KVM_CPUID_FLAG_SIGNIFCANT_INDEX as CPUID_FLAG_VALID_INDEX,
};
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffb_d000);
macro_rules! msr {
($msr:expr) => {
MsrEntry {
index: $msr,
data: 0x0,
..Default::default()
}
};
}
macro_rules! msr_data {
($msr:expr, $data:expr) => {
MsrEntry {
index: $msr,
data: $data,
..Default::default()
}
};
}
pub fn boot_msr_entries() -> MsrEntries {
MsrEntries::from_entries(&[
msr!(msr_index::MSR_IA32_SYSENTER_CS),
msr!(msr_index::MSR_IA32_SYSENTER_ESP),
msr!(msr_index::MSR_IA32_SYSENTER_EIP),
msr!(msr_index::MSR_STAR),
msr!(msr_index::MSR_CSTAR),
msr!(msr_index::MSR_LSTAR),
msr!(msr_index::MSR_KERNEL_GS_BASE),
msr!(msr_index::MSR_SYSCALL_MASK),
msr!(msr_index::MSR_IA32_TSC),
msr_data!(
msr_index::MSR_IA32_MISC_ENABLE,
msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64
),
msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB),
])
}
///
/// Check KVM extension for Linux
///
pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> {
if !kvm.check_extension(Cap::SignalMsi) {
return Err(KvmError::CapabilityMissing(Cap::SignalMsi));
}
if !kvm.check_extension(Cap::TscDeadlineTimer) {
return Err(KvmError::CapabilityMissing(Cap::TscDeadlineTimer));
}
if !kvm.check_extension(Cap::SplitIrqchip) {
return Err(KvmError::CapabilityMissing(Cap::SplitIrqchip));
}
Ok(())
}
#[derive(Clone, Serialize, Deserialize)]
pub struct VcpuKvmState {
pub msrs: MsrEntries,
pub vcpu_events: VcpuEvents,
pub regs: StandardRegisters,
pub sregs: SpecialRegisters,
pub fpu: FpuState,
pub lapic_state: LapicState,
pub xsave: Xsave,
pub xcrs: ExtendedControlRegisters,
pub mp_state: MpState,
}

61
hypervisor/src/lib.rs Normal file
View File

@@ -0,0 +1,61 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
//! A generic abstraction around hypervisor functionality
//!
//! This crate offers a trait abstraction for underlying hypervisors
//!
//! # Platform support
//!
//! - x86_64
//! - arm64
//!
#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_derive;
extern crate serde_json;
extern crate thiserror;
/// KVM implementation module
pub mod kvm;
/// Hypevisor related module
pub mod hypervisor;
/// Vm related module
pub mod vm;
/// Architecture specific definitions
pub mod arch;
/// CPU related module
mod cpu;
/// Device related module
mod device;
pub use crate::hypervisor::{Hypervisor, HypervisorError};
pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
pub use device::{Device, HypervisorDeviceError};
pub use kvm::*;
pub use vm::{DataMatch, HypervisorVmError, Vm};
use std::sync::Arc;
pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> {
#[cfg(feature = "kvm")]
let hv = kvm::KvmHypervisor::new()?;
Ok(Arc::new(hv))
}

187
hypervisor/src/vm.rs Normal file
View File

@@ -0,0 +1,187 @@
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
#[cfg(target_arch = "aarch64")]
use crate::aarch64::VcpuInit;
use crate::cpu::Vcpu;
use crate::device::Device;
#[cfg(target_arch = "x86_64")]
use crate::ClockData;
use crate::KvmVmState as VmState;
use crate::{CreateDevice, IoEventAddress, IrqRoutingEntry, MemoryRegion};
use kvm_ioctls::Cap;
use std::sync::Arc;
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
///
/// I/O events data matches (32 or 64 bits).
///
pub enum DataMatch {
DataMatch32(u32),
DataMatch64(u64),
}
impl Into<u64> for DataMatch {
fn into(self) -> u64 {
match self {
DataMatch::DataMatch32(dm) => dm.into(),
DataMatch::DataMatch64(dm) => dm,
}
}
}
#[derive(Error, Debug)]
///
/// Enum for VM error
pub enum HypervisorVmError {
///
/// Create Vcpu error
///
#[error("Failed to create Vcpu: {0}")]
CreateVcpu(#[source] anyhow::Error),
///
/// TSS address error
///
#[error("Failed to set TSS address: {0}")]
SetTssAddress(#[source] anyhow::Error),
///
/// Create interrupt controller error
///
#[error("Failed to create interrupt controller: {0}")]
CreateIrq(#[source] anyhow::Error),
///
/// Register interrupt event error
///
#[error("Failed to register interrupt event: {0}")]
RegisterIrqFd(#[source] anyhow::Error),
///
/// Un register interrupt event error
///
#[error("Failed to unregister interrupt event: {0}")]
UnregisterIrqFd(#[source] anyhow::Error),
///
/// Register IO event error
///
#[error("Failed to register IO event: {0}")]
RegisterIoEvent(#[source] anyhow::Error),
///
/// Unregister IO event error
///
#[error("Failed to unregister IO event: {0}")]
UnregisterIoEvent(#[source] anyhow::Error),
///
/// Set GSI routing error
///
#[error("Failed to set GSI routing: {0}")]
SetGsiRouting(#[source] anyhow::Error),
///
/// Set user memory error
///
#[error("Failed to set user memory: {0}")]
SetUserMemory(#[source] anyhow::Error),
///
/// Create device error
///
#[error("Failed to set GSI routing: {0}")]
CreateDevice(#[source] anyhow::Error),
///
/// Get preferred target error
///
#[error("Failed to get preferred target: {0}")]
GetPreferredTarget(#[source] anyhow::Error),
///
/// Enable split Irq error
///
#[error("Failed to enable split Irq: {0}")]
EnableSplitIrq(#[source] anyhow::Error),
///
/// Get clock error
///
#[error("Failed to get clock: {0}")]
GetClock(#[source] anyhow::Error),
///
/// Set clock error
///
#[error("Failed to set clock: {0}")]
SetClock(#[source] anyhow::Error),
///
/// Create passthrough device
///
#[error("Failed to create passthrough device: {0}")]
CreatePassthroughDevice(#[source] anyhow::Error),
}
///
/// Result type for returning from a function
///
pub type Result<T> = std::result::Result<T, HypervisorVmError>;
///
/// Trait to represent a Vm
///
/// This crate provides a hypervisor-agnostic interfaces for Vm
///
pub trait Vm: Send + Sync {
#[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<()>;
/// Creates an in-kernel interrupt controller.
fn create_irq_chip(&self) -> Result<()>;
/// Registers an event that will, when signaled, trigger the `gsi` IRQ.
fn register_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
/// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
fn create_vcpu(&self, id: u8) -> Result<Arc<dyn Vcpu>>;
/// Registers an event to be signaled whenever a certain address is written to.
fn register_ioevent(
&self,
fd: &EventFd,
addr: &IoEventAddress,
datamatch: Option<DataMatch>,
) -> Result<()>;
/// Unregister an event from a certain address it has been previously registered to.
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>;
/// Sets the GSI routing table entries, overwriting any previously set
fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> Result<()>;
/// Creates a memory region structure that can be used with set_user_memory_region
fn make_user_memory_region(
&self,
slot: u32,
guest_phys_addr: u64,
memory_size: u64,
userspace_addr: u64,
readonly: bool,
) -> MemoryRegion;
/// Creates/modifies a guest physical memory slot.
fn set_user_memory_region(&self, user_memory_region: MemoryRegion) -> Result<()>;
/// Creates an emulated device in the kernel.
fn create_device(&self, device: &mut CreateDevice) -> Result<Arc<dyn Device>>;
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> Result<()>;
/// Enable split Irq capability
#[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> Result<()>;
/// Retrieve guest clock.
#[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> Result<ClockData>;
/// Set guest clock.
#[cfg(target_arch = "x86_64")]
fn set_clock(&self, data: &ClockData) -> Result<()>;
/// Checks if a particular `Cap` is available.
fn check_extension(&self, c: Cap) -> bool;
/// Create a device that is used for passthrough
fn create_passthrough_device(&self) -> Result<Arc<dyn Device>>;
/// Get the Vm state. Return VM specific data
fn state(&self) -> Result<VmState>;
/// Set the VM state
fn set_state(&self, state: &VmState) -> Result<()>;
}

View File

@@ -4,4 +4,4 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
vmm-sys-util = { git = "https://github.com/rust-vmm/vmm-sys-util" }
vmm-sys-util = ">=0.3.1"

View File

@@ -4,14 +4,18 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
libc = "0.2.60"
rand = "0.7.0"
serde = "1.0.98"
epoll = ">=4.0.1"
libc = "0.2.77"
log = "0.4.11"
net_gen = { path = "../net_gen" }
vmm-sys-util = { git = "https://github.com/rust-vmm/vmm-sys-util" }
rand = "0.7.3"
serde = "1.0.116"
virtio-bindings = "0.1.0"
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1"
[dev-dependencies]
lazy_static = "1.3.0"
pnet = "0.22.0"
serde_json = "1.0.40"
pnet = "0.26.0"
serde_json = "1.0.57"

View File

@@ -11,21 +11,28 @@
#[macro_use]
extern crate lazy_static;
extern crate libc;
#[macro_use]
extern crate log;
extern crate net_gen;
extern crate rand;
extern crate serde;
extern crate net_gen;
extern crate virtio_bindings;
extern crate vm_memory;
extern crate vm_virtio;
extern crate vmm_sys_util;
mod mac;
mod open_tap;
mod queue_pair;
mod tap;
use std::io::Error as IoError;
use std::mem;
use std::net;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::{FromRawFd, RawFd};
use std::{io, mem, net};
pub use mac::{MacAddr, MAC_ADDR_LEN};
pub use open_tap::{open_tap, Error as OpenTapError};
pub use queue_pair::{NetCounters, NetQueuePair, NetQueuePairError, RxVirtio, TxVirtio};
pub use tap::{Error as TapError, Tap};
#[derive(Debug)]
@@ -62,6 +69,39 @@ fn create_socket() -> Result<net::UdpSocket> {
Ok(unsafe { net::UdpSocket::from_raw_fd(sock) })
}
fn vnet_hdr_len() -> usize {
use virtio_bindings::bindings::virtio_net::virtio_net_hdr_v1;
std::mem::size_of::<virtio_net_hdr_v1>()
}
pub fn register_listener(
epoll_fd: RawFd,
fd: RawFd,
ev_type: epoll::Events,
data: u64,
) -> std::result::Result<(), io::Error> {
epoll::ctl(
epoll_fd,
epoll::ControlOptions::EPOLL_CTL_ADD,
fd,
epoll::Event::new(ev_type, data),
)
}
pub fn unregister_listener(
epoll_fd: RawFd,
fd: RawFd,
ev_type: epoll::Events,
data: u64,
) -> std::result::Result<(), io::Error> {
epoll::ctl(
epoll_fd,
epoll::ControlOptions::EPOLL_CTL_DEL,
fd,
epoll::Event::new(ev_type, data),
)
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -6,7 +6,10 @@
// found in the THIRD-PARTY file.
use rand::Rng;
use std::fmt;
use std::io;
use std::result::Result;
use std::str::FromStr;
use serde::de::{Deserialize, Deserializer, Error};
use serde::ser::{Serialize, Serializer};
@@ -19,23 +22,31 @@ pub struct MacAddr {
}
impl MacAddr {
// The error contains the str that failed to be parsed, for nicer error message generation.
pub fn parse_str<S>(s: &S) -> Result<MacAddr, &str>
pub fn parse_str<S>(s: &S) -> Result<MacAddr, io::Error>
where
S: AsRef<str> + ?Sized,
{
let v: Vec<&str> = s.as_ref().split(':').collect();
let mut bytes = [0u8; MAC_ADDR_LEN];
let common_err = Err(io::Error::new(
io::ErrorKind::Other,
format!("parsing of {} into a MAC address failed", s.as_ref()),
));
if v.len() != MAC_ADDR_LEN {
return Err(s.as_ref());
return common_err;
}
for i in 0..MAC_ADDR_LEN {
if v[i].len() != 2 {
return Err(s.as_ref());
return common_err;
}
bytes[i] = u8::from_str_radix(v[i], 16).map_err(|_| s.as_ref())?;
bytes[i] = u8::from_str_radix(v[i], 16).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("parsing of {} into a MAC address failed: {}", s.as_ref(), e),
)
})?;
}
Ok(MacAddr { bytes })
@@ -66,14 +77,6 @@ impl MacAddr {
&self.bytes
}
pub fn to_string(self) -> String {
let b = &self.bytes;
format!(
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
b[0], b[1], b[2], b[3], b[4], b[5]
)
}
pub fn local_random() -> MacAddr {
// Generate a fully random MAC
let mut random_bytes = rand::thread_rng().gen::<[u8; MAC_ADDR_LEN]>();
@@ -87,6 +90,17 @@ impl MacAddr {
}
}
impl fmt::Display for MacAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let b = &self.bytes;
write!(
f,
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
b[0], b[1], b[2], b[3], b[4], b[5]
)
}
}
impl Serialize for MacAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -102,7 +116,20 @@ impl<'de> Deserialize<'de> for MacAddr {
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
MacAddr::parse_str(&s).map_err(|_| D::Error::custom("The provided MAC address is invalid."))
MacAddr::parse_str(&s)
.map_err(|e| D::Error::custom(format!("The provided MAC address is invalid: {}", e)))
}
}
pub enum MacAddrParseError {
InvalidValue(String),
}
impl FromStr for MacAddr {
type Err = MacAddrParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
MacAddr::parse_str(s).map_err(|_| MacAddrParseError::InvalidValue(s.to_owned()))
}
}

116
net_util/src/open_tap.rs Normal file
View File

@@ -0,0 +1,116 @@
// Copyright (c) 2020 Intel Corporation. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use super::{vnet_hdr_len, MacAddr, Tap, TapError};
use std::net::Ipv4Addr;
use std::path::Path;
use std::{fs, io};
#[derive(Debug)]
pub enum Error {
/// Failed to convert an hexadecimal string into an integer.
ConvertHexStringToInt(std::num::ParseIntError),
/// Error related to the multiqueue support (no support TAP side).
MultiQueueNoTapSupport,
/// Error related to the multiqueue support (no support device side).
MultiQueueNoDeviceSupport,
/// Failed to read the TAP flags from sysfs.
ReadSysfsTunFlags(io::Error),
/// Open tap device failed.
TapOpen(TapError),
/// Setting tap IP failed.
TapSetIp(TapError),
/// Setting tap netmask failed.
TapSetNetmask(TapError),
/// Setting MAC address failed
TapSetMac(TapError),
/// Getting MAC address failed
TapGetMac(TapError),
/// Setting tap interface offload flags failed.
TapSetOffload(TapError),
/// Setting vnet header size failed.
TapSetVnetHdrSize(TapError),
/// Enabling tap interface failed.
TapEnable(TapError),
}
type Result<T> = std::result::Result<T, Error>;
fn check_mq_support(if_name: &Option<&str>, queue_pairs: usize) -> Result<()> {
if let Some(tap_name) = if_name {
let mq = queue_pairs > 1;
let path = format!("/sys/class/net/{}/tun_flags", tap_name);
// interface does not exist, check is not required
if !Path::new(&path).exists() {
return Ok(());
}
let tun_flags_str = fs::read_to_string(path).map_err(Error::ReadSysfsTunFlags)?;
let tun_flags = u32::from_str_radix(tun_flags_str.trim().trim_start_matches("0x"), 16)
.map_err(Error::ConvertHexStringToInt)?;
if (tun_flags & net_gen::IFF_MULTI_QUEUE != 0) && !mq {
return Err(Error::MultiQueueNoDeviceSupport);
} else if (tun_flags & net_gen::IFF_MULTI_QUEUE == 0) && mq {
return Err(Error::MultiQueueNoTapSupport);
}
}
Ok(())
}
/// Create a new virtio network device with the given IP address and
/// netmask.
pub fn open_tap(
if_name: Option<&str>,
ip_addr: Option<Ipv4Addr>,
netmask: Option<Ipv4Addr>,
host_mac: &mut Option<MacAddr>,
num_rx_q: usize,
) -> Result<Vec<Tap>> {
let mut taps: Vec<Tap> = Vec::new();
let mut ifname: String = String::new();
let vnet_hdr_size = vnet_hdr_len() as i32;
let flag = net_gen::TUN_F_CSUM | net_gen::TUN_F_UFO | net_gen::TUN_F_TSO4 | net_gen::TUN_F_TSO6;
// In case the tap interface already exists, check if the number of
// queues is appropriate. The tap might not support multiqueue while
// the number of queues indicates the user expects multiple queues, or
// on the contrary, the tap might support multiqueue while the number
// of queues indicates the user doesn't expect multiple queues.
check_mq_support(&if_name, num_rx_q)?;
for i in 0..num_rx_q {
let tap: Tap;
if i == 0 {
tap = match if_name {
Some(name) => Tap::open_named(name, num_rx_q).map_err(Error::TapOpen)?,
None => Tap::new(num_rx_q).map_err(Error::TapOpen)?,
};
if let Some(ip) = ip_addr {
tap.set_ip_addr(ip).map_err(Error::TapSetIp)?;
}
if let Some(mask) = netmask {
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
}
if let Some(mac) = host_mac {
tap.set_mac_addr(*mac).map_err(Error::TapSetMac)?
} else {
*host_mac = Some(tap.get_mac_addr().map_err(Error::TapGetMac)?)
}
tap.enable().map_err(Error::TapEnable)?;
tap.set_offload(flag).map_err(Error::TapSetOffload)?;
tap.set_vnet_hdr_size(vnet_hdr_size)
.map_err(Error::TapSetVnetHdrSize)?;
ifname = String::from_utf8(tap.get_if_name()).unwrap();
} else {
tap = Tap::open_named(ifname.as_str(), num_rx_q).map_err(Error::TapOpen)?;
tap.set_offload(flag).map_err(Error::TapSetOffload)?;
tap.set_vnet_hdr_size(vnet_hdr_size)
.map_err(Error::TapSetVnetHdrSize)?;
}
taps.push(tap);
}
Ok(taps)
}

380
net_util/src/queue_pair.rs Normal file
View File

@@ -0,0 +1,380 @@
// Copyright (c) 2020 Intel Corporation. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use super::{register_listener, unregister_listener, vnet_hdr_len, Tap};
use libc::EAGAIN;
use std::cmp;
use std::io;
use std::io::{Read, Write};
use std::num::Wrapping;
use std::os::unix::io::{AsRawFd, RawFd};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap};
use vm_virtio::{DescriptorChain, Queue};
/// The maximum buffer size when segmentation offload is enabled. This
/// includes the 12-byte virtio net header.
/// http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html#x1-1740003
const MAX_BUFFER_SIZE: usize = 65562;
#[derive(Clone)]
pub struct TxVirtio {
pub iovec: Vec<(GuestAddress, usize)>,
pub frame_buf: [u8; MAX_BUFFER_SIZE],
pub counter_bytes: Wrapping<u64>,
pub counter_frames: Wrapping<u64>,
}
impl Default for TxVirtio {
fn default() -> Self {
Self::new()
}
}
impl TxVirtio {
pub fn new() -> Self {
TxVirtio {
iovec: Vec::new(),
frame_buf: [0u8; MAX_BUFFER_SIZE],
counter_bytes: Wrapping(0),
counter_frames: Wrapping(0),
}
}
pub fn process_desc_chain(&mut self, mem: &GuestMemoryMmap, tap: &mut Tap, queue: &mut Queue) {
while let Some(avail_desc) = queue.iter(&mem).next() {
let head_index = avail_desc.index;
let mut read_count = 0;
let mut next_desc = Some(avail_desc);
self.iovec.clear();
while let Some(desc) = next_desc {
if desc.is_write_only() {
break;
}
self.iovec.push((desc.addr, desc.len as usize));
read_count += desc.len as usize;
next_desc = desc.next_descriptor();
}
read_count = 0;
// Copy buffer from across multiple descriptors.
// TODO(performance - Issue #420): change this to use `writev()` instead of `write()`
// and get rid of the intermediate buffer.
for (desc_addr, desc_len) in self.iovec.drain(..) {
let limit = cmp::min((read_count + desc_len) as usize, self.frame_buf.len());
let read_result =
mem.read_slice(&mut self.frame_buf[read_count..limit as usize], desc_addr);
match read_result {
Ok(_) => {
// Increment by number of bytes actually read
read_count += limit - read_count;
}
Err(e) => {
println!("Failed to read slice: {:?}", e);
break;
}
}
}
let write_result = tap.write(&self.frame_buf[..read_count]);
match write_result {
Ok(_) => {}
Err(e) => {
println!("net: tx: error failed to write to tap: {}", e);
}
};
self.counter_bytes += Wrapping((read_count - vnet_hdr_len()) as u64);
self.counter_frames += Wrapping(1);
queue.add_used(&mem, head_index, 0);
queue.update_avail_event(&mem);
}
}
}
#[derive(Clone)]
pub struct RxVirtio {
pub deferred_frame: bool,
pub deferred_irqs: bool,
pub bytes_read: usize,
pub frame_buf: [u8; MAX_BUFFER_SIZE],
pub counter_bytes: Wrapping<u64>,
pub counter_frames: Wrapping<u64>,
}
impl Default for RxVirtio {
fn default() -> Self {
Self::new()
}
}
impl RxVirtio {
pub fn new() -> Self {
RxVirtio {
deferred_frame: false,
deferred_irqs: false,
bytes_read: 0,
frame_buf: [0u8; MAX_BUFFER_SIZE],
counter_bytes: Wrapping(0),
counter_frames: Wrapping(0),
}
}
pub fn process_desc_chain(
&mut self,
mem: &GuestMemoryMmap,
mut next_desc: Option<DescriptorChain>,
queue: &mut Queue,
) -> bool {
let head_index = next_desc.as_ref().unwrap().index;
let mut write_count = 0;
// Copy from frame into buffer, which may span multiple descriptors.
loop {
match next_desc {
Some(desc) => {
if !desc.is_write_only() {
break;
}
let limit = cmp::min(write_count + desc.len as usize, self.bytes_read);
let source_slice = &self.frame_buf[write_count..limit];
let write_result = mem.write_slice(source_slice, desc.addr);
match write_result {
Ok(_) => {
write_count = limit;
}
Err(e) => {
error!("Failed to write slice: {:?}", e);
break;
}
};
if write_count >= self.bytes_read {
break;
}
next_desc = desc.next_descriptor();
}
None => {
warn!("Receiving buffer is too small to hold frame of current size");
break;
}
}
}
self.counter_bytes += Wrapping((write_count - vnet_hdr_len()) as u64);
self.counter_frames += Wrapping(1);
queue.add_used(&mem, head_index, write_count as u32);
queue.update_avail_event(&mem);
// Mark that we have at least one pending packet and we need to interrupt the guest.
self.deferred_irqs = true;
// Update the frame_buf buffer.
if write_count < self.bytes_read {
self.frame_buf.copy_within(write_count..self.bytes_read, 0);
self.bytes_read -= write_count;
false
} else {
self.bytes_read = 0;
true
}
}
}
#[derive(Default, Clone)]
pub struct NetCounters {
pub tx_bytes: Arc<AtomicU64>,
pub tx_frames: Arc<AtomicU64>,
pub rx_bytes: Arc<AtomicU64>,
pub rx_frames: Arc<AtomicU64>,
}
#[derive(Debug)]
pub enum NetQueuePairError {
/// No memory configured
NoMemoryConfigured,
/// Error registering listener
RegisterListener(io::Error),
/// Error unregistering listener
UnregisterListener(io::Error),
/// Error reading from the TAP device
FailedReadTap,
}
pub struct NetQueuePair {
pub mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
pub tap: Tap,
pub rx: RxVirtio,
pub tx: TxVirtio,
pub epoll_fd: Option<RawFd>,
pub rx_tap_listening: bool,
pub counters: NetCounters,
pub tap_event_id: u16,
}
impl NetQueuePair {
// Copies a single frame from `self.rx.frame_buf` into the guest. Returns true
// if a buffer was used, and false if the frame must be deferred until a buffer
// is made available by the driver.
fn rx_single_frame(&mut self, mut queue: &mut Queue) -> Result<bool, NetQueuePairError> {
let mem = self
.mem
.as_ref()
.ok_or(NetQueuePairError::NoMemoryConfigured)
.map(|m| m.memory())?;
let next_desc = queue.iter(&mem).next();
if next_desc.is_none() {
// Queue has no available descriptors
if self.rx_tap_listening {
unregister_listener(
self.epoll_fd.unwrap(),
self.tap.as_raw_fd(),
epoll::Events::EPOLLIN,
u64::from(self.tap_event_id),
)
.map_err(NetQueuePairError::UnregisterListener)?;
self.rx_tap_listening = false;
info!("Listener unregistered");
}
return Ok(false);
}
Ok(self.rx.process_desc_chain(&mem, next_desc, &mut queue))
}
fn process_rx(&mut self, queue: &mut Queue) -> Result<bool, NetQueuePairError> {
// Read as many frames as possible.
loop {
match self.read_tap() {
Ok(count) => {
self.rx.bytes_read = count;
if !self.rx_single_frame(queue)? {
self.rx.deferred_frame = true;
break;
}
}
Err(e) => {
// The tap device is non-blocking, so any error aside from EAGAIN is
// unexpected.
match e.raw_os_error() {
Some(err) if err == EAGAIN => (),
_ => {
error!("Failed to read tap: {:?}", e);
return Err(NetQueuePairError::FailedReadTap);
}
};
break;
}
}
}
// Consume the counters from the Rx/Tx queues and accumulate into
// the counters for the device as whole. This consumption is needed
// to handle MQ.
self.counters
.rx_bytes
.fetch_add(self.rx.counter_bytes.0, Ordering::AcqRel);
self.counters
.rx_frames
.fetch_add(self.rx.counter_frames.0, Ordering::AcqRel);
self.rx.counter_bytes = Wrapping(0);
self.rx.counter_frames = Wrapping(0);
if self.rx.deferred_irqs {
self.rx.deferred_irqs = false;
let mem = self
.mem
.as_ref()
.ok_or(NetQueuePairError::NoMemoryConfigured)
.map(|m| m.memory())?;
Ok(queue.needs_notification(&mem, queue.next_used))
} else {
Ok(false)
}
}
pub fn resume_rx(&mut self, queue: &mut Queue) -> Result<bool, NetQueuePairError> {
if !self.rx_tap_listening {
register_listener(
self.epoll_fd.unwrap(),
self.tap.as_raw_fd(),
epoll::Events::EPOLLIN,
u64::from(self.tap_event_id),
)
.map_err(NetQueuePairError::RegisterListener)?;
self.rx_tap_listening = true;
info!("Listener registered");
}
if self.rx.deferred_frame {
if self.rx_single_frame(queue)? {
self.rx.deferred_frame = false;
// process_rx() was interrupted possibly before consuming all
// packets in the tap; try continuing now.
self.process_rx(queue)
} else if self.rx.deferred_irqs {
self.rx.deferred_irqs = false;
let mem = self
.mem
.as_ref()
.ok_or(NetQueuePairError::NoMemoryConfigured)
.map(|m| m.memory())?;
Ok(queue.needs_notification(&mem, queue.next_used))
} else {
Ok(false)
}
} else {
Ok(false)
}
}
pub fn process_tx(&mut self, mut queue: &mut Queue) -> Result<bool, NetQueuePairError> {
let mem = self
.mem
.as_ref()
.ok_or(NetQueuePairError::NoMemoryConfigured)
.map(|m| m.memory())?;
self.tx.process_desc_chain(&mem, &mut self.tap, &mut queue);
self.counters
.tx_bytes
.fetch_add(self.tx.counter_bytes.0, Ordering::AcqRel);
self.counters
.tx_frames
.fetch_add(self.tx.counter_frames.0, Ordering::AcqRel);
self.tx.counter_bytes = Wrapping(0);
self.tx.counter_frames = Wrapping(0);
Ok(queue.needs_notification(&mem, queue.next_used))
}
pub fn process_rx_tap(&mut self, mut queue: &mut Queue) -> Result<bool, NetQueuePairError> {
if self.rx.deferred_frame
// Process a deferred frame first if available. Don't read from tap again
// until we manage to receive this deferred frame.
{
if self.rx_single_frame(&mut queue)? {
self.rx.deferred_frame = false;
self.process_rx(&mut queue)
} else if self.rx.deferred_irqs {
self.rx.deferred_irqs = false;
Ok(true)
} else {
Ok(false)
}
} else {
self.process_rx(&mut queue)
}
}
fn read_tap(&mut self) -> io::Result<usize> {
self.tap.read(&mut self.rx.frame_buf)
}
}

View File

@@ -5,28 +5,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use super::{create_sockaddr, create_socket, Error as NetUtilError, MacAddr};
use mac::MAC_ADDR_LEN;
use net_gen;
use std::fs::File;
use std::io::{Error as IoError, Read, Result as IoResult, Write};
use std::net;
use std::os::raw::*;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use super::{create_sockaddr, create_socket, Error as NetUtilError};
use libc;
use net_gen;
use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ref, ioctl_with_val};
#[derive(Debug)]
pub enum Error {
/// Couldn't open /dev/net/tun.
OpenTun(IoError),
/// Unable to create tap interface.
CreateTap(IoError),
/// Unable to configure tap interface.
ConfigureTap(IoError),
/// Unable to retrieve features.
GetFeatures(IoError),
/// Missing multiqueue support in the kernel.
MultiQueueKernelSupport,
/// ioctl failed.
IoctlError(IoError),
/// Failed to create a socket.
NetUtil(NetUtilError),
InvalidIfname,
/// Error parsing MAC data
MacParsing(()),
}
pub type Result<T> = ::std::result::Result<T, Error>;
@@ -40,7 +45,7 @@ pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Tap {
tap_file: File,
if_name: [u8; 16usize],
if_name: Vec<u8>,
}
impl PartialEq for Tap {
@@ -49,6 +54,15 @@ impl PartialEq for Tap {
}
}
impl std::clone::Clone for Tap {
fn clone(&self) -> Self {
Tap {
tap_file: self.tap_file.try_clone().unwrap(),
if_name: self.if_name.clone(),
}
}
}
// Returns a byte vector representing the contents of a null terminated C string which
// contains if_name.
fn build_terminated_if_name(if_name: &str) -> Result<Vec<u8>> {
@@ -69,7 +83,7 @@ fn build_terminated_if_name(if_name: &str) -> Result<Vec<u8>> {
}
impl Tap {
pub fn open_named(if_name: &str) -> Result<Tap> {
pub fn open_named(if_name: &str, num_queue_pairs: usize) -> Result<Tap> {
let terminated_if_name = build_terminated_if_name(if_name)?;
let fd = unsafe {
@@ -87,6 +101,20 @@ impl Tap {
// We just checked that the fd is valid.
let tuntap = unsafe { File::from_raw_fd(fd) };
// Let's validate some features before going any further.
// ioctl is safe since we call it with a valid tap fd and check the return
// value.
let mut features = 0;
let ret = unsafe { ioctl_with_mut_ref(&tuntap, net_gen::TUNGETFEATURES(), &mut features) };
if ret < 0 {
return Err(Error::GetFeatures(IoError::last_os_error()));
}
// Check if the user parameters match the kernel support for MQ
if (features & net_gen::IFF_MULTI_QUEUE == 0) && num_queue_pairs > 1 {
return Err(Error::MultiQueueKernelSupport);
}
// This is pretty messy because of the unions used by ifreq. Since we
// don't call as_mut on the same union field more than once, this block
// is safe.
@@ -98,26 +126,31 @@ impl Tap {
name_slice.copy_from_slice(terminated_if_name.as_slice());
*ifru_flags =
(net_gen::IFF_TAP | net_gen::IFF_NO_PI | net_gen::IFF_VNET_HDR) as c_short;
if num_queue_pairs > 1 {
*ifru_flags |= net_gen::IFF_MULTI_QUEUE as c_short;
}
}
// ioctl is safe since we call it with a valid tap fd and check the return
// value.
let ret = unsafe { ioctl_with_mut_ref(&tuntap, net_gen::TUNSETIFF(), &mut ifreq) };
if ret < 0 {
return Err(Error::CreateTap(IoError::last_os_error()));
return Err(Error::ConfigureTap(IoError::last_os_error()));
}
let if_name_temp = unsafe { *ifreq.ifr_ifrn.ifrn_name.as_ref() };
let mut if_name = if_name_temp.to_vec();
if_name.truncate(terminated_if_name.len() - 1);
// Safe since only the name is accessed, and it's cloned out.
Ok(Tap {
tap_file: tuntap,
if_name: unsafe { *ifreq.ifr_ifrn.ifrn_name.as_ref() },
if_name,
})
}
/// Create a new tap interface.
pub fn new() -> Result<Tap> {
Self::open_named("vmtap%d")
pub fn new(num_queue_pairs: usize) -> Result<Tap> {
Self::open_named("vmtap%d", num_queue_pairs)
}
/// Set the host-side IP address for the tap interface.
@@ -144,6 +177,72 @@ impl Tap {
Ok(())
}
/// Set mac addr for tap interface.
pub fn set_mac_addr(&self, addr: MacAddr) -> Result<()> {
// Checking if the mac address already matches the desired one
// is useful to avoid making the "set ioctl" in the case where
// the VMM is running without the privilege to do that.
// In practice this comes from a reboot after the configuration
// has been update with the kernel generated address.
if self.get_mac_addr()? == addr {
return Ok(());
}
let sock = create_socket().map_err(Error::NetUtil)?;
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 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
// We only access one field of the ifru union, hence this is safe.
unsafe {
let ifru_hwaddr = ifreq.ifr_ifru.ifru_hwaddr.as_mut();
for (i, v) in addr.get_bytes().iter().enumerate() {
ifru_hwaddr.sa_data[i] = *v as c_char;
}
}
// 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 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Get mac addr for tap interface.
pub fn get_mac_addr(&self) -> Result<MacAddr> {
let sock = create_socket().map_err(Error::NetUtil)?;
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 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
// We only access one field of the ifru union, hence this is safe.
let addr = unsafe {
let ifru_hwaddr = ifreq.ifr_ifru.ifru_hwaddr.as_ref();
MacAddr::from_bytes(
&*(&ifru_hwaddr.sa_data[0..MAC_ADDR_LEN] as *const _ as *const [u8]),
)
.map_err(Error::MacParsing)?
};
Ok(addr)
}
/// Set the netmask for the subnet that the tap interface will exist on.
pub fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()> {
let sock = create_socket().map_err(Error::NetUtil)?;
@@ -187,9 +286,26 @@ 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 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
// If TAP device is already up don't try and enable it
let ifru_flags = unsafe { ifreq.ifr_ifru.ifru_flags.as_ref() };
if ifru_flags
& (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16
== (net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16
{
return Ok(());
}
// We only access one field of the ifru union, hence this is safe.
unsafe {
let ifru_flags = ifreq.ifr_ifru.ifru_flags.as_mut();
*ifru_flags =
(net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16;
}
@@ -223,11 +339,16 @@ impl Tap {
// in a single-field union.
unsafe {
let ifrn_name = ifreq.ifr_ifrn.ifrn_name.as_mut();
ifrn_name.clone_from_slice(&self.if_name);
let name_slice = &mut ifrn_name[..self.if_name.len()];
name_slice.copy_from_slice(&self.if_name);
}
ifreq
}
pub fn get_if_name(&self) -> Vec<u8> {
self.if_name.clone()
}
}
impl Read for Tap {
@@ -406,7 +527,7 @@ mod tests {
let interface = interfaces.into_iter().find(interface_name_matches).unwrap();
if let Ok(Ethernet(tx, rx)) = datalink::channel(&interface, Default::default()) {
(interface.mac_address(), tx, rx)
(interface.mac.unwrap(), tx, rx)
} else {
panic!("datalink channel error or unhandled channel type");
}
@@ -414,7 +535,7 @@ mod tests {
#[test]
fn test_tap_create() {
let t = Tap::new().unwrap();
let t = Tap::new(1).unwrap();
println!("created tap: {:?}", t);
}
@@ -426,7 +547,7 @@ mod tests {
// the end of the function.
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let tap = Tap::new().unwrap();
let tap = Tap::new(1).unwrap();
let ip_addr: net::Ipv4Addr = (*tap_ip_guard).parse().unwrap();
let netmask: net::Ipv4Addr = SUBNET_MASK.parse().unwrap();
@@ -439,21 +560,21 @@ mod tests {
#[test]
fn test_set_options() {
// This line will fail to provide an initialized FD if the test is not run as root.
let tap = Tap::new().unwrap();
let tap = Tap::new(1).unwrap();
tap.set_vnet_hdr_size(16).unwrap();
tap.set_offload(0).unwrap();
}
#[test]
fn test_tap_enable() {
let tap = Tap::new().unwrap();
let tap = Tap::new(1).unwrap();
let ret = tap.enable();
assert!(ret.is_ok());
}
#[test]
fn test_tap_get_ifreq() {
let tap = Tap::new().unwrap();
let tap = Tap::new(1).unwrap();
let ret = tap.get_ifreq();
assert_eq!(
"__BindgenUnionField",
@@ -463,7 +584,7 @@ mod tests {
#[test]
fn test_raw_fd() {
let tap = Tap::new().unwrap();
let tap = Tap::new(1).unwrap();
assert_eq!(tap.as_raw_fd(), tap.tap_file.as_raw_fd());
}
@@ -471,7 +592,7 @@ mod tests {
fn test_read() {
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let mut tap = Tap::new().unwrap();
let mut tap = Tap::new(1).unwrap();
tap.set_ip_addr((*tap_ip_guard).parse().unwrap()).unwrap();
tap.set_netmask(SUBNET_MASK.parse().unwrap()).unwrap();
tap.enable().unwrap();
@@ -532,7 +653,7 @@ mod tests {
fn test_write() {
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let mut tap = Tap::new().unwrap();
let mut tap = Tap::new(1).unwrap();
tap.set_ip_addr((*tap_ip_guard).parse().unwrap()).unwrap();
tap.set_netmask(SUBNET_MASK.parse().unwrap()).unwrap();
tap.enable().unwrap();

5
option_parser/Cargo.toml Normal file
View File

@@ -0,0 +1,5 @@
[package]
name = "option_parser"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"

267
option_parser/src/lib.rs Normal file
View File

@@ -0,0 +1,267 @@
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
#[derive(Default)]
pub struct OptionParser {
options: HashMap<String, OptionParserValue>,
}
struct OptionParserValue {
value: Option<String>,
requires_value: bool,
}
#[derive(Debug)]
pub enum OptionParserError {
UnknownOption(String),
InvalidSyntax(String),
Conversion(String, String),
}
impl fmt::Display for OptionParserError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OptionParserError::UnknownOption(s) => write!(f, "unknown option: {}", s),
OptionParserError::InvalidSyntax(s) => write!(f, "invalid syntax:{}", s),
OptionParserError::Conversion(field, value) => {
write!(f, "unable to parse {} for {}", value, field)
}
}
}
}
type OptionParserResult<T> = std::result::Result<T, OptionParserError>;
impl OptionParser {
pub fn new() -> Self {
Self {
options: HashMap::new(),
}
}
pub fn parse(&mut self, input: &str) -> OptionParserResult<()> {
if input.trim().is_empty() {
return Ok(());
}
let options_list: Vec<&str> = input.trim().split(',').collect();
for option in options_list.iter() {
let parts: Vec<&str> = option.split('=').collect();
match self.options.get_mut(parts[0]) {
None => return Err(OptionParserError::UnknownOption(parts[0].to_owned())),
Some(value) => {
if value.requires_value {
if parts.len() != 2 {
return Err(OptionParserError::InvalidSyntax((*option).to_owned()));
}
value.value = Some(parts[1].trim().to_owned());
} else {
value.value = Some(String::new());
}
}
}
}
Ok(())
}
pub fn add(&mut self, option: &str) -> &mut Self {
self.options.insert(
option.to_owned(),
OptionParserValue {
value: None,
requires_value: true,
},
);
self
}
pub fn add_valueless(&mut self, option: &str) -> &mut Self {
self.options.insert(
option.to_owned(),
OptionParserValue {
value: None,
requires_value: false,
},
);
self
}
pub fn get(&self, option: &str) -> Option<String> {
self.options
.get(option)
.and_then(|v| v.value.clone())
.and_then(|s| if s.is_empty() { None } else { Some(s) })
}
pub fn is_set(&self, option: &str) -> bool {
self.options
.get(option)
.and_then(|v| v.value.as_ref())
.is_some()
}
pub fn convert<T: FromStr>(&self, option: &str) -> OptionParserResult<Option<T>> {
match self.get(option) {
None => Ok(None),
Some(v) => Ok(Some(v.parse().map_err(|_| {
OptionParserError::Conversion(option.to_owned(), v.to_owned())
})?)),
}
}
}
pub struct Toggle(pub bool);
pub enum ToggleParseError {
InvalidValue(String),
}
impl FromStr for Toggle {
type Err = ToggleParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"" => Ok(Toggle(false)),
"on" => Ok(Toggle(true)),
"off" => Ok(Toggle(false)),
"true" => Ok(Toggle(true)),
"false" => Ok(Toggle(false)),
_ => Err(ToggleParseError::InvalidValue(s.to_owned())),
}
}
}
pub struct ByteSized(pub u64);
#[derive(Debug)]
pub enum ByteSizedParseError {
InvalidValue(String),
}
impl FromStr for ByteSized {
type Err = ByteSizedParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(ByteSized({
let s = s.trim();
let shift = if s.ends_with('K') {
10
} else if s.ends_with('M') {
20
} else if s.ends_with('G') {
30
} else {
0
};
let s = s.trim_end_matches(|c| c == 'K' || c == 'M' || c == 'G');
s.parse::<u64>()
.map_err(|_| ByteSizedParseError::InvalidValue(s.to_owned()))?
<< shift
}))
}
}
pub struct IntegerList(pub Vec<u64>);
pub enum IntegerListParseError {
InvalidValue(String),
}
impl FromStr for IntegerList {
type Err = IntegerListParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let mut integer_list = Vec::new();
let ranges_list: Vec<&str> = s.trim().split(':').collect();
for range in ranges_list.iter() {
let items: Vec<&str> = range.split('-').collect();
if items.len() > 2 {
return Err(IntegerListParseError::InvalidValue(range.to_string()));
}
let start_range = items[0]
.parse::<u64>()
.map_err(|_| IntegerListParseError::InvalidValue(items[0].to_owned()))?;
integer_list.push(start_range);
if items.len() == 2 {
let end_range = items[1]
.parse::<u64>()
.map_err(|_| IntegerListParseError::InvalidValue(items[1].to_owned()))?;
if start_range >= end_range {
return Err(IntegerListParseError::InvalidValue(range.to_string()));
}
for i in start_range..end_range {
integer_list.push(i + 1);
}
}
}
Ok(IntegerList(integer_list))
}
}
pub struct TupleTwoIntegers(pub Vec<(u64, u64)>);
pub enum TupleTwoIntegersParseError {
InvalidValue(String),
}
impl FromStr for TupleTwoIntegers {
type Err = TupleTwoIntegersParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let mut list = Vec::new();
let tuples_list: Vec<&str> = s.trim().split(':').collect();
for tuple in tuples_list.iter() {
let items: Vec<&str> = tuple.split('@').collect();
if items.len() != 2 {
return Err(TupleTwoIntegersParseError::InvalidValue(tuple.to_string()));
}
let item1 = items[0]
.parse::<u64>()
.map_err(|_| TupleTwoIntegersParseError::InvalidValue(items[0].to_owned()))?;
let item2 = items[1]
.parse::<u64>()
.map_err(|_| TupleTwoIntegersParseError::InvalidValue(items[1].to_owned()))?;
list.push((item1, item2));
}
Ok(TupleTwoIntegers(list))
}
}
pub struct StringList(pub Vec<String>);
pub enum StringListParseError {
InvalidValue(String),
}
impl FromStr for StringList {
type Err = StringListParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let string_list: Vec<String> = s.trim().split(':').map(|e| e.to_owned()).collect();
Ok(StringList(string_list))
}
}

View File

@@ -5,12 +5,21 @@ authors = ["Samuel Ortiz <sameo@linux.intel.com>"]
edition = "2018"
[dependencies]
anyhow = "1.0"
byteorder = "1.3.4"
hypervisor = { path = "../hypervisor" }
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
vmm-sys-util = ">=0.3.1"
libc = "0.2.77"
log = "0.4.11"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vm-allocator = { path = "../vm-allocator" }
byteorder = "1.3.2"
devices = { path = "../devices" }
kvm-bindings = "0.1.1"
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "master" }
libc = "0.2.60"
log = "0.4.8"
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
vmm-sys-util = { git = "https://github.com/rust-vmm/vmm-sys-util" }
vm-device = { path = "../vm-device" }
vm-memory = "0.2.1"
vm-migration = { path = "../vm-migration" }
[dependencies.vfio-bindings]
version = "0.2.0"
features = ["fam-wrappers"]

View File

@@ -5,16 +5,18 @@
use crate::configuration::{
PciBarRegionType, PciBridgeSubclass, PciClassCode, PciConfiguration, PciHeaderType,
};
use crate::device::{Error as PciDeviceError, PciDevice};
use crate::device::{DeviceRelocation, Error as PciDeviceError, PciDevice};
use byteorder::{ByteOrder, LittleEndian};
use devices::BusDevice;
use std;
use std::sync::Arc;
use std::sync::Mutex;
use std::any::Any;
use std::collections::HashMap;
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};
use vm_device::{Bus, BusDevice};
use vm_memory::{Address, GuestAddress, GuestUsize};
const VENDOR_ID_INTEL: u16 = 0x8086;
const DEVICE_ID_INTEL_VIRT_PCIE_HOST: u16 = 0x0d57;
const NUM_DEVICE_IDS: usize = 32;
/// Errors for device manager.
#[derive(Debug)]
@@ -24,9 +26,15 @@ pub enum PciRootError {
/// Could not allocate an IRQ number.
AllocateIrq,
/// Could not add a device to the port io bus.
PioInsert(devices::BusError),
PioInsert(vm_device::BusError),
/// Could not add a device to the mmio bus.
MmioInsert(devices::BusError),
MmioInsert(vm_device::BusError),
/// Could not find an available device slot on the PCI bus.
NoPciDeviceSlotAvailable,
/// Invalid PCI device identifier provided.
InvalidPciDeviceSlot(usize),
/// Valid PCI device identifier but already used.
AlreadyInUsePciDeviceSlot(usize),
}
pub type Result<T> = std::result::Result<T, PciRootError>;
@@ -46,6 +54,7 @@ impl PciRoot {
config: PciConfiguration::new(
VENDOR_ID_INTEL,
DEVICE_ID_INTEL_VIRT_PCIE_HOST,
0,
PciClassCode::BridgeDevice,
&PciBridgeSubclass::HostBridge,
None,
@@ -66,43 +75,54 @@ impl PciDevice for PciRoot {
self.config.write_config_register(reg_idx, offset, data);
}
fn read_config_register(&self, reg_idx: usize) -> u32 {
fn read_config_register(&mut self, reg_idx: usize) -> u32 {
self.config.read_reg(reg_idx)
}
fn as_any(&mut self) -> &mut dyn Any {
self
}
}
pub struct PciConfigIo {
pub struct PciBus {
/// Devices attached to this bus.
/// Device 0 is host bridge.
devices: Vec<Arc<Mutex<dyn PciDevice>>>,
/// Config space register.
config_address: u32,
devices: HashMap<u32, Arc<Mutex<dyn PciDevice>>>,
device_reloc: Arc<dyn DeviceRelocation>,
device_ids: Vec<bool>,
}
impl PciConfigIo {
pub fn new(pci_root: PciRoot) -> Self {
let mut devices: Vec<Arc<Mutex<dyn PciDevice>>> = Vec::new();
devices.push(Arc::new(Mutex::new(pci_root)));
impl PciBus {
pub fn new(pci_root: PciRoot, device_reloc: Arc<dyn DeviceRelocation>) -> Self {
let mut devices: HashMap<u32, Arc<Mutex<dyn PciDevice>>> = HashMap::new();
let mut device_ids: Vec<bool> = vec![false; NUM_DEVICE_IDS];
PciConfigIo {
devices.insert(0, Arc::new(Mutex::new(pci_root)));
device_ids[0] = true;
PciBus {
devices,
config_address: 0,
device_reloc,
device_ids,
}
}
pub fn register_mapping(
&self,
dev: Arc<Mutex<dyn BusDevice>>,
io_bus: &mut devices::Bus,
mmio_bus: &mut devices::Bus,
#[cfg(target_arch = "x86_64")] io_bus: &Bus,
mmio_bus: &Bus,
bars: Vec<(GuestAddress, GuestUsize, PciBarRegionType)>,
) -> Result<()> {
for (address, size, type_) in bars {
match type_ {
PciBarRegionType::IORegion => {
#[cfg(target_arch = "x86_64")]
io_bus
.insert(dev.clone(), address.raw_value(), size)
.map_err(PciRootError::PioInsert)?;
#[cfg(target_arch = "aarch64")]
error!("I/O region is not supported");
}
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
mmio_bus
@@ -114,11 +134,68 @@ impl PciConfigIo {
Ok(())
}
pub fn add_device(&mut self, device: Arc<Mutex<dyn PciDevice>>) -> Result<()> {
self.devices.push(device);
pub fn add_device(
&mut self,
pci_device_bdf: u32,
device: Arc<Mutex<dyn PciDevice>>,
) -> Result<()> {
self.devices.insert(pci_device_bdf >> 3, device);
Ok(())
}
pub fn remove_by_device(&mut self, device: &Arc<Mutex<dyn PciDevice>>) -> Result<()> {
self.devices.retain(|_, dev| !Arc::ptr_eq(dev, device));
Ok(())
}
pub fn next_device_id(&mut self) -> Result<u32> {
for (idx, device_id) in self.device_ids.iter_mut().enumerate() {
if !(*device_id) {
*device_id = true;
return Ok(idx as u32);
}
}
Err(PciRootError::NoPciDeviceSlotAvailable)
}
pub fn get_device_id(&mut self, id: usize) -> Result<()> {
if id < NUM_DEVICE_IDS {
if !self.device_ids[id] {
self.device_ids[id] = true;
Ok(())
} else {
Err(PciRootError::AlreadyInUsePciDeviceSlot(id))
}
} else {
Err(PciRootError::InvalidPciDeviceSlot(id))
}
}
pub fn put_device_id(&mut self, id: usize) -> Result<()> {
if id < NUM_DEVICE_IDS {
self.device_ids[id] = false;
Ok(())
} else {
Err(PciRootError::InvalidPciDeviceSlot(id))
}
}
}
pub struct PciConfigIo {
/// Config space register.
config_address: u32,
pci_bus: Arc<Mutex<PciBus>>,
}
impl PciConfigIo {
pub fn new(pci_bus: Arc<Mutex<PciBus>>) -> Self {
PciConfigIo {
pci_bus,
config_address: 0,
}
}
pub fn config_space_read(&self) -> u32 {
let enabled = (self.config_address & 0x8000_0000) != 0;
if !enabled {
@@ -126,7 +203,7 @@ impl PciConfigIo {
}
let (bus, device, function, register) =
parse_config_address(self.config_address & !0x8000_0000);
parse_io_config_address(self.config_address & !0x8000_0000);
// Only support one bus.
if bus != 0 {
@@ -138,9 +215,14 @@ impl PciConfigIo {
return 0xffff_ffff;
}
self.devices.get(device).map_or(0xffff_ffff, |d| {
d.lock().unwrap().read_config_register(register)
})
self.pci_bus
.lock()
.unwrap()
.devices
.get(&(device as u32))
.map_or(0xffff_ffff, |d| {
d.lock().unwrap().read_config_register(register)
})
}
pub fn config_space_write(&mut self, offset: u64, data: &[u8]) {
@@ -154,17 +236,36 @@ impl PciConfigIo {
}
let (bus, device, _function, register) =
parse_config_address(self.config_address & !0x8000_0000);
parse_io_config_address(self.config_address & !0x8000_0000);
// Only support one bus.
if bus != 0 {
return;
}
if let Some(d) = self.devices.get(device) {
d.lock()
.unwrap()
.write_config_register(register, offset, data);
let pci_bus = self.pci_bus.lock().unwrap();
if let Some(d) = pci_bus.devices.get(&(device as u32)) {
let mut device = d.lock().unwrap();
// Find out if one of the device's BAR is being reprogrammed, and
// reprogram it if needed.
if let Some(params) = device.detect_bar_reprogramming(register, data) {
if let Err(e) = pci_bus.device_reloc.move_bar(
params.old_base,
params.new_base,
params.len,
device.deref_mut(),
params.region_type,
) {
error!(
"Failed moving device BAR: {}: 0x{:x}->0x{:x}(0x{:x})",
e, params.old_base, params.new_base, params.len
);
}
}
// Update the register value
device.write_config_register(register, offset, data);
}
}
@@ -223,30 +324,30 @@ impl BusDevice for PciConfigIo {
/// Emulates PCI memory-mapped configuration access mechanism.
pub struct PciConfigMmio {
/// Devices attached to this bus.
/// Device 0 is host bridge.
devices: Vec<Arc<Mutex<dyn PciDevice>>>,
pci_bus: Arc<Mutex<PciBus>>,
}
impl PciConfigMmio {
pub fn new(pci_root: PciRoot) -> Self {
let mut devices: Vec<Arc<Mutex<dyn PciDevice>>> = Vec::new();
devices.push(Arc::new(Mutex::new(pci_root)));
PciConfigMmio { devices }
pub fn new(pci_bus: Arc<Mutex<PciBus>>) -> Self {
PciConfigMmio { pci_bus }
}
fn config_space_read(&self, config_address: u32) -> u32 {
let (bus, device, _function, register) = parse_config_address(config_address);
let (bus, device, _function, register) = parse_mmio_config_address(config_address);
// Only support one bus.
if bus != 0 {
return 0xffff_ffff;
}
self.devices.get(device).map_or(0xffff_ffff, |d| {
d.lock().unwrap().read_config_register(register)
})
self.pci_bus
.lock()
.unwrap()
.devices
.get(&(device as u32))
.map_or(0xffff_ffff, |d| {
d.lock().unwrap().read_config_register(register)
})
}
fn config_space_write(&mut self, config_address: u32, offset: u64, data: &[u8]) {
@@ -254,17 +355,36 @@ impl PciConfigMmio {
return;
}
let (bus, device, _function, register) = parse_config_address(config_address);
let (bus, device, _function, register) = parse_mmio_config_address(config_address);
// Only support one bus.
if bus != 0 {
return;
}
if let Some(d) = self.devices.get(device) {
d.lock()
.unwrap()
.write_config_register(register, offset, data);
let pci_bus = self.pci_bus.lock().unwrap();
if let Some(d) = pci_bus.devices.get(&(device as u32)) {
let mut device = d.lock().unwrap();
// Find out if one of the device's BAR is being reprogrammed, and
// reprogram it if needed.
if let Some(params) = device.detect_bar_reprogramming(register, data) {
if let Err(e) = pci_bus.device_reloc.move_bar(
params.old_base,
params.new_base,
params.len,
device.deref_mut(),
params.region_type,
) {
error!(
"Failed moving device BAR: {}: 0x{:x}->0x{:x}(0x{:x})",
e, params.old_base, params.new_base, params.len
);
}
}
// Update the register value
device.write_config_register(register, offset, data);
}
}
}
@@ -295,8 +415,33 @@ impl BusDevice for PciConfigMmio {
}
}
fn shift_and_mask(value: u32, offset: usize, mask: u32) -> usize {
((value >> offset) & mask) as usize
}
// Parse the MMIO address offset to a (bus, device, function, register) tuple.
// See section 7.2.2 PCI Express Enhanced Configuration Access Mechanism (ECAM)
// from the Pci Express Base Specification Revision 5.0 Version 1.0.
fn parse_mmio_config_address(config_address: u32) -> (usize, usize, usize, usize) {
const BUS_NUMBER_OFFSET: usize = 20;
const BUS_NUMBER_MASK: u32 = 0x00ff;
const DEVICE_NUMBER_OFFSET: usize = 15;
const DEVICE_NUMBER_MASK: u32 = 0x1f;
const FUNCTION_NUMBER_OFFSET: usize = 12;
const FUNCTION_NUMBER_MASK: u32 = 0x07;
const REGISTER_NUMBER_OFFSET: usize = 2;
const REGISTER_NUMBER_MASK: u32 = 0x3ff;
(
shift_and_mask(config_address, BUS_NUMBER_OFFSET, BUS_NUMBER_MASK),
shift_and_mask(config_address, DEVICE_NUMBER_OFFSET, DEVICE_NUMBER_MASK),
shift_and_mask(config_address, FUNCTION_NUMBER_OFFSET, FUNCTION_NUMBER_MASK),
shift_and_mask(config_address, REGISTER_NUMBER_OFFSET, REGISTER_NUMBER_MASK),
)
}
// Parse the CONFIG_ADDRESS register to a (bus, device, function, register) tuple.
fn parse_config_address(config_address: u32) -> (usize, usize, usize, usize) {
fn parse_io_config_address(config_address: u32) -> (usize, usize, usize, usize) {
const BUS_NUMBER_OFFSET: usize = 16;
const BUS_NUMBER_MASK: u32 = 0x00ff;
const DEVICE_NUMBER_OFFSET: usize = 11;
@@ -306,12 +451,10 @@ fn parse_config_address(config_address: u32) -> (usize, usize, usize, usize) {
const REGISTER_NUMBER_OFFSET: usize = 2;
const REGISTER_NUMBER_MASK: u32 = 0x3f;
let bus_number = ((config_address >> BUS_NUMBER_OFFSET) & BUS_NUMBER_MASK) as usize;
let device_number = ((config_address >> DEVICE_NUMBER_OFFSET) & DEVICE_NUMBER_MASK) as usize;
let function_number =
((config_address >> FUNCTION_NUMBER_OFFSET) & FUNCTION_NUMBER_MASK) as usize;
let register_number =
((config_address >> REGISTER_NUMBER_OFFSET) & REGISTER_NUMBER_MASK) as usize;
(bus_number, device_number, function_number, register_number)
(
shift_and_mask(config_address, BUS_NUMBER_OFFSET, BUS_NUMBER_MASK),
shift_and_mask(config_address, DEVICE_NUMBER_OFFSET, DEVICE_NUMBER_MASK),
shift_and_mask(config_address, FUNCTION_NUMBER_OFFSET, FUNCTION_NUMBER_MASK),
shift_and_mask(config_address, REGISTER_NUMBER_OFFSET, REGISTER_NUMBER_MASK),
)
}

355
pci/src/configuration.rs Executable file → Normal file
View File

@@ -2,14 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use std::sync::{Arc, Mutex};
use crate::device::BarReprogrammingParams;
use crate::{MsixConfig, PciInterruptPin};
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
use std::fmt::{self, Display};
use std::sync::{Arc, Mutex};
use vm_migration::{MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable};
// The number of 32bit registers in the config space, 256 bytes.
const NUM_CONFIGURATION_REGISTERS: usize = 64;
// The number of 32bit registers in the config space, 4096 bytes.
const NUM_CONFIGURATION_REGISTERS: usize = 1024;
const STATUS_REG: usize = 1;
const STATUS_REG_CAPABILITIES_USED_MASK: u32 = 0x0010_0000;
@@ -243,14 +245,66 @@ pub trait PciCapability {
fn id(&self) -> PciCapabilityID;
}
fn encode_32_bits_bar_size(bar_size: u32) -> Option<u32> {
if bar_size > 0 {
return Some(!(bar_size - 1));
}
None
}
fn decode_32_bits_bar_size(bar_size: u32) -> Option<u32> {
if bar_size > 0 {
return Some(!bar_size + 1);
}
None
}
fn encode_64_bits_bar_size(bar_size: u64) -> Option<(u32, u32)> {
if bar_size > 0 {
let result = !(bar_size - 1);
let result_hi = (result >> 32) as u32;
let result_lo = (result & 0xffff_ffff) as u32;
return Some((result_hi, result_lo));
}
None
}
fn decode_64_bits_bar_size(bar_size_hi: u32, bar_size_lo: u32) -> Option<u64> {
let bar_size: u64 = ((bar_size_hi as u64) << 32) | (bar_size_lo as u64);
if bar_size > 0 {
return Some(!bar_size + 1);
}
None
}
#[derive(Serialize, Deserialize, Default, Clone, Copy)]
struct PciBar {
addr: u32,
size: u32,
used: bool,
r#type: Option<PciBarRegionType>,
}
#[derive(Serialize, Deserialize)]
struct PciConfigurationState {
registers: Vec<u32>,
writable_bits: Vec<u32>,
bars: Vec<PciBar>,
rom_bar_addr: u32,
rom_bar_size: u32,
rom_bar_used: bool,
last_capability: Option<(usize, usize)>,
msix_cap_reg_idx: Option<usize>,
}
/// Contains the configuration space of a PCI node.
/// See the [specification](https://en.wikipedia.org/wiki/PCI_configuration_space).
/// The configuration space is accessed with DWORD reads and writes from the guest.
pub struct PciConfiguration {
registers: [u32; NUM_CONFIGURATION_REGISTERS],
writable_bits: [u32; NUM_CONFIGURATION_REGISTERS], // writable bits for each register.
bar_size: [u32; NUM_BAR_REGS],
bar_used: [bool; NUM_BAR_REGS],
bars: [PciBar; NUM_BAR_REGS],
rom_bar_addr: u32,
rom_bar_size: u32,
rom_bar_used: bool,
// Contains the byte offset and size of the last capability.
@@ -260,7 +314,7 @@ pub struct PciConfiguration {
}
/// See pci_regs.h in kernel
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum PciBarRegionType {
Memory32BitRegion = 0,
IORegion = 0x01,
@@ -293,6 +347,10 @@ pub enum Error {
CapabilityEmpty,
CapabilityLengthInvalid(usize),
CapabilitySpaceFull(usize),
Decode32BarSize,
Decode64BarSize,
Encode32BarSize,
Encode64BarSize,
RomBarAddressInvalid(u64, u64),
RomBarInUse(usize),
RomBarInvalid(usize),
@@ -320,6 +378,10 @@ impl Display for Error {
CapabilityEmpty => write!(f, "empty capabilities are invalid"),
CapabilityLengthInvalid(l) => write!(f, "Invalid capability length {}", l),
CapabilitySpaceFull(s) => write!(f, "capability of size {} doesn't fit", s),
Decode32BarSize => write!(f, "failed to decode 32 bits BAR size"),
Decode64BarSize => write!(f, "failed to decode 64 bits BAR size"),
Encode32BarSize => write!(f, "failed to encode 32 bits BAR size"),
Encode64BarSize => write!(f, "failed to encode 64 bits BAR size"),
RomBarAddressInvalid(a, s) => write!(f, "address {} size {} too big", a, s),
RomBarInUse(b) => write!(f, "rom bar {} already used", b),
RomBarInvalid(b) => write!(f, "rom bar {} invalid, max {}", b, NUM_BAR_REGS - 1),
@@ -333,6 +395,7 @@ impl PciConfiguration {
pub fn new(
vendor_id: u16,
device_id: u16,
revision_id: u8,
class_code: PciClassCode,
subclass: &dyn PciSubclass,
programming_interface: Option<&dyn PciProgrammingInterface>,
@@ -343,7 +406,6 @@ impl PciConfiguration {
) -> Self {
let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
let mut writable_bits = [0u32; NUM_CONFIGURATION_REGISTERS];
let bar_size = [0u32; NUM_BAR_REGS];
registers[0] = u32::from(device_id) << 16 | u32::from(vendor_id);
// TODO(dverkamp): Status should be write-1-to-clear
writable_bits[1] = 0x0000_ffff; // Status (r/o), command (r/w)
@@ -354,7 +416,8 @@ impl PciConfiguration {
};
registers[2] = u32::from(class_code.get_register_value()) << 24
| u32::from(subclass.get_register_value()) << 16
| u32::from(pi) << 8;
| u32::from(pi) << 8
| u32::from(revision_id);
writable_bits[3] = 0x0000_00ff; // Cacheline size (r/w)
match header_type {
PciHeaderType::Device => {
@@ -369,11 +432,13 @@ impl PciConfiguration {
};
registers[11] = u32::from(subsystem_id) << 16 | u32::from(subsystem_vendor_id);
let bars = [PciBar::default(); NUM_BAR_REGS];
PciConfiguration {
registers,
writable_bits,
bar_size,
bar_used: [false; NUM_BAR_REGS],
bars,
rom_bar_addr: 0,
rom_bar_size: 0,
rom_bar_used: false,
last_capability: None,
@@ -382,6 +447,31 @@ impl PciConfiguration {
}
}
fn state(&self) -> PciConfigurationState {
PciConfigurationState {
registers: self.registers.to_vec(),
writable_bits: self.writable_bits.to_vec(),
bars: self.bars.to_vec(),
rom_bar_addr: self.rom_bar_addr,
rom_bar_size: self.rom_bar_size,
rom_bar_used: self.rom_bar_used,
last_capability: self.last_capability,
msix_cap_reg_idx: self.msix_cap_reg_idx,
}
}
fn set_state(&mut self, state: &PciConfigurationState) {
self.registers.clone_from_slice(state.registers.as_slice());
self.writable_bits
.clone_from_slice(state.writable_bits.as_slice());
self.bars.clone_from_slice(state.bars.as_slice());
self.rom_bar_addr = state.rom_bar_addr;
self.rom_bar_size = state.rom_bar_size;
self.rom_bar_used = state.rom_bar_used;
self.last_capability = state.last_capability;
self.msix_cap_reg_idx = state.msix_cap_reg_idx;
}
/// Reads a 32bit register from `reg_idx` in the register map.
pub fn read_reg(&self, reg_idx: usize) -> u32 {
*(self.registers.get(reg_idx).unwrap_or(&0xffff_ffff))
@@ -390,15 +480,20 @@ impl PciConfiguration {
/// Writes a 32bit register to `reg_idx` in the register map.
pub fn write_reg(&mut self, reg_idx: usize, value: u32) {
let mut mask = self.writable_bits[reg_idx];
if reg_idx >= BAR0_REG
&& reg_idx < BAR0_REG + NUM_BAR_REGS
&& (value & BAR_MEM_ADDR_MASK) == BAR_MEM_ADDR_MASK
{
if reg_idx >= BAR0_REG && reg_idx < BAR0_REG + NUM_BAR_REGS {
// Handle very specific case where the BAR is being written with
// all 1's to retrieve the BAR size on next BAR reading.
mask = self.bar_size[reg_idx - 4];
} else if reg_idx == ROM_BAR_REG && (value & ROM_BAR_ADDR_MASK) == ROM_BAR_ADDR_MASK {
mask = self.rom_bar_size;
// all 1's to retrieve the BAR size during next BAR reading.
if value == 0xffff_ffff {
mask &= self.bars[reg_idx - 4].size;
}
} else if reg_idx == ROM_BAR_REG {
// Handle very specific case where the BAR is being written with
// all 1's on bits 31-11 to retrieve the BAR size during next BAR
// reading.
if value & ROM_BAR_ADDR_MASK == ROM_BAR_ADDR_MASK {
mask &= self.rom_bar_size;
}
}
if let Some(r) = self.registers.get_mut(reg_idx) {
@@ -459,7 +554,7 @@ impl PciConfiguration {
/// (i.e, region size must be power of two, register not already used). Returns 'None' on
/// failure all, `Some(BarIndex)` on success.
pub fn add_pci_bar(&mut self, config: &PciBarConfiguration) -> Result<usize> {
if self.bar_used[config.reg_idx] {
if self.bars[config.reg_idx].used {
return Err(Error::BarInUse(config.reg_idx));
}
@@ -481,6 +576,11 @@ impl PciConfiguration {
if end_addr > u64::from(u32::max_value()) {
return Err(Error::BarAddressInvalid(config.addr, config.size));
}
// Encode the BAR size as expected by the software running in
// the guest.
self.bars[config.reg_idx].size =
encode_32_bits_bar_size(config.size as u32).ok_or(Error::Encode32BarSize)?;
}
PciBarRegionType::Memory64BitRegion => {
if config.reg_idx + 1 >= NUM_BAR_REGS {
@@ -491,14 +591,21 @@ impl PciConfiguration {
return Err(Error::BarAddressInvalid(config.addr, config.size));
}
if self.bar_used[config.reg_idx + 1] {
if self.bars[config.reg_idx + 1].used {
return Err(Error::BarInUse64(config.reg_idx));
}
// Encode the BAR size as expected by the software running in
// the guest.
let (bar_size_hi, bar_size_lo) =
encode_64_bits_bar_size(config.size).ok_or(Error::Encode64BarSize)?;
self.registers[bar_idx + 1] = (config.addr >> 32) as u32;
self.writable_bits[bar_idx + 1] = 0xffff_ffff;
self.bar_size[config.reg_idx + 1] = (config.size >> 32) as u32;
self.bar_used[config.reg_idx + 1] = true;
self.bars[config.reg_idx + 1].addr = self.registers[bar_idx + 1];
self.bars[config.reg_idx].size = bar_size_lo;
self.bars[config.reg_idx + 1].size = bar_size_hi;
self.bars[config.reg_idx + 1].used = true;
}
}
@@ -512,8 +619,9 @@ impl PciConfiguration {
self.registers[bar_idx] = ((config.addr as u32) & mask) | lower_bits;
self.writable_bits[bar_idx] = mask;
self.bar_size[config.reg_idx] = config.size as u32;
self.bar_used[config.reg_idx] = true;
self.bars[config.reg_idx].addr = self.registers[bar_idx];
self.bars[config.reg_idx].used = true;
self.bars[config.reg_idx].r#type = Some(config.region_type);
Ok(config.reg_idx)
}
@@ -542,24 +650,26 @@ impl PciConfiguration {
self.registers[config.reg_idx] = (config.addr as u32) | active;
self.writable_bits[config.reg_idx] = ROM_BAR_ADDR_MASK;
self.rom_bar_size = config.size as u32;
self.rom_bar_addr = self.registers[config.reg_idx];
self.rom_bar_size =
encode_32_bits_bar_size(config.size as u32).ok_or(Error::Encode32BarSize)?;
self.rom_bar_used = true;
Ok(config.reg_idx)
}
/// Returns the address of the given 32 bits BAR region.
pub fn get_bar32_addr(&self, bar_num: usize) -> u32 {
/// Returns the address of the given BAR region.
pub fn get_bar_addr(&self, bar_num: usize) -> u64 {
let bar_idx = BAR0_REG + bar_num;
self.registers[bar_idx] & BAR_MEM_ADDR_MASK
}
let mut addr = u64::from(self.bars[bar_num].addr & self.writable_bits[bar_idx]);
/// Returns the address of the given 64 bits BAR region.
pub fn get_bar64_addr(&self, bar_num: usize) -> u64 {
let bar_idx = BAR0_REG + bar_num;
if let Some(bar_type) = self.bars[bar_num].r#type {
if bar_type == PciBarRegionType::Memory64BitRegion {
addr |= u64::from(self.bars[bar_num + 1].addr) << 32;
}
}
u64::from(self.registers[bar_idx] & BAR_MEM_ADDR_MASK)
| (u64::from(self.registers[bar_idx + 1]) << 32)
addr
}
/// Configures the IRQ line and pin used by this device.
@@ -645,6 +755,179 @@ impl PciConfiguration {
pub fn read_config_register(&self, reg_idx: usize) -> u32 {
self.read_reg(reg_idx)
}
pub fn detect_bar_reprogramming(
&mut self,
reg_idx: usize,
data: &[u8],
) -> Option<BarReprogrammingParams> {
if data.len() != 4 {
return None;
}
let value = LittleEndian::read_u32(data);
let mask = self.writable_bits[reg_idx];
if reg_idx >= BAR0_REG && reg_idx < BAR0_REG + NUM_BAR_REGS {
let bar_idx = reg_idx - 4;
if (value & mask) != (self.bars[bar_idx].addr & mask) {
// Handle special case where the address being written is
// different from the address initially provided. This is a
// BAR reprogramming case which needs to be properly caught.
if let Some(bar_type) = self.bars[bar_idx].r#type {
match bar_type {
PciBarRegionType::Memory64BitRegion => {}
_ => {
// Ignore the case where the BAR size is being
// asked for.
if value == 0xffff_ffff {
return None;
}
debug!(
"DETECT BAR REPROG: current 0x{:x}, new 0x{:x}",
self.registers[reg_idx], value
);
let old_base = u64::from(self.bars[bar_idx].addr & mask);
let new_base = u64::from(value & mask);
let len = u64::from(
decode_32_bits_bar_size(self.bars[bar_idx].size)
.ok_or(Error::Decode32BarSize)
.unwrap(),
);
let region_type = bar_type;
self.bars[bar_idx].addr = value;
return Some(BarReprogrammingParams {
old_base,
new_base,
len,
region_type,
});
}
}
} else if (reg_idx > BAR0_REG)
&& (self.registers[reg_idx - 1] & self.writable_bits[reg_idx - 1])
!= (self.bars[bar_idx - 1].addr & self.writable_bits[reg_idx - 1])
{
// Ignore the case where the BAR size is being asked for.
// Because we are in the 64bits case here, we have to check
// if the lower 32bits of the current BAR have already been
// asked for the BAR size too.
if value == 0xffff_ffff
&& self.registers[reg_idx - 1] & self.writable_bits[reg_idx - 1]
== self.bars[bar_idx - 1].size & self.writable_bits[reg_idx - 1]
{
return None;
}
debug!(
"DETECT BAR REPROG: current 0x{:x}, new 0x{:x}",
self.registers[reg_idx], value
);
let old_base = u64::from(self.bars[bar_idx].addr & mask) << 32
| u64::from(self.bars[bar_idx - 1].addr & self.writable_bits[reg_idx - 1]);
let new_base = u64::from(value & mask) << 32
| u64::from(self.registers[reg_idx - 1] & self.writable_bits[reg_idx - 1]);
let len = decode_64_bits_bar_size(
self.bars[bar_idx].size,
self.bars[bar_idx - 1].size,
)
.ok_or(Error::Decode64BarSize)
.unwrap();
let region_type = PciBarRegionType::Memory64BitRegion;
self.bars[bar_idx].addr = value;
self.bars[bar_idx - 1].addr = self.registers[reg_idx - 1];
return Some(BarReprogrammingParams {
old_base,
new_base,
len,
region_type,
});
}
}
} else if reg_idx == ROM_BAR_REG && (value & mask) != (self.rom_bar_addr & mask) {
// Ignore the case where the BAR size is being asked for.
if value & ROM_BAR_ADDR_MASK == ROM_BAR_ADDR_MASK {
return None;
}
debug!(
"DETECT ROM BAR REPROG: current 0x{:x}, new 0x{:x}",
self.registers[reg_idx], value
);
let old_base = u64::from(self.rom_bar_addr & mask);
let new_base = u64::from(value & mask);
let len = u64::from(
decode_32_bits_bar_size(self.rom_bar_size)
.ok_or(Error::Decode32BarSize)
.unwrap(),
);
let region_type = PciBarRegionType::Memory32BitRegion;
self.rom_bar_addr = value;
return Some(BarReprogrammingParams {
old_base,
new_base,
len,
region_type,
});
}
None
}
}
impl Pausable for PciConfiguration {}
impl Snapshottable for PciConfiguration {
fn id(&self) -> String {
String::from("pci_configuration")
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let snapshot =
serde_json::to_vec(&self.state()).map_err(|e| MigratableError::Snapshot(e.into()))?;
let mut config_snapshot = Snapshot::new(self.id().as_str());
config_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id()),
snapshot,
});
Ok(config_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(config_section) = snapshot
.snapshot_data
.get(&format!("{}-section", self.id()))
{
let config_state = match serde_json::from_slice(&config_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize {}: {}",
self.id(),
error
)))
}
};
self.set_state(&config_state);
return Ok(());
}
Err(MigratableError::Restore(anyhow!(
"Could not find {} snapshot section",
self.id()
)))
}
}
impl Default for PciBarConfiguration {
@@ -732,6 +1015,7 @@ mod tests {
let mut cfg = PciConfiguration::new(
0x1234,
0x5678,
0x1,
PciClassCode::MultimediaController,
&PciMultimediaSubclass::AudioController,
None,
@@ -787,6 +1071,7 @@ mod tests {
let cfg = PciConfiguration::new(
0x1234,
0x5678,
0x1,
PciClassCode::MultimediaController,
&PciMultimediaSubclass::AudioController,
Some(&TestPI::Test),

77
pci/src/device.rs Executable file → Normal file
View File

@@ -3,22 +3,12 @@
// found in the LICENSE-BSD-3-Clause file.
use crate::configuration::{self, PciBarRegionType};
use crate::msix::MsixTableEntry;
use crate::PciInterruptPin;
use devices::BusDevice;
use std;
use std::any::Any;
use std::fmt::{self, Display};
use std::sync::Arc;
use std::{self, io, result};
use vm_allocator::SystemAllocator;
use vm_device::BusDevice;
use vm_memory::{GuestAddress, GuestUsize};
use vmm_sys_util::eventfd::EventFd;
pub struct InterruptParameters<'a> {
pub msix: Option<&'a MsixTableEntry>,
}
pub type InterruptDelivery =
Box<dyn Fn(InterruptParameters) -> std::result::Result<(), std::io::Error> + Send + Sync>;
#[derive(Debug)]
pub enum Error {
@@ -47,20 +37,15 @@ impl Display for Error {
}
}
#[derive(Clone, Copy)]
pub struct BarReprogrammingParams {
pub old_base: u64,
pub new_base: u64,
pub len: u64,
pub region_type: PciBarRegionType,
}
pub trait PciDevice: BusDevice {
/// Assign a legacy PCI IRQ to this device.
/// The device may write to `irq_evt` to trigger an interrupt.
fn assign_pin_irq(
&mut self,
_irq_cb: Arc<InterruptDelivery>,
_irq_num: u32,
_irq_pin: PciInterruptPin,
) {
}
/// Assign MSI-X to this device.
fn assign_msix(&mut self, _msi_cb: Arc<InterruptDelivery>) {}
/// Allocates the needed PCI BARs space using the `allocate` function which takes a size and
/// returns an address. Returns a Vec of (GuestAddress, GuestUsize) tuples.
fn allocate_bars(
@@ -70,18 +55,26 @@ pub trait PciDevice: BusDevice {
Ok(Vec::new())
}
/// Gets a list of ioeventfds that should be registered with the running VM. The list is
/// returned as a Vec of (eventfd, addr, datamatch) tuples.
fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> {
Vec::new()
/// Frees the PCI BARs previously allocated with a call to allocate_bars().
fn free_bars(&mut self, _allocator: &mut SystemAllocator) -> Result<()> {
Ok(())
}
/// Sets a register in the configuration space.
/// * `reg_idx` - The index of the config register to modify.
/// * `offset` - Offset in to the register.
fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]);
/// Gets a register from the configuration space.
/// * `reg_idx` - The index of the config register to read.
fn read_config_register(&self, reg_idx: usize) -> u32;
fn read_config_register(&mut self, reg_idx: usize) -> u32;
/// Detects if a BAR is being reprogrammed.
fn detect_bar_reprogramming(
&mut self,
_reg_idx: usize,
_data: &[u8],
) -> Option<BarReprogrammingParams> {
None
}
/// Reads from a BAR region mapped in to the device.
/// * `addr` - The guest address inside the BAR.
/// * `data` - Filled with the data from `addr`.
@@ -90,4 +83,26 @@ pub trait PciDevice: BusDevice {
/// * `addr` - The guest address inside the BAR.
/// * `data` - The data to write.
fn write_bar(&mut self, _base: u64, _offset: u64, _data: &[u8]) {}
/// Relocates the BAR to a different address in guest address space.
fn move_bar(&mut self, _old_base: u64, _new_base: u64) -> result::Result<(), io::Error> {
Ok(())
}
/// Provides a mutable reference to the Any trait. This is useful to let
/// the caller have access to the underlying type behind the trait.
fn as_any(&mut self) -> &mut dyn Any;
}
/// This trait defines a set of functions which can be triggered whenever a
/// PCI device is modified in any way.
pub trait DeviceRelocation: Send + Sync {
/// The BAR needs to be moved to a different location in the guest address
/// space. This follows a decision from the software running in the guest.
fn move_bar(
&self,
old_base: u64,
new_base: u64,
len: u64,
pci_dev: &mut dyn PciDevice,
region_type: PciBarRegionType,
) -> result::Result<(), io::Error>;
}

View File

@@ -5,28 +5,32 @@
//! Implements pci devices and busses.
#[macro_use]
extern crate log;
extern crate devices;
extern crate kvm_ioctls;
extern crate hypervisor;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vm_memory;
extern crate vmm_sys_util;
mod bus;
mod configuration;
mod device;
mod msi;
mod msix;
mod vfio;
pub use self::bus::{PciConfigIo, PciConfigMmio, PciRoot, PciRootError};
pub use self::bus::{PciBus, PciConfigIo, PciConfigMmio, PciRoot, PciRootError};
pub use self::configuration::{
PciBarConfiguration, PciBarPrefetchable, PciBarRegionType, PciCapability, PciCapabilityID,
PciClassCode, PciConfiguration, PciHeaderType, PciMassStorageSubclass,
PciNetworkControllerSubclass, PciProgrammingInterface, PciSerialBusSubClass, PciSubclass,
};
pub use self::device::{
Error as PciDeviceError, InterruptDelivery, InterruptParameters, PciDevice,
BarReprogrammingParams, DeviceRelocation, Error as PciDeviceError, PciDevice,
};
pub use self::msi::MsiCap;
pub use self::msi::{msi_num_enabled_vectors, MsiCap, MsiConfig};
pub use self::msix::{MsixCap, MsixConfig, MsixTableEntry, MSIX_TABLE_ENTRY_SIZE};
pub use self::vfio::{VfioPciDevice, VfioPciError};
/// PCI has four interrupt pins A->D.
#[derive(Copy, Clone)]

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