author: Matteo Croce <mcroce@microsoft.com> 2021-07-16 13:45:50 +1000
committer: Emil Renner Berthing <kernel@esmil.dk> 2021-08-01 13:54:33 +0200
commit: fe093584bd428d561c6433843664b82d177942e7
parent: 30fa45b96fb40b6bf0efd5deee46a63860d16c36
Commit Summary:
Diffstat:
1 file changed, 27 insertions, 2 deletions
diff --git a/lib/string.c b/lib/string.c
index bc2b68b12236..1bff04a96b1d 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -810,10 +810,38 @@ EXPORT_SYMBOL(__sysfs_match_string);
*/
void *memset(void *s, int c, size_t count)
{
- char *xs = s;
+ union types dest = { .as_u8 = s };
+ if (count >= MIN_THRESHOLD) {
+ unsigned long cu = (unsigned long)c;
+
+ /* Compose an ulong with 'c' repeated 4/8 times */
+#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
+ cu *= 0x0101010101010101UL;
+#else
+ cu |= cu << 8;
+ cu |= cu << 16;
+ /* Suppress warning on 32 bit machines */
+ cu |= (cu << 16) << 16;
+#endif
+ if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ /*
+ * Fill the buffer one byte at time until
+ * the destination is word aligned.
+ */
+ for (; count && dest.as_uptr & WORD_MASK; count--)
+ *dest.as_u8++ = c;
+ }
+
+ /* Copy using the largest size allowed */
+ for (; count >= BYTES_LONG; count -= BYTES_LONG)
+ *dest.as_ulong++ = cu;
+ }
+
+ /* copy the remainder */
while (count--)
- *xs++ = c;
+ *dest.as_u8++ = c;
+
return s;
}
EXPORT_SYMBOL(memset);