Re: [PATCH] x86/lib: Use REP MOVSB for large memcpy() on ERMS CPUs without FSRM
From: Usama Arif
Date: Mon Nov 02 2026 - 18:03:51 EST
On 22/10/2026 10:49, David Laight wrote:
> On Wed, 21 Oct 2026 08:18:25 -1000
> Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
>> On Tue, 20 Oct 2026 at 23:55, Kiryl Shutsemau <kas@xxxxxxxxxx> wrote:
>>>
>>> Moving MOVQ inside ALTERNATIVE_2 is ugly...
>>
>> Yeah, maybe it would make sense to make that function be
>>
>> movq %rdi, %rax
>> movq %rdx, %rcx
>> ALTERNATIVE "jmp memcpy_orig", "rep movsb", X86_FEATURE_FSRM
>> RET
>>
>> instead? No nop instructions at all, and both alternatives are two bytes.
>>
>> Then do any ERMS logic at the top of memcpy_orig, which now has the
>> registers ready for string instructions anyway.
>
> Is it possibly to just patch "rep movsb; RET" over whatever gets generated
> for memcpy_orig (after the two register moves) ?
> Then there are neither nops nor a jmp.
>
> David
>
Hi,
Sorry for the late reply. I had taken time off for the past couple of weeks
and didnt have access to my work station.
I implemented Davids suggestion and I think it looks good. The scalar body is
now part of __memcpy(), and FSRM replaces the existing 32-byte check with
"rep movsb; RET". Non-FSRM calls fall straight into scalar code, and FSRM
returns before any padding.
I have retained the 2048-byte ERMS cutoff, since selecting REP from 32 bytes
regressed short copies in the Cooper Lake tests.
I asked LLM to review it and it indicated a problem with ITS: returns are
patched before alternatives are copied, so the return decision uses the
replacement's source address. I align replacement storage outside the
copied range so ITS retains the return thunk and relocation preserves its
target. This adds no executed padding.
Any thoughts on below? I will send it as a proper patch for review
if it looks acceptable.