From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x144.google.com (mail-il1-x144.google.com [IPv6:2607:f8b0:4864:20::144]) by sourceware.org (Postfix) with ESMTPS id D8EFC385DC26 for ; Thu, 30 Apr 2020 21:33:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D8EFC385DC26 Received: by mail-il1-x144.google.com with SMTP id w6so2839358ilg.1 for ; Thu, 30 Apr 2020 14:33:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=xIZYhCmD55Tb2Ov+f9rd04mnx2wvEPonAVn7jlPEb1Y=; b=K9lS/06M6717M8QQbPFC5EY5UBmLxFHpkNDYgINnBIbrO7ZrbBUcwlk5EufQ5ZxzyT qgzDjcaYNLMgpeOEv+dm7/ZAy79DU4woMt+Li97JcSD0cn+LscQBTYg4V9E/ipAZEXxA cNj50OufoA2jkXc97y7IuHRXqYZ+zzkkrHQjfx8dL/+qx8mjhiIRokH6J1Sq5b6UyPHj cNW7nflM9UvKy9yfO1AiluDL6YRGq2bUgN9L31T0PPb2rRsHs/lU1jxiTp6oGZWW9bMi bg9Z4uqSwnj3mMKNR5TeWcnMc+bm8yJN7VatfnMqM/TLrv4E04sBN1e6YABkDfD6dMLP Y8OA== X-Gm-Message-State: AGi0PuZ5Z4DACuUvfT7Bh09ufl/AgmvpQWY11+thoRmiNC3WpG3Fv13P W4SDzOPaBfl+xHU1NPOTbZ8tjWjuIHwar4OCpjDyASdpd7M= X-Google-Smtp-Source: APiQypLki83ptSLnSKgePwDCNmERLkdw+Znpfq5q0Y3rFjFDUPwR86AkcXXIH+oiOdUDOG/oT6v/RaY1SrNfSA4LFRk= X-Received: by 2002:a92:d5cf:: with SMTP id d15mr451163ilq.131.1588282427719; Thu, 30 Apr 2020 14:33:47 -0700 (PDT) MIME-Version: 1.0 References: <20200428220507.3409362-1-alistair.francis@wdc.com> <20200428220507.3409362-4-alistair.francis@wdc.com> <3bec18bd-cbee-5853-2d36-df377b6cf7cf@linaro.org> <8b082c6c-a025-233f-a396-120349f02d38@linaro.org> In-Reply-To: <8b082c6c-a025-233f-a396-120349f02d38@linaro.org> From: Alistair Francis Date: Thu, 30 Apr 2020 14:25:12 -0700 Message-ID: Subject: Re: [PATCH v6 3/3] sysv: linux: Pass 64-bit version of semctl syscall To: Adhemerval Zanella Cc: GNU C Library , Alistair Francis , Arnd Bergmann Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-19.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 21:33:52 -0000 On Thu, Apr 30, 2020 at 8:06 AM Adhemerval Zanella wrote: > > > > On 29/04/2020 20:24, Alistair Francis wrote: > > On Wed, Apr 29, 2020 at 2:09 PM Adhemerval Zanella > > wrote: > >> > >> > >> > >> On 28/04/2020 19:05, Alistair Francis via Libc-alpha wrote: > >>> The semctl_syscall() function passes a union semun to the kernel. The > >>> union includes struct semid_ds as a member. On 32-bit architectures the > >>> Linux kernel provides a *_high version of the 32-bit sem_otime and > >>> sem_ctime values. These can be combined to get a 64-bit version of the > >>> time. > >>> > >>> This patch adjusts the struct semid_ds to support the *_high versions > >>> of sem_otime and sem_ctime. For 32-bit systems with a 64-bit time_t > >>> this can be used to get a 64-bit time from the two 32-bit values. > >>> > >>> Due to alignment differences between 64-bit and 32-bit variables we > >>> also need to set nsems to ensure it's correct. > >> > >> I think this approach might trigger an issue on semid_ds definition for > >> time64 that I only noticed now. > >> > >> Since the idea of semctl is not use a different entrypoint neither to add > >> aditional flag when issuing the syscall (either semctl or ipc), with this > >> change we need to assure that __TIMESIZE == 32 sem_otime alignment matches > >> __TIMESIZE == 64 one. > > > > I don't follow. We don't assume that sem_otime has the same allignment > > for __TIMESIZE == 32 and 64. In fact for RV32 they are not alligned > > the same. > > > >> > >> However for semid_ds and msqid_ds time_t members can't not properly aligned > >> to be expanded to 64-bit (shmid_ds has a shm_segsz field before the > >> timestamp fields) due to the ipc_perm header consisting of 9 32-bit words > >> except on parisc/powerpc/sparc. The alignment difference will make > >> semctl once programs states build against a semid_ds with time_t > >> being an 64-bit type. > > > > I am missing something here as well, as that is exactly what RV32 is > > testing and the glibc tests are passing (and a LInux rootFS boots). > > The issue is for architectures that might select the __TIMESIZE at build > time, so two different semid_ds structure might be used with semctl. > For instance, on arm with current scheme: > > For __TIMESIZE == 32: > sizeof (struct ipc_perm): 36 > sizeof (struct semid_ds): 72 > offsetof (struct semid_ds, sem_perm): 0 > offsetof (struct semid_ds, sem_otime): 40 > offsetof (struct semid_ds, sem_ctime): 48 > offsetof (struct semid_ds, sem_nsems): 56 > > For __TIMESIZE == 64: > sizeof (struct ipc_perm): 36 > sizeof (struct semid_ds): 64 > offsetof (struct semid_ds, sem_perm): 0 > offsetof (struct semid_ds, sem_otime): 36 > offsetof (struct semid_ds, sem_ctime): 44 > offsetof (struct semid_ds, sem_nsems): 52 > > The syscall itself will use the expected structure, however the code: > > if (ret >= 0 && restore) > { > arg.buf = orig; > arg.buf->sem_perm = tmp.sem_perm; > arg.buf->sem_otime = tmp.sem_otime > | ((time_t) tmp.sem_otime_high << 32); > arg.buf->sem_ctime = tmp.sem_ctime > | ((time_t) tmp.sem_ctime_high << 32); > arg.buf->sem_nsems = tmp.sem_nsems; > > will write down the timestamps on wrong place for time64 timestamps. Ok, I think I understand now. > > This is not an issue for 32-bit architectures that does not have > support for 32-bit time_t (as RV32). > > > > >> > >> So we have 2 options here: > >> > >> 1. Keep the semid_ds layout as the kernel expected one and add the > >> newer time64 timestamps at the *end*, and redefine the command > >> arguments that passes a struct semid_ds to use > >> (IPC_STAT, SEM_STAT, SEM_STAT_ANY) to indicate that the semid_ds > >> is a time64 one. The IPC_64 bit might be a feasible hack since > >> kernel won't use on possible new commands. > > This solution would require to redefine IPC_STAT, SEM_STAT, SEM_STAT_ANY to > a different value for when building for __TIMESIZE==64 on ABIs that support > its selection. The easiest way would to parametrize the ipc commands > that handle per architecture: > > /* On each ABI that supports __TIMESIZE==32. */ > #if __TIMESIZE == 64 > # define __IPC_CMD_TIME_64 0x100 /* Same as __IPC_64. */ > #else > # define __IPC_CMD_TIME_64 0x0 > #endif > #define __IPC_TIME_64 1 So this should be for every __WORDSIZE ==32 except RV32? I'm not sure of a good place to put this though > > If fro architecture only support __TIMESIZE64 (default): > > #define __IPC_CMD_TIME64 0x0 > #define __IPC_TIME_64 0 For all __WORDSIZE == 64 and RV32. I have this in ipc_priv.h (before the include sys/ipc.h) but I'm not sure if that will work, testing now. > > Then on Linux ipc.h: > > #define IPC_STAT (2 | __IPC_CMD_TIME_64) Done. > > Same for sem.h: > > #define SEM_STAT (18 | __IPC_CMD_TIME_64) > #define SEM_STAT_ANY (20 | __IPC_CMD_TIME_64) Done. > > Then on semctl.c (totally untested): > > --- > union semun > { > int val; /* value for SETVAL */ > #if __IPC_TIME_64 > struct __semid_ds32 *buf32; > #endif > struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ > unsigned short int *array; /* array for GETALL & SETALL */ > struct seminfo *__buf; /* buffer for IPC_INFO */ > }; > > int > __new_semctl (int semid, int semnum, int cmd, ...) > { > /* POSIX states ipc_perm mode should have type of mode_t. */ > _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode) > == sizeof (mode_t), > "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); > > union semun arg = { 0 }; > va_list ap; > > /* Get the argument only if required. Ignore the __IPC_STAT_64. */ > switch (cmd & ~__IPC_CMD_TIME_64) > { > case SETVAL: /* arg.val */ > case GETALL: /* arg.array */ > case SETALL: > case IPC_STAT & ~__IPC_CMD_TIME_64: /* arg.buf */ > case IPC_SET: > case SEM_STAT & ~__IPC_CMD_TIME_64: > case IPC_INFO: /* arg.__buf */ > case SEM_INFO: > va_start (ap, cmd); > arg = va_arg (ap, union semun); > va_end (ap); > break; > } > > #ifdef __IPC_TIME_64 > struct __semid_ds32 tmp32; > struct __semid_ds64 *orig64; > if (cmd & __IPC_STAT_64) > { > tmp32 = (struct __semid_ds32) { 0 }; > orig64 = (struct __semid_ds64 *) arg.buf; > arg.buf32 = tmp32; > } > #endif > > #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > struct semid_ds tmpds; > if (cmd == IPC_SET) > { > tmpds = *arg.buf; > tmpds.sem_perm.mode *= 0x10000U; > arg.buf = &tmpds; > } > #endif > > int ret = semctl_syscall (semid, semnum, cmd & ~__IPC_CMD_TIME_64, arg); > if (ret < 0) > return ret; > > switch (cmd & ~__IPC_CMD_TIME_64) > { > case IPC_STAT: > case SEM_STAT: > case SEM_STAT_ANY: > #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > # if __IPC_TIME_64 > arg.buf32->sem_perm.mode >>= 16; > # else > arg.buf->sem_perm.mode >>= 16; > # endif > #else > /* Old Linux kernel versions might not clear the mode padding. */ > if (sizeof ((struct semid_ds){0}.sem_perm.mode) > ! = sizeof (__kernel_mode_t)) > # if __IPC_TIME_64 > arg.buf32->sem_perm.mode &= 0xFFFF; > # else > arg.buf->sem_perm.mode &= 0xFFFF; > # endif > #endif > } > > #ifdef __IPC_TIME_64 > if (cmd & & ~__IPC_CMD_TIME_64) > { > orig64->sem_perm = tmp32.sem_perm; > orig64->sem_otime = tmp32.sem_otime > | ((__time64_t) tmp32.sem_otime_high << 32); > orig64->sem_ctime = tmp32.sem_ctime > | ((__time64_t) tmp32.sem_ctime_high << 32); > orig64->sem_nsems = tmp32.sem_nsems; > arg.buf = (struct semid_ds *) orig64; > } > #endif > > return ret; > } Ok, compile testing now. Alistair > --- > > So basically: > > 1. If an ABI issues 'semctl (semid, semnum, IPC_STAT, ...)' with > IPC_STAT without _IPC_CMD_TIME_64, the provided semid_ds buffe > will be used directly on the syscall. This is the case for > 64-bit architectures and 32-bit architecture without > __TIMESIZE==32 support (RV32 for instance). > > 2. If an ABI issues 'semctl (semid, semnum, IPC_STAT, ...)' with > IPC_STAT with _IPC_CMD_TIME_64 then __TIMESIZE==64 is implied. > A temporary __semid_ds32 will be used to issue the syscall and its > contents will be copied to users semid_ds buffer (which is also > implied to be the __TIMESIZE==64). > > There is the requeriment to use define __semid_ds64 that uses __time64_t > explicitly for architecture that support __TIMESIZE==32. > > (The handling of __ASSUME_SYSVIPC_BROKEN_MODE_T and the kernel issue > regarding sem_perm.mode clearing could be improved/simplified). > > >> > >> 2. Add a new semctl64 to handle the time64 one semid_ds. > >> > >>> --- > >>> .../unix/sysv/linux/hppa/struct__semid_ds32.h | 32 +++++++++++++ > >>> .../unix/sysv/linux/mips/struct__semid_ds32.h | 30 ++++++++++++ > >>> .../sysv/linux/powerpc/struct__semid_ds32.h | 32 +++++++++++++ > >>> sysdeps/unix/sysv/linux/semctl.c | 47 +++++++++++++++++-- > >>> .../sysv/linux/sparc/struct__semid_ds32.h | 32 +++++++++++++ > >>> sysdeps/unix/sysv/linux/struct__semid_ds32.h | 32 +++++++++++++ > >>> .../unix/sysv/linux/x86/struct__semid_ds32.h | 32 +++++++++++++ > >>> 7 files changed, 233 insertions(+), 4 deletions(-) > >>> create mode 100644 sysdeps/unix/sysv/linux/hppa/struct__semid_ds32.h > >>> create mode 100644 sysdeps/unix/sysv/linux/mips/struct__semid_ds32.h > >>> create mode 100644 sysdeps/unix/sysv/linux/powerpc/struct__semid_ds32.h > >>> create mode 100644 sysdeps/unix/sysv/linux/sparc/struct__semid_ds32.h > >>> create mode 100644 sysdeps/unix/sysv/linux/struct__semid_ds32.h > >>> create mode 100644 sysdeps/unix/sysv/linux/x86/struct__semid_ds32.h > >>> > >>> diff --git a/sysdeps/unix/sysv/linux/hppa/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/hppa/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..9eceaaff2d > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/hppa/struct__semid_ds32.h > >>> @@ -0,0 +1,32 @@ > >>> +/* HPPA implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#if __WORDSIZE == 32 > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime_high; /* last semop() time high */ > >>> + __syscall_ulong_t sem_otime; /* last semop() time */ > >>> + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ > >>> + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t __glibc_reserved3; > >>> + __syscall_ulong_t __glibc_reserved4; > >>> +}; > >>> +#endif > >> > >> No need to define it for __WORDSIZE == 32, the ABI just supports it > >> anyway. > > > > Ok, I have removed these. > > > >> > >>> diff --git a/sysdeps/unix/sysv/linux/mips/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/mips/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..2e3e2fc562 > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/mips/struct__semid_ds32.h > >>> @@ -0,0 +1,30 @@ > >>> +/* MIPS implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#if __WORDSIZE == 32 > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime; /* last semop time */ > >>> + __syscall_ulong_t sem_ctime; /* last change time */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t sem_otime_high; > >>> + __syscall_ulong_t sem_ctime_high; > >>> +}; > >>> +#endif > >> > >> Ok, it cover mips64-n32 as well. > >> > >>> diff --git a/sysdeps/unix/sysv/linux/powerpc/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/powerpc/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..f509db5a02 > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct__semid_ds32.h > >>> @@ -0,0 +1,32 @@ > >>> +/* PowerPC implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#if __WORDSIZE == 32 > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime_high; /* last semop() time high */ > >>> + __syscall_ulong_t sem_otime; /* last semop() time */ > >>> + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ > >>> + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t __glibc_reserved3; > >>> + __syscall_ulong_t __glibc_reserved4; > >>> +}; > >>> +#endif > >> > >> Ok. > >> > >>> diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c > >>> index 30571af49f..0634cc1abe 100644 > >>> --- a/sysdeps/unix/sysv/linux/semctl.c > >>> +++ b/sysdeps/unix/sysv/linux/semctl.c > >>> @@ -22,8 +22,13 @@ > >>> #include > >>> #include > >>> #include > >>> +#include > >>> #include /* For __kernel_mode_t. */ > >>> > >>> +#define IPC_TIME64 \ > >>> + (__WORDSIZE == 32 && __TIMESIZE == 64 \ > >>> + && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) > >> > >> I think it would be better to move this definition to the common > >> ipc_priv.h header since it will most likely be used on msgctl > >> and shmctl y2038 support as well. > > > > Done. > > > >> > >>> + > >>> /* Define a `union semun' suitable for Linux here. */ > >>> union semun > >>> { > >>> @@ -44,13 +49,47 @@ union semun > >>> static int > >>> semctl_syscall (int semid, int semnum, int cmd, union semun arg) > >>> { > >>> + int ret; > >>> +#if IPC_TIME64 > >> > >> I think we shoul add a comment stating why we need a auxiliary buffer > >> for STAT/STAT_ANY operations. Something like: > >> > >> A temporary buffer is used to avoid both an issue where the export > >> semid_ds might not have follow kernel expected layout (due > >> sem_{o,c}time alignment in 64-bit time case) and the issue where > >> some kernel version might not clear the high bits when returning > >> then sem_{o,c}time information. > > > > Added > > > >> > >>> + struct __semid_ds32 tmp; > >>> + struct semid_ds *orig; > >>> + bool restore = false; > >>> + if (cmd == IPC_STAT || cmd == SEM_STAT || cmd == SEM_STAT_ANY) > >>> + { > >>> + tmp = (struct __semid_ds32) { > >>> + .sem_perm = arg.buf->sem_perm, > >>> + .sem_otime = arg.buf->sem_otime, > >>> + .sem_ctime = arg.buf->sem_ctime, > >>> + .sem_nsems = arg.buf->sem_nsems, > >>> + }; > >> > >> We need to fully initialize the temporary struct to avoid a kernel > >> issue fixed in 4693916846269d633a3664586650dbfac2c5562f (4.14) where > >> kernel does not clear the timestamps high bits. > > > > Added. > > > >> > >>> + orig = arg.buf; > >>> + arg.buf = (struct semid_ds*)&tmp; > >> > >> Space before &tmp. > > > > Added. > > > >> > >>> + restore = true; > >>> + } > >>> +#endif > >>> + > >>> #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > >>> - return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, > >>> - arg.array); > >>> + ret = INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, > >>> + arg.array); > >>> #else > >>> - return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, > >>> - SEMCTL_ARG_ADDRESS (arg)); > >>> + ret = INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, > >>> + SEMCTL_ARG_ADDRESS (arg)); > >>> #endif > >> > >> Ok. > >> > >>> + > >>> +#if IPC_TIME64 > >>> + if (ret >= 0 && restore) > >>> + { > >>> + arg.buf = orig; > >>> + arg.buf->sem_perm = tmp.sem_perm; > >>> + arg.buf->sem_otime = tmp.sem_otime > >>> + | ((time_t) tmp.sem_otime_high << 32); > >>> + arg.buf->sem_ctime = tmp.sem_ctime > >>> + | ((time_t) tmp.sem_ctime_high << 32); > >>> + arg.buf->sem_nsems = tmp.sem_nsems; > >> > >> I think it would be better to use __time64_t explicit here. > > > > Done. > > > > Alistair > > > >> > >>> + } > >>> +#endif > >>> + > >>> + return ret; > >>> } > >>> > >>> int > >>> diff --git a/sysdeps/unix/sysv/linux/sparc/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/sparc/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..f641825d37 > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/sparc/struct__semid_ds32.h > >>> @@ -0,0 +1,32 @@ > >>> +/* Sparc implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#if __WORDSIZE == 32 > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime_high; /* last semop() time high */ > >>> + __syscall_ulong_t sem_otime; /* last semop() time */ > >>> + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ > >>> + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t __glibc_reserved3; > >>> + __syscall_ulong_t __glibc_reserved4; > >>> +}; > >>> +#endif > >> > >> Ok. > >> > >>> diff --git a/sysdeps/unix/sysv/linux/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..51ff83206d > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/struct__semid_ds32.h > >>> @@ -0,0 +1,32 @@ > >>> +/* Generic implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#if __WORDSIZE == 32 > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime; /* last semop() time */ > >>> + __syscall_ulong_t sem_otime_high; /* last semop() time high */ > >>> + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ > >>> + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t __glibc_reserved3; > >>> + __syscall_ulong_t __glibc_reserved4; > >>> +}; > >>> +#endif > >> > >> Ok. > >> > >>> diff --git a/sysdeps/unix/sysv/linux/x86/struct__semid_ds32.h b/sysdeps/unix/sysv/linux/x86/struct__semid_ds32.h > >>> new file mode 100644 > >>> index 0000000000..f65c9fc877 > >>> --- /dev/null > >>> +++ b/sysdeps/unix/sysv/linux/x86/struct__semid_ds32.h > >>> @@ -0,0 +1,32 @@ > >>> +/* x86 implementation of the semaphore struct __semid_ds32. > >>> + Copyright (C) 1995-2020 Free Software Foundation, Inc. > >>> + This file is part of the GNU C Library. > >>> + > >>> + The GNU C Library is free software; you can redistribute it and/or > >>> + modify it under the terms of the GNU Lesser General Public > >>> + License as published by the Free Software Foundation; either > >>> + version 2.1 of the License, or (at your option) any later version. > >>> + > >>> + The GNU C Library is distributed in the hope that it will be useful, > >>> + but WITHOUT ANY WARRANTY; without even the implied warranty of > >>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > >>> + Lesser General Public License for more details. > >>> + > >>> + You should have received a copy of the GNU Lesser General Public > >>> + License along with the GNU C Library; if not, see > >>> + . */ > >>> + > >>> +#ifdef __i386__ > >>> +/* This is the "new" y2038 types defined after the 5.1 kernel. It allows > >>> + the kernel to use {o,c}time{_high} values to support a 64-bit time_t. */ > >>> +struct __semid_ds32 { > >>> + struct ipc_perm sem_perm; /* operation permission struct */ > >>> + __syscall_ulong_t sem_otime; /* last semop() time */ > >>> + __syscall_ulong_t sem_otime_high; /* last semop() time high */ > >>> + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ > >>> + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ > >>> + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ > >>> + __syscall_ulong_t __glibc_reserved3; > >>> + __syscall_ulong_t __glibc_reserved4; > >>> +}; > >>> +#endif > >>> > >> > >> Ok. > >> > >>