s390/string: Convert memset(16|32|64)() to C

Convert memset(16|32|64)() from assembler to C, which should make it
easier to read and change, if required. And it allows the compiler to
optimize the code, and use different instructions, except for the used
inline assemblies.

Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
Heiko Carstens
2026-06-09 12:33:41 +02:00
committed by Alexander Gordeev
parent 611b5c1f60
commit 90d7412cd1
7 changed files with 50 additions and 70 deletions

View File

@@ -31,7 +31,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
CFLAGS_string.o = -ffreestanding
obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
obj-y += string.o ebcdic.o sclp_early_core.o ipl_vmparm.o cmdline.o
obj-y += version.o pgm_check.o ctype.o ipl_data.o relocs.o alternative.o
obj-y += uv.o printk.o trampoline.o
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o

View File

@@ -1,2 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include "../lib/mem.S"

View File

@@ -43,11 +43,7 @@ ssize_t sized_strscpy(char *dst, const char *src, size_t count)
void *memset64(uint64_t *s, uint64_t v, size_t count)
{
uint64_t *xs = s;
while (count--)
*xs++ = v;
return s;
return __memset64(s, v, count * sizeof(v));
}
char *skip_spaces(const char *str)

View File

@@ -10,7 +10,6 @@ CFLAGS_string.o = -ffreestanding
lib-y += delay.o string.o uaccess.o find.o spinlock.o tishift.o
lib-y += csum-partial.o
obj-y += mem.o
lib-$(CONFIG_KPROBES) += probes.o
lib-$(CONFIG_UPROBES) += probes.o
obj-$(CONFIG_S390_KPROBES_SANITY_TEST) += test_kprobes_s390.o

View File

@@ -1,57 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* String handling functions.
*
* Copyright IBM Corp. 2012
*/
#include <linux/export.h>
#include <linux/linkage.h>
#include <asm/nospec-insn.h>
GEN_BR_THUNK %r14
/*
* __memset16/32/64
*
* void *__memset16(uint16_t *s, uint16_t v, size_t count)
* void *__memset32(uint32_t *s, uint32_t v, size_t count)
* void *__memset64(uint64_t *s, uint64_t v, size_t count)
*/
.macro __MEMSET bits,bytes,insn
SYM_FUNC_START(__memset\bits)
ltgr %r4,%r4
jz .L__memset_exit\bits
cghi %r4,\bytes
je .L__memset_store\bits
aghi %r4,-(\bytes+1)
srlg %r5,%r4,8
ltgr %r5,%r5
lgr %r1,%r2
jz .L__memset_remainder\bits
.L__memset_loop\bits:
\insn %r3,0(%r1)
mvc \bytes(256-\bytes,%r1),0(%r1)
la %r1,256(%r1)
brctg %r5,.L__memset_loop\bits
.L__memset_remainder\bits:
\insn %r3,0(%r1)
exrl %r4,.L__memset_mvc\bits
BR_EX %r14
.L__memset_store\bits:
\insn %r3,0(%r2)
.L__memset_exit\bits:
BR_EX %r14
.L__memset_mvc\bits:
mvc \bytes(1,%r1),0(%r1)
SYM_FUNC_END(__memset\bits)
.endm
__MEMSET 16,2,sth
EXPORT_SYMBOL(__memset16)
__MEMSET 32,4,st
EXPORT_SYMBOL(__memset32)
__MEMSET 64,8,stg
EXPORT_SYMBOL(__memset64)

View File

@@ -158,6 +158,53 @@ EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(memcpy);
#endif
#define DEFINE_MEMSET(_bits, _bytes, _type) \
void *__memset##_bits(_type *s, _type v, size_t n) \
{ \
_type *xs = s; \
\
if (!n) \
return s; \
while (n >= 256) { \
*xs = v; \
asm volatile( \
" mvc %[_b](256-%[_b],%[xs]),0(%[xs])\n" \
: \
: [xs] "a" (xs), [_b] "i" (_bytes) \
: "memory"); \
xs = (_type *)((char *)xs + 256); \
n -= 256; \
} \
if (!n) \
return s; \
*xs = v; \
if (n == _bytes) \
return s; \
n -= _bytes + 1; \
asm volatile( \
" exrl %[n],1f\n" \
" j 2f\n" \
"1: mvc %[_b](1,%[xs]),0(%[xs])\n" \
"2:" \
: \
: [n] "a" (n), [xs] "a" (xs), [_b] "i" (_bytes) \
: "memory"); \
return s; \
} \
EXPORT_SYMBOL(__memset##_bits)
#ifdef __HAVE_ARCH_MEMSET16
DEFINE_MEMSET(16, 2, uint16_t);
#endif
#ifdef __HAVE_ARCH_MEMSET32
DEFINE_MEMSET(32, 4, uint32_t);
#endif
#ifdef __HAVE_ARCH_MEMSET64
DEFINE_MEMSET(64, 8, uint64_t);
#endif
/*
* Helper functions to find the end of a string
*/

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
purgatory-y := head.o purgatory.o string.o sha256.o mem.o
purgatory-y := head.o purgatory.o string.o sha256.o
targets += $(purgatory-y) purgatory.lds purgatory purgatory.chk purgatory.ro
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
@@ -10,9 +10,6 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
CFLAGS_sha256.o := -D__NO_FORTIFY
$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE
$(call if_changed_rule,as_o_S)
CC_FLAGS_MARCH_MINIMUM := -march=z10
KBUILD_CFLAGS := $(CC_FLAGS_DIALECT) -fno-strict-aliasing -Wall -Wstrict-prototypes