test(realm): add testcase for REC exit due to Data/Instr abort

Add testcase to cause instruction or data abort in Realm by
accessing addr with
* HIPAS=UNASSIGNED and RIPAS=DESTROYED
* HIPAS=ASSIGNED and RIPAS=DESTROYED
* HIPAS=UNASSIGNED and RIPAS=RAM
Verify rec exit due to abort

Change-Id: Ic04c0ddaf1b18ec0cfd71c28753c4ed7298302da
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 88c873c..653dfd9 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -828,8 +828,28 @@
 #define EC_SERROR			U(0x2f)
 /* Data Fault Status code, not all error codes listed */
 #define ISS_DFSC_MASK			U(0x3f)
+#define DFSC_L0_TRANS_FAULT		U(4)
+#define DFSC_L1_TRANS_FAULT		U(5)
+#define DFSC_L2_TRANS_FAULT		U(6)
+#define DFSC_L3_TRANS_FAULT		U(7)
+#define DFSC_L0_SEA			U(0x14)
+#define DFSC_L1_SEA			U(0x15)
+#define DFSC_L2_SEA			U(0x16)
+#define DFSC_L3_SEA			U(0x17)
 #define DFSC_EXT_DABORT			U(0x10)
 #define DFSC_GPF_DABORT			U(0x28)
+
+/* Instr Fault Status code, not all error codes listed */
+#define ISS_IFSC_MASK			U(0x3f)
+#define IFSC_L0_TRANS_FAULT		U(4)
+#define IFSC_L1_TRANS_FAULT		U(5)
+#define IFSC_L2_TRANS_FAULT		U(6)
+#define IFSC_L3_TRANS_FAULT		U(7)
+#define IFSC_L0_SEA			U(0x24)
+#define IFSC_L1_SEA			U(0x25)
+#define IFSC_L2_SEA			U(0x26)
+#define IFSC_L3_SEA			U(0x27)
+
 /* ISS encoding an exception from HVC or SVC instruction execution */
 #define ISS_HVC_SMC_IMM16_MASK		U(0xffff)
 
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 4f81042..3159ad4 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -549,37 +549,64 @@
 u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr);
 u_register_t host_rmi_realm_destroy(u_register_t rd);
 u_register_t host_rmi_features(u_register_t index, u_register_t *features);
+u_register_t host_rmi_data_destroy(u_register_t rd,
+				   u_register_t map_addr,
+				   u_register_t *data,
+				   u_register_t *top);
+u_register_t host_rmi_rtt_readentry(u_register_t rd,
+				    u_register_t map_addr,
+				    u_register_t level,
+				    struct rtt_entry *rtt);
+u_register_t host_rmi_rtt_destroy(u_register_t rd,
+				  u_register_t map_addr,
+				  u_register_t level,
+				  u_register_t *rtt,
+				  u_register_t *top);
+u_register_t host_rmi_rtt_init_ripas(u_register_t rd,
+				   u_register_t start,
+				   u_register_t end,
+				   u_register_t *top);
+u_register_t host_rmi_create_rtt_levels(struct realm *realm,
+					u_register_t map_addr,
+					u_register_t level,
+					u_register_t max_level);
+u_register_t host_rmi_rtt_unmap_unprotected(u_register_t rd,
+					    u_register_t map_addr,
+					    u_register_t level,
+					    u_register_t *top);
+u_register_t host_rmi_rtt_set_ripas(u_register_t rd,
+				    u_register_t rec,
+				    u_register_t start,
+				    u_register_t end,
+				    u_register_t *top);
+u_register_t host_rmi_psci_complete(u_register_t calling_rec, u_register_t target_rec,
+				    unsigned long status);
+void host_rmi_init_cmp_result(void);
+bool host_rmi_get_cmp_result(void);
 
 /* Realm management */
 u_register_t host_realm_create(struct realm *realm);
 u_register_t host_realm_map_payload_image(struct realm *realm,
 					  u_register_t realm_payload_adr);
 u_register_t host_realm_map_ns_shared(struct realm *realm,
-					u_register_t ns_shared_mem_adr,
-					u_register_t ns_shared_mem_size);
+				      u_register_t ns_shared_mem_adr,
+				      u_register_t ns_shared_mem_size);
 u_register_t host_realm_rec_create(struct realm *realm);
 unsigned int host_realm_find_rec_by_mpidr(unsigned int mpidr, struct realm *realm);
 u_register_t host_realm_activate(struct realm *realm);
 u_register_t host_realm_destroy(struct realm *realm);
 u_register_t host_realm_rec_enter(struct realm *realm,
-					u_register_t *exit_reason,
-					unsigned int *host_call_result,
-					unsigned int rec_num);
+				  u_register_t *exit_reason,
+				  unsigned int *host_call_result,
+				  unsigned int rec_num);
 u_register_t host_realm_init_ipa_state(struct realm *realm, u_register_t level,
-					u_register_t start, uint64_t end);
-u_register_t host_rmi_psci_complete(u_register_t calling_rec, u_register_t target_rec,
-		unsigned long status);
-void host_rmi_init_cmp_result(void);
-bool host_rmi_get_cmp_result(void);
-u_register_t host_realm_map_protected_data(bool unknown,
-			struct realm *realm,
-			u_register_t target_pa,
-			u_register_t map_size,
-			u_register_t src_pa);
-u_register_t host_rmi_rtt_set_ripas(u_register_t rd,
-				  u_register_t rec,
-				  u_register_t start,
-				  u_register_t end,
-				  u_register_t *top);
+				       u_register_t start, uint64_t end);
+u_register_t host_realm_delegate_map_protected_data(bool unknown,
+					   struct realm *realm,
+					   u_register_t target_pa,
+					   u_register_t map_size,
+					   u_register_t src_pa);
+u_register_t host_realm_map_unprotected(struct realm *realm, u_register_t ns_pa,
+					u_register_t map_size);
 
 #endif /* HOST_REALM_RMI_H */
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 8549512..1ae1533 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -47,6 +47,8 @@
 	REALM_MULTIPLE_REC_PSCI_DENIED_CMD,
 	REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
 	REALM_GET_RSI_VERSION,
+	REALM_INSTR_FETCH_CMD,
+	REALM_DATA_ACCESS_CMD,
 	REALM_PMU_CYCLE,
 	REALM_PMU_EVENT,
 	REALM_PMU_PRESERVE,
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index ddaa3cb..55b5f9a 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -129,6 +129,38 @@
 	return false;
 }
 
+static bool test_realm_instr_fetch_cmd(void)
+{
+	u_register_t base;
+	void (*func_ptr)(void);
+	rsi_ripas_type ripas;
+
+	base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+	rsi_ipa_state_get(base, &ripas);
+	realm_printf("Initial ripas=0x%lx\n", ripas);
+	/* causes instruction abort */
+	realm_printf("Generate Instruction Abort\n");
+	func_ptr = (void (*)(void))base;
+	func_ptr();
+	/* should not return */
+	return false;
+}
+
+static bool test_realm_data_access_cmd(void)
+{
+	u_register_t base;
+	rsi_ripas_type ripas;
+
+	base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+	rsi_ipa_state_get(base, &ripas);
+	realm_printf("Initial ripas=0x%lx\n", ripas);
+	/* causes data abort */
+	realm_printf("Generate Data Abort\n");
+	*((volatile uint64_t *)base);
+	/* should not return */
+	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,
@@ -156,9 +188,16 @@
 			break;
 		case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
 			test_succeed = test_realm_multiple_rec_psci_denied_cmd();
+			break;
 		case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
 			test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
 			break;
+		case REALM_INSTR_FETCH_CMD:
+			test_succeed = test_realm_instr_fetch_cmd();
+			break;
+		case REALM_DATA_ACCESS_CMD:
+			test_succeed = test_realm_data_access_cmd();
+			break;
 		case REALM_PAUTH_SET_CMD:
 			test_succeed = test_realm_pauth_set_cmd();
 			break;
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 b706e3a..057dd00 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
@@ -142,10 +142,10 @@
 	return host_rmi_handler(&(smc_args) {RMI_REALM_DESTROY, rd}, 2U).ret0;
 }
 
-static inline u_register_t host_rmi_data_destroy(u_register_t rd,
-						 u_register_t map_addr,
-						 u_register_t *data,
-						 u_register_t *top)
+u_register_t host_rmi_data_destroy(u_register_t rd,
+				   u_register_t map_addr,
+				   u_register_t *data,
+				   u_register_t *top)
 {
 	smc_ret_values rets;
 
@@ -179,11 +179,11 @@
 				rd, rtt, map_addr, level}, 5U).ret0;
 }
 
-static inline u_register_t host_rmi_rtt_destroy(u_register_t rd,
-						u_register_t map_addr,
-						u_register_t level,
-						u_register_t *rtt,
-						u_register_t *top)
+u_register_t host_rmi_rtt_destroy(u_register_t rd,
+				  u_register_t map_addr,
+				  u_register_t level,
+				  u_register_t *rtt,
+				  u_register_t *top)
 {
 	smc_ret_values rets;
 
@@ -203,10 +203,10 @@
 	return rets.ret0;
 }
 
-static inline u_register_t host_rmi_rtt_init_ripas(u_register_t rd,
-						   u_register_t start,
-						   u_register_t end,
-						   u_register_t *top)
+u_register_t host_rmi_rtt_init_ripas(u_register_t rd,
+				   u_register_t start,
+				   u_register_t end,
+				   u_register_t *top)
 
 {
 	smc_ret_values rets;
@@ -263,10 +263,10 @@
 				rd, map_addr, level, ns_pa}, 5U).ret0;
 }
 
-static u_register_t host_rmi_rtt_readentry(u_register_t rd,
-					   u_register_t map_addr,
-					   u_register_t level,
-					   struct rtt_entry *rtt)
+u_register_t host_rmi_rtt_readentry(u_register_t rd,
+				   u_register_t map_addr,
+				   u_register_t level,
+				   struct rtt_entry *rtt)
 {
 	smc_ret_values rets;
 
@@ -279,10 +279,10 @@
 	return rets.ret0;
 }
 
-static inline u_register_t host_rmi_rtt_unmap_unprotected(u_register_t rd,
-							  u_register_t map_addr,
-							  u_register_t level,
-							  u_register_t *top)
+u_register_t host_rmi_rtt_unmap_unprotected(u_register_t rd,
+					  u_register_t map_addr,
+					  u_register_t level,
+					  u_register_t *top)
 {
 	smc_ret_values rets;
 
@@ -292,7 +292,7 @@
 	return rets.ret0;
 }
 
-static inline u_register_t host_rtt_level_mapsize(u_register_t level)
+u_register_t host_rtt_level_mapsize(u_register_t level)
 {
 	if (level > RTT_MAX_LEVEL) {
 		return PAGE_SIZE;
@@ -315,10 +315,10 @@
 	return host_rmi_rtt_create(realm->rd, phys, addr, level);
 }
 
-static u_register_t host_rmi_create_rtt_levels(struct realm *realm,
-						u_register_t map_addr,
-						u_register_t level,
-						u_register_t max_level)
+u_register_t host_rmi_create_rtt_levels(struct realm *realm,
+					u_register_t map_addr,
+					u_register_t level,
+					u_register_t max_level)
 {
 	u_register_t rtt, ret;
 
@@ -381,11 +381,11 @@
 
 }
 
-u_register_t host_realm_map_protected_data(bool unknown,
-					   struct realm *realm,
-					   u_register_t target_pa,
-					   u_register_t map_size,
-					   u_register_t src_pa)
+u_register_t host_realm_delegate_map_protected_data(bool unknown,
+						    struct realm *realm,
+						    u_register_t target_pa,
+						    u_register_t map_size,
+						    u_register_t src_pa)
 {
 	u_register_t rd = realm->rd;
 	u_register_t map_level, level;
@@ -514,7 +514,6 @@
 		ERROR("Unknown map_size=0x%lx\n", map_size);
 		return REALM_ERROR;
 	}
-
 	u_register_t desc = phys | S2TTE_ATTR_FWB_WB_RW;
 
 	ret = host_rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
@@ -858,7 +857,7 @@
 
 	/* MAP image regions */
 	while (i < (realm->par_size / PAGE_SIZE)) {
-		ret = host_realm_map_protected_data(false, realm,
+		ret = host_realm_delegate_map_protected_data(false, realm,
 						realm->par_base + i * PAGE_SIZE,
 						PAGE_SIZE,
 						src_pa + i * PAGE_SIZE);
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 1948c1f..796d27e 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
@@ -456,11 +456,11 @@
 			base + (PAGE_SIZE * test_page_num));
 
 	for (unsigned int i = 0U; i < test_page_num; i++) {
-		ret = host_realm_map_protected_data(true, &realm,
+		ret = host_realm_delegate_map_protected_data(true, &realm,
 				base + (PAGE_SIZE * i), PAGE_SIZE,
 				base + (PAGE_SIZE * i));
 		if (ret != REALM_SUCCESS) {
-			ERROR("host_realm_map_protected_data failed\n");
+			ERROR("host_realm_delegate_map_protected_data failed\n");
 			goto destroy_realm;
 		}
 	}
@@ -548,9 +548,9 @@
 
 	base = (u_register_t)page_alloc(PAGE_SIZE);
 
-	ret = host_realm_map_protected_data(true, &realm, base, PAGE_SIZE, base);
+	ret = host_realm_delegate_map_protected_data(true, &realm, base, PAGE_SIZE, base);
 	if (ret != RMI_SUCCESS) {
-		ERROR("host_realm_map_protected_data failede\n");
+		ERROR("host_realm_delegate_map_protected_data failede\n");
 		goto destroy_realm;
 	}
 	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
@@ -584,3 +584,369 @@
 	return host_call_result;
 }
 
+/*
+ * Test aims to generate REALM Exit due to abort
+ * when access page with RIPAS=DESTOYED HIPAS=ASSIGNED
+ * Host maps a protected page (calls data_create) when realm is in new state
+ * Initial state of PAGE is RIPAS=RAM HIPAS=ASSIGNED
+ * Host calls data_destroy, new state HIPAS=UNASSIGNED RIPAS=DESTROYED
+ * Enter Realm, Rec0 executes from page, and Rec1 reads the page
+ * Realm should trigger an Instr/Data abort, and will exit to Host.
+ * The Host verifies exit reason is Instr/Data abort
+ */
+test_result_t host_realm_abort_unassigned_destroyed(void)
+{
+	bool ret1, ret2;
+	test_result_t res = TEST_RESULT_FAIL;
+	u_register_t ret, data, top;
+	struct realm realm;
+	struct rmi_rec_run *run;
+	struct rtt_entry rtt;
+	u_register_t rec_flag[2U] = {RMI_RUNNABLE, RMI_RUNNABLE}, base;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!host_create_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, 2U)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(&realm, NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		goto destroy_realm;
+	}
+
+	base = (u_register_t)page_alloc(PAGE_SIZE);
+
+	run = (struct rmi_rec_run *)realm.run[0];
+
+	/* DATA_CREATE
+	 * Copies content of TFTF_BASE in newly created page, any PA can be used for dummy copy
+	 * maps 1:1 IPA:PA
+	 */
+	ret = host_realm_delegate_map_protected_data(false, &realm, base, PAGE_SIZE, TFTF_BASE);
+	if (ret != RMI_SUCCESS) {
+		ERROR("host_realm_delegate_map_protected_data failed\n");
+		goto destroy_realm;
+	}
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_ASSIGNED ||
+			(rtt.ripas != RMI_RAM)) {
+		ERROR("wrong state after DATA_CRATE_UNKNOWN\n");
+		goto undelegate_destroy;
+	}
+	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
+			base, rtt.state, rtt.ripas);
+	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+
+	ret = host_rmi_data_destroy(realm.rd, base, &data, &top);
+	if (ret != RMI_SUCCESS || data != base) {
+		ERROR("host_rmi_data_destroy failed\n");
+		goto undelegate_destroy;
+	}
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_UNASSIGNED ||
+			rtt.ripas != RMI_DESTROYED) {
+		ERROR("Wrong state after host_rmi_data_destroy\n");
+		goto undelegate_destroy;
+	}
+
+	INFO("New state4 base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
+			base, rtt.state, rtt.ripas);
+
+	if (host_realm_activate(&realm) != REALM_SUCCESS) {
+		ERROR("%s() failed\n", "host_realm_activate");
+		goto undelegate_destroy;
+	}
+
+	/* Realm0 expect rec exit due to Instr Abort unassigned destroyed page */
+	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
+		RMI_EXIT_SYNC, 0U);
+
+	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+			|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
+			|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+			|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
+		goto undelegate_destroy;
+	}
+	INFO("IA FAR=0x%lx, HPFAR=0x%lx ESR=0x%lx\n", run->exit.far, run->exit.hpfar,
+			run->exit.esr);
+
+	run = (struct rmi_rec_run *)realm.run[1];
+
+	/* Realm1 expect rec exit due to Data Abort unassigned destroyed page */
+	ret1 = host_enter_realm_execute(&realm, REALM_DATA_ACCESS_CMD,
+			RMI_EXIT_SYNC, 1U);
+
+	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault\n");
+		goto undelegate_destroy;
+	}
+	INFO("DA FAR=0x%lx, HPFAR=0x%lx ESR= 0x%lx\n", run->exit.far, run->exit.hpfar,
+			run->exit.esr);
+	res = TEST_RESULT_SUCCESS;
+
+undelegate_destroy:
+	ret = host_rmi_granule_undelegate(base);
+destroy_realm:
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret2) {
+		ERROR("%s(): destroy=%d\n",
+		__func__, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return res;
+}
+
+/*
+ * Test aims to generate REALM Exit due to Abort
+ * when access page with RIPAS=RAM HIPAS=UNASSIGNED
+ * Host allocates a PAGE, calls init_ripas when realm is in new state
+ * Initial state of PAGE is RIPAS=RAM HIPAS=UNASSIGNED
+ * Enter Realm, REC0 executes from page, and REC1 reads the page
+ * Realm should trigger an Instr/Data abort, and will exit to Host.
+ * Host verifies exit reason is Instr/Data abort.
+ */
+test_result_t host_realm_abort_unassigned_ram(void)
+{
+	bool ret1, ret2;
+	u_register_t ret, top;
+	struct realm realm;
+	struct rmi_rec_run *run;
+	struct rtt_entry rtt;
+	test_result_t res = TEST_RESULT_FAIL;
+	u_register_t rec_flag[2U] = {RMI_RUNNABLE, RMI_RUNNABLE}, base;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!host_create_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, 2U)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(&realm, NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		goto destroy_realm;
+	}
+
+	/* This is dummy allocation to get a base address */
+	base = (u_register_t)page_alloc(PAGE_SIZE);
+
+	run = (struct rmi_rec_run *)realm.run[0];
+
+	/* Set RIPAS of PAGE to RAM */
+	ret = host_rmi_rtt_init_ripas(realm.rd, base, base + PAGE_SIZE, &top);
+	if (ret != RMI_SUCCESS) {
+		ERROR("%s() failed, ret=0x%lx line=%u\n",
+			"host_rmi_rtt_init_ripas", ret, __LINE__);
+		goto destroy_realm;
+	}
+	if (host_realm_activate(&realm) != REALM_SUCCESS) {
+		ERROR("%s() failed\n", "host_realm_activate");
+		goto destroy_realm;
+	}
+
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_UNASSIGNED ||
+			(rtt.ripas != RMI_RAM)) {
+		ERROR("wrong initial state\n");
+		goto destroy_realm;
+	}
+	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
+			base, rtt.state, rtt.ripas);
+	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+
+	/* Rec0 expect rec exit due to Instr Abort unassigned ram page */
+	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
+			RMI_EXIT_SYNC, 0U);
+
+	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+			|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
+			|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+			|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
+		goto destroy_realm;
+	}
+	INFO("IA FAR=0x%lx, HPFAR=0x%lx ESR=0x%lx\n", run->exit.far, run->exit.hpfar,
+			run->exit.esr);
+	run = (struct rmi_rec_run *)realm.run[1];
+
+	/* Rec1 expect rec exit due to Data Abort unassigned ram page */
+	ret1 = host_enter_realm_execute(&realm, REALM_DATA_ACCESS_CMD,
+			RMI_EXIT_SYNC, 1U);
+
+	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
+		goto destroy_realm;
+	}
+	INFO("DA FAR=0x%lx, HPFAR=0x%lx ESR=0x%lx\n", run->exit.far, run->exit.hpfar,
+			run->exit.esr);
+	res = TEST_RESULT_SUCCESS;
+
+destroy_realm:
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret2) {
+		ERROR("%s(): destroy=%d\n",
+		__func__, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return res;
+}
+
+/*
+ * Test aims to generate REALM Exit due to Abort
+ * when access page with RIPAS=DESTOYED HIPAS=Assigned
+ * Host maps a protected page (calls data_create) when realm is in new state
+ * initial state of PAGE is RIPAS=RAM HIPAS=ASSIGNED
+ * Host calls data_destroy, new state HIPAS=UNASSIGNED RIPAS=DESTROYED
+ * Host calls data_create_unknown, new state HIPAS=ASSIGNED RIPAS=DESTROYED
+ * Enter Realm, REC0 executes from page, and REC1 reads the page
+ * Realm should trigger an Instr/Data abort, and will exit to Host.
+ * The Host verifies exit reason is Instr/Data abort
+ */
+test_result_t host_realm_abort_assigned_destroyed(void)
+{
+	bool ret1, ret2;
+	test_result_t res = TEST_RESULT_FAIL;
+	u_register_t ret, top, data;
+	struct realm realm;
+	struct rmi_rec_run *run;
+	struct rtt_entry rtt;
+	u_register_t rec_flag[2U] = {RMI_RUNNABLE, RMI_RUNNABLE}, base;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!host_create_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, 2U)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(&realm, NS_REALM_SHARED_MEM_BASE,
+			NS_REALM_SHARED_MEM_SIZE)) {
+		goto destroy_realm;
+	}
+
+	base = (u_register_t)page_alloc(PAGE_SIZE);
+	run = (struct rmi_rec_run *)realm.run[0];
+
+	/* DATA_CREATE */
+	/* Copied content of TFTF_BASE to new page, can use any adr, maps 1:1 IPA:PA */
+	ret = host_realm_delegate_map_protected_data(false, &realm, base, PAGE_SIZE, TFTF_BASE);
+	if (ret != RMI_SUCCESS) {
+		ERROR("host_realm_delegate_map_protected_data failed\n");
+		goto destroy_realm;
+	}
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_ASSIGNED ||
+			(rtt.ripas != RMI_RAM)) {
+		ERROR("wrong state after data create\n");
+		goto destroy_realm;
+	}
+	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
+			base, rtt.state, rtt.ripas);
+	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+
+	if (host_realm_activate(&realm) != REALM_SUCCESS) {
+		ERROR("%s() failed\n", "host_realm_activate");
+		goto destroy_realm;
+	}
+
+	ret = host_rmi_data_destroy(realm.rd, base, &data, &top);
+	if (ret != RMI_SUCCESS || data != base) {
+		ERROR("host_rmi_data_destroy failed\n");
+		goto destroy_realm;
+	}
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_UNASSIGNED ||
+			rtt.ripas != RMI_DESTROYED) {
+		ERROR("Wrong state after host_rmi_data_destroy\n");
+		goto destroy_realm;
+	}
+	ret = host_rmi_granule_undelegate(base);
+
+	/* DATA_CREATE_UNKNOWN */
+	ret = host_realm_delegate_map_protected_data(true, &realm, base, PAGE_SIZE, 0U);
+	if (ret != RMI_SUCCESS) {
+		ERROR("host_realm_delegate_map_protected_data failede\n");
+		goto destroy_realm;
+	}
+	ret = host_rmi_rtt_readentry(realm.rd, base, 3U, &rtt);
+	if (ret != RMI_SUCCESS || rtt.state != RMI_ASSIGNED ||
+			(rtt.ripas != RMI_DESTROYED)) {
+		ERROR("wrong state after data create unknown\n");
+		goto destroy_data;
+	}
+
+	/* Rec0, expect rec exit due to Instr Abort assigned destroyed page */
+	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
+		RMI_EXIT_SYNC, 0U);
+
+	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+		|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
+		|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
+		goto destroy_data;
+	}
+	INFO("IA FAR=0x%lx, HPFAR=0x%lx ESR=0x%lx\n", run->exit.far, run->exit.hpfar,
+				run->exit.esr);
+	run = (struct rmi_rec_run *)realm.run[1];
+
+	/* Rec1  expect rec exit due to Data Abort  assigned destroyed page */
+	ret1 = host_enter_realm_execute(&realm, REALM_DATA_ACCESS_CMD,
+			RMI_EXIT_SYNC, 1U);
+
+	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
+	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
+		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
+		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
+		goto destroy_data;
+	}
+	INFO("DA FAR=0x%lx, HPFAR=0x%lx ESR=0x%lx\n", run->exit.far, run->exit.hpfar,
+				run->exit.esr);
+	res = TEST_RESULT_SUCCESS;
+
+destroy_data:
+	ret = host_rmi_data_destroy(realm.rd, base, &data, &top);
+	ret = host_rmi_granule_undelegate(base);
+destroy_realm:
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret2) {
+		ERROR("%s(): destroy=%d\n",
+		__func__, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return res;
+}
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 68d68dd..934a34e 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -16,6 +16,12 @@
 	  function="host_realm_multi_rec_multiple_cpu" />
 	  <testcase name="Realm payload multi rec validations"
 	  function="host_realm_multi_rec_multiple_cpu2" />
+	  <testcase name="Realm Abort Unassigned RAM"
+	  function="host_realm_abort_unassigned_ram" />
+	  <testcase name="Realm Abort Unassigned Destroyed"
+	  function="host_realm_abort_unassigned_destroyed" />
+	  <testcase name="Realm Abort Assigned destroyed"
+	  function="host_realm_abort_assigned_destroyed" />
 	  <testcase name="Realm payload multi rec single cpu"
 	  function="host_realm_multi_rec_single_cpu" />
 	  <testcase name="Realm payload multi rec psci denied"