On Tue, Mar 10, 2020 at 5:29 PM Vineet Gupta <Vineet.Gupta1@xxxxxxxxxxxx> wrote: > > Hi Alistair, > > On 3/4/20 5:26 PM, Alistair Francis 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. > > > > We protect this new code via the __IPC_TIME64 marco, which is only true > > for 32-bit architectures with a 64-bit time_t. > > --- > > bits/ipc.h | 6 ++++- > > sysdeps/gnu/bits/ipc.h | 6 ++++- > > sysdeps/unix/sysv/linux/bits/ipc.h | 6 ++++- > > sysdeps/unix/sysv/linux/bits/semid_ds_t.h | 15 +++++++++++ > > .../unix/sysv/linux/hppa/bits/semid_ds_t.h | 15 +++++++++++ > > .../unix/sysv/linux/mips/bits/semid_ds_t.h | 13 ++++++++++ > > .../unix/sysv/linux/powerpc/bits/semid_ds_t.h | 15 +++++++++++ > > sysdeps/unix/sysv/linux/semctl.c | 25 ++++++++++++++++--- > > .../unix/sysv/linux/sparc/bits/semid_ds_t.h | 15 +++++++++++ > > sysdeps/unix/sysv/linux/x86/bits/semid_ds_t.h | 15 +++++++++++ > > 10 files changed, 124 insertions(+), 7 deletions(-) > > > > diff --git a/bits/ipc.h b/bits/ipc.h > > index e2981fd5c3..9ac8485193 100644 > > --- a/bits/ipc.h > > +++ b/bits/ipc.h > > @@ -29,7 +29,11 @@ > > /* Control commands for `msgctl', `semctl', and `shmctl'. */ > > #define IPC_RMID 0 /* remove identifier */ > > #define IPC_SET 1 /* set `ipc_perm' options */ > > -#define IPC_STAT 2 /* get `ipc_perm' options */ > > +#if __TIMESIZE == 64 && __WORDSIZE == 32 > > +# define IPC_STAT 0x102 /* Get `ipc_perm' options. */ > > +#else > > +# define IPC_STAT 2 /* Get `ipc_perm' options. */ > > +#endif > > Why is this needed. Linux kernel seems to be returning EINVAL for this cmd-id and > following fail for ARC. > > FAIL: sysvipc/test-sysvmsg > FAIL: sysvipc/test-sysvsem > FAIL: sysvipc/test-sysvshm > > Shouldn't this use the default __IPC_64 value which is 0 not 0x100. I think you are right. I have fixed this up in the next version. Alistair > > > > > /* Special key values. */ > > #define IPC_PRIVATE ((key_t) 0) /* private key */ > > diff --git a/sysdeps/gnu/bits/ipc.h b/sysdeps/gnu/bits/ipc.h > > index 47df305e1c..328c11a0d7 100644 > > --- a/sysdeps/gnu/bits/ipc.h > > +++ b/sysdeps/gnu/bits/ipc.h > > @@ -29,7 +29,11 @@ > > /* Control commands for `msgctl', `semctl', and `shmctl'. */ > > #define IPC_RMID 0 /* Remove identifier. */ > > #define IPC_SET 1 /* Set `ipc_perm' options. */ > > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > > +#if __TIMESIZE == 64 && __WORDSIZE == 32 > > +# define IPC_STAT 0x102 /* Get `ipc_perm' options. */ > > +#else > > +# define IPC_STAT 2 /* Get `ipc_perm' options. */ > > +#endif > > #ifdef __USE_GNU > > # define IPC_INFO 3 /* See ipcs. */ > > #endif > > diff --git a/sysdeps/unix/sysv/linux/bits/ipc.h b/sysdeps/unix/sysv/linux/bits/ipc.h > > index 085dd628ac..44449de62f 100644 > > --- a/sysdeps/unix/sysv/linux/bits/ipc.h > > +++ b/sysdeps/unix/sysv/linux/bits/ipc.h > > @@ -29,7 +29,11 @@ > > /* Control commands for `msgctl', `semctl', and `shmctl'. */ > > #define IPC_RMID 0 /* Remove identifier. */ > > #define IPC_SET 1 /* Set `ipc_perm' options. */ > > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > > +#if __TIMESIZE == 64 && __WORDSIZE == 32 > > +# define IPC_STAT 0x102 /* Get `ipc_perm' options. */ > > +#else > > +# define IPC_STAT 2 /* Get `ipc_perm' options. */ > > +#endif > > #ifdef __USE_GNU > > # define IPC_INFO 3 /* See ipcs. */ > > #endif > > diff --git a/sysdeps/unix/sysv/linux/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/bits/semid_ds_t.h > > index d9d902ed0d..b135301356 100644 > > --- a/sysdeps/unix/sysv/linux/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/bits/semid_ds_t.h > > @@ -20,6 +20,21 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > #if __TIMESIZE == 32 > > struct semid_ds > > diff --git a/sysdeps/unix/sysv/linux/hppa/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/hppa/bits/semid_ds_t.h > > index 39c0e53f38..3613c5ec94 100644 > > --- a/sysdeps/unix/sysv/linux/hppa/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/hppa/bits/semid_ds_t.h > > @@ -20,6 +20,21 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > #if __TIMESIZE == 32 > > struct semid_ds > > diff --git a/sysdeps/unix/sysv/linux/mips/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/mips/bits/semid_ds_t.h > > index 1ab16492dd..e26906a67f 100644 > > --- a/sysdeps/unix/sysv/linux/mips/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/mips/bits/semid_ds_t.h > > @@ -20,6 +20,19 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > struct semid_ds > > { > > diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/powerpc/bits/semid_ds_t.h > > index 79b4cba939..ec2ff552eb 100644 > > --- a/sysdeps/unix/sysv/linux/powerpc/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/powerpc/bits/semid_ds_t.h > > @@ -20,6 +20,21 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > #if __TIMESIZE == 32 > > struct semid_ds > > diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c > > index 0c3eb0932f..3ac6d01b84 100644 > > --- a/sysdeps/unix/sysv/linux/semctl.c > > +++ b/sysdeps/unix/sysv/linux/semctl.c > > @@ -23,11 +23,16 @@ > > #include <shlib-compat.h> > > #include <errno.h> > > > > +#define __IPC_TIME64 (IPC_STAT & __IPC_64) > > + > > /* Define a `union semun' suitable for Linux here. */ > > union semun > > { > > int val; /* value for SETVAL */ > > struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ > > +#if __WORDSIZE == 32 > > + struct __semid_ds32 *buf32; /* 32-bit buffer for IPC_STAT & IPC_SET */ > > +#endif > > unsigned short int *array; /* array for GETALL & SETALL */ > > struct seminfo *__buf; /* buffer for IPC_INFO */ > > }; > > @@ -43,13 +48,25 @@ union semun > > static int > > semctl_syscall (int semid, int semnum, int cmd, union semun arg) > > { > > + int ret; > > #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 > > + > > +#if __IPC_TIME64 > > + if (ret == 0 && (cmd & __IPC_TIME64)) > > + { > > + arg.buf->sem_ctime = arg.buf32->sem_ctime | > > + ((time_t) arg.buf32->sem_ctime_high << 32); > > + arg.buf->sem_otime = arg.buf32->sem_otime | > > + ((time_t) arg.buf32->sem_otime_high << 32); > > + } > > #endif > > + return ret; > > } > > > > int > > diff --git a/sysdeps/unix/sysv/linux/sparc/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/sparc/bits/semid_ds_t.h > > index f8de676e79..b08fb8a79e 100644 > > --- a/sysdeps/unix/sysv/linux/sparc/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/sparc/bits/semid_ds_t.h > > @@ -20,6 +20,21 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > #if __TIMESIZE == 32 > > struct semid_ds > > diff --git a/sysdeps/unix/sysv/linux/x86/bits/semid_ds_t.h b/sysdeps/unix/sysv/linux/x86/bits/semid_ds_t.h > > index 42694069d5..c7b9adce88 100644 > > --- a/sysdeps/unix/sysv/linux/x86/bits/semid_ds_t.h > > +++ b/sysdeps/unix/sysv/linux/x86/bits/semid_ds_t.h > > @@ -20,6 +20,21 @@ > > # error "Never include <bits/semid_ds_t.h> directly; use <sys/sem.h> instead." > > #endif > > > > +#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 > > + > > /* Data structure describing a set of semaphores. */ > > struct semid_ds > > { > > > _______________________________________________ linux-snps-arc mailing list linux-snps-arc@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/linux-snps-arc