test: load-address-relative-offset integration tests
Change-Id: If93a68dddffc8b2581d9da332c22714e59bbd39f
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/test/hftest/service_common.c b/test/hftest/service_common.c
index 2ec6e16..6ff2c71 100644
--- a/test/hftest/service_common.c
+++ b/test/hftest/service_common.c
@@ -7,12 +7,14 @@
*/
#include "hf/check.h"
+#include "hf/fdt.h"
#include "hf/fdt_handler.h"
#include "hf/ffa.h"
#include "hf/memiter.h"
#include "hf/mm.h"
#include "hf/std.h"
#include "hf/stdout.h"
+#include "hf/string.h"
#include "vmapi/hf/call.h"
@@ -109,6 +111,7 @@
struct string mem_region_node_name = STRING_INIT("memory-regions");
struct string dev_region_node_name = STRING_INIT("device-regions");
struct memiter uuid;
+ struct memiter description;
uint32_t uuid_word = 0;
uint16_t j = 0;
uint16_t i = 0;
@@ -177,6 +180,14 @@
cur_region->base_address =
ctx->partition_manifest.load_addr +
number;
+ cur_region->is_relative = true;
+ }
+
+ if (fdt_read_property(&ffa_node, "description",
+ &description)) {
+ EXPECT_EQ(string_init(&cur_region->description,
+ &description),
+ STRING_SUCCESS);
}
EXPECT_TRUE(fdt_read_number(&ffa_node, "attributes",
diff --git a/test/vmapi/primary_with_secondaries/boot.c b/test/vmapi/primary_with_secondaries/boot.c
index d2fc3f4..7eb4a54 100644
--- a/test/vmapi/primary_with_secondaries/boot.c
+++ b/test/vmapi/primary_with_secondaries/boot.c
@@ -7,6 +7,7 @@
*/
#include "hf/dlog.h"
+#include "hf/ffa.h"
#include "vmapi/hf/call.h"
@@ -73,3 +74,46 @@
EXPECT_FALSE(exception_received(&run_res, mb.recv));
}
+
+TEST_PRECONDITION(boot, memory_manifest_relative, service1_is_not_vm)
+{
+ struct mailbox_buffers mb = set_up_mailbox();
+ struct ffa_partition_info *service1_info = service1(mb.recv);
+ struct ffa_value run_res;
+
+ SERVICE_SELECT(service1_info->vm_id, "boot_memory_manifest_relative",
+ mb.send);
+ run_res = ffa_run(service1_info->vm_id, 0);
+
+ EXPECT_EQ(exception_received(&run_res, mb.recv), false);
+}
+
+TEST_PRECONDITION(boot, memory_manifest_relative_test_memory_ro,
+ service1_is_not_vm)
+{
+ struct mailbox_buffers mb = set_up_mailbox();
+ struct ffa_partition_info *service1_info = service1(mb.recv);
+ struct ffa_value run_res;
+
+ SERVICE_SELECT(service1_info->vm_id,
+ "boot_memory_manifest_relative_test_memory_ro", mb.send);
+ run_res = ffa_run(service1_info->vm_id, 0);
+
+ /* data abort exception expected due to accessing RO memory */
+ EXPECT_EQ(exception_received(&run_res, mb.recv), true);
+}
+
+TEST_PRECONDITION(boot, memory_manifest_relative_ro_secure_memory,
+ service1_is_not_vm)
+{
+ struct mailbox_buffers mb = set_up_mailbox();
+ struct ffa_partition_info *service1_info = service1(mb.recv);
+ struct ffa_value run_res;
+
+ SERVICE_SELECT(service1_info->vm_id,
+ "boot_memory_manifest_ro_secure_memory", mb.send);
+ run_res = ffa_run(service1_info->vm_id, 0);
+
+ /* data abort exception expected due to accessing RO memory */
+ EXPECT_EQ(exception_received(&run_res, mb.recv), true);
+}
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
index a76ec66..32f0102 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
@@ -14,7 +14,7 @@
/* Properties */
ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
- uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+ uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
execution-ctx-count = <8>;
exception-level = <2>; /* S-EL1 */
execution-state = <0>; /* AARCH64 */
@@ -37,25 +37,36 @@
compatible = "arm,ffa-manifest-memory-regions";
- test-memory {
+ test-memory-rw {
+ description = "test-memory-rw";
load-address-relative-offset = <0x300000>; /* effective address = 0x6780000 */
pages-count = <1>;
- attributes = <0x3>;
+ attributes = <0x3>; /* read-write */
+ };
+
+ test-memory-ro {
+ description = "test-memory-ro";
+ load-address-relative-offset = <0x400000>; /* effective address = 0x6780000 */
+ pages-count = <1>;
+ attributes = <0x1>; /* read-only */
};
secure-memory {
+ description = "secure-memory";
base-address = <0x00000000 0x7100000>;
pages-count = <1>;
attributes = <0x3>; /* read-write */
};
ro-secure-memory {
+ description = "ro-secure-memory";
base-address = <0x00000000 0x7200000>;
pages-count = <1>;
attributes = <0x1>; /* read-only */
};
ns-memory {
+ description = "ns-memory";
base-address = <0x00000000 0x9001F000>;
pages-count = <1>;
attributes = <0xb>; /* read-write and NS */
diff --git a/test/vmapi/primary_with_secondaries/services/boot.c b/test/vmapi/primary_with_secondaries/services/boot.c
index b474c25..710bbd9 100644
--- a/test/vmapi/primary_with_secondaries/services/boot.c
+++ b/test/vmapi/primary_with_secondaries/services/boot.c
@@ -169,3 +169,147 @@
}
ffa_yield();
}
+
+static void read_memory_region(const volatile struct memory_region* region)
+{
+ /* NOLINTNEXTLINE(performance-no-int-to-ptr) */
+ const volatile uint8_t* ptr = (volatile uint8_t*)region->base_address;
+ size_t page_count = region->page_count;
+ uint64_t sum = 0;
+
+ for (size_t i = 0; i < page_count * PAGE_SIZE; ++i) {
+ sum += ptr[i];
+ }
+
+ ASSERT_NE(sum, 0);
+}
+
+static void write_memory_region(struct memory_region* region)
+{
+ /* NOLINTNEXTLINE(performance-no-int-to-ptr) */
+ volatile uint8_t* ptr = (volatile uint8_t*)region->base_address;
+ size_t page_count = region->page_count;
+ uint8_t val;
+
+ for (size_t i = 0; i < page_count * PAGE_SIZE; ++i) {
+ val = ptr[i];
+ ptr[i] += 1;
+ ASSERT_EQ(ptr[i], val + 1);
+ }
+}
+
+/*
+ * Validate all memory regions provided to the SP.
+ */
+TEST_SERVICE(boot_memory_manifest_relative)
+{
+ struct hftest_context* ctx = hftest_get_context();
+ struct ffa_partition_manifest* manifest = &ctx->partition_manifest;
+ struct memory_region* mem_region;
+
+ if (!ctx->is_ffa_manifest_parsed) {
+ panic("This test requires the running partition to have "
+ "received and parsed its own FF-A manifest.\n");
+ }
+
+ exception_setup(NULL, exception_handler_yield_data_abort);
+
+ EXPECT_EQ(manifest->load_addr, 0x6480000);
+ EXPECT_EQ(manifest->mem_region_count, 5);
+
+ mem_region = &manifest->mem_regions[0];
+ EXPECT_STREQ(mem_region->description.data, "test-memory-rw");
+ EXPECT_EQ(mem_region->base_address, manifest->load_addr + 0x300000);
+ EXPECT_EQ(mem_region->is_relative, true);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x3); /* read-write */
+ write_memory_region(mem_region);
+
+ mem_region = &manifest->mem_regions[1];
+ EXPECT_STREQ(mem_region->description.data, "test-memory-ro");
+ EXPECT_EQ(mem_region->base_address, manifest->load_addr + 0x400000);
+ EXPECT_EQ(mem_region->is_relative, true);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x1); /* read-only */
+ read_memory_region(mem_region);
+
+ mem_region = &manifest->mem_regions[2];
+ EXPECT_STREQ(mem_region->description.data, "secure-memory");
+ EXPECT_EQ(mem_region->base_address, 0x7100000);
+ EXPECT_EQ(mem_region->is_relative, false);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x3); /* read-write */
+ write_memory_region(mem_region);
+
+ mem_region = &manifest->mem_regions[3];
+ EXPECT_STREQ(mem_region->description.data, "ro-secure-memory");
+ EXPECT_EQ(mem_region->base_address, 0x7200000);
+ EXPECT_EQ(mem_region->is_relative, false);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x1); /* read-only */
+ read_memory_region(mem_region);
+
+ ffa_yield();
+}
+
+/*
+ * Validate that attempting to write to "test-memory-ro" causes a
+ * fault because it is read-only.
+ */
+TEST_SERVICE(boot_memory_manifest_relative_test_memory_ro)
+{
+ struct hftest_context* ctx = hftest_get_context();
+ struct ffa_partition_manifest* manifest = &ctx->partition_manifest;
+ struct memory_region* mem_region;
+
+ if (!ctx->is_ffa_manifest_parsed) {
+ panic("This test requires the running partition to have "
+ "received and parsed its own FF-A manifest.\n");
+ }
+
+ exception_setup(NULL, exception_handler_yield_data_abort);
+
+ EXPECT_EQ(manifest->load_addr, 0x6480000);
+ EXPECT_EQ(manifest->mem_region_count, 5);
+
+ mem_region = &manifest->mem_regions[1];
+ EXPECT_STREQ(mem_region->description.data, "test-memory-ro");
+ EXPECT_EQ(mem_region->base_address, manifest->load_addr + 0x400000);
+ EXPECT_EQ(mem_region->is_relative, true);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x1); /* read-only */
+ write_memory_region(mem_region);
+
+ ffa_yield();
+}
+
+/*
+ * Validate that attempting to write to "ro-secure-memory" causes a
+ * fault because it is read-only.
+ */
+TEST_SERVICE(boot_memory_manifest_ro_secure_memory)
+{
+ struct hftest_context* ctx = hftest_get_context();
+ struct ffa_partition_manifest* manifest = &ctx->partition_manifest;
+ struct memory_region* mem_region;
+
+ if (!ctx->is_ffa_manifest_parsed) {
+ panic("This test requires the running partition to have "
+ "received and parsed its own FF-A manifest.\n");
+ }
+
+ exception_setup(NULL, exception_handler_yield_data_abort);
+
+ EXPECT_EQ(manifest->load_addr, 0x6480000);
+ EXPECT_EQ(manifest->mem_region_count, 5);
+
+ mem_region = &manifest->mem_regions[3];
+ EXPECT_STREQ(mem_region->description.data, "ro-secure-memory");
+ EXPECT_EQ(mem_region->base_address, 0x7200000);
+ EXPECT_EQ(mem_region->is_relative, false);
+ EXPECT_EQ(mem_region->page_count, 0x1);
+ EXPECT_EQ(mem_region->attributes, 0x1); /* read-only */
+ write_memory_region(mem_region);
+
+ ffa_yield();
+}