arch/x86/entry/vsyscall/vsyscall_64.c
Source file repositories/reference/linux-study-clean/arch/x86/entry/vsyscall/vsyscall_64.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/entry/vsyscall/vsyscall_64.c- Extension
.c- Size
- 10590 bytes
- Lines
- 404
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/timer.hlinux/sched/signal.hlinux/mm_types.hlinux/syscalls.hlinux/ratelimit.hasm/vsyscall.hasm/unistd.hasm/fixmap.hasm/traps.hvsyscall_trace.h
Detected Declarations
function vsyscall_setupfunction warn_bad_vsyscallfunction addr_to_vsyscall_nrfunction write_ok_or_segvfunction __emulate_vsyscallfunction pointerfunction emulate_vsyscall_pffunction emulate_vsyscall_gpfunction in_gate_areafunction in_gate_area_no_mmfunction set_vsyscall_pgtable_user_bitsfunction map_vsyscall
Annotated Snippet
if (cpu_feature_enabled(X86_FEATURE_LASS) && vsyscall_mode == EMULATE) {
setup_clear_cpu_cap(X86_FEATURE_LASS);
pr_warn_once("x86/cpu: Disabling LASS due to vsyscall=emulate\n");
}
return 0;
}
return -EINVAL;
}
early_param("vsyscall", vsyscall_setup);
static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
const char *message)
{
if (!show_unhandled_signals)
return;
printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n",
level, current->comm, task_pid_nr(current),
message, regs->ip, regs->cs,
regs->sp, regs->ax, regs->si, regs->di);
}
static int addr_to_vsyscall_nr(unsigned long addr)
{
int nr;
if ((addr & ~0xC00UL) != VSYSCALL_ADDR)
return -EINVAL;
nr = (addr & 0xC00UL) >> 10;
if (nr >= 3)
return -EINVAL;
return nr;
}
static bool write_ok_or_segv(unsigned long ptr, size_t size)
{
if (!access_ok((void __user *)ptr, size)) {
struct thread_struct *thread = ¤t->thread;
thread->error_code = X86_PF_USER | X86_PF_WRITE;
thread->cr2 = ptr;
thread->trap_nr = X86_TRAP_PF;
force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)ptr);
return false;
} else {
return true;
}
}
static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
{
unsigned long caller;
int vsyscall_nr, syscall_nr, tmp;
long ret;
unsigned long orig_dx;
/* Confirm that the fault happened in 64-bit user mode */
if (!user_64bit_mode(regs))
return false;
if (vsyscall_mode == NONE) {
warn_bad_vsyscall(KERN_INFO, regs,
"vsyscall attempted with vsyscall=none");
return false;
}
vsyscall_nr = addr_to_vsyscall_nr(address);
trace_emulate_vsyscall(vsyscall_nr);
if (vsyscall_nr < 0) {
warn_bad_vsyscall(KERN_WARNING, regs,
"misaligned vsyscall (exploit attempt or buggy program) -- look up the vsyscall kernel parameter if you need a workaround");
goto sigsegv;
}
if (get_user(caller, (unsigned long __user *)regs->sp) != 0) {
warn_bad_vsyscall(KERN_WARNING, regs,
"vsyscall with bad stack (exploit attempt?)");
goto sigsegv;
}
/*
* Check for access_ok violations and find the syscall nr.
*
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/timer.h`, `linux/sched/signal.h`, `linux/mm_types.h`, `linux/syscalls.h`, `linux/ratelimit.h`, `asm/vsyscall.h`, `asm/unistd.h`.
- Detected declarations: `function vsyscall_setup`, `function warn_bad_vsyscall`, `function addr_to_vsyscall_nr`, `function write_ok_or_segv`, `function __emulate_vsyscall`, `function pointer`, `function emulate_vsyscall_pf`, `function emulate_vsyscall_gp`, `function in_gate_area`, `function in_gate_area_no_mm`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.