mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d88996e5b | ||
|
|
3899cd0e30 | ||
|
|
9d93df4c8f | ||
|
|
4c27572b87 | ||
|
|
19fea1ad88 | ||
|
|
9a96ea44be | ||
|
|
e11b9d6449 | ||
|
|
ce5fe7f89d | ||
|
|
0dd0364bf8 | ||
|
|
3081d01fc3 | ||
|
|
fa58b725cb | ||
|
|
a38b4c7f17 | ||
|
|
5aa1540c5d | ||
|
|
7da8ae9c0f | ||
|
|
108e8f9dff | ||
|
|
5ab2feae70 | ||
|
|
c99660a8f9 | ||
|
|
08c1bb4b00 | ||
|
|
5bd177dde8 | ||
|
|
52ed1082fb | ||
|
|
03a23309b9 | ||
|
|
fa0965a11a | ||
|
|
524f26abef | ||
|
|
846d0976e3 | ||
|
|
4718dc1b72 | ||
|
|
0a9895e009 | ||
|
|
297b41d615 | ||
|
|
396aba7a52 | ||
|
|
35aaa1333a | ||
|
|
6768a13d95 | ||
|
|
0d50d0b257 | ||
|
|
f5a2f8473b | ||
|
|
03bb59db69 | ||
|
|
9e1fb3bfa1 | ||
|
|
4de422ad69 | ||
|
|
c441bb2968 | ||
|
|
5cb5115456 | ||
|
|
0fbba66b21 | ||
|
|
5388fa1ced | ||
|
|
655d512523 | ||
|
|
7d45473ff7 | ||
|
|
294d5fbb08 | ||
|
|
8c796e6d5d | ||
|
|
630f5c1f14 | ||
|
|
5cbf907200 | ||
|
|
bfeab76059 | ||
|
|
12143ca72f | ||
|
|
ba05bdd085 | ||
|
|
171b28ce52 | ||
|
|
5b929cb277 | ||
|
|
ee0b0d43d8 | ||
|
|
061482340e | ||
|
|
c43ae1dc9d | ||
|
|
7db3002e1d | ||
|
|
07b7457c2e | ||
|
|
dc9142f86c | ||
|
|
6fa7c84d2e | ||
|
|
cc734e2e44 | ||
|
|
e3e83362d6 | ||
|
|
730cf1e944 | ||
|
|
1caa69d0cc | ||
|
|
abcbf43433 | ||
|
|
af74de2779 | ||
|
|
dfebc8929d | ||
|
|
9988379f6b | ||
|
|
4d12192490 | ||
|
|
9f9cfeb5be |
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
- "1.77.0"
|
- "1.82.0"
|
||||||
target:
|
target:
|
||||||
- x86_64-unknown-linux-gnu
|
- x86_64-unknown-linux-gnu
|
||||||
- x86_64-unknown-linux-musl
|
- x86_64-unknown-linux-musl
|
||||||
|
|||||||
14
.github/workflows/docker-image.yaml
vendored
14
.github/workflows/docker-image.yaml
vendored
@@ -21,13 +21,13 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Login to ghcr
|
- name: Login to ghcr
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -36,17 +36,17 @@ jobs:
|
|||||||
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v4
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
# generate Docker tags based on the following events/attributes
|
# generate Docker tags based on the following events/attributes
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=20250111-0
|
type=raw,value=20250307-2
|
||||||
type=sha
|
type=sha
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
if: ${{ github.event_name == 'push' }}
|
if: ${{ github.event_name == 'push' }}
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
file: ./resources/Dockerfile
|
file: ./resources/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build only
|
- name: Build only
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
file: ./resources/Dockerfile
|
file: ./resources/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
11
.github/workflows/integration-metrics.yaml
vendored
11
.github/workflows/integration-metrics.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Tests (Metrics)
|
name: Tests (Metrics)
|
||||||
runs-on: garm-jammy-16
|
runs-on: bare-metal-9950x
|
||||||
env:
|
env:
|
||||||
METRICS_PUBLISH_KEY: ${{ secrets.METRICS_PUBLISH_KEY }}
|
METRICS_PUBLISH_KEY: ${{ secrets.METRICS_PUBLISH_KEY }}
|
||||||
steps:
|
steps:
|
||||||
@@ -15,15 +15,6 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Install Docker
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install ca-certificates curl gnupg
|
|
||||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
|
||||||
sudo chmod a+r /usr/share/keyrings/docker-archive-keyring.gpg
|
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt install -y docker-ce docker-ce-cli
|
|
||||||
- name: Run metrics tests
|
- name: Run metrics tests
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
run: scripts/dev_cli.sh tests --metrics -- -- --report-file /root/workloads/metrics.json
|
run: scripts/dev_cli.sh tests --metrics -- -- --report-file /root/workloads/metrics.json
|
||||||
|
|||||||
12
.github/workflows/integration-rate-limiter.yaml
vendored
12
.github/workflows/integration-rate-limiter.yaml
vendored
@@ -7,7 +7,7 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Tests (Rate-Limiter)
|
name: Tests (Rate-Limiter)
|
||||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-latest' || 'garm-jammy-16' }}
|
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-latest' || 'bare-metal-9950x' }}
|
||||||
env:
|
env:
|
||||||
AUTH_DOWNLOAD_TOKEN: ${{ secrets.AUTH_DOWNLOAD_TOKEN }}
|
AUTH_DOWNLOAD_TOKEN: ${{ secrets.AUTH_DOWNLOAD_TOKEN }}
|
||||||
steps:
|
steps:
|
||||||
@@ -16,16 +16,6 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Install Docker
|
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install ca-certificates curl gnupg
|
|
||||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
|
||||||
sudo chmod a+r /usr/share/keyrings/docker-archive-keyring.gpg
|
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt install -y docker-ce docker-ce-cli
|
|
||||||
- name: Run rate-limiter integration tests
|
- name: Run rate-limiter integration tests
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
|||||||
16
.github/workflows/lychee.yaml
vendored
Normal file
16
.github/workflows/lychee.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: Link Check (lychee)
|
||||||
|
on:
|
||||||
|
pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
link_check:
|
||||||
|
name: Link Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Code checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Link Availability Check
|
||||||
|
uses: lycheeverse/lychee-action@master
|
||||||
|
with:
|
||||||
|
args: --verbose --config .lychee.toml .
|
||||||
2
.github/workflows/preview-riscv64.yaml
vendored
2
.github/workflows/preview-riscv64.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
run: /opt/scripts/exec-in-qemu.sh rustup default 1.77.0
|
run: /opt/scripts/exec-in-qemu.sh rustup default 1.82.0
|
||||||
|
|
||||||
- name: Build ${{ matrix.module }} Module (kvm)
|
- name: Build ${{ matrix.module }} Module (kvm)
|
||||||
run: /opt/scripts/exec-in-qemu.sh cargo rustc --locked -p ${{ matrix.module }} --no-default-features --features "kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
|
run: /opt/scripts/exec-in-qemu.sh cargo rustc --locked -p ${{ matrix.module }} --no-default-features --features "kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states
|
||||||
|
|||||||
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -45,7 +45,7 @@ jobs:
|
|||||||
target: ${{ matrix.platform.target }}
|
target: ${{ matrix.platform.target }}
|
||||||
args: ${{ matrix.platform.args }}
|
args: ${{ matrix.platform.args }}
|
||||||
strip: true
|
strip: true
|
||||||
toolchain: "1.77.0"
|
toolchain: "1.82.0"
|
||||||
- name: Copy Release Binaries
|
- name: Copy Release Binaries
|
||||||
if: github.event_name == 'create' && github.event.ref_type == 'tag'
|
if: github.event_name == 'create' && github.event.ref_type == 'tag'
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
5
.gitlint
5
.gitlint
@@ -13,3 +13,8 @@ line-length=72
|
|||||||
# default 80
|
# default 80
|
||||||
[body-max-line-length]
|
[body-max-line-length]
|
||||||
line-length=72
|
line-length=72
|
||||||
|
|
||||||
|
# Allow developers to add long links to useful resources
|
||||||
|
[ignore-by-body]
|
||||||
|
regex=^https?:\/\/
|
||||||
|
ignore=body-max-line-length
|
||||||
|
|||||||
18
.lychee.toml
Normal file
18
.lychee.toml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
verbose = "info"
|
||||||
|
|
||||||
|
exclude = [
|
||||||
|
# Availability of links below should be manually verified.
|
||||||
|
# Page for intel SGX support, returns 403 while querying.
|
||||||
|
'^https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html',
|
||||||
|
# Page for intel TDX support, returns 403 while querying.
|
||||||
|
'^https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html',
|
||||||
|
# Page for TPM, returns 403 while querying.
|
||||||
|
'^https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p05p_r14_pub.pdf',
|
||||||
|
|
||||||
|
# GitHub user smibarber referenced in `CREDITS.md` no longer exist
|
||||||
|
'^https://github.com/smibarber',
|
||||||
|
]
|
||||||
|
|
||||||
|
max_retries = 3
|
||||||
|
|
||||||
|
retry_wait_time = 5
|
||||||
@@ -13,7 +13,7 @@ License](https://opensource.org/licenses/Apache-2.0).
|
|||||||
|
|
||||||
## Coding Style
|
## Coding Style
|
||||||
|
|
||||||
We follow the [Rust Style](https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/guide.md)
|
We follow the [Rust Style](https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide/src)
|
||||||
convention and enforce it through the Continuous Integration (CI) process calling into `rustfmt`
|
convention and enforce it through the Continuous Integration (CI) process calling into `rustfmt`
|
||||||
for each submitted Pull Request (PR).
|
for each submitted Pull Request (PR).
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ commit you make.
|
|||||||
|
|
||||||
## Certificate of Origin
|
## Certificate of Origin
|
||||||
|
|
||||||
In order to get a clear contribution chain of trust we use the [signed-off-by language](https://01.org/community/signed-process)
|
In order to get a clear contribution chain of trust we use the [signed-off-by language](https://web.archive.org/web/20230406041855/https://01.org/community/signed-process)
|
||||||
used by the Linux kernel project.
|
used by the Linux kernel project.
|
||||||
|
|
||||||
## Patch format
|
## Patch format
|
||||||
@@ -79,12 +79,12 @@ you want to merge your changes to `cloud-hypervisor`:
|
|||||||
|
|
||||||
1. Fork the [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor) project
|
1. Fork the [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor) project
|
||||||
into your github organization.
|
into your github organization.
|
||||||
2. Within your fork, create a branch for your contribution.
|
1. Within your fork, create a branch for your contribution.
|
||||||
3. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
|
1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
|
||||||
against the main branch of the Cloud Hypervisor repository.
|
against the main branch of the Cloud Hypervisor repository.
|
||||||
4. To update your pull request amend existing commits whenever applicable and
|
1. To update your pull request amend existing commits whenever applicable and
|
||||||
then push the new changes to your pull request branch.
|
then push the new changes to your pull request branch.
|
||||||
5. Once the pull request is approved it can be integrated.
|
1. Once the pull request is approved it can be integrated.
|
||||||
|
|
||||||
## Issue tracking
|
## Issue tracking
|
||||||
|
|
||||||
|
|||||||
131
Cargo.lock
generated
131
Cargo.lock
generated
@@ -66,11 +66,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstyle-query"
|
name = "anstyle-query"
|
||||||
version = "1.1.1"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
|
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -137,12 +137,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-channel"
|
name = "async-channel"
|
||||||
version = "2.3.0"
|
version = "2.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f2776ead772134d55b62dd45e59a79e21612d85d0af729b8b7d3967d601a62a"
|
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"event-listener",
|
|
||||||
"event-listener-strategy",
|
"event-listener-strategy",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@@ -258,9 +257,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.85"
|
version = "0.1.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
|
checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -420,7 +419,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "44.0.0"
|
version = "45.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"api_client",
|
"api_client",
|
||||||
@@ -611,23 +610,23 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -913,10 +912,22 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi 0.13.3+wasi-0.2.2",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
@@ -931,9 +942,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.15.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
@@ -997,9 +1008,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "igvm"
|
name = "igvm"
|
||||||
version = "0.3.3"
|
version = "0.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7984b10433b50e06a06bd50c69bca4888a5d7de8975f64ea4c2a7687eb99b09d"
|
checksum = "7b4ae8479aa3163c8a0fa716aa6ef08a6553e1097f8a89544f46fee695b5a162"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitfield-struct",
|
"bitfield-struct",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
@@ -1014,9 +1025,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "igvm_defs"
|
name = "igvm_defs"
|
||||||
version = "0.3.3"
|
version = "0.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b64ec5588c475372ae830475d3ee9a7bd255407dcb9f03faf6d493556eb6105a"
|
checksum = "e4f70c18b574e5c7fa6222c1f0ebd8bfe2e14b762573b799faf8697c044b0e2a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitfield-struct",
|
"bitfield-struct",
|
||||||
"open-enum",
|
"open-enum",
|
||||||
@@ -1026,9 +1037,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.6"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
@@ -1243,9 +1254,9 @@ checksum = "9bec4598fddb13cc7b528819e697852653252b760f1228b7642679bf2ff2cd07"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mshv-bindings"
|
name = "mshv-bindings"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0cb5031f3243a7459b7c13d960d25420980874eebda816db24ce6077e21d43"
|
checksum = "30f83f36cb864d90b62a4576556cef3319603d02f3aca58a87694e1e0694bdda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
@@ -1257,9 +1268,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mshv-ioctls"
|
name = "mshv-ioctls"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89abe853221fa6f14ad4066affb9abda241a03d65622887d5794e1422d0bd75a"
|
checksum = "7cd6d081aa1eb9916b8f2ac89a6f22adaaa9b5308c71ff5f14332143dc52aaf6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mshv-bindings",
|
"mshv-bindings",
|
||||||
@@ -1273,7 +1284,7 @@ version = "0.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1288,7 +1299,7 @@ name = "net_util"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"epoll",
|
"epoll",
|
||||||
"getrandom",
|
"getrandom 0.3.1",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"net_gen",
|
"net_gen",
|
||||||
@@ -1672,18 +1683,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.1.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_edit",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.92"
|
version = "1.0.93"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@@ -1724,7 +1735,7 @@ version = "0.6.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1764,13 +1775,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.6"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 1.0.62",
|
"thiserror 2.0.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1840,9 +1851,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.18"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
@@ -1852,9 +1863,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "seccompiler"
|
name = "seccompiler"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "345a3e4dddf721a478089d4697b83c6c0a8f5bf16086f6c13397e4534eb6e2e5"
|
checksum = "a4ae55de56877481d112a559bbc12667635fdaf5e005712fd4e2b2fa50ffc884"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -2103,15 +2114,15 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.5"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.21.1"
|
version = "0.22.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
@@ -2192,9 +2203,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
@@ -2208,7 +2219,7 @@ version = "1.12.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"rand",
|
"rand",
|
||||||
"uuid-macro-internal",
|
"uuid-macro-internal",
|
||||||
]
|
]
|
||||||
@@ -2539,6 +2550,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.13.3+wasi-0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.92"
|
version = "0.2.92"
|
||||||
@@ -2765,13 +2785,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.5.40"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rt"
|
||||||
|
version = "0.33.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdg-home"
|
name = "xdg-home"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
|||||||
17
Cargo.toml
17
Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
|
|||||||
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
|
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
|
||||||
license = "Apache-2.0 AND BSD-3-Clause"
|
license = "Apache-2.0 AND BSD-3-Clause"
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "44.0.0"
|
version = "45.0.0"
|
||||||
# Minimum buildable version:
|
# Minimum buildable version:
|
||||||
# Keep in sync with version in .github/workflows/build.yaml
|
# Keep in sync with version in .github/workflows/build.yaml
|
||||||
# Policy on MSRV (see #4318):
|
# Policy on MSRV (see #4318):
|
||||||
@@ -15,7 +15,7 @@ version = "44.0.0"
|
|||||||
# a.) A dependency requires it,
|
# a.) A dependency requires it,
|
||||||
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
|
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
|
||||||
# c.) There is a security issue that is addressed by the toolchain update.
|
# c.) There is a security issue that is addressed by the toolchain update.
|
||||||
rust-version = "1.77.0"
|
rust-version = "1.82.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
@@ -51,7 +51,7 @@ vmm-sys-util = { workspace = true }
|
|||||||
zbus = { version = "4.4.0", optional = true }
|
zbus = { version = "4.4.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dirs = "5.0.1"
|
dirs = "6.0.0"
|
||||||
net_util = { path = "net_util" }
|
net_util = { path = "net_util" }
|
||||||
once_cell = "1.20.2"
|
once_cell = "1.20.2"
|
||||||
serde_json = "1.0.120"
|
serde_json = "1.0.120"
|
||||||
@@ -102,13 +102,14 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
# rust-vmm crates
|
||||||
acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" }
|
acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" }
|
||||||
kvm-bindings = "0.10.0"
|
kvm-bindings = "0.10.0"
|
||||||
kvm-ioctls = "0.19.1"
|
kvm-ioctls = "0.19.1"
|
||||||
linux-loader = "0.13.0"
|
linux-loader = "0.13.0"
|
||||||
mshv-bindings = "0.3.2"
|
mshv-bindings = "0.3.3"
|
||||||
mshv-ioctls = "0.3.2"
|
mshv-ioctls = "0.3.3"
|
||||||
seccompiler = "0.4.0"
|
seccompiler = "0.5.0"
|
||||||
vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main" }
|
vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main" }
|
||||||
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
|
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" }
|
vfio_user = { git = "https://github.com/rust-vmm/vfio-user", branch = "main" }
|
||||||
@@ -119,3 +120,7 @@ virtio-queue = "0.14.0"
|
|||||||
vm-fdt = { git = "https://github.com/rust-vmm/vm-fdt", branch = "main" }
|
vm-fdt = { git = "https://github.com/rust-vmm/vm-fdt", branch = "main" }
|
||||||
vm-memory = "0.16.1"
|
vm-memory = "0.16.1"
|
||||||
vmm-sys-util = "0.12.1"
|
vmm-sys-util = "0.12.1"
|
||||||
|
|
||||||
|
# igvm crates
|
||||||
|
igvm = "0.3.4"
|
||||||
|
igvm_defs = "0.3.1"
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -59,9 +59,13 @@ based on the [Rust VMM](https://github.com/rust-vmm) crates.
|
|||||||
|
|
||||||
### Architectures
|
### Architectures
|
||||||
|
|
||||||
Cloud Hypervisor supports the `x86-64` and `AArch64` architectures. There are
|
Cloud Hypervisor supports the `x86-64`, `AArch64` and `riscv64`
|
||||||
minor differences in functionality between the two architectures
|
architectures, with functionality varying across these platforms. The
|
||||||
(see [#1125](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/1125)).
|
functionality differences between `x86-64` and `AArch64` are documented
|
||||||
|
in [#1125](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/1125).
|
||||||
|
The `riscv64` architecture support is experimental and offers limited
|
||||||
|
functionality. For more details and instructions, please refer to [riscv
|
||||||
|
documentation](docs/riscv.md).
|
||||||
|
|
||||||
### Guest OS
|
### Guest OS
|
||||||
|
|
||||||
@@ -298,7 +302,7 @@ As of 2023-01-03, the following cloud images are supported:
|
|||||||
|
|
||||||
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (focal-server-cloudimg-{amd64,arm64}.img)
|
- [Ubuntu Focal](https://cloud-images.ubuntu.com/focal/current/) (focal-server-cloudimg-{amd64,arm64}.img)
|
||||||
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (jammy-server-cloudimg-{amd64,arm64}.img )
|
- [Ubuntu Jammy](https://cloud-images.ubuntu.com/jammy/current/) (jammy-server-cloudimg-{amd64,arm64}.img )
|
||||||
- [Fedora 36](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/) ([Fedora-Cloud-Base-36-1.5.x86_64.raw.xz](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/x86_64/images/) / [Fedora-Cloud-Base-36-1.5.aarch64.raw.xz](https://fedora.mirrorservice.org/fedora/linux/releases/36/Cloud/aarch64/images/))
|
- [Fedora 36](https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/36/Cloud/) ([Fedora-Cloud-Base-36-1.5.x86_64.raw.xz](https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/36/Cloud/x86_64/images/) / [Fedora-Cloud-Base-36-1.5.aarch64.raw.xz](https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/36/Cloud/aarch64/images/))
|
||||||
|
|
||||||
Direct kernel boot to userspace should work with a rootfs from most
|
Direct kernel boot to userspace should work with a rootfs from most
|
||||||
distributions although you may need to enable exotic filesystem types in the
|
distributions although you may need to enable exotic filesystem types in the
|
||||||
|
|||||||
@@ -1109,10 +1109,7 @@ fn print_node(node: fdt_parser::node::FdtNode<'_, '_>, n_spaces: usize) {
|
|||||||
// - At first, try to convert it to CStr and print,
|
// - At first, try to convert it to CStr and print,
|
||||||
// - If failed, print it as u32 array.
|
// - If failed, print it as u32 array.
|
||||||
let value_result = match CStr::from_bytes_with_nul(value) {
|
let value_result = match CStr::from_bytes_with_nul(value) {
|
||||||
Ok(value_cstr) => match value_cstr.to_str() {
|
Ok(value_cstr) => value_cstr.to_str().ok(),
|
||||||
Ok(value_str) => Some(value_str),
|
|
||||||
Err(_e) => None,
|
|
||||||
},
|
|
||||||
Err(_e) => None,
|
Err(_e) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -747,12 +747,12 @@ pub fn generate_common_cpuid(
|
|||||||
// These features are not supported by TDX
|
// These features are not supported by TDX
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if config.tdx {
|
if config.tdx {
|
||||||
entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT
|
entry.eax &= !((1 << KVM_FEATURE_CLOCKSOURCE_BIT)
|
||||||
| 1 << KVM_FEATURE_CLOCKSOURCE2_BIT
|
| (1 << KVM_FEATURE_CLOCKSOURCE2_BIT)
|
||||||
| 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT
|
| (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)
|
||||||
| 1 << KVM_FEATURE_ASYNC_PF_BIT
|
| (1 << KVM_FEATURE_ASYNC_PF_BIT)
|
||||||
| 1 << KVM_FEATURE_ASYNC_PF_VMEXIT_BIT
|
| (1 << KVM_FEATURE_ASYNC_PF_VMEXIT_BIT)
|
||||||
| 1 << KVM_FEATURE_STEAL_TIME_BIT)
|
| (1 << KVM_FEATURE_STEAL_TIME_BIT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ pub struct TdHob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn align_hob(v: u64) -> u64 {
|
fn align_hob(v: u64) -> u64 {
|
||||||
(v + 7) / 8 * 8
|
v.div_ceil(8) * 8
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TdHob {
|
impl TdHob {
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ impl QcowFile {
|
|||||||
if refcount_bits != 16 {
|
if refcount_bits != 16 {
|
||||||
return Err(Error::UnsupportedRefcountOrder);
|
return Err(Error::UnsupportedRefcountOrder);
|
||||||
}
|
}
|
||||||
let refcount_bytes = (refcount_bits + 7) / 8;
|
let refcount_bytes = refcount_bits.div_ceil(8);
|
||||||
|
|
||||||
// Need at least one refcount cluster
|
// Need at least one refcount cluster
|
||||||
if header.refcount_table_clusters == 0 {
|
if header.refcount_table_clusters == 0 {
|
||||||
|
|||||||
9
build.rs
9
build.rs
@@ -3,6 +3,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
use std::env;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -12,10 +13,18 @@ fn main() {
|
|||||||
if git_out.status.success() {
|
if git_out.status.success() {
|
||||||
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
|
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
|
||||||
version = git_out_str;
|
version = git_out_str;
|
||||||
|
// Pop the trailing newline.
|
||||||
|
version.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append CH_EXTRA_VERSION to version if it is set.
|
||||||
|
if let Ok(extra_version) = env::var("CH_EXTRA_VERSION") {
|
||||||
|
println!("cargo:rerun-if-env-changed=CH_EXTRA_VERSION");
|
||||||
|
version.push_str(&format!("-{}", extra_version));
|
||||||
|
}
|
||||||
|
|
||||||
// This println!() has a special behavior, as it will set the environment
|
// This println!() has a special behavior, as it will set the environment
|
||||||
// variable BUILD_VERSION, so that it can be reused from the binary.
|
// variable BUILD_VERSION, so that it can be reused from the binary.
|
||||||
// Particularly, this is used from src/main.rs to display the exact
|
// Particularly, this is used from src/main.rs to display the exact
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# AMD SEV-SNP
|
# AMD SEV-SNP
|
||||||
|
|
||||||
### WARNING
|
### WARNING
|
||||||
|
|
||||||
This feature is only currently supported on MSHV.
|
This feature is only currently supported on MSHV.
|
||||||
|
|
||||||
AMD Secure Encrypted Virtualization & Secure Nested Paging (SEV-SNP) is an AMD
|
AMD Secure Encrypted Virtualization & Secure Nested Paging (SEV-SNP) is an AMD
|
||||||
@@ -9,8 +10,8 @@ malicious hypervisor-based attacks like data replay, memory-remapping and more
|
|||||||
in order to create an isolated execution environment. Here are some useful
|
in order to create an isolated execution environment. Here are some useful
|
||||||
links:
|
links:
|
||||||
|
|
||||||
* [SNP Homepage] (https://www.amd.com/en/processors/amd-secure-encrypted-virtualization)
|
- [SNP Homepage](https://www.amd.com/content/dam/amd/en/documents/epyc-business-docs/solution-briefs/amd-secure-encrypted-virtualization-solution-brief.pdf):
|
||||||
more information about SEV-SNP technical aspects, design and specification.
|
more information about SEV-SNP technical aspects, design and specification.
|
||||||
|
|
||||||
## Cloud Hypervisor support
|
## Cloud Hypervisor support
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# `cloud-hypervisor` debug IO ports
|
# `cloud-hypervisor` debug IO ports
|
||||||
|
|
||||||
When running x86 guests, `cloud-hypervisor` provides different kinds of debug ports:
|
When running x86 guests, `cloud-hypervisor` provides different kinds of debug ports:
|
||||||
- [`0x80` debug port](https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
|
|
||||||
|
- [`0x80` debug port](https://web.archive.org/web/20211028033025/https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
|
||||||
- Debug console (by default at `0xe9`).
|
- Debug console (by default at `0xe9`).
|
||||||
- Firmware debug port at `0x402`.
|
- Firmware debug port at `0x402`.
|
||||||
|
|
||||||
@@ -25,13 +26,13 @@ for debugging specific components of the guest software stack. When logging a
|
|||||||
write of one of those codes to the debug port, `cloud-hypervisor` adds a
|
write of one of those codes to the debug port, `cloud-hypervisor` adds a
|
||||||
pre-defined string to the logs.
|
pre-defined string to the logs.
|
||||||
|
|
||||||
| Code Range | Component | Log string |
|
| Code Range | Component | Log string |
|
||||||
| ---------------- | ----------- | ------------ |
|
| ---------------- | ---------- | ------------ |
|
||||||
| `0x00` to `0x1f` | Firmware | `Firmware` |
|
| `0x00` to `0x1f` | Firmware | `Firmware` |
|
||||||
| `0x20` to `0x3f` | Bootloader | `Bootloader` |
|
| `0x20` to `0x3f` | Bootloader | `Bootloader` |
|
||||||
| `0x40` to `0x5f` | Kernel | `Kernel` |
|
| `0x40` to `0x5f` | Kernel | `Kernel` |
|
||||||
| `0x60` to `0x7f` | Userspace | `Userspace` |
|
| `0x60` to `0x7f` | Userspace | `Userspace` |
|
||||||
| `0x80` to `0xff` | Custom | `Custom` |
|
| `0x80` to `0xff` | Custom | `Custom` |
|
||||||
|
|
||||||
One typical use case is guest boot time measurement and tracing. By writing
|
One typical use case is guest boot time measurement and tracing. By writing
|
||||||
different values to the debug I/O port at different boot process steps, the
|
different values to the debug I/O port at different boot process steps, the
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ the host kernel. The required Linux and KVM changes can be found in the
|
|||||||
[KVM SGX Tree](https://github.com/intel/kvm-sgx).
|
[KVM SGX Tree](https://github.com/intel/kvm-sgx).
|
||||||
|
|
||||||
Utilizing SGX in the guest requires a kernel/OS with SGX support, e.g. a kernel
|
Utilizing SGX in the guest requires a kernel/OS with SGX support, e.g. a kernel
|
||||||
built using the [SGX Linux Development Tree](https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-sgx.git)
|
since release 5.11, see
|
||||||
|
[here](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html)
|
||||||
or the [KVM SGX Tree](https://github.com/intel/kvm-sgx). Running KVM SGX as the
|
or the [KVM SGX Tree](https://github.com/intel/kvm-sgx). Running KVM SGX as the
|
||||||
guest kernel allows nested virtualization of SGX.
|
guest kernel allows nested virtualization of SGX.
|
||||||
|
|
||||||
For more information about SGX, please refer to the [SGX Homepage](https://software.intel.com/sgx).
|
For more information about SGX, please refer to the [SGX Homepage](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html).
|
||||||
|
|
||||||
For more information about SGX SDK and how to test SGX, please refer to the
|
For more information about SGX SDK and how to test SGX, please refer to the
|
||||||
following [instructions](https://github.com/intel/linux-sgx).
|
following [instructions](https://github.com/intel/linux-sgx).
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ Intel® Trust Domain Extensions (Intel® TDX) is an Intel technology designed to
|
|||||||
isolate virtual machines from the VMM, hypervisor and any other software on the
|
isolate virtual machines from the VMM, hypervisor and any other software on the
|
||||||
host platform. Here are some useful links:
|
host platform. Here are some useful links:
|
||||||
|
|
||||||
* [TDX Homepage](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html):
|
- [TDX Homepage](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html):
|
||||||
more information about TDX technical aspects, design and specification
|
more information about TDX technical aspects, design and specification
|
||||||
|
|
||||||
* [KVM TDX tree](https://github.com/intel/tdx/tree/kvm): the required
|
- [KVM TDX tree](https://github.com/intel/tdx/tree/kvm): the required
|
||||||
Linux kernel changes for the host side
|
Linux kernel changes for the host side
|
||||||
|
|
||||||
* [Guest TDX tree](https://github.com/intel/tdx/tree/guest): the Linux
|
- [Guest TDX tree](https://github.com/intel/tdx/tree/guest): the Linux
|
||||||
kernel changes for the guest side
|
kernel changes for the guest side
|
||||||
|
|
||||||
* [EDK2 project](https://github.com/tianocore/edk2): the TDVF firmware
|
- [EDK2 project](https://github.com/tianocore/edk2): the TDVF firmware
|
||||||
|
|
||||||
* [Confidential Containers project](https://github.com/confidential-containers/td-shim):
|
- [Confidential Containers project](https://github.com/confidential-containers/td-shim):
|
||||||
the TDShim firmware
|
the TDShim firmware
|
||||||
|
|
||||||
* [TDX Tools](https://github.com/intel/tdx-tools): a collection of tools
|
- [TDX Linux](https://github.com/intel/tdx-linux): a collection of tools
|
||||||
and scripts to setup TDX environment for testing purpose (such as
|
and scripts to setup TDX environment for testing purpose (such as
|
||||||
installing required packages on the host, creating guest images, and
|
installing required packages on the host, creating guest images, and
|
||||||
building the custom Linux kernel for TDX host and guest)
|
building the custom Linux kernel for TDX host and guest)
|
||||||
@@ -27,17 +27,13 @@ more information about TDX technical aspects, design and specification
|
|||||||
|
|
||||||
It is required to use a machine with TDX enabled in hardware and
|
It is required to use a machine with TDX enabled in hardware and
|
||||||
with the host OS compiled from the [KVM TDX tree](https://github.com/intel/tdx/tree/kvm).
|
with the host OS compiled from the [KVM TDX tree](https://github.com/intel/tdx/tree/kvm).
|
||||||
The host environment can also be setup with the [TDX Tools](https://github.com/intel/tdx-tools).
|
The host environment can also be setup with the [TDX Linux](https://github.com/intel/tdx-linux).
|
||||||
|
|
||||||
Cloud Hypervisor can run TDX VM (Trust Domain) by loading a TD firmware ([TDVF](https://github.com/tianocore/edk2)),
|
Cloud Hypervisor can run TDX VM (Trust Domain) by loading a TD firmware ([TDVF](https://github.com/tianocore/edk2)),
|
||||||
which will then load the guest kernel from the image. The image must be custom
|
which will then load the guest kernel from the image. The image must be custom
|
||||||
as it must include a kernel built from the [Guest TDX tree](https://github.com/intel/tdx/tree/guest).
|
as it must include a kernel built from the [Guest TDX tree](https://github.com/intel/tdx/tree/guest).
|
||||||
Cloud Hypervisor can also boot a TDX VM with direct kernel boot using [TDshim](https://github.com/confidential-containers/td-shim).
|
Cloud Hypervisor can also boot a TDX VM with direct kernel boot using [TDshim](https://github.com/confidential-containers/td-shim).
|
||||||
The custom Linux kernel for the guest can be built with the [TDX Tools](https://github.com/intel/tdx-tools).
|
The custom Linux kernel for the guest can be built with the [TDX Linux](https://github.com/intel/tdx-linux).
|
||||||
|
|
||||||
> **Note**
|
|
||||||
> The latest version of custom host and guest kernel being tested is
|
|
||||||
> from [TDX Tools - 2023ww01](https://github.com/intel/tdx-tools/commits/2023ww01).
|
|
||||||
|
|
||||||
### TDVF
|
### TDVF
|
||||||
|
|
||||||
@@ -110,6 +106,7 @@ direct kernel boot, which is useful for containers use cases.
|
|||||||
|
|
||||||
To build TDShim from source, it is required to install `Rust`, `NASM`,
|
To build TDShim from source, it is required to install `Rust`, `NASM`,
|
||||||
and `LLVM` first. The TDshim can be build as follows:
|
and `LLVM` first. The TDshim can be build as follows:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/confidential-containers/td-shim
|
git clone https://github.com/confidential-containers/td-shim
|
||||||
cd td-shim
|
cd td-shim
|
||||||
@@ -126,13 +123,14 @@ cargo image --release
|
|||||||
|
|
||||||
If debug logs from the TDShim is needed, here are the alternative
|
If debug logs from the TDShim is needed, here are the alternative
|
||||||
commands:
|
commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo image
|
cargo image
|
||||||
```
|
```
|
||||||
|
|
||||||
And run a TDX VM by providing the firmware previously built, along with a guest
|
And run a TDX VM by providing the firmware previously built, along with a guest
|
||||||
kernel built from the [Guest TDX tree](https://github.com/intel/tdx/tree/guest)
|
kernel built from the [Guest TDX tree](https://github.com/intel/tdx/tree/guest)
|
||||||
or the [TDX Tools](https://github.com/intel/tdx-tools).
|
or the [TDX Linux](https://github.com/intel/tdx-linux).
|
||||||
The appropriate kernel boot options must be provided through the `--cmdline`
|
The appropriate kernel boot options must be provided through the `--cmdline`
|
||||||
option as well.
|
option as well.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# I/O Throttling
|
# I/O Throttling
|
||||||
|
|
||||||
Cloud Hypervisor now supports I/O throttling on virtio-block and virtio-net
|
Cloud Hypervisor now supports I/O throttling on virtio-block and virtio-net
|
||||||
devices. This support is based on the [`rate-limiter` module](https://github.com/firecracker-microvm/firecracker/tree/master/src/rate_limiter)
|
devices. This support is based on the [`rate-limiter` module](https://github.com/firecracker-microvm/firecracker/tree/7a1231b141e958d15d5b2c079dd5e0880528b4b0/src/rate_limiter)
|
||||||
from Firecracker. This document explains the user interface of this
|
from Firecracker. This document explains the user interface of this
|
||||||
feature, and highlights some internal implementations that can help users
|
feature, and highlights some internal implementations that can help users
|
||||||
better understand the expected behavior of I/O throttling in practice.
|
better understand the expected behavior of I/O throttling in practice.
|
||||||
@@ -44,10 +44,12 @@ generally advisable to keep `bw/ops_refill_time` larger than `100 ms`
|
|||||||
expectation ("refill-rate").
|
expectation ("refill-rate").
|
||||||
|
|
||||||
## Rate Limit Groups
|
## Rate Limit Groups
|
||||||
|
|
||||||
It is possible to throttle the aggregate bandwidth or operations
|
It is possible to throttle the aggregate bandwidth or operations
|
||||||
of multiple virtio-blk devices using a `rate_limit_group`. virtio-blk devices may be
|
of multiple virtio-blk devices using a `rate_limit_group`. virtio-blk devices may be
|
||||||
dynamically added and removed from a `rate_limit_group`. The following example
|
dynamically added and removed from a `rate_limit_group`. The following example
|
||||||
demonstrates how to throttle the aggregate bandwidth of two disks to 10 MiB/s.
|
demonstrates how to throttle the aggregate bandwidth of two disks to 10 MiB/s.
|
||||||
|
|
||||||
```
|
```
|
||||||
--disk path=disk0.raw,rate_limit_group=group0 \
|
--disk path=disk0.raw,rate_limit_group=group0 \
|
||||||
path=disk1.raw,rate_limit_group=group0 \
|
path=disk1.raw,rate_limit_group=group0 \
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
The target audience of this document is both:
|
The target audience of this document is both:
|
||||||
|
|
||||||
* Developers who want to understand what log level to use and when,
|
- Developers who want to understand what log level to use and when,
|
||||||
* Users who want to debug issues with running their workloads in Cloud Hypervisor
|
- Users who want to debug issues with running their workloads in Cloud Hypervisor
|
||||||
|
|
||||||
## Control
|
## Control
|
||||||
|
|
||||||
@@ -29,7 +29,6 @@ A typical example of where this level of message should be generated is during a
|
|||||||
|
|
||||||
The user should investigate the meaning of this warning and take steps to ensure the correct functionality.
|
The user should investigate the meaning of this warning and take steps to ensure the correct functionality.
|
||||||
|
|
||||||
|
|
||||||
### `info!()`
|
### `info!()`
|
||||||
|
|
||||||
Use `-v` to enable.
|
Use `-v` to enable.
|
||||||
|
|||||||
88
docs/riscv.md
Normal file
88
docs/riscv.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# How to build and test Cloud Hypervisor on riscv64
|
||||||
|
|
||||||
|
This document introduces how to build and test Cloud Hypervisor on `riscv64`.
|
||||||
|
All instructions here are tested with Ubuntu 24.04.2 as the host OS.
|
||||||
|
|
||||||
|
## Hardware requirements
|
||||||
|
|
||||||
|
- riscv64 servers (recommended) or development boards equipped with the AIA
|
||||||
|
(Advance Interrupt Architecture) interrupt controller.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
We create a folder to build and run Cloud Hypervisor at `$HOME/cloud-hypervisor`
|
||||||
|
|
||||||
|
```console
|
||||||
|
export CLOUDH=$HOME/cloud-hypervisor
|
||||||
|
mkdir $CLOUDH
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
You need to install some prerequisite packages to build and test Cloud Hypervisor.
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
```console
|
||||||
|
# Install rust tool chain
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
|
# Install the tools used for building guest kernel, EDK2 and converting guest disk
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install git build-essential m4 bison flex uuid-dev qemu-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building Cloud Hypervisor
|
||||||
|
|
||||||
|
```console
|
||||||
|
pushd $CLOUDH
|
||||||
|
git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
|
||||||
|
cd cloud-hypervisor
|
||||||
|
cargo build
|
||||||
|
popd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disk image
|
||||||
|
|
||||||
|
Download the Ubuntu cloud image and convert the image type.
|
||||||
|
|
||||||
|
```console
|
||||||
|
pushd $CLOUDH
|
||||||
|
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-riscv64.img
|
||||||
|
qemu-img convert -p -f qcow2 -O raw jammy-server-cloudimg-riscv64.img jammy-server-cloudimg-riscv64.raw
|
||||||
|
popd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Direct-kernel booting
|
||||||
|
|
||||||
|
### Building kernel
|
||||||
|
|
||||||
|
```console
|
||||||
|
pushd $CLOUDH
|
||||||
|
git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b ch-6.12.8
|
||||||
|
cd linux
|
||||||
|
make ch_defconfig
|
||||||
|
make -j `nproc`
|
||||||
|
popd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Booting the guest VM
|
||||||
|
|
||||||
|
```console
|
||||||
|
pushd $CLOUDH
|
||||||
|
sudo $CLOUDH/cloud-hypervisor/target/debug/cloud-hypervisor \
|
||||||
|
--kernel $CLOUDH/linux/arch/riscv64/boot/Image \
|
||||||
|
--disk path=jammy-server-cloudimg-riscv64.raw \
|
||||||
|
--cmdline "console=hvc0 root=/dev/vda rw" \
|
||||||
|
--cpus boot=1 \
|
||||||
|
--memory size=1024M \
|
||||||
|
--seccomp false \
|
||||||
|
--log-file boot.log -vv
|
||||||
|
popd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known limitations
|
||||||
|
|
||||||
|
- Direct kernel boot only
|
||||||
|
- `64-bit Linux` guest OS only
|
||||||
|
- For more details, see
|
||||||
|
[here](https://github.com/cloud-hypervisor/cloud-hypervisor/issues/6978).
|
||||||
70
fuzz/Cargo.lock
generated
70
fuzz/Cargo.lock
generated
@@ -425,10 +425,22 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi 0.13.3+wasi-0.2.2",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
@@ -618,9 +630,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mshv-bindings"
|
name = "mshv-bindings"
|
||||||
version = "0.3.2"
|
version = "0.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0cb5031f3243a7459b7c13d960d25420980874eebda816db24ce6077e21d43"
|
checksum = "a9c369385758f81ca937414dc2147737c92032e4fb399669f287abf94d89252d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
@@ -636,7 +648,7 @@ version = "0.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -651,7 +663,7 @@ name = "net_util"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"epoll",
|
"epoll",
|
||||||
"getrandom",
|
"getrandom 0.3.1",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"net_gen",
|
"net_gen",
|
||||||
@@ -770,20 +782,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
|
"zerocopy 0.8.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.3.1"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
@@ -791,11 +803,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.6.4"
|
version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -834,9 +846,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "seccompiler"
|
name = "seccompiler"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "345a3e4dddf721a478089d4697b83c6c0a8f5bf16086f6c13397e4534eb6e2e5"
|
checksum = "a4ae55de56877481d112a559bbc12667635fdaf5e005712fd4e2b2fa50ffc884"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -1052,20 +1064,20 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.10.0"
|
version = "1.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.3.1",
|
||||||
"rand",
|
"rand",
|
||||||
"uuid-macro-internal",
|
"uuid-macro-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid-macro-internal"
|
name = "uuid-macro-internal"
|
||||||
version = "1.10.0"
|
version = "1.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee1cd046f83ea2c4e920d6ee9f7c3537ef928d75dce5d84a87c2c5d6b3999a3a"
|
checksum = "9521621447c21497fac206ffe6e9f642f977c4f82eeba9201055f64884d9cb01"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1303,6 +1315,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.13.3+wasi-0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.93"
|
version = "0.2.93"
|
||||||
@@ -1462,6 +1483,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rt"
|
||||||
|
version = "0.33.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.7.35"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch
|
|||||||
mshv-bindings = "0.3.2"
|
mshv-bindings = "0.3.2"
|
||||||
net_util = { path = "../net_util" }
|
net_util = { path = "../net_util" }
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
seccompiler = "0.4.0"
|
seccompiler = "0.5.0"
|
||||||
virtio-devices = { path = "../virtio-devices" }
|
virtio-devices = { path = "../virtio-devices" }
|
||||||
virtio-queue = "0.14.0"
|
virtio-queue = "0.14.0"
|
||||||
vm-device = { path = "../vm-device" }
|
vm-device = { path = "../vm-device" }
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ arc-swap = "1.7.1"
|
|||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
concat-idents = "1.1.5"
|
concat-idents = "1.1.5"
|
||||||
igvm = { version = "0.3.3", optional = true }
|
igvm = { workspace = true, optional = true }
|
||||||
igvm_defs = { version = "0.3.1", optional = true }
|
igvm_defs = { workspace = true, optional = true }
|
||||||
kvm-bindings = { workspace = true, optional = true, features = ["serde"] }
|
kvm-bindings = { workspace = true, optional = true, features = ["serde"] }
|
||||||
kvm-ioctls = { workspace = true, optional = true }
|
kvm-ioctls = { workspace = true, optional = true }
|
||||||
libc = "0.2.167"
|
libc = "0.2.167"
|
||||||
|
|||||||
@@ -10,18 +10,21 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[cfg(not(target_arch = "riscv64"))]
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use vm_memory::GuestAddress;
|
use vm_memory::GuestAddress;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
|
||||||
use crate::aarch64::{RegList, VcpuInit};
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
use crate::riscv64::RegList;
|
use crate::RegList;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use crate::VcpuInit;
|
||||||
use crate::{CpuState, MpState, StandardRegisters};
|
use crate::{CpuState, MpState, StandardRegisters};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -449,7 +452,26 @@ pub trait Vcpu: Send + Sync {
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn vcpu_finalize(&self, feature: i32) -> Result<()>;
|
fn vcpu_finalize(&self, feature: i32) -> Result<()>;
|
||||||
|
///
|
||||||
|
/// Gets the features that have been finalized for a given CPU.
|
||||||
|
///
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_get_finalized_features(&self) -> i32;
|
||||||
|
///
|
||||||
|
/// Sets processor features for a given CPU.
|
||||||
|
///
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_set_processor_features(
|
||||||
|
&self,
|
||||||
|
vm: &Arc<dyn crate::Vm>,
|
||||||
|
kvi: &mut VcpuInit,
|
||||||
|
id: u8,
|
||||||
|
) -> Result<()>;
|
||||||
|
///
|
||||||
|
/// Returns VcpuInit with default value set
|
||||||
|
///
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn create_vcpu_init(&self) -> VcpuInit;
|
||||||
///
|
///
|
||||||
/// Gets a list of the guest registers that are supported for the
|
/// Gets a list of the guest registers that are supported for the
|
||||||
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ use kvm_ioctls::DeviceFd;
|
|||||||
use crate::arch::aarch64::gic::{Error, Result};
|
use crate::arch::aarch64::gic::{Error, Result};
|
||||||
use crate::device::HypervisorDeviceError;
|
use crate::device::HypervisorDeviceError;
|
||||||
use crate::kvm::kvm_bindings::{
|
use crate::kvm::kvm_bindings::{
|
||||||
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG,
|
kvm_device_attr, kvm_one_reg, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, KVM_REG_ARM64,
|
||||||
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK,
|
KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT,
|
||||||
KVM_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_SIZE_U64,
|
KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
use crate::kvm::{Register, VcpuKvmState};
|
use crate::kvm::VcpuKvmState;
|
||||||
use crate::CpuState;
|
use crate::CpuState;
|
||||||
|
|
||||||
// Relevant redistributor registers that we want to save/restore.
|
// Relevant redistributor registers that we want to save/restore.
|
||||||
@@ -213,7 +213,7 @@ pub fn construct_gicr_typers(vcpu_states: &[CpuState]) -> Vec<u64> {
|
|||||||
let state: VcpuKvmState = state.clone().into();
|
let state: VcpuKvmState = state.clone().into();
|
||||||
let last = (index == vcpu_states.len() - 1) as u64;
|
let last = (index == vcpu_states.len() - 1) as u64;
|
||||||
// state.sys_regs is a big collection of system registers, including MIPDR_EL1
|
// state.sys_regs is a big collection of system registers, including MIPDR_EL1
|
||||||
let mpidr: Vec<Register> = state
|
let mpidr: Vec<kvm_one_reg> = state
|
||||||
.sys_regs
|
.sys_regs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|reg| reg.id == KVM_ARM64_SYSREG_MPIDR_EL1)
|
.filter(|reg| reg.id == KVM_ARM64_SYSREG_MPIDR_EL1)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ use kvm_bindings::{
|
|||||||
kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_CORE,
|
kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_CORE,
|
||||||
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
|
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
pub use kvm_bindings::{kvm_one_reg as Register, kvm_vcpu_init as VcpuInit, RegList};
|
|
||||||
pub use kvm_ioctls::{Cap, Kvm};
|
pub use kvm_ioctls::{Cap, Kvm};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ use vmm_sys_util::eventfd::EventFd;
|
|||||||
use crate::aarch64::gic::KvmGicV3Its;
|
use crate::aarch64::gic::KvmGicV3Its;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use crate::aarch64::{
|
pub use crate::aarch64::{
|
||||||
check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuInit,
|
check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuKvmState,
|
||||||
VcpuKvmState,
|
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
||||||
@@ -53,15 +52,11 @@ use crate::{offset_of, riscv64_reg_id};
|
|||||||
// x86_64 dependencies
|
// x86_64 dependencies
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
#[cfg(target_arch = "aarch64")]
|
|
||||||
use aarch64::{RegList, Register};
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use kvm_bindings::{
|
use kvm_bindings::{
|
||||||
kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP,
|
kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP,
|
||||||
KVM_GUESTDBG_USE_HW_BP,
|
KVM_GUESTDBG_USE_HW_BP,
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "riscv64")]
|
|
||||||
use riscv64::{RegList, Register};
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use x86_64::check_required_kvm_extensions;
|
use x86_64::check_required_kvm_extensions;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -116,6 +111,9 @@ use vfio_ioctls::VfioDeviceFd;
|
|||||||
use vmm_sys_util::{ioctl::ioctl_with_val, ioctl_ioc_nr, ioctl_iowr_nr};
|
use vmm_sys_util::{ioctl::ioctl_with_val, ioctl_ioc_nr, ioctl_iowr_nr};
|
||||||
pub use {kvm_bindings, kvm_ioctls};
|
pub use {kvm_bindings, kvm_ioctls};
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
|
use crate::RegList;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
const KVM_CAP_SGX_ATTRIBUTE: u32 = 196;
|
const KVM_CAP_SGX_ATTRIBUTE: u32 = 196;
|
||||||
|
|
||||||
@@ -353,6 +351,61 @@ impl From<ClockData> for kvm_clock_data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<kvm_bindings::kvm_one_reg> for crate::Register {
|
||||||
|
fn from(s: kvm_bindings::kvm_one_reg) -> Self {
|
||||||
|
crate::Register::Kvm(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::Register> for kvm_bindings::kvm_one_reg {
|
||||||
|
fn from(e: crate::Register) -> Self {
|
||||||
|
match e {
|
||||||
|
crate::Register::Kvm(e) => e,
|
||||||
|
/* Needed in case other hypervisors are enabled */
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => panic!("Register is not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<kvm_bindings::kvm_vcpu_init> for crate::VcpuInit {
|
||||||
|
fn from(s: kvm_bindings::kvm_vcpu_init) -> Self {
|
||||||
|
crate::VcpuInit::Kvm(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<crate::VcpuInit> for kvm_bindings::kvm_vcpu_init {
|
||||||
|
fn from(e: crate::VcpuInit) -> Self {
|
||||||
|
match e {
|
||||||
|
crate::VcpuInit::Kvm(e) => e,
|
||||||
|
/* Needed in case other hypervisors are enabled */
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => panic!("VcpuInit is not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
|
impl From<kvm_bindings::RegList> for crate::RegList {
|
||||||
|
fn from(s: kvm_bindings::RegList) -> Self {
|
||||||
|
crate::RegList::Kvm(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
|
impl From<crate::RegList> for kvm_bindings::RegList {
|
||||||
|
fn from(e: crate::RegList) -> Self {
|
||||||
|
match e {
|
||||||
|
crate::RegList::Kvm(e) => e,
|
||||||
|
/* Needed in case other hypervisors are enabled */
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => panic!("RegList is not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "riscv64"))]
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
impl From<kvm_bindings::kvm_regs> for crate::StandardRegisters {
|
impl From<kvm_bindings::kvm_regs> for crate::StandardRegisters {
|
||||||
fn from(s: kvm_bindings::kvm_regs) -> Self {
|
fn from(s: kvm_bindings::kvm_regs) -> Self {
|
||||||
@@ -754,10 +807,13 @@ impl vm::Vm for KvmVm {
|
|||||||
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
||||||
///
|
///
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> vm::Result<()> {
|
fn get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> vm::Result<()> {
|
||||||
|
let mut kvm_kvi: kvm_bindings::kvm_vcpu_init = (*kvi).into();
|
||||||
self.fd
|
self.fd
|
||||||
.get_preferred_target(kvi)
|
.get_preferred_target(&mut kvm_kvi)
|
||||||
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))
|
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))?;
|
||||||
|
*kvi = kvm_kvi.into();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -1437,302 +1493,64 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
fn get_regs(&self) -> cpu::Result<StandardRegisters> {
|
fn get_regs(&self) -> cpu::Result<StandardRegisters> {
|
||||||
let mut state = kvm_riscv_core::default();
|
let mut state = kvm_riscv_core::default();
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, pc);
|
/// Macro used to extract RISC-V register data from KVM Vcpu according
|
||||||
let mut bytes = [0_u8; 8];
|
/// to `$reg_name` provided to `state`.
|
||||||
self.fd
|
macro_rules! riscv64_get_one_reg_from_vcpu {
|
||||||
.lock()
|
(mode) => {
|
||||||
.unwrap()
|
let off = offset_of!(kvm_riscv_core, mode);
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
let mut bytes = [0_u8; 8];
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
self.fd
|
||||||
state.regs.pc = u64::from_le_bytes(bytes);
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
||||||
|
state.mode = u64::from_le_bytes(bytes);
|
||||||
|
};
|
||||||
|
($reg_name:ident) => {
|
||||||
|
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, $reg_name);
|
||||||
|
let mut bytes = [0_u8; 8];
|
||||||
|
self.fd
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
||||||
|
state.regs.$reg_name = u64::from_le_bytes(bytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, ra);
|
riscv64_get_one_reg_from_vcpu!(pc);
|
||||||
let mut bytes = [0_u8; 8];
|
riscv64_get_one_reg_from_vcpu!(ra);
|
||||||
self.fd
|
riscv64_get_one_reg_from_vcpu!(sp);
|
||||||
.lock()
|
riscv64_get_one_reg_from_vcpu!(gp);
|
||||||
.unwrap()
|
riscv64_get_one_reg_from_vcpu!(tp);
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
riscv64_get_one_reg_from_vcpu!(t0);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
riscv64_get_one_reg_from_vcpu!(t1);
|
||||||
state.regs.ra = u64::from_le_bytes(bytes);
|
riscv64_get_one_reg_from_vcpu!(t2);
|
||||||
|
riscv64_get_one_reg_from_vcpu!(s0);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, sp);
|
riscv64_get_one_reg_from_vcpu!(s1);
|
||||||
let mut bytes = [0_u8; 8];
|
riscv64_get_one_reg_from_vcpu!(a0);
|
||||||
self.fd
|
riscv64_get_one_reg_from_vcpu!(a1);
|
||||||
.lock()
|
riscv64_get_one_reg_from_vcpu!(a2);
|
||||||
.unwrap()
|
riscv64_get_one_reg_from_vcpu!(a3);
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
riscv64_get_one_reg_from_vcpu!(a4);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
riscv64_get_one_reg_from_vcpu!(a5);
|
||||||
state.regs.sp = u64::from_le_bytes(bytes);
|
riscv64_get_one_reg_from_vcpu!(a6);
|
||||||
|
riscv64_get_one_reg_from_vcpu!(a7);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, gp);
|
riscv64_get_one_reg_from_vcpu!(s2);
|
||||||
let mut bytes = [0_u8; 8];
|
riscv64_get_one_reg_from_vcpu!(s3);
|
||||||
self.fd
|
riscv64_get_one_reg_from_vcpu!(s4);
|
||||||
.lock()
|
riscv64_get_one_reg_from_vcpu!(s5);
|
||||||
.unwrap()
|
riscv64_get_one_reg_from_vcpu!(s6);
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
riscv64_get_one_reg_from_vcpu!(s7);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
riscv64_get_one_reg_from_vcpu!(s8);
|
||||||
state.regs.gp = u64::from_le_bytes(bytes);
|
riscv64_get_one_reg_from_vcpu!(s9);
|
||||||
|
riscv64_get_one_reg_from_vcpu!(s10);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, tp);
|
riscv64_get_one_reg_from_vcpu!(s11);
|
||||||
let mut bytes = [0_u8; 8];
|
riscv64_get_one_reg_from_vcpu!(t3);
|
||||||
self.fd
|
riscv64_get_one_reg_from_vcpu!(t4);
|
||||||
.lock()
|
riscv64_get_one_reg_from_vcpu!(t5);
|
||||||
.unwrap()
|
riscv64_get_one_reg_from_vcpu!(t6);
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
riscv64_get_one_reg_from_vcpu!(mode);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.tp = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t0);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t0 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t1);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t1 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t2);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t2 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s0);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s0 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s1);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s1 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a0);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a0 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a1);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a1 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a2);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a2 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a3);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a3 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a4);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a4 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a5);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a5 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a6);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a6 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a7);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.a7 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s2);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s2 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s3);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s3 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s4);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s4 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s5);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s5 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s6);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s6 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s7);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s7 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s8);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s8 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s9);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s9 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s10);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s10 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s11);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.s11 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t3);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t3 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t4);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t4 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t5);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t5 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t6);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.regs.t6 = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, mode);
|
|
||||||
let mut bytes = [0_u8; 8];
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_one_reg(riscv64_reg_id!(KVM_REG_RISCV_CORE, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRiscvCoreRegister(e.into()))?;
|
|
||||||
state.mode = u64::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
Ok(state.into())
|
Ok(state.into())
|
||||||
}
|
}
|
||||||
@@ -1882,335 +1700,66 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
// for some additional info on registers.
|
// for some additional info on registers.
|
||||||
let kvm_regs_state: kvm_riscv_core = (*state).into();
|
let kvm_regs_state: kvm_riscv_core = (*state).into();
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, pc);
|
/// Macro used to set value of specific RISC-V `$reg_name` stored in
|
||||||
self.fd
|
/// `state` to KVM Vcpu.
|
||||||
.lock()
|
macro_rules! riscv64_set_one_reg_to_vcpu {
|
||||||
.unwrap()
|
(mode) => {
|
||||||
.set_one_reg(
|
let off = offset_of!(kvm_riscv_core, mode);
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
self.fd
|
||||||
&kvm_regs_state.regs.pc.to_le_bytes(),
|
.lock()
|
||||||
)
|
.unwrap()
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
.set_one_reg(
|
||||||
|
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
||||||
|
&kvm_regs_state.mode.to_le_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
||||||
|
};
|
||||||
|
($reg_name:ident) => {
|
||||||
|
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, $reg_name);
|
||||||
|
self.fd
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.set_one_reg(
|
||||||
|
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
||||||
|
&kvm_regs_state.regs.$reg_name.to_le_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, ra);
|
riscv64_set_one_reg_to_vcpu!(pc);
|
||||||
self.fd
|
riscv64_set_one_reg_to_vcpu!(ra);
|
||||||
.lock()
|
riscv64_set_one_reg_to_vcpu!(sp);
|
||||||
.unwrap()
|
riscv64_set_one_reg_to_vcpu!(gp);
|
||||||
.set_one_reg(
|
riscv64_set_one_reg_to_vcpu!(tp);
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
riscv64_set_one_reg_to_vcpu!(t0);
|
||||||
&kvm_regs_state.regs.ra.to_le_bytes(),
|
riscv64_set_one_reg_to_vcpu!(t1);
|
||||||
)
|
riscv64_set_one_reg_to_vcpu!(t2);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
riscv64_set_one_reg_to_vcpu!(s0);
|
||||||
|
riscv64_set_one_reg_to_vcpu!(s1);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, sp);
|
riscv64_set_one_reg_to_vcpu!(a0);
|
||||||
self.fd
|
riscv64_set_one_reg_to_vcpu!(a1);
|
||||||
.lock()
|
riscv64_set_one_reg_to_vcpu!(a2);
|
||||||
.unwrap()
|
riscv64_set_one_reg_to_vcpu!(a3);
|
||||||
.set_one_reg(
|
riscv64_set_one_reg_to_vcpu!(a4);
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
riscv64_set_one_reg_to_vcpu!(a5);
|
||||||
&kvm_regs_state.regs.sp.to_le_bytes(),
|
riscv64_set_one_reg_to_vcpu!(a6);
|
||||||
)
|
riscv64_set_one_reg_to_vcpu!(a7);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
riscv64_set_one_reg_to_vcpu!(s2);
|
||||||
|
riscv64_set_one_reg_to_vcpu!(s3);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, gp);
|
riscv64_set_one_reg_to_vcpu!(s4);
|
||||||
self.fd
|
riscv64_set_one_reg_to_vcpu!(s5);
|
||||||
.lock()
|
riscv64_set_one_reg_to_vcpu!(s6);
|
||||||
.unwrap()
|
riscv64_set_one_reg_to_vcpu!(s7);
|
||||||
.set_one_reg(
|
riscv64_set_one_reg_to_vcpu!(s8);
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
riscv64_set_one_reg_to_vcpu!(s9);
|
||||||
&kvm_regs_state.regs.gp.to_le_bytes(),
|
riscv64_set_one_reg_to_vcpu!(s10);
|
||||||
)
|
riscv64_set_one_reg_to_vcpu!(s11);
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
riscv64_set_one_reg_to_vcpu!(t3);
|
||||||
|
riscv64_set_one_reg_to_vcpu!(t4);
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, tp);
|
riscv64_set_one_reg_to_vcpu!(t5);
|
||||||
self.fd
|
riscv64_set_one_reg_to_vcpu!(t6);
|
||||||
.lock()
|
riscv64_set_one_reg_to_vcpu!(mode);
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.tp.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t0);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t0.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t1);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t1.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t2);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t2.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s0);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s0.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s1);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s1.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a0);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a0.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a1);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a1.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a2);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a2.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a3);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a3.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a4);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a4.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a5);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a5.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a6);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a6.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, a7);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.a7.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s2);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s2.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s3);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s3.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s4);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s4.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s5);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s5.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s6);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s6.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s7);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s7.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s8);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s8.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s9);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s9.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s10);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s10.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, s11);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.s11.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t3);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t3.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t4);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t4.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t5);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t5.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, regs, user_regs_struct, t6);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.regs.t6.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_riscv_core, mode);
|
|
||||||
self.fd
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_one_reg(
|
|
||||||
riscv64_reg_id!(KVM_REG_RISCV_CORE, off),
|
|
||||||
&kvm_regs_state.mode.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -2602,11 +2151,70 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
|
fn vcpu_get_finalized_features(&self) -> i32 {
|
||||||
|
kvm_bindings::KVM_ARM_VCPU_SVE as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_set_processor_features(
|
||||||
|
&self,
|
||||||
|
vm: &Arc<dyn crate::Vm>,
|
||||||
|
kvi: &mut crate::VcpuInit,
|
||||||
|
id: u8,
|
||||||
|
) -> cpu::Result<()> {
|
||||||
|
use std::arch::is_aarch64_feature_detected;
|
||||||
|
#[allow(clippy::nonminimal_bool)]
|
||||||
|
let sve_supported =
|
||||||
|
is_aarch64_feature_detected!("sve") || is_aarch64_feature_detected!("sve2");
|
||||||
|
|
||||||
|
let mut kvm_kvi: kvm_bindings::kvm_vcpu_init = (*kvi).into();
|
||||||
|
|
||||||
|
// We already checked that the capability is supported.
|
||||||
|
kvm_kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
|
||||||
|
if vm
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::kvm::KvmVm>()
|
||||||
|
.unwrap()
|
||||||
|
.check_extension(Cap::ArmPmuV3)
|
||||||
|
{
|
||||||
|
kvm_kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if sve_supported
|
||||||
|
&& vm
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::kvm::KvmVm>()
|
||||||
|
.unwrap()
|
||||||
|
.check_extension(Cap::ArmSve)
|
||||||
|
{
|
||||||
|
kvm_kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_SVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-boot cpus are powered off initially.
|
||||||
|
if id > 0 {
|
||||||
|
kvm_kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
*kvi = kvm_kvi.into();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Return VcpuInit with default value set
|
||||||
|
///
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn create_vcpu_init(&self) -> crate::VcpuInit {
|
||||||
|
kvm_bindings::kvm_vcpu_init::default().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_init(&self, kvi: &crate::VcpuInit) -> cpu::Result<()> {
|
||||||
|
let kvm_kvi: kvm_bindings::kvm_vcpu_init = (*kvi).into();
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vcpu_init(kvi)
|
.vcpu_init(&kvm_kvi)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2625,11 +2233,14 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
||||||
///
|
///
|
||||||
fn get_reg_list(&self, reg_list: &mut RegList) -> cpu::Result<()> {
|
fn get_reg_list(&self, reg_list: &mut RegList) -> cpu::Result<()> {
|
||||||
|
let mut kvm_reg_list: kvm_bindings::RegList = reg_list.clone().into();
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_reg_list(reg_list)
|
.get_reg_list(&mut kvm_reg_list)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetRegList(e.into()))
|
.map_err(|e: kvm_ioctls::Error| cpu::HypervisorCpuError::GetRegList(e.into()))?;
|
||||||
|
*reg_list = kvm_reg_list.into();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -2917,8 +2528,8 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
// Get systerm register
|
// Get systerm register
|
||||||
// Call KVM_GET_REG_LIST to get all registers available to the guest.
|
// Call KVM_GET_REG_LIST to get all registers available to the guest.
|
||||||
// For ArmV8 there are around 500 registers.
|
// For ArmV8 there are around 500 registers.
|
||||||
let mut sys_regs: Vec<Register> = Vec::new();
|
let mut sys_regs: Vec<kvm_bindings::kvm_one_reg> = Vec::new();
|
||||||
let mut reg_list = RegList::new(500).unwrap();
|
let mut reg_list = kvm_bindings::RegList::new(500).unwrap();
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -2970,8 +2581,8 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
// Get non-core register
|
// Get non-core register
|
||||||
// Call KVM_GET_REG_LIST to get all registers available to the guest.
|
// Call KVM_GET_REG_LIST to get all registers available to the guest.
|
||||||
// For RISC-V 64-bit there are around 200 registers.
|
// For RISC-V 64-bit there are around 200 registers.
|
||||||
let mut sys_regs: Vec<Register> = Vec::new();
|
let mut sys_regs: Vec<kvm_bindings::kvm_one_reg> = Vec::new();
|
||||||
let mut reg_list = RegList::new(200).unwrap();
|
let mut reg_list = kvm_bindings::RegList::new(200).unwrap();
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use kvm_bindings::{
|
|||||||
kvm_mp_state, kvm_one_reg, kvm_riscv_core, KVM_REG_RISCV_CORE, KVM_REG_RISCV_TYPE_MASK,
|
kvm_mp_state, kvm_one_reg, kvm_riscv_core, KVM_REG_RISCV_CORE, KVM_REG_RISCV_TYPE_MASK,
|
||||||
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U64,
|
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
pub use kvm_bindings::{kvm_one_reg as Register, RegList};
|
|
||||||
pub use kvm_ioctls::{Cap, Kvm};
|
pub use kvm_ioctls::{Cap, Kvm};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ pub enum IoEventAddress {
|
|||||||
pub enum CpuState {
|
pub enum CpuState {
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
Kvm(kvm::VcpuKvmState),
|
Kvm(kvm::VcpuKvmState),
|
||||||
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
#[cfg(feature = "mshv")]
|
||||||
Mshv(mshv::VcpuMshvState),
|
Mshv(mshv::VcpuMshvState),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,16 +196,35 @@ pub enum IrqRoutingEntry {
|
|||||||
Mshv(mshv_bindings::mshv_user_irq_entry),
|
Mshv(mshv_bindings::mshv_user_irq_entry),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub enum VcpuInit {
|
||||||
|
#[cfg(all(feature = "kvm", target_arch = "aarch64"))]
|
||||||
|
Kvm(kvm_bindings::kvm_vcpu_init),
|
||||||
|
#[cfg(all(feature = "mshv", target_arch = "aarch64"))]
|
||||||
|
Mshv(mshv_bindings::MshvVcpuInit),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum RegList {
|
||||||
|
#[cfg(all(feature = "kvm", any(target_arch = "aarch64", target_arch = "riscv64")))]
|
||||||
|
Kvm(kvm_bindings::RegList),
|
||||||
|
#[cfg(all(feature = "mshv", target_arch = "aarch64"))]
|
||||||
|
Mshv(mshv_bindings::MshvRegList),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Register {
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
Kvm(kvm_bindings::kvm_one_reg),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum StandardRegisters {
|
pub enum StandardRegisters {
|
||||||
#[cfg(all(feature = "kvm", not(target_arch = "riscv64")))]
|
#[cfg(all(feature = "kvm", not(target_arch = "riscv64")))]
|
||||||
Kvm(kvm_bindings::kvm_regs),
|
Kvm(kvm_bindings::kvm_regs),
|
||||||
#[cfg(all(feature = "kvm", target_arch = "riscv64"))]
|
#[cfg(all(feature = "kvm", target_arch = "riscv64"))]
|
||||||
Kvm(kvm_bindings::kvm_riscv_core),
|
Kvm(kvm_bindings::kvm_riscv_core),
|
||||||
#[cfg(all(
|
#[cfg(any(feature = "mshv", feature = "mshv_emulator"))]
|
||||||
any(feature = "mshv", feature = "mshv_emulator"),
|
|
||||||
target_arch = "x86_64"
|
|
||||||
))]
|
|
||||||
Mshv(mshv_bindings::StandardRegisters),
|
Mshv(mshv_bindings::StandardRegisters),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +311,8 @@ macro_rules! set_aarch64_reg {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
StandardRegisters::Kvm(s) => s.regs.$reg_name = val,
|
StandardRegisters::Kvm(s) => s.regs.$reg_name = val,
|
||||||
|
#[cfg(feature = "mshv")]
|
||||||
|
StandardRegisters::Mshv(s) => s.$reg_name = val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,6 +329,8 @@ macro_rules! get_aarch64_reg {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
StandardRegisters::Kvm(s) => s.regs.$reg_name,
|
StandardRegisters::Kvm(s) => s.regs.$reg_name,
|
||||||
|
#[cfg(feature = "mshv")]
|
||||||
|
StandardRegisters::Mshv(s) => s.$reg_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
hypervisor/src/mshv/aarch64/mod.rs
Normal file
22
hypervisor/src/mshv/aarch64/mod.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
||||||
|
//
|
||||||
|
// Copyright © 2025, Microsoft Corporation
|
||||||
|
//
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Export generically-named wrappers of mshv_bindings for Unix-based platforms
|
||||||
|
///
|
||||||
|
pub use mshv_bindings::StandardRegisters as MshvStandardRegisters;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
pub struct VcpuMshvState {
|
||||||
|
pub regs: MshvStandardRegisters,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for VcpuMshvState {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Standard registers: {:?}", self.regs)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,15 +12,19 @@ use std::sync::{Arc, RwLock};
|
|||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use mshv_bindings::*;
|
use mshv_bindings::*;
|
||||||
use mshv_ioctls::{set_registers_64, InterruptRequest, Mshv, NoDatamatch, VcpuFd, VmFd, VmType};
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use mshv_ioctls::{set_registers_64, InterruptRequest};
|
||||||
|
use mshv_ioctls::{Mshv, NoDatamatch, VcpuFd, VmFd, VmType};
|
||||||
use vfio_ioctls::VfioDeviceFd;
|
use vfio_ioctls::VfioDeviceFd;
|
||||||
use vm::DataMatch;
|
use vm::DataMatch;
|
||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
use vm_memory::bitmap::AtomicBitmap;
|
use vm_memory::bitmap::AtomicBitmap;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::emulator::PlatformEmulator;
|
use crate::arch::emulator::PlatformEmulator;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::emulator::Emulator;
|
use crate::arch::x86::emulator::Emulator;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::mshv::emulator::MshvEmulatorContext;
|
use crate::mshv::emulator::MshvEmulatorContext;
|
||||||
use crate::vm::{self, InterruptSourceConfig, VmOps};
|
use crate::vm::{self, InterruptSourceConfig, VmOps};
|
||||||
use crate::{cpu, hypervisor, vec_with_array_field, HypervisorType};
|
use crate::{cpu, hypervisor, vec_with_array_field, HypervisorType};
|
||||||
@@ -29,10 +33,17 @@ mod snp_constants;
|
|||||||
// x86_64 dependencies
|
// x86_64 dependencies
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
|
// aarch64 dependencies
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub mod aarch64;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub use aarch64::VcpuMshvState;
|
||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
|
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
|
||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
@@ -50,6 +61,8 @@ pub use {
|
|||||||
mshv_bindings::mshv_device_attr as DeviceAttr, mshv_ioctls, mshv_ioctls::DeviceFd,
|
mshv_bindings::mshv_device_attr as DeviceAttr, mshv_ioctls, mshv_ioctls::DeviceFd,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{CpuIdEntry, FpuState, MsrEntry};
|
use crate::arch::x86::{CpuIdEntry, FpuState, MsrEntry};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -191,6 +204,44 @@ impl From<IrqRoutingEntry> for mshv_user_irq_entry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<mshv_bindings::MshvRegList> for crate::RegList {
|
||||||
|
fn from(s: mshv_bindings::MshvRegList) -> Self {
|
||||||
|
crate::RegList::Mshv(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<crate::RegList> for mshv_bindings::MshvRegList {
|
||||||
|
fn from(e: crate::RegList) -> Self {
|
||||||
|
match e {
|
||||||
|
crate::RegList::Mshv(e) => e,
|
||||||
|
/* Needed in case other hypervisors are enabled */
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => panic!("RegList is not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<mshv_bindings::MshvVcpuInit> for crate::VcpuInit {
|
||||||
|
fn from(s: mshv_bindings::MshvVcpuInit) -> Self {
|
||||||
|
crate::VcpuInit::Mshv(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl From<crate::VcpuInit> for mshv_bindings::MshvVcpuInit {
|
||||||
|
fn from(e: crate::VcpuInit) -> Self {
|
||||||
|
match e {
|
||||||
|
crate::VcpuInit::Mshv(e) => e,
|
||||||
|
/* Needed in case other hypervisors are enabled */
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => panic!("VcpuInit is not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MshvDirtyLogSlot {
|
struct MshvDirtyLogSlot {
|
||||||
guest_pfn: u64,
|
guest_pfn: u64,
|
||||||
memory_size: u64,
|
memory_size: u64,
|
||||||
@@ -443,6 +494,23 @@ impl hypervisor::Hypervisor for MshvHypervisor {
|
|||||||
fn get_guest_debug_hw_bps(&self) -> usize {
|
fn get_guest_debug_hw_bps(&self) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
///
|
||||||
|
/// Retrieve AArch64 host maximum IPA size supported by MSHV.
|
||||||
|
///
|
||||||
|
fn get_host_ipa_limit(&self) -> i32 {
|
||||||
|
let host_ipa = self.mshv.get_host_partition_property(
|
||||||
|
hv_partition_property_code_HV_PARTITION_PROPERTY_PHYSICAL_ADDRESS_WIDTH as u64,
|
||||||
|
);
|
||||||
|
|
||||||
|
match host_ipa {
|
||||||
|
Ok(ipa) => ipa,
|
||||||
|
Err(e) => {
|
||||||
|
panic!("Failed to get host IPA limit: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
@@ -1238,25 +1306,50 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn get_reg_list(&self, reg_list: &mut RegList) -> cpu::Result<()> {
|
fn get_reg_list(&self, _reg_list: &mut crate::RegList) -> cpu::Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
|
fn vcpu_init(&self, _kvi: &crate::VcpuInit) -> cpu::Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn set_regs(&self, regs: &StandardRegisters) -> cpu::Result<()> {
|
fn set_regs(&self, _regs: &crate::StandardRegisters) -> cpu::Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn get_regs(&self) -> cpu::Result<StandardRegisters> {
|
fn get_regs(&self) -> cpu::Result<crate::StandardRegisters> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_finalize(&self, _feature: i32) -> cpu::Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_get_finalized_features(&self) -> i32 {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn vcpu_set_processor_features(
|
||||||
|
&self,
|
||||||
|
_vm: &Arc<dyn crate::Vm>,
|
||||||
|
_kvi: &mut crate::VcpuInit,
|
||||||
|
_id: u8,
|
||||||
|
) -> cpu::Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn create_vcpu_init(&self) -> crate::VcpuInit {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
///
|
///
|
||||||
/// X86 specific call to setup the CPUID registers.
|
/// X86 specific call to setup the CPUID registers.
|
||||||
@@ -1868,7 +1961,7 @@ impl vm::Vm for MshvVm {
|
|||||||
|
|
||||||
fn create_passthrough_device(&self) -> vm::Result<VfioDeviceFd> {
|
fn create_passthrough_device(&self) -> vm::Result<VfioDeviceFd> {
|
||||||
let mut vfio_dev = mshv_create_device {
|
let mut vfio_dev = mshv_create_device {
|
||||||
type_: mshv_device_type_MSHV_DEV_TYPE_VFIO,
|
type_: MSHV_DEV_TYPE_VFIO,
|
||||||
fd: 0,
|
fd: 0,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
@@ -2095,7 +2188,7 @@ impl vm::Vm for MshvVm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> vm::Result<()> {
|
fn get_preferred_target(&self, _kvi: &mut crate::VcpuInit) -> vm::Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,7 @@ impl MshvEmulatorContext<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_memory_flags(
|
fn r(&self, gva: u64, data: &mut [u8], flags: u32) -> Result<(), PlatformError> {
|
||||||
&self,
|
|
||||||
gva: u64,
|
|
||||||
data: &mut [u8],
|
|
||||||
flags: u32,
|
|
||||||
) -> Result<(), PlatformError> {
|
|
||||||
let gpa = self.translate(gva, flags)?;
|
let gpa = self.translate(gva, flags)?;
|
||||||
debug!(
|
debug!(
|
||||||
"mshv emulator: memory read {} bytes from [{:#x} -> {:#x}]",
|
"mshv emulator: memory read {} bytes from [{:#x} -> {:#x}]",
|
||||||
@@ -59,17 +54,38 @@ impl MshvEmulatorContext<'_> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Platform emulation for Hyper-V
|
fn read_memory_flags(
|
||||||
impl PlatformEmulator for MshvEmulatorContext<'_> {
|
&self,
|
||||||
type CpuState = EmulatorCpuState;
|
gva: u64,
|
||||||
|
data: &mut [u8],
|
||||||
|
flags: u32,
|
||||||
|
) -> Result<(), PlatformError> {
|
||||||
|
let mut len = data.len() as u64;
|
||||||
|
|
||||||
fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> {
|
// Compare the page number of the first and last byte. If they are different, this is a
|
||||||
self.read_memory_flags(gva, data, HV_TRANSLATE_GVA_VALIDATE_READ)
|
// cross-page access.
|
||||||
|
let pg1 = gva >> HV_HYP_PAGE_SHIFT;
|
||||||
|
let pg2 = (gva + len - 1) >> HV_HYP_PAGE_SHIFT;
|
||||||
|
let cross_page = pg1 != pg2;
|
||||||
|
|
||||||
|
if cross_page {
|
||||||
|
// We only handle one page cross-page access
|
||||||
|
assert!(pg1 + 1 == pg2);
|
||||||
|
let n = (gva + len) & HV_HYP_PAGE_MASK as u64;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.r(gva, &mut data[..len as usize], flags)?;
|
||||||
|
|
||||||
|
if cross_page {
|
||||||
|
self.r(gva + len, &mut data[len as usize..], flags)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
|
fn w(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
|
||||||
let gpa = self.translate(gva, HV_TRANSLATE_GVA_VALIDATE_WRITE)?;
|
let gpa = self.translate(gva, HV_TRANSLATE_GVA_VALIDATE_WRITE)?;
|
||||||
debug!(
|
debug!(
|
||||||
"mshv emulator: memory write {} bytes at [{:#x} -> {:#x}]",
|
"mshv emulator: memory write {} bytes at [{:#x} -> {:#x}]",
|
||||||
@@ -88,6 +104,40 @@ impl PlatformEmulator for MshvEmulatorContext<'_> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Platform emulation for Hyper-V
|
||||||
|
impl PlatformEmulator for MshvEmulatorContext<'_> {
|
||||||
|
type CpuState = EmulatorCpuState;
|
||||||
|
|
||||||
|
fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> {
|
||||||
|
self.read_memory_flags(gva, data, HV_TRANSLATE_GVA_VALIDATE_READ)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
|
||||||
|
let mut len = data.len() as u64;
|
||||||
|
|
||||||
|
// Compare the page number of the first and last byte. If they are different, this is a
|
||||||
|
// cross-page access.
|
||||||
|
let pg1 = gva >> HV_HYP_PAGE_SHIFT;
|
||||||
|
let pg2 = (gva + len - 1) >> HV_HYP_PAGE_SHIFT;
|
||||||
|
let cross_page = pg1 != pg2;
|
||||||
|
|
||||||
|
if cross_page {
|
||||||
|
// We only handle one page cross-page access
|
||||||
|
assert!(pg1 + 1 == pg2);
|
||||||
|
let n = (gva + len) & HV_HYP_PAGE_MASK as u64;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.w(gva, &data[..len as usize])?;
|
||||||
|
|
||||||
|
if cross_page {
|
||||||
|
self.w(gva + len, &data[len as usize..])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn cpu_state(&self, cpu_id: usize) -> Result<Self::CpuState, PlatformError> {
|
fn cpu_state(&self, cpu_id: usize) -> Result<Self::CpuState, PlatformError> {
|
||||||
if cpu_id != self.vcpu.vp_index as usize {
|
if cpu_id != self.vcpu.vp_index as usize {
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
|
||||||
use crate::aarch64::VcpuInit;
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
@@ -351,7 +349,7 @@ pub trait Vm: Send + Sync + Any {
|
|||||||
fn remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>;
|
fn remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>;
|
||||||
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> Result<()>;
|
fn get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> Result<()>;
|
||||||
/// Enable split Irq capability
|
/// Enable split Irq capability
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn enable_split_irq(&self) -> Result<()>;
|
fn enable_split_irq(&self) -> Result<()>;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
epoll = "4.3.3"
|
epoll = "4.3.3"
|
||||||
getrandom = "0.2.15"
|
getrandom = "0.3.1"
|
||||||
libc = "0.2.167"
|
libc = "0.2.167"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
net_gen = { path = "../net_gen" }
|
net_gen = { path = "../net_gen" }
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ impl MacAddr {
|
|||||||
pub fn local_random() -> MacAddr {
|
pub fn local_random() -> MacAddr {
|
||||||
// Generate a fully random MAC
|
// Generate a fully random MAC
|
||||||
let mut random_bytes = [0u8; MAC_ADDR_LEN];
|
let mut random_bytes = [0u8; MAC_ADDR_LEN];
|
||||||
if let Err(e) = getrandom::getrandom(&mut random_bytes) {
|
if let Err(e) = getrandom::fill(&mut random_bytes) {
|
||||||
error!(
|
error!(
|
||||||
"Error populating MAC address with random data: {}",
|
"Error populating MAC address with random data: {}",
|
||||||
e.to_string()
|
e.to_string()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use std::any::Any;
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::sync::{Arc, Barrier, Mutex};
|
use std::sync::{Arc, Barrier, Mutex};
|
||||||
|
|
||||||
@@ -48,10 +49,10 @@ pub(crate) const VFIO_COMMON_ID: &str = "vfio_common";
|
|||||||
pub enum VfioPciError {
|
pub enum VfioPciError {
|
||||||
#[error("Failed to create user memory region: {0}")]
|
#[error("Failed to create user memory region: {0}")]
|
||||||
CreateUserMemoryRegion(#[source] HypervisorVmError),
|
CreateUserMemoryRegion(#[source] HypervisorVmError),
|
||||||
#[error("Failed to DMA map: {0} for device {1}")]
|
#[error("Failed to DMA map: {0} for device {1} (guest BDF: {2})")]
|
||||||
DmaMap(#[source] vfio_ioctls::VfioError, PciBdf),
|
DmaMap(#[source] vfio_ioctls::VfioError, PathBuf, PciBdf),
|
||||||
#[error("Failed to DMA unmap: {0} for device {1}")]
|
#[error("Failed to DMA unmap: {0} for device {1} (guest BDF: {2})")]
|
||||||
DmaUnmap(#[source] vfio_ioctls::VfioError, PciBdf),
|
DmaUnmap(#[source] vfio_ioctls::VfioError, PathBuf, PciBdf),
|
||||||
#[error("Failed to enable INTx: {0}")]
|
#[error("Failed to enable INTx: {0}")]
|
||||||
EnableIntx(#[source] VfioError),
|
EnableIntx(#[source] VfioError),
|
||||||
#[error("Failed to enable MSI: {0}")]
|
#[error("Failed to enable MSI: {0}")]
|
||||||
@@ -1411,6 +1412,7 @@ pub struct VfioPciDevice {
|
|||||||
iommu_attached: bool,
|
iommu_attached: bool,
|
||||||
memory_slot_allocator: MemorySlotAllocator,
|
memory_slot_allocator: MemorySlotAllocator,
|
||||||
bdf: PciBdf,
|
bdf: PciBdf,
|
||||||
|
device_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VfioPciDevice {
|
impl VfioPciDevice {
|
||||||
@@ -1428,6 +1430,7 @@ impl VfioPciDevice {
|
|||||||
memory_slot_allocator: MemorySlotAllocator,
|
memory_slot_allocator: MemorySlotAllocator,
|
||||||
snapshot: Option<Snapshot>,
|
snapshot: Option<Snapshot>,
|
||||||
x_nv_gpudirect_clique: Option<u8>,
|
x_nv_gpudirect_clique: Option<u8>,
|
||||||
|
device_path: PathBuf,
|
||||||
) -> Result<Self, VfioPciError> {
|
) -> Result<Self, VfioPciError> {
|
||||||
let device = Arc::new(device);
|
let device = Arc::new(device);
|
||||||
device.reset();
|
device.reset();
|
||||||
@@ -1453,6 +1456,7 @@ impl VfioPciDevice {
|
|||||||
iommu_attached,
|
iommu_attached,
|
||||||
memory_slot_allocator,
|
memory_slot_allocator,
|
||||||
bdf,
|
bdf,
|
||||||
|
device_path: device_path.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vfio_pci_device)
|
Ok(vfio_pci_device)
|
||||||
@@ -1552,7 +1556,7 @@ impl VfioPciDevice {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `vm` - The VM object. It is used to set the VFIO MMIO regions
|
/// * `vm` - The VM object. It is used to set the VFIO MMIO regions
|
||||||
/// as user memory regions.
|
/// as user memory regions.
|
||||||
/// * `mem_slot` - The closure to return a memory slot.
|
/// * `mem_slot` - The closure to return a memory slot.
|
||||||
pub fn map_mmio_regions(&mut self) -> Result<(), VfioPciError> {
|
pub fn map_mmio_regions(&mut self) -> Result<(), VfioPciError> {
|
||||||
let fd = self.device.as_raw_fd();
|
let fd = self.device.as_raw_fd();
|
||||||
@@ -1658,7 +1662,9 @@ impl VfioPciDevice {
|
|||||||
user_memory_region.size,
|
user_memory_region.size,
|
||||||
user_memory_region.host_addr,
|
user_memory_region.host_addr,
|
||||||
)
|
)
|
||||||
.map_err(|e| VfioPciError::DmaMap(e, self.bdf))?;
|
.map_err(|e| {
|
||||||
|
VfioPciError::DmaMap(e, self.device_path.clone(), self.bdf)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1719,7 +1725,7 @@ impl VfioPciDevice {
|
|||||||
if !self.iommu_attached {
|
if !self.iommu_attached {
|
||||||
self.container
|
self.container
|
||||||
.vfio_dma_map(iova, size, user_addr)
|
.vfio_dma_map(iova, size, user_addr)
|
||||||
.map_err(|e| VfioPciError::DmaMap(e, self.bdf))?;
|
.map_err(|e| VfioPciError::DmaMap(e, self.device_path.clone(), self.bdf))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1729,7 +1735,7 @@ impl VfioPciDevice {
|
|||||||
if !self.iommu_attached {
|
if !self.iommu_attached {
|
||||||
self.container
|
self.container
|
||||||
.vfio_dma_unmap(iova, size)
|
.vfio_dma_unmap(iova, size)
|
||||||
.map_err(|e| VfioPciError::DmaUnmap(e, self.bdf))?;
|
.map_err(|e| VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.13", features = ["wrap_help"] }
|
clap = { version = "4.5.13", features = ["wrap_help"] }
|
||||||
dirs = "5.0.1"
|
dirs = "6.0.0"
|
||||||
serde = { version = "1.0.208", features = ["derive", "rc"] }
|
serde = { version = "1.0.208", features = ["derive", "rc"] }
|
||||||
serde_json = "1.0.120"
|
serde_json = "1.0.120"
|
||||||
test_infra = { path = "../test_infra" }
|
test_infra = { path = "../test_infra" }
|
||||||
|
|||||||
374
release-notes.md
374
release-notes.md
@@ -1,36 +1,42 @@
|
|||||||
|
- [v45.0](#v450)
|
||||||
|
- [Experimental `riscv64` Architecture Support](#experimental-riscv64-architecture-support)
|
||||||
|
- [Alphabetically Sorted CLI Options](#alphabetically-sorted-cli-options)
|
||||||
|
- [Improved Downtime from VM Live Migration](#improved-downtime-from-vm-live-migration)
|
||||||
|
- [Notable Bug Fixes](#notable-bug-fixes)
|
||||||
|
- [Contributors](#contributors)
|
||||||
- [v44.0](#v440)
|
- [v44.0](#v440)
|
||||||
- [Configurable `virtio-iommu` Address Width](#configurable-virtio-iommu-address-width)
|
- [Configurable `virtio-iommu` Address Width](#configurable-virtio-iommu-address-width)
|
||||||
- [Notable Performance Improvements](#notable-performance-improvements)
|
- [Notable Performance Improvements](#notable-performance-improvements)
|
||||||
- [New Fuzzers](#new-fuzzers)
|
- [New Fuzzers](#new-fuzzers)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes)
|
- [Notable Bug Fixes](#notable-bug-fixes-1)
|
||||||
- [Contributors](#contributors)
|
- [Contributors](#contributors-1)
|
||||||
- [v43.0](#v430)
|
- [v43.0](#v430)
|
||||||
- [Live Migration over TCP Connections](#live-migration-over-tcp-connections)
|
- [Live Migration over TCP Connections](#live-migration-over-tcp-connections)
|
||||||
- [Notable Performance Improvements](#notable-performance-improvements-1)
|
- [Notable Performance Improvements](#notable-performance-improvements-1)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-1)
|
- [Notable Bug Fixes](#notable-bug-fixes-2)
|
||||||
- [Contributors](#contributors-1)
|
- [Contributors](#contributors-2)
|
||||||
- [v42.0](#v420)
|
- [v42.0](#v420)
|
||||||
- [SVE/SVE2 Support on AArch64](#svesve2-support-on-aarch64)
|
- [SVE/SVE2 Support on AArch64](#svesve2-support-on-aarch64)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-2)
|
- [Notable Bug Fixes](#notable-bug-fixes-3)
|
||||||
- [Sponsorships](#sponsorships)
|
- [Sponsorships](#sponsorships)
|
||||||
- [Contributors](#contributors-2)
|
- [Contributors](#contributors-3)
|
||||||
- [v41.0](#v410)
|
- [v41.0](#v410)
|
||||||
- [Experimental "Pvmemcontrol" Support](#experimental-pvmemcontrol-support)
|
- [Experimental "Pvmemcontrol" Support](#experimental-pvmemcontrol-support)
|
||||||
- [Sandboxing With Landlock Support](#sandboxing-with-landlock-support)
|
- [Sandboxing With Landlock Support](#sandboxing-with-landlock-support)
|
||||||
- [Notable Performance Improvements](#notable-performance-improvements-2)
|
- [Notable Performance Improvements](#notable-performance-improvements-2)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-3)
|
|
||||||
- [Contributors](#contributors-3)
|
|
||||||
- [v40.0](#v400)
|
|
||||||
- [Support for Restoring File Descriptor Backed Network Devices](#support-for-restoring-file-descriptor-backed-network-devices)
|
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-4)
|
- [Notable Bug Fixes](#notable-bug-fixes-4)
|
||||||
- [Contributors](#contributors-4)
|
- [Contributors](#contributors-4)
|
||||||
|
- [v40.0](#v400)
|
||||||
|
- [Support for Restoring File Descriptor Backed Network Devices](#support-for-restoring-file-descriptor-backed-network-devices)
|
||||||
|
- [Notable Bug Fixes](#notable-bug-fixes-5)
|
||||||
|
- [Contributors](#contributors-5)
|
||||||
- [v39.0](#v390)
|
- [v39.0](#v390)
|
||||||
- [Variable Sizing of PCI Apertures for Segments](#variable-sizing-of-pci-apertures-for-segments)
|
- [Variable Sizing of PCI Apertures for Segments](#variable-sizing-of-pci-apertures-for-segments)
|
||||||
- [Direct Booting with bzImages](#direct-booting-with-bzimages)
|
- [Direct Booting with bzImages](#direct-booting-with-bzimages)
|
||||||
- [Support for NVIDIA GPUDirect P2P Support](#support-for-nvidia-gpudirect-p2p-support)
|
- [Support for NVIDIA GPUDirect P2P Support](#support-for-nvidia-gpudirect-p2p-support)
|
||||||
- [Guest NMI Injection Support](#guest-nmi-injection-support)
|
- [Guest NMI Injection Support](#guest-nmi-injection-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-5)
|
- [Notable Bug Fixes](#notable-bug-fixes-6)
|
||||||
- [Contributors](#contributors-5)
|
- [Contributors](#contributors-6)
|
||||||
- [v38.0](#v380)
|
- [v38.0](#v380)
|
||||||
- [Group Rate Limiter on Block Devices](#group-rate-limiter-on-block-devices)
|
- [Group Rate Limiter on Block Devices](#group-rate-limiter-on-block-devices)
|
||||||
- [CPU Pinning Support for Block Device Worker Thread](#cpu-pinning-support-for-block-device-worker-thread)
|
- [CPU Pinning Support for Block Device Worker Thread](#cpu-pinning-support-for-block-device-worker-thread)
|
||||||
@@ -38,16 +44,16 @@
|
|||||||
- [New 'debug-console' Device](#new-debug-console-device)
|
- [New 'debug-console' Device](#new-debug-console-device)
|
||||||
- [Improved VFIO Device Support](#improved-vfio-device-support)
|
- [Improved VFIO Device Support](#improved-vfio-device-support)
|
||||||
- [Extended CPU Affinity Support](#extended-cpu-affinity-support)
|
- [Extended CPU Affinity Support](#extended-cpu-affinity-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-6)
|
- [Notable Bug Fixes](#notable-bug-fixes-7)
|
||||||
- [Contributors](#contributors-6)
|
- [Contributors](#contributors-7)
|
||||||
- [v37.0](#v370)
|
- [v37.0](#v370)
|
||||||
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
|
- [Long Term Support (LTS) Release](#long-term-support-lts-release)
|
||||||
- [Multiple PCI segments Support for 32-bit VFIO devices](#multiple-pci-segments-support-for-32-bit-vfio-devices)
|
- [Multiple PCI segments Support for 32-bit VFIO devices](#multiple-pci-segments-support-for-32-bit-vfio-devices)
|
||||||
- [Configurable Named TAP Devices](#configurable-named-tap-devices)
|
- [Configurable Named TAP Devices](#configurable-named-tap-devices)
|
||||||
- [TTY Output from Both Serial Device and Virtio Console](#tty-output-from-both-serial-device-and-virtio-console)
|
- [TTY Output from Both Serial Device and Virtio Console](#tty-output-from-both-serial-device-and-virtio-console)
|
||||||
- [Faster VM Restoration from Snapshots](#faster-vm-restoration-from-snapshots)
|
- [Faster VM Restoration from Snapshots](#faster-vm-restoration-from-snapshots)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-7)
|
- [Notable Bug Fixes](#notable-bug-fixes-8)
|
||||||
- [Contributors](#contributors-7)
|
- [Contributors](#contributors-8)
|
||||||
- [v36.0](#v360)
|
- [v36.0](#v360)
|
||||||
- [Command Line Changes](#command-line-changes)
|
- [Command Line Changes](#command-line-changes)
|
||||||
- [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli)
|
- [Enabled Features Reported via API Endpoint and CLI](#enabled-features-reported-via-api-endpoint-and-cli)
|
||||||
@@ -56,31 +62,31 @@
|
|||||||
- [Unix Socket Backend for Serial Port](#unix-socket-backend-for-serial-port)
|
- [Unix Socket Backend for Serial Port](#unix-socket-backend-for-serial-port)
|
||||||
- [AIO Backend for Block Devices](#aio-backend-for-block-devices)
|
- [AIO Backend for Block Devices](#aio-backend-for-block-devices)
|
||||||
- [Documentation Improvements](#documentation-improvements)
|
- [Documentation Improvements](#documentation-improvements)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-8)
|
- [Notable Bug Fixes](#notable-bug-fixes-9)
|
||||||
- [Contributors](#contributors-8)
|
- [Contributors](#contributors-9)
|
||||||
- [v35.0](#v350)
|
- [v35.0](#v350)
|
||||||
- [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63)
|
- [`virtio-vsock` Support for Linux Guest Kernel v6.3+](#virtio-vsock-support-for-linux-guest-kernel-v63)
|
||||||
- [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block)
|
- [User Specified Serial Number for `virtio-block`](#user-specified-serial-number-for-virtio-block)
|
||||||
- [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state)
|
- [vCPU TSC Frequency Included in Migration State](#vcpu-tsc-frequency-included-in-migration-state)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-9)
|
- [Notable Bug Fixes](#notable-bug-fixes-10)
|
||||||
- [Contributors](#contributors-9)
|
- [Contributors](#contributors-10)
|
||||||
- [v34.0](#v340)
|
- [v34.0](#v340)
|
||||||
- [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support)
|
- [Paravirtualised Panic Device Support](#paravirtualised-panic-device-support)
|
||||||
- [Improvements to VM Core Dump](#improvements-to-vm-core-dump)
|
- [Improvements to VM Core Dump](#improvements-to-vm-core-dump)
|
||||||
- [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files)
|
- [QCOW2 Support for Backing Files](#qcow2-support-for-backing-files)
|
||||||
- [Minimum Host Kernel Bump](#minimum-host-kernel-bump)
|
- [Minimum Host Kernel Bump](#minimum-host-kernel-bump)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-10)
|
- [Notable Bug Fixes](#notable-bug-fixes-11)
|
||||||
- [Contributors](#contributors-10)
|
- [Contributors](#contributors-11)
|
||||||
- [v33.0](#v330)
|
- [v33.0](#v330)
|
||||||
- [D-Bus based API](#d-bus-based-api)
|
- [D-Bus based API](#d-bus-based-api)
|
||||||
- [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64)
|
- [Expose Host CPU Cache Details for AArch64](#expose-host-cpu-cache-details-for-aarch64)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-11)
|
- [Notable Bug Fixes](#notable-bug-fixes-12)
|
||||||
- [Contributors](#contributors-11)
|
- [Contributors](#contributors-12)
|
||||||
- [v32.0](#v320)
|
- [v32.0](#v320)
|
||||||
- [Increased PCI Segment Limit](#increased-pci-segment-limit)
|
- [Increased PCI Segment Limit](#increased-pci-segment-limit)
|
||||||
- [API Changes](#api-changes)
|
- [API Changes](#api-changes)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-12)
|
- [Notable Bug Fixes](#notable-bug-fixes-13)
|
||||||
- [Contributors](#contributors-12)
|
- [Contributors](#contributors-13)
|
||||||
- [v31.1](#v311)
|
- [v31.1](#v311)
|
||||||
- [v31.0](#v310)
|
- [v31.0](#v310)
|
||||||
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
|
- [Update to Latest `acpi_tables`](#update-to-latest-acpi_tables)
|
||||||
@@ -88,15 +94,15 @@
|
|||||||
- [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler)
|
- [Improvements on Console `SIGWINCH` Handler](#improvements-on-console-sigwinch-handler)
|
||||||
- [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile)
|
- [Remove Directory Support from `MemoryZoneConfig::file`](#remove-directory-support-from-memoryzoneconfigfile)
|
||||||
- [Documentation Improvements](#documentation-improvements-1)
|
- [Documentation Improvements](#documentation-improvements-1)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-13)
|
- [Notable Bug Fixes](#notable-bug-fixes-14)
|
||||||
- [Contributors](#contributors-13)
|
- [Contributors](#contributors-14)
|
||||||
- [v30.0](#v300)
|
- [v30.0](#v300)
|
||||||
- [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size)
|
- [Command Line Changes for Reduced Binary Size](#command-line-changes-for-reduced-binary-size)
|
||||||
- [Basic vfio-user Server Support](#basic-vfio-user-server-support)
|
- [Basic vfio-user Server Support](#basic-vfio-user-server-support)
|
||||||
- [Heap Profiling Support](#heap-profiling-support)
|
- [Heap Profiling Support](#heap-profiling-support)
|
||||||
- [Documentation Improvements](#documentation-improvements-2)
|
- [Documentation Improvements](#documentation-improvements-2)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-14)
|
- [Notable Bug Fixes](#notable-bug-fixes-15)
|
||||||
- [Contributors](#contributors-14)
|
- [Contributors](#contributors-15)
|
||||||
- [v28.2](#v282)
|
- [v28.2](#v282)
|
||||||
- [v29.0](#v290)
|
- [v29.0](#v290)
|
||||||
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
|
- [Release Binary Supports Both MSHV and KVM](#release-binary-supports-both-mshv-and-kvm)
|
||||||
@@ -106,10 +112,10 @@
|
|||||||
- [`AArch64` Documentation Integration](#aarch64-documentation-integration)
|
- [`AArch64` Documentation Integration](#aarch64-documentation-integration)
|
||||||
- [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement)
|
- [`virtio-block` Counters Enhancement](#virtio-block-counters-enhancement)
|
||||||
- [TCP Offload Control](#tcp-offload-control)
|
- [TCP Offload Control](#tcp-offload-control)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-15)
|
- [Notable Bug Fixes](#notable-bug-fixes-16)
|
||||||
- [Removals](#removals)
|
- [Removals](#removals)
|
||||||
- [Deprecations](#deprecations)
|
- [Deprecations](#deprecations)
|
||||||
- [Contributors](#contributors-15)
|
- [Contributors](#contributors-16)
|
||||||
- [v28.1](#v281)
|
- [v28.1](#v281)
|
||||||
- [v28.0](#v280)
|
- [v28.0](#v280)
|
||||||
- [Community Engagement (Reminder)](#community-engagement-reminder)
|
- [Community Engagement (Reminder)](#community-engagement-reminder)
|
||||||
@@ -117,9 +123,9 @@
|
|||||||
- [Virtualised TPM Support](#virtualised-tpm-support)
|
- [Virtualised TPM Support](#virtualised-tpm-support)
|
||||||
- [Transparent Huge Page Support](#transparent-huge-page-support)
|
- [Transparent Huge Page Support](#transparent-huge-page-support)
|
||||||
- [README Quick Start Improved](#readme-quick-start-improved)
|
- [README Quick Start Improved](#readme-quick-start-improved)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-16)
|
- [Notable Bug Fixes](#notable-bug-fixes-17)
|
||||||
- [Removals](#removals-1)
|
- [Removals](#removals-1)
|
||||||
- [Contributors](#contributors-16)
|
- [Contributors](#contributors-17)
|
||||||
- [v27.0](#v270)
|
- [v27.0](#v270)
|
||||||
- [Community Engagement](#community-engagement)
|
- [Community Engagement](#community-engagement)
|
||||||
- [Prebuilt Packages](#prebuilt-packages)
|
- [Prebuilt Packages](#prebuilt-packages)
|
||||||
@@ -128,41 +134,41 @@
|
|||||||
- [Simplified Build Feature Flags](#simplified-build-feature-flags)
|
- [Simplified Build Feature Flags](#simplified-build-feature-flags)
|
||||||
- [Asynchronous Kernel Loading](#asynchronous-kernel-loading)
|
- [Asynchronous Kernel Loading](#asynchronous-kernel-loading)
|
||||||
- [GDB Support for AArch64](#gdb-support-for-aarch64)
|
- [GDB Support for AArch64](#gdb-support-for-aarch64)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-17)
|
- [Notable Bug Fixes](#notable-bug-fixes-18)
|
||||||
- [Deprecations](#deprecations-1)
|
- [Deprecations](#deprecations-1)
|
||||||
- [Contributors](#contributors-17)
|
- [Contributors](#contributors-18)
|
||||||
- [v26.0](#v260)
|
- [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)
|
- [Unified Binary MSHV and KVM Support](#unified-binary-mshv-and-kvm-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-18)
|
- [Notable Bug Fixes](#notable-bug-fixes-19)
|
||||||
- [Deprecations](#deprecations-2)
|
- [Deprecations](#deprecations-2)
|
||||||
- [Removals](#removals-2)
|
- [Removals](#removals-2)
|
||||||
- [Contributors](#contributors-18)
|
- [Contributors](#contributors-19)
|
||||||
- [v25.0](#v250)
|
- [v25.0](#v250)
|
||||||
- [`ch-remote` Improvements](#ch-remote-improvements-1)
|
- [`ch-remote` Improvements](#ch-remote-improvements-1)
|
||||||
- [VM "Coredump" Support](#vm-coredump-support)
|
- [VM "Coredump" Support](#vm-coredump-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-19)
|
- [Notable Bug Fixes](#notable-bug-fixes-20)
|
||||||
- [Removals](#removals-3)
|
- [Removals](#removals-3)
|
||||||
- [Contributors](#contributors-19)
|
- [Contributors](#contributors-20)
|
||||||
- [v24.0](#v240)
|
- [v24.0](#v240)
|
||||||
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
|
- [Bypass Mode for `virtio-iommu`](#bypass-mode-for-virtio-iommu)
|
||||||
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
|
- [Ensure Identifiers Uniqueness](#ensure-identifiers-uniqueness)
|
||||||
- [Sparse Mmap support](#sparse-mmap-support)
|
- [Sparse Mmap support](#sparse-mmap-support)
|
||||||
- [Expose Platform Serial Number](#expose-platform-serial-number)
|
- [Expose Platform Serial Number](#expose-platform-serial-number)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-20)
|
- [Notable Bug Fixes](#notable-bug-fixes-21)
|
||||||
- [Notable Improvements](#notable-improvements)
|
- [Notable Improvements](#notable-improvements)
|
||||||
- [Deprecations](#deprecations-3)
|
- [Deprecations](#deprecations-3)
|
||||||
- [New on the Website](#new-on-the-website)
|
- [New on the Website](#new-on-the-website)
|
||||||
- [Contributors](#contributors-20)
|
- [Contributors](#contributors-21)
|
||||||
- [v23.1](#v231)
|
- [v23.1](#v231)
|
||||||
- [v23.0](#v230)
|
- [v23.0](#v230)
|
||||||
- [vDPA Support](#vdpa-support)
|
- [vDPA Support](#vdpa-support)
|
||||||
- [Updated OS Support list](#updated-os-support-list)
|
- [Updated OS Support list](#updated-os-support-list)
|
||||||
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
|
- [`AArch64` Memory Map Improvements](#aarch64-memory-map-improvements)
|
||||||
- [`AMX` Support](#amx-support)
|
- [`AMX` Support](#amx-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-21)
|
- [Notable Bug Fixes](#notable-bug-fixes-22)
|
||||||
- [Deprecations](#deprecations-4)
|
- [Deprecations](#deprecations-4)
|
||||||
- [Contributors](#contributors-21)
|
- [Contributors](#contributors-22)
|
||||||
- [v22.1](#v221)
|
- [v22.1](#v221)
|
||||||
- [v22.0](#v220)
|
- [v22.0](#v220)
|
||||||
- [GDB Debug Stub Support](#gdb-debug-stub-support)
|
- [GDB Debug Stub Support](#gdb-debug-stub-support)
|
||||||
@@ -173,13 +179,13 @@
|
|||||||
- [PMU Support for AArch64](#pmu-support-for-aarch64)
|
- [PMU Support for AArch64](#pmu-support-for-aarch64)
|
||||||
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
|
- [Documentation Under CC-BY-4.0 License](#documentation-under-cc-by-40-license)
|
||||||
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
|
- [Deprecation of "Classic" `virtiofsd`](#deprecation-of-classic-virtiofsd)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-22)
|
- [Notable Bug Fixes](#notable-bug-fixes-23)
|
||||||
- [Contributors](#contributors-22)
|
- [Contributors](#contributors-23)
|
||||||
- [v21.0](#v210)
|
- [v21.0](#v210)
|
||||||
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
|
- [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)
|
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
|
||||||
- [Notable Bug fixes](#notable-bug-fixes-23)
|
- [Notable Bug fixes](#notable-bug-fixes-24)
|
||||||
- [Contributors](#contributors-23)
|
- [Contributors](#contributors-24)
|
||||||
- [v20.2](#v202)
|
- [v20.2](#v202)
|
||||||
- [v20.1](#v201)
|
- [v20.1](#v201)
|
||||||
- [v20.0](#v200)
|
- [v20.0](#v200)
|
||||||
@@ -188,8 +194,8 @@
|
|||||||
- [Improved VFIO support](#improved-vfio-support)
|
- [Improved VFIO support](#improved-vfio-support)
|
||||||
- [Safer code](#safer-code)
|
- [Safer code](#safer-code)
|
||||||
- [Extended documentation](#extended-documentation)
|
- [Extended documentation](#extended-documentation)
|
||||||
- [Notable bug fixes](#notable-bug-fixes-24)
|
- [Notable bug fixes](#notable-bug-fixes-25)
|
||||||
- [Contributors](#contributors-24)
|
- [Contributors](#contributors-25)
|
||||||
- [v19.0](#v190)
|
- [v19.0](#v190)
|
||||||
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
|
- [Improved PTY handling for serial and `virtio-console`](#improved-pty-handling-for-serial-and-virtio-console)
|
||||||
- [PCI boot time optimisations](#pci-boot-time-optimisations)
|
- [PCI boot time optimisations](#pci-boot-time-optimisations)
|
||||||
@@ -197,8 +203,8 @@
|
|||||||
- [Live migration enhancements](#live-migration-enhancements)
|
- [Live migration enhancements](#live-migration-enhancements)
|
||||||
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
|
- [`virtio-mem` support with `vfio-user`](#virtio-mem-support-with-vfio-user)
|
||||||
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
|
- [AArch64 for `virtio-iommu`](#aarch64-for-virtio-iommu)
|
||||||
- [Notable bug fixes](#notable-bug-fixes-25)
|
- [Notable bug fixes](#notable-bug-fixes-26)
|
||||||
- [Contributors](#contributors-25)
|
- [Contributors](#contributors-26)
|
||||||
- [v18.0](#v180)
|
- [v18.0](#v180)
|
||||||
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
|
- [Experimental User Device (`vfio-user`) support](#experimental-user-device-vfio-user-support)
|
||||||
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
|
- [Migration support for `vhost-user` devices](#migration-support-for-vhost-user-devices)
|
||||||
@@ -208,23 +214,23 @@
|
|||||||
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
|
- [Live migration on MSHV hypervisor](#live-migration-on-mshv-hypervisor)
|
||||||
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
|
- [AArch64 CPU topology support](#aarch64-cpu-topology-support)
|
||||||
- [Power button support on AArch64](#power-button-support-on-aarch64)
|
- [Power button support on AArch64](#power-button-support-on-aarch64)
|
||||||
- [Notable bug fixes](#notable-bug-fixes-26)
|
- [Notable bug fixes](#notable-bug-fixes-27)
|
||||||
- [Contributors](#contributors-26)
|
- [Contributors](#contributors-27)
|
||||||
- [v17.0](#v170)
|
- [v17.0](#v170)
|
||||||
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
|
- [ARM64 NUMA support using ACPI](#arm64-numa-support-using-acpi)
|
||||||
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
|
- [`Seccomp` support for MSHV backend](#seccomp-support-for-mshv-backend)
|
||||||
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
|
- [Hotplug of `macvtap` devices](#hotplug-of-macvtap-devices)
|
||||||
- [Improved SGX support](#improved-sgx-support)
|
- [Improved SGX support](#improved-sgx-support)
|
||||||
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
|
- [Inflight tracking for `vhost-user` devices](#inflight-tracking-for-vhost-user-devices)
|
||||||
- [Notable bug fixes](#notable-bug-fixes-27)
|
- [Notable bug fixes](#notable-bug-fixes-28)
|
||||||
- [Contributors](#contributors-27)
|
- [Contributors](#contributors-28)
|
||||||
- [v16.0](#v160)
|
- [v16.0](#v160)
|
||||||
- [Improved live migration support](#improved-live-migration-support)
|
- [Improved live migration support](#improved-live-migration-support)
|
||||||
- [Improved `vhost-user` support](#improved-vhost-user-support)
|
- [Improved `vhost-user` support](#improved-vhost-user-support)
|
||||||
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
|
- [ARM64 ACPI and UEFI support](#arm64-acpi-and-uefi-support)
|
||||||
- [Notable bug fixes](#notable-bug-fixes-28)
|
- [Notable bug fixes](#notable-bug-fixes-29)
|
||||||
- [Removed functionality](#removed-functionality)
|
- [Removed functionality](#removed-functionality)
|
||||||
- [Contributors](#contributors-28)
|
- [Contributors](#contributors-29)
|
||||||
- [v15.0](#v150)
|
- [v15.0](#v150)
|
||||||
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
|
- [Version numbering and stability guarantees](#version-numbering-and-stability-guarantees)
|
||||||
- [Network device rate limiting](#network-device-rate-limiting)
|
- [Network device rate limiting](#network-device-rate-limiting)
|
||||||
@@ -232,7 +238,7 @@
|
|||||||
- [`--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)
|
- [Bug fixes](#bug-fixes)
|
||||||
- [Deprecations](#deprecations-5)
|
- [Deprecations](#deprecations-5)
|
||||||
- [Contributors](#contributors-29)
|
- [Contributors](#contributors-30)
|
||||||
- [v0.14.1](#v0141)
|
- [v0.14.1](#v0141)
|
||||||
- [v0.14.0](#v0140)
|
- [v0.14.0](#v0140)
|
||||||
- [Structured event monitoring](#structured-event-monitoring)
|
- [Structured event monitoring](#structured-event-monitoring)
|
||||||
@@ -242,7 +248,7 @@
|
|||||||
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
|
- [PTY control for serial and `virtio-console`](#pty-control-for-serial-and-virtio-console)
|
||||||
- [Block device rate limiting](#block-device-rate-limiting)
|
- [Block device rate limiting](#block-device-rate-limiting)
|
||||||
- [Deprecations](#deprecations-6)
|
- [Deprecations](#deprecations-6)
|
||||||
- [Contributors](#contributors-30)
|
- [Contributors](#contributors-31)
|
||||||
- [v0.13.0](#v0130)
|
- [v0.13.0](#v0130)
|
||||||
- [Wider VFIO device support](#wider-vfio-device-support)
|
- [Wider VFIO device support](#wider-vfio-device-support)
|
||||||
- [Improved huge page support](#improved-huge-page-support)
|
- [Improved huge page support](#improved-huge-page-support)
|
||||||
@@ -250,13 +256,13 @@
|
|||||||
- [VHD disk image support](#vhd-disk-image-support)
|
- [VHD disk image support](#vhd-disk-image-support)
|
||||||
- [Improved Virtio device threading](#improved-virtio-device-threading)
|
- [Improved Virtio device threading](#improved-virtio-device-threading)
|
||||||
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
|
- [Clean shutdown support via synthetic power button](#clean-shutdown-support-via-synthetic-power-button)
|
||||||
- [Contributors](#contributors-31)
|
- [Contributors](#contributors-32)
|
||||||
- [v0.12.0](#v0120)
|
- [v0.12.0](#v0120)
|
||||||
- [ARM64 enhancements](#arm64-enhancements)
|
- [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)
|
- [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)
|
- [Migration of `vhost-user-fs` backend](#migration-of-vhost-user-fs-backend)
|
||||||
- [Enhanced "info" API](#enhanced-info-api)
|
- [Enhanced "info" API](#enhanced-info-api)
|
||||||
- [Contributors](#contributors-32)
|
- [Contributors](#contributors-33)
|
||||||
- [v0.11.0](#v0110)
|
- [v0.11.0](#v0110)
|
||||||
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
|
- [`io_uring` support by default for `virtio-block`](#io_uring-support-by-default-for-virtio-block)
|
||||||
- [Windows Guest Support](#windows-guest-support)
|
- [Windows Guest Support](#windows-guest-support)
|
||||||
@@ -268,15 +274,15 @@
|
|||||||
- [Default Log Level Changed](#default-log-level-changed)
|
- [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)
|
- [Experimental `virtio-watchdog` Support](#experimental-virtio-watchdog-support)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-29)
|
- [Notable Bug Fixes](#notable-bug-fixes-30)
|
||||||
- [Contributors](#contributors-33)
|
- [Contributors](#contributors-34)
|
||||||
- [v0.10.0](#v0100)
|
- [v0.10.0](#v0100)
|
||||||
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
|
- [`virtio-block` Support for Multiple Descriptors](#virtio-block-support-for-multiple-descriptors)
|
||||||
- [Memory Zones](#memory-zones)
|
- [Memory Zones](#memory-zones)
|
||||||
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
|
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements)
|
||||||
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
|
- [Preliminary KVM HyperV Emulation Control](#preliminary-kvm-hyperv-emulation-control)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-30)
|
- [Notable Bug Fixes](#notable-bug-fixes-31)
|
||||||
- [Contributors](#contributors-34)
|
- [Contributors](#contributors-35)
|
||||||
- [v0.9.0](#v090)
|
- [v0.9.0](#v090)
|
||||||
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
|
- [`io_uring` Based Block Device Support](#io_uring-based-block-device-support)
|
||||||
- [Block and Network Device Statistics](#block-and-network-device-statistics)
|
- [Block and Network Device Statistics](#block-and-network-device-statistics)
|
||||||
@@ -289,17 +295,17 @@
|
|||||||
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
|
- [Enhancements to ARM64 Support](#enhancements-to-arm64-support)
|
||||||
- [Intel SGX Support](#intel-sgx-support)
|
- [Intel SGX Support](#intel-sgx-support)
|
||||||
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
|
- [`Seccomp` Sandbox Improvements](#seccomp-sandbox-improvements-1)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-31)
|
- [Notable Bug Fixes](#notable-bug-fixes-32)
|
||||||
- [Contributors](#contributors-35)
|
- [Contributors](#contributors-36)
|
||||||
- [v0.8.0](#v080)
|
- [v0.8.0](#v080)
|
||||||
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
|
- [Experimental Snapshot and Restore Support](#experimental-snapshot-and-restore-support)
|
||||||
- [Experimental ARM64 Support](#experimental-arm64-support)
|
- [Experimental ARM64 Support](#experimental-arm64-support)
|
||||||
- [Support for Using 5-level Paging in Guests](#support-for-using-5-level-paging-in-guests)
|
- [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)
|
- [Virtio Device Interrupt Suppression for Network Devices](#virtio-device-interrupt-suppression-for-network-devices)
|
||||||
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
|
- [`vhost_user_fs` Improvements](#vhost_user_fs-improvements)
|
||||||
- [Notable Bug Fixes](#notable-bug-fixes-32)
|
- [Notable Bug Fixes](#notable-bug-fixes-33)
|
||||||
- [Command Line and API Changes](#command-line-and-api-changes)
|
- [Command Line and API Changes](#command-line-and-api-changes)
|
||||||
- [Contributors](#contributors-36)
|
- [Contributors](#contributors-37)
|
||||||
- [v0.7.0](#v070)
|
- [v0.7.0](#v070)
|
||||||
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
|
- [Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug](#block-network-persistent-memory-pmem-virtiofs-and-vsock-hotplug)
|
||||||
- [Alternative `libc` Support](#alternative-libc-support)
|
- [Alternative `libc` Support](#alternative-libc-support)
|
||||||
@@ -309,14 +315,14 @@
|
|||||||
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
|
- [`Seccomp` Sandboxing](#seccomp-sandboxing)
|
||||||
- [Updated Distribution Support](#updated-distribution-support)
|
- [Updated Distribution Support](#updated-distribution-support)
|
||||||
- [Command Line and API Changes](#command-line-and-api-changes-1)
|
- [Command Line and API Changes](#command-line-and-api-changes-1)
|
||||||
- [Contributors](#contributors-37)
|
- [Contributors](#contributors-38)
|
||||||
- [v0.6.0](#v060)
|
- [v0.6.0](#v060)
|
||||||
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
|
- [Directly Assigned Devices Hotplug](#directly-assigned-devices-hotplug)
|
||||||
- [Shared Filesystem Improvements](#shared-filesystem-improvements)
|
- [Shared Filesystem Improvements](#shared-filesystem-improvements)
|
||||||
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
|
- [Block and Networking IO Self Offloading](#block-and-networking-io-self-offloading)
|
||||||
- [Command Line Interface](#command-line-interface)
|
- [Command Line Interface](#command-line-interface)
|
||||||
- [PVH Boot](#pvh-boot)
|
- [PVH Boot](#pvh-boot)
|
||||||
- [Contributors](#contributors-38)
|
- [Contributors](#contributors-39)
|
||||||
- [v0.5.1](#v051)
|
- [v0.5.1](#v051)
|
||||||
- [v0.5.0](#v050)
|
- [v0.5.0](#v050)
|
||||||
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
|
- [Virtual Machine Dynamic Resizing](#virtual-machine-dynamic-resizing)
|
||||||
@@ -324,7 +330,7 @@
|
|||||||
- [New Interrupt Management Framework](#new-interrupt-management-framework)
|
- [New Interrupt Management Framework](#new-interrupt-management-framework)
|
||||||
- [Development Tools](#development-tools)
|
- [Development Tools](#development-tools)
|
||||||
- [Kata Containers Integration](#kata-containers-integration)
|
- [Kata Containers Integration](#kata-containers-integration)
|
||||||
- [Contributors](#contributors-39)
|
- [Contributors](#contributors-40)
|
||||||
- [v0.4.0](#v040)
|
- [v0.4.0](#v040)
|
||||||
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
|
- [Dynamic virtual CPUs addition](#dynamic-virtual-cpus-addition)
|
||||||
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
|
- [Programmatic firmware tables generation](#programmatic-firmware-tables-generation)
|
||||||
@@ -333,7 +339,7 @@
|
|||||||
- [Userspace IOAPIC by default](#userspace-ioapic-by-default)
|
- [Userspace IOAPIC by default](#userspace-ioapic-by-default)
|
||||||
- [PCI BAR reprogramming](#pci-bar-reprogramming)
|
- [PCI BAR reprogramming](#pci-bar-reprogramming)
|
||||||
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
|
- [New `cloud-hypervisor` organization](#new-cloud-hypervisor-organization)
|
||||||
- [Contributors](#contributors-40)
|
- [Contributors](#contributors-41)
|
||||||
- [v0.3.0](#v030)
|
- [v0.3.0](#v030)
|
||||||
- [Block device offloading](#block-device-offloading)
|
- [Block device offloading](#block-device-offloading)
|
||||||
- [Network device backend](#network-device-backend)
|
- [Network device backend](#network-device-backend)
|
||||||
@@ -360,11 +366,53 @@
|
|||||||
- [Unit testing](#unit-testing)
|
- [Unit testing](#unit-testing)
|
||||||
- [Integration tests parallelization](#integration-tests-parallelization)
|
- [Integration tests parallelization](#integration-tests-parallelization)
|
||||||
|
|
||||||
|
# v45.0
|
||||||
|
|
||||||
|
This release has been tracked in [v45.0
|
||||||
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v44.0%22)
|
||||||
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
|
### Experimental `riscv64` Architecture Support
|
||||||
|
|
||||||
|
Cloud Hypervisor now has experimental `riscv64` architecture
|
||||||
|
support. Details can be found from the [riscv
|
||||||
|
documentation](docs/riscv.md).
|
||||||
|
|
||||||
|
### Alphabetically Sorted CLI Options
|
||||||
|
|
||||||
|
To improve the readability of CLI options, the output of the `--help`
|
||||||
|
now is alphabetically sorted. (#6988)
|
||||||
|
|
||||||
|
### Improved Downtime of VM Live Migration
|
||||||
|
|
||||||
|
The downtime of VM live migration is reduced via delaying some of the
|
||||||
|
tearing down process of the source VM after the destination VM is up and
|
||||||
|
running. (#6987)
|
||||||
|
|
||||||
|
### Notable Bug Fixes
|
||||||
|
|
||||||
|
* Fix seccomp filters related to http-api thread (#6967)
|
||||||
|
* Handle cross-page access in the emulator for mshv (#6968)
|
||||||
|
|
||||||
|
### Contributors
|
||||||
|
|
||||||
|
Many thanks to everyone who has contributed to our release:
|
||||||
|
|
||||||
|
* Anatol Belski <anbelski@linux.microsoft.com>
|
||||||
|
* Andrew Consroe <aconz2@gmail.com>
|
||||||
|
* Bo Chen <bchen@crusoe.ai>
|
||||||
|
* Jinank Jain <jinankjain@microsoft.com>
|
||||||
|
* Jinrong Liang <cloudliang@tencent.com>
|
||||||
|
* Philipp Schuster <philipp.schuster@cyberus-technology.de>
|
||||||
|
* Ruoqing He <heruoqing@iscas.ac.cn>
|
||||||
|
* Stefan Kober <stefan.kober@cyberus-technology.de>
|
||||||
|
* Wei Liu <liuwe@microsoft.com>
|
||||||
|
|
||||||
# v44.0
|
# v44.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v44.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v44.0%22)
|
||||||
v44.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Configurable `virtio-iommu` Address Width
|
### Configurable `virtio-iommu` Address Width
|
||||||
|
|
||||||
@@ -405,9 +453,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v43.0
|
# v43.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v43.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v43.0%22)
|
||||||
v43.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Live Migration over TCP Connections
|
### Live Migration over TCP Connections
|
||||||
|
|
||||||
@@ -447,9 +495,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v42.0
|
# v42.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v42.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v42.0%22)
|
||||||
v42.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### SVE/SVE2 Support on AArch64
|
### SVE/SVE2 Support on AArch64
|
||||||
|
|
||||||
@@ -496,9 +544,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v41.0
|
# v41.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v41.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v41.0%22)
|
||||||
v41.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Experimental "Pvmemcontrol" Support
|
### Experimental "Pvmemcontrol" Support
|
||||||
|
|
||||||
@@ -555,9 +603,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v40.0
|
# v40.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v40.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v40.0%22)
|
||||||
v40.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Support for Restoring File Descriptor Backed Network Devices
|
### Support for Restoring File Descriptor Backed Network Devices
|
||||||
|
|
||||||
@@ -606,9 +654,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v39.0
|
# v39.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v39.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v39.0%22)
|
||||||
v39.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Variable Sizing of PCI Apertures for Segments
|
### Variable Sizing of PCI Apertures for Segments
|
||||||
|
|
||||||
@@ -677,9 +725,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v38.0
|
# v38.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v38.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v38.0%22)
|
||||||
v38.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Group Rate Limiter on Block Devices
|
### Group Rate Limiter on Block Devices
|
||||||
|
|
||||||
@@ -747,9 +795,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v37.0
|
# v37.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v37.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v37.0%22)
|
||||||
v37.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Long Term Support (LTS) Release
|
### Long Term Support (LTS) Release
|
||||||
|
|
||||||
@@ -809,9 +857,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v36.0
|
# v36.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v36.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v36.0%22)
|
||||||
v36.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Command Line Changes
|
### Command Line Changes
|
||||||
|
|
||||||
@@ -884,9 +932,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v35.0
|
# v35.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v35.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v35.0%22)
|
||||||
v35.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### `virtio-vsock` Support for Linux Guest Kernel v6.3+
|
### `virtio-vsock` Support for Linux Guest Kernel v6.3+
|
||||||
|
|
||||||
@@ -937,9 +985,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v34.0
|
# v34.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v34.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v34.0%22)
|
||||||
v34.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Paravirtualised Panic Device Support
|
### Paravirtualised Panic Device Support
|
||||||
|
|
||||||
@@ -997,9 +1045,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v33.0
|
# v33.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v33.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v33.0%22)
|
||||||
v33.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### D-Bus based API
|
### D-Bus based API
|
||||||
|
|
||||||
@@ -1041,9 +1089,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v32.0
|
# v32.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v32.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v32.0%22)
|
||||||
v32.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Increased PCI Segment Limit
|
### Increased PCI Segment Limit
|
||||||
|
|
||||||
@@ -1094,9 +1142,9 @@ This is a bug fix release. The following issues have been addressed:
|
|||||||
|
|
||||||
# v31.0
|
# v31.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v31.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v31.0%22)
|
||||||
v31.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Update to Latest `acpi_tables`
|
### Update to Latest `acpi_tables`
|
||||||
|
|
||||||
@@ -1160,9 +1208,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v30.0
|
# v30.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v30.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v30.0%22)
|
||||||
v30.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Command Line Changes for Reduced Binary Size
|
### Command Line Changes for Reduced Binary Size
|
||||||
|
|
||||||
@@ -1190,7 +1238,7 @@ heap profiling using `dhat` gated by the `dhat-heap` feature.
|
|||||||
|
|
||||||
The documentation on Intel TDX is expanded with details of the building
|
The documentation on Intel TDX is expanded with details of the building
|
||||||
and using [TD-Shim](https://github.com/confidential-containers/td-shim),
|
and using [TD-Shim](https://github.com/confidential-containers/td-shim),
|
||||||
references to [TDX Tools](https://github.com/intel/tdx-tools), and
|
references to [TDX Linux](https://github.com/intel/tdx-linux), and
|
||||||
version information of guest/host kernel/TDVF/TDShim being tested. Also,
|
version information of guest/host kernel/TDVF/TDShim being tested. Also,
|
||||||
a new 'heap profiling' documentation is added with improvements on the
|
a new 'heap profiling' documentation is added with improvements on the
|
||||||
existing 'profiling' documentation.
|
existing 'profiling' documentation.
|
||||||
@@ -1233,9 +1281,9 @@ This is a bug fix release. The following issues have been addressed:
|
|||||||
|
|
||||||
# v29.0
|
# v29.0
|
||||||
|
|
||||||
This release has been tracked in our [roadmap
|
This release has been tracked in [v29.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v29.0%22)
|
||||||
v29.0. The following user visible changes have been made:
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Release Binary Supports Both MSHV and KVM
|
### Release Binary Supports Both MSHV and KVM
|
||||||
|
|
||||||
@@ -1330,9 +1378,9 @@ addresses an infinite loop issue ([details](https://github.com/rust-vmm/linux-lo
|
|||||||
|
|
||||||
# v28.0
|
# v28.0
|
||||||
|
|
||||||
This release has been tracked in our new [roadmap
|
This release has been tracked in [v28.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v28.0%22)
|
||||||
v28.0.
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Community Engagement (Reminder)
|
### Community Engagement (Reminder)
|
||||||
|
|
||||||
@@ -1406,9 +1454,9 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v27.0
|
# v27.0
|
||||||
|
|
||||||
This release has been tracked in our new [roadmap
|
This release has been tracked in [v27.0
|
||||||
project](https://github.com/orgs/cloud-hypervisor/projects/6) as iteration
|
group](https://github.com/orgs/cloud-hypervisor/projects/6/views/4?filterQuery=release%3A%22Release+v27.0%22)
|
||||||
v27.0.
|
of our [roadmap project](https://github.com/orgs/cloud-hypervisor/projects/6/).
|
||||||
|
|
||||||
### Community Engagement
|
### Community Engagement
|
||||||
|
|
||||||
@@ -1497,9 +1545,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v26.0
|
# v26.0
|
||||||
|
|
||||||
This release has been tracked through the [v26.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/30).
|
|
||||||
|
|
||||||
### SMBIOS Improvements via `--platform`
|
### SMBIOS Improvements via `--platform`
|
||||||
|
|
||||||
`--platform` and the appropriate API structure has gained support for supplying
|
`--platform` and the appropriate API structure has gained support for supplying
|
||||||
@@ -1563,9 +1608,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v25.0
|
# v25.0
|
||||||
|
|
||||||
This release has been tracked through the [v25.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/29).
|
|
||||||
|
|
||||||
### `ch-remote` Improvements
|
### `ch-remote` Improvements
|
||||||
|
|
||||||
The `ch-remote` command has gained support for creating the VM from a JSON
|
The `ch-remote` command has gained support for creating the VM from a JSON
|
||||||
@@ -1609,9 +1651,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v24.0
|
# v24.0
|
||||||
|
|
||||||
This release has been tracked through the [v24.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/28).
|
|
||||||
|
|
||||||
### Bypass Mode for `virtio-iommu`
|
### Bypass Mode for `virtio-iommu`
|
||||||
|
|
||||||
`virtio-iommu` specification describes how a device can be attached by default
|
`virtio-iommu` specification describes how a device can be attached by default
|
||||||
@@ -1697,9 +1736,6 @@ This is a bug fix release. The following issues have been addressed:
|
|||||||
|
|
||||||
# v23.0
|
# v23.0
|
||||||
|
|
||||||
This release has been tracked through the [v23.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/27).
|
|
||||||
|
|
||||||
### vDPA Support
|
### vDPA Support
|
||||||
|
|
||||||
A vDPA device has a datapath that complies with the virtio specification but
|
A vDPA device has a datapath that complies with the virtio specification but
|
||||||
@@ -1768,9 +1804,6 @@ This is a bug fix release. The following issues have been addressed:
|
|||||||
|
|
||||||
# v22.0
|
# v22.0
|
||||||
|
|
||||||
This release has been tracked through the [v22.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/25).
|
|
||||||
|
|
||||||
### GDB Debug Stub Support
|
### GDB Debug Stub Support
|
||||||
|
|
||||||
Cloud Hypervisor can now be used as debug target with GDB. This is controlled
|
Cloud Hypervisor can now be used as debug target with GDB. This is controlled
|
||||||
@@ -1851,9 +1884,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v21.0
|
# v21.0
|
||||||
|
|
||||||
This release has been tracked through the [v21.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/24).
|
|
||||||
|
|
||||||
### Efficient Local Live Migration (for Live Upgrade)
|
### Efficient Local Live Migration (for Live Upgrade)
|
||||||
|
|
||||||
In order to support fast live upgrade of the VMM an optimised path has been
|
In order to support fast live upgrade of the VMM an optimised path has been
|
||||||
@@ -1916,9 +1946,6 @@ This is a bug fix release. The following issues have been addressed:
|
|||||||
|
|
||||||
# v20.0
|
# v20.0
|
||||||
|
|
||||||
This release has been tracked through the [v20.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/23).
|
|
||||||
|
|
||||||
### Multiple PCI segments support
|
### Multiple PCI segments support
|
||||||
|
|
||||||
Cloud Hypervisor is no longer limited to 31 PCI devices. For both `x86_64` and
|
Cloud Hypervisor is no longer limited to 31 PCI devices. For both `x86_64` and
|
||||||
@@ -1974,9 +2001,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v19.0
|
# v19.0
|
||||||
|
|
||||||
This release has been tracked through the [v19.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/22).
|
|
||||||
|
|
||||||
### Improved PTY handling for serial and `virtio-console`
|
### Improved PTY handling for serial and `virtio-console`
|
||||||
|
|
||||||
The PTY support for serial has been enhanced with improved buffering when the
|
The PTY support for serial has been enhanced with improved buffering when the
|
||||||
@@ -2037,9 +2061,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v18.0
|
# v18.0
|
||||||
|
|
||||||
This release has been tracked through the [v18.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/21).
|
|
||||||
|
|
||||||
### Experimental User Device (`vfio-user`) support
|
### Experimental User Device (`vfio-user`) support
|
||||||
|
|
||||||
Experimental support for running PCI devices in userspace via `vfio-user`
|
Experimental support for running PCI devices in userspace via `vfio-user`
|
||||||
@@ -2110,9 +2131,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v17.0
|
# v17.0
|
||||||
|
|
||||||
This release has been tracked through the [v17.0
|
|
||||||
project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/20).
|
|
||||||
|
|
||||||
### ARM64 NUMA support using ACPI
|
### ARM64 NUMA support using ACPI
|
||||||
|
|
||||||
The support for ACPI on ARM64 has been enhanced to include support for
|
The support for ACPI on ARM64 has been enhanced to include support for
|
||||||
@@ -2168,8 +2186,6 @@ Many thanks to everyone who has contributed to our release:
|
|||||||
|
|
||||||
# v16.0
|
# v16.0
|
||||||
|
|
||||||
This release has been tracked through the [v16.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/19).
|
|
||||||
|
|
||||||
### Improved live migration support
|
### Improved live migration support
|
||||||
|
|
||||||
The live migration support inside Cloud Hypervisor has been improved with the addition of the tracking of dirty pages written by the VMM to complement the tracking of dirty pages made by the guest itself. Further the internal state of the VMM now is versioned which allows the safe migration of VMs from one version of the VMM to a newer one. However further testing is required so this should be done with care. See the [live migration documentation](docs/live_migration.md) for more details.
|
The live migration support inside Cloud Hypervisor has been improved with the addition of the tracking of dirty pages written by the VMM to complement the tracking of dirty pages made by the guest itself. Further the internal state of the VMM now is versioned which allows the safe migration of VMs from one version of the VMM to a newer one. However further testing is required so this should be done with care. See the [live migration documentation](docs/live_migration.md) for more details.
|
||||||
@@ -2217,8 +2233,6 @@ Many thanks to everyone who has contributed to our release including some new fa
|
|||||||
|
|
||||||
# v15.0
|
# v15.0
|
||||||
|
|
||||||
This release has been tracked through the [v15.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/18).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version v15.0 include:
|
Highlights for `cloud-hypervisor` version v15.0 include:
|
||||||
|
|
||||||
### Version numbering and stability guarantees
|
### Version numbering and stability guarantees
|
||||||
@@ -2308,8 +2322,6 @@ in this release:
|
|||||||
|
|
||||||
# v0.14.0
|
# v0.14.0
|
||||||
|
|
||||||
This release has been tracked through the [0.14.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/17).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.14.0 include:
|
Highlights for `cloud-hypervisor` version 0.14.0 include:
|
||||||
|
|
||||||
### Structured event monitoring
|
### Structured event monitoring
|
||||||
@@ -2380,8 +2392,6 @@ some new faces.
|
|||||||
|
|
||||||
# v0.13.0
|
# v0.13.0
|
||||||
|
|
||||||
This release has been tracked through the [0.13.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/16).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.13.0 include:
|
Highlights for `cloud-hypervisor` version 0.13.0 include:
|
||||||
|
|
||||||
### Wider VFIO device support
|
### Wider VFIO device support
|
||||||
@@ -2442,8 +2452,6 @@ some new faces.
|
|||||||
|
|
||||||
# v0.12.0
|
# v0.12.0
|
||||||
|
|
||||||
This release has been tracked through the [0.12.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/15).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.12.0 include:
|
Highlights for `cloud-hypervisor` version 0.12.0 include:
|
||||||
|
|
||||||
### ARM64 enhancements
|
### ARM64 enhancements
|
||||||
@@ -2483,8 +2491,6 @@ Many thanks to everyone who has contributed to our 0.12.0 release:
|
|||||||
|
|
||||||
# v0.11.0
|
# v0.11.0
|
||||||
|
|
||||||
This release has been tracked through the [0.11.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/14).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.11.0 include:
|
Highlights for `cloud-hypervisor` version 0.11.0 include:
|
||||||
|
|
||||||
### `io_uring` support by default for `virtio-block`
|
### `io_uring` support by default for `virtio-block`
|
||||||
@@ -2533,7 +2539,7 @@ resources.
|
|||||||
|
|
||||||
The default logging level was changed to include warnings which should make it
|
The default logging level was changed to include warnings which should make it
|
||||||
easier to see potential issues. New [logging
|
easier to see potential issues. New [logging
|
||||||
documentation](docs/logging) was also added.
|
documentation](docs/logging.md) was also added.
|
||||||
|
|
||||||
### New `--balloon` Parameter Added
|
### New `--balloon` Parameter Added
|
||||||
|
|
||||||
@@ -2585,8 +2591,6 @@ Many thanks to everyone who has contributed to our 0.11.0 release including some
|
|||||||
|
|
||||||
# v0.10.0
|
# v0.10.0
|
||||||
|
|
||||||
This release has been tracked through the [0.10.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/13).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.10.0 include:
|
Highlights for `cloud-hypervisor` version 0.10.0 include:
|
||||||
|
|
||||||
### `virtio-block` Support for Multiple Descriptors
|
### `virtio-block` Support for Multiple Descriptors
|
||||||
@@ -2631,8 +2635,6 @@ Many thanks to everyone who has contributed to our 0.10.0 release including some
|
|||||||
|
|
||||||
# v0.9.0
|
# v0.9.0
|
||||||
|
|
||||||
This release has been tracked through the [0.9.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/12).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.9.0 include:
|
Highlights for `cloud-hypervisor` version 0.9.0 include:
|
||||||
|
|
||||||
### `io_uring` Based Block Device Support
|
### `io_uring` Based Block Device Support
|
||||||
@@ -2714,8 +2716,6 @@ Many thanks to everyone who has contributed to our 0.9.0 release including some
|
|||||||
|
|
||||||
# v0.8.0
|
# v0.8.0
|
||||||
|
|
||||||
This release has been tracked through the [0.8.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/10).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.8.0 include:
|
Highlights for `cloud-hypervisor` version 0.8.0 include:
|
||||||
|
|
||||||
### Experimental Snapshot and Restore Support
|
### Experimental Snapshot and Restore Support
|
||||||
@@ -2735,7 +2735,7 @@ a VM using passthrough (VFIO) devices. Issues with SMP have also been observed
|
|||||||
|
|
||||||
Included in this release is experimental support for running on ARM64.
|
Included in this release is experimental support for running on ARM64.
|
||||||
Currently only `virtio-mmio` devices and a serial port are supported. Full
|
Currently only `virtio-mmio` devices and a serial port are supported. Full
|
||||||
details can be found in the [ARM64 documentation](docs/arm64.md).
|
details can be found in the [ARM64 documentation](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/8ab15b9a984a448006f97b1211498c1bb583de3b/docs/arm64.md).
|
||||||
|
|
||||||
### Support for Using 5-level Paging in Guests
|
### Support for Using 5-level Paging in Guests
|
||||||
|
|
||||||
@@ -2804,8 +2804,6 @@ Many thanks to everyone who has contributed to our 0.8.0 release including some
|
|||||||
|
|
||||||
# v0.7.0
|
# v0.7.0
|
||||||
|
|
||||||
This release has been tracked through the [0.7.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/7).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.7.0 include:
|
Highlights for `cloud-hypervisor` version 0.7.0 include:
|
||||||
|
|
||||||
### Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug
|
### Block, Network, Persistent Memory (PMEM), VirtioFS and Vsock hotplug
|
||||||
@@ -2903,8 +2901,6 @@ Many thanks to everyone who has contributed to our 0.7.0 release including some
|
|||||||
|
|
||||||
# v0.6.0
|
# v0.6.0
|
||||||
|
|
||||||
This release has been tracked through the [0.6.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/7).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.6.0 include:
|
Highlights for `cloud-hypervisor` version 0.6.0 include:
|
||||||
|
|
||||||
### Directly Assigned Devices Hotplug
|
### Directly Assigned Devices Hotplug
|
||||||
@@ -2981,8 +2977,6 @@ This is a bugfix release branched off v0.5.0. It contains the following fixes:
|
|||||||
|
|
||||||
# v0.5.0
|
# v0.5.0
|
||||||
|
|
||||||
This release has been tracked through the [0.5.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/6).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.5.0 include:
|
Highlights for `cloud-hypervisor` version 0.5.0 include:
|
||||||
|
|
||||||
### Virtual Machine Dynamic Resizing
|
### Virtual Machine Dynamic Resizing
|
||||||
@@ -3042,8 +3036,6 @@ Many thanks to everyone that contributed to the 0.5.0 release:
|
|||||||
|
|
||||||
# v0.4.0
|
# v0.4.0
|
||||||
|
|
||||||
This release has been tracked through the [0.4.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/4).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.4.0 include:
|
Highlights for `cloud-hypervisor` version 0.4.0 include:
|
||||||
|
|
||||||
### Dynamic virtual CPUs addition
|
### Dynamic virtual CPUs addition
|
||||||
@@ -3121,8 +3113,6 @@ Many thanks to everyone that contributed to the 0.4.0 release:
|
|||||||
|
|
||||||
# v0.3.0
|
# v0.3.0
|
||||||
|
|
||||||
This release has been tracked through the [0.3.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/3).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.3.0 include:
|
Highlights for `cloud-hypervisor` version 0.3.0 include:
|
||||||
|
|
||||||
### Block device offloading
|
### Block device offloading
|
||||||
@@ -3190,8 +3180,6 @@ support guests with large amount of memory (more than 64GB).
|
|||||||
|
|
||||||
# v0.2.0
|
# v0.2.0
|
||||||
|
|
||||||
This release has been tracked through the [0.2.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/2).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.2.0 include:
|
Highlights for `cloud-hypervisor` version 0.2.0 include:
|
||||||
|
|
||||||
### Network device offloading
|
### Network device offloading
|
||||||
@@ -3216,7 +3204,7 @@ enabled by default.
|
|||||||
|
|
||||||
Based on the Firecracker idea of using a dedicated I/O port to measure guest
|
Based on the Firecracker idea of using a dedicated I/O port to measure guest
|
||||||
boot times, we added support for logging guest events through the
|
boot times, we added support for logging guest events through the
|
||||||
[0x80](https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
|
[0x80](https://web.archive.org/web/20211028033025/https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html)
|
||||||
PC debug port. This allows, among other things, for granular guest boot time
|
PC debug port. This allows, among other things, for granular guest boot time
|
||||||
measurements. See our [debug port documentation](docs/debug-port.md) for more
|
measurements. See our [debug port documentation](docs/debug-port.md) for more
|
||||||
details.
|
details.
|
||||||
@@ -3244,8 +3232,6 @@ our CI pipeline.
|
|||||||
|
|
||||||
# v0.1.0
|
# v0.1.0
|
||||||
|
|
||||||
This release has been tracked through the [0.1.0 project](https://github.com/cloud-hypervisor/cloud-hypervisor/projects/1).
|
|
||||||
|
|
||||||
Highlights for `cloud-hypervisor` version 0.1.0 include:
|
Highlights for `cloud-hypervisor` version 0.1.0 include:
|
||||||
|
|
||||||
### Shared filesystem
|
### Shared filesystem
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
# When changing this file don't forget to update the tag name in the
|
# 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
|
# .github/workflows/docker-image.yaml file if doing multiple per day
|
||||||
|
|
||||||
FROM ubuntu:22.04 as dev
|
FROM ubuntu:24.04 AS dev
|
||||||
|
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG RUST_TOOLCHAIN="1.77.0"
|
ARG RUST_TOOLCHAIN="1.82.0"
|
||||||
ARG CLH_SRC_DIR="/cloud-hypervisor"
|
ARG CLH_SRC_DIR="/cloud-hypervisor"
|
||||||
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
|
ARG CLH_BUILD_DIR="$CLH_SRC_DIR/build"
|
||||||
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"
|
ARG CARGO_REGISTRY_DIR="$CLH_BUILD_DIR/cargo_registry"
|
||||||
@@ -48,7 +48,6 @@ RUN apt-get update \
|
|||||||
python3 \
|
python3 \
|
||||||
python3-setuptools \
|
python3-setuptools \
|
||||||
ntfs-3g \
|
ntfs-3g \
|
||||||
python3-distutils \
|
|
||||||
uuid-dev \
|
uuid-dev \
|
||||||
iperf3 \
|
iperf3 \
|
||||||
zip \
|
zip \
|
||||||
@@ -108,7 +107,9 @@ ENV OPENSSL_INCLUDE_DIR=/usr/include/
|
|||||||
RUN export ARCH="$(uname -m)" \
|
RUN export ARCH="$(uname -m)" \
|
||||||
&& nohup curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "$RUST_TOOLCHAIN" \
|
&& nohup curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "$RUST_TOOLCHAIN" \
|
||||||
&& rustup target add "$ARCH"-unknown-linux-musl --toolchain "$RUST_TOOLCHAIN" \
|
&& rustup target add "$ARCH"-unknown-linux-musl --toolchain "$RUST_TOOLCHAIN" \
|
||||||
&& if [ "$TARGETARCH" = "amd64" ]; then rustup toolchain add --profile minimal $RUST_TOOLCHAIN-x86_64-unknown-linux-musl; fi \
|
&& if [ "$TARGETARCH" = "amd64" ]; then \
|
||||||
|
rustup toolchain add --profile minimal --force-non-host \
|
||||||
|
$RUST_TOOLCHAIN-x86_64-unknown-linux-musl; fi \
|
||||||
&& if [ "$TARGETARCH" = "amd64" ]; then rustup component add rustfmt; fi \
|
&& if [ "$TARGETARCH" = "amd64" ]; then rustup component add rustfmt; fi \
|
||||||
&& if [ "$TARGETARCH" = "amd64" ]; then rustup component add clippy; fi \
|
&& if [ "$TARGETARCH" = "amd64" ]; then rustup component add clippy; fi \
|
||||||
&& rm -rf "$CARGO_HOME/registry" \
|
&& rm -rf "$CARGO_HOME/registry" \
|
||||||
@@ -122,25 +123,31 @@ RUN echo 'source $CARGO_HOME/env' >> "$HOME"/.bashrc \
|
|||||||
&& mkdir "$HOME"/.cargo \
|
&& mkdir "$HOME"/.cargo \
|
||||||
&& ln -s $CARGO_HOME/env "$HOME"/.cargo/env
|
&& ln -s $CARGO_HOME/env "$HOME"/.cargo/env
|
||||||
|
|
||||||
# install SPDK NVMe
|
# Allow pip to install packages system wide
|
||||||
# only for 'x86_64' platform images as 'docker buildx' can't build 'spdk'
|
|
||||||
# hadolint ignore=DL3003,SC2046
|
# hadolint ignore=DL3003,SC2046
|
||||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
RUN rm /usr/lib/python3.12/EXTERNALLY-MANAGED \
|
||||||
git clone https://github.com/spdk/spdk \
|
&& git clone https://github.com/spdk/spdk \
|
||||||
&& cd spdk \
|
&& cd spdk \
|
||||||
&& git checkout ef8bcce58f3f02b79c0619a297e4f17e81e62b24 \
|
&& git checkout ef8bcce58f3f02b79c0619a297e4f17e81e62b24 \
|
||||||
&& git submodule update --init \
|
&& git submodule update --init \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& ./scripts/pkgdep.sh \
|
&& ./scripts/pkgdep.sh \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& ./configure --with-vfio-user \
|
&& ./configure --with-vfio-user \
|
||||||
&& make -j $(nproc) TARGET_ARCHITECTURE=skylake \
|
&& if [ "$TARGETARCH" = "amd64" ]; then \
|
||||||
&& rm -rf /usr/local/bin/spdk-nvme \
|
make -j $(nproc) TARGET_ARCHITECTURE=skylake; \
|
||||||
&& mkdir /usr/local/bin/spdk-nvme \
|
elif [ "$TARGETARCH" = "arm64" ]; then \
|
||||||
&& cp -f ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \
|
make -j $(nproc) TARGET_ARCHITECTURE="armv8.2-a" DPDKBUILD_FLAGS="-Dplatform=generic"; \
|
||||||
&& cp -f ./scripts/rpc.py /usr/local/bin/spdk-nvme \
|
else \
|
||||||
&& cp -rf ./python /usr/local/bin \
|
echo "Unsupported architecture: ${TARGETARCH}" && exit 1; \
|
||||||
&& cd .. && rm -rf spdk; fi
|
fi \
|
||||||
|
&& rm -rf /usr/local/bin/spdk-nvme \
|
||||||
|
&& mkdir /usr/local/bin/spdk-nvme \
|
||||||
|
&& cp -f ./build/bin/nvmf_tgt /usr/local/bin/spdk-nvme \
|
||||||
|
&& cp -f ./scripts/rpc.py /usr/local/bin/spdk-nvme \
|
||||||
|
&& cp -rf ./python/spdk/ /usr/local/bin/spdk-nvme \
|
||||||
|
&& cp -rf ./python /usr/local/bin \
|
||||||
|
&& cd .. && rm -rf spdk
|
||||||
|
|
||||||
# install ethr tool for performance tests
|
# install ethr tool for performance tests
|
||||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ CLI_NAME="Cloud Hypervisor"
|
|||||||
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
|
CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
|
||||||
|
|
||||||
# Needs to match explicit version in docker-image.yaml workflow
|
# Needs to match explicit version in docker-image.yaml workflow
|
||||||
CTR_IMAGE_VERSION="20250111-0"
|
CTR_IMAGE_VERSION="20250307-2"
|
||||||
: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
|
: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
|
||||||
|
|
||||||
DOCKER_RUNTIME="docker"
|
DOCKER_RUNTIME="docker"
|
||||||
|
|||||||
@@ -9,33 +9,6 @@ source "$(dirname "$0")"/common-aarch64.sh
|
|||||||
|
|
||||||
WORKLOADS_LOCK="$WORKLOADS_DIR/integration_test.lock"
|
WORKLOADS_LOCK="$WORKLOADS_DIR/integration_test.lock"
|
||||||
|
|
||||||
build_spdk_nvme() {
|
|
||||||
SPDK_DIR="$WORKLOADS_DIR/spdk"
|
|
||||||
SPDK_REPO="https://github.com/spdk/spdk.git"
|
|
||||||
SPDK_DEPLOY_DIR="/usr/local/bin/spdk-nvme"
|
|
||||||
checkout_repo "$SPDK_DIR" "$SPDK_REPO" master "ef8bcce58f3f02b79c0619a297e4f17e81e62b24"
|
|
||||||
|
|
||||||
if [ ! -f "$SPDK_DIR/.built" ]; then
|
|
||||||
pushd "$SPDK_DIR" || exit
|
|
||||||
git submodule update --init
|
|
||||||
apt-get update
|
|
||||||
sed -i "/grpcio/d" scripts/pkgdep/debian.sh
|
|
||||||
./scripts/pkgdep.sh
|
|
||||||
./configure --with-vfio-user
|
|
||||||
chmod +x /usr/local/lib/python3.10/dist-packages/ninja/data/bin/ninja
|
|
||||||
make -j "$(nproc)" || exit 1
|
|
||||||
touch .built
|
|
||||||
popd || exit
|
|
||||||
fi
|
|
||||||
if [ ! -d "/usr/local/bin/spdk-nvme" ]; then
|
|
||||||
mkdir -p $SPDK_DEPLOY_DIR
|
|
||||||
fi
|
|
||||||
cp "$WORKLOADS_DIR/spdk/build/bin/nvmf_tgt" $SPDK_DEPLOY_DIR/nvmf_tgt
|
|
||||||
cp "$WORKLOADS_DIR/spdk/scripts/rpc.py" $SPDK_DEPLOY_DIR/rpc.py
|
|
||||||
cp -r "$WORKLOADS_DIR/spdk/python/spdk/" $SPDK_DEPLOY_DIR/
|
|
||||||
cp -r "$WORKLOADS_DIR/spdk/python" $SPDK_DEPLOY_DIR/../
|
|
||||||
}
|
|
||||||
|
|
||||||
build_virtiofsd() {
|
build_virtiofsd() {
|
||||||
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
|
VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build"
|
||||||
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
|
VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git"
|
||||||
@@ -191,9 +164,6 @@ update_workloads() {
|
|||||||
echo "bar" >"$SHARED_DIR/file3" || exit 1
|
echo "bar" >"$SHARED_DIR/file3" || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Checkout and build SPDK NVMe
|
|
||||||
build_spdk_nvme
|
|
||||||
|
|
||||||
# Checkout and build EDK2
|
# Checkout and build EDK2
|
||||||
build_edk2
|
build_edk2
|
||||||
}
|
}
|
||||||
|
|||||||
624
src/main.rs
624
src/main.rs
@@ -176,58 +176,163 @@ fn default_rng() -> String {
|
|||||||
format!("src={}", vm_config::DEFAULT_RNG_SOURCE)
|
format!("src={}", vm_config::DEFAULT_RNG_SOURCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_app(default_vcpus: String, default_memory: String, default_rng: String) -> Command {
|
/// Returns all [`Arg`]s in alphabetical order. This is the order used in the
|
||||||
#[allow(clippy::let_and_return)]
|
/// `--help` output.
|
||||||
let app = Command::new("cloud-hypervisor")
|
fn get_cli_options_sorted(
|
||||||
// 'BUILD_VERSION' is set by the build script 'build.rs' at
|
default_vcpus: String,
|
||||||
// compile time
|
default_memory: String,
|
||||||
.author(env!("CARGO_PKG_AUTHORS"))
|
default_rng: String,
|
||||||
.about("Launch a cloud-hypervisor VMM.")
|
) -> Box<[Arg]> {
|
||||||
.arg_required_else_help(true)
|
[
|
||||||
.group(ArgGroup::new("vm-config").multiple(true).requires("vm-payload"))
|
Arg::new("api-socket")
|
||||||
.group(ArgGroup::new("vmm-config").multiple(true))
|
.long("api-socket")
|
||||||
.group(ArgGroup::new("logging").multiple(true))
|
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
|
||||||
.group(ArgGroup::new("vm-payload").multiple(true))
|
.num_args(1)
|
||||||
.arg(
|
.group("vmm-config"),
|
||||||
Arg::new("cpus")
|
Arg::new("balloon")
|
||||||
.long("cpus")
|
.long("balloon")
|
||||||
.help(
|
.help(BalloonConfig::SYNTAX)
|
||||||
"boot=<boot_vcpus>,max=<max_vcpus>,\
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("cmdline")
|
||||||
|
.long("cmdline")
|
||||||
|
.help("Kernel command line")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-config"), Arg::new("console")
|
||||||
|
.long("console")
|
||||||
|
.help(
|
||||||
|
"Control (virtio) console: \"off|null|pty|tty|file=</path/to/a/file>,iommu=on|off\"",
|
||||||
|
)
|
||||||
|
.default_value("tty")
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("cpus")
|
||||||
|
.long("cpus")
|
||||||
|
.help(
|
||||||
|
"boot=<boot_vcpus>,max=<max_vcpus>,\
|
||||||
topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,\
|
topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,\
|
||||||
kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,\
|
kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,\
|
||||||
affinity=<list_of_vcpus_with_their_associated_cpuset>,\
|
affinity=<list_of_vcpus_with_their_associated_cpuset>,\
|
||||||
features=<list_of_features_to_enable>",
|
features=<list_of_features_to_enable>",
|
||||||
)
|
)
|
||||||
.default_value(default_vcpus)
|
.default_value(default_vcpus)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
)
|
#[cfg(target_arch = "x86_64")]
|
||||||
.arg(
|
Arg::new("debug-console")
|
||||||
Arg::new("platform")
|
.long("debug-console")
|
||||||
.long("platform")
|
.help("Debug console: off|pty|tty|file=</path/to/a/file>,iobase=<port in hex>")
|
||||||
.help("num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,iommu_address_width=<bits>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>")
|
.default_value("off,iobase=0xe9")
|
||||||
.num_args(1)
|
.group("vm-config"),
|
||||||
.group("vm-config"),
|
#[cfg(feature = "dbus_api")]
|
||||||
)
|
Arg::new("dbus-service-name")
|
||||||
.arg(
|
.long("dbus-service-name")
|
||||||
Arg::new("memory")
|
.help("Well known name of the device")
|
||||||
.long("memory")
|
.num_args(1)
|
||||||
.help(
|
.group("vmm-config"),
|
||||||
"Memory parameters \
|
#[cfg(feature = "dbus_api")]
|
||||||
|
Arg::new("dbus-object-path")
|
||||||
|
.long("dbus-object-path")
|
||||||
|
.help("Object path to serve the dbus interface")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
#[cfg(feature = "dbus_api")]
|
||||||
|
Arg::new("dbus-system-bus")
|
||||||
|
.long("dbus-system-bus")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("Use the system bus instead of a session bus")
|
||||||
|
.num_args(0)
|
||||||
|
.group("vmm-config"),
|
||||||
|
Arg::new("device")
|
||||||
|
.long("device")
|
||||||
|
.help(DeviceConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("disk")
|
||||||
|
.long("disk")
|
||||||
|
.help(DiskConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("event-monitor")
|
||||||
|
.long("event-monitor")
|
||||||
|
.help("File to report events on: path=</path/to/a/file> or fd=<fd>")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
Arg::new("firmware")
|
||||||
|
.long("firmware")
|
||||||
|
.help("Path to firmware that is loaded in an architectural specific way")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-payload"),
|
||||||
|
Arg::new("fs")
|
||||||
|
.long("fs")
|
||||||
|
.help(FsConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
#[cfg(feature = "guest_debug")]
|
||||||
|
Arg::new("gdb")
|
||||||
|
.long("gdb")
|
||||||
|
.help("GDB socket (UNIX domain socket): path=</path/to/a/file>")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
#[cfg(feature = "igvm")]
|
||||||
|
Arg::new("igvm")
|
||||||
|
.long("igvm")
|
||||||
|
.help("Path to IGVM file to load.")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-payload"),
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
Arg::new("host-data")
|
||||||
|
.long("host-data")
|
||||||
|
.help("Host specific data to SEV SNP guest")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("initramfs")
|
||||||
|
.long("initramfs")
|
||||||
|
.help("Path to initramfs image")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("kernel")
|
||||||
|
.long("kernel")
|
||||||
|
.help(
|
||||||
|
"Path to kernel to load. This may be a kernel or firmware that supports a PVH \
|
||||||
|
entry point (e.g. vmlinux) or architecture equivalent",
|
||||||
|
)
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-payload"),
|
||||||
|
Arg::new("landlock")
|
||||||
|
.long("landlock")
|
||||||
|
.num_args(0)
|
||||||
|
.help(
|
||||||
|
"enable/disable Landlock.",
|
||||||
|
)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.default_value("false")
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("landlock-rules")
|
||||||
|
.long("landlock-rules")
|
||||||
|
.help(LandlockConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("log-file")
|
||||||
|
.long("log-file")
|
||||||
|
.help("Log file. Standard error is used if not specified")
|
||||||
|
.num_args(1)
|
||||||
|
.group("logging"),
|
||||||
|
Arg::new("memory")
|
||||||
|
.long("memory")
|
||||||
|
.help(
|
||||||
|
"Memory parameters \
|
||||||
\"size=<guest_memory_size>,mergeable=on|off,shared=on|off,\
|
\"size=<guest_memory_size>,mergeable=on|off,shared=on|off,\
|
||||||
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
hotplug_method=acpi|virtio-mem,\
|
hotplug_method=acpi|virtio-mem,\
|
||||||
hotplug_size=<hotpluggable_memory_size>,\
|
hotplug_size=<hotpluggable_memory_size>,\
|
||||||
hotplugged_size=<hotplugged_memory_size>,\
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
prefault=on|off,thp=on|off\"",
|
prefault=on|off,thp=on|off\"",
|
||||||
)
|
)
|
||||||
.default_value(default_memory)
|
.default_value(default_memory)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
)
|
Arg::new("memory-zone")
|
||||||
.arg(
|
.long("memory-zone")
|
||||||
Arg::new("memory-zone")
|
.help(
|
||||||
.long("memory-zone")
|
"User defined memory zone parameters \
|
||||||
.help(
|
|
||||||
"User defined memory zone parameters \
|
|
||||||
\"size=<guest_memory_region_size>,file=<backing_file>,\
|
\"size=<guest_memory_region_size>,file=<backing_file>,\
|
||||||
shared=on|off,\
|
shared=on|off,\
|
||||||
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
@@ -235,319 +340,143 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
|
|||||||
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
||||||
hotplugged_size=<hotplugged_memory_size>,\
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
prefault=on|off\"",
|
prefault=on|off\"",
|
||||||
)
|
)
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("firmware")
|
|
||||||
.long("firmware")
|
|
||||||
.help("Path to firmware that is loaded in an architectural specific way")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-payload"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("kernel")
|
|
||||||
.long("kernel")
|
|
||||||
.help(
|
|
||||||
"Path to kernel to load. This may be a kernel or firmware that supports a PVH \
|
|
||||||
entry point (e.g. vmlinux) or architecture equivalent",
|
|
||||||
)
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-payload"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("initramfs")
|
|
||||||
.long("initramfs")
|
|
||||||
.help("Path to initramfs image")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("cmdline")
|
|
||||||
.long("cmdline")
|
|
||||||
.help("Kernel command line")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("rate-limit-group")
|
|
||||||
.long("rate-limit-group")
|
|
||||||
.help(RateLimiterGroupConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("disk")
|
|
||||||
.long("disk")
|
|
||||||
.help(DiskConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("landlock")
|
|
||||||
.long("landlock")
|
|
||||||
.num_args(0)
|
|
||||||
.help(
|
|
||||||
"enable/disable Landlock.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue)
|
|
||||||
.default_value("false")
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("landlock-rules")
|
|
||||||
.long("landlock-rules")
|
|
||||||
.help(LandlockConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
)
|
Arg::new("net")
|
||||||
.arg(
|
.long("net")
|
||||||
Arg::new("net")
|
.help(NetConfig::SYNTAX)
|
||||||
.long("net")
|
|
||||||
.help(NetConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("rng")
|
|
||||||
.long("rng")
|
|
||||||
.help(
|
|
||||||
"Random number generator parameters \"src=<entropy_source_path>,iommu=on|off\"",
|
|
||||||
)
|
|
||||||
.default_value(default_rng)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("balloon")
|
|
||||||
.long("balloon")
|
|
||||||
.help(BalloonConfig::SYNTAX)
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("fs")
|
|
||||||
.long("fs")
|
|
||||||
.help(FsConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("pmem")
|
|
||||||
.long("pmem")
|
|
||||||
.help(PmemConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("serial")
|
|
||||||
.long("serial")
|
|
||||||
.help("Control serial port: off|null|pty|tty|file=</path/to/a/file>|socket=</path/to/a/file>")
|
|
||||||
.default_value("null")
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("console")
|
|
||||||
.long("console")
|
|
||||||
.help(
|
|
||||||
"Control (virtio) console: \"off|null|pty|tty|file=</path/to/a/file>,iommu=on|off\"",
|
|
||||||
)
|
|
||||||
.default_value("tty")
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("device")
|
|
||||||
.long("device")
|
|
||||||
.help(DeviceConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("user-device")
|
|
||||||
.long("user-device")
|
|
||||||
.help(UserDeviceConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("vdpa")
|
|
||||||
.long("vdpa")
|
|
||||||
.help(VdpaConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("vsock")
|
|
||||||
.long("vsock")
|
|
||||||
.help(VsockConfig::SYNTAX)
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("pvpanic")
|
|
||||||
.long("pvpanic")
|
|
||||||
.help("Enable pvpanic device")
|
|
||||||
.num_args(0)
|
|
||||||
.action(ArgAction::SetTrue)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("numa")
|
|
||||||
.long("numa")
|
|
||||||
.help(NumaConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("pci-segment")
|
|
||||||
.long("pci-segment")
|
|
||||||
.help(PciSegmentConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("watchdog")
|
|
||||||
.long("watchdog")
|
|
||||||
.help("Enable virtio-watchdog")
|
|
||||||
.num_args(0)
|
|
||||||
.action(ArgAction::SetTrue)
|
|
||||||
.group("vm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("v")
|
|
||||||
.short('v')
|
|
||||||
.action(ArgAction::Count)
|
|
||||||
.help("Sets the level of debugging output")
|
|
||||||
.group("logging"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("log-file")
|
|
||||||
.long("log-file")
|
|
||||||
.help("Log file. Standard error is used if not specified")
|
|
||||||
.num_args(1)
|
|
||||||
.group("logging"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("api-socket")
|
|
||||||
.long("api-socket")
|
|
||||||
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vmm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("event-monitor")
|
|
||||||
.long("event-monitor")
|
|
||||||
.help("File to report events on: path=</path/to/a/file> or fd=<fd>")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vmm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("restore")
|
|
||||||
.long("restore")
|
|
||||||
.help(RestoreConfig::SYNTAX)
|
|
||||||
.num_args(1)
|
|
||||||
.group("vmm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("seccomp")
|
|
||||||
.long("seccomp")
|
|
||||||
.num_args(1)
|
|
||||||
.value_parser(["true", "false", "log"])
|
|
||||||
.default_value("true"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("tpm")
|
|
||||||
.long("tpm")
|
|
||||||
.num_args(1)
|
|
||||||
.help(TpmConfig::SYNTAX)
|
|
||||||
.group("vm-config"),
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
let app = app.arg(
|
|
||||||
Arg::new("sgx-epc")
|
|
||||||
.long("sgx-epc")
|
|
||||||
.help(SgxEpcConfig::SYNTAX)
|
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
);
|
Arg::new("numa")
|
||||||
|
.long("numa")
|
||||||
#[cfg(target_arch = "x86_64")]
|
.help(NumaConfig::SYNTAX)
|
||||||
let app = app.arg(
|
.num_args(1..)
|
||||||
Arg::new("debug-console")
|
|
||||||
.long("debug-console")
|
|
||||||
.help("Debug console: off|pty|tty|file=</path/to/a/file>,iobase=<port in hex>")
|
|
||||||
.default_value("off,iobase=0xe9")
|
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
);
|
Arg::new("pci-segment")
|
||||||
|
.long("pci-segment")
|
||||||
#[cfg(feature = "guest_debug")]
|
.help(PciSegmentConfig::SYNTAX)
|
||||||
let app = app.arg(
|
.num_args(1..)
|
||||||
Arg::new("gdb")
|
.group("vm-config"),
|
||||||
.long("gdb")
|
Arg::new("platform")
|
||||||
.help("GDB socket (UNIX domain socket): path=</path/to/a/file>")
|
.long("platform")
|
||||||
.num_args(1)
|
.help(
|
||||||
.group("vmm-config"),
|
"num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,iommu_address_width=<bits>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>"
|
||||||
);
|
)
|
||||||
|
|
||||||
#[cfg(feature = "dbus_api")]
|
|
||||||
let app = app
|
|
||||||
.arg(
|
|
||||||
Arg::new("dbus-service-name")
|
|
||||||
.long("dbus-service-name")
|
|
||||||
.help("Well known name of the device")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vmm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("dbus-object-path")
|
|
||||||
.long("dbus-object-path")
|
|
||||||
.help("Object path to serve the dbus interface")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vmm-config"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::new("dbus-system-bus")
|
|
||||||
.long("dbus-system-bus")
|
|
||||||
.action(ArgAction::SetTrue)
|
|
||||||
.help("Use the system bus instead of a session bus")
|
|
||||||
.num_args(0)
|
|
||||||
.group("vmm-config"),
|
|
||||||
);
|
|
||||||
#[cfg(feature = "igvm")]
|
|
||||||
let app = app.arg(
|
|
||||||
Arg::new("igvm")
|
|
||||||
.long("igvm")
|
|
||||||
.help("Path to IGVM file to load.")
|
|
||||||
.num_args(1)
|
|
||||||
.group("vm-payload"),
|
|
||||||
);
|
|
||||||
#[cfg(feature = "sev_snp")]
|
|
||||||
let app = app.arg(
|
|
||||||
Arg::new("host-data")
|
|
||||||
.long("host-data")
|
|
||||||
.help("Host specific data to SEV SNP guest")
|
|
||||||
.num_args(1)
|
.num_args(1)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
);
|
Arg::new("pmem")
|
||||||
#[cfg(feature = "pvmemcontrol")]
|
.long("pmem")
|
||||||
let app = app.arg(
|
.help(PmemConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
#[cfg(feature = "pvmemcontrol")]
|
||||||
Arg::new("pvmemcontrol")
|
Arg::new("pvmemcontrol")
|
||||||
.long("pvmemcontrol")
|
.long("pvmemcontrol")
|
||||||
.help("Pvmemcontrol device")
|
.help("Pvmemcontrol device")
|
||||||
.num_args(0)
|
.num_args(0)
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
);
|
Arg::new("pvpanic")
|
||||||
|
.long("pvpanic")
|
||||||
app.arg(
|
.help("Enable pvpanic device")
|
||||||
|
.num_args(0)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("rate-limit-group")
|
||||||
|
.long("rate-limit-group")
|
||||||
|
.help(RateLimiterGroupConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("restore")
|
||||||
|
.long("restore")
|
||||||
|
.help(RestoreConfig::SYNTAX)
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
Arg::new("rng")
|
||||||
|
.long("rng")
|
||||||
|
.help(
|
||||||
|
"Random number generator parameters \"src=<entropy_source_path>,iommu=on|off\"",
|
||||||
|
)
|
||||||
|
.default_value(default_rng)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("seccomp")
|
||||||
|
.long("seccomp")
|
||||||
|
.num_args(1)
|
||||||
|
.value_parser(["true", "false", "log"])
|
||||||
|
.default_value("true"),
|
||||||
|
Arg::new("serial")
|
||||||
|
.long("serial")
|
||||||
|
.help("Control serial port: off|null|pty|tty|file=</path/to/a/file>|socket=</path/to/a/file>")
|
||||||
|
.default_value("null")
|
||||||
|
.group("vm-config"),
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
Arg::new("sgx-epc")
|
||||||
|
.long("sgx-epc")
|
||||||
|
.help(SgxEpcConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("tpm")
|
||||||
|
.long("tpm")
|
||||||
|
.num_args(1)
|
||||||
|
.help(TpmConfig::SYNTAX)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("user-device")
|
||||||
|
.long("user-device")
|
||||||
|
.help(UserDeviceConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("v")
|
||||||
|
.short('v')
|
||||||
|
.action(ArgAction::Count)
|
||||||
|
.help("Sets the level of debugging output")
|
||||||
|
.group("logging"),
|
||||||
|
Arg::new("vdpa")
|
||||||
|
.long("vdpa")
|
||||||
|
.help(VdpaConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
Arg::new("version")
|
Arg::new("version")
|
||||||
.short('V')
|
.short('V')
|
||||||
.long("version")
|
.long("version")
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
.help("Print version")
|
.help("Print version")
|
||||||
.num_args(0),
|
.num_args(0),
|
||||||
)
|
Arg::new("vsock")
|
||||||
|
.long("vsock")
|
||||||
|
.help(VsockConfig::SYNTAX)
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
|
Arg::new("watchdog")
|
||||||
|
.long("watchdog")
|
||||||
|
.help("Enable virtio-watchdog")
|
||||||
|
.num_args(0)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.group("vm-config"),
|
||||||
|
].to_vec().into_boxed_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the CLI definition of Cloud Hypervisor.
|
||||||
|
fn create_app(default_vcpus: String, default_memory: String, default_rng: String) -> Command {
|
||||||
|
let groups = [
|
||||||
|
ArgGroup::new("vm-config")
|
||||||
|
.multiple(true)
|
||||||
|
.requires("vm-payload"),
|
||||||
|
ArgGroup::new("vmm-config").multiple(true),
|
||||||
|
ArgGroup::new("logging").multiple(true),
|
||||||
|
ArgGroup::new("vm-payload").multiple(true),
|
||||||
|
];
|
||||||
|
|
||||||
|
let args = get_cli_options_sorted(default_vcpus, default_memory, default_rng);
|
||||||
|
|
||||||
|
Command::new("cloud-hypervisor")
|
||||||
|
// 'BUILD_VERSION' is set by the build script 'build.rs' at
|
||||||
|
// compile time
|
||||||
|
.author(env!("CARGO_PKG_AUTHORS"))
|
||||||
|
.about("Launch a cloud-hypervisor VMM.")
|
||||||
|
.arg_required_else_help(true)
|
||||||
|
.groups(groups)
|
||||||
|
.args(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
||||||
@@ -965,6 +894,7 @@ fn main() {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod unit_tests {
|
mod unit_tests {
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use vmm::config::VmParams;
|
use vmm::config::VmParams;
|
||||||
@@ -975,7 +905,7 @@ mod unit_tests {
|
|||||||
PayloadConfig, RngConfig, VmConfig,
|
PayloadConfig, RngConfig, VmConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{create_app, prepare_default_values};
|
use crate::{create_app, get_cli_options_sorted, prepare_default_values};
|
||||||
|
|
||||||
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
|
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
|
||||||
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
||||||
@@ -2075,4 +2005,24 @@ mod unit_tests {
|
|||||||
compare_vm_config_cli_vs_json(cli, openapi, *equal);
|
compare_vm_config_cli_vs_json(cli, openapi, *equal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO the check for the option list being sorted could be moved into the
|
||||||
|
// getter itself, when the getter becomes a const function. This however
|
||||||
|
// needs more support by Rust (as of March 2025).
|
||||||
|
#[test]
|
||||||
|
fn test_cli_options_sorted() {
|
||||||
|
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
||||||
|
let args = get_cli_options_sorted(default_vcpus, default_memory, default_rng);
|
||||||
|
|
||||||
|
let iter = args.iter().zip(args.iter().skip(1));
|
||||||
|
for (elem, next) in iter {
|
||||||
|
assert_ne!(
|
||||||
|
elem.get_id().cmp(next.get_id()),
|
||||||
|
Ordering::Greater,
|
||||||
|
"items not alphabetically sorted: elem={}, next={}",
|
||||||
|
elem.get_id(),
|
||||||
|
next.get_id()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ name = "test_infra"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dirs = "5.0.1"
|
dirs = "6.0.0"
|
||||||
epoll = "4.3.3"
|
epoll = "4.3.3"
|
||||||
libc = "0.2.167"
|
libc = "0.2.167"
|
||||||
once_cell = "1.20.2"
|
once_cell = "1.20.2"
|
||||||
|
|||||||
@@ -7587,6 +7587,7 @@ mod common_sequential {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg_attr(target_arch = "aarch64", ignore = "See #6970")]
|
||||||
fn test_snapshot_restore_with_fd() {
|
fn test_snapshot_restore_with_fd() {
|
||||||
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
|
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
|
||||||
let guest = Guest::new(Box::new(focal));
|
let guest = Guest::new(Box::new(focal));
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ struct PartiallyBalloonedPage {
|
|||||||
impl PartiallyBalloonedPage {
|
impl PartiallyBalloonedPage {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let page_size = get_page_size();
|
let page_size = get_page_size();
|
||||||
let len = ((page_size >> VIRTIO_BALLOON_PFN_SHIFT) + 63) / 64;
|
let len = (page_size >> VIRTIO_BALLOON_PFN_SHIFT).div_ceil(64);
|
||||||
// Initial each padding bit as 1 in bitmap.
|
// Initial each padding bit as 1 in bitmap.
|
||||||
let mut bitmap = vec![0_u64; len as usize];
|
let mut bitmap = vec![0_u64; len as usize];
|
||||||
let pad_num = len * 64 - (page_size >> VIRTIO_BALLOON_PFN_SHIFT);
|
let pad_num = len * 64 - (page_size >> VIRTIO_BALLOON_PFN_SHIFT);
|
||||||
@@ -134,7 +134,7 @@ impl PartiallyBalloonedPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
let len = ((self.page_size >> VIRTIO_BALLOON_PFN_SHIFT) + 63) / 64;
|
let len = (self.page_size >> VIRTIO_BALLOON_PFN_SHIFT).div_ceil(64);
|
||||||
self.addr = 0;
|
self.addr = 0;
|
||||||
self.bitmap = vec![0; len as usize];
|
self.bitmap = vec![0; len as usize];
|
||||||
let pad_num = len * 64 - (self.page_size >> VIRTIO_BALLOON_PFN_SHIFT);
|
let pad_num = len * 64 - (self.page_size >> VIRTIO_BALLOON_PFN_SHIFT);
|
||||||
|
|||||||
@@ -146,9 +146,9 @@ where
|
|||||||
/// Returns:
|
/// Returns:
|
||||||
/// - `Ok(())`: the packet has been successfully filled in and is ready for delivery;
|
/// - `Ok(())`: the packet has been successfully filled in and is ready for delivery;
|
||||||
/// - `Err(VsockError::NoData)`: there was no data available with which to fill in the
|
/// - `Err(VsockError::NoData)`: there was no data available with which to fill in the
|
||||||
/// packet;
|
/// packet;
|
||||||
/// - `Err(VsockError::PktBufMissing)`: the packet would've been filled in with data, but
|
/// - `Err(VsockError::PktBufMissing)`: the packet would've been filled in with data, but
|
||||||
/// it is missing the data buffer.
|
/// it is missing the data buffer.
|
||||||
///
|
///
|
||||||
fn recv_pkt(&mut self, pkt: &mut VsockPacket) -> VsockResult<()> {
|
fn recv_pkt(&mut self, pkt: &mut VsockPacket) -> VsockResult<()> {
|
||||||
// Perform some generic initialization that is the same for any packet operation (e.g.
|
// Perform some generic initialization that is the same for any packet operation (e.g.
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ pub trait Transportable: Pausable + Snapshottable {
|
|||||||
///
|
///
|
||||||
/// * `snapshot` - The migratable component snapshot to send.
|
/// * `snapshot` - The migratable component snapshot to send.
|
||||||
/// * `destination_url` - The destination URL to send the snapshot to. This
|
/// * `destination_url` - The destination URL to send the snapshot to. This
|
||||||
/// could be an HTTP endpoint, a TCP address or a local file.
|
/// could be an HTTP endpoint, a TCP address or a local file.
|
||||||
fn send(
|
fn send(
|
||||||
&self,
|
&self,
|
||||||
_snapshot: &Snapshot,
|
_snapshot: &Snapshot,
|
||||||
@@ -205,7 +205,7 @@ pub trait Transportable: Pausable + Snapshottable {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `source_url` - The source URL to fetch the snapshot from. This could be an HTTP
|
/// * `source_url` - The source URL to fetch the snapshot from. This could be an HTTP
|
||||||
/// endpoint, a TCP address or a local file.
|
/// endpoint, a TCP address or a local file.
|
||||||
fn recv(&self, _source_url: &str) -> std::result::Result<Snapshot, MigratableError> {
|
fn recv(&self, _source_url: &str) -> std::result::Result<Snapshot, MigratableError> {
|
||||||
Ok(Snapshot::default())
|
Ok(Snapshot::default())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ gdbstub = { version = "0.7.1", optional = true }
|
|||||||
gdbstub_arch = { version = "0.3.0", optional = true }
|
gdbstub_arch = { version = "0.3.0", optional = true }
|
||||||
hex = { version = "0.4.3", optional = true }
|
hex = { version = "0.4.3", optional = true }
|
||||||
hypervisor = { path = "../hypervisor" }
|
hypervisor = { path = "../hypervisor" }
|
||||||
igvm = { version = "0.3.3", optional = true }
|
igvm = { workspace = true, optional = true }
|
||||||
igvm_defs = { version = "0.3.1", optional = true }
|
igvm_defs = { workspace = true, optional = true }
|
||||||
landlock = "0.4.0"
|
landlock = "0.4.0"
|
||||||
libc = "0.2.167"
|
libc = "0.2.167"
|
||||||
linux-loader = { workspace = true, features = ["bzimage", "elf", "pe"] }
|
linux-loader = { workspace = true, features = ["bzimage", "elf", "pe"] }
|
||||||
|
|||||||
@@ -548,6 +548,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
initramfs:
|
initramfs:
|
||||||
type: string
|
type: string
|
||||||
|
igvm:
|
||||||
|
type: string
|
||||||
|
host_data:
|
||||||
|
type: string
|
||||||
description: Payloads to boot in guest
|
description: Payloads to boot in guest
|
||||||
|
|
||||||
VmConfig:
|
VmConfig:
|
||||||
@@ -732,6 +736,9 @@ components:
|
|||||||
tdx:
|
tdx:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
sev_snp:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
MemoryZoneConfig:
|
MemoryZoneConfig:
|
||||||
required:
|
required:
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::sync::{Arc, Barrier, Mutex};
|
use std::sync::{Arc, Barrier, Mutex};
|
||||||
use std::{cmp, io, result, thread};
|
use std::{cmp, io, result, thread};
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use acpi_tables::sdt::Sdt;
|
use acpi_tables::sdt::Sdt;
|
||||||
use acpi_tables::{aml, Aml};
|
use acpi_tables::{aml, Aml};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
@@ -44,10 +45,6 @@ use hypervisor::arch::x86::CpuIdEntry;
|
|||||||
use hypervisor::arch::x86::MsrEntry;
|
use hypervisor::arch::x86::MsrEntry;
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
use hypervisor::arch::x86::SpecialRegisters;
|
use hypervisor::arch::x86::SpecialRegisters;
|
||||||
#[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")]
|
#[cfg(feature = "tdx")]
|
||||||
use hypervisor::kvm::{TdxExitDetails, TdxExitStatus};
|
use hypervisor::kvm::{TdxExitDetails, TdxExitStatus};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -138,6 +135,10 @@ pub enum Error {
|
|||||||
#[error("Error fetching preferred target: {0}")]
|
#[error("Error fetching preferred target: {0}")]
|
||||||
VcpuArmPreferredTarget(#[source] hypervisor::HypervisorVmError),
|
VcpuArmPreferredTarget(#[source] hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
#[error("Error setting vCPU processor features: {0}")]
|
||||||
|
VcpuSetProcessorFeatures(#[source] hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
#[error("Error initialising vCPU: {0}")]
|
#[error("Error initialising vCPU: {0}")]
|
||||||
VcpuArmInit(#[source] hypervisor::HypervisorCpuError),
|
VcpuArmInit(#[source] hypervisor::HypervisorCpuError),
|
||||||
@@ -390,6 +391,8 @@ impl Vcpu {
|
|||||||
self.mpidr = arch::configure_vcpu(&self.vcpu, self.id, boot_setup)
|
self.mpidr = arch::configure_vcpu(&self.vcpu, self.id, boot_setup)
|
||||||
.map_err(Error::VcpuConfiguration)?;
|
.map_err(Error::VcpuConfiguration)?;
|
||||||
}
|
}
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
arch::configure_vcpu(&self.vcpu, self.id, boot_setup).map_err(Error::VcpuConfiguration)?;
|
||||||
info!("Configuring vCPU: cpu_id = {}", self.id);
|
info!("Configuring vCPU: cpu_id = {}", self.id);
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
arch::configure_vcpu(
|
arch::configure_vcpu(
|
||||||
@@ -413,7 +416,7 @@ impl Vcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the saved vCPU state.
|
/// Gets the saved vCPU state.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
pub fn get_saved_state(&self) -> Option<CpuState> {
|
pub fn get_saved_state(&self) -> Option<CpuState> {
|
||||||
self.saved_state.clone()
|
self.saved_state.clone()
|
||||||
}
|
}
|
||||||
@@ -422,42 +425,25 @@ impl Vcpu {
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub fn init(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
|
pub fn init(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
|
||||||
use std::arch::is_aarch64_feature_detected;
|
use std::arch::is_aarch64_feature_detected;
|
||||||
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
|
|
||||||
#[allow(clippy::nonminimal_bool)]
|
#[allow(clippy::nonminimal_bool)]
|
||||||
let sve_supported =
|
let sve_supported =
|
||||||
is_aarch64_feature_detected!("sve") || is_aarch64_feature_detected!("sve2");
|
is_aarch64_feature_detected!("sve") || is_aarch64_feature_detected!("sve2");
|
||||||
|
let mut kvi = self.vcpu.create_vcpu_init();
|
||||||
|
|
||||||
// This reads back the kernel's preferred target type.
|
// This reads back the kernel's preferred target type.
|
||||||
vm.get_preferred_target(&mut kvi)
|
vm.get_preferred_target(&mut kvi)
|
||||||
.map_err(Error::VcpuArmPreferredTarget)?;
|
.map_err(Error::VcpuArmPreferredTarget)?;
|
||||||
// We already checked that the capability is supported.
|
|
||||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if sve_supported
|
self.vcpu
|
||||||
&& vm
|
.vcpu_set_processor_features(vm, &mut kvi, self.id)
|
||||||
.as_any()
|
.map_err(Error::VcpuSetProcessorFeatures)?;
|
||||||
.downcast_ref::<hypervisor::kvm::KvmVm>()
|
|
||||||
.unwrap()
|
|
||||||
.check_extension(Cap::ArmSve)
|
|
||||||
{
|
|
||||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_SVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-boot cpus are powered off initially.
|
|
||||||
if self.id > 0 {
|
|
||||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
|
||||||
}
|
|
||||||
self.vcpu.vcpu_init(&kvi).map_err(Error::VcpuArmInit)?;
|
self.vcpu.vcpu_init(&kvi).map_err(Error::VcpuArmInit)?;
|
||||||
|
|
||||||
if sve_supported {
|
if sve_supported {
|
||||||
|
let finalized_features = self.vcpu.vcpu_get_finalized_features();
|
||||||
self.vcpu
|
self.vcpu
|
||||||
.vcpu_finalize(kvm_bindings::KVM_ARM_VCPU_SVE as i32)
|
.vcpu_finalize(finalized_features)
|
||||||
.map_err(Error::VcpuArmFinalize)?;
|
.map_err(Error::VcpuArmFinalize)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -814,7 +800,7 @@ impl CpuManager {
|
|||||||
let topology = self.get_vcpu_topology();
|
let topology = self.get_vcpu_topology();
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id as u32, topology);
|
let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id as u32, topology);
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
let x2apic_id = cpu_id as u32;
|
let x2apic_id = cpu_id as u32;
|
||||||
|
|
||||||
let mut vcpu = Vcpu::new(
|
let mut vcpu = Vcpu::new(
|
||||||
@@ -888,6 +874,9 @@ impl CpuManager {
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
vcpu.configure(&self.vm, boot_setup)?;
|
vcpu.configure(&self.vm, boot_setup)?;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
vcpu.configure(boot_setup)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1413,6 +1402,7 @@ impl CpuManager {
|
|||||||
.map(|t| (t.threads_per_core, t.cores_per_die, t.packages))
|
.map(|t| (t.threads_per_core, t.cores_per_die, t.packages))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
pub fn create_madt(&self) -> Sdt {
|
pub fn create_madt(&self) -> Sdt {
|
||||||
use crate::acpi;
|
use crate::acpi;
|
||||||
// This is also checked in the commandline parsing.
|
// This is also checked in the commandline parsing.
|
||||||
@@ -2950,8 +2940,7 @@ mod tests {
|
|||||||
use arch::layout;
|
use arch::layout;
|
||||||
use hypervisor::kvm::aarch64::is_system_register;
|
use hypervisor::kvm::aarch64::is_system_register;
|
||||||
use hypervisor::kvm::kvm_bindings::{
|
use hypervisor::kvm::kvm_bindings::{
|
||||||
kvm_vcpu_init, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM_CORE,
|
user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
|
||||||
KVM_REG_SIZE_U64,
|
|
||||||
};
|
};
|
||||||
use hypervisor::{arm64_core_reg_id, offset_of};
|
use hypervisor::{arm64_core_reg_id, offset_of};
|
||||||
|
|
||||||
@@ -2964,7 +2953,7 @@ mod tests {
|
|||||||
// Must fail when vcpu is not initialized yet.
|
// Must fail when vcpu is not initialized yet.
|
||||||
vcpu.setup_regs(0, 0x0, layout::FDT_START.0).unwrap_err();
|
vcpu.setup_regs(0, 0x0, layout::FDT_START.0).unwrap_err();
|
||||||
|
|
||||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
let mut kvi = vcpu.create_vcpu_init();
|
||||||
vm.get_preferred_target(&mut kvi).unwrap();
|
vm.get_preferred_target(&mut kvi).unwrap();
|
||||||
vcpu.vcpu_init(&kvi).unwrap();
|
vcpu.vcpu_init(&kvi).unwrap();
|
||||||
|
|
||||||
@@ -2976,7 +2965,7 @@ mod tests {
|
|||||||
let hv = hypervisor::new().unwrap();
|
let hv = hypervisor::new().unwrap();
|
||||||
let vm = hv.create_vm().unwrap();
|
let vm = hv.create_vm().unwrap();
|
||||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
let mut kvi = vcpu.create_vcpu_init();
|
||||||
vm.get_preferred_target(&mut kvi).unwrap();
|
vm.get_preferred_target(&mut kvi).unwrap();
|
||||||
|
|
||||||
// Must fail when vcpu is not initialized yet.
|
// Must fail when vcpu is not initialized yet.
|
||||||
@@ -3000,7 +2989,7 @@ mod tests {
|
|||||||
let hv = hypervisor::new().unwrap();
|
let hv = hypervisor::new().unwrap();
|
||||||
let vm = hv.create_vm().unwrap();
|
let vm = hv.create_vm().unwrap();
|
||||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
let mut kvi = vcpu.create_vcpu_init();
|
||||||
vm.get_preferred_target(&mut kvi).unwrap();
|
vm.get_preferred_target(&mut kvi).unwrap();
|
||||||
|
|
||||||
// Must fail when vcpu is not initialized yet.
|
// Must fail when vcpu is not initialized yet.
|
||||||
@@ -3027,7 +3016,7 @@ mod tests {
|
|||||||
let hv = hypervisor::new().unwrap();
|
let hv = hypervisor::new().unwrap();
|
||||||
let vm = hv.create_vm().unwrap();
|
let vm = hv.create_vm().unwrap();
|
||||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
let mut kvi = vcpu.create_vcpu_init();
|
||||||
vm.get_preferred_target(&mut kvi).unwrap();
|
vm.get_preferred_target(&mut kvi).unwrap();
|
||||||
|
|
||||||
let state = vcpu.get_mp_state().unwrap();
|
let state = vcpu.get_mp_state().unwrap();
|
||||||
|
|||||||
@@ -18,15 +18,18 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use acpi_tables::sdt::GenericAddress;
|
use acpi_tables::sdt::GenericAddress;
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use acpi_tables::{aml, Aml};
|
use acpi_tables::{aml, Aml};
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
|
use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
|
||||||
use arch::{layout, NumaNodes};
|
use arch::{layout, NumaNodes};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
use arch::{DeviceType, MmioDeviceInfo};
|
use arch::{DeviceType, MmioDeviceInfo};
|
||||||
use block::async_io::DiskFile;
|
use block::async_io::DiskFile;
|
||||||
use block::fixed_vhd_sync::FixedVhdDiskSync;
|
use block::fixed_vhd_sync::FixedVhdDiskSync;
|
||||||
@@ -39,6 +42,10 @@ use block::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "io_uring")]
|
#[cfg(feature = "io_uring")]
|
||||||
use block::{fixed_vhd_async::FixedVhdDiskAsync, raw_async::RawFileDisk};
|
use block::{fixed_vhd_async::FixedVhdDiskAsync, raw_async::RawFileDisk};
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
use devices::aia;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use devices::debug_console;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::debug_console::DebugConsole;
|
use devices::debug_console::DebugConsole;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@@ -48,6 +55,8 @@ use devices::interrupt_controller::InterruptController;
|
|||||||
use devices::ioapic;
|
use devices::ioapic;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::legacy::Pl011;
|
use devices::legacy::Pl011;
|
||||||
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
|
use devices::legacy::Serial;
|
||||||
#[cfg(feature = "pvmemcontrol")]
|
#[cfg(feature = "pvmemcontrol")]
|
||||||
use devices::pvmemcontrol::{PvmemcontrolBusDevice, PvmemcontrolPciDevice};
|
use devices::pvmemcontrol::{PvmemcontrolBusDevice, PvmemcontrolPciDevice};
|
||||||
use devices::{interrupt_controller, AcpiNotificationFlags};
|
use devices::{interrupt_controller, AcpiNotificationFlags};
|
||||||
@@ -88,8 +97,6 @@ use vm_migration::{
|
|||||||
};
|
};
|
||||||
use vm_virtio::{AccessPlatform, VirtioDeviceType};
|
use vm_virtio::{AccessPlatform, VirtioDeviceType};
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
use {devices::debug_console, devices::legacy::Serial};
|
|
||||||
|
|
||||||
use crate::console_devices::{ConsoleDeviceError, ConsoleInfo, ConsoleOutput};
|
use crate::console_devices::{ConsoleDeviceError, ConsoleInfo, ConsoleOutput};
|
||||||
use crate::cpu::{CpuManager, CPU_MANAGER_ACPI_SIZE};
|
use crate::cpu::{CpuManager, CPU_MANAGER_ACPI_SIZE};
|
||||||
@@ -105,7 +112,7 @@ use crate::vm_config::{
|
|||||||
};
|
};
|
||||||
use crate::{device_node, GuestRegionMmap, PciDeviceInfo, DEVICE_MANAGER_SNAPSHOT_ID};
|
use crate::{device_node, GuestRegionMmap, PciDeviceInfo, DEVICE_MANAGER_SNAPSHOT_ID};
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
const MMIO_LEN: u64 = 0x1000;
|
const MMIO_LEN: u64 = 0x1000;
|
||||||
|
|
||||||
// Singleton devices / devices the user cannot name
|
// Singleton devices / devices the user cannot name
|
||||||
@@ -823,9 +830,11 @@ pub struct DeviceManager {
|
|||||||
interrupt_controller: Option<Arc<Mutex<ioapic::Ioapic>>>,
|
interrupt_controller: Option<Arc<Mutex<ioapic::Ioapic>>>,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
interrupt_controller: Option<Arc<Mutex<gic::Gic>>>,
|
interrupt_controller: Option<Arc<Mutex<gic::Gic>>>,
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
interrupt_controller: Option<Arc<Mutex<aia::Aia>>>,
|
||||||
|
|
||||||
// Things to be added to the commandline (e.g. aarch64 early console)
|
// Things to be added to the commandline (e.g. aarch64 or riscv64 early console)
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
cmdline_additions: Vec<String>,
|
cmdline_additions: Vec<String>,
|
||||||
|
|
||||||
// ACPI GED notification device
|
// ACPI GED notification device
|
||||||
@@ -888,7 +897,7 @@ pub struct DeviceManager {
|
|||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
id_to_dev_info: HashMap<(DeviceType, String), MmioDeviceInfo>,
|
id_to_dev_info: HashMap<(DeviceType, String), MmioDeviceInfo>,
|
||||||
|
|
||||||
// seccomp action
|
// seccomp action
|
||||||
@@ -904,6 +913,7 @@ pub struct DeviceManager {
|
|||||||
// activation and thus start the threads from the VMM thread
|
// activation and thus start the threads from the VMM thread
|
||||||
activate_evt: EventFd,
|
activate_evt: EventFd,
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
acpi_address: GuestAddress,
|
acpi_address: GuestAddress,
|
||||||
|
|
||||||
selected_segment: usize,
|
selected_segment: usize,
|
||||||
@@ -936,12 +946,14 @@ pub struct DeviceManager {
|
|||||||
// List of unique identifiers provided at boot through the configuration.
|
// List of unique identifiers provided at boot through the configuration.
|
||||||
boot_id_list: BTreeSet<String>,
|
boot_id_list: BTreeSet<String>,
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
// Start time of the VM
|
// Start time of the VM
|
||||||
timestamp: Instant,
|
timestamp: Instant,
|
||||||
|
|
||||||
// Pending activations
|
// Pending activations
|
||||||
pending_activations: Arc<Mutex<Vec<VirtioPciDeviceActivator>>>,
|
pending_activations: Arc<Mutex<Vec<VirtioPciDeviceActivator>>>,
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
// Addresses for ACPI platform devices e.g. ACPI PM timer, sleep/reset registers
|
// Addresses for ACPI platform devices e.g. ACPI PM timer, sleep/reset registers
|
||||||
acpi_platform_addresses: AcpiPlatformAddresses,
|
acpi_platform_addresses: AcpiPlatformAddresses,
|
||||||
|
|
||||||
@@ -996,7 +1008,7 @@ impl DeviceManager {
|
|||||||
activate_evt: &EventFd,
|
activate_evt: &EventFd,
|
||||||
force_iommu: bool,
|
force_iommu: bool,
|
||||||
boot_id_list: BTreeSet<String>,
|
boot_id_list: BTreeSet<String>,
|
||||||
timestamp: Instant,
|
#[cfg(not(target_arch = "riscv64"))] timestamp: Instant,
|
||||||
snapshot: Option<Snapshot>,
|
snapshot: Option<Snapshot>,
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
) -> DeviceManagerResult<Arc<Mutex<Self>>> {
|
) -> DeviceManagerResult<Arc<Mutex<Self>>> {
|
||||||
@@ -1020,8 +1032,7 @@ impl DeviceManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut mmio32_aperture_weights: Vec<u32> =
|
let mut mmio32_aperture_weights: Vec<u32> =
|
||||||
std::iter::repeat(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT)
|
std::iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into())
|
||||||
.take(num_pci_segments.into())
|
|
||||||
.collect();
|
.collect();
|
||||||
if let Some(pci_segments) = &config.lock().unwrap().pci_segments {
|
if let Some(pci_segments) = &config.lock().unwrap().pci_segments {
|
||||||
for pci_segment in pci_segments.iter() {
|
for pci_segment in pci_segments.iter() {
|
||||||
@@ -1041,8 +1052,7 @@ impl DeviceManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut mmio64_aperture_weights: Vec<u32> =
|
let mut mmio64_aperture_weights: Vec<u32> =
|
||||||
std::iter::repeat(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT)
|
std::iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into())
|
||||||
.take(num_pci_segments.into())
|
|
||||||
.collect();
|
.collect();
|
||||||
if let Some(pci_segments) = &config.lock().unwrap().pci_segments {
|
if let Some(pci_segments) = &config.lock().unwrap().pci_segments {
|
||||||
for pci_segment in pci_segments.iter() {
|
for pci_segment in pci_segments.iter() {
|
||||||
@@ -1163,7 +1173,7 @@ impl DeviceManager {
|
|||||||
address_manager: Arc::clone(&address_manager),
|
address_manager: Arc::clone(&address_manager),
|
||||||
console: Arc::new(Console::default()),
|
console: Arc::new(Console::default()),
|
||||||
interrupt_controller: None,
|
interrupt_controller: None,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
cmdline_additions: Vec::new(),
|
cmdline_additions: Vec::new(),
|
||||||
ged_notification_device: None,
|
ged_notification_device: None,
|
||||||
config,
|
config,
|
||||||
@@ -1183,7 +1193,7 @@ impl DeviceManager {
|
|||||||
device_tree,
|
device_tree,
|
||||||
exit_evt,
|
exit_evt,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
id_to_dev_info: HashMap::new(),
|
id_to_dev_info: HashMap::new(),
|
||||||
seccomp_action,
|
seccomp_action,
|
||||||
numa_nodes,
|
numa_nodes,
|
||||||
@@ -1191,6 +1201,7 @@ impl DeviceManager {
|
|||||||
activate_evt: activate_evt
|
activate_evt: activate_evt
|
||||||
.try_clone()
|
.try_clone()
|
||||||
.map_err(DeviceManagerError::EventFd)?,
|
.map_err(DeviceManagerError::EventFd)?,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
acpi_address,
|
acpi_address,
|
||||||
selected_segment: 0,
|
selected_segment: 0,
|
||||||
serial_manager: None,
|
serial_manager: None,
|
||||||
@@ -1206,8 +1217,10 @@ impl DeviceManager {
|
|||||||
io_uring_supported: None,
|
io_uring_supported: None,
|
||||||
aio_supported: None,
|
aio_supported: None,
|
||||||
boot_id_list,
|
boot_id_list,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
timestamp,
|
timestamp,
|
||||||
pending_activations: Arc::new(Mutex::new(Vec::default())),
|
pending_activations: Arc::new(Mutex::new(Vec::default())),
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
acpi_platform_addresses: AcpiPlatformAddresses::default(),
|
acpi_platform_addresses: AcpiPlatformAddresses::default(),
|
||||||
snapshot,
|
snapshot,
|
||||||
rate_limit_groups,
|
rate_limit_groups,
|
||||||
@@ -1301,6 +1314,7 @@ impl DeviceManager {
|
|||||||
console_resize_pipe,
|
console_resize_pipe,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
if let Some(tpm) = self.config.clone().lock().unwrap().tpm.as_ref() {
|
if let Some(tpm) = self.config.clone().lock().unwrap().tpm.as_ref() {
|
||||||
let tpm_dev = self.add_tpm_device(tpm.socket.clone())?;
|
let tpm_dev = self.add_tpm_device(tpm.socket.clone())?;
|
||||||
self.bus_devices
|
self.bus_devices
|
||||||
@@ -1349,11 +1363,21 @@ impl DeviceManager {
|
|||||||
vgic_config.msi_addr + vgic_config.msi_size - 1,
|
vgic_config.msi_addr + vgic_config.msi_size - 1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
{
|
||||||
|
let vcpus = self.config.lock().unwrap().cpus.boot_vcpus;
|
||||||
|
let vaia_config = aia::Aia::create_default_config(vcpus.into());
|
||||||
|
(
|
||||||
|
vaia_config.imsic_addr,
|
||||||
|
vaia_config.imsic_addr + vaia_config.vcpu_count as u64 * arch::layout::IMSIC_SIZE
|
||||||
|
- 1,
|
||||||
|
)
|
||||||
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
(0xfee0_0000, 0xfeef_ffff)
|
(0xfee0_0000, 0xfeef_ffff)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
/// Gets the information of the devices registered up to some point in time.
|
/// Gets the information of the devices registered up to some point in time.
|
||||||
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> {
|
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> {
|
||||||
&self.id_to_dev_info
|
&self.id_to_dev_info
|
||||||
@@ -1518,6 +1542,43 @@ impl DeviceManager {
|
|||||||
self.interrupt_controller.as_ref()
|
self.interrupt_controller.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
fn add_interrupt_controller(
|
||||||
|
&mut self,
|
||||||
|
) -> DeviceManagerResult<Arc<Mutex<dyn InterruptController>>> {
|
||||||
|
let interrupt_controller: Arc<Mutex<aia::Aia>> = Arc::new(Mutex::new(
|
||||||
|
aia::Aia::new(
|
||||||
|
self.config.lock().unwrap().cpus.boot_vcpus,
|
||||||
|
Arc::clone(&self.msi_interrupt_manager),
|
||||||
|
self.address_manager.vm.clone(),
|
||||||
|
)
|
||||||
|
.map_err(DeviceManagerError::CreateInterruptController)?,
|
||||||
|
));
|
||||||
|
|
||||||
|
self.interrupt_controller = Some(interrupt_controller.clone());
|
||||||
|
|
||||||
|
// Restore the vAia if this is in the process of restoration
|
||||||
|
let id = String::from(aia::_AIA_SNAPSHOT_ID);
|
||||||
|
if let Some(_vaia_snapshot) = snapshot_from_id(self.snapshot.as_ref(), &id) {
|
||||||
|
// TODO: vAia snapshotting and restoration is scheduled to next stage of riscv64 support.
|
||||||
|
// TODO: PMU support is scheduled to next stage of riscv64 support.
|
||||||
|
// PMU support is optional. Nothing should be impacted if the PMU initialization failed.
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.device_tree
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id.clone(), device_node!(id, interrupt_controller));
|
||||||
|
|
||||||
|
Ok(interrupt_controller)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
pub fn get_interrupt_controller(&mut self) -> Option<&Arc<Mutex<aia::Aia>>> {
|
||||||
|
self.interrupt_controller.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn add_interrupt_controller(
|
fn add_interrupt_controller(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -1997,6 +2058,69 @@ impl DeviceManager {
|
|||||||
Ok(serial)
|
Ok(serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
fn add_serial_device(
|
||||||
|
&mut self,
|
||||||
|
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
|
||||||
|
serial_writer: Option<Box<dyn io::Write + Send>>,
|
||||||
|
) -> DeviceManagerResult<Arc<Mutex<Serial>>> {
|
||||||
|
let id = String::from(SERIAL_DEVICE_NAME);
|
||||||
|
|
||||||
|
let serial_irq = self
|
||||||
|
.address_manager
|
||||||
|
.allocator
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.allocate_irq()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let interrupt_group = interrupt_manager
|
||||||
|
.create_group(LegacyIrqGroupConfig {
|
||||||
|
irq: serial_irq as InterruptIndex,
|
||||||
|
})
|
||||||
|
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
||||||
|
|
||||||
|
let serial = Arc::new(Mutex::new(Serial::new(
|
||||||
|
id.clone(),
|
||||||
|
interrupt_group,
|
||||||
|
serial_writer,
|
||||||
|
state_from_id(self.snapshot.as_ref(), id.as_str())
|
||||||
|
.map_err(DeviceManagerError::RestoreGetState)?,
|
||||||
|
)));
|
||||||
|
|
||||||
|
self.bus_devices
|
||||||
|
.push(Arc::clone(&serial) as Arc<dyn BusDeviceSync>);
|
||||||
|
|
||||||
|
let addr = arch::layout::LEGACY_SERIAL_MAPPED_IO_START;
|
||||||
|
|
||||||
|
self.address_manager
|
||||||
|
.mmio_bus
|
||||||
|
.insert(serial.clone(), addr.0, MMIO_LEN)
|
||||||
|
.map_err(DeviceManagerError::BusError)?;
|
||||||
|
|
||||||
|
self.id_to_dev_info.insert(
|
||||||
|
(DeviceType::Serial, DeviceType::Serial.to_string()),
|
||||||
|
MmioDeviceInfo {
|
||||||
|
addr: addr.0,
|
||||||
|
len: MMIO_LEN,
|
||||||
|
irq: serial_irq,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
self.cmdline_additions
|
||||||
|
.push(format!("earlycon=uart,mmio,0x{:08x}", addr.0));
|
||||||
|
|
||||||
|
// Fill the device tree with a new node. In case of restore, we
|
||||||
|
// know there is nothing to do, so we can simply override the
|
||||||
|
// existing entry.
|
||||||
|
self.device_tree
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id.clone(), device_node!(id, serial));
|
||||||
|
|
||||||
|
Ok(serial)
|
||||||
|
}
|
||||||
|
|
||||||
fn add_virtio_console_device(
|
fn add_virtio_console_device(
|
||||||
&mut self,
|
&mut self,
|
||||||
virtio_devices: &mut Vec<MetaVirtioDevice>,
|
virtio_devices: &mut Vec<MetaVirtioDevice>,
|
||||||
@@ -2161,6 +2285,7 @@ impl DeviceManager {
|
|||||||
Ok(Arc::new(Console { console_resizer }))
|
Ok(Arc::new(Console { console_resizer }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
fn add_tpm_device(
|
fn add_tpm_device(
|
||||||
&mut self,
|
&mut self,
|
||||||
tpm_path: PathBuf,
|
tpm_path: PathBuf,
|
||||||
@@ -3433,6 +3558,7 @@ impl DeviceManager {
|
|||||||
memory_manager.lock().unwrap().memory_slot_allocator(),
|
memory_manager.lock().unwrap().memory_slot_allocator(),
|
||||||
vm_migration::snapshot_from_id(self.snapshot.as_ref(), vfio_name.as_str()),
|
vm_migration::snapshot_from_id(self.snapshot.as_ref(), vfio_name.as_str()),
|
||||||
device_cfg.x_nv_gpudirect_clique,
|
device_cfg.x_nv_gpudirect_clique,
|
||||||
|
device_cfg.path.clone(),
|
||||||
)
|
)
|
||||||
.map_err(DeviceManagerError::VfioPciCreate)?;
|
.map_err(DeviceManagerError::VfioPciCreate)?;
|
||||||
|
|
||||||
@@ -3906,7 +4032,7 @@ impl DeviceManager {
|
|||||||
&self.pci_segments
|
&self.pci_segments
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
pub fn cmdline_additions(&self) -> &[String] {
|
pub fn cmdline_additions(&self) -> &[String] {
|
||||||
self.cmdline_additions.as_slice()
|
self.cmdline_additions.as_slice()
|
||||||
}
|
}
|
||||||
@@ -4492,6 +4618,7 @@ impl DeviceManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
pub(crate) fn acpi_platform_addresses(&self) -> &AcpiPlatformAddresses {
|
pub(crate) fn acpi_platform_addresses(&self) -> &AcpiPlatformAddresses {
|
||||||
&self.acpi_platform_addresses
|
&self.acpi_platform_addresses
|
||||||
}
|
}
|
||||||
@@ -4517,8 +4644,10 @@ fn numa_node_id_from_pci_segment_id(numa_nodes: &NumaNodes, pci_segment_id: u16)
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
struct TpmDevice {}
|
struct TpmDevice {}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
impl Aml for TpmDevice {
|
impl Aml for TpmDevice {
|
||||||
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
|
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
|
||||||
aml::Device::new(
|
aml::Device::new(
|
||||||
@@ -4540,6 +4669,7 @@ impl Aml for TpmDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
impl Aml for DeviceManager {
|
impl Aml for DeviceManager {
|
||||||
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
|
fn to_aml_bytes(&self, sink: &mut dyn acpi_tables::AmlSink) {
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use std::path::PathBuf;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{Receiver, RecvError, SendError, Sender};
|
use std::sync::mpsc::{Receiver, RecvError, SendError, Sender};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{io, result, thread};
|
use std::{io, result, thread};
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ use crate::vm_config::{
|
|||||||
VmConfig, VsockConfig,
|
VmConfig, VsockConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
mod acpi;
|
mod acpi;
|
||||||
pub mod api;
|
pub mod api;
|
||||||
mod clone3;
|
mod clone3;
|
||||||
@@ -940,6 +942,7 @@ impl Vmm {
|
|||||||
MigratableError::MigrateReceive(anyhow!("Error cloning activate EventFd: {}", e))
|
MigratableError::MigrateReceive(anyhow!("Error cloning activate EventFd: {}", e))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
let timestamp = Instant::now();
|
let timestamp = Instant::now();
|
||||||
let hypervisor_vm = mm.lock().unwrap().vm.clone();
|
let hypervisor_vm = mm.lock().unwrap().vm.clone();
|
||||||
let mut vm = Vm::new_from_memory_manager(
|
let mut vm = Vm::new_from_memory_manager(
|
||||||
@@ -953,6 +956,7 @@ impl Vmm {
|
|||||||
&self.seccomp_action,
|
&self.seccomp_action,
|
||||||
self.hypervisor.clone(),
|
self.hypervisor.clone(),
|
||||||
activate_evt,
|
activate_evt,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
timestamp,
|
timestamp,
|
||||||
self.console_info.clone(),
|
self.console_info.clone(),
|
||||||
self.console_resize_pipe.clone(),
|
self.console_resize_pipe.clone(),
|
||||||
@@ -1205,9 +1209,6 @@ impl Vmm {
|
|||||||
|
|
||||||
// Send last batch of dirty pages
|
// Send last batch of dirty pages
|
||||||
Self::vm_maybe_send_dirty_pages(vm, &mut socket)?;
|
Self::vm_maybe_send_dirty_pages(vm, &mut socket)?;
|
||||||
|
|
||||||
// Stop logging dirty pages
|
|
||||||
vm.stop_dirty_log()?;
|
|
||||||
}
|
}
|
||||||
// Capture snapshot and send it
|
// Capture snapshot and send it
|
||||||
let vm_snapshot = vm.snapshot()?;
|
let vm_snapshot = vm.snapshot()?;
|
||||||
@@ -1227,6 +1228,11 @@ impl Vmm {
|
|||||||
MigratableError::MigrateSend(anyhow!("Error completing migration")),
|
MigratableError::MigrateSend(anyhow!("Error completing migration")),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Stop logging dirty pages
|
||||||
|
if !send_data_migration.local {
|
||||||
|
vm.stop_dirty_log()?;
|
||||||
|
}
|
||||||
|
|
||||||
info!("Migration complete");
|
info!("Migration complete");
|
||||||
|
|
||||||
// Let every Migratable object know about the migration being complete
|
// Let every Migratable object know about the migration being complete
|
||||||
@@ -2278,14 +2284,16 @@ impl RequestHandler for Vmm {
|
|||||||
vm,
|
vm,
|
||||||
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
||||||
self.hypervisor.clone(),
|
self.hypervisor.clone(),
|
||||||
send_data_migration,
|
send_data_migration.clone(),
|
||||||
)
|
)
|
||||||
.map_err(|migration_err| {
|
.map_err(|migration_err| {
|
||||||
error!("Migration failed: {:?}", migration_err);
|
error!("Migration failed: {:?}", migration_err);
|
||||||
|
|
||||||
// Stop logging dirty pages
|
// Stop logging dirty pages only for non-local migrations
|
||||||
if let Err(e) = vm.stop_dirty_log() {
|
if !send_data_migration.local {
|
||||||
return e;
|
if let Err(e) = vm.stop_dirty_log() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if vm.get_state().unwrap() == VmState::Paused {
|
if vm.get_state().unwrap() == VmState::Paused {
|
||||||
|
|||||||
@@ -1246,6 +1246,11 @@ impl MemoryManager {
|
|||||||
memory_manager.add_uefi_flash()?;
|
memory_manager.add_uefi_flash()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
{
|
||||||
|
memory_manager.allocate_address_space()?;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
if let Some(sgx_epc_config) = sgx_epc_config {
|
if let Some(sgx_epc_config) = sgx_epc_config {
|
||||||
memory_manager.setup_sgx(sgx_epc_config)?;
|
memory_manager.setup_sgx(sgx_epc_config)?;
|
||||||
@@ -1607,6 +1612,7 @@ impl MemoryManager {
|
|||||||
.checked_add(1)
|
.checked_add(1)
|
||||||
.ok_or(Error::GuestAddressOverFlow)?;
|
.ok_or(Error::GuestAddressOverFlow)?;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
if mem_end < arch::layout::MEM_32BIT_RESERVED_START {
|
if mem_end < arch::layout::MEM_32BIT_RESERVED_START {
|
||||||
return Ok(arch::layout::RAM_64BIT_START);
|
return Ok(arch::layout::RAM_64BIT_START);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ impl PciSegment {
|
|||||||
Ok(segment)
|
Ok(segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
pub(crate) fn new_default_segment(
|
pub(crate) fn new_default_segment(
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
|
|||||||
@@ -166,6 +166,12 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, Backe
|
|||||||
MSHV_INITIALIZE_PARTITION()
|
MSHV_INITIALIZE_PARTITION()
|
||||||
)?],
|
)?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?],
|
||||||
|
and![Cond::new(
|
||||||
|
1,
|
||||||
|
ArgLen::Dword,
|
||||||
|
Eq,
|
||||||
|
MSHV_GET_HOST_PARTITION_PROPERTY()
|
||||||
|
)?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_VP())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_VP())?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IRQFD())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IRQFD())?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IOEVENTFD())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IOEVENTFD())?],
|
||||||
@@ -173,7 +179,9 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, Backe
|
|||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_REGISTERS())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_REGISTERS())?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_REGISTERS())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_REGISTERS())?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_RUN_VP())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_RUN_VP())?],
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_STATE())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_STATE())?],
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_STATE())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_STATE())?],
|
||||||
and![Cond::new(
|
and![Cond::new(
|
||||||
1,
|
1,
|
||||||
@@ -194,6 +202,7 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, Backe
|
|||||||
MSHV_GET_GPAP_ACCESS_BITMAP()
|
MSHV_GET_GPAP_ACCESS_BITMAP()
|
||||||
)?],
|
)?],
|
||||||
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?],
|
and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?],
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
and![Cond::new(
|
and![Cond::new(
|
||||||
1,
|
1,
|
||||||
ArgLen::Dword,
|
ArgLen::Dword,
|
||||||
@@ -447,7 +456,13 @@ fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>
|
|||||||
Ok(arch_rules)
|
Ok(arch_rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "mshv"))]
|
#[cfg(all(target_arch = "riscv64", feature = "kvm"))]
|
||||||
|
fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError> {
|
||||||
|
let common_rules = create_vmm_ioctl_seccomp_rule_common(HypervisorType::Kvm)?;
|
||||||
|
Ok(common_rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mshv")]
|
||||||
fn create_vmm_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError> {
|
fn create_vmm_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError> {
|
||||||
create_vmm_ioctl_seccomp_rule_common(HypervisorType::Mshv)
|
create_vmm_ioctl_seccomp_rule_common(HypervisorType::Mshv)
|
||||||
}
|
}
|
||||||
@@ -825,6 +840,7 @@ fn http_api_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>
|
|||||||
Ok(vec![
|
Ok(vec![
|
||||||
(libc::SYS_accept4, vec![]),
|
(libc::SYS_accept4, vec![]),
|
||||||
(libc::SYS_brk, vec![]),
|
(libc::SYS_brk, vec![]),
|
||||||
|
(libc::SYS_clock_gettime, vec![]),
|
||||||
(libc::SYS_close, vec![]),
|
(libc::SYS_close, vec![]),
|
||||||
(libc::SYS_dup, vec![]),
|
(libc::SYS_dup, vec![]),
|
||||||
(libc::SYS_epoll_create1, vec![]),
|
(libc::SYS_epoll_create1, vec![]),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use std::{io, result, thread};
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::legacy::Pl011;
|
use devices::legacy::Pl011;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
use devices::legacy::Serial;
|
use devices::legacy::Serial;
|
||||||
use libc::EFD_NONBLOCK;
|
use libc::EFD_NONBLOCK;
|
||||||
use serial_buffer::SerialBuffer;
|
use serial_buffer::SerialBuffer;
|
||||||
@@ -108,7 +108,7 @@ impl From<u64> for EpollDispatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct SerialManager {
|
pub struct SerialManager {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
serial: Arc<Mutex<Serial>>,
|
serial: Arc<Mutex<Serial>>,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
serial: Arc<Mutex<Pl011>>,
|
serial: Arc<Mutex<Pl011>>,
|
||||||
@@ -122,7 +122,7 @@ pub struct SerialManager {
|
|||||||
|
|
||||||
impl SerialManager {
|
impl SerialManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
#[cfg(target_arch = "x86_64")] serial: Arc<Mutex<Serial>>,
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] serial: Arc<Mutex<Serial>>,
|
||||||
#[cfg(target_arch = "aarch64")] serial: Arc<Mutex<Pl011>>,
|
#[cfg(target_arch = "aarch64")] serial: Arc<Mutex<Pl011>>,
|
||||||
mut output: ConsoleOutput,
|
mut output: ConsoleOutput,
|
||||||
socket: Option<PathBuf>,
|
socket: Option<PathBuf>,
|
||||||
@@ -226,7 +226,7 @@ impl SerialManager {
|
|||||||
// after the connection happened, and if that's the case it flushes
|
// after the connection happened, and if that's the case it flushes
|
||||||
// all output from the serial to the PTY. Otherwise, it's a no-op.
|
// all output from the serial to the PTY. Otherwise, it's a no-op.
|
||||||
fn trigger_pty_flush(
|
fn trigger_pty_flush(
|
||||||
#[cfg(target_arch = "x86_64")] serial: &Arc<Mutex<Serial>>,
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] serial: &Arc<Mutex<Serial>>,
|
||||||
#[cfg(target_arch = "aarch64")] serial: &Arc<Mutex<Pl011>>,
|
#[cfg(target_arch = "aarch64")] serial: &Arc<Mutex<Pl011>>,
|
||||||
pty_write_out: Option<&Arc<AtomicBool>>,
|
pty_write_out: Option<&Arc<AtomicBool>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
|||||||
139
vmm/src/vm.rs
139
vmm/src/vm.rs
@@ -20,6 +20,7 @@ use std::num::Wrapping;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{cmp, result, str, thread};
|
use std::{cmp, result, str, thread};
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ use anyhow::anyhow;
|
|||||||
use arch::layout::{KVM_IDENTITY_MAP_START, KVM_TSS_START};
|
use arch::layout::{KVM_IDENTITY_MAP_START, KVM_TSS_START};
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
use arch::x86_64::tdx::TdvfSection;
|
use arch::x86_64::tdx::TdvfSection;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
use arch::PciSpaceInfo;
|
use arch::PciSpaceInfo;
|
||||||
use arch::{get_host_cpu_phys_bits, EntryPoint, NumaNode, NumaNodes};
|
use arch::{get_host_cpu_phys_bits, EntryPoint, NumaNode, NumaNodes};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@@ -47,7 +48,7 @@ use linux_loader::elf;
|
|||||||
use linux_loader::loader::bzimage::BzImage;
|
use linux_loader::loader::bzimage::BzImage;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
|
use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
use linux_loader::loader::pe::Error::InvalidImageMagicNumber;
|
use linux_loader::loader::pe::Error::InvalidImageMagicNumber;
|
||||||
use linux_loader::loader::KernelLoader;
|
use linux_loader::loader::KernelLoader;
|
||||||
use seccompiler::SeccompAction;
|
use seccompiler::SeccompAction;
|
||||||
@@ -466,8 +467,10 @@ pub struct Vm {
|
|||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
saved_clock: Option<hypervisor::ClockData>,
|
saved_clock: Option<hypervisor::ClockData>,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
numa_nodes: NumaNodes,
|
numa_nodes: NumaNodes,
|
||||||
#[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))]
|
#[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))]
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
stop_on_boot: bool,
|
stop_on_boot: bool,
|
||||||
load_payload_handle: Option<thread::JoinHandle<Result<EntryPoint>>>,
|
load_payload_handle: Option<thread::JoinHandle<Result<EntryPoint>>>,
|
||||||
@@ -487,7 +490,7 @@ impl Vm {
|
|||||||
seccomp_action: &SeccompAction,
|
seccomp_action: &SeccompAction,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
activate_evt: EventFd,
|
activate_evt: EventFd,
|
||||||
timestamp: Instant,
|
#[cfg(not(target_arch = "riscv64"))] timestamp: Instant,
|
||||||
console_info: Option<ConsoleInfo>,
|
console_info: Option<ConsoleInfo>,
|
||||||
console_resize_pipe: Option<Arc<File>>,
|
console_resize_pipe: Option<Arc<File>>,
|
||||||
original_termios: Arc<Mutex<Option<termios>>>,
|
original_termios: Arc<Mutex<Option<termios>>>,
|
||||||
@@ -634,6 +637,7 @@ impl Vm {
|
|||||||
&activate_evt,
|
&activate_evt,
|
||||||
force_iommu,
|
force_iommu,
|
||||||
boot_id_list,
|
boot_id_list,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
timestamp,
|
timestamp,
|
||||||
snapshot_from_id(snapshot.as_ref(), DEVICE_MANAGER_SNAPSHOT_ID),
|
snapshot_from_id(snapshot.as_ref(), DEVICE_MANAGER_SNAPSHOT_ID),
|
||||||
dynamic,
|
dynamic,
|
||||||
@@ -694,7 +698,9 @@ impl Vm {
|
|||||||
vm,
|
vm,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
saved_clock,
|
saved_clock,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
numa_nodes,
|
numa_nodes,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
hypervisor,
|
hypervisor,
|
||||||
stop_on_boot,
|
stop_on_boot,
|
||||||
load_payload_handle,
|
load_payload_handle,
|
||||||
@@ -803,6 +809,7 @@ impl Vm {
|
|||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
trace_scoped!("Vm::new");
|
trace_scoped!("Vm::new");
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
let timestamp = Instant::now();
|
let timestamp = Instant::now();
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
@@ -873,6 +880,7 @@ impl Vm {
|
|||||||
seccomp_action,
|
seccomp_action,
|
||||||
hypervisor,
|
hypervisor,
|
||||||
activate_evt,
|
activate_evt,
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
timestamp,
|
timestamp,
|
||||||
console_info,
|
console_info,
|
||||||
console_resize_pipe,
|
console_resize_pipe,
|
||||||
@@ -943,14 +951,16 @@ impl Vm {
|
|||||||
|
|
||||||
pub fn generate_cmdline(
|
pub fn generate_cmdline(
|
||||||
payload: &PayloadConfig,
|
payload: &PayloadConfig,
|
||||||
#[cfg(target_arch = "aarch64")] device_manager: &Arc<Mutex<DeviceManager>>,
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] device_manager: &Arc<
|
||||||
|
Mutex<DeviceManager>,
|
||||||
|
>,
|
||||||
) -> Result<Cmdline> {
|
) -> Result<Cmdline> {
|
||||||
let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE).map_err(Error::CmdLineCreate)?;
|
let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE).map_err(Error::CmdLineCreate)?;
|
||||||
if let Some(s) = payload.cmdline.as_ref() {
|
if let Some(s) = payload.cmdline.as_ref() {
|
||||||
cmdline.insert_str(s).map_err(Error::CmdLineInsertStr)?;
|
cmdline.insert_str(s).map_err(Error::CmdLineInsertStr)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
for entry in device_manager.lock().unwrap().cmdline_additions() {
|
for entry in device_manager.lock().unwrap().cmdline_additions() {
|
||||||
cmdline.insert_str(entry).map_err(Error::CmdLineInsertStr)?;
|
cmdline.insert_str(entry).map_err(Error::CmdLineInsertStr)?;
|
||||||
}
|
}
|
||||||
@@ -1005,6 +1015,47 @@ impl Vm {
|
|||||||
Ok(EntryPoint { entry_addr })
|
Ok(EntryPoint { entry_addr })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
fn load_kernel(
|
||||||
|
firmware: Option<File>,
|
||||||
|
kernel: Option<File>,
|
||||||
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
|
) -> Result<EntryPoint> {
|
||||||
|
let guest_memory = memory_manager.lock().as_ref().unwrap().guest_memory();
|
||||||
|
let mem = guest_memory.memory();
|
||||||
|
let alignment = 0x20_0000;
|
||||||
|
let aligned_kernel_addr = arch::layout::KERNEL_START.0 + (alignment - 1) & !(alignment - 1);
|
||||||
|
let entry_addr = match (firmware, kernel) {
|
||||||
|
(None, Some(mut kernel)) => {
|
||||||
|
match linux_loader::loader::pe::PE::load(
|
||||||
|
mem.deref(),
|
||||||
|
Some(GuestAddress(aligned_kernel_addr)),
|
||||||
|
&mut kernel,
|
||||||
|
None,
|
||||||
|
) {
|
||||||
|
Ok(entry_addr) => entry_addr.kernel_load,
|
||||||
|
// Try to load the binary as kernel PE file at first.
|
||||||
|
// If failed, retry to load it as UEFI binary.
|
||||||
|
// As the UEFI binary is formatless, it must be the last option to try.
|
||||||
|
Err(linux_loader::loader::Error::Pe(InvalidImageMagicNumber)) => {
|
||||||
|
// TODO: UEFI for riscv64 is scheduled to next stage.
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error::KernelLoad(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some(_firmware), None) => {
|
||||||
|
// TODO: UEFI for riscv64 is scheduled to next stage.
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
_ => return Err(Error::InvalidPayload),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(EntryPoint { entry_addr })
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "igvm")]
|
#[cfg(feature = "igvm")]
|
||||||
fn load_igvm(
|
fn load_igvm(
|
||||||
igvm: File,
|
igvm: File,
|
||||||
@@ -1133,7 +1184,7 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
fn load_payload(
|
fn load_payload(
|
||||||
payload: &PayloadConfig,
|
payload: &PayloadConfig,
|
||||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
@@ -1351,6 +1402,72 @@ impl Vm {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
fn configure_system(&mut self) -> Result<()> {
|
||||||
|
let cmdline = Self::generate_cmdline(
|
||||||
|
self.config.lock().unwrap().payload.as_ref().unwrap(),
|
||||||
|
&self.device_manager,
|
||||||
|
)?;
|
||||||
|
let num_vcpu = self.cpu_manager.lock().unwrap().vcpus().len();
|
||||||
|
let mem = self.memory_manager.lock().unwrap().boot_guest_memory();
|
||||||
|
let mut pci_space_info: Vec<PciSpaceInfo> = Vec::new();
|
||||||
|
let initramfs_config = match self.initramfs {
|
||||||
|
Some(_) => Some(self.load_initramfs(&mem)?),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_info = &self
|
||||||
|
.device_manager
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_device_info()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
for pci_segment in self.device_manager.lock().unwrap().pci_segments().iter() {
|
||||||
|
let pci_space = PciSpaceInfo {
|
||||||
|
pci_segment_id: pci_segment.id,
|
||||||
|
mmio_config_address: pci_segment.mmio_config_address,
|
||||||
|
pci_device_space_start: pci_segment.start_of_mem64_area,
|
||||||
|
pci_device_space_size: pci_segment.end_of_mem64_area
|
||||||
|
- pci_segment.start_of_mem64_area
|
||||||
|
+ 1,
|
||||||
|
};
|
||||||
|
pci_space_info.push(pci_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: IOMMU for riscv64 is not yet support in kernel.
|
||||||
|
|
||||||
|
let vaia = self
|
||||||
|
.device_manager
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_interrupt_controller()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_vaia()
|
||||||
|
.map_err(|_| {
|
||||||
|
Error::ConfigureSystem(arch::Error::PlatformSpecific(
|
||||||
|
arch::riscv64::Error::SetupAia,
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// TODO: PMU support for riscv64 is scheduled to next stage.
|
||||||
|
|
||||||
|
arch::configure_system(
|
||||||
|
&mem,
|
||||||
|
cmdline.as_cstring().unwrap().to_str().unwrap(),
|
||||||
|
num_vcpu as u32,
|
||||||
|
device_info,
|
||||||
|
&initramfs_config,
|
||||||
|
&pci_space_info,
|
||||||
|
&vaia,
|
||||||
|
)
|
||||||
|
.map_err(Error::ConfigureSystem)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn console_resize_pipe(&self) -> Option<Arc<File>> {
|
pub fn console_resize_pipe(&self) -> Option<Arc<File>> {
|
||||||
self.device_manager.lock().unwrap().console_resize_pipe()
|
self.device_manager.lock().unwrap().console_resize_pipe()
|
||||||
}
|
}
|
||||||
@@ -2017,6 +2134,7 @@ impl Vm {
|
|||||||
// In case of TDX being used, this is a no-op since the tables will be
|
// In case of TDX being used, this is a no-op since the tables will be
|
||||||
// created and passed when populating the HOB.
|
// created and passed when populating the HOB.
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
fn create_acpi_tables(&self) -> Option<GuestAddress> {
|
fn create_acpi_tables(&self) -> Option<GuestAddress> {
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if self.config.lock().unwrap().is_tdx_enabled() {
|
if self.config.lock().unwrap().is_tdx_enabled() {
|
||||||
@@ -2118,6 +2236,7 @@ impl Vm {
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
let rsdp_addr = self.create_acpi_tables();
|
let rsdp_addr = self.create_acpi_tables();
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "riscv64"))]
|
||||||
// Configure shared state based on loaded kernel
|
// Configure shared state based on loaded kernel
|
||||||
entry_point
|
entry_point
|
||||||
.map(|entry_point| {
|
.map(|entry_point| {
|
||||||
@@ -2127,6 +2246,9 @@ impl Vm {
|
|||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
self.configure_system().unwrap();
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
// Note: For x86, always call this function before invoking start boot vcpus.
|
// Note: For x86, always call this function before invoking start boot vcpus.
|
||||||
// Otherwise guest would fail to boot because we haven't created the
|
// Otherwise guest would fail to boot because we haven't created the
|
||||||
@@ -2327,6 +2449,11 @@ impl Vm {
|
|||||||
.map_err(Error::PowerButton)
|
.map_err(Error::PowerButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
pub fn power_button(&self) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn memory_manager_data(&self) -> MemoryManagerSnapshotData {
|
pub fn memory_manager_data(&self) -> MemoryManagerSnapshotData {
|
||||||
self.memory_manager.lock().unwrap().snapshot_data()
|
self.memory_manager.lock().unwrap().snapshot_data()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,7 +486,8 @@ pub struct PmemConfig {
|
|||||||
|
|
||||||
impl ApplyLandlock for PmemConfig {
|
impl ApplyLandlock for PmemConfig {
|
||||||
fn apply_landlock(&self, landlock: &mut Landlock) -> LandlockResult<()> {
|
fn apply_landlock(&self, landlock: &mut Landlock) -> LandlockResult<()> {
|
||||||
landlock.add_rule_with_access(self.file.to_path_buf(), "rw")?;
|
let access = if self.discard_writes { "r" } else { "rw" };
|
||||||
|
landlock.add_rule_with_access(self.file.to_path_buf(), access)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user