Merge "Initialize compsvc with allowlisted system properties"
diff --git a/microdroid/README.md b/microdroid/README.md
index a652139..681c23a 100644
--- a/microdroid/README.md
+++ b/microdroid/README.md
@@ -7,7 +7,7 @@
 
 ## Prerequisites
 
-Any 64-bit target (either x86_64 or arm64) is supported. 32-bit target is not
+Any 64-bit target (either x86\_64 or arm64) is supported. 32-bit target is not
 supported. Note that we currently don't support user builds; only userdebug
 builds are supported.
 
@@ -36,7 +36,7 @@
 adb reboot
 ```
 
-If your target is x86_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
+If your target is x86\_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
 with `aosp_x86_64`.
 
 ## Building an app
diff --git a/tests/hostside/AndroidTest.xml b/tests/hostside/AndroidTest.xml
index 79428ce..5c3e5d1 100644
--- a/tests/hostside/AndroidTest.xml
+++ b/tests/hostside/AndroidTest.xml
@@ -19,6 +19,12 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+        <!-- Permission checks are bypassed if shell is root -->
+        <option name="force-root" value="false"/>
+    </target_preparer>
+
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="MicrodroidHostTestCases.jar" />
     </test>
diff --git a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
index 9ee95c0..e2d4be1 100644
--- a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
@@ -478,6 +478,7 @@
     @Test
     public void testCustomVirtualMachinePermission()
             throws DeviceNotAvailableException, IOException, JSONException {
+        assumeTrue(isProtectedVmSupported());
         CommandRunner android = new CommandRunner(getDevice());
 
         // Pull etc/microdroid.json
diff --git a/vmbase/example/Android.bp b/vmbase/example/Android.bp
new file mode 100644
index 0000000..4cc4bf3
--- /dev/null
+++ b/vmbase/example/Android.bp
@@ -0,0 +1,62 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_ffi_static {
+    name: "libvmbase_example",
+    crate_name: "vmbase_example",
+    srcs: ["src/main.rs"],
+    edition: "2021",
+    no_stdlibs: true,
+    stdlibs: [
+        "libcompiler_builtins.rust_sysroot",
+        "libcore.rust_sysroot",
+    ],
+    rustlibs: [
+        "libvmbase",
+    ],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    apex_available: ["com.android.virt"],
+}
+
+cc_binary {
+    name: "vmbase_example_elf",
+    stem: "vmbase_example",
+    srcs: [
+        "idmap.S",
+    ],
+    static_libs: [
+        "libvmbase_entry",
+        "libvmbase_example",
+    ],
+    static_executable: true,
+    nocrt: true,
+    system_shared_libs: ["libc"],
+    stl: "none",
+    linker_scripts: ["image.ld"],
+    installable: false,
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    apex_available: ["com.android.virt"],
+}
+
+raw_binary {
+    name: "vmbase_example",
+    src: ":vmbase_example_elf",
+    stem: "vmbase_example.bin",
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+}
diff --git a/vmbase/example/idmap.S b/vmbase/example/idmap.S
new file mode 100644
index 0000000..f1df6cc
--- /dev/null
+++ b/vmbase/example/idmap.S
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.set .L_TT_TYPE_BLOCK, 0x1
+.set .L_TT_TYPE_PAGE,  0x3
+.set .L_TT_TYPE_TABLE, 0x3
+
+/* Access flag. */
+.set .L_TT_AF, 0x1 << 10
+/* Not global. */
+.set .L_TT_NG, 0x1 << 11
+.set .L_TT_RO, 0x2 << 6
+.set .L_TT_XN, 0x3 << 53
+
+.set .L_TT_MT_DEV, 0x0 << 2			// MAIR #0 (DEV_nGnRE)
+.set .L_TT_MT_MEM, (0x1 << 2) | (0x3 << 8)	// MAIR #1 (MEM_WBWA), inner shareable
+
+.set .L_BLOCK_RO,  .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_RO | .L_TT_XN
+.set .L_BLOCK_DEV, .L_TT_TYPE_BLOCK | .L_TT_MT_DEV | .L_TT_AF | .L_TT_XN
+.set .L_BLOCK_MEM, .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_XN | .L_TT_NG
+.set .L_BLOCK_MEM_XIP, .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_NG | .L_TT_RO
+
+.section ".rodata.idmap", "a", %progbits
+.global idmap
+.align 12
+idmap:
+	/* level 1 */
+	.quad		.L_BLOCK_DEV | 0x0		// 1 GB of device mappings
+	.quad		.L_BLOCK_DEV | 0x40000000	// Another 1 GB of device mapppings
+	.quad		.L_TT_TYPE_TABLE + 0f		// up to 1 GB of DRAM
+	.fill		509, 8, 0x0			// 509 GB of remaining VA space
+
+	/* level 2 */
+0:	.quad		.L_BLOCK_RO  | 0x80000000	// DT provided by VMM
+	.quad		.L_BLOCK_MEM_XIP | 0x80200000	// 2 MB of DRAM containing image
+	.quad		.L_BLOCK_MEM | 0x80400000	// 2 MB of writable DRAM
+	.fill		509, 8, 0x0
diff --git a/vmbase/example/image.ld b/vmbase/example/image.ld
new file mode 100644
index 0000000..4655f68
--- /dev/null
+++ b/vmbase/example/image.ld
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+MEMORY
+{
+	dtb_region	: ORIGIN = 0x80000000, LENGTH = 2M
+	image		: ORIGIN = 0x80200000, LENGTH = 2M
+	writable_data	: ORIGIN = 0x80400000, LENGTH = 2M
+}
+
+/*
+ * Code will start running at this symbol which is placed at the start of the
+ * image.
+ */
+ENTRY(entry)
+
+/*
+ * The following would be useful to check that .init code is not called back
+ * into once it has completed but it isn't supported by ld.lld.
+ *
+ * NOCROSSREFS_TO(.init .text)
+ */
+
+SECTIONS
+{
+	.dtb (NOLOAD) : {
+		dtb_begin = .;
+		. += LENGTH(dtb_region);
+		dtb_end = .;
+	} >dtb_region
+
+	/*
+	 * Collect together the code. This is page aligned so it can be mapped
+	 * as executable-only.
+	 */
+	.init : ALIGN(4096) {
+		text_begin = .;
+		*(.init.entry)
+		*(.init.*)
+	} >image
+	.text : {
+		*(.text.*)
+	} >image
+	text_end = .;
+
+	/*
+	 * Collect together read-only data. This is page aligned so it can be
+	 * mapped as read-only and non-executable.
+	 */
+	.rodata : ALIGN(4096) {
+		rodata_begin = .;
+		*(.rodata.*)
+	} >image
+	.got : {
+		*(.got)
+	} >image
+	rodata_end = .;
+
+	/*
+	 * Collect together the read-write data including .bss at the end which
+	 * will be zero'd by the entry code. This is page aligned so it can be
+	 * mapped as non-executable.
+	 */
+	.data : ALIGN(4096) {
+		data_begin = .;
+		*(.data.*)
+		/*
+		 * The entry point code assumes that .data is a multiple of 32
+		 * bytes long.
+		 */
+		. = ALIGN(32);
+		data_end = .;
+	} >writable_data AT>image
+	data_lma = LOADADDR(.data);
+
+	/* Everything beyond this point will not be included in the binary. */
+	bin_end = .;
+
+	/* The entry point code assumes that .bss is 16-byte aligned. */
+	.bss : ALIGN(16)  {
+		bss_begin = .;
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(16);
+		bss_end = .;
+	} >writable_data
+
+	.stack (NOLOAD) : ALIGN(4096) {
+		boot_stack_begin = .;
+		. += 40 * 4096;
+		. = ALIGN(4096);
+		boot_stack_end = .;
+	} >writable_data
+
+	/*
+	 * Remove unused sections from the image.
+	 */
+	/DISCARD/ : {
+		/* The image loads itself so doesn't need these sections. */
+		*(.gnu.hash)
+		*(.hash)
+		*(.interp)
+		*(.eh_frame_hdr)
+		*(.eh_frame)
+		*(.note.gnu.build-id)
+	}
+}
diff --git a/vmbase/example/src/exceptions.rs b/vmbase/example/src/exceptions.rs
new file mode 100644
index 0000000..61f7846
--- /dev/null
+++ b/vmbase/example/src/exceptions.rs
@@ -0,0 +1,79 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Exception handlers.
+
+use core::arch::asm;
+use vmbase::{console::emergency_write_str, eprintln, power::reboot};
+
+#[no_mangle]
+extern "C" fn sync_exception_current() {
+    emergency_write_str("sync_exception_current\n");
+    print_esr();
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn irq_current() {
+    emergency_write_str("irq_current\n");
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn fiq_current() {
+    emergency_write_str("fiq_current\n");
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn serr_current() {
+    emergency_write_str("serr_current\n");
+    print_esr();
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn sync_lower() {
+    emergency_write_str("sync_lower\n");
+    print_esr();
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn irq_lower() {
+    emergency_write_str("irq_lower\n");
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn fiq_lower() {
+    emergency_write_str("fiq_lower\n");
+    reboot();
+}
+
+#[no_mangle]
+extern "C" fn serr_lower() {
+    emergency_write_str("serr_lower\n");
+    print_esr();
+    reboot();
+}
+
+#[inline]
+fn print_esr() {
+    let mut esr: u64;
+    unsafe {
+        asm!("mrs {esr}, esr_el1", esr = out(reg) esr);
+    }
+    eprintln!("esr={:#08x}", esr);
+}
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
new file mode 100644
index 0000000..bbb64d9
--- /dev/null
+++ b/vmbase/example/src/main.rs
@@ -0,0 +1,29 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! VM bootloader example.
+
+#![no_main]
+#![no_std]
+
+mod exceptions;
+
+use vmbase::{main, println};
+
+main!(main);
+
+/// Entry point for VM bootloader.
+pub fn main() {
+    println!("Hello world");
+}