On 3/10/20 5:29 PM, Vineet Gupta via Libc-alpha 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. [snip...] >> >> 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. > >> 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) So __IPC_TIME64 can only happen if we have 0x102 based cmd ? But doesn't asm-generic ABI preclude the 0x100 ? >> + >> /* 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; >> } _______________________________________________ linux-snps-arc mailing list linux-snps-arc@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/linux-snps-arc