tools/testing/selftests/powerpc/mm/exec_prot.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/mm/exec_prot.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/powerpc/mm/exec_prot.c- Extension
.c- Size
- 5971 bytes
- Lines
- 232
- 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.hsys/mman.hpkeys.h
Detected Declarations
function is_fault_expectedfunction trap_handlerfunction segv_handlerfunction check_exec_faultfunction testfunction main
Annotated Snippet
if (mprotect(insns, pgsize, PROT_READ | PROT_WRITE | PROT_EXEC)) {
sigsafe_err("failed to set access permissions\n");
_exit(1);
}
} else {
sigsafe_err("got a fault with an unexpected code\n");
_exit(1);
}
remaining_faults--;
}
static int check_exec_fault(int rights)
{
/*
* Jump to the executable region.
*
* The first iteration also checks if the overwrite of the
* first instruction word from a trap to a no-op succeeded.
*/
fault_code = -1;
remaining_faults = 0;
if (!(rights & PROT_EXEC))
remaining_faults = 1;
FAIL_IF(mprotect(insns, pgsize, rights) != 0);
asm volatile("mtctr %0; bctrl" : : "r"(insns));
FAIL_IF(remaining_faults != 0);
if (!(rights & PROT_EXEC))
FAIL_IF(!is_fault_expected(fault_code));
return 0;
}
static int test(void)
{
struct sigaction segv_act, trap_act;
int i;
/* Skip the test if the CPU doesn't support Radix */
SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
/* Check if pkeys are supported */
pkeys_supported = pkeys_unsupported() == 0;
/* 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;
/*
* Pick the first instruction's address from the executable
* region.
Annotation
- Immediate include surface: `stdio.h`, `stdlib.h`, `string.h`, `signal.h`, `unistd.h`, `sys/mman.h`, `pkeys.h`.
- Detected declarations: `function is_fault_expected`, `function trap_handler`, `function segv_handler`, `function check_exec_fault`, `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.