Re: [PATCH] linux-user: Fix msqid_ds struct wrt 32-bit big endian architectures
Helge Deller <[email protected]> Sat, 1 Aug 2026 23:38:56 +0200
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
(Adding Geert as kernel m68k maintainer) On 8/1/26 22:58, Helge Deller wrote: > On 8/1/26 14:11, Peter Maydell wrote: >> On Fri, 31 Jul 2026 at 20:36, Helge Deller <[email protected]> wrote: >>> >>> Hello Peter, >>> >>> On 7/31/26 20:05, Peter Maydell wrote: >>>> On Tue, 28 Jul 2026 at 20:32, Helge Deller <[email protected]> wrote: >>>>> >>>>> From: Helge Deller <[email protected]> >>>>> >>>>> Make sure that the time entries (msg_stime, msg_rtime and msg_ctime) >>>>> are defined as 64-bit time_t values, since the userspace may access >>>>> the whole 64-bit value. By this change we fix the word ordering for >>>>> 32-bit big endian architectures as well. >>>>> >>>>> This fixes the msgctl01 LTP testcase on hppa32. >>>>> >>>>> Signed-off-by: Helge Deller <[email protected]> >>>>> --- >>>>> linux-user/syscall.c | 30 ++++++++++++------------------ >>>>> 1 file changed, 12 insertions(+), 18 deletions(-) >>>>> >>>>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c >>>>> index 740142825d..c93b770ced 100644 >>>>> --- a/linux-user/syscall.c >>>>> +++ b/linux-user/syscall.c >>>>> @@ -4216,21 +4216,15 @@ static inline abi_long do_semtimedop(int semid, >>>>> } >>>>> #endif >>>> >>>> I see this has already gone into git, but some late review >>>> comments. I suspect this is mostly me being confused rather >>>> than actual problems. >>>> >>>>> >>>>> +#define target_time64_t abi_ullong >>>>> +#define target_swap_time64(x) tswap64(x) >>>>> + >>>>> struct target_msqid_ds >>>> >>>> Is this the kernel's "struct msqid_ds" (which it calls "Obsolete, used >>>> only for backwards compatibility and libc5 compiles") or its msqid64_ds? >>> >>> Yes, it's msqid64_ds. >>> >>>> The layout matches msqid64_ds, which makes our struct a bit >>>> confusingly named. >>> >>> True. >>> In a follow-up patch this better should be renamed to target_msqid64_ds. >>> >>>>> { >>>>> struct target_ipc_perm msg_perm; >>>>> - abi_ulong msg_stime; >>>>> -#if TARGET_ABI_BITS == 32 >>>>> - abi_ulong __unused1; >>>>> -#endif >>>>> - abi_ulong msg_rtime; >>>>> -#if TARGET_ABI_BITS == 32 >>>>> - abi_ulong __unused2; >>>>> -#endif >>>>> - abi_ulong msg_ctime; >>>>> -#if TARGET_ABI_BITS == 32 >>>>> - abi_ulong __unused3; >>>>> -#endif >>>>> + target_time64_t msg_stime; >>>>> + target_time64_t msg_rtime; >>>>> + target_time64_t msg_ctime; >>>> >>>> Assuming msqid64_ds, the kernel version of this struct has a comment: >>>> * 64 bit architectures use a 64-bit long time field here, while >>>> * 32 bit architectures have a pair of unsigned long values. >>>> * On big-endian systems, the lower half is in the wrong place. >>> >>> Those comments are from the generic header: >>> include/uapi/asm-generic/msgbuf.h >>> and I think the last sentence about big-endian systems is wrong, as >>> most platforms provide an own architecture-specific header file, e.g: >>> arch/xtensa/include/uapi/asm/msgbuf.h >>> and the big-endian platforms seem to have their high-word first. >> >> The comment is correct for any bigendian 32-bit system that >> uses the kernel's asm-generic structure. Maybe there just aren't >> any of those that we care about? > > 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 { > >>>> That would make tswap64() not the right swap for 32-bit big >>>> endian guests. >>> >>> I did my testing on the 32-bit hppa/parisc platform, and with my patch >>> the results in qemu were correct and were the same as on physical machines. >>> >>> I just tried in a 32-bit powerpc chroot and the msgctl01 now succeeds there as well. >>> So, I think my patch is generally ok. >> >> Yeah, 32-bit powerpc also provides its own structure definition. >> >> I think it's worth having a comment about this, at least, because >> otherwise the obvious assumption is that our struct which has >> no target-specific ifdefs is supposed to match the kernel's >> asm-generic struct. > > Yes, I will the testing on m68k, afterwards I can come up with a proposal. > Maybe it makes sense to modify the kernel comment too.... The msgctl01 testcase from LTP gives this preprocessed code on m68k: ... # 27 "/usr/include/m68k-linux-gnu/bits/types/struct_msqid_ds.h" 3 4 struct msqid_ds { # 1 "/usr/include/m68k-linux-gnu/bits/types/struct_msqid64_ds_helper.h" 1 3 4 # 20 "/usr/include/m68k-linux-gnu/bits/types/struct_msqid64_ds_helper.h" 3 4 struct ipc_perm msg_perm; __time64_t msg_stime; __time64_t msg_rtime; __time64_t msg_ctime; __syscall_ulong_t __msg_cbytes; msgqnum_t msg_qnum; msglen_t msg_qbytes; __pid_t msg_lspid; __pid_t msg_lrpid; unsigned long int __glibc_reserved4; unsigned long int __glibc_reserved5; # 31 "/usr/include/m68k-linux-gnu/bits/types/struct_msqid_ds.h" 2 3 4 # 53 "/usr/include/m68k-linux-gnu/bits/types/struct_msqid_ds.h" 3 4 }; but the testcase fails with: msgctl01.c:53: TFAIL: msg_ctime = 6a6e65d900000000, expected 6a6e65d9 So, for m68k either the glibc or the kernel is wrong. At least they don't agree with each other. I think it would be beneficial, if the m68k kernel would follow m68k's glibc implementation of msqid64_ds. Helge