Add ARM CCA FVP (Fixed Virtual Platform) support to Flowey#2866
Add ARM CCA FVP (Fixed Virtual Platform) support to Flowey#2866weiding-msft wants to merge 18 commits intomicrosoft:mainfrom
Conversation
Use absolution path for shrinkwrap directory, since shrinkwrap will change directory during execution.
Fix a potential bug which has jobs executed out of order. The order of .dep_on() doesn't ensure execution ordering. Dependency must be implemented on artifact or side effect
- for unused destructured fields, add ': _' to ignore them
- delete cca_fvp_test.rs which is unused, we should to center
fvp logic inside cca_fvp.rs
We probably should even split cca_fvp.rs into fvp.rs and cca.rs,
fvp.rs to implement FVP install/build and CCA is for CCA related
configuration because FVP can be used for testing other architecture
features
1. Git clone openvmm and set up encironment + build openvmm and tmk_vmm 2. Fix an issue for fetching incorrect OHCL-Linux-Kernel branch
A temporary clone of openvmm with CCA support is used. This duplication is intentional for the initial implementation and will be removed once upstream openvmm gains full ARM CCA support.
For the initial implementation, planes.yaml is hosted in a remote repository so cca-fvp can clone and use it directly. This avoids manual configuration.
Extract duplicated logic into a function to improve reuse and maintainability.
Factor out common xshell command execution into helpers and organize kernel config flags into logical groups (CCA, 9P, Hyper-V). This reduces duplication and improves maintainability without changing behavior. Same for the rust binary build.
Remove the hardcoded ~/.shrinkwrap rootfs path and resolve it via configuration/environment variables to support portable setups.
Add a helper to resolve platform/overlay paths consistently by supporting absolute paths, legacy target/cca-fvp/shrinkwrap paths, and relative paths assumed to live under shrinkwrap/config.
The build failed with: Failed to enable CCA kernel configs because multiple CONFIG options were passed as a single --enable argument to scripts/config. Split options correctly so CONFIG_VIRT_DRIVERS and CONFIG_ARM_CCA_GUEST are enabled independently.
Resolve simple --platform/--overlay filenames via --dir and move target/cca-fvp output to the repo root. Accept simple filenames for --platform and --overlay and locate them relative to <dir>/shrinkwrap/config.
Add default values for common cca-fvp options: - Default --dir to target/cca-fvp - Default --platform to cca-3world.yaml - Provide default overlays and btvars when not specified - Compute default rootfs path from SHRINKWRAP_PACKAGE or HOME This improves usability while preserving explicit user overrides. Remove unused variables.
Improve handling of "Device or resource busy" errors by: - Attempting a normal unmount first, then falling back to a lazy unmount (-l) - Allowing the script to continue even if unmount attempts fail - Retrying unmount operations with delays to handle transient usage This reduces flakiness during mount cleanup and file injection.
…gration Adapts local_install_shrinkwrap to use the new RustRuntimeServices.sh pattern instead of direct xshell::Shell::new(). Updates all shell commands to use flowey::shell_cmd! macro.
|
@chris-oo Can you please take a look for the draft PR? Thank you! |
|
@microsoft-github-policy-service agree company="Microsoft" |
|
@microsoft-github-policy-service agree |
|
I'll try to review this today. @justus-camp-microsoft can you also help take a look? |
justus-camp-microsoft
left a comment
There was a problem hiding this comment.
Left some comments regarding flowey best practices. I see a couple things are pointed to your own forks - are there more people than just you that will use this pipeline?
| let venv_dir = shrinkwrap_dir.join("venv"); | ||
| let venv_bin = venv_dir.join("bin"); | ||
|
|
||
| let mut cmd = std::process::Command::new(&shrinkwrap_exe); |
There was a problem hiding this comment.
We shouldn't use std::process::Command anywhere. You should use flowey::shell_cmd! any place you're using std::process::Command and then use the builder args to get the same behavior you're getting here. flowey::shell_cmd! is relatively new (before I would've told you to use xshell::Cmd) so let me know if any of the builder commands you need aren't available.
| done, | ||
| } = request; | ||
|
|
||
| ctx.emit_rust_step("install shrinkwrap", |ctx| { |
There was a problem hiding this comment.
This step is basically a "mega-step" that does everything. Flowey best practices dictate the use of reusable, composable nodes and to leverage them when you can. For instance, there are several existing nodes that could be used here to significantly simplify the node:
- The inline
apt-get installcommands should be using theinstall_dist_pkgnode. clone_or_update_repois essentially a re-implementation of thegit_checkoutnode.- I believe the
rustup target addcommands are covered by theinstall_rustnode. - The
cargo buildcommands should be using therun_cargo_buildnode. - The cross-compilation setup should be handled by the
init_cross_buildnode.
There are few things here that should likely have nodes implemented for but I wouldn't block the PR for doing them inline here. Namely those are compiling the kernel, installing python, docker setup, and downloading the ARM GNU toolchain. For the ARM GNU toolchain, there's an argument that they should be downloaded as part of the restore-packages pipeline and then have a corresponding magicpath node (there are other magicpath nodes lying around to show what I mean) that puts it in a known place for use here.
There was a problem hiding this comment.
You’re right that this node is currently acting as a “mega-step”, and it would be better aligned with Flowey’s composable model concept by leveraging the existing reusable nodes.
I’ll refactor this to:
• Replace inline apt-get install calls with install_dist_pkg
• Use git_checkout instead of the custom clone_or_update_repo
• Replace the rustup target add logic with install_rust
• Use run_cargo_build for the cargo builds
• Move the cross-compilation setup into init_cross_build
For the remaining inline steps (kernel build, Python setup, Docker setup, ARM GNU toolchain download), I agree these likely deserve dedicated nodes or integration into existing pipelines. I probably won’t block this PR on introducing new nodes, but I’ll structure the code so they can be cleanly extracted later.
For the ARM GNU toolchain specifically, integrating it into the restore-packages pipeline with a corresponding magicpath node sounds like the right long-term solution. I’ll leave a TODO and follow up with a separate proposal for that.
Appreciate the guidance — these should make the flow much more maintainable and consistent with the rest of the project.
| verbose, | ||
| } = self; | ||
|
|
||
| let openvmm_repo = flowey_lib_common::git_checkout::RepoSource::ExistingClone( |
There was a problem hiding this comment.
We should add a bail_if_running_in_ci() guard here (assuming this isn't supposed to be run as part of CI)
| use std::path::Path; | ||
|
|
||
| const ARM_GNU_TOOLCHAIN_URL: &str = "https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-elf.tar.xz"; | ||
| const OHCL_LINUX_KERNEL_REPO: &str = "https://github.com/weiding-msft/OHCL-Linux-Kernel.git"; |
There was a problem hiding this comment.
Is this intentionally a forked repo?
There was a problem hiding this comment.
Yes, it is intentional for the initial implementation and will be removed once upstream openvmm gains full ARM CCA support.
| #[clap(long, default_value_t = true)] | ||
| pub install_missing_deps: bool, | ||
|
|
||
| /// If repo already exists, attempt `git pull --ff-only` | ||
| #[clap(long, default_value_t = true)] | ||
| pub update_shrinkwrap_repo: bool, |
There was a problem hiding this comment.
I don't think there's actually a way to turn these off if you default them to true (I think usage would be --install-missing-deps which is already true so this would be a no-op). We should have these default to false or flip the flag to --no-install-missing-deps.
| pub mod local_install_shrinkwrap; | ||
| pub mod local_shrinkwrap_build; | ||
| pub mod local_shrinkwrap_run; |
There was a problem hiding this comment.
nit: alphabetize the mod.rs file
|
The intention here is to eventually stand up a CI pass so we can validate CCA changes in CI until we have hardware available, if that gives you more context? |
Ok that makes sense - we'll have to add it to |
|
Right, I think it's fine to stage this first PR to make local work, then we can iterate on another PR to standup the right CI pass. It probably needs to be it's own new pass since it takes a while to setup all the deps & run the simulator. |
This PR adds a new cca-fvp pipeline to Flowey that enables testing of ARM Confidential Compute Architecture (CCA) configurations using the Arm Fixed Virtual Platform with Shrinkwrap.
Overview
The new pipeline automates the setup and execution of CCA-enabled ARM64 virtual machines by:
New Flowey Jobs:
Pipeline Features:
Code Quality Improvements:
Implementation Details
Kernel Configuration:
TMK Integration:
Shrinkwrap Integration:
Compatibility:
Usage
Testing
Successfully builds and runs on Ubuntu dev container with: