Compare commits

...

260 Commits
v36.1 ... v38.0

Author SHA1 Message Date
Bo Chen
ef4fbf086f build: Release v38.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-16 10:00:41 -08:00
Jinank Jain
9f8aeacd3d vmm: Force enable IOMMU incase of SEV-SNP guest
In case of SEV-SNP guest devices use sw-iotlb to gain access guest
memory for DMA. For that F_IOMMU/F_ACCESS_PLATFORM must be exposed in
the feature set of virtio devices.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-16 09:28:00 +00:00
Thomas Barrett
c9f94be7ab pci: vfio: naturally align bar
According to PCIe specification, a 64-bit MMIO BAR should be
naturally aligned. In addition to being more compliant with
the specification, natural aligned BARs are mapped with
the largest possible page size by the host iommu driver, which
should speed up boot time and reduce IOTLB thrashing for virtual
machines with VFIO devices.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-02-16 08:24:56 +00:00
dependabot[bot]
af49b10cf2 build: Bump darling from 0.20.3 to 0.20.6
Bumps [darling](https://github.com/TedDriggs/darling) from 0.20.3 to 0.20.6.
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/compare/v0.20.3...v0.20.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-16 00:29:27 +00:00
dependabot[bot]
2fc2cabcbc build: Bump js-sys from 0.3.67 to 0.3.68 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.67 to 0.3.68.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-15 23:45:29 +00:00
Thomas Barrett
ce7db3f7c3 arch: x86_64: allow more than 2 E820_RAM ranges
The 'generate_ram_ranges' function currently hardcodes the assumption
that there are only 2 E820 RAM entries. This is not flexible enough to
handle vendor specific memory holes. Returning a Vec is also more
convenient for users of this function.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-02-15 08:49:06 +00:00
dependabot[bot]
bcdd23956f build: Bump anstyle from 1.0.1 to 1.0.6
Bumps [anstyle](https://github.com/rust-cli/anstyle) from 1.0.1 to 1.0.6.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-ls-v1.0.1...v1.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-15 00:24:07 +00:00
dependabot[bot]
b1f3860d9a build: Bump clap from 4.4.18 to 4.5.0 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.18 to 4.5.0.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.18...clap_complete-v4.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-14 23:20:25 +00:00
dependabot[bot]
341152b4c7 build: Bump smallvec from 1.11.0 to 1.13.1
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.0 to 1.13.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.0...v1.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-14 02:15:15 +00:00
dependabot[bot]
e013fdd9d4 build: Bump anstyle from 1.0.4 to 1.0.6 in /fuzz
Bumps [anstyle](https://github.com/rust-cli/anstyle) from 1.0.4 to 1.0.6.
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.4...v1.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-13 23:13:14 +00:00
Jinank Jain
eee31f1d41 vmm: Don't set rsdp addr in case of SEV-SNP guest
Since the ACPI tables are generated inside the IGVM file in case of
SEV-SNP guest. So, we don't need to generate it inside the cloud
hypervisor.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-13 11:29:46 -08:00
Jinank Jain
d0be450b1b hypervisor: Do not register ioevent for SEV-SNP
... enabled VMs. IOEvents are not supported in case of SEV-SNP VMs. All
the IO events are delievered via GHCB protocol.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-13 11:26:20 -08:00
Jinank Jain
3a683b54d5 hypervisor: Add a flag to identify sev-snp VM
This will help in identify whether a VM supports sev-snp and based on
that disable/enable certain features.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-13 11:26:20 -08:00
Ruslan Mstoi
af4a193b43 build: add shell script linter workflow
Implement workflow to to run static analysis and linting of all shell
scripts by using shfmt and shellcheck.

Fixes: #5396

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-02-13 10:20:18 +00:00
Ruslan Mstoi
2b2d00653c scripts: fix shell scripts according to shellcheck errors
Unify coding style of shell scripts in accordance with
shellcheck errors.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-02-13 10:20:18 +00:00
Ruslan Mstoi
318caeb9d8 scripts: fix shell scripts format according to shfmt
Unify coding style of shell scripts in accordance with shfmt checks.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-02-13 10:20:18 +00:00
Peteris Rudzusiks
612a8dfb1b vmm: seccomp: Allow all threads to call sched_yield()
We occasionally saw cloud-hypervisor crashed due to seccomp violations. The
coredumps showed the HTTP API thread crashing after it attempted to call
sched_yield(). The call came from rust stdlib's mpmc module, which calls
sched_yield() if several attempts to busy-wait for a condition to fulfil fall
short.

Since the system call is harmless and it comes from the stdlib, I opted to allow
all threads to call it.

Signed-off-by: Peteris Rudzusiks <rye@stripe.com>
2024-02-13 10:20:07 +00:00
Jinank Jain
321d6f47e6 hypervisor: mshv: Add new memory region flag
GPA_MAP_ADJUSTABLE suggests hypervisor to adjust GPA permissions as
required.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2024-02-13 09:08:59 +00:00
acarp
035c4b20fb block: Set an option to pin virtio block threads to host cpus
Currently the only way to set the affinity for virtio block threads is
to boot the VM, search for the tid of each of the virtio block threads,
then set the affinity manually. This commit adds an option to pin virtio
block queues to specific host cpus (similar to pinning vcpus to host
cpus). A queue_affinity option has been added to the disk flag in
the cli to specify a mapping of queue indices to host cpus.

Signed-off-by: acarp <acarp@crusoeenergy.com>
2024-02-13 09:05:57 +00:00
dependabot[bot]
ee0cf3a715 build: Bump dhat from 0.3.2 to 0.3.3
Bumps [dhat](https://github.com/nnethercote/dhat-rs) from 0.3.2 to 0.3.3.
- [Release notes](https://github.com/nnethercote/dhat-rs/releases)
- [Commits](https://github.com/nnethercote/dhat-rs/compare/0.3.2...0.3.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-13 00:32:34 +00:00
dependabot[bot]
ffef4ae5ac build: Bump io-uring from 0.6.2 to 0.6.3 in /fuzz
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.2 to 0.6.3.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 23:30:29 +00:00
dependabot[bot]
8f98240ed4 build: Bump serde_json from 1.0.112 to 1.0.113 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.112 to 1.0.113.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.112...v1.0.113)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-10 00:38:41 +00:00
dependabot[bot]
5b0de115f0 build: Bump serde from 1.0.193 to 1.0.196
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.196.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.196)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 23:45:54 +00:00
dependabot[bot]
308b74f3a4 build: Bump proc-macro2 from 1.0.76 to 1.0.78 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.76 to 1.0.78.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.76...1.0.78)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 23:41:25 +00:00
Jinank Jain
441b58437f vmm: Don't configure vcpu in case of SEV-SNP
Traditional way to configure vcpu don't work for sev-snp guests. All the
vCPU configuration for SEV-SNP guest is provided via VMSA.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-09 09:46:19 -08:00
dependabot[bot]
829d310c57 build: Bump jobserver from 0.1.27 to 0.1.28 in /fuzz
Bumps [jobserver](https://github.com/alexcrichton/jobserver-rs) from 0.1.27 to 0.1.28.
- [Commits](https://github.com/alexcrichton/jobserver-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 07:52:31 +00:00
dependabot[bot]
9c7ee4ab3d build: Bump winnow from 0.5.18 to 0.5.39
Bumps [winnow](https://github.com/winnow-rs/winnow) from 0.5.18 to 0.5.39.
- [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md)
- [Commits](https://github.com/winnow-rs/winnow/compare/v0.5.18...v0.5.39)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 07:52:13 +00:00
Bo Chen
ab5a731160 block: vhdx: Remove unused 'struct RegionEntry'
This also fixes the following clippy warning on nightly build from cargo
fuzz:

warning: struct `RegionEntry` is never constructed
   --> /home/chenb/project/cloud-hypervisor/cloud-hypervisor/block/src/vhdx/vhdx_header.rs:357:8
    |
357 | struct RegionEntry {
    |        ^^^^^^^^^^^
    |
    = note: `RegionEntry` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
    = note: `#[warn(dead_code)]` on by default

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-09 07:51:57 +00:00
Thomas Barrett
f0c1f8d079 pci: vfio: VFIO_IOMMU_MAP_DMA mmio regions
For all VFIO devices, map all non-emulated MMIO regions to
the vfio container to allow PCIe P2P between all VFIO devices
on the virtual machine. This is required for a wide variety of
advanced GPU workloads such as GPUDirect P2P (DMA between two
GPUs), GPUDirect RDMA (DMA between a GPU and an IB device).

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-02-08 10:02:58 -08:00
Muminul Islam
56dbb8f0db main: Support igvm as a payload
Currently kernel and firmware are checked as a payload.
IGVM should be checked as well. Otherwise, it hangs indefinitely.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-08 09:46:45 -08:00
Muminul Islam
66f8841ba1 scripts: add main as a component
Main should be a component during the commit check.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-08 09:46:45 -08:00
dependabot[bot]
5641e3a283 build: Bump libc from 0.2.151 to 0.2.153
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.151 to 0.2.153.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.151...0.2.153)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 09:51:55 +00:00
dependabot[bot]
653d0548eb build: Bump darling from 0.20.3 to 0.20.5 in /fuzz
Bumps [darling](https://github.com/TedDriggs/darling) from 0.20.3 to 0.20.5.
- [Release notes](https://github.com/TedDriggs/darling/releases)
- [Changelog](https://github.com/TedDriggs/darling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TedDriggs/darling/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 00:04:04 +00:00
Jinank Jain
50241f94d9 hypervisor: mshv: Add support to handle unaccepted GPA
Unaccepted GPA is usually thrown by Microsoft hypervisor in case of
mismatch between GPA and GVA mappings. This is a fatal message from the
hypervisor perspective so we would need to error out from the vcpu run
loop. Along with add some debug message to identify the broken mapping
between GVA and GPA.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-07 11:00:00 -08:00
Sean Banko
7633d47293 vmm: prefault memory in parallel to optimize boot time
On guests with large amounts of memory, using the `prefault` option can
lead to a very long boot time. This commit implements the strategy
taken by QEMU to prefault memory in parallel using multiple threads,
decreasing the time to allocate memory for large guests by
an order of magnitude or more.

For example, this commit reduces the time to allocate memory for a
guest configured with 704 GiB of memory on 1 NUMA node using 1 GiB
hugepages from 81.44134669s to just 6.865287881s.

Signed-off-by: Sean Banko <sbanko@crusoeenergy.com>
2024-02-07 08:59:03 -08:00
dependabot[bot]
939cc348ed build: Bump futures from 0.3.28 to 0.3.30
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.30.
- [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.28...0.3.30)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-07 10:10:40 +00:00
dependabot[bot]
744f2b011b build: Bump wasm-bindgen from 0.2.90 to 0.2.91 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.90 to 0.2.91.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.90...0.2.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-07 09:41:27 +00:00
Bo Chen
08120b79fc fuzz: Fix cargo fuzz build issue with crc32c
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-07 09:25:40 +00:00
Bo Chen
9b0b881351 arch: Remove unused wrapper data structure for linux_loader
The `ByteValued` trait implementations for the data structures from the
'linux_loader' crate are no longer needed, and hence their wrappers can
be removed.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-07 09:25:40 +00:00
Bo Chen
c1f4a7b295 main: Clarify truncate behavior for event monitor file
Fix beta clippy issue:

error: file opened with `create`, but `truncate` behavior not defined
   --> src/main.rs:624:26
    |
624 |                         .create(true)
    |                          ^^^^^^^^^^^^- help: add: `.truncate(true)`
    |
    = help: if you intend to overwrite an existing file entirely, call `.truncate(true)`
    = help: if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`
    = help: alternatively, use `.append(true)` to append to the file instead of overwriting it
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options
    = note: `-D clippy::suspicious-open-options` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_open_options)]`

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-07 09:25:40 +00:00
Bo Chen
36890373cd tests: Avoid clippy warning of unhandled I/O bytes
Fixes beta clippy issue:

error: read amount is not handled
    --> tests/integration.rs:2121:15
     |
2121 |         match pty.read(&mut buf) {
     |               ^^^^^^^^^^^^^^^^^^
     |
     = help: use `Read::read_exact` instead, or handle partial reads
note: the result is consumed here, but the amount of I/O bytes remains unhandled
    --> tests/integration.rs:2122:13
     |
2122 | /             Ok(_) => {
2123 | |                 let output = std::str::from_utf8(&buf).unwrap().to_string();
2124 | |                 match tx.send(output) {
2125 | |                     Ok(_) => (),
2126 | |                     Err(_) => break,
2127 | |                 }
2128 | |             }
     | |_____________^
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
     = note: `#[deny(clippy::unused_io_amount)]` on by default

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
107f4bdc12 vhost_user_block: Allow dead_code for embedded error
The embedded error in the enum will be read on debug output of the
error.

Fixes beta clippy issue:

warning: field `0` is never read
  --> vhost_user_block/src/lib.rs:64:23
   |
64 |     CreateKillEventFd(io::Error),
   |     ----------------- ^^^^^^^^^
   |     |
   |     field in this variant
   |
   = note: `#[warn(dead_code)]` on by default
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
   |
64 |     CreateKillEventFd(()),
   |                       ~~

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
8899ebd63c performance-metrics: Allow dead_code for embedded error
The embedded error in the enum will be read on debug output of the
error.

Fixes beta clippy issue:

warning: field `0` is never read
  --> performance-metrics/src/performance_tests.rs:25:11
   |
25 |     Infra(InfraError),
   |     ----- ^^^^^^^^^^
   |     |
   |     field in this variant
   |
   = note: `#[warn(dead_code)]` on by default
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
   |
25 |     Infra(()),
   |           ~~

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
c19c73cb99 block: qcow: Fix beta clippy issue
warning: field `0` is never read
   --> block/src/qcow/vec_cache.rs:139:21
    |
139 |     struct NumCache(pub u64);
    |            -------- ^^^^^^^
    |            |
    |            field in this struct
    |
    = note: `#[warn(dead_code)]` on by default
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
    |
139 |     struct NumCache(());
    |                     ~~

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
4e0dc5203a arch: x86_64: Disable dead code detection for embedded struct
These structs directly embed another struct and then implement
ByteValued on that struct to implement ByteValued for the inner struct.
As such the inner struct is never directly accessed so to avoid the dead
code analysis mark this as allowed.

Beta clippy fix:

warning: field `0` is never read
   --> arch/src/x86_64/mod.rs:129:32
    |
129 | struct MemmapTableEntryWrapper(hvm_memmap_table_entry);
    |        ----------------------- ^^^^^^^^^^^^^^^^^^^^^^
    |        |
    |        field in this struct
    |
    = note: `MemmapTableEntryWrapper` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
    = note: `#[warn(dead_code)]` on by default
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
    |
129 | struct MemmapTableEntryWrapper(());
    |

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
61afd93a50 tests: Remove unnecessary use of vec![] macro
Beta clippy fix

warning: useless use of `vec!`
    --> tests/integration.rs:5845:23
     |
5845 |         let kernels = vec![direct_kernel_boot_path()];
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[direct_kernel_boot_path()]`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec
     = note: `#[warn(clippy::useless_vec)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
9dfc39d336 vmm: Make thread local initialiser constant
Beta clippy fix:

warning: initializer for `thread_local` value can be made `const`
  --> vmm/src/sigwinch_listener.rs:27:40
   |
27 |     static TX: RefCell<Option<File>> = RefCell::new(None);
   |                                        ^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(None) }`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#thread_local_initializer_can_be_made_const
   = note: `#[warn(clippy::thread_local_initializer_can_be_made_const)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
e70bf59809 vmm: Directly clone console resize pipe
Beta clippy fix:

warning: this call to `as_ref.map(...)` does nothing
    --> vmm/src/device_manager.rs:1234:9
     |
1234 |         self.console_resize_pipe.as_ref().map(Arc::clone)
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `self.console_resize_pipe.clone()`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref
     = note: `#[warn(clippy::useless_asref)]` on by default

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-07 09:25:40 +00:00
Rob Bradford
d516374c39 block: Replace use of crc32c crate with crc-any
According to crates.io the crc-any crate is actively maintained which
avoids issues with the crc32c crate and the nightly compiler.

Fixes: #6168

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-06 14:29:10 -08:00
Muminul Islam
9b84c6c3f5 vmm: check correct buffer size during import
When we import a page, we have a page with
some data or empty, empty does not mean there is no data,
it rather means it's full of zeros. We can skip writing the
data as guest memory of the page is already zeroed.

A page could be partially filled and the rest of the content is zero.
Our IGVM generation tool only fills data here if there is some data
without zeros. Rest of them are padded. We only write data
without padding and compare whether we complete  writing
the buffer content. Still it's a full page and update the variable
with length of the full page.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-06 14:28:42 -08:00
dependabot[bot]
9b54a8fb1c build: Bump js-sys from 0.3.66 to 0.3.67 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.66 to 0.3.67.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 20:51:30 +00:00
dependabot[bot]
dd13fee3d7 build: Bump pin-project from 1.1.3 to 1.1.4
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v1.1.3...v1.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 20:51:19 +00:00
dependabot[bot]
3042a0baf3 build: Bump crossbeam-utils from 0.8.16 to 0.8.19
Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.16 to 0.8.19.
- [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.16...crossbeam-utils-0.8.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-03 00:20:04 +00:00
dependabot[bot]
dbda3ade92 build: Bump semver from 1.0.20 to 1.0.21 in /fuzz
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.20...1.0.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-02 23:25:01 +00:00
dependabot[bot]
6dc7e21327 build: Bump semver from 1.0.20 to 1.0.21
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.20...1.0.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-02 00:39:59 +00:00
dependabot[bot]
166111a0d8 build: Bump pin-project from 1.1.3 to 1.1.4 in /fuzz
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v1.1.3...v1.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 23:19:42 +00:00
dependabot[bot]
73bfaace83 build: Bump async-trait from 0.1.74 to 0.1.76
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.74 to 0.1.76.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.74...0.1.76)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 00:20:46 +00:00
dependabot[bot]
95cd81073e build: Bump serde from 1.0.195 to 1.0.196 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.195 to 1.0.196.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.195...v1.0.196)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-31 23:24:29 +00:00
dependabot[bot]
3603c51f0b build: Bump openssl-sys from 0.9.93 to 0.9.99
Bumps [openssl-sys](https://github.com/sfackler/rust-openssl) from 0.9.93 to 0.9.99.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.93...openssl-sys-v0.9.99)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-31 00:22:37 +00:00
dependabot[bot]
8c172e41c6 build: Bump smallvec from 1.12.0 to 1.13.1 in /fuzz
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.12.0 to 1.13.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.12.0...v1.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-30 23:22:46 +00:00
Thomas Barrett
5ec47d4883 arch: x86_64: enable HTT flag
When the HTT flag CPUID.1.EDX[HTT] is 0, it indicates that there is
only a single logical processor in the package. When HTT is 1, it
indicates that CPUID.1.EBX[23:16] contains the number of logical
processors in the package.

When this information is not included in CPUID leaf 0x1, some cpu
topology enumeration software such as hwloc are known to crash.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-30 13:49:35 -08:00
Ruslan Mstoi
1617736937 scripts: check-image-compatibility.sh: remove unused variable COUNT
COUNT variable is never used, hence remove

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-01-30 09:07:34 -08:00
Ruslan Mstoi
a9340f5d9d scripts: check-image-compatibility.sh: remove unused variable extension
extenstion variable is never used, hence remove

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-01-30 09:07:34 -08:00
Ruslan Mstoi
82cac6f6ad scripts: check-image-compatibility.sh: fix variable name typo
Fix liness to lines

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-01-30 09:07:34 -08:00
dependabot[bot]
c1206b604e build: Bump concurrent-queue from 2.3.0 to 2.4.0
Bumps [concurrent-queue](https://github.com/smol-rs/concurrent-queue) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/smol-rs/concurrent-queue/releases)
- [Changelog](https://github.com/smol-rs/concurrent-queue/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/concurrent-queue/compare/v2.3.0...v2.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-30 10:57:17 +00:00
dependabot[bot]
0a32779506 build: Bump getrandom from 0.2.11 to 0.2.12 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.11 to 0.2.12.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.11...v0.2.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-30 00:06:21 +00:00
Ruslan Mstoi
4625f3ca3a scripts: dev_cli: remove unused cargo variable
Variable cargo is unused, hence remove it.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-01-29 10:03:49 -08:00
dependabot[bot]
3945253619 build: Bump zerocopy from 0.7.31 to 0.7.32
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.31 to 0.7.32.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.7.31...v0.7.32)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-27 00:35:32 +00:00
dependabot[bot]
a5296a8147 build: Bump serde_json from 1.0.111 to 1.0.112 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.111 to 1.0.112.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.111...v1.0.112)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-26 23:34:50 +00:00
dependabot[bot]
7acfff5da7 build: Bump gdbstub from 0.7.0 to 0.7.1
Bumps [gdbstub](https://github.com/daniel5151/gdbstub) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/daniel5151/gdbstub/releases)
- [Changelog](https://github.com/daniel5151/gdbstub/blob/master/CHANGELOG.md)
- [Commits](https://github.com/daniel5151/gdbstub/compare/0.7.0...0.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-26 10:03:23 +00:00
Bo Chen
026d8908fd build: Bump rustix from 0.38.8 to 0.38.25
Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-26 09:17:41 +00:00
dependabot[bot]
c8ad2bfc05 build: Bump wasm-bindgen from 0.2.89 to 0.2.90 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.89 to 0.2.90.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.89...0.2.90)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-25 23:40:20 +00:00
Philipp Schuster
e50a641126 devices: add debug-console device
This commit adds the debug-console (or debugcon) device to CHV. It is a
very simple device on I/O port 0xe9 supported by QEMU and BOCHS. It is
meant for printing information as easy as possible, without any
necessary configuration from the guest at all.

It is primarily interesting to OS/kernel and firmware developers as they
can produce output as soon as the guest starts without any configuration
of a serial device or similar. Furthermore, a kernel hacker might use
this device for information of type B whereas information of type A are
printed to the serial device.

This device is not used by default by Linux, Windows, or any other
"real" OS, but only by toy kernels and during firmware development.

In the CLI, it can be configured similar to --console or --serial with
the --debug-console parameter.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2024-01-25 10:25:14 -08:00
dependabot[bot]
8f90fba250 build: Bump serde from 1.0.168 to 1.0.193
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.168 to 1.0.193.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.168...v1.0.193)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-25 11:09:33 +00:00
Bo Chen
3ce0fef7fd build: Bump vmm-sys-util crate and its consumers
This patch bumps the following crates, including `kvm-bindings@0.7.0`*,
`kvm-ioctls@0.16.0`**, `linux-loader@0.11.0`, `versionize@0.2.0`,
`versionize_derive@0.1.6`***, `vhost@0.10.0`,
`vhost-user-backend@0.13.1`, `virtio-queue@0.11.0`, `vm-memory@0.14.0`,
`vmm-sys-util@0.12.1`, and the latest of `vfio-bindings`, `vfio-ioctls`,
`mshv-bindings`,`mshv-ioctls`, and `vfio-user`.

* A fork of the `kvm-bindings` crate is being used to support
serialization of various structs for migration [1]. Also, code changes
are made to accommodate the updated `struct xsave` from the Linux
kernel. Note: these changes related to `struct xsave` break
live-upgrade.

** The new `kvm-ioctls` crate introduced breaking changes for
the `get/set_one_reg` API on `aarch64` [2], so code changes are made to
the new APIs.

*** A fork of the `versionize_derive` crate is being used to support
versionize on packed structs [3].

[1] https://github.com/cloud-hypervisor/kvm-bindings/tree/ch-v0.7.0
[2] https://github.com/rust-vmm/kvm-ioctls/pull/223
[3] https://github.com/cloud-hypervisor/versionize_derive/tree/ch-0.1.6

Fixes: #6072

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-01-25 10:14:54 +00:00
dependabot[bot]
6cb1d908bf build: Bump serde_json from 1.0.110 to 1.0.111 in /fuzz
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.110 to 1.0.111.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.110...v1.0.111)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-24 23:20:37 +00:00
Muminul Islam
51ebc3ac92 vmm: set SEV control register for SEV-Enabled guest
Set the SEV control register so we know where to
start running.  This register configures the
SEV feature control state on a virtual processor.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-24 14:32:16 -08:00
Muminul Islam
5368ff28da hypervisor: Add api to set sev control register
This register configures the SEV feature control
state on a virtual processor.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-24 14:32:16 -08:00
Rob Bradford
3993663e5c hypervisor: kvm: Import TDX vmcall structure
Consistent with the other data structures and constants used in TDX
support code import the necessary structures from the kernel for
accessing the vmcall structure.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-01-24 11:02:05 -08:00
dependabot[bot]
2c9cf8d8af build: Bump proc-macro2 from 1.0.70 to 1.0.78
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.70 to 1.0.78.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.70...1.0.78)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-24 13:44:45 +00:00
dependabot[bot]
b4eb2af1c6 build: Bump anstream from 0.6.8 to 0.6.11 in /fuzz
Bumps [anstream](https://github.com/rust-cli/anstyle) from 0.6.8 to 0.6.11.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.8...anstream-v0.6.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-23 23:57:33 +00:00
Alyssa Ross
7674196113 vmm: remove Default impls for config
These Default implementations either don't produce valid configs, are
no longer used outside of tests, or both.

For the tests, we can define our own local "default" values that make
the most sense for the tests, without worrying about what's
a (somewhat) sensible "global" default value.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-23 12:44:44 +00:00
dependabot[bot]
c71cb00a5a build: Bump anyhow from 1.0.75 to 1.0.79
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.75 to 1.0.79.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.75...1.0.79)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-23 12:44:21 +00:00
Ravi kumar Veeramally
895dc12a74 vmm: Replace Debug with Display rendering in HTTP error message
Bumping anyhow crate from 1.0.75 to 1.0.79 will cause seccomp
failures through integration tests. Newly added backtrace support
relies on readlink and many other syscalls.

Issue noticed with test_api_http_pause_resume test, where second time
of VM PAUSE or VM RESUME prints error and causes panic.
Noticed that panic message in a thread which is not allowed to write
output triggered the issue.

So implementing Display trait for HttpError and ApiError enums to avoid
adding many syscalls to seccomp filter section.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2024-01-23 12:44:21 +00:00
dependabot[bot]
9cb996db09 build: Bump clap from 4.4.12 to 4.4.18 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.12 to 4.4.18.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.12...v4.4.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 23:38:27 +00:00
dependabot[bot]
90245be978 build: Bump anstyle-wincon from 3.0.1 to 3.0.2
Bumps [anstyle-wincon](https://github.com/rust-cli/anstyle) from 3.0.1 to 3.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.1...anstyle-wincon-v3.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-20 01:11:15 +00:00
dependabot[bot]
15e2218c25 build: Bump uuid from 1.6.1 to 1.7.0 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.6.1...1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-19 23:13:28 +00:00
Sean Banko
e33279471f vmm: support setting cpu affinity with host cpu indices >255
On hosts with >256 cpus, setting the cpu affinity to a host cpu index
>255 will return an error because type of `host_cpu` is `u8`.
This commit changes the type of `host_cpu` to `usize` to remove this
limitation.

Signed-off-by: Sean Banko <sbanko@crusoeenergy.com>
2024-01-19 09:30:16 +00:00
dependabot[bot]
993a8324e2 build: Bump serde from 1.0.194 to 1.0.195 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.194 to 1.0.195.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.194...v1.0.195)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-19 00:04:00 +00:00
Thomas Barrett
76dbe660f5 scripts: create download_ovmf helper function
Move the duplicated logic to download OVMF into a helper function.
Explicitly specify the OVMF_FW_TAG instead of downloading the latest
so that new OVMF versions can be easily tested.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-18 14:02:02 -08:00
Wei Liu
e61c6a1382 gitignore: ignore vendor directory
This is the default output directory for `cargo vendor`.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-01-18 14:00:37 -08:00
Alyssa Ross
4ae5503b58 vmm: remove redundant tests
These are all duplicates.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-18 15:03:24 +00:00
dependabot[bot]
7ae46e9b61 build: Bump anstream from 0.6.5 to 0.6.8 in /fuzz
Bumps [anstream](https://github.com/rust-cli/anstyle) from 0.6.5 to 0.6.8.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.5...anstream-v0.6.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-18 14:54:08 +00:00
Ravi kumar Veeramally
33a05c7247 docs: Update vhost-user-net-testing instructions
Testing instructions are very old and type=dpdkvhostuser is
deprecated from DPDK.

logs from /var/log/openvswitch/ovs-vswitchd.log

|netdev_dpdk|WARN|dpdkvhostuser ports are considered deprecated;
please migrate to dpdkvhostuserclient ports

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
2024-01-17 09:06:11 -08:00
Daniel Farina
9b67bc5fe5 docs: update kernel pre-requisite information for iommu
Linux 5.14 merged x86 support.  See
https://lore.kernel.org/lkml/YN7IDbKZFQnYFCNq@8bytes.org/

Signed-off-by: Daniel Farina <daniel@ubicloud.com>
2024-01-17 10:20:20 +00:00
Alyssa Ross
4ca18c082e vmm: use trait objects for API actions
Uses of the old ApiRequest enum conflated two different concerns:
identifying an API request endpoint, and storing data for an API
request.  This led to ApiRequest values being passed around with junk
data just to communicate a request type, which forced all API request
body types to implement Default, which in some cases doesn't make any
sense — what's the "default" path for a vhost-user socket?  The
nonsensical Default values have led to tests relying on being able to
use nonsensical data, which is an impediment to adding better
validation for these types.

Rather than having API request types be represented by an enum, which
has to carry associated body data everywhere it's used, it makes more
sense to represent API request types as trait objects.  These can have
an associated type for the type of the request body, and this makes it
possible to pass API request types and data around as siblings in a
type-safe way without forcing them into a single value even where it
doesn't make sense.  Trait objects also give us dynamic dispatch,
which lets us get rid of several large match blocks.

To keep it possible to fuzz the HTTP API, all the Vmm methods called
by the HTTP API are pulled out into a trait, so the fuzzer can provide
its own stub implementation of the VMM.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-17 10:20:02 +00:00
dependabot[bot]
6aa7afbb6f build: Bump futures-sink from 0.3.29 to 0.3.30 in /fuzz
Bumps [futures-sink](https://github.com/rust-lang/futures-rs) from 0.3.29 to 0.3.30.
- [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.29...0.3.30)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-16 16:37:25 -08:00
Rob Bradford
d3bc877a07 build: Re-enable test_vfio on AMD workers
With the change in 7bc764d to expose the SVM bit for nested
virtualisation test_vfio can be re-enabled on the AMD workers.

Fixes: #5895

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-01-16 11:07:33 -08:00
Rob Bradford
81bd07fc8b vmm: openapi: String quote the enum members of ConsoleConfig::Mode
This disambiguates from the null keyword.

Fixes: #6107

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-01-16 11:05:51 -08:00
dependabot[bot]
d5b813838c build: Bump smallvec from 1.11.2 to 1.12.0 in /fuzz
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.2 to 1.12.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.2...v1.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-16 00:05:52 +00:00
Thomas Barrett
7bc764d4e0 arch: x86_64: enable nested virtualization on amd if supported
When using amd topology, the svm feature flag on cpuid leaf
0x8000_0001.ecx is overwritten. We update the amd cpu topology
logic to use the flag values that originated in
KVM_GET_SUPPORTED_CPUID ioctl and override as necessary.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-15 17:50:40 +00:00
dependabot[bot]
34e965d775 build: Bump libc from 0.2.151 to 0.2.152 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.151 to 0.2.152.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.151...0.2.152)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-12 23:26:50 +00:00
dependabot[bot]
7c4ca2bcf9 build: Bump remain from 0.2.11 to 0.2.12 in /fuzz
Bumps [remain](https://github.com/dtolnay/remain) from 0.2.11 to 0.2.12.
- [Release notes](https://github.com/dtolnay/remain/releases)
- [Commits](https://github.com/dtolnay/remain/compare/0.2.11...0.2.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 23:16:12 +00:00
Alyssa Ross
0fb44c074f arch: fix rustdoc warning
warning: this URL is not a hyperlink
	   --> arch/src/aarch64/layout.rs:114:58
	    |
	114 | ...in https://www.kernel.org/doc/Documentation/arm64/booting.txt.
	    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.kernel.org/doc/Documentation/arm64/booting.txt.>`
	    |
	    = note: bare URLs are not automatically turned into clickable links
	    = note: `#[warn(rustdoc::bare_urls)]` on by default

I also noticed that it looks like this comment was supposed to be
applied to FDT_MAX_SIZE, not FDT_START, so I moved it.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-10 17:37:29 +00:00
Alyssa Ross
451d3fb2f0 vmm: limit VSOCK CIDs to 32 bits
The VIRTIO specification[1] says:

> The upper 32 bits of the CID are reserved and zeroed.

We should therefore not allow the user to supply a VSOCK CID with
those bits set.  To accomplish this, limit the public API of the
virtio-vsock device to only accept 32-bit CIDs, while still using
64-bit CIDs internally since that's how virtio-vsock works.

[1]: https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-4400004

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-10 17:28:56 +00:00
Alyssa Ross
7d0b85d727 vmm: forbid using special VSOCK CIDs for guests
I accidentally ran a VM with CID 2 (VMADDR_CID_HOST), and very strange
and difficult to debug behavior ensued.  I don't think a virtio-vsock
device should be allowed to have any of the special CIDs
(VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR, VMADDR_CID_LOCAL, VMADDR_CID_HOST).

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-10 10:43:21 +00:00
dependabot[bot]
5857d8a7cc build: Bump proc-macro2 from 1.0.75 to 1.0.76 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.75 to 1.0.76.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.75...1.0.76)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 23:35:10 +00:00
Alyssa Ross
48de800756 virtio-devices: fix reading vsock connect command
The socket is nonblocking, so it's not guaranteed that it will be
possible to read the whole connect command in a single iteration of
the event loop.  To reproduce:

	(echo -n 'CONNECT '; sleep 1; echo 1234; cat) | socat STDIO UNIX-CONNECT:vsock.sock

This would produce the error:

	cloud-hypervisor: 5.509209s: <_vsock4> INFO:virtio-devices/src/vsock/unix/muxer.rs:446 -- vsock: error adding local-init connection: UnixRead(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" })

To fix this, if we only get a partial command, we need to save it for
future iterations of the event loop, and only proceed once we've read
a complete command.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-09 16:01:52 +00:00
Muminul Islam
dc68a6e30f vmm: igvm: complete isolated import
Complete the isolated import, telling the
Microsoft hypervisor that import is done so that
MSHV can issue SNP_LAUNCH_FINISH command.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-08 15:55:39 -08:00
Muminul Islam
cbcbf635ab hypervisor: use right size of host_data
Use right and exact size 32 bytes for host data field
for completing the isolated import. This way OOB
can be avoided during a function call.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-08 15:55:39 -08:00
Muminul Islam
433d4ddc0c vmm: igvm: import the isolated pages
Import all the isolated pages after parsing is
done on the iGVM file. Hypervisor adds those
pages for PSP measurement(part of the hashing).

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-08 15:55:39 -08:00
dependabot[bot]
9d2a939714 build: Bump thiserror from 1.0.53 to 1.0.56 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.53 to 1.0.56.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.53...1.0.56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 23:32:11 +00:00
Jinank Jain
c97b56251d docs: Update instructions to build debug TD-SHIM
Current instructions are incorrect and there is now a new profile called
dev-opt to build the debug version of TD-SHIM.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2024-01-08 15:10:06 -08:00
Rob Bradford
e041defa67 fuzz: Fix warnings for unused arch code
Under the fuzzer this code appears dead:

error: field `0` is never read
   --> /home/rob/src/cloud-hypervisor/arch/src/x86_64/mod.rs:128:32
    |
128 | struct MemmapTableEntryWrapper(hvm_memmap_table_entry);
    |        ----------------------- ^^^^^^^^^^^^^^^^^^^^^^
    |        |
    |        field in this struct
    |
    = note: `MemmapTableEntryWrapper` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
    = note: `-D dead-code` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(dead_code)]`
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
    |
128 | struct MemmapTableEntryWrapper(());
    |                                ~~

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-01-08 17:39:05 +00:00
Alyssa Ross
9d5dfa879b fuzz: fix unused import warnings
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-08 17:39:05 +00:00
Rob Bradford
a511dd1b18 ci: Add cargo fuzz check to GitHub actions
See: #6085

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-01-08 17:39:05 +00:00
dependabot[bot]
a5b6e2c5fd build: Bump anyhow from 1.0.75 to 1.0.79 in /fuzz
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.75 to 1.0.79.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.75...1.0.79)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-05 23:52:38 +00:00
dependabot[bot]
2da5763cac build: Bump futures-core from 0.3.29 to 0.3.30
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.29 to 0.3.30.
- [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.29...0.3.30)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-05 00:15:57 +00:00
dependabot[bot]
3e3bb64f4b build: Bump micro_http from a4d632f to e75dfa1 in /fuzz
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `a4d632f` to `e75dfa1`.
- [Commits](a4d632f2c5...e75dfa1eee)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-04 23:58:15 +00:00
dependabot[bot]
61f0db7713 build: Bump serde_derive from 1.0.193 to 1.0.194 in /fuzz
Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.194.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.194)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-04 08:25:04 +00:00
dependabot[bot]
0eba2d1b81 build: Bump micro_http from a4d632f to e75dfa1
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `a4d632f` to `e75dfa1`.
- [Commits](a4d632f2c5...e75dfa1eee)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-03 23:54:23 +00:00
Thomas Barrett
9e9bcd24c6 tests: add rate-limit group integration tests
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-03 10:21:06 -08:00
Thomas Barrett
c297d8d796 vmm: use RateLimiterGroup for virtio-blk devices
Add a 'rate_limit_groups' field to VmConfig that defines a set of
named RateLimiterGroups.

When the 'rate_limit_group' field of DiskConfig is defined, all
virtio-blk queues will be rate-limited by a shared RateLimiterGroup.
The lifecycle of all RateLimiterGroups is tied to the Vm.
A RateLimiterGroup may exist even if no Disks are configured to use
the RateLimiterGroup. Disks may be hot-added or hot-removed from the
RateLimiterGroup.

When the 'rate_limiter' field of DiskConfig is defined, we construct
an anonymous RateLimiterGroup whose lifecycle is tied to the Disk.
This is primarily done for api backwards compatability. Importantly,
the behavior is not the same! This implementation rate_limits the
aggregate bandwidth / iops of an individual disk rather than the
bandwidth / iops of an individual queue of a disk.

When neither the 'rate_limit_group' or the 'rate_limiter' fields of
DiskConfig is defined, the Disk is not rate-limited.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-03 10:21:06 -08:00
Thomas Barrett
c71da496c0 rate_limiter: add RateLimiterGroup
Add a 'rate_limiter/group' module that defines the RateLimiterGroup
and a RateLimiterGroupHandle types.

The RateLimiterGroupHandle can be used in place of a RateLimiter to
limit the aggregate bandwidth and/or ops of multiple virtio-blk or
virtio-net queues.

Each RateLimiterGroup has an associated worker thread that broadcasts
an event to each RateLimiterGroupHandle when a RateLimiter is unblocked.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-03 10:21:06 -08:00
dependabot[bot]
d11480197e build: Bump serde_json from 1.0.107 to 1.0.109
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.109.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.109)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-02 08:58:51 +00:00
dependabot[bot]
533de1b3c3 build: Bump quote from 1.0.33 to 1.0.34 in /fuzz
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.33 to 1.0.34.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.33...1.0.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-02 08:58:36 +00:00
Yi Wang
3d6594a594 build: fix clippy ptr arg issue
CI reports errors:

error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> arch/src/x86_64/mod.rs:1351:19
     |
1351 |     epc_sections: &Vec<SgxEpcSection>,
     |                   ^^^^^^^^^^^^^^^^^^^ help: change this to: `&[SgxEpcSection]`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
     = note: `-D clippy::ptr-arg` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]`

Signed-off-by: Yi Wang <foxywang@tencent.com>
2024-01-02 08:58:11 +00:00
Yi Wang
ee2f0c3cb4 build: fix clippy Path::join issue
CI reports clippy errors:

error: argument to `Path::join` starts with a path separator
    --> tests/integration.rs:4076:58
     |
4076 |         let serial_socket = guest.tmp_dir.as_path().join("/tmp/serial.socket");
     |                                                          ^^^^^^^^^^^^^^^^^^^^
     |
     = note: joining a path starting with separator will replace the path instead
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths

Signed-off-by: Yi Wang <foxywang@tencent.com>
2024-01-02 08:58:11 +00:00
Yi Wang
9c2d650cb8 build: fix clippy complex closures issue
CI reports clippy errors:

error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
   --> test_infra/src/lib.rs:93:51
    |
93  |           match (|| -> Result<(), WaitForBootError> {
    |  ___________________________________________________^
94  | |             let listener =
95  | |                 TcpListener::bind(listen_addr.as_str()).map_err(WaitForBootError::Listen)?;
96  | |             listener
...   |
145 | |             }
146 | |         })() {
    | |_________^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions
    = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`

Signed-off-by: Yi Wang <foxywang@tencent.com>
2024-01-02 08:58:11 +00:00
Thomas Barrett
5c0b66529a arch: x86_64: handle npot CPU topology
This PR addresses a bug in which the cpu topology of a guest
with non power-of-two number of cores is incorrect. For example,
in some contexts, a virtual machine with 2-sockets and 12-cores
will incorrectly believe that 16 cores are on socket 1 and 8
cores are on socket 2. In other cases, common topology enumeration
software such as hwloc will crash.

The root of the problem was the way that cloud-hypervisor generates
apic_id. On x86_64, the (x2) apic_id embeds information about cpu
topology. The cpuid instruction is primarily used to discover the
number of sockets, dies, cores, threads, etc. Using this information,
the (x2) apic_id is masked to determine which {core, die, socket} the
cpu is on. When the cpu topology is not a power of two
(e.g. a 12-core machine), this requires non-contiguous (x2) apic_id.

Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2024-01-01 10:05:03 +00:00
dependabot[bot]
a2ceb00fbc build: Bump futures-core from 0.3.29 to 0.3.30 in /fuzz
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.29 to 0.3.30.
- [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.29...0.3.30)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-30 10:28:33 +00:00
dependabot[bot]
48fc91467b build: Bump thiserror from 1.0.40 to 1.0.52
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.40 to 1.0.52.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.40...1.0.52)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-30 10:28:17 +00:00
dependabot[bot]
c2b746fe15 build: Bump clap from 4.4.11 to 4.4.12 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.11 to 4.4.12.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.11...v4.4.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-29 09:35:08 +00:00
dependabot[bot]
27e8e4ece9 build: Bump getrandom from 0.2.10 to 0.2.11
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.10 to 0.2.11.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-29 09:34:56 +00:00
dependabot[bot]
e03c0c12a7 build: Bump zerocopy from 0.7.31 to 0.7.32 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.31 to 0.7.32.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.7.31...v0.7.32)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-28 10:17:57 +00:00
dependabot[bot]
f8195faaa1 build: Bump once_cell from 1.18.0 to 1.19.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.18.0 to 1.19.0.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-22 00:19:29 +00:00
dependabot[bot]
accac17b22 build: Bump proc-macro2 from 1.0.70 to 1.0.71 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.70 to 1.0.71.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.70...1.0.71)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-21 23:25:33 +00:00
dependabot[bot]
580b45505b build: Bump blocking from 1.3.1 to 1.5.1
Bumps [blocking](https://github.com/smol-rs/blocking) from 1.3.1 to 1.5.1.
- [Release notes](https://github.com/smol-rs/blocking/releases)
- [Changelog](https://github.com/smol-rs/blocking/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/blocking/compare/v1.3.1...v1.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-21 00:24:38 +00:00
Ravi kumar Veeramally
24f384d239 tests: Migrate docker container from ubuntu 20.04 to 22.04
The following tests have been temporarily disabled:

1. Live upgrade/migration test with ovs-dpdk (#5532);
2. Disk hotplug tests on windows guests (#6037);

This patch has been tested with PR #6048.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
Tested-by: Bo Chen <chen.bo@intel.com>
2023-12-20 12:12:05 -08:00
dependabot[bot]
eaef2ed7de build: Bump anstyle-query from 1.0.0 to 1.0.2
Bumps [anstyle-query](https://github.com/rust-cli/anstyle) from 1.0.0 to 1.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.0.0...anstyle-query-v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 23:52:22 +00:00
dependabot[bot]
4995e8db35 build: Bump tracing from 0.1.37 to 0.1.40
Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.37 to 0.1.40.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.37...tracing-0.1.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:59:09 +00:00
dependabot[bot]
16c3df6cad build: Bump thiserror from 1.0.50 to 1.0.51 in /fuzz
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.50 to 1.0.51.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.50...1.0.51)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:22:27 +00:00
Jinank Jain
42477207e2 misc: Add check for sev_snp and target_arch
Feature 'sev_snp' can only be enabled when the target_arch is 'x86_64'

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-18 08:55:43 -08:00
Jinank Jain
9b151d06ca vmm: igvm: Generate memory map for SEV-SNP guests
For SEV-SNP guests we need to provide the extended memory. It follows a
very simple layout and very similar to other x86 guests.

First segment: [HIGH_RAM_START - MEM_32BIT_RESERVED_START]
PCI hole: [MEM_32BIT_RESERVED_START - RAM_64BIT_START]
Second segment: [RAM_64BIT_START - RAM_END]

Fixes #5993

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-18 08:55:43 -08:00
Philipp Schuster
91fe48d5f7 scripts: more compatible shebangs
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-12-16 09:35:32 +00:00
dependabot[bot]
e0abeeb790 build: Bump acpi_tables from 1a733bf to 76e8552
Bumps [acpi_tables](https://github.com/rust-vmm/acpi_tables) from `1a733bf` to `76e8552`.
- [Commits](1a733bf690...76e8552f57)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-16 01:10:17 +00:00
dependabot[bot]
1302dfcafa build: Bump bitfield-struct from 0.5.4 to 0.5.6
Bumps [bitfield-struct](https://github.com/wrenger/bitfield-struct-rs) from 0.5.4 to 0.5.6.
- [Release notes](https://github.com/wrenger/bitfield-struct-rs/releases)
- [Commits](https://github.com/wrenger/bitfield-struct-rs/compare/0.5.4...0.5.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-16 00:09:12 +00:00
dependabot[bot]
6c9ed2a655 build: Bump libc from 0.2.150 to 0.2.151 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.150 to 0.2.151.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.150...0.2.151)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 23:50:46 +00:00
dependabot[bot]
b5ea8b7b02 build: Bump itoa from 1.0.9 to 1.0.10 in /fuzz
Bumps [itoa](https://github.com/dtolnay/itoa) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/dtolnay/itoa/releases)
- [Commits](https://github.com/dtolnay/itoa/compare/1.0.9...1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 23:37:42 +00:00
dependabot[bot]
82a3664139 build: Bump env_logger from 0.10.0 to 0.10.1
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.10.0 to 0.10.1.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.10.0...v0.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 17:46:09 +00:00
dependabot[bot]
b2a78c6188 build: Bump zerocopy from 0.7.21 to 0.7.31
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.21 to 0.7.31.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.7.21...v0.7.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 04:39:12 +00:00
dependabot[bot]
2b4e620813 build: Bump zerocopy from 0.7.29 to 0.7.31 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.29 to 0.7.31.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.7.29...v0.7.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 23:20:06 +00:00
Bo Chen
5e702dcd5e build: Release v37.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 09:49:25 -08:00
Bo Chen
602d704558 tests: Stabilize 'test_vfio_user' with retries to run host commands
The 'test_vfio_user' is prone to fail when the system is under high
workloads with errors:

```
Error while connecting to /var/tmp/spdk.sock
Is SPDK application running?
Error details: Invalid or non-existing address: '/var/tmp/spdk.sock'
```

This is because SPDK is not fully functional before we request to
create a nvme device using the vfio_user protocol. This patch stabilize
this test with allowing retires to execute host commands.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 07:12:04 -08:00
Bo Chen
38a2808d85 arch: x86_64: Refactor the way to generate e820 RAM maps
This patch defines a new function 'generate_ram_ranges', to generate
usable physical memory ranges for the guest based on the existing guest
memory managed by VMM. This function is also made public, so that it can
be reused, say by the IGVM loader in the future [1].

No functional change.

See: #6020

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-14 07:11:53 -08:00
dependabot[bot]
5e2f218832 build: Bump async-executor from 1.5.1 to 1.8.0
Bumps [async-executor](https://github.com/smol-rs/async-executor) from 1.5.1 to 1.8.0.
- [Release notes](https://github.com/smol-rs/async-executor/releases)
- [Changelog](https://github.com/smol-rs/async-executor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-executor/compare/v1.5.1...v1.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 00:46:10 +00:00
dependabot[bot]
2fb8854ff6 build: Bump once_cell from 1.18.0 to 1.19.0 in /fuzz
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.18.0 to 1.19.0.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 23:54:27 +00:00
dependabot[bot]
883bb22b65 build: Bump mshv-ioctls from 6901f9c to 0dd4d34
Bumps [mshv-ioctls](https://github.com/rust-vmm/mshv) from `6901f9c` to `0dd4d34`.
- [Commits](6901f9cbd3...0dd4d3452a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 23:24:43 +00:00
dependabot[bot]
442fe6afcb build: Bump anstyle-query from 1.0.0 to 1.0.2 in /fuzz
Bumps [anstyle-query](https://github.com/rust-cli/anstyle) from 1.0.0 to 1.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.0.0...anstyle-query-v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 23:44:37 +00:00
Bo Chen
e64b66054e vmm: tdx: Error out early for TD migration
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-12 11:45:40 -08:00
Bo Chen
ceb1be9f50 vmm: Fix a typo from send_migration()
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-12 11:45:40 -08:00
Muminul Islam
7d5ea5ca37 hypervisor: fix few typos and cosmetic issues
This patch adds missing new lines after functions,
fixes few typos in the comments, adds few missing
comments to SNP related functions.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-12 14:42:22 +00:00
dependabot[bot]
d5839fe03c build: Bump pin-project from 1.1.2 to 1.1.3
Bumps [pin-project](https://github.com/taiki-e/pin-project) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/taiki-e/pin-project/releases)
- [Changelog](https://github.com/taiki-e/pin-project/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project/compare/v1.1.2...v1.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 00:21:51 +00:00
dependabot[bot]
de1b7f5e83 build: Bump ryu from 1.0.15 to 1.0.16 in /fuzz
Bumps [ryu](https://github.com/dtolnay/ryu) from 1.0.15 to 1.0.16.
- [Release notes](https://github.com/dtolnay/ryu/releases)
- [Commits](https://github.com/dtolnay/ryu/compare/1.0.15...1.0.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 23:59:23 +00:00
Jinank Jain
cf8a348238 docs: Add a missing backslash
There is missing backslash in the qemu command to launch windows guest.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:30:24 +00:00
Jinank Jain
2197989782 vmm: igvm: Remove redundant copy_from_slice
There is no requirement to call copy_from_slice, since all the member
variables are identical and we can directly assign them value.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:30:05 +00:00
Jinank Jain
5d4fe8efb9 github: ci: Move to action/checkout v4
There is a mix of v2, v3 and v4 in the codebase. Let's move to v4
everywhere because v2 seems to be using a deprecated version of nodejs.
This is throwing warnings when the Github action CI is running.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:29:11 +00:00
Jinank Jain
638e29bdcc hypervisor: vmm: Fix warnings in Cargo.toml
Currently there are some inconsistencies in Cargo.toml which is causing
the following warnings during the build process:

Error parsing Cargo.toml manifest, fallback to caching entire file:
Invalid TOML document: expected key-value, found comma

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:29:11 +00:00
dependabot[bot]
d1560b4223 build: Bump futures-core from 0.3.28 to 0.3.29
Bumps [futures-core](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [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.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-09 00:45:57 +00:00
dependabot[bot]
6d7224dfee build: Bump anstream from 0.6.4 to 0.6.5 in /fuzz
Bumps [anstream](https://github.com/rust-cli/anstyle) from 0.6.4 to 0.6.5.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.4...anstream-v0.6.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 23:41:32 +00:00
Muminul Islam
f38adfa166 vmm: Pass IGVM file to the loader
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
7030b15e63 vmm: Add igvm module and loader module
vmm: Add igvm module and loader module

Add a separate module named igvm to the vmm crate
with definitions to parse and load igvm to the guest memory.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
ec79820b3f hypervisor: Add api to retrieve CPUID leaf
Add necessary API to retrieve cpuid leaf on MSHV.
This API is used to update cpuid information
during the parsing of the igvm file.

Microsoft hypervisor does not provide common
CpuID like KVM. That's why we need to call this API
during the IGVM parsing.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
b9117c9c50 github: workflow: Build/quality test for igvm
Extend the current github actions to build and
test clippy for igvm feature.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Muminul Islam
13ef424bf1 vmm: Add IGVM to the config/commandline
This patch adds igvm to the Vm config and params as well as
the command line argument to pass igvm file to load into
guest memory. The file must maintain the IGVM format.
The CLI option is featured guarded by igvm feature gate.

The IGVM(Independent Guest Virtual Machine) file format
is designed to encapsulate all information required to
launch a virtual machine on any given virtualization stack,
with support for different isolation technologies such as
AMD SEV-SNP and Intel TDX.

At a conceptual level, this file format is a set of commands created
by the tool that generated the file, used by the loader to construct
the initial guest state. The file format also contains measurement
information that the underlying platform will use to confirm that
the file was loaded correctly and signed by the appropriate authorities.

The IGVM file is generated by the tool:
https://github.com/microsoft/igvm-tooling

The IGVM file is parsed by the following crates:
https://github.com/microsoft/igvm

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00
Bo Chen
c0faa75922 tests: Print ExitStatus for 'test_serial_socket_interaction'
This test has been failing fairly often on the AMD worker. Let's
collect more log for debugging.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-08 11:26:33 +00:00
Bo Chen
5d411d257a tests: Stabilize snapshot_restore tests
See: #5938

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-08 11:26:33 +00:00
dependabot[bot]
77f4e35bc8 build: Bump io-uring from 0.6.1 to 0.6.2
Bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.6.1 to 0.6.2.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 17:47:36 -08:00
dependabot[bot]
b2249827f5 build: Bump zerocopy from 0.7.26 to 0.7.29 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.26 to 0.7.29.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.26...v0.7.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 00:10:23 +00:00
Michael Zhao
f0c5592ba1 scripts: Workaround random wget failures on AArch64
Random failures of downloading `cloud-hypervisor-static-aarch64` with
`wget` were seen. The commit applies a workaround to retry the download
for a few times.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2023-12-07 14:29:22 -08:00
dependabot[bot]
b92856f41b build: Bump anstyle-wincon from 3.0.1 to 3.0.2 in /fuzz
Bumps [anstyle-wincon](https://github.com/rust-cli/anstyle) from 3.0.1 to 3.0.2.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.1...anstyle-wincon-v3.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 00:08:28 +00:00
dependabot[bot]
6a90902a4b build: Bump anstyle-parse from 0.2.2 to 0.2.3 in /fuzz
Bumps [anstyle-parse](https://github.com/rust-cli/anstyle) from 0.2.2 to 0.2.3.
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.2...anstyle-parse-v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 00:08:06 +00:00
Markus Sütter
0e9513f2b7 vmm: Allow IP configuration on named TAP interfaces
This commit changes existing behavior of named TAP interfaces.
When booting a VM with configuration for a named TAP interface,
cloud-hypervisor will create the interface and apply a given
IP configuration to that interface. If the named interface
already exists on the system, the configuration is NOT overwritten.

Setting the ip and netmask fields in a tap interface configuration
for a named tap interface now works by handing this configuration
to the virtio_devices::Net object when it is created with a name.

This commit also touches net_util to make sure that the ip configuration
of existing TAP interfaces is not modified with ip or netmask handed to
open_tap.

Signed-off-by: Markus Sütter <markus.suetter@secunet.com>
2023-12-05 08:59:04 -08:00
Bo Chen
283ae7b33e build: Bump gdbstub and gdbstub_arch
This commit also makes changes due to the breaking API changes from the
`gdbstub` crate [1].

[1] https://github.com/daniel5151/gdbstub/releases/tag/0.7.0

Fix: #5997

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-05 10:50:06 +00:00
dependabot[bot]
102a1c9abc build: Bump clap from 4.4.10 to 4.4.11 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.10 to 4.4.11.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.10...v4.4.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 23:38:13 +00:00
Bo Chen
32124bce13 scripts: Show wget details for aarch64 worker
The wget has been causing frequent CI failure for the past few days,
while it can't be reproduced manually. Let's show the wget details in
our CI pipeline to understand better future errors.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-12-04 11:54:50 -08:00
dependabot[bot]
5f89461a7e build: Bump js-sys from 0.3.65 to 0.3.66 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.65 to 0.3.66.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-02 00:01:27 +00:00
dependabot[bot]
b00cc483f9 build: Bump clap from 4.4.9 to 4.4.10 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.9 to 4.4.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.9...v4.4.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 23:20:47 +00:00
dependabot[bot]
705fbefebe build: Bump proc-macro2 from 1.0.67 to 1.0.70
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.67 to 1.0.70.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.67...1.0.70)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 08:59:14 +00:00
dependabot[bot]
d448dbd751 build: Bump wasm-bindgen from 0.2.88 to 0.2.89 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.88 to 0.2.89.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.88...0.2.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 00:13:32 +00:00
dependabot[bot]
9d29769536 build: Bump indexmap from 2.0.2 to 2.1.0
Bumps [indexmap](https://github.com/bluss/indexmap) from 2.0.2 to 2.1.0.
- [Changelog](https://github.com/bluss/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/bluss/indexmap/compare/2.0.2...2.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 10:25:13 +00:00
dependabot[bot]
d9f7fd1db8 build: Bump proc-macro2 from 1.0.69 to 1.0.70 in /fuzz
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.69 to 1.0.70.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.69...1.0.70)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 23:56:56 +00:00
dependabot[bot]
a6d994bf75 build: Bump toml_datetime from 0.6.3 to 0.6.5
Bumps [toml_datetime](https://github.com/toml-rs/toml) from 0.6.3 to 0.6.5.
- [Commits](https://github.com/toml-rs/toml/compare/toml_datetime-v0.6.3...toml_datetime-v0.6.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 00:09:58 +00:00
dependabot[bot]
86aa60a226 build: Bump clap from 4.4.8 to 4.4.9 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.8 to 4.4.9.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.8...v4.4.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 23:12:42 +00:00
Ruslan Mstoi
800f971381 tests: test_watchdog: use event monitor
See: #5127

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-24 21:37:25 +00:00
Ruslan Mstoi
341a4558fe tests: test_vdpa_block: fix false positive
Running on host where vdpa_sim_blk module is not correctly loaded
test_vdpa_block passes.

"test common_parallel::test_vdpa_block ... ok"

This commit fixes the vdpa_sim_blk test to fail in that case.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-24 21:37:06 +00:00
dependabot[bot]
81b30bf390 build: Bump log from 0.4.17 to 0.4.20
Bumps [log](https://github.com/rust-lang/log) from 0.4.17 to 0.4.20.
- [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.17...0.4.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 08:47:05 +00:00
dependabot[bot]
526eba90e7 build: Bump uuid from 1.5.0 to 1.6.1 in /fuzz
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.5.0 to 1.6.1.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.5.0...1.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-23 13:41:27 +00:00
dependabot[bot]
451a084881 build: Bump futures-task from 0.3.28 to 0.3.29
Bumps [futures-task](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [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.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-23 13:41:12 +00:00
dependabot[bot]
a5f60338a2 build: Bump object from 0.30.3 to 0.30.4
Bumps [object](https://github.com/gimli-rs/object) from 0.30.3 to 0.30.4.
- [Changelog](https://github.com/gimli-rs/object/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/0.30.3...0.30.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-22 17:35:02 +00:00
dependabot[bot]
a18896bd63 build: Bump serde from 1.0.192 to 1.0.193 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-21 23:29:19 +00:00
Rui Chang
2b457584e0 vmm: add add-user-device support in cloud-hypervisor.yaml
The change is missed when add "add-user-device" support in
53b2e19934, use this commit to fix it.

Signed-off-by: Rui Chang <rui.chang@arm.com>
2023-11-21 09:13:22 +00:00
dependabot[bot]
57ee9b4f9c build: Bump rustix from 0.37.25 to 0.37.27
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.25 to 0.37.27.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.25...v0.37.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-21 00:06:15 +00:00
Thomas Barrett
45b01d592a vmm: assign each pci segment 32-bit mmio allocator
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-20 15:33:50 -08:00
dependabot[bot]
ef16ee37d9 build: Bump getrandom from 0.2.10 to 0.2.11 in /fuzz
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.10 to 0.2.11.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 23:31:17 +00:00
Ruslan Mstoi
851ab0ad43 gitlint: validate title components
Valid title format:
component1[, component2, componentN]: submodule: summary

Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated

See: #5846

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-20 08:39:43 -08:00
Michael Zhao
70380d289f ci: Enable OpenAPI validate action
Pull the container `openapitools/openapi-generator-cli` and run the
validation.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
2023-11-20 07:45:55 +00:00
dependabot[bot]
4b87964093 build: Bump num-traits from 0.2.16 to 0.2.17
Bumps [num-traits](https://github.com/rust-num/num-traits) from 0.2.16 to 0.2.17.
- [Changelog](https://github.com/rust-num/num-traits/blob/master/RELEASES.md)
- [Commits](https://github.com/rust-num/num-traits/compare/num-traits-0.2.16...num-traits-0.2.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-18 00:14:41 +00:00
dependabot[bot]
16809026cd build: Bump clap from 4.4.7 to 4.4.8 in /fuzz
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.7 to 4.4.8.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.7...v4.4.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-17 23:16:02 +00:00
Bo Chen
c427f3a862 Jenkinsfile: Skip worker build for more cases
We can skip the CI worker build if the changes are only from gitlint, or
the hidden files in the root folder, such as .github, .gitignore,
.gitlint, .rustfmt.toml, and .typos.toml.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:19 -08:00
Bo Chen
07475d2bc1 gitlint: Increase the title length limit to 72
This is particularly useful for commits with long component names. Of
course, it is better to have concise subject that is less than 50 char.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:19 -08:00
Bo Chen
4d80be3a04 tests: Enable live-upgrade tests based on release v36.0
These live-upgrade tests were disabled due to CLI changes (#5791).

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-17 08:43:13 +00:00
dependabot[bot]
af06adfd65 build: Bump serde_repr from 0.1.12 to 0.1.17
Bumps [serde_repr](https://github.com/dtolnay/serde-repr) from 0.1.12 to 0.1.17.
- [Release notes](https://github.com/dtolnay/serde-repr/releases)
- [Commits](https://github.com/dtolnay/serde-repr/compare/0.1.12...0.1.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-17 00:30:50 +00:00
dependabot[bot]
5ff53db239 build: Bump js-sys from 0.3.64 to 0.3.65 in /fuzz
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.64 to 0.3.65.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-16 23:54:04 +00:00
Jinank Jain
84b643f80b hypervisor: Add support to bringup AP threads for SEV-SNP guest
As part SMP bringup for a SEV-SNP guest, BSP sets up the VMSA page for
each AP threads and informs hypervisor about the same using a VMGEXIT.
Thus, extend the current GHCB interface to handle this scenario.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Jinank Jain
d7d6054b8c hypervisor: Add support for handling SNP guest request
SEV-SNP guest can request AMD's secure co-processor i.e., PSP to
generate an runtime attesation report. During this process guest needs
to inform PSP about the request and response GPAs where that report
would be generated by the PSP. This is handled via a VMGEXIT request.
Thus, extend the current GHCB handling to add support for it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Jinank Jain
96bc282759 hypervisor: mshv: Add VmFd to MshvVcpu struct
This would be required later to implement few additional operations on
top of it.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-11-16 14:58:53 -08:00
Yi Wang
a69d8c63b3 vmm: speed up JSON load when reading snap files
We found that it's slow to load JSON when reading snap files. As
described in [1], using from_slice instead of from_reader can fix
this.

Also, fix the error type being returned.

1. https://github.com/serde-rs/json/issues/160

Signed-off-by: Yi Wang <foxywang@tencent.com>
2023-11-16 14:56:04 -08:00
Rob Bradford
0eade51306 build: Remove OpenAPI validation
This container is now failing.

See: #5960

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-16 16:44:04 +00:00
Ruslan Mstoi
ea7999e064 build: add gitlint commit message linter
Implement commit message check workflow using gitlint

Fixes: #5840

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2023-11-16 16:09:17 +00:00
Thomas Barrett
5f3ff3c44a devices: fix pv_panic alignment
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-16 08:28:23 +00:00
dependabot[bot]
0299bec152 build: Bump async-recursion from 1.0.4 to 1.0.5
Bumps [async-recursion](https://github.com/dcchut/async-recursion) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/dcchut/async-recursion/releases)
- [Commits](https://github.com/dcchut/async-recursion/compare/v1.0.4...v1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-16 00:42:43 +00:00
dependabot[bot]
61529a6158 build: Bump zerocopy from 0.7.25 to 0.7.26 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.25 to 0.7.26.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.25...v0.7.26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-15 23:40:17 +00:00
dependabot[bot]
e5370cddf0 build: Bump concurrent-queue from 2.2.0 to 2.3.0
Bumps [concurrent-queue](https://github.com/smol-rs/concurrent-queue) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/smol-rs/concurrent-queue/releases)
- [Changelog](https://github.com/smol-rs/concurrent-queue/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/concurrent-queue/compare/v2.2.0...v2.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-15 00:45:15 +00:00
dependabot[bot]
c30339debc build: Bump arbitrary from 1.3.1 to 1.3.2 in /fuzz
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/derive_arbitrary@1.3.1...v1.3.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 23:27:53 +00:00
dependabot[bot]
819e7f7e4d build: Bump micro_http from 0d0fdcd to a4d632f
Bumps [micro_http](https://github.com/firecracker-microvm/micro-http) from `0d0fdcd` to `a4d632f`.
- [Commits](0d0fdcd50e...a4d632f2c5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 16:00:25 +00:00
Bo Chen
de2fcc2d87 tests: Stabilize snapshot_restore tests
Since the 'write()' to the event file was moved to its own thread
(see #5633), we have no reliable way to read the latest contents of
the event file from our integration tests, since we can't ensure the
'read()' from our test always happen after 'write()' is completed from
Cloud Hypervisor. This is also why we started to see random failures on
snapshot_restore tests (particularly when the system workload is high).

This patch adds a 1s sleep before reading the event file to mitigate the
random failures.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:19:25 +00:00
Bo Chen
d4892f41b3 misc: Stop using deprecated functions from vm-memory crate
See: https://github.com/rust-vmm/vm-memory/pull/247

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:17:42 +00:00
Bo Chen
4d7a4c598a build: Upgrade vm-memory crates and its consumers
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:17:42 +00:00
Bo Chen
d4a163dd39 virtio-devices: Fix beta clippy issue
error: use of a fallible conversion when an infallible one could be used
Error:    --> virtio-devices/src/vhost_user/vu_common_ctrl.rs:206:51
    |
206 |             let actual_size: usize = queue.size().try_into().unwrap();
    |                                                   ^^^^^^^^^^^^^^^^^^^ help: use: `into()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions
    = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`

error: could not compile `virtio-devices` (lib) due to previous error
Error: warning: build failed, waiting for other jobs to finish...
error: could not compile `virtio-devices` (lib test) due to previous error
Error: The process '/home/runner/.cargo/bin/cargo' failed with exit code 101

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:15:45 +00:00
dependabot[bot]
c1e613a9ff build: Bump serde from 1.0.189 to 1.0.192 in /fuzz
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.192.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.192)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 16:01:50 -08:00
dependabot[bot]
fcebc4491a build: Bump vfio-ioctls from 847b0aa to 59c604f
Bumps [vfio-ioctls](https://github.com/rust-vmm/vfio) from `847b0aa` to `59c604f`.
- [Release notes](https://github.com/rust-vmm/vfio/releases)
- [Commits](847b0aa504...59c604fa6e)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-11 09:04:38 +00:00
dependabot[bot]
f75515eedb build: Bump smallvec from 1.11.1 to 1.11.2 in /fuzz
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.1...v1.11.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-10 23:36:27 +00:00
Muminul Islam
4cea713adf docs: Add documentations for MSHV and related features
This patch adds brief overview and relation of mshv,
igvm, and sev-snp features.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-11-10 11:30:40 -08:00
dependabot[bot]
148955f725 build: Bump async-task from 4.4.0 to 4.5.0
Bumps [async-task](https://github.com/smol-rs/async-task) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/smol-rs/async-task/releases)
- [Changelog](https://github.com/smol-rs/async-task/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/async-task/compare/v4.4.0...v4.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-10 09:01:28 +00:00
dependabot[bot]
49ef29c9b5 build: Bump wasm-bindgen from 0.2.87 to 0.2.88 in /fuzz
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.87 to 0.2.88.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.87...0.2.88)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-09 23:45:20 +00:00
Bo Chen
62db13ba0e tests: Temporarily disable vhost_user_blk tests on aarch64
See: #5934

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-09 07:57:44 +00:00
Thomas Barrett
d9ed281719 block: fix aio backend behavior when writeback enabled
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
2023-11-08 19:24:40 -08:00
dependabot[bot]
56f0cfefa8 build: Bump libc from 0.2.149 to 0.2.150 in /fuzz
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.150.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.149...0.2.150)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-08 19:23:47 -08:00
dependabot[bot]
815c7f45c4 build: Bump clap from 4.3.11 to 4.4.7
Bumps [clap](https://github.com/clap-rs/clap) from 4.3.11 to 4.4.7.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.3.11...v4.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-08 17:01:37 -08:00
Rob Bradford
4817578ce9 build: Bump version used into container for clap crate
See: #5925

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-08 08:13:45 -08:00
Rob Bradford
13fae28635 build: Bump MSRV to 1.70 for clap crate
See: #5925

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-08 08:13:45 -08:00
Wei Liu
14907d0752 scripts: fix the check for GitHub authentication token
When the script is invoked via dev_cli.sh, it always gets AUTH_DOWNLOAD_TOKEN
from the environment. The original test always returns true.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2023-11-08 10:02:15 +00:00
dependabot[bot]
aad5cd7858 build: Bump futures-sink from 0.3.28 to 0.3.29 in /fuzz
Bumps [futures-sink](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [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.28...0.3.29)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-07 16:12:11 -08:00
Rob Bradford
99a2551046 scripts: Propagate AUTH_DOWNLOAD_TOKEN into container
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
8d31dfb154 build: Populate AUTH_DOWNLOAD_TOKEN environment variable
Use a stored credential in Jenkins to authenticate the downloads against
GitHub.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
5e1806aed2 scripts: Authenticate to GitHub if token present
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
Rob Bradford
72e213ebda scripts: Extract downloading hypervisor-fw to a function
This will reduce the number of locations that it will be necessary to
add authentication support.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-11-07 08:44:56 -08:00
dependabot[bot]
df242e9468 build: Bump zerocopy from 0.7.24 to 0.7.25 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.24 to 0.7.25.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.24...v0.7.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 16:58:27 -08:00
dependabot[bot]
3ce463f482 build: Bump mshv-bindings from af397ea to f00c7d4
Bumps [mshv-bindings](https://github.com/rust-vmm/mshv) from `af397ea` to `f00c7d4`.
- [Commits](af397ea851...f00c7d483c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 16:58:11 -08:00
dependabot[bot]
d38e951234 build: Bump parking from 2.1.1 to 2.2.0
Bumps [parking](https://github.com/smol-rs/parking) from 2.1.1 to 2.2.0.
- [Release notes](https://github.com/smol-rs/parking/releases)
- [Changelog](https://github.com/smol-rs/parking/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/parking/compare/v2.1.1...v2.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 17:42:38 +00:00
Bo Chen
1be40e2339 tests: Improve debuggability for "test_vfio"
Instead of relying on "wc" and "grep", this patch provides helper
functions for checking line counts and searching/counting keywords.
To understand assertion failures better, it also generate logs for the
L1/L2 VM commands when checks fail.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
bc04e75b4b test_infra, tests: Unify error message formatting
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
5f7a847822 test_infra: Print error and output if host commands failed
It helps with understanding integration test errors when host commands
failed to run or complete.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
Bo Chen
5976a37cf4 tests: Print details when checks on event monitor failed
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-06 08:50:58 -08:00
dependabot[bot]
1cfb793528 build: Bump zerocopy from 0.7.23 to 0.7.24 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.23 to 0.7.24.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.23...v0.7.24)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-03 23:51:34 +00:00
dependabot[bot]
30bc8ffa8d build: Bump unicode-ident from 1.0.11 to 1.0.12
Bumps [unicode-ident](https://github.com/dtolnay/unicode-ident) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.11...1.0.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-03 00:13:49 +00:00
dependabot[bot]
8b7c859d14 build: Bump zerocopy from 0.7.20 to 0.7.23 in /fuzz
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.20 to 0.7.23.
- [Commits](https://github.com/google/zerocopy/compare/v0.7.20...v0.7.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-02 23:22:08 +00:00
Yong He
d1ba50f10e tests: Add a test simultaneously set serial and console as TTY mode
Add a test that supports configuring serial and console as TTY mode
at the same time. With this configuration, the VM can set up a legacy
serial device as an early printk console device, and then change to a
virito console device after the virito console device is initialized.

In this case, we can capture the logs printed by legacy serial on early
boot, and later by the virtio console.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-11-02 11:06:30 -07:00
Yong He
bb38e4e599 vmm: Allow simultaneously set serial and console as TTY mode
Cloud Hypovrisor supports legacy serial device and virito console device
for VMs. Using legacy serial device, CH can capture full VM console logs,
but its implementation is based on KVM PIO emulation and has poor
performance. Using the virtio console device, the VM console logs will
be sent to CH through the virtio ring, the performance is better, but CH
will only capture the VM console logs after the virtio console device is
initialized, the VM early startup logs will be discarded.

This patch provides a way to enable both the legacy serial device and the
virtio console device as a TTY mode by setting the leagcy serial port as
the VM's early printk device and setting the virtio console as the VM's
main console device.

Then CH can capture early boot logs from the legacy serial device and
capture later logs from the virito console device with better performance.

Signed-off-by: Yong He <alexyonghe@tencent.com>
2023-11-02 11:06:30 -07:00
142 changed files with 8293 additions and 3663 deletions

View File

@@ -9,7 +9,7 @@ jobs:
name: Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -13,13 +13,13 @@ jobs:
- stable
- beta
- nightly
- "1.66"
- "1.70"
target:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -54,6 +54,9 @@ jobs:
- name: Build (sev_snp)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (igvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "igvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Build (mshv + kvm)
run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

View File

@@ -5,7 +5,7 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python 3.x
uses: actions/setup-python@v1
with:

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v1

View File

@@ -12,9 +12,11 @@ jobs:
- nightly
target:
- x86_64-unknown-linux-gnu
env:
RUSTFLAGS: -D warnings
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
@@ -22,8 +24,8 @@ jobs:
target: ${{ matrix.target }}
override: true
- name: Install Cargo fuzz
# Temporary fix for cargo-fuzz on latest nightly: https://github.com/rust-fuzz/cargo-fuzz/issues/276
#run: cargo install cargo-fuzz
run: cargo install --git https://github.com/rust-fuzz/cargo-fuzz --rev b4df3e58f767b5cad8d1aa6753961003f56f3609
- name: Cargo Fuzz Build
run: cargo install cargo-fuzz
- name: Fuzz Build
run: cargo fuzz build
- name: Fuzz Check
run: cargo fuzz check

26
.github/workflows/gitlint.yaml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Commit messages check
on:
pull_request:
jobs:
gitlint:
name: Check commit messages
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade gitlint
- name: Lint git commit messages
run: |
gitlint --commits origin/$GITHUB_BASE_REF..

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Lint Dockerfile
uses: hadolint/hadolint-action@master

16
.github/workflows/openapi.yaml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Cloud Hypervisor OpenAPI Validation
on:
pull_request:
jobs:
Validate:
runs-on: ubuntu-latest
container: openapitools/openapi-generator-cli
steps:
- uses: actions/checkout@v4
- name: Validate OpenAPI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
/usr/local/bin/docker-entrypoint.sh validate -i vmm/src/api/openapi/cloud-hypervisor.yaml

View File

@@ -34,7 +34,7 @@ jobs:
experimental: true
steps:
- name: Code checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -109,6 +109,14 @@ jobs:
command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (igvm)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
command: clippy
args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "igvm" -- -D warnings -D clippy::undocumented_unsafe_blocks
- name: Clippy (kvm + tdx)
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
uses: actions-rs/cargo@v1
@@ -125,6 +133,6 @@ jobs:
name: Typos / Spellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Executes "typos ."
- uses: crate-ci/typos@v1.16.11

View File

@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install musl-gcc
run: sudo apt install -y musl-tools
- name: Create release directory
@@ -16,29 +16,29 @@ jobs:
- name: Install Rust toolchain (x86_64-unknown-linux-gnu)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.67.1"
toolchain: "1.70"
target: x86_64-unknown-linux-gnu
- name: Install Rust toolchain (x86_64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.67.1"
toolchain: "1.70"
target: x86_64-unknown-linux-musl
- name: Build
uses: actions-rs/cargo@v1
with:
toolchain: "1.67.1"
toolchain: "1.70"
command: build
args: --all --release --features mshv --target=x86_64-unknown-linux-gnu
- name: Static Build
uses: actions-rs/cargo@v1
with:
toolchain: "1.67.1"
toolchain: "1.70"
command: build
args: --all --release --features mshv --target=x86_64-unknown-linux-musl
- name: Install Rust toolchain (aarch64-unknown-linux-musl)
uses: actions-rs/toolchain@v1
with:
toolchain: "1.67.1"
toolchain: "1.70"
target: aarch64-unknown-linux-musl
override: true
- name: Create Release

20
.github/workflows/shlint.yaml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Shell scripts check
on:
pull_request:
push:
branches:
- main
jobs:
sh-checker:
name: Check shell scripts
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run the shell script checkers
uses: luizm/action-sh-checker@master
env:
SHFMT_OPTS: -i 4 -d
SHELLCHECK_OPTS: -x --source-path scripts

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@
**/rusty-tags.vi
/rpm/SOURCES
/.vscode
/vendor

15
.gitlint Normal file
View File

@@ -0,0 +1,15 @@
[general]
extra-path=scripts/gitlint/rules.py
regex-style-search=true
[ignore-by-author-name]
regex=dependabot
ignore=all
# default 72
[title-max-length]
line-length=72
# default 80
[body-max-line-length]
line-length=72

601
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "36.0.0"
version = "38.0.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -15,7 +15,7 @@ homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
# a.) A dependency requires it,
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
# c.) There is a security issue that is addressed by the toolchain update.
rust-version = "1.66"
rust-version = "1.70"
[profile.release]
lto = true
@@ -29,38 +29,37 @@ strip = false
debug = true
[dependencies]
anyhow = "1.0.75"
anyhow = "1.0.79"
api_client = { path = "api_client" }
clap = { version = "4.3.11", features = ["string"] }
dhat = { version = "0.3.2", optional = true }
clap = { version = "4.4.7", features = ["string"] }
dhat = { version = "0.3.3", optional = true }
epoll = "4.3.3"
event_monitor = { path = "event_monitor" }
hypervisor = { path = "hypervisor" }
libc = "0.2.147"
log = { version = "0.4.17", features = ["std"] }
libc = "0.2.153"
log = { version = "0.4.20", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.4.0"
serde_json = "1.0.107"
serde_json = "1.0.109"
signal-hook = "0.3.17"
thiserror = "1.0.40"
thiserror = "1.0.52"
tpm = { path = "tpm"}
tracer = { path = "tracer" }
vmm = { path = "vmm" }
vmm-sys-util = "0.11.0"
vm-memory = "0.12.2"
vmm-sys-util = "0.12.1"
vm-memory = "0.14.0"
zbus = { version = "3.11.1", optional = true }
# List of patched crates
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx" }
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "main" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.7.0" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch-0.1.6" }
[dev-dependencies]
dirs = "5.0.0"
net_util = { path = "net_util" }
once_cell = "1.18.0"
serde_json = "1.0.107"
once_cell = "1.19.0"
serde_json = "1.0.109"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"
@@ -71,10 +70,11 @@ default = ["kvm", "io_uring"]
dbus_api = ["zbus", "vmm/dbus_api"]
dhat-heap = ["dhat"] # For heap profiling
guest_debug = ["vmm/guest_debug"]
igvm = ["vmm/igvm", "mshv"]
io_uring = ["vmm/io_uring"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
sev_snp = ["vmm/sev_snp", "mshv"]
sev_snp = ["igvm", "vmm/sev_snp", "mshv"]
tdx = ["vmm/tdx"]
tracing = ["vmm/tracing", "tracer/tracing"]

35
Jenkinsfile vendored
View File

@@ -53,6 +53,9 @@ pipeline {
return runWorkers
}
}
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages {
stage('Checkout') {
steps {
@@ -64,11 +67,6 @@ pipeline {
sh 'scripts/prepare_vdpa.sh'
}
}
stage('Run OpenAPI tests') {
steps {
sh 'scripts/run_openapi_tests.sh'
}
}
stage('Run unit tests') {
steps {
sh 'scripts/dev_cli.sh tests --unit'
@@ -125,6 +123,9 @@ pipeline {
return runWorkers
}
}
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages {
stage('Checkout') {
steps {
@@ -142,7 +143,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration -- -- --skip common_parallel::test_vfio'
sh 'scripts/dev_cli.sh tests --integration'
}
}
stage('Run live-migration integration tests') {
@@ -160,7 +161,7 @@ pipeline {
}
steps {
sh 'sudo modprobe openvswitch'
sh 'scripts/dev_cli.sh tests --integration --libc musl -- -- --skip common_parallel::test_vfio'
sh 'scripts/dev_cli.sh tests --integration --libc musl'
}
}
stage('Run live-migration integration tests for musl') {
@@ -364,6 +365,9 @@ pipeline {
}
}
}
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages {
stage('Checkout') {
steps {
@@ -405,6 +409,9 @@ pipeline {
}
}
}
environment {
AUTH_DOWNLOAD_TOKEN = credentials('8a26fd74-d40e-414c-9132-ff3f867806ef')
}
stages {
stage('Checkout') {
steps {
@@ -505,5 +512,19 @@ def boolean skipWorkerBuild() {
return true
}
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v '^\\.'"
) != 0) {
return true
}
if (sh(
returnStatus: true,
script: "git diff --name-only origin/${env.CHANGE_TARGET}... | grep -v 'gitlint'"
) != 0) {
return true
}
return false
}

View File

@@ -5,4 +5,4 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"

View File

@@ -10,20 +10,20 @@ sev_snp = []
tdx = []
[dependencies]
anyhow = "1.0.75"
anyhow = "1.0.79"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.147"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] }
log = "0.4.17"
serde = { version = "1.0.168", features = ["rc", "derive"] }
thiserror = "1.0.40"
libc = "0.2.153"
linux-loader = { version = "0.11.0", features = ["elf", "bzimage", "pe"] }
log = "0.4.20"
serde = { version = "1.0.196", features = ["rc", "derive"] }
thiserror = "1.0.52"
uuid = "1.3.4"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-bitmap"] }
versionize = "0.2.0"
versionize_derive = "0.1.6"
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
[target.'cfg(target_arch = "aarch64")'.dependencies]
fdt_parser = { version = "0.1.4", package = "fdt" }

View File

@@ -111,8 +111,9 @@ pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);
pub const CMDLINE_MAX_SIZE: usize = 2048;
/// FDT is at the beginning of RAM.
/// Maximum size of the device tree blob as specified in https://www.kernel.org/doc/Documentation/arm64/booting.txt.
pub const FDT_START: GuestAddress = RAM_START;
/// Maximum size of the device tree blob as specified in [the kernel
/// documentation](https://www.kernel.org/doc/Documentation/arm64/booting.txt).
pub const FDT_MAX_SIZE: u64 = 0x20_0000;
/// Put ACPI table above dtb

View File

@@ -1,8 +1,9 @@
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
use std::io::{Read, Seek, SeekFrom};
use std::os::fd::AsFd;
use std::result;
use vm_memory::{Bytes, GuestAddress, GuestMemory};
use vm_memory::{GuestAddress, GuestMemory};
/// Errors thrown while loading UEFI binary
#[derive(Debug)]
@@ -24,7 +25,7 @@ pub fn load_uefi<F, M: GuestMemory>(
uefi_image: &mut F,
) -> Result<()>
where
F: Read + Seek,
F: Read + Seek + AsFd,
{
let uefi_size = uefi_image
.seek(SeekFrom::End(0))
@@ -36,6 +37,6 @@ where
}
uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
guest_mem
.read_exact_from(guest_addr, uefi_image, uefi_size)
.read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
.map_err(|_| Error::ReadUefiImage)
}

View File

@@ -91,8 +91,9 @@ pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry, EntryPoint, _NSIG,
generate_ram_ranges, get_host_cpu_phys_bits, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry,
EntryPoint, _NSIG,
};
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.

View File

@@ -17,14 +17,13 @@ use crate::InitramfsConfig;
use crate::RegionType;
use hypervisor::arch::x86::{CpuIdEntry, CPUID_FLAG_VALID_INDEX};
use hypervisor::{CpuVendor, HypervisorCpuError, HypervisorError};
use linux_loader::loader::bootparam::boot_params;
use linux_loader::loader::elf::start_info::{
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
};
use std::collections::BTreeMap;
use std::mem;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryRegion, GuestUsize,
};
mod smbios;
@@ -116,38 +115,6 @@ impl SgxEpcRegion {
}
}
// 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);
#[derive(Copy, Clone, Default)]
struct MemmapTableEntryWrapper(hvm_memmap_table_entry);
#[derive(Copy, Clone, Default)]
struct ModlistEntryWrapper(hvm_modlist_entry);
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for StartInfoWrapper {}
// SAFETY: data structure only contain a series of integers
unsafe impl ByteValued for MemmapTableEntryWrapper {}
// SAFETY: data structure only contain a series of integers
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
// * all of the parameters being passed to the trait (if there are any) are also foreign
// is prohibited.
#[derive(Copy, Clone, Default)]
struct BootParamsWrapper(boot_params);
// SAFETY: BootParamsWrap is a wrapper over `boot_params` (a series of ints).
unsafe impl ByteValued for BootParamsWrapper {}
pub struct CpuidConfig {
pub sgx_epc_sections: Option<Vec<SgxEpcSection>>,
pub phys_bits: u8,
@@ -221,6 +188,26 @@ impl From<Error> for super::Error {
}
}
pub fn get_x2apic_id(cpu_id: u32, topology: Option<(u8, u8, u8)>) -> u32 {
if let Some(t) = topology {
let thread_mask_width = u8::BITS - (t.0 - 1).leading_zeros();
let core_mask_width = u8::BITS - (t.1 - 1).leading_zeros();
let die_mask_width = u8::BITS - (t.2 - 1).leading_zeros();
let thread_id = cpu_id % (t.0 as u32);
let core_id = cpu_id / (t.0 as u32) % (t.1 as u32);
let die_id = cpu_id / ((t.0 * t.1) as u32) % (t.2 as u32);
let socket_id = cpu_id / ((t.0 * t.1 * t.2) as u32);
return thread_id
| (core_id << thread_mask_width)
| (die_id << (thread_mask_width + core_mask_width))
| (socket_id << (thread_mask_width + core_mask_width + die_mask_width));
}
cpu_id
}
#[derive(Copy, Clone, Debug)]
pub enum CpuidReg {
EAX,
@@ -240,6 +227,26 @@ pub struct CpuidPatch {
}
impl CpuidPatch {
pub fn get_cpuid_reg(
cpuid: &[CpuIdEntry],
function: u32,
index: Option<u32>,
reg: CpuidReg,
) -> Option<u32> {
for entry in cpuid.iter() {
if entry.function == function && (index.is_none() || index.unwrap() == entry.index) {
return match reg {
CpuidReg::EAX => Some(entry.eax),
CpuidReg::EBX => Some(entry.ebx),
CpuidReg::ECX => Some(entry.ecx),
CpuidReg::EDX => Some(entry.edx),
};
}
}
None
}
pub fn set_cpuid_reg(
cpuid: &mut Vec<CpuIdEntry>,
function: u32,
@@ -777,31 +784,27 @@ pub fn configure_vcpu(
cpu_vendor: CpuVendor,
topology: Option<(u8, u8, u8)>,
) -> super::Result<()> {
let x2apic_id = get_x2apic_id(id as u32, topology);
// Per vCPU CPUID changes; common are handled via 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));
CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, x2apic_id);
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, x2apic_id);
if matches!(cpu_vendor, CpuVendor::AMD) {
CpuidPatch::set_cpuid_reg(
&mut cpuid,
0x8000_001e,
Some(0),
CpuidReg::EAX,
u32::from(id),
);
}
if let Some(t) = topology {
update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id);
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x8000_001e, Some(0), CpuidReg::EAX, x2apic_id);
}
// Set ApicId in cpuid for each vcpu
// SAFETY: get host cpuid when eax=1
let mut cpu_ebx = unsafe { core::arch::x86_64::__cpuid(1) }.ebx;
cpu_ebx &= 0xffffff;
cpu_ebx |= (id as u32) << 24;
cpu_ebx |= x2apic_id << 24;
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx);
if let Some(t) = topology {
update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id);
}
// The TSC frequency CPUID leaf should not be included when running with HyperV emulation
if !kvm_hyperv {
if let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {
@@ -896,6 +899,7 @@ pub fn configure_system(
serial_number: Option<&str>,
uuid: Option<&str>,
oem_strings: Option<&[&str]>,
topology: Option<(u8, u8, u8)>,
) -> super::Result<()> {
// Write EBDA address to location where ACPICA expects to find it
guest_mem
@@ -908,7 +912,7 @@ pub fn configure_system(
// 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)?;
mptable::setup_mptable(offset, guest_mem, _num_cpus, topology).map_err(Error::MpTableSetup)?;
// Check that the RAM is not smaller than the RSDP start address
if let Some(rsdp_addr) = rsdp_addr {
@@ -926,52 +930,11 @@ pub fn configure_system(
)
}
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();
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);
type RamRange = (u64, u64);
/// Returns usable physical memory ranges for the guest
/// These should be used to create e820_RAM memory maps
pub fn generate_ram_ranges(guest_mem: &GuestMemoryMmap) -> super::Result<Vec<RamRange>> {
// Merge continuous memory regions into one region.
// Note: memory regions from "GuestMemory" are sorted and non-zero sized.
let ram_regions = {
@@ -1004,16 +967,12 @@ fn configure_pvh(
ram_regions
};
if ram_regions.len() > 2 {
error!(
"There should be up to two non-continuous regions, devidided by the
gap at the end of 32bit address space (e.g. between 3G and 4G)."
);
return Err(super::Error::MemmapTableSetup);
}
// Create the memory map entry for memory region before the gap
{
let mut ram_ranges = vec![];
// Generate the first usable physical memory range before the gap. The e820 map
// should only report memory above 1MiB.
let first_ram_range = {
let (first_region_start, first_region_end) =
ram_regions.first().ok_or(super::Error::MemmapTableSetup)?;
let high_ram_start = layout::HIGH_RAM_START.raw_value();
@@ -1033,39 +992,87 @@ fn configure_pvh(
}
info!(
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
"first usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
high_ram_start, first_region_end
);
add_memmap_entry(
&mut memmap,
high_ram_start,
first_region_end - high_ram_start,
E820_RAM,
(high_ram_start, *first_region_end)
};
ram_ranges.push(first_ram_range);
// Generate additional usable physical memory range after the gap if any.
for ram_region in ram_regions.iter().skip(1) {
info!(
"found usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
ram_region.0, ram_region.1
);
ram_ranges.push(*ram_region);
}
// Create the memory map entry for memory region after the gap if any
if let Some((second_region_start, second_region_end)) = ram_regions.get(1) {
let ram_64bit_start = layout::RAM_64BIT_START.raw_value();
Ok(ram_ranges)
}
if second_region_start != &ram_64bit_start {
error!(
"Unexpected second memory region layout: start: 0x{:08x}, ram_64bit_start: 0x{:08x}",
second_region_start, ram_64bit_start
);
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;
return Err(super::Error::MemmapTableSetup);
}
let mut start_info = hvm_start_info {
magic: XEN_HVM_START_MAGIC_VALUE,
version: 1, // pvh has version 1
nr_modules: 0,
cmdline_paddr: cmdline_addr.raw_value(),
memmap_paddr: layout::MEMMAP_START.raw_value(),
..Default::default()
};
if let Some(rsdp_addr) = rsdp_addr {
start_info.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 = hvm_modlist_entry {
paddr: initramfs_config.address.raw_value(),
size: initramfs_config.size as u64,
..Default::default()
};
start_info.nr_modules += 1;
start_info.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);
// Get usable physical memory ranges
let ram_ranges = generate_ram_ranges(guest_mem)?;
// Create e820 memory map entries
for ram_range in ram_ranges {
info!(
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
ram_64bit_start, second_region_end
ram_range.0, ram_range.1
);
add_memmap_entry(
&mut memmap,
ram_64bit_start,
second_region_end - ram_64bit_start,
ram_range.0,
ram_range.1 - ram_range.0,
E820_RAM,
);
}
@@ -1086,7 +1093,7 @@ fn configure_pvh(
);
}
start_info.0.memmap_entries = memmap.len() as u32;
start_info.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.
@@ -1095,17 +1102,14 @@ fn configure_pvh(
guest_mem
.checked_offset(
memmap_start_addr,
mem::size_of::<hvm_memmap_table_entry>() * start_info.0.memmap_entries as usize,
mem::size_of::<hvm_memmap_table_entry>() * start_info.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 every entry in the memmap vector, 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)
.write_obj(memmap_entry, 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);
@@ -1191,10 +1195,24 @@ fn update_cpuid_topology(
cpu_vendor: CpuVendor,
id: u8,
) {
let x2apic_id = get_x2apic_id(
id as u32,
Some((threads_per_core, cores_per_die, dies_per_package)),
);
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;
let mut cpu_ebx = CpuidPatch::get_cpuid_reg(cpuid, 0x1, None, CpuidReg::EBX).unwrap_or(0);
cpu_ebx |= ((dies_per_package as u32) * (cores_per_die as u32) * (threads_per_core as u32))
& 0xff << 16;
CpuidPatch::set_cpuid_reg(cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx);
let mut cpu_edx = CpuidPatch::get_cpuid_reg(cpuid, 0x1, None, CpuidReg::EDX).unwrap_or(0);
cpu_edx |= 1 << 28;
CpuidPatch::set_cpuid_reg(cpuid, 0x1, None, CpuidReg::EDX, cpu_edx);
// CPU Topology leaf 0xb
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::EAX, thread_width);
CpuidPatch::set_cpuid_reg(
@@ -1253,7 +1271,7 @@ fn update_cpuid_topology(
0x8000_001e,
Some(0),
CpuidReg::EBX,
((threads_per_core as u32 - 1) << 8) | (id as u32 & 0xff),
((threads_per_core as u32 - 1) << 8) | (x2apic_id & 0xff),
);
CpuidPatch::set_cpuid_reg(
cpuid,
@@ -1264,21 +1282,21 @@ fn update_cpuid_topology(
);
CpuidPatch::set_cpuid_reg(cpuid, 0x8000_001e, Some(0), CpuidReg::EDX, 0);
if cores_per_die * threads_per_core > 1 {
let ecx =
CpuidPatch::get_cpuid_reg(cpuid, 0x8000_0001, Some(0), CpuidReg::ECX).unwrap_or(0);
CpuidPatch::set_cpuid_reg(
cpuid,
0x8000_0001,
Some(0),
CpuidReg::ECX,
(1u32 << 1) | (1u32 << 22),
ecx | (1u32 << 1) | (1u32 << 22),
);
CpuidPatch::set_cpuid_reg(
cpuid,
0x0000_0001,
Some(0),
CpuidReg::EBX,
((id as u32) << 24)
| (8 << 8)
| (((cores_per_die * threads_per_core) as u32) << 16),
(x2apic_id << 24) | (8 << 8) | (((cores_per_die * threads_per_core) as u32) << 16),
);
let cpuid_patches = vec![
// Patch tsc deadline timer bit
@@ -1311,7 +1329,7 @@ fn update_cpuid_topology(
// sections exposed to the guest.
fn update_cpuid_sgx(
cpuid: &mut Vec<CpuIdEntry>,
epc_sections: &Vec<SgxEpcSection>,
epc_sections: &[SgxEpcSection],
) -> Result<(), Error> {
// Something's wrong if there's no EPC section.
if epc_sections.is_empty() {
@@ -1383,6 +1401,7 @@ mod tests {
None,
None,
None,
None,
);
assert!(config_err.is_err());
@@ -1405,6 +1424,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
@@ -1432,6 +1452,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
@@ -1445,6 +1466,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
}
@@ -1473,4 +1495,25 @@ mod tests {
assert_eq!(format!("{memmap:?}"), format!("{expected_memmap:?}"));
}
#[test]
fn test_get_x2apic_id() {
let x2apic_id = get_x2apic_id(0, Some((2, 3, 1)));
assert_eq!(x2apic_id, 0);
let x2apic_id = get_x2apic_id(1, Some((2, 3, 1)));
assert_eq!(x2apic_id, 1);
let x2apic_id = get_x2apic_id(2, Some((2, 3, 1)));
assert_eq!(x2apic_id, 2);
let x2apic_id = get_x2apic_id(6, Some((2, 3, 1)));
assert_eq!(x2apic_id, 8);
let x2apic_id = get_x2apic_id(7, Some((2, 3, 1)));
assert_eq!(x2apic_id, 9);
let x2apic_id = get_x2apic_id(8, Some((2, 3, 1)));
assert_eq!(x2apic_id, 10);
}
}

View File

@@ -6,10 +6,9 @@
// found in the LICENSE-BSD-3-Clause file.
use crate::layout::{APIC_START, HIGH_RAM_START, IOAPIC_START};
use crate::x86_64::mpspec;
use crate::x86_64::{get_x2apic_id, mpspec};
use crate::GuestMemoryMmap;
use libc::c_char;
use std::io;
use std::mem;
use std::result;
use std::slice;
@@ -126,9 +125,18 @@ fn compute_mp_size(num_cpus: u8) -> usize {
}
/// Performs setup of the MP table for the given `num_cpus`.
pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
if num_cpus as u32 > MAX_SUPPORTED_CPUS {
return Err(Error::TooManyCpus);
pub fn setup_mptable(
offset: GuestAddress,
mem: &GuestMemoryMmap,
num_cpus: u8,
topology: Option<(u8, u8, u8)>,
) -> Result<()> {
if num_cpus > 0 {
let cpu_id_max = num_cpus - 1;
let x2apic_id_max = get_x2apic_id(cpu_id_max.into(), topology);
if x2apic_id_max >= MAX_SUPPORTED_CPUS {
return Err(Error::TooManyCpus);
}
}
// Used to keep track of the next base pointer into the MP table.
@@ -142,7 +150,7 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
}
let mut checksum: u8 = 0;
let ioapicid: u8 = num_cpus + 1;
let ioapicid: u8 = MAX_SUPPORTED_CPUS as u8 + 1;
// The checked_add here ensures the all of the following base_mp.unchecked_add's will be without
// overflow.
@@ -154,7 +162,7 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
return Err(Error::AddressOverflow);
}
mem.read_exact_from(base_mp, &mut io::repeat(0), mp_size)
mem.read_exact_volatile_from(base_mp, &mut vec![0; mp_size].as_slice(), mp_size)
.map_err(Error::Clear)?;
{
@@ -180,7 +188,7 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
for cpu_id in 0..num_cpus {
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
mpc_cpu.0.apicid = cpu_id;
mpc_cpu.0.apicid = get_x2apic_id(cpu_id as u32, topology) as u8;
mpc_cpu.0.apicver = APIC_VERSION;
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
| if cpu_id == 0 {
@@ -291,7 +299,10 @@ pub fn setup_mptable(offset: GuestAddress, mem: &GuestMemoryMmap, num_cpus: u8)
mod tests {
use super::*;
use crate::layout::MPTABLE_START;
use vm_memory::{GuestAddress, GuestUsize};
use vm_memory::{
bitmap::BitmapSlice, GuestAddress, GuestUsize, VolatileMemoryError, VolatileSlice,
WriteVolatile,
};
fn table_entry_size(type_: u8) -> usize {
match type_ as u32 {
@@ -310,7 +321,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus, None).unwrap();
}
#[test]
@@ -319,7 +330,7 @@ mod tests {
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)])
.unwrap();
assert!(setup_mptable(MPTABLE_START, &mem, num_cpus).is_err());
assert!(setup_mptable(MPTABLE_START, &mem, num_cpus, None).is_err());
}
#[test]
@@ -328,7 +339,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus, None).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
@@ -344,27 +355,31 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus).unwrap();
setup_mptable(MPTABLE_START, &mem, num_cpus, None).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
struct Sum(u8);
impl io::Write for Sum {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
for v in buf.iter() {
impl WriteVolatile for Sum {
fn write_volatile<B: BitmapSlice>(
&mut self,
buf: &VolatileSlice<B>,
) -> result::Result<usize, VolatileMemoryError> {
let mut tmp = vec![0u8; buf.len()];
tmp.write_all_volatile(buf)?;
for v in tmp.iter() {
self.0 = self.0.wrapping_add(*v);
}
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
let mut sum = Sum(0);
mem.write_to(mpc_offset, &mut sum, mpc_table.0.length as usize)
mem.write_volatile_to(mpc_offset, &mut sum, mpc_table.0.length as usize)
.unwrap();
assert_eq!(sum.0, 0);
}
@@ -378,7 +393,7 @@ mod tests {
.unwrap();
for i in 0..MAX_SUPPORTED_CPUS as u8 {
setup_mptable(MPTABLE_START, &mem, i).unwrap();
setup_mptable(MPTABLE_START, &mem, i, None).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
@@ -411,7 +426,7 @@ mod tests {
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8);
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8, None);
assert!(result.is_err());
}
}

View File

@@ -10,18 +10,18 @@ io_uring = ["dep:io-uring"]
[dependencies]
byteorder = "1.4.3"
crc32c = "0.6.4"
io-uring = { version = "0.6.1", optional = true }
libc = "0.2.147"
log = "0.4.17"
crc-any = "2.4.4"
io-uring = { version = "0.6.2", optional = true }
libc = "0.2.153"
log = "0.4.20"
remain = "0.2.11"
smallvec = "1.11.0"
thiserror = "1.0.40"
smallvec = "1.13.1"
thiserror = "1.0.52"
uuid = { version = "1.3.4", features = ["v4"] }
versionize = "0.1.10"
versionize_derive = "0.1.4"
versionize = "0.2.0"
versionize_derive = "0.1.6"
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.9.0"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.11.0"
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"

View File

@@ -143,10 +143,14 @@ pub enum ExecuteError {
Flush(io::Error),
#[error("Failed to read: {0}")]
Read(GuestMemoryError),
#[error("Failed to read_exact: {0}")]
ReadExact(io::Error),
#[error("Failed to seek: {0}")]
Seek(io::Error),
#[error("Failed to write: {0}")]
Write(GuestMemoryError),
#[error("Failed to write_all: {0}")]
WriteAll(io::Error),
#[error("Unsupported request: {0}")]
Unsupported(u32),
#[error("Failed to submit io uring: {0}")]
@@ -169,8 +173,10 @@ impl ExecuteError {
ExecuteError::BadRequest(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::ReadExact(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Seek(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Write(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::WriteAll(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Unsupported(_) => VIRTIO_BLK_S_UNSUPP,
ExecuteError::SubmitIoUring(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::GetHostAddress(_) => VIRTIO_BLK_S_IOERR,
@@ -351,13 +357,21 @@ impl Request {
match self.request_type {
RequestType::In => {
mem.read_exact_from(*data_addr, disk, *data_len as usize)
.map_err(ExecuteError::Read)?;
let mut buf = vec![0u8; *data_len as usize];
disk.read_exact(&mut buf).map_err(ExecuteError::ReadExact)?;
mem.read_exact_volatile_from(
*data_addr,
&mut buf.as_slice(),
*data_len as usize,
)
.map_err(ExecuteError::Read)?;
len += data_len;
}
RequestType::Out => {
mem.write_all_to(*data_addr, disk, *data_len as usize)
let mut buf: Vec<u8> = Vec::new();
mem.write_all_volatile_to(*data_addr, &mut buf, *data_len as usize)
.map_err(ExecuteError::Write)?;
disk.write_all(&buf).map_err(ExecuteError::WriteAll)?;
if !self.writeback {
disk.flush().map_err(ExecuteError::Flush)?;
}

View File

@@ -136,7 +136,7 @@ impl<T: Cacheable> CacheMap<T> {
mod tests {
use super::*;
struct NumCache(pub u64);
struct NumCache(());
impl Cacheable for NumCache {
fn dirty(&self) -> bool {
true
@@ -148,28 +148,28 @@ mod tests {
let mut cache = CacheMap::<NumCache>::new(3);
let mut evicted = None;
cache
.insert(0, NumCache(5), |index, _| {
.insert(0, NumCache(()), |index, _| {
evicted = Some(index);
Ok(())
})
.unwrap();
assert_eq!(evicted, None);
cache
.insert(1, NumCache(6), |index, _| {
.insert(1, NumCache(()), |index, _| {
evicted = Some(index);
Ok(())
})
.unwrap();
assert_eq!(evicted, None);
cache
.insert(2, NumCache(7), |index, _| {
.insert(2, NumCache(()), |index, _| {
evicted = Some(index);
Ok(())
})
.unwrap();
assert_eq!(evicted, None);
cache
.insert(3, NumCache(8), |index, _| {
.insert(3, NumCache(()), |index, _| {
evicted = Some(index);
Ok(())
})

View File

@@ -120,15 +120,20 @@ impl AsyncIo for RawFileAsyncAio {
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
let iocbs = [&mut aio::IoControlBlock {
aio_fildes: self.fd.as_raw_fd() as u32,
aio_lio_opcode: aio::IOCB_CMD_FSYNC as u16,
aio_data: user_data.unwrap_or(0),
aio_flags: aio::IOCB_FLAG_RESFD,
aio_resfd: self.eventfd.as_raw_fd() as u32,
..Default::default()
}];
let _ = self.ctx.submit(&iocbs[..]).map_err(AsyncIoError::Fsync)?;
if let Some(user_data) = user_data {
let iocbs = [&mut aio::IoControlBlock {
aio_fildes: self.fd.as_raw_fd() as u32,
aio_lio_opcode: aio::IOCB_CMD_FSYNC as u16,
aio_data: user_data,
aio_flags: aio::IOCB_FLAG_RESFD,
aio_resfd: self.eventfd.as_raw_fd() as u32,
..Default::default()
}];
let _ = self.ctx.submit(&iocbs[..]).map_err(AsyncIoError::Fsync)?;
} else {
// SAFETY: FFI call with a valid fd
unsafe { libc::fsync(self.fd) };
}
Ok(())
}

View File

@@ -192,7 +192,9 @@ impl Header {
};
new_header.get_header_as_buffer(&mut buffer);
new_header.checksum = crc32c::crc32c(&buffer);
let mut crc = crc_any::CRC::crc32c();
crc.digest(&buffer);
new_header.checksum = crc.get_crc() as u32;
new_header.get_header_as_buffer(&mut buffer);
f.seek(SeekFrom::Start(start))
@@ -351,12 +353,6 @@ impl RegionTableEntry {
}
}
#[derive(Clone, Debug)]
struct RegionEntry {
_start: u64,
_end: u64,
}
enum HeaderNo {
First,
Second,
@@ -480,7 +476,10 @@ pub fn calculate_checksum(buffer: &mut [u8], csum_offset: usize) -> Result<u32>
// Zero the checksum in the buffer
LittleEndian::write_u32(csum_buf, 0);
// Calculate the checksum on the resulting buffer
let new_csum = crc32c::crc32c(buffer);
let mut crc = crc_any::CRC::crc32c();
crc.digest(&buffer);
let new_csum = crc.get_crc() as u32;
// Put back the original checksum in the buffer
LittleEndian::write_u32(&mut buffer[csum_offset..csum_offset + 4], orig_csum);

View File

@@ -6,24 +6,24 @@ edition = "2021"
[dependencies]
acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" }
anyhow = "1.0.75"
anyhow = "1.0.79"
arch = { path = "../arch" }
bitflags = "2.4.1"
byteorder = "1.4.3"
event_monitor = { path = "../event_monitor" }
hypervisor = { path = "../hypervisor" }
libc = "0.2.147"
log = "0.4.17"
libc = "0.2.153"
log = "0.4.20"
pci = { path = "../pci" }
thiserror = "1.0.40"
thiserror = "1.0.52"
tpm = { path = "../tpm" }
versionize = "0.1.10"
versionize_derive = "0.1.4"
versionize = "0.2.0"
versionize_derive = "0.1.6"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = "0.12.2"
vm-memory = "0.14.0"
vm-migration = { path = "../vm-migration" }
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"
[target.'cfg(target_arch = "aarch64")'.dependencies]
arch = { path = "../arch" }

View File

@@ -0,0 +1,64 @@
// Copyright © 2023 Cyberus Technology
//
// SPDX-License-Identifier: Apache-2.0
//
//! Module for [`DebugconState`].
use std::io;
use std::io::Write;
use std::sync::{Arc, Barrier};
use vm_device::BusDevice;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
/// I/O-port.
pub const DEFAULT_PORT: u64 = 0xe9;
#[derive(Default)]
pub struct DebugconState {}
/// Emulates a debug console similar to the QEMU debugcon device. This device
/// is stateless and only prints the bytes (usually text) that are written to
/// it.
///
/// This device is only available on x86.
///
/// Reference:
/// - https://github.com/qemu/qemu/blob/master/hw/char/debugcon.c
/// - https://phip1611.de/blog/how-to-use-qemus-debugcon-feature-and-write-to-a-file/
pub struct DebugConsole {
id: String,
out: Box<dyn io::Write + Send>,
}
impl DebugConsole {
pub fn new(id: String, out: Box<dyn io::Write + Send>) -> Self {
Self { id, out }
}
}
impl BusDevice for DebugConsole {
fn read(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {}
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
if let Err(e) = self.out.write_all(data) {
// unlikely
error!("debug-console: failed writing data: {e:?}");
}
None
}
}
impl Snapshottable for DebugConsole {
fn id(&self) -> String {
self.id.clone()
}
fn snapshot(&mut self) -> Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&())
}
}
impl Pausable for DebugConsole {}
impl Transportable for DebugConsole {}
impl Migratable for DebugConsole {}

View File

@@ -15,6 +15,8 @@ extern crate event_monitor;
extern crate log;
pub mod acpi;
#[cfg(target_arch = "x86_64")]
pub mod debug_console;
#[cfg(target_arch = "aarch64")]
pub mod gic;
pub mod interrupt_controller;

View File

@@ -26,6 +26,7 @@ const PVPANIC_VENDOR_ID: u16 = 0x1b36;
const PVPANIC_DEVICE_ID: u16 = 0x0011;
pub const PVPANIC_DEVICE_MMIO_SIZE: u64 = 0x2;
pub const PVPANIC_DEVICE_MMIO_ALIGNMENT: u64 = 0x10;
const PVPANIC_PANICKED: u8 = 1 << 0;
const PVPANIC_CRASH_LOADED: u8 = 1 << 1;
@@ -180,8 +181,9 @@ impl PciDevice for PvPanicDevice {
fn allocate_bars(
&mut self,
allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator,
_allocator: &Arc<Mutex<SystemAllocator>>,
mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new();
@@ -189,10 +191,8 @@ impl PciDevice for PvPanicDevice {
let bar_id = 0;
let region_size = PVPANIC_DEVICE_MMIO_SIZE;
let restoring = resources.is_some();
let bar_addr = allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(None, region_size, None)
let bar_addr = mmio32_allocator
.allocate(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
let bar = PciBarConfiguration::default()
@@ -217,11 +217,12 @@ impl PciDevice for PvPanicDevice {
fn free_bars(
&mut self,
allocator: &mut SystemAllocator,
_mmio_allocator: &mut AddressAllocator,
_allocator: &mut SystemAllocator,
mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> std::result::Result<(), PciDeviceError> {
for bar in self.bar_regions.drain(..) {
allocator.free_mmio_hole_addresses(GuestAddress(bar.addr()), bar.size());
mmio32_allocator.free(GuestAddress(bar.addr()), bar.size());
}
Ok(())

View File

@@ -36,3 +36,5 @@ You can run a SEV-SNP VM using the following command:
--memory size=1G \
--disk path=ubuntu.img
```
For more information related to Microsoft Hypervisor please see [mshv.md](mshv.md)

View File

@@ -147,7 +147,7 @@ We want to create a virtual machine with the following characteristics:
`/opt/clh/images/focal-server-cloudimg-amd64.raw`
```shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X PUT 'http://localhost/api/v1/vm.create' \
@@ -167,7 +167,7 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i \
Once the VM is created, we can boot it:
```shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.boot'
```
@@ -177,7 +177,7 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1
We can fetch information about any VM, as soon as it's created:
```shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X GET 'http://localhost/api/v1/vm.info' \
@@ -189,7 +189,7 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i \
We can reboot a VM that's already booted:
```shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.reboot'
```
@@ -199,7 +199,7 @@ curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1
Once booted, we can shut a VM down from the REST API:
```shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i -X PUT 'http://localhost/api/v1/vm.shutdown'
```
@@ -385,7 +385,7 @@ APIs work together, let's look at a complete VM creation flow, from the
[REST API](#rest-api) in order to creates a virtual machine:
```
shell
#!/bin/bash
#!/usr/bin/env bash
curl --unix-socket /tmp/cloud-hypervisor.sock -i \
-X PUT 'http://localhost/api/v1/vm.create' \

View File

@@ -1,7 +1,16 @@
# `cloud-hypervisor` debug IO port
# `cloud-hypervisor` debug IO ports
`cloud-hypervisor` uses the [`0x80`](https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
I/O port to trace user defined guest events.
When running x86 guests, `cloud-hypervisor` provides different kinds of debug ports:
- [`0x80` debug port](https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
- Debug console (by default at `0xe9`).
- Firmware debug port at `0x402`.
All of them can be used to trace user-defined guest events and all of them can
be used simultaneously.
## Debug Ports Overview
### `0x80` I/O port
Whenever the guest write one byte between `0x0` and `0xF` on this particular
I/O port, `cloud-hypervisor` will log and timestamp that event at the `debug`
@@ -30,7 +39,7 @@ guest will have `cloud-hypervisor` generate timestamped logs of all those steps.
That provides a basic but convenient way of measuring not only the overall guest
boot time but all intermediate steps as well.
## Logging
#### Logging
Assuming parts of the guest software stack have been instrumented to use the
`cloud-hypervisor` debug I/O port, we may want to gather the related logs.
@@ -59,3 +68,29 @@ $ grep "Debug I/O port" /tmp/ch-fw.log
cloud-hypervisor: 19.762449ms: DEBUG:vmm/src/vm.rs:510 -- [Debug I/O port: Firmware code 0x0] 0.019004 seconds
cloud-hypervisor: 403.499628ms: DEBUG:vmm/src/vm.rs:510 -- [Debug I/O port: Firmware code 0x1] 0.402744 seconds
```
### Debug console port
The debug console is inspired by QEMU and Bochs, which have a similar feature.
By default, the I/O port `0xe9` is used. This port can be configured like a
console. Thus, it can print to a tty, a file, or a pty, for example.
### Firmware debug port
The firmware debug port is also a simple port that prints all bytes written to
it. The firmware debug port only prints to stdout.
## When do I need these ports?
The ports are on the one hand interesting for firmware or kernel developers, as
they provide an easy way to print debug information from within a guest.
Furthermore, you can patch "normal" software to measure certain events, such as
the boot time of a guest.
## Which port should I choose?
The `0x80` debug port and the port of the firmware debug device are always
available. The debug console must be activated via the command line, but
provides more configuration options.
You can use different ports for different aspect of your logging messages.

View File

@@ -103,7 +103,7 @@ firmware:
### TDShim
> **Note**
> The latest version of TDShim being tested is [_66bb334_](https://github.com/confidential-containers/td-shim/tree/66bb33451befbf1291abe3cfea7ee9e99d922b0d).
> The latest version of TDShim being tested is [_v0.8.0_](https://github.com/confidential-containers/td-shim/releases/tag/v0.8.0).
This is a lightweight version of the TDVF, written in Rust and designed for
direct kernel boot, which is useful for containers use cases.
@@ -113,7 +113,7 @@ and `LLVM` first. The TDshim can be build as follows:
```bash
git clone https://github.com/confidential-containers/td-shim
cd td-shim
git checkout 66bb33451befbf1291abe3cfea7ee9e99d922b0d
git checkout v0.8.0
cargo install cargo-xbuild
export CC=clang
export AR=llvm-ar
@@ -121,15 +121,13 @@ export CC_x86_64_unknown_none=clang
export AR_x86_64_unknown_none=llvm-ar
git submodule update --init --recursive
./sh_script/preparation.sh
cargo xbuild -p td-shim --target x86_64-unknown-none --release --features=main,tdx
cargo run -p td-shim-tools --bin td-shim-ld --features=linker -- target/x86_64-unknown-none/release/ResetVector.bin target/x86_64-unknown-none/release/td-shim -o target/release/final.bin
cargo image --release
```
If debug logs from the TDShim is needed, here are the alternative
commands:
```bash
cargo xbuild -p td-shim --target x86_64-unknown-none --features=main,tdx
cargo run -p td-shim-tools --bin td-shim-ld --features=linker -- target/x86_64-unknown-none/debug/ResetVector.bin target/x86_64-unknown-none/debug/td-shim -o target/debug/final.bin
cargo image
```
And run a TDX VM by providing the firmware previously built, along with a guest

View File

@@ -42,3 +42,14 @@ actual rate limit users get can be as low as
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").
## Rate Limit Groups
It is possible to throttle the aggregate bandwidth or operations
of multiple virtio-blk devices using a `rate_limit_group`. virtio-blk devices may be
dynamically added and removed from a `rate_limit_group`. The following example
demonstrates how to throttle the aggregate bandwidth of two disks to 10 MiB/s.
```
--disk path=disk0.raw,rate_limit_group=group0 \
path=disk1.raw,rate_limit_group=group0 \
--rate-limit-group bw_size=1048576,bw_refill_time,bw_refill_time=100
```

View File

@@ -60,10 +60,7 @@ implement a full emulation of a physical IOMMU.
### Kernel
Since virtio-iommu has landed partially into the version 5.3 of the Linux
kernel, a special branch is needed to get things working with Cloud Hypervisor.
By partially, we are talking about x86 specifically, as it is already fully
functional for ARM architectures.
As of Kernel 5.14, virtio-iommu is available for both X86-64 and Aarch64.
## Usage

48
docs/mshv.md Normal file
View File

@@ -0,0 +1,48 @@
# Microsoft Hypervisor
The Microsoft Hypervisor is a Type 1 hypervisor which runs on x64 and ARM64 architectures. As the foundation of the Hyper-V virtualization stack, it runs millions of Linux and Windows guests in Azure and on-premises deployments. It supports nested virtualization, and security features like AMD's SEV-SNP. It also supports various features in Windows such as [Device guard and confidential guard](https://techcommunity.microsoft.com/t5/iis-support-blog/windows-10-device-guard-and-credential-guard-demystified/ba-p/376419), and [WSL2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq)
Since 2020, Microsoft has been releasing open-source components to support Linux running as root partition on the Microsoft Hypervisor.
1. Kernel patches to support Linux booting as root partition
2. A Linux kernel driver exposing an IOCTL interface for managing guest partitions, via a device node - /dev/mshv
3. Rust bindings and IOCTL wrappers
4. IGVM related crates
## Components
The following components are related to MSHV support with Cloud-Hypervisor:
* [igvm-crates](https://github.com/microsoft/igvm) : Parsing IGVM file
* [mshv-crates](https://github.com/rust-vmm/mshv) : Rust crates to interact with kernel module (/dev/mshv)
* [igvm-tooling](https://github.com/microsoft/igvm-tooling) : Tool to generate IGVM file
## IGVM
Independent Guest Virtual Machine (IGVM) file format.The format specification can be found in the igvm_defs crate, with a Rust implementation of the binary format in the igvm crate.
The IGVM file format is designed to encapsulate all information required to launch a virtual machine on any given virtualization stack, with support for different isolation technologies such as AMD SEV-SNP and Intel TDX.
At a conceptual level, this file format is a set of commands created by the tool that generated the file, used by the loader to construct the initial guest state. The file format also contains measurement information that the underlying platform will use to confirm that the file was loaded correctly and signed by the appropriate authorities.
Cloud Hypervisor can be built using igvm feature flag along with mshv and/or sev-snp. IGVM only works with MSHV.
## SEV-SNP
AMD's [Secure Encrypted Virtualization (SEV)](https://www.amd.com/en/developer/sev.html) and extensions such as Secure Nested Paging (SEV-SNP) encrypt memory and restrict access to a guest VM's memory and registers, securing it against a compromised hypervisor or VMM. They utilize the Platform Security Processor (PSP) to store keys and encrypt/decrypt the data. Microsoft has been continuously adding/improving support for SEV-SNP on Microsoft Hyper-V. Cloud-Hypervisor can be built with the sev_snp feature including mshv and igvm feature.
## Use Cases
Cloud Hypervisor can be built to run on an MSHV root partition by enabling the mshv feature, e.g.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features mshv```
Cloud Hypervisor on MSHV can boot Linux guests using an IGVM file. IGVM feature depends on mshv for running legacy VMs.e.g.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features igvm```
For running confidential VMs on mshv, you will only need to enable sev_snp, it requires and enables mshv and igvm automatically, eg.:
```cargo build --locked --all --all-targets --no-default-features --tests --examples --features sev_snp```

View File

@@ -2,8 +2,8 @@
The purpose of this document is to illustrate how to test vhost-user-net
in cloud-hypervisor with OVS/DPDK as the backend. This document was
tested with Open vSwitch v2.13.1, DPDK v19.11.3, and Cloud Hypervisor
v15.0 on Ubuntu 20.04.1 (host kernel v5.4.0).
tested with Open vSwitch v2.17.8, DPDK v21.11.4, and Cloud Hypervisor
v37.0 on Ubuntu 22.04.3 (host kernel v5.15.0).
## Framework
@@ -74,8 +74,8 @@ Here is an example how to create a bridge and add two DPDK ports to it
# create a bridge
ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev
# create two DPDK ports and add them to the bridge
ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser
ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser
ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuserclient options:vhost-server-path=/tmp/vhost-user1
ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuserclient options:vhost-server-path=/tmp/vhost-user2
# set the number of rx queues
ovs-vsctl set Interface vhost-user1 options:n_rxq=2
ovs-vsctl set Interface vhost-user2 options:n_rxq=2
@@ -92,7 +92,7 @@ VMs run in client mode. They connect to the socket created by the `dpdkvhostuser
--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
--net mac=52:54:00:02:d9:01,vhost_user=true,socket=/tmp/vhost-user1,num_queues=4,vhost_mode=server
# 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 \
@@ -101,21 +101,21 @@ VMs run in client mode. They connect to the socket created by the `dpdkvhostuser
--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
--net mac=52:54:20:11:C5:02,vhost_user=true,socket=/tmp/vhost-user2,num_queues=4,vhost_mode=server
```
_Setup VM1_
```bash
# From inside the guest
sudo ip addr add 172.100.0.1/24 dev ens2
sudo ip link set up dev ens2
sudo ip addr add 172.100.0.1/24 dev ens3
sudo ip link set up dev ens3
```
_Setup VM2_
```bash
# From inside the guest
sudo ip addr add 172.100.0.2/24 dev ens2
sudo ip link set up dev ens2
sudo ip addr add 172.100.0.2/24 dev ens3
sudo ip link set up dev ens3
```
_Ping VM1 from VM2_

View File

@@ -49,7 +49,7 @@ qemu-system-x86_64 \
-m 4G \
-bios ./$OVMF_DIR/OVMF_CODE.fd \
-cdrom ./$WIN_ISO_FILE \
-drive file=./$VIRTIO_ISO_FILE,index=0,media=cdrom
-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 \

View File

@@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
flume = "0.10.14"
libc = "0.2.147"
once_cell = "1.18.0"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
libc = "0.2.153"
once_cell = "1.19.0"
serde = { version = "1.0.196", features = ["rc", "derive"] }
serde_json = "1.0.109"

330
fuzz/Cargo.lock generated
View File

@@ -12,9 +12,9 @@ dependencies = [
[[package]]
name = "anstream"
version = "0.6.4"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -26,33 +26,33 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.4"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.1"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys",
@@ -60,9 +60,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.75"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
[[package]]
name = "api_client"
@@ -73,9 +73,9 @@ dependencies = [
[[package]]
name = "arbitrary"
version = "1.3.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]]
name = "arc-swap"
@@ -137,7 +137,7 @@ name = "block"
version = "0.1.0"
dependencies = [
"byteorder",
"crc32c",
"crc-any",
"io-uring",
"libc",
"log",
@@ -184,34 +184,34 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.4.7"
version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.4.7"
version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
"strsim 0.11.0",
]
[[package]]
name = "clap_lex"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "cloud-hypervisor"
version = "35.0.0"
version = "37.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -252,6 +252,7 @@ dependencies = [
"virtio-queue",
"vm-device",
"vm-memory",
"vm-migration",
"vm-virtio",
"vmm",
"vmm-sys-util",
@@ -264,25 +265,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "crc32c"
version = "0.6.4"
name = "crc-any"
version = "2.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8f48d60e5b4d2c53d5c2b1d8a58c849a70ae5e5509b08a48d047e3b65714a74"
checksum = "c01a5e1f881f6fb6099a7bdf949e946719fd4f1fefa56264890574febf0eb6d0"
dependencies = [
"rustc_version",
"debug-helper",
]
[[package]]
name = "crc64"
version = "1.0.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910"
checksum = "2707e3afba5e19b75d582d88bc79237418f2a2a2d673d01cf9b03633b46e98f3"
[[package]]
name = "darling"
version = "0.20.3"
version = "0.20.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8"
dependencies = [
"darling_core",
"darling_macro",
@@ -290,29 +291,35 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.3"
version = "0.20.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.32",
"strsim 0.10.0",
"syn 2.0.47",
]
[[package]]
name = "darling_macro"
version = "0.20.3"
version = "0.20.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77"
dependencies = [
"darling_core",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]
[[package]]
name = "debug-helper"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
[[package]]
name = "devices"
version = "0.1.0"
@@ -386,21 +393,21 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "futures-core"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-sink"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "getrandom"
version = "0.2.10"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"js-sys",
@@ -435,9 +442,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "io-uring"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460648e47a07a43110fbfa2e0b14afb2be920093c31e5dccc50e49568e099762"
checksum = "a9febecd4aebbe9c7c23c8e536e966805fdf09944c8a915e7991ee51acb67087"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -445,32 +452,32 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "jobserver"
version = "0.1.27"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.64"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kvm-bindings"
version = "0.6.0"
source = "git+https://github.com/cloud-hypervisor/kvm-bindings?branch=ch-v0.6.0-tdx#7d9ffb47e5b9b1989577258800a0f57c93f1445f"
version = "0.7.0"
source = "git+https://github.com/cloud-hypervisor/kvm-bindings?branch=ch-v0.7.0#2dcf85d4f8aa55befcaa996b699ddb18ec9ed059"
dependencies = [
"serde",
"serde_derive",
@@ -479,10 +486,11 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.13.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8dc9c1896e5f144ec5d07169bc29f39a047686d29585a91f30489abfaeb6b"
checksum = "9002dff009755414f22b962ec6ae6980b07d6d8b06e5297b1062019d72bd6a8c"
dependencies = [
"bitflags 2.4.1",
"kvm-bindings",
"libc",
"vmm-sys-util",
@@ -490,9 +498,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.149"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libfuzzer-sys"
@@ -507,9 +515,9 @@ dependencies = [
[[package]]
name = "linux-loader"
version = "0.9.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db6a725c8000971f83fa93ed7ee1b600e55a1471a2a653379d3c84f72effdcf"
checksum = "eb68dd3452f25a8defaf0ae593509cff0c777683e4d8924f59ac7c5f89267a83"
dependencies = [
"vm-memory",
]
@@ -533,7 +541,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#a4d632f2c5ea45712c0d2002dc909a63879e85c3"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#e75dfa1eeea23b69caa7407bc2c3a76d7b7262fb"
dependencies = [
"libc",
"vmm-sys-util",
@@ -578,9 +586,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.18.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "option_parser"
@@ -611,38 +619,38 @@ dependencies = [
[[package]]
name = "pin-project"
version = "1.1.3"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.3"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
@@ -651,36 +659,29 @@ dependencies = [
name = "rate_limiter"
version = "0.1.0"
dependencies = [
"epoll",
"libc",
"log",
"thiserror",
"vmm-sys-util",
]
[[package]]
name = "remain"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bce3a7139d2ee67d07538ee5dba997364fbc243e7e7143e96eb830c74bfaa082"
checksum = "1ad5e011230cad274d0532460c5ab69828ea47ae75681b42a841663efffaf794"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
"syn 2.0.47",
]
[[package]]
name = "ryu"
version = "1.0.15"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "scopeguard"
@@ -697,37 +698,31 @@ dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.189"
version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.189"
version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]
[[package]]
name = "serde_json"
version = "1.0.108"
version = "1.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
dependencies = [
"itoa",
"ryu",
@@ -753,7 +748,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]
[[package]]
@@ -781,9 +776,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "spin"
@@ -800,6 +795,12 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "syn"
version = "1.0.109"
@@ -813,9 +814,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.32"
version = "2.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb"
dependencies = [
"proc-macro2",
"quote",
@@ -824,22 +825,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.50"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]
[[package]]
@@ -880,18 +881,18 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.5.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
]
[[package]]
name = "versionize"
version = "0.1.10"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca4b7062e7e6d685901e815c35f9671e059de97c1c0905eeff8592f3fff442f"
checksum = "62929d59c7f6730b7298fcb363760550f4db6e353fbac4076d447d0e82799d6d"
dependencies = [
"bincode",
"crc64",
@@ -906,8 +907,8 @@ dependencies = [
[[package]]
name = "versionize_derive"
version = "0.1.4"
source = "git+https://github.com/cloud-hypervisor/versionize_derive?branch=ch#e502b1d4aabab342386f0c53780d49f21a6a1df6"
version = "0.1.6"
source = "git+https://github.com/cloud-hypervisor/versionize_derive?branch=ch-0.1.6#7906da996152e2d0ab08f5526440683bf3ca7834"
dependencies = [
"proc-macro2",
"quote",
@@ -917,7 +918,7 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#0daff4d4c159e842cf18b8b90457a45032b2df5a"
dependencies = [
"vmm-sys-util",
]
@@ -925,7 +926,7 @@ dependencies = [
[[package]]
name = "vfio-ioctls"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#847b0aa504ac6367efe42ba7e96a2d050737d4f0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#0daff4d4c159e842cf18b8b90457a45032b2df5a"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -941,7 +942,7 @@ dependencies = [
[[package]]
name = "vfio_user"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#2d96b90a7279547356ad8f83aaa3115ad5497302"
source = "git+https://github.com/rust-vmm/vfio-user?branch=main#a1f6e52829e069b6d698b2cfeecac742e4653186"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -957,11 +958,11 @@ dependencies = [
[[package]]
name = "vhost"
version = "0.8.1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6"
checksum = "2b64e816d0d49769fbfaa1494eb77cc2a3ddc526ead05c7f922cb7d64106286f"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.4.1",
"libc",
"vm-memory",
"vmm-sys-util",
@@ -969,9 +970,9 @@ dependencies = [
[[package]]
name = "virtio-bindings"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c18d7b74098a946470ea265b5bacbbf877abc3373021388454de0d47735a5b98"
checksum = "878bcb1b2812a10c30d53b0ed054999de3d98f25ece91fc173973f9c57aaae86"
[[package]]
name = "virtio-devices"
@@ -1009,9 +1010,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.9.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f"
checksum = "e3f69a13d6610db9312acbb438b0390362af905d37634a2106be70c0f734986d"
dependencies = [
"log",
"virtio-bindings",
@@ -1048,9 +1049,9 @@ source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#c5a99ab71b130435927
[[package]]
name = "vm-memory"
version = "0.12.2"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b"
checksum = "74ffc42216c32c35f858fa4bfdcd9b61017dfd691e0240268fdc85dbf59e5459"
dependencies = [
"arc-swap",
"libc",
@@ -1105,6 +1106,7 @@ dependencies = [
"once_cell",
"option_parser",
"pci",
"rate_limiter",
"seccompiler",
"serde",
"serde_json",
@@ -1130,9 +1132,9 @@ dependencies = [
[[package]]
name = "vmm-sys-util"
version = "0.11.2"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48b7b084231214f7427041e4220d77dfe726897a6d41fddee450696e66ff2a29"
checksum = "1d1435039746e20da4f8d507a72ee1b916f7b4b05af7a91c093d2c6561934ede"
dependencies = [
"bitflags 1.3.2",
"libc",
@@ -1148,9 +1150,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.87"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -1158,24 +1160,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.87"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1183,22 +1185,22 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.87"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.87"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
[[package]]
name = "winapi"
@@ -1224,18 +1226,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
@@ -1248,51 +1250,51 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "zerocopy"
version = "0.7.20"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"byteorder",
"zerocopy-derive",
@@ -1300,11 +1302,11 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.7.20"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.32",
"syn 2.0.47",
]

View File

@@ -8,22 +8,26 @@ edition = "2021"
[package.metadata]
cargo-fuzz = true
[features]
igvm = []
[dependencies]
block = { path = "../block" }
devices = { path = "../devices" }
epoll = "4.3.1"
libc = "0.2.149"
libc = "0.2.152"
libfuzzer-sys = "0.4.7"
linux-loader = { version = "0.9.1", features = ["elf", "bzimage", "pe"] }
linux-loader = { version = "0.11.0", features = ["elf", "bzimage", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }
net_util = { path = "../net_util" }
once_cell = "1.18.0"
once_cell = "1.19.0"
seccompiler = "0.4.0"
virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.9.0"
virtio-queue = "0.11.0"
vmm = { path = "../vmm" }
vmm-sys-util = "0.11.2"
vm-memory = "0.12.2"
vmm-sys-util = "0.12.1"
vm-memory = "0.14.0"
vm-migration = { path = "../vm-migration" }
vm-device = { path = "../vm-device" }
vm-virtio = { path = "../vm-virtio" }
@@ -31,8 +35,8 @@ vm-virtio = { path = "../vm-virtio" }
path = ".."
[patch.crates-io]
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch" }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.7.0" }
versionize_derive = { git = "https://github.com/cloud-hypervisor/versionize_derive", branch = "ch-0.1.6" }
# Prevent this from interfering with workspaces
[workspace]

View File

@@ -21,6 +21,7 @@ use virtio_devices::{Block, VirtioDevice, VirtioInterrupt, VirtioInterruptType};
use virtio_queue::{Queue, QueueT};
use vm_memory::{bitmap::AtomicBitmap, Bytes, GuestAddress, GuestMemoryAtomic};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
use std::collections::BTreeMap;
type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>;
@@ -49,6 +50,7 @@ fuzz_target!(|bytes| {
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(RawFileDiskSync::new(disk_file)) as Box<dyn DiskFile>;
let queue_affinity = BTreeMap::new();
let mut block = Block::new(
"tmp".to_owned(),
qcow_disk,
@@ -62,6 +64,7 @@ fuzz_target!(|bytes| {
None,
EventFd::new(EFD_NONBLOCK).unwrap(),
None,
queue_affinity,
)
.unwrap();

View File

@@ -6,8 +6,6 @@
use devices::legacy::Cmos;
use libc::EFD_NONBLOCK;
use libfuzzer_sys::fuzz_target;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use vm_device::BusDevice;
use vmm_sys_util::eventfd::EventFd;

View File

@@ -7,9 +7,18 @@ use libfuzzer_sys::fuzz_target;
use micro_http::Request;
use once_cell::sync::Lazy;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::sync::mpsc::{channel, Receiver};
use std::sync::{Arc, Mutex};
use std::thread;
use vmm::api::{http::*, ApiRequest, ApiResponsePayload};
use vm_migration::MigratableError;
use vmm::api::{
http::*, ApiRequest, RequestHandler, VmInfoResponse, VmReceiveMigrationData,
VmSendMigrationData, VmmPingResponse,
};
use vmm::config::RestoreConfig;
use vmm::vm::{Error as VmError, VmState};
use vmm::vm_config::*;
use vmm::{EpollContext, EpollDispatch};
use vmm_sys_util::eventfd::EventFd;
@@ -69,6 +78,203 @@ fn generate_request(bytes: &[u8]) -> Option<Request> {
Request::try_from(&request, None).ok()
}
struct StubApiRequestHandler;
impl RequestHandler for StubApiRequestHandler {
fn vm_create(&mut self, _: Arc<Mutex<VmConfig>>) -> Result<(), VmError> {
Ok(())
}
fn vm_boot(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_pause(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_resume(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_snapshot(&mut self, _: &str) -> Result<(), VmError> {
Ok(())
}
fn vm_restore(&mut self, _: RestoreConfig) -> Result<(), VmError> {
Ok(())
}
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
fn vm_coredump(&mut self, _: &str) -> Result<(), VmError> {
Ok(())
}
fn vm_shutdown(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_reboot(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_info(&self) -> Result<VmInfoResponse, VmError> {
Ok(VmInfoResponse {
config: Arc::new(Mutex::new(VmConfig {
cpus: CpusConfig {
boot_vcpus: 1,
max_vcpus: 1,
topology: None,
kvm_hyperv: false,
max_phys_bits: 46,
affinity: None,
features: CpuFeatures::default(),
},
memory: MemoryConfig {
size: 536_870_912,
mergeable: false,
hotplug_method: HotplugMethod::Acpi,
hotplug_size: None,
hotplugged_size: None,
shared: false,
hugepages: false,
hugepage_size: None,
prefault: false,
zones: None,
thp: true,
},
payload: Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
firmware: None,
cmdline: None,
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
}),
rate_limit_groups: None,
disks: None,
net: None,
rng: RngConfig {
src: PathBuf::from("/dev/urandom"),
iommu: false,
},
balloon: None,
fs: None,
pmem: None,
serial: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Null,
iommu: false,
socket: None,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
socket: None,
},
#[cfg(target_arch = "x86_64")]
debug_console: DebugConsoleConfig::default(),
devices: None,
user_devices: None,
vdpa: None,
vsock: None,
pvpanic: false,
iommu: false,
#[cfg(target_arch = "x86_64")]
sgx_epc: None,
numa: None,
watchdog: false,
#[cfg(feature = "guest_debug")]
gdb: false,
platform: None,
tpm: None,
preserved_fds: None,
})),
state: VmState::Running,
memory_actual_size: 0,
device_tree: None,
})
}
fn vmm_ping(&self) -> VmmPingResponse {
VmmPingResponse {
build_version: String::new(),
version: String::new(),
pid: 0,
features: Vec::new(),
}
}
fn vm_delete(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vmm_shutdown(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_resize(&mut self, _: Option<u8>, _: Option<u64>, _: Option<u64>) -> Result<(), VmError> {
Ok(())
}
fn vm_resize_zone(&mut self, _: String, _: u64) -> Result<(), VmError> {
Ok(())
}
fn vm_add_device(&mut self, _: DeviceConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_user_device(&mut self, _: UserDeviceConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_remove_device(&mut self, _: String) -> Result<(), VmError> {
Ok(())
}
fn vm_add_disk(&mut self, _: DiskConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_fs(&mut self, _: FsConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_pmem(&mut self, _: PmemConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_net(&mut self, _: NetConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_vdpa(&mut self, _: VdpaConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_add_vsock(&mut self, _: VsockConfig) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_counters(&mut self) -> Result<Option<Vec<u8>>, VmError> {
Ok(None)
}
fn vm_power_button(&mut self) -> Result<(), VmError> {
Ok(())
}
fn vm_receive_migration(&mut self, _: VmReceiveMigrationData) -> Result<(), MigratableError> {
Ok(())
}
fn vm_send_migration(&mut self, _: VmSendMigrationData) -> Result<(), MigratableError> {
Ok(())
}
}
fn http_receiver_stub(exit_evt: EventFd, api_evt: EventFd, api_receiver: Receiver<ApiRequest>) {
let mut epoll = EpollContext::new().unwrap();
epoll.add_event(&exit_evt, EpollDispatch::Exit).unwrap();
@@ -98,89 +304,7 @@ fn http_receiver_stub(exit_evt: EventFd, api_evt: EventFd, api_receiver: Receive
EpollDispatch::Api => {
for _ in 0..api_evt.read().unwrap() {
let api_request = api_receiver.recv().unwrap();
match api_request {
ApiRequest::VmCreate(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmDelete(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmBoot(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmShutdown(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmReboot(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmInfo(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmmPing(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmPause(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmResume(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmSnapshot(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmRestore(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmmShutdown(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmResize(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmResizeZone(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddDevice(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddUserDevice(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmRemoveDevice(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddDisk(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddFs(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddPmem(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddNet(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddVdpa(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmAddVsock(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmCounters(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmReceiveMigration(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmSendMigration(_, sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
ApiRequest::VmPowerButton(sender) => {
sender.send(Ok(ApiResponsePayload::Empty)).unwrap();
}
}
api_request(&mut StubApiRequestHandler).unwrap();
}
}
_ => {

View File

@@ -23,6 +23,8 @@ fuzz_target!(|bytes| {
kernel: None,
cmdline: Some(String::from_utf8_lossy(&bytes).to_string()),
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
};
let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) {
Ok(cmdline) => cmdline,

View File

@@ -12,22 +12,22 @@ sev_snp = ["igvm_parser", "igvm_defs"]
tdx = []
[dependencies]
anyhow = "1.0.75"
anyhow = "1.0.79"
byteorder = "1.4.3"
igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm_defs", optional = true }
igvm_parser = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm", optional = true }
libc = "0.2.147"
log = "0.4.17"
kvm-ioctls = { version = "0.13.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.6.0-tdx", features = ["with-serde", "fam-wrappers"], optional = true }
igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main", package = "igvm_defs", optional = true }
igvm_parser = { git = "https://github.com/microsoft/igvm", branch = "main", package = "igvm", optional = true }
libc = "0.2.153"
log = "0.4.20"
kvm-ioctls = { version = "0.16.0", optional = true }
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch-v0.7.0", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-bindings = { git = "https://github.com/rust-vmm/mshv", branch = "main", features = ["with-serde", "fam-wrappers"], optional = true }
mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", branch = "main", optional = true}
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde = { version = "1.0.196", features = ["rc", "derive"] }
serde_with = { version = "3.4.0", default-features = false, features = ["macros"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
thiserror = "1.0.40"
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
thiserror = "1.0.52"
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]
optional = true
@@ -36,4 +36,4 @@ default-features = false
features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"]
[dev-dependencies]
env_logger = "0.10.0"
env_logger = "0.10.1"

View File

@@ -311,3 +311,17 @@ pub struct MsrEntry {
pub index: u32,
pub data: u64,
}
#[serde_with::serde_as]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct XsaveState {
#[serde_as(as = "[_; 1024usize]")]
pub region: [u32; 1024usize],
}
impl Default for XsaveState {
fn default() -> Self {
// SAFETY: this is plain old data structure
unsafe { ::std::mem::zeroed() }
}
}

View File

@@ -95,12 +95,12 @@ pub enum HypervisorCpuError {
#[error("Failed to get Msr entries: {0}")]
GetMsrEntries(#[source] anyhow::Error),
///
/// Setting MSR entries error
/// Setting multi-processing state error
///
#[error("Failed to set MP state: {0}")]
SetMpState(#[source] anyhow::Error),
///
/// Getting Msr entries error
/// Getting multi-processing state error
///
#[error("Failed to get MP state: {0}")]
GetMpState(#[source] anyhow::Error),
@@ -267,6 +267,17 @@ pub enum HypervisorCpuError {
///
#[error("Failed to write to GPA: {0}")]
GpaWrite(#[source] anyhow::Error),
///
/// Error getting CPUID leaf
///
#[error("Failed to get CPUID entries: {0}")]
GetCpuidVales(#[source] anyhow::Error),
///
/// Setting SEV control register error
///
#[cfg(feature = "sev_snp")]
#[error("Failed to set sev control register: {0}")]
SetSevControlRegister(#[source] anyhow::Error),
}
#[derive(Debug)]
@@ -477,4 +488,21 @@ pub trait Vcpu: Send + Sync {
fn set_tsc_khz(&self, _freq: u32) -> Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve cpuid leaf
///
fn get_cpuid_values(
&self,
_function: u32,
_index: u32,
_xfem: u64,
_xss: u64,
) -> Result<[u32; 4]> {
unimplemented!()
}
#[cfg(feature = "mshv")]
fn set_sev_control_register(&self, _reg: u64) -> Result<()> {
unimplemented!()
}
}

View File

@@ -47,7 +47,7 @@ use vmm_sys_util::eventfd::EventFd;
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
use crate::arch::x86::{
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters,
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, XsaveState,
NUM_IOAPIC_PINS,
};
#[cfg(target_arch = "x86_64")]
@@ -66,13 +66,11 @@ use kvm_bindings::{
#[cfg(target_arch = "x86_64")]
use x86_64::check_required_kvm_extensions;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{CpuId, ExtendedControlRegisters, MsrEntries, VcpuKvmState, Xsave};
pub use x86_64::{CpuId, ExtendedControlRegisters, MsrEntries, VcpuKvmState};
// aarch64 dependencies
#[cfg(target_arch = "aarch64")]
pub mod aarch64;
pub use kvm_bindings;
#[cfg(feature = "tdx")]
use kvm_bindings::KVMIO;
pub use kvm_bindings::{
kvm_clock_data, kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO, kvm_guest_debug,
kvm_irq_routing, kvm_irq_routing_entry, kvm_mp_state, kvm_userspace_memory_region,
@@ -86,6 +84,8 @@ use kvm_bindings::{
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK,
KVM_REG_ARM_CORE, KVM_REG_SIZE_U128, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
};
#[cfg(feature = "tdx")]
use kvm_bindings::{kvm_run__bindgen_ty_1, KVMIO};
pub use kvm_ioctls;
pub use kvm_ioctls::{Cap, Kvm};
#[cfg(target_arch = "aarch64")]
@@ -169,6 +169,52 @@ pub struct TdxCapabilities {
pub cpuid_configs: [TdxCpuidConfig; TDX_MAX_NR_CPUID_CONFIGS],
}
#[cfg(feature = "tdx")]
#[derive(Copy, Clone)]
pub struct KvmTdxExit {
pub type_: u32,
pub pad: u32,
pub u: KvmTdxExitU,
}
#[cfg(feature = "tdx")]
#[repr(C)]
#[derive(Copy, Clone)]
pub union KvmTdxExitU {
pub vmcall: KvmTdxExitVmcall,
}
#[cfg(feature = "tdx")]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct KvmTdxExitVmcall {
pub type_: u64,
pub subfunction: u64,
pub reg_mask: u64,
pub in_r12: u64,
pub in_r13: u64,
pub in_r14: u64,
pub in_r15: u64,
pub in_rbx: u64,
pub in_rdi: u64,
pub in_rsi: u64,
pub in_r8: u64,
pub in_r9: u64,
pub in_rdx: u64,
pub status_code: u64,
pub out_r11: u64,
pub out_r12: u64,
pub out_r13: u64,
pub out_r14: u64,
pub out_r15: u64,
pub out_rbx: u64,
pub out_rdi: u64,
pub out_rsi: u64,
pub out_r8: u64,
pub out_r9: u64,
pub out_rdx: u64,
}
impl From<kvm_userspace_memory_region> for UserMemoryRegion {
fn from(region: kvm_userspace_memory_region) -> Self {
let mut flags = USER_MEMORY_REGION_READ;
@@ -356,6 +402,7 @@ impl vm::Vm for KvmVm {
.set_identity_map_address(address)
.map_err(|e| vm::HypervisorVmError::SetIdentityMapAddress(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the three-page region in the VM's address space.
@@ -365,6 +412,7 @@ impl vm::Vm for KvmVm {
.set_tss_address(offset)
.map_err(|e| vm::HypervisorVmError::SetTssAddress(e.into()))
}
///
/// Creates an in-kernel interrupt controller.
///
@@ -373,6 +421,7 @@ impl vm::Vm for KvmVm {
.create_irq_chip()
.map_err(|e| vm::HypervisorVmError::CreateIrq(e.into()))
}
///
/// Registers an event that will, when signaled, trigger the `gsi` IRQ.
///
@@ -381,6 +430,7 @@ impl vm::Vm for KvmVm {
.register_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::RegisterIrqFd(e.into()))
}
///
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
///
@@ -389,6 +439,7 @@ impl vm::Vm for KvmVm {
.unregister_irqfd(fd, gsi)
.map_err(|e| vm::HypervisorVmError::UnregisterIrqFd(e.into()))
}
///
/// Creates a VcpuFd object from a vcpu RawFd.
///
@@ -411,6 +462,7 @@ impl vm::Vm for KvmVm {
};
Ok(Arc::new(vcpu))
}
#[cfg(target_arch = "aarch64")]
///
/// Creates a virtual GIC device.
@@ -420,6 +472,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::CreateVgic(anyhow!("Vgic error {:?}", e)))?;
Ok(Arc::new(Mutex::new(gic_device)))
}
///
/// Registers an event to be signaled whenever a certain address is written to.
///
@@ -447,6 +500,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into()))
}
}
///
/// Unregisters an event from a certain address it has been previously registered to.
///
@@ -541,6 +595,7 @@ impl vm::Vm for KvmVm {
.set_gsi_routing(&irq_routing[0])
.map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into()))
}
///
/// Creates a memory region structure that can be used with {create/remove}_user_memory_region
///
@@ -567,6 +622,7 @@ impl vm::Vm for KvmVm {
}
.into()
}
///
/// Creates a guest physical memory region.
///
@@ -603,6 +659,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::CreateUserMemory(e.into()))
}
}
///
/// Removes a guest physical memory region.
///
@@ -621,6 +678,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::RemoveUserMemory(e.into()))
}
}
///
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
///
@@ -630,6 +688,7 @@ impl vm::Vm for KvmVm {
.get_preferred_target(kvi)
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))
}
#[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> vm::Result<()> {
// Create split irqchip
@@ -645,6 +704,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::EnableSplitIrq(e.into()))?;
Ok(())
}
#[cfg(target_arch = "x86_64")]
fn enable_sgx_attribute(&self, file: File) -> vm::Result<()> {
let mut cap = kvm_enable_cap {
@@ -657,6 +717,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::EnableSgxAttribute(e.into()))?;
Ok(())
}
/// Retrieve guest clock.
#[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> vm::Result<ClockData> {
@@ -666,6 +727,7 @@ impl vm::Vm for KvmVm {
.map_err(|e| vm::HypervisorVmError::GetClock(e.into()))?
.into())
}
/// Set guest clock.
#[cfg(target_arch = "x86_64")]
fn set_clock(&self, data: &ClockData) -> vm::Result<()> {
@@ -674,6 +736,7 @@ impl vm::Vm for KvmVm {
.set_clock(&data)
.map_err(|e| vm::HypervisorVmError::SetClock(e.into()))
}
/// Create a device that is used for passthrough
fn create_passthrough_device(&self) -> vm::Result<VfioDeviceFd> {
let mut vfio_dev = kvm_create_device {
@@ -685,6 +748,7 @@ impl vm::Vm for KvmVm {
self.create_device(&mut vfio_dev)
.map_err(|e| vm::HypervisorVmError::CreatePassthroughDevice(e.into()))
}
///
/// Start logging dirty pages
///
@@ -826,6 +890,7 @@ impl vm::Vm for KvmVm {
)
.map_err(vm::HypervisorVmError::InitMemRegionTdx)
}
/// Downcast to the underlying KvmVm type
fn as_any(&self) -> &dyn Any {
self
@@ -892,7 +957,9 @@ pub enum KvmError {
#[error("Capability missing: {0:?}")]
CapabilityMissing(Cap),
}
pub type KvmResult<T> = result::Result<T, KvmError>;
impl KvmHypervisor {
/// Create a hypervisor based on Kvm
#[allow(clippy::new_ret_no_self)]
@@ -906,6 +973,7 @@ impl KvmHypervisor {
Ok(Arc::new(KvmHypervisor { kvm: kvm_obj }))
}
/// Check if the hypervisor is available
pub fn is_available() -> hypervisor::Result<bool> {
match std::fs::metadata("/dev/kvm") {
@@ -917,6 +985,7 @@ impl KvmHypervisor {
}
}
}
/// Implementation of Hypervisor trait for KVM
///
/// # Examples
@@ -935,6 +1004,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
fn hypervisor_type(&self) -> HypervisorType {
HypervisorType::Kvm
}
/// Create a KVM vm object of a specific VM type and return the object as Vm trait object
///
/// # Examples
@@ -1090,6 +1160,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
self.kvm.get_max_vcpus().min(u32::MAX as usize) as u32
}
}
/// Vcpu struct for KVM
pub struct KvmVcpu {
fd: VcpuFd,
@@ -1099,6 +1170,7 @@ pub struct KvmVcpu {
#[cfg(target_arch = "x86_64")]
hyperv_synic: AtomicBool,
}
/// Implementation of Vcpu trait for KVM
///
/// # Examples
@@ -1123,6 +1195,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))?
.into())
}
///
/// Returns the vCPU general purpose registers.
/// The `KVM_GET_REGS` ioctl is not available on AArch64, `KVM_GET_ONE_REG`
@@ -1137,71 +1210,64 @@ impl cpu::Vcpu for KvmVcpu {
// These actually are the general-purpose registers of the Armv8-a
// architecture (i.e x0-x30 if used as a 64bit register or w0-30 when used as a 32bit register).
for i in 0..31 {
state.regs.regs[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.regs.regs[i] = u64::from_le_bytes(bytes);
off += std::mem::size_of::<u64>();
}
// We are now entering the "Other register" section of the ARMv8-a architecture.
// First one, stack pointer.
let off = offset_of!(user_pt_regs, sp);
state.regs.sp = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.regs.sp = u64::from_le_bytes(bytes);
// Second one, the program counter.
let off = offset_of!(user_pt_regs, pc);
state.regs.pc = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.regs.pc = u64::from_le_bytes(bytes);
// Next is the processor state.
let off = offset_of!(user_pt_regs, pstate);
state.regs.pstate = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.regs.pstate = u64::from_le_bytes(bytes);
// The stack pointer associated with EL1
let off = offset_of!(kvm_regs, sp_el1);
state.sp_el1 = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.sp_el1 = u64::from_le_bytes(bytes);
// Exception Link Register for EL1, when taking an exception to EL1, this register
// holds the address to which to return afterwards.
let off = offset_of!(kvm_regs, elr_el1);
state.elr_el1 = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.elr_el1 = u64::from_le_bytes(bytes);
// Saved Program Status Registers, there are 5 of them used in the kernel.
let mut off = offset_of!(kvm_regs, spsr);
for i in 0..KVM_NR_SPSR as usize {
state.spsr[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.spsr[i] = u64::from_le_bytes(bytes);
off += std::mem::size_of::<u64>();
}
@@ -1209,32 +1275,32 @@ impl cpu::Vcpu for KvmVcpu {
// https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
let mut off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, vregs);
for i in 0..32 {
state.fp_regs.vregs[i] = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U128, off))
let mut bytes = [0_u8; 16];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U128, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.fp_regs.vregs[i] = u128::from_le_bytes(bytes);
off += mem::size_of::<u128>();
}
// Floating-point Status Register
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpsr);
state.fp_regs.fpsr = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 4];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.fp_regs.fpsr = u32::from_le_bytes(bytes);
// Floating-point Control Register
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpcr);
state.fp_regs.fpcr = self
.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off))
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?
.try_into()
.unwrap();
let mut bytes = [0_u8; 4];
self.fd
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?;
state.fp_regs.fpcr = u32::from_le_bytes(bytes);
Ok(state)
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU general purpose registers using the `KVM_SET_REGS` ioctl.
@@ -1260,7 +1326,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.regs[i].into(),
&state.regs.regs[i].to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += std::mem::size_of::<u64>();
@@ -1270,7 +1336,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.sp.into(),
&state.regs.sp.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1278,7 +1344,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.pc.into(),
&state.regs.pc.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1286,7 +1352,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.regs.pstate.into(),
&state.regs.pstate.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1294,7 +1360,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.sp_el1.into(),
&state.sp_el1.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1302,7 +1368,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.elr_el1.into(),
&state.elr_el1.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1311,7 +1377,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, off),
state.spsr[i].into(),
&state.spsr[i].to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += std::mem::size_of::<u64>();
@@ -1322,7 +1388,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U128, off),
state.fp_regs.vregs[i],
&state.fp_regs.vregs[i].to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
off += mem::size_of::<u128>();
@@ -1332,7 +1398,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
state.fp_regs.fpsr.into(),
&state.fp_regs.fpsr.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1340,7 +1406,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
state.fp_regs.fpcr.into(),
&state.fp_regs.fpcr.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
Ok(())
@@ -1357,6 +1423,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU special registers using the `KVM_SET_SREGS` ioctl.
@@ -1367,6 +1434,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_sregs(&sregs)
.map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the floating point state (FPU) from the vCPU.
@@ -1378,6 +1446,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct.
@@ -1388,6 +1457,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_fpu(&fpu)
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to setup the CPUID registers.
@@ -1402,6 +1472,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_cpuid2(&kvm_cpuid)
.map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to enable HyperV SynIC
@@ -1419,6 +1490,7 @@ impl cpu::Vcpu for KvmVcpu {
.enable_cap(&cap)
.map_err(|e| cpu::HypervisorCpuError::EnableHyperVSyncIc(e.into()))
}
///
/// X86 specific call to retrieve the CPUID registers.
///
@@ -1433,6 +1505,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(v)
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1444,6 +1517,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1454,6 +1528,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_lapic(&klapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the model-specific registers (MSR) for this vCPU.
@@ -1475,6 +1550,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(succ)
}
#[cfg(target_arch = "x86_64")]
///
/// Setup the model-specific registers (MSR) for this vCPU.
@@ -1487,6 +1563,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_msrs(&kvm_msrs)
.map_err(|e| cpu::HypervisorCpuError::SetMsrEntries(e.into()))
}
///
/// Returns the vcpu's current "multiprocessing state".
///
@@ -1497,6 +1574,7 @@ impl cpu::Vcpu for KvmVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetMpState(e.into()))?
.into())
}
///
/// Sets the vcpu's current "multiprocessing state".
///
@@ -1505,6 +1583,7 @@ impl cpu::Vcpu for KvmVcpu {
.set_mp_state(mp_state.into())
.map_err(|e| cpu::HypervisorCpuError::SetMpState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Translates guest virtual address to guest physical address using the `KVM_TRANSLATE` ioctl.
@@ -1523,6 +1602,7 @@ impl cpu::Vcpu for KvmVcpu {
_ => Ok((tr.physical_address, 0)),
}
}
///
/// Triggers the running of the current virtual CPU returning an exit reason.
///
@@ -1567,7 +1647,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(cpu::VmExit::Shutdown)
} else {
Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unexpected system event with type 0x{:x}, flags 0x{:x}",
"Unexpected system event with type 0x{:x}, flags 0x{:x?}",
event_type,
flags
)))
@@ -1614,6 +1694,7 @@ impl cpu::Vcpu for KvmVcpu {
},
}
}
#[cfg(target_arch = "x86_64")]
///
/// Let the guest know that it has been paused, which prevents from
@@ -1631,6 +1712,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(())
}
///
/// Sets debug registers to set hardware breakpoints and/or enable single step.
///
@@ -1684,12 +1766,14 @@ impl cpu::Vcpu for KvmVcpu {
.set_guest_debug(&dbg)
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))
}
#[cfg(target_arch = "aarch64")]
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
self.fd
.vcpu_init(kvi)
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
}
///
/// Gets a list of the guest registers that are supported for the
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
@@ -1700,6 +1784,7 @@ impl cpu::Vcpu for KvmVcpu {
.get_reg_list(reg_list)
.map_err(|e| cpu::HypervisorCpuError::GetRegList(e.into()))
}
///
/// Gets the value of a system register
///
@@ -1726,13 +1811,13 @@ impl cpu::Vcpu for KvmVcpu {
| KVM_REG_ARM64_SYSREG_CRN_MASK
| KVM_REG_ARM64_SYSREG_CRM_MASK
| KVM_REG_ARM64_SYSREG_OP2_MASK)) as u64);
Ok(self
.fd
.get_one_reg(id)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?
.try_into()
.unwrap())
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(id, &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?;
Ok(u64::from_le_bytes(bytes))
}
///
/// Configure core registers for a given CPU.
///
@@ -1757,7 +1842,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate),
PSTATE_FAULT_BITS_64.into(),
&PSTATE_FAULT_BITS_64.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
@@ -1766,7 +1851,10 @@ impl cpu::Vcpu for KvmVcpu {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset_of!(user_pt_regs, pc) + kreg_off;
self.fd
.set_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), boot_ip.into())
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, pc),
&boot_ip.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
// Last mandatory thing to set -> the address pointing to the FDT (also called DTB).
@@ -1777,7 +1865,7 @@ impl cpu::Vcpu for KvmVcpu {
self.fd
.set_one_reg(
arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0),
fdt_start.into(),
&fdt_start.to_le_bytes(),
)
.map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?;
}
@@ -1907,6 +1995,7 @@ impl cpu::Vcpu for KvmVcpu {
}
.into())
}
///
/// Get the current AArch64 CPU state
///
@@ -1941,14 +2030,13 @@ impl cpu::Vcpu for KvmVcpu {
// register list, we are simply calling KVM_GET_ONE_REG.
let indices = reg_list.as_slice();
for index in indices.iter() {
let mut bytes = [0_u8; 8];
self.fd
.get_one_reg(*index, &mut bytes)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?;
sys_regs.push(kvm_bindings::kvm_one_reg {
id: *index,
addr: self
.fd
.get_one_reg(*index)
.map_err(|e| cpu::HypervisorCpuError::GetSysRegister(e.into()))?
.try_into()
.unwrap(),
addr: u64::from_le_bytes(bytes),
});
}
@@ -1956,6 +2044,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(state.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Restore the previously saved CPU state
@@ -2045,6 +2134,7 @@ impl cpu::Vcpu for KvmVcpu {
Ok(())
}
///
/// Restore the previously saved AArch64 CPU state
///
@@ -2056,7 +2146,7 @@ impl cpu::Vcpu for KvmVcpu {
// Set system registers
for reg in &state.sys_regs {
self.fd
.set_one_reg(reg.id, reg.addr.into())
.set_one_reg(reg.id, &reg.addr.to_le_bytes())
.map_err(|e| cpu::HypervisorCpuError::SetSysRegister(e.into()))?;
}
@@ -2088,7 +2178,12 @@ impl cpu::Vcpu for KvmVcpu {
fn get_tdx_exit_details(&mut self) -> cpu::Result<TdxExitDetails> {
let kvm_run = self.fd.get_kvm_run();
// SAFETY: accessing a union field in a valid structure
let tdx_vmcall = unsafe { &mut kvm_run.__bindgen_anon_1.tdx.u.vmcall };
let tdx_vmcall = unsafe {
&mut (*((&mut kvm_run.__bindgen_anon_1) as *mut kvm_run__bindgen_ty_1
as *mut KvmTdxExit))
.u
.vmcall
};
tdx_vmcall.status_code = TDG_VP_VMCALL_INVALID_OPERAND;
@@ -2112,13 +2207,19 @@ impl cpu::Vcpu for KvmVcpu {
fn set_tdx_status(&mut self, status: TdxExitStatus) {
let kvm_run = self.fd.get_kvm_run();
// SAFETY: accessing a union field in a valid structure
let tdx_vmcall = unsafe { &mut kvm_run.__bindgen_anon_1.tdx.u.vmcall };
let tdx_vmcall = unsafe {
&mut (*((&mut kvm_run.__bindgen_anon_1) as *mut kvm_run__bindgen_ty_1
as *mut KvmTdxExit))
.u
.vmcall
};
tdx_vmcall.status_code = match status {
TdxExitStatus::Success => TDG_VP_VMCALL_SUCCESS,
TdxExitStatus::InvalidOperand => TDG_VP_VMCALL_INVALID_OPERAND,
};
}
#[cfg(target_arch = "x86_64")]
///
/// Return the list of initial MSR entries for a VCPU
@@ -2144,6 +2245,7 @@ impl cpu::Vcpu for KvmVcpu {
]
.to_vec()
}
#[cfg(target_arch = "aarch64")]
fn has_pmu_support(&self) -> bool {
let cpu_attr = kvm_bindings::kvm_device_attr {
@@ -2154,6 +2256,7 @@ impl cpu::Vcpu for KvmVcpu {
};
self.fd.has_device_attr(&cpu_attr).is_ok()
}
#[cfg(target_arch = "aarch64")]
fn init_pmu(&self, irq: u32) -> cpu::Result<()> {
let cpu_attr = kvm_bindings::kvm_device_attr {
@@ -2216,20 +2319,25 @@ impl KvmVcpu {
///
/// X86 specific call that returns the vcpu's current "xsave struct".
///
fn get_xsave(&self) -> cpu::Result<Xsave> {
self.fd
fn get_xsave(&self) -> cpu::Result<XsaveState> {
Ok(self
.fd
.get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xsave struct".
///
fn set_xsave(&self, xsave: &Xsave) -> cpu::Result<()> {
fn set_xsave(&self, xsave: &XsaveState) -> cpu::Result<()> {
let xsave: kvm_bindings::kvm_xsave = (*xsave).clone().into();
self.fd
.set_xsave(xsave)
.set_xsave(&xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xcrs".
@@ -2239,6 +2347,7 @@ impl KvmVcpu {
.get_xcrs()
.map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xcrs".
@@ -2248,6 +2357,7 @@ impl KvmVcpu {
.set_xcrs(xcrs)
.map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related
@@ -2258,6 +2368,7 @@ impl KvmVcpu {
.get_vcpu_events()
.map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets pending exceptions, interrupts, and NMIs as well as related states

View File

@@ -10,7 +10,7 @@
use crate::arch::x86::{
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
StandardRegisters, CPUID_FLAG_VALID_INDEX,
StandardRegisters, XsaveState, CPUID_FLAG_VALID_INDEX,
};
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
use serde::{Deserialize, Serialize};
@@ -23,7 +23,7 @@ pub use {
kvm_bindings::kvm_lapic_state, kvm_bindings::kvm_mp_state as MpState,
kvm_bindings::kvm_msr_entry, kvm_bindings::kvm_regs, kvm_bindings::kvm_segment,
kvm_bindings::kvm_sregs, kvm_bindings::kvm_vcpu_events as VcpuEvents,
kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave as Xsave,
kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave,
kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries,
kvm_bindings::KVM_CPUID_FLAG_SIGNIFCANT_INDEX,
};
@@ -64,7 +64,7 @@ pub struct VcpuKvmState {
pub sregs: kvm_sregs,
pub fpu: FpuState,
pub lapic_state: LapicState,
pub xsave: Xsave,
pub xsave: XsaveState,
pub xcrs: ExtendedControlRegisters,
pub mp_state: MpState,
pub tsc_khz: Option<u32>,
@@ -330,3 +330,18 @@ impl From<MsrEntry> for kvm_msr_entry {
}
}
}
impl From<kvm_xsave> for XsaveState {
fn from(s: kvm_xsave) -> Self {
Self { region: s.region }
}
}
impl From<XsaveState> for kvm_xsave {
fn from(s: XsaveState) -> Self {
Self {
region: s.region,
extra: Default::default(),
}
}
}

View File

@@ -134,6 +134,7 @@ pub const USER_MEMORY_REGION_READ: u32 = 1;
pub const USER_MEMORY_REGION_WRITE: u32 = 1 << 1;
pub const USER_MEMORY_REGION_EXECUTE: u32 = 1 << 2;
pub const USER_MEMORY_REGION_LOG_DIRTY: u32 = 1 << 3;
pub const USER_MEMORY_REGION_ADJUSTABLE: u32 = 1 << 4;
#[derive(Debug)]
pub enum MpState {

View File

@@ -31,7 +31,8 @@ use snp_constants::*;
use crate::{
ClockData, CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
USER_MEMORY_REGION_ADJUSTABLE, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ,
USER_MEMORY_REGION_WRITE,
};
#[cfg(feature = "sev_snp")]
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
@@ -73,6 +74,9 @@ impl From<mshv_user_mem_region> for UserMemoryRegion {
if region.flags & HV_MAP_GPA_EXECUTABLE != 0 {
flags |= USER_MEMORY_REGION_EXECUTE;
}
if region.flags & HV_MAP_GPA_ADJUSTABLE != 0 {
flags |= USER_MEMORY_REGION_ADJUSTABLE;
}
UserMemoryRegion {
guest_phys_addr: (region.guest_pfn << PAGE_SHIFT as u64)
@@ -97,6 +101,9 @@ impl From<UserMemoryRegion> for mshv_user_mem_region {
if region.flags & USER_MEMORY_REGION_EXECUTE != 0 {
flags |= HV_MAP_GPA_EXECUTABLE;
}
if region.flags & USER_MEMORY_REGION_ADJUSTABLE != 0 {
flags |= HV_MAP_GPA_ADJUSTABLE;
}
mshv_user_mem_region {
guest_pfn: region.guest_phys_addr >> PAGE_SHIFT,
@@ -200,6 +207,7 @@ impl MshvHypervisor {
}
}
}
/// Implementation of Hypervisor trait for Mshv
///
/// # Examples
@@ -298,6 +306,8 @@ impl hypervisor::Hypervisor for MshvHypervisor {
fd: vm_fd,
msrs,
dirty_log_slots: Arc::new(RwLock::new(HashMap::new())),
#[cfg(feature = "sev_snp")]
sev_snp_enabled: mshv_vm_type == VmType::Snp,
}))
}
@@ -338,6 +348,8 @@ pub struct MshvVcpu {
cpuid: Vec<CpuIdEntry>,
msrs: Vec<MsrEntry>,
vm_ops: Option<Arc<dyn vm::VmOps>>,
#[cfg(feature = "sev_snp")]
vm_fd: Arc<VmFd>,
}
/// Implementation of Vcpu trait for Microsoft Hypervisor
@@ -364,6 +376,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetStandardRegs(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU general purpose registers.
@@ -374,6 +387,7 @@ impl cpu::Vcpu for MshvVcpu {
.set_regs(&regs)
.map_err(|e| cpu::HypervisorCpuError::SetStandardRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the vCPU special registers.
@@ -385,6 +399,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetSpecialRegs(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the vCPU special registers.
@@ -395,6 +410,7 @@ impl cpu::Vcpu for MshvVcpu {
.set_sregs(&sregs)
.map_err(|e| cpu::HypervisorCpuError::SetSpecialRegs(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the floating point state (FPU) from the vCPU.
@@ -406,6 +422,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Set the floating point state (FPU) of a vCPU.
@@ -438,6 +455,7 @@ impl cpu::Vcpu for MshvVcpu {
Ok(succ)
}
#[cfg(target_arch = "x86_64")]
///
/// Setup the model-specific registers (MSR) for this vCPU.
@@ -459,6 +477,7 @@ impl cpu::Vcpu for MshvVcpu {
/* We always have SynIC enabled on MSHV */
Ok(())
}
#[allow(non_upper_case_globals)]
fn run(&self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
let hv_message: hv_message = hv_message::default();
@@ -587,6 +606,17 @@ impl cpu::Vcpu for MshvVcpu {
Ok(cpu::VmExit::Ignore)
}
hv_message_type_HVMSG_UNACCEPTED_GPA => {
let info = x.to_memory_info().unwrap();
let gva = info.guest_virtual_address;
let gpa = info.guest_physical_address;
Err(cpu::HypervisorCpuError::RunVcpu(anyhow!(
"Unhandled VCPU exit: Unaccepted GPA({:x}) found at GVA({:x})",
gpa,
gva,
)))
}
hv_message_type_HVMSG_X64_CPUID_INTERCEPT => {
let info = x.to_cpuid_info().unwrap();
debug!("cpuid eax: {:x}", { info.rax });
@@ -976,6 +1006,59 @@ impl cpu::Vcpu for MshvVcpu {
})?;
}
}
SVM_EXITCODE_SNP_GUEST_REQUEST => {
let req_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let rsp_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2;
let mshv_psp_req =
mshv_issue_psp_guest_request { req_gpa, rsp_gpa };
self.vm_fd
.psp_issue_guest_request(&mshv_psp_req)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
debug!(
"SNP guest request: req_gpa {:0x} rsp_gpa {:0x}",
req_gpa, rsp_gpa
);
let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_write(&mut swei2_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
SVM_EXITCODE_SNP_AP_CREATION => {
let vmsa_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2;
let apic_id =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 >> 32;
debug!(
"SNP AP CREATE REQUEST with VMSA GPA {:0x}, and APIC ID {:?}",
vmsa_gpa, apic_id
);
let mshv_ap_create_req = mshv_sev_snp_ap_create {
vp_id: apic_id,
vmsa_gpa,
};
self.vm_fd
.sev_snp_ap_create(&mshv_ap_create_req)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
byte_count: std::mem::size_of::<u64>() as u32,
..Default::default()
};
self.fd
.gpa_write(&mut swei2_rw_gpa_arg)
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
}
_ => panic!(
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
exit_code
@@ -1002,6 +1085,7 @@ impl cpu::Vcpu for MshvVcpu {
},
}
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to setup the CPUID registers.
@@ -1015,6 +1099,7 @@ impl cpu::Vcpu for MshvVcpu {
.register_intercept_result_cpuid(&mshv_cpuid)
.map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve the CPUID registers.
@@ -1022,6 +1107,23 @@ impl cpu::Vcpu for MshvVcpu {
fn get_cpuid2(&self, _num_entries: usize) -> cpu::Result<Vec<CpuIdEntry>> {
Ok(self.cpuid.clone())
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call to retrieve cpuid leaf
///
fn get_cpuid_values(
&self,
function: u32,
index: u32,
xfem: u64,
xss: u64,
) -> cpu::Result<[u32; 4]> {
self.fd
.get_cpuid_values(function, index, xfem, xss)
.map_err(|e| cpu::HypervisorCpuError::GetCpuidVales(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1033,6 +1135,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::GetlapicState(e.into()))?
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
@@ -1043,18 +1146,21 @@ impl cpu::Vcpu for MshvVcpu {
.set_lapic(&lapic)
.map_err(|e| cpu::HypervisorCpuError::SetLapicState(e.into()))
}
///
/// Returns the vcpu's current "multiprocessing state".
///
fn get_mp_state(&self) -> cpu::Result<MpState> {
Ok(MpState::Mshv)
}
///
/// Sets the vcpu's current "multiprocessing state".
///
fn set_mp_state(&self, _mp_state: MpState) -> cpu::Result<()> {
Ok(())
}
///
/// Set CPU state
///
@@ -1080,6 +1186,7 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::SetDebugRegs(e.into()))?;
Ok(())
}
///
/// Get CPU State
///
@@ -1116,6 +1223,7 @@ impl cpu::Vcpu for MshvVcpu {
}
.into())
}
#[cfg(target_arch = "x86_64")]
///
/// Translate guest virtual address to guest physical address
@@ -1132,6 +1240,7 @@ impl cpu::Vcpu for MshvVcpu {
Ok((gpa, result_code))
}
#[cfg(target_arch = "x86_64")]
///
/// Return the list of initial MSR entries for a VCPU
@@ -1152,6 +1261,18 @@ impl cpu::Vcpu for MshvVcpu {
]
.to_vec()
}
///
/// Sets the AMD specific vcpu's sev control register.
///
#[cfg(feature = "sev_snp")]
fn set_sev_control_register(&self, vmsa_pfn: u64) -> cpu::Result<()> {
let sev_control_reg = snp::get_sev_control_register(vmsa_pfn);
self.fd
.set_sev_control_register(sev_control_reg)
.map_err(|e| cpu::HypervisorCpuError::SetSevControlRegister(e.into()))
}
}
impl MshvVcpu {
@@ -1164,6 +1285,7 @@ impl MshvVcpu {
.get_xsave()
.map_err(|e| cpu::HypervisorCpuError::GetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xsave struct".
@@ -1173,6 +1295,7 @@ impl MshvVcpu {
.set_xsave(xsave)
.map_err(|e| cpu::HypervisorCpuError::SetXsaveState(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that returns the vcpu's current "xcrs".
@@ -1182,6 +1305,7 @@ impl MshvVcpu {
.get_xcrs()
.map_err(|e| cpu::HypervisorCpuError::GetXcsr(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// X86 specific call that sets the vcpu's current "xcrs".
@@ -1191,6 +1315,7 @@ impl MshvVcpu {
.set_xcrs(xcrs)
.map_err(|e| cpu::HypervisorCpuError::SetXcsr(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Returns currently pending exceptions, interrupts, and NMIs as well as related
@@ -1201,6 +1326,7 @@ impl MshvVcpu {
.get_vcpu_events()
.map_err(|e| cpu::HypervisorCpuError::GetVcpuEvents(e.into()))
}
#[cfg(target_arch = "x86_64")]
///
/// Sets pending exceptions, interrupts, and NMIs as well as related states
@@ -1343,6 +1469,8 @@ pub struct MshvVm {
fd: Arc<VmFd>,
msrs: Vec<MsrEntry>,
dirty_log_slots: Arc<RwLock<HashMap<u64, MshvDirtyLogSlot>>>,
#[cfg(feature = "sev_snp")]
sev_snp_enabled: bool,
}
impl MshvVm {
@@ -1380,6 +1508,7 @@ impl vm::Vm for MshvVm {
fn set_identity_map_address(&self, _address: u64) -> vm::Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
///
/// Sets the address of the three-page region in the VM's address space.
@@ -1387,12 +1516,14 @@ impl vm::Vm for MshvVm {
fn set_tss_address(&self, _offset: usize) -> vm::Result<()> {
Ok(())
}
///
/// Creates an in-kernel interrupt controller.
///
fn create_irq_chip(&self) -> vm::Result<()> {
Ok(())
}
///
/// Registers an event that will, when signaled, trigger the `gsi` IRQ.
///
@@ -1405,6 +1536,7 @@ impl vm::Vm for MshvVm {
Ok(())
}
///
/// Unregisters an event that will, when signaled, trigger the `gsi` IRQ.
///
@@ -1417,6 +1549,7 @@ impl vm::Vm for MshvVm {
Ok(())
}
///
/// Creates a VcpuFd object from a vcpu RawFd.
///
@@ -1435,23 +1568,33 @@ impl vm::Vm for MshvVm {
cpuid: Vec::new(),
msrs: self.msrs.clone(),
vm_ops,
#[cfg(feature = "sev_snp")]
vm_fd: self.fd.clone(),
};
Ok(Arc::new(vcpu))
}
#[cfg(target_arch = "x86_64")]
fn enable_split_irq(&self) -> vm::Result<()> {
Ok(())
}
#[cfg(target_arch = "x86_64")]
fn enable_sgx_attribute(&self, _file: File) -> vm::Result<()> {
Ok(())
}
fn register_ioevent(
&self,
fd: &EventFd,
addr: &IoEventAddress,
datamatch: Option<DataMatch>,
) -> vm::Result<()> {
#[cfg(feature = "sev_snp")]
if self.sev_snp_enabled {
return Ok(());
}
let addr = &mshv_ioctls::IoEventAddress::from(*addr);
debug!(
"register_ioevent fd {} addr {:x?} datamatch {:?}",
@@ -1476,6 +1619,7 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into()))
}
}
/// Unregister an event from a certain address it has been previously registered to.
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> {
let addr = &mshv_ioctls::IoEventAddress::from(*addr);
@@ -1530,7 +1674,7 @@ impl vm::Vm for MshvVm {
readonly: bool,
_log_dirty_pages: bool,
) -> UserMemoryRegion {
let mut flags = HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE;
let mut flags = HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_ADJUSTABLE;
if !readonly {
flags |= HV_MAP_GPA_WRITABLE;
}
@@ -1600,6 +1744,7 @@ impl vm::Vm for MshvVm {
.set_msi_routing(&msi_routing[0])
.map_err(|e| vm::HypervisorVmError::SetGsiRouting(e.into()))
}
///
/// Start logging dirty pages
///
@@ -1608,6 +1753,7 @@ impl vm::Vm for MshvVm {
.enable_dirty_page_tracking()
.map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))
}
///
/// Stop logging dirty pages
///
@@ -1626,6 +1772,7 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?;
Ok(())
}
///
/// Get dirty pages bitmap (one bit per page)
///
@@ -1638,20 +1785,24 @@ impl vm::Vm for MshvVm {
)
.map_err(|e| vm::HypervisorVmError::GetDirtyLog(e.into()))
}
/// Retrieve guest clock.
#[cfg(target_arch = "x86_64")]
fn get_clock(&self) -> vm::Result<ClockData> {
Ok(ClockData::Mshv)
}
/// Set guest clock.
#[cfg(target_arch = "x86_64")]
fn set_clock(&self, _data: &ClockData) -> vm::Result<()> {
Ok(())
}
/// Downcast to the underlying MshvVm type
fn as_any(&self) -> &dyn Any {
self
}
/// Initialize the SEV-SNP VM
#[cfg(feature = "sev_snp")]
fn sev_snp_init(&self) -> vm::Result<()> {
@@ -1663,6 +1814,9 @@ impl vm::Vm for MshvVm {
.map_err(|e| vm::HypervisorVmError::InitializeSevSnp(e.into()))
}
///
/// Importing isolated pages, these pages will be used
/// for the PSP(Platform Security Processor) measurement.
#[cfg(feature = "sev_snp")]
fn import_isolated_pages(
&self,
@@ -1690,11 +1844,16 @@ impl vm::Vm for MshvVm {
.import_isolated_pages(&isolated_pages[0])
.map_err(|e| vm::HypervisorVmError::ImportIsolatedPages(e.into()))
}
///
/// Complete isolated import, telling the hypervisor that
/// importing the pages to guest memory is complete.
///
#[cfg(feature = "sev_snp")]
fn complete_isolated_import(
&self,
snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
host_data: &[u8],
host_data: [u8; 32],
id_block_enabled: u8,
) -> vm::Result<()> {
let mut auth_info = hv_snp_id_auth_info {
@@ -1727,7 +1886,7 @@ impl vm::Vm for MshvVm {
policy: get_default_snp_guest_policy(),
},
id_auth_info: auth_info,
host_data: host_data[0..32].try_into().unwrap(),
host_data,
id_block_enabled,
author_key_enabled: 0,
},

View File

@@ -385,7 +385,7 @@ pub trait Vm: Send + Sync + Any {
fn complete_isolated_import(
&self,
_snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
_host_data: &[u8],
_host_data: [u8; 32],
_id_block_enabled: u8,
) -> Result<()> {
unimplemented!()

View File

@@ -5,4 +5,4 @@ authors = ["The Chromium OS Authors"]
edition = "2021"
[dependencies]
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"

View File

@@ -6,23 +6,23 @@ edition = "2021"
[dependencies]
epoll = "4.3.3"
getrandom = "0.2.10"
libc = "0.2.147"
log = "0.4.17"
getrandom = "0.2.11"
libc = "0.2.153"
log = "0.4.20"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.168"
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
serde = "1.0.196"
thiserror = "1.0.52"
versionize = "0.2.0"
versionize_derive = "0.1.6"
virtio-bindings = "0.2.0"
virtio-queue = "0.9.0"
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
virtio-queue = "0.11.0"
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"
[dev-dependencies]
once_cell = "1.18.0"
once_cell = "1.19.0"
pnet = "0.34.0"
pnet_datalink = "0.34.0"
serde_json = "1.0.107"
serde_json = "1.0.109"

View File

@@ -72,6 +72,10 @@ pub fn open_tap(
let mut taps: Vec<Tap> = Vec::new();
let mut ifname: String = String::new();
let vnet_hdr_size = vnet_hdr_len() as i32;
// Check if the given interface exists before we create it.
let tap_existed = if_name.map_or(false, |n| {
Path::new(&format!("/sys/class/net/{n}")).exists()
});
// In case the tap interface already exists, check if the number of
// queues is appropriate. The tap might not support multiqueue while
@@ -87,11 +91,19 @@ pub fn open_tap(
Some(name) => Tap::open_named(name, num_rx_q, flags).map_err(Error::TapOpen)?,
None => Tap::new(num_rx_q).map_err(Error::TapOpen)?,
};
if let Some(ip) = ip_addr {
tap.set_ip_addr(ip).map_err(Error::TapSetIp)?;
}
if let Some(mask) = netmask {
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
// Don't overwrite ip configuration of existing interfaces:
if !tap_existed {
if let Some(ip) = ip_addr {
tap.set_ip_addr(ip).map_err(Error::TapSetIp)?;
}
if let Some(mask) = netmask {
tap.set_netmask(mask).map_err(Error::TapSetNetmask)?;
}
} else {
warn!(
"Tap {} already exists. IP configuration will not be overwritten.",
if_name.unwrap_or_default()
);
}
if let Some(mac) = host_mac {
tap.set_mac_addr(*mac).map_err(Error::TapSetMac)?

View File

@@ -290,6 +290,17 @@ impl TupleValue for Vec<u64> {
}
}
impl TupleValue for Vec<usize> {
fn parse_value(input: &str) -> Result<Self, TupleError> {
Ok(IntegerList::from_str(input)
.map_err(TupleError::InvalidIntegerList)?
.0
.iter()
.map(|v| *v as usize)
.collect())
}
}
pub struct Tuple<S, T>(pub Vec<(S, T)>);
pub enum TupleError {

View File

@@ -10,21 +10,21 @@ kvm = ["vfio-ioctls/kvm"]
mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.75"
anyhow = "1.0.79"
byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main", features = ["fam-wrappers"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vfio_user = { git = "https://github.com/rust-vmm/vfio-user", branch = "main" }
vmm-sys-util = "0.11.0"
libc = "0.2.147"
log = "0.4.17"
serde = { version = "1.0.168", features = ["derive"] }
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vmm-sys-util = "0.12.1"
libc = "0.2.153"
log = "0.4.20"
serde = { version = "1.0.196", features = ["derive"] }
thiserror = "1.0.52"
versionize = "0.2.0"
versionize_derive = "0.1.6"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }

View File

@@ -58,7 +58,8 @@ pub trait PciDevice: BusDevice {
fn allocate_bars(
&mut self,
_allocator: &Arc<Mutex<SystemAllocator>>,
_mmio_allocator: &mut AddressAllocator,
_mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
_resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>> {
Ok(Vec::new())
@@ -68,7 +69,8 @@ pub trait PciDevice: BusDevice {
fn free_bars(
&mut self,
_allocator: &mut SystemAllocator,
_mmio_allocator: &mut AddressAllocator,
_mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> Result<()> {
Ok(())
}

View File

@@ -529,10 +529,13 @@ impl VfioCommon {
}
}
// The `allocator` argument is unused on `aarch64`
#[allow(unused_variables)]
pub(crate) fn allocate_bars(
&mut self,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new();
@@ -681,26 +684,23 @@ impl VfioCommon {
}
PciBarRegionType::Memory32BitRegion => {
// BAR allocation must be naturally aligned
allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(
restored_bar_addr,
region_size,
Some(region_size),
)
mmio32_allocator
.allocate(restored_bar_addr, region_size, Some(region_size))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?
}
PciBarRegionType::Memory64BitRegion => {
// We need do some fixup to keep MMIO RW region and msix cap region page size
// aligned.
region_size = self.fixup_msix_region(bar_id, region_size);
mmio_allocator
mmio64_allocator
.allocate(
restored_bar_addr,
region_size,
// SAFETY: FFI call. Trivially safe.
Some(unsafe { sysconf(_SC_PAGESIZE) as GuestUsize }),
Some(std::cmp::max(
// SAFETY: FFI call. Trivially safe.
unsafe { sysconf(_SC_PAGESIZE) as GuestUsize },
region_size,
)),
)
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?
}
@@ -742,10 +742,13 @@ impl VfioCommon {
Ok(bars)
}
// The `allocator` argument is unused on `aarch64`
#[allow(unused_variables)]
pub(crate) fn free_bars(
&mut self,
allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> {
for region in self.mmio_regions.iter() {
match region.type_ {
@@ -756,10 +759,10 @@ impl VfioCommon {
error!("I/O region is not supported");
}
PciBarRegionType::Memory32BitRegion => {
allocator.free_mmio_hole_addresses(region.start, region.length);
mmio32_allocator.free(region.start, region.length);
}
PciBarRegionType::Memory64BitRegion => {
mmio_allocator.free(region.start, region.length);
mmio64_allocator.free(region.start, region.length);
}
}
}
@@ -1568,6 +1571,16 @@ impl VfioPciDevice {
self.vm
.create_user_memory_region(mem_region)
.map_err(VfioPciError::CreateUserMemoryRegion)?;
if !self.iommu_attached {
self.container
.vfio_dma_map(
user_memory_region.start,
user_memory_region.size,
user_memory_region.host_addr,
)
.map_err(VfioPciError::DmaMap)?;
}
}
}
}
@@ -1578,6 +1591,16 @@ impl VfioPciDevice {
pub fn unmap_mmio_regions(&mut self) {
for region in self.common.mmio_regions.iter() {
for user_memory_region in region.user_memory_regions.iter() {
// Unmap from vfio container
if !self.iommu_attached {
if let Err(e) = self
.container
.vfio_dma_unmap(user_memory_region.start, user_memory_region.size)
{
error!("Could not unmap mmio region from vfio container: {}", e);
}
}
// Remove region
let r = self.vm.make_user_memory_region(
user_memory_region.slot,
@@ -1694,19 +1717,22 @@ impl PciDevice for VfioPciDevice {
fn allocate_bars(
&mut self,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common
.allocate_bars(allocator, mmio_allocator, resources)
.allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
}
fn free_bars(
&mut self,
allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> {
self.common.free_bars(allocator, mmio_allocator)
self.common
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
}
fn write_config_register(

View File

@@ -397,19 +397,22 @@ impl PciDevice for VfioUserPciDevice {
fn allocate_bars(
&mut self,
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common
.allocate_bars(allocator, mmio_allocator, resources)
.allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
}
fn free_bars(
&mut self,
allocator: &mut SystemAllocator,
mmio_allocator: &mut AddressAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> Result<(), PciDeviceError> {
self.common.free_bars(allocator, mmio_allocator)
self.common
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
}
fn as_any(&mut self) -> &mut dyn Any {

View File

@@ -6,10 +6,10 @@ edition = "2021"
build = "../build.rs"
[dependencies]
clap = { version = "4.0.32", features = ["wrap_help"] }
clap = { version = "4.4.7", features = ["wrap_help"] }
dirs = "5.0.0"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
serde = { version = "1.0.196", features = ["rc", "derive"] }
serde_json = "1.0.109"
test_infra = { path = "../test_infra" }
thiserror = "1.0.40"
thiserror = "1.0.52"
wait-timeout = "0.2.0"

View File

@@ -19,6 +19,7 @@ pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-amd64-custom-20210609-
#[cfg(target_arch = "aarch64")]
pub const FOCAL_IMAGE_NAME: &str = "focal-server-cloudimg-arm64-custom-20210929-0-update-tool.raw";
#[allow(dead_code)]
#[derive(Debug)]
enum Error {
BootTimeParse,

View File

@@ -4,6 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libc = "0.2.147"
log = "0.4.17"
vmm-sys-util = "0.11.0"
epoll = "4.3.3"
libc = "0.2.153"
log = "0.4.20"
thiserror = "1.0.40"
vmm-sys-util = "0.12.1"

526
rate_limiter/src/group.rs Normal file
View File

@@ -0,0 +1,526 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2023 Crusoe Energy Systems LLC
// SPDX-License-Identifier: Apache-2.0
use crate::{RateLimiter, TokenType};
use core::panic::AssertUnwindSafe;
use std::fs::File;
use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::result;
use std::sync::{Arc, Mutex};
use std::thread;
use thiserror::Error;
use vmm_sys_util::eventfd::EventFd;
/// Errors associated with rate-limiter group.
#[derive(Debug, Error)]
pub enum Error {
/// Cannot create thread
#[error("Error spawning rate-limiter thread {0}")]
ThreadSpawn(#[source] io::Error),
/// Cannot create epoll context.
#[error("Error creating epoll context: {0}")]
Epoll(#[source] io::Error),
/// Cannot create EventFd.
#[error("Error creating EventFd: {0}")]
EventFd(#[source] io::Error),
/// Cannot create RateLimiter.
#[error("Error creating RateLimiter: {0}")]
RateLimiter(#[source] io::Error),
/// Cannot read from EventFd.
#[error("Error reading from EventFd: {0}")]
EventFdRead(#[source] io::Error),
/// Cannot write to EventFd.
#[error("Error writing to EventFd: {0}")]
EventFdWrite(#[source] io::Error),
}
/// The RateLimiterGroupHandle is a handle to a RateLimiterGroup that may be
/// used in exactly the same way as the RateLimiter type. When the RateLimiter
/// within a RateLimiterGroup is unblocked, each RateLimiterGroupHandle will
/// be notified.
pub struct RateLimiterGroupHandle {
eventfd: Arc<EventFd>,
inner: Arc<RateLimiterGroupInner>,
}
impl RateLimiterGroupHandle {
fn new(inner: Arc<RateLimiterGroupInner>) -> result::Result<Self, Error> {
let eventfd = Arc::new(EventFd::new(0).map_err(Error::EventFd)?);
inner.handles.lock().unwrap().push(eventfd.clone());
Ok(Self { eventfd, inner })
}
/// Attempts to consume tokens and returns whether that is possible.
///
/// If rate limiting is disabled on provided `token_type`, this function will always succeed.
pub fn consume(&self, tokens: u64, token_type: TokenType) -> bool {
self.inner.rate_limiter.consume(tokens, token_type)
}
/// Adds tokens of `token_type` to their respective bucket.
///
/// Can be used to *manually* add tokens to a bucket. Useful for reverting a
/// `consume()` if needed.
pub fn manual_replenish(&self, tokens: u64, token_type: TokenType) {
self.inner.rate_limiter.manual_replenish(tokens, token_type)
}
/// This function needs to be called every time there is an event on the
/// FD provided by this object's `AsRawFd` trait implementation.
///
/// # Errors
///
/// If the rate limiter is disabled or is not blocked, an error is returned.
pub fn event_handler(&self) -> Result<(), Error> {
self.eventfd.read().map_err(Error::EventFdRead).map(|_| ())
}
/// Returns whether this rate limiter is blocked.
///
/// The limiter 'blocks' when a `consume()` operation fails because there was not enough
/// budget for it.
/// An event will be generated on the exported FD when the limiter 'unblocks'.
pub fn is_blocked(&self) -> bool {
self.inner.rate_limiter.is_blocked()
}
}
impl Clone for RateLimiterGroupHandle {
fn clone(&self) -> Self {
RateLimiterGroupHandle::new(self.inner.clone()).unwrap()
}
}
impl AsRawFd for RateLimiterGroupHandle {
fn as_raw_fd(&self) -> RawFd {
self.eventfd.as_raw_fd()
}
}
impl Drop for RateLimiterGroupHandle {
fn drop(&mut self) {
let mut handles = self.inner.handles.lock().unwrap();
let index = handles
.iter()
.position(|handle| handle.as_raw_fd() == self.eventfd.as_raw_fd())
.expect("RateLimiterGroupHandle must be subscribed to RateLimiterGroup");
handles.remove(index);
}
}
struct RateLimiterGroupInner {
id: String,
rate_limiter: RateLimiter,
handles: Mutex<Vec<Arc<EventFd>>>,
}
/// A RateLimiterGroup is an extension of RateLimiter that enables rate-limiting
/// the aggregate io consumption of multiple consumers.
pub struct RateLimiterGroup {
inner: Arc<RateLimiterGroupInner>,
epoll_file: File,
kill_evt: EventFd,
epoll_thread: Option<thread::JoinHandle<()>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u64)]
enum EpollDispatch {
Kill = 1,
Unblocked = 2,
Unknown,
}
impl From<u64> for EpollDispatch {
fn from(v: u64) -> Self {
use EpollDispatch::*;
match v {
1 => Kill,
2 => Unblocked,
_ => Unknown,
}
}
}
impl RateLimiterGroup {
/// Create a new RateLimiterGroup.
pub fn new(
id: &str,
bytes_total_capacity: u64,
bytes_one_time_burst: u64,
bytes_complete_refill_time_ms: u64,
ops_total_capacity: u64,
ops_one_time_burst: u64,
ops_complete_refill_time_ms: u64,
) -> result::Result<Self, Error> {
let rate_limiter = RateLimiter::new(
bytes_total_capacity,
bytes_one_time_burst,
bytes_complete_refill_time_ms,
ops_total_capacity,
ops_one_time_burst,
ops_complete_refill_time_ms,
)
.map_err(Error::RateLimiter)?;
let epoll_fd = epoll::create(true).map_err(Error::Epoll)?;
let kill_evt = EventFd::new(0).map_err(Error::EventFd)?;
epoll::ctl(
epoll_fd,
epoll::ControlOptions::EPOLL_CTL_ADD,
kill_evt.as_raw_fd(),
epoll::Event::new(epoll::Events::EPOLLIN, EpollDispatch::Kill as u64),
)
.map_err(Error::Epoll)?;
epoll::ctl(
epoll_fd,
epoll::ControlOptions::EPOLL_CTL_ADD,
rate_limiter.as_raw_fd(),
epoll::Event::new(epoll::Events::EPOLLIN, EpollDispatch::Unblocked as u64),
)
.map_err(Error::Epoll)?;
// Use 'File' to enforce closing on 'epoll_fd'
// SAFETY: epoll_fd is valid
let epoll_file = unsafe { File::from_raw_fd(epoll_fd) };
Ok(Self {
inner: Arc::new(RateLimiterGroupInner {
id: id.to_string(),
rate_limiter,
handles: Mutex::new(Vec::new()),
}),
epoll_file,
kill_evt,
epoll_thread: None,
})
}
/// Create a new RateLimiterGroupHandle.
pub fn new_handle(&self) -> result::Result<RateLimiterGroupHandle, Error> {
RateLimiterGroupHandle::new(self.inner.clone())
}
/// Start a worker thread to broadcast an event to each RateLimiterGroupHandle
/// when the RateLimiter becomes unblocked.
pub fn start_thread(&mut self, exit_evt: EventFd) -> result::Result<(), Error> {
let inner = self.inner.clone();
let epoll_fd = self.epoll_file.as_raw_fd();
thread::Builder::new()
.name(format!("rate-limit-group-{}", inner.id))
.spawn(move || {
let res = std::panic::catch_unwind(AssertUnwindSafe(move || {
const EPOLL_EVENTS_LEN: usize = 2;
let mut events =
[epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
loop {
let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) {
Ok(res) => res,
Err(e) => {
if e.kind() == io::ErrorKind::Interrupted {
continue;
} else {
return Err(Error::Epoll(e));
}
}
};
for event in events.iter().take(num_events) {
let dispatch_event: EpollDispatch = event.data.into();
match dispatch_event {
EpollDispatch::Unknown => {
let event = event.data;
warn!("Unknown rate-limiter loop event: {}", event);
}
EpollDispatch::Unblocked => {
inner.rate_limiter.event_handler().unwrap();
let handles = inner.handles.lock().unwrap();
for handle in handles.iter() {
handle.write(1).map_err(Error::EventFdWrite)?
}
}
EpollDispatch::Kill => {
info!(
"KILL_EVENT received, stopping rate-limit-group epoll loop"
);
return Ok(());
}
}
}
}
}));
match res {
Ok(res) => {
if let Err(e) = res {
error!("Error running rate-limit-group worker: {:?}", e);
exit_evt.write(1).unwrap();
}
}
Err(_) => {
error!("rate-limit-group worker panicked");
exit_evt.write(1).unwrap();
}
};
})
.map(|thread| self.epoll_thread.insert(thread))
.map_err(Error::ThreadSpawn)?;
Ok(())
}
}
impl Drop for RateLimiterGroup {
fn drop(&mut self) {
self.kill_evt.write(1).unwrap();
if let Some(t) = self.epoll_thread.take() {
if let Err(e) = t.join() {
error!("Error joining thread: {:?}", e);
}
}
}
}
#[cfg(test)]
pub(crate) mod tests {
use super::RateLimiterGroupHandle;
use crate::{group::RateLimiterGroup, TokenBucket, TokenType, REFILL_TIMER_INTERVAL_MS};
use std::{os::fd::AsRawFd, thread, time::Duration};
use vmm_sys_util::eventfd::EventFd;
impl RateLimiterGroupHandle {
pub fn bandwidth(&self) -> Option<TokenBucket> {
let guard = self.inner.rate_limiter.inner.lock().unwrap();
guard.bandwidth.clone()
}
pub fn ops(&self) -> Option<TokenBucket> {
let guard = self.inner.rate_limiter.inner.lock().unwrap();
guard.ops.clone()
}
}
#[test]
fn test_rate_limiter_group_new() {
let l = RateLimiterGroup::new("test", 1000, 1001, 1002, 1003, 1004, 1005).unwrap();
let h = l.new_handle().unwrap();
let bw = h.bandwidth().unwrap();
assert_eq!(bw.capacity(), 1000);
assert_eq!(bw.one_time_burst(), 1001);
assert_eq!(bw.refill_time_ms(), 1002);
assert_eq!(bw.budget(), 1000);
let ops = h.ops().unwrap();
assert_eq!(ops.capacity(), 1003);
assert_eq!(ops.one_time_burst(), 1004);
assert_eq!(ops.refill_time_ms(), 1005);
assert_eq!(ops.budget(), 1003);
}
#[test]
fn test_rate_limiter_group_manual_replenish() {
// rate limiter with limit of 1000 bytes/s and 1000 ops/s
let l = RateLimiterGroup::new("test", 1000, 0, 1000, 1000, 0, 1000).unwrap();
let h = l.new_handle().unwrap();
// consume 123 bytes
assert!(h.consume(123, TokenType::Bytes));
h.manual_replenish(23, TokenType::Bytes);
{
let bytes_tb = h.bandwidth().unwrap();
assert_eq!(bytes_tb.budget(), 900);
}
// consume 123 ops
assert!(h.consume(123, TokenType::Ops));
h.manual_replenish(23, TokenType::Ops);
{
let bytes_tb = h.ops().unwrap();
assert_eq!(bytes_tb.budget(), 900);
}
}
#[test]
fn test_rate_limiter_group_bandwidth() {
// rate limiter with limit of 1000 bytes/s
let mut l = RateLimiterGroup::new("test", 1000, 0, 1000, 0, 0, 0).unwrap();
l.start_thread(EventFd::new(0).unwrap()).unwrap();
let h = l.new_handle().unwrap();
// limiter should not be blocked
assert!(!h.is_blocked());
// raw FD for this disabled should be valid
assert!(h.as_raw_fd() > 0);
// ops/s limiter should be disabled so consume(whatever) should work
assert!(h.consume(u64::max_value(), TokenType::Ops));
// do full 1000 bytes
assert!(h.consume(1000, TokenType::Bytes));
// try and fail on another 100
assert!(!h.consume(100, TokenType::Bytes));
// since consume failed, limiter should be blocked now
assert!(h.is_blocked());
// wait half the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// limiter should still be blocked
assert!(h.is_blocked());
// wait the other half of the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// the timer_fd should have an event on it by now
assert!(h.event_handler().is_ok());
// limiter should now be unblocked
assert!(!h.is_blocked());
// try and succeed on another 100 bytes this time
assert!(h.consume(100, TokenType::Bytes));
}
#[test]
fn test_rate_limiter_group_ops() {
// rate limiter with limit of 1000 ops/s
let mut l = RateLimiterGroup::new("test", 0, 0, 0, 1000, 0, 1000).unwrap();
l.start_thread(EventFd::new(0).unwrap()).unwrap();
let h = l.new_handle().unwrap();
// limiter should not be blocked
assert!(!h.is_blocked());
// raw FD for this disabled should be valid
assert!(h.as_raw_fd() > 0);
// bytes/s limiter should be disabled so consume(whatever) should work
assert!(h.consume(u64::max_value(), TokenType::Bytes));
// do full 1000 ops
assert!(h.consume(1000, TokenType::Ops));
// try and fail on another 100
assert!(!h.consume(100, TokenType::Ops));
// since consume failed, limiter should be blocked now
assert!(h.is_blocked());
// wait half the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// limiter should still be blocked
assert!(h.is_blocked());
// wait the other half of the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// the timer_fd should have an event on it by now
assert!(h.event_handler().is_ok());
// limiter should now be unblocked
assert!(!h.is_blocked());
// try and succeed on another 100 ops this time
assert!(h.consume(100, TokenType::Ops));
}
#[test]
fn test_rate_limiter_group_full() {
// rate limiter with limit of 1000 bytes/s and 1000 ops/s
let mut l = RateLimiterGroup::new("test", 1000, 0, 1000, 1000, 0, 1000).unwrap();
l.start_thread(EventFd::new(0).unwrap()).unwrap();
let h = l.new_handle().unwrap();
// limiter should not be blocked
assert!(!h.is_blocked());
// raw FD for this disabled should be valid
assert!(h.as_raw_fd() > 0);
// do full 1000 bytes
assert!(h.consume(1000, TokenType::Ops));
// do full 1000 bytes
assert!(h.consume(1000, TokenType::Bytes));
// try and fail on another 100 ops
assert!(!h.consume(100, TokenType::Ops));
// try and fail on another 100 bytes
assert!(!h.consume(100, TokenType::Bytes));
// since consume failed, limiter should be blocked now
assert!(h.is_blocked());
// wait half the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// limiter should still be blocked
assert!(h.is_blocked());
// wait the other half of the timer period
thread::sleep(Duration::from_millis(REFILL_TIMER_INTERVAL_MS / 2));
// the timer_fd should have an event on it by now
assert!(h.event_handler().is_ok());
// limiter should now be unblocked
assert!(!h.is_blocked());
// try and succeed on another 100 ops this time
assert!(h.consume(100, TokenType::Ops));
// try and succeed on another 100 bytes this time
assert!(h.consume(100, TokenType::Bytes));
}
#[test]
fn test_rate_limiter_group_overconsumption() {
// initialize the rate limiter
let mut l = RateLimiterGroup::new("test", 1000, 0, 1000, 1000, 0, 1000).unwrap();
l.start_thread(EventFd::new(0).unwrap()).unwrap();
let h = l.new_handle().unwrap();
// try to consume 2.5x the bucket size
// we are "borrowing" 1.5x the bucket size in tokens since
// the bucket is full
assert!(h.consume(2500, TokenType::Bytes));
// check that even after a whole second passes, the rate limiter
// is still blocked
thread::sleep(Duration::from_millis(1000));
assert!(h.is_blocked());
// after 1.5x the replenish time has passed, the rate limiter
// is available again
thread::sleep(Duration::from_millis(500));
assert!(h.event_handler().is_ok());
assert!(!h.is_blocked());
// reset the rate limiter
let mut l = RateLimiterGroup::new("test", 1000, 0, 1000, 1000, 0, 1000).unwrap();
l.start_thread(EventFd::new(0).unwrap()).unwrap();
let h = l.new_handle().unwrap();
// try to consume 1.5x the bucket size
// we are "borrowing" 1.5x the bucket size in tokens since
// the bucket is full, should arm the timer to 0.5x replenish
// time, which is 500 ms
assert!(h.consume(1500, TokenType::Bytes));
// check that after more than the minimum refill time,
// the rate limiter is still blocked
thread::sleep(Duration::from_millis(200));
assert!(h.is_blocked());
// try to consume some tokens, which should fail as the timer
// is still active
assert!(!h.consume(100, TokenType::Bytes));
assert!(h.is_blocked());
// check that after the minimum refill time, the timer was not
// overwritten and the rate limiter is still blocked from the
// borrowing we performed earlier
thread::sleep(Duration::from_millis(100));
assert!(h.is_blocked());
assert!(!h.consume(100, TokenType::Bytes));
// after waiting out the full duration, rate limiter should be
// available again
thread::sleep(Duration::from_millis(200));
assert!(h.event_handler().is_ok());
assert!(!h.is_blocked());
assert!(h.consume(100, TokenType::Bytes));
}
}

View File

@@ -53,6 +53,9 @@ use std::sync::Mutex;
use std::time::{Duration, Instant};
use vmm_sys_util::timerfd::TimerFd;
/// Module for group rate limiting.
pub mod group;
#[derive(Debug)]
/// Describes the errors that may occur while handling rate limiter events.
pub enum Error {

View File

@@ -1,3 +1,20 @@
- [v38.0](#v380)
- [Group Rate Limiter on Block Devices](#group-rate-limiter-on-block-devices)
- [CPU Pinning Support for Block Device Worker Thread](#cpu-pinning-support-for-block-device-worker-thread)
- [Optimized Boot Time with Parallel Memory Prefault](#optimized-boot-time-with-parallel-memory-prefault)
- [New 'debug-console' Device](#new-debug-console-device)
- [Improved VFIO Device Support](#improved-vfio-device-support)
- [Extended CPU Affinity Support](#extended-cpu-affinity-support)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [v37.0](#v370)
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
- [Multiple PCI segments Support for 32-bit VFIO devices](#multiple-pci-segments-support-for-32-bit-vfio-devices)
- [Configurable Named TAP Devices](#configurable-named-tap-devices)
- [TTY Output from Both Serial Device and Virtio Console](#tty-output-from-both-serial-device-and-virtio-console)
- [Faster VM Restoration from Snapshots](#faster-vm-restoration-from-snapshots)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [v36.0](#v360)
- [Command Line Changes](#command-line-changes)
- [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli)
@@ -6,31 +23,31 @@
- [Unix Socket Backend for Serial Port](#unix-socket-backend-for-serial-port)
- [AIO Backend for Block Devices](#aio-backend-for-block-devices)
- [Documentation Improvements](#documentation-improvements)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [v35.0](#v350)
- [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63)
- [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block)
- [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [v34.0](#v340)
- [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support)
- [Improvements to VM Core Dump](#improvements-to-vm-core-dump)
- [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files)
- [Minimum Host Kernel Bump](#minimum-host-kernel-bump)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Contributors](#contributors-2)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [v33.0](#v330)
- [D-Bus based API](#d-bus-based-api)
- [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Contributors](#contributors-3)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [v32.0](#v320)
- [Increased PCI Segment Limit](#increased-pci-segment-limit)
- [API Changes](#api-changes)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Contributors](#contributors-4)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [v31.1](#v311)
- [v31.0](#v310)
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
@@ -38,15 +55,15 @@
- [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler)
- [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile)
- [Documentation Improvements](#documentation-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Contributors](#contributors-5)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Contributors](#contributors-7)
- [v30.0](#v300)
- [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size)
- [Basic vfio-user Server Support](#basic-vfio-user-server-support)
- [Heap Profiling Support](#heap-profiling-support)
- [Documentation Improvements](#documentation-improvements-2)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Contributors](#contributors-6)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-8)
- [v28.2](#v282)
- [v29.0](#v290)
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
@@ -56,20 +73,20 @@
- [`AArch64` Documentation Integration](#aarch64-documentation-integration)
- [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement)
- [TCP Offload Control](#tcp-offload-control)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Removals](#removals)
- [Deprecations](#deprecations)
- [Contributors](#contributors-7)
- [Contributors](#contributors-9)
- [v28.1](#v281)
- [v28.0](#v280)
- [Community Engagement (Reminder)](#community-engagement-reminder)
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
- [Long Term Support (LTS) Release](#long-term-support-lts-release-1)
- [Virtualised TPM Support](#virtualised-tpm-support)
- [Transparent Huge Page Support](#transparent-huge-page-support)
- [README Quick Start Improved](#readme-quick-start-improved)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Removals](#removals-1)
- [Contributors](#contributors-8)
- [Contributors](#contributors-10)
- [v27.0](#v270)
- [Community Engagement](#community-engagement)
- [Prebuilt Packages](#prebuilt-packages)
@@ -78,41 +95,41 @@
- [Simplified Build Feature Flags](#simplified-build-feature-flags)
- [Asynchronous Kernel Loading](#asynchronous-kernel-loading)
- [GDB Support for AArch64](#gdb-support-for-aarch64)
- [Notable Bug Fixes](#notable-bug-fixes-9)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-9)
- [Contributors](#contributors-11)
- [v26.0](#v260)
- [SMBIOS Improvements via `--platform`](#smbios-improvements-via---platform)
- [Unified Binary MSHV and KVM Support](#unified-binary-mshv-and-kvm-support)
- [Notable Bug Fixes](#notable-bug-fixes-10)
- [Notable Bug Fixes](#notable-bug-fixes-12)
- [Deprecations](#deprecations-2)
- [Removals](#removals-2)
- [Contributors](#contributors-10)
- [Contributors](#contributors-12)
- [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements-1)
- [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes-11)
- [Notable Bug Fixes](#notable-bug-fixes-13)
- [Removals](#removals-3)
- [Contributors](#contributors-11)
- [Contributors](#contributors-13)
- [v24.0](#v240)
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
- [Sparse Mmap support](#sparse-mmap-support)
- [Expose Platform Serial Number](#expose-platform-serial-number)
- [Notable Bug Fixes](#notable-bug-fixes-12)
- [Notable Bug Fixes](#notable-bug-fixes-14)
- [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations-3)
- [New on the Website](#new-on-the-website)
- [Contributors](#contributors-12)
- [Contributors](#contributors-14)
- [v23.1](#v231)
- [v23.0](#v230)
- [vDPA Support](#vdpa-support)
- [Updated OS Support list](#updated-os-support-list)
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
- [`AMX` Support](#amx-support)
- [Notable Bug Fixes](#notable-bug-fixes-13)
- [Notable Bug Fixes](#notable-bug-fixes-15)
- [Deprecations](#deprecations-4)
- [Contributors](#contributors-13)
- [Contributors](#contributors-15)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -123,13 +140,13 @@
- [PMU Support for AArch64](#pmu-support-for-aarch64)
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
- [Notable Bug Fixes](#notable-bug-fixes-14)
- [Contributors](#contributors-14)
- [Notable Bug Fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-16)
- [v21.0](#v210)
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
- [Notable Bug fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-15)
- [Notable Bug fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-17)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -138,8 +155,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-16)
- [Notable bug fixes](#notable-bug-fixes-18)
- [Contributors](#contributors-18)
- [v19.0](#v190)
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
- [PCI boot time optimisations](#pci-boot-time-optimisations)
@@ -147,8 +164,8 @@
- [Live migration enhancements](#live-migration-enhancements)
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
- [Notable bug fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-17)
- [Notable bug fixes](#notable-bug-fixes-19)
- [Contributors](#contributors-19)
- [v18.0](#v180)
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
@@ -158,23 +175,23 @@
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
- [Power button support on AArch64](#power-button-support-on-aarch64)
- [Notable bug fixes](#notable-bug-fixes-18)
- [Contributors](#contributors-18)
- [Notable bug fixes](#notable-bug-fixes-20)
- [Contributors](#contributors-20)
- [v17.0](#v170)
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
- [Improved SGX support](#improved-sgx-support)
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
- [Notable bug fixes](#notable-bug-fixes-19)
- [Contributors](#contributors-19)
- [Notable bug fixes](#notable-bug-fixes-21)
- [Contributors](#contributors-21)
- [v16.0](#v160)
- [Improved live migration support](#improved-live-migration-support)
- [Improved `vhost-user` support](#improved-vhost-user-support)
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
- [Notable bug fixes](#notable-bug-fixes-20)
- [Notable bug fixes](#notable-bug-fixes-22)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-20)
- [Contributors](#contributors-22)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
@@ -182,7 +199,7 @@
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-5)
- [Contributors](#contributors-21)
- [Contributors](#contributors-23)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -192,7 +209,7 @@
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
- [Block device rate limiting](#block-device-rate-limiting)
- [Deprecations](#deprecations-6)
- [Contributors](#contributors-22)
- [Contributors](#contributors-24)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -200,13 +217,13 @@
- [VHD disk image support](#vhd-disk-image-support)
- [Improved Virtio device threading](#improved-virtio-device-threading)
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
- [Contributors](#contributors-23)
- [Contributors](#contributors-25)
- [v0.12.0](#v0120)
- [ARM64 enhancements](#arm64-enhancements)
- [Removal of `vhost-user-net` and `vhost-user-block` self spawning](#removal-of-vhost-user-net-and-vhost-user-block-self-spawning)
- [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend)
- [Enhanced "info" API](#enhanced-info-api)
- [Contributors](#contributors-24)
- [Contributors](#contributors-26)
- [v0.11.0](#v0110)
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
- [Windows Guest Support](#windows-guest-support)
@@ -218,15 +235,15 @@
- [Default Log Level Changed](#default-log-level-changed)
- [New `--balloon` Parameter Added](#new---balloon-parameter-added)
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
- [Notable Bug Fixes](#notable-bug-fixes-21)
- [Contributors](#contributors-25)
- [Notable Bug Fixes](#notable-bug-fixes-23)
- [Contributors](#contributors-27)
- [v0.10.0](#v0100)
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
- [Memory Zones](#memory-zones)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
- [Notable Bug Fixes](#notable-bug-fixes-22)
- [Contributors](#contributors-26)
- [Notable Bug Fixes](#notable-bug-fixes-24)
- [Contributors](#contributors-28)
- [v0.9.0](#v090)
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
- [Block and Network Device Statistics](#block-and-network-device-statistics)
@@ -239,17 +256,17 @@
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
- [Intel SGX Support](#intel-sgx-support)
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
- [Notable Bug Fixes](#notable-bug-fixes-23)
- [Contributors](#contributors-27)
- [Notable Bug Fixes](#notable-bug-fixes-25)
- [Contributors](#contributors-29)
- [v0.8.0](#v080)
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
- [Experimental ARM64 Support](#experimental-arm64-support)
- [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests)
- [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices)
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
- [Notable Bug Fixes](#notable-bug-fixes-24)
- [Notable Bug Fixes](#notable-bug-fixes-26)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-28)
- [Contributors](#contributors-30)
- [v0.7.0](#v070)
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
- [Alternative `libc` Support](#alternative-libc-support)
@@ -259,14 +276,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-29)
- [Contributors](#contributors-31)
- [v0.6.0](#v060)
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
- [Shared Filesystem Improvements](#shared-filesystem-improvements)
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
- [Command Line Interface](#command-line-interface)
- [PVH Boot](#pvh-boot)
- [Contributors](#contributors-30)
- [Contributors](#contributors-32)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -274,7 +291,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-31)
- [Contributors](#contributors-33)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -283,7 +300,7 @@
- [Userspace IOAPIC by default](#userspace-ioapic-by-default)
- [PCI BAR reprogramming](#pci-bar-reprogramming)
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
- [Contributors](#contributors-32)
- [Contributors](#contributors-34)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -310,6 +327,138 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v38.0
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v38.0. The following user visible changes have been made:
### Group Rate Limiter on Block Devices
Users now can throttle a group of block devices with the new
`--rate-limiter-group` option. Details can be found from the [I/O
Throttling documentation](docs/io_throttling.md)
### CPU Pinning Support for Block Device Worker Thread
Users now have the option to pin virt-queue threads for block devices
to specific host cpus.
### Optimized Boot Time with Parallel Memory Prefault
The boot time with `prefault` option enabled is optimized via parallel
memory prefault.
### New 'debug-console' Device
A 'debug-console' device is added to provide a user-configurable debug
port for logging guest information. Details can be found from the [Debug
IO Ports documentation](docs/debug-port.md).
### Improved VFIO Device Support
All non-emulated MMIO regions of VFIO devices are now mapped to the VFIO
container, allowing PCIe P2P between all VFIO devices on the same
VM. This is required for a wide variety of multi-GPU workloads involving
GPUDirect P2P (DMA between two GPUs), GPUDirect RDMA (DMA between a GPU
and an IB device).
### Extended CPU Affinity Support
Users now can set the vcpu affinity to a host CPU with index larger
than 255.
### Notable Bug Fixes
* Enable HTT flag to avoid crashing cpu topology enumeration software
such as hwloc in the guest (#6146)
* Fix several security advisories from dependencies (#6134, #6141)
* Handle non-power-of-two CPU topology properly (#6062)
* Various bug fixes around `virtio-vsock`(#6080, #6091, #6095)
* Enable nested virtualization on AMD if supported (#6106)
* Align VFIO devices PCI BARs naturally (#6196)
### Contributors
Many thanks to everyone who has contributed to our release:
* Alyssa Ross <hi@alyssa.is>
* Bo Chen <chen.bo@intel.com>
* Daniel Farina <daniel@ubicloud.com>
* Jinank Jain <jinankjain@microsoft.com>
* Muminul Islam <muislam@microsoft.com>
* Peteris Rudzusiks <rye@stripe.com>
* Philipp Schuster <philipp.schuster@cyberus-technology.de>
* Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
* Rob Bradford <rbradford@rivosinc.com>
* Ruslan Mstoi <ruslan.mstoi@intel.com>
* Sean Banko <sbanko@crusoeenergy.com>
* Thomas Barrett <tbarrett@crusoeenergy.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <foxywang@tencent.com>
* acarp <acarp@crusoeenergy.com>
# v37.0
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v37.0. The following user visible changes have been made:
### Long Term Support (LTS) Release
This release is a LTS release. Point releases for bug fixes will be made
for the next 18 months; live migration and live upgrade will be
supported between the point releases of the LTS.
### Multiple PCI segments Support for 32-bit VFIO devices
Now VFIO devices with 32-bit memory BARs can be attached to non-zero PCI
segments on the guest, allowing users to have more 32-bit devices and
assign such devices to appropriate NUMA nodes for better performance.
### Configurable Named TAP Devices
Named TAP devices now accepts IP configuration from users, such as IP
and MAC address, as long as the named TAP device is created by Cloud
Hypervisor (e.g. not existing TAP devices).
### TTY Output from Both Serial Device and Virtio Console
Now legacy serial device and virtio console can be set as TTY mode as
the same time. This allows users to capture early boot logs with the
legacy serial device without losing performance benefits of using
virtio-console, when appropriate kernel configuration is used (such as
using kernel command-line `console=hvc0 earlyprintk=ttyS0` on x86).
### Faster VM Restoration from Snapshots
The speed of VM restoration from snapshots is improved with a better
implementation of deserializing JSON files.
### Notable Bug Fixes
* Fix aio backend behavior for block devices when writeback cache
disabled (#5930)
* Fix PvPanic device PCI BAR alignment (#5956)
* Bug fix to OpenAPI specification file (#5967)
* Error out early for live migration when TDX is enabled (#6025)
### Contributors
Many thanks to everyone who has contributed to our release:
* Bo Chen <chen.bo@intel.com>
* Jinank Jain <jinankjain@microsoft.com>
* Markus Sütter <markus.suetter@secunet.com>
* Michael Zhao <michael.zhao@arm.com>
* Muminul Islam <muislam@microsoft.com>
* Rob Bradford <rbradford@rivosinc.com>
* Rui Chang <rui.chang@arm.com>
* Ruslan Mstoi <ruslan.mstoi@intel.com>
* Thomas Barrett <tbarrett@crusoeenergy.com>
* Wei Liu <liuwe@microsoft.com>
* Yi Wang <foxywang@tencent.com>
* Yong He <alexyonghe@tencent.com>
# v36.0
This release has been tracked in our [roadmap

View File

@@ -3,10 +3,10 @@
# When changing this file don't forget to update the tag name in the
# .github/workflows/docker-image.yaml file if doing multiple per day
FROM ubuntu:20.04 as dev
FROM ubuntu:22.04 as dev
ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.67.1"
ARG RUST_TOOLCHAIN="1.70.0"
ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"
@@ -43,7 +43,6 @@ RUN apt-get update \
socat \
dosfstools \
cpio \
python \
python3 \
python3-setuptools \
ntfs-3g \

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
: '
This script checks if an image is compatible with Cloud Hypervisor.
At first, it detects the image type(raw or qcow2),
@@ -8,8 +8,6 @@
a message about the compatibility of the image.
'
usage="$(basename "$0") [-h] -f -w -- program to check Cloud Hypervisor compatible image
where:
@@ -18,12 +16,11 @@ where:
-w directory to be used for temporary files"
function check_command {
if ! command -v $1 &> /dev/null
then
echo "Command $1 could not be found"
if ! command -v "$1" &>/dev/null; then
echo "Command $1 could not be found"
exit 1
fi
};
}
function check_if_root {
if [ "$EUID" -ne 0 ]; then
@@ -31,27 +28,32 @@ function check_if_root {
exit 1
fi
};
}
check_if_root
working_dir=""
while getopts ':hf:w:' option; do
case "$option" in
h) echo "$usage"
exit
;;
f) file_name=$OPTARG
;;
w) working_dir=$OPTARG
;;
:) printf "missing argument for -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
h)
echo "$usage"
exit
;;
f)
file_name=$OPTARG
;;
w)
working_dir=$OPTARG
;;
:)
printf "missing argument for -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
\?)
printf "illegal option: -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
esac
done
@@ -59,67 +61,64 @@ shift $((OPTIND - 1))
if [ -z "${file_name}" ]; then
echo "You must provide the image file name"
exit 1
exit 1
fi
if [[ ! -f ${file_name} ]]; then
echo "File ${file_name} does not exist"
exit 1
fi
file_abs_path=`readlink -m ${file_name}`
file_abs_path=$(readlink -m "${file_name}")
if [[ "${working_dir}" != "" && ! -d "${working_dir}" ]]; then
echo "Directory ${working_dir} does not exist"
exit 1
elif [[ "${working_dir}" == "" ]]; then
working_dir=`mktemp -d`
working_dir=$(mktemp -d)
tmp_created=1
else
working_dir=`readlink -m ${working_dir}`
working_dir=$(readlink -m "${working_dir}")
fi
#get file extension and image type
extension="${file_name##*.}"
filename="${file_name%.*}"
dest_file=${working_dir}/${filename}.raw
image_type=$(qemu-img info ${file_abs_path} | grep 'file format:' | awk '{ print $3 }')
image_type=$(qemu-img info "${file_abs_path}" | grep 'file format:' | awk '{ print $3 }')
echo "Image type detected as ${image_type}"
if [[ "${image_type}" == "raw" ]]; then
dest_file=${file_abs_path}
dest_file=${file_abs_path}
elif [[ "$image_type" == "qcow2" ]]; then
if lsmod | grep "nbd" &> /dev/null ; then
if lsmod | grep "nbd" &>/dev/null; then
echo "Module nbd is loaded!"
else
echo "Module nbd is not loaded. Trying to load the module"
modprobe nbd max_part=8
if [ $? != 0 ]; then
if ! modprobe nbd max_part=8; then
echo "failed to load nbd module. Exiting"
exit 1
fi
fi
check_command qemu-img
dest_file=/dev/nbd0
qemu-nbd --connect=${dest_file} ${file_abs_path} --read-only
qemu-nbd --connect=${dest_file} "${file_abs_path}" --read-only
fi
check_command blkid
#get part info
part_type=$(blkid -o value -s PTTYPE ${dest_file})
part_type=$(blkid -o value -s PTTYPE "${dest_file}")
check_command partx
nr_partitions=`partx -g ${dest_file} | wc -l`
nr_partitions=$(partx -g "${dest_file}" | wc -l)
check_command fdisk
out=`fdisk -l ${dest_file} --bytes | grep -i -A ${nr_partitions} 'Device' | tail -n +2`
out=$(fdisk -l "${dest_file}" --bytes | grep -i -A "${nr_partitions}" 'Device' | tail -n +2)
IFS='
'
i=0
declare -A liness
for x in $out ; do
lines[$i]=$x
i=$((i+1))
declare -A lines
for x in $out; do
lines[$i]=$x
i=$((i + 1))
done
declare -A partitions
@@ -127,89 +126,86 @@ IFS=' '
i=0
ROWS=${#lines[@]}
for line in "${lines[@]}";
do
j=0
read -a str_arr <<< "$line"
for val in "${str_arr[@]}";
do
if [[ "$val" != "*" ]]; then
partitions[$i,$j]=$val
j=$((j+1))
fi
done
i=$((i+1))
for line in "${lines[@]}"; do
j=0
read -a -r str_arr <<<"$line"
for val in "${str_arr[@]}"; do
if [[ "$val" != "*" ]]; then
partitions[$i, $j]=$val
j=$((j + 1))
fi
done
i=$((i + 1))
done
COLUMNS=$j
COUNT=${#partitions[@]}
START_ADDRESS_INDEX=1
FILE_SYS_INDEX2=$((COLUMNS-1))
FILE_SYS_INDEX1=$((COLUMNS-2))
FILE_SYS_INDEX2=$((COLUMNS - 1))
FILE_SYS_INDEX1=$((COLUMNS - 2))
DEVICE_INDEX=0
# Here we have all the partition info now lets mount and analyze the contents
for ((i=0;i<ROWS;i++)) do
if [[ "$part_type" == "gpt" && "${partitions[$i,${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i,${FILE_SYS_INDEX2}]}" == "filesystem" ]]; then
for ((i = 0; i < ROWS; i++)); do
if [[ "$part_type" == "gpt" && "${partitions[$i, ${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i, ${FILE_SYS_INDEX2}]}" == "filesystem" ]]; then
echo "The image has GPT partitions"
MOUNT_ROW=$i
break
elif [[ "$part_type" == "dos" && "${partitions[$i,${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i,${FILE_SYS_INDEX2}]}" == "" ]]; then
break
elif [[ "$part_type" == "dos" && "${partitions[$i, ${FILE_SYS_INDEX1}]}" == "Linux" && "${partitions[$i, ${FILE_SYS_INDEX2}]}" == "" ]]; then
echo "The image has DOS partitions"
MOUNT_ROW=$i
break
fi
fi
done
start_address=${partitions[${MOUNT_ROW},${START_ADDRESS_INDEX}]}
offset=$((start_address*512))
start_address=${partitions[${MOUNT_ROW}, ${START_ADDRESS_INDEX}]}
offset=$((start_address * 512))
MOUNT_DIR=/mnt/clh-img-check/
rm -rf ${MOUNT_DIR}
mkdir ${MOUNT_DIR}
if [[ "${image_type}" == "raw" ]]; then
mount -o ro,loop,offset=$offset ${dest_file} ${MOUNT_DIR}
mount -o ro,loop,offset=$offset "${dest_file}" ${MOUNT_DIR}
elif [[ "${image_type}" == "qcow2" ]]; then
mount -o ro ${partitions[${MOUNT_ROW},${DEVICE_INDEX}]} ${MOUNT_DIR}
mount -o ro "${partitions[${MOUNT_ROW}, ${DEVICE_INDEX}]}" ${MOUNT_DIR}
fi
CONFIG_DIR=${MOUNT_DIR}boot/
if [[ "$part_type" == "dos" ]]; then
CONFIG_DIR=${MOUNT_DIR}
CONFIG_DIR=${MOUNT_DIR}
fi
#check VIRTIO
HAS_VIRTIO=1
for conf_file in ${CONFIG_DIR}config*; do
out=`grep -E "CONFIG_VIRTIO=y|CONFIG_VIRTIO_BLK=y|CONFIG_VIRTIO_BLK=m" ${conf_file} | wc -l`
for conf_file in "${CONFIG_DIR}"config*; do
out=$(grep -cE "CONFIG_VIRTIO=y|CONFIG_VIRTIO_BLK=y|CONFIG_VIRTIO_BLK=m" "${conf_file}")
if [[ "$out" != "2" ]]; then
echo "VIRTIO not found"
HAS_VIRTIO=0
fi
echo "VIRTIO not found"
HAS_VIRTIO=0
fi
done
#clean up
umount ${MOUNT_DIR}
if [[ "${tmp_created}" == "1" ]]; then
rm -rf ${working_dir}
rm -rf "${working_dir}"
fi
if [[ "${image_type}" == "qcow2" ]];then
qemu-nbd --disconnect ${dest_file} > /dev/null
if [[ "${image_type}" == "qcow2" ]]; then
qemu-nbd --disconnect "${dest_file}" >/dev/null
fi
result=""
if [[ "${part_type}" == "dos" ]]; then
result="dos mode not supported"
result="dos mode not supported"
fi
if [[ "${HAS_VIRTIO}" == "0" ]]; then
if [[ "$result" != "" ]]; then
result="${result},"
fi
result="$result VirtIO module not found in the image"
if [[ "$result" != "" ]]; then
result="${result},"
fi
result="$result VirtIO module not found in the image"
fi
if [[ "$result" == "" ]];then
echo "No incompatibilities found"
if [[ "$result" == "" ]]; then
echo "No incompatibilities found"
else
echo "$result"
echo "$result"
fi

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
WORKLOADS_DIR="$HOME/workloads"
@@ -22,26 +22,26 @@ build_edk2() {
# Prepare source code
checkout_repo "$EDK2_DIR" "$EDK2_REPO" master "46b4606ba23498d3d0e66b53e498eb3d5d592586"
pushd "$EDK2_DIR"
pushd "$EDK2_DIR" || exit
git submodule update --init
popd
popd || exit
checkout_repo "$EDK2_PLAT_DIR" "$EDK2_PLAT_REPO" master "8227e9e9f6a8aefbd772b40138f835121ccb2307"
checkout_repo "$ACPICA_DIR" "$ACPICA_REPO" master "b9c69f81a05c45611c91ea9cbce8756078d76233"
if [[ ! -f "$EDK2_DIR/.built" || \
! -f "$EDK2_PLAT_DIR/.built" || \
! -f "$ACPICA_DIR/.built" ]]; then
pushd "$EDK2_BUILD_DIR"
if [[ ! -f "$EDK2_DIR/.built" ||
! -f "$EDK2_PLAT_DIR/.built" ||
! -f "$ACPICA_DIR/.built" ]]; then
pushd "$EDK2_BUILD_DIR" || exit
# Build
make -C acpica -j `nproc`
make -C acpica -j "$(nproc)"
# shellcheck disable=SC1091
source edk2/edksetup.sh
make -C edk2/BaseTools -j `nproc`
make -C edk2/BaseTools -j "$(nproc)"
build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtCloudHv.dsc -b RELEASE -n 0
cp Build/ArmVirtCloudHv-AARCH64/RELEASE_GCC5/FV/CLOUDHV_EFI.fd "$WORKLOADS_DIR"
touch "$EDK2_DIR"/.built
touch "$EDK2_PLAT_DIR"/.built
touch "$ACPICA_DIR"/.built
popd
popd || exit
fi
}

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -x
rm -f /tmp/ubuntu-cloudinit.img
@@ -6,4 +6,3 @@ mkdosfs -n CIDATA -C /tmp/ubuntu-cloudinit.img 8192
mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/user-data ::
mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/meta-data ::
mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/network-config ::

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Copyright © 2020 Intel Corporation
@@ -7,7 +7,7 @@
CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
CTR_IMAGE_VERSION="20231012-0"
CTR_IMAGE_VERSION="20231220-0"
: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
DOCKER_RUNTIME="docker"
@@ -121,9 +121,7 @@ ensure_latest_ctr() {
if [ "$CTR_IMAGE_VERSION" = "local" ]; then
build_container
else
$DOCKER_RUNTIME pull "$CTR_IMAGE"
if [ $? -ne 0 ]; then
if ! $DOCKER_RUNTIME pull "$CTR_IMAGE"; then
build_container
fi
@@ -143,7 +141,8 @@ fix_dir_perms() {
--workdir "$CTR_CLH_ROOT_DIR" \
--rm \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
"$CTR_IMAGE" \
chown -R "$(id -u):$(id -g)" "$CTR_CLH_ROOT_DIR"
@@ -158,9 +157,9 @@ process_volumes_args() {
return
fi
exported_volumes=""
arr_vols=(${arg_vols//#/ })
arr_vols=("${arg_vols//#/ }")
for var in "${arr_vols[@]}"; do
parts=(${var//:/ })
parts=("${var//:/ }")
if [[ ! -e "${parts[0]}" ]]; then
echo "The volume ${parts[0]} does not exist."
exit 1
@@ -233,10 +232,10 @@ cmd_build() {
"--debug") { build="debug"; } ;;
"--release") { build="release"; } ;;
"--runtime")
shift
DOCKER_RUNTIME="$1"
export DOCKER_RUNTIME
;;
shift
DOCKER_RUNTIME="$1"
export DOCKER_RUNTIME
;;
"--libc")
shift
[[ "$1" =~ ^(musl|gnu)$ ]] ||
@@ -282,11 +281,11 @@ cmd_build() {
[ $build = "release" ] && cargo_args+=("--release")
cargo_args+=(--target "$target")
# shellcheck disable=SC2153
rustflags="$RUSTFLAGS"
target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="$rustflags -C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
target_cc="musl-gcc"
rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
fi
$DOCKER_RUNTIME run \
@@ -294,11 +293,12 @@ cmd_build() {
--workdir "$CTR_CLH_ROOT_DIR" \
--rm \
--volume $exported_device \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
"$CTR_IMAGE" \
cargo build --all $features_build \
cargo build --all "$features_build" \
--target-dir "$CTR_CLH_CARGO_TARGET" \
"${cargo_args[@]}" && say "Binaries placed under $CLH_CARGO_TARGET/$target/$build"
}
@@ -313,7 +313,8 @@ cmd_clean() {
--user "$(id -u):$(id -g)" \
--workdir "$CTR_CLH_ROOT_DIR" \
--rm \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
"$CTR_IMAGE" \
cargo clean \
--target-dir "$CTR_CLH_CARGO_TARGET" \
@@ -362,7 +363,6 @@ cmd_tests() {
hypervisor="$1"
;;
"--all") {
cargo=true
unit=true
integration=true
} ;;
@@ -384,7 +384,7 @@ cmd_tests() {
exported_device="/dev/mshv"
fi
if [ ! -e "${exported_device}" ] ; then
if [ ! -e "${exported_device}" ]; then
die "${exported_device} does not exist on the system"
fi
@@ -399,8 +399,7 @@ cmd_tests() {
rustflags="$RUSTFLAGS"
target_cc=""
if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
rustflags="$rustflags -C link-arg=-lgcc -C link_arg=-specs -C link_arg=/usr/lib/aarch64-linux-musl/musl-gcc.specs"
target_cc="musl-gcc"
rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
fi
if [[ "$unit" = true ]]; then
@@ -411,7 +410,8 @@ cmd_tests() {
--device $exported_device \
--device /dev/net/tun \
--cap-add net_admin \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
@@ -430,12 +430,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
dbus-run-session ./scripts/run_integration_tests_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -451,12 +453,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_sgx.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -472,12 +476,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_vfio.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -493,12 +499,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_windows_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -514,12 +522,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_live_migration.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -535,12 +545,14 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_integration_tests_rate_limiter.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -556,13 +568,15 @@ cmd_tests() {
--net="$CTR_CLH_NET" \
--mount type=tmpfs,destination=/tmp \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--env BUILD_TARGET="$target" \
--env RUSTFLAGS="$rustflags" \
--env TARGET_CC="$target_cc" \
--env RUST_BACKTRACE="${RUST_BACKTRACE}" \
--env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
"$CTR_IMAGE" \
./scripts/run_metrics.sh "$@" || fix_dir_perms $? || exit $?
fi
@@ -583,9 +597,9 @@ build_container() {
$DOCKER_RUNTIME build \
--target dev \
-t $CTR_IMAGE \
-t "$CTR_IMAGE" \
-f $BUILD_DIR/Dockerfile \
--build-arg TARGETARCH=$TARGETARCH \
--build-arg TARGETARCH="$TARGETARCH" \
$BUILD_DIR
}
@@ -645,7 +659,8 @@ cmd_shell() {
--net="$CTR_CLH_NET" \
--tmpfs /tmp:exec \
--volume /dev:/dev \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" $exported_volumes \
--volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
${exported_volumes:+"$exported_volumes"} \
--volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
--env USER="root" \
--entrypoint bash \

92
scripts/gitlint/rules.py Normal file
View File

@@ -0,0 +1,92 @@
from gitlint.rules import LineRule, RuleViolation, CommitMessageTitle
import re
class TitleStartsWithComponent(LineRule):
"""A rule to enforce valid commit message title
Valid title format:
component1[, component2, componentN]: submodule: summary
Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated
"""
# A rule MUST have a human friendly name
name = "title-has-valid-component"
# A rule MUST have a *unique* id.
# We recommend starting with UL (for User-defined Line-rule)
id = "UL1"
# A line-rule MUST have a target (not required for CommitRules).
target = CommitMessageTitle
def validate(self, line, _commit):
valid_components = (
'api_client',
'arch',
'block',
'build',
'ch-remote',
'ci',
'devices',
'docs',
'event_monitor',
'fuzz',
'github',
'gitignore',
'gitlint',
'hypervisor',
'Jenkinsfile',
'main',
'misc',
'net_gen',
'net_util',
'option_parser',
'pci',
'performance-metrics',
'rate_limiter',
'README',
'resources',
'scripts',
'serial_buffer',
'test_data',
'test_infra',
'tests',
'tpm',
'tracer',
'vhost_user_block',
'vhost_user_net',
'virtio-devices',
'vm-allocator',
'vm-device',
'vmm',
'vm-migration',
'vm-virtio')
ptrn_title = re.compile(r'^(.+?):\s(.+)$')
match = ptrn_title.match(line)
if not match:
self.log.debug("Invalid commit title {}", line)
return [RuleViolation(self.id, "Commit title does not comply with "
"rule: 'component: change summary'")]
components = match.group(1)
summary = match.group(2)
self.log.debug(f"\nComponents: {components}\nSummary: {summary}")
ptrn_components = re.compile(r',\s')
components_list = re.split(ptrn_components, components)
self.log.debug("components list: %s" % components_list)
for component in components_list:
if component not in valid_components:
return [RuleViolation(self.id,
f"Invalid component: {component}, "
"\nValid components are: {}".format(
" ".join(valid_components)))]

View File

@@ -1,20 +1,20 @@
#!/bin/bash
#!/usr/bin/env bash
set -x
sudo apt install -y libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf git make dpkg-dev libmnl-dev pkg-config iproute2
sudo sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list
sudo apt update
apt-get source linux-image-unsigned-`uname -r`
pushd linux-azure*/drivers/vdpa/vdpa_sim/
cat <<'EOF' > Makefile
apt-get source linux-image-unsigned-"$(uname -r)"
pushd linux-azure*/drivers/vdpa/vdpa_sim/ || exit
cat <<'EOF' >Makefile
# SPDX-License-Identifier: GPL-2.0
obj-m += vdpa_sim.o
obj-m += vdpa_sim_net.o
obj-m += vdpa_sim_blk.o
EOF
make -C /lib/modules/`uname -r`/build M=$PWD
sudo make -C /lib/modules/`uname -r`/build M=$PWD modules_install
popd
make -C /lib/modules/"$(uname -r)"/build M="$PWD"
sudo make -C /lib/modules/"$(uname -r)"/build M="$PWD" modules_install
popd || exit
sudo depmod -a
sudo modprobe vdpa
sudo modprobe vhost_vdpa

View File

@@ -1,9 +1,11 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
source $(dirname "$0")/common-aarch64.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
source "$(dirname "$0")"/common-aarch64.sh
WORKLOADS_LOCK="$WORKLOADS_DIR/integration_test.lock"
@@ -14,23 +16,23 @@ build_spdk_nvme() {
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "ef8bcce58f3f02b79c0619a297e4f17e81e62b24"
if [ ! -f "$SPDK_DIR/.built" ]; then
pushd $SPDK_DIR
pushd "$SPDK_DIR" || exit
git submodule update --init
apt-get update
sed -i "/grpcio/d" scripts/pkgdep/debian.sh
./scripts/pkgdep.sh
./configure --with-vfio-user
chmod +x /usr/local/lib/python3.8/dist-packages/ninja/data/bin/ninja
make -j `nproc` || exit 1
chmod +x /usr/local/lib/python3.10/dist-packages/ninja/data/bin/ninja
make -j "$(nproc)" || exit 1
touch .built
popd
popd || exit
fi
if [ ! -d "/usr/local/bin/spdk-nvme" ]; then
mkdir -p $SPDK_DEPLOY_DIR
fi
cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt
cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py
cp -r "$WORKLOADS_DIR/spdk/scripts/rpc" $SPDK_DEPLOY_DIR/rpc
cp -r "$WORKLOADS_DIR/spdk/python/spdk/" $SPDK_DEPLOY_DIR/
cp -r "$WORKLOADS_DIR/spdk/python" $SPDK_DEPLOY_DIR/../
}
@@ -38,36 +40,36 @@ build_virtiofsd() {
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.1.0 "220405d7a2606c92636d31992b5cb3036a41047b"
checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.8.0 "97ea7908fe7f9bc59916671a771bdcfaf4044b45"
if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then
pushd $VIRTIOFSD_DIR
pushd "$VIRTIOFSD_DIR" || exit
rm -rf target/
time RUSTFLAGS="" TARGET_CC="" cargo build --release
cp target/release/virtiofsd "$WORKLOADS_DIR/" || exit 1
touch .built
popd
popd || exit
fi
}
update_workloads() {
cp scripts/sha1sums-aarch64 $WORKLOADS_DIR
cp scripts/sha1sums-aarch64 "$WORKLOADS_DIR"
BIONIC_OS_IMAGE_DOWNLOAD_NAME="bionic-server-cloudimg-arm64.img"
BIONIC_OS_IMAGE_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$BIONIC_OS_IMAGE_DOWNLOAD_NAME"
BIONIC_OS_DOWNLOAD_IMAGE="$WORKLOADS_DIR/$BIONIC_OS_IMAGE_DOWNLOAD_NAME"
if [ ! -f "$BIONIC_OS_DOWNLOAD_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $BIONIC_OS_IMAGE_DOWNLOAD_URL || exit 1
popd
popd || exit
fi
BIONIC_OS_RAW_IMAGE_NAME="bionic-server-cloudimg-arm64.raw"
BIONIC_OS_RAW_IMAGE="$WORKLOADS_DIR/$BIONIC_OS_RAW_IMAGE_NAME"
if [ ! -f "$BIONIC_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $BIONIC_OS_IMAGE_DOWNLOAD_NAME $BIONIC_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
# Convert the raw image to qcow2 image to remove compressed blocks from the disk. Therefore letting the
@@ -75,97 +77,109 @@ update_workloads() {
BIONIC_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="bionic-server-cloudimg-arm64.qcow2"
BIONIC_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$BIONIC_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
if [ ! -f "$BIONIC_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then
pushd $WORKLOADS_DIR
time qemu-img convert -p -f raw -O qcow2 $BIONIC_OS_RAW_IMAGE_NAME $BIONIC_OS_QCOW2_UNCOMPRESSED_IMAGE || exit 1
popd
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f raw -O qcow2 $BIONIC_OS_RAW_IMAGE_NAME "$BIONIC_OS_QCOW2_UNCOMPRESSED_IMAGE" || exit 1
popd || exit
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.raw"
FOCAL_OS_RAW_IMAGE_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_RAW_IMAGE_NAME"
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_RAW_IMAGE_DOWNLOAD_URL || exit 1
popd
popd || exit
fi
FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="focal-server-cloudimg-arm64-custom-20210929-0.qcow2"
FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
if [ ! -f "$FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL || exit 1
popd
popd || exit
fi
FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME="focal-server-cloudimg-arm64-custom-20210929-0-backing.qcow2"
FOCAL_OS_QCOW2_BACKING_FILE_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME"
if [ ! -f "$FOCAL_OS_QCOW2_BACKING_FILE_IMAGE" ]; then
pushd $WORKLOADS_DIR
time qemu-img create -f qcow2 -b $FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE -F qcow2 $FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME
popd
pushd "$WORKLOADS_DIR" || exit
time qemu-img create -f qcow2 -b "$FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE" -F qcow2 $FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME
popd || exit
fi
JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.raw"
JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_RAW_IMAGE_NAME"
JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL || exit 1
popd
popd || exit
fi
JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.qcow2"
JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME"
if [ ! -f "$JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL || exit 1
popd
popd || exit
fi
ALPINE_MINIROOTFS_URL="http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/aarch64/alpine-minirootfs-3.11.3-aarch64.tar.gz"
ALPINE_MINIROOTFS_TARBALL="$WORKLOADS_DIR/alpine-minirootfs-aarch64.tar.gz"
if [ ! -f "$ALPINE_MINIROOTFS_TARBALL" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $ALPINE_MINIROOTFS_URL -O $ALPINE_MINIROOTFS_TARBALL || exit 1
popd
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $ALPINE_MINIROOTFS_URL -O "$ALPINE_MINIROOTFS_TARBALL" || exit 1
popd || exit
fi
ALPINE_INITRAMFS_IMAGE="$WORKLOADS_DIR/alpine_initramfs.img"
if [ ! -f "$ALPINE_INITRAMFS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
mkdir alpine-minirootfs
tar xf "$ALPINE_MINIROOTFS_TARBALL" -C alpine-minirootfs
cat > alpine-minirootfs/init <<-EOF
cat >alpine-minirootfs/init <<-EOF
#! /bin/sh
mount -t devtmpfs dev /dev
echo \$TEST_STRING > /dev/console
poweroff -f
EOF
chmod +x alpine-minirootfs/init
cd alpine-minirootfs
cd alpine-minirootfs || exit
find . -print0 |
cpio --null --create --verbose --owner root:root --format=newc > "$ALPINE_INITRAMFS_IMAGE"
popd
cpio --null --create --verbose --owner root:root --format=newc >"$ALPINE_INITRAMFS_IMAGE"
popd || exit
fi
pushd $WORKLOADS_DIR
sha1sum sha1sums-aarch64 --check
if [ $? -ne 0 ]; then
pushd "$WORKLOADS_DIR" || exit
if ! sha1sum sha1sums-aarch64 --check; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
popd || exit
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v34.0"
LAST_RELEASE_VERSION="v36.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64"
CH_RELEASE_NAME="cloud-hypervisor-static-aarch64"
pushd $WORKLOADS_DIR
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1
chmod +x $CH_RELEASE_NAME
popd
pushd "$WORKLOADS_DIR" || exit
# Repeat a few times to workaround a random wget failure
WGET_RETRY_MAX=10
wget_retry=0
until [ "$wget_retry" -ge "$WGET_RETRY_MAX" ]; do
time wget $CH_RELEASE_URL -O "$CH_RELEASE_NAME" && break
wget_retry=$((wget_retry + 1))
done
if [ $wget_retry -ge "$WGET_RETRY_MAX" ]; then
exit 1
else
chmod +x $CH_RELEASE_NAME
fi
popd || exit
# Build custom kernel for guest VMs
build_custom_linux
@@ -186,22 +200,22 @@ update_workloads() {
BLK_IMAGE="$WORKLOADS_DIR/blk.img"
MNT_DIR="mount_image"
if [ ! -f "$BLK_IMAGE" ]; then
pushd $WORKLOADS_DIR
fallocate -l 16M $BLK_IMAGE
mkfs.ext4 -j $BLK_IMAGE
pushd "$WORKLOADS_DIR" || exit
fallocate -l 16M "$BLK_IMAGE"
mkfs.ext4 -j "$BLK_IMAGE"
mkdir $MNT_DIR
sudo mount -t ext4 $BLK_IMAGE $MNT_DIR
sudo mount -t ext4 "$BLK_IMAGE" $MNT_DIR
sudo bash -c "echo bar > $MNT_DIR/foo" || exit 1
sudo umount $BLK_IMAGE
sudo umount "$BLK_IMAGE"
rm -r $MNT_DIR
popd
popd || exit
fi
SHARED_DIR="$WORKLOADS_DIR/shared_dir"
if [ ! -d "$SHARED_DIR" ]; then
mkdir -p $SHARED_DIR
echo "foo" > "$SHARED_DIR/file1"
echo "bar" > "$SHARED_DIR/file3" || exit 1
mkdir -p "$SHARED_DIR"
echo "foo" >"$SHARED_DIR/file1"
echo "bar" >"$SHARED_DIR/file3" || exit 1
fi
# Checkout and build SPDK NVMe
@@ -219,12 +233,11 @@ if [[ "$hypervisor" = "mshv" ]]; then
exit 1
fi
# lock the workloads folder to avoid parallel updating by different containers
(
echo "try to lock $WORKLOADS_DIR folder and update"
flock -x 12 && update_workloads
) 12>$WORKLOADS_LOCK
) 12>"$WORKLOADS_LOCK"
# Check if there is any error in the execution of `update_workloads`.
# If there is any error, then kill the shell. Otherwise the script will continue
@@ -236,7 +249,7 @@ fi
export RUST_BACKTRACE=1
cargo build --all --release --target $BUILD_TARGET
cargo build --all --release --target "$BUILD_TARGET"
# Enable KSM with some reasonable parameters so that it won't take too long
# for the memory to be merged between two processes.
@@ -245,19 +258,19 @@ sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs"
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
# Both test_vfio and ovs-dpdk rely on hugepages
HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
PAGE_NUM=`echo $((12288 * 1024 / $HUGEPAGESIZE))`
echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
HUGEPAGESIZE=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE))
echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Run all direct kernel boot (Device Tree) test cases in mod `parallel`
time cargo test "common_parallel::$test_filter" --target $BUILD_TARGET -- ${test_binary_args[*]}
time cargo test "common_parallel::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]}
RES=$?
# Run some tests in sequence since the result could be affected by other tests
# running in parallel.
if [ $RES -eq 0 ]; then
time cargo test "common_sequential::$test_filter" --target $BUILD_TARGET -- --test-threads=1 ${test_binary_args[*]}
time cargo test "common_sequential::$test_filter" --target "$BUILD_TARGET" -- --test-threads=1 ${test_binary_args[*]}
RES=$?
else
exit $RES
@@ -265,7 +278,7 @@ fi
# Run all ACPI test cases
if [ $RES -eq 0 ]; then
time cargo test "aarch64_acpi::$test_filter" --target $BUILD_TARGET -- ${test_binary_args[*]}
time cargo test "aarch64_acpi::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]}
RES=$?
else
exit $RES
@@ -273,14 +286,14 @@ fi
# Run all test cases related to live migration
if [ $RES -eq 0 ]; then
time cargo test "live_migration_parallel::$test_filter" --target $BUILD_TARGET -- ${test_binary_args[*]}
time cargo test "live_migration_parallel::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]}
RES=$?
else
exit $RES
fi
if [ $RES -eq 0 ]; then
time cargo test "live_migration_sequential::$test_filter" --target $BUILD_TARGET -- --test-threads=1 ${test_binary_args[*]}
time cargo test "live_migration_sequential::$test_filter" --target "$BUILD_TARGET" -- --test-threads=1 ${test_binary_args[*]}
RES=$?
else
exit $RES
@@ -288,9 +301,9 @@ fi
# Run tests on dbus_api
if [ $RES -eq 0 ]; then
cargo build --features "dbus_api" --all --release --target $BUILD_TARGET
cargo build --features "dbus_api" --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1
time cargo test "dbus_api::$test_filter" --target $BUILD_TARGET -- ${test_binary_args[*]}
time cargo test "dbus_api::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]}
RES=$?
fi

View File

@@ -1,8 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -12,45 +14,44 @@ process_common_args "$@"
# For now these values are default for kvm
test_features=""
if [ "$hypervisor" = "mshv" ] ; then
if [ "$hypervisor" = "mshv" ]; then
test_features="--features mshv"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
cp scripts/sha1sums-x86_64 "$WORKLOADS_DIR"
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $FOCAL_OS_IMAGE_NAME $FOCAL_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
pushd $WORKLOADS_DIR
grep focal sha1sums-x86_64 | sha1sum --check
if [ $? -ne 0 ]; then
pushd "$WORKLOADS_DIR" || exit
if ! grep focal sha1sums-x86_64 | sha1sum --check; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
popd || exit
# Download Cloud Hypervisor binary from its last stable release
LAST_RELEASE_VERSION="v34.0"
LAST_RELEASE_VERSION="v36.0"
CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static"
CH_RELEASE_NAME="cloud-hypervisor-static"
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $CH_RELEASE_URL -O "$CH_RELEASE_NAME" || exit 1
chmod +x $CH_RELEASE_NAME
popd
popd || exit
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
@@ -60,15 +61,16 @@ fi
CFLAGS=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
# Test ovs-dpdk relies on hugepages
HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
PAGE_NUM=`echo $((12288 * 1024 / $HUGEPAGESIZE))`
echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
HUGEPAGESIZE=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE))
echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1

View File

@@ -1,8 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -12,45 +14,45 @@ process_common_args "$@"
# For now these values are default for kvm
test_features=""
if [ "$hypervisor" = "mshv" ] ; then
if [ "$hypervisor" = "mshv" ]; then
test_features="--features mshv"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
cp scripts/sha1sums-x86_64 "$WORKLOADS_DIR"
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $FOCAL_OS_IMAGE_NAME $FOCAL_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
pushd $WORKLOADS_DIR
grep focal sha1sums-x86_64 | sha1sum --check
if [ $? -ne 0 ]; then
pushd "$WORKLOADS_DIR" || exit
if ! grep focal sha1sums-x86_64 | sha1sum --check; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
popd || exit
build_custom_linux
CFLAGS=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1
time cargo test $test_features "rate_limiter::$test_filter" -- --test-threads=1 ${test_binary_args[*]}

View File

@@ -1,8 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
process_common_args "$@"
@@ -14,36 +16,32 @@ fi
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
FW="$WORKLOADS_DIR/hypervisor-fw"
pushd $WORKLOADS_DIR
rm -f $FW
time wget --quiet $FW_URL || exit 1
popd
download_hypervisor_fw
JAMMY_OS_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.qcow2"
JAMMY_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_IMAGE_NAME"
JAMMY_OS_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $JAMMY_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.raw"
JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $JAMMY_OS_IMAGE_NAME $JAMMY_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
CFLAGS=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1

View File

@@ -1,4 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
# This set of vfio tests require to be ran on a specific machine with
@@ -7,25 +8,23 @@ set -x
# out of the scope of this script, including the custom guest image with
# Nvidia drivers installed, and properly configured Nvidia Tesla T4 card.
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
process_common_args "$@"
WORKLOADS_DIR="$HOME/workloads"
# Always download the latest "hypervisor-fw"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
pushd $WORKLOADS_DIR
time wget --quiet $FW_URL -O hypervisor-fw || exit 1
popd
download_hypervisor_fw
CFLAGS=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1
time cargo test "vfio::test_nvidia" -- --test-threads=1 ${test_binary_args[*]}

View File

@@ -1,9 +1,11 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
source $(dirname "$0")/common-aarch64.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
source "$(dirname "$0")"/common-aarch64.sh
process_common_args "$@"
@@ -27,8 +29,8 @@ if [[ ! -f ${WIN_IMAGE_FILE} || ! -f ${OVMF_FW} ]]; then
fi
# Use device mapper to create a snapshot of the Windows image
img_blk_size=$(du -b -B 512 ${WIN_IMAGE_FILE} | awk '{print $1;}')
loop_device=$(losetup --find --show --read-only ${WIN_IMAGE_FILE})
img_blk_size=$(du -b -B 512 "${WIN_IMAGE_FILE}" | awk '{print $1;}')
loop_device=$(losetup --find --show --read-only "${WIN_IMAGE_FILE}")
dmsetup create windows-base --table "0 $img_blk_size linear $loop_device 0"
dmsetup mknodes
dmsetup create windows-snapshot-base --table "0 $img_blk_size snapshot-origin /dev/mapper/windows-base"
@@ -36,11 +38,11 @@ dmsetup mknodes
export RUST_BACKTRACE=1
cargo build --all --release --target $BUILD_TARGET
cargo build --all --release --target "$BUILD_TARGET"
# Only run with 1 thread to avoid tests interfering with one another because
# Windows has a static IP configured
time cargo test "windows::$test_filter" --target $BUILD_TARGET -- ${test_binary_args[*]}
time cargo test "windows::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]}
RES=$?
dmsetup remove_all -f

View File

@@ -1,29 +1,27 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
process_common_args "$@"
# For now these values are default for kvm
test_features=""
if [ "$hypervisor" = "mshv" ] ; then
if [ "$hypervisor" = "mshv" ]; then
test_features="--features mshv"
fi
WIN_IMAGE_FILE="/root/workloads/windows-server-2022-amd64-2.raw"
WORKLOADS_DIR="/root/workloads"
OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
if [ ! -f "$OVMF_FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $OVMF_FW_URL || exit 1
popd
fi
download_ovmf
CFLAGS=""
if [[ "${BUILD_TARGET}" == "x86_64-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/x86_64-linux-musl/ -idirafter /usr/include/"
fi
@@ -41,7 +39,7 @@ dmsetup mknodes
dmsetup create windows-snapshot-base --table "0 $img_blk_size snapshot-origin /dev/mapper/windows-base"
dmsetup mknodes
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1

View File

@@ -1,8 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2048,SC2086
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -12,103 +14,90 @@ process_common_args "$@"
# For now these values are default for kvm
test_features=""
if [ "$hypervisor" = "mshv" ] ; then
if [ "$hypervisor" = "mshv" ]; then
test_features="--features mshv"
fi
cp scripts/sha1sums-x86_64 $WORKLOADS_DIR
cp scripts/sha1sums-x86_64 "$WORKLOADS_DIR"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
FW="$WORKLOADS_DIR/hypervisor-fw"
if [ ! -f "$FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $FW_URL || exit 1
popd
fi
download_hypervisor_fw
OVMF_FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/edk2/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
if [ ! -f "$OVMF_FW" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $OVMF_FW_URL || exit 1
popd
fi
download_ovmf
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $FOCAL_OS_IMAGE_NAME $FOCAL_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
FOCAL_OS_QCOW_BACKING_FILE_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0-backing.qcow2"
FOCAL_OS_QCOW_BACKING_FILE_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_QCOW_BACKING_FILE_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_QCOW_BACKING_FILE_IMAGE" ]; then
pushd $WORKLOADS_DIR
time qemu-img create -f qcow2 -b $FOCAL_OS_IMAGE -F qcow2 $FOCAL_OS_QCOW_BACKING_FILE_IMAGE_NAME
popd
pushd "$WORKLOADS_DIR" || exit
time qemu-img create -f qcow2 -b "$FOCAL_OS_IMAGE" -F qcow2 $FOCAL_OS_QCOW_BACKING_FILE_IMAGE_NAME
popd || exit
fi
JAMMY_OS_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.qcow2"
JAMMY_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$JAMMY_OS_IMAGE_NAME"
JAMMY_OS_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $JAMMY_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-amd64-custom-20230119-0.raw"
JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME"
if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $JAMMY_OS_IMAGE_NAME $JAMMY_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
ALPINE_MINIROOTFS_URL="http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-minirootfs-3.11.3-x86_64.tar.gz"
ALPINE_MINIROOTFS_TARBALL="$WORKLOADS_DIR/alpine-minirootfs-x86_64.tar.gz"
if [ ! -f "$ALPINE_MINIROOTFS_TARBALL" ]; then
pushd $WORKLOADS_DIR
time wget --quiet $ALPINE_MINIROOTFS_URL -O $ALPINE_MINIROOTFS_TARBALL || exit 1
popd
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $ALPINE_MINIROOTFS_URL -O "$ALPINE_MINIROOTFS_TARBALL" || exit 1
popd || exit
fi
ALPINE_INITRAMFS_IMAGE="$WORKLOADS_DIR/alpine_initramfs.img"
if [ ! -f "$ALPINE_INITRAMFS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
mkdir alpine-minirootfs
tar xf "$ALPINE_MINIROOTFS_TARBALL" -C alpine-minirootfs
cat > alpine-minirootfs/init <<-EOF
cat >alpine-minirootfs/init <<-EOF
#! /bin/sh
mount -t devtmpfs dev /dev
echo \$TEST_STRING > /dev/console
poweroff -f
EOF
chmod +x alpine-minirootfs/init
cd alpine-minirootfs
cd alpine-minirootfs || exit
find . -print0 |
cpio --null --create --verbose --owner root:root --format=newc > "$ALPINE_INITRAMFS_IMAGE"
popd
cpio --null --create --verbose --owner root:root --format=newc >"$ALPINE_INITRAMFS_IMAGE"
popd || exit
fi
pushd $WORKLOADS_DIR
sha1sum sha1sums-x86_64 --check
if [ $? -ne 0 ]; then
pushd "$WORKLOADS_DIR" || exit
if ! sha1sum sha1sums-x86_64 --check; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
popd || exit
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
@@ -119,52 +108,51 @@ fi
VIRTIOFSD="$WORKLOADS_DIR/virtiofsd"
VIRTIOFSD_DIR="virtiofsd_build"
if [ ! -f "$VIRTIOFSD" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
git clone "https://gitlab.com/virtio-fs/virtiofsd.git" $VIRTIOFSD_DIR
pushd $VIRTIOFSD_DIR
git checkout v1.1.0
pushd $VIRTIOFSD_DIR || exit
git checkout v1.8.0
time cargo build --release
cp target/release/virtiofsd $VIRTIOFSD || exit 1
popd
cp target/release/virtiofsd "$VIRTIOFSD" || exit 1
popd || exit
rm -rf $VIRTIOFSD_DIR
popd
popd || exit
fi
BLK_IMAGE="$WORKLOADS_DIR/blk.img"
MNT_DIR="mount_image"
if [ ! -f "$BLK_IMAGE" ]; then
pushd $WORKLOADS_DIR
fallocate -l 16M $BLK_IMAGE
mkfs.ext4 -j $BLK_IMAGE
mkdir $MNT_DIR
sudo mount -t ext4 $BLK_IMAGE $MNT_DIR
sudo bash -c "echo bar > $MNT_DIR/foo" || exit 1
sudo umount $BLK_IMAGE
rm -r $MNT_DIR
popd
pushd "$WORKLOADS_DIR" || exit
fallocate -l 16M "$BLK_IMAGE"
mkfs.ext4 -j "$BLK_IMAGE"
mkdir $MNT_DIR
sudo mount -t ext4 "$BLK_IMAGE" $MNT_DIR
sudo bash -c "echo bar > $MNT_DIR/foo" || exit 1
sudo umount "$BLK_IMAGE"
rm -r $MNT_DIR
popd || exit
fi
SHARED_DIR="$WORKLOADS_DIR/shared_dir"
if [ ! -d "$SHARED_DIR" ]; then
mkdir -p $SHARED_DIR
echo "foo" > "$SHARED_DIR/file1"
echo "bar" > "$SHARED_DIR/file3" || exit 1
mkdir -p "$SHARED_DIR"
echo "foo" >"$SHARED_DIR/file1"
echo "bar" >"$SHARED_DIR/file3" || exit 1
fi
VFIO_DIR="$WORKLOADS_DIR/vfio"
VFIO_DISK_IMAGE="$WORKLOADS_DIR/vfio.img"
rm -rf $VFIO_DIR $VFIO_DISK_IMAGE
mkdir -p $VFIO_DIR
cp $FOCAL_OS_RAW_IMAGE $VFIO_DIR
cp $FW $VFIO_DIR
cp $VMLINUX_IMAGE $VFIO_DIR || exit 1
rm -rf "$VFIO_DIR" "$VFIO_DISK_IMAGE"
mkdir -p "$VFIO_DIR"
cp "$FOCAL_OS_RAW_IMAGE" "$VFIO_DIR"
cp "$FW" "$VFIO_DIR"
cp "$VMLINUX_IMAGE" "$VFIO_DIR" || exit 1
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
# We always copy a fresh version of our binary for our L2 guest.
cp target/$BUILD_TARGET/release/cloud-hypervisor $VFIO_DIR
cp target/$BUILD_TARGET/release/ch-remote $VFIO_DIR
cp target/"$BUILD_TARGET"/release/cloud-hypervisor "$VFIO_DIR"
cp target/"$BUILD_TARGET"/release/ch-remote "$VFIO_DIR"
# Enable KSM with some reasonable parameters so that it won't take too long
# for the memory to be merged between two processes.
@@ -173,9 +161,9 @@ sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs"
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
# Both test_vfio, ovs-dpdk and vDPA tests rely on hugepages
HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
PAGE_NUM=`echo $((12288 * 1024 / $HUGEPAGESIZE))`
echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
HUGEPAGESIZE=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE))
echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Update max locked memory to 'unlimited' to avoid issues with vDPA
@@ -198,7 +186,7 @@ fi
# Run tests on dbus_api
if [ $RES -eq 0 ]; then
cargo build --features "mshv,dbus_api" --all --release --target $BUILD_TARGET
cargo build --features "mshv,dbus_api" --all --release --target "$BUILD_TARGET"
export RUST_BACKTRACE=1
# integration tests now do not reply on build feature "dbus_api"
time cargo test $test_features "dbus_api::$test_filter" -- ${test_binary_args[*]}

View File

@@ -1,10 +1,12 @@
#!/bin/bash
#!/usr/bin/env bash
set -x
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
export TEST_ARCH=$(uname -m)
TEST_ARCH=$(uname -m)
export TEST_ARCH
WORKLOADS_DIR="$HOME/workloads"
mkdir -p "$WORKLOADS_DIR"
@@ -15,34 +17,34 @@ build_fio() {
checkout_repo "$FIO_DIR" "$FIO_REPO" master "1953e1adb5a28ed21370e85991d7f5c3cdc699f3"
if [ ! -f "$FIO_DIR/.built" ]; then
pushd $FIO_DIR
pushd "$FIO_DIR" || exit
./configure
make -j `nproc`
make -j "$(nproc)"
cp fio "$WORKLOADS_DIR/fio"
touch .built
popd
popd || exit
fi
}
process_common_args "$@"
cp scripts/sha1sums-${TEST_ARCH} $WORKLOADS_DIR
cp scripts/sha1sums-"${TEST_ARCH}" "$WORKLOADS_DIR"
if [ ${TEST_ARCH} == "aarch64" ]; then
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.qcow2"
if [ "${TEST_ARCH}" == "aarch64" ]; then
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.qcow2"
else
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
FOCAL_OS_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.qcow2"
fi
FOCAL_OS_IMAGE_URL="https://cloud-hypervisor.azureedge.net/$FOCAL_OS_IMAGE_NAME"
FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time wget --quiet $FOCAL_OS_IMAGE_URL || exit 1
popd
popd || exit
fi
if [ ${TEST_ARCH} == "aarch64" ]; then
if [ "${TEST_ARCH}" == "aarch64" ]; then
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.raw"
else
FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-amd64-custom-20210609-0.raw"
@@ -50,20 +52,19 @@ fi
FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME"
if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
pushd "$WORKLOADS_DIR" || exit
time qemu-img convert -p -f qcow2 -O raw $FOCAL_OS_IMAGE_NAME $FOCAL_OS_RAW_IMAGE_NAME || exit 1
popd
popd || exit
fi
pushd $WORKLOADS_DIR
grep focal sha1sums-${TEST_ARCH} | sha1sum --check
if [ $? -ne 0 ]; then
pushd "$WORKLOADS_DIR" || exit
if ! grep focal sha1sums-"${TEST_ARCH}" | sha1sum --check; then
echo "sha1sum validation of images failed, remove invalid images to fix the issue."
exit 1
fi
popd
popd || exit
if [ ${TEST_ARCH} == "aarch64" ]; then
if [ "${TEST_ARCH}" == "aarch64" ]; then
build_fio
# Update the fio in the cloud image to use io_uring on AArch64
@@ -84,15 +85,16 @@ build_custom_linux
CFLAGS=""
if [[ "${BUILD_TARGET}" == "${TEST_ARCH}-unknown-linux-musl" ]]; then
# shellcheck disable=SC2034
CFLAGS="-I /usr/include/${TEST_ARCH}-linux-musl/ -idirafter /usr/include/"
fi
cargo build --features mshv --all --release --target $BUILD_TARGET
cargo build --features mshv --all --release --target "$BUILD_TARGET"
# setup hugepages
HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
PAGE_NUM=`echo $((12288 * 1024 / $HUGEPAGESIZE))`
echo $PAGE_NUM | sudo tee /proc/sys/vm/nr_hugepages
HUGEPAGESIZE=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE))
echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
if [ -n "$test_filter" ]; then
@@ -100,15 +102,16 @@ if [ -n "$test_filter" ]; then
fi
# Ensure that git commands can be run in this directory (for metrics report)
git config --global --add safe.directory $PWD
git config --global --add safe.directory "$PWD"
RUST_BACKTRACE_VALUE=`echo $RUST_BACKTRACE`
if [ -z $RUST_BACKTRACE_VALUE ];then
export RUST_BACKTRACE=1
RUST_BACKTRACE_VALUE=$RUST_BACKTRACE
if [ -z "$RUST_BACKTRACE_VALUE" ]; then
export RUST_BACKTRACE=1
else
echo "RUST_BACKTRACE is set to: $RUST_BACKTRACE_VALUE"
echo "RUST_BACKTRACE is set to: $RUST_BACKTRACE_VALUE"
fi
time target/$BUILD_TARGET/release/performance-metrics ${test_binary_args[*]}
# shellcheck disable=SC2048,SC2086
time target/"$BUILD_TARGET"/release/performance-metrics ${test_binary_args[*]}
RES=$?
exit $RES

View File

@@ -1,5 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
set -x
sudo docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli validate -i /local/vmm/src/api/openapi/cloud-hypervisor.yaml
sudo docker run --rm -v "${PWD}":/local openapitools/openapi-generator-cli validate -i /local/vmm/src/api/openapi/cloud-hypervisor.yaml

View File

@@ -1,12 +1,15 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2068
source $HOME/.cargo/env
source $(dirname "$0")/test-util.sh
# shellcheck source=/dev/null
source "$HOME"/.cargo/env
source "$(dirname "$0")"/test-util.sh
process_common_args "$@"
cargo_args=("")
# shellcheck disable=SC2154
if [[ $hypervisor = "mshv" ]]; then
cargo_args+=("--features $hypervisor")
elif [[ $(uname -m) = "x86_64" ]]; then
@@ -14,5 +17,5 @@ elif [[ $(uname -m) = "x86_64" ]]; then
fi
export RUST_BACKTRACE=1
cargo test --lib --bins --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1
cargo test --doc --target $BUILD_TARGET --workspace ${cargo_args[@]} || exit 1
cargo test --lib --bins --target "$BUILD_TARGET" --workspace ${cargo_args[@]} || exit 1
cargo test --doc --target "$BUILD_TARGET" --workspace ${cargo_args[@]} || exit 1

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
hypervisor="kvm"
test_filter=""
@@ -18,13 +18,13 @@ checkout_repo() {
# If commit is not specified, compare local HEAD and remote HEAD.
# Remove the folder if there is difference.
if [ -d "$SRC_DIR" ]; then
pushd $SRC_DIR
pushd "$SRC_DIR" || exit
git fetch
SRC_LOCAL_COMMIT=$(git rev-parse HEAD)
if [ -z "$GIT_COMMIT" ]; then
GIT_COMMIT=$(git rev-parse remotes/origin/"$GIT_BRANCH")
fi
popd
popd || exit
if [ "$SRC_LOCAL_COMMIT" != "$GIT_COMMIT" ]; then
rm -rf "$SRC_DIR"
fi
@@ -34,10 +34,10 @@ checkout_repo() {
if [ ! -d "$SRC_DIR" ]; then
git clone --depth 1 "$GIT_URL" -b "$GIT_BRANCH" "$SRC_DIR"
if [ "$GIT_COMMIT" ]; then
pushd "$SRC_DIR"
pushd "$SRC_DIR" || exit
git fetch --depth 1 origin "$GIT_COMMIT"
git reset --hard FETCH_HEAD
popd
popd || exit
fi
fi
}
@@ -51,23 +51,23 @@ build_custom_linux() {
checkout_repo "$LINUX_CUSTOM_DIR" "$LINUX_CUSTOM_URL" "$LINUX_CUSTOM_BRANCH"
cp $SRCDIR/resources/linux-config-${ARCH} $LINUX_CUSTOM_DIR/.config
cp "$SRCDIR"/resources/linux-config-"${ARCH}" "$LINUX_CUSTOM_DIR"/.config
pushd $LINUX_CUSTOM_DIR
make -j `nproc`
if [ ${ARCH} == "x86_64" ]; then
cp vmlinux "$WORKLOADS_DIR/" || exit 1
elif [ ${ARCH} == "aarch64" ]; then
cp arch/arm64/boot/Image "$WORKLOADS_DIR/" || exit 1
cp arch/arm64/boot/Image.gz "$WORKLOADS_DIR/" || exit 1
pushd "$LINUX_CUSTOM_DIR" || exit
make -j "$(nproc)"
if [ "${ARCH}" == "x86_64" ]; then
cp vmlinux "$WORKLOADS_DIR/" || exit 1
elif [ "${ARCH}" == "aarch64" ]; then
cp arch/arm64/boot/Image "$WORKLOADS_DIR/" || exit 1
cp arch/arm64/boot/Image.gz "$WORKLOADS_DIR/" || exit 1
fi
popd
popd || exit
}
cmd_help() {
echo ""
echo "Cloud Hypervisor $(basename $0)"
echo "Usage: $(basename $0) [<args>]"
echo "Cloud Hypervisor $(basename "$0")"
echo "Usage: $(basename "$0") [<args>]"
echo ""
echo "Available arguments:"
echo ""
@@ -80,30 +80,61 @@ cmd_help() {
process_common_args() {
while [ $# -gt 0 ]; do
case "$1" in
"-h"|"--help") { cmd_help; exit 1; } ;;
"--hypervisor")
shift
hypervisor="$1"
;;
"--test-filter")
shift
test_filter="$1"
;;
"--") {
shift
break
} ;;
*)
echo "Unknown test scripts argument: $1. Please use '-- --help' for help."
exit
;;
esac
shift
case "$1" in
"-h" | "--help") {
cmd_help
exit 1
} ;;
"--hypervisor")
shift
hypervisor="$1"
;;
"--test-filter")
shift
# shellcheck disable=SC2034
test_filter="$1"
;;
"--") {
shift
break
} ;;
*)
echo "Unknown test scripts argument: $1. Please use '-- --help' for help."
exit
;;
esac
shift
done
if [[ ! ("$hypervisor" = "kvm" || "$hypervisor" = "mshv") ]]; then
if [[ ! ("$hypervisor" = "kvm" || "$hypervisor" = "mshv") ]]; then
die "Hypervisor value must be kvm or mshv"
fi
test_binary_args=($@)
# shellcheck disable=SC2034
test_binary_args=("$@")
}
download_hypervisor_fw() {
if [ -n "$AUTH_DOWNLOAD_TOKEN" ]; then
echo "Using authenticated download from GitHub"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest \
--header "Authorization: Token $AUTH_DOWNLOAD_TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28" | grep "browser_download_url" | grep -o 'https://.*[^ "]')
else
echo "Using anonymous download from GitHub"
FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/latest | grep "browser_download_url" | grep -o 'https://.*[^ "]')
fi
FW="$WORKLOADS_DIR/hypervisor-fw"
pushd "$WORKLOADS_DIR" || exit
rm -f "$FW"
time wget --quiet "$FW_URL" || exit 1
popd || exit
}
download_ovmf() {
OVMF_FW_TAG="ch-6624aa331f"
OVMF_FW_URL="https://github.com/cloud-hypervisor/edk2/releases/download/$OVMF_FW_TAG/CLOUDHV.fd"
OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
pushd "$WORKLOADS_DIR" || exit
rm -f "$OVMF_FW"
time wget --quiet $OVMF_FW_URL || exit 1
popd || exit
}

View File

@@ -20,6 +20,7 @@ use std::sync::{Arc, Mutex};
use thiserror::Error;
#[cfg(feature = "dbus_api")]
use vmm::api::dbus::{dbus_api_graceful_shutdown, DBusApiOptions};
use vmm::api::ApiAction;
use vmm::config;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::signal::block_signal;
@@ -240,6 +241,13 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
.num_args(1)
.group("vm-config"),
)
.arg(
Arg::new("rate-limit-group")
.long("rate-limit-group")
.help(config::RateLimiterGroupConfig::SYNTAX)
.num_args(1..)
.group("vm-config"),
)
.arg(
Arg::new("disk")
.long("disk")
@@ -410,6 +418,15 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
.group("vm-config"),
);
#[cfg(target_arch = "x86_64")]
let app = app.arg(
Arg::new("debug-console")
.long("debug-console")
.help("Debug console: off|pty|tty|file=</path/to/a/file>,iobase=<port in hex>")
.default_value("off,iobase=0xe9")
.group("vm-config"),
);
#[cfg(feature = "guest_debug")]
let app = app.arg(
Arg::new("gdb")
@@ -443,7 +460,14 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
.num_args(0)
.group("vmm-config"),
);
#[cfg(feature = "igvm")]
let app = app.arg(
Arg::new("igvm")
.long("igvm")
.help("Path to IGVM file to load.")
.num_args(1)
.group("vm-config"),
);
app.arg(
Arg::new("version")
.short('V')
@@ -598,6 +622,7 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(parser.get("path").unwrap())
.map_err(Error::EventMonitorIo)?,
))
@@ -672,6 +697,11 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
.map_err(Error::StartVmmThread)?;
let r: Result<(), Error> = (|| {
#[cfg(feature = "igvm")]
let payload_present = cmd_arguments.contains_id("kernel")
|| cmd_arguments.contains_id("firmware")
|| cmd_arguments.contains_id("igvm");
#[cfg(not(feature = "igvm"))]
let payload_present =
cmd_arguments.contains_id("kernel") || cmd_arguments.contains_id("firmware");
@@ -681,22 +711,24 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
// Create and boot the VM based off the VM config we just built.
let sender = api_request_sender.clone();
vmm::api::vm_create(
api_evt.try_clone().unwrap(),
api_request_sender,
Arc::new(Mutex::new(vm_config)),
)
.map_err(Error::VmCreate)?;
vmm::api::vm_boot(api_evt.try_clone().unwrap(), sender).map_err(Error::VmBoot)?;
vmm::api::VmCreate
.send(
api_evt.try_clone().unwrap(),
api_request_sender,
Arc::new(Mutex::new(vm_config)),
)
.map_err(Error::VmCreate)?;
vmm::api::VmBoot
.send(api_evt.try_clone().unwrap(), sender, ())
.map_err(Error::VmBoot)?;
} else if let Some(restore_params) = cmd_arguments.get_one::<String>("restore") {
vmm::api::vm_restore(
api_evt.try_clone().unwrap(),
api_request_sender,
Arc::new(
vmm::api::VmRestore
.send(
api_evt.try_clone().unwrap(),
api_request_sender,
config::RestoreConfig::parse(restore_params).map_err(Error::ParsingRestore)?,
),
)
.map_err(Error::VmRestore)?;
)
.map_err(Error::VmRestore)?;
}
Ok(())
@@ -726,6 +758,9 @@ fn main() {
#[cfg(all(feature = "tdx", feature = "sev_snp"))]
compile_error!("Feature 'tdx' and 'sev_snp' are mutually exclusive.");
#[cfg(all(feature = "sev_snp", not(target_arch = "x86_64")))]
compile_error!("Feature 'sev_snp' needs target 'x86_64'");
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();
@@ -772,6 +807,8 @@ mod unit_tests {
ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, PayloadConfig,
RngConfig, VmConfig, VmParams,
};
#[cfg(target_arch = "x86_64")]
use vmm::vm_config::DebugConsoleConfig;
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
@@ -833,8 +870,13 @@ mod unit_tests {
},
payload: Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
..Default::default()
firmware: None,
cmdline: None,
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
}),
rate_limit_groups: None,
disks: None,
net: None,
rng: RngConfig {
@@ -856,6 +898,8 @@ mod unit_tests {
iommu: false,
socket: None,
},
#[cfg(target_arch = "x86_64")]
debug_console: DebugConsoleConfig::default(),
devices: None,
user_devices: None,
vdpa: None,
@@ -1106,6 +1150,29 @@ mod unit_tests {
}"#,
true,
),
(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--disk",
"path=/path/to/disk/1,rate_limit_group=group0",
"path=/path/to/disk/2,rate_limit_group=group0",
"--rate-limit-group",
"id=group0,bw_size=1000,bw_refill_time=100",
],
r#"{
"payload": {"kernel": "/path/to/kernel"},
"disks": [
{"path": "/path/to/disk/1", "rate_limit_group": "group0"},
{"path": "/path/to/disk/2", "rate_limit_group": "group0"}
],
"rate_limit_groups": [
{"id": "group0", "rate_limiter_config": {"bandwidth": {"size": 1000, "one_time_burst": 0, "refill_time": 100}}}
]
}"#,
true,
),
]
.iter()
.for_each(|(cli, openapi, equal)| {
@@ -1464,6 +1531,30 @@ mod unit_tests {
});
}
#[cfg(target_arch = "x86_64")]
#[test]
fn test_valid_vm_config_debug_console() {
[(
vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--debug-console",
"tty,iobase=0xe9",
],
// 233 == 0xe9
r#"{
"payload": {"kernel": "/path/to/kernel" },
"debug_console": {"mode": "Tty", "iobase": 233 }
}"#,
true,
)]
.iter()
.for_each(|(cli, openapi, equal)| {
compare_vm_config_cli_vs_json(cli, openapi, *equal);
});
}
#[test]
fn test_valid_vm_config_serial_console() {
[

View File

@@ -7,10 +7,10 @@ edition = "2021"
[dependencies]
dirs = "5.0.0"
epoll = "4.3.3"
libc = "0.2.147"
once_cell = "1.18.0"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
libc = "0.2.153"
once_cell = "1.19.0"
serde = { version = "1.0.196", features = ["rc", "derive"] }
serde_json = "1.0.109"
ssh2 = { version = "0.9.4", features = ["vendored-openssl"] }
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"
wait-timeout = "0.2.0"

View File

@@ -90,7 +90,7 @@ impl GuestNetworkConfig {
None => DEFAULT_TCP_LISTENER_TIMEOUT,
};
match (|| -> Result<(), WaitForBootError> {
let mut closure = || -> Result<(), WaitForBootError> {
let listener =
TcpListener::bind(listen_addr.as_str()).map_err(WaitForBootError::Listen)?;
listener
@@ -143,17 +143,19 @@ impl GuestNetworkConfig {
Err(WaitForBootError::Accept(e))
}
}
})() {
};
match closure() {
Err(e) => {
let duration = start.elapsed();
eprintln!(
"\n\n==== Start 'wait_vm_boot' (FAILED) ====\n\n\
duration =\"{duration:?}, timeout = {timeout}s\"\n\
listen_addr=\"{listen_addr}\"\n\
expected_guest_addr=\"{expected_guest_addr}\"\n\
message=\"{s}\"\n\
error=\"{e:?}\"\n\
\n==== End 'wait_vm_boot' outout ====\n\n"
"\n\n==== Start 'wait_vm_boot' (FAILED) ==== \
\n\nduration =\"{duration:?}, timeout = {timeout}s\" \
\nlisten_addr=\"{listen_addr}\" \
\nexpected_guest_addr=\"{expected_guest_addr}\" \
\nmessage=\"{s}\" \
\nerror=\"{e:?}\" \
\n\n==== End 'wait_vm_boot' outout ====\n\n"
);
Err(e)
@@ -559,7 +561,7 @@ fn scp_to_guest_with_auth(
) -> Result<(), SshCommandError> {
let mut counter = 0;
loop {
match (|| -> Result<(), SshCommandError> {
let closure = || -> Result<(), SshCommandError> {
let tcp =
TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?;
let mut sess = Session::new().unwrap();
@@ -592,7 +594,9 @@ fn scp_to_guest_with_auth(
let _ = channel.wait_close();
Ok(())
})() {
};
match closure() {
Ok(_) => break,
Err(e) => {
counter += 1;
@@ -647,7 +651,7 @@ pub fn ssh_command_ip_with_auth(
let mut counter = 0;
loop {
match (|| -> Result<(), SshCommandError> {
let mut closure = || -> Result<(), SshCommandError> {
let tcp =
TcpStream::connect(format!("{ip}:22")).map_err(SshCommandError::Connection)?;
let mut sess = Session::new().unwrap();
@@ -676,7 +680,9 @@ pub fn ssh_command_ip_with_auth(
} else {
Ok(())
}
})() {
};
match closure() {
Ok(_) => break,
Err(e) => {
counter += 1;
@@ -718,18 +724,77 @@ pub fn ssh_command_ip(
)
}
pub fn exec_host_command_with_retries(command: &str, retries: u32, interval: Duration) -> bool {
for _ in 0..retries {
let s = exec_host_command_output(command).status;
if !s.success() {
eprintln!("\n\n==== retrying in {:?} ===\n\n", interval);
thread::sleep(interval);
} else {
return true;
}
}
false
}
pub fn exec_host_command_status(command: &str) -> ExitStatus {
std::process::Command::new("bash")
.args(["-c", command])
.status()
.unwrap_or_else(|_| panic!("Expected '{command}' to run"))
exec_host_command_output(command).status
}
pub fn exec_host_command_output(command: &str) -> Output {
std::process::Command::new("bash")
let output = std::process::Command::new("bash")
.args(["-c", command])
.output()
.unwrap_or_else(|_| panic!("Expected '{command}' to run"))
.unwrap_or_else(|e| panic!("Expected '{command}' to run. Error: {:?}", e));
if !output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!(
"\n\n==== Start 'exec_host_command' failed ==== \
\n\n---stdout---\n{stdout}\n---stderr---{stderr} \
\n\n==== End 'exec_host_command' failed ====",
);
}
output
}
pub fn check_lines_count(input: &str, line_count: usize) -> bool {
if input.lines().count() == line_count {
true
} else {
eprintln!(
"\n\n==== Start 'check_lines_count' failed ==== \
\n\ninput = {input}\nline_count = {line_count} \
\n\n==== End 'check_lines_count' failed ====",
);
false
}
}
pub fn check_matched_lines_count(input: &str, keywords: Vec<&str>, line_count: usize) -> bool {
let mut matches = String::new();
for line in input.lines() {
if keywords.iter().all(|k| line.contains(k)) {
matches += line;
}
}
if matches.lines().count() == line_count {
true
} else {
eprintln!(
"\n\n==== Start 'check_matched_lines_count' failed ==== \
\nkeywords = {keywords:?}, line_count = {line_count} \
\n\ninput = {input} matches = {matches} \
\n\n==== End 'check_matched_lines_count' failed ====",
);
false
}
}
pub const PIPE_SIZE: i32 = 32 << 20;
@@ -1337,7 +1402,7 @@ pub fn parse_iperf3_output(output: &[u8], sender: bool, bandwidth: bool) -> Resu
})
.map_err(|_| {
eprintln!(
"=============== iperf3 output ===============\n\n{}\n\n===========end============\n\n",
"==== Start iperf3 output ===\n\n{}\n\n=== End iperf3 output ===\n\n",
String::from_utf8_lossy(output)
);
Error::Iperf3Parse
@@ -1415,9 +1480,7 @@ pub fn parse_fio_output(output: &str, fio_ops: &FioOps, num_jobs: u32) -> Result
total_bps
})
.map_err(|_| {
eprintln!(
"=============== Fio output ===============\n\n{output}\n\n===========end============\n\n"
);
eprintln!("=== Start Fio output ===\n\n{output}\n\n=== End Fio output ===\n\n");
Error::FioOutputParse
})
}
@@ -1470,9 +1533,7 @@ pub fn parse_fio_output_iops(output: &str, fio_ops: &FioOps, num_jobs: u32) -> R
total_iops
})
.map_err(|_| {
eprintln!(
"=============== Fio output ===============\n\n{output}\n\n===========end============\n\n"
);
eprintln!("=== Start Fio output ===\n\n{output}\n\n=== End Fio output ===\n\n");
Error::FioOutputParse
})
}
@@ -1605,7 +1666,7 @@ pub fn parse_ethr_latency_output(output: &[u8]) -> Result<Vec<f64>, Error> {
})
.map_err(|_| {
eprintln!(
"=============== ethr output ===============\n\n{}\n\n===========end============\n\n",
"=== Start ethr output ===\n\n{}\n\n=== End ethr output ===\n\n",
String::from_utf8_lossy(output)
);
Error::EthrLogParse

View File

@@ -687,6 +687,8 @@ fn resize_command(
device_id: None,
},
];
// See: #5938
thread::sleep(std::time::Duration::new(1, 0));
assert!(check_latest_events_exact(&latest_events, event_path));
}
@@ -858,6 +860,7 @@ fn fw_path(_fw_type: FwType) -> String {
fw_path.to_str().unwrap().to_string()
}
#[derive(Debug)]
struct MetaEvent {
event: String,
device_id: Option<String>,
@@ -910,7 +913,18 @@ fn check_sequential_events(expected_events: &[&MetaEvent], event_file: &str) ->
}
}
idx == len
let ret = idx == len;
if !ret {
eprintln!(
"\n\n==== Start 'check_sequential_events' failed ==== \
\n\nexpected_events={:?}\nactual_events={:?} \
\n\n==== End 'check_sequential_events' failed ====",
expected_events, json_events,
);
}
ret
}
// Return true if all events from the input 'expected_events' are matched exactly
@@ -922,6 +936,13 @@ fn check_sequential_events_exact(expected_events: &[&MetaEvent], event_file: &st
for (idx, e) in json_events.iter().enumerate() {
if !expected_events[idx].match_with_json_event(e) {
eprintln!(
"\n\n==== Start 'check_sequential_events_exact' failed ==== \
\n\nexpected_events={:?}\nactual_events={:?} \
\n\n==== End 'check_sequential_events_exact' failed ====",
expected_events, json_events,
);
return false;
}
}
@@ -938,6 +959,13 @@ fn check_latest_events_exact(latest_events: &[&MetaEvent], event_file: &str) ->
for (idx, e) in json_events.iter().enumerate() {
if !latest_events[idx].match_with_json_event(e) {
eprintln!(
"\n\n==== Start 'check_latest_events_exact' failed ==== \
\n\nexpected_events={:?}\nactual_events={:?} \
\n\n==== End 'check_latest_events_exact' failed ====",
latest_events, json_events,
);
return false;
}
}
@@ -1007,6 +1035,40 @@ fn test_cpu_topology(threads_per_core: u8, cores_per_package: u8, packages: u8,
.unwrap_or(0),
packages
);
#[cfg(target_arch = "x86_64")]
{
let mut cpu_id = 0;
for package_id in 0..packages {
for core_id in 0..cores_per_package {
for _ in 0..threads_per_core {
assert_eq!(
guest
.ssh_command(&format!("cat /sys/devices/system/cpu/cpu{cpu_id}/topology/physical_package_id"))
.unwrap()
.trim()
.parse::<u8>()
.unwrap_or(0),
package_id
);
assert_eq!(
guest
.ssh_command(&format!(
"cat /sys/devices/system/cpu/cpu{cpu_id}/topology/core_id"
))
.unwrap()
.trim()
.parse::<u8>()
.unwrap_or(0),
core_id
);
cpu_id += 1;
}
}
}
}
});
let _ = child.kill();
@@ -2057,7 +2119,7 @@ fn pty_read(mut pty: std::fs::File) -> Receiver<String> {
thread::sleep(std::time::Duration::new(1, 0));
let mut buf = [0; 512];
match pty.read(&mut buf) {
Ok(_) => {
Ok(_bytes) => {
let output = std::str::from_utf8(&buf).unwrap().to_string();
match tx.send(output) {
Ok(_) => (),
@@ -2513,7 +2575,63 @@ mod common_parallel {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
#[test]
fn test_virtio_queue_affinity() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
// We need the host to have at least 4 CPUs if we want to be able
// to run this test.
let host_cpus_count = exec_host_command_output("nproc");
assert!(
String::from_utf8_lossy(&host_cpus_count.stdout)
.trim()
.parse::<u16>()
.unwrap_or(0)
>= 4
);
let mut child = GuestCommand::new(&guest)
.args(["--cpus", "boot=4"])
.args(["--memory", "size=512M"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args([
"--disk",
format!(
"path={}",
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
)
.as_str(),
format!(
"path={},num_queues=4,queue_affinity=[0@[0,2],1@[1,3],2@[1],3@[3]]",
guest.disk_config.disk(DiskType::CloudInit).unwrap()
)
.as_str(),
])
.default_net()
.capture_output()
.spawn()
.unwrap();
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
let pid = child.id();
let taskset_q0 = exec_host_command_output(format!("taskset -pc $(ps -T -p {pid} | grep disk1_q0 | xargs | cut -f 2 -d \" \") | cut -f 6 -d \" \"").as_str());
assert_eq!(String::from_utf8_lossy(&taskset_q0.stdout).trim(), "0,2");
let taskset_q1 = exec_host_command_output(format!("taskset -pc $(ps -T -p {pid} | grep disk1_q1 | xargs | cut -f 2 -d \" \") | cut -f 6 -d \" \"").as_str());
assert_eq!(String::from_utf8_lossy(&taskset_q1.stdout).trim(), "1,3");
let taskset_q2 = exec_host_command_output(format!("taskset -pc $(ps -T -p {pid} | grep disk1_q2 | xargs | cut -f 2 -d \" \") | cut -f 6 -d \" \"").as_str());
assert_eq!(String::from_utf8_lossy(&taskset_q2.stdout).trim(), "1");
let taskset_q3 = exec_host_command_output(format!("taskset -pc $(ps -T -p {pid} | grep disk1_q3 | xargs | cut -f 2 -d \" \") | cut -f 6 -d \" \"").as_str());
assert_eq!(String::from_utf8_lossy(&taskset_q3.stdout).trim(), "3");
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
@@ -3405,16 +3523,19 @@ mod common_parallel {
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_default() {
test_vhost_user_blk(2, false, false, Some(&prepare_vubd))
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_readonly() {
test_vhost_user_blk(1, true, false, Some(&prepare_vubd))
}
#[test]
#[cfg(not(target_arch = "aarch64"))]
fn test_vhost_user_blk_direct() {
test_vhost_user_blk(1, false, true, Some(&prepare_vubd))
}
@@ -3929,7 +4050,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let serial_path = guest.tmp_dir.as_path().join("/tmp/serial-output");
let serial_path = guest.tmp_dir.as_path().join("serial-output");
#[cfg(target_arch = "x86_64")]
let console_str: &str = "console=ttyS0";
#[cfg(target_arch = "aarch64")]
@@ -4042,8 +4163,8 @@ mod common_parallel {
fn test_serial_socket_interaction() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let serial_socket = guest.tmp_dir.as_path().join("/tmp/serial.socket");
let serial_socket_pty = guest.tmp_dir.as_path().join("/tmp/serial.pty");
let serial_socket = guest.tmp_dir.as_path().join("serial.socket");
let serial_socket_pty = guest.tmp_dir.as_path().join("serial.pty");
let serial_option = if cfg!(target_arch = "x86_64") {
" console=ttyS0"
} else {
@@ -4097,7 +4218,12 @@ mod common_parallel {
let r = std::panic::catch_unwind(|| {
// Check that the cloud-hypervisor binary actually terminated
assert!(output.status.success())
if !output.status.success() {
panic!(
"Cloud Hypervisor process failed to terminate gracefully: {:?}",
output.status
);
}
});
handle_child_output(r, &output);
}
@@ -4151,7 +4277,7 @@ mod common_parallel {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let console_path = guest.tmp_dir.as_path().join("/tmp/console-output");
let console_path = guest.tmp_dir.as_path().join("console-output");
let mut child = GuestCommand::new(&guest)
.args(["--cpus", "boot=1"])
.args(["--memory", "size=512M"])
@@ -4212,8 +4338,8 @@ mod common_parallel {
fn test_vfio() {
setup_vfio_network_interfaces();
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new_from_ip_range(Box::new(focal), "172.18", 0);
let jammy = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string());
let guest = Guest::new_from_ip_range(Box::new(jammy), "172.18", 0);
let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads");
@@ -4318,49 +4444,35 @@ mod common_parallel {
// Let's ssh into it and verify that it's there. If it is it means
// we're in the right guest (The L2 one) because the QEMU L1 guest
// does not have this command line tag.
assert_eq!(
guest
.ssh_command_l2_1("grep -c VFIOTAG /proc/cmdline")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
assert!(check_matched_lines_count(
guest.ssh_command_l2_1("cat /proc/cmdline").unwrap().trim(),
vec!["VFIOTAG"],
1
);
));
// Let's also verify from the second virtio-net device passed to
// the L2 VM.
assert_eq!(
guest
.ssh_command_l2_2("grep -c VFIOTAG /proc/cmdline")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
assert!(check_matched_lines_count(
guest.ssh_command_l2_2("cat /proc/cmdline").unwrap().trim(),
vec!["VFIOTAG"],
1
);
));
// Check the amount of PCI devices appearing in L2 VM.
assert_eq!(
assert!(check_lines_count(
guest
.ssh_command_l2_1("ls /sys/bus/pci/devices | wc -l")
.ssh_command_l2_1("ls /sys/bus/pci/devices")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
8,
);
.trim(),
8
));
// Check both if /dev/vdc exists and if the block size is 16M in L2 VM
assert_eq!(
guest
.ssh_command_l2_1("lsblk | grep vdc | grep -c 16M")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
assert!(check_matched_lines_count(
guest.ssh_command_l2_1("lsblk").unwrap().trim(),
vec!["vdc", "16M"],
1
);
));
// Hotplug an extra virtio-net device through L2 VM.
guest
@@ -4378,35 +4490,33 @@ mod common_parallel {
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
)
.unwrap();
assert!(vfio_hotplug_output.contains("{\"id\":\"vfio123\",\"bdf\":\"0000:00:08.0\"}"));
assert!(check_matched_lines_count(
vfio_hotplug_output.trim(),
vec!["{\"id\":\"vfio123\",\"bdf\":\"0000:00:08.0\"}"],
1
));
thread::sleep(std::time::Duration::new(10, 0));
// Let's also verify from the third virtio-net device passed to
// the L2 VM. This third device has been hotplugged through the L2
// VM, so this is our way to validate hotplug works for VFIO PCI.
assert_eq!(
guest
.ssh_command_l2_3("grep -c VFIOTAG /proc/cmdline")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
assert!(check_matched_lines_count(
guest.ssh_command_l2_3("cat /proc/cmdline").unwrap().trim(),
vec!["VFIOTAG"],
1
);
));
// Check the amount of PCI devices appearing in L2 VM.
// There should be one more device than before, raising the count
// up to 9 PCI devices.
assert_eq!(
assert!(check_lines_count(
guest
.ssh_command_l2_1("ls /sys/bus/pci/devices | wc -l")
.ssh_command_l2_1("ls /sys/bus/pci/devices")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
9,
);
.trim(),
9
));
// Let's now verify that we can correctly remove the virtio-net
// device through the "remove-device" command responsible for
@@ -4422,15 +4532,13 @@ mod common_parallel {
// Check the amount of PCI devices appearing in L2 VM is back down
// to 8 devices.
assert_eq!(
assert!(check_lines_count(
guest
.ssh_command_l2_1("ls /sys/bus/pci/devices | wc -l")
.ssh_command_l2_1("ls /sys/bus/pci/devices")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
8,
);
.trim(),
8
));
// Perform memory hotplug in L2 and validate the memory is showing
// up as expected. In order to check, we will use the virtio-net
@@ -5790,7 +5898,7 @@ mod common_parallel {
#[cfg(target_arch = "x86_64")]
let mut kernels = vec![direct_kernel_boot_path()];
#[cfg(target_arch = "aarch64")]
let kernels = vec![direct_kernel_boot_path()];
let kernels = [direct_kernel_boot_path()];
#[cfg(target_arch = "x86_64")]
{
@@ -5949,6 +6057,8 @@ mod common_parallel {
event: "device-removed".to_string(),
device_id: Some(net_id.to_string()),
}];
// See: #5938
thread::sleep(std::time::Duration::new(1, 0));
assert!(check_latest_events_exact(&latest_events, &event_path));
// Plug the virtio-net device again
@@ -5972,6 +6082,8 @@ mod common_parallel {
device_id: None,
},
];
// See: #5938
thread::sleep(std::time::Duration::new(1, 0));
assert!(check_latest_events_exact(&latest_events, &event_path));
// Take a snapshot from the VM
@@ -5994,6 +6106,8 @@ mod common_parallel {
device_id: None,
},
];
// See: #5938
thread::sleep(std::time::Duration::new(1, 0));
assert!(check_latest_events_exact(&latest_events, &event_path));
});
@@ -6069,6 +6183,12 @@ mod common_parallel {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket_restored, "resume", None));
// There is no way that we can ensure the 'write()' to the
// event file is completed when the 'resume' request is
// returned successfully, because the 'write()' was done
// asynchronously from a different thread of Cloud
// Hypervisor (e.g. the event-monitor thread).
thread::sleep(std::time::Duration::new(1, 0));
let latest_events = [
&MetaEvent {
event: "resuming".to_string(),
@@ -6248,6 +6368,7 @@ mod common_parallel {
let api_socket = temp_api_path(&guest.tmp_dir);
let kernel_path = direct_kernel_boot_path();
let event_path = temp_event_monitor_path(&guest.tmp_dir);
let mut cmd = GuestCommand::new(&guest);
cmd.args(["--cpus", "boot=1"])
@@ -6258,6 +6379,7 @@ mod common_parallel {
.args(["--net", guest.default_net_string().as_str()])
.args(["--watchdog"])
.args(["--api-socket", &api_socket])
.args(["--event-monitor", format!("path={event_path}").as_str()])
.capture_output();
let mut child = cmd.spawn().unwrap();
@@ -6302,7 +6424,17 @@ mod common_parallel {
{
// Now pause the VM and remain offline for 30s
assert!(remote_command(&api_socket, "pause", None));
thread::sleep(std::time::Duration::new(30, 0));
let latest_events = [
&MetaEvent {
event: "pausing".to_string(),
device_id: None,
},
&MetaEvent {
event: "paused".to_string(),
device_id: None,
},
];
assert!(check_latest_events_exact(&latest_events, &event_path));
assert!(remote_command(&api_socket, "resume", None));
// Check no reboot
@@ -6734,10 +6866,11 @@ mod common_parallel {
.unwrap();
thread::sleep(std::time::Duration::new(2, 0));
assert!(exec_host_command_status(
"/usr/local/bin/spdk-nvme/rpc.py nvmf_create_transport -t VFIOUSER"
)
.success());
assert!(exec_host_command_with_retries(
"/usr/local/bin/spdk-nvme/rpc.py nvmf_create_transport -t VFIOUSER",
3,
std::time::Duration::new(5, 0),
));
assert!(exec_host_command_status(&format!(
"/usr/local/bin/spdk-nvme/rpc.py bdev_aio_create {} test 512",
nvme_dir.join("test-disk.raw").to_str().unwrap()
@@ -6852,9 +6985,7 @@ mod common_parallel {
#[cfg(target_arch = "x86_64")]
fn test_vdpa_block() {
// Before trying to run the test, verify the vdpa_sim_blk module is correctly loaded.
if !exec_host_command_status("lsmod | grep vdpa_sim_blk").success() {
return;
}
assert!(exec_host_command_status("lsmod | grep vdpa_sim_blk").success());
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
@@ -7093,6 +7224,58 @@ mod common_parallel {
handle_child_output(r, &output);
}
#[test]
#[cfg(target_arch = "x86_64")]
fn test_double_tty() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let mut cmd = GuestCommand::new(&guest);
let api_socket = temp_api_path(&guest.tmp_dir);
let tty_str: &str = "console=hvc0 earlyprintk=ttyS0 ";
// linux printk module enable console log.
let con_dis_str: &str = "console [hvc0] enabled";
// linux printk module disable console log.
let con_enb_str: &str = "bootconsole [earlyser0] disabled";
let kernel_path = direct_kernel_boot_path();
cmd.args(["--cpus", "boot=1"])
.args(["--memory", "size=512M"])
.args(["--kernel", kernel_path.to_str().unwrap()])
.args([
"--cmdline",
DIRECT_KERNEL_BOOT_CMDLINE
.replace("console=hvc0 ", tty_str)
.as_str(),
])
.capture_output()
.default_disks()
.default_net()
.args(["--serial", "tty"])
.args(["--console", "tty"])
.args(["--api-socket", &api_socket]);
let mut child = cmd.spawn().unwrap();
let mut r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
if r.is_ok() {
r = std::panic::catch_unwind(|| {
let s = String::from_utf8_lossy(&output.stdout);
assert!(s.contains(tty_str));
assert!(s.contains(con_dis_str));
assert!(s.contains(con_enb_str));
});
}
handle_child_output(r, &output);
}
}
mod dbus_api {
@@ -7929,6 +8112,7 @@ mod windows {
}
#[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug() {
@@ -8024,6 +8208,7 @@ mod windows {
}
#[test]
#[ignore = "See #6037"]
#[cfg(not(feature = "mshv"))]
#[cfg(not(target_arch = "aarch64"))]
fn test_windows_guest_disk_hotplug_multi() {
@@ -8447,8 +8632,13 @@ mod live_migration {
if !send_success {
let _ = send_migration.kill();
let output = send_migration.wait_with_output().unwrap();
eprintln!("\n\n==== Start 'send_migration' output ====\n\n---stdout---\n{}\n\n---stderr---\n{}\n\n==== End 'send_migration' output ====\n\n",
String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr));
eprintln!(
"\n\n==== Start 'send_migration' output ==== \
\n\n---stdout---\n{}\n\n---stderr---\n{} \
\n\n==== End 'send_migration' output ====\n\n",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
}
// The 'receive-migration' command should be executed successfully within the given timeout
@@ -8464,8 +8654,13 @@ mod live_migration {
if !receive_success {
let _ = receive_migration.kill();
let output = receive_migration.wait_with_output().unwrap();
eprintln!("\n\n==== Start 'receive_migration' output ====\n\n---stdout---\n{}\n\n---stderr---\n{}\n\n==== End 'receive_migration' output ====\n\n",
String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr));
eprintln!(
"\n\n==== Start 'receive_migration' output ==== \
\n\n---stdout---\n{}\n\n---stderr---\n{} \
\n\n==== End 'receive_migration' output ====\n\n",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
}
send_success && receive_success
@@ -9458,51 +9653,51 @@ mod live_migration {
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_basic() {
_test_live_migration(true, false)
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_local() {
_test_live_migration(true, true)
}
#[test]
#[ignore = "See #6134"]
#[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_numa() {
_test_live_migration_numa(true, false)
}
#[test]
#[ignore = "See #6134"]
#[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_numa_local() {
_test_live_migration_numa(true, true)
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_watchdog() {
_test_live_migration_watchdog(true, false)
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_watchdog_local() {
_test_live_migration_watchdog(true, true)
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_balloon() {
_test_live_migration_balloon(true, false)
}
#[test]
#[ignore = "See #5791"]
#[ignore = "See #6134"]
fn test_live_upgrade_balloon_local() {
_test_live_migration_balloon(true, true)
}
@@ -9515,6 +9710,7 @@ mod live_migration {
// Require to run ovs-dpdk tests sequentially because they rely on the same ovs-dpdk setup
#[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
fn test_live_migration_ovs_dpdk() {
@@ -9529,17 +9725,17 @@ mod live_migration {
}
#[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_ovs_dpdk() {
_test_live_migration_ovs_dpdk(true, false);
}
#[test]
#[ignore = "See #5532"]
#[cfg(target_arch = "x86_64")]
#[cfg(not(feature = "mshv"))]
#[ignore = "See #5791"]
fn test_live_upgrade_ovs_dpdk_local() {
_test_live_migration_ovs_dpdk(true, true);
}
@@ -9628,7 +9824,9 @@ mod rate_limiter {
}
eprintln!(
"\n\n==== check_rate_limit failed! ====\n\nmeasured={measured}, , lower_limit={lower_limit}, upper_limit={upper_limit}\n\n"
"\n\n==== Start 'check_rate_limit' failed ==== \
\n\nmeasured={measured}, , lower_limit={lower_limit}, upper_limit={upper_limit} \
\n\n==== End 'check_rate_limit' failed ====\n\n"
);
false
@@ -9689,9 +9887,8 @@ mod rate_limiter {
_test_rate_limiter_net(false);
}
fn _test_rate_limiter_block(bandwidth: bool) {
fn _test_rate_limiter_block(bandwidth: bool, num_queues: u32) {
let test_timeout = 10;
let num_queues = 1;
let fio_ops = FioOps::RandRW;
let bw_size = if bandwidth {
@@ -9718,11 +9915,11 @@ mod rate_limiter {
let test_blk_params = if bandwidth {
format!(
"path={blk_rate_limiter_test_img},bw_size={bw_size},bw_refill_time={bw_refill_time}"
"path={blk_rate_limiter_test_img},num_queues={num_queues},bw_size={bw_size},bw_refill_time={bw_refill_time}"
)
} else {
format!(
"path={blk_rate_limiter_test_img},ops_size={bw_size},ops_refill_time={bw_refill_time}"
"path={blk_rate_limiter_test_img},num_queues={num_queues},ops_size={bw_size},ops_refill_time={bw_refill_time}"
)
};
@@ -9775,13 +9972,137 @@ mod rate_limiter {
handle_child_output(r, &output);
}
fn _test_rate_limiter_group_block(bandwidth: bool, num_queues: u32, num_disks: u32) {
let test_timeout = 10;
let fio_ops = FioOps::RandRW;
let bw_size = if bandwidth {
10485760_u64 // bytes
} else {
100_u64 // I/O
};
let bw_refill_time = 100; // ms
let limit_rate = (bw_size * 1000) as f64 / bw_refill_time as f64;
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let api_socket = temp_api_path(&guest.tmp_dir);
let test_img_dir = TempDir::new_with_prefix("/var/tmp/ch").unwrap();
let rate_limit_group_arg = if bandwidth {
format!("id=group0,bw_size={bw_size},bw_refill_time={bw_refill_time}")
} else {
format!("id=group0,ops_size={bw_size},ops_refill_time={bw_refill_time}")
};
let mut disk_args = vec![
"--disk".to_string(),
format!(
"path={}",
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
),
format!(
"path={}",
guest.disk_config.disk(DiskType::CloudInit).unwrap()
),
];
for i in 0..num_disks {
let test_img_path = String::from(
test_img_dir
.as_path()
.join(format!("blk{}.img", i))
.to_str()
.unwrap(),
);
assert!(exec_host_command_output(&format!(
"dd if=/dev/zero of={test_img_path} bs=1M count=1024"
))
.status
.success());
disk_args.push(format!(
"path={test_img_path},num_queues={num_queues},rate_limit_group=group0"
));
}
let mut child = GuestCommand::new(&guest)
.args(["--cpus", &format!("boot={}", num_queues * num_disks)])
.args(["--memory", "size=4G"])
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.args(["--rate-limit-group", &rate_limit_group_arg])
.args(disk_args)
.default_net()
.args(["--api-socket", &api_socket])
.capture_output()
.spawn()
.unwrap();
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();
let mut fio_command = format!(
"sudo fio --name=global --output-format=json \
--direct=1 --bs=4k --ioengine=io_uring --iodepth=64 \
--rw={fio_ops} --runtime={test_timeout} --numjobs={num_queues}"
);
// Generate additional argument for each disk:
// --name=job0 --filename=/dev/vdc \
// --name=job1 --filename=/dev/vdd \
// --name=job2 --filename=/dev/vde \
// ...
for i in 0..num_disks {
let c: char = 'c';
let arg = format!(
" --name=job{i} --filename=/dev/vd{}",
char::from_u32((c as u32) + i).unwrap()
);
fio_command += &arg;
}
let output = guest.ssh_command(&fio_command).unwrap();
// Parse fio output
let measured_rate = if bandwidth {
parse_fio_output(&output, &fio_ops, num_queues * num_disks).unwrap()
} else {
parse_fio_output_iops(&output, &fio_ops, num_queues * num_disks).unwrap()
};
assert!(check_rate_limit(measured_rate, limit_rate, 0.1));
});
let _ = child.kill();
let output = child.wait_with_output().unwrap();
handle_child_output(r, &output);
}
#[test]
fn test_rate_limiter_block_bandwidth() {
_test_rate_limiter_block(true)
_test_rate_limiter_block(true, 1);
_test_rate_limiter_block(true, 2)
}
#[test]
fn test_rate_limiter_group_block_bandwidth() {
_test_rate_limiter_group_block(true, 1, 1);
_test_rate_limiter_group_block(true, 2, 1);
_test_rate_limiter_group_block(true, 1, 2);
_test_rate_limiter_group_block(true, 2, 2);
}
#[test]
fn test_rate_limiter_block_iops() {
_test_rate_limiter_block(false)
_test_rate_limiter_block(false, 1);
_test_rate_limiter_block(false, 2);
}
#[test]
fn test_rate_limiter_group_block_iops() {
_test_rate_limiter_group_block(false, 1, 1);
_test_rate_limiter_group_block(false, 2, 1);
_test_rate_limiter_group_block(false, 1, 2);
_test_rate_limiter_group_block(false, 2, 2);
}
}

View File

@@ -12,4 +12,4 @@ libc = "0.2.138"
log = "0.4.17"
net_gen = { path = "../net_gen" }
thiserror = "1.0.37"
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"

View File

@@ -5,11 +5,11 @@ authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
[dependencies]
libc = "0.2.147"
log = "0.4.17"
once_cell = "1.18.0"
serde = { version = "1.0.168", features = ["rc", "derive"] }
serde_json = "1.0.107"
libc = "0.2.153"
log = "0.4.20"
once_cell = "1.19.0"
serde = { version = "1.0.196", features = ["rc", "derive"] }
serde_json = "1.0.109"
[features]
tracing = []

View File

@@ -6,17 +6,16 @@ edition = "2021"
build = "../build.rs"
[dependencies]
clap = { version = "4.3.11", features = ["wrap_help","cargo"] }
clap = { version = "4.4.7", features = ["wrap_help","cargo"] }
block = { path = "../block" }
env_logger = "0.10.0"
env_logger = "0.10.1"
epoll = "4.3.3"
libc = "0.2.147"
log = "0.4.17"
libc = "0.2.153"
log = "0.4.20"
option_parser = { path = "../option_parser" }
vhost = { version = "0.8.1", features = ["vhost-user-slave"] }
vhost-user-backend = "0.10.1"
vhost = { version = "0.10.0", features = ["vhost-user-backend"] }
vhost-user-backend = "0.13.1"
virtio-bindings = "0.2.0"
virtio-queue = "0.9.0"
vm-memory = "0.12.2"
vmm-sys-util = "0.11.0"
virtio-queue = "0.11.0"
vm-memory = "0.14.0"
vmm-sys-util = "0.12.1"

View File

@@ -58,6 +58,7 @@ impl<D: Read + Seek + Write + Send> DiskFile for D {}
type Result<T> = std::result::Result<T, Error>;
type VhostUserBackendResult<T> = std::result::Result<T, std::io::Error>;
#[allow(dead_code)]
#[derive(Debug)]
enum Error {
/// Failed to create kill eventfd
@@ -299,9 +300,10 @@ impl VhostUserBlkBackend {
}
}
impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, AtomicBitmap>
for VhostUserBlkBackend
{
impl VhostUserBackendMut for VhostUserBlkBackend {
type Bitmap = AtomicBitmap;
type Vring = VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>;
fn num_queues(&self) -> usize {
self.config.num_queues as usize
}
@@ -350,7 +352,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
evset: EventSet,
vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>],
thread_id: usize,
) -> VhostUserBackendResult<bool> {
) -> VhostUserBackendResult<()> {
if evset != EventSet::IN {
return Err(Error::HandleEventNotEpollIn.into());
}
@@ -394,7 +396,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
thread.process_queue(&mut vring);
}
Ok(false)
Ok(())
}
_ => Err(Error::HandleEventUnknownEvent.into()),
}

View File

@@ -6,16 +6,15 @@ edition = "2021"
build = "../build.rs"
[dependencies]
clap = { version = "4.3.11", features = ["wrap_help","cargo"] }
env_logger = "0.10.0"
clap = { version = "4.4.7", features = ["wrap_help","cargo"] }
env_logger = "0.10.1"
epoll = "4.3.3"
libc = "0.2.147"
log = "0.4.17"
libc = "0.2.153"
log = "0.4.20"
net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" }
vhost = { version = "0.8.1", features = ["vhost-user-slave"] }
vhost-user-backend = "0.10.1"
vhost = { version = "0.10.0", features = ["vhost-user-backend"] }
vhost-user-backend = "0.13.1"
virtio-bindings = "0.2.0"
vm-memory = "0.12.2"
vmm-sys-util = "0.11.0"
vm-memory = "0.14.0"
vmm-sys-util = "0.12.1"

View File

@@ -158,9 +158,10 @@ impl VhostUserNetBackend {
}
}
impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, AtomicBitmap>
for VhostUserNetBackend
{
impl VhostUserBackendMut for VhostUserNetBackend {
type Bitmap = AtomicBitmap;
type Vring = VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>;
fn num_queues(&self) -> usize {
self.num_queues
}
@@ -203,7 +204,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
_evset: EventSet,
vrings: &[VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>],
thread_id: usize,
) -> VhostUserBackendResult<bool> {
) -> VhostUserBackendResult<()> {
let mut thread = self.threads[thread_id].lock().unwrap();
match device_event {
0 => {
@@ -245,7 +246,7 @@ impl VhostUserBackendMut<VringRwLock<GuestMemoryAtomic<GuestMemoryMmap>>, Atomic
_ => return Err(Error::HandleEventUnknownEvent.into()),
}
Ok(false)
Ok(())
}
fn exit_event(&self, thread_index: usize) -> Option<EventFd> {

View File

@@ -8,31 +8,31 @@ edition = "2021"
default = []
[dependencies]
anyhow = "1.0.75"
anyhow = "1.0.79"
arc-swap = "1.5.1"
block = { path = "../block" }
byteorder = "1.4.3"
epoll = "4.3.3"
event_monitor = { path = "../event_monitor" }
libc = "0.2.147"
log = "0.4.17"
libc = "0.2.153"
log = "0.4.20"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci" }
rate_limiter = { path = "../rate_limiter" }
seccompiler = "0.4.0"
serde = { version = "1.0.168", features = ["derive"] }
serde_json = "1.0.107"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.109"
serial_buffer = { path = "../serial_buffer" }
thiserror = "1.0.40"
versionize = "0.1.10"
versionize_derive = "0.1.4"
vhost = { version = "0.8.1", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] }
thiserror = "1.0.52"
versionize = "0.2.0"
versionize_derive = "0.1.6"
vhost = { version = "0.10.0", features = ["vhost-user-frontend", "vhost-user-backend", "vhost-kern", "vhost-vdpa"] }
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.9.0"
virtio-queue = "0.11.0"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"
vmm-sys-util = "0.12.1"

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