The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: Borislav Petkov <bp@alien8.de>
Cc: Usama Arif <usama.arif@linux.dev>,
	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,
	kas@kernel.org, hannes@cmpxchg.org, riel@surriel.com,
	shakeel.butt@linux.dev, kernel-team@meta.com
Subject: Re: [PATCH v3 2/2] x86/lib: Use REP MOVSB for large memcpy() on ERMS CPUs without FSRM
Date: Thu, 12 Nov 2026 09:37:29 +0000	[thread overview]
Message-ID: <20261112093729.065afd6c@pumpkin> (raw)
In-Reply-To: <20261111234608.GAavT-QFRo6EtvoL0y@fat_crate.local>

On Wed, 11 Nov 2026 15:46:08 -0800
Borislav Petkov <bp@alien8.de> wrote:

> On Wed, Nov 11, 2026 at 05:20:53AM -0800, Usama Arif wrote:
> > diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
> > index 7bb146c811029..5320862e0274e 100644
> > --- a/arch/x86/lib/memcpy_64.S
> > +++ b/arch/x86/lib/memcpy_64.S
> > @@ -27,15 +27,13 @@
> >   *
> >   * The 'rep movsb' itself is small enough to replace the call, but the
> >   * two register moves blow up the code. And one of them is "needed"
> > - * only for the return value that is the same as the source input,
> > + * only for the return value that is the same as the destination input,
> >   * 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,12 +43,16 @@ SYM_PIC_ALIAS(memcpy)
> >  EXPORT_SYMBOL(memcpy)
> >  
> >  SYM_FUNC_START_LOCAL(memcpy_orig)
> > -	movq %rdi, %rax
> > -	movq %rdx, %rcx
> > -
> >  	cmpq $0x20, %rcx
> >  	jb .Lhandle_tail
> >  
> > +	/*
> > +	 * 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  
> 
> Sorry, this is adding more JMPs in "conditional" alternatives code and thus
> turns this into a bigger and unmaintainable mess than it already is.
> 
> The 2K limit looks like something conjured out of a thin air as it seems it
> work for your particular case. I'm sure we will have to whack it in the future
> because someone else will complain of the opposite.
> 
> This needs to be done with alternative_call*, even at the price of some
> duplicated code but without turning what already is a mess, into a bigger one.

Multiple functions seems like a good idea.

In some cases you can patch the constant in the instruction.
That is safe here even if a multi-byte constant crosses a cache line
because it is only an optimisation.

Patching the call sites would certainly be cleaner.
More interesting would be having a function with a non-standard calling
convention (%rdi, %rsi, %rcx, everything else preserved, void result)
so that the 5 byte call can be patched with "rep movsb; nop3".
I can't see anywhere that uses the result.
Maybe start with "rep movsb; nop3" and patch with the call?
You'd still need a normal memcpy() for the calls gcc makes and if the
address is taken.

A special function to do the patching would also make sense.
All Intel non-atom cpu since sandy bridge run 'rep movsb' as fast
as 'rep movsq' - so you only need to worry about short copies.
Whereas some of the older Zen cpu run misaligned copies slowly.
So you could pick/patch the most appropriate code using more complex
logic than just whether one of the X86_FEATURE_xxx bits is set.

The same calling convention might make sense for memmove().
Although it probably wants a scratch register for the (dst - src < len)
check (it might want dst in the scratch register!).

David

> 
> Or a static key or even with stop_machine_nmi() (currently in review) which
> patches the kernel even later, when it is convenient to do so.
> 
> Whatever it takes to keep this code readable and sane.
> 
> But not this.
> 
> Sorry.
> 


  reply	other threads:[~2026-11-12  9:37 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 13:20 [PATCH v3 0/2] x86/lib: Use REP MOVSB for large memcpy() on ERMS CPUs without FSRM Usama Arif
2026-11-11 13:20 ` [PATCH v3 1/2] x86/lib: Keep the scalar memcpy() count in RCX Usama Arif
2026-11-11 13:20 ` [PATCH v3 2/2] x86/lib: Use REP MOVSB for large memcpy() on ERMS CPUs without FSRM Usama Arif
2026-11-11 13:56   ` Peter Zijlstra
2026-11-11 23:46   ` Borislav Petkov
2026-11-12  9:37     ` David Laight [this message]
2026-11-11 18:19 ` [PATCH v3 0/2] " Kiryl Shutsemau

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=20261112093729.065afd6c@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.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=usama.arif@linux.dev \
    --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