Merge "guest: trusty: enable pvmfw-verified pVM for security and test VMs" into main
diff --git a/guest/pvmfw/avb/Android.bp b/guest/pvmfw/avb/Android.bp
index 0294322..141c1d2 100644
--- a/guest/pvmfw/avb/Android.bp
+++ b/guest/pvmfw/avb/Android.bp
@@ -33,7 +33,7 @@
         ":microdroid_kernel_signed",
         ":microdroid_initrd_normal",
         ":microdroid_initrd_debuggable",
-        ":trusty_security_vm_signed",
+        ":trusty_test_vm_signed_bin",
         ":test_image_with_one_hashdesc",
         ":test_image_with_non_initrd_hashdesc",
         ":test_image_with_initrd_and_non_initrd_desc",
diff --git a/guest/pvmfw/avb/tests/api_test.rs b/guest/pvmfw/avb/tests/api_test.rs
index df33830..3027c47 100644
--- a/guest/pvmfw/avb/tests/api_test.rs
+++ b/guest/pvmfw/avb/tests/api_test.rs
@@ -61,11 +61,11 @@
 }
 
 #[test]
-fn latest_trusty_security_vm_kernel_passes_verification() -> Result<()> {
-    let salt = b"trusty_security_vm_salt";
+fn latest_trusty_test_vm_kernel_passes_verification() -> Result<()> {
+    let salt = b"trusty_test_vm_salt";
     let expected_rollback_index = 1;
     assert_payload_without_initrd_passes_verification(
-        &load_latest_trusty_security_vm_signed_kernel()?,
+        &load_latest_trusty_test_vm_signed_kernel()?,
         salt,
         expected_rollback_index,
         vec![Capability::TrustySecurityVm],
diff --git a/guest/pvmfw/avb/tests/utils.rs b/guest/pvmfw/avb/tests/utils.rs
index e8590ac..7282f3e 100644
--- a/guest/pvmfw/avb/tests/utils.rs
+++ b/guest/pvmfw/avb/tests/utils.rs
@@ -33,7 +33,7 @@
 const MICRODROID_KERNEL_IMG_PATH: &str = "microdroid_kernel";
 const INITRD_NORMAL_IMG_PATH: &str = "microdroid_initrd_normal.img";
 const INITRD_DEBUG_IMG_PATH: &str = "microdroid_initrd_debuggable.img";
-const TRUSTY_SECURITY_VM_KERNEL_IMG_PATH: &str = "trusty_security_vm_signed";
+const TRUSTY_TEST_VM_KERNEL_IMG_PATH: &str = "trusty_test_vm_signed.bin";
 const PUBLIC_KEY_RSA4096_PATH: &str = "data/testkey_rsa4096_pub.bin";
 
 pub const PUBLIC_KEY_RSA2048_PATH: &str = "data/testkey_rsa2048_pub.bin";
@@ -61,8 +61,8 @@
     Ok(fs::read(MICRODROID_KERNEL_IMG_PATH)?)
 }
 
-pub fn load_latest_trusty_security_vm_signed_kernel() -> Result<Vec<u8>> {
-    Ok(fs::read(TRUSTY_SECURITY_VM_KERNEL_IMG_PATH)?)
+pub fn load_latest_trusty_test_vm_signed_kernel() -> Result<Vec<u8>> {
+    Ok(fs::read(TRUSTY_TEST_VM_KERNEL_IMG_PATH)?)
 }
 
 pub fn load_latest_initrd_normal() -> Result<Vec<u8>> {
diff --git a/guest/trusty/common/Android.bp b/guest/trusty/common/Android.bp
index 0541ed5..d6c524f 100644
--- a/guest/trusty/common/Android.bp
+++ b/guest/trusty/common/Android.bp
@@ -1,7 +1,33 @@
+soong_config_module_type {
+    name: "trusty_vm_prebuilt_etc",
+    module_type: "prebuilt_etc",
+    config_namespace: "trusty_system_vm",
+    bool_variables: [
+        "enabled",
+        "placeholder_trusted_hal",
+    ],
+    properties: ["src"],
+}
+
+soong_config_module_type {
+    name: "trusty_vm_avb_add_hash_footer",
+    module_type: "avb_add_hash_footer",
+    config_namespace: "trusty_system_vm",
+    bool_variables: ["enabled"],
+    properties: ["src"],
+}
+
 prebuilt_etc {
     name: "early_vms.xml",
-    src: "early_vms.xml",
     filename: "early_vms.xml",
     relative_install_path: "avf",
     system_ext_specific: true,
+    enabled: select(soong_config_variable("trusty_system_vm", "enabled"), {
+        true: true,
+        default: false,
+    }),
+    src: select(soong_config_variable("trusty_system_vm", "enabled"), {
+        true: "early_vms.xml",
+        default: ":empty_file",
+    }),
 }
diff --git a/guest/trusty/security_vm/TEST_MAPPING b/guest/trusty/security_vm/TEST_MAPPING
index ad7b899..b4d2622 100644
--- a/guest/trusty/security_vm/TEST_MAPPING
+++ b/guest/trusty/security_vm/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
-  "trusty-security_vm-presubmit": [
+  "trusty_security_vm_presubmit": [
   ],
-  "trusty-security_vm-postsubmit": [
+  "trusty_security_vm_postsubmit": [
     {
       "name": "VtsAidlKeyMintTargetTest"
     },
diff --git a/guest/trusty/security_vm/launcher/Android.bp b/guest/trusty/security_vm/launcher/Android.bp
index ff628fd..c70de24 100644
--- a/guest/trusty/security_vm/launcher/Android.bp
+++ b/guest/trusty/security_vm/launcher/Android.bp
@@ -1,3 +1,19 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+prebuilt_etc {
+    name: "trusty_security_vm_launcher.rc",
+    src: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): "security_vm_launcher-arm64.rc",
+        ("android", "x86_64", true): "security_vm_launcher-x86_64.rc",
+        (default, default, default): ":empty_file",
+    }),
+    filename: "trusty_security_vm_launcher.rc",
+    relative_install_path: "init",
+    system_ext_specific: true,
+}
+
 rust_binary {
     name: "trusty_security_vm_launcher",
     crate_name: "trusty_security_vm_launcher",
@@ -13,8 +29,8 @@
     bootstrap: true,
     apex_available: ["//apex_available:platform"],
     system_ext_specific: true,
-    enabled: select(release_flag("RELEASE_AVF_ENABLE_EARLY_VM"), {
+    enabled: select(soong_config_variable("trusty_system_vm", "enabled"), {
         true: true,
-        false: false,
+        default: false,
     }),
 }
diff --git a/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc b/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc
new file mode 100644
index 0000000..c0e0537
--- /dev/null
+++ b/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc
@@ -0,0 +1,20 @@
+# TODO(b/393848713): use --protected for the vm launcher when issues are fixed
+# TODO(b/393848753): determine whether task_profiles shall be defined
+service trusty_security_vm_launcher /system_ext/bin/trusty_security_vm_launcher \
+--name trusty_security_vm_launcher \
+--kernel /system_ext/etc/vm/trusty_vm/trusty_security_vm.elf \
+--memory-size-mib 32
+    disabled
+    user system
+    group system virtualmachine
+    capabilities IPC_LOCK NET_BIND_SERVICE SYS_RESOURCE SYS_NICE
+    stdio_to_kmsg
+    oneshot
+    # task_profiles MaxPerformance
+
+# Starts the non-secure Trusty VM in /system_ext when the feature is enabled through
+# the system property set in vendor init.
+on init && property:trusty.security_vm.enabled=1
+    setprop trusty.security_vm.nonsecure_vm_ready 1
+    setprop trusty.security_vm.vm_cid 200
+    start trusty_security_vm_launcher
diff --git a/guest/trusty/security_vm/launcher/security_vm_launcher-x86_64.rc b/guest/trusty/security_vm/launcher/security_vm_launcher-x86_64.rc
new file mode 100644
index 0000000..b435309
--- /dev/null
+++ b/guest/trusty/security_vm/launcher/security_vm_launcher-x86_64.rc
@@ -0,0 +1,15 @@
+service trusty_security_vm_launcher /system_ext/bin/trusty_security_vm_launcher \
+--kernel /system_ext/etc/vm/trusty_vm/trusty_security_vm.elf \
+--memory-size-mib 16
+    disabled
+    user system
+    group system virtualmachine
+    capabilities IPC_LOCK NET_BIND_SERVICE SYS_RESOURCE SYS_NICE
+    stdio_to_kmsg
+
+# Starts the non-secure Trusty VM in /system_ext when the feature is enabled through
+# the system property set in vendor init.
+on init && property:trusty.security_vm.enabled=1
+    setprop trusty.security_vm.nonsecure_vm_ready 1
+    setprop trusty.security_vm.vm_cid 200
+    start trusty_security_vm_launcher
diff --git a/guest/trusty/security_vm/launcher/src/main.rs b/guest/trusty/security_vm/launcher/src/main.rs
index 5273d33..933e4b3 100644
--- a/guest/trusty/security_vm/launcher/src/main.rs
+++ b/guest/trusty/security_vm/launcher/src/main.rs
@@ -106,9 +106,9 @@
     .context("Failed to create VM")?;
     vm.start(None /* callback */).context("Failed to start VM")?;
 
-    println!("started trusty_security_vm_launcher VM");
+    println!("started {} VM", args.name.to_owned());
     let death_reason = vm.wait_for_death();
-    eprintln!("trusty_security_vm_launcher ended: {:?}", death_reason);
+    eprintln!("{} ended: {:?}", args.name.to_owned(), death_reason);
 
     // TODO(b/331320802): we may want to use android logger instead of stdio_to_kmsg?
 
diff --git a/guest/trusty/security_vm/security_vm.mk b/guest/trusty/security_vm/security_vm.mk
new file mode 100644
index 0000000..89c9cdc
--- /dev/null
+++ b/guest/trusty/security_vm/security_vm.mk
@@ -0,0 +1,23 @@
+# Copyright (C) 2025 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.
+
+
+ifeq ($(findstring enabled, $(TRUSTY_SYSTEM_VM)),enabled)
+PRODUCT_PACKAGES += \
+	trusty_security_vm.elf \
+	trusty_security_vm_launcher \
+	trusty_security_vm_launcher.rc \
+	early_vms.xml \
+
+endif
diff --git a/guest/trusty/security_vm/vm/Android.bp b/guest/trusty/security_vm/vm/Android.bp
index ee64095..d823448 100644
--- a/guest/trusty/security_vm/vm/Android.bp
+++ b/guest/trusty/security_vm/vm/Android.bp
@@ -2,32 +2,51 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+soong_config_module_type_import {
+    from: "packages/modules/Virtualization/guest/trusty/common/Android.bp",
+    module_types: ["trusty_vm_avb_add_hash_footer"],
+}
+
+// - Trusty VM payloads on arm64 are pvmfw enabled
+//   AVF VM build system uses the raw binary image (:trusty_security_vm_unsigned),
+//   adds pvmfw footer and generates a pvmfw-compliant signed elf file)
+// - Trusty VM payload on x86 are for now loaded in Cuttlefish unsigned
+//   the unsigned generated elf is used directly by AV
+//
+// see packages/modules/Virtualization/guest/trusty
+
 prebuilt_etc {
-    name: "lk_trusty.elf",
+    name: "trusty_security_vm.elf",
+    src: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): ":trusty_security_vm_signed",
+        ("android", "x86_64", true): ":trusty_security_vm_unsigned",
+        (default, default, default): ":empty_file",
+    }),
     system_ext_specific: true,
     relative_install_path: "vm/trusty_vm",
-    filename: "lk_trusty.elf",
-    arch: {
-        x86_64: {
-            src: ":trusty_security_vm_signed",
-        },
-        arm64: {
-            src: ":security_vm_elf",
-        },
-    },
-    src: ":empty_file",
+    filename: "trusty_security_vm.elf",
+}
+
+filegroup {
+    name: "trusty_vm_sections.ld",
+    srcs: [
+        "trusty_vm_sections.ld",
+    ],
+    visibility: [
+        "//packages/modules/Virtualization/guest/trusty/test_vm/vm",
+    ],
 }
 
 cc_binary {
-    name: "security_vm_elf",
+    name: "trusty_security_vm_signed",
     srcs: [
-        ":security_vm_signed_obj",
+        ":trusty_security_vm_signed_bin_obj",
     ],
     linker_scripts: [
-        "security_vm_sections.ld",
+        ":trusty_vm_sections.ld",
     ],
     ldflags: [
-        // Prevent the `trusty_security_vm_signed` segment from being garbage collected.
+        // Prevent the `trusty_security_vm_signed_bin_obj` segment from being garbage collected.
         "-Wl,--no-gc-sections",
         // Prevent the build ID segments from being added, as it would corrupt the integrity
         // of the original signed image.
@@ -40,49 +59,48 @@
     no_libcrt: true,
     static_executable: true,
     system_shared_libs: [],
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     strip: {
         none: true,
     },
+    enabled: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): true,
+        (default, default, default): false,
+    }),
 }
 
 cc_genrule {
     name: "security_vm.S",
     arch: {
         arm64: {
-            srcs: [":trusty_security_vm_signed"],
+            srcs: [":trusty_security_vm_signed_bin"],
         },
     },
     out: ["security_vm.S"],
     cmd: "(" +
-        "    echo '.section .security_vm_signed.bin';" +
-        "    echo '.globl security_vm_signed';" +
-        "    echo 'security_vm_signed:';" +
+        "    echo '.section .vm_payload_signed.bin';" +
+        "    echo '.globl vm_payload_signed';" +
+        "    echo 'vm_payload_signed:';" +
         "    echo '.incbin \"'$(in)'\"';" +
         ") > $(out)",
     visibility: ["//visibility:private"],
+    enabled: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): true,
+        (default, default, default): false,
+    }),
 }
 
 cc_object {
-    name: "security_vm_signed_obj",
+    name: "trusty_security_vm_signed_bin_obj",
     srcs: [
         ":security_vm.S",
     ],
-    static_libs: ["trusty_security_vm_signed"],
     crt: false,
     system_shared_libs: [],
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     visibility: ["//visibility:private"],
+    enabled: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): true,
+        (default, default, default): false,
+    }),
 }
 
 filegroup {
@@ -95,9 +113,9 @@
 
 TRUSTY_SECURITY_VM_VERSION = 1
 
-avb_add_hash_footer {
-    name: "trusty_security_vm_signed",
-    filename: "trusty_security_vm_signed",
+trusty_vm_avb_add_hash_footer {
+    name: "trusty_security_vm_signed_bin",
+    filename: "trusty_security_vm_signed.bin",
     partition_name: "boot",
     private_key: ":trusty_vm_sign_key",
     salt: trusty_security_vm_salt,
@@ -108,29 +126,12 @@
             value: "trusty_security_vm",
         },
     ],
-    src: ":empty_file",
-    enabled: false,
-    arch: {
-        x86_64: {
-            src: ":trusty-lk.elf",
-            enabled: true,
-        },
-        arm64: {
-            src: ":trusty_security_vm_unsigned",
-            enabled: true,
-        },
-    },
-}
-
-// TODO(b/379646659): Take the binary generated by trusty instead of extracting
-// it from ELF here.
-raw_binary {
-    name: "trusty_security_vm_unsigned",
-    src: ":trusty-test-lk.elf",
-    enabled: false,
-    arch: {
-        arm64: {
-            enabled: true,
-        },
-    },
+    src: select(soong_config_variable("trusty_system_vm", "enabled"), {
+        true: ":trusty_security_vm_unsigned",
+        default: ":empty_file",
+    }),
+    enabled: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
+        ("android", "arm64", true): true,
+        (default, default, default): false,
+    }),
 }
diff --git a/guest/trusty/security_vm/vm/security_vm_sections.ld b/guest/trusty/security_vm/vm/trusty_vm_sections.ld
similarity index 91%
rename from guest/trusty/security_vm/vm/security_vm_sections.ld
rename to guest/trusty/security_vm/vm/trusty_vm_sections.ld
index 63e5f5d..42627da 100644
--- a/guest/trusty/security_vm/vm/security_vm_sections.ld
+++ b/guest/trusty/security_vm/vm/trusty_vm_sections.ld
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-ENTRY(security_vm_signed)
+ENTRY(vm_payload_signed)
 
 SECTIONS
 {
     . = 0x0;
     .text : {
-        *(.security_vm_signed.bin)
+        *(.vm_payload_signed.bin)
     }
 }
diff --git a/guest/trusty/test_vm/Android.bp b/guest/trusty/test_vm/Android.bp
index 498028d..699b673 100644
--- a/guest/trusty/test_vm/Android.bp
+++ b/guest/trusty/test_vm/Android.bp
@@ -17,34 +17,16 @@
     default_team: "trendy_team_trusty",
 }
 
-// python -c "import hashlib; print(hashlib.sha256(b'trusty_test_vm_salt').hexdigest())"
-trusty_test_vm_salt = "5ce3eab1a08540e1334c83f54b8608aa6c23feee6939693cac41441449c5a51f"
-
-TRUSTY_TEST_VM_VERSION = 1
-
-avb_add_hash_footer {
-    name: "trusty_test_vm_signed",
-    filename: "trusty_test_vm_signed",
-    partition_name: "boot",
-    private_key: ":trusty_vm_sign_key",
-    salt: trusty_test_vm_salt,
-    rollback_index: TRUSTY_TEST_VM_VERSION,
-    src: ":empty_file",
-    enabled: false,
-    arch: {
-        x86_64: {
-            src: ":trusty-test-lk.elf",
-            enabled: true,
-        },
-    },
-}
-
 prebuilt_etc {
     name: "trusty_test_vm_config",
     enabled: false,
     arch: {
+        arm64: {
+            src: "trusty-test_vm-config-arm64.json",
+            enabled: true,
+        },
         x86_64: {
-            src: "vm_config_lk_x86_64.json",
+            src: "trusty-test_vm-config-x86_64.json",
             enabled: true,
         },
     },
@@ -55,11 +37,14 @@
     name: "trusty_vm_launcher_sh",
     enabled: false,
     arch: {
+        arm64: {
+            enabled: true,
+        },
         x86_64: {
-            src: "trusty-vm-launcher.sh",
             enabled: true,
         },
     },
+    src: "trusty-vm-launcher.sh",
     filename: "trusty-vm-launcher.sh",
 }
 
@@ -67,20 +52,32 @@
     name: "trusty_wait_ready_sh",
     enabled: false,
     arch: {
+        arm64: {
+            enabled: true,
+        },
         x86_64: {
-            src: "trusty-wait-ready.sh",
             enabled: true,
         },
     },
+    src: "trusty-wait-ready.sh",
     filename: "trusty-wait-ready.sh",
 }
 
 sh_test {
     name: "TrustyTestVM_UnitTests",
     src: "trusty-ut-ctrl.sh",
+    enabled: false,
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+        x86_64: {
+            enabled: true,
+        },
+    },
     filename_from_src: true,
     data: [
-        ":trusty_test_vm_signed",
+        ":trusty_test_vm_elf",
         ":trusty_test_vm_config",
         "trusty-vm-launcher.sh",
         "trusty-wait-ready.sh",
@@ -91,10 +88,4 @@
     test_suites: [
         "general-tests",
     ],
-    enabled: false,
-    arch: {
-        x86_64: {
-            enabled: true,
-        },
-    },
 }
diff --git a/guest/trusty/test_vm/AndroidTest.xml b/guest/trusty/test_vm/AndroidTest.xml
index d8710ab..6fb0879 100644
--- a/guest/trusty/test_vm/AndroidTest.xml
+++ b/guest/trusty/test_vm/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="push-file" key="trusty-vm-launcher.sh" value="/data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
         <option name="push-file" key="trusty-wait-ready.sh" value="/data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
         <option name="push-file" key="trusty-test_vm-config.json" value="/data/local/tmp/trusty_test_vm/trusty-test_vm-config.json" />
-        <option name="push-file" key="trusty_test_vm_signed" value="/data/local/tmp/trusty_test_vm/trusty_test_vm_signed" />
+        <option name="push-file" key="trusty_test_vm.elf" value="/data/local/tmp/trusty_test_vm/trusty_test_vm.elf" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="throw-if-cmd-fail" value="true" />
diff --git a/guest/trusty/test_vm/TEST_MAPPING b/guest/trusty/test_vm/TEST_MAPPING
index 6f2b56e..aa9d65d 100644
--- a/guest/trusty/test_vm/TEST_MAPPING
+++ b/guest/trusty/test_vm/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
-  "trusty-test_vm-presubmit": [
+  "trusty_test_vm_presubmit": [
   ],
-  "trusty-test_vm-postsubmit": [
+  "trusty_test_vm_postsubmit": [
     {
         "name": "TrustyTestVM_UnitTests"
     }
diff --git a/guest/trusty/test_vm/trusty-test_vm-config-arm64.json b/guest/trusty/test_vm/trusty-test_vm-config-arm64.json
new file mode 100644
index 0000000..18b275e
--- /dev/null
+++ b/guest/trusty/test_vm/trusty-test_vm-config-arm64.json
@@ -0,0 +1,7 @@
+{
+    "name": "trusty_test_vm",
+    "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm_.elf",
+    "platform_version": "1.0",
+    "memory_mib": 112,
+    "protected": true
+}
diff --git a/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json b/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json
new file mode 100644
index 0000000..d491c3a
--- /dev/null
+++ b/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json
@@ -0,0 +1,6 @@
+{
+    "name": "trusty_test_vm",
+    "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm.elf",
+    "platform_version": "1.0",
+    "memory_mib": 112
+}
diff --git a/guest/trusty/test_vm/vm/Android.bp b/guest/trusty/test_vm/vm/Android.bp
new file mode 100644
index 0000000..1db9078
--- /dev/null
+++ b/guest/trusty/test_vm/vm/Android.bp
@@ -0,0 +1,119 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+soong_config_module_type_import {
+    from: "packages/modules/Virtualization/guest/trusty/common/Android.bp",
+    module_types: ["trusty_vm_avb_add_hash_footer"],
+}
+
+prebuilt_etc {
+    name: "trusty_test_vm_elf",
+    system_ext_specific: true,
+    relative_install_path: "vm/trusty_vm",
+    filename: "trusty_test_vm.elf",
+    src: select((os(), arch()), {
+        ("android", "arm64"): ":trusty_test_vm_signed",
+        ("android", "x86_64"): ":trusty_test_vm_unsigned",
+        (default, default): ":empty_file",
+    }),
+}
+
+cc_binary {
+    name: "trusty_test_vm_signed",
+    srcs: [
+        ":trusty_test_vm_signed_bin_obj",
+    ],
+    // reuse the common trusty_vm_sections linker script
+    linker_scripts: [
+        ":trusty_vm_sections.ld",
+    ],
+    ldflags: [
+        // Prevent the `trusty_test_vm_signed_bin_obj` segment from being garbage collected.
+        "-Wl,--no-gc-sections",
+        // Prevent the build ID segments from being added, as it would corrupt the integrity
+        // of the original signed image.
+        "-Wl,--build-id=none",
+        // Use a standard page size of 4096, smaller than the default 16384, to avoid padding
+        // with extra bytes.
+        "-Wl,-z,max-page-size=4096",
+    ],
+    nocrt: true,
+    no_libcrt: true,
+    static_executable: true,
+    system_shared_libs: [],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    strip: {
+        none: true,
+    },
+}
+
+cc_genrule {
+    name: "test_vm.S",
+    enabled: false,
+    arch: {
+        arm64: {
+            srcs: [":trusty_test_vm_signed_bin"],
+            enabled: true,
+        },
+    },
+    out: ["test_vm.S"],
+    cmd: "(" +
+        "    echo '.section .vm_payload_signed.bin';" +
+        "    echo '.globl vm_payload_signed';" +
+        "    echo 'vm_payload_signed:';" +
+        "    echo '.incbin \"'$(in)'\"';" +
+        ") > $(out)",
+    visibility: ["//visibility:private"],
+}
+
+cc_object {
+    name: "trusty_test_vm_signed_bin_obj",
+    srcs: [
+        ":test_vm.S",
+    ],
+    crt: false,
+    system_shared_libs: [],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    visibility: ["//visibility:private"],
+}
+
+// python -c "import hashlib; print(hashlib.sha256(b'trusty_test_vm_salt').hexdigest())"
+trusty_test_vm_salt = "5ce3eab1a08540e1334c83f54b8608aa6c23feee6939693cac41441449c5a51f"
+
+TRUSTY_TEST_VM_VERSION = 1
+
+trusty_vm_avb_add_hash_footer {
+    name: "trusty_test_vm_signed_bin",
+    filename: "trusty_test_vm_signed.bin",
+    partition_name: "boot",
+    private_key: ":trusty_vm_sign_key",
+    salt: trusty_test_vm_salt,
+    rollback_index: TRUSTY_TEST_VM_VERSION,
+    props: [
+        {
+            name: "com.android.virt.cap",
+            value: "trusty_security_vm",
+        },
+    ],
+    src: ":trusty_test_vm_unsigned",
+    enabled: false,
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+        x86_64: {
+            enabled: true,
+        },
+    },
+}
diff --git a/guest/trusty/test_vm/vm_config_lk_x86_64.json b/guest/trusty/test_vm/vm_config_lk_x86_64.json
deleted file mode 100644
index 5effca5..0000000
--- a/guest/trusty/test_vm/vm_config_lk_x86_64.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "name": "trusty_test_vm",
-    "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm_signed",
-    "platform_version": "1.0",
-    "memory_mib": 112
-}