feat(manifest): disallow overlap with `load-address`
Disallow overlaps between memory regions and `load-address`, unless the
memory region is relative.
Change-Id: I78a788925f97bdc056711b21371d63d8b8eb32d8
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/manifest_test.cc b/src/manifest_test.cc
index 18d6a38..8bcef30 100644
--- a/src/manifest_test.cc
+++ b/src/manifest_test.cc
@@ -444,6 +444,32 @@
return manifest_init(mm_stage1_locked, m, &it, ¶ms, &ppool);
}
+ enum manifest_return_code ffa_manifest_from_spkg(
+ struct_manifest **m, Partition_package *spkg)
+ {
+ struct memiter it;
+ struct mm_stage1_locked mm_stage1_locked;
+ struct boot_params params;
+
+ boot_params_init(¶ms, spkg);
+
+ /* clang-format off */
+ std::vector<char> core_dtb = ManifestDtBuilder()
+ .StartChild("hypervisor")
+ .Compatible()
+ .StartChild("vm1")
+ .DebugName("primary_vm")
+ .FfaPartition()
+ .LoadAddress((uint64_t)spkg)
+ .EndChild()
+ .EndChild()
+ .Build(true);
+ /* clang-format on */
+ memiter_init(&it, core_dtb.data(), core_dtb.size());
+
+ return manifest_init(mm_stage1_locked, m, &it, ¶ms, &ppool);
+ }
+
enum manifest_return_code ffa_manifest_from_vec(
struct_manifest **m, const std::vector<char> &vec)
{
@@ -1527,6 +1553,32 @@
.Label("rx")
.StartChild("rx")
.Description("rx-buffer")
+ .Property("load-address-relative-offset", "<0x0>")
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<1>")
+ .EndChild()
+ .Label("tx")
+ .StartChild("tx")
+ .Description("tx-buffer")
+ .Property("load-address-relative-offset", "<0x0>")
+ .Property("pages-count", "<2>")
+ .Property("attributes", "<3>")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
+ MANIFEST_ERROR_MEM_REGION_OVERLAP);
+ manifest_dealloc();
+
+ /* clang-format off */
+ dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("memory-regions")
+ .Compatible({ "arm,ffa-manifest-memory-regions" })
+ .Label("rx")
+ .StartChild("rx")
+ .Description("rx-buffer")
.Property("base-address", "<0x7300000>")
.Property("pages-count", "<2>")
.Property("attributes", "<1>")
@@ -1570,6 +1622,92 @@
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
MANIFEST_ERROR_MEM_REGION_OVERLAP);
manifest_dealloc();
+
+ /* clang-format off */
+ Partition_package spkg(dtb);
+ dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("memory-regions")
+ .Compatible({ "arm,ffa-manifest-memory-regions" })
+ .StartChild("test-memory")
+ .Description("test-memory")
+ .Integer64Property("base-address", (uint64_t)&spkg,true)
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<1>")
+ .EndChild()
+ .EndChild()
+ .Build(true);
+ /* clang-format on */
+ spkg.init(dtb);
+ ASSERT_EQ(ffa_manifest_from_spkg(&m, &spkg),
+ MANIFEST_ERROR_MEM_REGION_OVERLAP);
+ manifest_dealloc();
+}
+
+TEST_F(manifest, ffa_validate_mem_regions_overlapping_allowed)
+{
+ struct_manifest *m;
+ std::vector<char> dtb;
+
+ /*
+ * Mem regions are allowed to overlap with parent `load-address` if the
+ * `load-address-relative-offset` was specified.
+ */
+ /* clang-format off */
+ dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("memory-regions")
+ .Compatible({ "arm,ffa-manifest-memory-regions" })
+ .Label("rx")
+ .StartChild("rx")
+ .Description("rx-buffer")
+ .Property("load-address-relative-offset", "<0x1000>")
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<1>")
+ .EndChild()
+ .Label("tx")
+ .StartChild("tx")
+ .Description("tx-buffer")
+ .Property("base-address", "<0x7300000>")
+ .Property("pages-count", "<2>")
+ .Property("attributes", "<3>")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
+ ASSERT_EQ(m->vm[0].partition.mem_regions[0].is_relative, true);
+ ASSERT_EQ(m->vm[0].partition.mem_regions[0].base_address,
+ m->vm[0].partition.load_addr + 0x1000);
+ manifest_dealloc();
+
+ /* clang-format off */
+ dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("memory-regions")
+ .Compatible({ "arm,ffa-manifest-memory-regions" })
+ .Label("rx")
+ .StartChild("rx")
+ .Description("rx-buffer")
+ .Property("base-address", "<0x7300000>")
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<1>")
+ .EndChild()
+ .Label("tx")
+ .StartChild("tx")
+ .Description("tx-buffer")
+ .Property("load-address-relative-offset", "<0x1000>")
+ .Property("pages-count", "<2>")
+ .Property("attributes", "<3>")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
+ ASSERT_EQ(m->vm[0].partition.mem_regions[1].is_relative, true);
+ ASSERT_EQ(m->vm[0].partition.mem_regions[1].base_address,
+ m->vm[0].partition.load_addr + 0x1000);
+ manifest_dealloc();
}
TEST_F(manifest, ffa_validate_mem_regions_unaligned)