tools/testing/selftests/mm/protection_keys.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/mm/protection_keys.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/mm/protection_keys.c- Extension
.c- Size
- 48426 bytes
- Lines
- 1793
- 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
errno.hlinux/elf.hlinux/futex.htime.hsys/time.hsys/syscall.hstring.hstdio.hstdint.hstdbool.hsignal.hassert.hstdlib.hucontext.hsys/mman.hsys/types.hsys/wait.hsys/stat.hfcntl.hunistd.hsys/ptrace.hsetjmp.hpkey-helpers.h
Detected Declarations
struct pkey_malloc_recordfunction read_ptrfunction cat_into_filefunction pkey_assertfunction tracing_root_okfunction tracing_onfunction tracing_offfunction abort_hooksfunction madvisefunction dump_memfunction hw_pkey_getfunction hw_pkey_setfunction pkey_disable_setfunction pkey_disable_clearfunction pkey_write_allowfunction pkey_write_denyfunction pkey_access_allowfunction pkey_access_denyfunction signal_handlerfunction sig_chldfunction setup_sigsegv_handlerfunction setup_handlersfunction fork_lazy_childfunction alloc_pkeyfunction mprotectfunction mprotect_pkeyfunction record_pkey_mallocfunction free_pkey_mallocfunction setup_hugetlbfsfunction expected_pkey_faultfunction __save_test_fdfunction get_test_read_fdfunction close_test_fdsfunction test_pkey_alloc_free_attach_pkey0function test_read_of_write_disabled_regionfunction test_read_of_access_disabled_regionfunction test_read_of_access_disabled_region_with_page_already_mappedfunction test_write_of_write_disabled_region_with_page_already_mappedfunction test_write_of_write_disabled_regionfunction test_write_of_access_disabled_regionfunction test_write_of_access_disabled_region_with_page_already_mappedfunction test_kernel_write_of_access_disabled_regionfunction test_kernel_write_of_write_disabled_regionfunction test_kernel_gup_of_access_disabled_regionfunction test_kernel_gup_write_to_write_disabled_regionfunction test_pkey_syscalls_on_non_allocated_pkeyfunction test_pkey_syscalls_bad_argsfunction become_child
Annotated Snippet
struct pkey_malloc_record {
void *ptr;
long size;
int prot;
};
struct pkey_malloc_record *pkey_malloc_records;
struct pkey_malloc_record *pkey_last_malloc_record;
static long nr_pkey_malloc_records;
void record_pkey_malloc(void *ptr, long size, int prot)
{
long i;
struct pkey_malloc_record *rec = NULL;
for (i = 0; i < nr_pkey_malloc_records; i++) {
rec = &pkey_malloc_records[i];
/* find a free record */
if (rec)
break;
}
if (!rec) {
/* every record is full */
size_t old_nr_records = nr_pkey_malloc_records;
size_t new_nr_records = (nr_pkey_malloc_records * 2 + 1);
size_t new_size = new_nr_records * sizeof(struct pkey_malloc_record);
dprintf2("new_nr_records: %zd\n", new_nr_records);
dprintf2("new_size: %zd\n", new_size);
pkey_malloc_records = realloc(pkey_malloc_records, new_size);
pkey_assert(pkey_malloc_records != NULL);
rec = &pkey_malloc_records[nr_pkey_malloc_records];
/*
* realloc() does not initialize memory, so zero it from
* the first new record all the way to the end.
*/
for (i = 0; i < new_nr_records - old_nr_records; i++)
memset(rec + i, 0, sizeof(*rec));
}
dprintf3("filling malloc record[%d/%p]: {%p, %ld}\n",
(int)(rec - pkey_malloc_records), rec, ptr, size);
rec->ptr = ptr;
rec->size = size;
rec->prot = prot;
pkey_last_malloc_record = rec;
nr_pkey_malloc_records++;
}
static void free_pkey_malloc(void *ptr)
{
long i;
int ret;
dprintf3("%s(%p)\n", __func__, ptr);
for (i = 0; i < nr_pkey_malloc_records; i++) {
struct pkey_malloc_record *rec = &pkey_malloc_records[i];
dprintf4("looking for ptr %p at record[%ld/%p]: {%p, %ld}\n",
ptr, i, rec, rec->ptr, rec->size);
if ((ptr < rec->ptr) ||
(ptr >= rec->ptr + rec->size))
continue;
dprintf3("found ptr %p at record[%ld/%p]: {%p, %ld}\n",
ptr, i, rec, rec->ptr, rec->size);
nr_pkey_malloc_records--;
ret = munmap(rec->ptr, rec->size);
dprintf3("munmap ret: %d\n", ret);
pkey_assert(!ret);
dprintf3("clearing rec->ptr, rec: %p\n", rec);
rec->ptr = NULL;
dprintf3("done clearing rec->ptr, rec: %p\n", rec);
return;
}
pkey_assert(false);
}
static void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
{
void *ptr;
int ret;
read_pkey_reg();
dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
size, prot, pkey);
pkey_assert(pkey < NR_PKEYS);
ptr = mmap(NULL, size, prot, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
pkey_assert(ptr != (void *)-1);
ret = mprotect_pkey((void *)ptr, PAGE_SIZE, prot, pkey);
pkey_assert(!ret);
record_pkey_malloc(ptr, size, prot);
read_pkey_reg();
dprintf1("%s() for pkey %d @ %p\n", __func__, pkey, ptr);
return ptr;
Annotation
- Immediate include surface: `errno.h`, `linux/elf.h`, `linux/futex.h`, `time.h`, `sys/time.h`, `sys/syscall.h`, `string.h`, `stdio.h`.
- Detected declarations: `struct pkey_malloc_record`, `function read_ptr`, `function cat_into_file`, `function pkey_assert`, `function tracing_root_ok`, `function tracing_on`, `function tracing_off`, `function abort_hooks`, `function madvise`, `function dump_mem`.
- 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.