Merge "libavf: Fix build" into main
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
index b79e346..a0fca82 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
@@ -76,6 +76,7 @@
private SharedPathJson[] sharedPath;
private DisplayJson display;
private GpuJson gpu;
+ private boolean auto_memory_balloon;
/** Parses JSON file at jsonPath */
static ConfigJson from(Context context, Path jsonPath) {
@@ -145,7 +146,8 @@
.setBootloaderPath(bootloader)
.setKernelPath(kernel)
.setInitrdPath(initrd)
- .useNetwork(network);
+ .useNetwork(network)
+ .useAutoMemoryBalloon(auto_memory_balloon);
if (input != null) {
builder.useTouch(input.touchscreen)
diff --git a/android/virtmgr/Android.bp b/android/virtmgr/Android.bp
index ad63995..3883c34 100644
--- a/android/virtmgr/Android.bp
+++ b/android/virtmgr/Android.bp
@@ -69,7 +69,7 @@
"liblibfdt",
"libfsfdt",
"libhypervisor_props",
- "libzerocopy",
+ "libzerocopy-0.7.35",
"libuuid",
// TODO(b/202115393) stabilize the interface
"packagemanager_aidl-rust",
diff --git a/android/virtualizationservice/vfio_handler/Android.bp b/android/virtualizationservice/vfio_handler/Android.bp
index 3635cf1..fec61f1 100644
--- a/android/virtualizationservice/vfio_handler/Android.bp
+++ b/android/virtualizationservice/vfio_handler/Android.bp
@@ -28,7 +28,7 @@
"liblog_rust",
"libnix",
"librustutils",
- "libzerocopy",
+ "libzerocopy-0.7.35",
],
apex_available: ["com.android.virt"],
}
diff --git a/guest/apkdmverity/Android.bp b/guest/apkdmverity/Android.bp
index 0cb8ca1..64dde3e 100644
--- a/guest/apkdmverity/Android.bp
+++ b/guest/apkdmverity/Android.bp
@@ -22,7 +22,7 @@
"libnum_traits",
"libscopeguard",
"libuuid",
- "libzerocopy",
+ "libzerocopy-0.7.35",
],
proc_macros: ["libnum_derive"],
multilib: {
diff --git a/guest/microdroid_manager/src/vm_secret.rs b/guest/microdroid_manager/src/vm_secret.rs
index 1ad2d88..5cc90ff 100644
--- a/guest/microdroid_manager/src/vm_secret.rs
+++ b/guest/microdroid_manager/src/vm_secret.rs
@@ -36,6 +36,8 @@
use secretkeeper_comm::data_types::error::SecretkeeperError;
use std::fs;
use zeroize::Zeroizing;
+use std::sync::Mutex;
+use std::sync::Arc;
const ENCRYPTEDSTORE_KEY_IDENTIFIER: &str = "encryptedstore_key";
const AUTHORITY_HASH: i64 = -4670549;
@@ -98,27 +100,20 @@
let explicit_dice = OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice_artifacts)
.context("Failed to get Dice artifacts in explicit key format")?;
- // For pVM, skp_secret are stored in Secretkeeper. For non-protected it is all 0s.
+ let session = SkVmSession::new(vm_service, &explicit_dice)?;
+ let id = super::get_instance_id()?.ok_or(anyhow!("Missing instance_id"))?;
+ let explicit_dice_chain = explicit_dice
+ .explicit_key_dice_chain()
+ .ok_or(anyhow!("Missing explicit dice chain, this is unusual"))?;
+ let policy = sealing_policy(explicit_dice_chain)
+ .map_err(|e| anyhow!("Failed to build a sealing_policy: {e}"))?;
let mut skp_secret = Zeroizing::new([0u8; SECRET_SIZE]);
- if super::is_strict_boot() {
- let sk_service = get_secretkeeper_service(vm_service)?;
- let mut session =
- SkSession::new(sk_service, &explicit_dice, Some(get_secretkeeper_identity()?))?;
- let id = super::get_instance_id()?.ok_or(anyhow!("Missing instance_id"))?;
- let explicit_dice_chain = explicit_dice
- .explicit_key_dice_chain()
- .ok_or(anyhow!("Missing explicit dice chain, this is unusual"))?;
- let policy = sealing_policy(explicit_dice_chain)
- .map_err(|e| anyhow!("Failed to build a sealing_policy: {e}"))?;
- if let Some(secret) = get_secret(&mut session, id, Some(policy.clone()))? {
- *skp_secret = secret;
- } else {
- log::warn!(
- "No entry found in Secretkeeper for this VM instance, creating new secret."
- );
- *skp_secret = rand::random();
- store_secret(&mut session, id, skp_secret.clone(), policy)?;
- }
+ if let Some(secret) = session.get_secret(id, Some(policy.clone()))? {
+ *skp_secret = secret
+ } else {
+ log::warn!("No entry found in Secretkeeper for this VM instance, creating new secret.");
+ *skp_secret = rand::random();
+ session.store_secret(id, skp_secret.clone(), policy)?;
}
Ok(Self::V2 {
dice_artifacts: explicit_dice,
@@ -231,48 +226,67 @@
.map_err(|e| format!("DicePolicy construction failed {e:?}"))
}
-fn store_secret(
- session: &mut SkSession,
- id: [u8; ID_SIZE],
- secret: Zeroizing<[u8; SECRET_SIZE]>,
- sealing_policy: Vec<u8>,
-) -> Result<()> {
- let store_request = StoreSecretRequest { id: Id(id), secret: Secret(*secret), sealing_policy };
- log::info!("Secretkeeper operation: {:?}", store_request);
+// The secure session between VM & Secretkeeper
+struct SkVmSession(Arc<Mutex<SkSession>>);
+impl SkVmSession {
+ fn new(
+ vm_service: &Strong<dyn IVirtualMachineService>,
+ dice: &OwnedDiceArtifactsWithExplicitKey,
+ ) -> Result<Self> {
+ let secretkeeper_proxy = get_secretkeeper_service(vm_service)?;
+ let secure_session =
+ SkSession::new(secretkeeper_proxy, dice, Some(get_secretkeeper_identity()?))?;
+ let secure_session = Arc::new(Mutex::new(secure_session));
+ Ok(Self(secure_session))
+ }
- let store_request = store_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
- let store_response = session.secret_management_request(&store_request)?;
- let store_response = ResponsePacket::from_slice(&store_response).map_err(anyhow_err)?;
- let response_type = store_response.response_type().map_err(anyhow_err)?;
- ensure!(
- response_type == ResponseType::Success,
- "Secretkeeper store failed with error: {:?}",
- *SecretkeeperError::deserialize_from_packet(store_response).map_err(anyhow_err)?
- );
- Ok(())
-}
+ fn store_secret(
+ &self,
+ id: [u8; ID_SIZE],
+ secret: Zeroizing<[u8; SECRET_SIZE]>,
+ sealing_policy: Vec<u8>,
+ ) -> Result<()> {
+ let store_request =
+ StoreSecretRequest { id: Id(id), secret: Secret(*secret), sealing_policy };
+ log::info!("Secretkeeper operation: {:?}", store_request);
-fn get_secret(
- session: &mut SkSession,
- id: [u8; ID_SIZE],
- updated_sealing_policy: Option<Vec<u8>>,
-) -> Result<Option<[u8; SECRET_SIZE]>> {
- let get_request = GetSecretRequest { id: Id(id), updated_sealing_policy };
- log::info!("Secretkeeper operation: {:?}", get_request);
- let get_request = get_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
- let get_response = session.secret_management_request(&get_request)?;
- let get_response = ResponsePacket::from_slice(&get_response).map_err(anyhow_err)?;
- let response_type = get_response.response_type().map_err(anyhow_err)?;
- if response_type == ResponseType::Success {
- let get_response =
- *GetSecretResponse::deserialize_from_packet(get_response).map_err(anyhow_err)?;
- Ok(Some(get_response.secret.0))
- } else {
- let error = SecretkeeperError::deserialize_from_packet(get_response).map_err(anyhow_err)?;
- if *error == SecretkeeperError::EntryNotFound {
- return Ok(None);
+ let store_request = store_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
+ let session = &mut *self.0.lock().unwrap();
+ let store_response = session.secret_management_request(&store_request)?;
+ let store_response = ResponsePacket::from_slice(&store_response).map_err(anyhow_err)?;
+ let response_type = store_response.response_type().map_err(anyhow_err)?;
+ ensure!(
+ response_type == ResponseType::Success,
+ "Secretkeeper store failed with error: {:?}",
+ *SecretkeeperError::deserialize_from_packet(store_response).map_err(anyhow_err)?
+ );
+ Ok(())
+ }
+
+ fn get_secret(
+ &self,
+ id: [u8; ID_SIZE],
+ updated_sealing_policy: Option<Vec<u8>>,
+ ) -> Result<Option<[u8; SECRET_SIZE]>> {
+ let get_request = GetSecretRequest { id: Id(id), updated_sealing_policy };
+ log::info!("Secretkeeper operation: {:?}", get_request);
+ let get_request = get_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
+ let session = &mut *self.0.lock().unwrap();
+ let get_response = session.secret_management_request(&get_request)?;
+ let get_response = ResponsePacket::from_slice(&get_response).map_err(anyhow_err)?;
+ let response_type = get_response.response_type().map_err(anyhow_err)?;
+ if response_type == ResponseType::Success {
+ let get_response =
+ *GetSecretResponse::deserialize_from_packet(get_response).map_err(anyhow_err)?;
+ Ok(Some(get_response.secret.0))
+ } else {
+ let error =
+ SecretkeeperError::deserialize_from_packet(get_response).map_err(anyhow_err)?;
+ if *error == SecretkeeperError::EntryNotFound {
+ return Ok(None);
+ }
+ Err(anyhow!("Secretkeeper get failed: {error:?}"))
}
- Err(anyhow!("Secretkeeper get failed: {error:?}"))
}
}
diff --git a/guest/pvmfw/Android.bp b/guest/pvmfw/Android.bp
index 51f7802..23755cf 100644
--- a/guest/pvmfw/Android.bp
+++ b/guest/pvmfw/Android.bp
@@ -32,7 +32,7 @@
"libuuid_nostd",
"libvirtio_drivers",
"libvmbase",
- "libzerocopy_nostd",
+ "libzerocopy-0.7.35_nostd",
"libzeroize_nostd",
],
}
@@ -77,7 +77,7 @@
"liblibfdt",
"liblog_rust",
"libpvmfw_fdt_template",
- "libzerocopy",
+ "libzerocopy-0.7.35",
],
data: [
":test_pvmfw_devices_vm_dtbo",
@@ -119,7 +119,7 @@
"libdiced_open_dice_nostd",
"libpvmfw_avb_nostd",
"libdiced_sample_inputs_nostd",
- "libzerocopy_nostd",
+ "libzerocopy-0.7.35_nostd",
"libhex",
],
static_libs: ["libopen_dice_clear_memory"],
diff --git a/guest/pvmfw/src/entry.rs b/guest/pvmfw/src/entry.rs
index 7c46515..862fb1d 100644
--- a/guest/pvmfw/src/entry.rs
+++ b/guest/pvmfw/src/entry.rs
@@ -15,10 +15,9 @@
//! Low-level entry and exit points of pvmfw.
use crate::config;
-use crate::memory;
+use crate::memory::MemorySlices;
use core::arch::asm;
use core::mem::size_of;
-use core::ops::Range;
use core::slice;
use log::error;
use log::warn;
@@ -88,14 +87,14 @@
let reboot_reason = match main_wrapper(fdt_address, payload_start, payload_size) {
Err(r) => r,
- Ok((next_stage, bcc)) => match next_stage {
- NextStage::LinuxBootWithUart(ep) => jump_to_payload(fdt_address, ep, bcc),
+ Ok((next_stage, slices)) => match next_stage {
+ NextStage::LinuxBootWithUart(ep) => jump_to_payload(ep, &slices),
NextStage::LinuxBoot(ep) => {
if let Err(e) = unshare_uart() {
error!("Failed to unmap UART: {e}");
RebootReason::InternalError
} else {
- jump_to_payload(fdt_address, ep, bcc)
+ jump_to_payload(ep, &slices)
}
}
},
@@ -112,11 +111,11 @@
///
/// Provide the abstractions necessary for start() to abort the pVM boot and for main() to run with
/// the assumption that its environment has been properly configured.
-fn main_wrapper(
+fn main_wrapper<'a>(
fdt: usize,
payload: usize,
payload_size: usize,
-) -> Result<(NextStage, Range<usize>), RebootReason> {
+) -> Result<(NextStage, MemorySlices<'a>), RebootReason> {
// Limitations in this function:
// - only access MMIO once (and while) it has been mapped and configured
// - only perform logging once the logger has been initialized
@@ -136,7 +135,7 @@
let config_entries = appended.get_entries();
- let slices = memory::MemorySlices::new(fdt, payload, payload_size)?;
+ let mut slices = MemorySlices::new(fdt, payload, payload_size)?;
// This wrapper allows main() to be blissfully ignorant of platform details.
let (next_bcc, debuggable_payload) = crate::main(
@@ -148,6 +147,7 @@
config_entries.vm_dtbo,
config_entries.vm_ref_dt,
)?;
+ slices.add_dice_chain(next_bcc);
// Keep UART MMIO_GUARD-ed for debuggable payloads, to enable earlycon.
let keep_uart = cfg!(debuggable_vms_improvements) && debuggable_payload;
@@ -162,7 +162,7 @@
let next_stage = select_next_stage(slices.kernel, keep_uart);
- Ok((next_stage, next_bcc))
+ Ok((next_stage, slices))
}
fn select_next_stage(kernel: &[u8], keep_uart: bool) -> NextStage {
@@ -173,7 +173,16 @@
}
}
-fn jump_to_payload(fdt_address: usize, payload_start: usize, bcc: Range<usize>) -> ! {
+fn jump_to_payload(entrypoint: usize, slices: &MemorySlices) -> ! {
+ let fdt_address = slices.fdt.as_ptr() as usize;
+ let bcc = slices
+ .dice_chain
+ .map(|slice| {
+ let r = slice.as_ptr_range();
+ (r.start as usize)..(r.end as usize)
+ })
+ .expect("Missing DICE chain");
+
deactivate_dynamic_page_tables();
const ASM_STP_ALIGN: usize = size_of::<u64>() * 2;
@@ -313,7 +322,7 @@
eh_stack_end = in(reg) u64::try_from(eh_stack.end.0).unwrap(),
dcache_line_size = in(reg) u64::try_from(min_dcache_line_size()).unwrap(),
in("x0") u64::try_from(fdt_address).unwrap(),
- in("x30") u64::try_from(payload_start).unwrap(),
+ in("x30") u64::try_from(entrypoint).unwrap(),
options(noreturn),
);
};
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index d04db06..a28a039 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -40,7 +40,6 @@
use alloc::borrow::Cow;
use alloc::boxed::Box;
use bssl_avf::Digester;
-use core::ops::Range;
use cstr::cstr;
use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
use libfdt::{Fdt, FdtNode};
@@ -54,7 +53,7 @@
use vmbase::rand;
use vmbase::virtio::pci;
-fn main(
+fn main<'a>(
untrusted_fdt: &mut Fdt,
signed_kernel: &[u8],
ramdisk: Option<&[u8]>,
@@ -62,7 +61,7 @@
mut debug_policy: Option<&[u8]>,
vm_dtbo: Option<&mut [u8]>,
vm_ref_dt: Option<&[u8]>,
-) -> Result<(Range<usize>, bool), RebootReason> {
+) -> Result<(&'a [u8], bool), RebootReason> {
info!("pVM firmware");
debug!("FDT: {:?}", untrusted_fdt.as_ptr());
debug!("Signed kernel: {:?} ({:#x} bytes)", signed_kernel.as_ptr(), signed_kernel.len());
@@ -201,13 +200,7 @@
})?;
info!("Starting payload...");
-
- let bcc_range = {
- let r = next_bcc.as_ptr_range();
- (r.start as usize)..(r.end as usize)
- };
-
- Ok((bcc_range, debuggable))
+ Ok((next_bcc, debuggable))
}
// Get the "salt" which is one of the input for DICE derivation.
diff --git a/guest/pvmfw/src/memory.rs b/guest/pvmfw/src/memory.rs
index d2f63b5..a663008 100644
--- a/guest/pvmfw/src/memory.rs
+++ b/guest/pvmfw/src/memory.rs
@@ -31,6 +31,7 @@
pub fdt: &'a mut libfdt::Fdt,
pub kernel: &'a [u8],
pub ramdisk: Option<&'a [u8]>,
+ pub dice_chain: Option<&'a [u8]>,
}
impl<'a> MemorySlices<'a> {
@@ -111,6 +112,12 @@
None
};
- Ok(Self { fdt: untrusted_fdt, kernel, ramdisk })
+ let dice_chain = None;
+
+ Ok(Self { fdt: untrusted_fdt, kernel, ramdisk, dice_chain })
+ }
+
+ pub fn add_dice_chain(&mut self, dice_chain: &'a [u8]) {
+ self.dice_chain = Some(dice_chain)
}
}
diff --git a/libs/devicemapper/Android.bp b/libs/devicemapper/Android.bp
index 5332469..17727f1 100644
--- a/libs/devicemapper/Android.bp
+++ b/libs/devicemapper/Android.bp
@@ -16,7 +16,7 @@
"libhex",
"libnix",
"libuuid",
- "libzerocopy",
+ "libzerocopy-0.7.35",
],
multilib: {
lib32: {
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
index 3829f9f..d120cd8 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -621,8 +621,8 @@
&& this.mVmOutputCaptured == other.mVmOutputCaptured
&& this.mVmConsoleInputSupported == other.mVmConsoleInputSupported
&& this.mConnectVmConsole == other.mConnectVmConsole
- && this.mConsoleInputDevice == other.mConsoleInputDevice
&& (this.mVendorDiskImage == null) == (other.mVendorDiskImage == null)
+ && Objects.equals(this.mConsoleInputDevice, other.mConsoleInputDevice)
&& Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
&& Objects.equals(this.mPayloadBinaryName, other.mPayloadBinaryName)
&& Objects.equals(this.mPackageName, other.mPackageName)
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 09f288d..1e24ff4 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -38,7 +38,7 @@
"libcstr",
"liblibfdt_bindgen",
"libstatic_assertions",
- "libzerocopy_nostd",
+ "libzerocopy-0.7.35_nostd",
],
}
diff --git a/libs/libvmbase/Android.bp b/libs/libvmbase/Android.bp
index 3088633..7bcdc1d 100644
--- a/libs/libvmbase/Android.bp
+++ b/libs/libvmbase/Android.bp
@@ -91,7 +91,7 @@
"libtinyvec_nostd",
"libuuid_nostd",
"libvirtio_drivers",
- "libzerocopy_nostd",
+ "libzerocopy-0.7.35_nostd",
"libzeroize_nostd",
],
whole_static_libs: [