tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/powerpc/mm/pkey_exec_prot.c- Extension
.c- Size
- 8058 bytes
- Lines
- 295
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
stdio.hstdlib.hstring.hsignal.hunistd.hpkeys.h
Detected Declarations
function trap_handlerfunction segv_handlerfunction testfunction main
Annotated Snippet
if (mprotect(insns, pgsize, PROT_READ | PROT_WRITE)) {
sigsafe_err("failed to set access permissions\n");
_exit(1);
}
break;
case SEGV_PKUERR:
if (signal_pkey != fault_pkey) {
sigsafe_err("got a fault for an unexpected pkey\n");
_exit(1);
}
switch (fault_type) {
case PKEY_DISABLE_ACCESS:
pkey_set_rights(fault_pkey, PKEY_UNRESTRICTED);
break;
case PKEY_DISABLE_EXECUTE:
/*
* Reassociate the exec-only pkey with the region
* to be able to continue. Unlike AMR, we cannot
* set IAMR directly from userspace to restore the
* permissions.
*/
if (mprotect(insns, pgsize, PROT_EXEC)) {
sigsafe_err("failed to set execute permissions\n");
_exit(1);
}
break;
default:
sigsafe_err("got a fault with an unexpected type\n");
_exit(1);
}
break;
default:
sigsafe_err("got a fault with an unexpected code\n");
_exit(1);
}
remaining_faults--;
}
static int test(void)
{
struct sigaction segv_act, trap_act;
unsigned long rights;
int pkey, ret, i;
ret = pkeys_unsupported();
if (ret)
return ret;
/* Setup SIGSEGV handler */
segv_act.sa_handler = 0;
segv_act.sa_sigaction = segv_handler;
FAIL_IF(sigprocmask(SIG_SETMASK, 0, &segv_act.sa_mask) != 0);
segv_act.sa_flags = SA_SIGINFO;
segv_act.sa_restorer = 0;
FAIL_IF(sigaction(SIGSEGV, &segv_act, NULL) != 0);
/* Setup SIGTRAP handler */
trap_act.sa_handler = 0;
trap_act.sa_sigaction = trap_handler;
FAIL_IF(sigprocmask(SIG_SETMASK, 0, &trap_act.sa_mask) != 0);
trap_act.sa_flags = SA_SIGINFO;
trap_act.sa_restorer = 0;
FAIL_IF(sigaction(SIGTRAP, &trap_act, NULL) != 0);
/* Setup executable region */
pgsize = getpagesize();
numinsns = pgsize / sizeof(unsigned int);
insns = (unsigned int *) mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
FAIL_IF(insns == MAP_FAILED);
/* Write the instruction words */
for (i = 1; i < numinsns - 1; i++)
insns[i] = PPC_INST_NOP;
/*
* Set the first instruction as an unconditional trap. If
* the last write to this address succeeds, this should
* get overwritten by a no-op.
*/
insns[0] = PPC_INST_TRAP;
/*
* Later, to jump to the executable region, we use a branch
* and link instruction (bctrl) which sets the return address
* automatically in LR. Use that to return back.
*/
insns[numinsns - 1] = PPC_INST_BLR;
Annotation
- Immediate include surface: `stdio.h`, `stdlib.h`, `string.h`, `signal.h`, `unistd.h`, `pkeys.h`.
- Detected declarations: `function trap_handler`, `function segv_handler`, `function test`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.