feat(interrupts): ns interrupt action in manifest
Each SP specifies the action it supports in response to a
non secure interrupt triggering in secure world through its
manifest.
Possible actions are:
NS_ACTION_QUEUED
NS_ACTION_ME
NS_ACTION_SIGNALED
Change-Id: I6a6249038e3e28cc508f62cd6a47de8f65cd60d6
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 38bce30..ef39ce4 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -829,7 +829,7 @@
bool plat_ffa_vm_managed_exit_supported(struct vm *vm)
{
- return vm->managed_exit;
+ return (vm->ns_interrupts_action == NS_ACTION_ME);
}
struct vm_locked plat_ffa_vm_find_locked(ffa_vm_id_t vm_id)
diff --git a/src/load.c b/src/load.c
index 9c6ec61..db4de88 100644
--- a/src/load.c
+++ b/src/load.c
@@ -204,8 +204,8 @@
vm_locked.vm->messaging_method =
manifest_vm->partition.messaging_method;
- vm_locked.vm->managed_exit =
- manifest_vm->partition.managed_exit;
+ vm_locked.vm->ns_interrupts_action =
+ manifest_vm->partition.ns_interrupts_action;
vm_locked.vm->notifications.enabled =
manifest_vm->partition.notification_support;
diff --git a/src/manifest.c b/src/manifest.c
index 1108c93..b6c6e9a 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -785,6 +785,7 @@
struct string mem_region_node_name = STRING_INIT("memory-regions");
struct string dev_region_node_name = STRING_INIT("device-regions");
struct string boot_info_node_name = STRING_INIT("boot-info");
+ bool managed_exit_field_present = false;
if (!fdt_find_node(fdt, "/", &root)) {
return MANIFEST_ERROR_NO_ROOT_NODE;
@@ -870,9 +871,45 @@
(uint8_t *)&vm->partition.messaging_method));
dlog_verbose(" Messaging method %u\n", vm->partition.messaging_method);
- TRY(read_bool(&root, "managed-exit", &vm->partition.managed_exit));
- if (vm->partition.managed_exit) {
- dlog_verbose(" Managed Exit Supported\n");
+ TRY(read_bool(&root, "managed-exit", &managed_exit_field_present));
+
+ TRY(read_optional_uint8(
+ &root, "ns-interrupts-action", NS_ACTION_SIGNALED,
+ (uint8_t *)&vm->partition.ns_interrupts_action));
+
+ /*
+ * An SP manifest can specify one of the fields listed below:
+ * `managed-exit`: Introduced in FF-A v1.0 spec.
+ * `ns-interrupts-action`: Introduced in FF-A v1.1 EAC0 spec.
+ * If both are missing from the manifest, the default response is
+ * NS_ACTION_SIGNALED.
+ */
+ if (managed_exit_field_present) {
+ vm->partition.ns_interrupts_action = NS_ACTION_ME;
+ }
+
+ if (vm->partition.ns_interrupts_action != NS_ACTION_QUEUED &&
+ vm->partition.ns_interrupts_action != NS_ACTION_ME &&
+ vm->partition.ns_interrupts_action != NS_ACTION_SIGNALED) {
+ return MANIFEST_ILLEGAL_NS_ACTION;
+ }
+
+ dlog_verbose(
+ "NS Interrupts %s\n",
+ (vm->partition.ns_interrupts_action == NS_ACTION_QUEUED)
+ ? "Queued"
+ : (vm->partition.ns_interrupts_action == NS_ACTION_SIGNALED)
+ ? "Signaled"
+ : "Managed exit");
+
+ if (vm->partition.ns_interrupts_action == NS_ACTION_ME) {
+ /* Managed exit only supported by S_EL1 partitions. */
+ if (vm->partition.run_time_el != S_EL1) {
+ dlog_error(
+ "Managed exit cannot be supported by this "
+ "partition\n");
+ return MANIFEST_ILLEGAL_NS_ACTION;
+ }
}
TRY(read_bool(&root, "notification-support",
@@ -1139,6 +1176,9 @@
return "Arguments-list node should have at least one argument";
case MANIFEST_ERROR_INTERRUPT_ID_REPEATED:
return "Interrupt ID already assigned to another endpoint";
+ case MANIFEST_ILLEGAL_NS_ACTION:
+ return "Illegal value specidied for the field: Action in "
+ "response to NS Interrupt";
}
panic("Unexpected manifest return code.");
diff --git a/src/manifest_test.cc b/src/manifest_test.cc
index a917fb4..0a71f8b 100644
--- a/src/manifest_test.cc
+++ b/src/manifest_test.cc
@@ -243,7 +243,7 @@
Property("xlat-granule", "<0>");
Property("boot-order", "<0>");
Property("messaging-method", "<4>");
- BooleanProperty("managed-exit");
+ Property("ns-interrupts-action", "<1>");
return *this;
}
@@ -738,6 +738,7 @@
.Property("entrypoint-offset", "<0x00002000>")
.Property("xlat-granule", "<0>")
.Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<1>")
.Build();
/* clang-format on */
@@ -781,6 +782,7 @@
.Property("xlat-granule", "<0>")
.Property("boot-order", "<0>")
.Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<1>")
.Build();
/* clang-format on */
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
@@ -799,6 +801,7 @@
.Property("xlat-granule", "<3>")
.Property("boot-order", "<0>")
.Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<1>")
.Build();
/* clang-format on */
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
@@ -817,6 +820,7 @@
.Property("xlat-granule", "<0>")
.Property("boot-order", "<0>")
.Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<0>")
.Build();
/* clang-format on */
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
@@ -835,6 +839,7 @@
.Property("xlat-granule", "<0>")
.Property("boot-order", "<0>")
.Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<0>")
.Build();
/* clang-format on */
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
@@ -853,10 +858,29 @@
.Property("xlat-granule", "<0>")
.Property("boot-order", "<0>")
.Property("messaging-method", "<16>")
+ .Property("ns-interrupts-action", "<0>")
.Build();
/* clang-format on */
ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
MANIFEST_ERROR_NOT_COMPATIBLE);
+
+ /* Incompatible NS interrupt action */
+ /* clang-format off */
+ dtb = ManifestDtBuilder()
+ .Compatible({ "arm,ffa-manifest-1.0" })
+ .Property("ffa-version", "<0x10000>")
+ .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
+ .Property("execution-ctx-count", "<1>")
+ .Property("exception-level", "<2>")
+ .Property("execution-state", "<0>")
+ .Property("entrypoint-offset", "<0x00002000>")
+ .Property("xlat-granule", "<0>")
+ .Property("boot-order", "<0>")
+ .Property("messaging-method", "<1>")
+ .Property("ns-interrupts-action", "<4>")
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_ILLEGAL_NS_ACTION);
}
TEST_F(manifest, ffa_validate_rxtx_info)
@@ -1307,7 +1331,7 @@
ASSERT_EQ(m.vm[0].partition.boot_order, 0);
ASSERT_EQ(m.vm[0].partition.messaging_method,
FFA_PARTITION_INDIRECT_MSG);
- ASSERT_EQ(m.vm[0].partition.managed_exit, true);
+ ASSERT_EQ(m.vm[0].partition.ns_interrupts_action, NS_ACTION_ME);
ASSERT_EQ(m.vm[0].partition.mem_regions[0].base_address, 0x7100000);
ASSERT_EQ(m.vm[0].partition.mem_regions[0].page_count, 4);
ASSERT_EQ(m.vm[0].partition.mem_regions[0].attributes, 3);
diff --git a/src/vcpu.c b/src/vcpu.c
index cb7bcca..1f154a8 100644
--- a/src/vcpu.c
+++ b/src/vcpu.c
@@ -65,6 +65,7 @@
vcpu->vm = vm;
vcpu->state = VCPU_STATE_OFF;
vcpu->direct_request_origin_vm_id = HF_INVALID_VM_ID;
+ vcpu->present_action_ns_interrupts = NS_ACTION_INVALID;
}
/**