On Thu, Apr 19, 2018 at 5:20 PM, Arnd Bergmann <arnd@xxxxxxxx> wrote: > On Thu, Apr 19, 2018 at 4:59 PM, Eric W. Biederman <ebiederm@xxxxxxxxxxxx> wrote: >> I suspect you want to use __kernel_ulong_t here instead of a raw >> unsigned long. If nothing else it seems inconsistent to use typedefs >> in one half of the structure and no typedefs in the other half. > > Good catch, there is definitely something wrong here, but I think using > __kernel_ulong_t for all members would also be wrong, as that > still changes the layout on x32, which effectively is > > struct msqid64_ds { > ipc64_perm msg_perm; > u64 msg_stime; > u32 __unused1; > /* 32 bit implict padding */ > u64 msg_rtime; > u32 __unused2; > /* 32 bit implict padding */ > u64 msg_ctime; > u32 __unused3; > /* 32 bit implict padding */ > __kernel_pid_t shm_cpid; /* pid of creator */ > __kernel_pid_t shm_lpid; /* pid of last operator */ > .... > }; > > The choices here would be to either use a mix of > __kernel_ulong_t and unsigned long, or taking the x32 > version back into arch/x86/include/uapi/asm/ so the > generic version at least makes some sense. > > I can't use __kernel_time_t for the lower half on 32-bit > since it really should be unsigned. After thinking about it some more, I conclude that the structure is simply incorrect on x32: The __kernel_ulong_t usage was introduced in 2013 in commit b9cd5ca22d67 ("uapi: Use __kernel_ulong_t in struct msqid64_ds") and apparently was correct initially as __BITS_PER_LONG evaluated to 64, but it broke with commit f4b4aae18288 ("x86/headers/uapi: Fix __BITS_PER_LONG value for x32 builds") that changed the value of __BITS_PER_LONG and introduced the extra padding in 2015. The same change apparently also broke a lot of other definitions, e.g. $ echo "#include <linux/types.h>" | gcc -mx32 -E -xc - | grep -A3 __kernel_size_t typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; Those used to be defined as 'unsigned long long' and 'long long' respectively, so now all kernel interfaces using those on x32 became incompatible! Arnd