diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index f3e4fe9..b026fe3 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -105,11 +105,11 @@
  * @hide
  */
 public class VirtualMachine implements AutoCloseable {
+    /** Map from context to a map of all that context's VMs by name. */
+    @GuardedBy("sCreateLock")
     private static final Map<Context, Map<String, WeakReference<VirtualMachine>>> sInstances =
             new WeakHashMap<>();
 
-    private static final Object sInstancesLock = new Object();
-
     /** Name of the directory under the files directory where all VMs created for the app exist. */
     private static final String VM_DIR = "vm";
 
@@ -138,7 +138,6 @@
     public static final String USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION =
             "android.permission.USE_CUSTOM_VIRTUAL_MACHINE";
 
-
     /**
      * Status of a virtual machine
      *
@@ -165,9 +164,6 @@
      */
     public static final int STATUS_DELETED = 2;
 
-    /** Lock for internal synchronization. */
-    private final Object mLock = new Object();
-
     /** The package which owns this VM. */
     @NonNull private final String mPackageName;
 
@@ -175,6 +171,11 @@
     @NonNull private final String mName;
 
     /**
+     * Path to the directory containing all the files related to this VM.
+     */
+    @NonNull private final File mVmRootPath;
+
+    /**
      * Path to the config file for this VM. The config file is where the configuration is persisted.
      */
     @NonNull private final File mConfigFilePath;
@@ -196,38 +197,69 @@
     }
 
     /**
-     * List of extra apks. Apks are specified by the vm config, and corresponding idsigs are to be
-     * generated.
+     * Unmodifiable list of extra apks. Apks are specified by the vm config, and corresponding
+     * idsigs are to be generated.
      */
     @NonNull private final List<ExtraApkSpec> mExtraApks;
 
     /** Size of the instance image. 10 MB. */
     private static final long INSTANCE_FILE_SIZE = 10 * 1024 * 1024;
 
+    // A note on lock ordering:
+    // You can take mLock while holding sCreateLock, but not vice versa.
+    // We never take any other lock while holding mCallbackLock; therefore you can
+    // take mCallbackLock while holding any other lock.
+
+    /**
+     * A lock used to synchronize the creation of virtual machines. It protects
+     * {@link #sInstances}, but is also held throughout VM creation / retrieval / deletion, to
+     * prevent these actions racing with each other.
+     */
+    static final Object sCreateLock = new Object();
+
+    /** Lock protecting our mutable state (other than callbacks). */
+    private final Object mLock = new Object();
+
+    /** Lock protecting callbacks. */
+    private final Object mCallbackLock = new Object();
+
+
     /** The configuration that is currently associated with this VM. */
-    @NonNull private VirtualMachineConfig mConfig;
+    @GuardedBy("mLock")
+    @NonNull
+    private VirtualMachineConfig mConfig;
 
     /** Handle to the "running" VM. */
-    @Nullable private IVirtualMachine mVirtualMachine;
+    @GuardedBy("mLock")
+    @Nullable
+    private IVirtualMachine mVirtualMachine;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleWriter;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mLogReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mLogWriter;
 
     /** The registered callback */
-    @GuardedBy("mLock")
+    @GuardedBy("mCallbackLock")
     @Nullable
     private VirtualMachineCallback mCallback;
 
     /** The executor on which the callback will be executed */
-    @GuardedBy("mLock")
+    @GuardedBy("mCallbackLock")
     @Nullable
     private Executor mCallbackExecutor;
 
-    @Nullable private ParcelFileDescriptor mConsoleReader;
-    @Nullable private ParcelFileDescriptor mConsoleWriter;
-
-    @Nullable private ParcelFileDescriptor mLogReader;
-    @Nullable private ParcelFileDescriptor mLogWriter;
-
-    @NonNull private final Context mContext;
-
     static {
         System.loadLibrary("virtualmachine_jni");
     }
@@ -235,86 +267,111 @@
     private VirtualMachine(
             @NonNull Context context, @NonNull String name, @NonNull VirtualMachineConfig config)
             throws VirtualMachineException {
-        mContext = context;
         mPackageName = context.getPackageName();
         mName = requireNonNull(name, "Name must not be null");
         mConfig = requireNonNull(config, "Config must not be null");
 
         File thisVmDir = getVmDir(context, mName);
+        mVmRootPath = thisVmDir;
         mConfigFilePath = new File(thisVmDir, CONFIG_FILE);
         mInstanceFilePath = new File(thisVmDir, INSTANCE_IMAGE_FILE);
         mIdsigFilePath = new File(thisVmDir, IDSIG_FILE);
         mExtraApks = setupExtraApks(context, config, thisVmDir);
     }
 
+    @GuardedBy("sCreateLock")
+    @NonNull
+    private static Map<String, WeakReference<VirtualMachine>> getInstancesMap(Context context) {
+        Map<String, WeakReference<VirtualMachine>> instancesMap;
+        if (sInstances.containsKey(context)) {
+            instancesMap = sInstances.get(context);
+        } else {
+            instancesMap = new HashMap<>();
+            sInstances.put(context, instancesMap);
+        }
+        return instancesMap;
+    }
+
+    @NonNull
+    private static File getVmDir(Context context, String name) {
+        File vmRoot = new File(context.getDataDir(), VM_DIR);
+        return new File(vmRoot, name);
+    }
+
     /**
      * Creates a virtual machine with the given name and config. Once a virtual machine is created
-     * it is persisted until it is deleted by calling {@link #delete()}. The created virtual machine
-     * is in {@link #STATUS_STOPPED} state. To run the VM, call {@link #run()}.
+     * it is persisted until it is deleted by calling {@link #delete}. The created virtual machine
+     * is in {@link #STATUS_STOPPED} state. To run the VM, call {@link #run}.
      */
+    @GuardedBy("sCreateLock")
     @NonNull
     static VirtualMachine create(
             @NonNull Context context, @NonNull String name, @NonNull VirtualMachineConfig config)
             throws VirtualMachineException {
-        VirtualMachine vm = new VirtualMachine(context, name, config);
+        File vmDir = getVmDir(context, name);
 
         try {
-            final File thisVmDir = vm.mConfigFilePath.getParentFile();
-            Files.createDirectories(thisVmDir.getParentFile().toPath());
+            // We don't need to undo this even if VM creation fails.
+            Files.createDirectories(vmDir.getParentFile().toPath());
 
             // The checking of the existence of this directory and the creation of it is done
             // atomically. If the directory already exists (i.e. the VM with the same name was
-            // already created), FileAlreadyExistsException is thrown
-            Files.createDirectory(thisVmDir.toPath());
-
-            try (FileOutputStream output = new FileOutputStream(vm.mConfigFilePath)) {
-                vm.mConfig.serialize(output);
-            }
+            // already created), FileAlreadyExistsException is thrown.
+            Files.createDirectory(vmDir.toPath());
         } catch (FileAlreadyExistsException e) {
             throw new VirtualMachineException("virtual machine already exists", e);
         } catch (IOException e) {
-            throw new VirtualMachineException(e);
+            throw new VirtualMachineException("failed to create directory for VM", e);
         }
 
         try {
-            vm.mInstanceFilePath.createNewFile();
-        } catch (IOException e) {
-            throw new VirtualMachineException("failed to create instance image", e);
-        }
+            VirtualMachine vm = new VirtualMachine(context, name, config);
 
-        IVirtualizationService service =
-                IVirtualizationService.Stub.asInterface(
-                        ServiceManager.waitForService(SERVICE_NAME));
-
-        try {
-            service.initializeWritablePartition(
-                    ParcelFileDescriptor.open(vm.mInstanceFilePath, MODE_READ_WRITE),
-                    INSTANCE_FILE_SIZE,
-                    PartitionType.ANDROID_VM_INSTANCE);
-        } catch (FileNotFoundException e) {
-            throw new VirtualMachineException("instance image missing", e);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        } catch (ServiceSpecificException | IllegalArgumentException e) {
-            throw new VirtualMachineException("failed to create instance partition", e);
-        }
-
-        synchronized (sInstancesLock) {
-            Map<String, WeakReference<VirtualMachine>> instancesMap;
-            if (sInstances.containsKey(context)) {
-                instancesMap = sInstances.get(context);
-            } else {
-                instancesMap = new HashMap<>();
-                sInstances.put(context, instancesMap);
+            try (FileOutputStream output = new FileOutputStream(vm.mConfigFilePath)) {
+                config.serialize(output);
+            } catch (IOException e) {
+                throw new VirtualMachineException("failed to write VM config", e);
             }
 
-            instancesMap.put(name, new WeakReference<>(vm));
-        }
+            try {
+                vm.mInstanceFilePath.createNewFile();
+            } catch (IOException e) {
+                throw new VirtualMachineException("failed to create instance image", e);
+            }
 
-        return vm;
+            IVirtualizationService service =
+                    IVirtualizationService.Stub.asInterface(
+                            ServiceManager.waitForService(SERVICE_NAME));
+
+            try {
+                service.initializeWritablePartition(
+                        ParcelFileDescriptor.open(vm.mInstanceFilePath, MODE_READ_WRITE),
+                        INSTANCE_FILE_SIZE,
+                        PartitionType.ANDROID_VM_INSTANCE);
+            } catch (FileNotFoundException e) {
+                throw new VirtualMachineException("instance image missing", e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException | IllegalArgumentException e) {
+                throw new VirtualMachineException("failed to create instance partition", e);
+            }
+
+            getInstancesMap(context).put(name, new WeakReference<>(vm));
+
+            return vm;
+        } catch (VirtualMachineException | RuntimeException e) {
+            // If anything goes wrong, delete any files created so far and the VM's directory
+            try {
+                deleteRecursively(vmDir);
+            } catch (IOException innerException) {
+                e.addSuppressed(innerException);
+            }
+            throw e;
+        }
     }
 
     /** Loads a virtual machine that is already created before. */
+    @GuardedBy("sCreateLock")
     @Nullable
     static VirtualMachine load(
             @NonNull Context context, @NonNull String name) throws VirtualMachineException {
@@ -331,32 +388,50 @@
             throw new VirtualMachineException("Failed to read config file", e);
         }
 
-        VirtualMachine vm = null;
-        synchronized (sInstancesLock) {
-            Map<String, WeakReference<VirtualMachine>> instancesMap;
-            if (sInstances.containsKey(context)) {
-                instancesMap = sInstances.get(context);
-            } else {
-                instancesMap = new HashMap<>();
-                sInstances.put(context, instancesMap);
-            }
+        Map<String, WeakReference<VirtualMachine>> instancesMap = getInstancesMap(context);
 
-            if (instancesMap.containsKey(name)) {
-                vm = instancesMap.get(name).get();
-            }
-            if (vm == null) {
-                vm = new VirtualMachine(context, name, config);
-                instancesMap.put(name, new WeakReference<>(vm));
-            }
+        VirtualMachine vm = null;
+        if (instancesMap.containsKey(name)) {
+            vm = instancesMap.get(name).get();
+        }
+        if (vm == null) {
+            vm = new VirtualMachine(context, name, config);
         }
 
         if (!vm.mInstanceFilePath.exists()) {
             throw new VirtualMachineException("instance image missing");
         }
 
+        instancesMap.put(name, new WeakReference<>(vm));
+
         return vm;
     }
 
+    @GuardedBy("sCreateLock")
+    static void delete(Context context, String name) throws VirtualMachineException {
+        Map<String, WeakReference<VirtualMachine>> instancesMap = sInstances.get(context);
+        VirtualMachine vm;
+        if (instancesMap != null && instancesMap.containsKey(name)) {
+            vm = instancesMap.get(name).get();
+        } else {
+            vm = null;
+        }
+
+        if (vm != null) {
+            synchronized (vm.mLock) {
+                vm.checkStopped();
+            }
+        }
+
+        try {
+            deleteRecursively(getVmDir(context, name));
+        } catch (IOException e) {
+            throw new VirtualMachineException(e);
+        }
+
+        if (instancesMap != null) instancesMap.remove(name);
+    }
+
     /**
      * Returns the name of this virtual machine. The name is unique in the package and can't be
      * changed.
@@ -379,7 +454,9 @@
      */
     @NonNull
     public VirtualMachineConfig getConfig() {
-        return mConfig;
+        synchronized (mLock) {
+            return mConfig;
+        }
     }
 
     /**
@@ -389,27 +466,70 @@
      */
     @Status
     public int getStatus() {
+        IVirtualMachine virtualMachine;
+        synchronized (mLock) {
+            virtualMachine = mVirtualMachine;
+        }
+        if (virtualMachine == null) {
+            return mVmRootPath.exists() ? STATUS_STOPPED : STATUS_DELETED;
+        } else {
+            try {
+                return stateToStatus(virtualMachine.getState());
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    private int stateToStatus(@VirtualMachineState int state) {
+        switch (state) {
+            case VirtualMachineState.STARTING:
+            case VirtualMachineState.STARTED:
+            case VirtualMachineState.READY:
+            case VirtualMachineState.FINISHED:
+                return STATUS_RUNNING;
+            case VirtualMachineState.NOT_STARTED:
+            case VirtualMachineState.DEAD:
+            default:
+                return STATUS_STOPPED;
+        }
+    }
+
+    // Throw an appropriate exception if we have a running VM, or the VM has been deleted.
+    @GuardedBy("mLock")
+    private void checkStopped() throws VirtualMachineException {
+        if (!mVmRootPath.exists()) {
+            throw new VirtualMachineException("VM has been deleted");
+        }
+        if (mVirtualMachine == null) {
+            return;
+        }
         try {
-            if (mVirtualMachine != null) {
-                switch (mVirtualMachine.getState()) {
-                    case VirtualMachineState.NOT_STARTED:
-                        return STATUS_STOPPED;
-                    case VirtualMachineState.STARTING:
-                    case VirtualMachineState.STARTED:
-                    case VirtualMachineState.READY:
-                    case VirtualMachineState.FINISHED:
-                        return STATUS_RUNNING;
-                    case VirtualMachineState.DEAD:
-                        return STATUS_STOPPED;
+            if (stateToStatus(mVirtualMachine.getState()) != STATUS_STOPPED) {
+                throw new VirtualMachineException("VM is not in stopped state");
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    // If we have an IVirtualMachine in the running state return it, otherwise throw.
+    @GuardedBy("mLock")
+    private IVirtualMachine getRunningVm() throws VirtualMachineException {
+        try {
+            if (mVirtualMachine != null
+                    && stateToStatus(mVirtualMachine.getState()) == STATUS_RUNNING) {
+                return mVirtualMachine;
+            } else {
+                if (!mVmRootPath.exists()) {
+                    throw new VirtualMachineException("VM has been deleted");
+                } else {
+                    throw new VirtualMachineException("VM is not in running state");
                 }
             }
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
-        if (!mConfigFilePath.exists()) {
-            return STATUS_DELETED;
-        }
-        return STATUS_STOPPED;
     }
 
     /**
@@ -420,7 +540,7 @@
      */
     public void setCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull VirtualMachineCallback callback) {
-        synchronized (mLock) {
+        synchronized (mCallbackLock) {
             mCallback = callback;
             mCallbackExecutor = executor;
         }
@@ -432,7 +552,7 @@
      * @hide
      */
     public void clearCallback() {
-        synchronized (mLock) {
+        synchronized (mCallbackLock) {
             mCallback = null;
             mCallbackExecutor = null;
         }
@@ -442,7 +562,7 @@
     private void executeCallback(Consumer<VirtualMachineCallback> fn) {
         final VirtualMachineCallback callback;
         final Executor executor;
-        synchronized (mLock) {
+        synchronized (mCallbackLock) {
             callback = mCallback;
             executor = mCallbackExecutor;
         }
@@ -469,117 +589,121 @@
      */
     @RequiresPermission(MANAGE_VIRTUAL_MACHINE_PERMISSION)
     public void run() throws VirtualMachineException {
-        if (getStatus() != STATUS_STOPPED) {
-            throw new VirtualMachineException(this + " is not in stopped state");
-        }
+        synchronized (mLock) {
+            checkStopped();
 
-        try {
-            mIdsigFilePath.createNewFile();
-            for (ExtraApkSpec extraApk : mExtraApks) {
-                extraApk.idsig.createNewFile();
-            }
-        } catch (IOException e) {
-            // If the file already exists, exception is not thrown.
-            throw new VirtualMachineException("failed to create idsig file", e);
-        }
-
-        IVirtualizationService service =
-                IVirtualizationService.Stub.asInterface(
-                        ServiceManager.waitForService(SERVICE_NAME));
-
-        try {
-            createVmPipes();
-
-            VirtualMachineAppConfig appConfig = getConfig().toVsConfig();
-            appConfig.name = mName;
-
-            // Fill the idsig file by hashing the apk
-            service.createOrUpdateIdsigFile(
-                    appConfig.apk, ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_WRITE));
-
-            for (ExtraApkSpec extraApk : mExtraApks) {
-                service.createOrUpdateIdsigFile(
-                        ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY),
-                        ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_WRITE));
-            }
-
-            // Re-open idsig file in read-only mode
-            appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
-            appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
-            List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
-            for (ExtraApkSpec extraApk : mExtraApks) {
-                extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
-            }
-            appConfig.extraIdsigs = extraIdsigs;
-
-            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 = () -> {
-                if (onDiedCalled.compareAndSet(false, true)) {
-                    executeCallback((cb) -> cb.onStopped(VirtualMachine.this,
-                            VirtualMachineCallback.STOP_REASON_VIRTUALIZATION_SERVICE_DIED));
+            try {
+                mIdsigFilePath.createNewFile();
+                for (ExtraApkSpec extraApk : mExtraApks) {
+                    extraApk.idsig.createNewFile();
                 }
-            };
+            } catch (IOException e) {
+                // If the file already exists, exception is not thrown.
+                throw new VirtualMachineException("failed to create idsig file", e);
+            }
 
-            mVirtualMachine = service.createVm(vmConfigParcel, mConsoleWriter, mLogWriter);
-            mVirtualMachine.registerCallback(
-                    new IVirtualMachineCallback.Stub() {
-                        @Override
-                        public void onPayloadStarted(int cid, ParcelFileDescriptor stream) {
-                            executeCallback(
-                                    (cb) -> cb.onPayloadStarted(VirtualMachine.this, stream));
-                        }
+            IVirtualizationService service =
+                    IVirtualizationService.Stub.asInterface(
+                            ServiceManager.waitForService(SERVICE_NAME));
 
-                        @Override
-                        public void onPayloadReady(int cid) {
-                            executeCallback((cb) -> cb.onPayloadReady(VirtualMachine.this));
-                        }
+            try {
+                createVmPipes();
 
-                        @Override
-                        public void onPayloadFinished(int cid, int exitCode) {
-                            executeCallback(
-                                    (cb) -> cb.onPayloadFinished(VirtualMachine.this, exitCode));
-                        }
+                VirtualMachineAppConfig appConfig = getConfig().toVsConfig();
+                appConfig.name = mName;
 
-                        @Override
-                        public void onError(int cid, int errorCode, String message) {
-                            int translatedError = getTranslatedError(errorCode);
-                            executeCallback(
-                                    (cb) -> cb.onError(VirtualMachine.this, translatedError,
-                                            message));
-                        }
+                // Fill the idsig file by hashing the apk
+                service.createOrUpdateIdsigFile(
+                        appConfig.apk, ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_WRITE));
 
-                        @Override
-                        public void onDied(int cid, int reason) {
-                            service.asBinder().unlinkToDeath(deathRecipient, 0);
-                            int translatedReason = getTranslatedReason(reason);
-                            if (onDiedCalled.compareAndSet(false, true)) {
+                for (ExtraApkSpec extraApk : mExtraApks) {
+                    service.createOrUpdateIdsigFile(
+                            ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY),
+                            ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_WRITE));
+                }
+
+                // Re-open idsig file in read-only mode
+                appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
+                appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath,
+                        MODE_READ_WRITE);
+                List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
+                for (ExtraApkSpec extraApk : mExtraApks) {
+                    extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
+                }
+                appConfig.extraIdsigs = extraIdsigs;
+
+                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 = () -> {
+                    if (onDiedCalled.compareAndSet(false, true)) {
+                        executeCallback((cb) -> cb.onStopped(VirtualMachine.this,
+                                VirtualMachineCallback.STOP_REASON_VIRTUALIZATION_SERVICE_DIED));
+                    }
+                };
+
+                mVirtualMachine = service.createVm(vmConfigParcel, mConsoleWriter, mLogWriter);
+                mVirtualMachine.registerCallback(
+                        new IVirtualMachineCallback.Stub() {
+                            @Override
+                            public void onPayloadStarted(int cid, ParcelFileDescriptor stream) {
                                 executeCallback(
-                                        (cb) -> cb.onStopped(VirtualMachine.this,
-                                                translatedReason));
+                                        (cb) -> cb.onPayloadStarted(VirtualMachine.this, stream));
+                            }
+
+                            @Override
+                            public void onPayloadReady(int cid) {
+                                executeCallback((cb) -> cb.onPayloadReady(VirtualMachine.this));
+                            }
+
+                            @Override
+                            public void onPayloadFinished(int cid, int exitCode) {
+                                executeCallback(
+                                        (cb) -> cb.onPayloadFinished(VirtualMachine.this,
+                                                exitCode));
+                            }
+
+                            @Override
+                            public void onError(int cid, int errorCode, String message) {
+                                int translatedError = getTranslatedError(errorCode);
+                                executeCallback(
+                                        (cb) -> cb.onError(VirtualMachine.this, translatedError,
+                                                message));
+                            }
+
+                            @Override
+                            public void onDied(int cid, int reason) {
+                                service.asBinder().unlinkToDeath(deathRecipient, 0);
+                                int translatedReason = getTranslatedReason(reason);
+                                if (onDiedCalled.compareAndSet(false, true)) {
+                                    executeCallback(
+                                            (cb) -> cb.onStopped(VirtualMachine.this,
+                                                    translatedReason));
+                                }
+                            }
+
+                            @Override
+                            public void onRamdump(int cid, ParcelFileDescriptor ramdump) {
+                                executeCallback(
+                                        (cb) -> cb.onRamdump(VirtualMachine.this, ramdump));
                             }
                         }
-
-                        @Override
-                        public void onRamdump(int cid, ParcelFileDescriptor ramdump) {
-                            executeCallback(
-                                    (cb) -> cb.onRamdump(VirtualMachine.this, ramdump));
-                        }
-                    }
-            );
-            service.asBinder().linkToDeath(deathRecipient, 0);
-            mVirtualMachine.start();
-        } catch (IOException | IllegalStateException | ServiceSpecificException e) {
-            throw new VirtualMachineException(e);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
+                );
+                service.asBinder().linkToDeath(deathRecipient, 0);
+                mVirtualMachine.start();
+            } catch (IOException | IllegalStateException | ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
         }
     }
 
+    @GuardedBy("mLock")
     private void createVmPipes() throws VirtualMachineException {
         try {
             if (mConsoleReader == null || mConsoleWriter == null) {
@@ -598,6 +722,185 @@
         }
     }
 
+    /**
+     * Returns the stream object representing the console output from the virtual machine.
+     *
+     * @throws VirtualMachineException if the stream could not be created.
+     * @hide
+     */
+    @NonNull
+    public InputStream getConsoleOutputStream() throws VirtualMachineException {
+        synchronized (mLock) {
+            createVmPipes();
+            return new FileInputStream(mConsoleReader.getFileDescriptor());
+        }
+    }
+
+    /**
+     * Returns the stream object representing the log output from the virtual machine.
+     *
+     * @throws VirtualMachineException if the stream could not be created.
+     * @hide
+     */
+    @NonNull
+    public InputStream getLogOutputStream() throws VirtualMachineException {
+        synchronized (mLock) {
+            createVmPipes();
+            return new FileInputStream(mLogReader.getFileDescriptor());
+        }
+    }
+
+    /**
+     * Stops this virtual machine. Stopping a virtual machine is like pulling the plug on a real
+     * computer; the machine halts immediately. Software running on the virtual machine is not
+     * notified of the event. A stopped virtual machine can be re-started by calling {@link
+     * #run()}.
+     *
+     * @throws VirtualMachineException if the virtual machine could not be stopped.
+     * @hide
+     */
+    public void stop() throws VirtualMachineException {
+        synchronized (mLock) {
+            if (mVirtualMachine == null) {
+                throw new VirtualMachineException("VM is not running");
+            }
+            try {
+                mVirtualMachine.stop();
+                mVirtualMachine = null;
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    /**
+     * Stops this virtual machine. See {@link #stop()}.
+     *
+     * @throws VirtualMachineException if the virtual machine could not be stopped.
+     * @hide
+     */
+    @Override
+    public void close() throws VirtualMachineException {
+        stop();
+    }
+
+    private static void deleteRecursively(File dir) throws IOException {
+        // Note: This doesn't follow symlinks, which is important. Instead they are just deleted
+        // (and Files.delete deletes the link not the target).
+        Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                Files.delete(file);
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
+                // Directory is deleted after we've visited (deleted) all its contents, so it
+                // should be empty by now.
+                Files.delete(dir);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    /**
+     * Returns the CID of this virtual machine, if it is running.
+     *
+     * @throws VirtualMachineException if the virtual machine is not running.
+     * @hide
+     */
+    public int getCid() throws VirtualMachineException {
+        synchronized (mLock) {
+            try {
+                return getRunningVm().getCid();
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Changes the config of this virtual machine to a new one. This can be used to adjust things
+     * like the number of CPU and size of the RAM, depending on the situation (e.g. the size of the
+     * application to run on the virtual machine, etc.)
+     *
+     * The new config must be {@link VirtualMachineConfig#isCompatibleWith compatible with} the
+     * existing config.
+     *
+     * @return the old config
+     * @throws VirtualMachineException if the virtual machine is not stopped, or the new config is
+     *         incompatible.
+     * @hide
+     */
+    @NonNull
+    public VirtualMachineConfig setConfig(@NonNull VirtualMachineConfig newConfig)
+            throws VirtualMachineException {
+        synchronized (mLock) {
+            VirtualMachineConfig oldConfig = mConfig;
+            if (!oldConfig.isCompatibleWith(newConfig)) {
+                throw new VirtualMachineException("incompatible config");
+            }
+            checkStopped();
+
+            try {
+                FileOutputStream output = new FileOutputStream(mConfigFilePath);
+                newConfig.serialize(output);
+                output.close();
+            } catch (IOException e) {
+                throw new VirtualMachineException("Failed to persist config", e);
+            }
+            mConfig = newConfig;
+            return oldConfig;
+        }
+    }
+
+    @Nullable
+    private static native IBinder nativeConnectToVsockServer(IBinder vmBinder, int port);
+
+    /**
+     * Connect to a VM's binder service via vsock and return the root IBinder object. Guest VMs are
+     * expected to set up vsock servers in their payload. After the host app receives the {@link
+     * VirtualMachineCallback#onPayloadReady(VirtualMachine)}, it can use this method to
+     * establish a connection to the guest VM.
+     *
+     * @throws VirtualMachineException if the virtual machine is not running or the connection
+     *         failed.
+     * @hide
+     */
+    @NonNull
+    public IBinder connectToVsockServer(int port) throws VirtualMachineException {
+        synchronized (mLock) {
+            IBinder iBinder = nativeConnectToVsockServer(getRunningVm().asBinder(), port);
+            if (iBinder == null) {
+                throw new VirtualMachineException("Failed to connect to vsock server");
+            }
+            return iBinder;
+        }
+    }
+
+    /**
+     * Opens a vsock connection to the VM on the given port.
+     *
+     * @throws VirtualMachineException if connecting fails.
+     * @hide
+     */
+    @NonNull
+    public ParcelFileDescriptor connectVsock(int port) throws VirtualMachineException {
+        synchronized (mLock) {
+            try {
+                return getRunningVm().connectVsock(port);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
     @VirtualMachineCallback.ErrorCode
     private int getTranslatedError(int reason) {
         switch (reason) {
@@ -652,206 +955,6 @@
         }
     }
 
-    /**
-     * Returns the stream object representing the console output from the virtual machine.
-     *
-     * @throws VirtualMachineException if the stream could not be created.
-     * @hide
-     */
-    @NonNull
-    public InputStream getConsoleOutputStream() throws VirtualMachineException {
-        createVmPipes();
-        return new FileInputStream(mConsoleReader.getFileDescriptor());
-    }
-
-    /**
-     * Returns the stream object representing the log output from the virtual machine.
-     *
-     * @throws VirtualMachineException if the stream could not be created.
-     * @hide
-     */
-    @NonNull
-    public InputStream getLogOutputStream() throws VirtualMachineException {
-        createVmPipes();
-        return new FileInputStream(mLogReader.getFileDescriptor());
-    }
-
-    /**
-     * Stops this virtual machine. Stopping a virtual machine is like pulling the plug on a real
-     * computer; the machine halts immediately. Software running on the virtual machine is not
-     * notified of the event. A stopped virtual machine can be re-started by calling {@link
-     * #run()}.
-     *
-     * @throws VirtualMachineException if the virtual machine could not be stopped.
-     * @hide
-     */
-    public void stop() throws VirtualMachineException {
-        if (mVirtualMachine == null) return;
-        try {
-            mVirtualMachine.stop();
-            mVirtualMachine = null;
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        } catch (ServiceSpecificException e) {
-            throw new VirtualMachineException(e);
-        }
-    }
-
-    /**
-     * Stops this virtual machine. See {@link #stop()}.
-     *
-     * @throws VirtualMachineException if the virtual machine could not be stopped.
-     * @hide
-     */
-    @Override
-    public void close() throws VirtualMachineException {
-        stop();
-    }
-
-    static void delete(Context context, String name) throws VirtualMachineException {
-        VirtualMachine vm;
-        synchronized (sInstancesLock) {
-            Map<String, WeakReference<VirtualMachine>> instancesMap = sInstances.get(context);
-            if (instancesMap != null && instancesMap.containsKey(name)) {
-                vm = instancesMap.get(name).get();
-            } else {
-                vm = null;
-            }
-        }
-
-        if (vm != null && vm.getStatus() != STATUS_STOPPED) {
-            throw new VirtualMachineException("Virtual machine is not stopped");
-        }
-
-        try {
-            deleteRecursively(getVmDir(context, name));
-        } catch (IOException e) {
-            throw new VirtualMachineException(e);
-        }
-
-        synchronized (sInstancesLock) {
-            Map<String, WeakReference<VirtualMachine>> instancesMap = sInstances.get(context);
-            if (instancesMap != null) instancesMap.remove(name);
-        }
-    }
-
-    private static void deleteRecursively(File dir) throws IOException {
-        // Note: This doesn't follow symlinks, which is important. Instead they are just deleted
-        // (and Files.delete deletes the link not the target).
-        Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<>() {
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                    throws IOException {
-                Files.delete(file);
-                return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
-                // Directory is deleted after we've visited (deleted) all its contents, so it
-                // should be empty by now.
-                Files.delete(dir);
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-
-    /**
-     * Returns the CID of this virtual machine, if it is running.
-     *
-     * @throws VirtualMachineException if the virtual machine is not running.
-     * @hide
-     */
-    public int getCid() throws VirtualMachineException {
-        if (getStatus() != STATUS_RUNNING) {
-            throw new VirtualMachineException("VM is not running");
-        }
-        try {
-            return mVirtualMachine.getCid();
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Changes the config of this virtual machine to a new one. This can be used to adjust things
-     * like the number of CPU and size of the RAM, depending on the situation (e.g. the size of the
-     * application to run on the virtual machine, etc.)
-     *
-     * The new config must be {@link VirtualMachineConfig#isCompatibleWith compatible with} the
-     * existing config.
-     *
-     * @return the old config
-     * @throws VirtualMachineException if the virtual machine is not stopped, or the new config is
-     *         incompatible.
-     * @hide
-     */
-    @NonNull
-    public VirtualMachineConfig setConfig(@NonNull VirtualMachineConfig newConfig)
-            throws VirtualMachineException {
-        final VirtualMachineConfig oldConfig = getConfig();
-        if (!oldConfig.isCompatibleWith(newConfig)) {
-            throw new VirtualMachineException("incompatible config");
-        }
-        if (getStatus() != STATUS_STOPPED) {
-            throw new VirtualMachineException(
-                    "can't change config while virtual machine is not stopped");
-        }
-
-        try {
-            FileOutputStream output = new FileOutputStream(mConfigFilePath);
-            newConfig.serialize(output);
-            output.close();
-        } catch (IOException e) {
-            throw new VirtualMachineException("Failed to persist config", e);
-        }
-        mConfig = newConfig;
-
-        return oldConfig;
-    }
-
-    @Nullable
-    private static native IBinder nativeConnectToVsockServer(IBinder vmBinder, int port);
-
-    /**
-     * Connect to a VM's binder service via vsock and return the root IBinder object. Guest VMs are
-     * expected to set up vsock servers in their payload. After the host app receives the {@link
-     * VirtualMachineCallback#onPayloadReady(VirtualMachine)}, it can use this method to
-     * establish a connection to the guest VM.
-     *
-     * @throws VirtualMachineException if the virtual machine is not running or the connection
-     *         failed.
-     * @hide
-     */
-    @NonNull
-    public IBinder connectToVsockServer(int port) throws VirtualMachineException {
-        if (getStatus() != STATUS_RUNNING) {
-            throw new VirtualMachineException("VM is not running");
-        }
-        IBinder iBinder = nativeConnectToVsockServer(mVirtualMachine.asBinder(), port);
-        if (iBinder == null) {
-            throw new VirtualMachineException("Failed to connect to vsock server");
-        }
-        return iBinder;
-    }
-
-    /**
-     * Opens a vsock connection to the VM on the given port.
-     *
-     * @throws VirtualMachineException if connecting fails.
-     * @hide
-     */
-    @NonNull
-    public ParcelFileDescriptor connectVsock(int port) throws VirtualMachineException {
-        try {
-            return mVirtualMachine.connectVsock(port);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        } catch (ServiceSpecificException e) {
-            throw new VirtualMachineException(e);
-        }
-    }
-
     @Override
     public String toString() {
         VirtualMachineConfig config = getConfig();
@@ -942,15 +1045,9 @@
                                 new File(vmDir, EXTRA_IDSIG_FILE_PREFIX + i)));
             }
 
-            return extraApks;
+            return Collections.unmodifiableList(extraApks);
         } catch (IOException e) {
             throw new VirtualMachineException("Couldn't parse extra apks from the vm config", e);
         }
     }
-
-    @NonNull
-    private static File getVmDir(Context context, String name) {
-        File vmRoot = new File(context.getDataDir(), VM_DIR);
-        return new File(vmRoot, name);
-    }
 }
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
index f2b7802..34b9fd9 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -26,6 +26,8 @@
 import android.content.Context;
 import android.sysprop.HypervisorProperties;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -51,6 +53,7 @@
         mContext = context;
     }
 
+    @GuardedBy("sInstances")
     private static final Map<Context, WeakReference<VirtualMachineManager>> sInstances =
             new WeakHashMap<>();
 
@@ -96,9 +99,6 @@
         }
     }
 
-    /** A lock used to synchronize the creation of virtual machines */
-    private static final Object sCreateLock = new Object();
-
     /**
      * Returns a set of flags indicating what this implementation of virtualization is capable of.
      *
@@ -136,7 +136,7 @@
     public VirtualMachine create(
             @NonNull String name, @NonNull VirtualMachineConfig config)
             throws VirtualMachineException {
-        synchronized (sCreateLock) {
+        synchronized (VirtualMachine.sCreateLock) {
             return VirtualMachine.create(mContext, name, config);
         }
     }
@@ -151,7 +151,9 @@
      */
     @Nullable
     public VirtualMachine get(@NonNull String name) throws VirtualMachineException {
-        return VirtualMachine.load(mContext, name);
+        synchronized (VirtualMachine.sCreateLock) {
+            return VirtualMachine.load(mContext, name);
+        }
     }
 
     /**
@@ -166,7 +168,7 @@
             @NonNull String name, @NonNull VirtualMachineConfig config)
             throws VirtualMachineException {
         VirtualMachine vm;
-        synchronized (sCreateLock) {
+        synchronized (VirtualMachine.sCreateLock) {
             vm = get(name);
             if (vm == null) {
                 vm = create(name, config);
@@ -188,6 +190,8 @@
      */
     public void delete(@NonNull String name) throws VirtualMachineException {
         requireNonNull(name);
-        VirtualMachine.delete(mContext, name);
+        synchronized (VirtualMachine.sCreateLock) {
+            VirtualMachine.delete(mContext, name);
+        }
     }
 }
