--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Arm Ltd
+ *
+ * Verify that the POR_EL0 register is left untouched on sigreturn if the
+ * POE frame record is missing.
+ */
+
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define POR_EL0_INIT 0x07ul
+#define POR_EL0_CUSTOM 0x77ul
+
+static bool failed_check;
+
+static bool modify_por_el0(struct tdescr *td)
+{
+ set_por_el0(POR_EL0_CUSTOM);
+
+ return true;
+}
+
+static int signal_remove_poe_context(struct tdescr *td, siginfo_t *si,
+ ucontext_t *uc)
+{
+ struct _aarch64_ctx *ctx = GET_UC_RESV_HEAD(uc);
+ size_t resv_size = GET_UCP_RESV_SIZE(uc);
+ struct _aarch64_ctx *poe_ctx_head;
+
+ poe_ctx_head = get_header(ctx, POE_MAGIC, resv_size, NULL);
+ if (!poe_ctx_head) {
+ fprintf(stderr, "Missing poe_context record\n");
+ failed_check = true;
+ return 0;
+ }
+
+ /*
+ * Actually removing the record would require moving down the next
+ * records. An easier option is to turn it into an ESR record, which is
+ * ignored by sigreturn().
+ */
+ poe_ctx_head->magic = ESR_MAGIC;
+
+ return 0;
+}
+
+static void check_por_el0_preserved(struct tdescr *td)
+{
+ uint64_t por_el0 = get_por_el0();
+
+ if (por_el0 == POR_EL0_INIT) {
+ fprintf(stderr, "POR_EL0 preserved\n");
+ } else {
+ fprintf(stderr, "POR_EL0 unexpectedly set to %lx\n", por_el0);
+ failed_check = true;
+ }
+
+ td->pass = !failed_check;
+}
+
+struct tdescr tde = {
+ .name = "POR_EL0 missing poe_context",
+ .descr = "Remove poe_context record and check POR_EL0 is preserved",
+ .feats_required = FEAT_POE,
+ .timeout = 3,
+ .sig_trig = SIGUSR1,
+ .init = modify_por_el0,
+ .run = signal_remove_poe_context,
+ .check_result = check_por_el0_preserved,
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Arm Ltd
+ *
+ * Verify that the POR_EL0 register is saved and restored as expected on signal
+ * entry/return.
+ */
+
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define POR_EL0_INIT 0x07ul
+#define POR_EL0_CUSTOM 0x77ul
+
+static bool failed_check;
+
+static bool modify_por_el0(struct tdescr *td)
+{
+ set_por_el0(POR_EL0_CUSTOM);
+
+ return true;
+}
+
+static int signal_check_por_el0_reset(struct tdescr *td, siginfo_t *si,
+ ucontext_t *uc)
+{
+ uint64_t signal_por_el0 = get_por_el0();
+
+ if (signal_por_el0 != POR_EL0_INIT) {
+ fprintf(stderr, "POR_EL0 is %lx in signal handler (expected %lx)\n",
+ signal_por_el0, POR_EL0_INIT);
+ failed_check = true;
+ }
+
+ return 0;
+}
+
+static void check_por_el0_restored(struct tdescr *td)
+{
+ uint64_t por_el0 = get_por_el0();
+
+ if (por_el0 == POR_EL0_CUSTOM) {
+ fprintf(stderr, "POR_EL0 restored\n");
+ } else {
+ fprintf(stderr, "POR_EL0 was %lx but is now %lx\n",
+ POR_EL0_CUSTOM, por_el0);
+ failed_check = true;
+ }
+
+ td->pass = !failed_check;
+}
+
+struct tdescr tde = {
+ .name = "POR_EL0 restore",
+ .descr = "Validate that POR_EL0 is saved/restored on signal entry/return",
+ .feats_required = FEAT_POE,
+ .timeout = 3,
+ .sig_trig = SIGUSR1,
+ .init = modify_por_el0,
+ .run = signal_check_por_el0_reset,
+ .check_result = check_por_el0_restored,
+};