tools/testing/selftests/arm64/mte/mte_common_util.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/mte/mte_common_util.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/arm64/mte/mte_common_util.c- Extension
.c- Size
- 11307 bytes
- Lines
- 426
- 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
fcntl.hsched.hsignal.hstdio.hstdlib.htime.hunistd.hlinux/auxvec.hsys/auxv.hsys/mman.hsys/prctl.hasm/hwcap.hkselftest.hmte_common_util.hmte_def.h
Detected Declarations
function mte_default_handlerfunction mte_register_signalfunction mte_wait_after_trigfunction mte_clear_tagsfunction __mte_free_memory_rangefunction mte_free_memory_tag_rangefunction mte_free_memoryfunction mte_initialize_current_contextfunction mte_switch_modefunction mte_default_setupfunction mte_restore_setupfunction create_temp_file
Annotated Snippet
if (si->si_code == SEGV_MTEAERR) {
if (cur_mte_cxt.trig_si_code == si->si_code)
cur_mte_cxt.fault_valid = true;
else
ksft_print_msg("Got unexpected SEGV_MTEAERR at pc=%llx, fault addr=%lx\n",
((ucontext_t *)uc)->uc_mcontext.pc,
addr);
return;
}
/* Compare the context for precise error */
else if (si->si_code == SEGV_MTESERR) {
if ((!mtefar_support && si_atag) || (si_atag != MT_FETCH_ATAG(cur_mte_cxt.trig_addr))) {
ksft_print_msg("Invalid MTE synchronous exception caught for address tag! si_tag=%x, si_atag: %x\n", si_tag, si_atag);
exit(KSFT_FAIL);
}
if (cur_mte_cxt.trig_si_code == si->si_code &&
((cur_mte_cxt.trig_range >= 0 &&
addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
(cur_mte_cxt.trig_range < 0 &&
addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)))) {
cur_mte_cxt.fault_valid = true;
/* Adjust the pc by 4 */
((ucontext_t *)uc)->uc_mcontext.pc += 4;
} else {
ksft_print_msg("Invalid MTE synchronous exception caught!\n");
exit(1);
}
} else {
ksft_print_msg("Unknown SIGSEGV exception caught!\n");
exit(1);
}
} else if (signum == SIGBUS) {
ksft_print_msg("INFO: SIGBUS signal at pc=%llx, fault addr=%lx, si_code=%x\n",
((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code);
if ((cur_mte_cxt.trig_range >= 0 &&
addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) ||
(cur_mte_cxt.trig_range < 0 &&
addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) &&
addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range))) {
cur_mte_cxt.fault_valid = true;
/* Adjust the pc by 4 */
((ucontext_t *)uc)->uc_mcontext.pc += 4;
}
}
}
void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *),
bool export_tags)
{
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
if (export_tags && signal == SIGSEGV)
sa.sa_flags |= SA_EXPOSE_TAGBITS;
sigemptyset(&sa.sa_mask);
sigaction(signal, &sa, NULL);
}
void mte_wait_after_trig(void)
{
sched_yield();
}
void *mte_insert_tags(void *ptr, size_t size)
{
void *tag_ptr;
int align_size;
if (!ptr || (unsigned long)(ptr) & MT_ALIGN_GRANULE) {
ksft_print_msg("FAIL: Addr=%p: invalid\n", ptr);
return NULL;
}
align_size = MT_ALIGN_UP(size);
tag_ptr = mte_insert_random_tag(ptr);
mte_set_tag_address_range(tag_ptr, align_size);
return tag_ptr;
}
void mte_clear_tags(void *ptr, size_t size)
{
if (!ptr || (unsigned long)(ptr) & MT_ALIGN_GRANULE) {
ksft_print_msg("FAIL: Addr=%p: invalid\n", ptr);
return;
Annotation
- Immediate include surface: `fcntl.h`, `sched.h`, `signal.h`, `stdio.h`, `stdlib.h`, `time.h`, `unistd.h`, `linux/auxvec.h`.
- Detected declarations: `function mte_default_handler`, `function mte_register_signal`, `function mte_wait_after_trig`, `function mte_clear_tags`, `function __mte_free_memory_range`, `function mte_free_memory_tag_range`, `function mte_free_memory`, `function mte_initialize_current_context`, `function mte_switch_mode`, `function mte_default_setup`.
- 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.