arch/x86/kernel/fpu/signal.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/fpu/signal.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/fpu/signal.c- Extension
.c- Size
- 14972 bytes
- Lines
- 532
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source 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.
- 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/compat.hlinux/cpu.hlinux/pagemap.hasm/fpu/signal.hasm/fpu/regset.hasm/fpu/xstate.hasm/sigframe.hasm/trapnr.hasm/trace/fpu.hcontext.hinternal.hlegacy.hxstate.h
Detected Declarations
function check_xstate_in_sigframefunction save_fsave_headerfunction save_sw_bytesfunction save_xstate_epilogfunction copy_fpregs_to_sigframefunction copy_fpstate_to_sigframefunction fpregs_soft_getfunction __restore_fpregs_from_userfunction restore_fpregs_from_userfunction __fpu_restore_sigfunction xstate_sigframe_sizefunction fpu__restore_sigfunction fpu__alloc_mathframefunction fpu__get_fpstate_size
Annotated Snippet
fpregs_soft_get(current, NULL, (struct membuf){.p = &fp,
.left = sizeof(fp)});
return !copy_to_user(buf, &fp, sizeof(fp));
}
if (!access_ok(buf, size))
return false;
if (use_xsave()) {
struct xregs_state __user *xbuf = buf_fx;
/*
* Clear the xsave header first, so that reserved fields are
* initialized to zero.
*/
if (__clear_user(&xbuf->header, sizeof(xbuf->header)))
return false;
}
retry:
/*
* Load the FPU registers if they are not valid for the current task.
* With a valid FPU state we can attempt to save the state directly to
* userland's stack frame which will likely succeed. If it does not,
* resolve the fault in the user memory and try again.
*/
fpregs_lock();
if (test_thread_flag(TIF_NEED_FPU_LOAD))
fpregs_restore_userregs();
pagefault_disable();
ret = copy_fpregs_to_sigframe(buf_fx, pkru);
pagefault_enable();
fpregs_unlock();
if (ret) {
if (!__clear_user(buf_fx, fpstate->user_size))
goto retry;
return false;
}
/* Save the fsave header for the 32-bit frames. */
if ((ia32_fxstate || !use_fxsr()) && !save_fsave_header(tsk, buf))
return false;
if (use_fxsr() && !save_xstate_epilog(buf_fx, ia32_fxstate, fpstate))
return false;
return true;
}
static int __restore_fpregs_from_user(void __user *buf, u64 ufeatures,
u64 xrestore, bool fx_only)
{
if (use_xsave()) {
u64 init_bv = ufeatures & ~xrestore;
int ret;
if (likely(!fx_only))
ret = xrstor_from_user_sigframe(buf, xrestore);
else
ret = fxrstor_from_user_sigframe(buf);
if (!ret && unlikely(init_bv))
os_xrstor(&init_fpstate, init_bv);
return ret;
} else if (use_fxsr()) {
return fxrstor_from_user_sigframe(buf);
} else {
return frstor_from_user_sigframe(buf);
}
}
/*
* Attempt to restore the FPU registers directly from user memory.
* Pagefaults are handled and any errors returned are fatal.
*/
static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only)
{
struct fpu *fpu = x86_task_fpu(current);
int ret;
/* Restore enabled features only. */
xrestore &= fpu->fpstate->user_xfeatures;
retry:
fpregs_lock();
/* Ensure that XFD is up to date */
xfd_update_state(fpu->fpstate);
pagefault_disable();
ret = __restore_fpregs_from_user(buf, fpu->fpstate->user_xfeatures,
xrestore, fx_only);
Annotation
- Immediate include surface: `linux/compat.h`, `linux/cpu.h`, `linux/pagemap.h`, `asm/fpu/signal.h`, `asm/fpu/regset.h`, `asm/fpu/xstate.h`, `asm/sigframe.h`, `asm/trapnr.h`.
- Detected declarations: `function check_xstate_in_sigframe`, `function save_fsave_header`, `function save_sw_bytes`, `function save_xstate_epilog`, `function copy_fpregs_to_sigframe`, `function copy_fpstate_to_sigframe`, `function fpregs_soft_get`, `function __restore_fpregs_from_user`, `function restore_fpregs_from_user`, `function __fpu_restore_sig`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source 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.