Commit Graph

37 Commits

Author SHA1 Message Date
Rob Bradford
3b9229e434 build: Consolidate sev_snp feature usage
Since igvm is a required feature of sev_snp and also sev_snp is x86-64
only the cfg attributes at build time can be consolidated & simplified.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 22:29:26 +00:00
Tushar Khatri
b059475dfb vmm: reevaluate #[allow] attributes
Remove stale #[allow]s whose lints no longer fire, convert the
unconditionally-firing ones to #[expect], and keep the
arch/feature-conditional ones as #[allow]. Verified across kvm/mshv,
x86_64/aarch64, and --all-features.

Part of #8326.

Signed-off-by: Tushar Khatri <hello@tusharkhatri.in>
2026-06-11 19:06:49 +00:00
Philipp Schuster
360e155cac vmm: replace #[allow(dead_code)] with expect()
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Philipp Schuster
f1f02e7144 vmm: remove unneeded #[allow(dead_code)]
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Julian Schindel
9a0fb1b06a vmm: fix UB in load_igvm(...)
With the `mshv` feature enabled, the immutable `data` `Vec` is mutated
via a pointer. This violates Rust aliasing rules. Fixed by cloning the
`Vec` to a mutable instance when the `mshv` feature is active.

Signed-off-by: Julian Schindel <mail@arctic-alpaca.de>
2026-05-04 08:22:29 +00:00
Ruben Hakobyan
c97d635d40 hypervisor, vmm: Build and pass SNP ID block to launch finish
Add KvmSevSnpIdBlock and KvmSevSnpIdAuth structs matching the AMD
SEV-SNP Firmware ABI Spec (Rev 1.58), and build them from the IGVM
SNP ID block directive during launch finish. This properly populates
id_block_uaddr/id_auth_uaddr in KVM_SEV_SNP_LAUNCH_FINISH and derives
auth_key_en from the assembled author key, matching QEMU's behavior.

Thread the guest policy from sev_snp_init to launch_finish via an
atomic on KvmVm so the ID block gets the correct policy value.

Also track has_snp_id_block in IgvmLoadedInfo to enable the ID block
based on whether the IGVM file actually contains one, rather than
hardcoding it for KVM.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-05-01 20:28:55 +00:00
Ruben Hakobyan
bfab43e252 vmm: Parse guest policy from IGVM initialization headers
Extract the SNP guest policy from IGVM initialization headers when
available, falling back to the default policy. This matches QEMU's
behaviour where only a non-zero IGVM policy overrides the default.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
4a91b4a608 vmm: Preserve SEV-SNP IGVM load ordering
Preserve the original IGVM import order for KVM SNP launch updates.
The launch digest is order-sensitive, so only coalesce adjacent pages
that already share the same page type and size. MSHV continues to
sort by GPA for hypercall batching.

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
982934fba0 vmm: Add SNP zero-page type for IGVM imports
Introduce the KVM_SNP_PAGE_TYPE_ZERO page type for ZERO
pages. AMD SEV SNP can accept ZERO pages as a page in which
the page memory is functionally just zeroes

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
70388fb1bb vmm: Introduce kernel hashes measured boot
This introduces the kernel hashes measured boot table into
cloud hypervisor if a cmdline and kernel is passed into an
SEV-SNP CVM, incorporating a kernel/cmdline/optional initrd
into a memory page that is measured into the launch digest
of a SEV-SNP CVM. If both --kernel and --cmdline are not
provided, we do not insert this data page

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Muminul Islam
4608de134f vmm: igvm: gate CPUID page read with runtime hypervisor check
The SnpCpuidInfo allocation and guest_memory.read() call in the
isolated page import loop are only needed for KVM's CPUID page
retry logic. However, when building with both 'mshv' and 'kvm'
features, #[cfg(feature = "kvm")] alone is insufficient as a
guard because both features compile into the same binary.

Without a runtime hypervisor type check, this code executes on
MSHV as well, reading guest memory at arbitrary GPAs that may
not be valid in the MSHV memory layout. This can cause undefined
behavior or crashes during IGVM loading.

Add #[cfg(feature = "kvm")] to the variable declarations and
wrap the guest_memory.read() call in a runtime check for
HypervisorType::Kvm to ensure it only executes on KVM.

Assisted-by: Claude:Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-04-30 10:39:28 +00:00
Muminul Islam
7d24608bcf vmm: igvm: use correct MSHV page types for CPUID and secrets
The PageTypeConfig for MSHV incorrectly mapped the cpuid field
to HV_ISOLATED_PAGE_TYPE_NORMAL (0) and the secrets field to
HV_ISOLATED_PAGE_TYPE_UNMEASURED (3).

The correct MSHV page type constants are:
- CPUID pages: HV_ISOLATED_PAGE_TYPE_CPUID (5)
- Secrets pages: HV_ISOLATED_PAGE_TYPE_SECRETS (4)

This was introduced in commit 75ed2c9f90 ("vmm: add KVM
SEV-SNP support to IGVM loader") which abstracted page types
into a PageTypeConfig struct but assigned wrong values for the
MSHV variant. Using incorrect page types causes the MSHV
hypervisor to reject or mishandle isolated page imports,
leading to guest boot failure.

Assisted-by: Claude:Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-04-30 10:39:28 +00:00
Ruben Hakobyan
75ed2c9f90 vmm: add KVM SEV-SNP support to IGVM loader
Adapt the IGVM loader to work with both MSHV and KVM backends, which
differ in page type constants, CPUID page layout, and VMSA handling.

Abstract page types into a PageTypeConfig struct populated at runtime
from the detected hypervisor, replacing hardcoded mshv_bindings constants.

Apply the VMSA register state to each vCPU via setup_sev_snp_regs(),
translating SevSelector attributes to KVM segment format using a bitfield
decoder.

KVM's SNP launch path sanitizes certain CPUID bits that could lead to
an insecure guest. If the VMM sets these bits, KVM rejects the CPUID
page import on the first attempt, requiring a retry with the
firmware-corrected values.

Pre-clear the known problematic bits before import to avoid the
reject-and-retry cycle:

- Leaf 0x1, ECX bit 24: TSC_DEADLINE (filtered by KVM)
- Leaf 0x7, EBX bit 1: SGX (filtered by KVM)
- Leaf 0x7, EDX: clear entirely (contains speculative features)
- Leaf 0x80000008, EBX bit 25: filtered by KVM
- Leaf 0x80000021, ECX: clear entirely

This keeps the CPUID page stable across launch updates and avoids
noisy error logs from the retry path.

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Co-authored-by: Dylan Reid <dgreid@fb.com>
Signed-off-by: Dylan Reid <dgreid@fb.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
24db5e1efd hypervisor, vmm: Add support for KVM_SEV_SNP_LAUNCH_UPDATE
Implement the KVM_SEV_SNP_LAUNCH_UPDATE ioctl.

Extend Vm::import_isolated_pages() with a uaddrs parameter carrying
host virtual addresses, which KVM needs, unlike MSHV. Compute uaddrs
from guest memory mappings in the IGVM loader.

Add KVM_SEV_SNP_LAUNCH_UPDATE to the seccomp allowlist.

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
2e004521e0 hypervisor, vmm: Add KVM SEV_{INIT2, SNP_LAUNCH_START} support
Introduce the SevFd abstraction that wraps /dev/sev and implements the
KVM_SEV_INIT2 and KVM_SEV_SNP_LAUNCH_START ioctls for SEV-SNP VM
initialization on KVM.

Key changes:
- Add sev.rs with KvmSevInit and KvmSevSnpLaunchStart ioctl structs
  matching the kernel layout (linux/arch/x86/include/uapi/asm/kvm.h)
- Implement KVM_SEV_INIT2 and KVM_SEV_SNP_LAUNCH_START ioctls
- Set KVM_MEMORY_ATTRIBUTE_PRIVATE on newly created memory regions
  when guest_memfd is supported
- Widen SevSnpPageAccessProxy cfg gates from mshv-only to all
  sev_snp-enabled builds
- Make sev_snp_init a required trait method (remove default impl)
- Include KVM_SEV_SNP_LAUNCH_START in the seccomp allowlist
- Parse VMSA SEV features from IGVM and include them in the
  KVM_SEV_INIT2 ioctl

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Co-authored-by: Rob Bradford <rbradford@meta.com>
Signed-off-by: Rob Bradford <rbradford@meta.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
425609a8b5 vmm: parse IGVM file early and thread it through VM setup
Move IGVM file parsing from load_igvm() into a dedicated parse_igvm()
helper in igvm/mod.rs, and parse the file upfront in Vm::new() so the
resulting IgvmFile struct is available throughout VM initialization.

This is a prerequisite for extracting VMSA SEV features from the parsed
IGVM before issuing KVM_SEV_INIT2, which needs sev_features.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Anatol Belski
4ebbbe2294 vmm: igvm: Use sort_by_key instead of sort_by
Do the necessary replacement to satisfy clippy::unnecessary_sort_by.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-06 12:32:38 +00:00
Muminul Islam
c9cd82b52b vmm: fix CVM boot failure on MSHV
Recent changes related to arm64 support in MSHV exposed
inconsistencies in the VM initialization and CVM boot paths.
The VM creation flow currently diverges across multiple scenarios,
including regular MSHV, CVM, and arm64, with each path performing
guest initialization steps in a different order.
Certain platform-specific requirements further constrain the ordering
of operations, such as the timing of address space creation,
IGVM loading, interrupt controller setup, and payload loading. For
CVM case address-space creation must be done after IGVM loading, and
PSP measurement. For Regular and arm64 this memory initialization
must be done early. For MSHV, vm.init() and sev_snp.init() are called in
different order which is run time and build time conditionally checked.

Additionally, while the KVM initialization path differs slightly
from MSHV, it shares common logic that is currently split across
separate conditional and build-time code paths, contributing to
fragmentation of the overall flow.

This change restructures the VM creation and initialization sequence
to better align shared logic, enforce scenario-specific ordering
constraints, and ensure consistent and correct behavior across all
supported configurations. In doing so, it restores proper CVM boot
behavior and improves the maintainability of the initialization code.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-01-21 19:40:17 +00:00
Philipp Schuster
c53781bf5f misc: clippy: add needless_pass_by_value
This is a follow-up of [0].

# Advantages

- This saves dozens of unneeded clone()s across the whole code base
- Makes it much easier to reason about how parameters are used
  (often we passed owned Arc/Rc versions without actually needing
  ownership)

# Exceptions

For certain code paths, the alternatives would require awkward or overly
complex code, and in some cases the functions are the logical owners of
the values they take. In those cases, I've added
#[allow(clippy::needless_pass_by_value)].

This does not mean that one should not improve this in the future.

[0] 6a86c157af

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-27 17:11:14 +00:00
Philipp Schuster
67fc9d990e misc: vmm: drop extern crate, use modern rust
This commit is part of a series of similar commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-24 22:36:46 +00:00
Philipp Schuster
c995b72384 build: treewide: clippy: collapse nested ifs, use let chains
This bumps the MSRV to 1.88 (also, Rust edition 2024 is mandatory).

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Songqian Li
cd2c43b489 misc: Fix beta clippy errors
Fix clippy error: "error: manual implementation of `.is_multiple_of()
`" from rustc 1.90.0-beta.1 (788da80fc 2025-08-04).

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-07 16:53:59 +00:00
Philipp Schuster
d7edd9d51f misc: vmm: streamline error Display::fmt()
The changes were mostly automatically applied using the following
Python script:

```python
import os, re

for root, _, files in os.walk("."):
    for f in files:
        if not f.endswith(".rs"):
            continue
        p = os.path.join(root, f)
        with open(p, "r", encoding="utf-8") as file:
            lines = file.readlines()
        changed = False
        for i in range(len(lines) - 1):
            if re.search(r'#\[error\(".*: \{0[^}]*\}"\)\]', lines[i]) and "#[source]" in lines[i + 1].strip():
                lines[i] = re.sub(r': \{0[^}]*\}"\)\]', '")]', lines[i])
                changed = True
        if changed:
            with open(p, "w", encoding="utf-8") as file:
                file.writelines(lines)
            print("Fixed:", p)
```

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com

# Conflicts:
#	vmm/src/api/http/mod.rs
2025-06-13 19:55:54 +00:00
Ruoqing He
af28569611 build: Bump zerocopy and acpi_tables
Manually bump zerocopy to 0.8.24 since our dependabot could not perform
the upgrade properly.

Manually bump acpi_tabls as well since it's depending on zerocopy.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-04-13 08:06:11 +00:00
Ruoqing He
61e57e1cb1 misc: Further improve imports styling
By introducing `imports_granularity="Module"` format strategy,
effectively groups imports from the same module into one line or block,
improving maintainability and readability.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2024-09-29 16:13:48 +00:00
Rob Bradford
88a9f79944 misc: Adapt consistent import style formatting
Historically the Cloud Hypervisor coding style has been to ensure that
all imports are ordered and placed in a single group. Unfortunately
cargo fmt has no support for ensuring that all imports are in a single
group so if whitespace lines were added as part of the import statements
then they would only be odered correctly in the group.

By adopting "group_imports="StdExternalCrate" we can enforce a style
where imports are placed in at most three groups for std, external
crates and the crate itself. Choosing a style enforceable by the tooling
reduces the reviewer burden.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-09-29 13:08:12 +01:00
Wei Liu
f6d99d9a9b build: use released version of the IGVM crates
No functional change.

While at it, consolidate some of the IGVM related import directives.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-04-29 11:13:59 +00:00
Rob Bradford
b89657ea22 hypervisor, vmm: Don't re-export the contents of mshv_bindings::*
The contents of this crate may change and cause conflicts - re-exporting
the contents is unnecessary.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-04-25 20:53:53 +00:00
Muminul Islam
1a4c890f83 vmm: pass host data to SevSnp guest
Host data that is passed to the hypervisor. Then
the firmware includes the data in the attestation report.
The data might include any key or secret that the SevSnp guest
might need later.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-23 13:32:56 -08:00
Thomas Barrett
ce7db3f7c3 arch: x86_64: allow more than 2 E820_RAM ranges
The 'generate_ram_ranges' function currently hardcodes the assumption
that there are only 2 E820 RAM entries. This is not flexible enough to
handle vendor specific memory holes. Returning a Vec is also more
convenient for users of this function.

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

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

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-02-06 14:28:42 -08:00
Muminul Islam
dc68a6e30f vmm: igvm: complete isolated import
Complete the isolated import, telling the
Microsoft hypervisor that import is done so that
MSHV can issue SNP_LAUNCH_FINISH command.

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

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2024-01-08 15:55:39 -08:00
Jinank Jain
9b151d06ca vmm: igvm: Generate memory map for SEV-SNP guests
For SEV-SNP guests we need to provide the extended memory. It follows a
very simple layout and very similar to other x86 guests.

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

Fixes #5993

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

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2023-12-11 13:30:05 +00:00
Muminul Islam
7030b15e63 vmm: Add igvm module and loader module
vmm: Add igvm module and loader module

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

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2023-12-08 09:22:42 -08:00