diff --git a/Cargo.lock b/Cargo.lock index d9c39c2aac..9d0d5ab337 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,9 +326,9 @@ checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" [[package]] name = "bitfield-struct" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be5a46ba01b60005ae2c51a36a29cfe134bcacae2dd5cedcd4615fbaad1494b" +checksum = "d3ca019570363e800b05ad4fd890734f28ac7b72f563ad8a35079efb793616f8" dependencies = [ "proc-macro2", "quote", @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "bitfield-struct" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3ca019570363e800b05ad4fd890734f28ac7b72f563ad8a35079efb793616f8" +checksum = "8769c4854c5ada2852ddf6fd09d15cf43d4c2aaeccb4de6432f5402f08a6003b" dependencies = [ "proc-macro2", "quote", @@ -3706,10 +3706,9 @@ dependencies = [ [[package]] name = "igvm" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67578b05ebcdfa1aa0fe13f77a13bdd7d87036128898a327f1bf8e7356cf09cd" +source = "git+https://github.com/microsoft/igvm?rev=3d1a950116d624746bf3342e09ea0a3416d89dd3#3d1a950116d624746bf3342e09ea0a3416d89dd3" dependencies = [ - "bitfield-struct 0.10.1", + "bitfield-struct 0.12.1", "crc32fast", "hex", "igvm_defs", @@ -3724,10 +3723,9 @@ dependencies = [ [[package]] name = "igvm_defs" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedd8c64460676101062f9f2ecdeb52d8f43e622da6a6c5bf5158f4ef08b0906" +source = "git+https://github.com/microsoft/igvm?rev=3d1a950116d624746bf3342e09ea0a3416d89dd3#3d1a950116d624746bf3342e09ea0a3416d89dd3" dependencies = [ - "bitfield-struct 0.10.1", + "bitfield-struct 0.12.1", "open-enum", "static_assertions", "zerocopy", diff --git a/Cargo.toml b/Cargo.toml index 74166fc35c..310b8d27e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -613,8 +613,8 @@ iced-x86 = { version = "1.17", default-features = false, features = [ "no_xop", "no_d3now", ] } -igvm = "0.4.0" -igvm_defs = { version = "0.4.0", default-features = false } +igvm = { git = "https://github.com/microsoft/igvm", rev = "3d1a950116d624746bf3342e09ea0a3416d89dd3" } +igvm_defs = { git = "https://github.com/microsoft/igvm", rev = "3d1a950116d624746bf3342e09ea0a3416d89dd3", default-features = false } kvm-bindings = "0.14.0" mshv-bindings = "0.6.8" mshv-ioctls = "0.6.8" diff --git a/openvmm/openvmm_core/src/worker/vm_loaders/igvm.rs b/openvmm/openvmm_core/src/worker/vm_loaders/igvm.rs index 28b9e9be53..8796e75159 100644 --- a/openvmm/openvmm_core/src/worker/vm_loaders/igvm.rs +++ b/openvmm/openvmm_core/src/worker/vm_loaders/igvm.rs @@ -855,6 +855,9 @@ fn load_igvm_x86( IgvmDirectiveHeader::X64NativeVpContext { .. } => { todo!("native igvm type not supported yet") } + IgvmDirectiveHeader::AArch64CcaVpContext { .. } => { + todo!("AArch64 CCA VP context not supported yet") + } } } else { panic!("no relocation region, cannot filter to VTL2"); @@ -1192,6 +1195,9 @@ fn load_igvm_x86( IgvmDirectiveHeader::X64NativeVpContext { .. } => { todo!("native vp context not supported") } + IgvmDirectiveHeader::AArch64CcaVpContext { .. } => { + todo!("AArch64 CCA VP context not supported") + } } } diff --git a/vm/loader/igvmfilegen/src/file_loader.rs b/vm/loader/igvmfilegen/src/file_loader.rs index 0785c11bf7..14f52ce033 100644 --- a/vm/loader/igvmfilegen/src/file_loader.rs +++ b/vm/loader/igvmfilegen/src/file_loader.rs @@ -831,9 +831,26 @@ impl IgvmLoader { } } - // Data size must match SNP VMSA size. - if data.len() != size_of::() { - anyhow::bail!("data len {:x} does not match VMSA size", data.len()); + // The VP context builder produces the architectural VMSA + // (`x86defs::snp::SevVmsa`, 1648 bytes); the igvm crate's `SevVmsa` + // is padded out to a full 4K page, so accept input in the range + // [architectural size, padded size] and zero-pad it to the padded + // size before reading. Anything smaller than the architectural size + // would be silently zero-extended into a malformed VMSA, so reject + // it. + if data.len() < size_of::() { + anyhow::bail!( + "data len {:x} is smaller than the architectural VMSA size {:x}", + data.len(), + size_of::() + ); + } + if data.len() > size_of::() { + anyhow::bail!( + "data len {:x} exceeds VMSA size {:x}", + data.len(), + size_of::() + ); } // Page count must be 1. @@ -841,11 +858,16 @@ impl IgvmLoader { anyhow::bail!("page count {page_count:x} for snp vmsa is not 1"); } + let mut padded = vec![0u8; size_of::()]; + padded[..data.len()].copy_from_slice(data); + self.directives.push(IgvmDirectiveHeader::SnpVpContext { gpa: page_base * PAGE_SIZE_4K, compatibility_mask: DEFAULT_COMPATIBILITY_MASK, vp_index: 0, - vmsa: Box::new(SevVmsa::read_from_bytes(data).expect("should be correct size")), // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) + vmsa: Box::new( + SevVmsa::read_from_bytes(padded.as_slice()).expect("should be correct size"), + ), // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) }); } else { for page in page_base..page_base + page_count { diff --git a/vm/loader/src/importer.rs b/vm/loader/src/importer.rs index e4063771d0..a74df3b5a0 100644 --- a/vm/loader/src/importer.rs +++ b/vm/loader/src/importer.rs @@ -263,6 +263,12 @@ pub enum Aarch64Register { Pc(u64), X0(u64), X1(u64), + X2(u64), + X3(u64), + X4(u64), + X5(u64), + X6(u64), + X7(u64), Cpsr(u64), VbarEl1(u64), Ttbr0El1(u64), @@ -279,6 +285,12 @@ impl From for Aarch64Register { igvm_reg::Pc(v) => Aarch64Register::Pc(v), igvm_reg::X0(v) => Aarch64Register::X0(v), igvm_reg::X1(v) => Aarch64Register::X1(v), + igvm_reg::X2(v) => Aarch64Register::X2(v), + igvm_reg::X3(v) => Aarch64Register::X3(v), + igvm_reg::X4(v) => Aarch64Register::X4(v), + igvm_reg::X5(v) => Aarch64Register::X5(v), + igvm_reg::X6(v) => Aarch64Register::X6(v), + igvm_reg::X7(v) => Aarch64Register::X7(v), igvm_reg::Cpsr(v) => Aarch64Register::Cpsr(v), igvm_reg::SctlrEl1(v) => Aarch64Register::SctlrEl1(v), igvm_reg::TcrEl1(v) => Aarch64Register::TcrEl1(v), @@ -297,6 +309,12 @@ impl From for igvm::registers::AArch64Register { Aarch64Register::Pc(v) => igvm_reg::Pc(v), Aarch64Register::X0(v) => igvm_reg::X0(v), Aarch64Register::X1(v) => igvm_reg::X1(v), + Aarch64Register::X2(v) => igvm_reg::X2(v), + Aarch64Register::X3(v) => igvm_reg::X3(v), + Aarch64Register::X4(v) => igvm_reg::X4(v), + Aarch64Register::X5(v) => igvm_reg::X5(v), + Aarch64Register::X6(v) => igvm_reg::X6(v), + Aarch64Register::X7(v) => igvm_reg::X7(v), Aarch64Register::Cpsr(v) => igvm_reg::Cpsr(v), Aarch64Register::SctlrEl1(v) => igvm_reg::SctlrEl1(v), Aarch64Register::TcrEl1(v) => igvm_reg::TcrEl1(v), diff --git a/vmm_core/vm_loader/src/initial_regs.rs b/vmm_core/vm_loader/src/initial_regs.rs index d97252b875..76f8945490 100644 --- a/vmm_core/vm_loader/src/initial_regs.rs +++ b/vmm_core/vm_loader/src/initial_regs.rs @@ -102,6 +102,12 @@ pub fn aarch64_initial_regs( Aarch64Register::Pc(v) => state.registers.pc = v, Aarch64Register::X0(v) => state.registers.x0 = v, Aarch64Register::X1(v) => state.registers.x1 = v, + Aarch64Register::X2(v) => state.registers.x2 = v, + Aarch64Register::X3(v) => state.registers.x3 = v, + Aarch64Register::X4(v) => state.registers.x4 = v, + Aarch64Register::X5(v) => state.registers.x5 = v, + Aarch64Register::X6(v) => state.registers.x6 = v, + Aarch64Register::X7(v) => state.registers.x7 = v, Aarch64Register::Cpsr(v) => state.registers.cpsr = v, Aarch64Register::Ttbr0El1(v) => state.system_registers.ttbr0_el1 = v, Aarch64Register::MairEl1(v) => state.system_registers.mair_el1 = v,