CustomPvmfwHostTestCases: Handle config version 1.2
Bug: 327489255
Bug: 323768068
Test: atest CustomPvmfwHostTestCases on CF and Pixel 8, and T/H
Change-Id: Ie6deb99b81698b0986b3911fc9f62066c13ef2f7
diff --git a/tests/pvmfw/Android.bp b/tests/pvmfw/Android.bp
index c12f67a..0483066 100644
--- a/tests/pvmfw/Android.bp
+++ b/tests/pvmfw/Android.bp
@@ -53,4 +53,5 @@
":test_avf_debug_policy_without_adb",
"assets/bcc.dat",
],
+ data_device_bins_first: ["dtc_static"],
}
diff --git a/tests/pvmfw/AndroidTest.xml b/tests/pvmfw/AndroidTest.xml
index 6ff7b6f..5784f26 100644
--- a/tests/pvmfw/AndroidTest.xml
+++ b/tests/pvmfw/AndroidTest.xml
@@ -22,6 +22,24 @@
<option name="force-root" value="true"/>
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="throw-if-cmd-fail" value="true" />
+ <!-- Prepare test directories. -->
+ <option name="run-command" value="mkdir -p /data/local/tmp/pvmfw" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/pvmfw" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="abort-on-push-failure" value="true" />
+ <option name="push-file" key="dtc_static" value="/data/local/tmp/pvmfw/dtc_static" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="throw-if-cmd-fail" value="true" />
+ <option name="run-command" value="[ ! -d /proc/device-tree/avf/reference ] || /data/local/tmp/pvmfw/dtc_static -f -qqq /proc/device-tree/avf/reference -o /data/local/tmp/pvmfw/reference_dt.dtb" />
+ </target_preparer>
+
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CustomPvmfwHostTestCases.jar" />
</test>
diff --git a/tests/pvmfw/helper/Android.bp b/tests/pvmfw/helper/Android.bp
index 1b96842..90ca03e 100644
--- a/tests/pvmfw/helper/Android.bp
+++ b/tests/pvmfw/helper/Android.bp
@@ -5,5 +5,8 @@
java_library_host {
name: "PvmfwHostTestHelper",
srcs: ["java/**/*.java"],
- libs: ["androidx.annotation_annotation"],
+ libs: [
+ "androidx.annotation_annotation",
+ "truth",
+ ],
}
diff --git a/tests/pvmfw/helper/java/com/android/pvmfw/test/host/Pvmfw.java b/tests/pvmfw/helper/java/com/android/pvmfw/test/host/Pvmfw.java
index b0c1207..a77ba40 100644
--- a/tests/pvmfw/helper/java/com/android/pvmfw/test/host/Pvmfw.java
+++ b/tests/pvmfw/helper/java/com/android/pvmfw/test/host/Pvmfw.java
@@ -16,6 +16,8 @@
package com.android.pvmfw.test.host;
+import static com.google.common.truth.Truth.assertThat;
+
import static java.nio.ByteOrder.LITTLE_ENDIAN;
import androidx.annotation.NonNull;
@@ -34,22 +36,52 @@
private static final int SIZE_4K = 4 << 10; // 4 KiB, PAGE_SIZE
private static final int BUFFER_SIZE = 1024;
private static final int HEADER_MAGIC = 0x666d7670;
- private static final int HEADER_DEFAULT_VERSION = getVersion(1, 0);
+ private static final int HEADER_DEFAULT_VERSION = makeVersion(1, 2);
private static final int HEADER_FLAGS = 0;
+ private static final int PVMFW_ENTRY_BCC = 0;
+ private static final int PVMFW_ENTRY_DP = 1;
+ private static final int PVMFW_ENTRY_VM_DTBO = 2;
+ private static final int PVMFW_ENTRY_VM_REFERENCE_DT = 3;
+ private static final int PVMFW_ENTRY_MAX = 4;
+
@NonNull private final File mPvmfwBinFile;
- @NonNull private final File mBccFile;
- @Nullable private final File mDebugPolicyFile;
+ private final File[] mEntries;
+ private final int mEntryCnt;
private final int mVersion;
+ public static int makeVersion(int major, int minor) {
+ return ((major & 0xFFFF) << 16) | (minor & 0xFFFF);
+ }
+
private Pvmfw(
@NonNull File pvmfwBinFile,
@NonNull File bccFile,
@Nullable File debugPolicyFile,
+ @Nullable File vmDtboFile,
+ @Nullable File vmReferenceDtFile,
int version) {
mPvmfwBinFile = Objects.requireNonNull(pvmfwBinFile);
- mBccFile = Objects.requireNonNull(bccFile);
- mDebugPolicyFile = debugPolicyFile;
+
+ if (version >= makeVersion(1, 2)) {
+ mEntryCnt = PVMFW_ENTRY_VM_REFERENCE_DT + 1;
+ } else if (version >= makeVersion(1, 1)) {
+ mEntryCnt = PVMFW_ENTRY_VM_DTBO + 1;
+ } else {
+ mEntryCnt = PVMFW_ENTRY_DP + 1;
+ }
+
+ mEntries = new File[PVMFW_ENTRY_MAX];
+ mEntries[PVMFW_ENTRY_BCC] = Objects.requireNonNull(bccFile);
+ mEntries[PVMFW_ENTRY_DP] = debugPolicyFile;
+
+ if (PVMFW_ENTRY_VM_DTBO < mEntryCnt) {
+ mEntries[PVMFW_ENTRY_VM_DTBO] = vmDtboFile;
+ }
+ if (PVMFW_ENTRY_VM_REFERENCE_DT < mEntryCnt) {
+ mEntries[PVMFW_ENTRY_VM_REFERENCE_DT] = Objects.requireNonNull(vmReferenceDtFile);
+ }
+
mVersion = version;
}
@@ -60,62 +92,54 @@
public void serialize(@NonNull File outFile) throws IOException {
Objects.requireNonNull(outFile);
- int headerSize = alignTo(getHeaderSize(mVersion), SIZE_8B);
- int bccOffset = headerSize;
- int bccSize = (int) mBccFile.length();
+ int headerSize = alignTo(getHeaderSize(), SIZE_8B);
+ int[] entryOffsets = new int[mEntryCnt];
+ int[] entrySizes = new int[mEntryCnt];
- int debugPolicyOffset = alignTo(bccOffset + bccSize, SIZE_8B);
- int debugPolicySize = mDebugPolicyFile == null ? 0 : (int) mDebugPolicyFile.length();
+ entryOffsets[PVMFW_ENTRY_BCC] = headerSize;
+ entrySizes[PVMFW_ENTRY_BCC] = (int) mEntries[PVMFW_ENTRY_BCC].length();
- int totalSize = debugPolicyOffset + debugPolicySize;
- if (hasVmDtbo(mVersion)) {
- // Add VM DTBO size as well.
- totalSize += Integer.BYTES * 2;
+ for (int i = 1; i < mEntryCnt; i++) {
+ entryOffsets[i] = alignTo(entryOffsets[i - 1] + entrySizes[i - 1], SIZE_8B);
+ entrySizes[i] = mEntries[i] == null ? 0 : (int) mEntries[i].length();
}
+ int totalSize = alignTo(entryOffsets[mEntryCnt - 1] + entrySizes[mEntryCnt - 1], SIZE_8B);
+
ByteBuffer header = ByteBuffer.allocate(headerSize).order(LITTLE_ENDIAN);
header.putInt(HEADER_MAGIC);
header.putInt(mVersion);
header.putInt(totalSize);
header.putInt(HEADER_FLAGS);
- header.putInt(bccOffset);
- header.putInt(bccSize);
- header.putInt(debugPolicyOffset);
- header.putInt(debugPolicySize);
-
- if (hasVmDtbo(mVersion)) {
- // Add placeholder entry for VM DTBO.
- // TODO(b/291191157): Add a real DTBO and test.
- header.putInt(0);
- header.putInt(0);
+ for (int i = 0; i < mEntryCnt; i++) {
+ header.putInt(entryOffsets[i]);
+ header.putInt(entrySizes[i]);
}
try (FileOutputStream pvmfw = new FileOutputStream(outFile)) {
appendFile(pvmfw, mPvmfwBinFile);
padTo(pvmfw, SIZE_4K);
+
+ int baseOffset = (int) pvmfw.getChannel().size();
pvmfw.write(header.array());
- padTo(pvmfw, SIZE_8B);
- appendFile(pvmfw, mBccFile);
- if (mDebugPolicyFile != null) {
+
+ for (int i = 0; i < mEntryCnt; i++) {
padTo(pvmfw, SIZE_8B);
- appendFile(pvmfw, mDebugPolicyFile);
+ if (mEntries[i] != null) {
+ assertThat((int) pvmfw.getChannel().size() - baseOffset)
+ .isEqualTo(entryOffsets[i]);
+ appendFile(pvmfw, mEntries[i]);
+ }
}
+
padTo(pvmfw, SIZE_4K);
}
}
private void appendFile(@NonNull FileOutputStream out, @NonNull File inFile)
throws IOException {
- byte buffer[] = new byte[BUFFER_SIZE];
try (FileInputStream in = new FileInputStream(inFile)) {
- int size;
- while (true) {
- size = in.read(buffer);
- if (size < 0) {
- return;
- }
- out.write(buffer, /* offset= */ 0, size);
- }
+ in.transferTo(out);
}
}
@@ -126,27 +150,15 @@
}
}
- private static int getHeaderSize(int version) {
- if (version == getVersion(1, 0)) {
- return Integer.BYTES * 8; // Header has 8 integers.
- }
- return Integer.BYTES * 10; // Default + VM DTBO (offset, size)
- }
-
- private static boolean hasVmDtbo(int version) {
- int major = getMajorVersion(version);
- int minor = getMinorVersion(version);
- return major > 1 || (major == 1 && minor >= 1);
+ private int getHeaderSize() {
+ // Header + (entry offset, entry, size) * mEntryCnt
+ return Integer.BYTES * (4 + mEntryCnt * 2);
}
private static int alignTo(int x, int size) {
return (x + size - 1) & ~(size - 1);
}
- private static int getVersion(int major, int minor) {
- return ((major & 0xFFFF) << 16) | (minor & 0xFFFF);
- }
-
private static int getMajorVersion(int version) {
return (version >> 16) & 0xFFFF;
}
@@ -160,6 +172,8 @@
@NonNull private final File mPvmfwBinFile;
@NonNull private final File mBccFile;
@Nullable private File mDebugPolicyFile;
+ @Nullable private File mVmDtboFile;
+ @Nullable private File mVmReferenceDtFile;
private int mVersion;
public Builder(@NonNull File pvmfwBinFile, @NonNull File bccFile) {
@@ -175,14 +189,32 @@
}
@NonNull
+ public Builder setVmDtbo(@Nullable File vmDtboFile) {
+ mVmDtboFile = vmDtboFile;
+ return this;
+ }
+
+ @NonNull
+ public Builder setVmReferenceDt(@Nullable File vmReferenceDtFile) {
+ mVmReferenceDtFile = vmReferenceDtFile;
+ return this;
+ }
+
+ @NonNull
public Builder setVersion(int major, int minor) {
- mVersion = getVersion(major, minor);
+ mVersion = makeVersion(major, minor);
return this;
}
@NonNull
public Pvmfw build() {
- return new Pvmfw(mPvmfwBinFile, mBccFile, mDebugPolicyFile, mVersion);
+ return new Pvmfw(
+ mPvmfwBinFile,
+ mBccFile,
+ mDebugPolicyFile,
+ mVmDtboFile,
+ mVmReferenceDtFile,
+ mVersion);
}
}
}
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/CustomPvmfwHostTestCaseBase.java b/tests/pvmfw/java/com/android/pvmfw/test/CustomPvmfwHostTestCaseBase.java
index d9d425a..a3216c2 100644
--- a/tests/pvmfw/java/com/android/pvmfw/test/CustomPvmfwHostTestCaseBase.java
+++ b/tests/pvmfw/java/com/android/pvmfw/test/CustomPvmfwHostTestCaseBase.java
@@ -19,6 +19,7 @@
import static com.android.tradefed.device.TestDevice.MicrodroidBuilder;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assume.assumeTrue;
@@ -26,16 +27,18 @@
import androidx.annotation.Nullable;
import com.android.microdroid.test.host.MicrodroidHostTestCaseBase;
+import com.android.microdroid.test.host.CommandRunner;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.device.TestDevice;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import org.junit.After;
import org.junit.Before;
import java.io.File;
-import java.util.Objects;
import java.util.Map;
/** Base class for testing custom pvmfw */
@@ -50,6 +53,9 @@
@NonNull
public static final String MICRODROID_CONFIG_PATH = "assets/microdroid/vm_config_apex.json";
+ @NonNull
+ public static final String VM_REFERENCE_DT_PATH = "/data/local/tmp/pvmfw/reference_dt.dtb";
+
@NonNull public static final String MICRODROID_LOG_PATH = TEST_ROOT + "log.txt";
public static final int BOOT_COMPLETE_TIMEOUT_MS = 30000; // 30 seconds
public static final int BOOT_FAILURE_WAIT_TIME_MS = 10000; // 10 seconds
@@ -60,17 +66,28 @@
@NonNull public static final String CUSTOM_PVMFW_IMG_PATH = TEST_ROOT + PVMFW_FILE_NAME;
@NonNull public static final String CUSTOM_PVMFW_IMG_PATH_PROP = "hypervisor.pvmfw.path";
- @Nullable private static File mPvmfwBinFileOnHost;
- @Nullable private static File mBccFileOnHost;
+ @NonNull private static final String DUMPSYS = "dumpsys";
- @Nullable private TestDevice mAndroidDevice;
+ @NonNull
+ private static final String DUMPSYS_MISSING_SERVICE_MSG_PREFIX = "Can't find service: ";
+
+ @NonNull
+ private static final String SECRET_KEEPER_AIDL =
+ "android.hardware.security.secretkeeper.ISecretkeeper/default";
+
+ @Nullable private File mPvmfwBinFileOnHost;
+ @Nullable private File mBccFileOnHost;
+ @Nullable private File mVmReferenceDtFile;
+ private boolean mSecretKeeperSupported;
+
+ @NonNull private TestDevice mAndroidDevice;
@Nullable private ITestDevice mMicrodroidDevice;
@Nullable private File mCustomPvmfwFileOnHost;
@Before
public void setUp() throws Exception {
- mAndroidDevice = (TestDevice) Objects.requireNonNull(getDevice());
+ mAndroidDevice = (TestDevice) getDevice();
// Check device capabilities
assumeDeviceIsCapable(mAndroidDevice);
@@ -78,12 +95,29 @@
"Skip if protected VMs are not supported",
mAndroidDevice.supportsMicrodroid(/* protectedVm= */ true));
- // tradefed copies the test artifacts under /tmp when running tests,
- // so we should *find* the artifacts with the file name.
- mPvmfwBinFileOnHost =
- getTestInformation().getDependencyFile(PVMFW_FILE_NAME, /* targetFirst= */ false);
- mBccFileOnHost =
- getTestInformation().getDependencyFile(BCC_FILE_NAME, /* targetFirst= */ false);
+ mPvmfwBinFileOnHost = findTestFile(PVMFW_FILE_NAME);
+ mBccFileOnHost = findTestFile(BCC_FILE_NAME);
+
+ // This is prepared by AndroidTest.xml
+ mVmReferenceDtFile = mAndroidDevice.pullFile(VM_REFERENCE_DT_PATH);
+
+ CommandRunner runner = new CommandRunner(mAndroidDevice);
+ CommandResult result = runner.runForResult(DUMPSYS, SECRET_KEEPER_AIDL);
+
+ // dumpsys prints 'Can't find service: ~' to stderr if secret keeper HAL is missing,
+ // but it doesn't return any error code for it.
+ // Read stderr to know whether secret keeper is supported, and stop test for any other case.
+ assertWithMessage("Failed to run " + DUMPSYS + ", result=" + result)
+ .that(result.getStatus() == CommandStatus.SUCCESS && result.getExitCode() == 0)
+ .isTrue();
+ if (result.getStderr() != null && !result.getStderr().trim().isEmpty()) {
+ assertWithMessage(
+ "Unexpected stderr from " + DUMPSYS + ", stderr=" + result.getStderr())
+ .that(result.getStderr().trim().startsWith(DUMPSYS_MISSING_SERVICE_MSG_PREFIX))
+ .isTrue();
+ } else {
+ mSecretKeeperSupported = true;
+ }
// Prepare for system properties for custom pvmfw.img.
// File will be prepared later in individual test and then pushed to device
@@ -100,15 +134,12 @@
@After
public void shutdown() throws Exception {
- if (!mAndroidDevice.supportsMicrodroid(/* protectedVm= */ true)) {
- return;
- }
- if (mMicrodroidDevice != null) {
- mAndroidDevice.shutdownMicrodroid(mMicrodroidDevice);
- mMicrodroidDevice = null;
- }
+ shutdownMicrodroid();
+
mAndroidDevice.uninstallPackage(PACKAGE_NAME);
+ FileUtil.deleteFile(mVmReferenceDtFile);
+
// Cleanup for custom pvmfw.img
setPropertyOrThrow(mAndroidDevice, CUSTOM_PVMFW_IMG_PATH_PROP, "");
FileUtil.deleteFile(mCustomPvmfwFileOnHost);
@@ -116,16 +147,30 @@
cleanUpVirtualizationTestSetup(mAndroidDevice);
}
+ /** Returns android device */
+ @NonNull
+ public TestDevice getAndroidDevice() {
+ return mAndroidDevice;
+ }
+
/** Returns pvmfw.bin file on host for building custom pvmfw with */
+ @NonNull
public File getPvmfwBinFile() {
return mPvmfwBinFileOnHost;
}
/** Returns BCC file on host for building custom pvmfw with */
+ @NonNull
public File getBccFile() {
return mBccFileOnHost;
}
+ /** Returns VM reference DT, generated from DUT, on host for building custom pvmfw with. */
+ @Nullable
+ public File getVmReferenceDtFile() {
+ return mVmReferenceDtFile;
+ }
+
/**
* Returns a custom pvmfw file.
*
@@ -133,11 +178,22 @@
* calling {@link #launchProtectedVmAndWaitForBootCompleted}, so virtualization manager can read
* the file path from sysprop and boot pVM with it.
*/
+ @NonNull
public File getCustomPvmfwFile() {
return mCustomPvmfwFileOnHost;
}
/**
+ * Returns whether a secretkeeper is supported.
+ *
+ * <p>If {@code true}, then VM reference DT must exist. (i.e. {@link #getVmReferenceDtFile} must
+ * exist {@code null}).
+ */
+ public boolean isSecretKeeperSupported() {
+ return mSecretKeeperSupported;
+ }
+
+ /**
* Launches protected VM with custom pvmfw ({@link #getCustomPvmfwFile}) and wait for boot
* completed. Throws exception when boot failed.
*/
@@ -162,4 +218,12 @@
assertThat(mMicrodroidDevice.enableAdbRoot()).isTrue();
return mMicrodroidDevice;
}
+
+ /** Shuts down microdroid if it's running */
+ public void shutdownMicrodroid() throws Exception {
+ if (mMicrodroidDevice != null) {
+ mAndroidDevice.shutdownMicrodroid(mMicrodroidDevice);
+ mMicrodroidDevice = null;
+ }
+ }
}
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java b/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
index 803405d..223f93f 100644
--- a/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
+++ b/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
@@ -192,10 +192,15 @@
getTestInformation()
.getDependencyFile(debugPolicyFileName, /* targetFirst= */ false);
- Pvmfw pvmfw =
+ Pvmfw.Builder builder =
new Pvmfw.Builder(getPvmfwBinFile(), getBccFile())
- .setDebugPolicyOverlay(mCustomDebugPolicyFileOnHost)
- .build();
+ .setDebugPolicyOverlay(mCustomDebugPolicyFileOnHost);
+ if (isSecretKeeperSupported()) {
+ builder.setVmReferenceDt(getVmReferenceDtFile());
+ } else {
+ builder.setVersion(1, 1);
+ }
+ Pvmfw pvmfw = builder.build();
pvmfw.serialize(getCustomPvmfwFile());
}
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
index b68316d..19334d6 100644
--- a/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
+++ b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
@@ -35,19 +35,31 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class PvmfwImgTest extends CustomPvmfwHostTestCaseBase {
@Test
- public void testConfigVersion1_0_boots() throws Exception {
- Pvmfw pvmfw = new Pvmfw.Builder(getPvmfwBinFile(), getBccFile()).setVersion(1, 0).build();
- pvmfw.serialize(getCustomPvmfwFile());
+ public void testPvmfw_beforeVmReferenceDt_whenSecretKeeperExists() throws Exception {
+ // VM reference DT is added since version 1.2
+ List<int[]> earlyVersions = Arrays.asList(new int[] {1, 0}, new int[] {1, 1});
+ Pvmfw.Builder builder = new Pvmfw.Builder(getPvmfwBinFile(), getBccFile());
- launchProtectedVmAndWaitForBootCompleted(BOOT_COMPLETE_TIMEOUT_MS);
- }
+ for (int[] pair : earlyVersions) {
+ int major = pair[0];
+ int minor = pair[1];
+ String version = "v" + major + "." + minor;
- @Test
- public void testConfigVersion1_1_boots() throws Exception {
- Pvmfw pvmfw = new Pvmfw.Builder(getPvmfwBinFile(), getBccFile()).setVersion(1, 1).build();
- pvmfw.serialize(getCustomPvmfwFile());
+ // Pvmfw config before v1.2 can't have secret keeper key in VM reference DT.
+ Pvmfw pvmfw = builder.setVersion(major, minor).build();
+ pvmfw.serialize(getCustomPvmfwFile());
- launchProtectedVmAndWaitForBootCompleted(BOOT_COMPLETE_TIMEOUT_MS);
+ if (isSecretKeeperSupported()) {
+ // If secret keeper is supported, we can't boot with early version
+ assertThrows(
+ "pvmfw shouldn't boot without VM reference DT, version=" + version,
+ DeviceRuntimeException.class,
+ () -> launchProtectedVmAndWaitForBootCompleted(BOOT_FAILURE_WAIT_TIME_MS));
+ } else {
+ launchProtectedVmAndWaitForBootCompleted(BOOT_COMPLETE_TIMEOUT_MS);
+ shutdownMicrodroid();
+ }
+ }
}
@Test
@@ -65,13 +77,21 @@
new int[] {0xFFFF, 1},
new int[] {0xFFFF, 0xFFFF});
- Pvmfw.Builder builder = new Pvmfw.Builder(getPvmfwBinFile(), getBccFile());
+ Pvmfw.Builder builder =
+ new Pvmfw.Builder(getPvmfwBinFile(), getBccFile())
+ .setVmReferenceDt(getVmReferenceDtFile());
for (int[] pair : invalid_versions) {
int major = pair[0];
int minor = pair[1];
String version = "v" + major + "." + minor;
+ if (Pvmfw.makeVersion(major, minor) >= Pvmfw.makeVersion(1, 2)
+ && getVmReferenceDtFile() == null) {
+ // VM reference DT is unavailable, so we can't even build Pvmfw.
+ continue;
+ }
+
Pvmfw pvmfw = builder.setVersion(major, minor).build();
pvmfw.serialize(getCustomPvmfwFile());
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/PvmfwTest.java b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwTest.java
new file mode 100644
index 0000000..bea72eb
--- /dev/null
+++ b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 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.
+ */
+
+package com.android.pvmfw.test;
+
+import static org.junit.Assert.assertThrows;
+
+import com.android.pvmfw.test.host.Pvmfw;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test test helper */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class PvmfwTest extends CustomPvmfwHostTestCaseBase {
+ @Test
+ public void testPvmfw_withConfig1_2_requiresReferenceDt() {
+ assertThrows(
+ "pvmfw config 1.2 must require VM reference DT",
+ NullPointerException.class,
+ () -> {
+ new Pvmfw.Builder(getPvmfwBinFile(), getBccFile()).setVersion(1, 2).build();
+ });
+ }
+
+ @Test
+ public void testPvmfw_before1_2_doesNotRequiresReferenceDt() {
+ new Pvmfw.Builder(getPvmfwBinFile(), getBccFile()).setVersion(1, 1).build();
+ }
+}
diff --git a/tests/pvmfw/tools/PvmfwTool.java b/tests/pvmfw/tools/PvmfwTool.java
index 62c641b..e150ec4 100644
--- a/tests/pvmfw/tools/PvmfwTool.java
+++ b/tests/pvmfw/tools/PvmfwTool.java
@@ -25,28 +25,41 @@
public class PvmfwTool {
public static void printUsage() {
System.out.println("pvmfw-tool: Appends pvmfw.bin and config payloads.");
- System.out.println("Requires BCC and optional debug policy dtbo files");
- System.out.println("");
- System.out.println("Usage: pvmfw-tool <out> <pvmfw.bin> <bcc.dat> [<dp.dtbo>]");
+ System.out.println(" Requires BCC and VM reference DT.");
+ System.out.println(" VM DTBO and Debug policy can optionally be specified");
+ System.out.println(
+ "Usage: pvmfw-tool <out> <pvmfw.bin> <bcc.dat> <VM reference DT> [VM DTBO] [debug"
+ + " policy]");
}
public static void main(String[] args) {
- if (args.length != 4 && args.length != 3) {
+ if (args.length < 3 || args.length > 6) {
printUsage();
System.exit(1);
}
File out = new File(args[0]);
- File pvmfw_bin = new File(args[1]);
- File bcc_dat = new File(args[2]);
+ File pvmfwBin = new File(args[1]);
+ File bccData = new File(args[2]);
+ File vmReferenceDt = new File(args[3]);
+
+ File vmDtbo = null;
+ File dp = null;
+ if (args.length > 4) {
+ vmDtbo = new File(args[4]);
+ }
+ if (args.length > 5) {
+ dp = new File(args[5]);
+ }
try {
- Pvmfw.Builder builder = new Pvmfw.Builder(pvmfw_bin, bcc_dat);
- if (args.length == 4) {
- File dtbo = new File(args[3]);
- builder.setDebugPolicyOverlay(dtbo);
- }
- builder.build().serialize(out);
+ Pvmfw pvmfw =
+ new Pvmfw.Builder(pvmfwBin, bccData)
+ .setVmReferenceDt(vmReferenceDt)
+ .setDebugPolicyOverlay(dp)
+ .setVmDtbo(vmDtbo)
+ .build();
+ pvmfw.serialize(out);
} catch (IOException e) {
e.printStackTrace();
printUsage();