mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-27 20:18:57 +00:00
Merge 0cb1535ad1
into 9379a18c8a
This commit is contained in:
commit
bc240aa2a1
@ -6,6 +6,8 @@
|
|||||||
#[cfg(any(target_arch = "s390x", target_arch = "x86_64", target_arch = "aarch64"))]
|
#[cfg(any(target_arch = "s390x", target_arch = "x86_64", target_arch = "aarch64"))]
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use std::arch::x86_64;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[cfg(all(target_arch = "powerpc64", target_endian = "little"))]
|
#[cfg(all(target_arch = "powerpc64", target_endian = "little"))]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -26,6 +28,7 @@ use std::fs;
|
|||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct SevSnpDetails {
|
pub struct SevSnpDetails {
|
||||||
pub cbitpos: u32,
|
pub cbitpos: u32,
|
||||||
|
pub phys_addr_reduction: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -117,17 +120,39 @@ pub fn arch_guest_protection(
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
let retrieve_sev_cbitpos = || -> Result<u32, ProtectionError> {
|
let retrieve_sev_params = || -> Result<(u32, u32), ProtectionError> {
|
||||||
Err(ProtectionError::CheckFailed(
|
// The initial checks for AMD and SEV shouldn't be necessary due to
|
||||||
"cbitpos retrieval NOT IMPLEMENTED YET".to_owned(),
|
// the context this function is currently called from, however it
|
||||||
))
|
// shouldn't hurt to double-check and have better logging if anything
|
||||||
|
// goes wrong.
|
||||||
|
|
||||||
|
let fn0 = unsafe { x86_64::__cpuid(0) };
|
||||||
|
// The values in [ ebx, edx, ecx ] spell out "AuthenticAMD" when
|
||||||
|
// interpreted byte-wise as ASCII. No need to bother here with an
|
||||||
|
// actual conversion to string though.
|
||||||
|
// See also AMD64 Architecture Programmer's Manual pg. 600
|
||||||
|
// https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24594.pdf
|
||||||
|
if fn0.ebx != 0x68747541 || fn0.edx != 0x69746e65 || fn0.ecx != 0x444d4163 {
|
||||||
|
return Err(ProtectionError::CheckFailed("Not an AMD processor".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// AMD64 Architecture Prgrammer's Manual Fn8000_001f docs on pg. 640
|
||||||
|
let fn8000_001f = unsafe { x86_64::__cpuid(0x8000_001f) };
|
||||||
|
if fn8000_001f.eax & 0x10 == 0 {
|
||||||
|
return Err(ProtectionError::CheckFailed("SEV not supported".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let cbitpos = fn8000_001f.ebx & 0b11_1111;
|
||||||
|
let phys_addr_reduction = (fn8000_001f.ebx & 0b1111_1100_0000) >> 6;
|
||||||
|
|
||||||
|
Ok((cbitpos, phys_addr_reduction))
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_snp_available = check_contents(snp_path)?;
|
let is_snp_available = check_contents(snp_path)?;
|
||||||
let is_sev_available = is_snp_available || check_contents(sev_path)?;
|
let is_sev_available = is_snp_available || check_contents(sev_path)?;
|
||||||
if is_snp_available || is_sev_available {
|
if is_snp_available || is_sev_available {
|
||||||
let cbitpos = retrieve_sev_cbitpos()?;
|
let (cbitpos, phys_addr_reduction) = retrieve_sev_params()?;
|
||||||
let sev_snp_details = SevSnpDetails { cbitpos };
|
let sev_snp_details = SevSnpDetails { cbitpos, phys_addr_reduction };
|
||||||
return Ok(if is_snp_available {
|
return Ok(if is_snp_available {
|
||||||
GuestProtection::Snp(sev_snp_details)
|
GuestProtection::Snp(sev_snp_details)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2144,7 +2144,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_tdx_rootfs_settings() {
|
fn test_check_tdx_rootfs_settings() {
|
||||||
let sev_snp_details = SevSnpDetails { cbitpos: 42 };
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let sev_snp_details = SevSnpDetails {
|
||||||
|
cbitpos: 42,
|
||||||
|
phys_addr_reduction: 42,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData<'a> {
|
struct TestData<'a> {
|
||||||
|
@ -539,7 +539,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_guest_protection_is_tdx() {
|
fn test_guest_protection_is_tdx() {
|
||||||
let sev_snp_details = SevSnpDetails { cbitpos: 42 };
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let sev_snp_details = SevSnpDetails {
|
||||||
|
cbitpos: 42,
|
||||||
|
phys_addr_reduction: 42,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
|
@ -1110,7 +1110,15 @@ mod tests {
|
|||||||
// available_guest_protection() requires super user privs.
|
// available_guest_protection() requires super user privs.
|
||||||
skip_if_not_root!();
|
skip_if_not_root!();
|
||||||
|
|
||||||
let sev_snp_details = SevSnpDetails { cbitpos: 42 };
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let sev_snp_details = SevSnpDetails {
|
||||||
|
cbitpos: 42,
|
||||||
|
phys_addr_reduction: 42,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
|
@ -21,6 +21,7 @@ pub enum ProtectionDeviceConfig {
|
|||||||
pub struct SevSnpConfig {
|
pub struct SevSnpConfig {
|
||||||
pub is_snp: bool,
|
pub is_snp: bool,
|
||||||
pub cbitpos: u32,
|
pub cbitpos: u32,
|
||||||
|
pub phys_addr_reduction: u32,
|
||||||
pub firmware: String,
|
pub firmware: String,
|
||||||
pub host_data: Option<String>,
|
pub host_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -1803,11 +1803,11 @@ struct ObjectSevSnpGuest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectSevSnpGuest {
|
impl ObjectSevSnpGuest {
|
||||||
fn new(is_snp: bool, cbitpos: u32, host_data: Option<String>) -> Self {
|
fn new(is_snp: bool, cbitpos: u32, reduced_phys_bits: u32, host_data: Option<String>) -> Self {
|
||||||
ObjectSevSnpGuest {
|
ObjectSevSnpGuest {
|
||||||
id: (if is_snp { "snp" } else { "sev" }).to_owned(),
|
id: (if is_snp { "snp" } else { "sev" }).to_owned(),
|
||||||
cbitpos,
|
cbitpos,
|
||||||
reduced_phys_bits: 1,
|
reduced_phys_bits,
|
||||||
kernel_hashes: true,
|
kernel_hashes: true,
|
||||||
host_data,
|
host_data,
|
||||||
is_snp,
|
is_snp,
|
||||||
@ -2433,8 +2433,13 @@ impl<'a> QemuCmdLine<'a> {
|
|||||||
.remove_all_by_key("rootfstype".to_string());
|
.remove_all_by_key("rootfstype".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_sev_protection_device(&mut self, cbitpos: u32, firmware: &str) {
|
pub fn add_sev_protection_device(
|
||||||
let sev_object = ObjectSevSnpGuest::new(true, cbitpos, None);
|
&mut self,
|
||||||
|
cbitpos: u32,
|
||||||
|
phys_addr_reduction: u32,
|
||||||
|
firmware: &str,
|
||||||
|
) {
|
||||||
|
let sev_object = ObjectSevSnpGuest::new(false, cbitpos, phys_addr_reduction, None);
|
||||||
self.devices.push(Box::new(sev_object));
|
self.devices.push(Box::new(sev_object));
|
||||||
|
|
||||||
self.devices.push(Box::new(Bios::new(firmware.to_owned())));
|
self.devices.push(Box::new(Bios::new(firmware.to_owned())));
|
||||||
@ -2447,10 +2452,12 @@ impl<'a> QemuCmdLine<'a> {
|
|||||||
pub fn add_sev_snp_protection_device(
|
pub fn add_sev_snp_protection_device(
|
||||||
&mut self,
|
&mut self,
|
||||||
cbitpos: u32,
|
cbitpos: u32,
|
||||||
|
phys_addr_reduction: u32,
|
||||||
firmware: &str,
|
firmware: &str,
|
||||||
host_data: &Option<String>,
|
host_data: &Option<String>,
|
||||||
) {
|
) {
|
||||||
let sev_snp_object = ObjectSevSnpGuest::new(true, cbitpos, host_data.clone());
|
let sev_snp_object =
|
||||||
|
ObjectSevSnpGuest::new(true, cbitpos, phys_addr_reduction, host_data.clone());
|
||||||
self.devices.push(Box::new(sev_snp_object));
|
self.devices.push(Box::new(sev_snp_object));
|
||||||
|
|
||||||
self.devices.push(Box::new(Bios::new(firmware.to_owned())));
|
self.devices.push(Box::new(Bios::new(firmware.to_owned())));
|
||||||
|
@ -136,12 +136,14 @@ impl QemuInner {
|
|||||||
if sev_snp_cfg.is_snp {
|
if sev_snp_cfg.is_snp {
|
||||||
cmdline.add_sev_snp_protection_device(
|
cmdline.add_sev_snp_protection_device(
|
||||||
sev_snp_cfg.cbitpos,
|
sev_snp_cfg.cbitpos,
|
||||||
|
sev_snp_cfg.phys_addr_reduction,
|
||||||
&sev_snp_cfg.firmware,
|
&sev_snp_cfg.firmware,
|
||||||
&sev_snp_cfg.host_data,
|
&sev_snp_cfg.host_data,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
cmdline.add_sev_protection_device(
|
cmdline.add_sev_protection_device(
|
||||||
sev_snp_cfg.cbitpos,
|
sev_snp_cfg.cbitpos,
|
||||||
|
sev_snp_cfg.phys_addr_reduction,
|
||||||
&sev_snp_cfg.firmware,
|
&sev_snp_cfg.firmware,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -393,6 +393,7 @@ impl VirtSandbox {
|
|||||||
Ok(Some(ProtectionDeviceConfig::SevSnp(SevSnpConfig {
|
Ok(Some(ProtectionDeviceConfig::SevSnp(SevSnpConfig {
|
||||||
is_snp: false,
|
is_snp: false,
|
||||||
cbitpos: details.cbitpos,
|
cbitpos: details.cbitpos,
|
||||||
|
phys_addr_reduction: details.phys_addr_reduction,
|
||||||
firmware: hypervisor_config.boot_info.firmware.clone(),
|
firmware: hypervisor_config.boot_info.firmware.clone(),
|
||||||
host_data: None,
|
host_data: None,
|
||||||
})))
|
})))
|
||||||
@ -413,6 +414,7 @@ impl VirtSandbox {
|
|||||||
Ok(Some(ProtectionDeviceConfig::SevSnp(SevSnpConfig {
|
Ok(Some(ProtectionDeviceConfig::SevSnp(SevSnpConfig {
|
||||||
is_snp,
|
is_snp,
|
||||||
cbitpos: details.cbitpos,
|
cbitpos: details.cbitpos,
|
||||||
|
phys_addr_reduction: details.phys_addr_reduction,
|
||||||
firmware: hypervisor_config.boot_info.firmware.clone(),
|
firmware: hypervisor_config.boot_info.firmware.clone(),
|
||||||
host_data: init_data,
|
host_data: init_data,
|
||||||
})))
|
})))
|
||||||
|
Loading…
Reference in New Issue
Block a user