From patchwork Tue Mar 31 08:35:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 38685 Return-Path: X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by sourceware.org (Postfix) with ESMTPS id 0E470385DC00 for ; Tue, 31 Mar 2020 08:35:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0E470385DC00 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: sourceware.org; spf=none smtp.mailfrom=lukma@denx.de Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48s2j71VNsz1qrFx; Tue, 31 Mar 2020 10:35:55 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48s2j70nWpz1r0cG; Tue, 31 Mar 2020 10:35:55 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id KD9HPJ_9jmax; Tue, 31 Mar 2020 10:35:53 +0200 (CEST) X-Auth-Info: zYvltpLe2imZnyKuKOXqsoTQR6QcTb6z9cX0YgYgnKQ= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 31 Mar 2020 10:35:53 +0200 (CEST) From: Lukasz Majewski To: Joseph Myers , Adhemerval Zanella Cc: Alistair Francis , Alistair Francis , GNU C Library , Florian Weimer , Andreas Schwab , Lukasz Majewski Subject: [PATCH v6 2/3] y2038: linux: Provide __mq_timedsend_time64 implementation Date: Tue, 31 Mar 2020 10:35:32 +0200 Message-Id: <20200331083533.8102-2-lukma@denx.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200331083533.8102-1-lukma@denx.de> References: <20200331083533.8102-1-lukma@denx.de> MIME-Version: 1.0 X-Spam-Status: No, score=-32.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: Tue, 31 Mar 2020 08:35:57 -0000 This patch provides new __mq_timedsend_time64 explicit 64 bit function for sending messages with absolute timeout. Moreover, a 32 bit version - __mq_timedsend has been refactored to internally use __mq_timedsend_time64. The __mq_timedsend is now supposed to be used on systems still supporting 32 bit time (__TIMESIZE != 64) - hence the necessary conversion to 64 bit struct __timespec64 from struct timespec. The new __mq_timedsend_time64 syscall available from Linux 5.1+ has been used, when applicable. As this wrapper function is also used internally in the glibc, to e.g. provide mq_send implementation, an explicit check for abs_timeout being NULL has been added due to conversions between struct timespec and struct __timespec64. Before this change the Linux kernel handled this NULL pointer. Build tests: - ./src/scripts/build-many-glibcs.py glibcs Run-time tests: - Run specific tests on ARM/x86 32bit systems (qemu): https://github.com/lmajewski/meta-y2038 and run tests: https://github.com/lmajewski/y2038-tests/commits/master Linux kernel, headers and minimal kernel version for glibc build test matrix: - Linux v5.1 (with mq_timedsend_time64) and glibc built with v5.1 as a minimal kernel version (--enable-kernel="5.1.0") The __ASSUME_TIME64_SYSCALLS flag defined. - Linux v5.1 and default minimal kernel version The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports mq_timedsend_time64 syscall. - Linux v4.19 (no mq_timedsend_time64 support) with default minimal kernel version for contemporary glibc (3.2.0) This kernel doesn't support mq_timedsend_time64 syscall, so the fallback to mq_timedsend is tested. Above tests were performed with Y2038 redirection applied as well as without (so the __TIMESIZE != 64 execution path is checked as well). Reviewed-by: Adhemerval Zanella --- Changes for v6: - Replace implicit check for abs_timeout with an explicit one - abs_timeout != NULL - Reformat the text to avoid long syscall line Changes for v5: - Adjust the code for new struct___timespec64.h location Changes for v4: - Include unconditionally, to keep consistency across different ports Changes for v3: - None Changes for v2: - Fix indentation for __mq_timedsend - #include instead of --- include/mqueue.h | 9 +++++ sysdeps/unix/sysv/linux/mq_timedsend.c | 49 ++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/include/mqueue.h b/include/mqueue.h index 3c66f1711e..32e6570529 100644 --- a/include/mqueue.h +++ b/include/mqueue.h @@ -10,4 +10,13 @@ extern __typeof (mq_timedreceive) __mq_timedreceive __nonnull ((2, 5)); hidden_proto (__mq_timedreceive) hidden_proto (mq_setattr) # endif +#include +#if __TIMESIZE == 64 +# define __mq_timedsend_time64 __mq_timedsend +#else +extern int __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, + size_t msg_len, unsigned int msg_prio, + const struct __timespec64 *abs_timeout); +librt_hidden_proto (__mq_timedsend_time64) +#endif #endif diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c index 888ec6744a..f2a43df300 100644 --- a/sysdeps/unix/sysv/linux/mq_timedsend.c +++ b/sysdeps/unix/sysv/linux/mq_timedsend.c @@ -22,12 +22,55 @@ /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking on full message queue if ABS_TIMEOUT expires. */ int -__mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len, - unsigned int msg_prio, const struct timespec *abs_timeout) +__mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len, + unsigned int msg_prio, + const struct __timespec64 *abs_timeout) { +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_mq_timedsend_time64 +# define __NR_mq_timedsend_time64 __NR_mq_timedsend +# endif + return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len, + msg_prio, abs_timeout); +#else + int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len, + msg_prio, abs_timeout); + if (ret == 0 || errno != ENOSYS) + return ret; + + struct timespec ts32; + if (abs_timeout != NULL) + { + if (! in_time_t_range (abs_timeout->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + ts32 = valid_timespec64_to_timespec (*abs_timeout); + } + return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio, - abs_timeout); + abs_timeout != NULL ? &ts32 : NULL); +#endif +} + +#if __TIMESIZE != 64 +librt_hidden_def (__mq_timedsend_time64) + +int +__mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len, + unsigned int msg_prio, const struct timespec *abs_timeout) +{ + struct __timespec64 ts64; + if (abs_timeout != NULL) + ts64 = valid_timespec_to_timespec64 (*abs_timeout); + + return __mq_timedsend_time64 (mqdes, msg_ptr, msg_len, msg_prio, + abs_timeout != NULL ? &ts64 : NULL); } +#endif + hidden_def (__mq_timedsend) weak_alias (__mq_timedsend, mq_timedsend) hidden_weak (mq_timedsend)