Skip to content

openvmm, virt_kvm: support cca isolated partitions based on the v15 KVM patch series - #4293

Open
Chris Oo (chris-oo) wants to merge 6 commits into
microsoft:mainfrom
chris-oo:openvmm-kvm-cca-v15-submit
Open

openvmm, virt_kvm: support cca isolated partitions based on the v15 KVM patch series#4293
Chris Oo (chris-oo) wants to merge 6 commits into
microsoft:mainfrom
chris-oo:openvmm-kvm-cca-v15-submit

Conversation

@chris-oo

@chris-oo Chris Oo (chris-oo) commented Aug 20, 2026

Copy link
Copy Markdown
Member

Add support for booting a Linux direct CCA guest using KVM with the v15 cca patch series currently in review on LKML. Note that we do not yet support inplace guest_memfd, but it seems like the patch series works just fine without it. This should support a guest with emulated serial, along with virtio devices exposed over PCIe, similar to the SNP support in KVM and mshv.

Tested via private additional local changes that test VM boot in FVP and QEMU with new incubator definitions and vmm_tests. Support for those will come in future changes, once they're cleaned up and ready for review.

@chris-oo
Chris Oo (chris-oo) requested a review from a team as a code owner August 20, 2026 20:25
Copilot AI lite review requested due to automatic review settings August 20, 2026 20:25
@github-actions github-actions Bot added Guide unsafe Related to unsafe code labels Aug 20, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds initial support for booting Arm CCA (Realm) isolated guests on the KVM backend, including guestmemfd-backed private memory handling, device/DT address aliasing via the “shared IPA bit”, and user-facing CLI/config validation to constrain unsupported configurations.

Changes:

  • Add CCA-aware KVM partition creation and VP run-loop handling (RMI populate for initial private pages; RIPAS change handling; shared-IPA address normalization for MMIO).
  • Extend the memory subsystem to model guestmemfd “private state” across x86_64 (VM attributes) and aarch64 (guestmemfd-default / CCA).
  • Wire the shared-IPA alias bit through platform info → loader (DT) → device guest memory aliasing, plus CLI/docs updates and validation tests.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vmm_core/virt/src/generic.rs Adds shared_gpa_bit to PlatformInfo so backends can report shared-IPA aliasing.
vmm_core/virt_whp/src/lib.rs Populates shared_gpa_bit: None for WHP backend.
vmm_core/virt_mshv/src/aarch64/mod.rs Populates shared_gpa_bit: None for MSHV aarch64 backend.
vmm_core/virt_kvm/src/memory.rs Generalizes guestmemfd private-state handling and adds CCA RIPAS-change cleanup logic.
vmm_core/virt_kvm/src/lib.rs Adds CCA error types/state, plus CCA-fatal handling and run-error mapping for memory faults.
vmm_core/virt_kvm/src/cca.rs Implements initial Realm page population using KVM_ARM_RMI_POPULATE and error mapping.
vmm_core/virt_kvm/src/arch/x86_64/mod.rs Updates SNP guestmemfd setup to use the new private-state enum.
vmm_core/virt_kvm/src/arch/aarch64/mod.rs Adds CCA partition bring-up, Realm VM creation, IPA-size probing, MMIO shared-bit stripping, and RIPAS-change handling.
vmm_core/virt_hvf/src/lib.rs Populates shared_gpa_bit: None for HVF backend.
vm/kvm/src/lib.rs Adds/updates KVM capability constants and a helper to probe maximum Realm IPA size.
openvmm/openvmm_entry/src/lib.rs Adds CLI/config validation for CCA isolation constraints.
openvmm/openvmm_entry/src/cli_args.rs Adds --isolation cca (aarch64) and option validation + tests (hugetlb/private/vhost-user).
openvmm/openvmm_core/src/worker/vm_loaders/linux.rs Threads shared-IPA bit into DT generation (addresses, PSCI method) for CCA guests.
openvmm/openvmm_core/src/worker/dispatch.rs Adds runtime validation for CCA configs and creates an aliased device GuestMemory for shared-IPA DMA.
openvmm/membacking/src/memory_manager/mod.rs Adds GuestMemoryClient::aliased_guest_memory + tests for shared-IPA aliasing.
Guide/src/reference/openvmm/management/cli.md Documents --isolation cca and its current constraints.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +493 to +498
let private = flags & kvm::KVM_MEMORY_EXIT_FLAG_PRIVATE_UAPI != 0;
let range = MemoryRange::new(gpa..end);
let state = self.memory.lock();
let segments = guest_memfd_range_intersections(range, &state.ranges)
.map_err(map_cca_conversion_error)?;

Create Arm CCA realm VMs with the KVM v15 ABI, probe a supported Realm IPA size, populate initial private pages through RMI, and distinguish CCA guestmemfd-default private state from SNP VM memory attributes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e377cd5-d7c7-4114-8408-e67a5dec5c2b
Copilot AI review requested due to automatic review settings August 20, 2026 20:58
@chris-oo
Chris Oo (chris-oo) force-pushed the openvmm-kvm-cca-v15-submit branch from 5c102ca to b41aa09 Compare August 20, 2026 20:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Comment on lines +1039 to +1042
assert!(matches!(
guest_memfd_range_intersections(range(0x1000, 0x4000), &slots),
Err(KvmError::InvalidMapGpaRange)
));
@chris-oo
Chris Oo (chris-oo) requested a balanced review from Copilot August 20, 2026 21:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (2)

vmm_core/virt_kvm/src/memory.rs:1041

  • This pattern uses the wrong error type: guest_memfd_range_intersections returns MemoryError, and KvmError has no InvalidMapGpaRange variant (and is not imported in x86 test builds). As written, the test target does not compile.
            Err(KvmError::InvalidMapGpaRange)

vmm_core/virt_kvm/src/cca.rs:87

  • KVM_ARM_RMI_POPULATE requires page-aligned base and size, but arbitrary InitialPageImport ranges reach the ioctl without validation, so the newly added UnalignedCcaPopulateRange error is never used and callers instead get an opaque ioctl failure. Validate both the range start and length before resolving the slot.
        for page in &pages {
            let flags = cca_populate_flags(page.import_type)?;

Copilot AI review requested due to automatic review settings August 20, 2026 22:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (2)

openvmm/openvmm_core/src/worker/dispatch.rs:3527

  • This binding is never read—the ACPI closure still accesses self.hypervisor_cfg.with_hv directly. Remove it to avoid the unused-variable warning (and the corresponding clippy failure when warnings are denied).
                let with_hv = self.hypervisor_cfg.with_hv;

vmm_core/virt_kvm/src/cca.rs:127

  • The new CCA import mapping has no automated coverage, even though the analogous SNP import-type mapping is tested in vmm_core/virt_kvm/src/arch/x86_64/snp.rs:37-69. Add cases proving that normal pages are measured, unmeasured pages use zero flags, and every unsupported import type is rejected; otherwise a flag/match regression can silently change Realm measurements or prevent direct boot.
fn cca_populate_flags(import_type: InitialPageImportType) -> Result<u32, KvmError> {
    match import_type {
        InitialPageImportType::Normal => Ok(kvm::KVM_ARM_RMI_POPULATE_FLAGS_MEASURE_UAPI),
        InitialPageImportType::NormalUnmeasured => Ok(0),

@github-actions

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

vmm_core/virt_kvm/src/cca.rs:91

  • This rejects any valid import that spans two KVM slots because private_memory_range_from_slots requires one containing slot, despite the following call explicitly resolving a fully covered multi-slot range. This can occur with supported NUMA layouts: adjacent nodes are separate RAM backings/slots, while the loader merges adjacent imports with identical metadata. Populate each returned segment separately using its own GPA, HVA, and guestmemfd extent, then discard the complete segment list.
            let private_range = private_memory_range_from_slots(page.range, &memory.ranges)
                .map_err(map_cca_private_range_error)?;
            let segments = crate::memory::guest_memfd_range_segments(page.range, &memory.ranges)
                .map_err(map_cca_private_range_error)?;

vmm_core/virt_kvm/src/cca.rs:87

  • InitialPageImport does not require a nonempty, page-aligned range, but this path never validates either condition even though UnalignedCcaPopulateRange was added for that purpose. In particular, a zero-length import skips the ioctl and is reported as successfully populated, while an unaligned import leaks a generic ioctl error. Reject empty or non-page-aligned ranges before processing them.
        for page in &pages {
            let flags = cca_populate_flags(page.import_type)?;

Chris Oo (chris-oo) and others added 5 commits August 21, 2026 10:46
Use the KVM-reported CCA shared GPA bit to build aliased device memory views and advertise shared MMIO addresses to the guest device tree. Mask shared MMIO addresses in KVM before dispatching to device emulation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject unsupported CCA firmware, Hyper-V, memory layout, backing, and device configurations before constructing the VM.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e377cd5-d7c7-4114-8408-e67a5dec5c2b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 602e3e75-e995-466b-8bb1-bf0d094e86e9
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 602e3e75-e995-466b-8bb1-bf0d094e86e9
@chris-oo
Chris Oo (chris-oo) force-pushed the openvmm-kvm-cca-v15-submit branch from f827879 to 592d1ce Compare August 21, 2026 18:08
Copilot AI review requested due to automatic review settings August 21, 2026 18:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Comment on lines +88 to +91
let private_range = private_memory_range_from_slots(page.range, &memory.ranges)
.map_err(map_cca_private_range_error)?;
let segments = crate::memory::guest_memfd_range_segments(page.range, &memory.ranges)
.map_err(map_cca_private_range_error)?;
Comment on lines +100 to +102
CCA support requires device-tree Linux direct boot with shared userspace RAM
backing. It does not support Hyper-V enlightenments, VTL2, VMBus, hugetlb
memory, assigned devices, vhost-user devices, PCIe hotplug, or CXL.
Comment on lines +1273 to +1276
match config.isolation {
virt::IsolationType::None => {}
virt::IsolationType::Cca => {
if config.hv_config.is_some() {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Guide unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants