From: David Laight <david.laight.linux@gmail.com>
To: Kiryl Shutsemau <kas@kernel.org>
Cc: Usama Arif <usama.arif@linux.dev>,
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: Tue, 10 Nov 2026 17:06:55 +0000 [thread overview]
Message-ID: <20261110170655.35a7c439@pumpkin> (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?
My suspicion is that ideally 'yes'.
But someone said (in this thread) that it is worse for RET in the first
half a cache line - so aligning the replacement that way is better.)
> 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?
It adds a jump to the non-FSRM path.
Cold cache that is likely to be measurable.
(But not if RET ends up being anything other than 0xc3 - that will
just kill everything.)
>
> > + /*
> > + * 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.
Register-register moves don't cost much (they can even be done my the
register renaming logic rather than the alu - but still have to be
fetched and decoded), but needing them is a bit of 'lack of attention
detail' when a simple backtrack can get the value where it is needed.
gcc is very bad at it, a compiler really ought to do a lot better.
David
>
> What about something like this? Untested.
>
> 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.
>
prev parent reply other threads:[~2026-11-10 17:06 UTC|newest]
Thread overview: 5+ 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 [this message]
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=20261110170655.35a7c439@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
all inboxes | Powered by JetHome®