mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Usama Arif <usama.arif@linux.dev>
To: Kiryl Shutsemau <kas@kernel.org>
Cc: Usama Arif <usama.arif@linux.dev>,
	david.laight.linux@gmail.com, bp@alien8.de,
	dave.hansen@linux.intel.com, dsterba@suse.com, hpa@zytor.com,
	linux-kernel@vger.kernel.org, mingo@redhat.com, terrelln@fb.com,
	tglx@kernel.org, x86@kernel.org, torvalds@linux-foundation.org,
	hannes@cmpxchg.org, riel@surriel.com, shakeel.butt@linux.dev,
	kernel-team@meta.com
Subject: Re: [PATCH v2] x86/lib: Use REP MOVSB for large memcpy() on ERMS CPUs without FSRM
Date: Wed, 11 Nov 2026 04:58:31 -0800	[thread overview]
Message-ID: <20261111125832.2541683-1-usama.arif@linux.dev> (raw)
In-Reply-To: <avNEZ6Zz5IhN2Zao@thinkstation>

On Tue, 10 Nov 2026 16:25:54 +0000 Kiryl Shutsemau <kas@kernel.org> wrote:

> On Wed, Nov 04, 2026 at 02:28:06PM -0800, Usama Arif wrote:
> > +#ifdef CONFIG_MITIGATION_ITS
> > +	/*
> > +	 * Returns are patched before alternatives. Align the replacement
> > +	 * source so its return is in the first half of a cache line and ITS
> > +	 * retains its thunk. The copied return can then execute in either
> > +	 * half of a cache line.
> > +	 */
> > +	.pushsection .altinstr_replacement, "ax"
> > +	.balign 64
> > +	.popsection
> > +#endif
> > +	ALTERNATIVE __stringify(cmpq $0x20, %rcx; jb .Lhandle_tail), \
> > +		    __stringify(rep movsb; RET), X86_FEATURE_FSRM
> 
> Does this mean any RET in a replacement needs the same alignment? Would
> anything catch it if the next one doesn't have it?

The issue is specific to address-dependent return handling, such as
ITS. apply_returns() runs before alternatives, so its decision uses
the replacement source address. Copying an unthunked return from the
safe half to the vulnerable half can invalidate that decision. The
patch had no check of the copied return's final ITS placement.

I have kept RET in ordinary text, so the decision now uses the address
where it executes. There is no return in either replacement and no
replacement alignment to maintain.


> 
> Linus' layout keeps the RET out of the replacement, with no padding:
> 
> 	movq %rdi, %rax
> 	movq %rdx, %rcx
> 	ALTERNATIVE "jmp memcpy_orig", "rep movsb", X86_FEATURE_FSRM
> 	RET
> 
> Non-FSRM takes the same jump it takes today. Does that avoid the ITS
> problem? Why not this layout?

Yes. I have adopted that layout and kept memcpy_orig() separate.
The entry prepares RAX and RCX; the scalar function no longer repeats
that preparation. FSRM replaces only the jump with REP MOVSB, leaving
RET in ordinary text. This resolves the ITS source-address issue.


> 
> > +	/*
> > +	 * RCX holds the count for REP MOVSB and scalar copying; RDX is scratch.
> > +	 * Shift RDX to check length >= 2048 without destroying the REP count.
> > +	 * The 10-byte alternative fits a NOP without ERMS.
> > +	 */
> > +	ALTERNATIVE "", __stringify(shrq $11, %rdx; jnz .Lerms), X86_FEATURE_ERMS
> 
> The RCX/RDX swap is most of the diff, and all it saves is one MOV on
> copies of 2K and up.

Agreed that the register change obscured the functional change. I have
split it into a preparatory patch. It consistently uses RCX for scalar
counts and indexes, and RDX for small-copy data. The subsequent ERMS
patch can shift RDX while preserving RCX for REP MOVSB.


> 
> What about something like this? Untested.

The entry layout is now the one you suggested. I retained the RCX
count in a separate patch, so the ERMS arm needs no count reload.
The gate remains after the 32-byte check and keeps the 2048 threshold.


> 
> diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
> --- a/arch/x86/lib/memcpy_64.S
> +++ b/arch/x86/lib/memcpy_64.S
> @@ -31,11 +31,9 @@
>   * which the compiler could/should do much better anyway.
>   */
>  SYM_TYPED_FUNC_START(__memcpy)
> -	ALTERNATIVE "jmp memcpy_orig", "", X86_FEATURE_FSRM
> -
>  	movq %rdi, %rax
>  	movq %rdx, %rcx
> -	rep movsb
> +	ALTERNATIVE "jmp memcpy_orig", "rep movsb", X86_FEATURE_FSRM
>  	RET
>  SYM_FUNC_END(__memcpy)
>  EXPORT_SYMBOL(__memcpy)
> @@ -45,11 +43,11 @@ SYM_PIC_ALIAS(memcpy)
>  EXPORT_SYMBOL(memcpy)
> 
>  SYM_FUNC_START_LOCAL(memcpy_orig)
> -	movq %rdi, %rax
> -
>  	cmpq $0x20, %rdx
>  	jb .Lhandle_tail
> 
> +	ALTERNATIVE "", __stringify(shrq $11, %rcx; jnz .Lerms), X86_FEATURE_ERMS
> +
>  	/*
>  	 * We check whether memory false dependence could occur,
>  	 * then jump to corresponding copy mode.
> @@ -169,5 +167,10 @@ SYM_FUNC_START_LOCAL(memcpy_orig)
> 
>  .Lend:
>  	RET
> +
> +.Lerms:
> +	movq %rdx, %rcx
> +	rep movsb
> +	RET
>  SYM_FUNC_END(memcpy_orig)
> 
> If you keep the swap, please make it a separate patch with no functional
> change.

Done. The first patch changes the scalar register allocation and
initializes RCX in memcpy_orig(), with no copy-policy change. The second
patch hoists that preparation and adds the ERMS path and FSRM layout.

> 
> -- 
>   Kiryl Shutsemau / Kirill A. Shutemov
> 

  parent reply	other threads:[~2026-11-11 12:58 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 22:28 Usama Arif
2026-11-05  8:12 ` David Laight
2026-11-05 17:28   ` Usama Arif
2026-11-10 16:25 ` Kiryl Shutsemau
2026-11-10 17:06   ` David Laight
2026-11-11 13:02     ` Usama Arif
2026-11-11 12:58   ` Usama Arif [this message]
2026-11-10 17:53 ` Linus Torvalds
2026-11-10 19:33   ` David Laight
2026-11-10 20:17   ` H. Peter Anvin
2026-11-10 20:59     ` Linus Torvalds
2026-11-10 22:35       ` David Laight
2026-11-11  1:16       ` Borislav Petkov
2026-11-11 13:24         ` Usama Arif
2026-11-10 21:00     ` David Laight
2026-11-11  0:24       ` H. Peter Anvin
2026-11-11 13:04   ` Usama Arif

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111125832.2541683-1-usama.arif@linux.dev \
    --to=usama.arif@linux.dev \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=david.laight.linux@gmail.com \
    --cc=dsterba@suse.com \
    --cc=hannes@cmpxchg.org \
    --cc=hpa@zytor.com \
    --cc=kas@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=riel@surriel.com \
    --cc=shakeel.butt@linux.dev \
    --cc=terrelln@fb.com \
    --cc=tglx@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®