Compare commits

...

2336 Commits

Author SHA1 Message Date
Rob Bradford
bb02c28b62 build: Update for v0.14.1 bug fix release
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-31 16:56:05 +01:00
Sebastien Boeuf
b2c96dea24 vmm: Add missing syscall for vCPU unplug
clock_nanosleep() is triggered when hot-unplugging a vCPU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
(cherry picked from commit 46f96f27a4)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-31 16:56:05 +01:00
Rob Bradford
2c81312433 vm-virtio: queue: Fix descriptor chain validation
DescriptorChain::is_valid() wrongly used .checked_offset() to attempt to
validate that the descriptor's data is in valid memory. This works in
all cases except where the guest has placed the data at the very end of
the guest memory as the offset + offset will be outside the range (as
the combined offset will be the next byte and as such out of the guest
memory). Instead use the function .check_range() takes an offset and a
length to validate

This fixes issues see with error messages featuring the
DescriptorChainTooShort error.

Fixes: #2424

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 1eb4ebe3d1)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-31 16:56:05 +01:00
Anatol Belski
e8ee29b4fe CpuManager: Fix MMIO read handling
There are two parts:

- Unconditionally zero the output area. The length of the incoming
  vector has been seen from 1 to 4 bytes, even though just the first
  byte might need to be handled. But also, this ensures any possibly
  unhandled offset will return zeroed result to the caller. The former
  implementation used an I/O port which seems to behave differently from
  MMIO and wouldn't require explicit output zeroing.
- An access with zero offset still takes place and needs to be handled.

Fixes #2437.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
(cherry picked from commit 9e9aba7c0b)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-31 16:56:05 +01:00
Anatol Belski
498939c297 hyperv: Fix CPU hotadd
The following is from the Hyper-V specification v6.0b.

Cpuid leaf 0x40000003 EDX:

Bit 3: Support for physical CPU dynamic partitioning events is
available.

When Windows determines to be running under a hypervisor, it will
require this cpuid bit to be set to support dynamic CPU operations.

Cpuid leaf 0x40000004 EAX:

Bit 5: Recommend using relaxed timing for this partition. If
used, the VM should disable any watchdog timeouts that
rely on the timely delivery of external interrupts.

This bit has been figured out as required after seeing guest BSOD
when CPU hotplug bit is enabled. Race conditions seem to arise after a
hotplug operation, when a system watchdog has expired.

Closes #1799.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
(cherry picked from commit 5b168f54a6)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-31 16:56:05 +01:00
Rob Bradford
84b3992146 build: Update Cargo.lock for release
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:46:55 +00:00
Rob Bradford
40c63dcf5e build: Update for 0.14.0 release
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:27 +00:00
Rob Bradford
970bc05271 aarch64: Address Rust 1.51.0 clippy issue (vec_init_then_push)
--> arch/src/aarch64/mod.rs:82:5
    |
82  | /     let mut regions = Vec::new();
83  | |     // 0 ~ 256 MiB: Reserved
84  | |     regions.push((
85  | |         GuestAddress(0),
...   |
107 | |         RegionType::Ram,
108 | |     ));
    | |_______^ help: consider using the `vec![]` macro: `let mut regions = vec![..];`
    |
    = note: `-D clippy::vec-init-then-push` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
4da6bcd5d5 aarch64: Address Rust 1.51.0 clippy issue (from_over_into)
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
Error:   --> devices/src/legacy/rtc_pl031.rs:73:1
   |
73 | impl Into<libc::clockid_t> for ClockType {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `-D clippy::from-over-into` implied by `-D warnings`
   = help: consider to implement `From` instead
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
3671f5e94c aarch64: Address Rust 1.51.0 clippy issue (redundant_slicing)
error: redundant slicing of the whole range
Error:    --> devices/src/legacy/gpio_pl061.rs:298:37
    |
298 |             let value = read_le_u32(&data[..]);
    |                                     ^^^^^^^^^ help: use the original slice instead: `data`
    |
    = note: `-D clippy::redundant-slicing` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
40da6210f4 aarch64: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
error: name `GPIOInterruptDisabled` contains a capitalized acronym

Error:   --> devices/src/legacy/gpio_pl061.rs:46:5
   |
46 |     GPIOInterruptDisabled,
   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GpioInterruptDisabled`
   |
   = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
3c6dfd7709 tdx: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
error: name `FinalizeTDX` contains a capitalized acronym
   --> vmm/src/vm.rs:274:5
    |
274 |     FinalizeTDX(hypervisor::HypervisorVmError),
    |     ^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `FinalizeTdx`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
e294688904 hypervisor: Address Rust 1.51.0 clippy issue (from_over_into)
warning: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
  --> hypervisor/src/vm.rs:41:1
   |
41 | impl Into<u64> for DataMatch {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(clippy::from_over_into)]` on by default
   = help: consider to implement `From` instead
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into

warning: 1 warning emitted

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
5c010d489d tests: Address Rust 1.51.0 clippy issue (needless_question_mark)
error: Question mark operator is useless here
   --> tests/integration.rs:494:13
    |
494 | /             Ok(self
495 | |                 .ssh_command("grep MemTotal /proc/meminfo | grep -o \"[0-9]*\"")?
496 | |                 .trim()
497 | |                 .parse()
498 | |                 .map_err(Error::Parsing)?)
    | |__________________________________________^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
c5d15fd938 devices: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `AcpiPMTimerDevice` contains a capitalized acronym
   --> devices/src/acpi.rs:175:12
    |
175 | pub struct AcpiPMTimerDevice {
    |            ^^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `AcpiPmTimerDevice`
    |
    = note: `#[warn(clippy::upper_case_acronyms)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
827229d8e4 pci: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `IORegion` contains a capitalized acronym
   --> pci/src/configuration.rs:320:5
    |
320 |     IORegion = 0x01,
    |     ^^^^^^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `IoRegion`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
6837de9057 vmm: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `ConvertFromUTF8` contains a capitalized acronym
  --> virtio-devices/src/vsock/unix/mod.rs:32:5
   |
32 |     ConvertFromUTF8(std::str::Utf8Error),
   |     ^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `ConvertFromUtf8`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
7c9a83f6e1 virtio-devices: Address Rust 1.51.0 clippy issue (needless_question_mark)
warning: Question mark operator is useless here
   --> virtio-devices/src/seccomp_filters.rs:485:5
    |
485 | /     Ok(SeccompFilter::new(
486 | |         rules.into_iter().collect(),
487 | |         SeccompAction::Log,
488 | |     )?)
    | |_______^
    |
    = note: `#[warn(clippy::needless_question_mark)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
help: try
    |
485 |     SeccompFilter::new(
486 |         rules.into_iter().collect(),
487 |         SeccompAction::Log,
488 |     )
    |

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
2571cc8041 virtio-devices: Address Rust 1.51.0 clippy issue (vec_init_then_push)
warning: calls to `push` immediately after creation
   --> virtio-devices/src/vhost_user/net.rs:291:13
    |
291 | /             let mut interrupt_list_sub: Vec<(Option<EventFd>, Queue)> = Vec::with_capacity(2);
292 | |             interrupt_list_sub.push(vu_interrupt_list.remove(0));
293 | |             interrupt_list_sub.push(vu_interrupt_list.remove(0));
    | |_________________________________________________________________^ help: consider using the `vec![]` macro: `let mut interrupt_list_sub: Vec<(Option<EventFd>, Queue)> = vec![..];`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
3b8d1f1411 vmm: Address Rust 1.51.0 clippy issue (vec_init_then_push)
warning: calls to `push` immediately after creation
   --> vmm/src/cpu.rs:630:9
    |
630 | /         let mut cpuid_patches = Vec::new();
631 | |
632 | |         // Patch tsc deadline timer bit
633 | |         cpuid_patches.push(CpuidPatch {
...   |
662 | |             edx_bit: Some(MTRR_EDX_BIT),
663 | |         });
    | |___________^ help: consider using the `vec![]` macro: `let mut cpuid_patches = vec![..];`
    |
    = note: `#[warn(clippy::vec_init_then_push)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
9762c8bc28 vmm: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `LocalAPIC` contains a capitalized acronym
   --> vmm/src/cpu.rs:197:8
    |
197 | struct LocalAPIC {
    |        ^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `LocalApic`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
7c302373ed vmm: Address Rust 1.51.0 clippy issue (needless_question_mark)
warning: Question mark operator is useless here
   --> vmm/src/seccomp_filters.rs:493:5
    |
493 | /     Ok(SeccompFilter::new(
494 | |         rules.into_iter().collect(),
495 | |         SeccompAction::Trap,
496 | |     )?)
    | |_______^
    |
    = note: `#[warn(clippy::needless_question_mark)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
help: try
    |
493 |     SeccompFilter::new(
494 |         rules.into_iter().collect(),
495 |         SeccompAction::Trap,
496 |     )
    |

warning: Question mark operator is useless here
   --> vmm/src/seccomp_filters.rs:507:5
    |
507 | /     Ok(SeccompFilter::new(
508 | |         rules.into_iter().collect(),
509 | |         SeccompAction::Log,
510 | |     )?)
    | |_______^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
help: try
    |
507 |     SeccompFilter::new(
508 |         rules.into_iter().collect(),
509 |         SeccompAction::Log,
510 |     )
    |

warning: Question mark operator is useless here
   --> vmm/src/vm.rs:887:9
    |
887 |         Ok(CString::new(cmdline).map_err(Error::CmdLineCString)?)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `CString::new(cmdline).map_err(Error::CmdLineCString)`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
19c5e91b6e main: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `StartVMMThread` contains a capitalized acronym
  --> src/main.rs:50:5
   |
50 |     StartVMMThread(#[source] vmm::Error),
   |     ^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `StartVmmThread`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
4a5939973c ch-remote: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `InvalidCPUCount` contains a capitalized acronym
  --> src/bin/ch-remote.rs:24:5
   |
24 |     InvalidCPUCount(std::num::ParseIntError),
   |     ^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `InvalidCpuCount`
   |
   = note: `#[warn(clippy::upper_case_acronyms)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
0c27f69f1c hypervisor: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
warning: name `TranslateGVA` contains a capitalized acronym
  --> hypervisor/src/arch/emulator/mod.rs:51:5
   |
51 |     TranslateGVA(#[source] anyhow::Error),
   |     ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `TranslateGva`
   |
   = note: `#[warn(clippy::upper_case_acronyms)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
7d5d9bdcf4 vhost_user_block: Address Rust 1.51.0 clippy issue (redundant_slicing)
error: redundant slicing of the whole range
   --> vhost_user_block/src/lib.rs:396:31
    |
396 |         right.copy_from_slice(&data[..]);
    |                               ^^^^^^^^^ help: use the original slice instead: `data`
    |
    = note: `-D clippy::redundant-slicing` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
85ad72490f arch: Address Rust 1.51.0 clippy issue (upper_case_acronyms)
error: name `RSDPPastRamEnd` contains a capitalized acronym
  --> arch/src/lib.rs:59:5
   |
59 |     RSDPPastRamEnd,
   |     ^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `RsdpPastRamEnd`
   |
   = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
80e48b545d block_util: Address Rust 1.51.0 clippy issue (ptr-arg)
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
  --> block_util/src/lib.rs:68:31
   |
68 | fn build_device_id(disk_path: &PathBuf) -> result::Result<String, Error> {
   |                               ^^^^^^^^ help: change this to: `&Path`
   |
   = note: `-D clippy::ptr-arg` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg

error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
  --> block_util/src/lib.rs:83:39
   |
83 | pub fn build_disk_image_id(disk_path: &PathBuf) -> Vec<u8> {
   |                                       ^^^^^^^^ help: change this to: `&Path`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg

error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
  --> block_util/src/lib.rs:68:31
   |
68 | fn build_device_id(disk_path: &PathBuf) -> result::Result<String, Error> {
   |                               ^^^^^^^^ help: change this to: `&Path`
   |
   = note: `-D clippy::ptr-arg` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg

error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
  --> block_util/src/lib.rs:83:39
   |
83 | pub fn build_disk_image_id(disk_path: &PathBuf) -> Vec<u8> {
   |                                       ^^^^^^^^ help: change this to: `&Path`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
eb18ea61f4 net_util: Address Rust 1.51.0 clippy issue (redundant_slicing)
error: redundant slicing of the whole range
  --> net_util/src/mac.rs:60:35
   |
60 |         bytes[..].copy_from_slice(&src[..]);
   |                                   ^^^^^^^^ help: use the original slice instead: `src`
   |
   = note: `-D clippy::redundant-slicing` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
bfbd75b2cf qcow: Address Rust 1.51.0 clippy issue (redundant-semicolons)
error: unnecessary trailing semicolon
    --> qcow/src/qcow.rs:2050:14
     |
2050 |             };
     |              ^ help: remove this semicolon
     |
     = note: `-D redundant-semicolons` implied by `-D warnings`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
6dc3d60b2d block_util: Address Rust 1.51.0 clippy issue (upper_case_acronyms)
error: name `TYPE_UNKNOWN` contains a capitalized acronym
  --> vm-virtio/src/lib.rs:48:5
   |
48 |     TYPE_UNKNOWN = 0xFF,
   |     ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Type_Unknown`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

error: name `GetDeviceID` contains a capitalized acronym
   --> block_util/src/lib.rs:138:5
    |
138 |     GetDeviceID,
    |     ^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GetDeviceId`
    |
    = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
aa34d545f6 vm-virtio, virtio-devices: Address Rust 1.51.0 clippy issue (upper_case_acronyms)
error: name `TYPE_UNKNOWN` contains a capitalized acronym
  --> vm-virtio/src/lib.rs:48:5
   |
48 |     TYPE_UNKNOWN = 0xFF,
   |     ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Type_Unknown`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
261c039831 acpi_tables: Address Rust 1.51.0 clippy issue (vec_init_then_push)
error: calls to `push` immediately after creation
    --> acpi_tables/src/aml.rs:1194:9
     |
1194 | /         let mut bytes = Vec::new();
1195 | |         bytes.push(0x8a); /* CreateDWordFieldOp */
     | |_________________________^ help: consider using the `vec![]` macro: `let mut bytes = vec![..];`
     |
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
db6516931d acpi_tables: Address Rust 1.51.0 clippy issue (upper_case_acronyms)
error: name `SDT` contains a capitalized acronym
  --> acpi_tables/src/sdt.rs:27:12
   |
27 | pub struct SDT {
   |            ^^^ help: consider making the acronym lowercase, except the initial letter: `Sdt`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
030d6046b2 api_client: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
--> api_client/src/lib.rs:40:5
   |
40 |     OK,
   |     ^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ok`
   |
   = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-26 11:32:09 +00:00
Rob Bradford
7390475636 arch: Report use of deprecated LinuxBoot protocol
With CONFIG_PVH in stable kernels for some time we should deprecate the
use of alternative boot methods since this will lead to a much simpler
boot flow and CI process.

See: #2231

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-25 13:59:19 +00:00
Rob Bradford
c4564f3ba8 block_util: Enhance error reporting for virtio-block usage
There are multiple reports of DescriptorChainTooShort errors and so add
some extra debugging to aid the debugging of this issue.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-25 13:41:54 +01:00
Wei Liu
27ba8133a4 vmm: interrupt: drop RoutingEntryExt trait
We can now directly use associated functions.

This simplifies code and causes no functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-25 10:13:43 +01:00
Wei Liu
f5c550affb vmm: interrupt: simplify interrupt handling traits
Drop the generic type E and use IrqRoutngEntry directly. This allows
dropping a bunch of trait bounds from code.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-25 10:13:43 +01:00
Wei Liu
1d9f27c9fb vmm: interrupt: extract common code from MSHV and KVM
Their make_entry functions look the same now. Extract the logic to a
common function.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-25 10:13:43 +01:00
Rob Bradford
8b7aafad16 virtio-devices: block: Remove unused members of Error enum
These are residual enum members from a previous refactoring.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-24 17:27:41 +01:00
Rob Bradford
46d082763f vm-virtio: queue: Fix comment for DescriptorChain::has_next()
This returns trues if this descriptor has another descriptor linked to
it. Not whether this descriptor chain has another one following it.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-24 17:26:53 +01:00
Rob Bradford
6170ba06d1 README.md: Update URL for hypervisor-fw
The 0.3.0 release (re)supports booting stock Ubuntu images so users
should be pointed towards that.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-24 11:41:13 +01:00
Sebastien Boeuf
63304d0be7 net_util: Check descriptor size
There is no point in queueing an empty descriptor in the list of iovecs.
Let's simply ignore such case and avoid some unnecessary processing.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-24 11:41:05 +01:00
Sebastien Boeuf
1cd186c83c docs: Update hotplug documentation with ch-remote
Replacing old instructions using curl with ch-remote ones.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-23 14:55:49 -07:00
Sebastien Boeuf
5581486149 docs: Expand memory hotplug documentation for virtio-mem
The hotplug documentation was missing the explanation on how to use
memory hotplug with virtio-mem.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-23 14:55:49 -07:00
Sebastien Boeuf
3e3c163285 docs: Extend documentation with PCI device hotplug
Add explanations about PCI device hotplug along with CPU and memory
hotplug.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-23 14:55:49 -07:00
Sebastien Boeuf
6190e64f2f docs: Add seccomp documentation
Document that seccomp is on and how to disable it along with a pointer
on how to identify missing syscalls during development.

Fixes #993

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-23 18:41:30 +01:00
Rob Bradford
88c30764e0 tests: Move test_infra from a module to crate
It must be specified as excluded from the workspace as it must not be
built on non-test targets due to issues with the ssh2 dependency and the
musl toolchain.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-23 18:04:50 +01:00
dependabot-preview[bot]
91145afa9b build(deps): bump serde from 1.0.124 to 1.0.125 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 11:52:04 +00:00
dependabot-preview[bot]
50d57b2b6f build(deps): bump serde_derive from 1.0.124 to 1.0.125 in /fuzz
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 11:15:32 +00:00
Vineeth Pillai
68401e6e4a hypervisor:mshv: Support the move of MSI routing to kernel
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
2021-03-23 11:06:13 +01:00
Vineeth Pillai
7fad74cb04 hypervisor: refactor vec_with_array_field function
refactor vec_with_array_field to common hypervisor code
so that mshv can also make use of it.

Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
2021-03-23 11:06:13 +01:00
dependabot-preview[bot]
b8c0cd5cd4 build(deps): bump serde_derive from 1.0.124 to 1.0.125
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 08:10:45 +00:00
dependabot-preview[bot]
874ffe60ca build(deps): bump serde from 1.0.124 to 1.0.125
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 07:28:35 +00:00
dependabot-preview[bot]
e9793020c2 build(deps): bump libc from 0.2.90 to 0.2.91
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.90 to 0.2.91.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.90...0.2.91)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 06:56:04 +00:00
Sebastien Boeuf
d370ea585b deps: bump iced-x86 from 1.10.3 to 1.11.0
Bumps iced-x86 from 1.10.3 to 1.11.0.

Manual update of the code was needed since memory_displacement() was
deprecated and replaced with either memory_displacement32() or
memory_displacement64().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-22 15:17:09 +00:00
Sebastien Boeuf
1e11e6789a vmm: device_manager: Factorize passthrough_device creation
There's no need to have the code creating the passthrough_device being
duplicated since we can factorize it in a function used in both cases
(both cold plugged and hot plugged devices VFIO devices).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-22 10:47:33 +01:00
dependabot-preview[bot]
f6da2bb5e1 build(deps): bump anyhow from 1.0.38 to 1.0.39 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.38 to 1.0.39.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.38...1.0.39)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-22 07:47:26 +00:00
dependabot-preview[bot]
987e52090f build(deps): bump anyhow from 1.0.38 to 1.0.39
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.38 to 1.0.39.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.38...1.0.39)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-20 08:05:06 +00:00
dependabot-preview[bot]
195ac4c5dc build(deps): bump vhost from ee3e872 to 05cd8b2
Bumps [vhost](https://github.com/rust-vmm/vhost) from `ee3e872` to `05cd8b2`.
- [Release notes](https://github.com/rust-vmm/vhost/releases)
- [Commits](ee3e872270...05cd8b2ad3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-19 07:52:46 +00:00
dependabot-preview[bot]
685a1760f3 build(deps): bump libc from 0.2.89 to 0.2.90 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.89 to 0.2.90.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.89...0.2.90)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-19 07:52:32 +00:00
dependabot-preview[bot]
e39924d45a build(deps): bump libc from 0.2.89 to 0.2.90
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.89 to 0.2.90.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.89...0.2.90)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-18 21:29:25 +00:00
Sebastien Boeuf
b06fd80fa9 vmm: device_manager: Use DeviceTree to store PCI devices
Extend and use the existing DeviceTree to retrieve useful information
related to PCI devices. This removes the duplication with pci_devices
field which was internal to the DeviceManager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Sebastien Boeuf
c8c3cad8cb vmm: device_manager: Update structure holding PCI IRQs
Make the code a bit clearer by changing the naming of the structure
holding the list of IRQs reserved for PCI devices. It is also modified
into an array of 32 entries since we know this is the amount of PCI
slots that is supported.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Sebastien Boeuf
e311fd66cd vmm: device_manager: Remove the need for Any
We define a new enum in order to classify PCI device under virtio or
VFIO. This is a cleaner approach than using the Any trait, and
downcasting it to find the object back.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Sebastien Boeuf
fbd624d816 vmm: device_manager: Remove pci_id_list
Introduces a tuple holding both information needed by pci_id_list and
pci_devices.

Changes pci_devices to be a BTreeMap of this new tuple.

Now that pci_devices holds the information needed from pci_id_list,
pci_id_list is no longer needed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Sebastien Boeuf
305e095d15 vmm: device_manager: Invert pci_id_list HashMap
In anticipation for further factorization, the pci_id_list is now a
hashmap of PCI b/d/f leading to each device name.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Sebastien Boeuf
62aaccee28 vmm: Device name verification based on DeviceTree
Instead of relying on a PCI specific device list, we use the DeviceTree
as a reference to determine if a device name is already in use or not.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-18 15:26:25 +01:00
Rob Bradford
13724dbd22 main: Remove messages from startup
Remove the startup message containing incomplete VM configuration
details. It's a bit unusual for a tool such as Cloud Hypervisor to print
those kind of details which are a direct representation of the command
line.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-18 11:32:28 +00:00
Rob Bradford
16cb40733a tests: Extract out generic integration test code
This includes:

* OS disk image management
* Cloud init creation
* SSH to guest access
* Waiting for guest to boot

This will be useful in other projects that want to do similar things in
their integration tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-17 12:18:04 +00:00
Rob Bradford
9440304183 vmm: http: Error out earlier if we can't create API server
This removes a panic inside the API thread.

Fixes: #2395

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-17 11:30:26 +00:00
Rob Bradford
78f9ddc6be main: Remove default API sever path
Only create an API server if the use specifies one with `--api-socket`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-17 11:30:26 +00:00
Rob Bradford
9b0996a71f vmm, main: Optionalise creation of API server
Only if we have a valid API server path then create the API server. For
now this has no functional change there is a default API server path in
the clap handling but rather prepares to do so optionally.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-17 11:30:26 +00:00
Zide Chen
f685f0e0b2 vm-virtio: initialize MSI-X vectors with VIRTIO_MSI_NO_VECTOR
In case of the virtio frontend driver doesn't need interupts for
certain queue event, it may explicitly write VIRTIO_MSI_NO_VECTOR
to the virtio common configuration, or it may doesn't configure
the event type vector at all.

This patch initializes both MSI-X configuration vector and queue vector
with VIRTIO_MSI_NO_VECTOR, so that the backend drivers won't trigger
unexpected interrupts to the guest.

Signed-off-by: Zide Chen <zide.chen@intel.com>
2021-03-17 08:05:24 +01:00
dependabot-preview[bot]
40a3c31df4 build(deps): bump vfio-ioctls from a87b13b to ed8d253
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio-ioctls) from `a87b13b` to `ed8d253`.
- [Release notes](https://github.com/rust-vmm/vfio-ioctls/releases)
- [Commits](a87b13bdec...ed8d253457)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-17 07:58:11 +01:00
Sebastien Boeuf
04dc496808 ci: Enable baremetal VFIO integration tests
Relying on a NVIDIA Tesla T4 card present in the SGX machine, this patch
enables baremetal VFIO testing, validated by running several NVIDIA
tools in the guest. The guest image has been prepared to include all the
software needed to run these tests.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-16 18:59:46 +00:00
Henry Wang
d0c0a98eda docs: Update the device model documentation
This commit updates the device model documentation with Arm
specific devices.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
Henry Wang
205e587fad tests: Enable test_power_button for AArch64
This commit enables the test_power_button test case for AArch64.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
Henry Wang
2bb153de2b vmm: Implement the power button method for AArch64
This commit implements the power button method for AArch64 using
the PL061 GPIO controller.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
Henry Wang
c853ed3fdc resources: Enable GPIO PL061 driver in kernel
This commit enables the kernel config of PL061 GPIO controller.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
Henry Wang
a59ff42a95 aarch64: Add PL061 for device tree implementation
This commit adds a new legacy device PL011 for the AArch64 device
tree implementation.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
Penny Zheng
7c86ef8a69 devices: legacy: Add Arm PL061 GPIO controller
This commit implements ARM PrimeCell General Purpose Input/Output
(GPIO) PL061 device specification.

Signed-off-by: Penny Zheng <penny.zheng@arm.com>
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 20:27:15 +08:00
dependabot-preview[bot]
c7438c8b22 build(deps): bump libc from 0.2.88 to 0.2.89 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.88 to 0.2.89.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.88...0.2.89)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-16 08:13:22 +00:00
dependabot-preview[bot]
3df2e2629b build(deps): bump io-uring from 0.5.0 to 0.5.1 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.0 to 0.5.1.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [Commits](https://github.com/tokio-rs/io-uring/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-16 08:13:10 +00:00
Henry Wang
06d83d2eb3 docs: device_model: Updated the serial device doc
As we switched the AArch64 serial device to PL011, we also need to
update the documentation.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 11:53:51 +08:00
Henry Wang
9c3b489f0e tests: Switch AArch64 serial test cases to ttyAMA0
This commit switches the serial test cases for AArch64 to ttyAMA0.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 11:53:51 +08:00
Henry Wang
3965a8505b resources: AArch64: Enable PL011 driver in kernel
This commit enables the kernel config of PL011 UART controller.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 11:53:51 +08:00
Henry Wang
a8cde12b14 vmm: AArch64: Use PL011 for AArch64 device tree
This commit switches the default serial device from 16550 to the
Arm dedicated UART controller PL011. The `ttyAMA0` can be enabled.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 11:53:51 +08:00
Henry Wang
fd95acc60f devices: legacy: Implement Arm PL011 UART
This commit implements the Arm PrimeCell UART(PL011) device.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2021-03-16 11:53:51 +08:00
dependabot-preview[bot]
c85fba0c43 build(deps): bump libc from 0.2.88 to 0.2.89
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.88 to 0.2.89.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.88...0.2.89)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-15 23:40:01 +00:00
Iggy Jackson
fea1f370ff docs: Add virtiofs root howto
Add a quick HowTo for using a virtiofs root filesystem in a
cloud-hypervisor guest.

Signed-off-by: Iggy Jackson <iggy@theiggy.com>
2021-03-16 00:10:49 +01:00
Bo Chen
6307db5699 virtio-devices: seccomp: Add 'timerfd_settime' to block device
The `timerfd_settime` syscall is required when I/O throttling is
enabled.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-03-15 20:19:33 +00:00
dependabot-preview[bot]
548426c128 build(deps): bump io-uring from 0.5.0 to 0.5.1
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.0 to 0.5.1.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [Commits](https://github.com/tokio-rs/io-uring/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-15 17:51:01 +00:00
Michael Zhao
c3a75dafc5 tests: Enable serial test cases for AArch64
Enabled all "ttyS0" related test cases:
- test_serial_off
- test_serial_tty
- test_serial_file

Enabled mandatory guest kernel driver for "ns16550a" on AArch64.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2021-03-15 20:59:50 +08:00
Michael Zhao
ee7fcdb3cf aarch64: Correct wrong settings for serial device
Corrected:
- The device name in FDT
- MMIO mapping size

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2021-03-15 20:59:50 +08:00
Michael Zhao
afc83582be aarch64: Enable IRQ routing for legacy devices
On AArch64, interrupt controller (GIC) is emulated by KVM. VMM need to
set IRQ routing for devices, including legacy ones.

Before this commit, IRQ routing was only set for MSI. Legacy routing
entries of type KVM_IRQ_ROUTING_IRQCHIP were missing. That is way legacy
devices (like serial device ttyS0) does not work.

The setting of X86 IRQ routing entries are not impacted.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2021-03-15 20:59:50 +08:00
dependabot-preview[bot]
2a8bdf710d build(deps): bump syn from 1.0.63 to 1.0.64 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.63 to 1.0.64.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.63...1.0.64)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-15 08:35:57 +00:00
dependabot-preview[bot]
210a9d40c8 build(deps): bump regex from 1.4.4 to 1.4.5
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.4 to 1.4.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.4.4...1.4.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-14 22:03:20 +00:00
dependabot-preview[bot]
5bb10adf22 build(deps): bump syn from 1.0.63 to 1.0.64
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.63 to 1.0.64.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.63...1.0.64)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-14 22:03:04 +00:00
dependabot-preview[bot]
97f8f0fb31 build(deps): bump openssl-sys from 0.9.60 to 0.9.61
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.60 to 0.9.61.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.60...openssl-sys-v0.9.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-14 22:02:49 +00:00
Rob Bradford
5bc311184e build: Remove url crate dependency
This removes multiple transitive dependencies and speeds up our build.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-12 16:52:55 +01:00
Rob Bradford
7f96eb2b67 vmm: migration: Simplify url socket handling in migration code
Extract URL handling to a common function and simplify to remove url
crate dependency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-12 16:52:55 +01:00
Rob Bradford
ab4b30edd3 vmm: Switch MemoryManager::send() to url_to_path()
This continues the work in cc78a597cd

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-12 16:52:55 +01:00
Rob Bradford
cc78a597cd vmm: Simplify snapshot/restore path handling
Extend the existing url_to_path() to take the URL string and then use
that to simplify the snapshot/restore code paths.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-12 13:03:01 +01:00
Bo Chen
ebcbab739e vmm: openapi: Add rate_limiter_config to the `DiskConfig
Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-03-12 09:35:03 +01:00
Bo Chen
0c7541473c docs: Add documentation on I/O throttling
Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-03-12 09:35:03 +01:00
Bo Chen
169d6f6756 fuzz: Update the 'block' fuzz target with the rate limiter support
Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-03-12 09:35:03 +01:00
Bo Chen
af8def364d virtio-devices, vmm: add I/O rate limiter on block device
This patch is based on the 'rate_limiter' module from firecracker[1]. To
simplify dependencies, we reply on 'vmm-sys-util::TimerFd' instead of
the `timerfd` crate.

[1]https://github.com/firecracker-microvm/firecracker/tree/master/src/rate_limiter

Fixes: #1285

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-03-12 09:35:03 +01:00
dependabot-preview[bot]
c45a9a390d build(deps): bump regex from 1.4.3 to 1.4.4
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.3 to 1.4.4.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.4.3...1.4.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-12 08:33:23 +00:00
dependabot-preview[bot]
b5929645c6 build(deps): bump regex-syntax from 0.6.22 to 0.6.23
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.22 to 0.6.23.
- [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>
2021-03-12 08:33:05 +00:00
Sebastien Boeuf
ec9e6edcd0 virtio-devices: Remove unused update_memory() from VirtioDevice trait
Now that virtio devices can be updated with add_memory_region(), there's
no need to keep update_memory() around.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
00873e5f84 vmm: device_manager: Update virtio devices memory with a single region
Relies on the preliminary work allowing virtio devices to be updated
with a single memory at a time instead of updating the entire memory at
once.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
9e53efa3ca virtio-devices: Add support for adding a single memory region
Assuming vhost-user devices support CONFIGURE_MEM_SLOTS protocol
feature, we introduce a new method to the VirtioDevice trait in order to
update one single memory at a time.

In case CONFIGURE_MEM_SLOTS is not supported by the backend (feature not
acked), we fallback onto the current way of updating the memory
mappings, that is with SET_MEM_TABLE.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
4f22f57651 vhost_user_net: Enable CONFIGURE_MEM_SLOTS protocol feature
In order to support GET_MAX_MEM_SLOTS, ADD_MEM_REG and REM_MEM_REG, the
protocol feature CONFIGURE_MEM_SLOTS must be enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
1e1cbc53c1 vhost_user_blk: Enable CONFIGURE_MEM_SLOTS protocol feature
In order to support GET_MAX_MEM_SLOTS, ADD_MEM_REG and REM_MEM_REG, the
protocol feature CONFIGURE_MEM_SLOTS must be enabled.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
8255d5f774 vhost_user_backend: Move to latest vhost version
The latest vhost version adds the support for the new commands
get_max_mem_slots(), add_mem_region() and remove_mem_region(), all
related to the new vhost-user protocol feature CONFIGURE_MEM_SLOTS.

The vhost_user_backend crate is updated accordingly in order to support
these new commands, mostly related to the capability of updating the
guest memory mappings with a finer control than set_mem_table() command.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
e3a8d6c13c virtio-devices: vhost-user: net: Fix seccomp filters
On x86_64 architecture, multiple syscalls were missing when shutting
down the vhost-user-net device along with the VM. This was causing the
usual crash related to seccomp filters.

This commit adds these missing syscalls to fix the issue.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Sebastien Boeuf
581bf4aad5 virtio-devices: vhost-user: Fix device reset
There is no need to get the vring base when resetting the vhost-user
device. This was mostly ignored, but in some cases, it was causing some
actual errors.

A reset must simply be a combination of disabling the vrings along with
the reset of the owner.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-11 19:04:21 +01:00
Jiachen Zhang
16b82f3dfe vhost-user: Make ActivateError messages more consistent
Originally, VhostUserSetup is only used by vhost-user-fs. While
vhost-user-blk and vhost-user-net have their own error messages,
we rename VhostUserSetup to VhostUserFsSetup.

Signed-off-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
2021-03-11 15:09:07 +00:00
dependabot-preview[bot]
675a8f808c build(deps): bump signal-hook from 0.3.6 to 0.3.7 in /fuzz
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.6 to 0.3.7.
- [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>
2021-03-11 09:29:26 +00:00
dependabot-preview[bot]
59e5048436 build(deps): bump byteorder from 1.4.2 to 1.4.3 in /fuzz
Bumps [byteorder](https://github.com/BurntSushi/byteorder) from 1.4.2 to 1.4.3.
- [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.4.2...1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-11 08:45:59 +00:00
dependabot-preview[bot]
7b3e79cdfa build(deps): bump signal-hook from 0.3.6 to 0.3.7
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.6 to 0.3.7.
- [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>
2021-03-11 08:45:27 +00:00
Rob Bradford
66ffaceffc vmm: tdx: Correctly populate the 64-bit MMIO region
The MMIO structure contains the length rather than the maximum address
so it is necessary to subtract the starting address from the end address
to calculate the length.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-10 14:45:51 +00:00
dependabot-preview[bot]
4e307788b7 build(deps): bump byteorder from 1.4.2 to 1.4.3
Bumps [byteorder](https://github.com/BurntSushi/byteorder) from 1.4.2 to 1.4.3.
- [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.4.2...1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 13:14:58 +00:00
Muminul Islam
8739f6cccb scripts: Fix windows test script for running on MSHV
In order to run Windows test on MSHV we need to build and test using
MSHV feature.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-03-10 10:08:12 +00:00
dependabot-preview[bot]
5599cbef50 build(deps): bump syn from 1.0.62 to 1.0.63 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.62...1.0.63)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 08:03:10 +00:00
dependabot-preview[bot]
4c52ad2550 build(deps): bump syn from 1.0.62 to 1.0.63
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.62...1.0.63)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 08:02:59 +00:00
Rob Bradford
a0c07474a3 vmm: seccomp: Add KVM_MEMORY_ENCRYPT_OP ioctl to seccomp filter
This is the basis for TDX based operations on the various KVM file
descriptors.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-09 16:26:06 +01:00
Rob Bradford
be0cbb09b1 build: Clippy check with "tdx" feature
In the absence of a way of integration testing this testing that it
compiles is reasonable compromise.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
d24aa887b6 vmm: Reject VM snapshot request if TDX in use
It is not possible to snapshot the contents of a TDX VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
835a31e283 vmm: config: Require max and boot vCPUs to be equal for TDX
CPU hotplug is not possible with TDX

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
57c8c250fd tdx: Permit starting Cloud Hypervisor without --kernel
This is not required if TDX is present.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
62abc117ab tdx: Configure TDX state for the VM
Load the sections backed from the file into their required addresses in
memory and populate the HOB with details of the memory. Using the HOB
address initialize the TDX state in the vCPUs and finalize the TDX
configuration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
1c54fc3ab7 hypervisor: Support creating a VM of a specified KVM type
This is necessary to support creating a TD VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
57ce0986f7 vmm: cpu: Add functionality for enabling TDX for all vCPUs
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
c8cad394b5 vmm: cpu: Expose the common/shared CPUID data for all vCPUs
This allows the CPUID data to be passed into the VM level ioctl used for
initalizing TDX.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
b02aff5761 vmm: memory_manager: Disable dirty page logging when running on TDX
It is not permitted to have this enabled in memory that is part of a TD.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
f282cc001a tdx: Add abstraction to call TDX ioctls to hypervisor
Add API to the hypervisor interface and implement for KVM to allow the
special TDX KVM ioctls on the VM and vCPU FDs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
c48e82915d vmm: Make kernel optional in VM internals
When booting with TDX no kernel is supplied as the TDFV is responsible
for loading the OS. The requirement to have the kernel is still
currently enforced at the validation entry point; this change merely
changes function prototypes and stored state to use Option<> to support.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
66a3bed086 vmm: config: Add "--tdx" option parsing
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
45cc26f940 tdx: Add support for generating a TD HOB list
This is used to communicate details of the memory configuration from the
VMM into the TDMF.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
77955bd8f9 tdx: Add support for parsing TDVF metadata
Add support extracting the sections out for a TDVF file which can be
then used to load the TDVF and TD HOB data into their appropriate
locations.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Rob Bradford
e61ee6bcac tdx: Add "tdx" feature with an empty module inside arch to implement
Add the skeleton of the "tdx" feature with a module ready inside the
arch crate to store implementation details.

TEST=cargo build --features="tdx"

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 18:30:00 +00:00
Vineeth Pillai
fd9bd1c86c main: minor fix in the help message for event monitor
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
2021-03-08 15:32:18 +00:00
Rob Bradford
cf9e81c05a build: Update kvm-ioctls and kvm-bindings dependencies
These need to be updated together as the kvm-ioctls depends upon a
strictly newer version of kvm-bindings which requires a rebase in the CH
fork.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-08 14:52:30 +00:00
dependabot-preview[bot]
a4a2d6fbee build(deps): bump syn from 1.0.61 to 1.0.62 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.61 to 1.0.62.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.61...1.0.62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 08:56:23 +00:00
dependabot-preview[bot]
94083793a6 build(deps): bump serde from 1.0.123 to 1.0.124 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 08:46:07 +00:00
dependabot-preview[bot]
8ae966e975 build(deps): bump syn from 1.0.61 to 1.0.62
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.61 to 1.0.62.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.61...1.0.62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 07:46:17 +00:00
dependabot-preview[bot]
f68fe54b9b build(deps): bump vhost from 62fd4ec to 7784304
Bumps [vhost](https://github.com/rust-vmm/vhost) from `62fd4ec` to `7784304`.
- [Release notes](https://github.com/rust-vmm/vhost/releases)
- [Commits](62fd4ec5a4...7784304860)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 07:45:52 +00:00
dependabot-preview[bot]
54e1796da6 build(deps): bump serde from 1.0.123 to 1.0.124
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-07 23:09:32 +00:00
dependabot-preview[bot]
c8be08adf6 build(deps): bump serde_derive from 1.0.123 to 1.0.124
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-07 21:54:56 +00:00
dependabot-preview[bot]
ccfa34d066 build(deps): bump libc from 0.2.87 to 0.2.88
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.87 to 0.2.88.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.87...0.2.88)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-05 18:39:37 +00:00
Sebastien Boeuf
d65a0b68b9 Revert "Jenkinsfile: Temporarily disable SGX CI"
This reverts commit 526cf32a78.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-05 19:02:30 +01:00
William Douglas
56028fb214 Try to restore pty configuration on reboot
When a vm is created with a pty device, on reboot the pty fd (sub
only) will only be associated with the vmm through the epoll event
loop. The fd being polled will have been closed due to the vm itself
dropping the pty files (and potentially reopening the fd index to a
different item making things quite confusing) and new pty fds will be
opened but not polled on for input.

This change creates a structure to encapsulate the information about
the pty fd (main File, sub File and the path to the sub File). On
reboot, a copy of the console and serial pty structs is then passed
down to the new Vm  instance which will be used instead of creating a
new pty device.

This resolves the underlying issue from #2316.

Signed-off-by: William Douglas <william.r.douglas@gmail.com>
2021-03-05 18:34:52 +01:00
Sebastien Boeuf
933d41cf2f vmm: Provide DMA mapping handlers to virtio-mem devices
Now that virtio-mem devices can update VFIO mappings through dedicated
handlers, let's provide them from the DeviceManager.

Important to note these handlers should either be provided to virtio-mem
devices or to the unique virtio-iommu device. This must be mutually
exclusive.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-05 10:38:42 +01:00
Sebastien Boeuf
61f9a4ec6c virtio-devices: mem: Accept handlers to update DMA mappings
Create two functions for registering/unregistering DMA mapping handlers,
each handler being associated with a VFIO device.

Whenever the plugged_size is modified (which means triggered by the
virtio-mem driver in the guest), the virtio-mem backend is responsible
for updating the DMA mappings related to every VFIO device through the
handler previously provided.

It's important to update the map when the handler is either registered
or unregistered as well, as we don't want to miss some plugged memory
that would have been added before the VFIO device is added to the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-05 10:38:42 +01:00
Sebastien Boeuf
080ea31813 pci, vmm: Manage VFIO DMA mapping from DeviceManager
Instead of letting the VfioPciDevice take the decision on how/when to
perform the DMA mapping/unmapping, we move this to the DeviceManager
instead.

The point is to let the DeviceManager choose which guest memory regions
should be mapped or not. In particular, we don't want the virtio-mem
region to be mapped/unmapped as it will be virtio-mem device
responsibility to do so.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-05 10:38:42 +01:00
Sebastien Boeuf
d6db2fdf96 vmm: memory_manager: Add ACPI hotplug region to default memory zone
When memory is resized through ACPI, a new region is added to the guest
memory. This region must also be added to the corresponding memory zone
in order to keep everything in sync.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-05 10:38:42 +01:00
dependabot-preview[bot]
f1aa09f178 build(deps): bump syn from 1.0.60 to 1.0.61 in /fuzz
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.60 to 1.0.61.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.60...1.0.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-05 07:49:52 +00:00
dependabot-preview[bot]
8cbb7b15a9 build(deps): bump syn from 1.0.60 to 1.0.61
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.60 to 1.0.61.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.60...1.0.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-05 07:14:58 +00:00
Rob Bradford
b65502c3c1 main: Refine event monitor control
Replace "--monitor-fd" with "--event-monitor" which can either take
"fd=<int>" or "path=<path>" which can point to e.g. a named pipe and
allow more flexibility.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-04 19:12:40 +01:00
dependabot-preview[bot]
3ef7c8eac5 build(deps): bump vhost from 576694b to 62fd4ec
Bumps [vhost](https://github.com/rust-vmm/vhost) from `576694b` to `62fd4ec`.
- [Release notes](https://github.com/rust-vmm/vhost/releases)
- [Commits](576694bcfb...62fd4ec5a4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-04 08:38:19 +00:00
Sebastien Boeuf
526cf32a78 Jenkinsfile: Temporarily disable SGX CI
Since the SGX server is down for maintenance, all builds are waiting on
the node agent to answer, causing all PRs to be blocked.

Let's disable temporarily the SGX CI until the server is back up.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-03 09:56:05 +00:00
dependabot-preview[bot]
b0ddc5bd60 build(deps): bump libc from 0.2.86 to 0.2.87 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.86 to 0.2.87.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.86...0.2.87)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 10:21:43 +01:00
dependabot-preview[bot]
b72f6046e5 build(deps): bump vfio-ioctls from 0903c22 to a87b13b
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio-ioctls) from `0903c22` to `a87b13b`.
- [Release notes](https://github.com/rust-vmm/vfio-ioctls/releases)
- [Commits](0903c222fa...a87b13bdec)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 10:21:17 +01:00
dependabot-preview[bot]
8a2bd01e25 build(deps): bump once_cell from 1.7.1 to 1.7.2
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.7.1 to 1.7.2.
- [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.7.1...v1.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 15:53:53 +00:00
dependabot-preview[bot]
d433ae1656 build(deps): bump libc from 0.2.86 to 0.2.87
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.86 to 0.2.87.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.86...0.2.87)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 11:14:57 +00:00
dependabot-preview[bot]
0348f480fa build(deps): bump once_cell from 1.7.0 to 1.7.1
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.7.0 to 1.7.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.7.0...v1.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 09:24:39 +00:00
Wei Liu
74565538ae hypervisor: mshv: hook up TranslateGVA hypercall
At this stage this is the bare minimum needed to make Windows server
2019 work on MSHV.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-02 07:08:36 +01:00
Rob Bradford
99baee8d37 tests: Move Windows integration test to updated OVMF
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-03-01 22:11:19 +00:00
Wei Liu
030a86db17 hypervisor: mshv: simplify GVA to GPA cache
So far we've only had the need to emulate one instruction. There is no
need to use a HashMap when a simple tuple for the initial mapping will
do.

We can bring back the HashMap once more sophisticated use cases surface.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-01 17:50:47 +00:00
Wei Liu
3eb5b67dc3 hypervisor: mshv: make SoftTLB part of MshvEmulatorContext
This avoids code complexity down the line when we get around
implementing Windows support.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-03-01 17:50:47 +00:00
Sebastien Boeuf
c27d6df233 vhost: Bump to latest version from upstream
Moving to the latest version of the rust-vmm/vhost crate, before it gets
published on crates.io.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-01 15:53:46 +01:00
dependabot-preview[bot]
30cd3cb764 deps: bump io-uring from 0.4.0 to 0.5.0
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/tokio-rs/io-uring/releases)
- [Commits](https://github.com/tokio-rs/io-uring/commits)

The API was changed, hence some changes were needed to keep the code
building and functional.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-03-01 11:08:25 +00:00
dependabot-preview[bot]
e31c2be60a build(deps): bump serde_json from 1.0.63 to 1.0.64
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.63 to 1.0.64.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.63...v1.0.64)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-28 18:35:17 +00:00
dependabot-preview[bot]
fb853a50b1 build(deps): bump serde_json from 1.0.62 to 1.0.63
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.62...v1.0.63)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 13:00:32 +00:00
dependabot-preview[bot]
8c38d9576c build(deps): bump adler from 1.0.1 to 1.0.2
Bumps [adler](https://github.com/jonas-schievink/adler) from 1.0.1 to 1.0.2.
- [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/v1.0.1...v1.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 12:46:18 +00:00
dependabot-preview[bot]
5e98810c2d build(deps): bump libfuzzer-sys from 0.3.5 to 0.4.0 in /fuzz
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.3.5 to 0.4.0.
- [Release notes](https://github.com/rust-fuzz/libfuzzer/releases)
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/commits/0.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 12:07:51 +00:00
Rob Bradford
f8875acec2 misc: Bulk upgrade dependencies
In particular update for the vmm-sys-util upgrade and all the other
dependent packages. This requires an updated forked version of
kvm-bindings (due to updated vfio-ioctls) but allowed the removal of our
forked version of kvm-ioctls.

The changes to the API from kvm-ioctls and vmm-sys-util required some
other minor changes to the code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-26 11:31:08 +00:00
Sebastien Boeuf
fa8fcf5f4c vhost: Move to upstream crate
The vhost crate from rust-vmm is ready, which is why we do the switch
from the Cloud Hypervisor fork to the upstream crate.

At the same time, we rename the crate from vhost_rs to vhost.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-25 11:20:41 +01:00
dependabot-preview[bot]
3e847112db build(deps): bump once_cell from 1.6.0 to 1.7.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.6.0 to 1.7.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.6.0...v1.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-24 19:43:07 +00:00
Sebastien Boeuf
a0a89b1346 pci, vmm: Move to upstream vfio-ioctls crate
This commit moves both pci and vmm code from the internal vfio-ioctls
crate to the upstream one from the rust-vmm project.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-24 08:02:37 +01:00
Sebastien Boeuf
aee1155870 virtio-devices, vmm: Move to ExternalDmaMapping from vm-device
Now that ExternalDmaMapping is defined in vm-device, let's use it from
there.

This commit also defines the function get_host_address_range() to move
away from the vfio-ioctls dependency.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-24 08:02:37 +01:00
Sebastien Boeuf
5bd05b1af0 vm-device: Move ExternalDmaMapping trait out of vfio-ioctls
By moving the trait and its VFIO implementation out of vfio-ioctls, we
give anticipate for the move to the vfio-ioctls from rust-vmm.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-24 08:02:37 +01:00
Rob Bradford
727287b69d build: Drop aarch64 cross-build
This has been lagging behind on an older Rust version and we have
enough coverage from our Jenkins CI agent.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
deedfcdc35 vmm: Improve restore error message about URL conversion
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
2122233047 build: Remove "wait-timeout" dependency to dev-dependencies
This is only use in the integration test and was erroneously included in
the main binary dependencies.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
afce21ba59 arch: Run interrupt tests
The interrupt tests were not being run as they were erroneously under a
feature guard that does not exist in arch.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
ade5097878 arch: use libc::getrandom() instead of rand crate
This removes the last use of rand in our tree and the removal of several
dependencies.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
24922ce1e3 tests: Move integration tests to vmm_sys_util::tempdir::TempDir
This removes the dependency on "tempdir" which in turn depends on the
large rand dependency chain.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Rob Bradford
c1be41bfbf net_util: Replace use of rand crate with libc::getrandom()
The rand crate provides a full cross platform true cryptographic random
number implementation. As such it brings it lots of othe dependencies
and increases our binary size and compile time. This is excessive for
generating a MAC address.

From the cargo tree output:

│   │   ├── rand v0.8.3
│   │   │   ├── libc v0.2.86
│   │   │   ├── rand_chacha v0.3.0
│   │   │   │   ├── ppv-lite86 v0.2.10
│   │   │   │   └── rand_core v0.6.0
│   │   │   │       └── getrandom v0.2.0
│   │   │   │           ├── cfg-if v0.1.10
│   │   │   │           └── libc v0.2.86
│   │   │   └── rand_core v0.6.0 (*)

And cargo bloat:

 0.0%   0.4% 40.4KiB rand_chacha rand_chacha::guts::refill_wide::impl_sse2
 0.0%   0.4% 40.0KiB rand_chacha rand_chacha::guts::refill_wide::impl_ssse3
 0.0%   0.3% 37.6KiB rand_chacha rand_chacha::guts::refill_wide::impl_avx
 0.0%   0.3% 37.2KiB rand_chacha rand_chacha::guts::refill_wide::impl_sse41
 0.0%   0.2% 26.1KiB rand_chacha rand_chacha::guts::refill_wide::impl_avx2

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-23 11:07:48 +00:00
Bo Chen
d361fc1a36 vmm: config: Fix and complete the help info for the '--disk' option
The help information displayed for our `--disk` option is incorrect and
incomplete, e.g. missing the `direct` and `poll_queue` field.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-02-23 08:55:33 +01:00
Wei Liu
49214cf02b hypervisor: emulator: fix MOVZX
According to Intel's mnemonic (which is used by iced-x86) the first
argument is destination while the second is source.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-23 07:42:33 +01:00
Rob Bradford
d78b2ec8b5 tests: Use vmm_sys_util::tempfile::Tempfile in integration tests
This removes the requirement for an extra crate and simplifies the
dependency chain.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
Rob Bradford
946c484590 devices: Remove dependency on tempfile crate
This was completely unused.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
Rob Bradford
cd700bf449 virtio-devices: Remove dependency on tempfile crate
This was completely unused.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
Rob Bradford
cf7a05ecb5 block_util: Use vmm_sys_util::tempfile::Tempfile
This removes the requirement for an extra crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
Rob Bradford
0497a7c311 qcow: Use vmm_sys_util::tempfile::Tempfile
This removes the requirement for an extra crate.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
Rob Bradford
05a2b3fac2 vmm: Remove "tempfile" dependency from vmm
This was completely unused.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-22 14:29:53 +01:00
dependabot-preview[bot]
d33c0563af build(deps): bump once_cell from 1.5.2 to 1.6.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.5.2 to 1.6.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.5.2...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 13:28:54 +00:00
Sebastien Boeuf
4ed0e1a3c8 net_util: Simplify TX/RX queue handling
The main idea behind this commit is to remove all the complexity
associated with TX/RX handling for virtio-net. By using writev() and
readv() syscalls, we could get rid of intermediate buffers for both
queues.

The complexity regarding the TAP registration has been simplified as
well. The RX queue is only processed when some data are ready to be
read from TAP. The event related to the RX queue getting more
descriptors only serves the purpose to register the TAP file if it's not
already.

With all these simplifications, the code is more readable but more
performant as well. We can see an improvement of 10% for a single
queue device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-22 10:39:23 +00:00
dependabot-preview[bot]
5ed2a654e8 build(deps): bump generator from 0.6.23 to 0.6.24
Bumps [generator](https://github.com/Xudong-Huang/generator-rs) from 0.6.23 to 0.6.24.
- [Release notes](https://github.com/Xudong-Huang/generator-rs/releases)
- [Commits](https://github.com/Xudong-Huang/generator-rs/compare/0.6.23...0.6.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 06:30:32 +00:00
dependabot-preview[bot]
ae04fe432c build(deps): bump signal-hook from 0.3.4 to 0.3.6
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.4 to 0.3.6.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.4...v0.3.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-21 09:36:30 +00:00
dependabot-preview[bot]
c8d142eb55 build(deps): bump crossbeam-utils from 0.8.1 to 0.8.2
Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.1 to 0.8.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.8.1...crossbeam-utils-0.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-21 09:36:12 +00:00
dependabot-preview[bot]
8533d63514 build(deps): bump cc from 1.0.66 to 1.0.67
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.66 to 1.0.67.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.66...1.0.67)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-19 22:54:50 +00:00
Muminul Islam
0ef69fa592 tests: Use constant instead of static value for windows image name
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-02-19 10:09:23 +00:00
Muminul Islam
29f924405a scripts: Check if windows image is in the host
Currently script does not exit early if the image/firmware not present
in the host. We should not progress further if the images are not pre
downloaded.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-02-19 10:09:23 +00:00
Muminul Islam
282134a490 scripts: Use variable for with windows image file
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-02-19 10:09:23 +00:00
dependabot-preview[bot]
1fbdca16bf build(deps): bump form_urlencoded from 1.0.0 to 1.0.1
Bumps [form_urlencoded](https://github.com/servo/rust-url) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v1.0.0...percent-encoding-v1.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-19 09:53:49 +00:00
Rob Bradford
32a2000ecc build: Only build the {kvm,mshv}-{ioctls,bindings} needed
This simplifies the Cloud Hypervisor dependency chain slightly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-19 08:27:30 +01:00
dependabot-preview[bot]
6a499f02d9 build(deps): bump linux-loader from 2855be1 to 4ab9dad
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `2855be1` to `4ab9dad`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](2855be15a7...4ab9dade2c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-19 07:14:55 +00:00
dependabot-preview[bot]
0a9c052ebd build(deps): bump thiserror from 1.0.23 to 1.0.24
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.23 to 1.0.24.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.23...1.0.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-19 07:14:39 +00:00
dependabot-preview[bot]
bfb12b7777 build(deps): bump url from 2.2.0 to 2.2.1
Bumps [url](https://github.com/servo/rust-url) from 2.2.0 to 2.2.1.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.2.0...v2.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-18 21:56:54 +00:00
Rob Bradford
c89095ab85 virtio-devices: Report events for virtio device activation and reset
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-18 16:15:13 +00:00
Rob Bradford
9260c4c10e vmm: Use event!() for some key VM actions
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-18 16:15:13 +00:00
Rob Bradford
4822ed79e1 main: Add "--monitor-fd" to write structured event data to
If supplied then structured JSON event data will be written to that file
descriptor.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-18 16:15:13 +00:00
Rob Bradford
ddbef7450d event_monitor: Add new crate for event reporting
This crate exposes the abililty for the VMM to set a file that events
should be written to. The event!() macro provides an interface to report
those events allowing the specification of an event source, an event
type and optional extra data. This will be written to the provided file
descriptor as JSON data.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-18 16:15:13 +00:00
Rob Bradford
c1d9edbfc0 vmm: seccomp: Add getrandom to vCPU thread filter
This can be triggered upon device reset.

Fixes: #2278

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-18 16:15:13 +00:00
dependabot-preview[bot]
0d209e135e build(deps): bump idna from 0.2.1 to 0.2.2
Bumps [idna](https://github.com/servo/rust-url) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v0.2.1...idna-v0.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-18 09:26:35 +00:00
Wei Liu
e22b6ec768 hypervisor: x86: emulate MOVS instruction
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-17 09:36:19 +01:00
Wei Liu
b59243f6cf hypervisor: mshv: support reading and writing guest memory in emulator
We don't have an easy way to figure out if a GPA points to normal memory
or device memory, but the guest's normal memory regions shouldn't
overlap with device regions. We can simply try to do a normal memory
read / write, and proceed to do device memory read / write if that
fails.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-17 09:36:19 +01:00
Rob Bradford
07a09eda27 hypervisor: kvm: Remove whitespace from use statements
This allows cargo fmt to correctly order the statements.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-16 18:38:57 +01:00
Rob Bradford
38c41a5074 vmm: memory_manager: Extract code for allocating new memory
This function can then be used by the TDX code to allocate the memory at
specific locations required for the TDVF to run from.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-16 18:38:57 +01:00
Rob Bradford
6e4c90f305 arch: Include "thiserror" crate as well as "anyhow"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-16 18:38:57 +01:00
Rob Bradford
707bb0ba72 vmm: Simplify return path of vm_boot
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-16 18:38:57 +01:00
Wei Liu
29881a2d6a hypervisor: mshv: explicitly skip a few IO ports
OVMF would use string IO on those ports. String IO has not been
implemented, so that leads to panics.

Skip them explicitly in MSHV. Leave a long-ish comment in code to
explain the situation. We should properly implement string IO once it
becomes feasible / necessary.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-16 10:04:58 +01:00
Rob Bradford
a330a1569a arch, arch_gen, hypervisor: Remove some unnecessary clippy attributes
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-15 18:03:27 +01:00
Wei Liu
cf6480f012 hypervisor: mshv: drop some clippy attributes
They were used to suppress warnings during development. At this stage
they aren't needed anymore.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-15 14:52:26 +01:00
Bo Chen
a838d0bde1 scripts, tests: Rustify the network setup commands for tests
Fixes: #2218

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-02-15 08:34:23 +00:00
Rob Bradford
f58b6f8417 build, release-notes.md, rpm: Release 0.13.0
Update version numbers and release notes for new release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-12 10:38:48 +00:00
dependabot-preview[bot]
71ae9cfe06 build(deps): bump quote from 1.0.8 to 1.0.9
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.8...1.0.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-12 08:16:19 +00:00
dependabot-preview[bot]
f0b7a09a49 build(deps): bump env_logger from 0.8.2 to 0.8.3
Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.8.2 to 0.8.3.
- [Release notes](https://github.com/env-logger-rs/env_logger/releases)
- [Changelog](https://github.com/env-logger-rs/env_logger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.2...v0.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-12 08:15:55 +00:00
Rob Bradford
bc84a1c79b build: Remove nested matches
Update for clippy in Rust 1.50.0:

error: Unnecessary nested match
   --> vmm/src/vm.rs:419:17
    |
419 | /                 if let vm_device::BusError::MissingAddressRange = e {
420 | |                     warn!("Guest MMIO write to unregistered address 0x{:x}", gpa);
421 | |                 }
    | |_________________^
    |
    = note: `-D clippy::collapsible-match` implied by `-D warnings`
help: The outer pattern can be modified to include the inner pattern.
   --> vmm/src/vm.rs:418:17
    |
418 |             Err(e) => {
    |                 ^ Replace this binding
419 |                 if let vm_device::BusError::MissingAddressRange = e {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ with this pattern
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-11 18:18:44 +00:00
Rob Bradford
9c5be6f660 build: Remove unnecessary Result<> returns
If the function can never return an error this is now a clippy failure:

error: this function's return value is unnecessarily wrapped by `Result`
   --> virtio-devices/src/watchdog.rs:215:5
    |
215 | /     fn set_state(&mut self, state: &WatchdogState) -> io::Result<()> {
216 | |         self.common.avail_features = state.avail_features;
217 | |         self.common.acked_features = state.acked_features;
218 | |         // When restoring enable the watchdog if it was previously enabled. We reset the timer
...   |
223 | |         Ok(())
224 | |     }
    | |_____^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-11 18:18:44 +00:00
Rob Bradford
8e9a5a0dbb vm-migration: Use vm-memory's ByteValued instead of own AsBytes
This addresses a newly added clippy issue:

error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name
  --> vm-migration/src/protocol.rs:57:34
   |
57 |     fn as_mut_bytes<T: Sized>(p: &mut T) -> &mut [u8] {
   |                                  ^^^^^^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention

error: aborting due to 2 previous errors

error: could not compile `vm-migration`

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-11 18:18:44 +00:00
Bo Chen
d561b45552 tests: Add integration test test_macvtap
This integration test mimics the instructions from
`docs/macvtap-bridge.md`.

Fixes: #2215

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-02-11 15:25:32 +00:00
Sebastien Boeuf
9353856426 vmm: Fix seccomp filters for vCPUs
Depending on the host OS the code for looking up the time for the CMOS
make require extra syscalls to be permitted for the vCPU thread.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-11 11:24:57 +00:00
Sebastien Boeuf
9af477e964 pci: vfio: Check VFIO device interrupt's support
In case the VFIO device does not support MSI or MSI-X, the capabilities
should not be parsed, avoiding the exposure of unsupported capabilities.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
27515a6ec4 pci: vfio: Propagate errors when enabling interrupts
Make sure to propagate the error coming from VfioDevice when trying to
enable INTx, MSI or MSI-X interrutps.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
169a6bb83b docs: vfio: Remove documentation regarding VFIO limitations
Since INTx is now supported for VFIO PCI devices, there is no more
limitations regarding VFIO, which means the documentation must be
updated accordingly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
19167e7647 pci: vfio: Implement INTx support
With all the preliminary work done in the previous commits, we can
update the VFIO implementation to support INTx along with MSI and MSI-X.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
2cdc3e3546 vmm: device_manager: Add PCI routing table to ACPI
Here we are adding the PCI routing table, commonly called _PRT, to the
ACPI DSDT. For simplification reasons, we chose not to implement PCI
links as this involves dynamic decision from the guest OS, which result
in lots of complexity both from an AML perspective and from a device
manager perspective.

That's why the _PRT creates a static list of 32 entries, each assigned
with the IRQ number previously reserved by the device manager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
de9471fc72 vmm: device_manager: Allocate IRQs for PCI devices
In order to support INTx for PCI devices, each PCI device must be
assigned an IRQ. This is preliminary work to reserve 8 IRQs which will
be shared across the 32 PCI devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
b5450ca72c vmm: device_manager: Store legacy interrupt manager
In anticipation for accessing the legacy interrupt manager from the
function creating a VFIO PCI device, we store it as part of the
DeviceManager, to make it available for all methods.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
8008aad545 vmm: device_manager: Don't pass the MSI interrupt manager around
The DeviceManager already has a hold onto the MSI interrupt manager,
therefore there's no need to pass it through every function. Instead,
let's simplify the code by using the attribute from DeviceManager's
instance.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
3bd47ffdc1 interrupt: Add a notifier method to the InterruptController
Both GIC and IOAPIC must implement a new method notifier() in order to
provide the caller with an EventFd corresponding to the IRQ it refers
to.

This is needed in anticipation for supporting INTx with VFIO PCI
devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Sebastien Boeuf
acfbee5b7a interrupt: Make notifier function return Option<EventFd>
In anticipation for supporting the notifier function for the legacy
interrupt source group, we need this function to return an EventFd
instead of a reference to this same EventFd.

The reason is we can't return a reference when there's an Arc<Mutex<>>
involved in the call chain.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-10 17:34:56 +00:00
Wei Liu
62c6efb2e5 build: fix cargo fuzz build
The dependency on vm-memory was not updated by dependabot.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-10 14:42:41 +01:00
Wei Liu
aec0d309ee hypervisor: emulator: also set ES segment in MockVMM
Some instructions, such as MOVS, need a valid ES segment.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-10 11:31:03 +00:00
Wei Liu
5fc12862e6 hypervisor, vmm: minor changes to VmmOps
Swap the last two parameters of guest_mem_{read,write} to be consistent
with other read / write functions.

Use more descriptive parameter names.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-10 11:31:03 +00:00
Wei Liu
f4159ca016 hypervisor: emulator: drop useless set_ip calls
The instruction pointer is already pointing at the instruction being
emulated.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-10 11:31:03 +00:00
dependabot-preview[bot]
6d63018d9f build(deps): bump vm-memory from 0.4.0 to 0.5.0
Bumps [vm-memory](https://github.com/rust-vmm/vm-memory) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/rust-vmm/vm-memory/releases)
- [Changelog](https://github.com/rust-vmm/vm-memory/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-vmm/vm-memory/compare/v0.4.0...v0.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-10 11:30:05 +00:00
dependabot-preview[bot]
073e0f979b build(deps): bump vfio-ioctls from 49cc362 to 6ea1b93
Bumps [vfio-ioctls](https://github.com/cloud-hypervisor/vfio-ioctls) from `49cc362` to `6ea1b93`.
- [Release notes](https://github.com/cloud-hypervisor/vfio-ioctls/releases)
- [Commits](49cc3626f6...6ea1b934bb)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-10 07:01:43 +00:00
Rob Bradford
50a995b63d vmm: Rename patch_cpuid() to generate_common_cpuid()
This reflects that it generates CPUID state used across all vCPUs.
Further ensure that errors from this function get correctly propagated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-09 16:02:25 +00:00
Rob Bradford
ccdea0274c vmm, arch: Move KVM HyperV emulation handling to shared CPUID code
Move the code for populating the CPUID with KVM HyperV emulation details from
the per-vCPU CPUID handling code to the shared CPUID handling code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-09 16:02:25 +00:00
Rob Bradford
688ead51c6 vmm, arch: Move CPU identification handling to shared CPUID code
Move the code for populating the CPUID with details of the CPU
identification from the per-vCPU CPUID handling code to the shared CPUID
handling code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-09 16:02:25 +00:00
Rob Bradford
9792c9aafa vmm, arch: Move max_phys_bits handling to shared CPUID code
Move the code for populating the CPUID with details of the maximum
address space from the per-vCPU CPUID handling code to the shared CPUID
handling code.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-09 16:02:25 +00:00
William Douglas
48963e322a Enable pty console
Add the ability for cloud-hypervisor to create, manage and monitor a
pty for serial and/or console I/O from a user. The reasoning for
having cloud-hypervisor create the ptys is so that clients, libvirt
for example, could exit and later re-open the pty without causing I/O
issues. If the clients were responsible for creating the pty, when
they exit the main pty fd would close and cause cloud-hypervisor to
get I/O errors on writes.

Ideally the main and subordinate pty fds would be kept in the main
vmm's Vm structure. However, because the device manager owns parsing
the configuration for the serial and console devices, the information
is instead stored in new fields under the DeviceManager structure
directly.

From there hooking up the main fd is intended to look as close to
handling stdin and stdout on the tty as possible (there is some future
work ahead for perhaps moving support for the pty into the
vmm_sys_utils crate).

The main fd is used for reading user input and writing to output of
the Vm device. The subordinate fd is used to setup raw mode and it is
kept open in order to avoid I/O errors when clients open and close the
pty device.

The ability to handle multiple inputs as part of this change is
intentional. The current code allows serial and console ptys to be
created and both be used as input. There was an implementation gap
though with the queue_input_bytes needing to be modified so the pty
handlers for serial and console could access the methods on the serial
and console structures directly. Without this change only a single
input source could be processed as the console would switch based on
its input type (this is still valid for tty and isn't otherwise
modified).

Signed-off-by: William Douglas <william.r.douglas@gmail.com>
2021-02-09 10:03:28 +00:00
dependabot-preview[bot]
a59fbf0e37 build(deps): bump unicode-normalization from 0.1.16 to 0.1.17
Bumps [unicode-normalization](https://github.com/unicode-rs/unicode-normalization) from 0.1.16 to 0.1.17.
- [Release notes](https://github.com/unicode-rs/unicode-normalization/releases)
- [Commits](https://github.com/unicode-rs/unicode-normalization/compare/v0.1.16...v0.1.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-09 06:43:17 +00:00
Rob Bradford
a6b839b35c build: Update to latest kvm-ioctls
Update the version of the fork pointed to which has been rebased on the
latest upstream.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-08 18:16:18 +00:00
dependabot-preview[bot]
aa3d5cfbfe build(deps): bump libc from 0.2.85 to 0.2.86
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.85 to 0.2.86.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.85...0.2.86)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-08 16:19:06 +00:00
Wei Liu
ddd0552c83 virtio-devices: vhost-user-net: unpark control queue thread in resume
This thread is virtio-net specific, so it is not handled in the common
virtio device code.

The non-vhost implementation resumes the thread itself. Do the same
thing for vhost-user-net.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-08 16:16:13 +00:00
Wei Liu
1fc8c9165a vmm: drop two unused errors
Their last users were gone in af3c6c34c3.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-02-08 16:15:31 +00:00
dependabot-preview[bot]
47f47ad53f build(deps): bump iced-x86 from 1.10.0 to 1.10.3
Bumps [iced-x86](https://github.com/0xd4d/iced) from 1.10.0 to 1.10.3.
- [Release notes](https://github.com/0xd4d/iced/releases)
- [Commits](https://github.com/0xd4d/iced/compare/v1.10.0...v1.10.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-08 07:24:59 +00:00
dependabot-preview[bot]
69d1186ccb build(deps): bump serde_json from 1.0.61 to 1.0.62
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.61 to 1.0.62.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.61...v1.0.62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-06 10:01:35 +00:00
dependabot-preview[bot]
d0601a1473 build(deps): bump idna from 0.2.0 to 0.2.1
Bumps [idna](https://github.com/servo/rust-url) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/idna-v0.2.0...v0.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-05 11:17:52 +00:00
Rob Bradford
b91b829a28 openapi: Update API spec to include hugepage_size parameter
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-05 09:24:02 +00:00
Rob Bradford
7928a697dc vmm: Support configurable huge pages in MemoryManager
Use the newly added hugepages_size option if provided by the user to
pick a huge page size when creating the memfd region. If none is
specified use the system default.

Sadly different huge pages cannot be tested by an integration test as
creating a pool of the non-default size cannot be done at runtime
(requires kernel to be booted with certain parameters.)

TETS=Manually tested with a kernel booted with both 1GiB and 2MiB huge
pages (hugepagesz=1G hugepages=1 hugepagesz=2M hugepages=512)

Fixes: #2230

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-05 09:24:02 +00:00
Rob Bradford
b5fb744828 docs: Update documentation for hugepage_size option
Including a warning that the user is respsonsible for ensuring that they
have sufficient pages of the specified size.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-05 09:24:02 +00:00
Rob Bradford
29607f38ad vmm: config: Add a hugepage_size option
This allows the user to use an alternative huge page size otherwise the
default size will be used.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-05 09:24:02 +00:00
Rob Bradford
9c3a73706f vmm: config: Remove ineffectual code from test
Remove a change the invalid configuration that is not ever tested again.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-02-05 09:24:02 +00:00
Muminul Islam
024675d1d8 scripts: error exit if aarch64 test is run on MSHV
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-02-05 09:22:58 +00:00
dependabot-preview[bot]
2c913b8130 build(deps): bump thread_local from 1.1.2 to 1.1.3
Bumps [thread_local](https://github.com/Amanieu/thread_local-rs) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/Amanieu/thread_local-rs/releases)
- [Commits](https://github.com/Amanieu/thread_local-rs/compare/v1.1.2...v1.1.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-04 20:53:44 +00:00
Sebastien Boeuf
c397c9c95e vmm, virtio-devices: mem: Don't use MADV_DONTNEED on hugepages
This commit introduces a new information to the VirtioMemZone structure
in order to know if the memory zone is backed by hugepages.

Based on this new information, the virtio-mem device is now able to
determine if madvise(MADV_DONTNEED) should be performed or not. The
madvise documentation specifies that MADV_DONTNEED advice will fail if
the memory range has been allocated with some hugepages.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Hui Zhu <teawater@antfin.com>
2021-02-04 17:52:30 +00:00
Sebastien Boeuf
54f814f34a virtio-devices: mem: Refactor MemEpollHandler
This commit performs some refactoring to make all functions a method
from a specific object, and in particular methods for MemEpollHandler.

The point is to simplify the code to make it more readable.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-04 17:52:30 +00:00
Sebastien Boeuf
ad8adcb955 virtio-devices: mem: Adjust based on specification
Adjust the code to comply better with the virtio-mem specification by
adding some validation for the virtio-mem configuration, but also by
updating the virtio-mem configuration itself.

Nowhere in the virtio-mem specification is stated the usable region size
must be adjusted everytime the plugged size changes. For simplification
reason, and without going against the specification, the usable region
size is now kept static, setting its value to the size of the whole
region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-04 17:52:30 +00:00
Sebastien Boeuf
f24094392e virtio-devices: mem: Improve semantic around Resize object
By introducing a ResizeSender object, we avoid having a Resize clone
with a different content than the original Resize object.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-04 17:52:30 +00:00
Samuel Ortiz
eee218f1f5 hypervisor: emulator: Add MOVZX unit tests
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2021-02-03 14:11:18 +01:00
Samuel Ortiz
5ada3f59c8 hypervisor: emulator: Emulate MOVZX
MOV R/RM is a special case of MOVZX, so we generalize the mov_r_rm macro
to make it support both instructions.

Fixes: #2227

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2021-02-03 14:11:18 +01:00
dependabot-preview[bot]
89008a49cf build(deps): bump libc from 0.2.84 to 0.2.85
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.84 to 0.2.85.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.84...0.2.85)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-02 07:47:41 +00:00
dependabot-preview[bot]
295f4df7bf build(deps): bump ssh2 from 0.9.0 to 0.9.1
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.9.0...0.9.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-01 18:48:26 +00:00
dependabot-preview[bot]
769194cac8 build(deps): bump libssh2-sys from 0.2.20 to 0.2.21
Bumps [libssh2-sys](https://github.com/alexcrichton/ssh2-rs) from 0.2.20 to 0.2.21.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/libssh2-sys-0.2.20...libssh2-sys-0.2.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-01 18:13:04 +00:00
Sebastien Boeuf
13a3ac6a77 block_util: Add unit testing for VHD format
The vhd module is the implementation of the VHD specification, which is
why it is important to unit test it.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-01 13:45:08 +00:00
Sebastien Boeuf
b26777cb01 ci: Add integration test for VHD format
Let's create a fixed VHD disk file from the existing RAW file thanks to
qemu-img, and create a new integration test to validate that
Cloud-Hypervisor can boot VHD disk image.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-01 13:45:08 +00:00
Sebastien Boeuf
24c8cce012 block_util: Add synchronous support for fixed VHD disk files
Relying on the simplified version of the synchronous support for RAW
disk files, the new fixed_vhd_sync module in the block_util crate
introduces the synchronous support for fixed VHD disk files.

With this patch, the fixed VHD support is complete as it is implemented
in both synchronous and asynchronous versions.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-01 13:45:08 +00:00
Sebastien Boeuf
c6854c5a97 block_util: Simplify RAW synchronous implementation
Using directly preadv and pwritev, we can simply use a RawFd instead of
a file, and we don't need to use the more complex implementation from
the qcow crate.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-01 13:45:08 +00:00
Sebastien Boeuf
b2e5dbaecb block_util, vmm: Add fixed VHD asynchronous implementation
This commit adds the asynchronous support for fixed VHD disk files.

It introduces FixedVhd as a new ImageType, moving the image type
detection to the block_util crate (instead of qcow crate).

It creates a new vhd module in the block_util crate in order to handle
VHD footer, following the VHD specification.

It creates a new fixed_vhd_async module in the block_util crate to
implement the asynchronous version of fixed VHD disk file. It relies on
io_uring.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-02-01 13:45:08 +00:00
Muminul Islam
5bbf2dca80 vmm: Remove unneeded return statement
This unneeded return statement giving clippy warnings

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-01-30 08:58:09 +00:00
dependabot-preview[bot]
1df952726a build(deps): bump libc from 0.2.83 to 0.2.84
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.83 to 0.2.84.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-29 06:21:38 +00:00
Rob Bradford
9ea087597f vmm: acpi: Ensure field size address matches ResourceTag
dsdt.dsl    960:             CreateDWordField (MR64, \_SB.MHPC.MCRS._Y00._MIN, MINL)  // _MIN: Minimum Base Address
Warning  3128 -                              ResourceTag larger than Field ^  (Size mismatch, Tag: 64 bits, Field: 32 bits)

dsdt.dsl    962:             CreateDWordField (MR64, \_SB.MHPC.MCRS._Y00._MAX, MAXL)  // _MAX: Maximum Base Address
Warning  3128 -                              ResourceTag larger than Field ^  (Size mismatch, Tag: 64 bits, Field: 32 bits)

dsdt.dsl    964:             CreateDWordField (MR64, \_SB.MHPC.MCRS._Y00._LEN, LENL)  // _LEN: Length
Warning  3128 -                              ResourceTag larger than Field ^  (Size mismatch, Tag: 64 bits, Field: 32 bits)

Fixes: #2216

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-28 14:30:34 +01:00
Rob Bradford
952f9bd3fe vmm: acpi: Remove incorrect return statement
_EJx built in should not return.

dsdt.dsl    813:                 Return (CEJ0 (0x00))
Warning  3104 -                            ^ Reserved method should not return a value (_EJ0)

dsdt.dsl    813:                 Return (CEJ0 (0x00))
Error    6080 -                            ^ Called method returns no value

Fixes: #2216

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-28 14:30:34 +01:00
Rob Bradford
c29caf2a85 vmm: acpi: Fix incorrect mutex timeout value
The mutex timeout should be 0xffff rather than 0xfff to disable the
timeout feature.

dsdt.dsl    745:             Acquire (\_SB.PRES.CPLK, 0x0FFF)
Warning  3130 -                                           ^ Result is not used, possible operator timeout will be missed

dsdt.dsl    767:             Acquire (\_SB.PRES.CPLK, 0x0FFF)
Warning  3130 -                                           ^ Result is not used, possible operator timeout will be missed

dsdt.dsl    775:             Acquire (\_SB.PRES.CPLK, 0x0FFF)
Warning  3130 -                                           ^ Result is not used, possible operator timeout will be missed

Fixes: #2216

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-28 14:30:34 +01:00
Bo Chen
5fbeacabad tests: Remove manual delete of the TAP interface in test_tap_from_fd
By using `net_util::open_tap` to create the TAP interface, the created
interface will be deleted when the returned variable (`net_utils::Tap`)
is dropped.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-01-28 09:11:39 +00:00
Bo Chen
f7502057d9 tests: Extend test_tap_from_fd() with using multiple TAP fds
Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-01-28 09:11:39 +00:00
Bo Chen
ff54909d2c vmm: openapi: Update the fd field of the NetConfig definition
Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-01-28 09:11:39 +00:00
Bo Chen
6664e5a6e7 net_util, virtio-devices, vmm: Accept multiple TAP fds
This patch enables multi-queue support for creating virtio-net devices by
accepting multiple TAP fds, e.g. '--net fds=3:7'.

Fixes: #2164

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-01-28 09:11:39 +00:00
Rob Bradford
5209026f52 tests: Port test_tap_from_fd to use net_util::open_tap
This removes the need for manually creating the interface and assigning
the IP.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-28 09:11:39 +00:00
Rob Bradford
5db9b0ec99 net_util: Support supplying flags to open_tap() helper
This helper can open a TAP device and configure the interface on it. If
the device needs to be opened multiple times for MQ then it also handles
that correctly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-28 09:11:39 +00:00
Muminul Islam
c4fb0f36bd scripts: Use hypervisor variable instead of kvm
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-01-28 09:11:02 +00:00
Muminul Islam
9cdcbb5121 script: Modify unit tests to support mshv
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-01-28 09:11:02 +00:00
Muminul Islam
a194dad98c arch, vmm: Run KVM specific unit tests with kvm feature guard
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-01-28 09:11:02 +00:00
Muminul Islam
b339aa6b88 scripts: Export devices(/dev/kvm or /dev/mshv) based on hypervisor
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2021-01-28 09:11:02 +00:00
Sebastien Boeuf
276c9a10fd docs: Clarify VFIO limitations regarding NVIDIA cards
Because of the behavior of the NVIDIA proprietary driver, we can't
expect NVIDIA cards with only MSI support to be functioning correctly
after they've been passed through with Cloud-Hypervisor.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-28 09:10:45 +00:00
dependabot-preview[bot]
36360c7630 build(deps): bump libc from 0.2.82 to 0.2.83
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.82 to 0.2.83.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.82...0.2.83)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-28 06:30:03 +00:00
Wei Liu
b959849149 vmm: drop unnecessary semicolon
Building with 1.51 nightly produces the following warning:

warning: unnecessary trailing semicolon
   --> vmm/src/device_manager.rs:396:6
    |
396 |     };
    |      ^ help: remove this semicolon
    |
    = note: `#[warn(redundant_semicolons)]` on by default

warning: 1 warning emitted

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-01-27 14:43:20 +00:00
dependabot-preview[bot]
50a89c6808 build(deps): bump rand from 0.8.2 to 0.8.3
Bumps [rand](https://github.com/rust-random/rand) from 0.8.2 to 0.8.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>
2021-01-27 13:26:04 +00:00
dependabot-preview[bot]
192d69d601 build(deps): bump log from 0.4.13 to 0.4.14
Bumps [log](https://github.com/rust-lang/log) from 0.4.13 to 0.4.14.
- [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.13...0.4.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-27 12:48:52 +00:00
Rob Bradford
b8342ebeb4 scripts: Don't download container on help invocations
Delay downloading the container until it is being used.

Fixes: #2065

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-26 13:29:05 +01:00
Rob Bradford
58009af85d tests: Add clippy check for integration test building
Ensure that we try and keep the integration tests clippy clean.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-26 13:23:16 +01:00
dependabot-preview[bot]
0655f25da4 build(deps): bump serde from 1.0.121 to 1.0.123
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.121 to 1.0.123.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.121...v1.0.123)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-26 10:49:12 +00:00
dependabot-preview[bot]
2547f144cd build(deps): bump tinyvec from 1.1.0 to 1.1.1
Bumps [tinyvec](https://github.com/Lokathor/tinyvec) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/Lokathor/tinyvec/releases)
- [Changelog](https://github.com/Lokathor/tinyvec/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Lokathor/tinyvec/compare/v1.1.0...v1.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-26 09:43:10 +00:00
dependabot-preview[bot]
ec7700544c build(deps): bump serde_derive from 1.0.122 to 1.0.123
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.122 to 1.0.123.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.122...v1.0.123)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-26 09:42:42 +00:00
Rob Bradford
0c60fa8268 net_util: tests: Avoid trying to create TAP devices simultaneously
The unit tests ask the Linux kernel to generate a TAP device name on
demand by passing in a format string. I suspect, but haven't been able
to confirm that there might be a rare race that triggers when creating
lots of devices in a short period of time. This is appearing in our unit
test as the occassional flake of the test_tap_read() which although it
has successfully created the device it fails to set the IP address on it
when looking it back up by it's name.

Since this is the most frequent cause of failures on our CI use a lock
to ensure that multiple TAP devices are not created simultaneously.

Fixes: #2135

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-26 10:42:02 +01:00
Rob Bradford
76e15a4240 vmm: acpi: Support compiling ACPI code on aarch64
This skeleton commit brings in the support for compiling aarch64 with
the "acpi" feature ready to the ACPI enabling. It builds on the work to
move the ACPI hotplug devices from I/O ports to MMIO and conditionalises
any code that is x86_64 only (i.e. because it uses an I/O port.)

Filling in the aarch64 specific details in tables such as the MADT it
out of the scope.

See: #2178

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-26 15:19:02 +08:00
Vineeth Pillai
7659055eec mshv: Use in-kernel ioeventfd mechanism
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
2021-01-25 21:20:29 +00:00
Vineeth Pillai
5209bd6120 mshv: Use in-kernel irqfd mechanism
Convert MshvIrqRoutingEntry functions to methods as well.

Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
2021-01-25 21:20:29 +00:00
Rob Bradford
c2acea5156 tests: Support filtering integration tests
e.g.

scripts/dev_cli.sh tests --integration -- --test-filter test_watchdog

This used to be supported by passing "$@" but was broken when multiple
hypervisor support was added.

Fixes: #2182

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-25 17:34:10 +00:00
Wei Liu
fd9972ecc5 hypervisor: fix exception vector numbers
According to Intel SDM, #DE should be 0 and #DB should be 1.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-01-25 16:39:08 +00:00
dependabot-preview[bot]
ca4ab99f42 build(deps): bump serde_derive from 1.0.121 to 1.0.122
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.121 to 1.0.122.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.121...v1.0.122)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-25 12:16:07 +00:00
dependabot-preview[bot]
977d824cf8 build(deps): bump syn from 1.0.59 to 1.0.60
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.59 to 1.0.60.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.59...1.0.60)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-25 09:23:17 +00:00
dependabot-preview[bot]
38fa630ce7 build(deps): bump thread_local from 1.1.1 to 1.1.2
Bumps [thread_local](https://github.com/Amanieu/thread_local-rs) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/Amanieu/thread_local-rs/releases)
- [Commits](https://github.com/Amanieu/thread_local-rs/compare/v1.1.1...v1.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-25 09:23:07 +00:00
Rob Bradford
a59b361058 resources: Use Rust 1.49.0 in container
This is the latest stable version.

Fixes: #2092

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-24 17:05:07 +00:00
dependabot-preview[bot]
fa5b5fd602 build(deps): bump serde from 1.0.120 to 1.0.121
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.120 to 1.0.121.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.120...v1.0.121)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-24 16:21:11 +00:00
dependabot-preview[bot]
7765398045 build(deps): bump serde_derive from 1.0.120 to 1.0.121
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.120 to 1.0.121.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.120...v1.0.121)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-24 15:37:25 +00:00
dependabot-preview[bot]
9282ad82b0 build(deps): bump syn from 1.0.58 to 1.0.59
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.58 to 1.0.59.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.58...1.0.59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-23 11:58:14 +00:00
dependabot-preview[bot]
a09feecc36 build(deps): bump thread_local from 1.1.0 to 1.1.1
Bumps [thread_local](https://github.com/Amanieu/thread_local-rs) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/Amanieu/thread_local-rs/releases)
- [Commits](https://github.com/Amanieu/thread_local-rs/compare/v1.1.0...v1.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-23 11:57:46 +00:00
Sebastien Boeuf
060df69f07 block_util: Factorize common code for synchronous implementations
Since QCOW and RAW synchronous implementation are very close, it makes
sense to introduce some common functions that can be shared between
these two.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
f6c8e4b045 vmm: device_manager: Add info!() message about disk file backend
It might be useful debugging information for the user to know what kind
of disk file implementation is in use.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
2824642e80 virtio-devices: Rename BlockIoUring to Block
Now that BlockIoUring is the only implementation of virtio-block,
handling both synchronous and asynchronous backends based on the
AsyncIo trait, we can rename it to Block.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
41cfdb50cd virtio-devices: Remove virtio-block synchronous implementation
Now that both synchronous and asynchronous backends rely on the
asynchronous version of virtio-block (namely BlockIoUring), we can
get rid of the synchronous version (namely Block).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
12e20effd7 block_util: Port synchronous QCOW file to AsyncIo trait
Based on the synchronous QCOW file implementation present in the qcow
crate, we created a new qcow_sync module in block_util that ports this
synchronous implementation to the AsyncIo trait.

The point is to reuse virtio-blk asynchronous implementation for both
synchronous and asynchronous backends.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
9fc86a91e2 block_util: Port synchronous RAW file to AsyncIo trait
Based on the synchronous RAW file implementation present in the qcow
crate, we created a new raw_sync module in block_util that ports this
synchronous implementation to the AsyncIo trait.

The point is to reuse virtio-blk asynchronous implementation for both
synchronous and asynchronous backends.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
da8ce25abf virtio-devices: Use asynchronous traits for virtio-blk io_uring
Based on the new DiskFile and AsyncIo traits, the implementation of
asynchronous block support does not have to be tied to io_uring anymore.
Instead, the only thing the virtio-blk implementation knows is that it
is using an asynchronous implementation of the underlying disk file.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
23e3b022eb block_util: Implement asynchronous traits for RAW disk file
This provides the implementation of DiskFile and AsyncIo for the RAW
file format.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Sebastien Boeuf
30033bdaea block_util: Add new traits for handling disk files asynchronously
Both DiskFile and AsyncIo traits are introduced to allow all kind of
files (RAW, QCOW, VHD) to be able to handle asynchronous access to the
underlying file.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-22 16:10:34 +00:00
Rob Bradford
d578c408b7 vmm: acpi: Move DeviceManager ACPI device to an MMIO address
Migrate the DeviceManager from a fixed I/O port address to an allocated
MMIO address.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-22 16:08:41 +01:00
Rob Bradford
55a3a38e14 vmm: acpi: Move CpuManager ACPI device to an MMIO address
Migrate the CpuManager from a fixed I/O port address to an allocated
MMIO address.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-22 16:08:41 +01:00
Rob Bradford
6006068951 vmm: acpi: Move MemoryManager ACPI device to an MMIO address
Migrate the MemoryManager from a fixed I/O port address to an allocated
MMIO address.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-22 16:08:41 +01:00
Rob Bradford
28ab6cea0e vmm: acpi: Move ACPI GED device to MMIO bus
Currently the GED control is in a fixed I/O port address but instead use
an MMIO address that has been chosen by the allocator.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-22 16:08:41 +01:00
Rob Bradford
4ebeeb1310 vmm: device_manager: Rename shutdown ACPI device
Rename the variable for the shutdown device to clarify it's purpose in
the function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-22 16:08:41 +01:00
dependabot-preview[bot]
77f6cd5ef4 build(deps): bump mshv-bindings from 2ded6da to 3a7d7ba
Bumps [mshv-bindings](https://github.com/cloud-hypervisor/mshv) from `2ded6da` to `3a7d7ba`.
- [Release notes](https://github.com/cloud-hypervisor/mshv/releases)
- [Commits](2ded6daf97...3a7d7ba07e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-22 07:09:54 +00:00
dependabot-preview[bot]
f2c2a44ca6 build(deps): bump backtrace from 0.3.55 to 0.3.56
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.55 to 0.3.56.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.55...0.3.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-21 17:18:29 +00:00
Bo Chen
8d418e1fca vmm: Refine the seccomp filter list for the vCPU thread
This patch refines the sccomp filter list for the vCPU thread, as we are
no longer spawning virtio-device threads from the vCPU thread.

Fixes: #2170

Signed-off-by: Bo Chen <chen.bo@intel.com>
2021-01-21 09:41:40 +00:00
Rob Bradford
c90f77e399 virtio-devices: Enforce a minimum number of queues
Even though the driver can provide fewer queues than those advertised
for some device types their is a minimum number that is required for
operation.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-20 18:54:36 +01:00
Rob Bradford
a105089702 virtio-devices: Support driver programming fewer queues
It is permissable for the driver to program fewer queues than offered by
the device. Filter the queues so that only the ready ones are included
and check that they have valid addresses configured.

Fixes: #2136

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-20 18:54:36 +01:00
Rob Bradford
c366efc19e virtio-devices: block, block_io_uring: Don't assume max queue count
Don't assume that the number of queues provided match the number of
queues offered. The virtio spec allows the driver to program fewer
queues.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-20 18:54:36 +01:00
Rob Bradford
c9b68a3be6 .github: Simplify cross-build action
Remove unnecessary commands to simplify the cross-build action.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-20 18:51:42 +01:00
Xie Yongji
72b736153e vm-virtio: Fix update_avail_event() memory ordering
We should use full memory barrier to ensure both guest and us
can see the correct avail_idx and avail_event_idx. Something
like this pattern:

VM:                           CLH:
update vring.avail->idx       update avail_event_idx
mb()                          mb()
read avail_event_idx          read vring.avail->idx

Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
2021-01-20 08:32:56 +01:00
dependabot-preview[bot]
79a2afe44e build(deps): bump serde from 1.0.119 to 1.0.120
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.119 to 1.0.120.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.119...v1.0.120)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-19 08:19:23 +00:00
dependabot-preview[bot]
7d299f1055 build(deps): bump serde_derive from 1.0.119 to 1.0.120
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.119 to 1.0.120.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.119...v1.0.120)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-19 07:37:46 +00:00
Rob Bradford
23f9ec50fb virtio-devices: Simplify virtio device reset
Rather than having to give and return the ioeventfd used for a device
clone them each time. This will make it simpler when we start handling
the driver enabling fewer queues than advertised by the device.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-18 15:05:54 +00:00
dependabot-preview[bot]
c99d3f70ac build(deps): bump signal-hook from 0.3.3 to 0.3.4
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.3 to 0.3.4.
- [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/v0.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-17 20:27:52 +00:00
dependabot-preview[bot]
33d339c406 build(deps): bump hermit-abi from 0.1.17 to 0.1.18
Bumps [hermit-abi](https://github.com/hermitcore/libhermit-rs) from 0.1.17 to 0.1.18.
- [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>
2021-01-17 20:27:34 +00:00
Rob Bradford
22649c4a87 virtio-devices: Upon reset reap/join the device threads
We have killed the device thread by writing to the exit EventFd but we
should wait for them to quit to ensure consistency.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-14 17:25:14 +01:00
dependabot-preview[bot]
ef363d79fb build(deps): bump humantime from 2.0.1 to 2.1.0
Bumps [humantime](https://github.com/tailhook/humantime) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/tailhook/humantime/releases)
- [Commits](https://github.com/tailhook/humantime/compare/v2.0.1...v2.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-13 21:49:27 +00:00
Rob Bradford
92f3f86669 tests: Add integration test for power button
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
f6d6495b93 resources: Add CONFIG_ACPI_BUTTON to linux-config-x86_64
Thise is needed to enable clean shutdown of the guest via an ACPI power
button.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
68d90cbe65 opeenapi: Add power button API entry point
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
d0b59ca3a0 ch-remote: Add support for "power-button"
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
981bb72a09 vmm: api: Add "power-button" API entry point
This will lead to the triggering of an ACPI button inside the guest in
order to cleanly shutdown the guest.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
843a010163 vmm: vm, device_manager: Trigger a power button notification via ACPI
Use the ACPI GED device to trigger a notitifcation of type
POWER_BUTTON_CHANGED which will ultimately lead to the guest being
notified.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
c381b36b87 devices: acpi: Trigger the power button upon GED event
If a GED event of type 0x8 (for power button) is received notify the
guest OS that this button device has been activated.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
ff4d378f1b vmm: device_manager: acpi: Add a power button (PNP0C0C)
Add a power button to the devices defined in the \_SB

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
74a4aba257 devices: Add notification value for power button
Add a value to the ACPI notification type to indicate the power button
is to be triggered.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
7b376fa8e0 devices: acpi: Generalise the HotPlugNotificationFlags
Renamed this bitfield as it will also be used for non-hotplug purposes
such as synthesising a power button.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 17:00:39 +00:00
Rob Bradford
23afe89089 virtio-devices: Derive thread names from device ids
In order to make the thread naming more useful derive their name from
the device id (which can be supplied by the user) and a device specific
suffix that has details of the individual queue (or queue pair.)

e.g.

rob@artemis:~$ pstree -p -c -l -t `pidof cloud-hypervisor`
cloud-hyperviso(27501)─┬─{_console}(27525)
                       ├─{_disk0_q0}(27529)
                       ├─{_disk0_q1}(27532)
                       ├─{_net1_ctrl}(27533)
                       ├─{_net1_qp0}(27534)
                       ├─{_net1_qp1}(27535)
                       ├─{_rng}(27526)
                       ├─{http-server}(27504)
                       ├─{seccomp_signal_}(27502)
                       ├─{signal_handler}(27523)
                       ├─{vcpu0}(27520)
                       ├─{vcpu1}(27522)
                       └─{vmm}(27503)

Fixes: #2077

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-13 16:56:44 +01:00
Sebastien Boeuf
3b43551d98 ci: Use device mapper to avoid copying Windows image
The Windows image is quite large (about 20GiB), hence it takes some time
to copy it for every test in order to avoid potential corruption.

One way to mitigate that without compromising on safety between each
test is by using device mapper. By creating a read-only base, we ensure
the image won't be modified by any of the tests, and by creating one
snapshot for each test, we avoid copying the entire image each time.
A dedicated Copy On Write disk image is created to handle any change
that might be performed on the base image, letting the tests behave as
expected.

Fixes #2155

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-13 10:48:06 +00:00
Sebastien Boeuf
c3df42d42f ci: Copy Windows image for each integration test
By relying on the Guest object, Windows dedicated tests copy the Windows
guest image before booting from it. The point being to avoid corruption
between multiple tests. This is already how the rest of the integration
tests work, Windows tests were the only ones missing this feature.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-13 10:48:06 +00:00
dependabot-preview[bot]
6b424b5f6b build(deps): bump rand from 0.8.1 to 0.8.2
Bumps [rand](https://github.com/rust-random/rand) from 0.8.1 to 0.8.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.8.1...0.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-13 10:41:29 +00:00
dependabot-preview[bot]
b2dd03b2dc build(deps): bump getrandom from 0.1.15 to 0.1.16
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.1.15 to 0.1.16.
- [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.15...v0.1.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-13 07:19:44 +00:00
dependabot-preview[bot]
4ebca7f4ea build(deps): bump thread_local from 1.0.1 to 1.1.0
Bumps [thread_local](https://github.com/Amanieu/thread_local-rs) from 1.0.1 to 1.1.0.
- [Release notes](https://github.com/Amanieu/thread_local-rs/releases)
- [Commits](https://github.com/Amanieu/thread_local-rs/compare/v1.0.1...v1.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-13 07:19:20 +00:00
Rob Bradford
d036210ecd build: deps: Bump serde and serde_derive together
The tight coupling of these packages caused issues for dependabot trying
to update them separately so instead combine them together into one
update.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-12 11:16:22 +01:00
Rob Bradford
39d080e0c1 main: Give a friendly message when we get a seccomp violation
If we receive SIGSYS and identify it as a seccomp violation then give
friendly instructions on how to debug further. We are unable to decode
the siginfo_t struct ourselves due to https://github.com/rust-lang/libc/issues/716

Fixes: #2139

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-12 09:23:29 +00:00
dependabot-preview[bot]
d83c9a74f4 build(deps): bump tempfile from 3.1.0 to 3.2.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/Stebalien/tempfile/releases)
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS)
- [Commits](https://github.com/Stebalien/tempfile/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-12 08:21:47 +00:00
dependabot-preview[bot]
d26866e018 build(deps): bump libc from 0.2.81 to 0.2.82
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.81 to 0.2.82.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.81...0.2.82)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-12 07:06:21 +00:00
Rob Bradford
ba7864e111 tests: Send systemd journal to console
This will aid debugging of test issues especially those for critical
services during the boot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 16:38:07 +00:00
Rob Bradford
5881809126 tests: Update integration tests to use new image without pollinate
This image does not have the pollinate service which can sometimes fail
and prevent SSH from starting as it marks itself as a prerequisite. This
service will never fully succeed as it tries to make a network
connection which will fail inside our test VMs.

Fixes: #2113

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 16:38:07 +00:00
Rob Bradford
21ba34542d doc: Update documentation to note removal of pollinate package
Also update to include a simple version number in the image name.

See: #2113

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 16:38:07 +00:00
dependabot-preview[bot]
ab456affb3 build(deps): bump log from 0.4.11 to 0.4.13
Bumps [log](https://github.com/rust-lang/log) from 0.4.11 to 0.4.13.
- [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.11...0.4.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-11 12:49:34 +00:00
Rob Bradford
852bf0b2ce scripts, resources: aarch64: Update to Linux kernel v5.10 base
This allows the removal of most of the custom patches in particular all
the virtio-fs ones have been integrated.

Fixes: #2070

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 12:56:05 +01:00
Rob Bradford
642a1a610f scripts: Update to Linux fork using latest virtio-iommu patches
The ch-5.10.6 branch is rebased on top of Linux stable and includes the
latest virtio-iommu support patches.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 12:56:05 +01:00
Rob Bradford
bdfe6a69ef virtio-devices: iommu: Update to latest version of IOMMU spec
This is order to support the latest patches from
https://jpbrucker.net/git/linux/commit/?h=virtio-iommu/devel&id=ddc3e6ce3f534af827a9c8f91e12a7082de8ec61

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 12:56:05 +01:00
Sebastien Boeuf
7889fc9207 scripts: Run test container with the default bridge network
Using --net=host is not necessary for any of the integration tests, so
let's use the default network option called "bridge".

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-11 11:18:48 +00:00
Rob Bradford
cb826aa2f1 vmm: seccomp: Add open() to vCPU permitted syscalls
Older libc (like RHEL7) uses open() rather than openat(). This was
demonstrated through a failure to open /etc/localtime as used by
gmtime() libc call trigged from the vCPU thread (CMOS device.)

Fixes: #2111

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 11:24:13 +01:00
Sebastien Boeuf
df522cf12c ci: Re-enable test_windows_guest_snapshot_restore
This reverts commit 72d054bf40.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-11 09:32:58 +00:00
Rob Bradford
a920ef48de Revert "tests: Temporarily disable test_watchdog on aarch64"
This reverts commit 49b49421d0.

Probable solution was applied in f70852c04b

Fixes: #2103

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-11 10:26:52 +01:00
dependabot-preview[bot]
9cd8aa1af9 build(deps): bump addr2line from 0.14.0 to 0.14.1
Bumps [addr2line](https://github.com/gimli-rs/addr2line) from 0.14.0 to 0.14.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.14.0...0.14.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-11 08:09:26 +00:00
dependabot-preview[bot]
f6b63af06d build(deps): bump anyhow from 1.0.37 to 1.0.38
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.37...1.0.38)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-11 08:08:59 +00:00
dependabot-preview[bot]
8ff1142bf4 build(deps): bump signal-hook from 0.3.2 to 0.3.3
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.2 to 0.3.3.
- [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>
2021-01-11 08:08:39 +00:00
dependabot-preview[bot]
5de4d03238 build(deps): bump regex from 1.4.2 to 1.4.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.2 to 1.4.3.
- [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.4.2...1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-08 18:20:40 +00:00
dependabot-preview[bot]
302e4c17d2 build(deps): bump smallvec from 1.6.0 to 1.6.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.6.0...v1.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-08 18:17:57 +00:00
Sebastien Boeuf
b49c7dfd65 ci: Always download the Windows image
Because we're back on transient builder, let's download the image
everytime.

This reverts commit b5653d5278.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-08 17:18:28 +00:00
dependabot-preview[bot]
985da4d3fe build(deps): bump regex-syntax from 0.6.21 to 0.6.22
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.21 to 0.6.22.
- [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>
2021-01-08 16:45:25 +00:00
dependabot-preview[bot]
2ec7d1ae05 build(deps): bump linux-loader from acf9c21 to 2855be1
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `acf9c21` to `2855be1`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](acf9c21591...2855be15a7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-08 16:29:48 +00:00
dependabot-preview[bot]
fc47dd6645 build(deps): bump thiserror from 1.0.22 to 1.0.23
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.22 to 1.0.23.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.22...1.0.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-08 16:01:10 +00:00
dependabot-preview[bot]
2e924f458e build(deps): bump syn from 1.0.57 to 1.0.58
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.57...1.0.58)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-08 15:33:20 +00:00
Sebastien Boeuf
20fde6b924 tests: Increase sleep time in Windows integration tests
Some sporadic failures were due to an early connection to the VM while
it was not fully ready. Increasing sleep times fixes these issues.

Fixes #2104

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-08 15:03:04 +00:00
Rob Bradford
72d054bf40 tests: Teporarily disable test_windows_guest_snapshot_restore
This test is reliably failing on our CI and we need time to investigate
why.

See: #2126

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-08 15:03:04 +00:00
Rob Bradford
e0d79196c8 virtio-devices, vmm: Enhance debugging around virtio device activation
Sometimes when running under the CI tests fail due to a barrier not
being released and the guest blocks on an MMIO write. Add further
debugging to try and identify the issue.

See: #2118

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-08 14:06:44 +00:00
Bo Chen
a286e960ed tests: Remove the check on the "booted" message in 'wait_vm_boot()'
Given we already check the connected IP address matches the expected
guest IP address, the check on the "booted" message is not needed.

Fixes: #2117

Signed-off-by: Bo Chen <chen.bo@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-08 12:54:35 +00:00
Sebastien Boeuf
f70852c04b virtio-devices: Update seccomp filters for virtio-net thread
On aarch64, the openat() syscall was missing from the seccomp filters
list, preventing the test_watchdog from running properly.

Fixes #2103

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2021-01-08 12:37:32 +00:00
Rob Bradford
8f740f5c02 Jenkinsfile: Disable fast failing
Temporarily disable fast failing to try and make progress on CI
stabilisation to allow more test coverage.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-08 12:24:33 +00:00
Rob Bradford
17c9e2cd4b tests: Make boot notifications retry
If the guest fails to communicate with the test harness then retry.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-08 12:24:33 +00:00
Rob Bradford
b5653d5278 Jenkinsfile: Don't download the Windows images
They are already provisioned on the builder machine.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-07 17:31:02 +00:00
Rob Bradford
28abe63f46 tests: Fix test_virtio_block_disable_io_uring()
This test wasn't actually disabling io_uring.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 18:26:02 +00:00
Rob Bradford
49b49421d0 tests: Temporarily disable test_watchdog on aarch64
This test is very flaky and regularly causing CI failures. Until we can
identify the root cause we should disable this test.

See: #2103

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 18:26:02 +00:00
Rob Bradford
ef12216c19 tests: Add explicit QCOW2 based image test
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 18:26:02 +00:00
Rob Bradford
e05ed9240a tests: Use raw images for all tests
Simplify our image handling by not copying both QCOW2 and raw images for
every test. Allow the test to choose QCOW2 or raw by specifying the
image name manually. A follow on patch will add explicity QCOW2 tests.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 18:26:02 +00:00
Rob Bradford
c91d25ea64 tests: Don't swallow SSH errors
When an SSH command fails we want to be able to see, via a panic() why
and where it failed. Replace use of .unwrap_or_default() from SSH
command calls to ensure that we can see the location of the panic.

Also enhance the existing SSH output code to show the error if there is
one.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 13:51:26 +01:00
Rob Bradford
315a730128 virtio-devices: net: Reduce debug level of EVENT_IDX messages
This logging is too spammy for info!() level and should be handled as
debug!() level

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 13:51:26 +01:00
Rob Bradford
230e8a23a0 vm-virtio: queue: Reduce logging level of EVENT_IDX logs
This logging is too spammy for info!() level and should be handled as
debug!() level

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-06 13:51:26 +01:00
Mikko Ylinen
f583aa9d30 sgx: update virt EPC device path and docs
Based on the LKML feedback, the devices under /dev/sgx/* are
not justified. SGX RFC v40 moves the SGX device nodes to /dev/sgx_*
and this is reflected in kvm-sgx (next branch) too.

Update cloud-hypervisor code and documentation to follow this.

Signed-off-by: Mikko Ylinen <mikko.ylinen@intel.com>
2021-01-05 15:48:17 +00:00
Rob Bradford
76adea46d0 Revert "build(deps): bump linux-loader from acf9c21 to b18d387"
This reverts commit 7f1f335950.

This breaks the compilation on Fedora/RedHat machines by requiring
dpkg-deb in the build.rs

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-05 15:43:40 +00:00
dependabot-preview[bot]
7f1f335950 build(deps): bump linux-loader from acf9c21 to b18d387
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `acf9c21` to `b18d387`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](acf9c21591...b18d387889)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-05 11:15:02 +00:00
dependabot-preview[bot]
2e6f93e1a9 build(deps): bump smallvec from 1.5.1 to 1.6.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-05 07:02:07 +00:00
Rob Bradford
539708e45e scripts, resources: x86_64: Update to Linux kernel v5.10 base
This allows the removal of most of the custom patches in particular all
the virtio-fs ones have been integrated.

Partially fixes: #2070

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 22:44:40 +00:00
Rob Bradford
2e87d5ae02 tests: integration: Check different virtio-fs SHM region names
Depending on the kernel version the SHM region has a different name.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 22:44:40 +00:00
Rob Bradford
14af74cb5b vmm: seccomp: Allow clock_gettime() on the vCPU thread
If the vCPU thread calls log!() the time difference between the call
time and the boot up time is reported. On most environments and
architectures this covered by a vDSO call rather than a syscall. However
on some platforms this turns into a syscall.

Fixes: #2080

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 10:13:42 -08:00
dependabot-preview[bot]
73612401a5 build(deps): bump signal-hook from 0.2.2 to 0.3.2
Manually changed to reflect changes in mutability of signals and
rearrangement of constants.

Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.2.2 to 0.3.2.
- [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.2.2...v0.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 17:59:41 +00:00
dependabot-preview[bot]
858f64b3dc build(deps): bump rand from 0.8.0 to 0.8.1
Bumps [rand](https://github.com/rust-random/rand) from 0.8.0 to 0.8.1.
- [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.8.0...0.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-04 16:36:19 +00:00
dependabot-preview[bot]
225bedcb20 build(deps): bump arc-swap from 1.1.0 to 1.2.0
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.1.0 to 1.2.0.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-04 13:32:54 +00:00
dependabot-preview[bot]
8367784cf3 build(deps): bump syn from 1.0.56 to 1.0.57
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.56...1.0.57)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-04 13:32:17 +00:00
Rob Bradford
ecc1da95dd arch: aarch64: Remove unnecessary literal cast
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
184baff355 hypervisor: kvm: aarch64: Use struct initialisation
error: field assignment outside of initializer for an instance created with Default::default()
Error:     --> hypervisor/src/kvm/mod.rs:1239:9
     |
1239 |         state.mp_state = self.get_mp_state()?;
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
note: consider initializing the variable with `kvm::aarch64::VcpuKvmState { mp_state: self.get_mp_state()?, ..Default::default() }` and removing relevant reassignments
    --> hypervisor/src/kvm/mod.rs:1237:9
     |
1237 |         let mut state = CpuState::default();
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
3ad94ddf7c devices: rtc_pl031: Don't use manual range check
error: manual `Range::contains` implementation
Error:    --> devices/src/legacy/rtc_pl031.rs:342:12
    |
342 |         if offset < AMBA_ID_HIGH && offset >= AMBA_ID_LOW {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset)`
    |
    = note: `-D clippy::manual-range-contains` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
fabd63072b misc: Remove unnecessary literal casts
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
05cdef17f4 virtio-devices: mem, balloon: Use struct initialisation
error: field assignment outside of initializer for an instance created with Default::default()
   --> virtio-devices/src/mem.rs:496:9
    |
496 |         resp.resp_type = resp_type;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
note: consider initializing the variable with `mem::VirtioMemResp { resp_type: resp_type, ..Default::default() }` and removing relevant reassignments
   --> virtio-devices/src/mem.rs:495:9
    |
495 |         let mut resp = VirtioMemResp::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
6ccd32c904 pci: Remove manual range checks
error: manual `Range::contains` implementation
   --> pci/src/vfio.rs:948:12
    |
948 |         if (reg_idx >= PCI_CONFIG_BAR0_INDEX && reg_idx < PCI_CONFIG_BAR0_INDEX + BAR_NUMS)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(PCI_CONFIG_BAR0_INDEX..PCI_CONFIG_BAR0_INDEX + BAR_NUMS).contains(&reg_idx)`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
50dae04c05 arch: smbios: Use literal types rather than casts
We must explicitly mark these values as u8 as the function that consumes
them takes a T and needs to use the specific width.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
44ac11efc7 arch: smbios: Use struct initialiser where possible
Checking arch v0.1.0 (/home/rob/src/cloud-hypervisor/arch)
error: field assignment outside of initializer for an instance created with Default::default()
   --> arch/src/x86_64/smbios.rs:174:9
    |
174 |         smbios_biosinfo.typ = BIOS_INFORMATION;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
note: consider initializing the variable with `x86_64::smbios::SmbiosBiosInfo { typ: BIOS_INFORMATION, length: mem::size_of::<SmbiosBiosInfo>() as u8, handle: handle, vendor: 1, version: 2, characteristics: PCI_SUPPORTED, characteristics_ext2: IS_VIRTUAL_MACHINE, ..Default::default() }` and removing relevant reassignments
   --> arch/src/x86_64/smbios.rs:173:9
    |
173 |         let mut smbios_biosinfo = SmbiosBiosInfo::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
f452fe7497 hypervisor: kvm: Use struct initialiser where possible
error: field assignment outside of initializer for an instance created with Default::default()
   --> hypervisor/src/kvm/mod.rs:318:9
    |
318 |         cap.cap = KVM_CAP_SPLIT_IRQCHIP;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
note: consider initializing the variable with `kvm_bindings::kvm_enable_cap { cap: KVM_CAP_SPLIT_IRQCHIP, ..Default::default() }` and removing relevant reassignments
   --> hypervisor/src/kvm/mod.rs:317:9
    |
317 |         let mut cap: kvm_enable_cap = Default::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
a2e1e13918 vhost_user_block: Use struct instantiation rather than mut variable
error: field assignment outside of initializer for an instance created with Default::default()
   --> vhost_user_block/src/lib.rs:223:9
    |
223 |         config.capacity = nsectors;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
note: consider initializing the variable with `block_util::VirtioBlockConfig { capacity: nsectors, blk_size: BLK_SIZE, size_max: 65535, seg_max: 128 - 2, min_io_size: 1, opt_io_size: 1, num_queues: num_queues as u16, writeback: 1, ..Default::default() }` and removing relevant reassignments
   --> vhost_user_block/src/lib.rs:221:9
    |
221 |         let mut config = VirtioBlockConfig::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
a4134f6b25 net_util: Remove unit error from Result
error: this returns a `Result<_, ()>
  --> net_util/src/mac.rs:68:5
   |
68 |     pub fn from_bytes(src: &[u8]) -> Result<MacAddr, ()> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `-D clippy::result-unit-err` implied by `-D warnings`
   = help: use a custom Error type instead
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err

Replace with std::io::Error like other locations in the same file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
d2de263774 qcow: Use .contains() for range check
error: manual `!RangeInclusive::contains` implementation
   --> qcow/src/qcow.rs:412:12
    |
412 |         if cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!(MIN_CLUSTER_BITS..=MAX_CLUSTER_BITS).contains(&cluster_bits)`
    |
    = note: `-D clippy::manual-range-contains` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
9f2e7f455f block_util, vhost_user_block: Avoid unnecessary literal cast
error: casting integer literal to `u64` is unnecessary
  --> block_util/src/lib.rs:35:30
   |
35 | pub const SECTOR_SIZE: u64 = (0x01 as u64) << SECTOR_SHIFT;
   |                              ^^^^^^^^^^^^^ help: try: `0x01_u64`
   |
   = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Rob Bradford
faba6a3fb3 vmm: memory_manager: Use workaround for conditional function arguments
With Rust 1.49 using attributes on a function parameter is not allowed.
The recommended workaround is to put it in a new block.

error[E0658]: attributes on expressions are experimental
   --> vmm/src/memory_manager.rs:698:17
    |
698 |                 #[cfg(target_arch = "x86_64")]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information

error: removing an expression is not supported in this position
   --> vmm/src/memory_manager.rs:698:17
    |
698 |                 #[cfg(target_arch = "x86_64")]
    |

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2021-01-04 13:46:37 +01:00
Wei Liu
2aaf0540b6 hypervisor: drop linux-loader dependency
It is not used anywhere inside the hypervisor crate.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2021-01-04 10:17:20 +00:00
dependabot-preview[bot]
d82e74e4bf build(deps): bump quote from 1.0.7 to 1.0.8
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.7...1.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-01 11:12:44 +00:00
dependabot-preview[bot]
f9a3476016 build(deps): bump serde_json from 1.0.60 to 1.0.61
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.60 to 1.0.61.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.60...v1.0.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-01 11:12:19 +00:00
dependabot-preview[bot]
aaa364a9c5 build(deps): bump openssl-sys from 0.9.59 to 0.9.60
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.59 to 0.9.60.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.59...openssl-sys-v0.9.60)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-30 07:54:34 +00:00
dependabot-preview[bot]
d20e07b271 build(deps): bump itoa from 0.4.6 to 0.4.7
Bumps [itoa](https://github.com/dtolnay/itoa) from 0.4.6 to 0.4.7.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/0.4.6...0.4.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-30 07:54:24 +00:00
dependabot-preview[bot]
3074b178bd build(deps): bump rand from 0.7.3 to 0.8.0
Bumps [rand](https://github.com/rust-random/rand) from 0.7.3 to 0.8.0.
- [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-12-29 20:13:28 +00:00
dependabot-preview[bot]
4751a5949d build(deps): bump syn from 1.0.54 to 1.0.56
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.54 to 1.0.56.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.54...1.0.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-29 19:25:53 +00:00
dependabot-preview[bot]
25d567b6c6 build(deps): bump anyhow from 1.0.35 to 1.0.37
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.35 to 1.0.37.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.35...1.0.37)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-29 19:25:41 +00:00
Rob Bradford
bb1ef5f1b8 tests: integration: Remove quiet from kernel command line
It will be useful to see kernel output from our integration tests when
they fail.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-18 16:05:14 +00:00
Rob Bradford
d9e1eec47d tests: integration: Use direct kernel boot for most tests
The boot time for direct kernel boot based tests is significantly
quicker than booting via the firmware and stock kernel as it triggers a
reboot during the boot process due to the initrd handling.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-18 16:05:14 +00:00
Rob Bradford
a4c076bd09 tests: integration: Don't always have kernel serial output
When doing a direct kernel boot only have console=ttyS0 in the command
line if we are explicitly testing the serial output. The default
behaviour is `--serial null` so this output will not be visible but will
trigger a KVM exit for every byte which is very costly when running
under nested virtualization.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-18 16:05:14 +00:00
Rob Bradford
8a27735826 main: Add thread name to log output
If there is no thread then the name is reported as "anonymous".

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-18 16:05:14 +00:00
Rob Bradford
e8c72b1b01 virtio-devices: pci: Improve debugging for activation barriers
On the CI we are seeing issues with the activation barriers not being released:

cloud-hypervisor: 12.452434193s: INFO:vmm/src/vm.rs:413 -- Waiting for barrier
cloud-hypervisor: 12.452499794s: INFO:virtio-devices/src/block.rs:382 -- Changing cache mode to writeback
cloud-hypervisor: 12.452605195s: INFO:vmm/src/vm.rs:413 -- Waiting for barrier
cloud-hypervisor: 12.452684596s: INFO:virtio-devices/src/transport/pci_device.rs:671 -- Waiting for barrier
cloud-hypervisor: 12.452708196s: INFO:virtio-devices/src/transport/pci_device.rs:673 -- Barrier released
cloud-hypervisor: 12.452717596s: INFO:vmm/src/vm.rs:415 -- Barrier released

Add some debugging to try and identify the vause of this issue.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-18 16:05:14 +00:00
Rob Bradford
ee537d9bde docs: Add instructions for using MACVTAP for bridging
Now that we can support supplying an fd to the TAP device we can support
the MACVTAP and MACVLAN use cases.

Fixes: #872

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
873c79a931 tests: Add test_tap_from_fd()
This test creates new TAP device, opens it and then passed the fd in via
--net fd=<fd>

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
7a51be48c6 vmm: openapi: Add fd to NetConfig definition
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
7f9cdf1183 vmm: device_manager: Create a virtio-net device from TAP fd
If a TAP fd is supplied then create an virtio-net device using that TAP
fd.

Fixes: #2052

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
72e5ed3372 vmm: config: Extend NetConfig to include fd for tap device
Add an "fd=" parameter to allow specifying a TAP fd to use. Currently
only one fd for one queue pair is supported.

Fixes: #2052

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
ca48f1c995 virtio-devices: net: Support creating a device from a TAP fd
Add support for creating virtio-net device from existing TAP fd.
Currently only a single fd and thus no-more than 2 queues (one pair) is
suppored.

Fixes: #2052

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
444905071b vmm: seccomp: Permit TUNGETIFF through the filter
This is used to obtain the TAP device name.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
385d734847 net_util: Add API for creating a Tap from an fd
Ultimately this will allow the creation of a virtio-net device that is
backed by a file descriptor.

This function ensures that the TAP device is correctly setup with
offloading and non-blocking.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Rob Bradford
16c2eebfd1 net_util: Extend Tap::open_named() to take flags
This allows us to open the named TAP device without O_CLOEXEC for an
integration test.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 22:51:30 +01:00
Samuel Ortiz
21dcac7721 hypervisor: Bump iced-x86 to 1.10.0
And fix related warnings: op_kind and op_register are being deprecated
as they might panic.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 18:58:34 +00:00
Rob Bradford
3ee56112cb tests: Bump boot default timeout
Starting the virtio device threads from the VMM thread has slowed down
the start of the VM when running on a highly contested system like the
CI.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
03db48306b vmm: Activate virtio device from VMM thread
When a device is ready to be activated signal to the VMM thread via an
EventFd that there is a device to be activated. When the VMM receives a
notification on the EventFd that there is a device to be activated
notify the device manager to attempt to activate any devices that have
not been activated.

As a side effect the VMM thread will create the virtio device threads.

Fixes: #1863

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
dee42ebb29 virtio-devices: pci_device: Split out device activation
This can then be used to activate the device from a separate thread.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
7cc729c7d9 pci, virtio-devices: Extend barrier returning through PCI code
We need to be able to return the barrier from the code that prepares to
activate the virtio device. This triggered by a write to the
configuration fields stored in the PCI BAR. Since bars can be accessed
by both memory mapping and through PCI config I/O several prototypes
must be changed.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
a8643dc523 vm-device, vmm: Wait for barrier if one is returned
Wait for the barrier if one is provided by the result of the MMIO and
PIO write.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
1fc6d50f3e misc: Make Bus::write() return an Option<Arc<Barrier>>
This can be uses to indicate to the caller that it should wait on the
barrier before returning as there is some asynchronous activity
triggered by the write which requires the KVM exit to block until it's
completed.

This is useful for having vCPU thread wait for the VMM thread to proceed
to activate the virtio devices.

See #1863

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
Rob Bradford
dbf4a252ad devices: acpi: Remove empty BusDevice::write implementation
The trait already includes an empty implementation of this function.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-17 11:23:53 +00:00
dependabot-preview[bot]
add9b13497 build(deps): bump signal-hook from 0.2.1 to 0.2.2
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.2.1 to 0.2.2.
- [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.2.1...v0.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-15 18:03:49 +00:00
dependabot-preview[bot]
3d097eef44 build(deps): bump arc-swap from 1.0.0 to 1.1.0
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.0.0 to 1.1.0.
- [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/v1.0.0...v1.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-14 09:13:04 +00:00
Muminul Islam
8c85dd32fa hypervisor: Move msr and msr_data macro to arch/x86
Currently these two macros(msr, msr_data) reside both on kvm and mshv
module. Definition is same for both module. Moving them to arch/x86
module eliminates redundancy and makes more sense.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-11 00:59:46 +01:00
Muminul Islam
aac86f4523 hypervisor: Fix clippy errors in the mshv module
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-10 19:43:58 +00:00
dependabot-preview[bot]
f3e889c204 build(deps): bump vcpkg from 0.2.10 to 0.2.11
Bumps [vcpkg](https://github.com/mcgoo/vcpkg-rs) from 0.2.10 to 0.2.11.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 19:19:55 +00:00
Rob Bradford
3eb9e61a32 rpm: Update spec file for version bump
Update the spec file for the rpm to the latest version.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-10 18:13:59 +00:00
Rob Bradford
d42b50845b build, release-notes.md: Document 0.12.0 release
Update release notes and version number for the new release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-10 18:11:56 +00:00
Rob Bradford
06f391e022 tests: integration: Retry epoll if we receive -EINTR or -EAGAIN
On the CI we are seeing that sometimes the epoll is receiving these
errors which do not indicate a failure but that we should retry.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-10 10:11:19 -08:00
dependabot-preview[bot]
60d2469e7a build(deps): bump openssl-sys from 0.9.58 to 0.9.59
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.58 to 0.9.59.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.58...openssl-sys-v0.9.59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 07:33:54 +00:00
Wei Liu
c4f8e4b000 main: provide a sensible error message when /dev/mshv is missing
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-09 17:28:36 +00:00
Muminul Islam
c32959261e gh: Expand clippy tests to cover the mshv feature
Since we can't test mshv and kvm at the same time, --all-features no
longer work.
We factorize all, non-hypervisor related features into a common set and
mix that with either mshv and kvm.

Co-Developed-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
ef3fad8388 hypervisor: mshv: Implement CPU state for MshvVcpu
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
2b42f6c835 hypervisor: mhsv: Implement CPU run loop
Handle CPU exits, adding instruction emulations.
Keep CPU specific data inside vmm for later use.

Co-Developed-by: Nuno Das Neves <nudasnev@microsoft.com>
Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
Co-Developed-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Co-Developed-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
7acb5c6437 hypervisor, mshv: Define MshvEmulatorContext
This patch adds the definition and implementation
MshvEmulatorContext which is platform emulation for Hyper-V.

Co-Developed-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
63f356b75b hypervisor: mhsv: Define software emulated TLB
A software emulated TLB. This is mostly used by
the instruction emulator to cache gva to gpa
translations passed from the hypervisor.

Co-Developed-by: Nuno Das Neves <nudasnev@microsoft.com>
Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
Co-Developed-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Co-Developed-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
fd0ef6cfb5 hypervisor: mshv: Emulate IrqFd and IOEventFd for mshv module
We don't have IrqFd and IOEventFd support in the kernel for now.
So an emulation layer is needed. In the future, we will be adding this
support in the kernel.

Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
286a23fbd4 hypervisor: mshv: Add vmmops to MshvVm struct
vmmops trait object is needed to get access some
of the upper level vmm functionalities i.e guest
memory access, IO read write etc.

Co-Developed-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
3a93487b82 hypervisor: mshv: Add Microsoft Hypervisor specific data to Mshv{Vm,Vcpu}
Adding hv_state (hyperv state) to Vm and Vcpu struct for mshv.
This state is needed to keep some kernel data(for now hypercall page)
in the vmm.

Co-Developed-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
23c46b162e hypervisor, vmm: Implement the mshv module and add mshv support in vmm
Implement hypervisor, Vm, Vcpu crate at a minimal
functionalities. Also adds the mshv feature gate,
separates out the functionalities between kvm and
mshv inside the vmm crate.

Co-Developed-by: Nuno Das Neves <nudasnev@microsoft.com>
Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
Co-Developed-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Co-Developed-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
f4af668d76 hypervisor, vmm: Implement MsiInterruptOps for mshv
Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
7fe5d276a3 hypervisor: mshv: Add x86_64 module
Add x86_64 specific definitions as we only plan
to support x86_64 for the moment.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
e664fa386b hypervisor: Modify toml file to add mshv-{bindings, ioctls) crates
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
9919dec1d9 hypervisor: Introduce mshv module in the hypervisor
This is the initial folder structure of the mshv module inside
the hypervisor crate. The aim of this module is to support Microsoft
Hyper-V as a supported Hypervisor.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
Muminul Islam
9ce6c3b75c hypervisor, vmm: Feature guard KVM specific code
There are some code base and function which are purely KVM specific for
now and we don't have those supports in mshv at the moment but we have plan
for the future. We are doing a feature guard with KVM. For example, KVM has
mp_state, cpu clock support,  which we don't have for mshv. In order to build
those code we are making the code base for KVM specific compilation.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-09 14:55:20 +01:00
dependabot-preview[bot]
47f59409db build(deps): bump anyhow from 1.0.34 to 1.0.35
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.34 to 1.0.35.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.34...1.0.35)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 09:01:03 +00:00
dependabot-preview[bot]
b51f112629 build(deps): bump libc from 0.2.80 to 0.2.81
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.80 to 0.2.81.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.80...0.2.81)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 08:13:51 +00:00
dependabot-preview[bot]
d158fa8de2 build(deps): bump linux-loader from 3cf96c5 to acf9c21
Bumps [linux-loader](https://github.com/rust-vmm/linux-loader) from `3cf96c5` to `acf9c21`.
- [Release notes](https://github.com/rust-vmm/linux-loader/releases)
- [Commits](3cf96c53ed...acf9c21591)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 08:13:27 +00:00
dependabot-preview[bot]
c64de38140 build(deps): bump syn from 1.0.53 to 1.0.54
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.53 to 1.0.54.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.53...1.0.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 22:10:21 +00:00
Rob Bradford
9594ecec0d build: Only pull in iced-x86 for x86_64 builds
Fixes: #2024

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-07 17:42:42 +00:00
Anatol Belski
6c0c47a530 docs/windows.md: Add explicit note on how to start WinDbg
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2020-12-07 16:56:00 +00:00
Wei Liu
6d38612f6c hypervisor: x86: move RFLAGS bits to regs.rs
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Wei Liu
a44d96c9cc hypervisor: emulator: switch to use vec in MockVMM
The customized hashmap macro can't be lifted to common MockVMM code.
MockVMM only needs a collection to iterate over to get initial register
states. A vector is just as good as a hashmap.

Switch to use a vector to store initial register states. This allows us
to drop the hashmap macro everywhere.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Wei Liu
93b7dcac12 hypervisor: emulator: emulate CMP
Unfortunately Rust stable does not yet have inline ASM support the flag
calculation will have to be implemented in software.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Wei Liu
dd3844a892 hypervisor: emulator: drop imm_op macro
It is not needed anymore.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Wei Liu
0c3ef986fa hypervisor: emulator: rewrite MOV emulation with get/set_op
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Wei Liu
53c3b00fb0 hypervisor: emulator: introduce get/set_op
Provide two helpers to get and set operands. This reduces repetition.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-07 14:35:35 +01:00
Rob Bradford
03b824be0b build: Disable fast failing for build actions
nightly / beta are not required actions but if they fail then all other
builds will be cancelled and so prevent the PR from being cleared as
buildable.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-07 12:36:38 +00:00
dependabot-preview[bot]
558975aa51 build(deps): bump serde_derive from 1.0.117 to 1.0.118
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 09:22:13 +00:00
dependabot-preview[bot]
d78b9bd287 build(deps): bump smallvec from 1.5.0 to 1.5.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.5.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 09:08:31 +00:00
dependabot-preview[bot]
365d39ca2c build(deps): bump serde from 1.0.117 to 1.0.118
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 08:36:52 +00:00
Muminul Islam
d79594aa3f scripts: dev_cli: Remove unnecessary spaces
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-05 00:01:41 +01:00
Muminul Islam
27b5f8d7e3 scripts: Add an option to accept hypervisor argument
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-12-05 00:01:41 +01:00
Rob Bradford
2cc312b65c build: Fix cargo fuzz build
Unfortunately it seems patch entries are ignored when obtaining
dependencies from another workspace.

Remove the problematic kvm-ioctls and kvm-bindings patch entries and use
the forked repository directly.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-04 11:38:44 +00:00
dependabot-preview[bot]
d416271457 build(deps): bump cc from 1.0.65 to 1.0.66
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.65 to 1.0.66.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.65...1.0.66)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-04 10:51:49 +00:00
Rob Bradford
9e6a023f7f vmm: Don't continue to lookup debug I/O port
When using an PIO write to 0x80 which is a special case handle that and
then return without going through the resolve.

This removes an extra warning that is reported.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-03 07:25:42 -08:00
Wei Liu
90ae4676c8 hypervisor: x86: emulator: drop unneeded curly brackets
There is no need to have a pair of curly brackets for structures without
any member.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-03 14:52:00 +01:00
dependabot-preview[bot]
89bc413add build(deps): bump serde_json from 1.0.59 to 1.0.60
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.59 to 1.0.60.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.59...v1.0.60)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-03 13:50:29 +00:00
Wei Liu
c352b59857 hypervisor: emulator: drop InstructionMap
It is not needed anymore.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-02 19:45:36 +01:00
Wei Liu
ab89b48143 hypervisor: emulator: use static mapping to dispatch emulation
The mapping between code and its handler is static. We can drop the
HashMap in favour of a static match expression.

This has two benefits:
1. No more memory allocation and deallocation for the HashMap.
2. Shorter look-up time.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-12-02 19:45:36 +01:00
Rob Bradford
ffaab46934 misc: Use a more relaxed memory model when possible
When a total ordering between multiple atomic variables is not required
then use Ordering::Acquire with atomic loads and Ordering::Release with
atomic stores.

This will improve performance as this does not require a memory fence
on x86_64 which Ordering::SeqCst will use.

Add a comment to the code in the vCPU handling code where it operates on
multiple atomics to explain why Ordering::SeqCst is required.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-02 19:04:30 +01:00
Rob Bradford
280d4fb245 vmm: Include device tree in vm.info API
The DeviceNode cannot be fully represented as it embeds a Rust style
enum (i.e. with data) which is instead represented by a simple
associative array.

Fixes: #1167

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-01 16:44:25 +01:00
Samuel Ortiz
15f0451c34 hypervisor: emulator: Format instructions on error paths
Formatting instructions might be costly, so we only want to do that on
the emulation error paths.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-12-01 11:13:54 +01:00
Samuel Ortiz
3fa6e17cc4 hypervisor: x86: Make imm_op available to all emulated instructions
By moving it to the instructions root module.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-12-01 11:13:54 +01:00
Wei Liu
e2c81f9ed8 hypervisor: x86: Extend the imm_op() macro
To support every kind of immediate operands.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-12-01 11:13:54 +01:00
Rob Bradford
ead8453120 build: Remove vhost_user_fs
This has been superseded by virtiofsd-rs.

Fixes: #2013

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-01 11:13:21 +01:00
Rob Bradford
c4ebe83576 rpm: Update .spec file to not reference vhost_user_fs
Fixes: #2013

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-01 11:13:21 +01:00
Rob Bradford
1908f488c3 tests: Move tests from vhost_user_fs to virtiofsd-rs
Download and build virtiofsd-rs and then use that in the integration
test suite.

Fixes: #2013

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-01 11:13:21 +01:00
Rob Bradford
593a958fe5 pci, vmm: Include VFIO devices in device tree
Fixes: #1687

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-12-01 10:49:04 +01:00
Wei Liu
ba71390d6a hypervisor: drop arc-swap dependency
It is no longer needed after 0fec32658.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-11-30 16:47:32 +00:00
Samuel Ortiz
f6892f2ede hypervisor: emulator: Add a negative instruction fetch unit test
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
251434862f hypervisor: emulator: Fix logic bug in MockVMM
emulate_first_insn() really means we want only the first instruction to
be emulated.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
1ac4c42a84 hypervisor: emulator: Add initial fetch support
When the x86 instruction decoder tells us about some missing bytes from
the instruction stream, we call into the platform fetch method and
emulate one last instruction.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
7dc92d1dac hypervisor: emulator: Decoding loop restructuring
In preparation for the instruction fetching step, we modify the decoding
loop so that we can check what the last decoding error is.

We also switch to explictly using decode_out() which removes a 32 bytes
copy compared to decode().

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
7a4edecd29 hypervisor: x86: Add an address linearization method to CpuStateManager
From a CPU state and a segment, we can translate a logical (segmented)
address into a linear one.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
d419e30df1 hypervisor: x86: Add a SegmentRegistorOps trait
In order to validate emulated memory accesses, we need to be able to get
all the segments descriptor attributes.

This is done by abstracting the SegmentRegister attributes through a
trait that each hypervisor will have to implement.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
3faffcb087 hypervisor: emulator: Add a CPU mode getter to CpuStateManager
We need to be able to build the CPU mode from its state in order to
start implementing mode related checks in the x86 emulator.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
Samuel Ortiz
b3a1f5f1be hypervisor: Start moving register definitions to the hypervisor crate
Most of arch/src/x86_64/regs.rs will eventually move unde
hypervisor/src/x86/regs.rs.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-30 13:09:19 +00:00
dependabot-preview[bot]
2bc5119730 build(deps): bump syn from 1.0.52 to 1.0.53
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.52 to 1.0.53.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.52...1.0.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-30 09:09:26 +00:00
dependabot-preview[bot]
5100bc94cc build(deps): bump syn from 1.0.51 to 1.0.52
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.51...1.0.52)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-28 00:28:08 +00:00
dependabot-preview[bot]
6bf9fe487b build(deps): bump pnet from 0.26.0 to 0.27.2
Bumps [pnet](https://github.com/libpnet/libpnet) from 0.26.0 to 0.27.2.
- [Release notes](https://github.com/libpnet/libpnet/releases)
- [Commits](https://github.com/libpnet/libpnet/compare/v0.26.0...v0.27.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-27 23:56:02 +00:00
Rob Bradford
d1a23d9085 docs: Add instructions for using perf
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-27 19:19:14 +01:00
Rob Bradford
05f785fa88 build: Move timeouts to integration test blocks
If we rely on timeouts at the top level we can get builds being aborted
simply because they took too long to be scheduled rather than because
the actual integration tests took too long.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-27 19:18:39 +01:00
Samuel Ortiz
a3d957ba4d hypervisor: emulator: Clean the MockVMM initialization path
Separate the standalone _init_and_run() function into 2 MockVMM methods:
new() and emulate_insn().

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-27 19:17:35 +01:00
Samuel Ortiz
5bd63efa45 hypervisor: emulator: Move MockVMM into a shared test module
The MockVMM platform will be used by other instructions emulation
implementations, but also by the emulator framework.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-27 19:17:35 +01:00
Wei Liu
66b001665f hypervisor: x86: only calculate address when necessary in MOV emulation
Only calculate the address when the operand is memory.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-11-26 16:12:23 +01:00
Wei Liu
c6aea5af5d hypervisor: x86: drop an extraneous box indirection
There is no need to put a box into another box.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-11-26 12:02:47 +00:00
Wei Liu
c8b655490e hypervisor: x86: reference PlatformEmulator in Emulator
The observation here is PlatformEmulator can be seen as the context for
emulation to take place. It should be rather easy to construct a context
that satisfies the lifetime constraints for instruction emulation.

The thread doing the emulation will have full ownership over the
context, so this removes the need to wrap PlatformEmulator in Arc and
Mutex, as well as the need for the context to be either Clone or Copy.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-11-26 12:14:40 +01:00
Rob Bradford
72741c557a actions: Add "--all --tests" to clippy in quality action
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
b2608ca285 vmm: cpu: Fix clippy issues inside test
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
74fe032827 vm-device: bus: Fix clippy issues inside tests
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
40a2e3b462 vhost_user_block: Fix clippy issue
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
abc6672f21 qcow: Fix clippy issues inside tests
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
053c9e4d73 devices: serial: Fix clippy issues inside tests
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
9ea19852b5 arch: x86_64: Fix clippy issues inside tests
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
Rob Bradford
9871ff454b arch_gen: mpspec: Fix clippy issues inside tests
Found by:  cargo clippy --all-features --all --tests

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-26 09:32:46 +01:00
dependabot-preview[bot]
e817b4f36c build(deps): bump crossbeam-utils from 0.8.0 to 0.8.1
Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.0 to 0.8.1.
- [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.8.0...crossbeam-utils-0.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-26 08:32:02 +00:00
Rob Bradford
6f63cd00eb vmm: device_manager: Remove ActivatedBackend struct
This was used for vhost-user self spawning but no longer has any users.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 20:47:43 +01:00
Wei Liu
a6ad85dc40 hypervisor: x86: handle more registers in emulator
List all GPRs documented in Intel's SDM.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-11-25 20:18:40 +01:00
Samuel Ortiz
0f4f30dbde hypervisor: x86: Add MOV to the emulator instruction map
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
fe5401223b hypervisor: x86: Emulate MOV
And add a few unit tests based on a Mock platform.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
12b7a498d9 hypervisor: x86: Add an instruction emulator
The emulator gets a CPU state from a CpuStateManager instance, emulates
the passed instructions stream and returns the modified CPU state.

The emulator is a skeleton for now since it comes with an empty
instruction mnemonic map.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
1fc97e91a4 hypervisor: x86: Add an InstructionHandler interface
And an InstructionMap helper structure to map x86 mnemonic codes
to instruction handlers.

Any instruction emulation implementation should then boil down with
implementing InstructionHandler for any supported mnemonic.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
fc5d6c96be hypervisor: x86: Add a minimal CpuStateManager implementation
Minimal will be defined by the amount of emulated instructions.
Carrying all GPRs, all CRs, segment registers and table registers should
cover quite a few instructions.

Co-developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
546778ebfb hypervisor: x86: Add a CpuStateManager interface
For efficiently emulating x86 instructions, we need to build and pass a
CPU state copy/reference to instruction emulation handlers. Those handlers
will typically modify the CPU state and let the caller commit those
changes back through the PlatformEmulator trait set_cpu_state method.

Hypervisors typically have internal CPU state structures, that maps back
to the correspinding kernel APIs. By implementing the CpuState trait,
instruction emulators will be able to directly work on CPU state
instances that are directly consumable by the underlying hypervisor and
its kernel APIs.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
f0360aff83 hypervisor: Architecture agnostic instruction emulation interface
In order to emulate instructions, we need a way to get access to some of
the guest resources. The PlatformEmulator interface provides guest
memory and CPU state access to emulator implementations.

Typically, an hypervisor will implement PlatformEmulator for architecture
specific instruction emulators to build their framework on top of.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Samuel Ortiz
ae96aeda65 arch: Move the gdt module to the hypervisor crate
We will need the GDT API for the hypervisor's x86 instruction
emulator implementation, it's better if the arch crate depends on the
hypervisor one rather than the other way around.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-25 17:02:11 +01:00
Rob Bradford
b5b97f7b05 vmm: When receiving a migration store the config
The configuration is stored separately to the Vm in the VMM. The failure
to store the config was preventing the VM from shutting down correctly
as Vmm::vm_delete() checks for the presence of the config.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 01:27:26 +01:00
Rob Bradford
9fc2613b41 vm-device: bus: Remove unwrap() when upgrading weak reference
Rather return the None to the caller to handle instead. This removes the
source of a potential panic.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 01:27:26 +01:00
Rob Bradford
44b5a19209 bin: ch-remote: Fix typo in error message
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 01:27:26 +01:00
Rob Bradford
df6b52924f vmm: Unlink created socket after source connects
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 01:27:26 +01:00
Rob Bradford
1ab1341775 vmm: seccomp_filters: Add KVM_GET_DIRTY_LOG to permitted calls
The live migration support added use of this ioctl but it wasn't
included in the permitted list.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-25 01:27:26 +01:00
dependabot-preview[bot]
a29f7ffcc7 build(deps): bump signal-hook from 0.2.0 to 0.2.1
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.2.0 to 0.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-11-25 00:26:27 +00:00
dependabot-preview[bot]
eda39d0469 build(deps): bump rust-argon2 from 0.8.2 to 0.8.3
Bumps [rust-argon2](https://github.com/sru-systems/rust-argon2) from 0.8.2 to 0.8.3.
- [Release notes](https://github.com/sru-systems/rust-argon2/releases)
- [Changelog](https://github.com/sru-systems/rust-argon2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sru-systems/rust-argon2/compare/0.8.2...0.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-24 09:38:49 +00:00
dependabot-preview[bot]
de0c24810e build(deps): bump syn from 1.0.50 to 1.0.51
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.50 to 1.0.51.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.50...1.0.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-24 06:01:35 +00:00
Samuel Ortiz
fadeb98c67 cargo: Bulk update
Includes updates for ssh2, cc, syn, tinyvec, backtrace micro-http and libssh2.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-23 12:25:31 +01:00
Samuel Ortiz
1fc0b94fcd cargo: Move to crates.io vm-memory 0.4.0
vm-memory 0.4.0 now contains all our fixes.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-23 10:55:13 +01:00
Samuel Ortiz
ef4c896bbf arch: aarch64: Fix rust 1.48 clippy warnings
methods called `new` usually return `Self`
See https://rust-lang.github.io/rust-clippy/master/index.html#new_ret_no_self

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-20 17:09:28 +01:00
Samuel Ortiz
72bb255ff6 pci, virtio-devices: Fix rust 1.48 clippy warnings
Unnecessary closure used to substitute value for `Option::None`
See https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-20 17:09:28 +01:00
Samuel Ortiz
a406d90059 arch: Fix rust 1.48 clippy warnings
const should not be mutable types:
https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2020-11-20 17:09:28 +01:00
dependabot-preview[bot]
0dfffee6ba build(deps): bump cc from 1.0.62 to 1.0.63
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.62 to 1.0.63.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.62...1.0.63)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-18 23:37:01 +00:00
Rob Bradford
0fec326582 hypervisor, vmm: Remove shared ownership of VmmOps
This interface is used by the vCPU thread to delegate responsibility for
handling MMIO/PIO operations and to support different approaches than a
VM exit.

During profiling I found that we were spending 13.75% of the boot CPU
uage acquiring access to the object holding the VmmOps via
ArcSwap::load_full()

    13.75%     6.02%  vcpu0            cloud-hypervisor    [.] arc_swap::ArcSwapAny<T,S>::load_full
            |
            ---arc_swap::ArcSwapAny<T,S>::load_full
               |
                --13.43%--<hypervisor::kvm::KvmVcpu as hypervisor::cpu::Vcpu>::run
                          std::sys_common::backtrace::__rust_begin_short_backtrace
                          core::ops::function::FnOnce::call_once{{vtable-shim}}
                          std::sys::unix::thread::Thread::new::thread_start

However since the object implementing VmmOps does not need to be mutable
and it is only used from the vCPU side we can change the ownership to
being a simple Arc<> that is passed in when calling create_vcpu().

This completely removes the above CPU usage from subsequent profiles.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-19 00:16:02 +01:00
dependabot-preview[bot]
6a591ca81d build(deps): bump pin-project from 1.0.1 to 1.0.2
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 1.0.1 to 1.0.2.
- [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/v1.0.1...v1.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-18 22:15:58 +00:00
dependabot-preview[bot]
a525f8365f build(deps): bump unicode-normalization from 0.1.15 to 0.1.16
Bumps [unicode-normalization](https://github.com/unicode-rs/unicode-normalization) from 0.1.15 to 0.1.16.
- [Release notes](https://github.com/unicode-rs/unicode-normalization/releases)
- [Commits](https://github.com/unicode-rs/unicode-normalization/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-18 22:15:49 +00:00
Rob Bradford
f271378811 tests: Wait for reboot in test_virtio_watchdog()
Aim to reduce flaky failures of this test by waiting for the VM to come
back after a reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 18:27:34 +01:00
Rob Bradford
78b9edf848 tests: Get output from firmware and Linux for test_large_vm()
As we switched to focal for this test we no longer get any output during
the boot unless serial is used over virtio-console.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 18:27:34 +01:00
Rob Bradford
d0aebfb922 tests: Increase time waited for hotplugged memory to appear
There have been a lot of flakes around tests such as
test_virtio_fs_hotplug_dax_on_w_vhost_user_fs_daemon() or
test_virtio_fs_hotplug_dax_on() which all try and hotplug memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 18:27:34 +01:00
Rob Bradford
f913dd6150 tests: Add integration test to force io_uring off for block
Fixes: #1561

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 11:47:54 +01:00
Rob Bradford
c622278030 config, device_manager: Add support for disabling io_uring for testing
Add config parameter to --disk called "_disable_io_uring" (the
underscore prefix indicating it is not for public consumpion.) Use this
option to disable io_uring if it would otherwise be used.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 11:47:54 +01:00
Rob Bradford
d1d0421103 main: Remove --net-backend and --block-backend from cloud-hypervisor
Remove the parameters used for self spawning from the cloud-hypervisor
binary.

See: #1925

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 11:46:32 +01:00
Rob Bradford
fb70baece0 tests: Make integration test use vhost_user_{net,block} binaries
With the removal of vhost-user self-spawning support we should migrate
the tests to use the binaries so that we can remove the functionality
from the cloud-hypervisor binary itself.

See: #1925

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-18 11:46:32 +01:00
dependabot-preview[bot]
0159ab93e1 build(deps): bump unicode-normalization from 0.1.14 to 0.1.15
Bumps [unicode-normalization](https://github.com/unicode-rs/unicode-normalization) from 0.1.14 to 0.1.15.
- [Release notes](https://github.com/unicode-rs/unicode-normalization/releases)
- [Commits](https://github.com/unicode-rs/unicode-normalization/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-18 09:01:29 +00:00
dependabot-preview[bot]
609d704168 build(deps): bump smallvec from 1.4.2 to 1.5.0
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.4.2 to 1.5.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.4.2...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-17 21:56:51 +00:00
Rob Bradford
3ac9b6c404 vmm: Implement live migration
Now the VM is paused/resumed by the migration process itself.

0. The guest configuration is sent to the destination
1. Dirty page log tracking is started by start_memory_dirty_log()
2. All guest memory is sent to the destination
3. Up to 5 attempts are made to send the dirty guest memory to the
   destination...
4. ...before the VM is paused
5. One last set of dirty pages is sent to the destination
6. The guest is snapshotted and sent to the destination
7. When the migration is completed the destination unpauses the received
   VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
b34703d29f vmm: vm: Add dirty log related passthrough methods
This allows code running in the VMM to access the VM's MemoryManager's
functionality for managing the dirty log including resetting it but also
generating a table.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
cf6763dfdb vmm: migration: Add missing response check
A read and check of the response was missing from when sending the
memory to the destination.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
11a69450ba vm-migration, vmm: Send configuration in separate step
Prior to sending the memory the full state is not needed only the
configuration. This is sufficient to create the appropriate structures
in the guest and have the memory allocations ready for filling.

Update the protocol documentation to add a separate config step and move
the state to after the memory is transferred. As the VM is created in a
separate step to restoring it the requires a slightly different
constructor as well as saving the VM object for the subsequent commands.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
c62e409827 memory_manager: Generate a MemoryRangeTable for dirty ranges
In order to do this we must extend the MemoryManager API to add the
ability to specify the tracking of the dirty pages when creating the
userspace mappings and also keep track of the userspace mappings that
have been created for RAM regions.

Currently the dirty pages are collected into ranges based on a block
level of 64 pages. The algorithm could be tweaked to create smaller
ranges but for now if any page in the block of 64 is dirty the whole
block is added to the range.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
041724a7cf hypervisor: Add ability to get dirty logged pages
Return a bitmap of pages that have been dirtied (written to) since it
was last called.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Rob Bradford
8baa244ec1 hypervisor: Add control for dirty page logging
When creating a userspace mapping provide a control for enabling the
logging of dirty pages.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-17 16:57:11 +00:00
Anatol Belski
b399287430 memory_manager: Make addressable space size 64k aligned
While the addressable space size reduction of 4k in necessary due to
the Linux bug, the 64k alignment of the addressable space size is
required by Windows. This patch satisfies both.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2020-11-16 16:39:11 +00:00
Rob Bradford
c0827e01b1 build: Update arc-swap dependency to 1.0.0
Also bump the vm-memory version to one that depends on arc-swap 1.0.0
too.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-16 14:10:09 +01:00
Rob Bradford
46e736973e hypervisor: kvm: Correctly share VmmOps between Kvm{Vm,Vcpu}
Cloning the ArcSwapOption (like the ArcSwap) does not act like a
.clone() on an Arc, instead an entirely new ArcSwap is created with the
same contents. To correctly share the ArcSwap needs to be placed inside
an Arc.

See: 2433d5719b (diff-6c6d94533c44c19bd1416ef17bad1a878e63dca6e98d59181228fbe8f967c62bR6)

Due to this being wrongly used ::clone() was removed from
ArcSwap/ArcSwapOption in 1.0.0.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-16 14:10:09 +01:00
dependabot-preview[bot]
096d99664d build(deps): bump ssh2 from 0.8.2 to 0.8.3
Bumps [ssh2](https://github.com/alexcrichton/ssh2-rs) from 0.8.2 to 0.8.3.
- [Release notes](https://github.com/alexcrichton/ssh2-rs/releases)
- [Commits](https://github.com/alexcrichton/ssh2-rs/compare/0.8.2...0.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-15 16:01:54 +00:00
dependabot-preview[bot]
f7c42dc7d2 build(deps): bump vmm-sys-util from 0.6.1 to 0.7.0
Bumps [vmm-sys-util](https://github.com/rust-vmm/vmm-sys-util) from 0.6.1 to 0.7.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.6.1...v0.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-13 15:55:05 +00:00
dependabot-preview[bot]
37f947d614 build(deps): bump unicode-normalization from 0.1.13 to 0.1.14
Bumps [unicode-normalization](https://github.com/unicode-rs/unicode-normalization) from 0.1.13 to 0.1.14.
- [Release notes](https://github.com/unicode-rs/unicode-normalization/releases)
- [Commits](https://github.com/unicode-rs/unicode-normalization/compare/v0.1.13...v0.1.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-12 16:18:48 +00:00
dependabot-preview[bot]
47d2421e39 build(deps): bump once_cell from 1.5.1 to 1.5.2
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.5.1 to 1.5.2.
- [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.5.1...v1.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-12 14:02:38 +00:00
dependabot-preview[bot]
04419065a3 build(deps): bump once_cell from 1.5.0 to 1.5.1
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.5.0 to 1.5.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.5.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-11 11:19:21 +00:00
Rob Bradford
ca60adda70 vmm: Add support for sending and receiving migration if VM is paused
This is tested by:

Source VMM:

target/debug/cloud-hypervisor --kernel ~/src/linux/vmlinux \
--pmem file=~/workloads/focal.raw --cpus boot=1 \
--memory size=2048M \
--cmdline"root=/dev/pmem0p1 console=ttyS0" --serial tty --console off \
--api-socket=/tmp/api1 -v

Destination VMM:

target/debug/cloud-hypervisor --api-socket=/tmp/api2 -v

And the following commands:

target/debug/ch-remote --api-socket=/tmp/api1 pause
target/debug/ch-remote --api-socket=/tmp/api2 receive-migration unix:/tmp/foo &
target/debug/ch-remote --api-socket=/tmp/api1 send-migration unix:/tmp/foo
target/debug/ch-remote --api-socket=/tmp/api2 resume

The VM is then responsive on the destination VMM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-11 11:07:24 +01:00
Rob Bradford
dfe2dadb3e vmm: memory_manager: Make the snapshot source directory an Option
This allows the code to be reused when creating the VM from a snapshot
when doing VM migration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-11 11:07:24 +01:00
Rob Bradford
523029449e bin: ch-remote: Add support for receive/send migration commands
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-11 11:07:24 +01:00
Rob Bradford
7ac764518c vmm: api: Implement API support for migration
Add API entry points with stub implementation for sending and receiving
a VM from one VMM to another.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-11 11:07:24 +01:00
Rob Bradford
aa98589bb4 vm-migration: Add protocol documentation and data structures
Add the documentation and basic implementation for supporting migration.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-11 11:07:24 +01:00
dependabot-preview[bot]
ca5f1d6de8 build(deps): bump once_cell from 1.4.1 to 1.5.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.4.1 to 1.5.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.4.1...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-11 08:47:02 +00:00
Julio Montes
270631922d vmm: openapi: remove omitempty json tag
Due to a known limitation in OpenAPITools/openapi-generator tool,
it's impossible to send go zero types, like false and 0 to
cloud-hypervisor because `omitempty` is added if a field is not
required.
Set cache_size, dax, num_queues and queue_size as required to remove
`omitempty` from the json tag.

fixes #1961

Signed-off-by: Julio Montes <julio.montes@intel.com>
2020-11-10 19:09:17 +01:00
Muminul Islam
465ef3f7ad scripts: dev_cli: Export volumes for windows test as well
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-11-09 14:58:26 -08:00
dependabot-preview[bot]
50e0423304 build(deps): bump futures from 0.3.7 to 0.3.8
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.7 to 0.3.8.
- [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.7...0.3.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-09 21:50:00 +00:00
Anatol Belski
906a1eb18d doc: Add notes to compile OVMF with legacy support
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2020-11-09 17:41:03 +01:00
Rob Bradford
7b77f1ef90 vmm: Remove self-spawning functionality for vhost-user-{net,block}
This also removes the need to lookup up the "exe" symlink for finding
the VMM executable path.

Fixes: #1925

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-09 00:16:15 +01:00
Rob Bradford
0005d11e32 vmm: config: Require a socket when using vhost-user
With self-spawning being removed both parameters are now required.

Fixes: #1925

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-09 00:16:15 +01:00
Rob Bradford
ec84abc5c7 tests: Remove self spawning integration tests
Fixes: #1925

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-11-09 00:16:15 +01:00
dependabot-preview[bot]
2ea0d8eb91 build(deps): bump cc from 1.0.61 to 1.0.62
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.61 to 1.0.62.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.61...1.0.62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-06 22:50:38 +00:00
dependabot-preview[bot]
6a25aaf6b9 build(deps): bump url from 2.1.1 to 2.2.0
Bumps [url](https://github.com/servo/rust-url) from 2.1.1 to 2.2.0.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.1.1...v2.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-06 09:06:10 +00:00
dependabot-preview[bot]
1b6b45bf2f build(deps): bump thiserror from 1.0.21 to 1.0.22
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.21 to 1.0.22.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.21...1.0.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-04 16:24:46 +00:00
dependabot-preview[bot]
ecda97f759 build(deps): bump micro_http from 40309b7 to 59ab644
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `40309b7` to `59ab644`.
- [Release notes](https://github.com/firecracker-microvm/micro-http/releases)
- [Commits](40309b72ee...59ab64440a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-04 16:01:50 +00:00
Michael Zhao
5566992422 scripts: Fix the failure to fetch latest guest kernel code on AArch64
The integration script failed to obtain the new guest kernel commit when
the code folder had been existing on CI machine.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-11-04 16:00:12 +00:00
dependabot-preview[bot]
cc637f12f6 build(deps): bump aho-corasick from 0.7.14 to 0.7.15
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 0.7.14 to 0.7.15.
- [Release notes](https://github.com/BurntSushi/aho-corasick/releases)
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/0.7.14...0.7.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-04 15:15:55 +00:00
dependabot-preview[bot]
592babaadd build(deps): bump ppv-lite86 from 0.2.9 to 0.2.10
Bumps [ppv-lite86](https://github.com/cryptocorrosion/cryptocorrosion) from 0.2.9 to 0.2.10.
- [Release notes](https://github.com/cryptocorrosion/cryptocorrosion/releases)
- [Commits](https://github.com/cryptocorrosion/cryptocorrosion/compare/ppv-lite86-0.2.9...ppv-lite86-0.2.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 08:31:08 +00:00
dependabot-preview[bot]
138a8156c8 build(deps): bump blake2b_simd from 0.5.10 to 0.5.11
Bumps [blake2b_simd](https://github.com/oconnor663/blake2_simd) from 0.5.10 to 0.5.11.
- [Release notes](https://github.com/oconnor663/blake2_simd/releases)
- [Commits](https://github.com/oconnor663/blake2_simd/compare/0.5.10...0.5.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 08:30:59 +00:00
dependabot-preview[bot]
7a008e66a4 build(deps): bump anyhow from 1.0.33 to 1.0.34
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.33...1.0.34)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 08:30:50 +00:00
Michael Zhao
164d481683 tests: Enable watchdog test case on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-11-02 08:19:07 +00:00
Michael Zhao
52f60188ca resources: Enable watchdog in guest driver
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-11-02 08:19:07 +00:00
dependabot-preview[bot]
8cb29af712 build(deps): bump regex from 1.4.1 to 1.4.2
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.1 to 1.4.2.
- [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.4.1...1.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-02 08:17:11 +00:00
dependabot-preview[bot]
60768a84c5 build(deps): bump signal-hook-registry from 1.2.1 to 1.2.2
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.2.1 to 1.2.2.
- [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-11-01 09:24:50 +00:00
dependabot-preview[bot]
3266eb7cce build(deps): bump backtrace from 0.3.53 to 0.3.54
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.53 to 0.3.54.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.53...0.3.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-31 07:42:56 +00:00
Muminul Islam
c9a28312a9 rpm: Fix vhost_user_block binary name and use latest tag
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-10-31 07:42:39 +00:00
Michael Zhao
a278704ae0 tests: Enable reboot test case on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-30 17:14:44 +00:00
Michael Zhao
093a581ee1 vmm: Implement VM rebooting on AArch64
The logic to handle AArch64 system event was: SHUTDOWN and RESET were
all treated as RESET.

Now we handle them differently:
- RESET event will trigger Vmm::vm_reboot(),
- SHUTDOWN event will trigger Vmm::vm_shutdown().

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-30 17:14:44 +00:00
Michael Zhao
69394c9c35 vmm: Handle hypervisor VCPU run result from Vcpu to VcpuManager
Now Vcpu::run() returns a boolean value to VcpuManager, indicating
whether the VM is going to reboot (false) or just continue (true).
Moving the handling of hypervisor VCPU run result from Vcpu to
VcpuManager gives us the flexibility to handle more scenarios like
shutting down on AArch64.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-30 17:14:44 +00:00
Michael Zhao
0f5e5d9e6d tests: Fix some build warnings in integration test on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-30 17:14:12 +00:00
Michael Zhao
4606f0f28a tests: Make migration test case X86 only
Set the test case test_snapshot_restore X86 only, instead of excluding
it from test command line.

The command line option was added because we used to support migration
with Virtio-MMIO, but not Virtio-PCI.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-30 17:14:12 +00:00
Rob Bradford
cb88ceeae8 vmm: memory_manager: Move the restoration of guest memory later
Rather than filling the guest memory from a file at the point of the the
guest memory region being created instead fill from the file later. This
simplifies the region creation code but also adds flexibility for
sourcing the guest memory from a source other than an on disk file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-30 12:31:47 +01:00
Rob Bradford
7dcd3aff05 build, release-notes.md: Document 0.11.0 release
Update release notes and version number for the new release.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-29 17:36:02 +00:00
Bo Chen
8c268e351c tests: Port more tests to use wait_vm_boot
Tests not ported include 1) the ones that start guest VMs without
network (e.g. test_net_hotplug, test_initramfs), 2) test_vfio that
involves l2 guest. Also, some tests that use bionic guest image are
given extended timeout (120s) for 'wait_vm_boot'.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-29 15:30:17 +00:00
Bo Chen
a79f058a90 tests: Accept custom timeout for wait_vm_boot
This allows known slow tests to have a longer/customized timeout while
keeping the default timeout short.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-29 15:30:17 +00:00
Bo Chen
26783fea89 tests: Wait explicitly for vm shutdown w/ the 'wait-timeout' crate
Instead of waiting blindly with fixed amount of sleeping time, we can
use the `wait-timeout` crate to explicitly wait VM shutdown (with a
timeout). It can reduces the execution time of some tests
substantially. Also, this patch increases the `shutdown` timeout for
'test_reboot', which should fix the recent sporadic failures on this
test.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-29 15:30:17 +00:00
Bo Chen
cd1c2ed31e build: Add the 'v' prefix when using the crate version
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-29 08:19:25 -07:00
dependabot-preview[bot]
b947320feb build(deps): bump memchr from 2.3.3 to 2.3.4
Bumps [memchr](https://github.com/BurntSushi/rust-memchr) from 2.3.3 to 2.3.4.
- [Release notes](https://github.com/BurntSushi/rust-memchr/releases)
- [Commits](https://github.com/BurntSushi/rust-memchr/compare/2.3.3...2.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-29 09:24:32 +00:00
Rob Bradford
d54544046c build: Use stable virtio-fs QEMU branch
Address build failure from activity in the development virtio-fs branch
by using the stable fork.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-29 08:52:25 +00:00
Bo Chen
8c92d1dbdc tests: Wait explicitly for the guest vm to boot
Instead of blindly waiting for 20-40s for the guest VM to boot, this
patch waits the notification from the guest VM explicitly by using a
simple TcpListener on the host and a custom systemd service in the
guest.

This patch also ported few tests to use this new machanism, while more
tests are to be ported.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-28 11:27:25 -07:00
dependabot-preview[bot]
cc67a05474 build(deps): bump proc-macro-hack from 0.5.18 to 0.5.19
Bumps [proc-macro-hack](https://github.com/dtolnay/proc-macro-hack) from 0.5.18 to 0.5.19.
- [Release notes](https://github.com/dtolnay/proc-macro-hack/releases)
- [Commits](https://github.com/dtolnay/proc-macro-hack/compare/0.5.18...0.5.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-28 08:04:11 +00:00
Rob Bradford
21db6f53c8 vmm: memory_manager: Write all guest region to disk
As a mirror of bdbea19e23 which ensured
that GuestMemoryMmap::read_exact_from() was used to read all the file to
the region ensure that all the guest memory region is written to disk.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 12:11:31 -07:00
Rob Bradford
be1b6bc1e1 main: Remove API socket when exiting
When exiting remove the API socket from the filesystem.

Fixes: #1241

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 13:27:23 +00:00
Rob Bradford
c22b788b47 main: Simplify error and return handling in start_vmm
Use a Result<> type with an error to simplify the code in start_vmm().
This will also make it easier to add cleanup funtionality.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 13:27:23 +00:00
Rob Bradford
dfd21cbfc5 vmm: Use thiserror/anyhow for vmm::Error
This gives a nicer user experience and this error can now be used as the
source for other errors based off this.

See: #1910

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 13:27:23 +00:00
Rob Bradford
6d4656c68f virtio-devices: seccomp_filters: Add fsync to block io_uring filter
This is required when booting with hypervisor-fw.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 10:53:54 +00:00
Rob Bradford
338521c700 build: Enable io_uring feature by default
Now that we that our CI is running with a kernel that is new enough to
support io_uring we can turn this feature on by default.

See: #1561

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-27 10:53:54 +00:00
Muminul Islam
2e1866a5db scripts: dev_cli: Add an option to dev_cli to export volumes
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-10-27 09:52:35 +00:00
Rob Bradford
8bd3fdea8f build: Move on-demand workers from bionic to groovy
This is an interim step to be able to test io_uring on our CI system.

See: #1561

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-26 14:27:20 -07:00
dependabot-preview[bot]
f0d0d8ccaf build(deps): bump libc from 0.2.79 to 0.2.80
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.79 to 0.2.80.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.79...0.2.80)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-26 09:31:03 +00:00
dependabot-preview[bot]
0415146018 build(deps): bump syn from 1.0.46 to 1.0.48
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.46 to 1.0.48.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.46...1.0.48)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-24 21:58:39 +00:00
dependabot-preview[bot]
499fbd0367 build(deps): bump futures from 0.3.6 to 0.3.7
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.6 to 0.3.7.
- [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.6...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-24 00:08:41 +00:00
dependabot-preview[bot]
e70674943f build(deps): bump futures-sink from 0.3.6 to 0.3.7
Bumps [futures-sink](https://github.com/rust-lang/futures-rs) from 0.3.6 to 0.3.7.
- [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.6...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-23 20:00:07 +00:00
Sebastien Boeuf
7e127df415 vmm: memory_manager: Replace 'ext_region' by 'saved_region'
Any occurrence of of a variable containing `ext_region` is replaced with
the less confusing name `saved_region`. The point is to clearly identify
the memory regions that might have been saved during a snapshot, while
the `ext` standing for `external` was pretty unclear.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-23 21:59:52 +02:00
Sebastien Boeuf
c0e8e5b53f vmm: memory_manager: Replace 'backing_file' variable names
In the context of saving the memory regions content through snapshot,
using the term "backing file" brings confusion with the actual backing
file that might back the memory mapping.

To avoid such conflicting naming, the 'backing_file' field from the
MemoryRegion structure gets replaced with 'content', as this is
designating the potential file containing the memory region data.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-23 21:59:52 +02:00
dependabot-preview[bot]
1409b36cad build(deps): bump futures-task from 0.3.6 to 0.3.7
Bumps [futures-task](https://github.com/rust-lang/futures-rs) from 0.3.6 to 0.3.7.
- [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.6...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-23 18:58:11 +00:00
dependabot-preview[bot]
cf067d94c3 build(deps): bump futures-io from 0.3.6 to 0.3.7
Bumps [futures-io](https://github.com/rust-lang/futures-rs) from 0.3.6 to 0.3.7.
- [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.6...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-23 18:57:45 +00:00
dependabot-preview[bot]
c377c1398f build(deps): bump futures-macro from 0.3.6 to 0.3.7
Bumps [futures-macro](https://github.com/rust-lang/futures-rs) from 0.3.6 to 0.3.7.
- [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.6...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-23 18:57:26 +00:00
dependabot-preview[bot]
b64a48adb8 build(deps): bump arrayvec from 0.5.1 to 0.5.2
Bumps [arrayvec](https://github.com/bluss/arrayvec) from 0.5.1 to 0.5.2.
- [Release notes](https://github.com/bluss/arrayvec/releases)
- [Changelog](https://github.com/bluss/arrayvec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bluss/arrayvec/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-23 17:27:29 +00:00
Rob Bradford
bdbea19e23 vmm: memory_manager: Completely fill guest ram from snapshot
Use GuestRegionMmap::read_exact_from() to ensure that all of the file is
read into the guest. This addresses an issue where
GuestRegionMmap::read_from() was only copying the first 2GiB of the
memory and so lead to snapshot-restore was failing when the guest RAM
was 2GiB or greater.

This change also propagates any error from the copying upwards.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-23 17:56:19 +01:00
Rob Bradford
8de3bd728c ch-remote, api_client: Split HTTP/API client code into new crate
Split out the HTTP request handling code from ch-remote into a new
crate which can be used in other places where talking to the API server
by HTTP is necessary.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-23 14:50:36 +02:00
Rob Bradford
654846f433 bin: ch-remote: Generalise functions that work on a HTTP socket
Use the trait for Read/Write rather than specifying the concrete type.
This allows for the functionality to be used for different socket types.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-23 14:50:36 +02:00
Rob Bradford
a60b437f89 vmm: memory_manager: Always copy anonymous RAM regions from disk
When restoring if a region of RAM is backed by anonymous memory i.e from
memfd_create() then copy the contents of the ram from the file that has
been saved to disk.

Previously the code would map the memory from that file into the guest
using a MAP_PRIVATE mapping. This has the effect of
minimising the restore time but provides an issue where the restored VM
does not have the same structure as the snapshotted VM, in particular
memory is backed by files in the restored VM that were anonymously
backed in the original.

This creates two problems:

* The snapshot data is mapped from files for the pages of the guest
  which prevents the storage from being reclaimed.
* When snapshotting again the guest memory will not be correctly saved
  as it will have looked like it was backed by a file so it will not be
  written to disk but as it is a MAP_PRIVATE mapping the changes will
  never be written to the disk again. This results in incorrect
  behaviour.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-23 12:34:32 +02:00
Wei Liu
255dbd29ef tests: factor out windows_auth
This avoid repetition once we have more Windows tests.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-22 18:23:08 +02:00
Wei Liu
2902a96ae6 tests: add Windows guest snapshot test
We also need to restrict the number of test threads to 1 to avoid tests
interfere with each other.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-22 18:23:08 +02:00
Sebastien Boeuf
89b3d7b49b ci: Update integration tests with latest balloon changes
Now that virtio-balloon is not declared as part of the --memory
parameter, the integration tests are updated to keep the correct
behavior.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-22 16:33:16 +02:00
Sebastien Boeuf
f4e391922f vmm: Remove balloon options from --memory parameter
The standalone `--balloon` parameter being fully functional at this
point, we can get rid of the balloon options from the --memory
parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-22 16:33:16 +02:00
Sebastien Boeuf
3594685279 vmm: Move balloon code from MemoryManager to DeviceManager
Now that we have a new dedicated way of asking for a balloon through the
CLI and the REST API, we can move all the balloon code to the device
manager. This allows us to simplify the memory manager, which is already
quite complex.

It also simplifies the behavior of the balloon resizing command. Instead
of providing the expected size for the RAM, which is complex when memory
zones are involved, it now expects the balloon size. This is a much more
straightforward behavior as it really resizes the balloon to the desired
size. Additionally to the simplication, the benefit of this approach is
that it does not need to be tied to the memory manager at all.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-22 16:33:16 +02:00
Sebastien Boeuf
1d479e5e08 vmm: Introduce new --balloon parameter
This introduces a new way of defining the virtio-balloon device. Instead
of going through the --memory parameter, the idea is to consider balloon
as a standalone virtio device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-22 16:33:16 +02:00
dependabot-preview[bot]
ae296d2229 build(deps): bump syn from 1.0.45 to 1.0.46
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.45 to 1.0.46.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.45...1.0.46)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-22 06:53:06 +00:00
dependabot-preview[bot]
555610181b build(deps): bump rustc-demangle from 0.1.17 to 0.1.18
Bumps [rustc-demangle](https://github.com/alexcrichton/rustc-demangle) from 0.1.17 to 0.1.18.
- [Release notes](https://github.com/alexcrichton/rustc-demangle/releases)
- [Commits](https://github.com/alexcrichton/rustc-demangle/compare/0.1.17...0.1.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-21 21:26:57 +00:00
Sebastien Boeuf
28e12e9f3a vmm, hypervisor: Fix snapshot/restore for Windows guest
The snasphot/restore feature is not working because some CPU states are
not properly saved, which means they can't be restored later on.

First thing, we ensure the CPUID is stored so that it can be properly
restored later. The code is simplified and pushed down to the hypervisor
crate.

Second thing, we identify for each vCPU if the Hyper-V SynIC device is
emulated or not. In case it is, that means some specific MSRs will be
set by the guest. These MSRs must be saved in order to properly restore
the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-21 19:11:03 +01:00
Rob Bradford
700f63fad8 tests: Add integration test for virtio-watchdog
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-21 16:02:39 +01:00
Rob Bradford
7ee63134d2 resources: Update Linux config to enable virtio-watchdog
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-21 16:02:39 +01:00
Rob Bradford
885ee9567b vmm: Add support for creating virtio-watchdog
The watchdog device is created through the "--watchdog" parameter. At
most a single watchdog can be created per VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-21 16:02:39 +01:00
Rob Bradford
d2c7645731 virtio-devices: Add simple virtio-watchdog device
This device operates a single virtq. When the driver offers a descriptor
to the device it is interpreted as a "ping" to indicate that the guest
is alive. A periodic timer fires and if when the timer is fired there
has not been a "ping" from the guest then the device will reset the VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-21 16:02:39 +01:00
Rob Bradford
ae375434cd vm-virtio: Add (temporary) number allocation for virtio-watchdog
The next available number for allocation is 35.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-21 16:02:39 +01:00
Michael Zhao
0b0596ef30 arch: Simplify PCI space address handling in AArch64 FDT
Before Virtio-mmio was removed, we passed an optional PCI space address
parameter to AArch64 code for generating FDT. The address is none if the
transport is MMIO.
Now Virtio-PCI is the only option, the parameter is mandatory.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-21 12:20:30 +01:00
Bo Chen
e83d99ab10 tests: Run binary with INFO (-v) level logging
Given the increased amount of output from cloud-hypervisor, this patch
also increased the PIPE_SIZE to 32MB (from 256KB).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-21 08:48:28 +01:00
Bo Chen
e869d2f1bc tests: Print full commandline for better debugging
This patch prints the complete commandline when launching
cloud-hypervisor. It also prints the details of the `ssh` command if
the command is failing.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-21 08:48:28 +01:00
Muminul Islam
5867a1af4a hypervisor: Update Author and license info in the toml file
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-10-20 11:51:32 +01:00
Rob Bradford
e9880ab0d1 vhost_user_fs: seccomp: Propagate error correctly
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-19 21:53:38 -07:00
Rob Bradford
02621c6150 vhost_user_fs: sandbox: Fix clippy errors
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-19 21:53:38 -07:00
Rob Bradford
cf86ca15c2 virtio-devices: vsock: Fix clippy issue in tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-19 21:53:38 -07:00
Rob Bradford
05c79119b9 virtio-devices: pci_common_config: Fix clippy issues in tests
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-19 21:53:38 -07:00
Rob Bradford
c4dc25de09 hypervisor: kvm: aarch64: Trigger reset upon KVM_SYSTEM_EVENT_RESET
This will trigger Vm::vm_reboot to make the VM reboot.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-20 12:46:35 +08:00
Anatol Belski
b076602b87 doc: Add Windows debug instructions
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2020-10-19 16:31:26 +01:00
Michael Zhao
2f2e10ea35 arch: Remove GICv2
Virtio-mmio is removed, now virtio-pci is the only option for virtio
transport layer. We use MSI for PCI device interrupt. While GICv2, the
legacy interrupt controller, doesn't support MSI. So GICv2 is not very
practical for Cloud-hypervisor, we can remove it.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
58474854f2 docs: Remove all virtio-mmio references
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
8b9c9bc97f ci: Remove all references to 'mmio' feature
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
f73a345107 scripts: Remove all references to 'mmio' feature
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
74c08e5669 github-actions: Remove all references to 'mmio' feature
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
cc8b553e86 virtio-devices: Remove mmio and pci differentiation
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
Sebastien Boeuf
af3c6c34c3 vmm: Remove mmio and pci differentiation
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-19 14:58:48 +01:00
pierwill
d2741fdc84 docs: Edit README.md
Add link to issue and fix two typos.

Signed-off-by: pierwill <19642016+pierwill@users.noreply.github.com>
2020-10-19 07:30:13 +02:00
dependabot-preview[bot]
9c6b03927a build(deps): bump syn from 1.0.44 to 1.0.45
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.44 to 1.0.45.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.44...1.0.45)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-19 05:28:55 +00:00
dependabot-preview[bot]
d986f74e27 build(deps): bump serde_derive from 1.0.116 to 1.0.117
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-16 09:02:37 +00:00
dependabot-preview[bot]
fee873e325 build(deps): bump serde from 1.0.116 to 1.0.117
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-16 08:21:05 +00:00
Sebastien Boeuf
7cbd47a71a vmm: Prevent KVM device fd from being unusable from VfioContainer
When shutting down a VM using VFIO, the following error has been
detected:

vfio-ioctls/src/vfio_device.rs:312 -- Could not delete VFIO group:
KvmSetDeviceAttr(Error(9))

After some investigation, it appears the KVM device file descriptor used
for removing a VFIO group was already closed. This is coming from the
Rust sequence of Drop, from the DeviceManager all the way down to
VfioDevice.

Because the DeviceManager owns passthrough_device, which is effectively
a KVM device file descriptor, when the DeviceManager is dropped, the
passthrough_device follows, with the effect of closing the KVM device
file descriptor. Problem is, VfioDevice has not been dropped yet and it
still needs a valid KVM device file descriptor.

That's why the simple way to fix this issue coming from Rust dropping
all resources is to make Linux accountable for it by duplicating the
file descriptor. This way, even when the passthrough_device is dropped,
the KVM file descriptor is closed, but a duplicated instance is still
valid and owned by the VfioContainer.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-15 19:15:28 +02:00
Wei Liu
d667ed0c70 vmm: don't call notify_guest_clock_paused when Hyper-V emulation is on
We turn on that emulation for Windows. Windows does not have KVM's PV
clock, so calling notify_guest_clock_paused results in an error.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-15 19:14:25 +02:00
Sebastien Boeuf
0c967e1aa0 virtio-devices: iommu: Update the list of seccomp filters
While using the virtio-iommu device involving L2 scenario, and tearing
things down all the way from L2 back to L0 exposed some bad syscalls
that were not part of the authorized list.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-14 19:15:09 +02:00
Wei Liu
57f81d0375 scripts: dev_cli: clarify which integration test is running
This makes it easier to grep. No functional change obviously.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-14 14:23:11 +02:00
Rob Bradford
1bae38ceb4 build: Add Jenkinsfile entry for Windows guest
Add one more parallel stage to run Windows guest tests in a dedicated
VM.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-14 11:19:29 +02:00
Rob Bradford
934f992536 scripts: dev_cli: Add support for Windows guest integration tests
Now that we've written Windows integration tests and the associated
script to launch them, this patch enables the support for Windows tests
in dev_cli.sh, so that we can run it in our Cloud Hypervisor container.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-14 11:19:29 +02:00
Rob Bradford
76c04878fa scripts: Add wrapper script to run Windows guest integration tests
Adding a dedicated script to avoid confusion with other Linux
integration tests scripts.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-14 11:19:29 +02:00
Rob Bradford
d598341534 tests: Add Windows guest integration test
This is a new integration test running Windows as a guest with Cloud
Hypervisor. Once the VM is booted, the test connects to the guest
through SSH and shutdown the VM. If this succeeds, this means the VM
was properly booted to userspace and that the network was functional.

Important to note that because this test generates lots of logs, it
requires a large pipe size for both stdout and stderr.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-14 11:19:29 +02:00
Rob Bradford
0eabc00b27 tests: Allow controlling the password for SSH auth
The login details for the Windows VM are different.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-14 11:19:29 +02:00
dependabot-preview[bot]
08ded4b449 build(deps): bump regex from 1.4.0 to 1.4.1
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.0 to 1.4.1.
- [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.4.0...1.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-13 17:41:10 +00:00
Sebastien Boeuf
9d882bc8fe ci: Add integration test for testing maximum physical bits
Introduce a new test that will validate the new option `max_phys_bits`
from the `--cpus` parameter behaves as expected.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-13 18:58:36 +02:00
Sebastien Boeuf
1b9890b807 vmm: cpu: Set CPU physical bits based on user input
If the user specified a maximum physical bits value through the
`max_phys_bits` option from `--cpus` parameter, the guest CPUID
will be patched accordingly to ensure the guest will find the
right amount of physical bits.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-13 18:58:36 +02:00
Sebastien Boeuf
aec88e20d7 vmm: memory_manager: Rely on physical bits for address space size
If the user provided a maximum physical bits value for the vCPUs, the
memory manager will adapt the guest physical address space accordingly
so that devices are not placed further than the specified value.

It's important to note that if the number exceed what is available on
the host, the smaller number will be picked.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-13 18:58:36 +02:00
Sebastien Boeuf
52ad78886c vmm: Introduce new CPU option to set maximum physical bits
In order to let the user choose maximum address space size, this patch
introduces a new option `max_phys_bits` to the `--cpus` parameter.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-13 18:58:36 +02:00
dependabot-preview[bot]
c97824ab76 build(deps): bump pkg-config from 0.3.18 to 0.3.19
Bumps [pkg-config](https://github.com/rust-lang/pkg-config-rs) from 0.3.18 to 0.3.19.
- [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.18...0.3.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-13 13:14:47 +00:00
Bo Chen
e9738a4a49 vmm: Replace the use of 'unchecked_add' with 'checked_add'
The 'GuestAddress::unchecked_add' function has undefined behavior when
an overflow occurs. Its alternative 'checked_add' requires use to handle
the overflow explicitly.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-13 12:09:22 +02:00
Bo Chen
9ab2a34b40 vmm: Remove reserved 256M gaps for hotplugging memory with ACPI
We are now reserving a 256M gap in the guest address space each time
when hotplugging memory with ACPI, which prevents users from hotplugging
memory to the maximum size they requested. We confirm that there is no
need to reserve this gap.

This patch removes the 'reserved gaps'. It also refactors the
'MemoryManager::start_addr' so that it is rounding-up to 128M alignment
when hotplugged memory is allowed with ACPI.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-13 12:09:22 +02:00
Henry Wang
8bf0bac5a7 dev_cli: Fix TARGETARCH inconsistancy
In previous dev_cli.sh, the `uname -m` command will generate
either `x86_64` or `aarch64`, which is inconsistent with the
architectures in the Dockerfile, namely `amd64` and `arm64`.

This will cause some dependancy missing in the docker container
when the docker image is built locally.

This commit fixes this inconsistancy.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-10-13 11:57:01 +02:00
dependabot-preview[bot]
ef1e5fd953 build(deps): bump serde_json from 1.0.58 to 1.0.59
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.58 to 1.0.59.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.58...v1.0.59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-13 06:57:48 +00:00
dependabot-preview[bot]
a06a6e4696 build(deps): bump aho-corasick from 0.7.13 to 0.7.14
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 0.7.13 to 0.7.14.
- [Release notes](https://github.com/BurntSushi/aho-corasick/releases)
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/0.7.13...0.7.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-13 06:57:37 +00:00
Bo Chen
10f380f95b vmm: Report no error when resizing to current memory size with ACPI
We now try to create a ram region of size 0 when the requested memory
size is the same as current memory size. It results in an error of
`GuestMemoryRegion(Mmap(Os { code: 22, kind: InvalidInput, message:
"Invalid argument" }))`. This error is not meaningful to users and we
should not report it.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-12 08:46:38 +02:00
dependabot-preview[bot]
299e83bf43 build(deps): bump regex from 1.3.9 to 1.4.0
Bumps [regex](https://github.com/rust-lang/regex) from 1.3.9 to 1.4.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.3.9...1.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-12 05:17:07 +00:00
dependabot-preview[bot]
54d2298a93 build(deps): bump regex-syntax from 0.6.18 to 0.6.19
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.18 to 0.6.19.
- [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-10-12 05:16:46 +00:00
dependabot-preview[bot]
74627d2de5 build(deps): bump backtrace from 0.3.52 to 0.3.53
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.52 to 0.3.53.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.52...0.3.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-12 05:16:17 +00:00
dependabot-preview[bot]
818dc72e5f build(deps): bump pin-project from 0.4.26 to 0.4.27
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.26 to 0.4.27.
- [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.26...v0.4.27)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-12 05:12:45 +00:00
dependabot-preview[bot]
a4be05ac40 build(deps): bump syn from 1.0.43 to 1.0.44
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.43 to 1.0.44.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.43...1.0.44)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-12 05:12:12 +00:00
Muminul Islam
029a6d8ab9 README: Add steps to install prerequisites
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-10-10 09:52:06 +02:00
Muminul Islam
0f48b61265 README: Syntax cleanups
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2020-10-10 09:52:06 +02:00
Bo Chen
789ee7b3e4 vmm: Support resizing memory up to and including hotplug size
The start address after the hottplugged memory can be the start address of
device area.

Fixes: #1803

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-10 09:51:32 +02:00
dependabot-preview[bot]
f639a8a0fd build(deps): bump syn from 1.0.42 to 1.0.43
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.42 to 1.0.43.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.42...1.0.43)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-09 17:56:30 +00:00
dependabot-preview[bot]
eabfd642e0 build(deps): bump cc from 1.0.60 to 1.0.61
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.60 to 1.0.61.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.60...1.0.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-09 10:23:32 +00:00
dependabot-preview[bot]
ab32375666 build(deps): bump backtrace from 0.3.51 to 0.3.52
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.51 to 0.3.52.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.51...0.3.52)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-09 09:33:32 +00:00
Michael Zhao
2a7b1d78ff build: Fix AArch64 musl cross build failure
A failure appeared in AArch64 musl cross build, after upgrading rust
to v1.47.0. A symbol "strrchr" was missing while linking against
static libfdt.a.

The issue could be caused by missing symbol(s) in new rust toolchain.

This fix pins the rust version in this cross build action to a stable-
enough version. Further upgrade will be done manually after testing.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2020-10-09 10:49:54 +02:00
Rob Bradford
573a5c63cf hypervisor: kvm: Use unstable_sort() to keep clippy happy
"Using a stable sort consumes more memory and cpu cycles. Because values
which compare equal are identical, preserving their relative order (the
guarantee that a stable sort provides) means nothing, while the extra
costs still apply."

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-09 10:49:54 +02:00
Rob Bradford
bb5b9584d2 pci, ch-remote, vmm: Replace simple match blocks with matches!
This is a new clippy check introduced in 1.47 which requires the use of
the matches!() macro for simple match blocks that return a boolean.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-09 10:49:54 +02:00
Sebastien Boeuf
2fac41f154 deps: Patch kvm-ioctls and kvm-bindings crates
Instead of having the hypervisor crate embedding Cloud-Hypervisor forks
from the rust-vmm project, it's more appropriate to leave the rust-vmm
references in the hypervisor crate, and have the root Cargo.toml being
patched.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-08 18:45:42 +02:00
Anatol Belski
095ea049e2 doc: Add UEFI and Windows consumer pages
This changeset extends the documentation with the UEFI and Windows
related info. The focus is on providing consumer with a minimum
necessary and proper piece of the information to enter the features
quickly. While UEFI is a cross platform topic, it is a required
prerequisite for the Windows usage.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2020-10-08 15:45:30 +01:00
dependabot-preview[bot]
ff0d2431d0 build(deps): bump rustc-demangle from 0.1.16 to 0.1.17
Bumps [rustc-demangle](https://github.com/alexcrichton/rustc-demangle) from 0.1.16 to 0.1.17.
- [Release notes](https://github.com/alexcrichton/rustc-demangle/releases)
- [Commits](https://github.com/alexcrichton/rustc-demangle/compare/0.1.16...0.1.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-08 08:59:34 +00:00
Wei Liu
ed1fdd1f7d hypervisor, arch: rename "OneRegister" and relevant code
The OneRegister literally means "one (arbitrary) register". Just call it
"Register" instead. There is no need to inherit KVM's naming scheme in
the hypervisor agnostic code.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-08 08:55:10 +02:00
Wei Liu
9ad14e6b3a aarch64: Add OneReg to the list required extensions for KVM
Without that capability save / restore for aarch64 won't work.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-08 08:54:38 +02:00
Sebastien Boeuf
30e1162d7c virtio: Replace some repr(C, packed) with repr(C)
The goal here is to replace anywhere possible a virtio structure
with a "C, packed" representation by a "C" representation. Some
virtio structures are not expected to be packed, therefore there's
no reason for using the more restrictive "C, packed" representation.

This is important since "packed" representation can still cause
undefined behaviors with Rust 2018.

By removing the need for "packed" representation, we can simplify a
bit of code by deriving the Serialize trait without writing the
implementation ourselves.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-07 22:11:36 +02:00
dependabot-preview[bot]
2333c5e233 build(deps): bump miniz_oxide from 0.4.2 to 0.4.3
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.4.2 to 0.4.3.
- [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.2...0.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-07 15:55:10 +00:00
Sebastien Boeuf
1e3a6cb450 vmm: Simplify some of the io_uring code
Small patch creating a dedicated `block_io_uring_is_supported()`
function for the non-io_uring case, so that we can simplify the
code in the DeviceManager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-07 14:26:49 +02:00
Wei Liu
ac32b1e35f ci: use cargo check to validate building commits
The purpose of that step is to make sure each commit builds. The `check`
command is much faster for that purpose.

On my 32-core machine `cargo check --all` takes around 25 seconds while
`cargo build --all` takes around 35 seconds, so that's quite a bit of
time saving there.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-10-07 14:26:32 +02:00
Sebastien Boeuf
67025948dc ci: Simplify test scripts
Since all unit and integration tests are run inside containers because
they are called from dev_cli.sh, they always run as root. That's why
both unit and integration scripts can be simplified as they don't need
to apply specific capabilities and run cargo tests in a dedicated 'kvm'
group.

Fixes #1683

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-07 14:26:13 +02:00
dependabot-preview[bot]
a5d3604272 build(deps): bump anyhow from 1.0.32 to 1.0.33
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.32...1.0.33)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-07 06:58:14 +00:00
dependabot-preview[bot]
f48398083c build(deps): bump thiserror from 1.0.20 to 1.0.21
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.20...1.0.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-07 05:38:10 +00:00
Rob Bradford
00c0b9e170 devices: ioapic: Tolerate Windows writing zero to version register
Windows will write zero to the IOAPIC version register as part of
probing if the device is there.

Fixes: #1791

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-06 18:13:33 +01:00
Sebastien Boeuf
162789a2d1 ci: Extend virtio-blk hotplug integration test
The existing virtio-blk hotplug test is extended by removing and
re-adding the virtio-blk device. This ensures the unplug/re-plug
feature is properly tested.

Fixes #1809

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 17:22:29 +01:00
Sebastien Boeuf
14163c5200 ci: Extend virtio-net hotplug integration test
The existing virtio-net hotplug test is extended by removing and
re-adding the virtio-net device. This ensures the unplug/re-plug
feature is properly tested.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 17:22:29 +01:00
Rob Bradford
8824da27cb docs: Add documentation about the log levels and when to use them
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-06 16:52:29 +01:00
Rob Bradford
03f7d39ce5 main: Set default log level to warn!() equivalent.
Using our standard configuration and default kernel we trigger no
messages at this level.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-06 16:52:29 +01:00
Sebastien Boeuf
c02a02edfc vmm: Allow unlink syscall for vCPU threads
Without the unlink(2) syscall being allowed, Cloud-Hypervisor crashes
when we remove a virtio-vsock device that has been previously added.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 16:05:59 +01:00
Sebastien Boeuf
cc7a5aca6c ci: Validate each commit can be built
It's important to ensure Cloud-Hypervisor's Git tree is bisectable, and
that's why this commit extends the existing build.yaml Github action.
This will validate that each commit from an incoming pull request can be
built.

Fixes #1808

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 14:28:54 +01:00
Sebastien Boeuf
b33969896b virtio-devices: Rely on vhost crate from Cloud-Hypervisor fork
The Cloud-Hypervisor fork of the vhost crate contains one small
additional patch compared to the rust-vmm upstream version, meant for
increasing the connection timeout.

This patch is intended to be merged in order to check if it helps our CI
fixing the vhost-user-blk flakes that we've been observing recently.

If it fixes it, we'll submit a similar patch upstream and switch back to
the upstream vhost crate, otherwise we'll simply switch back to the
upstream crate, discarding this patch.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 12:56:33 +02:00
Sebastien Boeuf
6aa5e21212 vmm: device_manager: Fix PCI device unplug issues
Because of the PCI refactoring that happened in the previous commit
d793cc4da3, the ability to fully remove a
PCI device was altered.

The refactoring was correct, but the usage of a generic function to pass
the same reference for both BusDevice, PciDevice and Any + Send + Sync
causes the Arc::ptr_eq() function to behave differently than expected,
as it does not match the references later in the code. That means we
were not able to remove the device reference from the MMIO and/or PIO
buses, which was leading to some bus range overlapping error once we
were trying to add a device again to the previous range that should have
been removed.

Fixes #1802

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-06 12:56:17 +02:00
dependabot-preview[bot]
a32bd2fae1 build(deps): bump hermit-abi from 0.1.16 to 0.1.17
Bumps [hermit-abi](https://github.com/hermitcore/libhermit-rs) from 0.1.16 to 0.1.17.
- [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-10-06 09:25:31 +00:00
dependabot-preview[bot]
e553c053af build(deps): bump futures from 0.3.5 to 0.3.6
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.5 to 0.3.6.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-06 06:34:18 +00:00
dependabot-preview[bot]
83f6aa47c9 build(deps): bump futures-core from 0.3.5 to 0.3.6
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.5 to 0.3.6.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-05 20:58:50 +00:00
dependabot-preview[bot]
a4ebb6399a build(deps): bump futures-task from 0.3.5 to 0.3.6
Bumps [futures-task](https://github.com/rust-lang/futures-rs) from 0.3.5 to 0.3.6.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-05 20:58:24 +00:00
dependabot-preview[bot]
0c25b4d9fb build(deps): bump futures-io from 0.3.5 to 0.3.6
Bumps [futures-io](https://github.com/rust-lang/futures-rs) from 0.3.5 to 0.3.6.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-05 20:57:51 +00:00
dependabot-preview[bot]
c2cc26fc82 build(deps): bump libc from 0.2.78 to 0.2.79
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.78 to 0.2.79.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.78...0.2.79)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-05 07:02:05 +00:00
dependabot-preview[bot]
03eebcede2 build(deps): bump pin-project from 0.4.25 to 0.4.26
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.25 to 0.4.26.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/v0.4.26/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v0.4.25...v0.4.26)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-04 21:22:01 +00:00
Praveen Paladugu
71c435ce91 hypervisor, vmm: Introduce VmmOps trait
Run loop in hypervisor needs a callback mechanism to access resources
like guest memory, mmio, pio etc.

VmmOps trait is introduced here, which is implemented by vmm module.
While handling vcpuexits in run loop, this trait allows hypervisor
module access to the above mentioned resources via callbacks.

Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-02 16:42:55 +01:00
Rob Bradford
6a9934d933 build: Fix vm-memory bump build error
A new version of vm-memory was released upstream which resulted in some
components pulling in that new version. Update the version number used
to point to the latest version but continue to use our patched version
due to the fix for #1258

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-02 16:38:02 +01:00
Rob Bradford
2d457ab974 vmm: device_manager: Make PMEM "discard_writes" mode true CoW
The PMEM support has an option called "discard_writes" which when true
will prevent changes to the device from hitting the backing file. This
is trying to be the equivalent of "readonly" support of the block
device.

Previously the memory of the device was marked as KVM_READONLY. This
resulted in a trap when the guest attempted to write to it resulting a
VM exit (and recently a warning). This has a very detrimental effect on
the performance so instead make "discard_writes" truly CoW by mapping
the memory as `PROT_READ | PROT_WRITE` and using `MAP_PRIVATE` to
establish the CoW mapping.

Fixes: #1795

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-02 14:26:15 +02:00
Daniel Verkamp
6eeab85db0 qcow: avoid out-of-bounds access in alloc_refblocks
When all refblocks are consumed, the loop looking for the first free
cluster would access the element at refcounts[refcounts.len()], which is
out of bounds.  Modify the free cluster search loop to check that the
index is in bounds before accessing it.

Tested-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>

(cherry picked from crosvm commit f21572c7187c8beb9c6bfea6446351ae93200d01)

Fixes: #1792

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-02 09:43:09 +02:00
Hui Zhu
c75f8b2f89 virtio-balloon: Add memory_actual_size to vm.info to show memory actual size
The virtio-balloon change the memory size is asynchronous.
VirtioBalloonConfig.actual of balloon device show current balloon size.

This commit add memory_actual_size to vm.info to show memory actual size.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-10-01 17:46:30 +02:00
Sebastien Boeuf
9dffc5da5c devices: ioapic: Always retrieve destination field on 8 bits
When the destination mode is physical, the destination field should
only be defined through bits 56-59, as defined in the IOAPIC spec. But
from the APIC specification, the APIC ID is always defined on 8 bits no
matter which destination mode is selected. That's why we always retrieve
the destination field based on bits 56-63.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-01 14:35:38 +01:00
dependabot-preview[bot]
a8c2d70869 build(deps): bump pin-project from 0.4.24 to 0.4.25
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.24 to 0.4.25.
- [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.24...v0.4.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 11:15:43 +00:00
Bo Chen
a070f44a51 build: github: Add a new action to build cargo fuzz
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-01 11:16:35 +01:00
Bo Chen
dda1df0a58 fuzz: Fix the building errors with recent changes
This patch adds two required dependencies to fuzz/Cargo.toml, and fixes
the building error on the 'block' fuzzer.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-10-01 11:16:35 +01:00
Rob Bradford
2c2e7016c7 main: Improve documentation for --kernel
Fixes: #1712

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-10-01 10:08:25 +01:00
Sebastien Boeuf
532b3063be ci: No need to build Docker image locally for arm64
Now that Docker images are automatically generated for both amd64 and
arm64 architectures, there's no need to generate the arm64 image locally
on the ARM CI during a CI run. The image should be available from
DockerHub instead.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-10-01 10:04:32 +01:00
dependabot-preview[bot]
91314e7b6c build(deps): bump serde_json from 1.0.57 to 1.0.58
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.57...v1.0.58)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 08:07:53 +00:00
dependabot-preview[bot]
8851b48ce6 build(deps): bump proc-macro2 from 1.0.23 to 1.0.24
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.23 to 1.0.24.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.23...1.0.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 05:40:28 +00:00
dependabot-preview[bot]
76c3230e08 build(deps): bump libc from 0.2.77 to 0.2.78
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.77 to 0.2.78.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.77...0.2.78)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 05:40:02 +00:00
Rob Bradford
664c3ceda6 vmm: device_manager: Warn that vhost-user self spawning is deprecated
See #1724 for details.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-30 18:32:50 +02:00
Rob Bradford
0a4be7ddf5 vmm: "Cleanly" shutdown on SIGTERM
Write to the exit_evt EventFD which will trigger all the devices and
vCPUs to exit. This is slightly cleaner than just exiting the process as
any temporary files will be removed.

Fixes: #1242

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-30 18:32:16 +02:00
Sebastien Boeuf
8a11ef5ba6 ci: Move back to latest virtiofsd version
This commit moves back to the branch "virtio-fs-dev" from virtiofsd, as
we figured the changes needed to use this branch and the requirements
from the new meson build from QEMU.

It updates the container version to ensure the dev_cli.sh script will
rely on the latest container which contains the needed packages.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-30 13:10:23 +01:00
Sebastien Boeuf
1e5d35d13a resources: Finalize automated generation of the Docker image
By fixing the Dockerfile, we have now finalized the automated generation
of the Docker images for both architectures (amd64 and arm64).

Fixes #953

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-30 10:03:06 +01:00
Rob Bradford
df26b428b1 arch: x86_64: Copy CPU identification string into guest cpuid
This is stored in leaves 0x80000002 to 0x80000004 inclusive.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-30 08:18:08 +01:00
Bo Chen
6d30fe05e4 vmm: openapi: Add the 'iommu' and 'id' option to 'VmAddDevice'
This patch adds the missing the `iommu` and `id` option for
`VmAddDevice` in the openApi yaml to respect the internal data structure
in the code base. Also, setting the `id` explicitly for VFIO device
hotplug is required for VFIO device unplug through openAPI calls.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-30 08:17:44 +01:00
dependabot-preview[bot]
af0c4c1659 build(deps): bump backtrace from 0.3.50 to 0.3.51
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.50 to 0.3.51.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.50...0.3.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-29 20:25:50 +00:00
Julio Montes
668c563dac vmm: openapi: fix integers format
According to openAPI specification [1], the format for `integer` types
can be only `int32` or `int64`, unsigned and 8-bits integers are not
supported.
This patch replaces `uint64` with `int64`, `uint32` with `int32` and
`uint8` with `int32`.

[1]: https://swagger.io/specification/#data-types

Signed-off-by: Julio Montes <julio.montes@intel.com>
2020-09-29 12:55:40 -07:00
Rob Bradford
5a0d3277c8 vmm: vm: Replace \n newline character with \r
This allows the CMD prompt under SAC to be used without affecting getty
on Linux.

Fixes: #1770

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-29 16:10:12 +02:00
Wei Liu
4ef97d8ddb vmm: interrupts: clearly separate MsiInterruptGroup and InterruptRoute
MsiInterruptGroup doesn't need to know the internal field names of
InterruptRoute. Introduce two helper functions to eliminate references
to irq_fd. This is done similarly to the enable and disable helper
functions.

Also drop the pub keyword from InterruptRoute fields. It is not needed
anymore.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-09-29 13:51:35 +02:00
Sebastien Boeuf
db5d42ad41 resources: Fix Dockerfile to support multi-architecture
In order to support both amd64 and arm64, we rely on the TARGETARCH
variable that is passed from the docker buildx command, based on the
platform used to build the container image.

There is no way to rely directly on $(uname -m) to assign a variable
with the correct x86_64 or aarch64 values we're looking for. Both ENV
and ARG don't evaluate the command, which means they see it as a simple
string. Using RUN is the only way to evaluate a command.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-29 09:29:36 +02:00
dependabot-preview[bot]
315cd5a054 build(deps): bump pin-project from 0.4.23 to 0.4.24
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 0.4.23 to 0.4.24.
- [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.23...v0.4.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-28 14:34:47 +00:00
Sebastien Boeuf
77e9fcdebd resources: Update Dockerfile to install missing Python packages
In order to build virtiofsd from the latest build system, the Python
package python3-setuptools is required.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-28 09:28:37 +02:00
Sebastien Boeuf
3534b6932a github: Add a new action to update the Docker image
The idea is to rely on this new Github Action to detect when the
Dockerfile is updated after a push to the master branch on the
repository.

Once triggered, this action builds the Docker image for both
linux/amd64 and linux/arm64 platforms, and updates it directly
on Docker Hub.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-28 08:25:11 +02:00
dependabot-preview[bot]
34dd3b83af build(deps): bump syn from 1.0.41 to 1.0.42
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.41 to 1.0.42.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.41...1.0.42)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-28 05:20:09 +00:00
dependabot-preview[bot]
e105611eb6 build(deps): bump proc-macro2 from 1.0.21 to 1.0.23
Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.21 to 1.0.23.
- [Release notes](https://github.com/alexcrichton/proc-macro2/releases)
- [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.21...1.0.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-28 05:19:46 +00:00
Praveen Paladugu
f10872e706 vmm: fix clippy warnings
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
2020-09-26 14:07:12 +01:00
Praveen Paladugu
4b32252028 hypervisor, vmm: fix clippy warnings
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
2020-09-26 14:07:12 +01:00
Praveen Paladugu
6ebeaa9246 option_parser: fix clippy warnings
Signed-off-by: Praveen Paladugu <prapal@microsoft.com>
2020-09-26 14:07:12 +01:00
Julio Montes
c54452c08a vmm: openapi: fix integers format
According to openAPI specification[1], the format for `integer` types
can be only `int32` or `int64`, unsigned integers are not supported.
This patch replaces `uint64` with `int64`.

[1]: https://swagger.io/specification/#data-types

Signed-off-by: Julio Montes <julio.montes@intel.com>
2020-09-26 14:05:51 +01:00
Rob Bradford
f762bc7573 arch: x86_64: Create MP table after SMBIOS table if space
In order to speed up the Linux boot (so as to avoid it having to scan a
large number of pages) place the MP table directly after the SMBIOS
table if there is sufficient room. The start address of the SMBIOS table
is one of the three (and the largest) location that the MP table can
also be located at.

Before:
[    0.000399] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
[    0.014945] check: Scanning 1 areas for low memory corruption

After:
[    0.000284] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
[    0.000421] found SMP MP-table at [mem 0x000f0090-0x000f009f]

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-25 19:41:24 +02:00
Wei Liu
7e130a65ba vmm: interrupts: adjust set_gsi_routes
There is no point in manually dropping the lock for gsi_msi_routes then
instantly grabbing it again in set_gsi_routes.

Make set_gsi_routes take a reference to the routing hashmap instead.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2020-09-25 17:17:35 +02:00
Hui Zhu
4913acc05e vmm: Add 'balloon' to memory parameters
Add the option 'balloon' to --memory.

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-09-25 17:13:39 +02:00
Sebastien Boeuf
c85e396ce5 vmm: cpu: x86: Enable MTRR feature in CPUID
The MTRR feature was missing from the CPUID, which is causing the guest
to ignore the MTRR settings exposed through dedicated MSRs.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-25 15:03:52 +02:00
Rob Bradford
f4ec915c5d resources: Remove unused PPS features from kernel config
In particular this removes the annoying PPS messages that fill up the
dmesg log.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-25 14:07:41 +02:00
Sebastien Boeuf
ae44e9c076 resources: Reduce x86_64 kernel configuration to fix warnings
Removing the ISA DMA configurations prevents the kernel from accessing
the port I/O 0x87, which was generating the following warning:

WARN:vmm/src/cpu.rs:378 -- Guest PIO read to unregistered address 0x87

Removing the TELCLOCK configuration prevents the kernel from accessing
the port I/O reserved for the memory manager, which was causing the
following warning:

WARN:vmm/src/memory_manager.rs:289 -- Unexpected offset for accessing
memory manager device: 15

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-25 10:22:28 +01:00
Rob Bradford
29b74804e1 main: Improve the error reporting when creating the hypervisor object
The ::new() does very little beyond trying to open the /dev/kvm device
so provide a hint to the user about what has gone wrong.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2020-09-25 11:08:01 +02:00
Bo Chen
1d3c3bc6ec tests: Capture child process stdout/err in 'test_memory_mergeable'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-25 08:40:23 +02:00
Bo Chen
2441798fe4 tests: Resize the pipe size to 256K for capturing child stdout/err
As discussed in #1707, the `vcpu` thread can be stalled when using
`--serial tty`. To workaround that issue, this patch enforces to resize
the pipe size to 256K when we capture the stdout/stderr of the
cloud-hypervisor child process in the integration tests. Note that the
pipe size (256K) is chosen based on the output size of our integration
tests at this point, which may need to be increased in the future.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-25 08:40:23 +02:00
Bo Chen
365b947023 tests: Port test_simple_launch to the new methodology
This is the last test to be ported to the new methodology.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-25 08:40:23 +02:00
Bo Chen
cb2f11724a tests: Port test_reboot to the new methodology
Signed-off-by: Bo Chen <chen.bo@intel.com>
2020-09-25 08:40:23 +02:00
Hui Zhu
d03a48162f balloon.rs: BalloonEpollHandler: Fix wrong error in handle_event
error!("Unknown event for virtio-mem");
This error should be
error!("Unknown event for virtio-balloon");

Signed-off-by: Hui Zhu <teawater@antfin.com>
2020-09-25 08:36:23 +02:00
Sebastien Boeuf
de88bef429 pci: msix: Fix masking/enabling semantics
By looking at Linux kernel boot time, we identified that a lot of time
was spent registering and unregistering IRQ fds to KVM. This is not
efficient and certainly not a wrong behavior from the Linux kernel,
but rather a problem with the Cloud-Hypervisor's implementation of
MSI-X.

The way to fix this issue is by ensuring the initial conditions are
correct, which means the entire MSI-X vector table must be disabled
and masked. Additionally, each vector must be individually masked.

With these correct conditions, Linux won't start masking interrupt
vectors, and later unmask them since they will be seen as masked from
the beginning. This means the OS will simply have to unmask them when
needed, avoiding the extra operation.

Another aspect of this patch is to prevent Cloud-Hypervisor from
enabling (by registering IRQ fd) all vectors when either the global
'mask' or 'enable' bits are set. Instead, we can simply let the mask()
and unmask() operations take care of it if needed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-24 22:29:16 +02:00
Sebastien Boeuf
64351c1f3f build: Update Cargo.lock
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-23 19:03:19 +02:00
Sebastien Boeuf
2eaf1c70c0 vmm: acpi: Advertise the correct PCI bus range
Since Cloud-Hypervisor currently support one single PCI bus, we must
reflect this through the MCFG table, as it advertises the first bus and
the last bus available. In this case both are bus 0.

This patch saves quite some time during guest kernel boot, as it
prevents from checking each bus for available devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-23 19:03:19 +02:00
Sebastien Boeuf
ec56710c9b devices: ioapic: Mask entries by default
When created, the IOAPIC entries should be masked, as it is the guest's
responsibility (FW and/or OS) to unmask them if/when necessary.

This patch saves a full round of port I/O writes from the guest to the
IOAPIC, meant for masking the unmasked entries.

Because they're now masked, the entries are not enabled, which means
they are not connected from a KVM perspective, saving from unneeded
registration/unregistration of the irq fds.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-23 19:03:19 +02:00
Sebastien Boeuf
827810dbd5 ci: Fix virtiofsd build by staying on older branch
While we figure out the details on how to correctly build virtiofsd from
the latest rebase from the branch "virtio-fs-dev" (which now relies on
QEMU's new build system), let's fix the CI by relying on an older branch
which still relies on the previous build system.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-23 17:06:34 +01:00
Henry Wang
c85c1f0d76 ci: AArch64: enable snapshot/restore integration test case
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
961c5f2cb2 vmm: AArch64: enable VM states save/restore for AArch64
The states of GIC should be part of the VM states. This commit
enables the AArch64 VM states save/restore by adding save/restore
of GIC states.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
7c40a78b66 arch: Fix wrong trial of creating GICv3-ITS for non-PCI use cases
Currently for AArch64, the GICv3-ITS is tried to be created first
when PCI is not needed, which is unnecessary. This commit fixes
the problem.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
3ea4a0797d vmm: seccomp: unify AArch64 and x86_64 FTRUNCATE syscall
The definition of libc::SYS_ftruncate on AArch64 is different
from that on x86_64. This commit unifies the previously hard-coded
syscall number for AArch64.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
48544e4e82 vmm: seccomp: whitelist KVM_GET_REG_LIST in seccomp
`KVM_GET_REG_LIST` ioctl is needed in save/restore AArch64 vCPU.
Therefore we whitelist this ioctl in seccomp.

Also this commit unifies the `SYS_FTRUNCATE` syscall for x86_64
and AArch64.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
c6b47d39e0 vmm: refactor vCPU save/restore code in restoring VM
Similarly as the VM booting process, on AArch64 systems,
the vCPUs should be created before the creation of GIC. This
commit refactors the vCPU save/restore code to achieve the
above-mentioned restoring order.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
970a5a410d vmm: decouple vCPU init from configure_vcpus
Since calling `KVM_GET_ONE_REG` before `KVM_VCPU_INIT` will
result in an error: Exec format error (os error 8). This commit
decouples the vCPU init process from `configure_vcpus`. Therefore
in the process of restoring the vCPUs, these vCPUs can be
initialized separately before started.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
47e65cd341 vmm: AArch64: add methods to get saved vCPU states
The construction of `GICR_TYPER` register will need vCPU states.
Therefore this commit adds methods to extract saved vCPU states
from the cpu manager.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
381d0b4372 devices: remove the migration traits for the Gic struct
Unlike x86_64, the "interrupt_controller" in the device manager
for AArch64 is only a `Gic` object that implements the
`InterruptController` to provide the interrupt delivery service.
This is not the real GIC device so that we do not need to save
its states. Also, we do not need to insert it to the device_tree.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
39c9583b48 arch: AArch64: implement save/restore for GICv3
This commit implements the save/restore for GICv3.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
7ddcad1d8b arch: AArch64: add a field gicr_typers for GIC implementations
The value of GIC register `GICR_TYPER` is needed in restoring
the GIC states. This commit adds a field in the GIC device struct
and a method to construct its value.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
dcf6d9d731 device_manager: AArch64: add a field to set/get GIC device entity
In AArch64 systems, the state of GIC device can only be
retrieved from `KVM_GET_DEVICE_ATTR` ioctl. Therefore to implement
saving/restoring the GIC states, we need to make sure that the
GIC object (either the file descriptor or the device itself) can
be extracted after the VM is started.

This commit refactors the code of GIC creation by adding a new
field `gic_device_entity` in device manager and methods to set/get
this field. The GIC object can be therefore saved in the device
manager after calling `arch::configure_system`.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
e7acbcc184 arch: AArch64: support saving RDIST pending tables into guest RAM
This commit adds a function which allows to save RDIST pending
tables to the guest RAM, as well as unit test case for it.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
29ce3076c2 tests: AArch64: Add unit test cases for accessing GIC registers
This commit adds the unit test cases for getting/setting the GIC
distributor, redistributor and ICC registers.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
09d53aad11 arch: AArch64: Porting GIC icc_regs implementation
This commit ports the implementation of GIC ICC registers
from Firecracker.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
bfde6977c8 arch: AArch64: Porting GIC redist_regs implementation
This commit ports the implementation of GIC redistributor registers
from Firecracker.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
f53990c7e7 arch: AArch64: Porting GIC dist_regs implementation
This commit ports the implementation of GIC distributor registers
from Firecracker.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
89a6b63e6e hypervisor: Implement get_device_attr method for AArch64
This commit implements the `get_device_attr` method for the
`KVM_GET_DEVICE_ATTR` ioctl. This ioctl will be used in retrieving
the GIC status.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
b1285cf528 arch: AArch64: move GIC implementations to a separate module
This commit moves the GIC-related code to a separate module.
Therefore the implementation of GIC registers can be introduced
to the new module.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
9dd188a8e8 tests: AArch64: Add unit test cases for vCPU save/restore
Adds 3 more unit test cases for AArch64:

*save_restore_core_regs
*save_restore_system_regs
*get_set_mpstate

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
ffafeda4b6 AArch64: Implement AArch64 vCPU states save/restore
This commit adds methods to save/restore AArch64 vCPU registers,
including:

1. The AArch64 `VcpuKvmState` structure.

2. Some `Vcpu` trait methods of the `KvmVcpu` structure to
enable the save/restore of the AArch64 vCPU states.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Henry Wang
e3d45be6f7 AArch64: Preparation for vCPU save/restore
This commit ports code from firecracker and refactors the existing
AArch64 code as the preparation for implementing save/restore
AArch64 vCPU, including:

1. Modification of `arm64_core_reg` macro to retrive the index of
arm64 core register and implemention of a helper to determine if
a register is a system register.

2. Move some macros and helpers in `arch` crate to the `hypervisor`
crate.

3. Added related unit tests for above functions and macros.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
2020-09-23 12:37:25 +01:00
Josh Soref
5c3f4dbe6f ch: Fix various misspelled words
Misspellings were identified by https://github.com/marketplace/actions/check-spelling
* Initial corrections suggested by Google Sheets
* Additional corrections by Google Chrome auto-suggest
* Some manual corrections

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2020-09-23 08:59:31 +01:00
Jiangbo Wu
22a2a99e5f acpi: Add hotplug numa node
virtio-mem device would use 'VIRTIO_MEM_F_ACPI_PXM' to add memory to NUMA
node, which MUST be existed, otherwise it will be assigned to node id 0,
even if user specify different node id.

According ACPI spec about Memory Affinity Structure, system hardware
supports hot-add memory region using 'Hot Pluggable | Enabled' flags.

Signed-off-by: Jiangbo Wu <jiangbo.wu@intel.com>
2020-09-22 13:11:39 +02:00
Jiangbo Wu
223189c063 mm: Apply zone's property instread of global config
Apply memory zone's property for associated virtio-mem regions.

Signed-off-by: Jiangbo Wu <jiangbo.wu@intel.com>
2020-09-22 09:56:37 +02:00
Jiangbo Wu
80be8ac0dc mm: Apply memory policy for virtio-mem region
Use zone.host_numa_node to create memory zone, so that memory zone
can apply memory policy in according with host numa node ID

Signed-off-by: Jiangbo Wu <jiangbo.wu@intel.com>
2020-09-22 09:56:37 +02:00
dependabot-preview[bot]
097ba3b191 build(deps): bump hermit-abi from 0.1.15 to 0.1.16
Bumps [hermit-abi](https://github.com/hermitcore/libhermit-rs) from 0.1.15 to 0.1.16.
- [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-09-22 06:00:35 +00:00
Sebastien Boeuf
7c346c3844 vmm: Kill vhost-user self-spawned process on failure
If after the creation of the self-spawned backend, the VMM cannot create
the corresponding vhost-user frontend, the VMM must kill the freshly
spawned process in order to ensure the error propagation can happen.

In case the child process would still be around, the VMM cannot return
the error as it waits onto the child to terminate.

This should help us identify when self-spawned failures are caused by a
connection being refused between the VMM and the backend.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2020-09-18 17:26:25 +01:00
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
290 changed files with 59207 additions and 30502 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 }}

44
.github/workflows/build.yaml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Cloud Hypervisor Build
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust:
- stable
- beta
- nightly
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- name: Debug Check (default features)
run: |
git rev-list origin/master..$GITHUB_SHA | xargs -t -I % sh -c 'git checkout %; cargo check --all --target=${{ matrix.target }}'
git checkout $GITHUB_SHA
- name: Build (acpi,kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "acpi,kvm" -- -D warnings
- name: Build (kvm)
run: cargo rustc --bin cloud-hypervisor --no-default-features --features "kvm" -- -D warnings
- name: Release Build (default features)
run: cargo build --all --release --target=${{ matrix.target }}

36
.github/workflows/docker-image.yaml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: Cloud-Hypervisor's Docker image update
on:
push:
branches: master
paths: resources/Dockerfile
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
file: ./resources/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: cloudhypervisor/dev:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

27
.github/workflows/fuzz-build.yaml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Cloud Hypervisor Cargo Fuzz Build
on: [pull_request, create]
jobs:
build:
if: github.event_name == 'pull_request'
name: Cargo Fuzz Build
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- nightly
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
- name: Install Cargo fuzz
run: cargo install -f cargo-fuzz
- name: Cargo Fuzz Build
run: cargo fuzz build

34
.github/workflows/quality-aarch64.yaml vendored Normal file
View File

@@ -0,0 +1,34 @@
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 && mkdir -p 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 (kvm)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: clippy
args: --target=${{ matrix.target }} --no-default-features --features "kvm" -- -D warnings

51
.github/workflows/quality.yaml vendored Normal file
View File

@@ -0,0 +1,51 @@
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,kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,kvm" -- -D warnings
- name: Clippy (all features,mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "common,mshv" -- -D warnings
- name: Clippy (acpi,kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,kvm" -- -D warnings
- name: Clippy (acpi,kvm,tdx)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,kvm,tdx" -- -D warnings
- name: Clippy (kvm)
run: cargo clippy --all --all-targets --no-default-features --tests --features "kvm" -- -D warnings
- name: Clippy (acpi,mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "acpi,mshv" -- -D warnings
- name: Clippy (mshv)
run: cargo clippy --all --all-targets --no-default-features --tests --features "mshv" -- -D warnings
- name: Clippy (integration tests)
run: cargo clippy --all --all-targets --tests --features "integration_tests" -- -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,16 +0,0 @@
language: rust
rust:
- stable
script:
- cargo build --release
deploy:
provider: releases
api_key: $GITHUB_OAUTH_TOKEN
file: target/release/cloud-hypervisor
skip_cleanup: true
draft: true
on:
tags: true

View File

@@ -88,5 +88,5 @@ Fixes #88
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
```
Then, after the correspoding PR is merged, Github will automatically close that issue when parsing the
Then, after the corresponding PR is merged, Github will automatically close that issue when parsing the
[commit message](https://help.github.com/articles/closing-issues-via-commit-messages/).

1553
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +1,89 @@
[package]
name = "cloud-hypervisor"
version = "0.5.0"
version = "0.14.1"
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]
arc-swap = ">=0.4.4"
clap = "2.33.0"
epoll = ">=4.0.1"
lazy_static = "1.4.0"
libc = "0.2.66"
log = { version = "0.4.10", features = ["std"] }
vhost_user_backend = { path = "vhost_user_backend"}
vhost_user_block = { path = "vhost_user_block"}
vhost_user_fs = { path = "vhost_user_fs"}
vhost_user_net = { path = "vhost_user_net"}
virtio-bindings = "0.1.0"
anyhow = "1.0.39"
api_client = { path = "api_client" }
clap = { version = "2.33.3", features = ["wrap_help"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.91"
log = { version = "0.4.14", features = ["std"] }
option_parser = { path = "option_parser" }
seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" }
serde_json = "1.0.64"
signal-hook = "0.3.7"
thiserror = "1.0.24"
vmm = { path = "vmm" }
vm-device = { path = "vm-device" }
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
vmm-sys-util = ">=0.3.1"
vm-virtio = { path = "vm-virtio" }
vmm-sys-util = "0.8.0"
vm-memory = "0.5.0"
[build-dependencies]
clap = { version = "2.33.3", features = ["wrap_help"] }
# List of patched crates
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.4.0", features = ["with-serde", "fam-wrappers"] }
[dev-dependencies]
ssh2 = "0.7.1"
dirs = "2.0.2"
credibility = "0.1.3"
tempdir= "0.3.7"
dirs = "3.0.1"
lazy_static= "1.4.0"
serde_json = ">=1.0.9"
[dependencies.vhost_rs]
path = "vhost_rs"
features = ["vhost-user-slave"]
net_util = { path = "net_util" }
serde_json = "1.0.64"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
[features]
default = ["acpi", "pci", "cmos"]
default = ["acpi", "cmos", "io_uring", "kvm"]
# Common features for all hypervisors
common = ["acpi", "cmos", "fwdebug", "io_uring"]
acpi = ["vmm/acpi"]
pci = ["vmm/pci_support"]
mmio = ["vmm/mmio_support"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
io_uring = ["vmm/io_uring"]
tdx = ["vmm/tdx"]
# Integration tests require a special environment to run in
integration_tests = []
[workspace]
members = [
"arch",
"devices",
"vhost_rs",
"qcow",
"pci",
"vmm",
"vm-virtio",
"vm-device",
"vhost_user_block",
"vhost_user_backend",
"vhost_user_fs",
"vhost_user_net",
"vfio",
"net_util",
"acpi_tables",
"api_client",
"arch",
"arch_gen",
"block_util",
"devices",
"event_monitor",
"hypervisor",
"net_gen",
"net_util",
"option_parser",
"pci",
"qcow",
"vhost_user_backend",
"vhost_user_block",
"vhost_user_net",
"virtio-devices",
"vmm",
"vm-allocator",
"vm-device",
"vm-migration",
"vm-virtio"
]
exclude = ["test_infra"]

246
Jenkinsfile vendored
View File

@@ -1,7 +1,7 @@
pipeline{
agent none
stages {
stage ('Master build') {
stage ('Early checks') {
agent { node { label 'master' } }
stages {
stage ('Check for RFC/WIP builds') {
@@ -14,55 +14,217 @@ pipeline{
}
}
stage ('Cancel older builds') {
when { not { branch 'master' } }
steps {
cancelPreviousBuilds()
}
}
}
}
stage ('Worker build') {
agent { node { label 'bionic' } }
options {
timeout(time: 1, unit: 'HOURS')
stage ('Build') {
parallel {
stage ('Worker build') {
agent { node { label 'groovy' } }
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') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration"
}
}
}
}
stage ('AArch64 worker build') {
agent { node { label 'bionic-arm64' } }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run unit tests') {
steps {
sh "scripts/dev_cli.sh tests --unit"
}
}
stage ('Run integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
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 'groovy' } }
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') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration --libc musl"
}
}
}
}
stage ('Worker build SGX') {
agent { node { label 'bionic-sgx' } }
when { branch 'master' }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run SGX integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-sgx"
}
}
stage ('Run SGX integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-sgx --libc musl"
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage ('Worker build VFIO') {
agent { node { label 'bionic-vfio' } }
when { branch 'master' }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Run VFIO integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-vfio"
}
}
stage ('Run VFIO integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-vfio --libc musl"
}
}
}
post {
always {
sh "sudo chown -R jenkins.jenkins ${WORKSPACE}"
deleteDir()
}
}
}
stage ('Worker build - Windows guest') {
agent { node { label 'groovy-win' } }
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
stage ('Download assets') {
steps {
sh "mkdir ${env.HOME}/workloads"
azureDownload(storageCredentialId: 'ch-image-store',
containerName: 'private-images',
includeFilesPattern: 'OVMF-4b47d0c6c8.fd',
downloadType: 'container',
downloadDirLoc: "${env.HOME}/workloads")
azureDownload(storageCredentialId: 'ch-image-store',
containerName: 'private-images',
includeFilesPattern: 'windows-server-2019.raw',
downloadType: 'container',
downloadDirLoc: "${env.HOME}/workloads")
}
}
stage ('Run Windows guest integration tests') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-windows"
}
}
stage ('Run Windows guest integration tests for musl') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "scripts/dev_cli.sh tests --integration-windows --libc musl"
}
}
}
}
}
stages {
stage ('Checkout') {
steps {
checkout scm
}
}
}
post {
regression {
script {
if (env.BRANCH_NAME == 'master') {
slackSend (color: '#ff0000', message: '"master" branch build is now failing')
}
stage ('Install system packages') {
steps {
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 libcap-ng-dev socat"
sh "sudo snap install docker"
}
}
stage ('Install Rust') {
steps {
sh "nohup curl https://sh.rustup.rs -sSf | sh -s -- -y"
}
}
stage ('Run Cargo tests') {
steps {
sh "scripts/run_cargo_tests.sh"
}
}
stage ('Run OpenAPI tests') {
steps {
sh "scripts/run_openapi_tests.sh"
}
}
stage ('Run unit tests') {
steps {
sh "scripts/run_unit_tests.sh"
}
}
stage ('Run integration tests') {
steps {
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')
}
}
}

195
README.md
View File

@@ -1,35 +1,34 @@
[![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)
* [Device Model](#device-model)
* [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.
@@ -37,27 +36,24 @@ Cloud Hypervisor is implemented in [Rust](https://www.rust-lang.org/) and is bas
### High Level
* KVM and KVM only based
* Minimal emulation
* Low latency
* Low memory footprint
* Low complexity
* High performance
* Small attack surface
* 64-bit support only
* Build time configurable CPU, memory, PCI and NVDIMM hotplug
* Machine to machine migration
- KVM based
- Minimal emulation
- Low latency
- Low memory footprint
- Low complexity
- High performance
- Small attack surface
- 64-bit support only
- 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` architectures. There are some small differences in functionality between the two architectures (see [#1125](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/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
@@ -68,6 +64,23 @@ $ export CLOUDH=$HOME/cloud-hypervisor
$ mkdir $CLOUDH
```
## Install prerequisites
You need to install some prerequisite packages in order to build and test Cloud Hypervisor.
Here, all the steps are based on Ubuntu, for other Linux distributions please replace the
package manager and package name.
```shell
# Install git
$ sudo apt install git
# Install rust tool chain
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install build-essential
$ sudo apt install build-essential
# If you want to build statically linked binary please add musl target
$ rustup target add x86_64-unknown-linux-musl
```
## Clone and build
First you need to clone and build the cloud-hypervisor repo:
@@ -81,6 +94,8 @@ $ cargo build --release
# We need to give the cloud-hypervisor binary the NET_ADMIN capabilities for it to set TAP interfaces up on the host.
$ sudo setcap cap_net_admin+ep ./target/release/cloud-hypervisor
# If you want to build statically linked binary
$ cargo build --release --target=x86_64-unknown-linux-musl --all
$ popd
```
@@ -120,20 +135,20 @@ You can run a guest VM by either using an existing cloud image or booting into y
### Cloud image
`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
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/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/31890/clear/clear-31890-kvm.img.xz
$ unxz clear-31890-kvm.img.xz
$ wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.2.6/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.3.0/hypervisor-fw
$ popd
```
@@ -142,7 +157,7 @@ $ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=clear-31890-kvm.img \
--disk path=focal-server-cloudimg-amd64.raw \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
@@ -156,8 +171,7 @@ Multiple arguments can be given to the `--disk` parameter.
#### Building your kernel
`cloud-hypervisor` also supports direct kernel boot into a `vmlinux` ELF kernel
image. 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.
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:
@@ -165,11 +179,11 @@ To build the kernel:
# Clone the Cloud Hypervisor Linux branch
$ pushd $CLOUDH
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b virtio-fs-virtio-iommu-5.5-rc1 linux-cloud-hypervisor
$ 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-virtio-fs-virtio-iommu-config .config
$ cp $CLOUDH/cloud-hypervisor/resources/linux-config-x86_64 .config
$ make bzImage -j `nproc`
$ popd
```
@@ -178,18 +192,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/31890/clear/clear-31890-kvm.img.xz
$ unxz clear-31890-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
@@ -197,8 +211,8 @@ $ 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 path=clear-31890-kvm.img \
--cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--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=" \
@@ -217,8 +231,8 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \
--serial tty \
--disk path=clear-31890-kvm.img \
--cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \
--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=" \
@@ -227,52 +241,52 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \
# 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-12-12, the following cloud images are supported:
* [Clear Linux](https://download.clearlinux.org/current/) (cloudguest and kvm)
* [Ubuntu Bionic](https://cloud-images.ubuntu.com/bionic/current/) (cloudimg)
* [Ubuntu Eoan](https://cloud-images.ubuntu.com/eoan/current/) (cloudimg)
As of 2020-07-02, the following cloud images are supported:
Direct kernel boot to userspace should work with most rootfs.
- [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
This [document](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/hotplug.md) details how to add devices to
a running VM. Currently only CPU hot plug is supported.
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
Follow this [documentation](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/master/docs/device_model.md).
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
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
@@ -287,6 +301,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.
@@ -298,27 +317,3 @@ etc, are all equal and welcome means of contribution. See the [CONTRIBUTING](CON
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.5.0"

View File

@@ -95,8 +95,7 @@ pub type Byte = u8;
impl Aml for Byte {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x0a); /* BytePrefix */
let mut bytes = vec![0x0a]; /* BytePrefix */
bytes.push(*self);
bytes
}
@@ -106,8 +105,7 @@ pub type Word = u16;
impl Aml for Word {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x0bu8); /* WordPrefix */
let mut bytes = vec![0x0bu8]; /* WordPrefix */
bytes.append(&mut self.to_le_bytes().to_vec());
bytes
}
@@ -117,8 +115,7 @@ pub type DWord = u32;
impl Aml for DWord {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x0c); /* DWordPrefix */
let mut bytes = vec![0x0c]; /* DWordPrefix */
bytes.append(&mut self.to_le_bytes().to_vec());
bytes
}
@@ -128,8 +125,7 @@ pub type QWord = u64;
impl Aml for QWord {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x0e); /* QWordPrefix */
let mut bytes = vec![0x0e]; /* QWordPrefix */
bytes.append(&mut self.to_le_bytes().to_vec());
bytes
}
@@ -147,8 +143,7 @@ impl Aml for Name {
impl Name {
pub fn new(path: Path, inner: &dyn Aml) -> Self {
let mut bytes = Vec::new();
bytes.push(0x08); /* NameOp */
let mut bytes = vec![0x08]; /* NameOp */
bytes.append(&mut path.to_aml_bytes());
bytes.append(&mut inner.to_aml_bytes());
Name { bytes }
@@ -161,8 +156,7 @@ pub struct Package<'a> {
impl<'a> Aml for Package<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(self.children.len() as u8);
let mut bytes = vec![self.children.len() as u8];
for child in &self.children {
bytes.append(&mut child.to_aml_bytes());
}
@@ -239,11 +233,11 @@ fn create_pkg_length(data: &[u8], include_self: bool) -> Vec<u8> {
result
}
pub struct EISAName {
pub struct EisaName {
value: DWord,
}
impl EISAName {
impl EisaName {
pub fn new(name: &str) -> Self {
assert_eq!(name.len(), 7);
@@ -258,11 +252,11 @@ impl EISAName {
| name.chars().nth(6).unwrap().to_digit(16).unwrap())
.swap_bytes();
EISAName { value }
EisaName { value }
}
}
impl Aml for EISAName {
impl Aml for EisaName {
fn to_aml_bytes(&self) -> Vec<u8> {
self.value.to_aml_bytes()
}
@@ -289,8 +283,7 @@ impl Aml for Usize {
}
fn create_aml_string(v: &str) -> Vec<u8> {
let mut data = Vec::new();
data.push(0x0D); /* String Op */
let mut data = vec![0x0D]; /* String Op */
data.extend_from_slice(v.as_bytes());
data.push(0x0); /* NullChar */
data
@@ -374,9 +367,7 @@ impl Memory32Fixed {
impl Aml for Memory32Fixed {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x86); /* Memory32Fixed */
let mut bytes = vec![0x86]; /* Memory32Fixed */
bytes.append(&mut 9u16.to_le_bytes().to_vec());
// 9 bytes of payload
@@ -390,7 +381,7 @@ impl Aml for Memory32Fixed {
#[derive(Copy, Clone)]
enum AddressSpaceType {
Memory,
IO,
Io,
BusNumber,
}
@@ -421,7 +412,7 @@ impl<T> AddressSpace<T> {
pub fn new_io(min: T, max: T) -> Self {
AddressSpace {
r#type: AddressSpaceType::IO,
r#type: AddressSpaceType::Io,
min,
max,
type_flags: 3, /* EntireRange */
@@ -510,16 +501,16 @@ impl Aml for AddressSpace<u64> {
}
}
pub struct IO {
pub struct Io {
min: u16,
max: u16,
alignment: u8,
length: u8,
}
impl IO {
impl Io {
pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
IO {
Io {
min,
max,
alignment,
@@ -528,11 +519,10 @@ impl IO {
}
}
impl Aml for IO {
impl Aml for Io {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
let mut bytes = vec![0x47]; /* Io Port Descriptor */
bytes.push(0x47); /* IO Port Descriptor */
bytes.push(1); /* IODecode16 */
bytes.append(&mut self.min.to_le_bytes().to_vec());
bytes.append(&mut self.max.to_le_bytes().to_vec());
@@ -571,9 +561,7 @@ impl Interrupt {
impl Aml for Interrupt {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x89); /* Extended IRQ Descriptor */
let mut bytes = vec![0x89]; /* Extended IRQ Descriptor */
bytes.append(&mut 6u16.to_le_bytes().to_vec());
let flags = (self.shared as u8) << 3
| (self.active_low as u8) << 2
@@ -699,8 +687,7 @@ impl<'a> Return<'a> {
impl<'a> Aml for Return<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0xa4); /* ReturnOp */
let mut bytes = vec![0xa4]; /* ReturnOp */
bytes.append(&mut self.value.to_aml_bytes());
bytes
}
@@ -788,14 +775,14 @@ impl Aml for Field {
#[derive(Clone, Copy)]
pub enum OpRegionSpace {
SystemMemory,
SystemIO,
PCIConfig,
SystemIo,
PConfig,
EmbeddedControl,
SMBus,
SystemCMOS,
Smbus,
SystemCmos,
PciBarTarget,
IPMI,
GeneralPurposeIO,
Ipmi,
GeneralPurposeIo,
GenericSerialBus,
}
@@ -876,8 +863,7 @@ impl<'a> Equal<'a> {
impl<'a> Aml for Equal<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x93); /* LEqualOp */
let mut bytes = vec![0x93]; /* LEqualOp */
bytes.extend_from_slice(&self.left.to_aml_bytes());
bytes.extend_from_slice(&self.right.to_aml_bytes());
bytes
@@ -897,8 +883,7 @@ impl<'a> LessThan<'a> {
impl<'a> Aml for LessThan<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x95); /* LLessOp */
let mut bytes = vec![0x95]; /* LLessOp */
bytes.extend_from_slice(&self.left.to_aml_bytes());
bytes.extend_from_slice(&self.right.to_aml_bytes());
bytes
@@ -940,8 +925,7 @@ impl<'a> Store<'a> {
impl<'a> Aml for Store<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x70); /* StoreOp */
let mut bytes = vec![0x70]; /* StoreOp */
bytes.extend_from_slice(&self.value.to_aml_bytes());
bytes.extend_from_slice(&self.name.to_aml_bytes());
bytes
@@ -961,8 +945,7 @@ impl Mutex {
impl Aml for Mutex {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x5b); /* ExtOpPrefix */
let mut bytes = vec![0x5b]; /* ExtOpPrefix */
bytes.push(0x01); /* MutexOp */
bytes.extend_from_slice(&self.path.to_aml_bytes());
bytes.push(self.sync_level);
@@ -983,8 +966,7 @@ impl Acquire {
impl Aml for Acquire {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x5b); /* ExtOpPrefix */
let mut bytes = vec![0x5b]; /* ExtOpPrefix */
bytes.push(0x23); /* AcquireOp */
bytes.extend_from_slice(&self.mutex.to_aml_bytes());
bytes.extend_from_slice(&self.timeout.to_le_bytes());
@@ -1004,8 +986,7 @@ impl Release {
impl Aml for Release {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x5b); /* ExtOpPrefix */
let mut bytes = vec![0x5b]; /* ExtOpPrefix */
bytes.push(0x27); /* ReleaseOp */
bytes.extend_from_slice(&self.mutex.to_aml_bytes());
bytes
@@ -1025,8 +1006,7 @@ impl<'a> Notify<'a> {
impl<'a> Aml for Notify<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x86); /* NotifyOp */
let mut bytes = vec![0x86]; /* NotifyOp */
bytes.extend_from_slice(&self.object.to_aml_bytes());
bytes.extend_from_slice(&self.value.to_aml_bytes());
bytes
@@ -1082,8 +1062,7 @@ macro_rules! binary_op {
impl<'a> Aml for $name<'a> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push($opcode); /* Op for the binary operator */
let mut bytes = vec![$opcode]; /* Op for the binary operator */
bytes.extend_from_slice(&self.a.to_aml_bytes());
bytes.extend_from_slice(&self.b.to_aml_bytes());
bytes.extend_from_slice(&self.target.to_aml_bytes());
@@ -1180,8 +1159,7 @@ impl<'a, T> CreateField<'a, T> {
impl<'a> Aml for CreateField<'a, u64> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x8f); /* CreateQWordFieldOp */
let mut bytes = vec![0x8f]; /* CreateQWordFieldOp */
bytes.extend_from_slice(&self.buffer.to_aml_bytes());
bytes.extend_from_slice(&self.offset.to_aml_bytes());
bytes.extend_from_slice(&self.field.to_aml_bytes());
@@ -1191,8 +1169,7 @@ impl<'a> Aml for CreateField<'a, u64> {
impl<'a> Aml for CreateField<'a, u32> {
fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(0x8a); /* CreateDWordFieldOp */
let mut bytes = vec![0x8a]; /* CreateDWordFieldOp */
bytes.extend_from_slice(&self.buffer.to_aml_bytes());
bytes.extend_from_slice(&self.offset.to_aml_bytes());
bytes.extend_from_slice(&self.field.to_aml_bytes());
@@ -1235,12 +1212,12 @@ mod tests {
Device::new(
"_SB_.COM1".into(),
vec![
&Name::new("_HID".into(), &EISAName::new("PNP0501")),
&Name::new("_HID".into(), &EisaName::new("PNP0501")),
&Name::new(
"_CRS".into(),
&ResourceTemplate::new(vec![
&Interrupt::new(true, true, false, false, 4),
&IO::new(0x3f8, 0x3f8, 0, 0x8)
&Io::new(0x3f8, 0x3f8, 0, 0x8)
])
)
]
@@ -1476,7 +1453,7 @@ mod tests {
"_CRS".into(),
&ResourceTemplate::new(vec![
&Interrupt::new(true, true, false, false, 4),
&IO::new(0x3f8, 0x3f8, 0, 0x8)
&Io::new(0x3f8, 0x3f8, 0, 0x8)
])
)
.to_aml_bytes(),
@@ -1519,7 +1496,7 @@ mod tests {
#[test]
fn test_eisa_name() {
assert_eq!(
Name::new("_HID".into(), &EISAName::new("PNP0501")).to_aml_bytes(),
Name::new("_HID".into(), &EisaName::new("PNP0501")).to_aml_bytes(),
[0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01],
)
}
@@ -1665,14 +1642,14 @@ mod tests {
#[test]
fn test_op_region() {
/*
OperationRegion (PRST, SystemIO, 0x0CD8, 0x0C)
OperationRegion (PRST, SystemIo, 0x0CD8, 0x0C)
*/
let op_region_data = [
0x5Bu8, 0x80, 0x50, 0x52, 0x53, 0x54, 0x01, 0x0B, 0xD8, 0x0C, 0x0A, 0x0C,
];
assert_eq!(
OpRegion::new("PRST".into(), OpRegionSpace::SystemIO, 0xcd8, 0xc).to_aml_bytes(),
OpRegion::new("PRST".into(), OpRegionSpace::SystemIo, 0xcd8, 0xc).to_aml_bytes(),
&op_region_data[..]
);
}
@@ -1766,7 +1743,7 @@ mod tests {
Device::new(
"_SB_.MHPC".into(),
vec![
&Name::new("_HID".into(), &EISAName::new("PNP0A06")),
&Name::new("_HID".into(), &EisaName::new("PNP0A06")),
&mutex,
&Method::new(
"TEST".into(),
@@ -1807,7 +1784,7 @@ mod tests {
Device::new(
"_SB_.MHPC".into(),
vec![
&Name::new("_HID".into(), &EISAName::new("PNP0A06")),
&Name::new("_HID".into(), &EisaName::new("PNP0A06")),
&Method::new(
"TEST".into(),
0,
@@ -1848,7 +1825,7 @@ mod tests {
Device::new(
"_SB_.MHPC".into(),
vec![
&Name::new("_HID".into(), &EISAName::new("PNP0A06")),
&Name::new("_HID".into(), &EisaName::new("PNP0A06")),
&Method::new(
"TEST".into(),
0,

View File

@@ -7,7 +7,7 @@ use vm_memory::ByteValued;
#[repr(packed)]
#[derive(Clone, Copy, Default)]
pub struct RSDP {
pub struct Rsdp {
pub signature: [u8; 8],
pub checksum: u8,
pub oem_id: [u8; 6],
@@ -19,17 +19,17 @@ pub struct RSDP {
_reserved: [u8; 3],
}
unsafe impl ByteValued for RSDP {}
unsafe impl ByteValued for Rsdp {}
impl RSDP {
impl Rsdp {
pub fn new(oem_id: [u8; 6], xsdt_addr: u64) -> Self {
let mut rsdp = RSDP {
let mut rsdp = Rsdp {
signature: *b"RSD PTR ",
checksum: 0,
oem_id,
revision: 2,
_rsdt_addr: 0,
length: std::mem::size_of::<RSDP>() as u32,
length: std::mem::size_of::<Rsdp>() as u32,
xsdt_addr,
extended_checksum: 0,
_reserved: [0; 3],
@@ -41,18 +41,18 @@ impl RSDP {
}
pub fn len() -> usize {
std::mem::size_of::<RSDP>()
std::mem::size_of::<Rsdp>()
}
}
#[cfg(test)]
mod tests {
use super::RSDP;
use super::Rsdp;
use vm_memory::bytes::ByteValued;
#[test]
fn test_rsdp() {
let rsdp = RSDP::new(*b"CHYPER", 0xdead_beef);
let rsdp = Rsdp::new(*b"CHYPER", 0xdead_beef);
let sum = rsdp
.as_slice()
.iter()

View File

@@ -13,23 +13,23 @@ 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),
}
}
}
pub struct SDT {
pub struct Sdt {
data: Vec<u8>,
}
#[allow(clippy::len_without_is_empty)]
impl SDT {
impl Sdt {
pub fn new(
signature: [u8; 4],
length: u32,
@@ -53,7 +53,7 @@ impl SDT {
assert_eq!(data.len(), 36);
data.resize(length as usize, 0);
let mut sdt = SDT { data };
let mut sdt = Sdt { data };
sdt.update_checksum();
sdt
@@ -117,11 +117,11 @@ impl SDT {
#[cfg(test)]
mod tests {
use super::SDT;
use super::Sdt;
#[test]
fn test_sdt() {
let mut sdt = SDT::new(*b"TEST", 40, 1, *b"CLOUDH", *b"TESTTEST", 1);
let mut sdt = Sdt::new(*b"TEST", 40, 1, *b"CLOUDH", *b"TESTTEST", 1);
let sum: u8 = sdt
.as_slice()
.iter()

5
api_client/Cargo.toml Normal file
View File

@@ -0,0 +1,5 @@
[package]
name = "api_client"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"

175
api_client/src/lib.rs Normal file
View File

@@ -0,0 +1,175 @@
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use std::fmt;
use std::io::{Read, Write};
#[derive(Debug)]
pub enum Error {
Socket(std::io::Error),
StatusCodeParsing(std::num::ParseIntError),
MissingProtocol,
ContentLengthParsing(std::num::ParseIntError),
ServerResponse(StatusCode, Option<String>),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Error::*;
match self {
Socket(e) => write!(f, "Error writing to or reading from HTTP socket: {}", e),
StatusCodeParsing(e) => write!(f, "Error parsing HTTP status code: {}", e),
MissingProtocol => write!(f, "HTTP output is missing protocol statement"),
ContentLengthParsing(e) => write!(f, "Error parsing HTTP Content-Length field: {}", e),
ServerResponse(s, o) => {
if let Some(o) = o {
write!(f, "Server responded with an error: {:?}: {}", s, o)
} else {
write!(f, "Server responded with an error: {:?}", s)
}
}
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum StatusCode {
Continue,
Ok,
NoContent,
BadRequest,
NotFound,
InternalServerError,
NotImplemented,
Unknown,
}
impl StatusCode {
fn from_raw(code: usize) -> StatusCode {
match code {
100 => StatusCode::Continue,
200 => StatusCode::Ok,
204 => StatusCode::NoContent,
400 => StatusCode::BadRequest,
404 => StatusCode::NotFound,
500 => StatusCode::InternalServerError,
501 => StatusCode::NotImplemented,
_ => StatusCode::Unknown,
}
}
fn parse(code: &str) -> Result<StatusCode, Error> {
Ok(StatusCode::from_raw(
code.trim().parse().map_err(Error::StatusCodeParsing)?,
))
}
fn is_server_error(self) -> bool {
!matches!(
self,
StatusCode::Ok | StatusCode::Continue | StatusCode::NoContent
)
}
}
fn get_header<'a>(res: &'a str, header: &'a str) -> Option<&'a str> {
let header_str = format!("{}: ", header);
if let Some(o) = res.find(&header_str) {
Some(&res[o + header_str.len()..o + res[o..].find('\r').unwrap()])
} else {
None
}
}
fn get_status_code(res: &str) -> Result<StatusCode, Error> {
if let Some(o) = res.find("HTTP/1.1") {
Ok(StatusCode::parse(
&res[o + "HTTP/1.1 ".len()..res[o..].find('\r').unwrap()],
)?)
} else {
Err(Error::MissingProtocol)
}
}
fn parse_http_response(socket: &mut dyn Read) -> Result<Option<String>, Error> {
let mut res = String::new();
let mut body_offset = None;
let mut content_length: Option<usize> = None;
loop {
let mut bytes = vec![0; 256];
let count = socket.read(&mut bytes).map_err(Error::Socket)?;
res.push_str(std::str::from_utf8(&bytes[0..count]).unwrap());
// End of headers
if let Some(o) = res.find("\r\n\r\n") {
body_offset = Some(o + "\r\n\r\n".len());
// With all headers available we can see if there is any body
content_length = if let Some(length) = get_header(&res, "Content-Length") {
Some(length.trim().parse().map_err(Error::ContentLengthParsing)?)
} else {
None
};
if content_length.is_none() {
break;
}
}
if let Some(body_offset) = body_offset {
if let Some(content_length) = content_length {
if res.len() >= content_length + body_offset {
break;
}
}
}
}
let body_string = content_length.and(Some(String::from(&res[body_offset.unwrap()..])));
let status_code = get_status_code(&res)?;
if status_code.is_server_error() {
Err(Error::ServerResponse(status_code, body_string))
} else {
Ok(body_string)
}
}
pub fn simple_api_command<T: Read + Write>(
socket: &mut T,
method: &str,
c: &str,
request_body: Option<&str>,
) -> Result<(), Error> {
socket
.write_all(
format!(
"{} /api/v1/vm.{} HTTP/1.1\r\nHost: localhost\r\nAccept: */*\r\n",
method, c
)
.as_bytes(),
)
.map_err(Error::Socket)?;
if let Some(request_body) = request_body {
socket
.write_all(format!("Content-Length: {}\r\n", request_body.len()).as_bytes())
.map_err(Error::Socket)?;
}
socket.write_all(b"\r\n").map_err(Error::Socket)?;
if let Some(request_body) = request_body {
socket
.write_all(request_body.as_bytes())
.map_err(Error::Socket)?;
}
socket.flush().map_err(Error::Socket)?;
if let Some(body) = parse_http_response(socket)? {
println!("{}", body);
}
Ok(())
}

View File

@@ -5,23 +5,22 @@ authors = ["The Chromium OS Authors"]
[features]
default = []
acpi = ["acpi_tables"]
tdx = []
[dependencies]
byteorder = "1.3.4"
kvm-bindings = "0.2.0"
kvm-ioctls = "0.5.0"
libc = "0.2.60"
acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0"
arch_gen = { path = "../arch_gen" }
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.91"
linux-loader = { version = "0.3.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.14"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
thiserror = "1.0"
vm-memory = { version = "0.5.0", features = ["backend-mmap"] }
vm-migration = { path = "../vm-migration" }
[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.3"

636
arch/src/aarch64/fdt.rs Normal file
View File

@@ -0,0 +1,636 @@
// 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;
// This is a value for uniquely identifying the FDT node containing the gpio controller.
const GPIO_PHANDLE: u32 = 4;
// 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;
// Keys and Buttons
// System Power Down
const KEY_POWER: u32 = 116;
// 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: &(u64, u64),
) -> Result<Vec<u8>> {
// Allocate 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)?;
create_pci_nodes(&mut fdt, pci_space_address.0, pci_space_address.1)?;
// 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_compatibility())?;
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 compatible = b"arm,pl011\0arm,primecell\0";
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!("pl011@{:x}", dev_info.addr()))?;
append_property(fdt, "compatible", compatible)?;
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_gpio_node<T: DeviceInfoForFdt + Clone + Debug>(
fdt: &mut Vec<u8>,
dev_info: &T,
) -> Result<()> {
// PL061 GPIO controller node
let compatible = b"arm,pl061\0arm,primecell\0";
let gpio_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!("pl061@{:x}", dev_info.addr()))?;
append_property(fdt, "compatible", compatible)?;
append_property(fdt, "reg", &gpio_reg_prop)?;
append_property(fdt, "interrupts", &irq)?;
append_property_null(fdt, "gpio-controller")?;
append_property_u32(fdt, "#gpio-cells", 2)?;
append_property_u32(fdt, "clocks", CLOCK_PHANDLE)?;
append_property_string(fdt, "clock-names", "apb_pclk")?;
append_property_u32(fdt, "phandle", GPIO_PHANDLE)?;
append_end_node(fdt)?;
// gpio-keys node
append_begin_node(fdt, "/gpio-keys")?;
append_property_string(fdt, "compatible", "gpio-keys")?;
append_property_u32(fdt, "#size-cells", 0)?;
append_property_u32(fdt, "#address-cells", 1)?;
append_begin_node(fdt, "/gpio-keys/poweroff")?;
append_property_string(fdt, "label", "GPIO Key Poweroff")?;
append_property_u32(fdt, "linux,code", KEY_POWER)?;
let gpios = generate_prop32(&[GPIO_PHANDLE, 3, 0]);
append_property(fdt, "gpios", &gpios)?;
append_end_node(fdt)?;
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::Gpio => create_gpio_node(fdt, info)?,
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(())
}

View File

@@ -0,0 +1,182 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use crate::layout::IRQ_BASE;
use hypervisor::kvm::kvm_bindings::{
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
};
use std::sync::Arc;
/*
Distributor registers as detailed at page 456 from
https://static.docs.arm.com/ihi0069/c/IHI0069C_gic_architecture_specification.pdf.
Address offsets are relative to the Distributor base address defined
by the system memory map. Unless otherwise stated in the register description,
all GIC registers are 32-bits wide.
*/
const GICD_CTLR: u32 = 0x0;
const GICD_STATUSR: u32 = 0x0010;
const GICD_IGROUPR: u32 = 0x0080;
const GICD_ISENABLER: u32 = 0x0100;
const GICD_ICENABLER: u32 = 0x0180;
const GICD_ISPENDR: u32 = 0x0200;
const GICD_ICPENDR: u32 = 0x0280;
const GICD_ISACTIVER: u32 = 0x0300;
const GICD_ICACTIVER: u32 = 0x0380;
const GICD_IPRIORITYR: u32 = 0x0400;
const GICD_ICFGR: u32 = 0x0C00;
const GICD_IROUTER: u32 = 0x6000;
/// This is how we represent the registers of the vgic's distributor.
/// Some of the distributor register )(i.e GICD_STATUSR) are simple
/// registers (i.e they are associated to a 32 bit value).
/// However, there are other registers that have variable lengths since
/// they dedicate some of the 32 bits to some specific interrupt. So, their length
/// depends on the number of interrupts (i.e the ones that are represented as GICD_REG<n>)
/// in the documentation mentioned above.
struct DistReg {
/// Offset from distributor address.
base: u32,
/// Bits per interrupt.
/// Relevant for registers that DO share IRQs.
bpi: u8,
/// Length of the register.
/// Relevant for registers that DO NOT share IRQs.
length: u16,
}
// All or at least the registers we are interested in are 32 bit, so
// we use a constant for size(u32).
const REG_SIZE: u8 = 4;
// Creates a vgic distributor register.
macro_rules! VGIC_DIST_REG {
($base:expr, $bpi:expr, $length:expr) => {
DistReg {
base: $base,
bpi: $bpi,
length: $length,
}
};
}
// List with relevant distributor registers that we will be restoring.
// Order is taken from qemu.
static VGIC_DIST_REGS: &'static [DistReg] = &[
VGIC_DIST_REG!(GICD_STATUSR, 0, 4),
VGIC_DIST_REG!(GICD_ICENABLER, 1, 0),
VGIC_DIST_REG!(GICD_ISENABLER, 1, 0),
VGIC_DIST_REG!(GICD_IGROUPR, 1, 0),
VGIC_DIST_REG!(GICD_IROUTER, 64, 0),
VGIC_DIST_REG!(GICD_ICFGR, 2, 0),
VGIC_DIST_REG!(GICD_ICPENDR, 1, 0),
VGIC_DIST_REG!(GICD_ISPENDR, 1, 0),
VGIC_DIST_REG!(GICD_ICACTIVER, 1, 0),
VGIC_DIST_REG!(GICD_ISACTIVER, 1, 0),
VGIC_DIST_REG!(GICD_IPRIORITYR, 8, 0),
];
fn dist_attr_access(
gic: &Arc<dyn hypervisor::Device>,
offset: u32,
val: &u32,
set: bool,
) -> Result<()> {
let mut gic_dist_attr = kvm_device_attr {
group: KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
attr: offset as u64,
addr: val as *const u32 as u64,
flags: 0,
};
if set {
gic.set_device_attr(&gic_dist_attr)
.map_err(Error::SetDeviceAttribute)?;
} else {
gic.get_device_attr(&mut gic_dist_attr)
.map_err(Error::GetDeviceAttribute)?;
}
Ok(())
}
/// Get the distributor control register.
pub fn read_ctlr(gic: &Arc<dyn hypervisor::Device>) -> Result<u32> {
let val: u32 = 0;
dist_attr_access(gic, GICD_CTLR, &val, false)?;
Ok(val)
}
/// Set the distributor control register.
pub fn write_ctlr(gic: &Arc<dyn hypervisor::Device>, val: u32) -> Result<()> {
dist_attr_access(gic, GICD_CTLR, &val, true)
}
fn get_interrupts_num(gic: &Arc<dyn hypervisor::Device>) -> Result<u32> {
let num_irq = 0;
let mut nr_irqs_attr = kvm_device_attr {
group: KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
attr: 0,
addr: &num_irq as *const u32 as u64,
flags: 0,
};
gic.get_device_attr(&mut nr_irqs_attr)
.map_err(Error::GetDeviceAttribute)?;
Ok(num_irq)
}
fn compute_reg_len(gic: &Arc<dyn hypervisor::Device>, reg: &DistReg, base: u32) -> Result<u32> {
let mut end = base;
let num_irq = get_interrupts_num(gic)?;
if reg.length > 0 {
// This is the single type register (i.e one that is not DIST_X<n>) and for which
// the bpi is 0.
// Look in the kernel for REGISTER_DESC_WITH_LENGTH.
end = base + reg.length as u32;
}
if reg.bpi > 0 {
// This is the type of register that takes into account the number of interrupts
// that the model has. It is also the type of register where
// a register relates to multiple interrupts.
end = base + (reg.bpi as u32 * (num_irq - IRQ_BASE) / 8);
if reg.bpi as u32 * (num_irq - IRQ_BASE) % 8 > 0 {
end += REG_SIZE as u32;
}
}
Ok(end)
}
/// Set distributor registers of the GIC.
pub fn set_dist_regs(gic: &Arc<dyn hypervisor::Device>, state: &[u32]) -> Result<()> {
let mut idx = 0;
for dreg in VGIC_DIST_REGS {
let mut base = dreg.base + REG_SIZE as u32 * dreg.bpi as u32;
let end = compute_reg_len(gic, &dreg, base)?;
while base < end {
let val = state[idx];
dist_attr_access(gic, base, &val, true)?;
idx += 1;
base += REG_SIZE as u32;
}
}
Ok(())
}
/// Get distributor registers of the GIC.
pub fn get_dist_regs(gic: &Arc<dyn hypervisor::Device>) -> Result<Vec<u32>> {
let mut state = Vec::new();
for dreg in VGIC_DIST_REGS {
let mut base = dreg.base + REG_SIZE as u32 * dreg.bpi as u32;
let end = compute_reg_len(gic, &dreg, base)?;
while base < end {
let val: u32 = 0;
dist_attr_access(gic, base, &val, false)?;
state.push(val);
base += REG_SIZE as u32;
}
}
Ok(state)
}

View File

@@ -0,0 +1,275 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
pub mod kvm {
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
use crate::aarch64::gic::icc_regs::{get_icc_regs, set_icc_regs};
use crate::aarch64::gic::kvm::{save_pending_tables, KvmGicDevice};
use crate::aarch64::gic::redist_regs::{get_redist_regs, set_redist_regs};
use crate::aarch64::gic::GicDevice;
use crate::layout;
use anyhow::anyhow;
use hypervisor::kvm::kvm_bindings;
use std::any::Any;
use std::convert::TryInto;
use std::sync::Arc;
use std::{boxed::Box, result};
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
/// Errors thrown while saving/restoring the GICv3.
#[derive(Debug)]
pub enum Error {
/// Error in saving RDIST pending tables into guest RAM.
SavePendingTables(crate::aarch64::gic::Error),
/// Error in saving GIC distributor registers.
SaveDistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor registers.
RestoreDistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC distributor control registers.
SaveDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC distributor control registers.
RestoreDistributorCtrlRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC redistributor registers.
SaveRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC redistributor registers.
RestoreRedistributorRegisters(crate::aarch64::gic::Error),
/// Error in saving GIC CPU interface registers.
SaveIccRegisters(crate::aarch64::gic::Error),
/// Error in restoring GIC CPU interface registers.
RestoreIccRegisters(crate::aarch64::gic::Error),
}
type Result<T> = result::Result<T, Error>;
pub struct KvmGicV3 {
/// The hypervisor agnostic device
device: Arc<dyn hypervisor::Device>,
/// Vector holding values of GICR_TYPER for each vCPU
gicr_typers: Vec<u64>,
/// GIC device properties, to be used for setting up the fdt entry
properties: [u64; 4],
/// Number of CPUs handled by the device
vcpu_count: u64,
}
#[derive(Serialize, Deserialize)]
pub struct Gicv3State {
dist: Vec<u32>,
rdist: Vec<u32>,
icc: Vec<u32>,
// special register that enables interrupts and affinity routing
gicd_ctlr: u32,
}
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
}
/// Save the state of GIC.
fn state(&self, gicr_typers: &[u64]) -> Result<Gicv3State> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(&self.device()).map_err(Error::SavePendingTables)?;
let gicd_ctlr =
read_ctlr(&self.device()).map_err(Error::SaveDistributorCtrlRegisters)?;
let dist_state =
get_dist_regs(&self.device()).map_err(Error::SaveDistributorRegisters)?;
let rdist_state = get_redist_regs(&self.device(), &gicr_typers)
.map_err(Error::SaveRedistributorRegisters)?;
let icc_state =
get_icc_regs(&self.device(), &gicr_typers).map_err(Error::SaveIccRegisters)?;
Ok(Gicv3State {
dist: dist_state,
rdist: rdist_state,
icc: icc_state,
gicd_ctlr,
})
}
/// Restore the state of GIC.
fn set_state(&mut self, gicr_typers: &[u64], state: &Gicv3State) -> Result<()> {
write_ctlr(&self.device(), state.gicd_ctlr)
.map_err(Error::RestoreDistributorCtrlRegisters)?;
set_dist_regs(&self.device(), &state.dist)
.map_err(Error::RestoreDistributorRegisters)?;
set_redist_regs(&self.device(), gicr_typers, &state.rdist)
.map_err(Error::RestoreRedistributorRegisters)?;
set_icc_regs(&self.device(), &gicr_typers, &state.icc)
.map_err(Error::RestoreIccRegisters)?;
Ok(())
}
}
impl GicDevice for KvmGicV3 {
fn device(&self) -> &Arc<dyn hypervisor::Device> {
&self.device
}
fn fdt_compatibility(&self) -> &str {
"arm,gic-v3"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
}
fn device_properties(&self) -> &[u64] {
&self.properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>) {
self.gicr_typers = gicr_typers;
}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
self
}
}
impl KvmGicDevice for KvmGicV3 {
fn version() -> u32 {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice> {
Box::new(KvmGicV3 {
device,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
properties: [
KvmGicV3::get_dist_addr(),
KvmGicV3::get_dist_size(),
KvmGicV3::get_redists_addr(vcpu_count),
KvmGicV3::get_redists_size(vcpu_count),
],
vcpu_count,
})
}
fn init_device_attributes(
_vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GicDevice,
) -> crate::aarch64::gic::Result<()> {
/* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
&KvmGicV3::get_dist_addr() as *const u64 as u64,
0,
)?;
/* Setting up the redistributors' attribute.
We are calculating here the start of the redistributors address. We have one per CPU.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
&KvmGicV3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64,
0,
)?;
Ok(())
}
}
pub const GIC_V3_SNAPSHOT_ID: &str = "gic-v3";
impl Snapshottable for KvmGicV3 {
fn id(&self) -> String {
GIC_V3_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let gicr_typers = self.gicr_typers.clone();
let snapshot = serde_json::to_vec(&self.state(&gicr_typers).unwrap())
.map_err(|e| MigratableError::Snapshot(e.into()))?;
let mut gic_v3_snapshot = Snapshot::new(self.id().as_str());
gic_v3_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id()),
snapshot,
});
Ok(gic_v3_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(gic_v3_section) = snapshot
.snapshot_data
.get(&format!("{}-section", self.id()))
{
let gic_v3_state = match serde_json::from_slice(&gic_v3_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize GICv3 {}",
error
)))
}
};
let gicr_typers = self.gicr_typers.clone();
return self.set_state(&gicr_typers, &gic_v3_state).map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3 state {:?}", e))
});
}
Err(MigratableError::Restore(anyhow!(
"Could not find GICv3 snapshot section"
)))
}
}
impl Pausable for KvmGicV3 {}
impl Transportable for KvmGicV3 {}
impl Migratable for KvmGicV3 {}
}

View File

@@ -0,0 +1,147 @@
// Copyright 2020 ARM Limited
// SPDX-License-Identifier: Apache-2.0
pub mod kvm {
use std::any::Any;
use std::convert::TryInto;
use std::sync::Arc;
use std::{boxed::Box, result};
type Result<T> = result::Result<T, Error>;
use crate::aarch64::gic::gicv3::kvm::KvmGicV3;
use crate::aarch64::gic::kvm::KvmGicDevice;
use crate::aarch64::gic::{Error, GicDevice};
use hypervisor::kvm::kvm_bindings;
pub struct KvmGicV3Its {
/// The hypervisor agnostic device
device: Arc<dyn hypervisor::Device>,
/// Vector holding values of GICR_TYPER for each vCPU
gicr_typers: Vec<u64>,
/// GIC device properties, to be used for setting up the fdt entry
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_compatibility(&self) -> &str {
"arm,gic-v3-its"
}
fn fdt_maint_irq(&self) -> u32 {
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
}
fn msi_properties(&self) -> &[u64] {
&self.msi_properties
}
fn device_properties(&self) -> &[u64] {
&self.gic_properties
}
fn vcpu_count(&self) -> u64 {
self.vcpu_count
}
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>) {
self.gicr_typers = gicr_typers;
}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
self
}
}
impl KvmGicDevice for KvmGicV3Its {
fn version() -> u32 {
KvmGicV3::version()
}
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice> {
Box::new(KvmGicV3Its {
device,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
gic_properties: [
KvmGicV3::get_dist_addr(),
KvmGicV3::get_dist_size(),
KvmGicV3::get_redists_addr(vcpu_count),
KvmGicV3::get_redists_size(vcpu_count),
],
msi_properties: [
KvmGicV3Its::get_msi_addr(vcpu_count),
KvmGicV3Its::get_msi_size(),
],
vcpu_count,
})
}
fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>,
gic_device: &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

@@ -0,0 +1,196 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use hypervisor::kvm::kvm_bindings::{
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, KVM_REG_ARM64_SYSREG_CRM_MASK,
KVM_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_SHIFT,
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP1_MASK,
KVM_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT,
};
use std::sync::Arc;
const KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT: u32 = 32;
const KVM_DEV_ARM_VGIC_V3_MPIDR_MASK: u64 = 0xffffffff << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT as u64;
const ICC_CTLR_EL1_PRIBITS_SHIFT: u32 = 8;
const ICC_CTLR_EL1_PRIBITS_MASK: u32 = 7 << ICC_CTLR_EL1_PRIBITS_SHIFT;
macro_rules! arm64_vgic_sys_reg {
($name: tt, $op0: tt, $op1: tt, $crn: tt, $crm: tt, $op2: expr) => {
const $name: 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);
};
}
macro_rules! SYS_ICC_AP0Rn_EL1 {
($name: tt, $n: tt) => {
arm64_vgic_sys_reg!($name, 3, 0, 12, 8, (4 | $n));
};
}
macro_rules! SYS_ICC_AP1Rn_EL1 {
($name: tt, $n: tt) => {
arm64_vgic_sys_reg!($name, 3, 0, 12, 9, $n);
};
}
arm64_vgic_sys_reg!(SYS_ICC_SRE_EL1, 3, 0, 12, 12, 5);
arm64_vgic_sys_reg!(SYS_ICC_CTLR_EL1, 3, 0, 12, 12, 4);
arm64_vgic_sys_reg!(SYS_ICC_IGRPEN0_EL1, 3, 0, 12, 12, 6);
arm64_vgic_sys_reg!(SYS_ICC_IGRPEN1_EL1, 3, 0, 12, 12, 7);
arm64_vgic_sys_reg!(SYS_ICC_PMR_EL1, 3, 0, 4, 6, 0);
arm64_vgic_sys_reg!(SYS_ICC_BPR0_EL1, 3, 0, 12, 8, 3);
arm64_vgic_sys_reg!(SYS_ICC_BPR1_EL1, 3, 0, 12, 12, 3);
SYS_ICC_AP0Rn_EL1!(SYS_ICC_AP0R0_EL1, 0);
SYS_ICC_AP0Rn_EL1!(SYS_ICC_AP0R1_EL1, 1);
SYS_ICC_AP0Rn_EL1!(SYS_ICC_AP0R2_EL1, 2);
SYS_ICC_AP0Rn_EL1!(SYS_ICC_AP0R3_EL1, 3);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R0_EL1, 0);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R1_EL1, 1);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R2_EL1, 2);
SYS_ICC_AP1Rn_EL1!(SYS_ICC_AP1R3_EL1, 3);
static VGIC_ICC_REGS: &'static [u64] = &[
SYS_ICC_SRE_EL1,
SYS_ICC_CTLR_EL1,
SYS_ICC_IGRPEN0_EL1,
SYS_ICC_IGRPEN1_EL1,
SYS_ICC_PMR_EL1,
SYS_ICC_BPR0_EL1,
SYS_ICC_BPR1_EL1,
SYS_ICC_AP0R0_EL1,
SYS_ICC_AP0R1_EL1,
SYS_ICC_AP0R2_EL1,
SYS_ICC_AP0R3_EL1,
SYS_ICC_AP1R0_EL1,
SYS_ICC_AP1R1_EL1,
SYS_ICC_AP1R2_EL1,
SYS_ICC_AP1R3_EL1,
];
fn icc_attr_access(
gic: &Arc<dyn hypervisor::Device>,
offset: u64,
typer: u64,
val: &u32,
set: bool,
) -> Result<()> {
let mut gic_icc_attr = kvm_device_attr {
group: KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
attr: ((typer & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) | offset), // this needs the mpidr
addr: val as *const u32 as u64,
flags: 0,
};
if set {
#[allow(clippy::unnecessary_mut_passed)]
gic.set_device_attr(&mut gic_icc_attr)
.map_err(Error::SetDeviceAttribute)?;
} else {
gic.get_device_attr(&mut gic_icc_attr)
.map_err(Error::GetDeviceAttribute)?;
}
Ok(())
}
/// Get ICC registers.
pub fn get_icc_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
let mut state: Vec<u32> = Vec::new();
// We need this for the ICC_AP<m>R<n>_EL1 registers.
let mut num_priority_bits = 0;
for ix in gicr_typer {
let i = *ix;
for icc_offset in VGIC_ICC_REGS {
let val = 0;
if *icc_offset == SYS_ICC_CTLR_EL1 {
// calculate priority bits by reading the ctrl_el1 register.
icc_attr_access(gic, *icc_offset, i, &val, false)?;
// The priority bits are found in the ICC_CTLR_EL1 register (bits from 10:8).
// See page 194 from https://static.docs.arm.com/ihi0069/c/IHI0069C_gic_
// architecture_specification.pdf.
// Citation:
// "Priority bits. Read-only and writes are ignored. The number of priority bits
// implemented, minus one."
num_priority_bits =
((val & ICC_CTLR_EL1_PRIBITS_MASK) >> ICC_CTLR_EL1_PRIBITS_SHIFT) + 1;
state.push(val);
}
// As per ARMv8 documentation: https://static.docs.arm.com/ihi0069/c/IHI0069C_
// gic_architecture_specification.pdf
// page 178,
// ICC_AP0R1_EL1 is only implemented in implementations that support 6 or more bits of
// priority.
// ICC_AP0R2_EL1 and ICC_AP0R3_EL1 are only implemented in implementations that support
// 7 bits of priority.
else if *icc_offset == SYS_ICC_AP0R1_EL1 || *icc_offset == SYS_ICC_AP1R1_EL1 {
if num_priority_bits >= 6 {
icc_attr_access(gic, *icc_offset, i, &val, false)?;
state.push(val);
}
} else if *icc_offset == SYS_ICC_AP0R2_EL1
|| *icc_offset == SYS_ICC_AP0R3_EL1
|| *icc_offset == SYS_ICC_AP1R2_EL1
|| *icc_offset == SYS_ICC_AP1R3_EL1
{
if num_priority_bits == 7 {
icc_attr_access(gic, *icc_offset, i, &val, false)?;
state.push(val);
}
} else {
icc_attr_access(gic, *icc_offset, i, &val, false)?;
state.push(val);
}
}
}
Ok(state)
}
/// Set ICC registers.
pub fn set_icc_regs(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &[u32],
) -> Result<()> {
let mut num_priority_bits = 0;
let mut idx = 0;
for ix in gicr_typer {
let i = *ix;
for icc_offset in VGIC_ICC_REGS {
if *icc_offset == SYS_ICC_CTLR_EL1 {
let ctrl_el1 = state[idx];
num_priority_bits =
((ctrl_el1 & ICC_CTLR_EL1_PRIBITS_MASK) >> ICC_CTLR_EL1_PRIBITS_SHIFT) + 1;
}
if *icc_offset == SYS_ICC_AP0R1_EL1 || *icc_offset == SYS_ICC_AP1R1_EL1 {
if num_priority_bits >= 6 {
icc_attr_access(gic, *icc_offset, i, &state[idx], true)?;
idx += 1;
}
continue;
}
if *icc_offset == SYS_ICC_AP0R2_EL1
|| *icc_offset == SYS_ICC_AP0R3_EL1
|| *icc_offset == SYS_ICC_AP1R2_EL1
|| *icc_offset == SYS_ICC_AP1R3_EL1
{
if num_priority_bits == 7 {
icc_attr_access(gic, *icc_offset, i, &state[idx], true)?;
idx += 1;
}
continue;
}
icc_attr_access(gic, *icc_offset, i, &state[idx], true)?;
idx += 1;
}
}
Ok(())
}

211
arch/src/aarch64/gic/mod.rs Normal file
View File

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

View File

@@ -0,0 +1,179 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::{Error, Result};
use hypervisor::kvm::kvm_bindings::{kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS};
use std::sync::Arc;
// Relevant redistributor registers that we want to save/restore.
const GICR_CTLR: u32 = 0x0000;
const GICR_STATUSR: u32 = 0x0010;
const GICR_WAKER: u32 = 0x0014;
const GICR_PROPBASER: u32 = 0x0070;
const GICR_PENDBASER: u32 = 0x0078;
/* SGI and PPI Redistributor registers, offsets from RD_base */
/*
* Redistributor frame offsets from RD_base which is actually SZ_
*/
const GICR_SGI_OFFSET: u32 = 0x0001_0000;
const GICR_IGROUPR0: u32 = GICR_SGI_OFFSET + 0x0080;
const GICR_ICENABLER0: u32 = GICR_SGI_OFFSET + 0x0180;
const GICR_ISENABLER0: u32 = GICR_SGI_OFFSET + 0x0100;
const GICR_ISPENDR0: u32 = GICR_SGI_OFFSET + 0x0200;
const GICR_ICPENDR0: u32 = GICR_SGI_OFFSET + 0x0280;
const GICR_ISACTIVER0: u32 = GICR_SGI_OFFSET + 0x0300;
const GICR_ICACTIVER0: u32 = GICR_SGI_OFFSET + 0x0380;
const GICR_IPRIORITYR0: u32 = GICR_SGI_OFFSET + 0x0400;
const GICR_ICFGR0: u32 = GICR_SGI_OFFSET + 0x0C00;
const KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT: u32 = 32;
const KVM_DEV_ARM_VGIC_V3_MPIDR_MASK: u64 = 0xffffffff << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT as u64;
/// This is how we represent the registers of a distributor.
/// It is relrvant their offset from the base address of the
/// distributor.
/// Each register has a different number
/// of bits_per_irq and is therefore variable length.
/// First 32 interrupts (0-32) are private to each CPU (SGIs and PPIs).
/// and so we save the first irq to identify between the type of the interrupt
/// that the respective register deals with.
struct RdistReg {
/// Offset from distributor address.
base: u32,
/// Length of the register.
length: u8,
}
// All or at least the registers we are interested in are 32 bit, so
// we use a constant for size(u32).
const REG_SIZE: u8 = 4;
// Creates a vgic redistributor register.
macro_rules! VGIC_RDIST_REG {
($base:expr, $len:expr) => {
RdistReg {
base: $base,
length: $len,
}
};
}
// List with relevant distributor registers that we will be restoring.
static VGIC_RDIST_REGS: &'static [RdistReg] = &[
VGIC_RDIST_REG!(GICR_CTLR, 4),
VGIC_RDIST_REG!(GICR_STATUSR, 4),
VGIC_RDIST_REG!(GICR_WAKER, 4),
VGIC_RDIST_REG!(GICR_PROPBASER, 8),
VGIC_RDIST_REG!(GICR_PENDBASER, 8),
];
// List with relevant distributor registers that we will be restoring.
static VGIC_SGI_REGS: &'static [RdistReg] = &[
VGIC_RDIST_REG!(GICR_IGROUPR0, 4),
VGIC_RDIST_REG!(GICR_ICENABLER0, 4),
VGIC_RDIST_REG!(GICR_ISENABLER0, 4),
VGIC_RDIST_REG!(GICR_ICFGR0, 8),
VGIC_RDIST_REG!(GICR_ICPENDR0, 4),
VGIC_RDIST_REG!(GICR_ISPENDR0, 4),
VGIC_RDIST_REG!(GICR_ICACTIVER0, 4),
VGIC_RDIST_REG!(GICR_ISACTIVER0, 4),
VGIC_RDIST_REG!(GICR_IPRIORITYR0, 32),
];
fn redist_attr_access(
gic: &Arc<dyn hypervisor::Device>,
offset: u32,
typer: u64,
val: &u32,
set: bool,
) -> Result<()> {
let mut gic_dist_attr = kvm_device_attr {
group: KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
attr: (typer & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) | (offset as u64), // this needs the mpidr
addr: val as *const u32 as u64,
flags: 0,
};
if set {
#[allow(clippy::unnecessary_mut_passed)]
gic.set_device_attr(&mut gic_dist_attr)
.map_err(Error::SetDeviceAttribute)?;
} else {
gic.get_device_attr(&mut gic_dist_attr)
.map_err(Error::GetDeviceAttribute)?;
}
Ok(())
}
fn access_redists_aux(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &mut Vec<u32>,
reg_list: &'static [RdistReg],
idx: &mut usize,
set: bool,
) -> Result<()> {
for i in gicr_typer {
for rdreg in reg_list {
let mut base = rdreg.base;
let end = base + rdreg.length as u32;
while base < end {
let mut val = 0;
if set {
val = state[*idx];
redist_attr_access(gic, base, *i, &val, true)?;
*idx += 1;
} else {
redist_attr_access(gic, base, *i, &val, false)?;
state.push(val);
}
base += REG_SIZE as u32;
}
}
}
Ok(())
}
/// Get redistributor registers.
pub fn get_redist_regs(gic: &Arc<dyn hypervisor::Device>, gicr_typer: &[u64]) -> Result<Vec<u32>> {
let mut state = Vec::new();
let mut idx: usize = 0;
access_redists_aux(
gic,
&gicr_typer,
&mut state,
VGIC_RDIST_REGS,
&mut idx,
false,
)?;
access_redists_aux(gic, &gicr_typer, &mut state, VGIC_SGI_REGS, &mut idx, false)?;
Ok(state)
}
/// Set redistributor registers.
pub fn set_redist_regs(
gic: &Arc<dyn hypervisor::Device>,
gicr_typer: &[u64],
state: &[u32],
) -> Result<()> {
let mut idx: usize = 0;
let mut mut_state = state.to_owned();
access_redists_aux(
gic,
gicr_typer,
&mut mut_state,
VGIC_RDIST_REGS,
&mut idx,
true,
)?;
access_redists_aux(
gic,
gicr_typer,
&mut mut_state,
VGIC_SGI_REGS,
&mut idx,
true,
)
}

View File

@@ -1,7 +1,87 @@
// 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 +---------------------------------------------------------------|
// | |
// | Reserved (now GIC is here) |
// | |
// 0GB +---------------------------------------------------------------+
//
//
use vm_memory::GuestAddress;
/// 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;
pub const LEGACY_GPIO_MAPPED_IO_START: u64 = 0x0902_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: u64 = 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 256 interrupts.
/// First usable interrupt on aarch64.
pub const IRQ_BASE: u32 = 0;
/// Last usable interrupt on aarch64.
pub const IRQ_MAX: u32 = 255;

View File

@@ -1,27 +1,242 @@
// 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;
/// 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 aarch64::gic::GicDevice;
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 configuring the MPIDR register
VcpuRegMpidr(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,
_rsdp_addr: Option<GuestAddress>,
) -> super::Result<()> {
Ok(())
impl From<Error> for super::Error {
fn from(e: Error) -> super::Error {
super::Error::AArch64Setup(e)
}
}
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn get_reserved_mem_addr() -> usize {
0
#[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,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
) -> super::Result<u64> {
if let Some(kernel_entry_point) = kernel_entry_point {
regs::setup_regs(
fd,
id,
kernel_entry_point.entry_addr.raw_value(),
&vm_memory.memory(),
)
.map_err(Error::RegsConfiguration)?;
}
let mpidr = fd.read_mpidr().map_err(Error::VcpuRegMpidr)?;
Ok(mpidr)
}
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> {
vec![
// 0 ~ 256 MiB: Reserved
(
GuestAddress(0),
layout::MEM_32BIT_DEVICES_START.0 as usize,
RegionType::Reserved,
),
// 256 MiB ~ 1 G: MMIO space
(
layout::MEM_32BIT_DEVICES_START,
layout::MEM_32BIT_DEVICES_SIZE as usize,
RegionType::SubRegion,
),
// 1G ~ 2G: reserved. The leading 256M for PCIe MMCONFIG space
(
layout::PCI_MMCONFIG_START,
(layout::RAM_64BIT_START - layout::PCI_MMCONFIG_START.0) as usize,
RegionType::Reserved,
),
(
GuestAddress(layout::RAM_64BIT_START),
size as usize,
RegionType::Ram,
),
]
}
/// 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: &(u64, u64),
) -> super::Result<Box<dyn GicDevice>> {
let gic_device = gic::kvm::create_gic(vm, vcpu_count).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(gic_device)
}
/// 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 maximum 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 maximum 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();
}
}

81
arch/src/aarch64/regs.rs Normal file
View File

@@ -0,0 +1,81 @@
// 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::{
kvm_regs, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
};
use hypervisor::{arm64_core_reg_id, offset__of};
use std::sync::Arc;
use std::{mem, result};
use vm_memory::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;
/// 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<()> {
let kreg_off = offset__of!(kvm_regs, regs);
// Get the register index of the PSTATE (Processor State) register.
let pstate = offset__of!(user_pt_regs, pstate) + kreg_off;
vcpu.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate),
PSTATE_FAULT_BITS_64,
)
.map_err(Error::SetCoreRegister)?;
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
vcpu.set_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip as u64)
.map_err(Error::SetCoreRegister)?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
vcpu.set_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0),
get_fdt_addr(mem) as u64,
)
.map_err(Error::SetCoreRegister)?;
}
Ok(())
}

View File

@@ -1,40 +1,69 @@
// 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
#![allow(
clippy::unreadable_literal,
clippy::redundant_static_lifetimes,
clippy::cast_lossless,
clippy::transmute_ptr_to_ptr,
clippy::cast_ptr_alignment
)]
//! Implements platform specific functionality.
//! Supported platforms: x86_64, aarch64.
#![allow(clippy::transmute_ptr_to_ptr, clippy::redundant_static_lifetimes)]
extern crate anyhow;
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 serde;
extern crate vm_memory;
extern crate vm_migration;
#[cfg(target_arch = "aarch64")]
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate thiserror;
use std::fmt;
use std::result;
/// 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(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,13 +81,15 @@ pub enum RegionType {
Reserved,
}
/// 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")]
@@ -66,5 +97,69 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, layout, 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,
/// Device Type: GPIO.
#[cfg(target_arch = "aarch64")]
Gpio,
}
/// 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
}
}

View File

@@ -5,30 +5,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use hypervisor::x86_64::LapicState;
use std::io::Cursor;
use std::mem;
use std::result;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use kvm_bindings::kvm_lapic_state;
use kvm_ioctls;
use std::sync::Arc;
#[derive(Debug)]
pub enum Error {
GetLapic(kvm_ioctls::Error),
SetLapic(kvm_ioctls::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 +39,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 +52,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 +76,19 @@ 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,54 +98,25 @@ 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);
}
#[test]
fn test_apic_delivery_mode() {
let mut rng = rand::thread_rng();
let mut v: Vec<u32> = (0..20).map(|_| rng.gen::<u32>()).collect();
let mut v: Vec<u32> = Vec::new();
v.resize(20, 0);
unsafe {
assert_eq!(
libc::getrandom(v.as_mut_ptr() as *mut _ as *mut libc::c_void, 80, 0),
80
);
}
v.iter_mut()
.for_each(|x| *x = set_apic_delivery_mode(*x, 2));
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,7 +7,7 @@
// 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, GuestUsize};
use vm_memory::GuestAddress;
/*
@@ -26,6 +28,17 @@ pub const LOW_RAM_START: GuestAddress = GuestAddress(0x0);
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);
@@ -34,9 +47,10 @@ pub const BOOT_STACK_START: GuestAddress = GuestAddress(0x8000);
pub const BOOT_STACK_POINTER: GuestAddress = GuestAddress(0x8ff0);
// Initial pagetables.
pub const PML4_START: GuestAddress = GuestAddress(0x9000);
pub const PDPTE_START: GuestAddress = GuestAddress(0xa000);
pub const PDE_START: GuestAddress = GuestAddress(0xb000);
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);
@@ -56,6 +70,8 @@ pub const EBDA_START: GuestAddress = GuestAddress(0xa0000);
// 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) **
@@ -65,22 +81,22 @@ pub const HIGH_RAM_START: GuestAddress = GuestAddress(0x100000);
// ** 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);
pub const MEM_32BIT_RESERVED_SIZE: u64 = 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);
pub const MEM_32BIT_DEVICES_SIZE: u64 = 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);
pub const PCI_MMCONFIG_SIZE: u64 = 256 << 20;
// IOAPIC
pub const IOAPIC_START: GuestAddress = GuestAddress(0xfec0_0000);
pub const IOAPIC_SIZE: GuestUsize = 0x20;
pub const IOAPIC_SIZE: u64 = 0x20;
// APIC
pub const APIC_START: GuestAddress = GuestAddress(0xfee0_0000);

View File

@@ -1,26 +1,132 @@
// 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.
mod gdt;
use std::sync::Arc;
pub mod interrupts;
pub mod layout;
mod mptable;
pub mod regs;
use crate::InitramfsConfig;
use crate::RegionType;
use hypervisor::{CpuId, CpuIdEntry, CPUID_FLAG_VALID_INDEX};
use linux_loader::loader::bootparam::{boot_params, setup_header};
use linux_loader::loader::elf::start_info::{
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
};
use std::mem;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestUsize,
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryMmap, GuestMemoryRegion, GuestUsize,
};
mod smbios;
use std::arch::x86_64;
#[cfg(feature = "tdx")]
pub mod tdx;
#[derive(Debug, Copy, Clone)]
pub enum BootProtocol {
LinuxBoot,
PvhBoot,
}
impl ::std::fmt::Display for BootProtocol {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match self {
BootProtocol::LinuxBoot => write!(f, "Linux 64-bit boot protocol"),
BootProtocol::PvhBoot => write!(f, "PVH boot protocol"),
}
}
}
#[derive(Debug, Copy, Clone)]
/// Specifies the entry point address where the guest must start
/// executing code, as well as which of the supported boot protocols
/// is to be used to configure the guest initial state.
pub struct EntryPoint {
/// Address in guest memory where the guest must start execution
pub entry_addr: GuestAddress,
/// Specifies which boot protocol to use
pub protocol: BootProtocol,
/// This field is used for bzImage to fill zero page
pub setup_header: Option<setup_header>,
}
const E820_RAM: u32 = 1;
const E820_RESERVED: u32 = 2;
#[derive(Clone)]
pub struct SgxEpcSection {
start: GuestAddress,
size: GuestUsize,
}
impl SgxEpcSection {
pub fn new(start: GuestAddress, size: GuestUsize) -> Self {
SgxEpcSection { start, size }
}
pub fn start(&self) -> GuestAddress {
self.start
}
pub fn size(&self) -> GuestUsize {
self.size
}
}
#[derive(Clone)]
pub struct SgxEpcRegion {
start: GuestAddress,
size: GuestUsize,
epc_sections: Vec<SgxEpcSection>,
}
impl SgxEpcRegion {
pub fn new(start: GuestAddress, size: GuestUsize) -> Self {
SgxEpcRegion {
start,
size,
epc_sections: Vec::new(),
}
}
pub fn start(&self) -> GuestAddress {
self.start
}
pub fn size(&self) -> GuestUsize {
self.size
}
pub fn epc_sections(&self) -> &Vec<SgxEpcSection> {
&self.epc_sections
}
pub fn push(&mut self, epc_section: SgxEpcSection) {
self.epc_sections.push(epc_section);
}
}
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `DataInit`) where:
// * the type that is implementing the trait is foreign or
// * all of the parameters being passed to the trait (if there are any) are also foreign
// is prohibited.
#[derive(Copy, Clone, Default)]
struct StartInfoWrapper(hvm_start_info);
// It is safe to initialize StartInfoWrapper which is a wrapper over `hvm_start_info` (a series of ints).
unsafe impl ByteValued for StartInfoWrapper {}
#[derive(Copy, Clone, Default)]
struct MemmapTableEntryWrapper(hvm_memmap_table_entry);
unsafe impl ByteValued for MemmapTableEntryWrapper {}
#[derive(Copy, Clone, Default)]
struct ModlistEntryWrapper(hvm_modlist_entry);
unsafe impl ByteValued for ModlistEntryWrapper {}
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `DataInit`) where:
// * the type that is implementing the trait is foreign or
@@ -36,8 +142,39 @@ unsafe impl ByteValued for BootParamsWrapper {}
pub enum Error {
/// Invalid e820 setup params.
E820Configuration,
/// Error writing MP table to memory.
MpTableSetup(mptable::Error),
/// Error configuring the general purpose registers
RegsConfiguration(regs::Error),
/// Error configuring the special registers
SregsConfiguration(regs::Error),
/// Error configuring the floating point related registers
FpuConfiguration(regs::Error),
/// Error configuring the MSR registers
MsrsConfiguration(regs::Error),
/// Failed to set supported CPUs.
SetSupportedCpusFailed(anyhow::Error),
/// Cannot set the local interruption due to bad configuration.
LocalIntConfiguration(anyhow::Error),
/// Error setting up SMBIOS table
SmbiosSetup(smbios::Error),
/// Could not find any SGX EPC section
NoSgxEpcSection,
/// Missing SGX CPU feature
MissingSgxFeature,
/// Missing SGX_LC CPU feature
MissingSgxLaunchControlFeature,
}
impl From<Error> for super::Error {
@@ -46,6 +183,190 @@ impl From<Error> for super::Error {
}
}
#[allow(dead_code, clippy::upper_case_acronyms)]
#[derive(Copy, Clone)]
pub enum CpuidReg {
EAX,
EBX,
ECX,
EDX,
}
pub struct CpuidPatch {
pub function: u32,
pub index: u32,
pub flags_bit: Option<u8>,
pub eax_bit: Option<u8>,
pub ebx_bit: Option<u8>,
pub ecx_bit: Option<u8>,
pub edx_bit: Option<u8>,
}
impl CpuidPatch {
pub fn set_cpuid_reg(
cpuid: &mut CpuId,
function: u32,
index: Option<u32>,
reg: CpuidReg,
value: u32,
) {
let entries = cpuid.as_mut_slice();
let mut entry_found = false;
for entry in entries.iter_mut() {
if entry.function == function && (index == None || index.unwrap() == entry.index) {
entry_found = true;
match reg {
CpuidReg::EAX => {
entry.eax = value;
}
CpuidReg::EBX => {
entry.ebx = value;
}
CpuidReg::ECX => {
entry.ecx = value;
}
CpuidReg::EDX => {
entry.edx = value;
}
}
}
}
if entry_found {
return;
}
// Entry not found, so let's add it.
if let Some(index) = index {
let mut entry = CpuIdEntry {
function,
index,
flags: CPUID_FLAG_VALID_INDEX,
..Default::default()
};
match reg {
CpuidReg::EAX => {
entry.eax = value;
}
CpuidReg::EBX => {
entry.ebx = value;
}
CpuidReg::ECX => {
entry.ecx = value;
}
CpuidReg::EDX => {
entry.edx = value;
}
}
if let Err(e) = cpuid.push(entry) {
error!("Failed adding new CPUID entry: {:?}", e);
}
}
}
pub fn patch_cpuid(cpuid: &mut CpuId, patches: Vec<CpuidPatch>) {
let entries = cpuid.as_mut_slice();
for entry in entries.iter_mut() {
for patch in patches.iter() {
if entry.function == patch.function && entry.index == patch.index {
if let Some(flags_bit) = patch.flags_bit {
entry.flags |= 1 << flags_bit;
}
if let Some(eax_bit) = patch.eax_bit {
entry.eax |= 1 << eax_bit;
}
if let Some(ebx_bit) = patch.ebx_bit {
entry.ebx |= 1 << ebx_bit;
}
if let Some(ecx_bit) = patch.ecx_bit {
entry.ecx |= 1 << ecx_bit;
}
if let Some(edx_bit) = patch.edx_bit {
entry.edx |= 1 << edx_bit;
}
}
}
}
}
pub fn is_feature_enabled(
cpuid: &CpuId,
function: u32,
index: u32,
reg: CpuidReg,
feature_bit: usize,
) -> bool {
let entries = cpuid.as_slice();
let mask = 1 << feature_bit;
for entry in entries.iter() {
if entry.function == function && entry.index == index {
let reg_val: u32;
match reg {
CpuidReg::EAX => {
reg_val = entry.eax;
}
CpuidReg::EBX => {
reg_val = entry.ebx;
}
CpuidReg::ECX => {
reg_val = entry.ecx;
}
CpuidReg::EDX => {
reg_val = entry.edx;
}
}
return (reg_val & mask) == mask;
}
}
false
}
}
pub fn configure_vcpu(
fd: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpuid: CpuId,
kvm_hyperv: bool,
) -> super::Result<()> {
// Per vCPU CPUID changes; common are handled via CpuManager::generate_common_cpuid()
let mut cpuid = cpuid;
CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id));
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id));
fd.set_cpuid2(&cpuid)
.map_err(|e| Error::SetSupportedCpusFailed(e.into()))?;
if kvm_hyperv {
fd.enable_hyperv_synic().unwrap();
}
regs::setup_msrs(fd).map_err(Error::MsrsConfiguration)?;
if let Some(kernel_entry_point) = kernel_entry_point {
// Safe to unwrap because this method is called after the VM is configured
regs::setup_regs(
fd,
kernel_entry_point.entry_addr.raw_value(),
layout::BOOT_STACK_POINTER.raw_value(),
layout::ZERO_PAGE_START.raw_value(),
kernel_entry_point.protocol,
)
.map_err(Error::RegsConfiguration)?;
regs::setup_fpu(fd).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&vm_memory.memory(), fd, kernel_entry_point.protocol)
.map_err(Error::SregsConfiguration)?;
}
interrupts::set_lint(fd).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
Ok(())
}
/// Returns a Vec of the valid memory addresses.
/// These should be used to configure the GuestMemory structure for the platform.
/// For x86_64 all addresses are valid from the start of the kernel except a
@@ -106,33 +427,231 @@ pub fn configure_system(
guest_mem: &GuestMemoryMmap,
cmdline_addr: GuestAddress,
cmdline_size: usize,
num_cpus: u8,
initramfs: &Option<InitramfsConfig>,
_num_cpus: u8,
setup_hdr: Option<setup_header>,
rsdp_addr: Option<GuestAddress>,
boot_prot: BootProtocol,
sgx_epc_region: Option<SgxEpcRegion>,
) -> super::Result<()> {
let size = smbios::setup_smbios(guest_mem).map_err(Error::SmbiosSetup)?;
// Place the MP table after the SMIOS table aligned to 16 bytes
let offset = GuestAddress(layout::SMBIOS_START).unchecked_add(size);
let offset = GuestAddress((offset.0 + 16) & !0xf);
mptable::setup_mptable(offset, guest_mem, _num_cpus).map_err(Error::MpTableSetup)?;
// Check that the RAM is not smaller than the RSDP start address
if let Some(rsdp_addr) = rsdp_addr {
if rsdp_addr.0 > guest_mem.last_addr().0 {
return Err(super::Error::RsdpPastRamEnd);
}
}
match boot_prot {
BootProtocol::PvhBoot => {
configure_pvh(
guest_mem,
cmdline_addr,
initramfs,
rsdp_addr,
sgx_epc_region,
)?;
}
BootProtocol::LinuxBoot => {
error!("Using deprecated LinuxBoot protocol: Please configure your kernel with CONFIG_PVH=y and supply the `vmlinux` file to `--kernel`");
configure_64bit_boot(
guest_mem,
cmdline_addr,
cmdline_size,
initramfs,
setup_hdr,
rsdp_addr,
sgx_epc_region,
)?;
}
}
Ok(())
}
fn configure_pvh(
guest_mem: &GuestMemoryMmap,
cmdline_addr: GuestAddress,
initramfs: &Option<InitramfsConfig>,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
) -> super::Result<()> {
const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578;
let mut start_info: StartInfoWrapper = StartInfoWrapper(hvm_start_info::default());
start_info.0.magic = XEN_HVM_START_MAGIC_VALUE;
start_info.0.version = 1; // pvh has version 1
start_info.0.nr_modules = 0;
start_info.0.cmdline_paddr = cmdline_addr.raw_value() as u64;
start_info.0.memmap_paddr = layout::MEMMAP_START.raw_value();
if let Some(rsdp_addr) = rsdp_addr {
start_info.0.rsdp_paddr = rsdp_addr.0;
}
if let Some(initramfs_config) = initramfs {
// The initramfs has been written to guest memory already, here we just need to
// create the module structure that describes it.
let ramdisk_mod: ModlistEntryWrapper = ModlistEntryWrapper(hvm_modlist_entry {
paddr: initramfs_config.address.raw_value(),
size: initramfs_config.size as u64,
..Default::default()
});
start_info.0.nr_modules += 1;
start_info.0.modlist_paddr = layout::MODLIST_START.raw_value();
// Write the modlist struct to guest memory.
guest_mem
.write_obj(ramdisk_mod, layout::MODLIST_START)
.map_err(super::Error::ModlistSetup)?;
}
// Vector to hold the memory maps which needs to be written to guest memory
// at MEMMAP_START after all of the mappings are recorded.
let mut memmap: Vec<hvm_memmap_table_entry> = Vec::new();
// Create the memory map entries.
add_memmap_entry(&mut memmap, 0, layout::EBDA_START.raw_value(), E820_RAM);
let mem_end = guest_mem.last_addr();
if mem_end < layout::MEM_32BIT_RESERVED_START {
add_memmap_entry(
&mut memmap,
layout::HIGH_RAM_START.raw_value(),
mem_end.unchecked_offset_from(layout::HIGH_RAM_START) + 1,
E820_RAM,
);
} else {
add_memmap_entry(
&mut memmap,
layout::HIGH_RAM_START.raw_value(),
layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::HIGH_RAM_START),
E820_RAM,
);
if mem_end > layout::RAM_64BIT_START {
add_memmap_entry(
&mut memmap,
layout::RAM_64BIT_START.raw_value(),
mem_end.unchecked_offset_from(layout::RAM_64BIT_START) + 1,
E820_RAM,
);
}
}
add_memmap_entry(
&mut memmap,
layout::PCI_MMCONFIG_START.0,
layout::PCI_MMCONFIG_SIZE,
E820_RESERVED,
);
if let Some(sgx_epc_region) = sgx_epc_region {
add_memmap_entry(
&mut memmap,
sgx_epc_region.start().raw_value(),
sgx_epc_region.size() as u64,
E820_RESERVED,
);
}
start_info.0.memmap_entries = memmap.len() as u32;
// Copy the vector with the memmap table to the MEMMAP_START address
// which is already saved in the memmap_paddr field of hvm_start_info struct.
let mut memmap_start_addr = layout::MEMMAP_START;
guest_mem
.checked_offset(
memmap_start_addr,
mem::size_of::<hvm_memmap_table_entry>() * start_info.0.memmap_entries as usize,
)
.ok_or(super::Error::MemmapTablePastRamEnd)?;
// For every entry in the memmap vector, create a MemmapTableEntryWrapper
// and write it to guest memory.
for memmap_entry in memmap {
let map_entry_wrapper: MemmapTableEntryWrapper = MemmapTableEntryWrapper(memmap_entry);
guest_mem
.write_obj(map_entry_wrapper, memmap_start_addr)
.map_err(|_| super::Error::MemmapTableSetup)?;
memmap_start_addr =
memmap_start_addr.unchecked_add(mem::size_of::<hvm_memmap_table_entry>() as u64);
}
// The hvm_start_info struct itself must be stored at PVH_START_INFO
// address, and %rbx will be initialized to contain PVH_INFO_START prior to
// starting the guest, as required by the PVH ABI.
let start_info_addr = layout::PVH_INFO_START;
guest_mem
.checked_offset(start_info_addr, mem::size_of::<hvm_start_info>())
.ok_or(super::Error::StartInfoPastRamEnd)?;
// Write the start_info struct to guest memory.
guest_mem
.write_obj(start_info, start_info_addr)
.map_err(|_| super::Error::StartInfoSetup)?;
Ok(())
}
fn add_memmap_entry(memmap: &mut Vec<hvm_memmap_table_entry>, addr: u64, size: u64, mem_type: u32) {
// Add the table entry to the vector
memmap.push(hvm_memmap_table_entry {
addr,
size,
type_: mem_type,
reserved: 0,
});
}
fn configure_64bit_boot(
guest_mem: &GuestMemoryMmap,
cmdline_addr: GuestAddress,
cmdline_size: usize,
initramfs: &Option<InitramfsConfig>,
setup_hdr: Option<setup_header>,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
) -> super::Result<()> {
const KERNEL_BOOT_FLAG_MAGIC: u16 = 0xaa55;
const KERNEL_HDR_MAGIC: u32 = 0x53726448;
const KERNEL_LOADER_OTHER: u8 = 0xff;
const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x1000000; // Must be non-zero.
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
mptable::setup_mptable(guest_mem, num_cpus).map_err(Error::MpTableSetup)?;
let mut params: BootParamsWrapper = BootParamsWrapper(boot_params::default());
if let Some(hdr) = setup_hdr {
// We should use the header if the loader provides one (e.g. from a bzImage).
params.0.hdr = hdr;
params.0.hdr.cmd_line_ptr = cmdline_addr.raw_value() as u32;
params.0.hdr.cmdline_size = cmdline_size as u32;
} else {
params.0.hdr.type_of_loader = KERNEL_LOADER_OTHER;
params.0.hdr.boot_flag = KERNEL_BOOT_FLAG_MAGIC;
params.0.hdr.header = KERNEL_HDR_MAGIC;
params.0.hdr.cmd_line_ptr = cmdline_addr.raw_value() as u32;
params.0.hdr.cmdline_size = cmdline_size as u32;
params.0.hdr.kernel_alignment = KERNEL_MIN_ALIGNMENT_BYTES;
};
// Common bootparams settings
if params.0.hdr.type_of_loader == 0 {
params.0.hdr.type_of_loader = KERNEL_LOADER_OTHER;
}
params.0.hdr.cmd_line_ptr = cmdline_addr.raw_value() as u32;
params.0.hdr.cmdline_size = cmdline_size as u32;
if let Some(initramfs_config) = initramfs {
params.0.hdr.ramdisk_image = initramfs_config.address.raw_value() as u32;
params.0.hdr.ramdisk_size = initramfs_config.size as u32;
}
add_e820_entry(&mut params.0, 0, layout::EBDA_START.raw_value(), E820_RAM)?;
let mem_end = guest_mem.last_addr();
@@ -167,6 +686,15 @@ pub fn configure_system(
E820_RESERVED,
)?;
if let Some(sgx_epc_region) = sgx_epc_region {
add_e820_entry(
&mut params.0,
sgx_epc_region.start().raw_value(),
sgx_epc_region.size() as u64,
E820_RESERVED,
)?;
}
if let Some(rsdp_addr) = rsdp_addr {
params.0.acpi_rsdp_addr = rsdp_addr.0;
}
@@ -202,6 +730,161 @@ fn add_e820_entry(
Ok(())
}
/// 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 first_region = guest_mem
.find_region(GuestAddress::new(0))
.ok_or(super::Error::InitramfsAddress)?;
// It's safe to cast to usize because the size of a region can't be greater than usize.
let lowmem_size = first_region.len() as usize;
if lowmem_size < initramfs_size {
return Err(super::Error::InitramfsAddress);
}
let aligned_addr: u64 = ((lowmem_size - initramfs_size) & !(crate::pagesize() - 1)) as u64;
Ok(aligned_addr)
}
pub fn get_host_cpu_phys_bits() -> u8 {
unsafe {
let leaf = x86_64::__cpuid(0x8000_0000);
// Detect and handle AMD SME (Secure Memory Encryption) properly.
// Some physical address bits may become reserved when the feature is enabled.
// See AMD64 Architecture Programmer's Manual Volume 2, Section 7.10.1
let reduced = if leaf.eax >= 0x8000_001f
&& leaf.ebx == 0x6874_7541 // Vendor ID: AuthenticAMD
&& leaf.ecx == 0x444d_4163
&& leaf.edx == 0x6974_6e65
&& x86_64::__cpuid(0x8000_001f).eax & 0x1 != 0
{
(x86_64::__cpuid(0x8000_001f).ebx >> 6) & 0x3f
} else {
0
};
if leaf.eax >= 0x8000_0008 {
let leaf = x86_64::__cpuid(0x8000_0008);
((leaf.eax & 0xff) - reduced) as u8
} else {
36
}
}
}
pub fn update_cpuid_topology(
cpuid: &mut CpuId,
threads_per_core: u8,
cores_per_die: u8,
dies_per_package: u8,
) {
let thread_width = 8 - (threads_per_core - 1).leading_zeros();
let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width;
let die_width = (8 - (dies_per_package - 1).leading_zeros()) + core_width;
// CPU Topology leaf 0xb
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::EAX, thread_width);
CpuidPatch::set_cpuid_reg(
cpuid,
0xb,
Some(0),
CpuidReg::EBX,
u32::from(threads_per_core),
);
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::ECX, 1 << 8);
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::EAX, die_width);
CpuidPatch::set_cpuid_reg(
cpuid,
0xb,
Some(1),
CpuidReg::EBX,
u32::from(dies_per_package * cores_per_die * threads_per_core),
);
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::ECX, 2 << 8);
// CPU Topology leaf 0x1f
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(0), CpuidReg::EAX, thread_width);
CpuidPatch::set_cpuid_reg(
cpuid,
0x1f,
Some(0),
CpuidReg::EBX,
u32::from(threads_per_core),
);
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(0), CpuidReg::ECX, 1 << 8);
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(1), CpuidReg::EAX, core_width);
CpuidPatch::set_cpuid_reg(
cpuid,
0x1f,
Some(1),
CpuidReg::EBX,
u32::from(cores_per_die * threads_per_core),
);
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(1), CpuidReg::ECX, 2 << 8);
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::EAX, die_width);
CpuidPatch::set_cpuid_reg(
cpuid,
0x1f,
Some(2),
CpuidReg::EBX,
u32::from(dies_per_package * cores_per_die * threads_per_core),
);
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::ECX, 5 << 8);
}
// The goal is to update the CPUID sub-leaves to reflect the number of EPC
// sections exposed to the guest.
pub fn update_cpuid_sgx(cpuid: &mut CpuId, epc_sections: Vec<SgxEpcSection>) -> Result<(), Error> {
// Something's wrong if there's no EPC section.
if epc_sections.is_empty() {
return Err(Error::NoSgxEpcSection);
}
// We can't go further if the hypervisor does not support SGX feature.
if !CpuidPatch::is_feature_enabled(cpuid, 0x7, 0, CpuidReg::EBX, 2) {
return Err(Error::MissingSgxFeature);
}
// We can't go further if the hypervisor does not support SGX_LC feature.
if !CpuidPatch::is_feature_enabled(cpuid, 0x7, 0, CpuidReg::ECX, 30) {
return Err(Error::MissingSgxLaunchControlFeature);
}
// Get host CPUID for leaf 0x12, subleaf 0x2. This is to retrieve EPC
// properties such as confidentiality and integrity.
let leaf = unsafe { std::arch::x86_64::__cpuid_count(0x12, 0x2) };
for (i, epc_section) in epc_sections.iter().enumerate() {
let subleaf_idx = i + 2;
let start = epc_section.start().raw_value();
let size = epc_section.size() as u64;
let eax = (start & 0xffff_f000) as u32 | 0x1;
let ebx = (start >> 32) as u32;
let ecx = (size & 0xffff_f000) as u32 | (leaf.ecx & 0xf);
let edx = (size >> 32) as u32;
// CPU Topology leaf 0x12
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EAX, eax);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EBX, ebx);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::ECX, ecx);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EDX, edx);
}
// Add one NULL entry to terminate the dynamic list
let subleaf_idx = epc_sections.len() + 2;
// CPU Topology leaf 0x12
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EAX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EBX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::ECX, 0);
CpuidPatch::set_cpuid_reg(cpuid, 0x12, Some(subleaf_idx as u32), CpuidReg::EDX, 0);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
@@ -209,7 +892,7 @@ mod tests {
#[test]
fn regions_lt_4gb() {
let regions = arch_memory_regions(1 << 29 as GuestUsize);
let regions = arch_memory_regions(1 << 29);
assert_eq!(3, regions.len());
assert_eq!(GuestAddress(0), regions[0].0);
assert_eq!(1usize << 29, regions[0].1);
@@ -217,7 +900,7 @@ mod tests {
#[test]
fn regions_gt_4gb() {
let regions = arch_memory_regions((1 << 32 as GuestUsize) + 0x8000);
let regions = arch_memory_regions((1 << 32) + 0x8000);
assert_eq!(4, regions.len());
assert_eq!(GuestAddress(0), regions[0].0);
assert_eq!(GuestAddress(1 << 32), regions[1].0);
@@ -226,8 +909,18 @@ mod tests {
#[test]
fn test_system_configuration() {
let no_vcpus = 4;
let gm = GuestMemoryMmap::from_ranges(&vec![(GuestAddress(0), 0x10000)]).unwrap();
let config_err = configure_system(&gm, GuestAddress(0), 0, 1, None, None);
let gm = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let config_err = configure_system(
&gm,
GuestAddress(0),
0,
&None,
1,
None,
Some(layout::RSDP_POINTER),
BootProtocol::LinuxBoot,
None,
);
assert!(config_err.is_err());
// Now assigning some memory that falls before the 32bit memory hole.
@@ -239,7 +932,31 @@ mod tests {
.map(|r| (r.0, r.1))
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus, None, None).unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::LinuxBoot,
None,
)
.unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::PvhBoot,
None,
)
.unwrap();
// Now assigning some memory that is equal to the start of the 32bit memory hole.
let mem_size = 3328 << 20;
@@ -250,7 +967,31 @@ mod tests {
.map(|r| (r.0, r.1))
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus, None, None).unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::LinuxBoot,
None,
)
.unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::PvhBoot,
None,
)
.unwrap();
// Now assigning some memory that falls after the 32bit memory hole.
let mem_size = 3330 << 20;
@@ -261,7 +1002,31 @@ mod tests {
.map(|r| (r.0, r.1))
.collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus, None, None).unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::LinuxBoot,
None,
)
.unwrap();
configure_system(
&gm,
GuestAddress(0),
0,
&None,
no_vcpus,
None,
None,
BootProtocol::PvhBoot,
None,
)
.unwrap();
}
#[test]
@@ -303,4 +1068,29 @@ mod tests {
)
.is_err());
}
#[test]
fn test_add_memmap_entry() {
let mut memmap: Vec<hvm_memmap_table_entry> = Vec::new();
let expected_memmap = vec![
hvm_memmap_table_entry {
addr: 0x0,
size: 0x1000,
type_: E820_RAM,
..Default::default()
},
hvm_memmap_table_entry {
addr: 0x10000,
size: 0xa000,
type_: E820_RESERVED,
..Default::default()
},
];
add_memmap_entry(&mut memmap, 0, 0x1000, E820_RAM);
add_memmap_entry(&mut memmap, 0x10000, 0xa000, E820_RESERVED);
assert_eq!(format!("{:?}", memmap), format!("{:?}", expected_memmap));
}
}

View File

@@ -13,8 +13,10 @@ use std::slice;
use libc::c_char;
use arch_gen::x86::mpspec;
use layout::{APIC_START, IOAPIC_START, MPTABLE_START};
use vm_memory::{Address, ByteValued, Bytes, GuestMemory, GuestMemoryError, GuestMemoryMmap};
use layout::{APIC_START, HIGH_RAM_START, IOAPIC_START};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap,
};
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `ByteValued`) where:
@@ -121,16 +123,21 @@ fn compute_mp_size(num_cpus: u8) -> usize {
}
/// Performs setup of the MP table for the given `num_cpus`.
pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
if num_cpus as u32 > MAX_SUPPORTED_CPUS {
return Err(Error::TooManyCpus);
}
// Used to keep track of the next base pointer into the MP table.
let mut base_mp = MPTABLE_START;
let mut base_mp = offset;
let mp_size = compute_mp_size(num_cpus);
if offset.unchecked_add(mp_size as u64) >= HIGH_RAM_START {
warn!("Skipping mptable creation due to insufficient space");
return Ok(());
}
let mut checksum: u8 = 0;
let ioapicid: u8 = num_cpus + 1;
@@ -280,6 +287,7 @@ pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use layout::MPTABLE_START;
use vm_memory::{GuestAddress, GuestUsize};
fn table_entry_size(type_: u8) -> usize {
@@ -299,7 +307,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
}
#[test]
@@ -308,7 +316,7 @@ mod tests {
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)])
.unwrap();
assert!(setup_mptable(&mem, num_cpus).is_err());
assert!(setup_mptable(MPTABLE_START, &mem, num_cpus).is_err());
}
#[test]
@@ -317,7 +325,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
@@ -333,7 +341,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
@@ -367,7 +375,7 @@ mod tests {
.unwrap();
for i in 0..MAX_SUPPORTED_CPUS as u8 {
setup_mptable(&mem, i).unwrap();
setup_mptable(MPTABLE_START, &mem, i).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
@@ -400,7 +408,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let result = setup_mptable(&mem, cpus as u8);
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8);
assert!(result.is_err());
}
}

View File

@@ -1,47 +1,49 @@
// 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 super::gdt::{gdt_entry, kvm_segment_from_gdt};
use arch_gen::x86::msr_index;
use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_regs, kvm_sregs, Msrs};
use kvm_ioctls::VcpuFd;
use layout::{BOOT_GDT_START, BOOT_IDT_START, PDE_START, PDPTE_START, PML4_START};
use super::BootProtocol;
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
use hypervisor::arch::x86::regs::*;
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};
// 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;
#[derive(Debug)]
pub enum Error {
/// Failed to get SREGs for this CPU.
GetStatusRegisters(kvm_ioctls::Error),
GetStatusRegisters(hypervisor::HypervisorCpuError),
/// Failed to set base registers for this CPU.
SetBaseRegisters(kvm_ioctls::Error),
SetBaseRegisters(hypervisor::HypervisorCpuError),
/// Failed to configure the FPU.
SetFPURegisters(kvm_ioctls::Error),
SetFpuRegisters(hypervisor::HypervisorCpuError),
/// Setting up MSRs failed.
SetModelSpecificRegisters(kvm_ioctls::Error),
SetModelSpecificRegisters(hypervisor::HypervisorCpuError),
/// Failed to set SREGs for this CPU.
SetStatusRegisters(kvm_ioctls::Error),
SetStatusRegisters(hypervisor::HypervisorCpuError),
/// Checking the GDT address failed.
CheckGDTAddr,
CheckGdtAddr,
/// Writing the GDT to RAM failed.
WriteGDT(GuestMemoryError),
WriteGdt(GuestMemoryError),
/// Writing the IDT to RAM failed.
WriteIDT(GuestMemoryError),
WriteIdt(GuestMemoryError),
/// Writing PDPTE to RAM failed.
WritePDPTEAddress(GuestMemoryError),
WritePdpteAddress(GuestMemoryError),
/// Writing PDE to RAM failed.
WritePDEAddress(GuestMemoryError),
WritePdeAddress(GuestMemoryError),
/// Writing PML4 to RAM failed.
WritePML4Address(GuestMemoryError),
WritePml4Address(GuestMemoryError),
/// Writing PML5 to RAM failed.
WritePml5Address(GuestMemoryError),
}
pub type Result<T> = result::Result<T, Error>;
@@ -51,14 +53,14 @@ 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()
};
vcpu.set_fpu(&fpu).map_err(Error::SetFPURegisters)
vcpu.set_fpu(&fpu).map_err(Error::SetFpuRegisters)
}
/// Configure Model Specific Registers (MSRs) for a given CPU.
@@ -66,8 +68,8 @@ 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<()> {
vcpu.set_msrs(&create_msr_entries())
pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
vcpu.set_msrs(&hypervisor::x86_64::boot_msr_entries())
.map_err(Error::SetModelSpecificRegisters)?;
Ok(())
@@ -81,16 +83,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)
}
@@ -100,31 +117,31 @@ 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_MAX: usize = 4;
const EFER_LMA: u64 = 0x400;
const EFER_LME: u64 = 0x100;
const X86_CR0_PE: u64 = 0x1;
const X86_CR0_PG: u64 = 0x80000000;
const X86_CR4_PAE: u64 = 0x20;
fn write_gdt_table(table: &[u64], guest_mem: &GuestMemoryMmap) -> Result<()> {
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::CheckGDTAddr)?;
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(())
}
@@ -133,20 +150,38 @@ fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> {
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)?;
@@ -165,111 +200,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 = CR0_PE;
sregs.cr4 = 0;
}
BootProtocol::LinuxBoot => {
/* 64-bit protected mode */
sregs.cr0 |= 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 |= 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;
sregs.cr4 |= CR4_PAE;
sregs.cr0 |= CR0_PG;
Ok(())
}
fn create_msr_entries() -> Msrs {
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()
});
Msrs::from_entries(&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::from_ranges(&vec![(GuestAddress(0), 0x10000)]).unwrap()
GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap()
}
fn read_u64(gm: &GuestMemoryMmap, offset: GuestAddress) -> u64 {
@@ -278,9 +266,9 @@ 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_START));
assert_eq!(
@@ -298,26 +286,59 @@ mod tests {
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!(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!(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,
@@ -325,99 +346,12 @@ mod tests {
);
}
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 mut msrs = Msrs::from_entries(&[kvm_msr_entry {
index: msr_index::MSR_IA32_MISC_ENABLE,
..Default::default()
}]);
// 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();
assert_eq!(entry_vec.as_slice()[9], msrs.as_slice()[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);
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!(CR4_PAE, sregs.cr4);
assert_eq!(CR0_PG, sregs.cr0);
}
}

271
arch/src/x86_64/smbios.rs Normal file
View File

@@ -0,0 +1,271 @@
// 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, 0u8, curptr)?;
Ok(curptr)
}
pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<u64> {
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 smbios_biosinfo = SmbiosBiosInfo {
typ: BIOS_INFORMATION,
length: mem::size_of::<SmbiosBiosInfo>() as u8,
handle,
vendor: 1, // First string written in this section
version: 2, // Second string written in this section
characteristics: PCI_SUPPORTED,
characteristics_ext2: IS_VIRTUAL_MACHINE,
..Default::default()
};
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, 0u8, curptr)?;
}
{
handle += 1;
let smbios_sysinfo = SmbiosSysInfo {
typ: SYSTEM_INFORMATION,
length: mem::size_of::<SmbiosSysInfo>() as u8,
handle,
manufacturer: 1, // First string written in this section
product_name: 2, // Second string written in this section
..Default::default()
};
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, 0u8, curptr)?;
}
{
handle += 1;
let smbios_sysinfo = SmbiosSysInfo {
typ: END_OF_TABLE,
length: mem::size_of::<SmbiosSysInfo>() as u8,
handle,
..Default::default()
};
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
curptr = write_and_incr(mem, 0u8, curptr)?;
}
{
let mut smbios_ep = Smbios30Entrypoint {
signature: *SM3_MAGIC_IDENT,
length: mem::size_of::<Smbios30Entrypoint>() as u8,
// SMBIOS rev 3.2.0
majorver: 0x03,
minorver: 0x02,
docrev: 0x00,
revision: 0x01, // SMBIOS 3.0
max_size: curptr.unchecked_offset_from(physptr) as u32,
physptr: physptr.0,
..Default::default()
};
smbios_ep.checksum = compute_checksum(&smbios_ep);
mem.write_obj(smbios_ep, GuestAddress(SMBIOS_START))
.map_err(|_| Error::WriteSmbiosEp)?;
}
Ok(curptr.unchecked_offset_from(physptr))
}
#[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);
}
}

318
arch/src/x86_64/tdx/mod.rs Normal file
View File

@@ -0,0 +1,318 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use thiserror::Error;
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap};
#[derive(Error, Debug)]
pub enum TdvfError {
#[error("Failed read TDVF descriptor: {0}")]
ReadDescriptor(#[source] std::io::Error),
#[error("Failed read TDVF descriptor offset: {0}")]
ReadDescriptorOffset(#[source] std::io::Error),
#[error("Invalid descriptor signature")]
InvalidDescriptorSignature,
#[error("Invalid descriptor size")]
InvalidDescriptorSize,
#[error("Invalid descriptor version")]
InvalidDescriptorVersion,
#[error("Failed to write HOB details to guest memory: {0}")]
GuestMemoryWriteHob(#[source] GuestMemoryError),
}
// TDVF_DESCRIPTOR
#[repr(packed)]
pub struct TdvfDescriptor {
signature: [u8; 4],
length: u32,
version: u32,
num_sections: u32, // NumberOfSectionEntry
}
// TDVF_SECTION
#[repr(packed)]
#[derive(Clone, Copy, Default, Debug)]
pub struct TdvfSection {
pub data_offset: u32,
pub data_size: u32, // RawDataSize
pub address: u64, // MemoryAddress
pub size: u64, // MemoryDataSize
pub r#type: TdvfSectionType,
pub attributes: u32,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum TdvfSectionType {
Bfv,
Cfv,
TdHob,
TempMem,
Reserved = 0xffffffff,
}
impl Default for TdvfSectionType {
fn default() -> Self {
TdvfSectionType::Reserved
}
}
pub fn parse_tdvf_sections(file: &mut File) -> Result<Vec<TdvfSection>, TdvfError> {
// The 32-bit offset to the TDVF metadata is located 32 bytes from
// the end of the file.
// See "TDVF Metadata Pointer" in "TDX Virtual Firmware Design Guide
file.seek(SeekFrom::End(-0x20))
.map_err(TdvfError::ReadDescriptorOffset)?;
let mut descriptor_offset: [u8; 4] = [0; 4];
file.read_exact(&mut descriptor_offset)
.map_err(TdvfError::ReadDescriptorOffset)?;
let descriptor_offset = u32::from_le_bytes(descriptor_offset) as u64;
file.seek(SeekFrom::Start(descriptor_offset))
.map_err(TdvfError::ReadDescriptor)?;
let mut descriptor: TdvfDescriptor = unsafe { std::mem::zeroed() };
// Safe as we read exactly the size of the descriptor header
file.read_exact(unsafe {
std::slice::from_raw_parts_mut(
&mut descriptor as *mut _ as *mut u8,
std::mem::size_of::<TdvfDescriptor>(),
)
})
.map_err(TdvfError::ReadDescriptor)?;
if &descriptor.signature != b"TDVF" {
return Err(TdvfError::InvalidDescriptorSignature);
}
if descriptor.length as usize
!= std::mem::size_of::<TdvfDescriptor>()
+ std::mem::size_of::<TdvfSection>() * descriptor.num_sections as usize
{
return Err(TdvfError::InvalidDescriptorSize);
}
if descriptor.version != 1 {
return Err(TdvfError::InvalidDescriptorVersion);
}
let mut sections = Vec::new();
sections.resize_with(descriptor.num_sections as usize, TdvfSection::default);
// Safe as we read exactly the advertised sections
file.read_exact(unsafe {
std::slice::from_raw_parts_mut(
sections.as_mut_ptr() as *mut u8,
descriptor.num_sections as usize * std::mem::size_of::<TdvfSection>(),
)
})
.map_err(TdvfError::ReadDescriptor)?;
Ok(sections)
}
#[repr(u16)]
#[derive(Copy, Clone, Debug)]
enum HobType {
Handoff = 0x1,
ResourceDescriptor = 0x3,
Unused = 0xfffe,
EndOfHobList = 0xffff,
}
impl Default for HobType {
fn default() -> Self {
HobType::Unused
}
}
#[repr(C)]
#[derive(Copy, Clone, Default, Debug)]
struct HobHeader {
r#type: HobType,
length: u16,
reserved: u32,
}
unsafe impl ByteValued for HobHeader {}
#[repr(C)]
#[derive(Copy, Clone, Default, Debug)]
struct HobHandoffInfoTable {
header: HobHeader,
version: u32,
efi_memory_top: u64,
efi_memory_bottom: u64,
efi_free_memory_top: u64,
efi_free_memory_bottom: u64,
efi_end_of_hob_list: u64,
}
unsafe impl ByteValued for HobHandoffInfoTable {}
#[repr(C)]
#[derive(Copy, Clone, Default, Debug)]
struct EfiGuid {
data1: u32,
data2: u16,
data3: u16,
data4: [u8; 8],
}
#[repr(C)]
#[derive(Copy, Clone, Default, Debug)]
struct HobResourceDescriptor {
header: HobHeader,
owner: EfiGuid,
resource_type: u32,
resource_attribute: u32,
physical_start: u64,
resource_length: u64,
}
unsafe impl ByteValued for HobResourceDescriptor {}
pub struct TdHob {
start_offset: u64,
current_offset: u64,
}
fn align_hob(v: u64) -> u64 {
(v + 7) / 8 * 8
}
impl TdHob {
fn update_offset<T>(&mut self) {
self.current_offset = align_hob(self.current_offset + std::mem::size_of::<T>() as u64)
}
pub fn start(offset: u64) -> TdHob {
// Leave a gap to place the HandoffTable at the start as it can only be filled in later
let mut hob = TdHob {
start_offset: offset,
current_offset: offset,
};
hob.update_offset::<HobHandoffInfoTable>();
hob
}
pub fn finish(&mut self, mem: &GuestMemoryMmap) -> Result<(), TdvfError> {
// Write end
let end = HobHeader {
r#type: HobType::EndOfHobList,
length: std::mem::size_of::<HobHeader>() as u16,
reserved: 0,
};
info!("Writing HOB end {:x} {:x?}", self.current_offset, end);
mem.write_obj(end, GuestAddress(self.current_offset))
.map_err(TdvfError::GuestMemoryWriteHob)?;
self.update_offset::<HobHeader>();
// Write handoff, delayed as it needs end of HOB list
let efi_end_of_hob_list = self.current_offset;
let handoff = HobHandoffInfoTable {
header: HobHeader {
r#type: HobType::Handoff,
length: std::mem::size_of::<HobHandoffInfoTable>() as u16,
reserved: 0,
},
version: 0x9,
efi_memory_top: 0,
efi_memory_bottom: 0,
efi_free_memory_top: 0,
efi_free_memory_bottom: 0,
efi_end_of_hob_list,
};
info!("Writing HOB start {:x} {:x?}", self.start_offset, handoff);
mem.write_obj(handoff, GuestAddress(self.start_offset))
.map_err(TdvfError::GuestMemoryWriteHob)
}
pub fn add_resource(
&mut self,
mem: &GuestMemoryMmap,
physical_start: u64,
resource_length: u64,
resource_type: u32,
resource_attribute: u32,
) -> Result<(), TdvfError> {
let resource_descriptor = HobResourceDescriptor {
header: HobHeader {
r#type: HobType::ResourceDescriptor,
length: std::mem::size_of::<HobResourceDescriptor>() as u16,
reserved: 0,
},
owner: EfiGuid::default(),
resource_type,
resource_attribute,
physical_start,
resource_length,
};
info!(
"Writing HOB resource {:x} {:x?}",
self.current_offset, resource_descriptor
);
mem.write_obj(resource_descriptor, GuestAddress(self.current_offset))
.map_err(TdvfError::GuestMemoryWriteHob)?;
self.update_offset::<HobResourceDescriptor>();
Ok(())
}
pub fn add_memory_resource(
&mut self,
mem: &GuestMemoryMmap,
physical_start: u64,
resource_length: u64,
ram: bool,
) -> Result<(), TdvfError> {
self.add_resource(
mem,
physical_start,
resource_length,
if ram {
0 /* EFI_RESOURCE_SYSTEM_MEMORY */
} else {
0x5 /*EFI_RESOURCE_MEMORY_RESERVED */
},
/* TODO:
* QEMU currently fills it in like this:
* EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED
* which differs from the spec (due to TDVF implementation issue?)
*/
0x7,
)
}
pub fn add_mmio_resource(
&mut self,
mem: &GuestMemoryMmap,
physical_start: u64,
resource_length: u64,
) -> Result<(), TdvfError> {
self.add_resource(
mem,
physical_start,
resource_length,
0x1, /* EFI_RESOURCE_MEMORY_MAPPED_IO */
/*
* EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
*/
0x403,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_parse_tdvf_sections() {
let mut f = std::fs::File::open("tdvf.fd").unwrap();
let sections = parse_tdvf_sections(&mut f).unwrap();
for section in sections {
eprintln!("{:x?}", section)
}
}
}

View File

@@ -8,18 +8,7 @@
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[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
)]
#[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;

View File

@@ -67,7 +67,7 @@ fn bindgen_test_layout_mpf_intel() {
concat!("Alignment of ", stringify!(mpf_intel))
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).signature as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -77,7 +77,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).physptr as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).physptr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -87,7 +87,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).length as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).length as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
@@ -97,7 +97,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).specification as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).specification as *const _ as usize },
9usize,
concat!(
"Alignment of field: ",
@@ -107,7 +107,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).checksum as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).checksum as *const _ as usize },
10usize,
concat!(
"Alignment of field: ",
@@ -117,7 +117,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature1 as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).feature1 as *const _ as usize },
11usize,
concat!(
"Alignment of field: ",
@@ -127,7 +127,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature2 as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).feature2 as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
@@ -137,7 +137,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature3 as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).feature3 as *const _ as usize },
13usize,
concat!(
"Alignment of field: ",
@@ -147,7 +147,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature4 as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).feature4 as *const _ as usize },
14usize,
concat!(
"Alignment of field: ",
@@ -157,7 +157,7 @@ fn bindgen_test_layout_mpf_intel() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature5 as *const _ as usize },
unsafe { &(*std::ptr::null::<mpf_intel>()).feature5 as *const _ as usize },
15usize,
concat!(
"Alignment of field: ",
@@ -200,7 +200,7 @@ fn bindgen_test_layout_mpc_table() {
concat!("Alignment of ", stringify!(mpc_table))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).signature as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -210,7 +210,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).length as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).length as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -220,7 +220,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).spec as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).spec as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
@@ -230,7 +230,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).checksum as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).checksum as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
@@ -240,7 +240,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oem as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).oem as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
@@ -250,7 +250,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).productid as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).productid as *const _ as usize },
16usize,
concat!(
"Alignment of field: ",
@@ -260,7 +260,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemptr as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).oemptr as *const _ as usize },
28usize,
concat!(
"Alignment of field: ",
@@ -270,7 +270,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemsize as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).oemsize as *const _ as usize },
32usize,
concat!(
"Alignment of field: ",
@@ -280,7 +280,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemcount as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).oemcount as *const _ as usize },
34usize,
concat!(
"Alignment of field: ",
@@ -290,7 +290,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).lapic as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).lapic as *const _ as usize },
36usize,
concat!(
"Alignment of field: ",
@@ -300,7 +300,7 @@ fn bindgen_test_layout_mpc_table() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).reserved as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_table>()).reserved as *const _ as usize },
40usize,
concat!(
"Alignment of field: ",
@@ -339,7 +339,7 @@ fn bindgen_test_layout_mpc_cpu() {
concat!("Alignment of ", stringify!(mpc_cpu))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).type_ as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -349,7 +349,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).apicid as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).apicid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
@@ -359,7 +359,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).apicver as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).apicver as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
@@ -369,7 +369,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).cpuflag as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).cpuflag as *const _ as usize },
3usize,
concat!(
"Alignment of field: ",
@@ -379,7 +379,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).cpufeature as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).cpufeature as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -389,7 +389,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).featureflag as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).featureflag as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
@@ -399,7 +399,7 @@ fn bindgen_test_layout_mpc_cpu() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).reserved as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_cpu>()).reserved as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
@@ -434,7 +434,7 @@ fn bindgen_test_layout_mpc_bus() {
concat!("Alignment of ", stringify!(mpc_bus))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).type_ as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_bus>()).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -444,7 +444,7 @@ fn bindgen_test_layout_mpc_bus() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).busid as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_bus>()).busid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
@@ -454,7 +454,7 @@ fn bindgen_test_layout_mpc_bus() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).bustype as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_bus>()).bustype as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
@@ -491,7 +491,7 @@ fn bindgen_test_layout_mpc_ioapic() {
concat!("Alignment of ", stringify!(mpc_ioapic))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).type_ as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_ioapic>()).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -501,7 +501,7 @@ fn bindgen_test_layout_mpc_ioapic() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicid as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_ioapic>()).apicid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
@@ -511,7 +511,7 @@ fn bindgen_test_layout_mpc_ioapic() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicver as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_ioapic>()).apicver as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
@@ -521,7 +521,7 @@ fn bindgen_test_layout_mpc_ioapic() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).flags as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_ioapic>()).flags as *const _ as usize },
3usize,
concat!(
"Alignment of field: ",
@@ -531,7 +531,7 @@ fn bindgen_test_layout_mpc_ioapic() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicaddr as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_ioapic>()).apicaddr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -570,7 +570,7 @@ fn bindgen_test_layout_mpc_intsrc() {
concat!("Alignment of ", stringify!(mpc_intsrc))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).type_ as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -580,7 +580,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).irqtype as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).irqtype as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
@@ -590,7 +590,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).irqflag as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).irqflag as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
@@ -600,7 +600,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).srcbus as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).srcbus as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -610,7 +610,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).srcbusirq as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).srcbusirq as *const _ as usize },
5usize,
concat!(
"Alignment of field: ",
@@ -620,7 +620,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).dstapic as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).dstapic as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
@@ -630,7 +630,7 @@ fn bindgen_test_layout_mpc_intsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).dstirq as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_intsrc>()).dstirq as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
@@ -674,7 +674,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
concat!("Alignment of ", stringify!(mpc_lintsrc))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).type_ as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -684,7 +684,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).irqtype as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).irqtype as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
@@ -694,7 +694,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).irqflag as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).irqflag as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
@@ -704,7 +704,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusid as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).srcbusid as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -714,7 +714,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusirq as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).srcbusirq as *const _ as usize },
5usize,
concat!(
"Alignment of field: ",
@@ -724,7 +724,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).destapic as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).destapic as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
@@ -734,7 +734,7 @@ fn bindgen_test_layout_mpc_lintsrc() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).destapiclint as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_lintsrc>()).destapiclint as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
@@ -771,7 +771,7 @@ fn bindgen_test_layout_mpc_oemtable() {
concat!("Alignment of ", stringify!(mpc_oemtable))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).signature as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_oemtable>()).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
@@ -781,7 +781,7 @@ fn bindgen_test_layout_mpc_oemtable() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).length as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_oemtable>()).length as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
@@ -791,7 +791,7 @@ fn bindgen_test_layout_mpc_oemtable() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).rev as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_oemtable>()).rev as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
@@ -801,7 +801,7 @@ fn bindgen_test_layout_mpc_oemtable() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).checksum as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_oemtable>()).checksum as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
@@ -811,7 +811,7 @@ fn bindgen_test_layout_mpc_oemtable() {
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).mpc as *const _ as usize },
unsafe { &(*std::ptr::null::<mpc_oemtable>()).mpc as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",

24
block_util/Cargo.toml Normal file
View File

@@ -0,0 +1,24 @@
[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.91"
log = "0.4.14"
qcow = { path = "../qcow" }
serde = ">=1.0.27"
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
thiserror = "1.0"
virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]}
vm-memory = { version = "0.5.0", features = ["backend-mmap", "backend-atomic"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1"

View File

@@ -0,0 +1,56 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
#[derive(Error, Debug)]
pub enum DiskFileError {
/// Failed getting disk file size.
#[error("Failed getting disk file size: {0}")]
Size(#[source] std::io::Error),
/// Failed creating a new AsyncIo.
#[error("Failed creating a new AsyncIo: {0}")]
NewAsyncIo(#[source] std::io::Error),
}
pub type DiskFileResult<T> = std::result::Result<T, DiskFileError>;
pub trait DiskFile: Send + Sync {
fn size(&mut self) -> DiskFileResult<u64>;
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>>;
}
#[derive(Error, Debug)]
pub enum AsyncIoError {
/// Failed vectored reading from file.
#[error("Failed vectored reading from file: {0}")]
ReadVectored(#[source] std::io::Error),
/// Failed vectored writing to file.
#[error("Failed vectored writing to file: {0}")]
WriteVectored(#[source] std::io::Error),
/// Failed synchronizing file.
#[error("Failed synchronizing file: {0}")]
Fsync(#[source] std::io::Error),
}
pub type AsyncIoResult<T> = std::result::Result<T, AsyncIoError>;
pub trait AsyncIo: Send + Sync {
fn notifier(&self) -> &EventFd;
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()>;
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()>;
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()>;
fn complete(&mut self) -> Vec<(u64, i32)>;
}

View File

@@ -0,0 +1,110 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::raw_async::RawFileAsync;
use crate::vhd::VhdFooter;
use std::fs::File;
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
pub struct FixedVhdDiskAsync {
file: File,
size: u64,
}
impl FixedVhdDiskAsync {
pub fn new(mut file: File) -> std::io::Result<Self> {
let footer = VhdFooter::new(&mut file)?;
Ok(FixedVhdDiskAsync {
file,
size: footer.current_size(),
})
}
}
impl DiskFile for FixedVhdDiskAsync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self.size)
}
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
FixedVhdAsync::new(self.file.as_raw_fd(), ring_depth, self.size)
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
}
pub struct FixedVhdAsync {
raw_file_async: RawFileAsync,
size: u64,
}
impl FixedVhdAsync {
pub fn new(fd: RawFd, ring_depth: u32, size: u64) -> std::io::Result<Self> {
let raw_file_async = RawFileAsync::new(fd, ring_depth)?;
Ok(FixedVhdAsync {
raw_file_async,
size,
})
}
}
impl AsyncIo for FixedVhdAsync {
fn notifier(&self) -> &EventFd {
self.raw_file_async.notifier()
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::ReadVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_async.read_vectored(offset, iovecs, user_data)
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::WriteVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_async
.write_vectored(offset, iovecs, user_data)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
self.raw_file_async.fsync(user_data)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.raw_file_async.complete()
}
}

View File

@@ -0,0 +1,107 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::raw_sync::RawFileSync;
use crate::vhd::VhdFooter;
use std::fs::File;
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
pub struct FixedVhdDiskSync {
file: File,
size: u64,
}
impl FixedVhdDiskSync {
pub fn new(mut file: File) -> std::io::Result<Self> {
let footer = VhdFooter::new(&mut file)?;
Ok(FixedVhdDiskSync {
file,
size: footer.current_size(),
})
}
}
impl DiskFile for FixedVhdDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self.size)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
FixedVhdSync::new(self.file.as_raw_fd(), self.size)
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
}
pub struct FixedVhdSync {
raw_file_sync: RawFileSync,
size: u64,
}
impl FixedVhdSync {
pub fn new(fd: RawFd, size: u64) -> std::io::Result<Self> {
Ok(FixedVhdSync {
raw_file_sync: RawFileSync::new(fd),
size,
})
}
}
impl AsyncIo for FixedVhdSync {
fn notifier(&self) -> &EventFd {
self.raw_file_sync.notifier()
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::ReadVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_sync.read_vectored(offset, iovecs, user_data)
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::WriteVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_sync.write_vectored(offset, iovecs, user_data)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
self.raw_file_sync.fsync(user_data)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.raw_file_sync.complete()
}
}

701
block_util/src/lib.rs Normal file
View File

@@ -0,0 +1,701 @@
// 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;
pub mod async_io;
pub mod fixed_vhd_async;
pub mod fixed_vhd_sync;
pub mod qcow_sync;
pub mod raw_async;
pub mod raw_sync;
pub mod vhd;
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, DiskFileError, DiskFileResult};
#[cfg(feature = "io_uring")]
use io_uring::{opcode, IoUring, Probe};
use serde::ser::{Serialize, SerializeStruct, Serializer};
use std::cmp;
use std::convert::TryInto;
use std::fs::File;
use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use std::os::linux::fs::MetadataExt;
#[cfg(feature = "io_uring")]
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::result;
use std::sync::{Arc, Mutex};
use virtio_bindings::bindings::virtio_blk::*;
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
use vm_virtio::DescriptorChain;
use vmm_sys_util::eventfd::EventFd;
const SECTOR_SHIFT: u8 = 9;
pub const SECTOR_SIZE: u64 = 0x01 << 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: &Path) -> 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: &Path) -> 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),
AsyncRead(AsyncIoError),
AsyncWrite(AsyncIoError),
AsyncFlush(AsyncIoError),
}
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,
ExecuteError::AsyncRead(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::AsyncWrite(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::AsyncFlush(_) => 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)
}
#[derive(Debug)]
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)
.map_err(|e| {
error!("Only head descriptor present: request = {:?}", req);
e
})?;
if !desc.has_next() {
status_desc = desc;
// Only flush requests are allowed to skip the data descriptor.
if req.request_type != RequestType::Flush {
error!("Need a data descriptor: request = {:?}", req);
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)
.map_err(|e| {
error!("DescriptorChain corrupted: request = {:?}", req);
e
})?;
}
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)
}
pub fn execute_async(
&self,
mem: &GuestMemoryMmap,
disk_nsectors: u64,
disk_image: &mut dyn AsyncIo,
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 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 => {
disk_image
.read_vectored(offset, iovecs, user_data)
.map_err(ExecuteError::AsyncRead)?;
}
RequestType::Out => {
disk_image
.write_vectored(offset, iovecs, user_data)
.map_err(ExecuteError::AsyncWrite)?;
}
RequestType::Flush => {
disk_image
.fsync(Some(user_data))
.map_err(ExecuteError::AsyncFlush)?;
}
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)),
}
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
}
#[cfg(not(feature = "io_uring"))]
pub fn block_io_uring_is_supported() -> bool {
false
}
pub fn disk_size(file: &mut dyn Seek, semaphore: &mut Arc<Mutex<()>>) -> DiskFileResult<u64> {
// Take the semaphore to ensure other threads are not interacting with
// the underlying file.
let _lock = semaphore.lock().unwrap();
Ok(file.seek(SeekFrom::End(0)).map_err(DiskFileError::Size)? as u64)
}
pub trait ReadSeekFile: Read + Seek {}
impl<F: Read + Seek> ReadSeekFile for F {}
pub fn read_vectored_sync(
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
file: &mut dyn ReadSeekFile,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSliceMut
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSliceMut::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?;
// Read vectored
file.read_vectored(slices.as_mut_slice())
.map_err(AsyncIoError::ReadVectored)?
};
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
pub trait WriteSeekFile: Write + Seek {}
impl<F: Write + Seek> WriteSeekFile for F {}
pub fn write_vectored_sync(
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
file: &mut dyn WriteSeekFile,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
// Convert libc::iovec into IoSlice
let mut slices = Vec::new();
for iovec in iovecs.iter() {
slices.push(IoSlice::new(unsafe { std::mem::transmute(*iovec) }));
}
let result = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Move the cursor to the right offset
file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?;
// Write vectored
file.write_vectored(slices.as_slice())
.map_err(AsyncIoError::WriteVectored)?
};
completion_list.push((user_data, result as i32));
eventfd.write(1).unwrap();
Ok(())
}
pub fn fsync_sync(
user_data: Option<u64>,
file: &mut dyn Write,
eventfd: &EventFd,
completion_list: &mut Vec<(u64, i32)>,
semaphore: &mut Arc<Mutex<()>>,
) -> AsyncIoResult<()> {
let result: i32 = {
// Take the semaphore to ensure other threads are not interacting
// with the underlying file.
let _lock = semaphore.lock().unwrap();
// Flush
file.flush().map_err(AsyncIoError::Fsync)?;
0
};
if let Some(user_data) = user_data {
completion_list.push((user_data, result));
eventfd.write(1).unwrap();
}
Ok(())
}
pub enum ImageType {
FixedVhd,
Qcow2,
Raw,
}
const QCOW_MAGIC: u32 = 0x5146_49fb;
/// Determine image type through file parsing.
pub fn detect_image_type(f: &mut File) -> std::io::Result<ImageType> {
// We must create a buffer aligned on 512 bytes with a size being a
// multiple of 512 bytes as the file might be opened with O_DIRECT flag.
#[repr(align(512))]
struct Sector {
data: [u8; 512],
}
let mut s = Sector { data: [0; 512] };
f.read_exact(&mut s.data)?;
// Check 4 first bytes to get the header value and determine the image type
let image_type = if u32::from_be_bytes(s.data[0..4].try_into().unwrap()) == QCOW_MAGIC {
ImageType::Qcow2
} else if vhd::is_fixed_vhd(f)? {
ImageType::FixedVhd
} else {
ImageType::Raw
};
Ok(image_type)
}

111
block_util/src/qcow_sync.rs Normal file
View File

@@ -0,0 +1,111 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileResult};
use crate::{disk_size, fsync_sync, read_vectored_sync, write_vectored_sync};
use qcow::{QcowFile, RawFile};
use std::fs::File;
use std::sync::{Arc, Mutex};
use vmm_sys_util::eventfd::EventFd;
pub struct QcowDiskSync {
qcow_file: QcowFile,
semaphore: Arc<Mutex<()>>,
}
impl QcowDiskSync {
pub fn new(file: File, direct_io: bool) -> Self {
QcowDiskSync {
qcow_file: QcowFile::from(RawFile::new(file, direct_io))
.expect("Failed creating QcowFile"),
semaphore: Arc::new(Mutex::new(())),
}
}
}
impl DiskFile for QcowDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
disk_size(&mut self.qcow_file, &mut self.semaphore)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(QcowSync::new(
self.qcow_file.clone(),
self.semaphore.clone(),
)) as Box<dyn AsyncIo>)
}
}
pub struct QcowSync {
qcow_file: QcowFile,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
semaphore: Arc<Mutex<()>>,
}
impl QcowSync {
pub fn new(qcow_file: QcowFile, semaphore: Arc<Mutex<()>>) -> Self {
QcowSync {
qcow_file,
eventfd: EventFd::new(libc::EFD_NONBLOCK)
.expect("Failed creating EventFd for QcowSync"),
completion_list: Vec::new(),
semaphore,
}
}
}
impl AsyncIo for QcowSync {
fn notifier(&self) -> &EventFd {
&self.eventfd
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
read_vectored_sync(
offset,
iovecs,
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
write_vectored_sync(
offset,
iovecs,
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
fsync_sync(
user_data,
&mut self.qcow_file,
&self.eventfd,
&mut self.completion_list,
&mut self.semaphore,
)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.completion_list.drain(..).collect()
}
}

159
block_util/src/raw_async.rs Normal file
View File

@@ -0,0 +1,159 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use io_uring::{opcode, squeue, types, IoUring};
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
pub struct RawFileDisk {
file: File,
}
impl RawFileDisk {
pub fn new(file: File) -> Self {
RawFileDisk { file }
}
}
impl DiskFile for RawFileDisk {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self
.file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)? as u64)
}
fn new_async_io(&self, ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
RawFileAsync::new(self.file.as_raw_fd(), ring_depth)
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
}
pub struct RawFileAsync {
fd: RawFd,
io_uring: IoUring,
eventfd: EventFd,
}
impl RawFileAsync {
pub fn new(fd: RawFd, ring_depth: u32) -> std::io::Result<Self> {
let io_uring = IoUring::new(ring_depth)?;
let eventfd = EventFd::new(libc::EFD_NONBLOCK)?;
// Register the io_uring eventfd that will notify when something in
// the completion queue is ready.
io_uring.submitter().register_eventfd(eventfd.as_raw_fd())?;
Ok(RawFileAsync {
fd,
io_uring,
eventfd,
})
}
}
impl AsyncIo for RawFileAsync {
fn notifier(&self) -> &EventFd {
&self.eventfd
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
sq.push(
&opcode::Readv::new(types::Fd(self.fd), iovecs.as_ptr(), iovecs.len() as u32)
.offset(offset)
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
// Update the submission queue and submit new operations to the
// io_uring instance.
sq.sync();
submitter.submit().map_err(AsyncIoError::ReadVectored)?;
Ok(())
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid and we
// relied on vm-memory to provide the buffer address.
let _ = unsafe {
sq.push(
&opcode::Writev::new(types::Fd(self.fd), iovecs.as_ptr(), iovecs.len() as u32)
.offset(offset)
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
// Update the submission queue and submit new operations to the
// io_uring instance.
sq.sync();
submitter.submit().map_err(AsyncIoError::WriteVectored)?;
Ok(())
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
if let Some(user_data) = user_data {
let (submitter, mut sq, _) = self.io_uring.split();
// Safe because we know the file descriptor is valid.
let _ = unsafe {
sq.push(
&opcode::Fsync::new(types::Fd(self.fd))
.build()
.flags(squeue::Flags::ASYNC)
.user_data(user_data),
)
};
// Update the submission queue and submit new operations to the
// io_uring instance.
sq.sync();
submitter.submit().map_err(AsyncIoError::Fsync)?;
} else {
unsafe { libc::fsync(self.fd) };
}
Ok(())
}
fn complete(&mut self) -> Vec<(u64, i32)> {
let mut completion_list = Vec::new();
let cq = self.io_uring.completion();
for cq_entry in cq {
completion_list.push((cq_entry.user_data(), cq_entry.result()));
}
completion_list
}
}

122
block_util/src/raw_sync.rs Normal file
View File

@@ -0,0 +1,122 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use std::fs::File;
use std::io::{Seek, SeekFrom};
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
pub struct RawFileDiskSync {
file: File,
}
impl RawFileDiskSync {
pub fn new(file: File) -> Self {
RawFileDiskSync { file }
}
}
impl DiskFile for RawFileDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self
.file
.seek(SeekFrom::End(0))
.map_err(DiskFileError::Size)? as u64)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(RawFileSync::new(self.file.as_raw_fd())) as Box<dyn AsyncIo>)
}
}
pub struct RawFileSync {
fd: RawFd,
eventfd: EventFd,
completion_list: Vec<(u64, i32)>,
}
impl RawFileSync {
pub fn new(fd: RawFd) -> Self {
RawFileSync {
fd,
eventfd: EventFd::new(libc::EFD_NONBLOCK).expect("Failed creating EventFd for RawFile"),
completion_list: Vec::new(),
}
}
}
impl AsyncIo for RawFileSync {
fn notifier(&self) -> &EventFd {
&self.eventfd
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
let result = unsafe {
libc::preadv(
self.fd as libc::c_int,
iovecs.as_ptr() as *const libc::iovec,
iovecs.len() as libc::c_int,
offset,
)
};
if result < 0 {
return Err(AsyncIoError::ReadVectored(std::io::Error::last_os_error()));
}
self.completion_list.push((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
let result = unsafe {
libc::pwritev(
self.fd as libc::c_int,
iovecs.as_ptr() as *const libc::iovec,
iovecs.len() as libc::c_int,
offset,
)
};
if result < 0 {
return Err(AsyncIoError::WriteVectored(std::io::Error::last_os_error()));
}
self.completion_list.push((user_data, result as i32));
self.eventfd.write(1).unwrap();
Ok(())
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
let result = unsafe { libc::fsync(self.fd as libc::c_int) };
if result < 0 {
return Err(AsyncIoError::Fsync(std::io::Error::last_os_error()));
}
if let Some(user_data) = user_data {
self.completion_list.push((user_data, result as i32));
self.eventfd.write(1).unwrap();
}
Ok(())
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.completion_list.drain(..).collect()
}
}

221
block_util/src/vhd.rs Normal file
View File

@@ -0,0 +1,221 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryInto;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
#[derive(Clone, Copy)]
pub struct VhdFooter {
cookie: u64,
features: u32,
file_format_version: u32,
data_offset: u64,
time_stamp: u32,
creator_application: u32,
creator_version: u32,
creator_host_os: u32,
original_size: u64,
current_size: u64,
disk_geometry: u32,
disk_type: u32,
checksum: u32,
unique_id: u128,
saved_state: u8,
}
impl VhdFooter {
pub fn new(file: &mut File) -> std::io::Result<VhdFooter> {
// We must create a buffer aligned on 512 bytes with a size being a
// multiple of 512 bytes as the file might be opened with O_DIRECT flag.
#[repr(align(512))]
struct Sector {
data: [u8; 512],
}
let mut s = Sector { data: [0; 512] };
// Place the cursor 512 bytes before the end of the file, as this is
// where the footer starts.
file.seek(SeekFrom::End(-512))?;
// Fill in the VhdFooter structure
file.read_exact(&mut s.data)?;
Ok(VhdFooter {
cookie: u64::from_be_bytes(s.data[0..8].try_into().unwrap()),
features: u32::from_be_bytes(s.data[8..12].try_into().unwrap()),
file_format_version: u32::from_be_bytes(s.data[12..16].try_into().unwrap()),
data_offset: u64::from_be_bytes(s.data[16..24].try_into().unwrap()),
time_stamp: u32::from_be_bytes(s.data[24..28].try_into().unwrap()),
creator_application: u32::from_be_bytes(s.data[28..32].try_into().unwrap()),
creator_version: u32::from_be_bytes(s.data[32..36].try_into().unwrap()),
creator_host_os: u32::from_be_bytes(s.data[36..40].try_into().unwrap()),
original_size: u64::from_be_bytes(s.data[40..48].try_into().unwrap()),
current_size: u64::from_be_bytes(s.data[48..56].try_into().unwrap()),
disk_geometry: u32::from_be_bytes(s.data[56..60].try_into().unwrap()),
disk_type: u32::from_be_bytes(s.data[60..64].try_into().unwrap()),
checksum: u32::from_be_bytes(s.data[64..68].try_into().unwrap()),
unique_id: u128::from_be_bytes(s.data[68..84].try_into().unwrap()),
saved_state: u8::from_be_bytes(s.data[84..85].try_into().unwrap()),
})
}
pub fn cookie(&self) -> u64 {
self.cookie
}
pub fn features(&self) -> u32 {
self.features
}
pub fn file_format_version(&self) -> u32 {
self.file_format_version
}
pub fn data_offset(&self) -> u64 {
self.data_offset
}
pub fn time_stamp(&self) -> u32 {
self.time_stamp
}
pub fn creator_application(&self) -> u32 {
self.creator_application
}
pub fn creator_version(&self) -> u32 {
self.creator_version
}
pub fn creator_host_os(&self) -> u32 {
self.creator_host_os
}
pub fn original_size(&self) -> u64 {
self.original_size
}
pub fn current_size(&self) -> u64 {
self.current_size
}
pub fn disk_geometry(&self) -> u32 {
self.disk_geometry
}
pub fn disk_type(&self) -> u32 {
self.disk_type
}
pub fn checksum(&self) -> u32 {
self.checksum
}
pub fn unique_id(&self) -> u128 {
self.unique_id
}
pub fn saved_state(&self) -> u8 {
self.saved_state
}
}
/// Determine image type through file parsing.
pub fn is_fixed_vhd(f: &mut File) -> std::io::Result<bool> {
let footer = VhdFooter::new(f)?;
// "conectix" => 0x636f6e6563746978
Ok(footer.cookie() == 0x636f6e6563746978
&& footer.file_format_version() == 0x0001_0000
&& footer.data_offset() == 0xffff_ffff_ffff_ffff
&& footer.disk_type() == 0x2)
}
#[cfg(test)]
mod tests {
use super::{is_fixed_vhd, VhdFooter};
use std::fs::File;
use std::io::{Seek, SeekFrom, Write};
use vmm_sys_util::tempfile::TempFile;
fn valid_fixed_vhd_footer() -> Vec<u8> {
vec![
0x63, 0x6f, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x78, // cookie
0x00, 0x00, 0x00, 0x02, // features
0x00, 0x01, 0x00, 0x00, // file format version
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // data offset
0x27, 0xa6, 0xa6, 0x5d, // time stamp
0x71, 0x65, 0x6d, 0x75, // creator application
0x00, 0x05, 0x00, 0x03, // creator version
0x57, 0x69, 0x32, 0x6b, // creator host os
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // original size
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // current size
0x11, 0xe0, 0x10, 0x3f, // disk geometry
0x00, 0x00, 0x00, 0x02, // disk type
0x00, 0x00, 0x00, 0x00, // checksum
0x98, 0x7b, 0xb1, 0xcd, 0x84, 0x14, 0x41, 0xfc, 0xa4, 0xab, 0xd0, 0x69, 0x45, 0x2b,
0xf2, 0x23, // unique id
0x00, // saved state
]
}
fn valid_dynamic_vhd_footer() -> Vec<u8> {
vec![
0x63, 0x6f, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x78, // cookie
0x00, 0x00, 0x00, 0x02, // features
0x00, 0x01, 0x00, 0x00, // file format version
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // data offset
0x27, 0xa6, 0xa6, 0x5d, // time stamp
0x71, 0x65, 0x6d, 0x75, // creator application
0x00, 0x05, 0x00, 0x03, // creator version
0x57, 0x69, 0x32, 0x6b, // creator host os
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // original size
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // current size
0x11, 0xe0, 0x10, 0x3f, // disk geometry
0x00, 0x00, 0x00, 0x03, // disk type
0x00, 0x00, 0x00, 0x00, // checksum
0x98, 0x7b, 0xb1, 0xcd, 0x84, 0x14, 0x41, 0xfc, 0xa4, 0xab, 0xd0, 0x69, 0x45, 0x2b,
0xf2, 0x23, // unique id
0x00, // saved state
]
}
fn with_file<F>(footer: &[u8], mut testfn: F)
where
F: FnMut(File),
{
let mut disk_file: File = TempFile::new().unwrap().into_file();
disk_file.set_len(0x1000_0200).unwrap();
disk_file.seek(SeekFrom::Start(0x1000_0000)).unwrap();
disk_file.write_all(&footer).unwrap();
testfn(disk_file); // File closed when the function exits.
}
#[test]
fn test_check_vhd_footer() {
with_file(&valid_fixed_vhd_footer(), |mut file: File| {
let vhd_footer = VhdFooter::new(&mut file).expect("Failed to create VHD footer");
assert_eq!(vhd_footer.cookie(), 0x636f_6e65_6374_6978);
assert_eq!(vhd_footer.features(), 0x0000_0002);
assert_eq!(vhd_footer.file_format_version(), 0x0001_0000);
assert_eq!(vhd_footer.data_offset(), 0xffff_ffff_ffff_ffff);
assert_eq!(vhd_footer.time_stamp(), 0x27a6_a65d);
assert_eq!(vhd_footer.creator_application(), 0x7165_6d75);
assert_eq!(vhd_footer.creator_version(), 0x0005_0003);
assert_eq!(vhd_footer.creator_host_os(), 0x5769_326b);
assert_eq!(vhd_footer.original_size(), 0x0000_0000_1000_0000);
assert_eq!(vhd_footer.current_size(), 0x0000_0000_1000_0000);
assert_eq!(vhd_footer.disk_geometry(), 0x11e0_103f);
assert_eq!(vhd_footer.disk_type(), 0x0000_0002);
assert_eq!(vhd_footer.checksum(), 0x0000_0000);
assert_eq!(
vhd_footer.unique_id(),
0x987b_b1cd_8414_41fc_a4ab_d069_452b_f223
);
assert_eq!(vhd_footer.saved_state(), 0x00);
});
}
#[test]
fn test_is_fixed_vhd() {
with_file(&valid_fixed_vhd_footer(), |mut file: File| {
assert!(is_fixed_vhd(&mut file).unwrap());
});
}
#[test]
fn test_is_not_fixed_vhd() {
with_file(&valid_dynamic_vhd_footer(), |mut file: File| {
assert!(!(is_fixed_vhd(&mut file).unwrap()));
});
}
}

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 = "v".to_owned() + crate_version!();
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,19 +4,23 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
anyhow = "1.0"
bitflags = ">=1.2.1"
byteorder = "1.3.4"
byteorder = "1.4.3"
epoll = ">=4.0.1"
libc = "0.2.60"
log = "0.4.8"
libc = "0.2.91"
log = "0.4.14"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vm-device = { path = "../vm-device" }
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
acpi_tables = { path = "../acpi_tables", optional = true }
vm-memory = "0.5.0"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = ">=0.3.1"
[dev-dependencies]
tempfile = "3.1.0"
[features]
default = []
acpi = []
acpi = ["acpi_tables"]
cmos = []
fwdebug = []

View File

@@ -3,11 +3,16 @@
// SPDX-License-Identifier: Apache-2.0
//
use std::sync::Arc;
use acpi_tables::{aml, aml::Aml};
use std::sync::{Arc, Barrier};
use std::time::Instant;
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_memory::GuestAddress;
use vmm_sys_util::eventfd::EventFd;
use BusDevice;
use HotPlugNotificationFlags;
use AcpiNotificationFlags;
pub const GED_DEVICE_ACPI_SIZE: usize = 0x1;
/// A device for handling ACPI shutdown and reboot
pub struct AcpiShutdownDevice {
@@ -34,7 +39,7 @@ impl BusDevice for AcpiShutdownDevice {
}
}
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) {
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data[0] == 1 {
debug!("ACPI Reboot signalled");
if let Err(e) = self.reset_evt.write(1) {
@@ -52,28 +57,35 @@ impl BusDevice for AcpiShutdownDevice {
error!("Error triggering ACPI shutdown event: {}", e);
}
}
None
}
}
/// A device for handling ACPI GED event generation
pub struct AcpiGEDDevice {
pub struct AcpiGedDevice {
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
notification_type: HotPlugNotificationFlags,
notification_type: AcpiNotificationFlags,
ged_irq: u32,
address: GuestAddress,
}
impl AcpiGEDDevice {
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>, ged_irq: u32) -> AcpiGEDDevice {
AcpiGEDDevice {
impl AcpiGedDevice {
pub fn new(
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
ged_irq: u32,
address: GuestAddress,
) -> AcpiGedDevice {
AcpiGedDevice {
interrupt,
notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED,
notification_type: AcpiNotificationFlags::NO_DEVICES_CHANGED,
ged_irq,
address,
}
}
pub fn notify(
&mut self,
notification_type: HotPlugNotificationFlags,
notification_type: AcpiNotificationFlags,
) -> Result<(), std::io::Error> {
self.notification_type |= notification_type;
self.interrupt.trigger(0)
@@ -85,12 +97,111 @@ impl AcpiGEDDevice {
}
// I/O port reports what type of notification was made
impl BusDevice for AcpiGEDDevice {
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;
self.notification_type = AcpiNotificationFlags::NO_DEVICES_CHANGED;
}
}
#[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::SystemMemory,
self.address.0 as usize,
GED_DEVICE_ACPI_SIZE,
),
&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![])],
),
&aml::And::new(&aml::Local(1), &aml::Local(0), &8usize),
&aml::If::new(
&aml::Equal::new(&aml::Local(1), &8usize),
vec![&aml::Notify::new(
&aml::Path::new("\\_SB_.PWRB"),
&0x80usize,
)],
),
],
),
],
)
.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]) {}
}

86
devices/src/gic.rs Normal file
View File

@@ -0,0 +1,86 @@
// 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, InterruptSourceConfig, InterruptSourceGroup,
LegacyIrqSourceConfig, MsiIrqGroupConfig,
};
use vmm_sys_util::eventfd::EventFd;
type Result<T> = result::Result<T, Error>;
// Reserve 32 IRQs for legacy device.
pub const IRQ_LEGACY_BASE: usize = 0;
pub const IRQ_LEGACY_COUNT: usize = 32;
// This Gic struct implements InterruptController to provide interrupt delivery service.
// The Gic source files in arch/ folder maintain the Aarch64 specific Gic device.
// The 2 Gic instances could be merged together.
// Leave this refactoring to future. Two options may be considered:
// 1. Move Gic*.rs from arch/ folder here.
// 2. Move this file and ioapic.rs to arch/, as they are architecture specific.
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_LEGACY_BASE 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<()> {
// Set irqfd for legacy interrupts
self.interrupt_source_group
.enable()
.map_err(Error::EnableInterrupt)?;
// Set irq_routing for legacy interrupts.
// irqchip: Hardcode to 0 as we support only 1 GIC
// pin: Use irq number as pin
for i in IRQ_LEGACY_BASE..(IRQ_LEGACY_BASE + IRQ_LEGACY_COUNT) {
let config = LegacyIrqSourceConfig {
irqchip: 0,
pin: i as u32,
};
self.interrupt_source_group
.update(
i as InterruptIndex,
InterruptSourceConfig::LegacyIrq(config),
)
.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(())
}
fn notifier(&self, irq: usize) -> Option<EventFd> {
self.interrupt_source_group.notifier(irq as InterruptIndex)
}
}

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;
use vmm_sys_util::eventfd::EventFd;
#[derive(Debug)]
pub enum Error {
/// 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);
fn notifier(&self, irq: usize) -> Option<EventFd>;
}

View File

@@ -9,38 +9,26 @@
// 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 std::io;
use std::result;
use std::sync::Arc;
use std::sync::{Arc, Barrier};
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,
};
use vmm_sys_util::eventfd::EventFd;
#[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),
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "GuestAddress")]
pub struct GuestAddressDef(pub u64);
type Result<T> = result::Result<T, Error>;
@@ -80,10 +68,12 @@ fn trigger_mode(entry: RedirectionTableEntry) -> u8 {
fn interrupt_mask(entry: RedirectionTableEntry) -> u8 {
((entry >> 16) & 0x1u64) as u8
}
fn destination_field_physical(entry: RedirectionTableEntry) -> u8 {
((entry >> 56) & 0xfu64) as u8
}
fn destination_field_logical(entry: RedirectionTableEntry) -> u8 {
fn destination_field(entry: RedirectionTableEntry) -> u8 {
// When the destination mode is physical, the destination field should only
// be defined through bits 56-59, as defined in the IOAPIC specification.
// But from the APIC specification, the APIC ID is always defined on 8 bits
// no matter which destination mode is selected. That's why we always
// retrieve the destination field based on bits 56-63.
((entry >> 56) & 0xffu64) as u8
}
fn set_delivery_status(entry: &mut RedirectionTableEntry, val: u8) {
@@ -99,25 +89,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;
@@ -132,12 +103,6 @@ const IOWIN_OFF: u8 = 0x10;
const IOWIN_SCALE: u8 = 0x2;
const REG_MAX_OFFSET: u8 = IOWIN_OFF + (NUM_IOAPIC_PINS as u8 * 2) - 1;
#[repr(u8)]
enum DestinationMode {
Physical = 0,
Logical = 1,
}
#[repr(u8)]
enum TriggerMode {
Edge = 0,
@@ -148,9 +113,9 @@ enum TriggerMode {
enum DeliveryMode {
Fixed = 0b000,
Lowest = 0b001,
SMI = 0b010, // System management interrupt
Smi = 0b010, // System management interrupt
RemoteRead = 0b011, // This is no longer supported by intel.
NMI = 0b100, // Non maskable interrupt
Nmi = 0b100, // Non maskable interrupt
Init = 0b101,
Startup = 0b110,
External = 0b111,
@@ -166,13 +131,25 @@ 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],
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 {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
assert!(data.len() == 4);
@@ -191,7 +168,7 @@ impl BusDevice for Ioapic {
LittleEndian::write_u32(data, value);
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
assert!(data.len() == 4);
debug!("IOAPIC_W @ offset 0x{:x}", offset);
@@ -205,63 +182,123 @@ impl BusDevice for Ioapic {
error!("IOAPIC: failed writing at offset {}", offset);
}
}
None
}
}
impl Ioapic {
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,
base: 0,
count: NUM_IOAPIC_PINS as InterruptIndex,
})
.map_err(Error::CreateInterruptSourceGroup)?;
interrupt_source_group
.enable()
.map_err(Error::EnableInterrupt)?;
// The IOAPIC is created with entries already masked. The guest will be
// in charge of unmasking them if/when necessary.
Ok(Ioapic {
id: 0,
id,
id_reg: 0,
reg_sel: 0,
reg_entries: [0; NUM_IOAPIC_PINS],
reg_entries: [0x10000; NUM_IOAPIC_PINS],
used_entries: [false; NUM_IOAPIC_PINS],
apic_address,
interrupt_source_group,
})
}
// 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);
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_VERSION => {
if val == 0 {
// Windows writes zero here (see #1791)
} else {
error!(
"IOAPIC: invalid write to version register (0x{:x}): 0x{:x}",
self.reg_sel, val
);
}
}
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 {
self.reg_entries[index] &= 0xffff_ffff;
self.reg_entries[index] |= u64::from(val) << 32;
} else {
// Ensure not to override read-only bits:
// - Delivery Status (bit 12)
// - Remote IRR (bit 14)
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 0x{:x}",
self.reg_sel
),
}
}
fn ioapic_read(&self) -> u32 {
debug!("IOAPIC_R reg 0x{:x}", self.reg_sel);
match self.reg_sel as u8 {
IOAPIC_REG_VERSION => IOAPIC_VERSION_ID,
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 {
(self.reg_entries[index] >> 32) as u32
} else {
(self.reg_entries[index] & 0xffff_ffff) as u32
}
}
_ => {
error!(
"IOAPIC: invalid read from register offset 0x{:x}",
self.reg_sel
);
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];
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);
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)?;
}
}
// Clear the Delivery Status bit
set_delivery_status(entry, 0);
Ok(())
}
@@ -271,11 +308,7 @@ impl Ioapic {
// 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),
};
let destination_id = destination_field(entry);
// When this bit is set, the message is directed to the processor with
// the lowest interrupt priority among processors that can receive the
@@ -300,9 +333,9 @@ impl Ioapic {
match delivery_mode {
x if (x == DeliveryMode::Fixed as u8)
|| (x == DeliveryMode::Lowest as u8)
|| (x == DeliveryMode::SMI as u8)
|| (x == DeliveryMode::Smi as u8)
|| (x == DeliveryMode::RemoteRead as u8)
|| (x == DeliveryMode::NMI as u8)
|| (x == DeliveryMode::Nmi as u8)
|| (x == DeliveryMode::Init as u8)
|| (x == DeliveryMode::Startup as u8)
|| (x == DeliveryMode::External as u8) => {}
@@ -319,6 +352,7 @@ impl Ioapic {
high_addr: 0x0,
low_addr,
data,
devid: 0,
};
self.interrupt_source_group
@@ -337,52 +371,88 @@ impl Ioapic {
Ok(())
}
}
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,
IOWIN_OFF..=REG_MAX_OFFSET => {
let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8);
if is_high_bits {
self.reg_entries[index] &= 0xffff_ffff;
self.reg_entries[index] |= u64::from(val) << 32;
} else {
// Ensure not to override read-only bits:
// - Delivery Status (bit 12)
// - Remote IRR (bit 14)
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);
}
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);
}
_ => error!("IOAPIC: invalid write to register offset"),
}
}
fn ioapic_read(&self) -> u32 {
debug!("IOAPIC_R reg 0x{:x}", self.reg_sel);
// 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];
match self.reg_sel as u8 {
IOAPIC_REG_VERSION => IOAPIC_VERSION_ID,
IOAPIC_REG_ID | IOAPIC_REG_ARBITRATION_ID => (self.id & 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 {
(self.reg_entries[index] >> 32) as u32
} else {
(self.reg_entries[index] & 0xffff_ffff) as u32
}
}
_ => {
error!("IOAPIC: invalid read from register offset");
0
}
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(())
}
fn notifier(&self, irq: usize) -> Option<EventFd> {
self.interrupt_source_group.notifier(irq as InterruptIndex)
}
}
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 {}

View File

@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use libc::{gmtime_r, time, time_t, tm};
use libc::{clock_gettime, gmtime_r, time_t, timespec, tm, CLOCK_REALTIME};
use std::cmp::min;
use std::mem;
use crate::BusDevice;
use std::sync::{Arc, Barrier};
use vm_device::BusDevice;
const INDEX_MASK: u8 = 0x7f;
const INDEX_OFFSET: u64 = 0x0;
@@ -45,16 +45,17 @@ impl Cmos {
}
impl BusDevice for Cmos {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data.len() != 1 {
return;
return None;
}
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),
}
};
None
}
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
@@ -77,14 +78,17 @@ impl BusDevice for Cmos {
let day;
let month;
let year;
// The time 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
// struct because it contains only plain data.
unsafe {
// 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();
let mut now: time_t = 0;
time(&mut now as *mut _);
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;
@@ -93,6 +97,11 @@ impl BusDevice for Cmos {
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),
@@ -102,6 +111,8 @@ impl BusDevice for Cmos {
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.

View File

@@ -0,0 +1,43 @@
// 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 std::sync::{Arc, Barrier};
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]) -> Option<Arc<Barrier>> {
if data.len() == 1 {
print!("{}", data[0] as char);
} else {
error!("Invalid write size on debug port: {}", data.len())
}
None
}
}

View File

@@ -0,0 +1,484 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//! ARM PrimeCell General Purpose Input/Output(PL061)
//!
//! This module implements an ARM PrimeCell General Purpose Input/Output(PL061) to support gracefully poweroff microvm from external.
//!
use crate::{read_le_u32, write_le_u32};
use anyhow::anyhow;
use std::result;
use std::sync::{Arc, Barrier};
use std::{fmt, io};
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
const OFS_DATA: u64 = 0x400; // Data Register
const GPIODIR: u64 = 0x400; // Direction Register
const GPIOIS: u64 = 0x404; // Interrupt Sense Register
const GPIOIBE: u64 = 0x408; // Interrupt Both Edges Register
const GPIOIEV: u64 = 0x40c; // Interrupt Event Register
const GPIOIE: u64 = 0x410; // Interrupt Mask Register
const GPIORIE: u64 = 0x414; // Raw Interrupt Status Register
const GPIOMIS: u64 = 0x418; // Masked Interrupt Status Register
const GPIOIC: u64 = 0x41c; // Interrupt Clear Register
const GPIOAFSEL: u64 = 0x420; // Mode Control Select Register
// From 0x424 to 0xFDC => reserved space.
// From 0xFE0 to 0xFFC => Peripheral and PrimeCell Identification Registers which are Read Only registers.
// Thses registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral.
// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
const GPIO_ID: [u8; 8] = [0x61, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
// ID Margins
const GPIO_ID_LOW: u64 = 0xfe0;
const GPIO_ID_HIGH: u64 = 0x1000;
const N_GPIOS: u32 = 8;
#[derive(Debug)]
pub enum Error {
BadWriteOffset(u64),
GpioInterruptDisabled,
GpioInterruptFailure(io::Error),
GpioTriggerKeyFailure(u32),
}
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::GpioInterruptDisabled => write!(f, "GPIO interrupt disabled by guest driver.",),
Error::GpioInterruptFailure(ref e) => {
write!(f, "Could not trigger GPIO interrupt: {}.", e)
}
Error::GpioTriggerKeyFailure(key) => {
write!(f, "Invalid GPIO Input key triggerd: {}.", key)
}
}
}
}
type Result<T> = result::Result<T, Error>;
/// A GPIO device following the PL061 specification.
pub struct Gpio {
id: String,
// Data Register
data: u32,
old_in_data: u32,
// Direction Register
dir: u32,
// Interrupt Sense Register
isense: u32,
// Interrupt Both Edges Register
ibe: u32,
// Interrupt Event Register
iev: u32,
// Interrupt Mask Register
im: u32,
// Raw Interrupt Status Register
istate: u32,
// Mode Control Select Register
afsel: u32,
// GPIO irq_field
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
}
#[derive(Serialize, Deserialize)]
pub struct GpioState {
data: u32,
old_in_data: u32,
dir: u32,
isense: u32,
ibe: u32,
iev: u32,
im: u32,
istate: u32,
afsel: u32,
}
impl Gpio {
/// Constructs an PL061 GPIO device.
pub fn new(id: String, interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> Self {
Self {
id,
data: 0,
old_in_data: 0,
dir: 0,
isense: 0,
ibe: 0,
iev: 0,
im: 0,
istate: 0,
afsel: 0,
interrupt,
}
}
fn state(&self) -> GpioState {
GpioState {
data: self.data,
old_in_data: self.old_in_data,
dir: self.dir,
isense: self.isense,
ibe: self.ibe,
iev: self.iev,
im: self.im,
istate: self.istate,
afsel: self.afsel,
}
}
fn set_state(&mut self, state: &GpioState) {
self.data = state.data;
self.old_in_data = state.old_in_data;
self.dir = state.dir;
self.isense = state.isense;
self.ibe = state.ibe;
self.iev = state.iev;
self.im = state.im;
self.istate = state.istate;
self.afsel = state.afsel;
}
fn pl061_internal_update(&mut self) {
// FIXME:
// Missing Output Interrupt Emulation.
// Input Edging Interrupt Emulation.
let changed = ((self.old_in_data ^ self.data) & !self.dir) as u32;
if changed > 0 {
self.old_in_data = self.data;
for i in 0..N_GPIOS {
let mask = (1 << i) as u32;
if (changed & mask) > 0 {
// Bits set high in GPIOIS(Interrupt sense register) configure the corresponding
// pins to detect levels, otherwise, detect edges.
if (self.isense & mask) == 0 {
if (self.ibe & mask) > 0 {
// Bits set high in GPIOIBE(Interrupt both-edges register) configure the corresponding
// pins to detect both falling and rising edges.
// Clearing a bit configures the pin to be controlled by GPIOIEV.
self.istate |= mask;
} else {
// Bits set to high in GPIOIEV(Interrupt event register) configure the
// corresponding pin to detect rising edges, otherwise, detect falling edges.
self.istate |= !(self.data ^ self.iev) & mask;
}
}
}
}
}
// Input Level Interrupt Emulation.
self.istate |= !(self.data ^ self.iev) & self.isense;
}
fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> {
if offset < OFS_DATA {
// In order to write to data register, the corresponding bits in the mask, resulting
// from the offsite[9:2], must be HIGH. otherwise the bit values remain unchanged.
let mask = (offset >> 2) as u32 & self.dir;
self.data = (self.data & !mask) | (val & mask);
} else {
match offset {
GPIODIR => {
/* Direction Register */
self.dir = val & 0xff;
}
GPIOIS => {
/* Interrupt Sense Register */
self.isense = val & 0xff;
}
GPIOIBE => {
/* Interrupt Both Edges Register */
self.ibe = val & 0xff;
}
GPIOIEV => {
/* Interrupt Event Register */
self.iev = val & 0xff;
}
GPIOIE => {
/* Interrupt Mask Register */
self.im = val & 0xff;
}
GPIOIC => {
/* Interrupt Clear Register */
self.istate &= !val;
}
GPIOAFSEL => {
/* Mode Control Select Register */
self.afsel = val & 0xff;
}
o => {
return Err(Error::BadWriteOffset(o));
}
}
}
Ok(())
}
pub fn trigger_key(&mut self, key: u32) -> Result<()> {
let mask = (1 << key) as u32;
if (!self.dir & mask) > 0 {
// emulate key event
// By default, Input Pin is configured to detect both rising and falling edges.
// So reverse the input pin data to generate a pulse.
self.data |= !(self.data & mask) & mask;
self.pl061_internal_update();
match self.trigger_gpio_interrupt() {
Ok(_) | Err(Error::GpioInterruptDisabled) => return Ok(()),
Err(e) => return Err(e),
}
}
Err(Error::GpioTriggerKeyFailure(key))
}
fn trigger_gpio_interrupt(&self) -> Result<()> {
// Bits set to high in GPIOIE(Interrupt mask register) allow the corresponding pins to
// trigger their individual interrupts and then the combined GPIOINTR line.
if (self.istate & self.im) == 0 {
warn!("Failed to trigger GPIO input interrupt (disabled by guest OS)");
return Err(Error::GpioInterruptDisabled);
}
self.interrupt
.trigger(0)
.map_err(Error::GpioInterruptFailure)?;
Ok(())
}
}
impl BusDevice for Gpio {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let value;
let mut read_ok = true;
if (GPIO_ID_LOW..GPIO_ID_HIGH).contains(&offset) {
let index = ((offset - GPIO_ID_LOW) >> 2) as usize;
value = u32::from(GPIO_ID[index]);
} else if offset < OFS_DATA {
value = self.data & ((offset >> 2) as u32)
} else {
value = match offset {
GPIODIR => self.dir,
GPIOIS => self.isense,
GPIOIBE => self.ibe,
GPIOIEV => self.iev,
GPIOIE => self.im,
GPIORIE => self.istate,
GPIOMIS => self.istate & self.im,
GPIOAFSEL => self.afsel,
_ => {
read_ok = false;
0
}
};
}
if read_ok && data.len() <= 4 {
write_le_u32(data, value);
} else {
warn!(
"Invalid GPIO PL061 read: offset {}, data length {}",
offset,
data.len()
);
}
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data.len() <= 4 {
let value = read_le_u32(&data);
if let Err(e) = self.handle_write(offset, value) {
warn!("Failed to write to GPIO PL061 device: {}", e);
}
} else {
warn!(
"Invalid GPIO PL061 write: offset {}, data length {}",
offset,
data.len()
);
}
None
}
}
impl Snapshottable for Gpio {
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 gpio_snapshot = Snapshot::new(self.id.as_str());
gpio_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id),
snapshot,
});
Ok(gpio_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(gpio_section) = snapshot.snapshot_data.get(&format!("{}-section", self.id)) {
let gpio_state = match serde_json::from_slice(&gpio_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize GPIO {}",
error
)))
}
};
self.set_state(&gpio_state);
return Ok(());
}
Err(MigratableError::Restore(anyhow!(
"Could not find the GPIO snapshot section"
)))
}
}
impl Pausable for Gpio {}
impl Transportable for Gpio {}
impl Migratable for Gpio {}
#[cfg(test)]
mod tests {
use super::*;
use crate::{read_le_u32, write_le_u32};
use std::sync::Arc;
use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig};
use vmm_sys_util::eventfd::EventFd;
const GPIO_NAME: &str = "gpio";
const LEGACY_GPIO_MAPPED_IO_START: u64 = 0x0902_0000;
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.try_clone().unwrap())
}
}
impl TestInterrupt {
fn new(event_fd: EventFd) -> Self {
TestInterrupt { event_fd }
}
}
#[test]
fn test_gpio_read_write_and_event() {
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let mut gpio = Gpio::new(
String::from(GPIO_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
);
let mut data = [0; 4];
// Read and write to the GPIODIR register.
// Set pin 0 output pin.
write_le_u32(&mut data, 1);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIODIR, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIODIR, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 1);
// Read and write to the GPIODATA register.
write_le_u32(&mut data, 1);
// Set pin 0 high.
let offset = 0x00000004 as u64;
gpio.write(LEGACY_GPIO_MAPPED_IO_START, offset, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, offset, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 1);
// Read and write to the GPIOIS register.
// Configure pin 0 detecting level interrupt.
write_le_u32(&mut data, 1);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIOIS, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOIS, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 1);
// Read and write to the GPIOIBE register.
// Configure pin 1 detecting both falling and rising edges.
write_le_u32(&mut data, 2);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIOIBE, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOIBE, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 2);
// Read and write to the GPIOIEV register.
// Configure pin 2 detecting both falling and rising edges.
write_le_u32(&mut data, 4);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIOIEV, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOIEV, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 4);
// Read and write to the GPIOIE register.
// Configure pin 0...2 capable of triggering their individual interrupts
// and then the combined GPIOINTR line.
write_le_u32(&mut data, 7);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIOIE, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOIE, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 7);
let mask = 0x00000002 as u32;
// emulate an rising pulse in pin 1.
gpio.data |= !(gpio.data & mask) & mask;
gpio.pl061_internal_update();
// The interrupt line on pin 1 should be on.
// Read the GPIOMIS register.
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOMIS, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 2);
// Read and Write to the GPIOIC register.
// clear interrupt in pin 1.
write_le_u32(&mut data, 2);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIOIC, &mut data);
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIOIC, &mut data);
let v = read_le_u32(&data);
assert_eq!(v, 2);
// Attempts to write beyond the writable space.
write_le_u32(&mut data, 0);
gpio.write(LEGACY_GPIO_MAPPED_IO_START, GPIO_ID_LOW, &mut data);
let mut data = [0; 4];
gpio.read(LEGACY_GPIO_MAPPED_IO_START, GPIO_ID_LOW, &mut data);
let index = GPIO_ID_LOW + 3;
assert_eq!(data[0], GPIO_ID[((index - GPIO_ID_LOW) >> 2) as usize]);
}
}

View File

@@ -2,10 +2,10 @@
// 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, Barrier};
use vm_device::BusDevice;
use vmm_sys_util::eventfd::EventFd;
use BusDevice;
/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
pub struct I8042Device {
reset_evt: EventFd,
@@ -32,12 +32,14 @@ impl BusDevice for I8042Device {
}
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data.len() == 1 && data[0] == 0xfe && offset == 3 {
debug!("i8042 reset signalled");
if let Err(e) = self.reset_evt.write(1) {
error!("Error triggering i8042 reset event: {}", e);
}
}
None
}
}

View File

@@ -7,10 +7,29 @@
#[cfg(feature = "cmos")]
mod cmos;
#[cfg(feature = "fwdebug")]
mod fwdebug;
#[cfg(target_arch = "aarch64")]
mod gpio_pl061;
mod i8042;
#[cfg(target_arch = "aarch64")]
mod rtc_pl031;
mod serial;
#[cfg(target_arch = "aarch64")]
mod uart_pl011;
#[cfg(feature = "cmos")]
pub use self::cmos::Cmos;
#[cfg(feature = "fwdebug")]
pub use self::fwdebug::FwDebugDevice;
pub use self::i8042::I8042Device;
pub use self::serial::Serial;
#[cfg(target_arch = "aarch64")]
pub use self::gpio_pl061::Error as GpioDeviceError;
#[cfg(target_arch = "aarch64")]
pub use self::gpio_pl061::Gpio;
#[cfg(target_arch = "aarch64")]
pub use self::rtc_pl031::Rtc;
#[cfg(target_arch = "aarch64")]
pub use self::uart_pl011::Pl011;

View File

@@ -0,0 +1,586 @@
// 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 crate::{read_le_u32, write_le_u32};
use std::fmt;
use std::sync::{Arc, Barrier};
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 Register.
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;
#[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 From<ClockType> for libc::clockid_t {
fn from(ct: ClockType) -> libc::clockid_t {
match ct {
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>>) -> Self {
Self {
// 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 (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) {
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]) -> Option<Arc<Barrier>> {
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()
);
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
read_be_u16, read_be_u32, read_le_i32, read_le_u16, read_le_u32, read_le_u64, write_be_u16,
write_be_u32, write_le_i32, write_le_u16, write_le_u32, write_le_u64,
};
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.try_clone().unwrap())
}
}
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,11 +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;
use anyhow::anyhow;
use std::collections::VecDeque;
use std::sync::Arc;
use std::sync::{Arc, Barrier};
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;
@@ -55,6 +60,7 @@ 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: Arc<Box<dyn InterruptSourceGroup>>,
@@ -68,12 +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(
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,
@@ -90,15 +111,16 @@ impl Serial {
/// Constructs a Serial port ready for output.
pub fn new_out(
id: String,
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
out: Box<dyn io::Write + Send>,
) -> Serial {
Self::new(interrupt, Some(out))
Self::new(id, interrupt, Some(out))
}
/// Constructs a Serial port with no connected output.
pub fn new_sink(interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> 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
@@ -194,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 {
@@ -227,15 +275,62 @@ impl BusDevice for Serial {
};
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data.len() != 1 {
return;
return None;
}
if let Err(_e) = self.handle_write(offset as u8, data[0]) {}
self.handle_write(offset as u8, data[0]).ok();
None
}
}
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::*;
@@ -244,6 +339,8 @@ mod tests {
use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig};
use vmm_sys_util::eventfd::EventFd;
const SERIAL_NAME: &str = "serial";
struct TestInterrupt {
event_fd: EventFd,
}
@@ -259,6 +356,9 @@ mod tests {
) -> result::Result<(), std::io::Error> {
Ok(())
}
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
Some(self.event_fd.try_clone().unwrap())
}
}
impl TestInterrupt {
@@ -294,17 +394,18 @@ mod tests {
let intr_evt = EventFd::new(0).unwrap();
let serial_out = SharedBuffer::new();
let mut serial = Serial::new_out(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Box::new(serial_out.clone()),
);
serial.write(0, DATA as u64, &['x' as u8, 'y' as u8]);
serial.write(0, DATA as u64, &['a' as u8]);
serial.write(0, DATA as u64, &['b' as u8]);
serial.write(0, DATA as u64, &['c' as u8]);
serial.write(0, DATA as u64, &[b'x', b'y']);
serial.write(0, DATA as u64, &[b'a']);
serial.write(0, DATA as u64, &[b'b']);
serial.write(0, DATA as u64, &[b'c']);
assert_eq!(
serial_out.buf.lock().unwrap().as_slice(),
&['a' as u8, 'b' as u8, 'c' as u8]
&[b'a', b'b', b'c']
);
}
@@ -313,17 +414,16 @@ mod tests {
let intr_evt = EventFd::new(0).unwrap();
let serial_out = SharedBuffer::new();
let mut serial = Serial::new_out(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Box::new(serial_out.clone()),
Box::new(serial_out),
);
// 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)
assert!(intr_evt.write(1).is_ok());
serial.write(0, IER as u64, &[IER_RECV_BIT]);
serial
.queue_input_bytes(&['a' as u8, 'b' as u8, 'c' as u8])
.unwrap();
serial.queue_input_bytes(&[b'a', b'b', b'c']).unwrap();
assert_eq!(intr_evt.read().unwrap(), 2);
@@ -336,11 +436,11 @@ mod tests {
serial.read(0, LSR as u64, &mut data[..]);
assert_ne!(data[0] & LSR_DATA_BIT, 0);
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'a' as u8);
assert_eq!(data[0], b'a');
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'b' as u8);
assert_eq!(data[0], b'b');
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'c' as u8);
assert_eq!(data[0], b'c');
// check if reading from the largest u8 offset returns 0
serial.read(0, 0xff, &mut data[..]);
@@ -350,15 +450,16 @@ mod tests {
#[test]
fn serial_thr() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial = Serial::new_sink(Arc::new(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)
assert!(intr_evt.write(1).is_ok());
serial.write(0, IER as u64, &[IER_THR_BIT]);
serial.write(0, DATA as u64, &['a' as u8]);
serial.write(0, DATA as u64, &[b'a']);
assert_eq!(intr_evt.read().unwrap(), 2);
let mut data = [0u8];
@@ -371,17 +472,18 @@ mod tests {
#[test]
fn serial_dlab() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial = Serial::new_sink(Arc::new(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]);
serial.write(0, DLAB_HIGH as u64, &[0x34 as u8]);
serial.write(0, LCR as u64, &[LCR_DLAB_BIT]);
serial.write(0, DLAB_LOW as u64, &[0x12]);
serial.write(0, DLAB_HIGH as u64, &[0x34]);
let mut data = [0u8];
serial.read(0, LCR as u64, &mut data[..]);
assert_eq!(data[0], LCR_DLAB_BIT as u8);
assert_eq!(data[0], LCR_DLAB_BIT);
serial.read(0, DLAB_LOW as u64, &mut data[..]);
assert_eq!(data[0], 0x12);
serial.read(0, DLAB_HIGH as u64, &mut data[..]);
@@ -391,39 +493,41 @@ mod tests {
#[test]
fn serial_modem() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial = Serial::new_sink(Arc::new(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]);
serial.write(0, DATA as u64, &['b' as u8]);
serial.write(0, DATA as u64, &['c' as u8]);
serial.write(0, MCR as u64, &[MCR_LOOP_BIT]);
serial.write(0, DATA as u64, &[b'a']);
serial.write(0, DATA as u64, &[b'b']);
serial.write(0, DATA as u64, &[b'c']);
let mut data = [0u8];
serial.read(0, MSR as u64, &mut data[..]);
assert_eq!(data[0], DEFAULT_MODEM_STATUS as u8);
assert_eq!(data[0], DEFAULT_MODEM_STATUS);
serial.read(0, MCR as u64, &mut data[..]);
assert_eq!(data[0], MCR_LOOP_BIT as u8);
assert_eq!(data[0], MCR_LOOP_BIT);
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'a' as u8);
assert_eq!(data[0], b'a');
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'b' as u8);
assert_eq!(data[0], b'b');
serial.read(0, DATA as u64, &mut data[..]);
assert_eq!(data[0], 'c' as u8);
assert_eq!(data[0], b'c');
}
#[test]
fn serial_scratch() {
let intr_evt = EventFd::new(0).unwrap();
let mut serial = Serial::new_sink(Arc::new(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]);
serial.write(0, SCR as u64, &[0x12]);
let mut data = [0u8];
serial.read(0, SCR as u64, &mut data[..]);
assert_eq!(data[0], 0x12 as u8);
assert_eq!(data[0], 0x12);
}
}

View File

@@ -0,0 +1,506 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//! ARM PrimeCell UART(PL011)
//!
//! This module implements an ARM PrimeCell UART(PL011).
//!
use crate::{read_le_u32, write_le_u32};
use anyhow::anyhow;
use std::collections::VecDeque;
use std::fmt;
use std::sync::{Arc, Barrier};
use std::{io, result};
use vm_device::interrupt::InterruptSourceGroup;
use vm_device::BusDevice;
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
/* Registers */
const UARTDR: u64 = 0;
const UARTRSR_UARTECR: u64 = 1;
const UARTFR: u64 = 6;
const UARTILPR: u64 = 8;
const UARTIBRD: u64 = 9;
const UARTFBRD: u64 = 10;
const UARTLCR_H: u64 = 11;
const UARTCR: u64 = 12;
const UARTIFLS: u64 = 13;
const UARTIMSC: u64 = 14;
const UARTRIS: u64 = 15;
const UARTMIS: u64 = 16;
const UARTICR: u64 = 17;
const UARTDMACR: u64 = 18;
const PL011_INT_TX: u32 = 0x20;
const PL011_INT_RX: u32 = 0x10;
const PL011_FLAG_RXFF: u32 = 0x40;
const PL011_FLAG_RXFE: u32 = 0x10;
const PL011_ID: [u8; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
// We are only interested in the margins.
const AMBA_ID_LOW: u64 = 0x3f8;
const AMBA_ID_HIGH: u64 = 0x401;
#[derive(Debug)]
pub enum Error {
BadWriteOffset(u64),
DmaNotImplemented,
InterruptFailure(io::Error),
WriteAllFailure(io::Error),
FlushFailure(io::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {}", offset),
Error::DmaNotImplemented => write!(f, "pl011: DMA not implemented."),
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
Error::WriteAllFailure(e) => write!(f, "Failed to write: {}", e),
Error::FlushFailure(e) => write!(f, "Failed to flush: {}", e),
}
}
}
type Result<T> = result::Result<T, Error>;
/// A PL011 device following the PL011 specification.
pub struct Pl011 {
id: String,
flags: u32,
lcr: u32,
rsr: u32,
cr: u32,
dmacr: u32,
int_enabled: u32,
int_level: u32,
read_fifo: VecDeque<u8>,
ilpr: u32,
ibrd: u32,
fbrd: u32,
ifl: u32,
read_count: u32,
read_trigger: u32,
irq: Arc<Box<dyn InterruptSourceGroup>>,
out: Option<Box<dyn io::Write + Send>>,
}
#[derive(Serialize, Deserialize)]
pub struct Pl011State {
flags: u32,
lcr: u32,
rsr: u32,
cr: u32,
dmacr: u32,
int_enabled: u32,
int_level: u32,
read_fifo: VecDeque<u8>,
ilpr: u32,
ibrd: u32,
fbrd: u32,
ifl: u32,
read_count: u32,
read_trigger: u32,
}
impl Pl011 {
/// Constructs an AMBA PL011 UART device.
pub fn new(
id: String,
irq: Arc<Box<dyn InterruptSourceGroup>>,
out: Option<Box<dyn io::Write + Send>>,
) -> Self {
Self {
id,
flags: 0x90u32,
lcr: 0u32,
rsr: 0u32,
cr: 0x300u32,
dmacr: 0u32,
int_enabled: 0u32,
int_level: 0u32,
read_fifo: VecDeque::new(),
ilpr: 0u32,
ibrd: 0u32,
fbrd: 0u32,
ifl: 0x12u32,
read_count: 0u32,
read_trigger: 1u32,
irq,
out,
}
}
fn state(&self) -> Pl011State {
Pl011State {
flags: self.flags,
lcr: self.lcr,
rsr: self.rsr,
cr: self.cr,
dmacr: self.dmacr,
int_enabled: self.int_enabled,
int_level: self.int_level,
read_fifo: self.read_fifo.clone(),
ilpr: self.ilpr,
ibrd: self.ibrd,
fbrd: self.fbrd,
ifl: self.ifl,
read_count: self.read_count,
read_trigger: self.read_trigger,
}
}
fn set_state(&mut self, state: &Pl011State) {
self.flags = state.flags;
self.lcr = state.lcr;
self.rsr = state.rsr;
self.cr = state.cr;
self.dmacr = state.dmacr;
self.int_enabled = state.int_enabled;
self.int_level = state.int_level;
self.read_fifo = state.read_fifo.clone();
self.ilpr = state.ilpr;
self.ibrd = state.ibrd;
self.fbrd = state.fbrd;
self.ifl = state.ifl;
self.read_count = state.read_count;
self.read_trigger = state.read_trigger;
}
/// Queues raw bytes for the guest to read and signals the interrupt
pub fn queue_input_bytes(&mut self, c: &[u8]) -> vmm_sys_util::errno::Result<()> {
self.read_fifo.extend(c);
self.read_count += c.len() as u32;
self.flags &= !PL011_FLAG_RXFE;
if ((self.lcr & 0x10) == 0) || (self.read_count == 16) {
self.flags |= PL011_FLAG_RXFF;
}
if self.read_count >= self.read_trigger {
self.int_level |= PL011_INT_RX;
self.trigger_interrupt()?;
}
Ok(())
}
fn pl011_get_baudrate(&self) -> u32 {
if self.fbrd == 0 {
return 0;
}
let clk = 24_000_000; // We set the APB_PLCK to 24M in device tree
(clk / ((self.ibrd << 6) + self.fbrd)) << 2
}
fn pl011_trace_baudrate_change(&self) {
debug!(
"=== New baudrate: {:#?} (clk: {:#?}Hz, ibrd: {:#?}, fbrd: {:#?}) ===",
self.pl011_get_baudrate(),
24_000_000, // We set the APB_PLCK to 24M in device tree
self.ibrd,
self.fbrd
);
}
fn pl011_set_read_trigger(&mut self) {
self.read_trigger = 1;
}
fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> {
match offset >> 2 {
UARTDR => {
self.int_level |= PL011_INT_TX;
if let Some(out) = self.out.as_mut() {
out.write_all(&[val.to_le_bytes()[0]])
.map_err(Error::WriteAllFailure)?;
out.flush().map_err(Error::FlushFailure)?;
}
}
UARTRSR_UARTECR => {
self.rsr = 0;
}
UARTFR => { /* Writes to Flag register are ignored.*/ }
UARTILPR => {
self.ilpr = val;
}
UARTIBRD => {
self.ibrd = val;
self.pl011_trace_baudrate_change();
}
UARTFBRD => {
self.fbrd = val;
self.pl011_trace_baudrate_change();
}
UARTLCR_H => {
/* Reset the FIFO state on FIFO enable or disable */
if ((self.lcr ^ val) & 0x10) != 0 {
self.read_count = 0;
}
self.lcr = val;
self.pl011_set_read_trigger();
}
UARTCR => {
self.cr = val;
}
UARTIFLS => {
self.ifl = val;
self.pl011_set_read_trigger();
}
UARTIMSC => {
self.int_enabled = val;
self.trigger_interrupt().map_err(Error::InterruptFailure)?;
}
UARTICR => {
self.int_level &= !val;
self.trigger_interrupt().map_err(Error::InterruptFailure)?;
}
UARTDMACR => {
self.dmacr = val;
if (val & 3) != 0 {
return Err(Error::DmaNotImplemented);
}
}
off => {
return Err(Error::BadWriteOffset(off));
}
}
Ok(())
}
fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> {
self.irq.trigger(0)
}
}
impl BusDevice for Pl011 {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
let v;
let mut read_ok = true;
if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) {
let index = ((offset - 0xfe0) >> 2) as usize;
v = u32::from(PL011_ID[index]);
} else {
v = match offset >> 2 {
UARTDR => {
let c: u32;
let r: u32;
self.flags &= !PL011_FLAG_RXFF;
c = self.read_fifo.pop_front().unwrap_or_default().into();
if self.read_count > 0 {
self.read_count -= 1;
}
if self.read_count == 0 {
self.flags |= PL011_FLAG_RXFE;
}
if self.read_count == (self.read_trigger - 1) {
self.int_level &= !PL011_INT_RX;
}
self.rsr = c >> 8;
r = c;
r
}
UARTRSR_UARTECR => self.rsr,
UARTFR => self.flags,
UARTILPR => self.ilpr,
UARTIBRD => self.ibrd,
UARTFBRD => self.fbrd,
UARTLCR_H => self.lcr,
UARTCR => self.cr,
UARTIFLS => self.ifl,
UARTIMSC => self.int_enabled,
UARTRIS => self.int_level,
UARTMIS => (self.int_level & self.int_enabled),
UARTDMACR => self.dmacr,
_ => {
read_ok = false;
0
}
}
}
if read_ok && data.len() <= 4 {
write_le_u32(data, v);
} else {
warn!(
"Invalid PL011 read: offset {}, data length {}",
offset,
data.len()
);
}
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if data.len() <= 4 {
let v = read_le_u32(&data);
if let Err(e) = self.handle_write(offset, v) {
warn!("Failed to write to PL011 device: {}", e);
}
} else {
warn!(
"Invalid PL011 write: offset {}, data length {}",
offset,
data.len()
);
}
None
}
}
impl Snapshottable for Pl011 {
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 pl011_snapshot = Snapshot::new(self.id.as_str());
pl011_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", self.id),
snapshot,
});
Ok(pl011_snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
if let Some(pl011_section) = snapshot.snapshot_data.get(&format!("{}-section", self.id)) {
let pl011_state = match serde_json::from_slice(&pl011_section.snapshot) {
Ok(state) => state,
Err(error) => {
return Err(MigratableError::Restore(anyhow!(
"Could not deserialize PL011 {}",
error
)))
}
};
self.set_state(&pl011_state);
return Ok(());
}
Err(MigratableError::Restore(anyhow!(
"Could not find the PL011 snapshot section"
)))
}
}
impl Pausable for Pl011 {}
impl Transportable for Pl011 {}
impl Migratable for Pl011 {}
#[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 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.try_clone().unwrap())
}
}
impl TestInterrupt {
fn new(event_fd: EventFd) -> Self {
TestInterrupt { event_fd }
}
}
#[derive(Clone)]
struct SharedBuffer {
buf: Arc<Mutex<Vec<u8>>>,
}
impl SharedBuffer {
fn new() -> SharedBuffer {
SharedBuffer {
buf: Arc::new(Mutex::new(Vec::new())),
}
}
}
impl io::Write for SharedBuffer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buf.lock().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.buf.lock().unwrap().flush()
}
}
#[test]
fn pl011_output() {
let intr_evt = EventFd::new(0).unwrap();
let pl011_out = SharedBuffer::new();
let mut pl011 = Pl011::new(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Some(Box::new(pl011_out.clone())),
);
pl011.write(0, UARTDR as u64, &[b'x', b'y']);
pl011.write(0, UARTDR as u64, &[b'a']);
pl011.write(0, UARTDR as u64, &[b'b']);
pl011.write(0, UARTDR as u64, &[b'c']);
assert_eq!(
pl011_out.buf.lock().unwrap().as_slice(),
&[b'x', b'a', b'b', b'c']
);
}
#[test]
fn pl011_input() {
let intr_evt = EventFd::new(0).unwrap();
let pl011_out = SharedBuffer::new();
let mut pl011 = Pl011::new(
String::from(SERIAL_NAME),
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
Some(Box::new(pl011_out)),
);
// 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)
assert!(intr_evt.write(1).is_ok());
pl011.queue_input_bytes(&[b'a', b'b', b'c']).unwrap();
assert_eq!(intr_evt.read().unwrap(), 2);
let mut data = [0u8];
pl011.read(0, UARTDR as u64, &mut data);
assert_eq!(data[0], b'a');
pl011.read(0, UARTDR as u64, &mut data);
assert_eq!(data[0], b'b');
pl011.read(0, UARTDR as u64, &mut data);
assert_eq!(data[0], b'c');
}
}

View File

@@ -6,6 +6,7 @@
// found in the LICENSE-BSD-3-Clause file.
//! Emulates virtual and hardware devices.
extern crate anyhow;
#[macro_use]
extern crate bitflags;
extern crate byteorder;
@@ -13,65 +14,95 @@ extern crate epoll;
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;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[cfg(feature = "acpi")]
mod acpi;
mod bus;
pub mod acpi;
#[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::{AcpiGEDDevice, AcpiShutdownDevice};
pub use self::bus::{Bus, BusDevice, Error as BusError};
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 use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice};
bitflags! {
pub struct HotPlugNotificationFlags: u8 {
pub struct AcpiNotificationFlags: u8 {
const NO_DEVICES_CHANGED = 0;
const CPU_DEVICES_CHANGED = 0b1;
const MEMORY_DEVICES_CHANGED = 0b10;
const PCI_DEVICES_CHANGED = 0b100;
const POWER_BUTTON_CHANGED = 0b1000;
}
}
#[allow(unused_macros)]
#[cfg(target_arch = "aarch64")]
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)]
#[cfg(target_arch = "aarch64")]
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;
}
}
};
}
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_le_u16, u16, u8, 2, from_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_le_u32, u32, u8, 4, from_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_le_u64, u64, u8, 8, from_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_le_i32, i32, i8, 4, from_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_be_u16, u16, u8, 2, from_be_bytes);
#[cfg(target_arch = "aarch64")]
generate_read_fn!(read_be_u32, u32, u8, 4, from_be_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_le_u16, u16, u8, to_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_le_u32, u32, u8, to_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_le_u64, u64, u8, to_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_le_i32, i32, i8, to_le_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_be_u16, u16, u8, to_be_bytes);
#[cfg(target_arch = "aarch64")]
generate_write_fn!(write_be_u32, u32, u8, to_be_bytes);

View File

@@ -12,7 +12,7 @@
* [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)
+ [REST API and CLI Architectural 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)
@@ -78,18 +78,27 @@ Shut the VMM down | `/vmm.shutdown` | N/A | N/A
#### 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 | The VM is created but not booted
Boot the VM | `/vm.boot` | N/A | N/A | The VM is created
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
Remove memory from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted
Dump the VM information | `/vm.info` | N/A | `/schemas/VmInfo` | The VM is created
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
@@ -114,10 +123,10 @@ 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.5.0 Linux kernel located at
* Direct kernel boot from a custom 5.6.0-rc4 Linux kernel located at
`/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu`
* Using a Clear Linux image as its root filesystem, located at
`/opt/clh/images/clear-30080-kvm.img`
* Using a Ubuntu image as its root filesystem, located at
`/opt/clh/images/focal-server-cloudimg-amd64.raw`
```shell
#!/bin/bash
@@ -129,8 +138,8 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-d '{
"cpus":{"boot_vcpus": 4, "max_vcpus": 4},
"kernel":{"path":"/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu"},
"cmdline":{"args":"console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3"},
"disks":[{"path":"/opt/clh/images/clear-30080-kvm.img"}],
"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"}]
}'
@@ -267,7 +276,7 @@ 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.
end of an [MPSC](https://doc.rust-lang.org/std/sync/mpsc/) channel.
The sender of any internal API command is therefore responsible for:
@@ -297,8 +306,8 @@ APIs work together, let's look at a complete VM creation flow, from the
-d '{
"cpus":{"boot_vcpus": 4, "max_vcpus": 4},
"kernel":{"path":"/opt/clh/kernel/vmlinux-virtio-fs-virtio-iommu"},
"cmdline":{"args":"console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3"},
"disks":[{"path":"/opt/clh/images/clear-30080-kvm.img"}],
"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"}]
}'
@@ -347,7 +356,7 @@ APIs work together, let's look at a complete VM creation flow, from the
} else {
Err(ApiError::VmAlreadyCreated)
};
sender.send(response).map_err(Error::ApiResponseSend)?;
}
```
@@ -368,4 +377,3 @@ APIs work together, let's look at a complete VM creation flow, from the
user. This is abstracted by the
[micro_http](https://github.com/firecracker-microvm/firecracker/tree/master/src/micro_http)
crate.

58
docs/arm64.md Normal file
View File

@@ -0,0 +1,58 @@
# 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
Using PCI devices requires GICv3-ITS for MSI messaging. GICv3-ITS is very common in modern servers.
```bash
cargo build --no-default-features --features 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:
```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 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`.

View File

@@ -1,96 +1,149 @@
# How to create a custom Clear Linux image
# How to create a custom Ubuntu image
In the context of adding more utility to the cloudguest image being used
for integration testing, this is a quick guide on how to achieve the creation
of your own Clear Linux image using the official Clear Linux tooling.
## Prepare the environment
From the host, the goal is run a Clear Linux VM that will allow us to build
the custom image we want.
```bash
# Get latest CL version:
IMG_VERSION=$(curl https://download.clearlinux.org/latest)
# Get latest clear-kvm image:
wget -P $HOME/workloads/ https://download.clearlinux.org/current/clear-${IMG_VERSION}-kvm.img.xz
# Extract the image
unxz $HOME/workloads/clear-${IMG_VERSION}-kvm.img.xz
# Make sure cloud-hypervisor binary has CAP_NET_ADMIN capability set
sudo setcap cap_net_admin+ep cloud-hypervisor
# Boot cloud-hypervisor VM with the downloaded image
./cloud-hypervisor -v --kernel $HOME/workloads/vmlinux --disk path=clear-${IMG_VERSION}-kvm.img --cmdline "console=ttyS0 console=hvc0 reboot=k panic=1 nomodules root=/dev/vda3 rw" --cpus 1 --memory size=4G --net tap=,mac=
# Setup connectivity
# First make sure to enable IP forwarding (disabled on Linux by default)
sudo bash -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
# Retrieve the interface name and the gateway IP
IFACE=$(ip route | grep default | awk -F 'dev' '{print $2}' | awk -F ' ' '{print $1}')
GW=$(ip route | grep vmtap0 | awk -F ' ' '{print $1}')
# Create a new masquerade rule to tag the packets going out
sudo iptables -t nat -A POSTROUTING -s ${GW} -o ${IFACE} -j MASQUERADE
```
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
From the guest, we can now 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
# Setup connectivity
sudo ip addr add 192.168.249.2/24 dev enp0s3
sudo ip route add default via 192.168.249.1
# Install necessary bundles
sudo swupd bundle-add clr-installer
sudo swupd bundle-add os-installer
# Download and update cloudguest image configuration
wget https://download.clearlinux.org/current/config/image/cloudguest.yaml
sed -i '/size: \"864M\"/d' cloudguest.yaml
sed -i 's/\"800M\"/\"2G\"/g' cloudguest.yaml
sed -i 's/bootloader,/bootloader,\n iperf,/g' cloudguest.yaml
sed -i 's/systemd-networkd-autostart/sysadmin-basic,\n systemd-networkd-autostart/g' cloudguest.yaml
# Create the custom cloudguest image
clr-installer -c cloudguest.yaml
# Make the guest accessible through ssh
sudo mkdir -p /etc/ssh
sudo bash -c "echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config"
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
```
### Retrieve the image
Once the new image has been created and the guest is accessible through
`ssh`, it is time to retrieve the image from the host.
### Check the file format is QCOW2
```bash
# Retrieve new image (this is a raw image)
scp root@192.168.249.2:cloudguest.img .
mv cloudguest.img clear-cloudguest-raw.img
# Create the QCOW image from the RAW image
qemu-img convert -p -f raw -O qcow2 clear-cloudguest-raw.img clear-cloudguest.img
# Compress the QCOW image
xz -k -T $(nproc) clear-cloudguest.img
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 counterproductive packages
* 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.
* pollinate:
Remove this package which can fail and lead to the SSH daemon failing to start.
See #2113 for details.
```bash
apt remove --purge snapd pollinate
```
### 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-$(date "+%Y%m%d")-0.raw
```
The `-0` is the revision and is only necessary to change if multiple images are
updated on the same day.
### 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-$(date "+%Y%m%d")-0.raw focal-server-cloudimg-amd64-custom-$(date "+%Y%m%d")-0.qcow2
```
## Switch CI to use the new image
### Upload to Azure storage
The next step is to update the image stored as part of the Azure storage
account, replacing it with the newly created image. This will make this
new image available from the integration tests.
This is usually achieved through the web interface.
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 the UUID of this new image so that it can be used
directly from the tests.
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.
Proceed as follow to determine this UUID:
```bash
# Mount the image
sudo mount -o loop,offset=$((2048 * 512)) clear-cloudguest-raw.img /mnt/
# Identify UUID
sudo cat /mnt/loader/entries/Clear-linux-kvm-*.conf | grep "root=PARTUUID="
# Unmount the image
sudo umount /mnt
```
Update all references to the previous image name to the new one.

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 path=~/hypervisor/images/clear-30080-kvm.img \
--disk path=~/hypervisor/images/focal-server-cloudimg-amd64.raw \
--cpus 4 \
--memory size=1024M \
--rng \

View File

@@ -28,9 +28,13 @@ This document describes the device model supported by `cloud-hypervisor`.
### 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.
addresses. The serial port can be very useful to gather early logs from the
operating system booted inside the VM.
For x86_64, The default serial port is from an emulated 16550A device. It can
be used as the default console for Linux when booting with the option
`console=ttyS0`. For AArch64, the default serial port is from an emulated
PL011 UART device. The related command line for AArch64 is `console=ttyAMA0`.
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`.
@@ -44,6 +48,10 @@ 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.
For AArch64 machines, an ARM PrimeCell Real Time Clock(PL031) is implemented.
This device is built-in by default for the AArch64 platform, and 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
@@ -65,6 +73,11 @@ 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.
### ARM PrimeCell General Purpose Input/Output (PL061)
Simplified ARM PrimeCell GPIO (PL061) implementation. Only supports key 3 to
trigger a graceful shutdown of the AArch64 guest.
### ACPI device
This is a dedicated device for handling ACPI shutdown and reboot when ACPI is
@@ -75,12 +88,8 @@ 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.
For all virtio devices listed below, only `virtio-pci` transport layer is
supported.
### virtio-block

View File

@@ -52,28 +52,28 @@ 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 path=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=myfs,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,sock=/tmp/virtiofs,num_queues=1,queue_size=512,dax=on,cache_size=4G
--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,sock=/tmp/virtiofs,num_queues=1,queue_size=512,dax=off
--fs tag=virtiofs,socket=/tmp/virtiofs,num_queues=1,queue_size=512,dax=off
```

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/)

View File

@@ -5,9 +5,7 @@ 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.5rc1 and later): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/drivers/acpi/Makefile?id=ac36d37e943635fc072e9d4f47e40a48fbcdb3f0
This patch is integrated into the Clear Linux KVM and cloudguest images.
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
@@ -22,13 +20,14 @@ To use CPU hotplug start the VM with the number of max vCPUs greater than the nu
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=clear-31890-kvm.img \
--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
--api-socket=/tmp/ch-socket
$ popd
```
@@ -37,7 +36,7 @@ Notice the addition of `--api-socket=/tmp/ch-socket` and a `max` parameter on `-
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
./ch-remote --api-socket=/tmp/ch-socket resize --cpus 8
```
The extra vCPU threads will be created and advertised to the running kernel. The kernel does not bring up the CPUs immediately and instead the user must "online" them from inside the VM:
@@ -57,31 +56,36 @@ 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
./ch-remote --api-socket=/tmp/ch-socket resize --cpus 2
```
As per adding CPUs to the guest, after a reboot the VM will be running with the reduced number of vCPUs.
## Memory Hot Plug
Extra memory can be added from a runing Cloud Hypervisor instance. This is controlled by two mechanisms:
### ACPI method
Extra memory can be added from a running 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.
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.
Because the ACPI method is the default, there is no need to add the extra option `hotplug_method=acpi`.
```shell
$ pushd $CLOUDH
$ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor
$ ./cloud-hypervisor/target/release/cloud-hypervisor \
--kernel ./hypervisor-fw \
--disk path=clear-31890-kvm.img \
--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
--api-socket=/tmp/ch-socket
$ popd
```
@@ -91,10 +95,10 @@ Before issuing the API request it is necessary to run the following command insi
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:
To ask the VMM to expand the RAM for the VM:
```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
./ch-remote --api-socket=/tmp/ch-socket resize --memory 3G
```
The new memory is now available to use inside the VM:
@@ -110,4 +114,135 @@ Due to guest OS limitations is is necessary to ensure that amount of memory adde
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.
Memory and CPU resizing can be combined together into the same HTTP API request.
### virtio-mem method
Extra memory can be added and removed from a running 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.
To use memory hotplug start the VM specifying some size RAM in the `hotplug_size` parameter along with `hotplug_method=virtio-mem` to the memory configuration.
```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 \
--memory size=1024M,hotplug_size=8192M,hotplug_method=virtio-mem \
--net "tap=,mac=,ip=,mask=" \
--api-socket=/tmp/ch-socket
$ popd
```
To ask the VMM to expand the RAM for the VM (request is in bytes):
```shell
./ch-remote --api-socket=/tmp/ch-socket resize --memory 3G
```
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
```
The same API can also be used to reduce the desired RAM for a VM. It is important to note that reducing RAM size might only partially work, as the guest might be using some of it.
## PCI Device Hot Plug
Extra PCI devices can be added and removed from a running Cloud Hypervisor instance. This is controlled by making a HTTP API request to the VMM to ask for the additional device to be added, or for the existing device to be removed.
To use PCI device hotplug start the VM with the HTTP server.
```shell
$ 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 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask=" \
--api-socket=/tmp/ch-socket
```
Notice the addition of `--api-socket=/tmp/ch-socket`.
### Add VFIO Device
To ask the VMM to add additional VFIO device then use the `add-device` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-device path=/sys/bus/pci/devices/0000:01:00.0/
```
### Add Disk Device
To ask the VMM to add additional disk device then use the `add-disk` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-disk path=/foo/bar/cloud.img
```
### Add Fs Device
To ask the VMM to add additional fs device then use the `add-fs` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-fs tag=myfs,socket=/foo/bar/virtiofs.sock
```
### Add Net Device
To ask the VMM to add additional network device then use the `add-net` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-net tap=chtap0
```
### Add Pmem Device
To ask the VMM to add additional PMEM device then use the `add-pmem` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-pmem file=/foo/bar.cloud.img
```
### Add Vsock Device
To ask the VMM to add additional vsock device then use the `add-vsock` API.
```shell
./ch-remote --api-socket=/tmp/ch-socket add-vsock cid=3,socket=/foo/bar/vsock.sock
```
### Common Across All PCI Devices
The extra PCI device will be created and advertised to the running kernel. The new device can be found by checking the list of PCI devices.
```shell
root@ch-guest ~ # lspci
00:00.0 Host bridge: Intel Corporation Device 0d57
00:01.0 Unassigned class [ffff]: Red Hat, Inc. Virtio console (rev 01)
00:02.0 Mass storage controller: Red Hat, Inc. Virtio block device (rev 01)
00:03.0 Unassigned class [ffff]: Red Hat, Inc. Virtio RNG (rev 01)
```
After a reboot the added PCI device will remain.
### Remove PCI device
Removing a PCI device works the same way for all kind of PCI devices. The unique identifier related to the device must be provided. This identifier can be provided by the user when adding the new device, or by default Cloud Hypervisor will assign one.
```shell
./ch-remote --api-socket=/tmp/ch-socket remove-device _disk0
```
As per adding a PCI device to the guest, after a reboot the VM will be running without the removed PCI device.

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
built using the [SGX Linux Development Tree](https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/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*
/dev/sgx_enclave /dev/sgx_provision /dev/sgx_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.

41
docs/io_throttling.md Normal file
View File

@@ -0,0 +1,41 @@
# I/O Throttling
Cloud Hypervisor now supports I/O throttling on virtio-block
devices. This support is based on the [`rate-limiter` module](https://github.com/firecracker-microvm/firecracker/tree/master/src/rate_limiter)
from Firecracker. This document explains the user interface of this
feature, and highlights some internal implementations that can help users
better understand the expected behavior of I/O throttling in practice.
Cloud Hypervisor allows to limit both the I/O bandwidth (e.g. bytes/s)
and I/O operations (ops/s) independently. To limit the I/O bandwidth, it
provides three user options, i.e., `bw_size` (bytes), `bw_one_time_burst`
(bytes), and `bw_refill_time` (ms). Both `bw_size` and `bw_refill_time`
are required, while `bw_one_time_burst` is optional.
Internally, these options define a TokenBucket with a maximum capacity
(`bw_size` bytes), an initial burst size (`bw_one_time_burst`) and an
interval for refilling purposes (`bw_refill_time`). The "refill-rate" is
`bw_size` bytes per `bw_refill_time` ms, and it is the constant rate at
which the tokens replenish. The refill process only starts happening
after the initial burst budget is consumed. Consumption from the token
bucket is unbounded in speed which allows for bursts bound in size by
the amount of tokens available. Once the token bucket is empty,
consumption speed is bound by the "refill-rate". Similarly, Cloud
Hypervisor provides another three options for limiting I/O operations,
i.e., `ops_size` (I/O operations), `bw_one_time_burst` (I/O operations),
and `bw_refill_time` (ms).
One caveat in the I/O throttling is that every-time the bucket gets
empty, it will stop I/O operations for a fixed amount of time
(`cool_down_time`). The `cool_down_time` now is fixed at `100 ms`, it
can have big implications to the actual rate limit (which can be a lot
different the expected "refill-rate" derived from user inputs). For
example, to have a 1000 IOPS limit, users should be able to provide
either of the following two options:
`ops_size=1000,ops_refill_time=1000` or
`ops_size=10,ops_refill_time=10`. However, the actual IOPS limits are
likely to be ~1000 IOPS and ~100 IOPS respectively. The reason is the
actual rate limit users get can be as low as
`ops_size/(ops_refill_time+cool_down_time)`. As a result, it is
generally advisable to keep `bw/ops_refill_time` larger than `100 ms`
(`cool_down_time`) to make sure the actual rate limit is close to users'
expectation ("refill-rate").

View File

@@ -86,11 +86,11 @@ virtual IOMMU:
```bash
./cloud-hypervisor \
--cpus 1 \
--cpus boot=1 \
--memory size=512M \
--disk path=clear-kvm.img,iommu=on \
--disk path=focal-server-cloudimg-amd64.raw,iommu=on \
--kernel custom-bzImage \
--cmdline "console=ttyS0 root=/dev/vda3" \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
```
From a guest perspective, it is easy to verify if the device is protected by
@@ -163,11 +163,11 @@ be consumed.
```bash
./cloud-hypervisor \
--cpus 1 \
--memory size=8G,file=/dev/hugepages \
--disk path=clear-kvm.img \
--cpus boot=1 \
--memory size=8G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 root=/dev/vda3 hugepagesz=2M hugepages=2048" \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw hugepagesz=2M hugepages=2048" \
--net tap=,mac=,iommu=on
```
@@ -180,11 +180,11 @@ passing through is `0000:00:01.0`.
```bash
./cloud-hypervisor \
--cpus 1 \
--memory size=8G,file=/dev/hugepages \
--disk path=clear-kvm.img \
--cpus boot=1 \
--memory size=8G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 root=/dev/vda3 kvm-intel.nested=1 vfio_iommu_type1.allow_unsafe_interrupts rw hugepagesz=2M hugepages=2048" \
--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
```
@@ -200,10 +200,10 @@ Last thing is to start the L2 guest with the huge pages memory backend.
```bash
./cloud-hypervisor \
--cpus 1 \
--memory size=4G,file=/dev/hugepages \
--disk path=clear-kvm.img \
--cpus boot=1 \
--memory size=4G,hugepages=on \
--disk path=focal-server-cloudimg-amd64.raw \
--kernel custom-bzImage \
--cmdline "console=ttyS0 root=/dev/vda3" \
--cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \
--device path=/sys/bus/pci/devices/0000:00:04.0
```

43
docs/logging.md Normal file
View File

@@ -0,0 +1,43 @@
# Logging
The target audience of this document is both:
* Developers who want to understand what log level to use and when,
* Users who want to debug issues with running their workloads in Cloud Hypervisor
## Control
The number of `-v` parameters passed to the `cloud-hypervisor` binary will determine the log level. Currenly the default is log messages up to `WARN:` (`warn!`) are included by default. The `--log-file` allows the log to be sent to a location other than `stderr`.
## Levels
### `error!()`
For immediate, unrecoverable errors where it does not make sense for the execution to continue as the behaviour of the VM is considerablely impacted.
Cloud Hypervisor should exit shortly after reporting this error (with a non-zero exit code). Generally this should be used during initial construction of the VM state before the virtual CPUs have begun running code.
A typical situation where this might occur is when the user is using command line options that conflict with each other or is trying to use a file that is not present on the filesystem.
Users should react to this error by checking their initial VM configuration.
### `warn!()`
A serious problem has occured but the execution of the VM can continue although some functionality might be impacted.
A typical example of where this level of message should be generated is during an API call request that cannot be fulfilled.
The user should investigate the meaning of this warning and take steps to ensure the correct functionality.
### `info!()`
Use `-v` to enable.
This level is for the benefit of developers. It should be used for sporadic and infrequent messages. The same message should not "spam" the logs. The VM should be usable when this level of debugging is enabled and trying to use `stdin/stdout` and the logs are going to `stderr`.
### `debug!()`
Use `-vv` to enable.
For the most verbose of logging messages. It is acceptable to "spam" the log with repeated invocations of the same message. This level of logging would be combined with `--log-file`.

32
docs/macvtap-bridge.md Normal file
View File

@@ -0,0 +1,32 @@
# Using MACVTAP to Bridge onto Host Network
Cloud Hypervisor supports using a MACVTAP device which is derived from a MACVLAN. Full details of configuring MACVLAN or MACVTAP is out of scope of this document. However the example below indicates how to bridge the guest directly onto the the network the host is on. Due to the lack of hairpin mode it not usually possible to reach the guest directly from the host.
```bash
# The MAC address must be attached to the macvtap and be used inside the guest
mac="c2:67:4f:53:29:cb"
# Host network adapter to bridge the guest onto
host_net="eno1"
# Create the macvtap0 as a new virtual MAC associated with the host network
sudo ip link add link "$host_net" name macvtap0 type macvtap
sudo ip link set macvtap0 address "$mac" up
sudo ip link show macvtap0
# A new character device is created for this interface
tapindex=$(< /sys/class/net/macvtap0/ifindex)
tapdevice="/dev/tap$tapindex"
# Ensure that we can access this device
sudo chown "$UID.$UID" "$tapdevice"
# Use --net fd=3 to point to fd 3 which the shell has opened to point to the /dev/tapN device
target/debug/cloud-hypervisor \
--kernel ~/src/linux/vmlinux \
--disk path=~/workloads/focal.raw \
--cpus boot=1 --memory size=512M \
--cmdline "root=/dev/vda1 console=hvc0" \
--net fd=3,mac=$mac 3<>$"$tapdevice"
```
As the guest is now connected to the same L2 network as the host you can obtain an IP address based on your host network (potentially including via DHCP)

453
docs/memory.md Normal file
View File

@@ -0,0 +1,453 @@
# 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,
hugepage_size: Option<u64>,
hotplug_method: HotplugMethod,
hotplug_size: Option<u64>,
hotplugged_size: Option<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>"
```
### `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` and `hugepage_size`
Specifies if the memory must be created and `mmap(2)` with `MAP_HUGETLB` and size
flags. This performs a memory mapping relying on the specified huge page size. If no huge page size is supplied the system's default huge page size is used.
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.
The user is responsible for ensuring there are sufficient huge pages of the specified size for the VMM to use. Failure to do so may result in strange VMM behaviour.
By default this option is turned off.
_Example_
```
--memory size=1G,hugepages=on,hugepage_size=2M
```
### `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
```
## 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,6 @@
# 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-hypervisor.
## Multiple queue support for net devices ##
@@ -14,7 +14,7 @@ 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 vhost-user-net will be covered once vhost-user-net backend has multiple 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
@@ -25,9 +25,9 @@ Use one `--net` command-line argument from cloud-hypervisor to specify the emula
./cloud-hypervisor \
--cpus 4 \
--memory "size=512M" \
--disk path=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" \
--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
```
@@ -51,6 +51,11 @@ If the tap device is pre-created on host before guest boot up. To use multiple q
[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

45
docs/profiling.md Normal file
View File

@@ -0,0 +1,45 @@
# Profiling
`perf` can be used to profile the `cloud-hypervisor` binary but it is necessary to make some modifications to the the build in order to produce a binary that gives useful results.
## Building a suitable binary
Modify the `Cargo.toml` file to add `debug = 1` to the `[profile.release]` block. It should look like this:
```
[profile.release]
lto = true
debug = 1
```
This adds the symbol information to the release binary but does not otherwise affect the performance.
The binary must also be built with frame pointers included so that the call graph can be captured by the profiler.
```
$ cargo clean && RUSTFLAGS='-C force-frame-pointers=y' cargo build --release
```
## Profiling
`perf` may then be used in the usual manner:
e.g.
```
$ perf record -g target/release/cloud-hypervisor \
--kernel ~/src/linux/vmlinux \
--pmem file=~/workloads/focal.raw \
--cpus boot=1 --memory size=1G \
--cmdline "root=/dev/pmem0p1 console=ttyS0" \
--serial tty --console off \
--api-socket=/tmp/api1
```
For analysing the samples:
```
$ perf report -g
```
If profiling with a network device attached either the TAP device must be already created and configured or the profiling must be done as root so that the TAP device can be created.

68
docs/seccomp.md Normal file
View File

@@ -0,0 +1,68 @@
# Seccomp filtering
As a means to harden Cloud Hypervisor's security, the project leverages seccomp
filtering.
## What is seccomp filtering
A seccomp filter is a way for a process to tell the kernel which system calls
are authorized.
In case this process calls into a prohibited system call, the kernel will kill
the process right away.
## How does it apply to Cloud Hypervisor
Cloud Hypervisor is a multi threaded application. It spawns dedicated threads
for virtual CPUs, virtio devices and HTTP server, along with the main thread
representing the VMM.
Each of these threads has a limited scope of what it is expected to perform,
which is why different filters are applied to each of them.
By default, Cloud Hypervisor enables seccomp filtering as the project believes
that security should not be an option.
For development and debugging purposes, one might want to disable this feature
or log the faulty system call.
### Disabling seccomp filters
Append `--seccomp false` to Cloud Hypervisor's command line to prevent seccomp
filtering from being applied.
### Logging prohibited system calls
In the context of debug, one alternative to disabling seccomp filtering is to
log faulty system calls that would have caused the application to be killed by
the kernel.
Append `--seccomp log` to Cloud Hypervisor's command line to enable faulty
system calls to be logged.
The kernel running on the host machine must have the `audit` parameter enabled.
If this is not the case, update kernel boot options by appending `audit=1`.
Unauthorized system calls will be logged to the journal similarly to the
following example
```
type=SECCOMP msg=audit(1423263412.694:7878): auid=1000 uid=1000 gid=1000 ses=3 subj=unconfined_u:unconfined_r:cloud_hypervisor:s0-s0:c0.c1023 pid=1193 comm="cloud-hypervisor" exe="/usr/bin/cloud-hypervisor" sig=0 arch=c000003e syscall=47 compat=0 ip=0x7f4f63982604 code=0x50000
```
Provided `ausyscall` has been installed on the host, the system call can be
identified with
```
$ ausyscall 47
recvmsg
```
### Further debug with `strace`
One more way of debugging seccomp related issues is to use the `strace` tool as
it will log every system call issued by the process. It is important to use
`-f` option in order to trace each and every thread belonging to the process.
```
strace -f ./cloud-hypervisor ...
```

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 distinct 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 occurred.
## 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.

75
docs/uefi.md Normal file
View File

@@ -0,0 +1,75 @@
# UEFI Boot
Cloud Hypervisor supports UEFI boot through the utilization of the EDK II based UEFI firmware.
## Building UEFI Firmware
To avoid any unnecessary issues, it is recommended to use Ubuntu 18.04 and its default toolset. Any other compatible Linux distribution is otherwise suitable, however it is suggested to use a temporary Docker container with Ubuntu 18.04 for a quick build on an existing Linux machine.
The commands below will compile an OVMF firmware suitable for Cloud Hypervisor.
```shell
sudo apt-get update
sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git
git clone https://github.com/cloud-hypervisor/edk2 -b ch
cd edk2
. edksetup.sh
git submodule update --init
echo "ACTIVE_PLATFORM=OvmfPkg/OvmfCh.dsc" >> Conf/target.txt
echo "TARGET_ARCH=X64" >> Conf/target.txt
echo "TOOL_CHAIN_TAG=GCC5" >> Conf/target.txt
make -C ./BaseTools
build
```
After the successful build, the resulting firmware binaries are available under `Build/OvmfCh/DEBUG_GCC5/FV` underneath the edk2 checkout.
## Using OVMF Binaries
Any UEFI capable image can be booted using the Cloud Hypervisor specific firmware. Windows guests under Cloud Hypervisor only support UEFI boot, therefore OVMF is mandatory there.
To make Cloud Hypervisor use UEFI boot, pass the `OVMF.fd` file path as an argument to the `--kernel` option. The firmware file will be opened in read only mode.
The same firmware can be used with Cloud Hypervisor or with QEMU. This is particularly useful if using QEMU for the preparation phase.
## Building UEFI Firmware with Compatibility Support Module (CSM)
CSM is a module that allows to boot legacy operating systems using the OVMF firmware. OVMF can embed a CSM build of SeaBIOS. To build the SeaBIOS with CSM support, add `CONFIG_CSM=y` to `.config` before the build. The outcome `out/Csm16.bin` is to be moved into `OvmfPkg/Csm/Csm16/Csm16.bin` before OVMF is built. Then, the OVMF build will have to be passed the `-D CSM_ENABLE` option in order to generate a legacy aware UEFI firmware. At the current stage, all the necessary patches are included in the Cloud Hypervisor specific [SeaBIOS branch](https://github.com/cloud-hypervisor/seabios/tree/ch). Taking into account the previous instructions, the modified command sequence to compile an OVMF binary with CSM support is the following one:
```shell
sudo apt-get update
sudo apt-get install uuid-dev nasm iasl build-essential python3-distutils git
git checkout https://github.com/cloud-hypervisor/seabios -b ch
cd seabios
make menuconfig
# Enable `CONFIG_CSM` and `CONFIG_QEMU_HARDWARE`
make CONFIG_CSM=y CONFIG_QEMU_HARDWARE=y
cd ..
git clone https://github.com/cloud-hypervisor/edk2 -b ch
cd edk2
. edksetup.sh
git submodule update --init
cp ../seabios/out/Csm16.bin OvmfPkg/Csm/Csm16/
echo "ACTIVE_PLATFORM=OvmfPkg/OvmfCh.dsc" >> Conf/target.txt
echo "TARGET_ARCH=X64" >> Conf/target.txt
echo "TOOL_CHAIN_TAG=GCC5" >> Conf/target.txt
make -C ./BaseTools
build
```
Please note, that the CSM support has currently only been tested with Linux guests. There are no plans to provide legacy support for other OSes (e.g. Windows).
# Links
- [OVMF wiki](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)
- [Cloud Hypervisor specific tree](https://github.com/cloud-hypervisor/edk2/tree/ch)
- [Redhat OVMF Status Report](https://access.redhat.com/sites/default/files/attachments/ovmf-whtepaper-031815.pdf)
- [SeaBIOS Build Overview](https://www.seabios.org/Build_overview#Build_as_a_UEFI_Compatibility_Support_Module_.28CSM.29)

View File

@@ -66,10 +66,10 @@ takes the device's sysfs path as an argument. In our example it is
```
./target/debug/cloud-hypervisor \
--kernel ~/vmlinux \
--disk path=~/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 path=/sys/bus/pci/devices/0000:01:00.0/
@@ -78,5 +78,3 @@ takes the device's sysfs path as an argument. In our example it is
The guest kernel will then detect the card reader on its PCI bus and provided
that support for this device is enabled, it will probe and enable it for the
guest to use.

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 &
```

92
docs/virtiofs-root.md Normal file
View File

@@ -0,0 +1,92 @@
# HOWTO VirtioFS rootfs
A quick guide for using virtiofs as a cloud-hypervisor guest's rootfs (i.e.
with no root block device). This document is a quick getting started guide.
There are many more steps to take to make this a production ready, secure
setup.
## Prerequisites
1. virtiofsd from the qemu project
* We are using the Qemu version for now
* There is a Rust version being worked on that may be a better option in the future
* Part of the qemu-system-common package on Ubuntu
* Part of the qemu-common package on Fedora
2. cloud-hypervisor - the newer the better, but I tested with 0.12
3. a rootfs - This howto uses an alpine rootfs available here:
* https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.2-x86_64.tar.gz
* Others should work
## To create the VM rootfs
```bash
mkdir rootfs/
cd rootfs
# this needs sudo to be able to set root permissions on fs components
sudo tar -xf /path/to/alpine-minirootfs-3.13.1-x86_64.tar.gz
# this will get created when the VM actually boots by the dhcp client
# but we need it in the chroot to download packages
sudo cp /etc/resolv.conf etc/
# the alpine mini rootfs is meant for docker containers, we need a few extra
# things for a working rootfs
sudo chroot $PWD apk add openrc busybox-initscripts
# we are using the paravirt console in cloud-hypervisor, so enable it in init
# append it after the other console since it doesn't work just appending it
sudo sed -i '/vt100/a \n# paravirt console\nhvc0::respawn:/sbin/getty -L hvc0 115200 vt100' etc/inittab
# set no password for root user... you obviously don't want to do this for
# any sort of production setup
sudo sed -i 's/root:!::0:::::/root:::0:::::/' etc/shadow
# set up init scripts
for i in acpid crond
sudo ln -sf /etc/init.d/$i etc/runlevels/default/$i
end
for i in bootmisc hostname hwclock loadkmap modules networking swap sysctl syslog urandom
sudo ln -sf /etc/init.d/$i etc/runlevels/boot/$i
end
for i in killprocs mount-ro savecache
sudo ln -sf /etc/init.d/$i etc/runlevels/shutdown/$i
end
for i in devfs dmesg hwdrivers mdev
sudo ln -sf /etc/init.d/$i etc/runlevels/sysinit/$i
end
# setup network config
echo 'auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
' | sudo tee etc/network/interfaces
```
## To run the VM
```bash
# starting in the directory above rootfs
sudo virtiofsd --socket-path=$PWD/virtiofs-rootfs.sock -o source=$PWD/rootfs -o cache=none &
sudo cloud-hypervisor \
--cpus boot=1,max=1 \
--kernel vmlinux \
--fs tag=/dev/root,socket=$PWD/virtiofs-rootfs.sock \
--memory size=2G,shared=on \
--cmdline "console=hvc0 rootfstype=virtiofs root=/dev/root ro debug" \
--api-socket $PWD/ch.sock \
--rng \
--net ...
```
Note: an important part of the above is the `tag=/dev/root` and
`root=/dev/root` parts. For whatever reason, it would only work with that as
the tag.
Note: another important bit is that the memory is shared. This is required for
virtiofs
## Message from the author
If you find any issues or have suggestions, feel free to reach out to @iggy on
the cloud-hypervisor slack. Also if this works for you, I'd like to know as
well. It would also be nice to get steps for preparing other distribution root
filesystems.

337
docs/windows.md Normal file
View File

@@ -0,0 +1,337 @@
# Windows Support
Starting with the release version [0.10.0](https://github.com/cloud-hypervisor/cloud-hypervisor/releases/tag/v0.10.0), Cloud Hypervisor supports Windows guests.
__Requirements__
- Host with KVM enabled
- [UEFI](uefi.md) capable Windows guest image with Virtio drivers integrated
Any modern Windows Server version is compatible. Cloud Hypervisor has been successfully tested with Windows Server 2019 and Windows Server Core 2004.
At the current stage, only UEFI capable Windows images are supported. This implies the presence of the OVMF firmware during the Windows installation and in any subsequent usage. BIOS boot is not supported.
The subsequent sections will tell, in detail, how to prepare an appropriate Windows image.
## Image Preparation
### Installation using the stock Windows ISO
__Prerequisites__
- QEMU, version >=5.0.0 is recommended.
- Windows installation ISO. Obtained through MSDN, Visual Studio subscription, evaluation center, etc.
- [VirtIO driver ISO](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/)
- Suitable [OVMF](uefi.md) firmware
- With the suggested image size of 30G, there should be enough free disk space to hold the installation ISO and any other necessary files
This step currently requires QEMU to install Windows onto the guest. QEMU is only used at the preparation stage, the resulting image is then fully functional with Cloud Hypervisor.
Preparing several command parts as these will be used in the follow up sections as well.
```shell
IMG_FILE=windows-disk.qcow
WIN_ISO_FILE=en_windows_server_version_2004_updated_may_2020_x64_dvd_1e7f1cfa.iso
VIRTIO_ISO_FILE=virtio-win-0.1.185.iso
OVMF_DIR=./FV
```
Create an empty image file, `qcow` or `raw` is supported.
```shell
qemu-img create -f qcow2 $IMG_FILE 30G
```
Begin the Windows installation process under QEMU
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
-cpu host \
-m 4G \
-bios ./$OVMF_DIR/OVMF_CODE.fd \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-drive if=none,id=root,file=./$IMG_FILE \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
-netdev user,id=mynet0 \
-vga std
```
Before the installation can proceed, point the Windows installation program to the VirtIO disk and install the necessary storage controller drivers. After that, the attached hard drive will become visible and the actual installation can commence.
After the installation has completed, proceed further to the configuration section. QEMU will be needed at least once more to enable the Windows Special Administration Console (SAC) and to possibly install extra device drivers.
## Image Usage
The basic command to boot a Windows image. The configuration section should be checked before executing it for the first time.
```shell
cloud-hypervisor \
--kernel ./$OVMF_DIR/OVMF.fd \
--disk path=./$IMG_FILE \
--cpus boot=1,kvm_hyperv=on \
--memory size=4G \
--serial tty \
--console off \
--net tap=
```
It is necessary to always:
- Carry the OVMF firmware in the `--kernel` option
- Add `kvm_hyperv=on` to the `--cpus` option
In cases where the host processor supports address space > 39 bits, it might be necessary to limit the address space. It can be done by appending the option `max_phys_bits=X` to the `--cpus` parameter, where `X` is the number of bits to be supported. Windows was tested to support at least 39-bit address space.
To daemonize the Cloud Hypervisor process, `nohup` can be used. Some STDIO redirections might need to be done. In a simple case it is sufficient to just redirect all the output to `/dev/null`.
## Image Configuration
### Device Drivers
After the Windows installation has finished under QEMU, there might be still devices with no drivers installed. This might happen for example, when a device was not used during the installation. In particular it is important to ensure that the VirtIO network device is setup correctly because further steps for the configuration and the usage require network in most case.
Boot once more under QEMU and use the [Device Manager](https://support.microsoft.com/en-in/help/4028443/windows-10-update-drivers), to ensure all the device drivers, and especially the network card, are installed correctly. Also, as Cloud Hypervisor can introduce new devices, it is advisable to repeat the procedure while booted under Cloud Hypervisor, when the RDP access to the image is functional.
### Windows Special Administration Console (SAC) enablement
SAC provides a text based console access to the Windows guest. As Cloud Hypervisor doesn't implement a VGA adaptor, SAC is an important instrument for the Windows guest management.
Boot the Windows image under QEMU and execute the below commands to permanently enable SAC
```cmd
bcdedit /emssettings emsport:1 emsbaudrate:115200
bcdedit /ems on
bcdedit /bootems on
```
Once SAC is enabled, the image can be booted under Cloud Hypervisor. The SAC prompt will show up
<pre>
Computer is booting, SAC started and initialized.
Use the "ch -?" command for information about using channels.
Use the "?" command for general help.
SAC>
</pre>
To open a console on the guest, the command sequence below can be used
<pre>
SAC>cmd
The Command Prompt session was successfully launched.
SAC>
EVENT: A new channel has been created. Use "ch -?" for channel help.
Channel: Cmd0001
SAC>ch -si 1
</pre>
See also the [links](#Links) section for a more extended SAC documentation.
## Network
This section illustrates the Windows specific corner points for the VM network configuration. For the extended networking guide, including bridging for multiple VMs, follow [networking.md](networking.md).
### Basic Networking
As the simplest option, using `--net tap=` in the Cloud Hypervisor command line will create a `vmtapX` device on the host with the default IPv4 adress `192.168.249.1`. After SAC becomes available, the guest configuration can be set with
<pre>
SAC>i 10 192.168.249.2 255.255.255.0 192.168.249.1
</pre>
Where `10` is the device index as shown by the `i` command.
### Guest Internet Connectivity
Additional steps are necessary to provide the guest with internet access.
- On the guest, add the DNS server either by using `netsh` or by opening `Network and Connectivity Center` and editing the adapter properties.
- On the host, configure the traffic forwarding. Replace the `NET_DEV` with the name of your network device.
```shell
NET_DEV=wlp3s0
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $NET_DEV -j MASQUERADE
```
### Remote Desktop Protocol (RDP) enablement
#### Using QEMU
- Execute `SystemPropertiesRemote`
- In the properties window, choose "Allow remote connections to this computer"
- Click "Select Users" and add some user to the allow list
#### Using powershell
```powershell
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\" -Name "fDenyTSConnections" -Value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
Add-LocalGroupMember -Group "Remote Desktop Users" -Member someuser
```
Administrators can always RDP, non administrator users have to be explicitly enabled.
Once the configuration is set, RDP clients can connect to `192.168.249.2`.
### SSH
#### Enable using powershell
```powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
```
This allows for SSH login from a remote machine, for example through the `administrator` user: `ssh administrator@192.168.249.2`. For a more detailed OpenSSH guide, please follow the MSDN article from the [links](#links) section.
## Debugging
The Windows guest debugging process relies heavily on QEMU and [socat](http://www.dest-unreach.org/socat/). The procedure requires two Windows VMs:
- A debugger VM running under QEMU.
- A debuggee, a Windows VM that has been created in the previous steps, running under Cloud Hypervisor or QEMU.
The connection between both guests happens over TCP, whereby on the guest side it is automatically translated to a COM port. Because the VMs are connected through TCP, the debugging infrastructure can be distributed over the network. The serial port, while slowly transferring data, is common enough to support a wide range of cases and tools.
In this excercise, [WinDbg](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) is used. Any other debugger of choice with the ability to use serial connection can be used instead.
### Debugger and Debuggee
#### WinDbg VM
For simplicity, the debugger VM is supposed to be only running under QEMU. It will require VGA and doesn't neccessarily depend on UEFI. As an OS, it can carry any supported Windows OS where the debugger of choice can be installed. The simplest way is to follow the image preparation instructions from the previous chapter, but avoid using the OVMF firmware. It is also not required to use VirtIO drivers, whereby it might be useful in some case. Though, while creating the image file for the debugger VM, be sure to choose a sufficient disk size that counts in the need to save the corresponding debug symbols and sources.
To create the debugger Windows VM, the following command can be used:
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
-cpu host \
-smp 1 \
-m 4G \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-drive if=none,id=root,file=./windbg-disk.qcow \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
-netdev user,id=mynet0,net=192.168.178.0/24,host=192.168.178.1,dhcpstart=192.168.178.64,hostname=windbg-host \
-vga std
```
A non server Windows OS like Windows 10 can be used to carry the debugging tools in the debugger VM.
#### Debuggee VM
The debuggee VM is the one that we've learned to configure and run in the first section. There might be various reasons to debug. For example, there could be an issue in the Windows guest with an emulated device or an included driver. Or, we might want to develop a custom feature like a kernel driver to be available in the guest.
Note, that there are several ways to debug Windows, not all of them need to be enabled at the same time. For example, if developing a kernel module, the only useful options would be to configure for the serial debugging and enable the kernel debug. In that case, any crash or misbehavior in the boot loader or kernel would be ignored. The commands below must be run as administrator on the debuggee guest VM.
##### Turn On Serial Debugging
This will configure the debugging to be enabled and instruct to use the serial port for it.
```cmd
bcdedit /dbgsettings serial debugport:1 baudrate:115200
```
##### Turn On Kernel Debuging
```cmd
bcdedit /debug on
```
##### Turn On Boot Loader Debug
```cmd
bcdedit /bootdebug on
```
##### Turn on boot manager debug
```cmd
bcdedit /set {bootmgr} bootdebug on
```
##### Disable Recovery Screen On Boot Failure
There could be a situation, where a crash is debugged. In such cases, the guest could be left in an inconsistent state. The default Windows behavior would be to boot into the recovery screen, however in some cases it might be not desired. To make Windows ignore failures and always proceed to booting the OS, use the command below:
```cmd
bcdedit /set {default} bootstatuspolicy ignoreallfailures
```
### Debugging Process
#### Invoke the WinDbg VM
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
-cpu host \
-smp 1 \
-m 4G \
-drive if=none,id=root,file=./windbg-disk.qcow \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-serial tcp::4445,server,nowait \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
-netdev user,id=mynet0,net=192.168.178.0/24,host=192.168.178.1,dhcpstart=192.168.178.64,hostname=windbg-host \
-vga std
```
Note, this VM has the networking enabled. It is needed, because symbols and sources might need to be fetched from a network location.
Also, notice the `-serial` parameter - that's what does the magic on exposing the serial port to the guest while connecting the debugger VM with a client VM through the network. SAC/EMS needs to be disabled in the debugger VM, as otherwise the COM device might be blocked.
Hereafter, WinDbg can be started using a command below:
```cmd
set _NT_DEBUG_PORT=com1
set _NT_DEBUG_BAUD_RATE=115200
windbg -v -d -k
```
Once started, WinDbg will wait for an incoming connection which is going to be initialized by the debuggee VM started in the next section.
#### Invoke the Debuggee VM
##### Under QEMU
Essentially it would be the command like depicted in the guest preparation sections, with a few modifications:
```shell
qemu-system-x86_64 \
-machine q35,accel=kvm \
-cpu host \
-m 4G \
-bios ./$OVMF_DIR/OVMF_CODE.fd \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-drive if=none,id=root,file=./$IMG_FILE \
-device virtio-blk-pci,drive=root,disable-legacy=on \
-device virtio-net-pci,netdev=mynet0,disable-legacy=on \
-netdev user,id=mynet0 \
-serial tcp:127.0.0.1:4445 \
-vga std
```
It is to see, that `-serial` parameter is used here, to establish the connection with the debugger VM.
To disable HPET, attach `--no-hpet`. To enable hypervisor reference timer, use `-cpu host,hv-time`. These and other options can be used to achieve better [Hyper-V compatibility](https://archive.fosdem.org/2019/schedule/event/vai_enlightening_kvm/attachments/slides/2860/export/events/attachments/vai_enlightening_kvm/slides/2860/vkuznets_fosdem2019_enlightening_kvm.pdf).
##### Cloud Hypervisor
The `socat` tool is used to establish the QEMU compatible behavior. Here as well, the Cloud Hypervisor command used to run the Windows guest is to be used. Put the command into a shell script:
`socat SYSTEM:"./ch-script",openpty,raw,echo=0 TCP:localhost:4445`
The reason to pack the command into the shell script is that the command might contain a comma. When using SYSTEM, the shell command can't contain `,` or `!!`.
## Links
- [Fedora VirtIO guide for Windows](https://docs.fedoraproject.org/en-US/quick-docs/creating-windows-virtual-machines-using-virtio-drivers/)
- [VirtIO driver binaries](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/)
- [VirtIO driver sources](https://github.com/virtio-win/kvm-guest-drivers-windows)
- [Emergency Management Services](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc787940(v=ws.10))
- [OpenSSH server/client configuration](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse)
- [Windows guest debugging under KVM](https://www.linux-kvm.org/page/WindowsGuestDrivers/GuestDebugging)
- ["ENLIGHTENING" KVM](https://archive.fosdem.org/2019/schedule/event/vai_enlightening_kvm/attachments/slides/2860/export/events/attachments/vai_enlightening_kvm/slides/2860/vkuznets_fosdem2019_enlightening_kvm.pdf)

11
event_monitor/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "event_monitor"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[dependencies]
libc = "0.2.91"
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"

77
event_monitor/src/lib.rs Normal file
View File

@@ -0,0 +1,77 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use]
extern crate serde_derive;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use std::time::{Duration, Instant};
static mut MONITOR: Option<(File, Instant)> = None;
/// This function must only be called once from the main process before any threads
/// are created to avoid race conditions
pub fn set_monitor(file: File) -> Result<(), std::io::Error> {
assert!(unsafe { MONITOR.is_none() });
let fd = file.as_raw_fd();
let ret = unsafe {
let mut flags = libc::fcntl(fd, libc::F_GETFL);
flags |= libc::O_NONBLOCK;
libc::fcntl(fd, libc::F_SETFL, flags)
};
if ret < 0 {
return Err(std::io::Error::last_os_error());
}
unsafe {
MONITOR = Some((file, Instant::now()));
};
Ok(())
}
#[derive(Serialize)]
struct Event<'a> {
timestamp: Duration,
source: &'a str,
event: &'a str,
properties: Option<&'a HashMap<Cow<'a, str>, Cow<'a, str>>>,
}
pub fn event_log(source: &str, event: &str, properties: Option<&HashMap<Cow<str>, Cow<str>>>) {
if let Some((file, start)) = unsafe { MONITOR.as_ref() } {
let e = Event {
timestamp: start.elapsed(),
source,
event,
properties,
};
serde_json::to_writer_pretty(file, &e).ok();
}
}
/*
Through the use of Cow<'a, str> it is possible to use String as well as
&str as the parameters:
e.g.
event!("cpu_manager", "create_vcpu", "id", cpu_id.to_string());
*/
#[macro_export]
macro_rules! event {
($source:expr, $event:expr) => {
$crate::event_log($source, $event, None)
};
($source:expr, $event:expr, $($key:expr, $value:expr),*) => {
{
let mut properties = ::std::collections::HashMap::new();
$(
properties.insert($key.into(), $value.into());
)+
$crate::event_log($source, $event, Some(&properties))
}
};
}

4
fuzz/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
target
corpus
artifacts

765
fuzz/Cargo.lock generated Normal file
View File

@@ -0,0 +1,765 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "acpi_tables"
version = "0.1.0"
dependencies = [
"vm-memory",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"
[[package]]
name = "api_client"
version = "0.1.0"
[[package]]
name = "arbitrary"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "698b65a961a9d730fb45b6b0327e20207810c9f61ee421b082b27ba003f49e2b"
[[package]]
name = "arc-swap"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d7d63395147b81a9e570bcc6243aaf71c017bd666d4909cfef0085bdda8d73"
[[package]]
name = "arch"
version = "0.1.0"
dependencies = [
"acpi_tables",
"anyhow",
"arch_gen",
"byteorder",
"hypervisor",
"libc",
"linux-loader",
"log",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vm-memory",
"vm-migration",
]
[[package]]
name = "arch_gen"
version = "0.1.0"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "block_util"
version = "0.1.0"
dependencies = [
"io-uring",
"libc",
"log",
"qcow",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"virtio-bindings",
"vm-memory",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"term_size",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "cloud-hypervisor"
version = "0.13.0"
dependencies = [
"anyhow",
"api_client",
"clap",
"epoll",
"event_monitor",
"hypervisor",
"libc",
"log",
"option_parser",
"seccomp",
"serde_json",
"signal-hook",
"thiserror",
"vm-memory",
"vmm",
"vmm-sys-util",
]
[[package]]
name = "cloud-hypervisor-fuzz"
version = "0.0.0"
dependencies = [
"block_util",
"cloud-hypervisor",
"libc",
"libfuzzer-sys",
"qcow",
"seccomp",
"virtio-devices",
"vm-memory",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "devices"
version = "0.1.0"
dependencies = [
"acpi_tables",
"anyhow",
"bitflags",
"byteorder",
"epoll",
"libc",
"log",
"serde",
"serde_derive",
"serde_json",
"vm-device",
"vm-memory",
"vm-migration",
"vmm-sys-util",
]
[[package]]
name = "epoll"
version = "4.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20df693c700404f7e19d4d6fae6b15215d2913c27955d2b9d6f2c0f537511cd0"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "event_monitor"
version = "0.1.0"
dependencies = [
"libc",
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "hypervisor"
version = "0.1.0"
dependencies = [
"anyhow",
"epoll",
"iced-x86",
"kvm-bindings",
"kvm-ioctls",
"libc",
"log",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vm-memory",
"vmm-sys-util",
]
[[package]]
name = "iced-x86"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4261b15a556aa9b83b976b7aa4613f5a3b80351683af14c5d8d7e62c00869d5a"
dependencies = [
"lazy_static",
"static_assertions",
]
[[package]]
name = "io-uring"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb82832e05cc4ca298f198a8db108837b4f7b7b1248e3cba8e48f151aece80cf"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "kvm-bindings"
version = "0.4.0"
source = "git+https://github.com/cloud-hypervisor/kvm-bindings?branch=ch-v0.4.0#1a68725639283e622f4bb64584885b30bfe8be44"
dependencies = [
"serde",
"serde_derive",
"vmm-sys-util",
]
[[package]]
name = "kvm-ioctls"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74058b16912c6723db02d4ca3ec919b73cd41512ccd3b6202cf91ae8d6c9dce5"
dependencies = [
"kvm-bindings",
"libc",
"vmm-sys-util",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
[[package]]
name = "libfuzzer-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86c975d637bc2a2f99440932b731491fc34c7f785d239e38af3addd3c2fd0e46"
dependencies = [
"arbitrary",
"cc",
]
[[package]]
name = "linux-loader"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c819cc8275b0f2c1ed9feec455ca288b45d82932384a6a5f7a86812ee3427459"
dependencies = [
"vm-memory",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=master#59ab64440a95f7b16253fef67b5201c2ec4adaf7"
dependencies = [
"epoll",
]
[[package]]
name = "net_gen"
version = "0.1.0"
dependencies = [
"vmm-sys-util",
]
[[package]]
name = "net_util"
version = "0.1.0"
dependencies = [
"epoll",
"libc",
"log",
"net_gen",
"serde",
"virtio-bindings",
"vm-memory",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "option_parser"
version = "0.1.0"
[[package]]
name = "pci"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"hypervisor",
"libc",
"log",
"serde",
"serde_derive",
"serde_json",
"vfio-bindings",
"vfio-ioctls",
"vm-allocator",
"vm-device",
"vm-memory",
"vm-migration",
"vmm-sys-util",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "qcow"
version = "0.1.0"
dependencies = [
"byteorder",
"libc",
"log",
"remain",
"vmm-sys-util",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "remain"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "seccomp"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/firecracker?tag=v0.22.0#cc5387637c132e500b4857b80b5a239d8d732b77"
dependencies = [
"libc",
]
[[package]]
name = "serde"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
[[package]]
name = "serde_derive"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "signal-hook"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa894ef3fade0ee7243422f4fbbd6c2b48e6de767e621d37ef65f2310f53cea"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-registry"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
dependencies = [
"libc",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"term_size",
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "vfio-bindings"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a21f546f2bda37f5a8cfb138c87f95b8e34d2d78d6a7a92ba3785f4e08604a7"
dependencies = [
"vmm-sys-util",
]
[[package]]
name = "vfio-ioctls"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio-ioctls?branch=master#a87b13bdec026e8144b91f30f35451a966d8c1ca"
dependencies = [
"byteorder",
"kvm-bindings",
"kvm-ioctls",
"log",
"vfio-bindings",
"vm-memory",
"vmm-sys-util",
]
[[package]]
name = "vhost"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vhost?branch=master#ee3e8722706c984b3dfe12d3a130e92101b78e8f"
dependencies = [
"bitflags",
"libc",
"vmm-sys-util",
]
[[package]]
name = "virtio-bindings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff512178285488516ed85f15b5d0113a7cdb89e9e8a760b269ae4f02b84bd6b"
[[package]]
name = "virtio-devices"
version = "0.1.0"
dependencies = [
"anyhow",
"arc-swap",
"block_util",
"byteorder",
"epoll",
"event_monitor",
"io-uring",
"libc",
"log",
"net_gen",
"net_util",
"pci",
"seccomp",
"serde",
"serde_derive",
"serde_json",
"vhost",
"virtio-bindings",
"vm-allocator",
"vm-device",
"vm-memory",
"vm-migration",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "vm-allocator"
version = "0.1.0"
dependencies = [
"arch",
"libc",
"vm-memory",
]
[[package]]
name = "vm-device"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vfio-ioctls",
"vm-memory",
"vmm-sys-util",
]
[[package]]
name = "vm-memory"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "625f401b1b8b3ac3d43f53903cd138cfe840bd985f8581e553027b31d2bb8ae8"
dependencies = [
"arc-swap",
"libc",
"winapi",
]
[[package]]
name = "vm-migration"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"vm-memory",
]
[[package]]
name = "vm-virtio"
version = "0.1.0"
dependencies = [
"log",
"serde",
"serde_derive",
"serde_json",
"virtio-bindings",
"vm-memory",
]
[[package]]
name = "vmm"
version = "0.1.0"
dependencies = [
"acpi_tables",
"anyhow",
"arc-swap",
"arch",
"bitflags",
"block_util",
"clap",
"devices",
"epoll",
"event_monitor",
"hypervisor",
"lazy_static",
"libc",
"linux-loader",
"log",
"micro_http",
"net_util",
"option_parser",
"pci",
"qcow",
"seccomp",
"serde",
"serde_derive",
"serde_json",
"signal-hook",
"thiserror",
"vfio-ioctls",
"virtio-devices",
"vm-allocator",
"vm-device",
"vm-memory",
"vm-migration",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "vmm-sys-util"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cf11afbc4ebc0d5c7a7748a77d19e2042677fc15faa2f4ccccb27c18a60605"
dependencies = [
"bitflags",
"libc",
"serde",
"serde_derive",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

42
fuzz/Cargo.toml Normal file
View File

@@ -0,0 +1,42 @@
[package]
name = "cloud-hypervisor-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"
[package.metadata]
cargo-fuzz = true
[dependencies]
block_util = { path = "../block_util" }
libc = "0.2.90"
libfuzzer-sys = "0.4"
qcow = { path = "../qcow" }
seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" }
virtio-devices = { path = "../virtio-devices" }
vmm-sys-util = "0.8.0"
vm-virtio = { path = "../vm-virtio" }
vm-memory = "0.5.0"
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.4.0", features = ["with-serde", "fam-wrappers"] }
[dependencies.cloud-hypervisor]
path = ".."
# 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

140
fuzz/fuzz_targets/block.rs Normal file
View File

@@ -0,0 +1,140 @@
// 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 block_util::{async_io::DiskFile, qcow_sync::QcowDiskSync};
use libfuzzer_sys::fuzz_target;
use seccomp::SeccompAction;
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 qcow_disk = Box::new(QcowDiskSync::new(disk_file, false)) as Box<dyn DiskFile>;
let mut block = Block::new(
"tmp".to_owned(),
qcow_disk,
PathBuf::from(""),
false,
false,
2,
256,
SeccompAction::Allow,
None,
)
.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)
}
}

35
hypervisor/Cargo.toml Normal file
View File

@@ -0,0 +1,35 @@
[package]
name = "hypervisor"
version = "0.1.0"
authors = ["Microsoft Authors"]
edition = "2018"
license = "Apache-2.0 OR BSD-3-Clause"
[features]
kvm = ["kvm-ioctls", "kvm-bindings"]
mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0"
epoll = ">=4.0.1"
thiserror = "1.0"
libc = "0.2.91"
log = "0.4.14"
kvm-ioctls = { version = "0.8.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.4.0", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-bindings = {git = "https://github.com/cloud-hypervisor/mshv", branch = "master", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-ioctls = { git = "https://github.com/cloud-hypervisor/mshv", branch = "master", optional = true}
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vm-memory = { version = "0.5.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = ">=0.5.0", features = ["with-serde"] }
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]
version = "1.11"
default-features = false
features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"]
[dev-dependencies]
env_logger = "0.8.3"

View File

@@ -0,0 +1,148 @@
//
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
extern crate thiserror;
use core::fmt::Debug;
use std::fmt::{self, Display};
use thiserror::Error;
#[derive(Clone, Copy, Error, Debug)]
pub struct Exception<T: Debug> {
vector: T,
ip: u64,
error: Option<u32>,
payload: Option<u64>,
}
impl<T: Debug> Display for Exception<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Exception {:?} at IP {:#x}", self.vector, self.ip)
}
}
#[derive(Error, Debug)]
pub enum PlatformError {
#[error("Invalid address: {0}")]
InvalidAddress(#[source] anyhow::Error),
#[error("Invalid register: {0}")]
InvalidRegister(#[source] anyhow::Error),
#[error("Invalid state: {0}")]
InvalidState(#[source] anyhow::Error),
#[error("Memory read failure: {0}")]
MemoryReadFailure(#[source] anyhow::Error),
#[error("Memory write failure: {0}")]
MemoryWriteFailure(#[source] anyhow::Error),
#[error("Get CPU state failure: {0}")]
GetCpuStateFailure(#[source] anyhow::Error),
#[error("Set CPU state failure: {0}")]
SetCpuStateFailure(#[source] anyhow::Error),
#[error("Translate virtual address: {0}")]
TranslateVirtualAddress(#[source] anyhow::Error),
#[error("Unsupported CPU Mode: {0}")]
UnsupportedCpuMode(#[source] anyhow::Error),
#[error("Invalid instruction operand: {0}")]
InvalidOperand(#[source] anyhow::Error),
}
#[derive(Error, Debug)]
pub enum EmulationError<T: Debug> {
#[error("Unsupported instruction: {0}")]
UnsupportedInstruction(#[source] anyhow::Error),
#[error("Unsupported memory size: {0}")]
UnsupportedMemorySize(#[source] anyhow::Error),
#[error("Invalid operand: {0}")]
InvalidOperand(#[source] anyhow::Error),
#[error("Wrong number of operands: {0}")]
WrongNumberOperands(#[source] anyhow::Error),
#[error("Instruction Exception: {0}")]
InstructionException(Exception<T>),
#[error("Instruction fetching error: {0}")]
InstructionFetchingError(#[source] anyhow::Error),
#[error("Platform emulation error: {0}")]
PlatformEmulationError(PlatformError),
#[error(transparent)]
EmulationError(#[from] anyhow::Error),
}
/// The PlatformEmulator trait emulates a guest platform.
/// It's mostly a guest resources (memory and CPU state) getter and setter.
///
/// A CpuState is an architecture specific type, representing a CPU state.
/// The emulator and its instruction handlers modify a given CPU state and
/// eventually ask the platform to commit it back through `set_cpu_state`.
pub trait PlatformEmulator: Send + Sync {
type CpuState: Clone;
/// Read guest memory into a u8 slice.
///
/// # Arguments
///
/// * `gva` - Guest virtual address to read from.
/// * `data` - Data slice to read into.
///
fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError>;
/// Write a u8 slice into guest memory.
///
/// # Arguments
///
/// * `gva` - Guest virtual address to write into.
/// * `data` - Data slice to be written.
///
fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError>;
/// Get a CPU state from the guest.
///
/// # Arguments
///
/// * `cpu_id` - Logical CPU ID.
///
fn cpu_state(&self, cpu_id: usize) -> Result<Self::CpuState, PlatformError>;
/// Set a guest CPU state.
///
/// # Arguments
///
/// * `cpu_id` - Logical CPU ID.
/// * `state` - State to set the CPU into.
///
fn set_cpu_state(&self, cpu_id: usize, state: Self::CpuState) -> Result<(), PlatformError>;
/// Translate a guest virtual address into a physical one
///
/// # Arguments
///
/// * `gva` - Guest virtual address to translate.
///
fn gva_to_gpa(&self, gva: u64) -> Result<u64, PlatformError>;
/// Fetch instruction bytes from memory.
///
/// # Arguments
///
/// * `ip` - Instruction pointer virtual address to start fetching instructions from.
///
fn fetch(&self, ip: u64, instruction_bytes: &mut [u8]) -> Result<(), PlatformError>;
}
pub type EmulationResult<S, E> = std::result::Result<S, EmulationError<E>>;

View File

@@ -0,0 +1,18 @@
// 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
//
pub mod emulator;
#[cfg(target_arch = "x86_64")]
#[macro_use]
pub mod x86;

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