test(realm): testcase for RMI_RTT_SET_RIPAS reject
Add testcase for realm to call rsi_ipa_state_set,
host will reject and call RMI_RTT_SET_RIPAS
re-enter rec with response RSI_REJECT
Change-Id: I6809fdabba580b23269aedc2aa844b15fbcce981
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h
index 6f3f227..4f81042 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -411,6 +411,19 @@
}, 0x800, 0x1000);
};
+/* Whether Host has completed emulation for an Emulatable Data Abort */
+#define REC_ENTRY_FLAG_EMUL_MMIO (UL(1) << 0)
+
+/* Whether to inject a Synchronous External Abort into Realm */
+#define REC_ENTRY_FLAG_INJECT_SEA (UL(1) << 1)
+
+/* Whether to trap WFI/WFE execution by Realm */
+#define REC_ENTRY_FLAG_TRAP_WFI (UL(1) << 2)
+#define REC_ENTRY_FLAG_TRAP_WFE (UL(1) << 3)
+
+/* Host response to RIPAS change request */
+#define REC_ENTRY_FLAG_RIPAS_RESPONSE_REJECT (UL(1) << 4)
+
/*
* Structure contains data passed from the Host to the RMM on REC entry
*/
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index e674f46..57af48d 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -53,6 +53,7 @@
REALM_REQ_FPU_FILL_CMD,
REALM_REQ_FPU_CMP_CMD,
REALM_SET_RIPAS_CMD,
+ REALM_REJECT_SET_RIPAS_CMD,
REALM_SVE_RDVL,
REALM_SVE_ID_REGISTERS,
REALM_SVE_PROBE_VL,
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index 9b2be83..5c488ee 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -101,6 +101,34 @@
return true;
}
+bool test_realm_reject_set_ripas(void)
+{
+ u_register_t ret, base, new_base;
+ rsi_ripas_respose_type response;
+ rsi_ripas_type ripas;
+
+ base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+ ret = rsi_ipa_state_get(base, &ripas);
+ if (ret != RSI_SUCCESS || ripas != RSI_EMPTY) {
+ realm_printf("Wrong initial ripas=0x%lx\n", ripas);
+ return false;
+ }
+ ret = rsi_ipa_state_set(base, base + PAGE_SIZE, RSI_RAM,
+ RSI_NO_CHANGE_DESTROYED, &new_base, &response);
+ if (ret == RSI_SUCCESS && response == RSI_REJECT) {
+ realm_printf("rsi_ipa_state_set passed response = %d\n", response);
+ ret = rsi_ipa_state_get(base, &ripas);
+ if (ret == RSI_SUCCESS && ripas == RSI_EMPTY) {
+ return true;
+ } else {
+ realm_printf("rsi_ipa_state_get failed ripas = %d\n", ripas);
+ return false;
+ }
+ }
+ realm_printf("rsi_ipa_state_set failed ret=0x%lx, response = %d\n", ret, response);
+ return false;
+}
+
/*
* This is the entry function for Realm payload, it first requests the shared buffer
* IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
@@ -162,6 +190,9 @@
test_succeed = !fpu_state_compare(&rl_fpu_state_write,
&rl_fpu_state_read);
break;
+ case REALM_REJECT_SET_RIPAS_CMD:
+ test_succeed = test_realm_reject_set_ripas();
+ break;
case REALM_SET_RIPAS_CMD:
test_succeed = test_realm_set_ripas();
break;
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index 0fd65fd..1948c1f 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -513,3 +513,74 @@
page_free(base);
return host_call_result;
}
+
+/*
+ * Test set_ripas reject functionality in Realm
+ * Test allocates PAGE and passes to Realm
+ * Realm: verifies that initial RIPAS of page is EMPTY
+ * Realm: requests RIPAS Change to RAM
+ * Host: changes rejects RIPAS change and enters Realm
+ * Realm: verifies REJECT response
+ * Realm: verifies PAGE has RIPAS=EMPTY
+ */
+
+test_result_t host_realm_reject_set_ripas(void)
+{
+ bool ret1, ret2;
+ u_register_t ret, exit_reason;
+ unsigned int host_call_result = TEST_RESULT_FAIL;
+ struct realm realm;
+ struct rmi_rec_run *run;
+ u_register_t rec_flag[1] = {RMI_RUNNABLE}, base;
+
+ SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+ if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+ (u_register_t)PAGE_POOL_BASE,
+ (u_register_t)PAGE_POOL_MAX_SIZE,
+ 0UL, rec_flag, 1U)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (!host_create_shared_mem(&realm, NS_REALM_SHARED_MEM_BASE,
+ NS_REALM_SHARED_MEM_SIZE)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ base = (u_register_t)page_alloc(PAGE_SIZE);
+
+ ret = host_realm_map_protected_data(true, &realm, base, PAGE_SIZE, base);
+ if (ret != RMI_SUCCESS) {
+ ERROR("host_realm_map_protected_data failede\n");
+ goto destroy_realm;
+ }
+ host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+ ret1 = host_enter_realm_execute(&realm, REALM_REJECT_SET_RIPAS_CMD,
+ RMI_EXIT_RIPAS_CHANGE, 0U);
+
+ if (!ret1) {
+ ERROR("Rec did not request RIPAS change\n");
+ goto destroy_realm;
+ }
+ run = (struct rmi_rec_run *)realm.run[0];
+ if (run->exit.ripas_base != base) {
+ ERROR("Rec requested wrong exit.ripas_base\n");
+ goto destroy_realm;
+ }
+ run->entry.flags = REC_ENTRY_FLAG_RIPAS_RESPONSE_REJECT;
+ ret = host_realm_rec_enter(&realm, &exit_reason, &host_call_result, 0U);
+ if (ret != RMI_SUCCESS || exit_reason != RMI_EXIT_HOST_CALL) {
+ ERROR("Re-enter rec failed exit_reason=0x%lx", exit_reason);
+ }
+
+destroy_realm:
+ ret2 = host_destroy_realm(&realm);
+
+ if (!ret2) {
+ ERROR("%s(): destroy=%d\n",
+ __func__, ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ return host_call_result;
+}
+
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index bcc72ec..dbd9cd5 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -44,6 +44,8 @@
function="host_realm_fpu_access_in_rl_ns_se" />
<testcase name="Realm request set_ripas"
function="host_realm_set_ripas" />
+ <testcase name="Realm reject set_ripas"
+ function="host_realm_reject_set_ripas" />
<!-- Test case related to SVE support and SIMD state -->
<testcase name="Check RMI reports proper SVE VL"
function="host_check_rmi_reports_proper_sve_vl" />