f991f01571
Most architectures now use the asm-generic copy of the sysvipc data
structures (msqid64_ds, semid64_ds, shmid64_ds), which use 32-bit
__kernel_time_t on 32-bit architectures but have padding behind them to
allow extending the type to 64-bit.
Unfortunately, that fails on all big-endian architectures, which have the
padding on the wrong side. As so many of them get it wrong, we decided to
not bother even trying to fix it up when we introduced the asm-generic
copy. Instead we always use the padding word now to provide the upper
32 bits of the seconds value, regardless of the endianess.
A libc implementation on a typical big-endian system can deal with
this by providing its own copy of the structure definition to user
space, and swapping the two 32-bit words before returning from the
semctl/shmctl/msgctl system calls.
Note that msqid64_ds and shmid64_ds were broken on x32 since commit
f4b4aae182
("x86/headers/uapi: Fix __BITS_PER_LONG value for x32
builds"). I have sent a separate fix for that, but as we no longer
have to worry about x32 here, I no longer worry about x32 here and
use 'unsigned long' instead of __kernel_ulong_t.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
48 lines
1.6 KiB
C
48 lines
1.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
#ifndef __ASM_GENERIC_MSGBUF_H
|
|
#define __ASM_GENERIC_MSGBUF_H
|
|
|
|
#include <asm/bitsperlong.h>
|
|
/*
|
|
* generic msqid64_ds structure.
|
|
*
|
|
* Note extra padding because this structure is passed back and forth
|
|
* between kernel and user space.
|
|
*
|
|
* msqid64_ds was originally meant to be architecture specific, but
|
|
* everyone just ended up making identical copies without specific
|
|
* optimizations, so we may just as well all use the same one.
|
|
*
|
|
* 64 bit architectures typically define a 64 bit __kernel_time_t,
|
|
* so they do not need the first three padding words.
|
|
* On big-endian systems, the padding is in the wrong place.
|
|
*
|
|
* Pad space is left for:
|
|
* - 2 miscellaneous 32-bit values
|
|
*/
|
|
|
|
struct msqid64_ds {
|
|
struct ipc64_perm msg_perm;
|
|
#if __BITS_PER_LONG == 64
|
|
__kernel_time_t msg_stime; /* last msgsnd time */
|
|
__kernel_time_t msg_rtime; /* last msgrcv time */
|
|
__kernel_time_t msg_ctime; /* last change time */
|
|
#else
|
|
unsigned long msg_stime; /* last msgsnd time */
|
|
unsigned long msg_stime_high;
|
|
unsigned long msg_rtime; /* last msgrcv time */
|
|
unsigned long msg_rtime_high;
|
|
unsigned long msg_ctime; /* last change time */
|
|
unsigned long msg_ctime_high;
|
|
#endif
|
|
unsigned long msg_cbytes; /* current number of bytes on queue */
|
|
unsigned long msg_qnum; /* number of messages in queue */
|
|
unsigned long msg_qbytes; /* max number of bytes on queue */
|
|
__kernel_pid_t msg_lspid; /* pid of last msgsnd */
|
|
__kernel_pid_t msg_lrpid; /* last receive pid */
|
|
unsigned long __unused4;
|
|
unsigned long __unused5;
|
|
};
|
|
|
|
#endif /* __ASM_GENERIC_MSGBUF_H */
|