Compare commits

..

20 Commits
v31.0 ... v30.1

Author SHA1 Message Date
Bo Chen
93d7e01b41 build: Release v30.1 (bug fix release)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 16:41:05 -07:00
Bo Chen
4fe593e12d tests: Enable live-upgrade tests based on v30.0
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
4203a61947 vmm: Remove unnecessary parentheses (beta 1.69 clippy check)
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
e397e739bf tests: Extend '_test_macvtap()' with reboot
In this way, we can cover the scenario where a VM with hotplugged net
device using FDs can work properly with reboot.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
2724edd1e5 vmm: Add valid FDs for TAP devices to 'VmConfig::preserved_fds'
In this way, valid FDs for TAP devices will be closed when the holding
VmConfig instance is destroyed.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
269844da73 vmm: Add unit test for 'VmConfig::preserved_fds'
Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
a299a10874 vmm: Implement Clone and Drop for VmConfig
The custom 'clone' duplicates 'preserved_fds' so that the validation
logic can be safely carried out on the clone of the VmConfig.

The custom 'drop' ensures 'preserved_fds' are safely closed when the
holding VmConfig instance is destroyed.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
015941e294 vmm: config: Extend 'VmConfig' with 'preserved_fds'
Preserved FDs are the ones that share the same life-time as its holding
VmConfig instance, such as FDs for creating TAP devices.

Preserved FDs will stay open as long as the holding VmConfig instance is
valid, and will be closed when the holding VmConfig instance is destroyed.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
ca6fe2a98e Revert "vmm: config: Implement Clone for NetConfig"
This reverts commit ea4a95c4f6.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
f4090b0196 Revert "vmm: config: Close FDs for TAP devices that are provided to VM"
This reverts commit b14427540b.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
3432c0ce5e Revert "vmm: config: Don't close reserved FDs from NetConfig::drop()"
This reverts commit 0110fb4edc.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
ec70af1606 Revert "vmm: config: Avoid closing invalid FDs from 'test_net_parsing()'"
This reverts commit 0567def931.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Bo Chen
bb0d82c365 Revert "vmm: config: Replace use of memfd_create with fd pointing to /dev/null"
This reverts commit 46066d6ae1.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Alyssa Ross
2d98a16d05 vmm: only touch the tty flags if it's being used
When neither serial nor console are connected to the tty,
cloud-hypervisor shouldn't touch the tty at all.  One way in which
this is annoying is that if I am running cloud-hypervisor without it
using my terminal, I expect to be able to suspend it with ^Z like any
other process, but that doesn't work if it's put the terminal into raw
mode.

Instead of putting the tty into raw mode when a VM is created or
restored, do it when a serial or console device is created.  Since we
now know it can't be put into raw mode until the Vm object is created,
we can move setting it back to canon mode into the drop handler for
that object, which should always be run in normal operation.  We still
also put the tty into canon mode in the SIGTERM / SIGINT handler, but
check whether the tty was actually used, rather than whether stdin is
a tty.  This requires passing on_tty around as an atomic boolean.

I explored more of an abstraction over the tty — having an object that
encapsulated stdout and put the tty into raw mode when initialized and
into canon mode when dropped — but it wasn't practical, mostly due to
the special requirements of the signal handler.  I also investigated
whether the SIGWINCH listener process could be used here, which I
think would have worked but I'm hesitant to involve it in serial
handling as well as conosle handling.

There's no longer a check for whether the file descriptor is a tty
before setting it into canon mode — it's redundant, because if it's
not a tty it just won't respond to the ioctl.

Tested by shutting down through the API, SIGTERM, and an error
injected after setting raw mode.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-04-18 11:47:31 -07:00
Alyssa Ross
cd1a645421 vmm: don't redundantly set the TTY to canon mode
If the VM is shut down, either it's going to be started again, in
which case we still want to be in raw mode, or the process is about to
exit, in which case canon mode will be set at the end of main.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-04-18 11:47:31 -07:00
Alyssa Ross
4485210de5 vmm: only use KVM_ARM_VCPU_PMU_V3 if available
Having PMU in guests isn't critical, and not all hardware supports
it (e.g. Apple Silicon).

CpuManager::init_pmu already has a fallback for if PMU is not
supported by the VCPU, but we weren't getting that far, because we
would always try to initialise the VCPU with KVM_ARM_VCPU_PMU_V3, and
then bail when it returned with EINVAL.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-04-18 11:47:31 -07:00
Alyssa Ross
0aa858c266 virtio-devices: seccomp: add vhost-user syscalls
Cloud Hypervisor's vhost-user implementation will reconnect if it gets
disconnected from the backend.  That means connections happen inside
the vhost-user seccomp sandbox, so all syscalls used in reconnecting
have to be allowed in that sandbox.

clock_nanosleep is used by Glibc, and nanosleep is used by musl.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-04-18 11:47:31 -07:00
Bo Chen
499e8433c3 vmm: Ignore and warn TAP FDs sent via the HTTP request body
Valid FDs can only be sent from another process via `SCM_RIGHTS`.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-04-18 11:47:31 -07:00
Omer Faruk Bayram
ff27b00f5a ch-remote: fixed ShutdownVmm and Shutdown commands
Fixed `ShutdownVmm` and `Shutdown` commands to call the correct API
endpoint.

Signed-off-by: Omer Faruk Bayram <omer.faruk@sartura.hr>
2023-04-18 11:47:31 -07:00
Hao Xu
d09af361bc virtio-devices: Reset offset properly upon unmap for virtio-fs.
We should reset the offset to 0, when asked to remove the whole dax
mapping.

Signed-off-by: Hao Xu <howeyxu@tencent.com>
2023-04-18 11:47:31 -07:00
72 changed files with 1126 additions and 1249 deletions

View File

@@ -7,10 +7,6 @@ on:
pull_request:
paths: resources/Dockerfile
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
main:
runs-on: ubuntu-latest
@@ -24,19 +20,19 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to ghcr
uses: docker/login-action@v2
- name: Login to DockerHub
if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v3
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# list of Docker images to use as base name for tags
images: cloudhypervisor/dev
# generate Docker tags based on the following events/attributes
tags: |
type=raw,value={{date 'YYYYMMDD'}}-0

View File

@@ -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.62"
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.62"
target: x86_64-unknown-linux-musl
- name: Build
uses: actions-rs/cargo@v1
with:
toolchain: "1.67.1"
toolchain: "1.62"
command: build
args: --all --release --no-default-features --features "kvm,mshv" --target=x86_64-unknown-linux-gnu
- name: Static Build
uses: actions-rs/cargo@v1
with:
toolchain: "1.67.1"
toolchain: "1.62"
command: build
args: --all --release --no-default-features --features "kvm,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.62"
target: aarch64-unknown-linux-musl
override: true
- name: Create Release

136
Cargo.lock generated
View File

@@ -5,9 +5,9 @@ version = 3
[[package]]
name = "acpi_tables"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#0b892e2c2053c4ecfac8d9e5a52babae75114702"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#12bb6d7b252831527e630f8b3ef48877dbb11924"
dependencies = [
"zerocopy",
"vm-memory",
]
[[package]]
@@ -179,7 +179,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cloud-hypervisor"
version = "31.0.0"
version = "30.1.0"
dependencies = [
"anyhow",
"api_client",
@@ -224,9 +224,9 @@ checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910"
[[package]]
name = "darling"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
dependencies = [
"darling_core",
"darling_macro",
@@ -234,9 +234,9 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
dependencies = [
"fnv",
"ident_case",
@@ -248,9 +248,9 @@ dependencies = [
[[package]]
name = "darling_macro"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
dependencies = [
"darling_core",
"quote",
@@ -382,9 +382,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "gdbstub"
version = "0.6.4"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4fddc6f9d12cbef29e395d9a6b48c128f513c8a2ded7048c97ed5c484e53e7"
checksum = "32c95766e0414f8bfc1d07055574c621b67739466d6ba516c4fef8e99d30d2e6"
dependencies = [
"bitflags",
"cfg-if",
@@ -497,9 +497,9 @@ dependencies = [
[[package]]
name = "io-uring"
version = "0.5.13"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd1e1a01cfb924fd8c5c43b6827965db394f5a3a16c599ce03452266e1cf984c"
checksum = "41c85eff7f7c8d3ab8c7ec87313c0c194bbaf4371bb7d40f80293ba01bce8264"
dependencies = [
"bitflags",
"libc",
@@ -516,9 +516,9 @@ dependencies = [
[[package]]
name = "is-terminal"
version = "0.4.5"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e"
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
dependencies = [
"hermit-abi",
"io-lifetimes",
@@ -528,9 +528,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.6"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "kvm-bindings"
@@ -545,8 +545,7 @@ dependencies = [
[[package]]
name = "kvm-ioctls"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8dc9c1896e5f144ec5d07169bc29f39a047686d29585a91f30489abfaeb6b"
source = "git+https://github.com/rust-vmm/kvm-ioctls?branch=main#23a3bb045a467e60bb00328a0b13cea13b5815d0"
dependencies = [
"kvm-bindings",
"libc",
@@ -668,7 +667,7 @@ dependencies = [
[[package]]
name = "mshv-bindings"
version = "0.1.1"
source = "git+https://github.com/rust-vmm/mshv?branch=main#66531ba242be0b744ee2e4cd602ab0000377bdf7"
source = "git+https://github.com/rust-vmm/mshv?branch=main#0b2af251285385f8e39c2cd0fe8ffacab534932f"
dependencies = [
"libc",
"serde",
@@ -680,7 +679,7 @@ dependencies = [
[[package]]
name = "mshv-ioctls"
version = "0.1.1"
source = "git+https://github.com/rust-vmm/mshv?branch=main#66531ba242be0b744ee2e4cd602ab0000377bdf7"
source = "git+https://github.com/rust-vmm/mshv?branch=main#0b2af251285385f8e39c2cd0fe8ffacab534932f"
dependencies = [
"libc",
"mshv-bindings",
@@ -760,9 +759,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.83"
version = "0.9.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7"
dependencies = [
"autocfg",
"cc",
@@ -826,9 +825,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.12"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "pci"
@@ -965,9 +964,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.52"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@@ -1034,9 +1033,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.29"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "remain"
@@ -1086,9 +1085,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.13"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "scopeguard"
@@ -1107,9 +1106,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.17"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "serde"
@@ -1133,9 +1132,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.95"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
dependencies = [
"itoa",
"ryu",
@@ -1144,9 +1143,9 @@ dependencies = [
[[package]]
name = "serde_with"
version = "2.3.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85456ffac572dc8826334164f2fb6fb40a7c766aebe195a2a21ee69ee2885ecf"
checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c"
dependencies = [
"serde",
"serde_with_macros",
@@ -1154,9 +1153,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "2.3.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cbcd6104f8a4ab6af7f6be2a0da6be86b9de3c401f6e86bb856ab2af739232f"
checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e"
dependencies = [
"darling",
"proc-macro2",
@@ -1170,9 +1169,9 @@ version = "0.1.0"
[[package]]
name = "signal-hook"
version = "0.3.15"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
dependencies = [
"libc",
"signal-hook-registry",
@@ -1258,18 +1257,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.39"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.39"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
@@ -1329,9 +1328,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "versionize"
version = "0.1.10"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca4b7062e7e6d685901e815c35f9671e059de97c1c0905eeff8592f3fff442f"
checksum = "d6e2495726cf917e7ba7ec8bf0f0fceab543dd38d0a4195ed6bef331e38a290f"
dependencies = [
"bincode",
"crc64",
@@ -1357,7 +1356,7 @@ dependencies = [
[[package]]
name = "vfio-bindings"
version = "0.4.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#ea8f710464a24690ce109e6b7dfaa623dc518304"
source = "git+https://github.com/rust-vmm/vfio?branch=main#43439e056ddfa84a4f7906ee7f2f58be70505c08"
dependencies = [
"vmm-sys-util",
]
@@ -1365,7 +1364,7 @@ dependencies = [
[[package]]
name = "vfio-ioctls"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vfio?branch=main#ea8f710464a24690ce109e6b7dfaa623dc518304"
source = "git+https://github.com/rust-vmm/vfio?branch=main#43439e056ddfa84a4f7906ee7f2f58be70505c08"
dependencies = [
"byteorder",
"kvm-bindings",
@@ -1524,9 +1523,9 @@ dependencies = [
[[package]]
name = "virtio-queue"
version = "0.7.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ba81e2bcc21c0d2fc5e6683e79367e26ad219197423a498df801d79d5ba77bd"
checksum = "19e927d93d54c365034fd7f31a5f458a1f540de4a37c52e892670dad9692173c"
dependencies = [
"log",
"virtio-bindings 0.1.0",
@@ -1559,7 +1558,7 @@ dependencies = [
[[package]]
name = "vm-fdt"
version = "0.2.0"
source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#ad21ede0ddb4cc97448eeb64c1dfc27803b9ec08"
source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#c5a99ab71b130435927d19b50c85fcd5ce904a8c"
[[package]]
name = "vm-memory"
@@ -1640,7 +1639,6 @@ dependencies = [
"vm-migration",
"vm-virtio",
"vmm-sys-util",
"zerocopy",
]
[[package]]
@@ -1727,9 +1725,9 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
@@ -1742,45 +1740,45 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "zerocopy"

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "31.0.0"
version = "30.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"
@@ -40,9 +40,9 @@ libc = "0.2.139"
log = { version = "0.4.17", features = ["std"] }
option_parser = { path = "option_parser" }
seccompiler = "0.3.0"
serde_json = "1.0.95"
signal-hook = "0.3.15"
thiserror = "1.0.39"
serde_json = "1.0.93"
signal-hook = "0.3.14"
thiserror = "1.0.38"
tpm = { path = "tpm"}
tracer = { path = "tracer" }
vmm = { path = "vmm" }
@@ -52,13 +52,14 @@ vm-memory = "0.10.0"
# 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" }
[dev-dependencies]
dirs = "4.0.0"
net_util = { path = "net_util" }
once_cell = "1.17.1"
serde_json = "1.0.95"
serde_json = "1.0.93"
test_infra = { path = "test_infra" }
wait-timeout = "0.2.0"

View File

@@ -113,7 +113,7 @@ Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware) or an
edk2 UEFI firmware called `CLOUDHV` / `CLOUDHV_EFI`.)
Binary builds of the firmware files are available for the latest release of
[Rust Hypervisor
[Rust Hyperivor
Firmware](https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/latest)
and [our edk2
repository](https://github.com/cloud-hypervisor/edk2/releases/latest)
@@ -124,7 +124,7 @@ may be required.
### Firmware Booting
Cloud Hypervisor supports booting disk images containing all needed components
to run cloud workloads, a.k.a. cloud images.
to run cloud workloads, a.k.a. cloud images.
The following sample commands will download an Ubuntu Cloud image, converting
it into a format that Cloud Hypervisor can use and a firmware to boot the image
@@ -178,7 +178,7 @@ To build the kernel:
```shell
# Clone the Cloud Hypervisor Linux branch
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-6.2 linux-cloud-hypervisor
$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-6.1.6 linux-cloud-hypervisor
$ pushd linux-cloud-hypervisor
# Use the x86-64 cloud-hypervisor kernel config to build your kernel for x86-64
$ wget https://raw.githubusercontent.com/cloud-hypervisor/cloud-hypervisor/main/resources/linux-config-x86_64
@@ -372,8 +372,8 @@ are all equal and welcome means of contribution. See the
## Slack
Get an [invite to our Slack channel](https://join.slack.com/t/cloud-hypervisor/shared_invite/enQtNjY3MTE3MDkwNDQ4LWQ1MTA1ZDVmODkwMWQ1MTRhYzk4ZGNlN2UwNTI3ZmFlODU0OTcwOWZjMTkwZDExYWE3YjFmNzgzY2FmNDAyMjI),
[join us on Slack](https://cloud-hypervisor.slack.com/), and [participate in our community activities](https://cloud-hypervisor.slack.com/archives/C04R5DUQVBN).
Get an [invite to our Slack channel](https://join.slack.com/t/cloud-hypervisor/shared_invite/enQtNjY3MTE3MDkwNDQ4LWQ1MTA1ZDVmODkwMWQ1MTRhYzk4ZGNlN2UwNTI3ZmFlODU0OTcwOWZjMTkwZDExYWE3YjFmNzgzY2FmNDAyMjI)
and [join us on Slack](https://cloud-hypervisor.slack.com/).
## Mailing list

View File

@@ -16,9 +16,9 @@ libc = "0.2.139"
linux-loader = { version = "0.8.1", features = ["elf", "bzimage", "pe"] }
log = "0.4.17"
serde = { version = "1.0.151", features = ["rc", "derive"] }
thiserror = "1.0.39"
thiserror = "1.0.38"
uuid = "1.3.0"
versionize = "0.1.10"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }

View File

@@ -21,8 +21,6 @@ use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic, GuestUsize};
pub const _NSIG: i32 = 65;
/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
pub enum Error {

View File

@@ -1,17 +1,18 @@
// Copyright 2022 Arm Limited (or its affiliates). All rights reserved.
// SPDX-License-Identifier: Apache-2.0
// AArch64 system register encoding:
// See https://developer.arm.com/documentation/ddi0487 (chapter D12)
//
// 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
// +----------+---+-----+-----+-----+-----+-----+----+
// |1101010100| L | op0 | op1 | CRn | CRm | op2 | Rt |
// +----------+---+-----+-----+-----+-----+-----+----+
//
// Notes:
// - L and Rt are reserved as implementation defined fields, ignored.
///
/// AArch64 system register encoding:
/// See https://developer.arm.com/documentation/ddi0487 (chapter D12)
///
/// 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
/// +----------+---+-----+-----+-----+-----+-----+----+
/// |1101010100| L | op0 | op1 | CRn | CRm | op2 | Rt |
/// +----------+---+-----+-----+-----+-----+-----+----+
///
/// Notes:
/// - L and Rt are reserved as implementation defined fields, ignored.
///
const SYSREG_HEAD: u32 = 0b1101010100u32 << 22;
const SYSREG_OP0_SHIFT: u32 = 19;
const SYSREG_OP0_MASK: u32 = 0b11u32 << 19;

View File

@@ -82,7 +82,7 @@ pub mod aarch64;
pub use aarch64::{
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt,
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
layout::IRQ_BASE, uefi, EntryPoint, _NSIG,
layout::IRQ_BASE, uefi, EntryPoint,
};
#[cfg(target_arch = "x86_64")]
@@ -92,7 +92,7 @@ pub mod 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, CpuidFeatureEntry, EntryPoint, _NSIG,
layout::CMDLINE_START, regs, CpuidFeatureEntry, EntryPoint,
};
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.

View File

@@ -53,8 +53,6 @@ const KVM_FEATURE_ASYNC_PF_VMEXIT_BIT: u8 = 10;
#[cfg(feature = "tdx")]
const KVM_FEATURE_STEAL_TIME_BIT: u8 = 5;
pub const _NSIG: i32 = 65;
#[derive(Debug, Copy, Clone)]
/// Specifies the entry point address where the guest must start
/// executing code, as well as which of the supported boot protocols

View File

@@ -8,17 +8,17 @@ edition = "2021"
default = []
[dependencies]
io-uring = "0.5.13"
io-uring = "0.5.12"
libc = "0.2.139"
log = "0.4.17"
qcow = { path = "../qcow" }
smallvec = "1.10.0"
thiserror = "1.0.39"
versionize = "0.1.10"
thiserror = "1.0.38"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vhdx = { path = "../vhdx" }
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"

View File

@@ -13,9 +13,9 @@ byteorder = "1.4.3"
hypervisor = { path = "../hypervisor" }
libc = "0.2.139"
log = "0.4.17"
thiserror = "1.0.39"
thiserror = "1.0.38"
tpm = { path = "../tpm" }
versionize = "0.1.10"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-device = { path = "../vm-device" }
vm-memory = "0.10.0"

View File

@@ -4,7 +4,7 @@
//
use super::AcpiNotificationFlags;
use acpi_tables::{aml, Aml, AmlSink};
use acpi_tables::{aml, aml::Aml};
use std::sync::{Arc, Barrier};
use std::time::Instant;
use vm_device::interrupt::InterruptSourceGroup;
@@ -103,11 +103,11 @@ impl BusDevice for AcpiGedDevice {
}
impl Aml for AcpiGedDevice {
fn to_aml_bytes(&self, sink: &mut dyn AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
aml::Device::new(
"_SB_.GEC_".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_UID".into(), &"Generic Event Controller"),
&aml::Name::new(
"_CRS".into(),
@@ -121,13 +121,12 @@ impl Aml for AcpiGedDevice {
&aml::OpRegion::new(
"GDST".into(),
aml::OpRegionSpace::SystemMemory,
&(self.address.0 as usize),
&GED_DEVICE_ACPI_SIZE,
self.address.0 as usize,
GED_DEVICE_ACPI_SIZE,
),
&aml::Field::new(
"GDST".into(),
aml::FieldAccessType::Byte,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::WriteAsZeroes,
vec![aml::FieldEntry::Named(*b"GDAT", 8)],
),
@@ -164,7 +163,7 @@ impl Aml for AcpiGedDevice {
),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
aml::Device::new(
"_SB_.GED_".into(),
vec![
@@ -188,7 +187,7 @@ impl Aml for AcpiGedDevice {
),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}

View File

@@ -78,40 +78,33 @@ The Cloud Hypervisor API exposes the following actions through its endpoints:
#### Virtual Machine (VM) Actions
| Action | Endpoint | Request Body | Response Body | Prerequisites |
| ---------------------------------- | ----------------------- | ------------------------------- | ------------------------ | ------------------------------------------------------ |
| Create the VM | `/vm.create` | `/schemas/VmConfig` | N/A | The VM is not created yet |
| Delete the VM | `/vm.delete` | N/A | N/A | N/A |
| Boot the VM | `/vm.boot` | N/A | N/A | The VM is created but not booted |
| Shut the VM down | `/vm.shutdown` | N/A | N/A | The VM is booted |
| Reboot the VM | `/vm.reboot` | N/A | N/A | The VM is booted |
| Trigger power button of the VM | `/vm.power-button` | N/A | N/A | The VM is booted |
| Pause the VM | `/vm.pause` | N/A | N/A | The VM is booted |
| Resume the VM | `/vm.resume` | N/A | N/A | The VM is paused |
| Task a snapshot of the VM | `/vm.snapshot` | `/schemas/VmSnapshotConfig` | N/A | The VM is paused |
| Perform a coredump of the VM* | `/vm.coredump` | `/schemas/VmCoredumpData` | N/A | The VM is paused |
| Restore the VM from a snapshot | `/vm.restore` | `/schemas/RestoreConfig` | N/A | The VM is created but not booted |
| Add/remove CPUs to/from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted |
| Add/remove memory from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted |
| Add/remove memory from a zone | `/vm.resize-zone` | `/schemas/VmResizeZone` | N/A | The VM is booted |
| Dump the VM information | `/vm.info` | N/A | `/schemas/VmInfo` | The VM is created |
| Add VFIO PCI device to the VM | `/vm.add-device` | `/schemas/VmAddDevice` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add disk device to the VM | `/vm.add-disk` | `/schemas/DiskConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add fs device to the VM | `/vm.add-fs` | `/schemas/FsConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add pmem device to the VM | `/vm.add-pmem` | `/schemas/PmemConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add network device to the VM | `/vm.add-net` | `/schemas/NetConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add userspace PCI device to the VM | `/vm.add-user-device` | `/schemas/VmAddUserDevice` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add vdpa device to the VM | `/vm.add-vdpa` | `/schemas/VdpaConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add vsock device to the VM | `/vm.add-vsock` | `/schemas/VsockConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Remove device from the VM | `/vm.remove-device` | `/schemas/VmRemoveDevice` | N/A | The VM is booted |
| Dump the VM counters | `/vm.counters` | N/A | `/schemas/VmCounters` | The VM is booted |
| Prepare to receive a migration | `/vm.receive-migration` | `/schemas/ReceiveMigrationData` | N/A | N/A |
| Start to send migration to target | `/vm.send-migration` | `/schemas/SendMigrationData` | N/A | The VM is booted and (shared mem or hugepages enabled) |
* The `vmcoredump` action is available exclusively for the `x86_64`
architecture and can be executed only when the `guest_debug` feature is
enabled. Without this feature, the corresponding REST API endpoint is not
available.
| Action | Endpoint | Request Body | Response Body | Prerequisites |
| ---------------------------------- | --------------------- | --------------------------- | ------------------------ | -------------------------------- |
| Create the VM | `/vm.create` | `/schemas/VmConfig` | N/A | The VM is not created yet |
| Delete the VM | `/vm.delete` | N/A | N/A | N/A |
| Boot the VM | `/vm.boot` | N/A | N/A | The VM is created but not booted |
| Shut the VM down | `/vm.shutdown` | N/A | N/A | The VM is booted |
| Reboot the VM | `/vm.reboot` | N/A | N/A | The VM is booted |
| Trigger power button of the VM | `/vm.power-button` | N/A | N/A | The VM is booted |
| Pause the VM | `/vm.pause` | N/A | N/A | The VM is booted |
| Resume the VM | `/vm.resume` | N/A | N/A | The VM is paused |
| Task a snapshot of the VM | `/vm.snapshot` | `/schemas/VmSnapshotConfig` | N/A | The VM is paused |
| Perform a coredump of the VM | `/vm.coredump` | `/schemas/VmCoredumpData` | N/A | The VM is paused |
| Restore the VM from a snapshot | `/vm.restore` | `/schemas/RestoreConfig` | N/A | The VM is created but not booted |
| Add/remove CPUs to/from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted |
| Add/remove memory from the VM | `/vm.resize` | `/schemas/VmResize` | N/A | The VM is booted |
| Add/remove memory from a zone | `/vm.resize-zone` | `/schemas/VmResizeZone` | N/A | The VM is booted |
| Dump the VM information | `/vm.info` | N/A | `/schemas/VmInfo` | The VM is created |
| Add VFIO PCI device to the VM | `/vm.add-device` | `/schemas/VmAddDevice` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add disk device to the VM | `/vm.add-disk` | `/schemas/DiskConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add fs device to the VM | `/vm.add-fs` | `/schemas/FsConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add pmem device to the VM | `/vm.add-pmem` | `/schemas/PmemConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add network device to the VM | `/vm.add-net` | `/schemas/NetConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add userspace PCI device to the VM | `/vm.add-user-device` | `/schemas/VmAddUserDevice` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add vdpa device to the VM | `/vm.add-vdpa` | `/schemas/VdpaConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Add vsock device to the VM | `/vm.add-vsock` | `/schemas/VsockConfig` | `/schemas/PciDeviceInfo` | The VM is booted |
| Remove device from the VM | `/vm.remove-device` | `/schemas/VmRemoveDevice` | N/A | The VM is booted |
| Dump the VM counters | `/vm.counters` | N/A | `/schemas/VmCounters` | The VM is booted |
### REST API Examples
@@ -228,7 +221,7 @@ The CLI options are parsed by the
[internal API](#internal-api) commands.
The REST API is processed by an HTTP thread using the
[Firecracker's `micro_http`](https://github.com/firecracker-microvm/micro-http)
[Firecracker's `micro_http`](https://github.com/firecracker-microvm/firecracker/tree/master/src/micro_http)
crate. As with the CLI, the HTTP requests eventually get translated into
[internal API](#internal-api) commands.
@@ -386,5 +379,5 @@ APIs work together, let's look at a complete VM creation flow, from the
```
1. The Cloud Hypervisor HTTP thread sends the formed HTTP response back to the
user. This is abstracted by the
[micro_http](https://github.com/firecracker-microvm/micro-http)
[micro_http](https://github.com/firecracker-microvm/firecracker/tree/master/src/micro_http)
crate.

View File

@@ -266,8 +266,11 @@ _Example_
### `file`
Path to the file backing the memory zone. The file will be opened and used as
the backing file for the `mmap(2)` operation.
Path to the file backing the memory zone. This can be either a file or a
directory. In case of a file, it will be opened and used as the backing file
for the `mmap(2)` operation. In case of a directory, a temporary file with no
hard link on the filesystem will be created. This file will be used as the
backing file for the `mmap(2)` operation.
This option can be particularly useful when trying to back a part of the guest
RAM with a well known file. In the context of the snapshot/restore feature, and

View File

@@ -7,4 +7,4 @@ edition = "2021"
[dependencies]
libc = "0.2.139"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"

151
fuzz/Cargo.lock generated
View File

@@ -5,16 +5,16 @@ version = 3
[[package]]
name = "acpi_tables"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#0b892e2c2053c4ecfac8d9e5a52babae75114702"
source = "git+https://github.com/rust-vmm/acpi_tables?branch=main#4fd38dd5f746730ec5ae848dafcf8c2f50a13fc3"
dependencies = [
"zerocopy",
"vm-memory",
]
[[package]]
name = "anyhow"
version = "1.0.70"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
[[package]]
name = "api_client"
@@ -25,9 +25,9 @@ dependencies = [
[[package]]
name = "arbitrary"
version = "1.3.0"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e"
checksum = "3e90af4de65aa7b293ef2d09daff88501eb254f58edde2e1ac02c82d873eadad"
[[package]]
name = "arc-swap"
@@ -76,7 +76,7 @@ dependencies = [
"argh_shared",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@@ -143,7 +143,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cloud-hypervisor"
version = "30.0.0"
version = "29.0.0"
dependencies = [
"anyhow",
"api_client",
@@ -208,9 +208,9 @@ checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910"
[[package]]
name = "darling"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
dependencies = [
"darling_core",
"darling_macro",
@@ -218,27 +218,27 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 1.0.109",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.14.4"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
dependencies = [
"darling_core",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@@ -351,15 +351,15 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.6"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jobserver"
version = "0.1.26"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
dependencies = [
"libc",
]
@@ -393,9 +393,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.141"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libfuzzer-sys"
@@ -498,9 +498,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@@ -518,9 +518,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.26"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
@@ -536,13 +536,13 @@ dependencies = [
[[package]]
name = "remain"
version = "0.2.8"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13cca257d068dd3a390d04b2c3009a3fad2ee5048dfa8f239d048372810470c"
checksum = "5704e2cda92fd54202f05430725317ba0ea7d0c96b246ca0a92e45177127ba3b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.4",
"syn",
]
[[package]]
@@ -556,9 +556,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.13"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "seccompiler"
@@ -571,35 +571,35 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.17"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "serde"
version = "1.0.159"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.159"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.4",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.95"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
dependencies = [
"itoa",
"ryu",
@@ -608,9 +608,9 @@ dependencies = [
[[package]]
name = "serde_with"
version = "2.3.2"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0"
checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c"
dependencies = [
"serde",
"serde_with_macros",
@@ -618,14 +618,14 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "2.3.2"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c"
checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@@ -665,20 +665,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.109"
version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c622ae390c9302e214c31013517c2061ecb2699935882c60a9b37f82f8625ae"
checksum = "d56e159d99e6c2b93995d171050271edb50ecc5288fbc7cc17de8fdce4e58c14"
dependencies = [
"proc-macro2",
"quote",
@@ -687,22 +676,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.40"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.40"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.4",
"syn",
]
[[package]]
@@ -731,9 +720,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.8"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "uuid"
@@ -746,9 +735,9 @@ dependencies = [
[[package]]
name = "versionize"
version = "0.1.10"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca4b7062e7e6d685901e815c35f9671e059de97c1c0905eeff8592f3fff442f"
checksum = "d6e2495726cf917e7ba7ec8bf0f0fceab543dd38d0a4195ed6bef331e38a290f"
dependencies = [
"bincode",
"crc64",
@@ -756,7 +745,7 @@ dependencies = [
"quote",
"serde",
"serde_derive",
"syn 1.0.109",
"syn",
"versionize_derive",
"vmm-sys-util",
]
@@ -764,11 +753,11 @@ dependencies = [
[[package]]
name = "versionize_derive"
version = "0.1.4"
source = "git+https://github.com/cloud-hypervisor/versionize_derive?branch=ch#e502b1d4aabab342386f0c53780d49f21a6a1df6"
source = "git+https://github.com/cloud-hypervisor/versionize_derive?branch=ch#ae35ef7a3ddabd3371ab8ac0193a383aff6e4b1b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn",
]
[[package]]
@@ -1000,7 +989,6 @@ dependencies = [
"vm-migration",
"vm-virtio",
"vmm-sys-util",
"zerocopy",
]
[[package]]
@@ -1042,24 +1030,3 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "zerocopy"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6505e6815af7de1746a08f69c69606bb45695a17149517680f3b2149713b19a3"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]

View File

@@ -12,7 +12,7 @@ cargo-fuzz = true
block_util = { path = "../block_util" }
devices = { path = "../devices" }
epoll = "4.3.1"
libc = "0.2.141"
libc = "0.2.138"
libfuzzer-sys = "0.4.6"
linux-loader = { version = "0.8.1", features = ["elf", "bzimage", "pe"] }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" }

View File

@@ -6,14 +6,14 @@ edition = "2021"
license = "Apache-2.0 OR BSD-3-Clause"
[features]
kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"]
mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv"]
kvm = ["kvm-ioctls", "kvm-bindings"]
mshv = ["mshv-ioctls", "mshv-bindings"]
tdx = []
[dependencies]
anyhow = "1.0.69"
byteorder = "1.4.3"
thiserror = "1.0.39"
thiserror = "1.0.38"
libc = "0.2.139"
log = "0.4.17"
kvm-ioctls = { version = "0.13.0", optional = true }
@@ -21,7 +21,7 @@ kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branc
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.151", features = ["rc", "derive"] }
serde_with = { version = "2.3.1", default-features = false, features = ["macros"] }
serde_with = { version = "2.1.0", default-features = false, features = ["macros"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }

View File

@@ -330,22 +330,21 @@ impl KvmVm {
Ok(VfioDeviceFd::new_from_kvm(device_fd))
}
/// Checks if a particular `Cap` is available.
fn check_extension(&self, c: Cap) -> bool {
pub fn check_extension(&self, c: Cap) -> bool {
self.fd.check_extension(c)
}
}
///
/// Implementation of Vm trait for KVM
///
/// # Examples
///
/// ```
/// # use hypervisor::kvm::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = KvmHypervisor::new().unwrap();
/// let hypervisor = Arc::new(kvm);
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// ```
/// vm.set/get().unwrap()
///
impl vm::Vm for KvmVm {
#[cfg(target_arch = "x86_64")]
///
@@ -918,16 +917,13 @@ impl KvmHypervisor {
}
}
/// Implementation of Hypervisor trait for KVM
///
/// # Examples
///
/// ```
/// # use hypervisor::kvm::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = KvmHypervisor::new().unwrap();
/// let hypervisor = Arc::new(kvm);
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// ```
///
impl hypervisor::Hypervisor for KvmHypervisor {
///
/// Returns the type of the hypervisor
@@ -936,15 +932,13 @@ impl hypervisor::Hypervisor for KvmHypervisor {
HypervisorType::Kvm
}
/// Create a KVM vm object of a specific VM type and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # use hypervisor::kvm::KvmHypervisor;
/// use hypervisor::kvm::KvmVm;
/// Example
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// use hypervisor::KvmVm;
/// let hypervisor = KvmHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm_with_type(0).unwrap();
/// ```
/// let vm = hypervisor.create_vm_with_type(KvmVmType::LegacyVm).unwrap()
///
fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result<Arc<dyn vm::Vm>> {
let fd: VmFd;
loop {
@@ -998,15 +992,13 @@ impl hypervisor::Hypervisor for KvmHypervisor {
}
/// Create a KVM vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// # use hypervisor::kvm::KvmHypervisor;
/// use hypervisor::kvm::KvmVm;
/// Example
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// use hypervisor::KvmVm;
/// let hypervisor = KvmHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
/// let vm = hypervisor.create_vm().unwrap()
///
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
#[allow(unused_mut)]
let mut vm_type: u64 = 0; // Create with default platform type
@@ -1095,17 +1087,15 @@ pub struct KvmVcpu {
hyperv_synic: AtomicBool,
}
/// Implementation of Vcpu trait for KVM
///
/// # Examples
///
/// ```
/// # use hypervisor::kvm::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = KvmHypervisor::new().unwrap();
/// let hypervisor = Arc::new(kvm);
/// Example:
/// #[cfg(feature = "kvm")]
/// extern crate hypervisor
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// let vcpu = vm.create_vcpu(0, None).unwrap();
/// ```
/// vcpu.get/set().unwrap()
///
impl cpu::Vcpu for KvmVcpu {
#[cfg(target_arch = "x86_64")]
///
@@ -1807,10 +1797,11 @@ impl cpu::Vcpu for KvmVcpu {
/// # Example
///
/// ```rust
/// # use hypervisor::kvm::KvmHypervisor;
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = KvmHypervisor::new().unwrap();
/// let hv = Arc::new(kvm);
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hv.create_vm().expect("new VM fd creation failed");
/// vm.enable_split_irq().unwrap();
/// let vcpu = vm.create_vcpu(0, None).unwrap();
@@ -1978,10 +1969,11 @@ impl cpu::Vcpu for KvmVcpu {
/// # Example
///
/// ```rust
/// # use hypervisor::kvm::KvmHypervisor;
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = KvmHypervisor::new().unwrap();
/// let hv = Arc::new(kvm);
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hv.create_vm().expect("new VM fd creation failed");
/// vm.enable_split_irq().unwrap();
/// let vcpu = vm.create_vcpu(0, None).unwrap();

View File

@@ -48,9 +48,9 @@ mod cpu;
/// Device related module
mod device;
pub use crate::hypervisor::{Hypervisor, HypervisorError};
pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
pub use device::HypervisorDeviceError;
pub use hypervisor::{Hypervisor, HypervisorError};
#[cfg(all(feature = "kvm", target_arch = "aarch64"))]
pub use kvm::{aarch64, GicState};
use std::sync::Arc;

View File

@@ -195,16 +195,13 @@ impl MshvHypervisor {
}
}
/// Implementation of Hypervisor trait for Mshv
///
/// # Examples
///
/// ```
/// # use hypervisor::mshv::MshvHypervisor;
/// # use std::sync::Arc;
/// let mshv = MshvHypervisor::new().unwrap();
/// let hypervisor = Arc::new(mshv);
/// Example:
/// #[cfg(feature = "mshv")]
/// extern crate hypervisor
/// let mshv = hypervisor::mshv::MshvHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(mshv);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// ```
///
impl hypervisor::Hypervisor for MshvHypervisor {
///
/// Returns the type of the hypervisor
@@ -213,16 +210,13 @@ impl hypervisor::Hypervisor for MshvHypervisor {
HypervisorType::Mshv
}
/// Create a mshv vm object and return the object as Vm trait object
///
/// # Examples
///
/// ```
/// Example
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm;
/// # use hypervisor::MshvHypervisor;
/// use hypervisor::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap();
/// ```
/// let vm = hypervisor.create_vm().unwrap()
///
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
let fd: VmFd;
loop {
@@ -291,17 +285,15 @@ pub struct MshvVcpu {
}
/// Implementation of Vcpu trait for Microsoft Hypervisor
///
/// # Examples
///
/// ```
/// # use hypervisor::mshv::MshvHypervisor;
/// # use std::sync::Arc;
/// let mshv = MshvHypervisor::new().unwrap();
/// let hypervisor = Arc::new(mshv);
/// Example:
/// #[cfg(feature = "mshv")]
/// extern crate hypervisor
/// let mshv = hypervisor::mshv::MshvHypervisor::new().unwrap();
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(mshv);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// let vcpu = vm.create_vcpu(0, None).unwrap();
/// ```
/// let vcpu = vm.create_vcpu(0).unwrap();
/// vcpu.get/set().unwrap()
///
impl cpu::Vcpu for MshvVcpu {
#[cfg(target_arch = "x86_64")]
///
@@ -925,17 +917,15 @@ impl MshvVm {
///
/// Implementation of Vm trait for Mshv
///
/// # Examples
///
/// ```
/// Example:
/// #[cfg(feature = "mshv")]
/// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor;
/// # use std::sync::Arc;
/// # use hypervisor::MshvHypervisor;
/// let mshv = MshvHypervisor::new().unwrap();
/// let hypervisor = Arc::new(mshv);
/// let hypervisor: Arc<dyn hypervisor::Hypervisor> = Arc::new(mshv);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
/// ```
/// vm.set/get().unwrap()
///
impl vm::Vm for MshvVm {
#[cfg(target_arch = "x86_64")]
///

View File

@@ -12,11 +12,11 @@ log = "0.4.17"
net_gen = { path = "../net_gen" }
rate_limiter = { path = "../rate_limiter" }
serde = "1.0.151"
thiserror = "1.0.39"
versionize = "0.1.10"
thiserror = "1.0.38"
versionize = "0.1.9"
versionize_derive = "0.1.4"
virtio-bindings = "0.2.0"
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = "0.11.0"
@@ -25,4 +25,4 @@ vmm-sys-util = "0.11.0"
once_cell = "1.17.1"
pnet = "0.33.0"
pnet_datalink = "0.33.0"
serde_json = "1.0.95"
serde_json = "1.0.93"

View File

@@ -21,8 +21,8 @@ vmm-sys-util = "0.11.0"
libc = "0.2.139"
log = "0.4.17"
serde = { version = "1.0.151", features = ["derive"] }
thiserror = "1.0.39"
versionize = "0.1.10"
thiserror = "1.0.38"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }

View File

@@ -9,7 +9,7 @@ build = "../build.rs"
argh = "0.1.9"
dirs = "4.0.0"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"
test_infra = { path = "../test_infra" }
thiserror = "1.0.39"
thiserror = "1.0.38"
wait-timeout = "0.2.0"

View File

@@ -110,23 +110,18 @@ impl Default for MetricsReport {
#[derive(Default)]
pub struct PerformanceTestOverrides {
test_iterations: Option<u32>,
test_timeout: Option<u32>,
}
impl fmt::Display for PerformanceTestOverrides {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(test_iterations) = self.test_iterations {
write!(f, "test_iterations = {test_iterations}, ")?;
}
if let Some(test_timeout) = self.test_timeout {
write!(f, "test_timeout = {test_timeout}")?;
write!(f, "test_iterations = {test_iterations}")?;
}
Ok(())
}
}
#[derive(Clone)]
pub struct PerformanceTestControl {
test_timeout: u32,
test_iterations: u32,
@@ -193,14 +188,7 @@ impl PerformanceTest {
.test_iterations
.unwrap_or(self.control.test_iterations)
{
// update the timeout in control if passed explicitly and run testcase with it
if let Some(test_timeout) = overrides.test_timeout {
let mut control: PerformanceTestControl = self.control.clone();
control.test_timeout = test_timeout;
metrics.push((self.func_ptr)(&control));
} else {
metrics.push((self.func_ptr)(&self.control));
}
metrics.push((self.func_ptr)(&self.control));
}
let mean = (self.unit_adjuster)(mean(&metrics).unwrap());
@@ -219,9 +207,9 @@ impl PerformanceTest {
// Calculate the timeout for each test
// Note: To cover the setup/cleanup time, 20s is added for each iteration of the test
pub fn calc_timeout(&self, test_iterations: &Option<u32>, test_timeout: &Option<u32>) -> u64 {
((test_timeout.unwrap_or(self.control.test_timeout) + 20)
* test_iterations.unwrap_or(self.control.test_iterations)) as u64
pub fn calc_timeout(&self, test_iterations: &Option<u32>) -> u64 {
((self.control.test_timeout + 20) * test_iterations.unwrap_or(self.control.test_iterations))
as u64
}
}
@@ -599,7 +587,6 @@ fn run_test_with_timeout(
) -> Result<PerformanceTestResult, Error> {
let (sender, receiver) = channel::<Result<PerformanceTestResult, Error>>();
let test_iterations = overrides.test_iterations;
let test_timeout = overrides.test_timeout;
let overrides = overrides.clone();
thread::spawn(move || {
println!(
@@ -622,7 +609,7 @@ fn run_test_with_timeout(
});
// Todo: Need to cleanup/kill all hanging child processes
let test_timeout = test.calc_timeout(&test_iterations, &test_timeout);
let test_timeout = test.calc_timeout(&test_iterations);
receiver
.recv_timeout(Duration::from_secs(test_timeout))
.map_err(|_| {
@@ -658,10 +645,6 @@ struct Options {
/// override number of test iterations
iterations: Option<u32>,
#[argh(option, long = "timeout")]
/// override test timeout, Ex. --timeout 5
timeout: Option<u32>,
#[argh(switch, short = 'V', long = "version")]
/// print version information
version: bool,
@@ -700,7 +683,6 @@ fn main() {
let overrides = Arc::new(PerformanceTestOverrides {
test_iterations: opts.iterations,
test_timeout: opts.timeout,
});
for test in test_list.iter() {

View File

@@ -1,18 +1,11 @@
- [v31.0](#v310)
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
- [Update Reference Kernel to 6.2](#update-reference-kernel-to-62)
- [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)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [v30.1](#v301)
- [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-1)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Contributors](#contributors-1)
- [Documentation Improvements](#documentation-improvements)
- [Notable Bug Fixes](#notable-bug-fixes)
- [Contributors](#contributors)
- [v28.2](#v282)
- [v29.0](#v290)
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
@@ -22,10 +15,10 @@
- [`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-2)
- [Notable Bug Fixes](#notable-bug-fixes-1)
- [Removals](#removals)
- [Deprecations](#deprecations)
- [Contributors](#contributors-2)
- [Contributors](#contributors-1)
- [v28.1](#v281)
- [v28.0](#v280)
- [Community Engagement (Reminder)](#community-engagement-reminder)
@@ -33,9 +26,9 @@
- [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-3)
- [Notable Bug Fixes](#notable-bug-fixes-2)
- [Removals](#removals-1)
- [Contributors](#contributors-3)
- [Contributors](#contributors-2)
- [v27.0](#v270)
- [Community Engagement](#community-engagement)
- [Prebuilt Packages](#prebuilt-packages)
@@ -44,41 +37,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-4)
- [Notable Bug Fixes](#notable-bug-fixes-3)
- [Deprecations](#deprecations-1)
- [Contributors](#contributors-4)
- [Contributors](#contributors-3)
- [v26.0](#v260)
- [SMBIOS Improvements via `--platform`](#smbios-improvements-via---platform)
- [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-5)
- [Notable Bug Fixes](#notable-bug-fixes-4)
- [Deprecations](#deprecations-2)
- [Removals](#removals-2)
- [Contributors](#contributors-5)
- [Contributors](#contributors-4)
- [v25.0](#v250)
- [`ch-remote` Improvements](#ch-remote-improvements-1)
- [VM "Coredump" Support](#vm-coredump-support)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Notable Bug Fixes](#notable-bug-fixes-5)
- [Removals](#removals-3)
- [Contributors](#contributors-6)
- [Contributors](#contributors-5)
- [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-7)
- [Notable Bug Fixes](#notable-bug-fixes-6)
- [Notable Improvements](#notable-improvements)
- [Deprecations](#deprecations-3)
- [New on the Website](#new-on-the-website)
- [Contributors](#contributors-7)
- [Contributors](#contributors-6)
- [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-8)
- [Notable Bug Fixes](#notable-bug-fixes-7)
- [Deprecations](#deprecations-4)
- [Contributors](#contributors-8)
- [Contributors](#contributors-7)
- [v22.1](#v221)
- [v22.0](#v220)
- [GDB Debug Stub Support](#gdb-debug-stub-support)
@@ -89,13 +82,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-9)
- [Contributors](#contributors-9)
- [Notable Bug Fixes](#notable-bug-fixes-8)
- [Contributors](#contributors-8)
- [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-10)
- [Contributors](#contributors-10)
- [Notable Bug fixes](#notable-bug-fixes-9)
- [Contributors](#contributors-9)
- [v20.2](#v202)
- [v20.1](#v201)
- [v20.0](#v200)
@@ -104,8 +97,8 @@
- [Improved VFIO support](#improved-vfio-support)
- [Safer code](#safer-code)
- [Extended documentation](#extended-documentation)
- [Notable bug fixes](#notable-bug-fixes-11)
- [Contributors](#contributors-11)
- [Notable bug fixes](#notable-bug-fixes-10)
- [Contributors](#contributors-10)
- [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)
@@ -113,8 +106,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-12)
- [Contributors](#contributors-12)
- [Notable bug fixes](#notable-bug-fixes-11)
- [Contributors](#contributors-11)
- [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)
@@ -124,31 +117,31 @@
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
- [Power button support on AArch64](#power-button-support-on-aarch64)
- [Notable bug fixes](#notable-bug-fixes-13)
- [Contributors](#contributors-13)
- [Notable bug fixes](#notable-bug-fixes-12)
- [Contributors](#contributors-12)
- [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-14)
- [Contributors](#contributors-14)
- [Notable bug fixes](#notable-bug-fixes-13)
- [Contributors](#contributors-13)
- [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-15)
- [Notable bug fixes](#notable-bug-fixes-14)
- [Removed functionality](#removed-functionality)
- [Contributors](#contributors-15)
- [Contributors](#contributors-14)
- [v15.0](#v150)
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
- [Network device rate limiting](#network-device-rate-limiting)
- [Support for runtime control of `virtio-net` guest offload](#support-for-runtime-control-of-virtio-net-guest-offload)
- [`--api-socket` supports file descriptor parameter](#--api-socket-supports-file-descriptor-parameter)
- [`--api-socket` supports file descriptor parameter](#-api-socket-supports-file-descriptor-parameter)
- [Bug fixes](#bug-fixes)
- [Deprecations](#deprecations-5)
- [Contributors](#contributors-16)
- [Contributors](#contributors-15)
- [v0.14.1](#v0141)
- [v0.14.0](#v0140)
- [Structured event monitoring](#structured-event-monitoring)
@@ -158,7 +151,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-17)
- [Contributors](#contributors-16)
- [v0.13.0](#v0130)
- [Wider VFIO device support](#wider-vfio-device-support)
- [Improved huge page support](#improved-huge-page-support)
@@ -166,13 +159,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-18)
- [Contributors](#contributors-17)
- [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-19)
- [Contributors](#contributors-18)
- [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)
@@ -182,17 +175,17 @@
- [Improved Linux Boot Time](#improved-linux-boot-time)
- [`SIGTERM/SIGINT` Interrupt Signal Handling](#sigtermsigint-interrupt-signal-handling)
- [Default Log Level Changed](#default-log-level-changed)
- [New `--balloon` Parameter Added](#new---balloon-parameter-added)
- [New `--balloon` Parameter Added](#new-balloon-parameter-added)
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
- [Notable Bug Fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-20)
- [Notable Bug Fixes](#notable-bug-fixes-15)
- [Contributors](#contributors-19)
- [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-17)
- [Contributors](#contributors-21)
- [Notable Bug Fixes](#notable-bug-fixes-16)
- [Contributors](#contributors-20)
- [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)
@@ -205,17 +198,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-18)
- [Contributors](#contributors-22)
- [Notable Bug Fixes](#notable-bug-fixes-17)
- [Contributors](#contributors-21)
- [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-19)
- [Notable Bug Fixes](#notable-bug-fixes-18)
- [Command Line and API Changes](#command-line-and-api-changes)
- [Contributors](#contributors-23)
- [Contributors](#contributors-22)
- [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)
@@ -225,14 +218,14 @@
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
- [Updated Distribution Support](#updated-distribution-support)
- [Command Line and API Changes](#command-line-and-api-changes-1)
- [Contributors](#contributors-24)
- [Contributors](#contributors-23)
- [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-25)
- [Contributors](#contributors-24)
- [v0.5.1](#v051)
- [v0.5.0](#v050)
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
@@ -240,7 +233,7 @@
- [New Interrupt Management Framework](#new-interrupt-management-framework)
- [Development Tools](#development-tools)
- [Kata Containers Integration](#kata-containers-integration)
- [Contributors](#contributors-26)
- [Contributors](#contributors-25)
- [v0.4.0](#v040)
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
@@ -249,7 +242,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-27)
- [Contributors](#contributors-26)
- [v0.3.0](#v030)
- [Block device offloading](#block-device-offloading)
- [Network device backend](#network-device-backend)
@@ -276,71 +269,19 @@
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v31.0
# v30.1
This release has been tracked in our [roadmap
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
v31.0. The following user visible changes have been made:
This is a bug fix release. The following issues have been addressed:
### Update to Latest `acpi_tables`
Adapted to the latest [acpi_tables](https://github.com/rust-vmm/acpi_tables).
There has been significant API changes in the crate.
### Update Reference Kernel to 6.2
Updated the recommended guest kernel version from 6.1.6 to 6.2.
### Improvements on Console `SIGWINCH` Handler
A separate thread had been created to capture the `SIGWINCH` signal and resize
the guest console. Now the thread is skipped if the console is not resizable.
Two completely different code paths existed for handling console resizing, one
for `tty` and the other for `pty`. That makes the understanding of the console
handling code unnecessarily complicated. Now the code paths are unified. Both
`tty` and `pty` are supported in single `SIGWINCH` handler. And the new handler
can works with kernel versions earlier than v5.5.
### Remove Directory Support from `MemoryZoneConfig::file`
Setting a directory to `MemoryZoneConfig::file` is no longer supported.
Before this change, user can set a directory to `file` of the `--memory-zone`
option. In that case, a temporary file will be created as the backing file for
the `mmap(2)` operation. This functionality has been unnecessary since we had
the native support for hugepages and allocating anonymous shared memory.
### Documentation Improvements
* Various improvements in API document
* Improvements in Doc comments
* Updated Slack channel information in README
### Notable Bug Fixes
* Fixed the offset setting while removing the entire mapping of `vhost-user` FS
client.
* Fixed the `ShutdownVmm` and `Shutdown` commands to call the correct API
endpoint.
### 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@fdr.io>
* Dom <peng6662001@163.com>
* Hao Xu <howeyxu@tencent.com>
* Muminul Islam <muislam@microsoft.com>
* Omer Faruk Bayram <omer.faruk@sartura.hr>
* Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
* Rob Bradford <rbradford@rivosinc.com>
* Ruslan Mstoi <ruslan.mstoi@intel.com>
* Smit Gardhariya <gardhariya.smit@gmail.com>
* Yang <ailin.yang@intel.com>
* Yong He <alexyonghe@tencent.com>
* Ignore and warn TAP FDs sent via the HTTP request body (#5350)
* Properly preserve and close valid FDs for TAP devices (#5373)
* Only use `KVM_ARM_VCPU_PMU_V3` if available (#5360)
* Only touch the tty flags if it's being used (#5343)
* Fix seccomp filter lists for vhost-user devices (#5361)
* Fix the offset setting while removing the entire mapping of
`vhost-user` FS client (#5235)
* Fix the `ShutdownVmm` and `Shutdown` commands to call the correct API
endpoint (#5322)
# v30.0

View File

@@ -1,12 +1,10 @@
# SPDX-License-Identifier: Apache-2.0
#
# 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
ARG TARGETARCH
ARG RUST_TOOLCHAIN="1.67.1"
ARG RUST_TOOLCHAIN="1.66.1"
ARG CLH_SRC_DIR="/cloud-hypervisor"
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"

View File

@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 6.2.0 Kernel Configuration
# Linux/arm64 6.1.6 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
CONFIG_CC_IS_GCC=y
@@ -55,6 +55,7 @@ CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_IRQ_IPI=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_IRQ_MSI_IOMMU=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
@@ -202,7 +203,6 @@ CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
CONFIG_SYSCTL=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_EXPERT=y
@@ -227,7 +227,6 @@ CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_SELFTEST is not set
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
@@ -250,7 +249,7 @@ CONFIG_PERF_EVENTS=y
# end of General setup
CONFIG_ARM64=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_ARM64_PAGE_SHIFT=12
@@ -350,7 +349,6 @@ CONFIG_ARM64_ERRATUM_2054223=y
CONFIG_ARM64_ERRATUM_2067961=y
CONFIG_ARM64_ERRATUM_2441009=y
CONFIG_ARM64_ERRATUM_2457168=y
CONFIG_ARM64_ERRATUM_2645198=y
CONFIG_CAVIUM_ERRATUM_22375=y
CONFIG_CAVIUM_ERRATUM_23144=y
CONFIG_CAVIUM_ERRATUM_23154=y
@@ -378,7 +376,7 @@ CONFIG_ARM64_PA_BITS=48
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SCHED_MC=y
# CONFIG_SCHED_CLUSTER is not set
CONFIG_SCHED_CLUSTER is not set
CONFIG_SCHED_SMT=y
CONFIG_NR_CPUS=128
CONFIG_HOTPLUG_CPU=y
@@ -473,6 +471,7 @@ CONFIG_RANDOMIZE_BASE=y
CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_STACKPROTECTOR_PER_TASK=y
CONFIG_ARCH_NR_GPIO=0
# end of Kernel Features
#
@@ -560,7 +559,6 @@ CONFIG_ACPI_GENERIC_GSI=y
CONFIG_ACPI_CCA_REQUIRED=y
# CONFIG_ACPI_DEBUGGER is not set
CONFIG_ACPI_SPCR_TABLE=y
# CONFIG_ACPI_FPDT is not set
# CONFIG_ACPI_EC_DEBUGFS is not set
# CONFIG_ACPI_AC is not set
# CONFIG_ACPI_BATTERY is not set
@@ -593,10 +591,8 @@ CONFIG_HAVE_ACPI_APEI=y
# CONFIG_ACPI_PFRUT is not set
CONFIG_ACPI_IORT=y
CONFIG_ACPI_GTDT=y
CONFIG_ACPI_APMT=y
CONFIG_ACPI_PPTT=y
# CONFIG_ACPI_PCC is not set
# CONFIG_ACPI_FFH is not set
# CONFIG_PMIC_OPREGION is not set
CONFIG_ACPI_VIOT=y
# CONFIG_ACPI_PRMT is not set
@@ -605,9 +601,6 @@ CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQFD=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_KVM_DIRTY_RING=y
CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y
CONFIG_NEED_KVM_DIRTY_RING_WITH_BITMAP=y
CONFIG_HAVE_KVM_EVENTFD=y
CONFIG_KVM_MMIO=y
CONFIG_HAVE_KVM_MSI=y
@@ -661,7 +654,6 @@ CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
CONFIG_MMU_GATHER_TABLE_FREE=y
CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
@@ -726,7 +718,6 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling
CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_FUNCTION_ALIGNMENT=0
# end of General architecture-dependent options
CONFIG_RT_MUTEXES=y
@@ -893,8 +884,7 @@ CONFIG_ZSMALLOC_STAT=y
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB_DEPRECATED is not set
# CONFIG_SLUB_TINY is not set
# CONFIG_SLOB is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
CONFIG_SLAB_FREELIST_HARDENED=y
@@ -961,7 +951,6 @@ CONFIG_ZONE_DMA32=y
CONFIG_ZONE_DEVICE=y
# CONFIG_DEVICE_PRIVATE is not set
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
CONFIG_ARCH_USES_PG_ARCH_X=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
# CONFIG_GUP_TEST is not set
@@ -1133,6 +1122,7 @@ CONFIG_PCIE_PME=y
# CONFIG_PCIE_DPC is not set
# CONFIG_PCIE_PTM is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PCI_QUIRKS=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_STUB=y
@@ -1282,6 +1272,7 @@ CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB=y
# CONFIG_EFI_ZBOOT is not set
CONFIG_EFI_ARMSTUB_DTB_LOADER=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
@@ -1335,7 +1326,6 @@ CONFIG_ZRAM_DEF_COMP_LZORLE=y
CONFIG_ZRAM_DEF_COMP="lzo-rle"
# CONFIG_ZRAM_WRITEBACK is not set
# CONFIG_ZRAM_MEMORY_TRACKING is not set
# CONFIG_ZRAM_MULTI_COMP is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_DRBD is not set
@@ -1586,7 +1576,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_LEGACY_TIOCSTI is not set
# CONFIG_LDISC_AUTOLOAD is not set
#
@@ -1662,6 +1651,8 @@ CONFIG_DEVMEM=y
CONFIG_DEVPORT=y
# CONFIG_TCG_TPM is not set
# CONFIG_XILLYBUS is not set
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices
#
@@ -1750,7 +1741,6 @@ CONFIG_GPIO_PL061=y
# Virtual GPIO drivers
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_LATCH is not set
# CONFIG_GPIO_MOCKUP is not set
# CONFIG_GPIO_VIRTIO is not set
# CONFIG_GPIO_SIM is not set
@@ -2168,10 +2158,9 @@ CONFIG_UIO_DMEM_GENIRQ=y
# CONFIG_UIO_PRUSS is not set
# CONFIG_UIO_MF624 is not set
CONFIG_VFIO=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_VIRQFD=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_MMAP=y
CONFIG_VFIO_PCI_INTX=y
@@ -2270,7 +2259,6 @@ CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
# CONFIG_IOMMUFD is not set
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_SMMU_V3 is not set
CONFIG_VIRTIO_IOMMU=y
@@ -2407,7 +2395,6 @@ CONFIG_ARM_PMU_ACPI=y
# CONFIG_HISI_PMU is not set
# CONFIG_HISI_PCIE_PMU is not set
# CONFIG_HNS3_PMU is not set
# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set
# end of Performance monitor support
CONFIG_RAS=y
@@ -2583,10 +2570,8 @@ CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_FILE_CACHE=y
# CONFIG_SQUASHFS_FILE_DIRECT is not set
CONFIG_SQUASHFS_DECOMP_SINGLE=y
# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set
CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set
# CONFIG_SQUASHFS_DECOMP_MULTI is not set
# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
# CONFIG_SQUASHFS_XATTR is not set
CONFIG_SQUASHFS_ZLIB=y
# CONFIG_SQUASHFS_LZ4 is not set
@@ -2725,6 +2710,7 @@ CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_NULL2=y
# CONFIG_CRYPTO_PCRYPT is not set
@@ -2886,8 +2872,6 @@ CONFIG_CRYPTO_USER_API_RNG=y
# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
# CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set
# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set
# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set
# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set
# end of Accelerated Cryptographic Algorithms for CPU (arm64)
@@ -2926,7 +2910,6 @@ CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
#
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
# CONFIG_CRYPTO_LIB_CHACHA is not set
# CONFIG_CRYPTO_LIB_CURVE25519 is not set
@@ -3062,8 +3045,7 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
# CONFIG_DEBUG_INFO_COMPRESSED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
# CONFIG_DEBUG_INFO_BTF is not set
# CONFIG_GDB_SCRIPTS is not set
@@ -3224,7 +3206,7 @@ CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
@@ -3263,6 +3245,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_HEXDUMP is not set
# CONFIG_STRING_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_STRSCPY is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_TEST_PRINTF is not set
# CONFIG_TEST_SCANF is not set
@@ -3271,6 +3254,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_XARRAY is not set
# CONFIG_TEST_MAPLE_TREE is not set
# CONFIG_TEST_RHASHTABLE is not set
# CONFIG_TEST_SIPHASH is not set
# CONFIG_TEST_IDA is not set
# CONFIG_FIND_BIT_BENCHMARK is not set
# CONFIG_TEST_FIRMWARE is not set

View File

@@ -1,18 +1,18 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 6.2.0 Kernel Configuration
# Linux/x86 6.1.6 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0"
CONFIG_CC_VERSION_TEXT="gcc (GCC) 12.2.1 20221121 (Red Hat 12.2.1-4)"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=110300
CONFIG_GCC_VERSION=120201
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23800
CONFIG_AS_VERSION=23700
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23800
CONFIG_LD_VERSION=23700
CONFIG_LLD_VERSION=0
CONFIG_RUST_IS_AVAILABLE=y
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
@@ -70,6 +70,7 @@ CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_IRQ_MSI_IOMMU=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
@@ -227,7 +228,6 @@ CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
CONFIG_SYSCTL=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
@@ -254,7 +254,6 @@ CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_SELFTEST is not set
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
@@ -275,6 +274,7 @@ CONFIG_PERF_EVENTS=y
# end of Kernel Performance Events And Counters
# CONFIG_PROFILING is not set
# CONFIG_RUST is not set
# end of General setup
CONFIG_64BIT=y
@@ -294,6 +294,7 @@ CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_NR_GPIO=1024
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_AUDIT_ARCH=y
CONFIG_X86_64_SMP=y
@@ -421,10 +422,7 @@ CONFIG_X86_INTEL_TSX_MODE_OFF=y
# CONFIG_X86_SGX is not set
CONFIG_EFI=y
CONFIG_EFI_STUB=y
# CONFIG_EFI_HANDOVER_PROTOCOL is not set
# CONFIG_EFI_MIXED is not set
# CONFIG_EFI_FAKE_MEMMAP is not set
CONFIG_EFI_RUNTIME_MAP=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
@@ -457,20 +455,11 @@ CONFIG_HAVE_LIVEPATCH=y
CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y
CONFIG_CC_HAS_ENTRY_PADDING=y
CONFIG_FUNCTION_PADDING_CFI=11
CONFIG_FUNCTION_PADDING_BYTES=16
CONFIG_CALL_PADDING=y
CONFIG_HAVE_CALL_THUNKS=y
CONFIG_CALL_THUNKS=y
CONFIG_PREFIX_SYMBOLS=y
CONFIG_SPECULATION_MITIGATIONS=y
CONFIG_PAGE_TABLE_ISOLATION=y
CONFIG_RETPOLINE=y
CONFIG_RETHUNK=y
CONFIG_CPU_UNRET_ENTRY=y
CONFIG_CALL_DEPTH_TRACKING=y
# CONFIG_CALL_THUNKS_DEBUG is not set
CONFIG_CPU_IBPB_ENTRY=y
CONFIG_CPU_IBRS_ENTRY=y
# CONFIG_SLS is not set
@@ -544,7 +533,6 @@ CONFIG_HAVE_ACPI_APEI_NMI=y
# CONFIG_ACPI_CONFIGFS is not set
# CONFIG_ACPI_PFRUT is not set
# CONFIG_ACPI_PCC is not set
# CONFIG_ACPI_FFH is not set
# CONFIG_PMIC_OPREGION is not set
CONFIG_ACPI_VIOT=y
# CONFIG_ACPI_PRMT is not set
@@ -640,7 +628,6 @@ CONFIG_KVM=y
# CONFIG_KVM_WERROR is not set
CONFIG_KVM_INTEL=y
# CONFIG_KVM_AMD is not set
CONFIG_KVM_SMM=y
# CONFIG_KVM_XEN is not set
CONFIG_AS_AVX512=y
CONFIG_AS_SHA1_NI=y
@@ -697,7 +684,6 @@ CONFIG_MMU_GATHER_TABLE_FREE=y
CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
@@ -779,9 +765,6 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling
CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FUNCTION_ALIGNMENT_16B=y
CONFIG_FUNCTION_ALIGNMENT=16
# end of General architecture-dependent options
CONFIG_RT_MUTEXES=y
@@ -899,8 +882,7 @@ CONFIG_ZSMALLOC_STAT=y
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB_DEPRECATED is not set
# CONFIG_SLUB_TINY is not set
# CONFIG_SLOB is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
CONFIG_SLAB_FREELIST_HARDENED=y
@@ -975,6 +957,7 @@ CONFIG_SECRETMEM=y
CONFIG_USERFAULTFD=y
CONFIG_HAVE_ARCH_USERFAULTFD_WP=y
CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y
CONFIG_PTE_MARKER=y
CONFIG_PTE_MARKER_UFFD_WP=y
# CONFIG_LRU_GEN is not set
@@ -1139,6 +1122,7 @@ CONFIG_PCIE_PME=y
# CONFIG_PCIE_DPC is not set
# CONFIG_PCIE_PTM is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PCI_QUIRKS=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_STUB=y
@@ -1267,8 +1251,11 @@ CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# EFI (Extensible Firmware Interface) Support
#
CONFIG_EFI_ESRT=y
CONFIG_EFI_RUNTIME_MAP=y
# CONFIG_EFI_FAKE_MEMMAP is not set
CONFIG_EFI_DXE_MEM_ATTRIBUTES=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
# CONFIG_EFI_CAPSULE_LOADER is not set
# CONFIG_EFI_TEST is not set
@@ -1309,7 +1296,6 @@ CONFIG_ZRAM_DEF_COMP_LZORLE=y
CONFIG_ZRAM_DEF_COMP="lzo-rle"
# CONFIG_ZRAM_WRITEBACK is not set
# CONFIG_ZRAM_MEMORY_TRACKING is not set
# CONFIG_ZRAM_MULTI_COMP is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_DRBD is not set
@@ -1564,7 +1550,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_LEGACY_TIOCSTI is not set
# CONFIG_LDISC_AUTOLOAD is not set
#
@@ -1639,6 +1624,8 @@ CONFIG_HANGCHECK_TIMER=y
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
# CONFIG_XILLYBUS is not set
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices
#
@@ -1687,7 +1674,6 @@ CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_CDEV_V1=y
CONFIG_GPIO_IDIO_16=y
#
# Memory mapped GPIO drivers
@@ -1731,7 +1717,6 @@ CONFIG_GPIO_PCI_IDIO_16=y
# Virtual GPIO drivers
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_LATCH is not set
# CONFIG_GPIO_MOCKUP is not set
# CONFIG_GPIO_VIRTIO is not set
# CONFIG_GPIO_SIM is not set
@@ -1799,7 +1784,6 @@ CONFIG_WATCHDOG_OPEN_TIMEOUT=0
# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not set
# CONFIG_ADVANTECH_EC_WDT is not set
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_EBC_C384_WDT is not set
@@ -2140,10 +2124,9 @@ CONFIG_UIO_DMEM_GENIRQ=y
# CONFIG_UIO_MF624 is not set
# CONFIG_UIO_HV_GENERIC is not set
CONFIG_VFIO=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_VIRQFD=y
# CONFIG_VFIO_NOIOMMU is not set
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_MMAP=y
CONFIG_VFIO_PCI_INTX=y
@@ -2219,7 +2202,6 @@ CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
CONFIG_IOMMU_DMA=y
# CONFIG_AMD_IOMMU is not set
# CONFIG_INTEL_IOMMU is not set
# CONFIG_IOMMUFD is not set
# CONFIG_IRQ_REMAP is not set
CONFIG_HYPERV_IOMMU=y
CONFIG_VIRTIO_IOMMU=y
@@ -2562,7 +2544,12 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity"
#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
# CONFIG_INIT_STACK_NONE is not set
# CONFIG_INIT_STACK_ALL_PATTERN is not set
CONFIG_INIT_STACK_ALL_ZERO=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
@@ -2598,6 +2585,7 @@ CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_NULL2=y
# CONFIG_CRYPTO_PCRYPT is not set
@@ -2807,7 +2795,6 @@ CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
#
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
# CONFIG_CRYPTO_LIB_CHACHA is not set
# CONFIG_CRYPTO_LIB_CURVE25519 is not set
@@ -2895,7 +2882,6 @@ CONFIG_FONT_8x16=y
CONFIG_SG_POOL=y
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_MEMREGION=y
CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAS_COPY_MC=y
CONFIG_ARCH_STACKWALK=y
@@ -2936,8 +2922,7 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
# CONFIG_DEBUG_INFO_COMPRESSED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
# CONFIG_DEBUG_INFO_BTF is not set
# CONFIG_GDB_SCRIPTS is not set
@@ -3113,7 +3098,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_OBJTOOL_MCOUNT=y
CONFIG_HAVE_OBJTOOL_NOP_MCOUNT=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACING_SUPPORT=y
@@ -3173,6 +3157,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_HEXDUMP is not set
# CONFIG_STRING_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_STRSCPY is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_TEST_PRINTF is not set
# CONFIG_TEST_SCANF is not set
@@ -3181,6 +3166,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_XARRAY is not set
# CONFIG_TEST_MAPLE_TREE is not set
# CONFIG_TEST_RHASHTABLE is not set
# CONFIG_TEST_SIPHASH is not set
# CONFIG_TEST_IDA is not set
# CONFIG_FIND_BIT_BENCHMARK is not set
# CONFIG_TEST_FIRMWARE is not set

View File

@@ -6,8 +6,8 @@
CLI_NAME="Cloud Hypervisor"
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
CTR_IMAGE_VERSION="20230316-0"
CTR_IMAGE_TAG="cloudhypervisor/dev"
CTR_IMAGE_VERSION="20230123-0"
CTR_IMAGE="${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}"
DOCKER_RUNTIME="docker"
@@ -172,11 +172,7 @@ process_volumes_args() {
cmd_help() {
echo ""
echo "Cloud Hypervisor $(basename "$0")"
echo "Usage: $(basename "$0") [flags] <command> [<command args>]"
echo ""
echo "Available flags":
echo ""
echo " --local Set the container image version being used to \"local\"."
echo "Usage: $(basename "$0") <command> [<command args>]"
echo ""
echo "Available commands:"
echo ""

View File

@@ -240,9 +240,7 @@ 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
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Run all direct kernel boot (Device Tree) test cases in mod `parallel`

View File

@@ -56,8 +56,26 @@ popd
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
if [ ! -f "$VMLINUX_IMAGE" ]; then
build_custom_linux
SRCDIR=$PWD
pushd $WORKLOADS_DIR
time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-6.1.6" $LINUX_CUSTOM_DIR
cp $SRCDIR/resources/linux-config-x86_64 $LINUX_CUSTOM_DIR/.config
popd
fi
if [ ! -f "$VMLINUX_IMAGE" ]; then
pushd $LINUX_CUSTOM_DIR
time make bzImage -j `nproc`
cp vmlinux $VMLINUX_IMAGE || exit 1
popd
fi
if [ -d "$LINUX_CUSTOM_DIR" ]; then
rm -rf $LINUX_CUSTOM_DIR
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
@@ -71,9 +89,7 @@ fi
cargo build --no-default-features --features "kvm,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
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1

View File

@@ -45,7 +45,29 @@ if [ $? -ne 0 ]; then
fi
popd
build_custom_linux
# Build custom kernel based on virtio-pmem and virtio-fs upstream patches
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
if [ ! -f "$VMLINUX_IMAGE" ]; then
SRCDIR=$PWD
pushd $WORKLOADS_DIR
time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-6.1.6" $LINUX_CUSTOM_DIR
cp $SRCDIR/resources/linux-config-x86_64 $LINUX_CUSTOM_DIR/.config
popd
fi
if [ ! -f "$VMLINUX_IMAGE" ]; then
pushd $LINUX_CUSTOM_DIR
time make bzImage -j `nproc`
cp vmlinux $VMLINUX_IMAGE || exit 1
popd
fi
if [ -d "$LINUX_CUSTOM_DIR" ]; then
rm -rf $LINUX_CUSTOM_DIR
fi
BUILD_TARGET="$(uname -m)-unknown-linux-${CH_LIBC}"
CFLAGS=""

View File

@@ -12,7 +12,9 @@ FOCAL_OS_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_IMAGE_NAME"
FW="$WORKLOADS_DIR/hypervisor-fw"
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
build_custom_linux
if [ ! -f "$VMLINUX_IMAGE" ]; then
build_custom_linux
fi
BLK_IMAGE="$WORKLOADS_DIR/blk.img"
MNT_DIR="mount_image"
@@ -50,9 +52,7 @@ cp target/$BUILD_TARGET/release/cloud-hypervisor $VFIO_DIR
cp target/$BUILD_TARGET/release/ch-remote $VFIO_DIR
# test_vfio 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
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
export RUST_BACKTRACE=1

View File

@@ -169,9 +169,7 @@ 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
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Update max locked memory to 'unlimited' to avoid issues with vDPA

View File

@@ -95,9 +95,7 @@ fi
cargo build --no-default-features --features "kvm,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
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
if [ -n "$test_filter" ]; then

View File

@@ -22,4 +22,3 @@ 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

View File

@@ -46,7 +46,7 @@ build_custom_linux() {
ARCH=$(uname -m)
SRCDIR=$PWD
LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
LINUX_CUSTOM_BRANCH="ch-6.2"
LINUX_CUSTOM_BRANCH="ch-6.1.6"
LINUX_CUSTOM_URL="https://github.com/cloud-hypervisor/linux.git"
checkout_repo "$LINUX_CUSTOM_DIR" "$LINUX_CUSTOM_URL" "$LINUX_CUSTOM_BRANCH"

View File

@@ -21,7 +21,6 @@ use thiserror::Error;
use vmm::config;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::signal::block_signal;
use vmm_sys_util::terminal::Terminal;
#[cfg(feature = "dhat-heap")]
#[global_allocator]
@@ -586,14 +585,6 @@ fn main() {
}
};
// SAFETY: trivially safe
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO) } != 0;
if on_tty {
// Don't forget to set the terminal in canonical mode
// before to exit.
std::io::stdin().lock().set_canon_mode().unwrap();
}
#[cfg(feature = "dhat-heap")]
drop(_profiler);
@@ -731,6 +722,7 @@ mod unit_tests {
gdb: false,
platform: None,
tpm: None,
preserved_fds: None,
};
assert_eq!(expected_vm_config, result_vm_config);

View File

@@ -10,7 +10,7 @@ epoll = "4.3.1"
libc = "0.2.139"
once_cell = "1.17.1"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"
ssh2 = { version = "0.9.4", features = ["vendored-openssl"] }
vmm-sys-util = "0.11.0"
wait-timeout = "0.2.0"

View File

@@ -1352,7 +1352,6 @@ pub fn parse_iperf3_output(output: &[u8], sender: bool, bandwidth: bool) -> Resu
})
}
#[derive(Clone)]
pub enum FioOps {
Read,
RandomRead,

View File

@@ -10,8 +10,6 @@
extern crate test_infra;
use api_client::simple_api_command;
use api_client::simple_api_full_command;
use net_util::MacAddr;
use std::collections::HashMap;
use std::fs;
@@ -254,6 +252,26 @@ fn prepare_swtpm_daemon(tmp_dir: &TempDir) -> (std::process::Command, String) {
(swtpm_command, swtpm_socket_path)
}
fn curl_command(api_socket: &str, method: &str, url: &str, http_body: Option<&str>) {
let mut curl_args: Vec<&str> = ["--unix-socket", api_socket, "-i", "-X", method, url].to_vec();
if let Some(body) = http_body {
curl_args.push("-H");
curl_args.push("Accept: application/json");
curl_args.push("-H");
curl_args.push("Content-Type: application/json");
curl_args.push("-d");
curl_args.push(body);
}
let status = Command::new("curl")
.args(curl_args)
.status()
.expect("Failed to launch curl command");
assert!(status.success());
}
fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
let mut cmd = Command::new(clh_command("ch-remote"));
cmd.args(["--api-socket", api_socket, command]);
@@ -1904,7 +1922,7 @@ fn enable_guest_watchdog(guest: &Guest, watchdog_sec: u32) {
}
mod common_parallel {
use std::{fs::OpenOptions, io::SeekFrom, os::unix::net::UnixStream};
use std::{fs::OpenOptions, io::SeekFrom};
use crate::*;
@@ -2230,7 +2248,7 @@ mod common_parallel {
"--memory-zone",
"id=mem0,size=1G,hotplug_size=2G",
"--memory-zone",
"id=mem1,size=1G,shared=on",
"id=mem1,size=1G,file=/dev/shm",
"--memory-zone",
"id=mem2,size=1G,host_numa_node=0,hotplug_size=2G",
])
@@ -3726,7 +3744,7 @@ mod common_parallel {
// line (We tag the command line from cloud-hypervisor for that purpose).
// The third device is added to validate that hotplug works correctly since
// it is being added to the L2 VM through hotplugging mechanism.
// Also, we pass-through a virtio-blk device to the L2 VM to test the 32-bit
// Also, we pass-through a vitio-blk device to the L2 VM to test the 32-bit
// vfio device support
fn test_vfio() {
setup_vfio_network_interfaces();
@@ -4046,9 +4064,8 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(1, 0));
let mut socket = UnixStream::connect(&api_socket).unwrap();
// Verify API server is running
simple_api_full_command(&mut socket, "GET", "vmm.ping", None).unwrap();
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
// Create the VM first
let cpu_count: u8 = 4;
@@ -4101,9 +4118,8 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(1, 0));
let mut socket = UnixStream::connect(&api_socket).unwrap();
// Verify API server is running
simple_api_full_command(&mut socket, "GET", "vmm.ping", None).unwrap();
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
// Create the VM first
let cpu_count: u8 = 4;
@@ -4114,12 +4130,15 @@ mod common_parallel {
);
let r = std::panic::catch_unwind(|| {
// socket has to be created again inside catch_unwind block to avoid errors
let mut socket = UnixStream::connect(&api_socket).unwrap();
simple_api_command(&mut socket, "PUT", "create", Some(&http_body)).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.create",
Some(&http_body),
);
// Then boot it
simple_api_command(&mut socket, "PUT", "boot", None).unwrap();
curl_command(&api_socket, "PUT", "http://localhost/api/v1/vm.boot", None);
guest.wait_vm_boot(None).unwrap();
@@ -4136,10 +4155,15 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(20, 0));
// Then shut it down
simple_api_command(&mut socket, "PUT", "shutdown", None).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.shutdown",
None,
);
// Then boot it again
simple_api_command(&mut socket, "PUT", "boot", None).unwrap();
curl_command(&api_socket, "PUT", "http://localhost/api/v1/vm.boot", None);
guest.wait_vm_boot(None).unwrap();
@@ -4172,9 +4196,8 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(1, 0));
let mut socket = UnixStream::connect(&api_socket).unwrap();
// Verify API server is running
simple_api_full_command(&mut socket, "GET", "vmm.ping", None).unwrap();
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
// Create the VM first
let cpu_count: u8 = 4;
@@ -4185,12 +4208,15 @@ mod common_parallel {
);
let r = std::panic::catch_unwind(|| {
// socket has to be created again inside catch_unwind block to avoid errors
let mut socket = UnixStream::connect(&api_socket).unwrap();
simple_api_command(&mut socket, "PUT", "create", Some(&http_body)).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.create",
Some(&http_body),
);
// Then boot it
simple_api_command(&mut socket, "PUT", "boot", None).unwrap();
curl_command(&api_socket, "PUT", "http://localhost/api/v1/vm.boot", None);
guest.wait_vm_boot(None).unwrap();
@@ -4207,12 +4233,22 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(20, 0));
// Then delete it
simple_api_command(&mut socket, "PUT", "delete", None).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.delete",
None,
);
simple_api_command(&mut socket, "PUT", "create", Some(&http_body)).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.create",
Some(&http_body),
);
// Then boot it again
simple_api_command(&mut socket, "PUT", "boot", None).unwrap();
curl_command(&api_socket, "PUT", "http://localhost/api/v1/vm.boot", None);
guest.wait_vm_boot(None).unwrap();
@@ -4246,9 +4282,8 @@ mod common_parallel {
thread::sleep(std::time::Duration::new(1, 0));
let mut socket = UnixStream::connect(&api_socket).unwrap();
// Verify API server is running
simple_api_full_command(&mut socket, "GET", "vmm.ping", None).unwrap();
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
// Create the VM first
let cpu_count: u8 = 4;
@@ -4257,12 +4292,15 @@ mod common_parallel {
direct_kernel_boot_path().to_str().unwrap(),
DIRECT_KERNEL_BOOT_CMDLINE,
);
simple_api_command(&mut socket, "PUT", "create", Some(&http_body)).unwrap();
curl_command(
&api_socket,
"PUT",
"http://localhost/api/v1/vm.create",
Some(&http_body),
);
// Then boot it
simple_api_command(&mut socket, "PUT", "boot", None).unwrap();
curl_command(&api_socket, "PUT", "http://localhost/api/v1/vm.boot", None);
thread::sleep(std::time::Duration::new(20, 0));
let r = std::panic::catch_unwind(|| {
@@ -5199,7 +5237,6 @@ mod common_parallel {
}
#[test]
#[cfg(not(feature = "mshv"))]
fn test_virtio_balloon_free_page_reporting() {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
@@ -6238,6 +6275,18 @@ mod common_parallel {
.unwrap_or_default(),
2
);
guest.reboot_linux(0, None);
assert_eq!(
guest
.ssh_command("ip -o link | wc -l")
.unwrap()
.trim()
.parse::<u32>()
.unwrap_or_default(),
2
);
});
let _ = child.kill();

View File

@@ -9,7 +9,7 @@ libc = "0.2.139"
log = "0.4.17"
once_cell = "1.17.1"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"
[features]
tracing = []

View File

@@ -11,5 +11,5 @@ crc32c = "0.6.3"
libc = "0.2.139"
log = "0.4.17"
remain = "0.2.6"
thiserror = "1.0.39"
thiserror = "1.0.38"
uuid = { version = "1.3.0", features = ["v4"] }

View File

@@ -17,7 +17,7 @@ qcow = { path = "../qcow" }
vhost = { version = "0.6.0", features = ["vhost-user-slave"] }
vhost-user-backend = "0.8.0"
virtio-bindings = "0.2.0"
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-memory = "0.10.0"
vmm-sys-util = "0.11.0"

View File

@@ -14,7 +14,7 @@ block_util = { path = "../block_util" }
byteorder = "1.4.3"
epoll = "4.3.1"
event_monitor = { path = "../event_monitor" }
io-uring = "0.5.13"
io-uring = "0.5.12"
libc = "0.2.139"
log = "0.4.17"
net_gen = { path = "../net_gen" }
@@ -23,14 +23,14 @@ pci = { path = "../pci" }
rate_limiter = { path = "../rate_limiter" }
seccompiler = "0.3.0"
serde = { version = "1.0.151", features = ["derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"
serial_buffer = { path = "../serial_buffer" }
thiserror = "1.0.39"
versionize = "0.1.10"
thiserror = "1.0.38"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vhost = { version = "0.6.0", features = ["vhost-user-master", "vhost-user-slave", "vhost-kern", "vhost-vdpa"] }
virtio-bindings = { version = "0.2.0", features = ["virtio-v5_0_0"] }
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }

View File

@@ -151,6 +151,7 @@ fn virtio_rng_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn virtio_vhost_fs_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_clock_nanosleep, vec![]),
(libc::SYS_connect, vec![]),
(libc::SYS_nanosleep, vec![]),
(libc::SYS_pread64, vec![]),
@@ -170,8 +171,11 @@ fn virtio_vhost_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_accept4, vec![]),
(libc::SYS_bind, vec![]),
(libc::SYS_clock_nanosleep, vec![]),
(libc::SYS_connect, vec![]),
(libc::SYS_getcwd, vec![]),
(libc::SYS_listen, vec![]),
(libc::SYS_nanosleep, vec![]),
(libc::SYS_recvmsg, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_sendto, vec![]),
@@ -184,7 +188,14 @@ fn virtio_vhost_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
}
fn virtio_vhost_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![]
vec![
(libc::SYS_clock_nanosleep, vec![]),
(libc::SYS_connect, vec![]),
(libc::SYS_nanosleep, vec![]),
(libc::SYS_recvmsg, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_socket, vec![]),
]
}
fn create_vsock_ioctl_seccomp_rule() -> Vec<SeccompRule> {

View File

@@ -1,28 +1,28 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
//! The main job of `VsockConnection` is to forward data traffic, back and forth, between a
//! guest-side AF_VSOCK socket and a host-side generic `Read + Write + AsRawFd` stream, while
//! also managing its internal state.
//! To that end, `VsockConnection` implements:
//! - `VsockChannel` for:
//! - moving data from the host stream to a guest-provided RX buffer, via `recv_pkt()`; and
//! - moving data from a guest-provided TX buffer to the host stream, via `send_pkt()`; and
//! - updating its internal state, by absorbing control packets (anything other than
//! VSOCK_OP_RW).
//! - `VsockEpollListener` for getting notified about the availability of data or free buffer
//! space at the host stream.
//!
//! Note: there is a certain asymmetry to the RX and TX data flows:
//! - RX transfers do not need any data buffering, since data is read straight from the
//! host stream and into the guest-provided RX buffer;
//! - TX transfers may require some data to be buffered by `VsockConnection`, if the host
//! peer can't keep up with reading the data that we're writing. This is because, once
//! the guest driver provides some data in a virtio TX buffer, the vsock device must
//! consume it. If that data can't be forwarded straight to the host stream, we'll
//! have to store it in a buffer (and flush it at a later time). Vsock flow control
//! ensures that our TX buffer doesn't overflow.
//
/// The main job of `VsockConnection` is to forward data traffic, back and forth, between a
/// guest-side AF_VSOCK socket and a host-side generic `Read + Write + AsRawFd` stream, while
/// also managing its internal state.
/// To that end, `VsockConnection` implements:
/// - `VsockChannel` for:
/// - moving data from the host stream to a guest-provided RX buffer, via `recv_pkt()`; and
/// - moving data from a guest-provided TX buffer to the host stream, via `send_pkt()`; and
/// - updating its internal state, by absorbing control packets (anything other than
/// VSOCK_OP_RW).
/// - `VsockEpollListener` for getting notified about the availability of data or free buffer
/// space at the host stream.
///
/// Note: there is a certain asymmetry to the RX and TX data flows:
/// - RX transfers do not need any data buffering, since data is read straight from the
/// host stream and into the guest-provided RX buffer;
/// - TX transfers may require some data to be buffered by `VsockConnection`, if the host
/// peer can't keep up with reading the data that we're writing. This is because, once
/// the guest driver provides some data in a virtio TX buffer, the vsock device must
/// consume it. If that data can't be forwarded straight to the host stream, we'll
/// have to store it in a buffer (and flush it at a later time). Vsock flow control
/// ensures that our TX buffer doesn't overflow.
///
// The code in this file is best read with a fresh memory of the vsock protocol inner-workings.
// To help with that, here is a
//

View File

@@ -1,9 +1,9 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
//! This module implements our vsock connection state machine. The heavy lifting is done by
//! `connection::VsockConnection`, while this file only defines some constants and helper structs.
/// This module implements our vsock connection state machine. The heavy lifting is done by
/// `connection::VsockConnection`, while this file only defines some constants and helper structs.
///
mod connection;
mod txbuf;

View File

@@ -2,19 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
//
//! `VsockPacket` provides a thin wrapper over the buffers exchanged via virtio queues.
//! There are two components to a vsock packet, each using its own descriptor in a
//! virtio queue:
//! - the packet header; and
//! - the packet data/buffer.
//! There is a 1:1 relation between descriptor chains and packets: the first (chain head) holds
//! the header, and an optional second descriptor holds the data. The second descriptor is only
//! present for data packets (VSOCK_OP_RW).
//!
//! `VsockPacket` wraps these two buffers and provides direct access to the data stored
//! in guest memory. This is done to avoid unnecessarily copying data from guest memory
//! to temporary buffers, before passing it on to the vsock backend.
/// `VsockPacket` provides a thin wrapper over the buffers exchanged via virtio queues.
/// There are two components to a vsock packet, each using its own descriptor in a
/// virtio queue:
/// - the packet header; and
/// - the packet data/buffer.
/// There is a 1:1 relation between descriptor chains and packets: the first (chain head) holds
/// the header, and an optional second descriptor holds the data. The second descriptor is only
/// present for data packets (VSOCK_OP_RW).
///
/// `VsockPacket` wraps these two buffers and provides direct access to the data stored
/// in guest memory. This is done to avoid unnecessarily copying data from guest memory
/// to temporary buffers, before passing it on to the vsock backend.
///
use byteorder::{ByteOrder, LittleEndian};
use std::ops::Deref;
use std::sync::Arc;

View File

@@ -2,13 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
//
//! This module implements the Unix Domain Sockets backend for vsock - a mediator between
//! guest-side AF_VSOCK sockets and host-side AF_UNIX sockets. The heavy lifting is performed by
//! `muxer::VsockMuxer`, a connection multiplexer that uses `super::csm::VsockConnection` for
//! handling vsock connection states.
//!
//! Check out `muxer.rs` for a more detailed explanation of the inner workings of this backend.
/// This module implements the Unix Domain Sockets backend for vsock - a mediator between
/// guest-side AF_VSOCK sockets and host-side AF_UNIX sockets. The heavy lifting is performed by
/// `muxer::VsockMuxer`, a connection multiplexer that uses `super::csm::VsockConnection` for
/// handling vsock connection states.
/// Check out `muxer.rs` for a more detailed explanation of the inner workings of this backend.
///
mod muxer;
mod muxer_killq;
mod muxer_rxq;

View File

@@ -2,42 +2,35 @@
// SPDX-License-Identifier: Apache-2.0
//
//! `VsockMuxer` is the device-facing component of the Unix domain sockets vsock backend. I.e.
//! by implementing the `VsockBackend` trait, it abstracts away the gory details of translating
//! between AF_VSOCK and AF_UNIX, and presents a clean interface to the rest of the vsock
//! device model.
//!
//! The vsock muxer has two main roles:
//!
//! ## Vsock connection multiplexer
//!
//! It's the muxer's job to create, manage, and terminate `VsockConnection` objects. The
//! muxer also routes packets to their owning connections. It does so via a connection
//! `HashMap`, keyed by what is basically a (host_port, guest_port) tuple.
//!
//! Vsock packet traffic needs to be inspected, in order to detect connection request
//! packets (leading to the creation of a new connection), and connection reset packets
//! (leading to the termination of an existing connection). All other packets, though, must
//! belong to an existing connection and, as such, the muxer simply forwards them.
//!
//! ## Event dispatcher
//!
//! There are three event categories that the vsock backend is interested it:
//! 1. A new host-initiated connection is ready to be accepted from the listening host Unix
//! socket;
//! 2. Data is available for reading from a newly-accepted host-initiated connection (i.e.
//! the host is ready to issue a vsock connection request, informing us of the
//! destination port to which it wants to connect);
//! 3. Some event was triggered for a connected Unix socket, that belongs to a
//! `VsockConnection`.
//!
//! The muxer gets notified about all of these events, because, as a `VsockEpollListener`
//! implementor, it gets to register a nested epoll FD into the main VMM epolling loop. All
//! other pollable FDs are then registered under this nested epoll FD.
//!
//! To route all these events to their handlers, the muxer uses another `HashMap` object,
//! mapping `RawFd`s to `EpollListener`s.
/// `VsockMuxer` is the device-facing component of the Unix domain sockets vsock backend. I.e.
/// by implementing the `VsockBackend` trait, it abstracts away the gory details of translating
/// between AF_VSOCK and AF_UNIX, and presents a clean interface to the rest of the vsock
/// device model.
///
/// The vsock muxer has two main roles:
/// 1. Vsock connection multiplexer:
/// It's the muxer's job to create, manage, and terminate `VsockConnection` objects. The
/// muxer also routes packets to their owning connections. It does so via a connection
/// `HashMap`, keyed by what is basically a (host_port, guest_port) tuple.
/// Vsock packet traffic needs to be inspected, in order to detect connection request
/// packets (leading to the creation of a new connection), and connection reset packets
/// (leading to the termination of an existing connection). All other packets, though, must
/// belong to an existing connection and, as such, the muxer simply forwards them.
/// 2. Event dispatcher
/// There are three event categories that the vsock backend is interested it:
/// 1. A new host-initiated connection is ready to be accepted from the listening host Unix
/// socket;
/// 2. Data is available for reading from a newly-accepted host-initiated connection (i.e.
/// the host is ready to issue a vsock connection request, informing us of the
/// destination port to which it wants to connect);
/// 3. Some event was triggered for a connected Unix socket, that belongs to a
/// `VsockConnection`.
/// The muxer gets notified about all of these events, because, as a `VsockEpollListener`
/// implementor, it gets to register a nested epoll FD into the main VMM epolling loop. All
/// other pollable FDs are then registered under this nested epoll FD.
/// To route all these events to their handlers, the muxer uses another `HashMap` object,
/// mapping `RawFd`s to `EpollListener`s.
///
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{self, Read};
@@ -87,7 +80,7 @@ enum EpollListener {
},
/// A listener interested in new host-initiated connections.
HostSock,
/// A listener interested in reading host "connect \<port>" commands from a freshly
/// A listener interested in reading host "connect <port>" commands from a freshly
/// connected host socket.
LocalStream(UnixStream),
}
@@ -113,7 +106,7 @@ pub struct VsockMuxer {
/// The Unix socket, through which host-initiated connections are accepted.
host_sock: UnixListener,
/// The file system path of the host-side Unix socket. This is used to figure out the path
/// to Unix sockets listening on specific ports. I.e. "\<this path>_\<port number>".
/// to Unix sockets listening on specific ports. I.e. "<this path>_<port number>".
host_sock_path: String,
/// The nested epoll File, used to register epoll listeners.
epoll_file: File,

View File

@@ -2,29 +2,29 @@
// SPDX-License-Identifier: Apache-2.0
//
//! `MuxerKillQ` implements a helper object that `VsockMuxer` can use for scheduling forced
//! connection termination. I.e. after one peer issues a clean shutdown request
//! (VSOCK_OP_SHUTDOWN), the concerned connection is queued for termination (VSOCK_OP_RST) in
//! the near future (herein implemented via an expiring timer).
//!
//! Whenever the muxer needs to schedule a connection for termination, it pushes it (or rather
//! an identifier - the connection key) to this queue. A subsequent pop() operation will
//! succeed if and only if the first connection in the queue is ready to be terminated (i.e.
//! its kill timer expired).
//!
//! Without using this queue, the muxer would have to walk its entire connection pool
//! (hashmap), whenever it needs to check for expired kill timers. With this queue, both
//! scheduling and termination are performed in constant time. However, since we don't want to
//! waste space on a kill queue that's as big as the connection hashmap itself, it is possible
//! that this queue may become full at times. We call this kill queue "synchronized" if we are
//! certain that all connections that are awaiting termination are present in the queue. This
//! means a simple constant-time pop() operation is enough to check whether any connections
//! need to be terminated. When the kill queue becomes full, though, pushing fails, so
//! connections that should be terminated are left out. The queue is not synchronized anymore.
//! When that happens, the muxer will first drain the queue, and then replace it with a new
//! queue, created by walking the connection pool, looking for connections that will be
//! expiring in the future.
/// `MuxerKillQ` implements a helper object that `VsockMuxer` can use for scheduling forced
/// connection termination. I.e. after one peer issues a clean shutdown request
/// (VSOCK_OP_SHUTDOWN), the concerned connection is queued for termination (VSOCK_OP_RST) in
/// the near future (herein implemented via an expiring timer).
///
/// Whenever the muxer needs to schedule a connection for termination, it pushes it (or rather
/// an identifier - the connection key) to this queue. A subsequent pop() operation will
/// succeed if and only if the first connection in the queue is ready to be terminated (i.e.
/// its kill timer expired).
///
/// Without using this queue, the muxer would have to walk its entire connection pool
/// (hashmap), whenever it needs to check for expired kill timers. With this queue, both
/// scheduling and termination are performed in constant time. However, since we don't want to
/// waste space on a kill queue that's as big as the connection hashmap itself, it is possible
/// that this queue may become full at times. We call this kill queue "synchronized" if we are
/// certain that all connections that are awaiting termination are present in the queue. This
/// means a simple constant-time pop() operation is enough to check whether any connections
/// need to be terminated. When the kill queue becomes full, though, pushing fails, so
/// connections that should be terminated are left out. The queue is not synchronized anymore.
/// When that happens, the muxer will first drain the queue, and then replace it with a new
/// queue, created by walking the connection pool, looking for connections that will be
/// expiring in the future.
///
use std::collections::{HashMap, VecDeque};
use std::time::Instant;

View File

@@ -2,20 +2,20 @@
// SPDX-License-Identifier: Apache-2.0
//
//! `MuxerRxQ` implements a helper object that `VsockMuxer` can use for queuing RX (host -> guest)
//! packets (or rather instructions on how to build said packets).
//!
//! Under ideal operation, every connection, that has pending RX data, will be present in the muxer
//! RX queue. However, since the RX queue is smaller than the connection pool, it may, under some
//! conditions, become full, meaning that it can no longer account for all the connections that can
//! yield RX data. When that happens, we say that it is no longer "synchronized" (i.e. with the
//! connection pool). A desynchronized RX queue still holds valid data, and the muxer will
//! continue to pop packets from it. However, when a desynchronized queue is drained, additional
//! data may still be available, so the muxer will have to perform a more costly walk of the entire
//! connection pool to find it. This walk is performed here, as part of building an RX queue from
//! the connection pool. When an out-of-sync is drained, the muxer will discard it, and attempt to
//! rebuild a synced one.
/// `MuxerRxQ` implements a helper object that `VsockMuxer` can use for queuing RX (host -> guest)
/// packets (or rather instructions on how to build said packets).
///
/// Under ideal operation, every connection, that has pending RX data, will be present in the muxer
/// RX queue. However, since the RX queue is smaller than the connection pool, it may, under some
/// conditions, become full, meaning that it can no longer account for all the connections that can
/// yield RX data. When that happens, we say that it is no longer "synchronized" (i.e. with the
/// connection pool). A desynchronized RX queue still holds valid data, and the muxer will
/// continue to pop packets from it. However, when a desynchronized queue is drained, additional
/// data may still be available, so the muxer will have to perform a more costly walk of the entire
/// connection pool to find it. This walk is performed here, as part of building an RX queue from
/// the connection pool. When an out-of-sync is drained, the muxer will discard it, and attempt to
/// rebuild a synced one.
///
use std::collections::{HashMap, VecDeque};
use super::super::VsockChannel;

View File

@@ -12,7 +12,7 @@ mshv = ["vfio-ioctls/mshv"]
[dependencies]
anyhow = "1.0.69"
hypervisor = { path = "../hypervisor" }
thiserror = "1.0.39"
thiserror = "1.0.38"
serde = { version = "1.0.151", features = ["rc", "derive"] }
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.10.0", features = ["backend-mmap"] }

View File

@@ -6,9 +6,9 @@ edition = "2021"
[dependencies]
anyhow = "1.0.69"
thiserror = "1.0.39"
thiserror = "1.0.38"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
versionize = "0.1.10"
serde_json = "1.0.93"
versionize = "0.1.9"
versionize_derive = "0.1.4"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic"] }

View File

@@ -12,8 +12,8 @@ use versionize::{VersionMap, Versionize};
pub mod protocol;
/// Global VMM version for versioning
const MAJOR_VERSION: u16 = 31;
const MINOR_VERSION: u16 = 0;
const MAJOR_VERSION: u16 = 30;
const MINOR_VERSION: u16 = 1;
const VMM_VERSION: u16 = MAJOR_VERSION << 12 | MINOR_VERSION & 0b1111;
pub trait VersionMapped {

View File

@@ -9,5 +9,5 @@ default = []
[dependencies]
log = "0.4.17"
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }

View File

@@ -22,7 +22,7 @@ block_util = { path = "../block_util" }
devices = { path = "../devices" }
epoll = "4.3.1"
event_monitor = { path = "../event_monitor" }
gdbstub = { version = "0.6.4", optional = true }
gdbstub = { version = "0.6.3", optional = true }
gdbstub_arch = { version = "0.2.4", optional = true }
hypervisor = { path = "../hypervisor" }
libc = "0.2.139"
@@ -36,23 +36,22 @@ pci = { path = "../pci" }
qcow = { path = "../qcow" }
seccompiler = "0.3.0"
serde = { version = "1.0.151", features = ["rc", "derive"] }
serde_json = "1.0.95"
serde_json = "1.0.93"
serial_buffer = { path = "../serial_buffer" }
signal-hook = "0.3.15"
thiserror = "1.0.39"
signal-hook = "0.3.14"
thiserror = "1.0.38"
tracer = { path = "../tracer" }
uuid = "1.3.0"
versionize = "0.1.10"
versionize = "0.1.9"
versionize_derive = "0.1.4"
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" }
vhdx = { path = "../vhdx" }
virtio-devices = { path = "../virtio-devices" }
virtio-queue = "0.7.1"
virtio-queue = "0.7.0"
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
zerocopy = "0.6.1"

View File

@@ -9,7 +9,7 @@ use crate::pci_segment::PciSegment;
use crate::{GuestMemoryMmap, GuestRegionMmap};
#[cfg(target_arch = "aarch64")]
use acpi_tables::sdt::GenericAddress;
use acpi_tables::{rsdp::Rsdp, sdt::Sdt, Aml};
use acpi_tables::{aml::Aml, rsdp::Rsdp, sdt::Sdt};
#[cfg(target_arch = "aarch64")]
use arch::aarch64::DeviceInfoForFdt;
#[cfg(target_arch = "aarch64")]
@@ -20,8 +20,7 @@ use pci::PciBdf;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use tracer::trace_scoped;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemoryRegion};
use zerocopy::AsBytes;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryRegion};
/* Values for Type in APIC sub-headers */
#[cfg(target_arch = "x86_64")]
@@ -180,9 +179,9 @@ pub fn create_dsdt_table(
let mut bytes = Vec::new();
device_manager.lock().unwrap().to_aml_bytes(&mut bytes);
cpu_manager.lock().unwrap().to_aml_bytes(&mut bytes);
memory_manager.lock().unwrap().to_aml_bytes(&mut bytes);
device_manager.lock().unwrap().append_aml_bytes(&mut bytes);
cpu_manager.lock().unwrap().append_aml_bytes(&mut bytes);
memory_manager.lock().unwrap().append_aml_bytes(&mut bytes);
dsdt.append_slice(&bytes);
dsdt
@@ -812,7 +811,7 @@ pub fn create_acpi_tables(
// RSDP
let rsdp = Rsdp::new(*b"CLOUDH", xsdt_offset.0);
guest_mem
.write_slice(rsdp.as_bytes(), rsdp_offset)
.write_slice(rsdp.as_slice(), rsdp_offset)
.expect("Error writing RSDP");
info!(

View File

@@ -105,6 +105,10 @@ impl EndpointHandler for VmActionHandler {
),
AddNet(_) => {
let mut net_cfg: NetConfig = serde_json::from_slice(body.raw())?;
if net_cfg.fds.is_some() {
warn!("Ignoring FDs sent via the HTTP request body");
net_cfg.fds = None;
}
// Update network config with optional files that might have
// been sent through control message.
if !files.is_empty() {

View File

@@ -1134,38 +1134,6 @@ impl NetConfig {
}
}
impl Clone for NetConfig {
fn clone(&self) -> Self {
NetConfig {
tap: self.tap.clone(),
vhost_socket: self.vhost_socket.clone(),
id: self.id.clone(),
fds: self
.fds
.as_ref()
// SAFETY: We have been handed these FDs through the API
.map(|fds| fds.iter().map(|fd| unsafe { libc::dup(*fd) }).collect()),
..*self
}
}
}
impl Drop for NetConfig {
fn drop(&mut self) {
if let Some(mut fds) = self.fds.take() {
for fd in fds.drain(..) {
// Skip reserved FDs
if fd <= 2 {
continue;
}
// SAFETY: Safe as the fd was given to the config by the API
unsafe { libc::close(fd) };
}
}
}
}
impl RngConfig {
pub fn parse(rng: &str) -> Result<Self> {
let mut parser = OptionParser::new();
@@ -2125,23 +2093,83 @@ impl VmConfig {
gdb,
platform,
tpm,
preserved_fds: None,
};
config.validate().map_err(Error::Validation)?;
Ok(config)
}
/// # Safety
/// To use this safely, the caller must guarantee that the input
/// fds are all valid.
pub unsafe fn add_preserved_fds(&mut self, mut fds: Vec<i32>) {
if fds.is_empty() {
return;
}
if let Some(preserved_fds) = &self.preserved_fds {
fds.append(&mut preserved_fds.clone());
}
self.preserved_fds = Some(fds);
}
#[cfg(feature = "tdx")]
pub fn is_tdx_enabled(&self) -> bool {
self.platform.as_ref().map(|p| p.tdx).unwrap_or(false)
}
}
impl Clone for VmConfig {
fn clone(&self) -> Self {
VmConfig {
cpus: self.cpus.clone(),
memory: self.memory.clone(),
payload: self.payload.clone(),
disks: self.disks.clone(),
net: self.net.clone(),
rng: self.rng.clone(),
balloon: self.balloon.clone(),
fs: self.fs.clone(),
pmem: self.pmem.clone(),
serial: self.serial.clone(),
console: self.console.clone(),
devices: self.devices.clone(),
user_devices: self.user_devices.clone(),
vdpa: self.vdpa.clone(),
vsock: self.vsock.clone(),
#[cfg(target_arch = "x86_64")]
sgx_epc: self.sgx_epc.clone(),
numa: self.numa.clone(),
platform: self.platform.clone(),
tpm: self.tpm.clone(),
preserved_fds: self
.preserved_fds
.as_ref()
// SAFETY: FFI call with valid FDs
.map(|fds| fds.iter().map(|fd| unsafe { libc::dup(*fd) }).collect()),
..*self
}
}
}
impl Drop for VmConfig {
fn drop(&mut self) {
if let Some(mut fds) = self.preserved_fds.take() {
for fd in fds.drain(..) {
// SAFETY: FFI call with valid FDs
unsafe { libc::close(fd) };
}
}
}
}
#[cfg(test)]
mod tests {
use std::{fs::File, os::fd::AsRawFd};
use super::*;
use net_util::MacAddr;
use std::fs::File;
use std::os::unix::io::AsRawFd;
#[test]
fn test_cpu_parsing() -> Result<()> {
@@ -2361,10 +2389,6 @@ mod tests {
NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(),
host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()),
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}
);
@@ -2375,9 +2399,6 @@ mod tests {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(),
host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()),
id: Some("mynet0".to_owned()),
fds: None,
tap: None,
vhost_socket: None,
..Default::default()
}
);
@@ -2392,9 +2413,6 @@ mod tests {
tap: Some("tap0".to_owned()),
ip: "192.168.100.1".parse().unwrap(),
mask: "255.255.255.128".parse().unwrap(),
fds: None,
id: None,
vhost_socket: None,
..Default::default()
}
);
@@ -2408,9 +2426,6 @@ mod tests {
host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()),
vhost_user: true,
vhost_socket: Some("/tmp/sock".to_owned()),
fds: None,
id: None,
tap: None,
..Default::default()
}
);
@@ -2423,31 +2438,18 @@ mod tests {
num_queues: 4,
queue_size: 1024,
iommu: true,
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}
);
// SAFETY: Safe as the file was just opened
let fd1 = unsafe { libc::dup(File::open("/dev/null").unwrap().as_raw_fd()) };
// SAFETY: Safe as the file was just opened
let fd2 = unsafe { libc::dup(File::open("/dev/null").unwrap().as_raw_fd()) };
assert_eq!(
&format!(
"{:?}",
NetConfig::parse(&format!(
"mac=de:ad:be:ef:12:34,fd=[{fd1},{fd2}],num_queues=4"
))?
),
&format!("NetConfig {{ tap: None, ip: 192.168.249.1, mask: 255.255.255.0, \
mac: MacAddr {{ bytes: [222, 173, 190, 239, 18, 52] }}, host_mac: None, mtu: None, \
iommu: false, num_queues: 4, queue_size: 256, vhost_user: false, vhost_socket: None, \
vhost_mode: Client, id: None, fds: Some([{fd1}, {fd2}]), \
rate_limiter_config: None, pci_segment: 0, offload_tso: true, offload_ufo: true, offload_csum: true }}")
NetConfig::parse("mac=de:ad:be:ef:12:34,fd=[3,7],num_queues=4")?,
NetConfig {
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(),
fds: Some(vec![3, 7]),
num_queues: 4,
..Default::default()
}
);
Ok(())
@@ -2774,6 +2776,7 @@ mod tests {
gdb: false,
platform: None,
tpm: None,
preserved_fds: None,
};
assert!(valid_config.validate().is_ok());
@@ -2868,10 +2871,6 @@ mod tests {
let mut invalid_config = valid_config.clone();
invalid_config.net = Some(vec![NetConfig {
vhost_user: true,
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}]);
assert_eq!(
@@ -2883,9 +2882,6 @@ mod tests {
still_valid_config.net = Some(vec![NetConfig {
vhost_user: true,
vhost_socket: Some("/path/to/sock".to_owned()),
fds: None,
id: None,
tap: None,
..Default::default()
}]);
still_valid_config.memory.shared = true;
@@ -2894,9 +2890,6 @@ mod tests {
let mut invalid_config = valid_config.clone();
invalid_config.net = Some(vec![NetConfig {
fds: Some(vec![0]),
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}]);
assert_eq!(
@@ -2907,10 +2900,6 @@ mod tests {
let mut invalid_config = valid_config.clone();
invalid_config.net = Some(vec![NetConfig {
offload_csum: false,
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}]);
assert_eq!(
@@ -3014,10 +3003,6 @@ mod tests {
still_valid_config.net = Some(vec![NetConfig {
iommu: true,
pci_segment: 1,
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}]);
assert!(still_valid_config.validate().is_ok());
@@ -3086,10 +3071,6 @@ mod tests {
invalid_config.net = Some(vec![NetConfig {
iommu: false,
pci_segment: 1,
fds: None,
id: None,
tap: None,
vhost_socket: None,
..Default::default()
}]);
assert_eq!(
@@ -3205,7 +3186,7 @@ mod tests {
]);
assert!(still_valid_config.validate().is_ok());
let mut invalid_config = valid_config;
let mut invalid_config = valid_config.clone();
invalid_config.devices = Some(vec![
DeviceConfig {
path: "/device1".into(),
@@ -3217,5 +3198,16 @@ mod tests {
},
]);
assert!(invalid_config.validate().is_err());
let mut still_valid_config = valid_config;
// SAFETY: Safe as the file was just opened
let fd1 = unsafe { libc::dup(File::open("/dev/null").unwrap().as_raw_fd()) };
// SAFETY: Safe as the file was just opened
let fd2 = unsafe { libc::dup(File::open("/dev/null").unwrap().as_raw_fd()) };
// SAFETY: safe as both FDs are valid
unsafe {
still_valid_config.add_preserved_fds(vec![fd1, fd2]);
}
let _still_valid_config = still_valid_config.clone();
}
}

View File

@@ -27,7 +27,7 @@ use crate::seccomp_filters::{get_seccomp_filter, Thread};
use crate::vm::physical_bits;
use crate::GuestMemoryMmap;
use crate::CPU_MANAGER_SNAPSHOT_ID;
use acpi_tables::{aml, sdt::Sdt, Aml};
use acpi_tables::{aml, aml::Aml, sdt::Sdt};
use anyhow::anyhow;
#[cfg(all(target_arch = "aarch64", feature = "guest_debug"))]
use arch::aarch64::regs;
@@ -52,6 +52,8 @@ use hypervisor::arch::x86::MsrEntry;
use hypervisor::arch::x86::{SpecialRegisters, StandardRegisters};
#[cfg(target_arch = "aarch64")]
use hypervisor::kvm::kvm_bindings;
#[cfg(all(target_arch = "aarch64", feature = "kvm"))]
use hypervisor::kvm::kvm_ioctls::Cap;
#[cfg(feature = "tdx")]
use hypervisor::kvm::{TdxExitDetails, TdxExitStatus};
use hypervisor::{CpuState, HypervisorCpuError, HypervisorType, VmExit, VmOps};
@@ -370,7 +372,14 @@ impl Vcpu {
.map_err(Error::VcpuArmPreferredTarget)?;
// We already checked that the capability is supported.
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
if vm
.as_any()
.downcast_ref::<hypervisor::kvm::KvmVm>()
.unwrap()
.check_extension(Cap::ArmPmuV3)
{
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
}
// Non-boot cpus are powered off initially.
if self.id > 0 {
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
@@ -1717,7 +1726,7 @@ impl Cpu {
}
impl Aml for Cpu {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
#[cfg(target_arch = "x86_64")]
let mat_data: Vec<u8> = self.generate_mat();
#[allow(clippy::if_same_then_else)]
@@ -1758,7 +1767,7 @@ impl Aml for Cpu {
// containing the LAPIC for this processor with the enabled bit set
// even it if is disabled in the MADT (non-boot CPU)
#[cfg(target_arch = "x86_64")]
&aml::Name::new("_MAT".into(), &aml::BufferData::new(mat_data)),
&aml::Name::new("_MAT".into(), &aml::Buffer::new(mat_data)),
// Trigger CPU ejection
#[cfg(target_arch = "x86_64")]
&aml::Method::new(
@@ -1770,7 +1779,7 @@ impl Aml for Cpu {
),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
} else {
aml::Device::new(
format!("C{:03}", self.cpu_id).as_str().into(),
@@ -1795,10 +1804,10 @@ impl Aml for Cpu {
// containing the LAPIC for this processor with the enabled bit set
// even it if is disabled in the MADT (non-boot CPU)
#[cfg(target_arch = "x86_64")]
&aml::Name::new("_MAT".into(), &aml::BufferData::new(mat_data)),
&aml::Name::new("_MAT".into(), &aml::Buffer::new(mat_data)),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
}
}
@@ -1808,13 +1817,13 @@ struct CpuNotify {
}
impl Aml for CpuNotify {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let object = aml::Path::new(&format!("C{:03}", self.cpu_id));
aml::If::new(
&aml::Equal::new(&aml::Arg(0), &self.cpu_id),
vec![&aml::Notify::new(&object, &aml::Arg(1))],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
@@ -1824,7 +1833,7 @@ struct CpuMethods {
}
impl Aml for CpuMethods {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
if self.dynamic {
// CPU status method
aml::Method::new(
@@ -1848,19 +1857,19 @@ impl Aml for CpuMethods {
&aml::Return::new(&aml::Local(0)),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
let mut cpu_notifies = Vec::new();
for cpu_id in 0..self.max_vcpus {
cpu_notifies.push(CpuNotify { cpu_id });
}
let mut cpu_notifies_refs: Vec<&dyn Aml> = Vec::new();
let mut cpu_notifies_refs: Vec<&dyn aml::Aml> = Vec::new();
for cpu_id in 0..self.max_vcpus {
cpu_notifies_refs.push(&cpu_notifies[usize::from(cpu_id)]);
}
aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).to_aml_bytes(sink);
aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).append_aml_bytes(bytes);
aml::Method::new(
"CEJ0".into(),
@@ -1875,7 +1884,7 @@ impl Aml for CpuMethods {
&aml::Release::new("\\_SB_.PRES.CPLK".into()),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
aml::Method::new(
"CSCN".into(),
@@ -1929,22 +1938,22 @@ impl Aml for CpuMethods {
&aml::Release::new("\\_SB_.PRES.CPLK".into()),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
} else {
aml::Method::new("CSCN".into(), 0, true, vec![]).to_aml_bytes(sink)
aml::Method::new("CSCN".into(), 0, true, vec![]).append_aml_bytes(bytes)
}
}
}
impl Aml for CpuManager {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
#[cfg(target_arch = "x86_64")]
if let Some(acpi_address) = self.acpi_address {
// CPU hotplug controller
aml::Device::new(
"_SB_.PRES".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_UID".into(), &"CPU Hotplug Controller"),
// Mutex to protect concurrent access as we write to choose CPU and then read back status
&aml::Mutex::new("CPLK".into(), 0),
@@ -1961,13 +1970,12 @@ impl Aml for CpuManager {
&aml::OpRegion::new(
"PRST".into(),
aml::OpRegionSpace::SystemMemory,
&(acpi_address.0 as usize),
&CPU_MANAGER_ACPI_SIZE,
acpi_address.0 as usize,
CPU_MANAGER_ACPI_SIZE,
),
&aml::Field::new(
"PRST".into(),
aml::FieldAccessType::Byte,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::WriteAsZeroes,
vec![
aml::FieldEntry::Reserved(32),
@@ -1982,7 +1990,6 @@ impl Aml for CpuManager {
&aml::Field::new(
"PRST".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::Preserve,
vec![
aml::FieldEntry::Named(*b"CSEL", 32),
@@ -1992,18 +1999,18 @@ impl Aml for CpuManager {
),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
// CPU devices
let hid = aml::Name::new("_HID".into(), &"ACPI0010");
let uid = aml::Name::new("_CID".into(), &aml::EISAName::new("PNP0A05"));
let uid = aml::Name::new("_CID".into(), &aml::EisaName::new("PNP0A05"));
// Bundle methods together under a common object
let methods = CpuMethods {
max_vcpus: self.config.max_vcpus,
dynamic: self.dynamic,
};
let mut cpu_data_inner: Vec<&dyn Aml> = vec![&hid, &uid, &methods];
let mut cpu_data_inner: Vec<&dyn aml::Aml> = vec![&hid, &uid, &methods];
let mut cpu_devices = Vec::new();
for cpu_id in 0..self.config.max_vcpus {
@@ -2021,7 +2028,7 @@ impl Aml for CpuManager {
cpu_data_inner.push(cpu_device);
}
aml::Device::new("_SB_.CPUS".into(), cpu_data_inner).to_aml_bytes(sink)
aml::Device::new("_SB_.CPUS".into(), cpu_data_inner).append_aml_bytes(bytes)
}
}

View File

@@ -26,7 +26,7 @@ use crate::GuestRegionMmap;
use crate::PciDeviceInfo;
use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID};
use acpi_tables::sdt::GenericAddress;
use acpi_tables::{aml, Aml};
use acpi_tables::{aml, aml::Aml};
use anyhow::anyhow;
use arch::layout;
#[cfg(target_arch = "x86_64")]
@@ -70,6 +70,7 @@ use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::path::PathBuf;
use std::result;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Instant;
use tracer::trace_scoped;
@@ -100,6 +101,7 @@ use vm_migration::{
use vm_virtio::AccessPlatform;
use vm_virtio::VirtioDeviceType;
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::terminal::Terminal;
#[cfg(target_arch = "aarch64")]
const MMIO_LEN: u64 = 0x1000;
@@ -530,14 +532,6 @@ pub struct Console {
}
impl Console {
pub fn need_resize(&self) -> bool {
if let Some(_resizer) = self.console_resizer.as_ref() {
return true;
}
false
}
pub fn update_console_size(&self) {
if let Some(resizer) = self.console_resizer.as_ref() {
resizer.update_console_size()
@@ -831,6 +825,9 @@ pub struct DeviceManager {
// pty foreground status,
console_resize_pipe: Option<Arc<File>>,
// Are any devices using the tty?
on_tty: Option<Arc<AtomicBool>>,
// Interrupt controller
#[cfg(target_arch = "x86_64")]
interrupt_controller: Option<Arc<Mutex<ioapic::Ioapic>>>,
@@ -1115,6 +1112,7 @@ impl DeviceManager {
serial_manager: None,
console_pty: None,
console_resize_pipe: None,
on_tty: None,
virtio_mem_devices: Vec::new(),
#[cfg(target_arch = "aarch64")]
gpio_device: None,
@@ -1162,6 +1160,7 @@ impl DeviceManager {
serial_pty: Option<PtyPair>,
console_pty: Option<PtyPair>,
console_resize_pipe: Option<File>,
on_tty: Arc<AtomicBool>,
) -> DeviceManagerResult<()> {
trace_scoped!("create_devices");
@@ -1223,7 +1222,9 @@ impl DeviceManager {
serial_pty,
console_pty,
console_resize_pipe,
&on_tty,
)?;
self.on_tty = Some(on_tty);
if let Some(tpm) = self.config.clone().lock().unwrap().tpm.as_ref() {
let tpm_dev = self.add_tpm_device(tpm.socket.clone())?;
@@ -1864,12 +1865,12 @@ impl DeviceManager {
Ok(())
}
fn set_raw_mode(&self, f: &mut File) -> vmm_sys_util::errno::Result<()> {
fn set_raw_mode(&self, f: &mut dyn AsRawFd) -> vmm_sys_util::errno::Result<()> {
// SAFETY: FFI call. Variable t is guaranteed to be a valid termios from modify_mode.
self.modify_mode(f.as_raw_fd(), |t| unsafe { cfmakeraw(t) })
}
fn listen_for_sigwinch_on_tty(&mut self, pty_sub: File) -> std::io::Result<()> {
fn listen_for_sigwinch_on_tty(&mut self, pty_main: File, pty_sub: File) -> std::io::Result<()> {
let seccomp_filter = get_seccomp_filter(
&self.seccomp_action,
Thread::PtyForeground,
@@ -1877,8 +1878,14 @@ impl DeviceManager {
)
.unwrap();
self.console_resize_pipe =
Some(Arc::new(start_sigwinch_listener(seccomp_filter, pty_sub)?));
match start_sigwinch_listener(seccomp_filter, pty_main, pty_sub) {
Ok(pipe) => {
self.console_resize_pipe = Some(Arc::new(pipe));
}
Err(e) => {
warn!("Ignoring error from setting up SIGWINCH listener: {}", e)
}
}
Ok(())
}
@@ -1888,6 +1895,7 @@ impl DeviceManager {
virtio_devices: &mut Vec<MetaVirtioDevice>,
console_pty: Option<PtyPair>,
resize_pipe: Option<File>,
on_tty: &Arc<AtomicBool>,
) -> DeviceManagerResult<Option<Arc<virtio_devices::ConsoleResizer>>> {
let console_config = self.config.lock().unwrap().console.clone();
let endpoint = match console_config.mode {
@@ -1911,7 +1919,8 @@ impl DeviceManager {
self.config.lock().unwrap().console.file = Some(path.clone());
let file = main.try_clone().unwrap();
assert!(resize_pipe.is_none());
self.listen_for_sigwinch_on_tty(sub).unwrap();
self.listen_for_sigwinch_on_tty(main.try_clone().unwrap(), sub)
.unwrap();
self.console_pty = Some(Arc::new(Mutex::new(PtyPair { main, path })));
Endpoint::PtyPair(file.try_clone().unwrap(), file)
}
@@ -1926,13 +1935,12 @@ impl DeviceManager {
return vmm_sys_util::errno::errno_result().map_err(DeviceManagerError::DupFd);
}
// SAFETY: stdout is valid and owned solely by us.
let stdout = unsafe { File::from_raw_fd(stdout) };
let mut stdout = unsafe { File::from_raw_fd(stdout) };
// SAFETY: FFI call. Trivially safe.
if unsafe { libc::isatty(libc::STDOUT_FILENO) } == 1 {
self.listen_for_sigwinch_on_tty(stdout.try_clone().unwrap())
.unwrap();
}
on_tty.store(true, Ordering::SeqCst);
// Make sure stdout is in raw mode, if it's a terminal.
let _ = self.set_raw_mode(&mut stdout);
// If an interactive TTY then we can accept input
// SAFETY: FFI call. Trivially safe.
@@ -2004,6 +2012,7 @@ impl DeviceManager {
serial_pty: Option<PtyPair>,
console_pty: Option<PtyPair>,
console_resize_pipe: Option<File>,
on_tty: &Arc<AtomicBool>,
) -> DeviceManagerResult<Arc<Console>> {
let serial_config = self.config.lock().unwrap().serial.clone();
let serial_writer: Option<Box<dyn io::Write + Send>> = match serial_config.mode {
@@ -2025,7 +2034,12 @@ impl DeviceManager {
}
None
}
ConsoleOutputMode::Tty => Some(Box::new(stdout())),
ConsoleOutputMode::Tty => {
let mut out = stdout();
on_tty.store(true, Ordering::SeqCst);
let _ = self.set_raw_mode(&mut out);
Some(Box::new(out))
}
ConsoleOutputMode::Off | ConsoleOutputMode::Null => None,
};
if serial_config.mode != ConsoleOutputMode::Off {
@@ -2052,8 +2066,12 @@ impl DeviceManager {
};
}
let console_resizer =
self.add_virtio_console_device(virtio_devices, console_pty, console_resize_pipe)?;
let console_resizer = self.add_virtio_console_device(
virtio_devices,
console_pty,
console_resize_pipe,
on_tty,
)?;
Ok(Arc::new(Console { console_resizer }))
}
@@ -2388,26 +2406,31 @@ impl DeviceManager {
.map_err(DeviceManagerError::CreateVirtioNet)?,
))
} else if let Some(fds) = &net_cfg.fds {
Arc::new(Mutex::new(
virtio_devices::Net::from_tap_fds(
id.clone(),
fds,
Some(net_cfg.mac),
net_cfg.mtu,
self.force_iommu | net_cfg.iommu,
net_cfg.queue_size,
self.seccomp_action.clone(),
net_cfg.rate_limiter_config,
self.exit_evt
.try_clone()
.map_err(DeviceManagerError::EventFd)?,
state,
net_cfg.offload_tso,
net_cfg.offload_ufo,
net_cfg.offload_csum,
)
.map_err(DeviceManagerError::CreateVirtioNet)?,
))
let net = virtio_devices::Net::from_tap_fds(
id.clone(),
fds,
Some(net_cfg.mac),
net_cfg.mtu,
self.force_iommu | net_cfg.iommu,
net_cfg.queue_size,
self.seccomp_action.clone(),
net_cfg.rate_limiter_config,
self.exit_evt
.try_clone()
.map_err(DeviceManagerError::EventFd)?,
state,
net_cfg.offload_tso,
net_cfg.offload_ufo,
net_cfg.offload_csum,
)
.map_err(DeviceManagerError::CreateVirtioNet)?;
// SAFETY: 'fds' are valid because TAP devices are created successfully
unsafe {
self.config.lock().unwrap().add_preserved_fds(fds.clone());
}
Arc::new(Mutex::new(net))
} else {
Arc::new(Mutex::new(
virtio_devices::Net::new(
@@ -4227,7 +4250,7 @@ fn numa_node_id_from_memory_zone_id(numa_nodes: &NumaNodes, memory_zone_id: &str
struct TpmDevice {}
impl Aml for TpmDevice {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn to_aml_bytes(&self) -> Vec<u8> {
aml::Device::new(
"TPM2".into(),
vec![
@@ -4243,12 +4266,12 @@ impl Aml for TpmDevice {
),
],
)
.to_aml_bytes(sink)
.to_aml_bytes()
}
}
impl Aml for DeviceManager {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
#[cfg(target_arch = "aarch64")]
use arch::aarch64::DeviceInfoForFdt;
@@ -4268,7 +4291,7 @@ impl Aml for DeviceManager {
aml::Device::new(
"_SB_.PHPR".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_STA".into(), &0x0bu8),
&aml::Name::new("_UID".into(), &"PCI Hotplug Controller"),
&aml::Mutex::new("BLCK".into(), 0),
@@ -4285,13 +4308,12 @@ impl Aml for DeviceManager {
&aml::OpRegion::new(
"PCST".into(),
aml::OpRegionSpace::SystemMemory,
&(self.acpi_address.0 as usize),
&DEVICE_MANAGER_ACPI_SIZE,
self.acpi_address.0 as usize,
DEVICE_MANAGER_ACPI_SIZE,
),
&aml::Field::new(
"PCST".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::WriteAsZeroes,
vec![
aml::FieldEntry::Named(*b"PCIU", 32),
@@ -4320,10 +4342,10 @@ impl Aml for DeviceManager {
&aml::Method::new("PSCN".into(), 0, true, pci_scan_inner),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
for segment in &self.pci_segments {
segment.to_aml_bytes(sink);
segment.append_aml_bytes(bytes);
}
let mut mbrd_memory = Vec::new();
@@ -4344,12 +4366,12 @@ impl Aml for DeviceManager {
aml::Device::new(
"_SB_.MBRD".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0C02")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0C02")),
&aml::Name::new("_UID".into(), &aml::ZERO),
&aml::Name::new("_CRS".into(), &aml::ResourceTemplate::new(mbrd_memory_refs)),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
// Serial device
#[cfg(target_arch = "x86_64")]
@@ -4373,7 +4395,7 @@ impl Aml for DeviceManager {
&aml::Name::new(
"_HID".into(),
#[cfg(target_arch = "x86_64")]
&aml::EISAName::new("PNP0501"),
&aml::EisaName::new("PNP0501"),
#[cfg(target_arch = "aarch64")]
&"ARMH0011",
),
@@ -4384,7 +4406,7 @@ impl Aml for DeviceManager {
&aml::ResourceTemplate::new(vec![
&aml::Interrupt::new(true, true, false, false, serial_irq),
#[cfg(target_arch = "x86_64")]
&aml::IO::new(0x3f8, 0x3f8, 0, 0x8),
&aml::Io::new(0x3f8, 0x3f8, 0, 0x8),
#[cfg(target_arch = "aarch64")]
&aml::Memory32Fixed::new(
true,
@@ -4395,23 +4417,25 @@ impl Aml for DeviceManager {
),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
aml::Name::new("_S5_".into(), &aml::Package::new(vec![&5u8])).to_aml_bytes(sink);
aml::Name::new("_S5_".into(), &aml::Package::new(vec![&5u8])).append_aml_bytes(bytes);
aml::Device::new(
"_SB_.PWRB".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0C0C")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0C0C")),
&aml::Name::new("_UID".into(), &aml::ZERO),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
if self.config.lock().unwrap().tpm.is_some() {
// Add tpm device
TpmDevice {}.to_aml_bytes(sink);
let tpm_acpi = TpmDevice {};
let tpm_dsdt_data = tpm_acpi.to_aml_bytes();
bytes.extend_from_slice(tpm_dsdt_data.as_slice());
}
self.ged_notification_device
@@ -4419,7 +4443,7 @@ impl Aml for DeviceManager {
.unwrap()
.lock()
.unwrap()
.to_aml_bytes(sink)
.append_aml_bytes(bytes);
}
}
@@ -4631,5 +4655,11 @@ impl Drop for DeviceManager {
for handle in self.virtio_devices.drain(..) {
handle.virtio_device.lock().unwrap().shutdown();
}
if let Some(ref on_tty) = self.on_tty {
if on_tty.load(Ordering::SeqCst) {
let _ = std::io::stdin().lock().set_canon_mode();
}
}
}
}

View File

@@ -41,6 +41,7 @@ use std::os::unix::net::UnixListener;
use std::os::unix::net::UnixStream;
use std::panic::AssertUnwindSafe;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, RecvError, SendError, Sender};
use std::sync::{Arc, Mutex};
use std::time::Instant;
@@ -407,12 +408,13 @@ pub struct Vmm {
activate_evt: EventFd,
signals: Option<Handle>,
threads: Vec<thread::JoinHandle<()>>,
on_tty: Arc<AtomicBool>,
}
impl Vmm {
pub const HANDLED_SIGNALS: [i32; 2] = [SIGTERM, SIGINT];
fn signal_handler(mut signals: Signals, on_tty: bool, exit_evt: &EventFd) {
fn signal_handler(mut signals: Signals, on_tty: Arc<AtomicBool>, exit_evt: &EventFd) {
for sig in &Self::HANDLED_SIGNALS {
unblock_signal(*sig).unwrap();
}
@@ -422,7 +424,7 @@ impl Vmm {
SIGTERM | SIGINT => {
if exit_evt.write(1).is_err() {
// Resetting the terminal is usually done as the VMM exits
if on_tty {
if on_tty.load(Ordering::SeqCst) {
io::stdin()
.lock()
.set_canon_mode()
@@ -442,8 +444,7 @@ impl Vmm {
Ok(signals) => {
self.signals = Some(signals.handle());
let exit_evt = self.exit_evt.try_clone().map_err(Error::EventFdClone)?;
// SAFETY: trivially safe
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO) } != 0;
let on_tty = Arc::clone(&self.on_tty);
let signal_handler_seccomp_filter = get_seccomp_filter(
&self.seccomp_action,
@@ -532,6 +533,7 @@ impl Vmm {
activate_evt,
signals: None,
threads: vec![],
on_tty: Arc::new(AtomicBool::new(false)),
})
}
@@ -582,6 +584,7 @@ impl Vmm {
None,
None,
None,
Arc::clone(&self.on_tty),
None,
None,
None,
@@ -680,6 +683,7 @@ impl Vmm {
None,
None,
None,
Arc::clone(&self.on_tty),
Some(snapshot),
Some(source_url),
Some(restore_cfg.prefault),
@@ -760,6 +764,7 @@ impl Vmm {
serial_pty,
console_pty,
console_resize_pipe,
Arc::clone(&self.on_tty),
None,
None,
None,
@@ -1262,6 +1267,7 @@ impl Vmm {
None,
None,
None,
Arc::clone(&self.on_tty),
Some(snapshot),
)
.map_err(|e| {
@@ -2130,6 +2136,7 @@ mod unit_tests {
gdb: false,
platform: None,
tpm: None,
preserved_fds: None,
}))
}

View File

@@ -12,7 +12,7 @@ use crate::coredump::{
use crate::migration::url_to_path;
use crate::MEMORY_MANAGER_SNAPSHOT_ID;
use crate::{GuestMemoryMmap, GuestRegionMmap};
use acpi_tables::{aml, Aml};
use acpi_tables::{aml, aml::Aml};
use anyhow::anyhow;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::{SgxEpcRegion, SgxEpcSection};
@@ -327,9 +327,6 @@ pub enum Error {
#[cfg(target_arch = "aarch64")]
/// Failed to create UEFI flash
CreateUefiFlash(HypervisorVmError),
/// Using a directory as a backing file for memory is not supported
DirectoryAsBackingFileForMemory,
}
const ENABLE_FLAG: usize = 0;
@@ -1274,9 +1271,37 @@ impl MemoryManager {
Ok(FileOffset::new(f, 0))
}
fn open_backing_file(backing_file: &PathBuf, file_offset: u64) -> Result<FileOffset, Error> {
fn open_backing_file(
backing_file: &PathBuf,
file_offset: u64,
size: usize,
) -> Result<FileOffset, Error> {
if backing_file.is_dir() {
Err(Error::DirectoryAsBackingFileForMemory)
warn!(
"Using a directory as a backing file for memory is deprecated \
and will be removed in a future release. (See #5082)"
);
// Override file offset as it does not apply in this case.
info!(
"Ignoring file offset since the backing file is a \
temporary file created from the specified directory."
);
let fs_str = format!("{}{}", backing_file.display(), "/tmpfile_XXXXXX");
let fs = ffi::CString::new(fs_str).unwrap();
let mut path = fs.as_bytes_with_nul().to_owned();
let path_ptr = path.as_mut_ptr() as *mut _;
// SAFETY: FFI call
let fd = unsafe { libc::mkstemp(path_ptr) };
if fd == -1 {
return Err(Error::SharedFileCreate(std::io::Error::last_os_error()));
}
// SAFETY: FFI call
unsafe { libc::unlink(path_ptr) };
// SAFETY: fd is valid
let f = unsafe { File::from_raw_fd(fd) };
f.set_len(size as u64).map_err(Error::SharedFileSetLen)?;
Ok(FileOffset::new(f, 0))
} else {
let f = OpenOptions::new()
.read(true)
@@ -1316,7 +1341,7 @@ impl MemoryManager {
} else {
mmap_flags |= libc::MAP_PRIVATE;
}
Some(Self::open_backing_file(backing_file, file_offset)?)
Some(Self::open_backing_file(backing_file, file_offset, size)?)
} else if shared || hugepages {
// For hugepages we must also MAP_SHARED otherwise we will trigger #4805
// because the MAP_PRIVATE will trigger CoW against the backing file with
@@ -2069,13 +2094,13 @@ struct MemoryNotify {
}
impl Aml for MemoryNotify {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let object = aml::Path::new(&format!("M{:03}", self.slot_id));
aml::If::new(
&aml::Equal::new(&aml::Arg(0), &self.slot_id),
vec![&aml::Notify::new(&object, &aml::Arg(1))],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
@@ -2084,11 +2109,11 @@ struct MemorySlot {
}
impl Aml for MemorySlot {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
aml::Device::new(
format!("M{:03}", self.slot_id).as_str().into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0C80")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0C80")),
&aml::Name::new("_UID".into(), &self.slot_id),
/*
_STA return value:
@@ -2122,7 +2147,7 @@ impl Aml for MemorySlot {
),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
@@ -2131,9 +2156,9 @@ struct MemorySlots {
}
impl Aml for MemorySlots {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
for slot_id in 0..self.slots {
MemorySlot { slot_id }.to_aml_bytes(sink);
MemorySlot { slot_id }.append_aml_bytes(bytes);
}
}
}
@@ -2143,19 +2168,19 @@ struct MemoryMethods {
}
impl Aml for MemoryMethods {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
// Add "MTFY" notification method
let mut memory_notifies = Vec::new();
for slot_id in 0..self.slots {
memory_notifies.push(MemoryNotify { slot_id });
}
let mut memory_notifies_refs: Vec<&dyn Aml> = Vec::new();
let mut memory_notifies_refs: Vec<&dyn aml::Aml> = Vec::new();
for memory_notifier in memory_notifies.iter() {
memory_notifies_refs.push(memory_notifier);
}
aml::Method::new("MTFY".into(), 2, true, memory_notifies_refs).to_aml_bytes(sink);
aml::Method::new("MTFY".into(), 2, true, memory_notifies_refs).append_aml_bytes(bytes);
// MSCN method
aml::Method::new(
@@ -2201,7 +2226,7 @@ impl Aml for MemoryMethods {
&aml::Release::new("MLCK".into()),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
// Memory status method
aml::Method::new(
@@ -2225,7 +2250,7 @@ impl Aml for MemoryMethods {
&aml::Return::new(&aml::Local(0)),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
// Memory range method
aml::Method::new(
@@ -2246,36 +2271,12 @@ impl Aml for MemoryMethods {
0xFFFF_FFFF_FFFF_FFFEu64,
)]),
),
&aml::CreateQWordField::new(
&aml::Path::new("MINL"),
&aml::Path::new("MR64"),
&14usize,
),
&aml::CreateDWordField::new(
&aml::Path::new("MINH"),
&aml::Path::new("MR64"),
&18usize,
),
&aml::CreateQWordField::new(
&aml::Path::new("MAXL"),
&aml::Path::new("MR64"),
&22usize,
),
&aml::CreateDWordField::new(
&aml::Path::new("MAXH"),
&aml::Path::new("MR64"),
&26usize,
),
&aml::CreateQWordField::new(
&aml::Path::new("LENL"),
&aml::Path::new("MR64"),
&38usize,
),
&aml::CreateDWordField::new(
&aml::Path::new("LENH"),
&aml::Path::new("MR64"),
&42usize,
),
&aml::CreateField::<u64>::new(&aml::Path::new("MR64"), &14usize, "MINL".into()),
&aml::CreateField::<u32>::new(&aml::Path::new("MR64"), &18usize, "MINH".into()),
&aml::CreateField::<u64>::new(&aml::Path::new("MR64"), &22usize, "MAXL".into()),
&aml::CreateField::<u32>::new(&aml::Path::new("MR64"), &26usize, "MAXH".into()),
&aml::CreateField::<u64>::new(&aml::Path::new("MR64"), &38usize, "LENL".into()),
&aml::CreateField::<u32>::new(&aml::Path::new("MR64"), &42usize, "LENH".into()),
&aml::Store::new(&aml::Path::new("MINL"), &aml::Path::new("\\_SB_.MHPC.MHBL")),
&aml::Store::new(&aml::Path::new("MINH"), &aml::Path::new("\\_SB_.MHPC.MHBH")),
&aml::Store::new(&aml::Path::new("LENL"), &aml::Path::new("\\_SB_.MHPC.MHLL")),
@@ -2304,18 +2305,18 @@ impl Aml for MemoryMethods {
&aml::Return::new(&aml::Path::new("MR64")),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
impl Aml for MemoryManager {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
if let Some(acpi_address) = self.acpi_address {
// Memory Hotplug Controller
aml::Device::new(
"_SB_.MHPC".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_UID".into(), &"Memory Hotplug Controller"),
// Mutex to protect concurrent access as we write to choose slot and then read back status
&aml::Mutex::new("MLCK".into(), 0),
@@ -2332,13 +2333,12 @@ impl Aml for MemoryManager {
&aml::OpRegion::new(
"MHPR".into(),
aml::OpRegionSpace::SystemMemory,
&(acpi_address.0 as usize),
&MEMORY_MANAGER_ACPI_SIZE,
acpi_address.0 as usize,
MEMORY_MANAGER_ACPI_SIZE,
),
&aml::Field::new(
"MHPR".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::Preserve,
vec![
aml::FieldEntry::Named(*b"MHBL", 32), // Base (low 4 bytes)
@@ -2350,7 +2350,6 @@ impl Aml for MemoryManager {
&aml::Field::new(
"MHPR".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::Preserve,
vec![
aml::FieldEntry::Reserved(128),
@@ -2360,7 +2359,6 @@ impl Aml for MemoryManager {
&aml::Field::new(
"MHPR".into(),
aml::FieldAccessType::Byte,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::WriteAsZeroes,
vec![
aml::FieldEntry::Reserved(160),
@@ -2373,7 +2371,6 @@ impl Aml for MemoryManager {
&aml::Field::new(
"MHPR".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::NoLock,
aml::FieldUpdateRule::Preserve,
vec![
aml::FieldEntry::Named(*b"MSEL", 32), // Selector
@@ -2389,18 +2386,18 @@ impl Aml for MemoryManager {
},
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
} else {
aml::Device::new(
"_SB_.MHPC".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_UID".into(), &"Memory Hotplug Controller"),
// Empty MSCN for GED
&aml::Method::new("MSCN".into(), 0, true, vec![]),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
#[cfg(target_arch = "x86_64")]
@@ -2412,7 +2409,7 @@ impl Aml for MemoryManager {
aml::Device::new(
"_SB_.EPC_".into(),
vec![
&aml::Name::new("_HID".into(), &aml::EISAName::new("INT0E0C")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("INT0E0C")),
// QWORD describing the EPC region start and size
&aml::Name::new(
"_CRS".into(),
@@ -2426,7 +2423,7 @@ impl Aml for MemoryManager {
&aml::Method::new("_STA".into(), 0, false, vec![&aml::Return::new(&0xfu8)]),
],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
}
}

View File

@@ -10,7 +10,7 @@
//
use crate::device_manager::{AddressManager, DeviceManagerError, DeviceManagerResult};
use acpi_tables::{self, aml, Aml};
use acpi_tables::aml::{self, Aml};
use arch::layout;
use pci::{DeviceRelocation, PciBdf, PciBus, PciConfigMmio, PciRoot};
#[cfg(target_arch = "x86_64")]
@@ -171,7 +171,7 @@ struct PciDevSlot {
}
impl Aml for PciDevSlot {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let sun = self.device_id;
let adr: u32 = (self.device_id as u32) << 16;
aml::Device::new(
@@ -190,7 +190,7 @@ impl Aml for PciDevSlot {
),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
@@ -199,33 +199,33 @@ struct PciDevSlotNotify {
}
impl Aml for PciDevSlotNotify {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let device_id_mask: u32 = 1 << self.device_id;
let object = aml::Path::new(&format!("S{:03}", self.device_id));
aml::And::new(&aml::Local(0), &aml::Arg(0), &device_id_mask).to_aml_bytes(sink);
aml::And::new(&aml::Local(0), &aml::Arg(0), &device_id_mask).append_aml_bytes(bytes);
aml::If::new(
&aml::Equal::new(&aml::Local(0), &device_id_mask),
vec![&aml::Notify::new(&object, &aml::Arg(1))],
)
.to_aml_bytes(sink);
.append_aml_bytes(bytes);
}
}
struct PciDevSlotMethods {}
impl Aml for PciDevSlotMethods {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let mut device_notifies = Vec::new();
for device_id in 0..32 {
device_notifies.push(PciDevSlotNotify { device_id });
}
let mut device_notifies_refs: Vec<&dyn Aml> = Vec::new();
let mut device_notifies_refs: Vec<&dyn aml::Aml> = Vec::new();
for device_notify in device_notifies.iter() {
device_notifies_refs.push(device_notify);
}
aml::Method::new("DVNT".into(), 2, true, device_notifies_refs).to_aml_bytes(sink);
aml::Method::new("DVNT".into(), 2, true, device_notifies_refs).append_aml_bytes(bytes);
aml::Method::new(
"PCNT".into(),
0,
@@ -244,14 +244,14 @@ impl Aml for PciDevSlotMethods {
&aml::Release::new("\\_SB_.PHPR.BLCK".into()),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
struct PciDsmMethod {}
impl Aml for PciDsmMethod {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
// Refer to ACPI spec v6.3 Ch 9.1.1 and PCI Firmware spec v3.3 Ch 4.6.1
// _DSM (Device Specific Method), the following is the implementation in ASL.
/*
@@ -292,11 +292,11 @@ impl Aml for PciDsmMethod {
false,
vec![
&aml::If::new(
&aml::Equal::new(&aml::Arg(0), &aml::BufferData::new(uuid_buf)),
&aml::Equal::new(&aml::Arg(0), &aml::Buffer::new(uuid_buf)),
vec![
&aml::If::new(
&aml::Equal::new(&aml::Arg(2), &aml::ZERO),
vec![&aml::Return::new(&aml::BufferData::new(vec![0x21]))],
vec![&aml::Return::new(&aml::Buffer::new(vec![0x21]))],
),
&aml::If::new(
&aml::Equal::new(&aml::Arg(2), &0x05u8),
@@ -304,19 +304,19 @@ impl Aml for PciDsmMethod {
),
],
),
&aml::Return::new(&aml::BufferData::new(vec![0])),
&aml::Return::new(&aml::Buffer::new(vec![0])),
],
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}
impl Aml for PciSegment {
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
let mut pci_dsdt_inner_data: Vec<&dyn Aml> = Vec::new();
let hid = aml::Name::new("_HID".into(), &aml::EISAName::new("PNP0A08"));
fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let mut pci_dsdt_inner_data: Vec<&dyn aml::Aml> = Vec::new();
let hid = aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A08"));
pci_dsdt_inner_data.push(&hid);
let cid = aml::Name::new("_CID".into(), &aml::EISAName::new("PNP0A03"));
let cid = aml::Name::new("_CID".into(), &aml::EisaName::new("PNP0A03"));
pci_dsdt_inner_data.push(&cid);
let adr = aml::Name::new("_ADR".into(), &aml::ZERO);
pci_dsdt_inner_data.push(&adr);
@@ -346,7 +346,7 @@ impl Aml for PciSegment {
&aml::ResourceTemplate::new(vec![
&aml::AddressSpace::new_bus_number(0x0u16, 0x0u16),
#[cfg(target_arch = "x86_64")]
&aml::IO::new(0xcf8, 0xcf8, 1, 0x8),
&aml::Io::new(0xcf8, 0xcf8, 1, 0x8),
&aml::AddressSpace::new_memory(
aml::AddressSpaceCachable::NotCacheable,
true,
@@ -421,6 +421,6 @@ impl Aml for PciSegment {
format!("_SB_.PCI{:X}", self.id).as_str().into(),
pci_dsdt_inner_data,
)
.to_aml_bytes(sink)
.append_aml_bytes(bytes)
}
}

View File

@@ -41,7 +41,6 @@ macro_rules! or {
const TCGETS: u64 = 0x5401;
const TCSETS: u64 = 0x5402;
const TIOCSCTTY: u64 = 0x540E;
const TIOCGPGRP: u64 = 0x540F;
const TIOCSPGRP: u64 = 0x5410;
const TIOCGWINSZ: u64 = 0x5413;
const TIOCSPTLCK: u64 = 0x4004_5431;
@@ -265,7 +264,6 @@ fn create_vmm_ioctl_seccomp_rule_common(
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFNETMASK)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGTPEER)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
@@ -457,7 +455,6 @@ fn signal_handler_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, Backend
fn create_pty_foreground_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
Ok(or![
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP)?],
])
@@ -501,7 +498,6 @@ fn vmm_thread_rules(
(libc::SYS_clone, vec![]),
(libc::SYS_clone3, vec![]),
(libc::SYS_close, vec![]),
(libc::SYS_close_range, vec![]),
(libc::SYS_connect, vec![]),
(libc::SYS_dup, vec![]),
(libc::SYS_epoll_create1, vec![]),

View File

@@ -1,19 +1,16 @@
// Copyright 2021, 2023 Alyssa Ross <hi@alyssa.is>
// Copyright 2021 Alyssa Ross <hi@alyssa.is>
// SPDX-License-Identifier: Apache-2.0
use crate::clone3::{clone3, clone_args, CLONE_CLEAR_SIGHAND};
use arch::_NSIG;
use libc::{
c_int, c_void, close, fork, getpgrp, ioctl, pipe2, poll, pollfd, setsid, sigemptyset,
siginfo_t, signal, sigprocmask, syscall, tcgetpgrp, tcsetpgrp, SYS_close_range, EINVAL, ENOSYS,
ENOTTY, O_CLOEXEC, POLLERR, SIGWINCH, SIG_DFL, SIG_SETMASK, STDERR_FILENO, TIOCSCTTY,
c_int, c_void, close, getpgrp, ioctl, pipe2, poll, pollfd, setsid, sigemptyset, siginfo_t,
sigprocmask, tcsetpgrp, O_CLOEXEC, POLLERR, SIGWINCH, SIG_SETMASK, STDIN_FILENO, STDOUT_FILENO,
TIOCSCTTY,
};
use seccompiler::{apply_filter, BpfProgram};
use std::cell::RefCell;
use std::collections::BTreeSet;
use std::fs::{read_dir, File};
use std::fs::File;
use std::io::{self, ErrorKind, Read, Write};
use std::iter::once;
use std::mem::size_of;
use std::mem::MaybeUninit;
use std::os::unix::prelude::*;
@@ -63,107 +60,17 @@ fn unblock_all_signals() -> io::Result<()> {
Ok(())
}
/// # Safety
///
/// Caller is responsible for ensuring all file descriptors not listed
/// in `keep_fds` are not accessed after this point, and that no other
/// thread is opening file descriptors while this function is
/// running.
unsafe fn close_fds_fallback(keep_fds: &BTreeSet<RawFd>) {
// We collect these instead of iterating through them, because we
// don't want to close the descriptor for /proc/self/fd while
// we're iterating through it.
let open_fds: BTreeSet<RawFd> = read_dir("/proc/self/fd")
.unwrap()
.map(Result::unwrap)
.filter_map(|s| s.file_name().into_string().ok()?.parse().ok())
.collect();
for fd in open_fds.difference(keep_fds) {
close(*fd);
}
}
/// # Safety
///
/// Caller is responsible for ensuring all file descriptors not listed
/// in `keep_fds` are not accessed after this point, and that no other
/// thread is opening file descriptors while this function is
/// running.
unsafe fn close_unused_fds(keep_fds: &mut [RawFd]) {
keep_fds.sort();
// Iterate over the gaps between descriptors we want to keep.
let firsts = keep_fds.iter().map(|fd| fd + 1);
for (i, first) in once(0).chain(firsts).enumerate() {
// The next fd is the one at i, because the indexes in the
// iterator are offset by one due to the initial 0.
let next_keep_fd = keep_fds.get(i);
let last = next_keep_fd.map(|fd| fd - 1).unwrap_or(RawFd::MAX);
if first > last {
continue;
}
if syscall(SYS_close_range, first, last, 0) == -1 {
// The kernel might be too old to have close_range, in
// which case we need to fall back to an uglier method.
let e = io::Error::last_os_error();
if e.raw_os_error() == Some(ENOSYS) {
return close_fds_fallback(&keep_fds.iter().copied().collect());
}
panic!("close_range: {e}");
}
}
}
fn set_foreground_process_group(tty: &mut File) -> io::Result<()> {
// SAFETY: trivially safe.
let my_pgrp = unsafe { getpgrp() };
// SAFETY: we have borrowed tty.
let tty_pgrp = unsafe { tcgetpgrp(tty.as_raw_fd()) };
if tty_pgrp == -1 {
let e = io::Error::last_os_error();
if e.raw_os_error() != Some(ENOTTY) {
return Err(e);
}
}
if tty_pgrp == my_pgrp {
return Ok(());
}
// SAFETY: trivially safe.
let my_pgrp = unsafe { setsid() };
if my_pgrp == -1 {
return Err(io::Error::last_os_error());
}
// Set the tty to be this process's controlling terminal.
// SAFETY: we have borrowed tty.
if unsafe { ioctl(tty.as_raw_fd(), TIOCSCTTY, 0) } == -1 {
return Err(io::Error::last_os_error());
}
// Become the foreground process group of the tty.
// SAFETY: we have borrowed tty.
if unsafe { tcsetpgrp(tty.as_raw_fd(), my_pgrp) } == -1 {
return Err(io::Error::last_os_error());
}
Ok(())
}
fn sigwinch_listener_main(seccomp_filter: BpfProgram, tx: File, mut tty: File) -> ! {
// SAFETY: any references to these file descriptors are
// unreachable, because this function never returns.
unsafe {
close_unused_fds(&mut [STDERR_FILENO, tx.as_raw_fd(), tty.as_raw_fd()]);
}
fn sigwinch_listener_main(seccomp_filter: BpfProgram, tx: File, pty: File) -> ! {
TX.with(|opt| opt.replace(Some(tx)));
let pty_fd = pty.into_raw_fd();
// SAFETY: FFI calls
unsafe {
close(STDIN_FILENO);
close(STDOUT_FILENO);
}
unblock_all_signals().unwrap();
if !seccomp_filter.is_empty() {
@@ -172,8 +79,20 @@ fn sigwinch_listener_main(seccomp_filter: BpfProgram, tx: File, mut tty: File) -
register_signal_handler(SIGWINCH, sigwinch_handler).unwrap();
set_foreground_process_group(&mut tty).unwrap();
drop(tty);
// SAFETY: FFI calls
unsafe {
// Create a new session (and therefore a new process group).
assert_ne!(setsid(), -1);
// Set the tty to be this process's controlling terminal.
assert_ne!(ioctl(pty_fd, TIOCSCTTY, 0), -1);
// Become the foreground process group of the tty.
assert_ne!(tcsetpgrp(pty_fd, getpgrp()), -1);
// Close the PTY fd
assert_ne!(close(pty_fd), -1);
}
notify();
@@ -200,36 +119,11 @@ fn sigwinch_listener_main(seccomp_filter: BpfProgram, tx: File, mut tty: File) -
exit(0);
}
/// # Safety
///
/// Same as [`fork`].
unsafe fn clone_clear_sighand() -> io::Result<u64> {
let mut args = clone_args::default();
args.flags |= CLONE_CLEAR_SIGHAND;
let r = clone3(&mut args, size_of::<clone_args>());
if r != -1 {
return Ok(r.try_into().unwrap());
}
let e = io::Error::last_os_error();
if e.raw_os_error() != Some(ENOSYS) && e.raw_os_error() != Some(EINVAL) {
return Err(e);
}
// If CLONE_CLEAR_SIGHAND isn't available, fall back to resetting
// all the signal handlers one by one.
let r = fork();
if r == -1 {
return Err(io::Error::last_os_error());
}
if r == 0 {
for signum in 1.._NSIG {
let _ = signal(signum, SIG_DFL);
}
}
Ok(r.try_into().unwrap())
}
pub fn start_sigwinch_listener(seccomp_filter: BpfProgram, tty_sub: File) -> io::Result<File> {
pub fn start_sigwinch_listener(
seccomp_filter: BpfProgram,
pty_main: File,
pty_sub: File,
) -> io::Result<File> {
let mut pipe = [-1; 2];
// SAFETY: FFI call with valid arguments
if unsafe { pipe2(pipe.as_mut_ptr(), O_CLOEXEC) } == -1 {
@@ -241,9 +135,18 @@ pub fn start_sigwinch_listener(seccomp_filter: BpfProgram, tty_sub: File) -> io:
// SAFETY: pipe[1] is valid
let tx = unsafe { File::from_raw_fd(pipe[1]) };
let mut args = clone_args::default();
args.flags |= CLONE_CLEAR_SIGHAND;
// SAFETY: FFI call
if unsafe { clone_clear_sighand() }? == 0 {
sigwinch_listener_main(seccomp_filter, tx, tty_sub);
match unsafe { clone3(&mut args, size_of::<clone_args>()) } {
-1 => return Err(io::Error::last_os_error()),
0 => {
drop(rx);
drop(pty_main);
sigwinch_listener_main(seccomp_filter, tx, pty_sub);
}
_ => (),
}
drop(tx);

View File

@@ -21,7 +21,7 @@ use crate::coredump::{
CpuElf64Writable, DumpState, Elf64Writable, GuestDebuggable, GuestDebuggableError, NoteDescType,
};
use crate::cpu;
use crate::device_manager::{DeviceManager, DeviceManagerError, PtyPair};
use crate::device_manager::{Console, DeviceManager, DeviceManagerError, PtyPair};
use crate::device_tree::DeviceTree;
#[cfg(feature = "guest_debug")]
use crate::gdb::{Debuggable, DebuggableError, GdbRequestPayload, GdbResponsePayload};
@@ -33,6 +33,7 @@ use crate::migration::get_vm_snapshot;
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
use crate::migration::url_to_file;
use crate::migration::{url_to_path, SNAPSHOT_CONFIG_FILE, SNAPSHOT_STATE_FILE};
use crate::seccomp_filters::{get_seccomp_filter, Thread};
use crate::GuestMemoryMmap;
use crate::{
PciDeviceInfo, CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID,
@@ -55,7 +56,6 @@ use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs;
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs;
use hypervisor::{HypervisorVmError, VmOps};
use libc::SIGWINCH;
use linux_loader::cmdline::Cmdline;
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
use linux_loader::elf;
@@ -64,8 +64,9 @@ use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
#[cfg(target_arch = "aarch64")]
use linux_loader::loader::pe::Error::InvalidImageMagicNumber;
use linux_loader::loader::KernelLoader;
use seccompiler::SeccompAction;
use seccompiler::{apply_filter, SeccompAction};
use serde::{Deserialize, Serialize};
use signal_hook::{consts::SIGWINCH, iterator::backend::Handle, iterator::Signals};
use std::cmp;
use std::collections::BTreeMap;
use std::collections::HashMap;
@@ -79,6 +80,8 @@ use std::mem::size_of;
use std::num::Wrapping;
use std::ops::Deref;
use std::os::unix::net::UnixStream;
use std::panic::AssertUnwindSafe;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex, RwLock};
use std::time::Instant;
use std::{result, str, thread};
@@ -94,8 +97,8 @@ use vm_migration::{
SnapshotData, Snapshottable, Transportable,
};
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::signal::unblock_signal;
use vmm_sys_util::sock_ctrl_msg::ScmSocket;
use vmm_sys_util::terminal::Terminal;
/// Errors associated with VM management
#[derive(Debug, Error)]
@@ -138,12 +141,6 @@ pub enum Error {
#[error("Error from device manager: {0:?}")]
DeviceManager(DeviceManagerError),
#[error("Cannot setup terminal in raw mode: {0}")]
SetTerminalRaw(#[source] vmm_sys_util::errno::Error),
#[error("Cannot setup terminal in canonical mode.: {0}")]
SetTerminalCanon(#[source] vmm_sys_util::errno::Error),
#[error("Cannot spawn a signal handler thread: {0}")]
SignalHandlerSpawn(#[source] io::Error),
@@ -437,7 +434,7 @@ pub struct Vm {
threads: Vec<thread::JoinHandle<()>>,
device_manager: Arc<Mutex<DeviceManager>>,
config: Arc<Mutex<VmConfig>>,
on_tty: bool,
signals: Option<Handle>,
state: RwLock<VmState>,
cpu_manager: Arc<Mutex<cpu::CpuManager>>,
memory_manager: Arc<Mutex<MemoryManager>>,
@@ -447,7 +444,8 @@ pub struct Vm {
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
saved_clock: Option<hypervisor::ClockData>,
numa_nodes: NumaNodes,
#[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))]
seccomp_action: SeccompAction,
exit_evt: EventFd,
hypervisor: Arc<dyn hypervisor::Hypervisor>,
stop_on_boot: bool,
load_payload_handle: Option<thread::JoinHandle<Result<EntryPoint>>>,
@@ -471,6 +469,7 @@ impl Vm {
serial_pty: Option<PtyPair>,
console_pty: Option<PtyPair>,
console_resize_pipe: Option<File>,
on_tty: Arc<AtomicBool>,
snapshot: Option<Snapshot>,
) -> Result<Self> {
trace_scoped!("Vm::new_from_memory_manager");
@@ -592,12 +591,9 @@ impl Vm {
device_manager
.lock()
.unwrap()
.create_devices(serial_pty, console_pty, console_resize_pipe)
.create_devices(serial_pty, console_pty, console_resize_pipe, on_tty)
.map_err(Error::DeviceManager)?;
// SAFETY: trivially safe
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO) } != 0;
#[cfg(feature = "tdx")]
let kernel = config
.lock()
@@ -639,8 +635,8 @@ impl Vm {
initramfs,
device_manager,
config,
on_tty,
threads: Vec::with_capacity(1),
signals: None,
state: RwLock::new(vm_state),
cpu_manager,
memory_manager,
@@ -648,6 +644,8 @@ impl Vm {
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
saved_clock,
numa_nodes,
seccomp_action: seccomp_action.clone(),
exit_evt,
hypervisor,
stop_on_boot,
load_payload_handle,
@@ -746,6 +744,7 @@ impl Vm {
serial_pty: Option<PtyPair>,
console_pty: Option<PtyPair>,
console_resize_pipe: Option<File>,
on_tty: Arc<AtomicBool>,
snapshot: Option<Snapshot>,
source_url: Option<&str>,
prefault: Option<bool>,
@@ -815,6 +814,7 @@ impl Vm {
serial_pty,
console_pty,
console_resize_pipe,
on_tty,
snapshot,
)
}
@@ -1205,13 +1205,9 @@ impl Vm {
state.valid_transition(new_state)?;
if self.on_tty {
// Don't forget to set the terminal in canonical mode
// before to exit.
io::stdin()
.lock()
.set_canon_mode()
.map_err(Error::SetTerminalCanon)?;
// Trigger the termination of the signal_handler thread
if let Some(signals) = self.signals.take() {
signals.close();
}
// Wake up the DeviceManager threads so they will get terminated cleanly
@@ -1619,6 +1615,18 @@ impl Vm {
Ok(self.device_manager.lock().unwrap().counters())
}
fn signal_handler(mut signals: Signals, console_input_clone: Arc<Console>) {
for sig in &Vm::HANDLED_SIGNALS {
unblock_signal(*sig).unwrap();
}
for signal in signals.forever() {
if signal == SIGWINCH {
console_input_clone.update_console_size();
}
}
}
#[cfg(feature = "tdx")]
fn extract_tdvf_sections(&mut self) -> Result<(Vec<TdvfSection>, bool)> {
use arch::x86_64::tdx::*;
@@ -1915,14 +1923,46 @@ impl Vm {
Ok(())
}
fn setup_tty(&self) -> Result<()> {
if self.on_tty {
io::stdin()
.lock()
.set_raw_mode()
.map_err(Error::SetTerminalRaw)?;
fn setup_signal_handler(&mut self) -> Result<()> {
let console = self.device_manager.lock().unwrap().console().clone();
let signals = Signals::new(Vm::HANDLED_SIGNALS);
match signals {
Ok(signals) => {
self.signals = Some(signals.handle());
let exit_evt = self.exit_evt.try_clone().map_err(Error::EventFdClone)?;
let signal_handler_seccomp_filter = get_seccomp_filter(
&self.seccomp_action,
Thread::SignalHandler,
self.hypervisor.hypervisor_type(),
)
.map_err(Error::CreateSeccompFilter)?;
self.threads.push(
thread::Builder::new()
.name("vm_signal_handler".to_string())
.spawn(move || {
if !signal_handler_seccomp_filter.is_empty() {
if let Err(e) = apply_filter(&signal_handler_seccomp_filter)
.map_err(Error::ApplySeccompFilter)
{
error!("Error applying seccomp filter: {:?}", e);
exit_evt.write(1).ok();
return;
}
}
std::panic::catch_unwind(AssertUnwindSafe(|| {
Vm::signal_handler(signals, console);
}))
.map_err(|_| {
error!("vm signal_handler thread panicked");
exit_evt.write(1).ok()
})
.ok();
})
.map_err(Error::SignalHandlerSpawn)?,
);
}
Err(e) => error!("Signal not found {}", e),
}
Ok(())
}
@@ -1979,7 +2019,7 @@ impl Vm {
#[cfg(target_arch = "x86_64")]
let rsdp_addr = self.create_acpi_tables();
self.setup_tty()?;
self.setup_signal_handler()?;
// Load kernel synchronously or if asynchronous then wait for load to
// finish.
@@ -2093,7 +2133,7 @@ impl Vm {
.start_restored_vcpus()
.map_err(Error::CpuManager)?;
self.setup_tty()?;
self.setup_signal_handler()?;
event!("vm", "restored");
Ok(())

View File

@@ -183,7 +183,7 @@ impl Default for MemoryConfig {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
pub enum VhostMode {
#[default]
Client,
@@ -248,7 +248,7 @@ impl Default for DiskConfig {
}
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct NetConfig {
#[serde(default = "default_netconfig_tap")]
pub tap: Option<String>,
@@ -563,7 +563,7 @@ pub struct TpmConfig {
pub socket: PathBuf,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct VmConfig {
#[serde(default)]
pub cpus: CpusConfig,
@@ -596,4 +596,10 @@ pub struct VmConfig {
pub gdb: bool,
pub platform: Option<PlatformConfig>,
pub tpm: Option<TpmConfig>,
// Preseved FDs are the ones that share the same life-time as its holding
// VmConfig instance, such as FDs for creating TAP devices.
// Perserved FDs will stay open as long as the holding VmConfig instance is
// valid, and will be closed when the holding VmConfig instance is destroyed.
#[serde(skip)]
pub preserved_fds: Option<Vec<i32>>,
}