summaryrefslogtreecommitdiff
path: root/arch/m68k
diff options
context:
space:
mode:
authorDaniel Palmer <daniel@thingy.jp>2025-12-13 21:04:01 +0900
committerSasha Levin <sashal@kernel.org>2026-03-04 07:20:37 -0500
commit47de304543b36adcba8aa1043ca633d497db5691 (patch)
treea6e2234dba5091aefc53fa3c810ef3dccd41a9a4 /arch/m68k
parent1bbcd112bc464cafae0a012de88cb3dbe7f5ae53 (diff)
m68k: nommu: fix memmove() with differently aligned src and dest for 68000
[ Upstream commit 590fe2f46c8698bb758f9002cb247ca10ce95569 ] 68000 has different alignment needs to 68020+. memcpy() checks if the destination is aligned and does a smaller copy to fix the alignment and then critically for 68000 it checks if the source is still unaligned and if it is reverts to smaller copies. memmove() does not currently do the second part and malfunctions if one of the pointers is aligned and the other isn't. This is apparently getting triggered by printk. If I put breakpoints into the new checks added by this commit the first hit looks like this: memmove (n=205, src=0x2f3971 <printk_shared_pbufs+205>, dest=0x2f3980 <printk_shared_pbufs+220>) at arch/m68k/lib/memmove.c:82 Signed-off-by: Daniel Palmer <daniel@thingy.jp> Signed-off-by: Greg Ungerer <gerg@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/lib/memmove.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/m68k/lib/memmove.c b/arch/m68k/lib/memmove.c
index 6519f7f349f6..e33f00b02e4c 100644
--- a/arch/m68k/lib/memmove.c
+++ b/arch/m68k/lib/memmove.c
@@ -24,6 +24,15 @@ void *memmove(void *dest, const void *src, size_t n)
src = csrc;
n--;
}
+#if defined(CONFIG_M68000)
+ if ((long)src & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ for (; n; n--)
+ *cdest++ = *csrc++;
+ return xdest;
+ }
+#endif
if (n > 2 && (long)dest & 2) {
short *sdest = dest;
const short *ssrc = src;
@@ -66,6 +75,15 @@ void *memmove(void *dest, const void *src, size_t n)
src = csrc;
n--;
}
+#if defined(CONFIG_M68000)
+ if ((long)src & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ for (; n; n--)
+ *--cdest = *--csrc;
+ return xdest;
+ }
+#endif
if (n > 2 && (long)dest & 2) {
short *sdest = dest;
const short *ssrc = src;