Merge "Remove MicrodroidTestApp.signed"
diff --git a/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb b/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
index 4199b2b..a8abf97 100644
--- a/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
+++ b/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8134799"
+ build_id: "8149267"
target: "u-boot_pvmfw"
source_file: "pvmfw.img"
}
diff --git a/compos/apk/assets/vm_config.json b/compos/apk/assets/vm_config.json
index 260332e..b93c3f7 100644
--- a/compos/apk/assets/vm_config.json
+++ b/compos/apk/assets/vm_config.json
@@ -5,10 +5,7 @@
},
"task": {
"type": "executable",
- "command": "/apex/com.android.compos/bin/compsvc",
- "args": [
- "--log_to_stderr"
- ]
+ "command": "/apex/com.android.compos/bin/compsvc"
},
"extra_apks": [
{
diff --git a/compos/apk/assets/vm_config_staged.json b/compos/apk/assets/vm_config_staged.json
index 1affa79..83fa6eb 100644
--- a/compos/apk/assets/vm_config_staged.json
+++ b/compos/apk/assets/vm_config_staged.json
@@ -5,10 +5,7 @@
},
"task": {
"type": "executable",
- "command": "/apex/com.android.compos/bin/compsvc",
- "args": [
- "--log_to_stderr"
- ]
+ "command": "/apex/com.android.compos/bin/compsvc"
},
"prefer_staged": true,
"extra_apks": [
diff --git a/compos/common/compos_client.rs b/compos/common/compos_client.rs
index 6a35fb0..72d2b76 100644
--- a/compos/common/compos_client.rs
+++ b/compos/common/compos_client.rs
@@ -37,6 +37,7 @@
};
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
use log::{info, warn};
+use rustutils::system_properties;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::num::NonZeroU32;
@@ -86,6 +87,8 @@
idsig_manifest_apk: &Path,
parameters: &VmParameters,
) -> Result<VmInstance> {
+ let protected_vm = want_protected_vm()?;
+
let instance_fd = ParcelFileDescriptor::new(instance_image);
let apex_dir = Path::new(COMPOS_APEX_ROOT);
@@ -109,7 +112,9 @@
.context("Failed to create system log file")?;
let console_fd = ParcelFileDescriptor::new(console_fd);
let log_fd = ParcelFileDescriptor::new(log_fd);
- (Some(console_fd), Some(log_fd), DebugLevel::FULL)
+ // Full debug is not available in a protected VM
+ let debug_level = if protected_vm { DebugLevel::APP_ONLY } else { DebugLevel::FULL };
+ (Some(console_fd), Some(log_fd), debug_level)
} else {
(None, None, DebugLevel::NONE)
};
@@ -122,7 +127,7 @@
configPath: config_path.to_owned(),
debugLevel: debug_level,
extraIdsigs: vec![idsig_manifest_apk_fd],
- protectedVm: false,
+ protectedVm: protected_vm,
memoryMib: VM_MEMORY_MIB,
numCpus: parameters.cpus.map_or(1, NonZeroU32::get) as i32,
cpuAffinity: parameters.cpu_set.clone(),
@@ -193,6 +198,31 @@
Ok(idsig_fd)
}
+fn want_protected_vm() -> Result<bool> {
+ let have_protected_vm =
+ system_properties::read_bool("ro.boot.hypervisor.protected_vm.supported", false)
+ .unwrap_or(false);
+ if have_protected_vm {
+ info!("Starting protected VM");
+ return Ok(true);
+ }
+
+ let build_type = system_properties::read("ro.build.type")?;
+ let is_debug_build = matches!(build_type.as_str(), "userdebug" | "eng");
+ if !is_debug_build {
+ bail!("Protected VM not supported, unable to start VM");
+ }
+
+ let have_unprotected_vm =
+ system_properties::read_bool("ro.boot.hypervisor.vm.supported", false).unwrap_or(false);
+ if have_unprotected_vm {
+ warn!("Protected VM not supported, falling back to unprotected on {} build", build_type);
+ return Ok(false);
+ }
+
+ bail!("No VM support available")
+}
+
struct VsockFactory<'a> {
vm: &'a dyn IVirtualMachine,
}
diff --git a/compos/common/timeouts.rs b/compos/common/timeouts.rs
index 42cfe69..c86ae34 100644
--- a/compos/common/timeouts.rs
+++ b/compos/common/timeouts.rs
@@ -53,7 +53,7 @@
// Note: the source of truth for these odrefresh timeouts is art/odrefresh/odr_config.h.
odrefresh_max_execution_time: Duration::from_secs(300),
odrefresh_max_child_process_time: Duration::from_secs(90),
- vm_max_time_to_ready: Duration::from_secs(10),
+ vm_max_time_to_ready: Duration::from_secs(15),
};
/// The timeouts that we use when need_extra_time() returns true.
diff --git a/compos/composd/src/odrefresh_task.rs b/compos/composd/src/odrefresh_task.rs
index 47ff590..82eedc4 100644
--- a/compos/composd/src/odrefresh_task.rs
+++ b/compos/composd/src/odrefresh_task.rs
@@ -27,7 +27,7 @@
CompilationMode::CompilationMode, ICompOsService,
};
use compos_common::odrefresh::ExitCode;
-use log::{error, warn};
+use log::{error, info, warn};
use rustutils::system_properties;
use std::fs::{remove_dir_all, File, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
@@ -96,7 +96,10 @@
// We don't do the callback if cancel has already happened.
if let Some(task) = task {
let result = match exit_code {
- Ok(ExitCode::CompilationSuccess) => task.callback.onSuccess(),
+ Ok(ExitCode::CompilationSuccess) => {
+ info!("CompilationSuccess");
+ task.callback.onSuccess()
+ }
Ok(exit_code) => {
error!("Unexpected odrefresh result: {:?}", exit_code);
task.callback.onFailure()
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index 48ba4a6..ae4a29d 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -62,7 +62,9 @@
system_server_compiler_filter: &'a str,
) -> Result<Self> {
if compilation_mode != CompilationMode::NORMAL_COMPILE {
- let debuggable = system_properties::read_bool("ro.boot.microdroid.debuggable", false)?;
+ let debuggable = is_property_set("ro.boot.microdroid.debuggable")
+ || is_property_set("ro.boot.logd.enabled")
+ || is_property_set("ro.boot.adb.enabled");
if !debuggable {
bail!("Requested compilation mode only available in debuggable VMs");
}
@@ -97,6 +99,12 @@
}
}
+// Return whether the named property is definitely enabled. Deliberately conservative; returns
+// false if the property does not exist or cannot be read or is malformed.
+fn is_property_set(name: &str) -> bool {
+ system_properties::read_bool(name, false).unwrap_or(false)
+}
+
pub fn odrefresh(
odrefresh_path: &Path,
context: OdrefreshContext,
diff --git a/compos/src/compsvc_main.rs b/compos/src/compsvc_main.rs
index ebb5514..16e3031 100644
--- a/compos/src/compsvc_main.rs
+++ b/compos/src/compsvc_main.rs
@@ -51,20 +51,13 @@
}
fn try_main() -> Result<()> {
- let args = clap::App::new("compsvc")
- .arg(clap::Arg::with_name("log_to_stderr").long("log_to_stderr"))
- .get_matches();
- if args.is_present("log_to_stderr") {
- env_logger::builder().filter_level(log::LevelFilter::Debug).init();
- } else {
- android_logger::init_once(
- android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
- );
- // Redirect panic messages to logcat.
- panic::set_hook(Box::new(|panic_info| {
- log::error!("{}", panic_info);
- }));
- }
+ android_logger::init_once(
+ android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
+ );
+ // Redirect panic messages to logcat.
+ panic::set_hook(Box::new(|panic_info| {
+ error!("{}", panic_info);
+ }));
let service = compsvc::new_binder()?.as_binder();
let vm_service = get_vm_service()?;
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
index df3ad37..a49c9be 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -60,11 +60,13 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef({
DEATH_REASON_VIRTUALIZATIONSERVICE_DIED,
- DEATH_REASON_SHUTDOWN,
- DEATH_REASON_REBOOT,
+ DEATH_REASON_INFRASTRUCTURE_ERROR,
DEATH_REASON_KILLED,
DEATH_REASON_UNKNOWN,
- DEATH_REASON_INFRASTRUCTURE_ERROR
+ DEATH_REASON_SHUTDOWN,
+ DEATH_REASON_ERROR,
+ DEATH_REASON_REBOOT,
+ DEATH_REASON_CRASH
})
@interface DeathReason {}
@@ -74,20 +76,26 @@
*/
int DEATH_REASON_VIRTUALIZATIONSERVICE_DIED = -1;
- /** The VM requested to shut down. */
- int DEATH_REASON_SHUTDOWN = 0;
-
- /** The VM requested to reboot, possibly as the result of a kernel panic. */
- int DEATH_REASON_REBOOT = 1;
+ /** There was an error waiting for the VM. */
+ int DEATH_REASON_INFRASTRUCTURE_ERROR = 0;
/** The VM was killed. */
- int DEATH_REASON_KILLED = 2;
+ int DEATH_REASON_KILLED = 1;
/** The VM died for an unknown reason. */
- int DEATH_REASON_UNKNOWN = 3;
+ int DEATH_REASON_UNKNOWN = 2;
- /** There was an error waiting for the VM. */
- int DEATH_REASON_INFRASTRUCTURE_ERROR = 4;
+ /** The VM requested to shut down. */
+ int DEATH_REASON_SHUTDOWN = 3;
+
+ /** crosvm had an error starting the VM. */
+ int DEATH_REASON_ERROR = 4;
+
+ /** The VM requested to reboot, possibly as the result of a kernel panic. */
+ int DEATH_REASON_REBOOT = 5;
+
+ /** The VM or crosvm crashed. */
+ int DEATH_REASON_CRASH = 6;
/** Called when the payload starts in the VM. */
void onPayloadStarted(@NonNull VirtualMachine vm, @Nullable ParcelFileDescriptor stream);
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 3566bd2..7384cef 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -518,11 +518,6 @@
prebuilt_etc {
name: "microdroid_uboot_env",
src: ":microdroid_uboot_env_gen",
- arch: {
- x86_64: {
- src: ":microdroid_uboot_env_gen_x86_64",
- },
- },
filename: "uboot_env.img",
}
@@ -546,26 +541,6 @@
"--image $(out)",
}
-genrule {
- name: "microdroid_uboot_env_gen_x86_64",
- tools: [
- "mkenvimage_host",
- "avbtool",
- ],
- srcs: [
- "uboot-env-x86_64.txt",
- ":microdroid_sign_key",
- ],
- out: ["output.img"],
- cmd: "$(location mkenvimage_host) -s 4096 -o $(out) $(location uboot-env-x86_64.txt) && " +
- "$(location avbtool) add_hash_footer " +
- "--algorithm SHA256_RSA4096 " +
- "--partition_name uboot_env " +
- "--key $(location :microdroid_sign_key) " +
- "--partition_size $$(( " + avb_hash_footer_kb + " * 1024 + ( $$(stat --format=%s $(out)) + 4096 - 1 ) / 4096 * 4096 )) " +
- "--image $(out)",
-}
-
// Note that keys can be different for filesystem images even though we're using the same key
// for microdroid. However, the key signing VBmeta should match with the pubkey embedded in
// bootloader.
diff --git a/microdroid/uboot-env-x86_64.txt b/microdroid/uboot-env-x86_64.txt
deleted file mode 100644
index 07a9b18..0000000
--- a/microdroid/uboot-env-x86_64.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Static u-boot environment variables for microdroid. See b/180481192
-
-# Boot the device following the Android boot procedure
-# `0` is the disk number of os_composite.img
-# `a` and `_a` are the slot index for A/B
-bootcmd=verified_boot_android virtio 0 a
-
-bootdelay=0
-
-# U-Boot in x86_64 by defaults loads kernel at 0x20000000 (512MB), which is
-# out of the physical memory when the VM is launched with the default memory
-# size of 256MB. To avoid that, explicitly set the kernel load addresss using
-# loadaddr variable.
-loadaddr=0x02000000
-fdtaddr=0x40000000
-
-# Microdroid doesn't use keymint yet
-android_keymint_needed=N
diff --git a/microdroid/uboot-env.txt b/microdroid/uboot-env.txt
index 0385b50..e5f8b79 100644
--- a/microdroid/uboot-env.txt
+++ b/microdroid/uboot-env.txt
@@ -1,12 +1 @@
-# Static u-boot environment variables for microdroid. See b/180481192
-
-# Boot the device following the Android boot procedure
-# `0` is the disk number of os_composite.img
-# `a` and `_a` are the slot index for A/B
-bootcmd=verified_boot_android virtio 0 a
-
-bootdelay=0
-fdtaddr=0x80000000
-
-# Microdroid doesn't use keymint yet
-android_keymint_needed=N
+# Empty environment for bootloader debugging
diff --git a/microdroid_manager/src/instance.rs b/microdroid_manager/src/instance.rs
index f3bbf16..4d65421 100644
--- a/microdroid_manager/src/instance.rs
+++ b/microdroid_manager/src/instance.rs
@@ -33,6 +33,8 @@
//! The payload of a partition is encrypted/signed by a key that is unique to the loader and to the
//! VM as well. Failing to decrypt/authenticate a partition by a loader stops the boot process.
+use crate::ioutil;
+
use android_security_dice::aidl::android::security::dice::IDiceNode::IDiceNode;
use anyhow::{anyhow, bail, Context, Result};
use binder::wait_for_interface;
@@ -180,7 +182,7 @@
// Persist the encrypted payload data
self.file.write_all(&data)?;
- self.file.flush()?;
+ ioutil::blkflsbuf(&mut self.file)?;
Ok(())
}
diff --git a/microdroid_manager/src/ioutil.rs b/microdroid_manager/src/ioutil.rs
index 8ab2413..8ac3712 100644
--- a/microdroid_manager/src/ioutil.rs
+++ b/microdroid_manager/src/ioutil.rs
@@ -14,11 +14,13 @@
//! IO utilities
-use anyhow::{anyhow, Result};
+use anyhow::{anyhow, bail, Result};
use log::debug;
use std::fmt::Debug;
use std::fs::File;
use std::io;
+use std::os::unix::fs::FileTypeExt;
+use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::thread;
use std::time::{Duration, Instant};
@@ -45,6 +47,20 @@
}
}
+// From include/uapi/linux/fs.h
+const BLK: u8 = 0x12;
+const BLKFLSBUF: u8 = 97;
+nix::ioctl_none!(_blkflsbuf, BLK, BLKFLSBUF);
+
+pub fn blkflsbuf(f: &mut File) -> Result<()> {
+ if !f.metadata()?.file_type().is_block_device() {
+ bail!("{:?} is not a block device", f.as_raw_fd());
+ }
+ // SAFETY: The file is kept open until the end of this function.
+ unsafe { _blkflsbuf(f.as_raw_fd()) }?;
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/pvmfw/pvmfw.img b/pvmfw/pvmfw.img
index a2541a3..c036c76 100644
--- a/pvmfw/pvmfw.img
+++ b/pvmfw/pvmfw.img
Binary files differ
diff --git a/tests/aidl/Android.bp b/tests/aidl/Android.bp
index a2315ce..893ec0b 100644
--- a/tests/aidl/Android.bp
+++ b/tests/aidl/Android.bp
@@ -9,7 +9,7 @@
backend: {
java: {
platform_apis: true,
- require_rpc: true,
+ gen_rpc: true,
},
cpp: {
enabled: true,
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 803bdc6..8cfb3a1 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -226,11 +226,6 @@
new VmEventListener() {
@Override
public void onPayloadReady(VirtualMachine vm) {
- // TODO(b/208639280): remove this sleep. For now, we need to wait for a few
- // seconds so that crosvm can actually persist instance.img.
- try {
- Thread.sleep(30 * 1000);
- } catch (InterruptedException e) { }
forceStop(vm);
}
};
@@ -291,11 +286,6 @@
} catch (Exception e) {
fail("Exception while connecting to service: " + e.toString());
}
- // TODO(b/208639280): remove this sleep. For now, we need to wait for a few
- // seconds so that crosvm can actually persist instance.img.
- try {
- Thread.sleep(30 * 1000);
- } catch (InterruptedException e) { }
forceStop(vm);
}
};
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
index 2f454a9..d736f1b 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
@@ -20,14 +20,18 @@
*/
@Backing(type="int")
enum DeathReason {
- /** The VM requested to shut down. */
- SHUTDOWN = 0,
- /** The VM requested to reboot, possibly as the result of a kernel panic. */
- REBOOT = 1,
- /** The VM was killed. */
- KILLED = 2,
- /** The VM died for an unknown reason. */
- UNKNOWN = 3,
/** There was an error waiting for the VM. */
- INFRASTRUCTURE_ERROR = 4,
+ INFRASTRUCTURE_ERROR = 0,
+ /** The VM was killed. */
+ KILLED = 1,
+ /** The VM died for an unknown reason. */
+ UNKNOWN = 2,
+ /** The VM requested to shut down. */
+ SHUTDOWN = 3,
+ /** crosvm had an error starting the VM. */
+ ERROR = 4,
+ /** The VM requested to reboot, possibly as the result of a kernel panic. */
+ REBOOT = 5,
+ /** The VM or crosvm crashed. */
+ CRASH = 6,
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 5b0c9b7..ebb01b3 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -50,7 +50,7 @@
use binder_common::{lazy_service::LazyServiceGuard, new_binder_exception};
use disk::QcowFile;
use idsig::{HashAlgorithm, V4Signature};
-use log::{debug, error, info, warn};
+use log::{debug, error, info, warn, trace};
use microdroid_payload_config::VmPayloadConfig;
use rustutils::system_properties;
use statslog_virtualization_rust::vm_creation_requested::{stats_write, Hypervisor};
@@ -440,9 +440,9 @@
fn write_vm_creation_stats(protected: bool, success: bool) {
match stats_write(Hypervisor::Pkvm, protected, success) {
Err(e) => {
- info!("stastlog_rust fails with error: {}", e);
+ warn!("statslog_rust failed with error: {}", e);
}
- Ok(_) => info!("stastlog_rust succeeded for virtualization service"),
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
}
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 76f4f47..2c50fed 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -36,8 +36,12 @@
const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
+/// The exit status which crosvm returns when it has an error starting a VM.
+const CROSVM_ERROR_STATUS: i32 = 1;
/// The exit status which crosvm returns when a VM requests a reboot.
const CROSVM_REBOOT_STATUS: i32 = 32;
+/// The exit status which crosvm returns when it crashes due to an error.
+const CROSVM_CRASH_STATUS: i32 = 33;
/// Configuration for a VM to run with crosvm.
#[derive(Debug)]
@@ -243,7 +247,9 @@
match status.code() {
None => DeathReason::KILLED,
Some(0) => DeathReason::SHUTDOWN,
+ Some(CROSVM_ERROR_STATUS) => DeathReason::ERROR,
Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
+ Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
Some(_) => DeathReason::UNKNOWN,
}
} else {
diff --git a/vm/src/run.rs b/vm/src/run.rs
index d558add..6a0fc15 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -293,11 +293,13 @@
self.dead.raise();
match reason {
- DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
- DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+ DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
DeathReason::KILLED => println!("VM was killed."),
DeathReason::UNKNOWN => println!("VM died for an unknown reason."),
- DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
+ DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
+ DeathReason::ERROR => println!("Error starting VM."),
+ DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+ DeathReason::CRASH => println!("VM crashed."),
_ => println!("VM died for an unrecognised reason."),
}
Ok(())