Merge changes I22ebac41,Ib81cfb24

* changes:
  Update kernel to builds 8798673
  Update kernel to builds 8798673
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 0ca6211..2d3f6ff 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -44,6 +44,9 @@
       "path": "packages/modules/Virtualization/authfs"
     },
     {
+      "path": "packages/modules/Virtualization/vmbase"
+    },
+    {
       "path": "packages/modules/Virtualization/zipfuse"
     }
   ]
diff --git a/docs/getting_started/pixel6.md b/docs/getting_started/pixel6.md
new file mode 100644
index 0000000..82391c4
--- /dev/null
+++ b/docs/getting_started/pixel6.md
@@ -0,0 +1,129 @@
+# Instructions for building custom AVF on Pixel 6 or 6 Pro
+
+This document provides steps for building AVF from AOSP, and then install it to
+Pixel 6 series to better understand AVF and do some experiments.
+
+**WARNING**: Unless Android 13 is released to AOSP (expected to be at Summer
+2022, exact date TBD) by the time when you read this documentation, or you or
+your company have early access to Android Tiramisu source tree, you **CANNOT**
+follow this instruction. In that case, you can only **USE** the AVF that is
+shipped in the Android 13 Beta Image.
+
+This is because AVF in the beta image is signed by Google and therefore it can't
+be updated to a new AVF built in AOSP which can't be signed by the Google key
+that is not shared with AOSP.
+
+## Upgrade to Android 13 Beta Image
+
+First, upgrade your Pixel 6 or Pixel 6 Pro to the Android 13 Beta Image. This
+can be done in two ways:
+
+* Join [Android Beta Program](https://www.google.com/android/beta) and then OTA
+  to Android 13.
+* Manually flash [Android 13 Beta Images](https://developer.android.com/about/versions/13/download#factory-images).
+
+Then enable ADB debugging in "Settings" -> "System" -> "Developer options".
+Finally, enable PKVM.
+
+```shell
+adb reboot bootloader
+fastboot flashing unlock
+fastboot oem pkvm enable
+fastboot reboot
+```
+
+## Building GSI and flashing it
+
+Prepare your Android 13 (Tiramisu) source tree.
+
+```shell
+mkdir tm
+cd tm
+repo init -u <URL> -m <your_tm_branch>
+repo sync -c --no-tags -j 10
+```
+
+Patch GSI so that it includes AVF. Edit
+`build/make/target/product/gsi_release.mk` and add the following line to the
+end (or anywhere in the file that makes sense):
+
+```
+PRODUCT_PACKAGES += com.android.virt
+```
+
+Build GSI.
+
+```shell
+source build/envsetup.sh
+choosecombo 1 aosp_arm64 userdebug
+m
+```
+
+Flash GSI to the Pixel device.
+
+```shell
+adb reboot bootloader
+fastboot reboot fastboot
+fastboot delete-logical-partition product_a
+fastboot flash system out/target/product/generic_arm64/system.img
+fastboot --disable-verification flash vbmeta out/target/product/generic_arm64/vbmeta.img
+fastboot -w reboot
+```
+
+Deleting the logical partition `product_a` is needed because the GSI image is
+bigger than the logical partition `system_a` of the beta image.
+`--disable-verification` when flashing the `vbmeta` partition is critical. Don't
+miss it.
+
+Lastly, check if you are running GSI.
+
+```shell
+adb shell getprop ro.build.product
+adb shell ls /dev/kvm
+adb shell ls /apex/com.android.virt/bin/vm
+```
+
+The result should be as follows.
+
+```
+generic_arm64
+/dev/kvm
+/apex/com.android.virt/bin/vm
+```
+
+## Building and installing AVF from AOSP
+
+Checkout AOSP master branch.
+
+```shell
+mkdir aosp
+cd aosp
+repo init -u https://android.googlesource.com/platform/manifest -b master
+repo sync -c --no-tags -j 10
+```
+
+Then build the `com.android.virt` APEX.
+
+```shell
+source build/envsetup.sh
+banchan com.android.virt aosp_arm64
+UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist
+```
+
+Install the newly built AVF to the device
+
+```shell
+adb install out/dist/com.android.virt.apex
+adb reboot
+```
+
+If this doesn't work for some reason, try this:
+
+```
+adb root
+adb shell setenforce 0
+adb push out/dist/com.android.virt.apex /data/local/
+adb shell cmd -w apexservice deactivatePackage /system/system_ext/apex/com.android.virt.apex
+adb shell cmd -w apexservice activatePackage /data/local/com.android.virt.apex
+// Don't adb reboot
+```
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 15d6663..350fbc5 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -299,7 +299,9 @@
     dice_derivation(&verified_data, &metadata.payload_config_path)?;
 
     // Before reading a file from the APK, start zipfuse
+    let noexec = false;
     run_zipfuse(
+        noexec,
         "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
         Path::new("/dev/block/mapper/microdroid-apk"),
         Path::new("/mnt/apk"),
@@ -364,9 +366,12 @@
     cmd.spawn().context("Spawn apkdmverity")
 }
 
-fn run_zipfuse(option: &str, zip_path: &Path, mount_dir: &Path) -> Result<Child> {
-    Command::new(ZIPFUSE_BIN)
-        .arg("-o")
+fn run_zipfuse(noexec: bool, option: &str, zip_path: &Path, mount_dir: &Path) -> Result<Child> {
+    let mut cmd = Command::new(ZIPFUSE_BIN);
+    if noexec {
+        cmd.arg("--noexec");
+    }
+    cmd.arg("-o")
         .arg(option)
         .arg(zip_path)
         .arg(mount_dir)
@@ -537,7 +542,9 @@
         create_dir(Path::new(&mount_dir)).context("Failed to create mount dir for extra apks")?;
 
         // don't wait, just detach
+        let noexec = true;
         run_zipfuse(
+            noexec,
             "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:extra_apk_file:s0",
             Path::new(&format!("/dev/block/mapper/extra-apk-{}", i)),
             Path::new(&mount_dir),
diff --git a/vmbase/TEST_MAPPING b/vmbase/TEST_MAPPING
new file mode 100644
index 0000000..9b7e4cb
--- /dev/null
+++ b/vmbase/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "vmbase_example.integration_test"
+    }
+  ]
+}
diff --git a/zipfuse/src/main.rs b/zipfuse/src/main.rs
index c3fae69..874056a 100644
--- a/zipfuse/src/main.rs
+++ b/zipfuse/src/main.rs
@@ -46,6 +46,12 @@
                 .required(false)
                 .help("Comma separated list of mount options"),
         )
+        .arg(
+            Arg::with_name("noexec")
+                .long("noexec")
+                .takes_value(false)
+                .help("Disallow the execution of binary files"),
+        )
         .arg(Arg::with_name("ZIPFILE").required(true))
         .arg(Arg::with_name("MOUNTPOINT").required(true))
         .get_matches();
@@ -53,12 +59,18 @@
     let zip_file = matches.value_of("ZIPFILE").unwrap().as_ref();
     let mount_point = matches.value_of("MOUNTPOINT").unwrap().as_ref();
     let options = matches.value_of("options");
-    run_fuse(zip_file, mount_point, options)?;
+    let noexec = matches.is_present("noexec");
+    run_fuse(zip_file, mount_point, options, noexec)?;
     Ok(())
 }
 
 /// Runs a fuse filesystem by mounting `zip_file` on `mount_point`.
-pub fn run_fuse(zip_file: &Path, mount_point: &Path, extra_options: Option<&str>) -> Result<()> {
+pub fn run_fuse(
+    zip_file: &Path,
+    mount_point: &Path,
+    extra_options: Option<&str>,
+    noexec: bool,
+) -> Result<()> {
     const MAX_READ: u32 = 1 << 20; // TODO(jiyong): tune this
     const MAX_WRITE: u32 = 1 << 13; // This is a read-only filesystem
 
@@ -76,12 +88,12 @@
         mount_options.push(MountOption::Extra(value));
     }
 
-    fuse::mount(
-        mount_point,
-        "zipfuse",
-        libc::MS_NOSUID | libc::MS_NODEV | libc::MS_RDONLY,
-        &mount_options,
-    )?;
+    let mut mount_flags = libc::MS_NOSUID | libc::MS_NODEV | libc::MS_RDONLY;
+    if noexec {
+        mount_flags |= libc::MS_NOEXEC;
+    }
+
+    fuse::mount(mount_point, "zipfuse", mount_flags, &mount_options)?;
     let mut config = fuse::FuseConfig::new();
     config.dev_fuse(dev_fuse).max_write(MAX_WRITE).max_read(MAX_READ);
     Ok(config.enter_message_loop(ZipFuse::new(zip_file)?)?)
@@ -435,22 +447,28 @@
     use zip::write::FileOptions;
 
     #[cfg(not(target_os = "android"))]
-    fn start_fuse(zip_path: &Path, mnt_path: &Path) {
+    fn start_fuse(zip_path: &Path, mnt_path: &Path, noexec: bool) {
         let zip_path = PathBuf::from(zip_path);
         let mnt_path = PathBuf::from(mnt_path);
         std::thread::spawn(move || {
-            crate::run_fuse(&zip_path, &mnt_path, None).unwrap();
+            crate::run_fuse(&zip_path, &mnt_path, None, noexec).unwrap();
         });
     }
 
     #[cfg(target_os = "android")]
-    fn start_fuse(zip_path: &Path, mnt_path: &Path) {
+    fn start_fuse(zip_path: &Path, mnt_path: &Path, noexec: bool) {
         // Note: for some unknown reason, running a thread to serve fuse doesn't work on Android.
         // Explicitly spawn a zipfuse process instead.
         // TODO(jiyong): fix this
+        let noexec = if noexec { "--noexec" } else { "" };
         assert!(std::process::Command::new("sh")
             .arg("-c")
-            .arg(format!("/data/local/tmp/zipfuse {} {}", zip_path.display(), mnt_path.display()))
+            .arg(format!(
+                "/data/local/tmp/zipfuse {} {} {}",
+                noexec,
+                zip_path.display(),
+                mnt_path.display()
+            ))
             .spawn()
             .is_ok());
     }
@@ -476,6 +494,14 @@
     // Creates a zip file, adds some files to the zip file, mounts it using zipfuse, runs the check
     // routine, and finally unmounts.
     fn run_test(add: fn(&mut zip::ZipWriter<File>), check: fn(&std::path::Path)) {
+        run_test_noexec(false, add, check);
+    }
+
+    fn run_test_noexec(
+        noexec: bool,
+        add: fn(&mut zip::ZipWriter<File>),
+        check: fn(&std::path::Path),
+    ) {
         // Create an empty zip file
         let test_dir = tempfile::TempDir::new().unwrap();
         let zip_path = test_dir.path().join("test.zip");
@@ -492,7 +518,7 @@
         let mnt_path = test_dir.path().join("mnt");
         assert!(fs::create_dir(&mnt_path).is_ok());
 
-        start_fuse(&zip_path, &mnt_path);
+        start_fuse(&zip_path, &mnt_path, noexec);
 
         let mnt_path = test_dir.path().join("mnt");
         // Give some time for the fuse to boot up
@@ -577,6 +603,26 @@
     }
 
     #[test]
+    fn noexec() {
+        fn add_executable(zip: &mut zip::ZipWriter<File>) {
+            zip.start_file("executable", FileOptions::default().unix_permissions(0o755)).unwrap();
+        }
+
+        // Executables can be run when not mounting with noexec.
+        run_test(add_executable, |root| {
+            let res = std::process::Command::new(root.join("executable")).status();
+            res.unwrap();
+        });
+
+        // Mounting with noexec results in permissions denial when running an executable.
+        let noexec = true;
+        run_test_noexec(noexec, add_executable, |root| {
+            let res = std::process::Command::new(root.join("executable")).status();
+            assert!(matches!(res.unwrap_err().kind(), std::io::ErrorKind::PermissionDenied));
+        });
+    }
+
+    #[test]
     fn single_dir() {
         run_test(
             |zip| {
@@ -688,7 +734,8 @@
         let mnt_path = test_dir.join("mnt");
         assert!(fs::create_dir(&mnt_path).is_ok());
 
-        start_fuse(zip_path, &mnt_path);
+        let noexec = false;
+        start_fuse(zip_path, &mnt_path, noexec);
 
         // Give some time for the fuse to boot up
         assert!(wait_for_mount(&mnt_path).is_ok());