Merge changes Ib977d21a,I9daaa3bb

* changes:
  Update kernel to builds 9223523
  Update kernel to builds 9223523
diff --git a/microdroid/vm_payload/Android.bp b/microdroid/vm_payload/Android.bp
index dc314ce..eeca1c1 100644
--- a/microdroid/vm_payload/Android.bp
+++ b/microdroid/vm_payload/Android.bp
@@ -13,6 +13,7 @@
         "libandroid_logger",
         "libanyhow",
         "libbinder_rs",
+        "liblazy_static",
         "liblog_rust",
         "librpcbinder_rs",
     ],
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index dc01662..2aeb44e 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -96,6 +96,17 @@
  */
 bool AVmPayload_getDiceAttestationCdi(void *data, size_t size, size_t *total);
 
+/**
+ * Gets the path to the APK contents. It is a directory, under which are
+ * the unzipped contents of the APK containing the payload, all read-only
+ * but accessible to the payload.
+ *
+ * \return the path to the APK contents. The returned string should not be
+ * deleted or freed by the application. The string remains valid for the
+ * lifetime of the VM.
+ */
+const char *AVmPayload_getApkContentsPath(void);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs
index bec4fde..b0dd891 100644
--- a/microdroid/vm_payload/src/vm_payload_service.rs
+++ b/microdroid/vm_payload/src/vm_payload_service.rs
@@ -15,12 +15,19 @@
 //! This module handles the interaction with virtual machine payload service.
 
 use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
-    IVmPayloadService, VM_PAYLOAD_SERVICE_NAME};
+    IVmPayloadService, VM_PAYLOAD_SERVICE_NAME, VM_APK_CONTENTS_PATH};
 use anyhow::{Context, Result};
 use binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}};
+use lazy_static::lazy_static;
 use log::{error, info, Level};
 use rpcbinder::run_vsock_rpc_server;
-use std::os::raw::c_void;
+use std::ffi::CString;
+use std::os::raw::{c_char, c_void};
+
+lazy_static! {
+    static ref VM_APK_CONTENTS_PATH_C: CString =
+        CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed");
+}
 
 /// Notifies the host that the payload is ready.
 /// Returns true if the notification succeeds else false.
@@ -185,6 +192,12 @@
     }
 }
 
+/// Gets the path to the APK contents.
+#[no_mangle]
+pub extern "C" fn AVmPayload_getApkContentsPath() -> *const c_char {
+    (*VM_APK_CONTENTS_PATH_C).as_ptr()
+}
+
 fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
     get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
 }
diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
index 4dd3db6..4823bb8 100644
--- a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -24,6 +24,9 @@
     /** Name of the service IVmPayloadService. */
     const String VM_PAYLOAD_SERVICE_NAME = "virtual_machine_payload_service";
 
+    /** Path to the APK contents path. */
+    const String VM_APK_CONTENTS_PATH = "/mnt/apk";
+
     /** Notifies that the payload is ready to serve. */
     void notifyPayloadReady();
 
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index e42f159..b8e85e7 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -33,6 +33,7 @@
     VirtualMachineCpuStatus::VirtualMachineCpuStatus,
     VirtualMachineMemStatus::VirtualMachineMemStatus,
 };
+use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::VM_APK_CONTENTS_PATH;
 use anyhow::{anyhow, bail, ensure, Context, Error, Result};
 use apkverify::{get_public_key_der, verify, V4Signature};
 use binder::{ProcessState, Strong};
@@ -398,7 +399,7 @@
         MountForExec::Allowed,
         "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
         Path::new("/dev/block/mapper/microdroid-apk"),
-        Path::new("/mnt/apk"),
+        Path::new(VM_APK_CONTENTS_PATH),
         Some(APK_MOUNT_DONE_PROP),
     )
     .context("Failed to run zipfuse")?;
@@ -824,7 +825,7 @@
     let mut watcher = PropertyWatcher::new("ro.product.cpu.abilist")?;
     let value = watcher.read(|_name, value| Ok(value.trim().to_string()))?;
     let abi = value.split(',').next().ok_or_else(|| anyhow!("no abilist"))?;
-    let path = format!("/mnt/apk/lib/{}/{}", abi, name);
+    let path = format!("{}/lib/{}/{}", VM_APK_CONTENTS_PATH, abi, name);
 
     let metadata = fs::metadata(&path).with_context(|| format!("Unable to access {}", path))?;
     if !metadata.is_file() {
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index d0fc9a9..b644905 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -10,6 +10,7 @@
     edition: "2021",
     rustlibs: [
         "liblog_rust_nostd",
+        "libpvmfw_embedded_key",
         "libvmbase",
     ],
     apex_available: ["com.android.virt"],
@@ -44,6 +45,34 @@
 }
 
 prebuilt_etc {
+    name: "pvmfw_embedded_key",
+    src: ":avb_testkey_rsa4096_pub_bin",
+    installable: false,
+}
+
+genrule {
+    name: "pvmfw_embedded_key_rs",
+    srcs: [":pvmfw_embedded_key"],
+    out: ["lib.rs"],
+    cmd: "(" +
+        "    echo '#![no_std]';" +
+        "    echo '#![allow(missing_docs)]';" +
+        "    echo 'pub const PUBLIC_KEY: &[u8] = &[';" +
+        "    xxd -i < $(in);" +
+        "    echo '];';" +
+        ") > $(out)",
+}
+
+rust_library_rlib {
+    name: "libpvmfw_embedded_key",
+    defaults: ["vmbase_ffi_defaults"],
+    prefer_rlib: true,
+    srcs: [":pvmfw_embedded_key_rs"],
+    crate_name: "pvmfw_embedded_key",
+    apex_available: ["com.android.virt"],
+}
+
+prebuilt_etc {
     name: "pvmfw_sign_key",
     src: ":avb_testkey_rsa4096",
     installable: false,
diff --git a/pvmfw/src/avb.rs b/pvmfw/src/avb.rs
new file mode 100644
index 0000000..1abe73f
--- /dev/null
+++ b/pvmfw/src/avb.rs
@@ -0,0 +1,17 @@
+// 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.
+
+//! Image verification.
+
+pub use pvmfw_embedded_key::PUBLIC_KEY;
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 9f8cbd2..870172d 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -17,12 +17,14 @@
 #![no_main]
 #![no_std]
 
+mod avb;
 mod entry;
 mod exceptions;
 mod helpers;
 mod mmio_guard;
 mod smccc;
 
+use avb::PUBLIC_KEY;
 use log::{debug, info};
 
 fn main(fdt: &mut [u8], payload: &[u8]) {
@@ -33,6 +35,6 @@
         payload.as_ptr() as usize,
         payload.len(),
     );
-
+    debug!("AVB public key: addr={:?}, size={:#x} ({1})", PUBLIC_KEY.as_ptr(), PUBLIC_KEY.len());
     info!("Starting payload...");
 }
diff --git a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
index ebb2bcf..e8c435f 100644
--- a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
+++ b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
@@ -33,4 +33,7 @@
 
     /* get the VM's boot certificate chain (BCC). */
     byte[] getBcc();
+
+    /* get the APK contents path. */
+    String getApkContentsPath();
 }
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 5c9cf42..c4296df 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -111,6 +111,7 @@
         assertThat(testResults.mAddInteger).isEqualTo(123 + 456);
         assertThat(testResults.mAppRunProp).isEqualTo("true");
         assertThat(testResults.mSublibRunProp).isEqualTo("true");
+        assertThat(testResults.mApkContentsPath).isEqualTo("/mnt/apk");
     }
 
     @Test
@@ -538,6 +539,7 @@
         String mAppRunProp;
         String mSublibRunProp;
         String mExtraApkTestProp;
+        String mApkContentsPath;
     }
 
     private TestResults runVmTestService(VirtualMachine vm) throws Exception {
@@ -557,6 +559,7 @@
                                     testService.readProperty("debug.microdroid.app.sublib.run");
                             testResults.mExtraApkTestProp =
                                     testService.readProperty("debug.microdroid.test.extra_apk");
+                            testResults.mApkContentsPath = testService.getApkContentsPath();
                         } catch (Exception e) {
                             testResults.mException = e;
                         }
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index d57d224..1a3e940 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -112,6 +112,17 @@
             }
             return ndk::ScopedAStatus::ok();
         }
+
+        ndk::ScopedAStatus getApkContentsPath(std::string* out) override {
+            const char* path_c = AVmPayload_getApkContentsPath();
+            if (path_c == nullptr) {
+                return ndk::ScopedAStatus::
+                        fromServiceSpecificErrorWithMessage(0, "Failed to get APK contents path");
+            }
+            std::string path(path_c);
+            *out = path;
+            return ndk::ScopedAStatus::ok();
+        }
     };
     auto testService = ndk::SharedRefBase::make<TestService>();
 
diff --git a/vmbase/common.h b/vmbase/common.h
new file mode 100644
index 0000000..788dcf0
--- /dev/null
+++ b/vmbase/common.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#define PSCI_SYSTEM_RESET (0x84000009)
+
+.macro adr_l, reg:req, sym:req
+	adrp \reg, \sym
+	add \reg, \reg, :lo12:\sym
+.endm
+
+.macro mov_i, reg:req, imm:req
+	movz \reg, :abs_g3:\imm
+	movk \reg, :abs_g2_nc:\imm
+	movk \reg, :abs_g1_nc:\imm
+	movk \reg, :abs_g0_nc:\imm
+.endm
+
+.macro reset_or_hang
+	mov_i x0, PSCI_SYSTEM_RESET
+	hvc 0
+999:	wfi
+	b 999b
+.endm
diff --git a/vmbase/entry.S b/vmbase/entry.S
index 75ab90b..5f0a2ce 100644
--- a/vmbase/entry.S
+++ b/vmbase/entry.S
@@ -14,17 +14,7 @@
  * limitations under the License.
  */
 
-.macro adr_l, reg:req, sym:req
-	adrp \reg, \sym
-	add \reg, \reg, :lo12:\sym
-.endm
-
-.macro mov_i, reg:req, imm:req
-	movz \reg, :abs_g3:\imm
-	movk \reg, :abs_g2_nc:\imm
-	movk \reg, :abs_g1_nc:\imm
-	movk \reg, :abs_g0_nc:\imm
-.endm
+#include <common.h>
 
 .set .L_MAIR_DEV_nGnRE,	0x04
 .set .L_MAIR_MEM_WBWA,	0xff
@@ -95,6 +85,16 @@
 	adr x30, vector_table_panic
 	msr vbar_el1, x30
 
+	/*
+	 * Our load address is set by the host so validate it before proceeding.
+	 */
+	adr x30, entry
+	mov_i x29, entry
+	cmp x29, x30
+	b.eq 1f
+	reset_or_hang
+1:
+
 	adrp x30, idmap
 	msr ttbr0_el1, x30
 
diff --git a/vmbase/exceptions_panic.S b/vmbase/exceptions_panic.S
index 4a3f2db..54735b2 100644
--- a/vmbase/exceptions_panic.S
+++ b/vmbase/exceptions_panic.S
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <common.h>
+
 /**
  * The following table is intended to trap any fault resulting from the very
  * first memory accesses. They assume that PSCI v0.2 is available and provides
@@ -21,80 +23,69 @@
  * results in the core busy-looping.
  */
 
-.macro exception_panic
-	mov	x0, 0x84000000
-	movk	x0, 9
-	mov	x1, 0
-	mov	x2, 0
-	mov	x3, 0
-	hvc	0
-0:	wfi
-	b	0b
-.endm
-
 .section .text.vector_table_panic, "ax"
 .global vector_table_panic
 .balign 0x800
 vector_table_panic:
 sync_cur_sp0_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 irq_cur_sp0_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 fiq_cur_sp0_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 serr_cur_sp0_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 sync_cur_spx_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 irq_cur_spx_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 fiq_cur_spx_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 serr_cur_spx_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 sync_lower_64_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 irq_lower_64_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 fiq_lower_64_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 serr_lower_64_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 sync_lower_32_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 irq_lower_32_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 fiq_lower_32_panic:
-	exception_panic
+	reset_or_hang
 
 .balign 0x80
 serr_lower_32_panic:
-	exception_panic
+	reset_or_hang