Merge "Disable AVF debug policies for tests"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 3217ee1..d17b434 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -4,6 +4,9 @@
       "name": "MicrodroidHostTestCases"
     },
     {
+      "name": "ComposHostTestCases"
+    },
+    {
       "name": "MicrodroidTestApp"
     },
     {
@@ -33,9 +36,6 @@
       "name": "ComposBenchmarkApp"
     },
     {
-      "name": "ComposHostTestCases"
-    },
-    {
       "name": "AVFHostTestCases"
     }
   ],
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index eb2e072..8c7aeeb 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -23,6 +23,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assume.assumeFalse;
+
 import android.platform.test.annotations.RootPermissionTest;
 
 import com.android.microdroid.test.host.CommandRunner;
@@ -81,6 +83,8 @@
     @Before
     public void setUp() throws Exception {
         assumeDeviceIsCapable(getDevice());
+        // We get a very high level of (apparently bogus) OOM errors on Cuttlefish (b/264496291).
+        assumeFalse("Skipping test on Cuttlefish", isCuttlefish());
 
         String value = getDevice().getProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME);
         if (value == null) {
diff --git a/pvmfw/README.md b/pvmfw/README.md
index 2d2b253..4e93648 100644
--- a/pvmfw/README.md
+++ b/pvmfw/README.md
@@ -270,3 +270,166 @@
 
 For details about device tree properties for debug policies, see
 [microdroid's debugging policy guide](../microdroid/README.md#option-1-running-microdroid-on-avf-debug-policy-configured-device).
+
+### Platform Requirements
+
+pvmfw is intended to run in a virtualized environment according to the `crosvm`
+[memory layout][crosvm-mem] for protected VMs and so it expects to have been
+loaded at address `0x7fc0_0000` and uses the 2MiB region at address
+`0x7fe0_0000` as scratch memory. It makes use of the virtual PCI bus to obtain a
+virtio interface to the host and prints its logs through the 16550 UART (address
+`0x3f8`).
+
+At boot, pvmfw discovers the running hypervisor in order to select the
+appropriate hypervisor calls to share/unshare memory, mark IPA regions as MMIO,
+obtain trusted true entropy, and reboot the virtual machine. In particular, it
+makes use of the following hypervisor calls:
+
+- Arm [SMC Calling Convention][smccc] v1.1 or above:
+
+    - `SMCCC_VERSION`
+    - Vendor Specific Hypervisor Service Call UID Query
+
+- Arm [Power State Coordination Interface][psci] v1.0 or above:
+
+    - `PSCI_VERSION`
+    - `PSCI_FEATURES`
+    - `PSCI_SYSTEM_RESET`
+    - `PSCI_SYSTEM_SHUTDOWN`
+
+- Arm [True Random Number Generator Firmware Interface][smccc-trng] v1.0:
+
+    - `TRNG_VERSION`
+    - `TRNG_FEATURES`
+    - `TRNG_RND`
+
+- When running under KVM, the pKVM-specific hypervisor interface must provide:
+
+    - `MEMINFO` (function ID `0xc6000002`)
+    - `MEM_SHARE` (function ID `0xc6000003`)
+    - `MEM_UNSHARE` (function ID `0xc6000004`)
+    - `MMIO_GUARD_INFO` (function ID `0xc6000005`)
+    - `MMIO_GUARD_ENROLL` (function ID `0xc6000006`)
+    - `MMIO_GUARD_MAP` (function ID `0xc6000007`)
+    - `MMIO_GUARD_UNMAP` (function ID `0xc6000008`)
+
+[crosvm-mem]: https://crosvm.dev/book/appendix/memory_layout.html
+[psci]: https://developer.arm.com/documentation/den0022
+[smccc]: https://developer.arm.com/documentation/den0028
+[smccc-trng]: https://developer.arm.com/documentation/den0098
+
+## Booting Protected Virtual Machines
+
+### Boot Protocol
+
+As the hypervisor makes pvmfw the entry point of the VM, the initial value of
+the registers it receives is configured by the VMM and is expected to follow the
+[Linux ABI] _i.e._
+
+- x0 = physical address of device tree blob (dtb) in system RAM.
+- x1 = 0 (reserved for future use)
+- x2 = 0 (reserved for future use)
+- x3 = 0 (reserved for future use)
+
+Images to be verified, which have been loaded to guest memory by the VMM prior
+to booting the VM, are described to pvmfw using the device tree (x0):
+
+- the kernel in the `/config` DT node _e.g._
+
+    ```
+    / {
+        config {
+            kernel-address = <0x80200000>;
+            kernel-size = <0x1000000>;
+        };
+    };
+    ````
+
+- the (optional) ramdisk in the standard `/chosen` node _e.g._
+
+    ```
+    / {
+        chosen {
+            linux,initrd-start = <0x82000000>;
+            linux,initrd-end = <0x82800000>;
+        };
+    };
+    ```
+
+[Linux ABI]: https://www.kernel.org/doc/Documentation/arm64/booting.txt
+
+### Handover ABI
+
+After verifying the guest kernel, pvmfw boots it using the Linux ABI described
+above. It uses the device tree to pass the following:
+
+- a reserved memory node containing the produced BCC:
+
+    ```
+    / {
+        reserved-memory {
+            #address-cells = <0x02>;
+            #size-cells = <0x02>;
+            ranges;
+            dice {
+                compatible = "google,open-dice";
+                no-map;
+                reg = <0x0 0x7fe0000>, <0x0 0x1000>;
+            };
+        };
+    };
+    ```
+
+- the `/chosen/avf,new-instance` flag, set when pvmfw generated a new secret
+  (_i.e._ the pVM instance was booted for the first time). This should be used
+  by the next stages to ensure that an attacker isn't trying to force new
+  secrets to be generated by one stage, in isolation;
+
+- the `/chosen/avf,strict-boot` flag, always set and can be used by guests to
+  enable extra validation
+
+### Guest Image Signing
+
+pvmfw verifies the guest kernel image (loaded by the VMM) by re-using tools and
+formats introduced by the Android Verified Boot. In particular, it expects the
+kernel region (see `/config/kernel-{address,size}` described above) to contain
+an appended VBMeta structure, which can be generated as follows:
+
+```
+avbtool add_hash_footer --image <kernel.bin> \
+    --partition_name boot \
+    --dynamic_partition_size \
+    --key $KEY
+```
+
+In cases where a ramdisk is required by the guest, pvmfw must also verify it. To
+do so, it must be covered by a hash descriptor in the VBMeta of the kernel:
+
+```
+cp <initrd.bin> /tmp/
+avbtool add_hash_footer --image /tmp/<initrd.bin> \
+    --partition_name $INITRD_NAME \
+    --dynamic_partition_size \
+    --key $KEY
+avbtool add_hash_footer --image <kernel.bin> \
+    --partition_name boot \
+    --dynamic_partition_size \
+    --include_descriptor_from_image /tmp/<initrd.bin> \
+    --key $KEY
+```
+
+Note that the `/tmp/<initrd.bin>` file is only created to temporarily hold the
+hash descriptor to be added to the kernel footer and that the unsigned
+`<initrd.bin>` should be passed to the VMM when booting a pVM.
+
+The name of the AVB "partition" for the ramdisk (`$INITRD_NAME`) can be used by
+the signer to specify if pvmfw must consider the guest to be debuggable
+(`initrd_debug`) or not (`initrd_normal`), which will be reflected in the
+certificate of the guest and will affect the secrets being provisioned.
+
+If pVM guest kernels are built and/or packaged using the Android Build system,
+the signing described above is recommended to be done through an
+`avb_add_hash_footer` Soong module (see [how we sign the Microdroid
+kernel][soong-udroid]).
+
+[soong-udroid]: https://cs.android.com/android/platform/superproject/+/master:packages/modules/Virtualization/microdroid/Android.bp;l=427;drc=ca0049be4d84897b8c9956924cfae506773103eb