flowey_lib_hvlite/
build_snp_linux_direct_igvm.rs1use crate::build_igvmfilegen::IgvmfilegenBuildParams;
7use crate::build_igvmfilegen::IgvmfilegenOutput;
8use crate::common::CommonArch;
9use crate::common::CommonPlatform;
10use crate::common::CommonProfile;
11use crate::common::CommonTriple;
12use crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile;
13use crate::resolve_openvmm_test_linux_kernel::SNP_GUEST_LINUX_TEST_KERNEL_VERSION;
14use crate::run_cargo_build::BuildProfile;
15use anyhow::Context;
16use flowey::node::prelude::*;
17use igvmfilegen_config::ResourceType;
18use std::collections::BTreeMap;
19
20#[derive(Serialize, Deserialize)]
21pub struct SnpLinuxDirectIgvmOutput {
22 #[serde(rename = "snp-linux-direct.bin")]
23 pub igvm_bin: PathBuf,
24 #[serde(
25 rename = "snp-linux-direct.bin.map",
26 skip_serializing_if = "Option::is_none"
27 )]
28 pub igvm_map: Option<PathBuf>,
29}
30
31impl Artifact for SnpLinuxDirectIgvmOutput {}
32
33flowey_request! {
34 pub struct Request {
35 pub snp_linux_direct_igvm: WriteVar<SnpLinuxDirectIgvmOutput>,
36 }
37}
38
39new_simple_flow_node!(struct Node);
40
41impl SimpleFlowNode for Node {
42 type Request = Request;
43
44 fn imports(ctx: &mut ImportCtx<'_>) {
45 ctx.import::<crate::build_igvmfilegen::Node>();
46 ctx.import::<crate::build_pipette::Node>();
47 ctx.import::<crate::build_snp_bootshim::Node>();
48 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
49 ctx.import::<crate::resolve_openvmm_test_linux_kernel::Node>();
50 ctx.import::<crate::resolve_openvmm_test_initrd::Node>();
51 ctx.import::<crate::run_igvmfilegen::Node>();
52 }
53
54 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
55 if !matches!(ctx.platform(), FlowPlatform::Linux(_)) {
56 anyhow::bail!("SNP Linux-direct IGVM builds require a Linux host");
57 }
58
59 let host_arch: CommonArch = ctx.arch().try_into()?;
60 let igvmfilegen = ctx.reqv(|v| crate::build_igvmfilegen::Request {
61 build_params: IgvmfilegenBuildParams {
62 target: CommonTriple::Common {
63 arch: host_arch,
64 platform: CommonPlatform::LinuxGnu,
65 },
66 profile: BuildProfile::Light,
67 },
68 igvmfilegen: v,
69 });
70 let igvmfilegen = igvmfilegen.map(ctx, |o| match o {
71 IgvmfilegenOutput::LinuxBin { bin, .. } => bin,
72 IgvmfilegenOutput::WindowsBin { .. } => unreachable!("Linux host build"),
73 });
74 let bootshim = ctx.reqv(|v| crate::build_snp_bootshim::Request { snp_bootshim: v });
75 let kernel = ctx.reqv(|v| {
76 crate::resolve_openvmm_test_linux_kernel::Request::Get(
77 OpenvmmTestKernelFile::BzImage,
78 CommonArch::X86_64,
79 SNP_GUEST_LINUX_TEST_KERNEL_VERSION,
80 v,
81 )
82 });
83 let initrd =
84 ctx.reqv(|v| crate::resolve_openvmm_test_initrd::Request::Get(CommonArch::X86_64, v));
85 let pipette = ctx.reqv(|v| crate::build_pipette::Request {
86 target: CommonTriple::X86_64_LINUX_MUSL,
87 profile: CommonProfile::Release,
88 pipette: v,
89 });
90 let initrd = ctx.emit_rust_stepv("embed pipette in SNP test initrd", |ctx| {
91 claim_vars!(ctx, (initrd, pipette));
92 move |rt| {
93 let initrd = rt.read(initrd);
94 let pipette = match rt.read(pipette) {
95 crate::build_pipette::PipetteOutput::LinuxBin { bin, .. } => bin,
96 crate::build_pipette::PipetteOutput::WindowsBin { .. } => {
97 anyhow::bail!("SNP guest requires a Linux pipette")
98 }
99 };
100 let compressed = initrd_cpio::inject_into_initrd(
101 &std::fs::read(&initrd).context("reading SNP test initrd")?,
102 "pipette",
103 &std::fs::read(&pipette).context("reading Linux pipette")?,
104 0o100755,
105 )
106 .context("embedding pipette in SNP test initrd")?;
107 let path = rt.sh.current_dir().join("snp-linux-direct-initrd.cpio.gz");
108 std::fs::write(&path, compressed).context("writing SNP test initrd")?;
109 Ok(path)
110 }
111 });
112 let repo = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
113 let manifest = repo.map(ctx, |p| {
114 p.join("vm/loader/manifests/snp-linux-direct-pipette.json")
115 });
116
117 let resources = ctx.emit_minor_rust_stepv("enumerate SNP IGVM resources", |ctx| {
118 claim_vars!(ctx, (kernel, initrd, bootshim));
119 |rt| {
120 BTreeMap::from([
121 (ResourceType::LinuxKernel, rt.read(kernel)),
122 (ResourceType::LinuxInitrd, rt.read(initrd)),
123 (ResourceType::SnpBootshim, rt.read(bootshim).bin),
124 ])
125 }
126 });
127 let igvm = ctx.reqv(|v| crate::run_igvmfilegen::Request {
128 igvmfilegen,
129 manifest,
130 resources,
131 disable_secure_avic: false,
132 confidential_debug: false,
133 add_temp_snp_id_block: false,
134 igvm: v,
135 });
136 igvm.write_into_with(ctx, request.snp_linux_direct_igvm, |o| {
137 SnpLinuxDirectIgvmOutput {
138 igvm_bin: o.igvm_bin,
139 igvm_map: o.igvm_map,
140 }
141 });
142
143 Ok(())
144 }
145}