[PATCH v2] x86/boot: add volatile, clobbers and zero-length test in memcmp()

Mauricio Faria de Oliveira posted 1 patch 22 hours ago
arch/x86/boot/string.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
[PATCH v2] x86/boot: add volatile, clobbers and zero-length test in memcmp()
Posted by Mauricio Faria de Oliveira 22 hours ago
Add the volatile qualifier and clobbers parameter to prevent bugs with
instruction reordering and optimization.

Also add TEST for the zero-length case to set ZF, as, if the count register
is zero, the REPE prefix does not run the CMPSB instruction, leaving the ZF
flag undetermined.

Suggested-by: Borislav Petkov <bp@alien8.de>
Closes: https://sashiko.dev/#/patchset/20260701-pvh-kasan-inline-v6-0-ba99045dfa9f%40igalia.com
Link: https://lore.kernel.org/all/20260718150230.GAaluVhlozNI__9IsA@fat_crate.local/
Fixes: 62bd0337d0c4 ("Top header file for new x86 setup code")
Link: https://lore.kernel.org/all/20260722170334.GCamD35gwrCng30WH1@fat_crate.local/
Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
Sending this patch separately from its previous series ("v1" below) as requested [1].

The backports for 6.12 and earlier will be slightly different due to
commit c6c973dbfa5e ("x86/asm: Remove code depending on __GCC_ASM_FLAG_OUTPUTS__").
I'd be happy to handle it.

The disassembly of memcmp() in arch/x86/boot/string.o is as expected:

  32:   66 85 c9                test   %cx,%cx
  35:   f3 a6                   repz cmpsb %es:(%edi),%ds:(%esi)
  37:   0f 95 c0                setne  %al

And bzImage still boots.

[1] https://lore.kernel.org/all/20260722170334.GCamD35gwrCng30WH1@fat_crate.local/

Changes in v2:
- Remove this patch from "v1" series (Borislav Petkov).
- Change some words' capitalization/quotes (Borislav Petkov).
- Change zero-length check from C to asm (H. Peter Anvin).
- Link to "v1": https://lore.kernel.org/all/20260721-pvh-kasan-inline-v7-2-38979a50cef0@igalia.com/
---
 arch/x86/boot/string.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c
index ac0f900ebc47efa81c92e1bb2010ea41677899c4..6827551720dd9b96afe8c55a051401d6cdc6f05e 100644
--- a/arch/x86/boot/string.c
+++ b/arch/x86/boot/string.c
@@ -32,8 +32,10 @@
 int memcmp(const void *s1, const void *s2, size_t len)
 {
 	bool diff;
-	asm("repe cmpsb"
-	    : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	asm volatile("test %3, %3\n\t"
+		     "repe cmpsb"
+		     : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len)
+		     : : "cc", "memory");
 	return diff;
 }
 

---
base-commit: b4515cf4156356e8f4fe6e0fdc17f59adab9772f
change-id: 20260723-x86-memcmp-asm-082937e9c391

Best regards,
-- 
Mauricio Faria de Oliveira <mfo@igalia.com>