Skip to content

Initial Arm CCA enablement for OpenHCL and TMK test infrastructure#3455

Open
jiong-microsoft wants to merge 6 commits into
microsoft:mainfrom
jiong-microsoft:cca-dev
Open

Initial Arm CCA enablement for OpenHCL and TMK test infrastructure#3455
jiong-microsoft wants to merge 6 commits into
microsoft:mainfrom
jiong-microsoft:cca-dev

Conversation

@jiong-microsoft
Copy link
Copy Markdown

@jiong-microsoft jiong-microsoft commented May 11, 2026

This PR adds the initial Arm Confidential Compute Architecture (CCA) enablement
across OpenHCL, the mshv_vtl backend, and the TMK test path.

At a high level, this wires CCA into OpenHCL as a new hardware-isolated AArch64
CVM backend, parallel to the existing SNP/TDX hardware-isolated paths on x86-64.
The implementation introduces the CCA-specific HCL ioctl surface, models the RSI
plane-run ABI used to enter and resume lower-privilege planes, extends OpenHCL
memory setup for CCA protected memory, and adds a TMK/FVP-based test flow for
exercising the initial realm execution path. FVP (Fixed Virtual Platform) is a
software emulator released by Arm. It aims helping software developement before
the silicon is avaiable and we are using it for CCA OpenHCL testing.

OpenHCL Implementation

CCA is integrated at the same architectural layer as the other OpenHCL
hardware-isolated backends:

  • IsolationType::Cca is added to the platform abstraction so higher layers can
    select CCA as a hardware-isolated partition type.
  • openhcl/hcl adds the CCA-specific /dev/mshv_vtl interface:
    • realm configuration query
    • RSI system register write support
    • RSI memory permission programming
    • CCA VP backing state using a private DMA-allocated plane_run page
  • vm/aarch64/rsi defines the RSI data structures shared with the kernel/RMM
    interface, including realm config and the plane entry/exit/run page layouts.
  • openhcl/underhill_mem treats CCA as a hardware-isolated memory configuration
    and routes lower-VTL memory permission setup through the CCA/RSI path.
  • openhcl/virt_mshv_vtl adds CcaBacked and CcaBackedShared, making CCA a
    first-class backend alongside the existing hypervisor, SNP, and TDX
    backends:
    • Per-partition state is stored in the shared CVM partition state.
    • Per-VP state owns the CCA plane state.
    • VP entry uses the RSI plane-run page.
    • Register state is translated through the RSI plane entry/exit
      structures.
    • The initial exit handling supports the TMK path, including basic
      synchronous exit with MMIO handling supported
  • TMK gains a --hv cca mode that runs inside the paravisor environment,
    allocates private CCA RAM through DMA/PFN-backed memory, constructs an
    OpenHCL CCA partition, binds VPs with CcaBacked, and runs the test
    microkernel inside the realm.

Test Infrastructure

This PR also adds Flowey-based local CCA test support around the Arm CCA FVP
environment:

  • installs/checks the CCA emulation prerequisites
  • builds or updates TF-A, TF-RMM, Plane0 Linux, kvmtool, and rootfs assets
  • injects tmk_vmm and simple_tmk into the emulated realm environment
  • launches the CCA 3-world shrinkwrap configuration ('shrinkwrap' is an python
    based tool released by Arm to simply FVP deployment)
  • adds test data overlays for CCA planes and realm auto-launch

A new user can run CCA OpenHCL test by the following steps:

  • install the env: cargo xflowey cca-tests --install-emu
  • run tests: cargo xflowey cca-tests

If any components (firmwares, plane0 linux kernel etc.) are update, can update
the env using:

cargo xflowey cca-tests --update-emu --rebuild-plane0-linux --rebuild-rootfs

Scope

This is intended as initial enablement rather than full CCA feature completion.
Several paths are deliberately minimal and focused on bringing up the first
OpenHCL/TMK realm execution flow. Follow-up work is expected for fuller
interrupt/GIC handling, complete system register state, broader exit handling,
and production hardening.

Testing Done

  • cargo xflowey cca-tests passed on ARM64

Signed-off-by: Ben Aram b-bearam@microsoft.com
Signed-off-by: Wei Ding b-weiding@microsoft.com
Signed-off-by: Jiong Wang b-jiongwang@microsoft.com

Copilot AI review requested due to automatic review settings May 11, 2026 17:49
@jiong-microsoft jiong-microsoft requested a review from a team as a code owner May 11, 2026 17:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds initial Arm CCA (Confidential Compute Architecture) enablement across OpenHCL and the TMK/FVP test flow, wiring CCA as a new hardware-isolated backend on AArch64.

Changes:

  • Introduces IsolationType::Cca end-to-end (virt, hvdef, OpenHCL backends, and HCL ioctl surface) and adds RSI/plane-run ABI structs (rsi crate).
  • Implements initial CCA-backed VP execution via RSI plane-run pages and routes lower-VTL memory protections through CCA/RSI.
  • Adds Flowey cca-tests pipeline plus shrinkwrap/FVP assets and overlays for local CCA emulation testing.

Reviewed changes

Copilot reviewed 46 out of 47 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vmm_tests/vmm_tests/test_data/cca_realm_overlay.yaml Buildroot overlay to auto-launch realm and inject TMK startup script
vmm_tests/vmm_tests/test_data/cca_planes.yaml Shrinkwrap overlay for TF-RMM/TF-A/Linux/kvmtool inputs and FVP run params
vmm_core/virt_whp/src/lib.rs Unifies vendor detection across x86_64/aarch64 WHP capabilities
vmm_core/virt_mshv/src/aarch64/mod.rs Adds AArch64 vendor caps; reworks ESR ISS extraction for data aborts
vmm_core/virt_kvm/src/arch/aarch64/mod.rs Adds AArch64 vendor caps for KVM backend
vmm_core/virt_hvf/src/lib.rs Adds AArch64 vendor caps for HVF backend
vmm_core/virt/src/generic.rs Adds IsolationType::Cca and updates mappings/hardware-isolated check
vmm_core/virt/src/aarch64/mod.rs Extends AArch64 partition capabilities with vendor
vm/hv1/hvdef/src/lib.rs Adds HvPartitionIsolationType::CCA
vm/hv1/hv1_emulator/src/hv.rs Gates x86-only hypercall page logic; prepares for AArch64 vendor usage
vm/hv1/hv1_emulator/Cargo.toml Adds aarch64defs dependency
vm/aarch64/rsi/src/lib.rs New RSI/plane-run ABI structs and constants
vm/aarch64/rsi/Cargo.toml New rsi crate definition
vm/aarch64/aarch64emu/src/emulator.rs Updates data-abort ISS reconstruction for new ESR layout
vm/aarch64/aarch64defs/src/lib.rs Refactors EsrEl2 ISS layout; adds Vendor type and helpers
tmk/tmk_vmm/src/run.rs Adds Linux/AArch64 CCA private DMA allocation and memory layout path
tmk/tmk_vmm/src/paravisor_vmm.rs Passes VTOM and CVM late params; binds CCA VPs to CcaBacked
tmk/tmk_vmm/src/main.rs Adds --hv cca option and options finalization
tmk/tmk_vmm/src/load.rs Splits x86/aarch64 loader paths; adds load offset for aarch64
tmk/tmk_vmm/Cargo.toml Adds deps for CCA memory ranges and user_driver
support/safe_intrinsics/src/lib.rs Adds AArch64 read_cntfrq_el0() helper
openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs Adds explicit expect()s for required DMA clients/allocations
openhcl/virt_mshv_vtl/src/processor/snp/mod.rs Adds explicit expect()s for required direct-overlay DMA allocations
openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs Uses let ... else { unreachable!() } for backing match
openhcl/virt_mshv_vtl/src/processor/mod.rs Adds CCA processor module; adjusts trait gating and imports
openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Adds Cca match arm (currently unreachable) in x64 initial context
openhcl/virt_mshv_vtl/src/processor/cca/mod.rs New CCA-backed processor implementation using RSI plane-run
openhcl/virt_mshv_vtl/src/lib.rs Adds CCA backing shared state; optional DMA clients; aarch64 timing path
openhcl/virt_mshv_vtl/Cargo.toml Adds rsi dependency
openhcl/underhill_mem/src/lib.rs Adds CCA memory permission plumbing and RSI perm ioctl usage
openhcl/underhill_mem/src/init.rs Refactors VTL0 protections into helper; treats CCA like SNP for VTOM mapping
openhcl/underhill_mem/Cargo.toml Adds rsi dependency
openhcl/openhcl_boot/src/host_params/shim_params.rs Marks CCA as hardware-backed isolation
openhcl/hcl/src/ioctl/register.rs Adds CCA VSM caps default; adjusts aarch64 privilege query for hardware isolation
openhcl/hcl/src/ioctl/cca.rs New HCL ioctl surface for realm config, RSI sysreg write, and mem perms
openhcl/hcl/src/ioctl.rs Registers new CCA ioctls/types; adds CCA backing state allocation
openhcl/hcl/Cargo.toml Adds aarch64defs and rsi deps
flowey/flowey_lib_hvlite/src/_jobs/mod.rs Wires new local CCA emu/test jobs
flowey/flowey_lib_hvlite/src/_jobs/local_update_cca_emu.rs Adds emu update job (rebuild plane0 linux/rootfs)
flowey/flowey_lib_hvlite/src/_jobs/local_run_cca_test.rs Adds job to inject artifacts into rootfs and launch shrinkwrap/FVP run
flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs Adds job to install shrinkwrap + plane0 linux build + overlay syncing
flowey/flowey_lib_hvlite/src/_jobs/local_check_cca_emu_prereq.rs Adds env prerequisite checks (packages, docker group)
flowey/flowey_hvlite/src/pipelines/mod.rs Adds cca-tests pipeline entrypoint
flowey/flowey_hvlite/src/pipelines/cca_tests.rs New cargo xflowey cca-tests pipeline (install/update/run)
Guide/src/dev_guide/dev_tools/xflowey.md Documents cargo xflowey cca-tests
Cargo.toml Adds rsi workspace member
Comments suppressed due to low confidence (3)

tmk/tmk_vmm/src/paravisor_vmm.rs:1

  • cvm_params is now always Some(...) and unconditionally unwraps m.cvm_memory(). For non-hardware-isolated runs (e.g., IsolationType::None used by KVM/HVF/WHP paths), cvm_memory() is expected to be None, causing a panic. Gate cvm_params creation on m.cvm_memory().is_some() (or on isolation == IsolationType::Cca) and avoid unwrap() by using if let Some(cvm) = m.cvm_memory() { ... }.
    vmm_core/virt_mshv/src/aarch64/mod.rs:1
  • The reconstructed ISS value omits the new EsrEl2 bits a/b/c/d (bits 21–24). For data aborts, this includes flags such as ISV (bit 24), so iss.isv() can become false even when the syndrome is valid, potentially turning valid data abort handling into a fatal error. Reconstruct the full 25-bit ISS by OR-ing in a/b/c/d at bits 21–24 (matching the approach used in vm/aarch64/aarch64emu/src/emulator.rs), or add an EsrEl2::iss_u32() helper in aarch64defs and use it consistently.
    vm/aarch64/rsi/src/lib.rs:1
  • size_of is used but not imported/qualified in this new crate, which will fail to compile. Add use core::mem::size_of; near the top, or fully qualify (core::mem::size_of::<...>()) at each call site.

Comment thread openhcl/underhill_mem/src/init.rs Outdated
Comment thread openhcl/hcl/src/ioctl/cca.rs Outdated
Comment thread openhcl/hcl/src/ioctl.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/lib.rs Outdated
Comment thread flowey/flowey_lib_hvlite/src/_jobs/local_run_cca_test.rs
@github-actions github-actions Bot added Guide unsafe Related to unsafe code labels May 11, 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

@jiong-microsoft
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree [company="Microsoft"]

@jiong-microsoft
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="Microsoft"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions
Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings May 13, 2026 00:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 53 out of 54 changed files in this pull request and generated 12 comments.

Comments suppressed due to low confidence (4)

openhcl/virt_mshv_vtl/src/processor/cca/mod.rs:142

  • This From<u64> impl panics on unknown plane exit reasons. A malformed/unknown exit reason should not crash the VMM/OpenHCL process; treat it as an error path and propagate a structured error instead of panic!().
        match value {
            0 => PlaneExitReason::Sync,
            1 => PlaneExitReason::Irq,
            _ => panic!("Unknown CCA plane exit reason: {value}"),
        }

openhcl/virt_mshv_vtl/src/processor/cca/mod.rs:276

  • todo!() in the MMIO read path will panic if the realm performs an MMIO read (guest-triggerable). This should be implemented (read via dev.read_mmio, write back to the appropriate GPR based on SRT/access size) or fail gracefully without panicking.
                            } else {
                                // Handle MMIO read
                                todo!();
                            }
                            this.runner.cca_rsi_plane_entry().pc += 4; // Advance PC

openhcl/virt_mshv_vtl/src/processor/cca/mod.rs:281

  • todo!() for instruction abort handling will panic on an instruction abort exit from the realm. This is guest-triggerable and should be handled or converted into a recoverable/diagnostic error rather than crashing.
                        ExceptionClass::InstructionAbort => {
                            // Handle instruction abort
                            todo!();
                        }

openhcl/virt_mshv_vtl/src/processor/cca/mod.rs:319

  • unimplemented!() here will panic if untrusted SINT readiness is requested. Since this can be triggered via guest/hypervisor interactions, it should return a proper error / be a no-op for now (with logging), rather than crashing.
    fn request_untrusted_sint_readiness(_this: &mut UhProcessor<'_, Self>, _sints: u16) {
        // TODO: CCA: handle this for CCA untrusted synic
        unimplemented!();
    }

Comment thread vm/aarch64/rsi/src/lib.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/cca/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/lib.rs
Comment thread openhcl/hcl/src/ioctl/cca.rs
Comment on lines +1098 to +1101
#[cfg(guest_arch = "aarch64")]
whp::abi::WHvProcessorVendorArm => Vendor::ARM,
_ => panic!("unsupported processor vendor"),
};
Comment thread openhcl/underhill_attestation/src/igvm_attest/mod.rs
hv_vp_context
}
virt::IsolationType::Tdx => hvdef::hypercall::InitialVpContextX64::new_zeroed(),
virt::IsolationType::Cca => unreachable!(),
Comment thread flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs
Comment on lines 364 to 372
match ec {
ExceptionClass::DATA_ABORT_LOWER => {
let iss = IssDataAbort::from(syndrome.iss());
let iss = IssDataAbort::from(
u32::from(syndrome.lower_iss())
| (u32::from(syndrome.wnr()) << 6)
| (u32::from(syndrome.mid_iss()) << 7)
| (u32::from(syndrome.b_srt()) << 16),
);
if !iss.isv() {
Comment on lines +105 to +112
pub fn srt(&self) -> u8 {
// The SRT field is only valid for data aborts.
if (ExceptionClass::DATA_ABORT_LOWER.0..ExceptionClass::DATA_ABORT.0).contains(&self.ec()) {
self.b_srt()
} else {
0
}
}
@github-actions
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings May 13, 2026 17:59
weiding-msft and others added 4 commits May 13, 2026 11:10
The hardware that support ARM64 CCA is not widely available yet, so the
OpenVMM enablement work is tested using ARM's emulator, Fixed Virtual
Platform (FVP) now.

Arm also has release a python framework, 'shrinkwrap', which simplifies
the deployement of FVP.

This commit add initial test pipeline into flowey
  - add a new `cca-fvp` pipeline entry in `flowey_hvlite`
  - add a local install job to clone/update shrinkwrap, prepare its config,
    install required host dependencies, and fetch/build the external pieces
    needed by the flow
  - add a local shrinkwrap build job which runs `shrinkwrap build` and saves
    the output log under the pipeline working directory
  - add a local shrinkwrap run job which updates `rootfs.ext2` with the
    generated/local artifacts and then invokes `shrinkwrap run`

The new pipeline also provides basic argument handling for platform,
overlays, build-time variables, runtime variables, and output directory
layout, so the whole shrinkwrap environment can live under one self-contained
working directory.

After this commit, the user can use the follow command to build and
launch OpenVMM CCA test

  cargo xflowey cca-fvp

Signed-off-by: Wei Ding <b-weiding@microsoft.com>
Signed-off-by: Jiong Wang <b-jiongwang@microsoft.com>
Signed-off-by: Ben Aram <b-bearam@microsoft.com>
This commit introduces initial ARM CCA enablement across the stack.

Key changes:
  - Add CCA ioctl support and related protocol updates
  - Introduce CCA processor support in virt_mshv_vtl
  - Add RSI support for AArch64
  - Update hypervisor definitions and emulator logic
  - Extend memory initialization and mapping for CCA
  - Integrate changes into VMM and TMK components
  - General fixes, cleanup, and refactoring

This represents the initial end-to-end integration of CCA support.

Signed-off-by: Ben Aram <b-bearam@microsoft.com>
Signed-off-by: Jiong Wang <b-jiongwang@microsoft.com>
Signed-off-by: Wei Ding <b-weiding@microsoft.com>
  - fix all regresssions on x86-64
  - fix all typos in comments
  - fix all 'cargo doc' build errors
  - further remove unnecessary cfgs
  - remove packed structure to avoid unaligned access
  - remove unused method
  - remove unused dependency for 'rsi' crate
  - remove duplicated code blocks inside underhill_mem
  - use 'expect' rather than 'allow' across the code
  - remove unnecessary introducing of Option
  - remove unnecessary touch on TDX and SNP code
  - enable existing tmk aarch64 test sequence rather hacked version
  - redesign flowey based test flow, now we have:
    - cargo xflowey cca-tests --install-emu
    - cargo xflowey cca-tests --update-emu [subcommands]
      [subcommands] can be --rebuild-plane0-linux --rebuild-rootfs
  - also automate flowey testflow by packing some test scrips into
    guest rootfs and init process

Signed-off-by: Jiong Wang <b-jiongwang@microsoft.com>
Signed-off-by: Ben Aram <b-bearam@microsoft.com>
Signed-off-by: Wei Ding <b-weiding@microsoft.com>
When running simple_tmk, CCA plane1 runs on GPA due to no MMU initialization.
Therefore we need to find continuous GPA for holding the test code. DMA pages
are used and this commit further searches DMA pages with continous PHY address
from the page pool.

Signed-off-by: Wei Ding <b-weiding@microsoft.com>
Signed-off-by: Jiong Wang <b-jiongwang@microsoft.com>
Signed-off-by: Ben Aram <b-bearam@microsoft.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 53 out of 54 changed files in this pull request and generated 27 comments.

Comments suppressed due to low confidence (4)

openhcl/underhill_core/src/worker.rs:2889

  • CCA is mapped to an attestation type, but the CCA branch below still panics. Any CCA VM that requests an attestation helper will crash here; return an unsupported attestation error or avoid advertising CCA attestation until it is implemented.

This issue also appears on line 2914 of the same file.

            let request_ak_cert = GetTpmRequestAkCertHelperHandle::new(
                attestation_type,
                attestation_vm_config,
                platform_attestation_data.agent_data,

openhcl/underhill_core/src/worker.rs:2917

  • The CCA attestation helper arm is still todo!(), so after selecting AttestationType::Cca the VM startup path can panic when this helper is needed. This should return a typed unsupported error until CCA attestation is implemented.
            TpmRegisterLayout::IoPort
        } else {
            TpmRegisterLayout::Mmio
        };

flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs:8

  • Correct “simply” to “simplify” in this module comment.
//! published an python based tool, 'shrinkwrap', to simply the deployment
//! process, this installation use it as well.

flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs:8

  • Correct “installation use” to “installation uses” in this module comment.
//! process, this installation use it as well.

Comment on lines 366 to +371
ExceptionClass::DATA_ABORT_LOWER => {
let iss = IssDataAbort::from(syndrome.iss());
let iss = IssDataAbort::from(
u32::from(syndrome.lower_iss())
| (u32::from(syndrome.wnr()) << 6)
| (u32::from(syndrome.mid_iss()) << 7)
| (u32::from(syndrome.b_srt()) << 16),
Comment thread openhcl/hcl/src/ioctl.rs Outdated
Comment on lines +1863 to +1864
// TODO: we should check if the underlying arm64 arhcitecture extension support CCA
IsolationType::Cca
Comment on lines +17 to +18
// The guest Linux kernel (with cca/plane driver) hasn't been upstreamed yet, fetch it from our private repo
const PLANE0_LINUX_REPO: &str = "https://github.com/jiong-microsoft/OHCL-Linux-Kernel.git";
Comment on lines +188 to +189
let venv_bin_path = format!("{}:{}", venv_dir.join("bin").display(), env::var("PATH").unwrap_or_default());
flowey::shell_cmd!(rt, "{shrinkwrap_exe} run cca-3world.yaml --rtvar ROOTFS={rootfs_file}")
Comment on lines +194 to +196
GpaVtlPermissions::Cca(_index) => {
// TODO: CCA: implement me!
}
Comment on lines +225 to +233
let cmd = format!(
"{} build cca-3world.yaml \
--overlay buildroot.yaml \
--overlay cca_realm_overlay.yaml \
--overlay cca_planes.yaml \
--btvar GUEST_ROOTFS={rootfs} \
--btvar TFA_REVISION={tfa_revision} \
2>&1 | tee {}",
shrinkwrap_exe.display(),
Comment on lines +120 to +124
0b0010_0000 => ExceptionClass::InstructionAbort,
0b0000_0111 => ExceptionClass::SimdAccess,
0b0001_0111 => ExceptionClass::SmcError,
_ => panic!("Unknown exception class: {value}"),
}
Comment on lines +138 to +142
match value {
0 => PlaneExitReason::Sync,
1 => PlaneExitReason::Irq,
_ => panic!("Unknown CCA plane exit reason: {value}"),
}
Comment on lines +265 to +269
dev.write_mmio(
this.vp_index(),
address,
&this.runner.cca_rsi_plane_exit().gprs[esr_el2.srt() as usize]
.to_ne_bytes(),
Comment on lines +42 to +46
tfa_rev: _,
tfrmm_rev: _,
plane0_linux_rev: _,
} = sub_cmds;

The realm-visible ID registers can be sanitized/virtualized, so using
ID_AA64PFR0_EL1.RME inside the paravisor/realm is not a reliable way to decide
whether the outer platform supports CCA. We should use ioctl instead.

This commit still adds the arm64 version 'cpuid' as it could be useful in other
places.
Copy link
Copy Markdown
Member

@chris-oo chris-oo left a comment

Choose a reason for hiding this comment

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

see comments

Comment thread openhcl/hcl/src/ioctl/cca.rs
Comment thread openhcl/hcl/src/ioctl/cca.rs
Comment thread openhcl/hcl/src/ioctl/cca.rs Outdated
Comment thread openhcl/hcl/src/ioctl/cca.rs
Comment thread openhcl/hcl/src/ioctl/cca.rs Outdated
Comment thread vm/aarch64/rsi/src/lib.rs
Comment thread vm/aarch64/rsi/src/lib.rs
return Some(Vec::new());
}

let mut pfns = self.pfns().to_vec();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

seems silly we call to_vec twice doing another allocation?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good point, will fix this.


/// Returns a sorted contiguous subset of PFNs large enough for `asking_size`
/// bytes.
pub fn contiguous_subpfns(&self, asking_size: usize) -> Option<Vec<u64>> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is this used by the TMK? i'm wondering if we really need this in user_driver?

- mkdir -p ${param:builddir}/overlay/etc/init.d

# =========================
# run_realm_test.sh
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should this script be separate and not inline in yaml? is it possible to package it that way or nope?

Copy link
Copy Markdown

@weiding-msft weiding-msft May 14, 2026

Choose a reason for hiding this comment

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

Yes, we can package a separate file into the Buildroot overlay. However, the reason we didn’t place this logic in a separate file is that this step is highly specific to ARM CCA testing automation, and we do not expect it to require any changes. Keeping it inline also makes future maintenance simpler.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ah i see this is to launch the realm itself/the linux "host" running inside the FVP? I think from other discussions we want a better way to drive interactions with the linux host and linux realm guest (vsock?), so i'm okay with this as-is and we can continue iterating further

];

let mut missing_packages = Vec::new();
for pkg in required_packages {
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.

We already have infrastructure to automatically check for and automatically install packages, see install_dist_pkg

VmmTestsRun(VmmTestsRunCli),

/// Build and run CCA tests with installation of emulation environment supported
CcaTests(CcaTestsCli),
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.

Why does this have to be a whole separate command? Would this not be considered a TMK for VMM test?


new_simple_flow_node!(struct Node);

fn clone_repo(
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.

We already have git_checkout LocalOnlyNewClone

mount {rootfs_file} mnt
mkdir -p mnt/cca
cp {simple_tmk_bin} mnt/cca/
cp {tmk_vmm_bin} mnt/cca/
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.

Why are we doing all of this logic in a bash script instead of rust?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes, we should keep only the privileged operations as commands and move the orchestration into Rust. So Rust will own the file list, cleanup, and error handling; sudo related commands stay as external commands as they need privileges.

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

//! Install CCA emulation environment. Now we only support using ARM's Fixed
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.

Why is this local only? Seems like it could be refactored to support any backend.

@tjones60
Copy link
Copy Markdown
Contributor

This is a huge PR and it would be great if we can find a way to split it up a bit to make it more reviewable.

I think we should see what it would take to re-write the test infrastructure to integrate with the existing vmm-tests and petri infrastructure so we aren't reinventing things here. I'm a bit confused how your tests work today, so perhaps it would be good to chat sometime about your emulator and such. Maybe the best way to model this would be a new petri backend for the CCA emulator, especially if we want to use this long term for more complicated tests. If this is intended to be a short term thing for bring up only and we are going to remove all the new flowey code soon, then maybe I'm overthinking it.

@jiong-microsoft
Copy link
Copy Markdown
Author

jiong-microsoft commented May 14, 2026

This is a huge PR and it would be great if we can find a way to split it up a bit to make it more reviewable.

I think we should see what it would take to re-write the test infrastructure to integrate with the existing vmm-tests and petri infrastructure so we aren't reinventing things here. I'm a bit confused how your tests work today, so perhaps it would be good to chat sometime about your emulator and such. Maybe the best way to model this would be a new petri backend for the CCA emulator, especially if we want to use this long term for more complicated tests. If this is intended to be a short term thing for bring up only and we are going to remove all the new flowey code soon, then maybe I'm overthinking it.

Hi @tjones60, for the test flow implementation, we’re using Arm’s shrinkwrap, which is a small Python tool that helps deploy and launch emulations. The overall xflowey cca-tests flow works as follows:

  1. Check out shrinkwrap and use it to build Arm’s predefined CCA software stack, including the Linux host kernel, host rootfs/buildroot, TF-A, and TF-RMM with specified versions.
  2. Build openhcl, tmk_vmm, and simple_tmk, then package them into the guest rootfs.
  3. Use shrinkwrap to start the emulation. The emulation boots the host Linux, and the host rootfs contains a prebuilt kvmtool. We also define an init task that instructs kvmtool to launch the CCA Realm.
  4. The emulation then continues by entering the Realm and running the Plane0 paravisor, after which it stops at the console and waits for user input.
  5. Finally, the user invokes the simple_tmk test at this point. The binaries are packaged and injected into the Realm rootfs during step 2.

@weiding-msft, could you follow-up and drive solution on flowey and test-infra related review questions

  - single crate for each use
  - static size check on rsi data structures
  - factor out rsi data structure into cca module
  - add TODO in a few places
  - add tracing::warn/log in several places
  - initialize a few system register in 'init' rather than deferred to
    set_sysreg

Signed-off-by: Ben Aram <b-bearam@microsoft.com>
Signed-off-by: Jiong Wang <b-jiongwang@microsoft.com>
Copilot AI review requested due to automatic review settings May 15, 2026 05:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 53 out of 54 changed files in this pull request and generated 19 comments.

Comments suppressed due to low confidence (3)

flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs:19

  • The install flow depends on a personal/private GitHub fork for the Plane0 Linux kernel. That makes the public cargo xflowey cca-tests --install-emu path non-reproducible for contributors who do not have access (and can change outside this repo); use a public, pinned source or make the dependency an explicit user-provided path/revision.
// The guest Linux kernel (with cca/plane driver) hasn't been upstreamed yet, fetch it from our private repo
const PLANE0_LINUX_REPO: &str = "https://github.com/jiong-microsoft/OHCL-Linux-Kernel.git";
const PLANE0_LINUX_BRANCH: &str = "cca-dev";

flowey/flowey_lib_hvlite/src/_jobs/local_install_cca_emu.rs:308

  • If the shrinkwrap source directory already exists but the venv is missing or incomplete (for example after a failed install), this branch skips venv creation and dependency installation, and the later rootfs build fails. Check/create the venv independently of whether the repo directory already exists so --install-emu is idempotent.
                if shrinkwrap_dir.exists() {
                    log::info!(
                        "'shrinkwrap' source tree is already installed at: {}",
                        shrinkwrap_dir.display()
                    );

openhcl/virt_mshv_vtl/src/processor/cca/mod.rs:151

  • exit_reason is read from the CCA plane-run exit page, so an unexpected value should not panic OpenHCL. Convert this to a fallible decode and surface an unsupported-exit VP error instead of panicking on input from the lower plane/RMM boundary.
        match value {
            0 => PlaneExitReason::Sync,
            1 => PlaneExitReason::Irq,
            _ => panic!("Unknown CCA plane exit reason: {value}"),
        }

Comment on lines +191 to +194
} else {
// Prepare VTL0 memory for mapping.
apply_vtl0_protections(
acceptor.as_deref().unwrap(),
Comment thread tmk/tmk_vmm/src/run.rs
Comment on lines 523 to 527
let virt::aarch64::Aarch64InitialRegs {
registers,
system_registers,
system_registers: _,
} = self.regs.as_ref();
state.set_registers(registers)?;
Comment on lines +194 to +196
GpaVtlPermissions::Cca(_index) => {
tracing::warn!("cca: GpaVtlPermissions::set is doing nothing now");
}
Comment on lines +292 to +293
// Handle MMIO read
todo!();

#[cfg(guest_arch = "aarch64")]
fn request_msi(&self, _vtl: Vtl, _request: MsiRequest) {
todo!()
.attempt_ak_cert_callback()
}),
),
AttestationType::Cca => todo!(),
Comment on lines +1738 to +1741

// Update the final param stored in UhProtoPartition.
UhPartitionNewParams {
vtom: Some(1_u64 << (realm_config.ipa_width() - 1)),
Comment on lines +105 to +109
pub fn srt(&self) -> u8 {
// The SRT field is only valid for data aborts.
if (ExceptionClass::DATA_ABORT_LOWER.0..ExceptionClass::DATA_ABORT.0).contains(&self.ec()) {
self.b_srt()
} else {
Comment on lines +367 to +371
let iss = IssDataAbort::from(
u32::from(syndrome.lower_iss())
| (u32::from(syndrome.wnr()) << 6)
| (u32::from(syndrome.mid_iss()) << 7)
| (u32::from(syndrome.b_srt()) << 16),
Comment on lines +283 to +290
// Handle MMIO write
dev.write_mmio(
this.vp_index(),
address,
&this.runner.cca_rsi_plane_exit().gprs[esr_el2.srt() as usize]
.to_ne_bytes(),
)
.await;
@github-actions
Copy link
Copy Markdown

/// Read the CNTFRQ_EL0 system register, which contains the frequency of the
/// system timer in Hz. This is used to determine the frequency of the
/// system timer for the current execution level (EL0).
#[inline]
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.

Why inline?

caps: Aarch64PartitionCapabilities {
// Apple Silicon does not support aarch32.
supports_aarch32_el0: false,
vendor: Vendor::ARM,
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.

Is this accurate for mac silicon?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

probably fine?

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Vendor(pub u32);

impl Vendor {
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.

Should we should combine x86's Vendor with this in some more generic location so that consumers don't have to cfg(arch) everytime they touch Vendor?

/// Bitarray type for representing IRR bits in a x86-64 APIC
/// Each bit represent the 256 possible vectors.
type IrrBitmap = BitArray<[u32; 8], Lsb0>;
use virt::X86Partition;
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.

nit: keep usings sorted, keep pub uses and type defs separated from regular usings

#[cfg(guest_arch = "x86_64")]
Tdx(#[inspect(flatten)] TdxBackedShared),
#[cfg(guest_arch = "aarch64")]
Cca(#[inspect(flatten)] Box<CcaBackedShared>),
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.

Why box?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

CcaBackedShared has much bigger size, that there was some check warning suggesting to hide inside Box


impl UhProcessorBox {
/// Return the isolation type
pub fn get_isolation(&self) -> IsolationType {
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.

Who's calling this? Do we really need it?

Comment thread openhcl/virt_mshv_vtl/src/processor/cca/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/cca/mod.rs
.request_msi(vtl.try_into().expect("higher vtl not configured"), request)
}

#[cfg(guest_arch = "aarch64")]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this doesn't seem right? is it just cca where the msi path is undefined? aren't we going to break MSIs on non-cca aarch64 otherwise?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Make sense, we should check isolation type

}
} else {
// Prepare VTL0 memory for mapping.
apply_vtl0_protections(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is a behavior change right? why are we doing this? it doesn't look correct?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agree, I am double checking the logic inside underhill_mem, this change probably is causing the intel/amd regression

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.

7 participants