tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c
Extension
.c
Size
1681 bytes
Lines
74
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// 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,
};

Annotation

Implementation Notes