tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/arm64/signal/testcases/gcs_frame.c- Extension
.c- Size
- 1930 bytes
- Lines
- 89
- 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.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
signal.hucontext.hsys/prctl.htest_signals_utils.htestcases.h
Detected Declarations
function gcs_regs
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2023 ARM Limited
*/
#include <signal.h>
#include <ucontext.h>
#include <sys/prctl.h>
#include "test_signals_utils.h"
#include "testcases.h"
static union {
ucontext_t uc;
char buf[1024 * 64];
} context;
static int gcs_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
{
size_t offset;
struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
struct gcs_context *gcs;
unsigned long expected, gcspr;
uint64_t *u64_val;
int ret;
ret = prctl(PR_GET_SHADOW_STACK_STATUS, &expected, 0, 0, 0);
if (ret != 0) {
fprintf(stderr, "Unable to query GCS status\n");
return 1;
}
/* We expect a cap to be added to the GCS in the signal frame */
gcspr = get_gcspr_el0();
gcspr -= 8;
fprintf(stderr, "Expecting GCSPR_EL0 %lx\n", gcspr);
if (!get_current_context(td, &context.uc, sizeof(context))) {
fprintf(stderr, "Failed getting context\n");
return 1;
}
/* Ensure that the signal restore token was consumed */
u64_val = (uint64_t *)get_gcspr_el0() + 1;
if (*u64_val) {
fprintf(stderr, "GCS value at %p is %lx not 0\n",
u64_val, *u64_val);
return 1;
}
fprintf(stderr, "Got context\n");
head = get_header(head, GCS_MAGIC, GET_BUF_RESV_SIZE(context),
&offset);
if (!head) {
fprintf(stderr, "No GCS context\n");
return 1;
}
gcs = (struct gcs_context *)head;
/* Basic size validation is done in get_current_context() */
if (gcs->features_enabled != expected) {
fprintf(stderr, "Features enabled %llx but expected %lx\n",
gcs->features_enabled, expected);
return 1;
}
if (gcs->gcspr != gcspr) {
fprintf(stderr, "Got GCSPR %llx but expected %lx\n",
gcs->gcspr, gcspr);
return 1;
}
fprintf(stderr, "GCS context validated\n");
td->pass = 1;
return 0;
}
struct tdescr tde = {
.name = "GCS basics",
.descr = "Validate a GCS signal context",
.feats_required = FEAT_GCS,
.timeout = 3,
.run = gcs_regs,
};
Annotation
- Immediate include surface: `signal.h`, `ucontext.h`, `sys/prctl.h`, `test_signals_utils.h`, `testcases.h`.
- Detected declarations: `function gcs_regs`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.