Commit 22a78a25438d for kernel

commit 22a78a25438d246e4e951960523bee6a5155897d
Merge: a804c5742bff 14b482c98dfe
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Wed Oct 21 07:19:30 2026 -1000

    Merge __{get,put}_user() removal branch

    This is long over-due: the __get_user() and __put_user() functions are
    entirely historical, and are never the rigth thing to use any more.  And
    when mis-used (read: every case) they are not only slower than the right
    thing, but also insecure because they don't check the user address
    range.

    Most of the usage sites have been converted long ago, but various
    left-overs remained.  So this started out as a single patch that I wrote
    as a "show people how to convert __{get,put}_user() to modern code".

    In particular, Thomas last year implemented the very nice new scoped
    user access region helpers (see commit e497310b4ffb: "uaccess: Provide
    scoped user access regions") that makes the modern interfaces
    particularly easy to use and really removes any excuse for the old
    horrors.

    That small example patch then grew to this, partly using Claude as a
    glorified coccinelle script to apply the pattern to other places.

    There were a few different reasons for using __put_user() and
    __get_user() rather than the alternatives, but the original historical
    one was performance: when doing multiple accesses off the same base
    pointer, doing a single range check followed by multiple non-checked
    accesses used to create smaller and faster code.

    The keyword here is "used to".  It hasn't been true for years, because
    the range check isn't actually the real cost these days.  The real cost
    of user accesses on modern hardware is turning the user accesses on and
    off in the first place (on x86, using the STAC/CLAC instructions).

    Those sequences get turned into 'scoped_user_read_access() { }' blocks,
    see for example that first patch in the series: "signal: use scoped user
    access for old-style sigaction".

    Another, historical reason for using __get_user() and friends is that
    you actually want to do a kernel pointer access, but the pointer might
    not be entirely reliable (typically during fault handling), so you want
    to have exception handling for the kernel access.

    The modern way to do that kind of non-faulting kernel access is using
    "get_kernel_nofault()", but some code predates that helper existing at
    all, and used __get_user() as a way to just get a memory access with
    exception handling.  For that pattern, see for example "alpha: use
    get_kernel_nofault() in dik_show_code()"

    A third bad reason for using __get_user() and friends was that the
    proper get_user() had a "might_fault()" in it, and code that ran in
    atomic regions but hadn't disabled page faults would result in a
    warning.  That kind of code needs to explicitly disable page faults,
    because "atomic region" is not well defined at run-time and can be
    invisible (eg a preempt-off region in a non-preemptible kernel).

    See "vdpa_sim: disable page faults around vringh_need_notify_iotlb()"
    for an example of that pattern, where the local_bh_disable() now also
    grows a pagefault_disable(), which makes the normal get_user() no longer
    warn about the user access in non-process context, because it can see
    that the potential page fault will not cause problems.

    And finally, the really nasty reason to use __get_user() and friends:
    pointers that can be either kernel pointers or user pointers.  We've
    gotten rid of almost all such cases, but a couple remained.  See for
    example "x86/sev: Use explicit user-or-kernel accessors for #VC memory
    operands".

    NOTE! This series removes all __get/put_user() calls from generic code
    but only does the final removal of the whole interface on x86.  Other
    architectures have not been entirely converted, for a variety of reasons:

     - arm64 makes __{get,put}_user() be exactly the same as
       {get,put}_user() so it's harmless and didn't have the dangers of the
       legacy use cases.

     - any architecture that uses <asm-generic/uaccess.h> will still use
       __{get,put}_user as the underlying helper function name

     - several architectures had some legacy uses that weren't entirely
       trivial and I didn't want to extend this patch series to things that
       I don't know and that don't really matter.

    but I did do a couple of the obvious "follows the exact same pattern"
    just because it could be done mindlessly and automatically.

    Let's see if I broke anything, but we should have done this years ago.

    * uaccess-cleanups: (48 commits)
      drm/i915/gem: ignore errors on presumed_offset write-back
      powerpc/align: use get_user_instr() for a user-mode instruction
      powerpc/signal64: use scoped user access in setup_trampoline()
      powerpc/signal64: use get_user() for the single context reads
      powerpc/signal32: use get_user() for the single context reads
      KVM: PPC: Book3S HV: use get_user()/put_user() for the HPT fd
      powerpc/powernv: use get_user()/put_user() in the LPC debugfs files
      s390: use get_user()/put_user() instead of the unchecked variants
      ARM: OABI: use scoped user access in epoll_put_uevent()
      ARM: signal: stop using __put_user() for the signal frame
      ARM: signal: check the FDPIC function descriptor address
      alpha: split the prefetch check in do_page_fault() by mode
      openrisc: use get_kernel_nofault() in show_registers()
      alpha: use get_kernel_nofault() in dik_show_code()
      nios2: use scoped user access for the signal frame
      nios2: check the signal frame address before writing to it
      hexagon: use scoped user access for the signal frame
      alpha: use scoped user access when setting up signal frames
      alpha: use scoped user access in the sigreturn path
      alpha: use scoped user access in osf_sigaction()
      ...

diff --cc arch/s390/kernel/signal.c
index deeef053758c,81709cd2e9e5..70094d533866
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@@ -278,47 -293,58 +278,47 @@@ static int setup_frame(int sig, struct
  	if (cpu_has_vx())
  		frame_size += sizeof(frame->sregs_ext);
  	frame = get_sigframe(ka, regs, frame_size);
 -	if (frame == (void __user *) -1UL)
 +	if (frame == (void __user *)-1UL)
  		return -EFAULT;
 -
  	/* Set up backchain. */
- 	if (__put_user(regs->gprs[15], (addr_t __user *)frame))
 -	if (put_user(regs->gprs[15], (addr_t __user *) frame))
++	if (put_user(regs->gprs[15], (addr_t __user *)frame))
  		return -EFAULT;
 -
 -	/* Create struct sigcontext on the signal stack */
 +	/* Create struct sigcontext on the signal stack. */
  	memcpy(&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE);
 -	sc.sregs = (_sigregs __user __force *) &frame->sregs;
 +	sc.sregs = (_sigregs __user __force *)&frame->sregs;
  	if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
  		return -EFAULT;
 -
 -	/* Store registers needed to create the signal frame */
 +	/* Store registers needed to create the signal frame. */
  	store_sigregs();
 -
 -	/* Create _sigregs on the signal stack */
 +	/* Create _sigregs on the signal stack. */
  	if (save_sigregs(regs, &frame->sregs))
  		return -EFAULT;
 -
 -	/* Place signal number on stack to allow backtrace from handler.  */
 -	if (put_user(regs->gprs[2], (int __user *) &frame->signo))
 +	/* Place signal number on stack to allow backtrace from handler. */
- 	if (__put_user(regs->gprs[2], (int __user *)&frame->signo))
++	if (put_user(regs->gprs[2], (int __user *)&frame->signo))
  		return -EFAULT;
 -
 -	/* Create _sigregs_ext on the signal stack */
 +	/* Create _sigregs_ext on the signal stack. */
  	if (save_sigregs_ext(regs, &frame->sregs_ext))
  		return -EFAULT;
 -
 -	/* Set up to return from userspace.  If provided, use a stub
 -	   already in userspace.  */
 +	/*
 +	 * Set up to return from userspace. If provided, use a stub
 +	 * already in userspace.
 +	 */
  	if (ka->sa.sa_flags & SA_RESTORER)
 -		restorer = (unsigned long) ka->sa.sa_restorer;
 +		restorer = (unsigned long)ka->sa.sa_restorer;
  	else
  		restorer = VDSO_SYMBOL(current, sigreturn);
 -
 -	/* Set up registers for signal handler */
 +	/* Set up registers for signal handler. */
  	regs->gprs[14] = restorer;
 -	regs->gprs[15] = (unsigned long) frame;
 +	regs->gprs[15] = (unsigned long)frame;
  	/* Force default amode and default user address space control. */
 -	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
 -		(PSW_USER_BITS & PSW_MASK_ASC) |
 -		(regs->psw.mask & ~PSW_MASK_ASC);
 -	regs->psw.addr = (unsigned long) ka->sa.sa_handler;
 -
 +	regs->psw.mask &= ~PSW_MASK_ASC;
 +	regs->psw.mask |= (PSW_USER_BITS & PSW_MASK_ASC) | PSW_MASK_EA | PSW_MASK_BA;
 +	regs->psw.addr = (unsigned long)ka->sa.sa_handler;
  	regs->gprs[2] = sig;
 -	regs->gprs[3] = (unsigned long) &frame->sc;
 -
 -	/* We forgot to include these in the sigcontext.
 -	   To avoid breaking binary compatibility, they are passed as args. */
 -	if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
 -	    sig == SIGTRAP || sig == SIGFPE) {
 -		/* set extra registers only for synchronous signals */
 +	regs->gprs[3] = (unsigned long)&frame->sc;
 +	/* Missing in sigcontext. Keep binary compatibility by passing as args. */
 +	if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP || sig == SIGFPE) {
 +		/* Set extra registers only for synchronous signals. */
  		regs->gprs[4] = regs->int_code & 127;
  		regs->gprs[5] = regs->int_parm_long;
  		regs->gprs[6] = current->thread.last_break;
@@@ -339,27 -366,30 +339,27 @@@ static int setup_rt_frame(struct ksigna
  		uc_flags |= UC_VXRS;
  	}
  	frame = get_sigframe(&ksig->ka, regs, frame_size);
 -	if (frame == (void __user *) -1UL)
 +	if (frame == (void __user *)-1UL)
  		return -EFAULT;
 -
  	/* Set up backchain. */
- 	if (__put_user(regs->gprs[15], (addr_t __user *)frame))
 -	if (put_user(regs->gprs[15], (addr_t __user *) frame))
++	if (put_user(regs->gprs[15], (addr_t __user *)frame))
  		return -EFAULT;
 -
 -	/* Set up to return from userspace.  If provided, use a stub
 -	   already in userspace.  */
 +	/*
 +	 * Set up to return from userspace. If provided, use a stub
 +	 * already in userspace.
 +	 */
  	if (ksig->ka.sa.sa_flags & SA_RESTORER)
 -		restorer = (unsigned long) ksig->ka.sa.sa_restorer;
 +		restorer = (unsigned long)ksig->ka.sa.sa_restorer;
  	else
  		restorer = VDSO_SYMBOL(current, rt_sigreturn);
 -
 -	/* Create siginfo on the signal stack */
 +	/* Create siginfo on the signal stack. */
  	if (copy_siginfo_to_user(&frame->info, &ksig->info))
  		return -EFAULT;
 -
 -	/* Store registers needed to create the signal frame */
 +	/* Store registers needed to create the signal frame. */
  	store_sigregs();
 -
  	/* Create ucontext on the signal stack. */
- 	if (__put_user(uc_flags, &frame->uc.uc_flags) ||
- 	    __put_user(NULL, &frame->uc.uc_link) ||
+ 	if (put_user(uc_flags, &frame->uc.uc_flags) ||
+ 	    put_user(NULL, &frame->uc.uc_link) ||
  	    __save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
  	    save_sigregs(regs, &frame->uc.uc_mcontext) ||
  	    __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)) ||
diff --cc arch/x86/kernel/fpu/signal.c
index 1f721ac84283,0a82a39ef9ae..164255df3d2e
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@@ -49,36 -48,12 +49,36 @@@ static inline bool check_xstate_in_sigf
  	 * fpstate layout with out copying the extended state information
  	 * in the memory layout.
  	 */
- 	if (__get_user(magic2, (__u32 __user *)(buf + fx_sw->xstate_size)))
 -	if (get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
++	if (get_user(magic2, (__u32 __user *)(buf + fx_sw->xstate_size)))
  		return false;
 +	if (unlikely(magic2 != FP_XSTATE_MAGIC2))
 +		goto err_setfx;

 -	if (likely(magic2 == FP_XSTATE_MAGIC2))
 -		return true;
 -setfx:
 +	if (fx_sw->xstate_size != fpstate->user_size ||
 +	    fx_sw->xfeatures != fpstate->user_xfeatures) {
 +		unsigned int xsize;
 +		u64 xfeatures;
 +
 +		/* Calculate size of enabled features only. */
 +		xfeatures = fx_sw->xfeatures & fpstate->user_xfeatures;
 +
 +		xsize = xstate_calculate_size(xfeatures, false);
 +		if (fx_sw->xstate_size < xsize)
 +			return false;
 +
 +		fx_sw->xstate_size = xsize;
 +	}
 +
 +	return true;
 +err_setfx:
 +	/*
 +	 * The fallback to FX-only state is used to preserve backward
 +	 * compatibility with user-space processes that are not aware of xsave
 +	 * states.
 +	 *
 +	 * In all other cases, returning false (to trigger SIGSEGV) is
 +	 * preferred to avoid silent user-space state corruption.
 +	 */
  	trace_x86_fpu_xstate_check_failed(x86_task_fpu(current));

  	/* Set the parameters for fx only state */