tools/testing/selftests/x86/fsgsbase.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/x86/fsgsbase.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/x86/fsgsbase.c- Extension
.c- Size
- 16254 bytes
- Lines
- 661
- 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.hstdbool.hstring.hsys/syscall.hunistd.herr.hsys/user.hasm/prctl.hsys/prctl.hsignal.hlimits.hsys/ucontext.hsched.hlinux/futex.hpthread.hasm/ldt.hsys/mman.hstddef.hsys/ptrace.hsys/wait.hsetjmp.hhelpers.h
Detected Declarations
enum which_basefunction sigsegvfunction sigillfunction rdgsbasefunction rdfsbasefunction wrgsbasefunction read_basefunction check_gs_valuefunction mov_0_gsfunction do_remote_basefunction load_gsfunction test_wrbasefunction set_gs_and_switch_tofunction test_unexpected_basefunction test_ptrace_write_gs_read_basefunction test_ptrace_write_gsbasefunction GSBASEfunction main
Annotated Snippet
if (ret != 0) {
printf("[NOTE]\tcould not create a segment -- test won't do anything\n");
return 0;
}
printf("\tusing GDT slot %d\n", desc.entry_number);
set_thread_area_entry_number = desc.entry_number;
unsigned short gs = (unsigned short)((desc.entry_number << 3) | 0x3);
asm volatile ("mov %0, %%gs" : : "rm" (gs));
return gs;
}
}
void test_wrbase(unsigned short index, unsigned long base)
{
unsigned short newindex;
unsigned long newbase;
printf("[RUN]\tGS = 0x%hx, GSBASE = 0x%lx\n", index, base);
asm volatile ("mov %0, %%gs" : : "rm" (index));
wrgsbase(base);
remote_base = 0;
ftx = 1;
syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
while (ftx != 0)
syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
asm volatile ("mov %%gs, %0" : "=rm" (newindex));
newbase = rdgsbase();
if (newindex == index && newbase == base) {
printf("[OK]\tIndex and base were preserved\n");
} else {
printf("[FAIL]\tAfter switch, GS = 0x%hx and GSBASE = 0x%lx\n",
newindex, newbase);
nerrs++;
}
}
static void *threadproc(void *ctx)
{
while (1) {
while (ftx == 0)
syscall(SYS_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0);
if (ftx == 3)
return NULL;
if (ftx == 1) {
do_remote_base();
} else if (ftx == 2) {
/*
* On AMD chips, this causes GSBASE != 0, GS == 0, and
* thread.gsbase == 0.
*/
load_gs();
asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0));
} else {
errx(1, "helper thread got bad command");
}
ftx = 0;
syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
}
}
static void set_gs_and_switch_to(unsigned long local,
unsigned short force_sel,
unsigned long remote)
{
unsigned long base;
unsigned short sel_pre_sched, sel_post_sched;
bool hard_zero = false;
if (local == HARD_ZERO) {
hard_zero = true;
local = 0;
}
printf("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n",
local, hard_zero ? " and clear gs" : "", remote);
if (force_sel)
printf("\tBefore schedule, set selector to 0x%hx\n", force_sel);
if (syscall(SYS_arch_prctl, ARCH_SET_GS, local) != 0)
err(1, "ARCH_SET_GS");
if (hard_zero)
asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0));
Annotation
- Immediate include surface: `stdio.h`, `stdlib.h`, `stdbool.h`, `string.h`, `sys/syscall.h`, `unistd.h`, `err.h`, `sys/user.h`.
- Detected declarations: `enum which_base`, `function sigsegv`, `function sigill`, `function rdgsbase`, `function rdfsbase`, `function wrgsbase`, `function read_base`, `function check_gs_value`, `function mov_0_gs`, `function do_remote_base`.
- 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.