Re: [PATCH] linux-user: Fix msqid_ds struct wrt 32-bit big endian architectures

Helge Deller <[email protected]> Mon, 3 Aug 2026 23:01:35 +0200
Newsgroups gmane.comp.emulators.qemu
Message-ID <anEBr8nK-4nKmuXj@p100>
* Andreas Schwab <[email protected]>:
> On Aug 01 2026, Helge Deller wrote:
> 
> > m68k could be a problem.
> > The other big-arches seem to be handled correctly by the kernel:
> > arch/sparc/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/parisc/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/xtensa/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/x86/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/powerpc/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/mips/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/mips/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> > arch/mips/include/uapi/asm/msgbuf.h:struct msqid64_ds {
> 
> glibc commit 9f9feb6d5d says:
> 
>     * Some older 32-bit big-endian architectures have padding before
>       rather than after time fields, although the preferred generic
>       approach is padding after the time fields independent of endianness.
> 
> and m68k uses the "preferred" approach.

Thanks for the info, Andreas!
The msgctl01 LTP testcase does work correctly on a physical m68k
machine for me, so glibc/kernel seems ok, esp. regarding msqid64_ds.

Regarding qemu linux-user the patch below seems to fix the LTP msgctl01
testcase in my m68k qemu chroot. Peter, do you mind reviewing the patch?

Helge
-------

From: Helge Deller <[email protected]>
Date: Mon, 3 Aug 2026 22:49:46 +0200
Subject: [PATCH] linux-user: Fox msqid64_ds for 32-bit big endian m68k target

On some older 32 bit big-endian architectures (like m68k) the 64-bit time
fields of msqid64_ds is a pair of unsigned long values, where the lower
half is in the wrong place. Adjust the target_swap_time64() macro
accordingly.

Fixes: 9e3df3019d21 ("linux-user: Fix msqid_ds struct wrt 32-bit big endian architectures")
Noticed-by: Peter Maydell <[email protected]>
Signed-off-by: Helge Deller <[email protected]>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dc028686f4..1a18fea52d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4217,7 +4217,16 @@ static inline abi_long do_semtimedop(int semid,
 #endif
 
 #define target_time64_t         abi_ullong
-#define target_swap_time64(x)   tswap64(x)
+/*
+  * On some older 32 bit big-endian architectures (like m68k) the 64-bit time
+  * fields of msqid64_ds is a pair of unsigned long values, where the lower
+  * half is in the wrong place.
+ */
+#ifdef TARGET_M68K
+# define target_swap_time64(x)   (tswap32(x) | (((uint64_t)tswap32((x) >> 32)) << 32))
+#else
+# define target_swap_time64(x)   tswap64(x)
+#endif
 
 struct target_msqid_ds
 {