Merge "Run a non-protected VM at DebugLevel::APP_ONLY"
diff --git a/compos/common/timeouts.rs b/compos/common/timeouts.rs
index b3ec1e5..bdabb1e 100644
--- a/compos/common/timeouts.rs
+++ b/compos/common/timeouts.rs
@@ -26,8 +26,6 @@
pub struct Timeouts {
/// Total time that odrefresh may take to perform compilation
pub odrefresh_max_execution_time: Duration,
- /// Time allowed for a single compilation step run by odrefresh
- pub odrefresh_max_child_process_time: Duration,
/// Time allowed for the CompOS VM to start up and become ready.
pub vm_max_time_to_ready: Duration,
}
@@ -55,13 +53,11 @@
pub const NORMAL_TIMEOUTS: Timeouts = Timeouts {
// 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(20),
+ vm_max_time_to_ready: Duration::from_secs(15),
};
/// The timeouts that we use when need_extra_time() returns true.
pub const EXTENDED_TIMEOUTS: Timeouts = Timeouts {
odrefresh_max_execution_time: Duration::from_secs(480),
- odrefresh_max_child_process_time: Duration::from_secs(150),
vm_max_time_to_ready: Duration::from_secs(120),
};
diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md
index f598034..be97ad5 100644
--- a/docs/getting_started/index.md
+++ b/docs/getting_started/index.md
@@ -83,7 +83,7 @@
/data/local/tmp/virt/instance.img assets/vm_config.json
```
-## Building and updating CrosVM and VirtualizationService
+## Building and updating CrosVM and VirtualizationService {#building-and-updating}
You can update CrosVM and the VirtualizationService by updating the `com.android.virt` APEX instead
of rebuilding the entire image.
@@ -94,3 +94,28 @@
adb install out/dist/com.android.virt.apex
adb reboot
```
+
+## Building and updating GKI inside Microdroid
+
+Checkout the Android common kernel and build it following the [official
+guideline](https://source.android.com/setup/build/building-kernels).
+
+```shell
+mkdir android-kernel && cd android-kernel
+repo init -u https://android.googlesource.com/kernel/manifest -b common-android12-5.10
+repo sync
+FAST_BUILD=1 DIST_DIR=out/dist BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh -j80
+```
+
+Replace `build.config.gki.aarch64` with `build.config.gki.x86_64` if building
+for x86.
+
+Then copy the built kernel to the Android source tree.
+
+```
+cp out/dist/Image <android_root>/kernel/prebuilts/5.10/arm64/kernel-5.10
+```
+
+Finally rebuild the `com.android.virt` APEX and install it by following the
+steps shown in [Building and updating Crosvm and
+Virtualization](#building-and-updating).
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 65ce7ea..ed2c2a1 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -36,6 +36,8 @@
import android.system.virtualizationservice.VirtualMachineState;
import android.util.JsonReader;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -52,6 +54,8 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import java.util.zip.ZipFile;
/**
@@ -92,6 +96,9 @@
DELETED,
}
+ /** Lock for internal synchronization. */
+ private final Object mLock = new Object();
+
/** The package which owns this VM. */
private final @NonNull String mPackageName;
@@ -135,9 +142,11 @@
private @Nullable IVirtualMachine mVirtualMachine;
/** The registered callback */
+ @GuardedBy("mLock")
private @Nullable VirtualMachineCallback mCallback;
/** The executor on which the callback will be executed */
+ @GuardedBy("mLock")
private @Nullable Executor mCallbackExecutor;
private @Nullable ParcelFileDescriptor mConsoleReader;
@@ -299,20 +308,37 @@
public void setCallback(
@NonNull @CallbackExecutor Executor executor,
@NonNull VirtualMachineCallback callback) {
- mCallbackExecutor = executor;
- mCallback = callback;
+ synchronized (mLock) {
+ mCallback = callback;
+ mCallbackExecutor = executor;
+ }
}
/** Clears the currently registered callback. */
public void clearCallback() {
- // TODO(b/220730550): synchronize with the callers of the callback
- mCallback = null;
- mCallbackExecutor = null;
+ synchronized (mLock) {
+ mCallback = null;
+ mCallbackExecutor = null;
+ }
}
- /** Returns the currently registered callback. */
- public @Nullable VirtualMachineCallback getCallback() {
- return mCallback;
+ /** Executes a callback on the callback executor. */
+ private void executeCallback(Consumer<VirtualMachineCallback> fn) {
+ final VirtualMachineCallback callback;
+ final Executor executor;
+ synchronized (mLock) {
+ callback = mCallback;
+ executor = mCallbackExecutor;
+ }
+ if (callback == null || executor == null) {
+ return;
+ }
+ final long restoreToken = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> fn.accept(callback));
+ } finally {
+ Binder.restoreCallingIdentity(restoreToken);
+ }
}
/**
@@ -376,14 +402,15 @@
android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel =
android.system.virtualizationservice.VirtualMachineConfig.appConfig(appConfig);
+ // The VM should only be observed to die once
+ AtomicBoolean onDiedCalled = new AtomicBoolean(false);
+
IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
- final VirtualMachineCallback cb = mCallback;
- if (cb != null) {
- // TODO(b/220730550): don't call if the VM already died
- cb.onDied(VirtualMachine.this, VirtualMachineCallback
- .DEATH_REASON_VIRTUALIZATIONSERVICE_DIED);
+ if (onDiedCalled.compareAndSet(false, true)) {
+ executeCallback((cb) -> cb.onDied(VirtualMachine.this,
+ VirtualMachineCallback.DEATH_REASON_VIRTUALIZATIONSERVICE_DIED));
}
}
};
@@ -393,80 +420,32 @@
new IVirtualMachineCallback.Stub() {
@Override
public void onPayloadStarted(int cid, ParcelFileDescriptor stream) {
- final VirtualMachineCallback cb = mCallback;
- if (cb == null) {
- return;
- }
- final long restoreToken = Binder.clearCallingIdentity();
- try {
- mCallbackExecutor.execute(
- () -> cb.onPayloadStarted(VirtualMachine.this, stream));
- } finally {
- Binder.restoreCallingIdentity(restoreToken);
- }
+ executeCallback(
+ (cb) -> cb.onPayloadStarted(VirtualMachine.this, stream));
}
-
@Override
public void onPayloadReady(int cid) {
- final VirtualMachineCallback cb = mCallback;
- if (cb == null) {
- return;
- }
- final long restoreToken = Binder.clearCallingIdentity();
- try {
- mCallbackExecutor.execute(
- () -> cb.onPayloadReady(VirtualMachine.this));
- } finally {
- Binder.restoreCallingIdentity(restoreToken);
- }
+ executeCallback((cb) -> cb.onPayloadReady(VirtualMachine.this));
}
-
@Override
public void onPayloadFinished(int cid, int exitCode) {
- final VirtualMachineCallback cb = mCallback;
- if (cb == null) {
- return;
- }
- final long restoreToken = Binder.clearCallingIdentity();
- try {
- mCallbackExecutor.execute(
- () -> cb.onPayloadFinished(VirtualMachine.this, exitCode));
- } finally {
- Binder.restoreCallingIdentity(restoreToken);
- }
+ executeCallback(
+ (cb) -> cb.onPayloadFinished(VirtualMachine.this, exitCode));
}
-
@Override
public void onError(int cid, int errorCode, String message) {
- final VirtualMachineCallback cb = mCallback;
- if (cb == null) {
- return;
- }
- final long restoreToken = Binder.clearCallingIdentity();
- try {
- mCallbackExecutor.execute(
- () -> cb.onError(VirtualMachine.this, errorCode, message));
- } finally {
- Binder.restoreCallingIdentity(restoreToken);
- }
+ executeCallback(
+ (cb) -> cb.onError(VirtualMachine.this, errorCode, message));
}
-
@Override
public void onDied(int cid, int reason) {
service.asBinder().unlinkToDeath(deathRecipient, 0);
- final VirtualMachineCallback cb = mCallback;
- if (cb == null) {
- return;
- }
- final long restoreToken = Binder.clearCallingIdentity();
- try {
- mCallbackExecutor.execute(
- () -> cb.onDied(VirtualMachine.this, reason));
- } finally {
- Binder.restoreCallingIdentity(restoreToken);
+ if (onDiedCalled.compareAndSet(false, true)) {
+ executeCallback((cb) -> cb.onDied(VirtualMachine.this, reason));
}
}
- });
+ }
+ );
service.asBinder().linkToDeath(deathRecipient, 0);
mVirtualMachine.start();
} catch (IOException e) {
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 0ca7036..4631cf8 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -70,6 +70,7 @@
"libartpalette-system",
"apexd",
+ "atrace",
"debuggerd",
"diced.microdroid",
"linker",
diff --git a/microdroid/init.rc b/microdroid/init.rc
index 2ccdc3b..f6d5092 100644
--- a/microdroid/init.rc
+++ b/microdroid/init.rc
@@ -24,10 +24,8 @@
chmod 0755 /dev/binderfs
symlink /dev/binderfs/binder /dev/binder
- symlink /dev/binderfs/hwbinder /dev/hwbinder
symlink /dev/binderfs/vndbinder /dev/vndbinder
- chmod 0666 /dev/binderfs/hwbinder
chmod 0666 /dev/binderfs/binder
chmod 0666 /dev/binderfs/vndbinder