Merge changes from topic "rmm-eac5"

* changes:
  feat(rmm-eac5): update RSI_VERSION, RMI_VERSION
  feat(rmm) : add api for rec force exit
  test(rmm-eac4): add testcase for CPU_ON denied
diff --git a/Makefile b/Makefile
index 64bac58..58af796 100644
--- a/Makefile
+++ b/Makefile
@@ -121,6 +121,7 @@
 
 # Set flags for Realm Payload Tests
 ifeq (${ENABLE_REALM_PAYLOAD_TESTS},1)
+ARM_ARCH_MINOR := 5
 BRANCH_PROTECTION := 2
 endif
 
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 4972d6a..6b44d0a 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -294,7 +294,7 @@
 
 #define SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP()				\
 	do {									\
-		u_register_t retrmm;						\
+		u_register_t retrmm = 0U;					\
 										\
 		if (!get_armv9_2_feat_rme_support()) {				\
 			tftf_testcase_printf("FEAT_RME not supported\n");	\
@@ -302,7 +302,7 @@
 		}								\
 										\
 		host_rmi_init_cmp_result();					\
-		retrmm = host_rmi_version();					\
+		retrmm = host_rmi_version(RMI_ABI_VERSION_VAL);			\
 										\
 		VERBOSE("RMM version is: %lu.%lu\n",				\
 			RMI_ABI_VERSION_GET_MAJOR(retrmm),			\
diff --git a/include/runtime_services/host_realm_managment/host_realm_helper.h b/include/runtime_services/host_realm_managment/host_realm_helper.h
index b0a9e59..407c8e8 100644
--- a/include/runtime_services/host_realm_managment/host_realm_helper.h
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -21,6 +21,7 @@
 		u_register_t ns_shared_mem_adr,
 		u_register_t ns_shared_mem_size);
 bool host_destroy_realm(void);
+void host_rec_send_sgi(unsigned int sgi, unsigned int rec_num);
 bool host_enter_realm_execute(uint8_t cmd, struct realm **realm_ptr,
 		int test_exit_reason, unsigned int rec_num);
 test_result_t host_cmp_result(void);
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 842ccb5..5030c38 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -28,6 +28,10 @@
 
 #define RMI_ABI_VERSION_GET_MAJOR(_version)	(((_version) >> 16U) & 0x8FFF)
 #define RMI_ABI_VERSION_GET_MINOR(_version)	((_version) & 0xFFFF)
+#define RMI_ABI_VERSION_MAJOR			U(1)
+#define RMI_ABI_VERSION_MINOR			U(0)
+#define RMI_ABI_VERSION_VAL			((RMI_ABI_VERSION_MAJOR << 16U) | \
+						 RMI_ABI_VERSION_MINOR)
 
 #define __ALIGN_MASK(x, mask)		(((x) + (mask)) & ~(mask))
 #define __ALIGN(x, a)			__ALIGN_MASK(x, (typeof(x))(a) - 1U)
@@ -508,6 +512,7 @@
 	u_register_t run[MAX_REC_COUNT];
 	u_register_t rec_flag[MAX_REC_COUNT];
 	u_register_t mpidr[MAX_REC_COUNT];
+	u_register_t host_mpidr[MAX_REC_COUNT];
 	u_register_t num_aux;
 	u_register_t rmm_feat_reg0;
 	u_register_t ipa_ns_buffer;
@@ -521,7 +526,7 @@
 };
 
 /* RMI/SMC */
-u_register_t host_rmi_version(void);
+u_register_t host_rmi_version(u_register_t req_ver);
 u_register_t host_rmi_granule_delegate(u_register_t addr);
 u_register_t host_rmi_granule_undelegate(u_register_t addr);
 u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr);
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 c8f9238..b561fc5 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -41,6 +41,8 @@
  */
 enum realm_cmd {
 	REALM_SLEEP_CMD = 1U,
+	REALM_LOOP_CMD,
+	REALM_MULTIPLE_REC_PSCI_DENIED_CMD,
 	REALM_GET_RSI_VERSION,
 	REALM_PMU_CYCLE,
 	REALM_PMU_EVENT,
diff --git a/realm/include/realm_rsi.h b/realm/include/realm_rsi.h
index e9b6ce8..547db0d 100644
--- a/realm/include/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -26,7 +26,7 @@
  * The major version number of the RSI implementation.  Increase this whenever
  * the binary format or semantics of the SMC calls change.
  */
-#define RSI_ABI_VERSION_MAJOR		12U
+#define RSI_ABI_VERSION_MAJOR		1U
 
 /*
  * The minor version number of the RSI implementation.  Increase this when
@@ -94,7 +94,7 @@
 #define RSI_HOST_CALL		SMC_RSI_FID(9U)
 
 
-#define RSI_ABI_VERSION		SMC_RSI_FID(0U)
+#define RSI_VERSION		SMC_RSI_FID(0U)
 
 /*
  * arg0 == struct rsi_realm_config address
@@ -102,7 +102,7 @@
 #define RSI_REALM_CONFIG	SMC_RSI_FID(6U)
 
 /* This function return RSI_ABI_VERSION */
-u_register_t rsi_get_version(void);
+u_register_t rsi_get_version(u_register_t req_ver);
 
 /* This function will call the Host to request IPA of the NS shared buffer */
 u_register_t rsi_get_ns_buffer(void);
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 1351415..ac839ac 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -22,6 +22,7 @@
 bool test_realm_sve_fill_regs(void);
 bool test_realm_sve_cmp_regs(void);
 bool test_realm_sve_undef_abort(void);
+bool test_realm_multiple_rec_psci_denied_cmd(void);
 
 #endif /* REALM_TESTS_H */
 
diff --git a/realm/realm.mk b/realm/realm.mk
index debbda2..9b0a230 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -28,6 +28,7 @@
 	aarch64/realm_exceptions.S					\
 	realm_debug.c							\
 	realm_interrupt.c						\
+	realm_multiple_rec.c						\
 	realm_pauth.c							\
 	realm_payload_main.c						\
 	realm_pmuv3.c							\
diff --git a/realm/realm_multiple_rec.c b/realm/realm_multiple_rec.c
new file mode 100644
index 0000000..bc357bc
--- /dev/null
+++ b/realm/realm_multiple_rec.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <fpu.h>
+#include <host_realm_helper.h>
+#include <host_shared_data.h>
+#include <psci.h>
+#include "realm_def.h"
+#include <realm_rsi.h>
+#include <realm_tests.h>
+#include <realm_psci.h>
+#include <tftf_lib.h>
+
+#define CXT_ID_MAGIC 0x100
+static uint64_t is_secondary_cpu_booted;
+
+static void rec1_handler(u_register_t cxt_id)
+{
+	realm_printf("Realm: running on CPU = 0x%lx cxt_id= 0x%lx\n",
+			read_mpidr_el1() & MPID_MASK, cxt_id);
+	if (cxt_id < CXT_ID_MAGIC || cxt_id > CXT_ID_MAGIC + MAX_REC_COUNT) {
+		realm_printf("Realm: Wrong cxt_id\n");
+		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+	}
+	is_secondary_cpu_booted++;
+	realm_cpu_off();
+}
+
+static void rec2_handler(u_register_t cxt_id)
+{
+	rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+}
+
+bool test_realm_multiple_rec_psci_denied_cmd(void)
+{
+	u_register_t ret;
+
+	is_secondary_cpu_booted = 0U;
+	ret = realm_cpu_on(1U, (uintptr_t)rec1_handler, 0x100);
+	if (ret != PSCI_E_DENIED) {
+		return false;
+	}
+
+	if (is_secondary_cpu_booted != 0U) {
+		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+	}
+
+	ret = realm_psci_affinity_info(1U, MPIDR_AFFLVL0);
+	if (ret != PSCI_STATE_OFF) {
+		realm_printf("CPU 1 should have been off\n");
+		return false;
+	}
+
+	ret = realm_cpu_on(2U, (uintptr_t)rec2_handler, 0x102);
+	if (ret != PSCI_E_ALREADY_ON) {
+		realm_printf("CPU 2 should have been already on\n");
+		return false;
+	}
+	return true;
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index 43cbf2d..aaf7479 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -33,24 +33,32 @@
 	waitms(sleep);
 }
 
+static void realm_loop_cmd(void)
+{
+	while (true) {
+		waitms(500);
+	}
+}
+
 /*
  * This function requests RSI/ABI version from RMM.
  */
-static void realm_get_rsi_version(void)
+static bool realm_get_rsi_version(void)
 {
-	u_register_t version;
+	u_register_t version = 0U;
 
-	version = rsi_get_version();
+	version = rsi_get_version(RSI_ABI_VERSION_VAL);
 	if (version == (u_register_t)SMC_UNKNOWN) {
-		realm_printf("SMC_RSI_ABI_VERSION failed (%ld)", (long)version);
-		return;
+		realm_printf("SMC_RSI_ABI_VERSION failed\n");
+		return false;
 	}
 
-	realm_printf("RSI ABI version %u.%u (expected: %u.%u)",
+	realm_printf("RSI ABI version %u.%u (expected: %u.%u)\n",
 	RSI_ABI_VERSION_GET_MAJOR(version),
 	RSI_ABI_VERSION_GET_MINOR(version),
-	RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION),
-	RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION));
+	RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION_VAL),
+	RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION_VAL));
+	return true;
 }
 
 /*
@@ -74,6 +82,13 @@
 			realm_sleep_cmd();
 			test_succeed = true;
 			break;
+		case REALM_LOOP_CMD:
+			realm_loop_cmd();
+			test_succeed = true;
+			break;
+		case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
+			test_succeed = test_realm_multiple_rec_psci_denied_cmd();
+			break;
 		case REALM_PAUTH_SET_CMD:
 			test_succeed = test_realm_pauth_set_cmd();
 			break;
@@ -84,8 +99,7 @@
 			test_succeed = test_realm_pauth_fault();
 			break;
 		case REALM_GET_RSI_VERSION:
-			realm_get_rsi_version();
-			test_succeed = true;
+			test_succeed = realm_get_rsi_version();
 			break;
 		case REALM_PMU_CYCLE:
 			test_succeed = test_pmuv3_cycle_works_realm();
diff --git a/realm/realm_pmuv3.c b/realm/realm_pmuv3.c
index 862e93e..58c05f0 100644
--- a/realm/realm_pmuv3.c
+++ b/realm/realm_pmuv3.c
@@ -227,7 +227,7 @@
 	read_all_pmu_configs(pmu_cfg_start);
 
 	/* Give RMM a chance to scramble everything */
-	(void)rsi_get_version();
+	(void)rsi_get_version(RSI_ABI_VERSION_VAL);
 
 	/* Get after reading */
 	read_all_counters(ctr_end, impl_ev_ctrs);
diff --git a/realm/realm_rsi.c b/realm/realm_rsi.c
index 586d4d2..d82aa6f 100644
--- a/realm/realm_rsi.c
+++ b/realm/realm_rsi.c
@@ -14,14 +14,18 @@
 static struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
 
 /* This function return RSI_ABI_VERSION */
-u_register_t rsi_get_version(void)
+u_register_t rsi_get_version(u_register_t req_ver)
 {
 	smc_ret_values res = {};
 
 	res = tftf_smc(&(smc_args)
-		{RSI_ABI_VERSION, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+		{RSI_VERSION, req_ver, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
 
-	return res.ret0;
+	if (res.ret0 == SMC_UNKNOWN) {
+		return SMC_UNKNOWN;
+	}
+	/* Return lower version. */
+	return res.ret1;
 }
 
 /* This function will call the Host to request IPA of the NS shared buffer */
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
index 51b058c..a3a07db 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -15,9 +15,11 @@
 #include <host_realm_mem_layout.h>
 #include <host_realm_rmi.h>
 #include <host_shared_data.h>
+#include <platform.h>
 #include <plat_topology.h>
 #include <power_management.h>
 #include <realm_def.h>
+#include <sgi.h>
 #include <test_helpers.h>
 #include <xlat_tables_v2.h>
 
@@ -336,3 +338,26 @@
 	return TEST_RESULT_FAIL;
 }
 
+/*
+ * Returns Host core position for specified Rec
+ * Host mpidr is saved on every rec enter
+ */
+static unsigned int host_realm_find_core_pos_by_rec(unsigned int rec_num)
+{
+	if (rec_num < MAX_REC_COUNT && realm.run[rec_num] != 0U) {
+		return platform_get_core_pos(realm.host_mpidr[rec_num]);
+	}
+	return (unsigned int)-1;
+}
+
+/*
+ * Send SGI on core running specified Rec
+ * API can be used to forcefully exit from Realm
+ */
+void host_rec_send_sgi(unsigned int sgi, unsigned int rec_num)
+{
+	unsigned int core_pos = host_realm_find_core_pos_by_rec(rec_num);
+	if (core_pos < PLATFORM_CORE_COUNT) {
+		tftf_send_sgi(sgi, core_pos);
+	}
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
index 47713d5..8d9e8e9 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -716,9 +716,16 @@
 	return host_rmi_handler(&(smc_args) {RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0;
 }
 
-u_register_t host_rmi_version(void)
+u_register_t host_rmi_version(u_register_t requested_ver)
 {
-	return host_rmi_handler(&(smc_args) {RMI_VERSION}, 1U).ret0;
+	smc_ret_values ret;
+
+	ret = host_rmi_handler(&(smc_args) {RMI_VERSION, requested_ver}, 2U);
+	if (ret.ret0 == (u_register_t)SMC_UNKNOWN) {
+		return SMC_UNKNOWN;
+	}
+	/* Return lower version. */
+	return ret.ret1;
 }
 
 u_register_t host_realm_create(struct realm *realm)
@@ -1231,6 +1238,7 @@
 	}
 
 	run = (struct rmi_rec_run *)realm->run[rec_num];
+	realm->host_mpidr[rec_num] = read_mpidr_el1();
 	do {
 		re_enter_rec = false;
 		ret = host_rmi_handler(&(smc_args) {RMI_REC_ENTER,
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
index 77d2db0..ce604c0 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
@@ -70,7 +70,7 @@
  */
 test_result_t host_realm_version_single_cpu(void)
 {
-	u_register_t retrmm;
+	u_register_t retrmm = 0U;
 
 	if (get_armv9_2_feat_rme_support() == 0U) {
 		return TEST_RESULT_SKIPPED;
@@ -78,11 +78,13 @@
 
 	host_rmi_init_cmp_result();
 
-	retrmm = host_rmi_version();
+	retrmm = host_rmi_version(RMI_ABI_VERSION_VAL);
 
-	tftf_testcase_printf("RMM version is: %lu.%lu\n",
+	tftf_testcase_printf("RMM version is: %lu.%lu (expected: %u.%u)\n",
 			RMI_ABI_VERSION_GET_MAJOR(retrmm),
-			RMI_ABI_VERSION_GET_MINOR(retrmm));
+			RMI_ABI_VERSION_GET_MINOR(retrmm),
+			RMI_ABI_VERSION_GET_MAJOR(RMI_ABI_VERSION_VAL),
+			RMI_ABI_VERSION_GET_MINOR(RMI_ABI_VERSION_VAL));
 
 	return host_cmp_result();
 }
@@ -173,11 +175,11 @@
 
 static test_result_t host_realm_multi_cpu_payload_test(void)
 {
-	u_register_t retrmm;
+	u_register_t retrmm = 0U;
 
 	host_rmi_init_cmp_result();
 
-	retrmm = host_rmi_version();
+	retrmm = host_rmi_version(RMI_ABI_VERSION_VAL);
 
 	tftf_testcase_printf("Multi CPU RMM version on CPU %llx is: %lu.%lu\n",
 			(long long)read_mpidr_el1() & MPID_MASK, RMI_ABI_VERSION_GET_MAJOR(retrmm),
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
index bd120ca..916e848 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
@@ -5,9 +5,13 @@
  */
 
 #include <stdlib.h>
+#include <drivers/arm/arm_gic.h>
 #include <debug.h>
+#include <platform.h>
+#include <plat_topology.h>
 #include <power_management.h>
 #include <psci.h>
+#include <sgi.h>
 #include <test_helpers.h>
 
 #include <host_realm_helper.h>
@@ -15,6 +19,7 @@
 #include <host_realm_pmu.h>
 #include <host_shared_data.h>
 
+static uint64_t is_secondary_cpu_on;
 /*
  * Test tries to create max Rec
  * Enters all Rec from single CPU
@@ -59,3 +64,221 @@
 
 	return TEST_RESULT_SUCCESS;
 }
+
+/*
+ * Test creates 3 Rec
+ * Rec0 requests CPU ON for rec 1
+ * Host denies CPU On for rec 1
+ * Host tried to enter rec 1 and fails
+ * Host re-enters rec 0
+ * Rec 0 checks CPU ON is denied
+ * Rec0 requests CPU ON for rec 2
+ * Host denies CPU On which should fail as rec is runnable
+ * Host allows CPU ON and re-enters rec 0
+ * Rec 0 checks return already_on
+ */
+test_result_t host_realm_multi_rec_psci_denied(void)
+{
+	struct realm *realm_ptr;
+	bool ret1, ret2;
+	u_register_t ret;
+	unsigned int host_call_result;
+	u_register_t exit_reason;
+	unsigned int rec_num;
+	struct rmi_rec_run *run;
+	/* Create 3 rec Rec 0 and 2 are runnable, Rec 1 in not runnable */
+	u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_NOT_RUNNABLE, RMI_RUNNABLE};
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+			(u_register_t)PAGE_POOL_BASE,
+			(u_register_t)(PAGE_POOL_MAX_SIZE +
+			NS_REALM_SHARED_MEM_SIZE),
+			(u_register_t)PAGE_POOL_MAX_SIZE,
+			0UL, rec_flag, 3U)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	ret1 = host_enter_realm_execute(REALM_MULTIPLE_REC_PSCI_DENIED_CMD, &realm_ptr,
+			RMI_EXIT_PSCI, 0U);
+	run = (struct rmi_rec_run *)realm_ptr->run[0];
+
+	if (run->exit.gprs[0] != SMC_PSCI_CPU_ON_AARCH64) {
+		ERROR("Host did not receive CPU ON request\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+	rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], realm_ptr);
+	if (rec_num != 1U) {
+		ERROR("Invalid mpidr requested\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+	INFO("Requesting PSCI Complete Status Denied REC %d\n", rec_num);
+	ret = host_rmi_psci_complete(realm_ptr->rec[0], realm_ptr->rec[rec_num],
+			(unsigned long)PSCI_E_DENIED);
+	if (ret != RMI_SUCCESS) {
+		ERROR("host_rmi_psci_complete failed\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+
+	/* Enter rec1, should fail */
+	ret = host_realm_rec_enter(realm_ptr, &exit_reason, &host_call_result, 1U);
+	if (ret == RMI_SUCCESS) {
+		ERROR("Rec1 enter should have failed\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+	ret = host_realm_rec_enter(realm_ptr, &exit_reason, &host_call_result, 0U);
+
+	if (run->exit.gprs[0] != SMC_PSCI_AFFINITY_INFO_AARCH64) {
+		ERROR("Host did not receive PSCI_AFFINITY_INFO request\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+	rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], realm_ptr);
+	if (rec_num != 1U) {
+		ERROR("Invalid mpidr requested\n");
+		goto destroy_realm;
+	}
+
+	INFO("Requesting PSCI Complete Affinity Info REC %d\n", rec_num);
+	ret = host_rmi_psci_complete(realm_ptr->rec[0], realm_ptr->rec[rec_num],
+			(unsigned long)PSCI_E_SUCCESS);
+	if (ret != RMI_SUCCESS) {
+		ERROR("host_rmi_psci_complete failed\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+
+	/* Re-enter REC0 complete PSCI_AFFINITY_INFO */
+	ret = host_realm_rec_enter(realm_ptr, &exit_reason, &host_call_result, 0U);
+
+
+	if (run->exit.gprs[0] != SMC_PSCI_CPU_ON_AARCH64) {
+		ERROR("Host did not receive CPU ON request\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+	rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], realm_ptr);
+	if (rec_num != 2U) {
+		ERROR("Invalid mpidr requested\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+
+	INFO("Requesting PSCI Complete Status Denied REC %d\n", rec_num);
+	/* PSCI_DENIED should fail as rec2 is RMI_RUNNABLE */
+	ret = host_rmi_psci_complete(realm_ptr->rec[0], realm_ptr->rec[rec_num],
+			(unsigned long)PSCI_E_DENIED);
+	if (ret == RMI_SUCCESS) {
+		ret1 = false;
+		ERROR("host_rmi_psci_complete should have failed\n");
+		goto destroy_realm;
+	}
+
+	ret = host_realm_rec_enter(realm_ptr, &exit_reason, &host_call_result, 0U);
+	if (ret != RMI_SUCCESS) {
+		ERROR("Rec0 re-enter failed\n");
+		ret1 = false;
+		goto destroy_realm;
+	}
+
+destroy_realm:
+	ret2 = host_destroy_realm();
+
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+}
+
+/* Lock used to avoid concurrent accesses to the secondary_cpu_on counter */
+spinlock_t secondary_cpu_lock;
+
+static test_result_t cpu_on_handler2(void)
+{
+	bool ret;
+
+	spin_lock(&secondary_cpu_lock);
+	is_secondary_cpu_on++;
+	spin_unlock(&secondary_cpu_lock);
+
+	ret = host_enter_realm_execute(REALM_LOOP_CMD, NULL, RMI_EXIT_IRQ, is_secondary_cpu_on);
+	if (!ret) {
+		return TEST_RESULT_FAIL;
+	}
+	return TEST_RESULT_SUCCESS;
+}
+
+test_result_t host_realm_multi_rec_exit_irq(void)
+{
+	bool ret1, ret2;
+	unsigned int rec_count = MAX_REC_COUNT;
+	u_register_t other_mpidr, my_mpidr, ret;
+	int cpu_node;
+	u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
+		RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
+		RMI_RUNNABLE};
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+	SKIP_TEST_IF_LESS_THAN_N_CPUS(rec_count);
+
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+			(u_register_t)PAGE_POOL_BASE,
+			(u_register_t)(PAGE_POOL_MAX_SIZE +
+			NS_REALM_SHARED_MEM_SIZE),
+			(u_register_t)PAGE_POOL_MAX_SIZE,
+			0UL, rec_flag, rec_count)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	is_secondary_cpu_on = 0U;
+	my_mpidr = read_mpidr_el1() & MPID_MASK;
+	ret1 = host_enter_realm_execute(REALM_GET_RSI_VERSION, NULL, RMI_EXIT_HOST_CALL, 0U);
+	for_each_cpu(cpu_node) {
+		other_mpidr = tftf_get_mpidr_from_node(cpu_node);
+		if (other_mpidr == my_mpidr) {
+			continue;
+		}
+		/* Power on the other CPU */
+		ret = tftf_try_cpu_on(other_mpidr, (uintptr_t)cpu_on_handler2, 0);
+		if (ret != PSCI_E_SUCCESS) {
+			goto destroy_realm;
+		}
+	}
+
+	INFO("Wait for all CPU to come up\n");
+	while (is_secondary_cpu_on != (rec_count - 1U)) {
+		waitms(100U);
+	}
+
+destroy_realm:
+	tftf_irq_enable(IRQ_NS_SGI_7, GIC_HIGHEST_NS_PRIORITY);
+	for (unsigned int i = 1U; i < rec_count; i++) {
+		INFO("Raising NS IRQ for rec %d\n", i);
+		host_rec_send_sgi(IRQ_NS_SGI_7, i);
+	}
+	tftf_irq_disable(IRQ_NS_SGI_7);
+	ret2 = host_destroy_realm();
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+}
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 0732605..48b3e24 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
@@ -61,6 +61,41 @@
 }
 
 /*
+ * @Test_Aim@ Test realm payload creation and execution
+ */
+test_result_t host_test_realm_rsi_version(void)
+{
+	bool ret1, ret2;
+	u_register_t rec_flag[] = {RMI_RUNNABLE};
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+			(u_register_t)PAGE_POOL_BASE,
+			(u_register_t)(PAGE_POOL_MAX_SIZE +
+			NS_REALM_SHARED_MEM_SIZE),
+			(u_register_t)PAGE_POOL_MAX_SIZE,
+			0UL, rec_flag, 1U)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	ret1 = host_enter_realm_execute(REALM_GET_RSI_VERSION, NULL, RMI_EXIT_HOST_CALL, 0U);
+	ret2 = host_destroy_realm();
+
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+}
+
+/*
  * @Test_Aim@ Test PAuth in realm
  */
 test_result_t host_realm_enable_pauth(void)
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 10cc04b..cf707a5 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -12,6 +12,12 @@
 	  function="host_test_realm_create_enter" />
 	  <testcase name="Realm payload multi rec single cpu"
 	  function="host_realm_multi_rec_single_cpu" />
+	  <testcase name="Realm payload multi rec psci denied"
+	  function="host_realm_multi_rec_psci_denied" />
+	  <testcase name="Realm payload multi rec force exit on NS IRQ"
+	  function="host_realm_multi_rec_exit_irq" />
+	  <testcase name="Realm EL1 creation and RSI version"
+	  function="host_test_realm_rsi_version" />
 	  <testcase name="Realm payload boot"
 	  function="host_realm_version_single_cpu" />
 	  <testcase name="Realm payload multi CPU request"