From patchwork Wed Sep 16 13:45:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: WEN Pingbo X-Patchwork-Id: 7195161 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 42FB8BEEC1 for ; Wed, 16 Sep 2015 13:46:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3D4EE20862 for ; Wed, 16 Sep 2015 13:46:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2151620859 for ; Wed, 16 Sep 2015 13:46:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752616AbbIPNqm (ORCPT ); Wed, 16 Sep 2015 09:46:42 -0400 Received: from mail-pa0-f47.google.com ([209.85.220.47]:35239 "EHLO mail-pa0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752330AbbIPNql (ORCPT ); Wed, 16 Sep 2015 09:46:41 -0400 Received: by pacfv12 with SMTP id fv12so214230591pac.2 for ; Wed, 16 Sep 2015 06:46:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2T0F6nuDRgT7qS4XxDJCqtH72hzAZA/S1Ur3yeitFcA=; b=b19Na2/f3epFnViU67emKNQF618Y4UsjzlBpdLOXPf4y7CkkVz+W8NWiO7gPjCaeqN KxhoMb5vlNcV7Iua01Saic+exF1xGkNI7zs2N7GwChcU3VduUgLdLsI/Tto0tqQUg2YC WC81u9D34u2rYwtMU6+6kv/dto73B7MVkMGibMsaT+YlYe6MFVVWk+b/lDF9+y8dChOs aHCiAwAAC+/yJy10a89f/HFBlRZcdK91/mgWk/lZ6S2iWXeAxIB0301/JeKMjgcGhpzc rYOWo12V4m1eclC97rZTSdAlKi/t7XPi6kd/2DZvijhrjVdG06XqMbyvvcv3vzcN86PW ONQw== X-Gm-Message-State: ALoCoQltrfUJdVLnBRcHvXkJ/O0b3ghyG9avWPRIowr2d12YPAYZ0uPrmJKlnatMKlUi0dJF4hqr X-Received: by 10.66.160.133 with SMTP id xk5mr59478314pab.131.1442411201081; Wed, 16 Sep 2015 06:46:41 -0700 (PDT) Received: from localhost.localdomain ([202.130.115.78]) by smtp.gmail.com with ESMTPSA id u3sm10449585pbs.33.2015.09.16.06.46.38 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Sep 2015 06:46:40 -0700 (PDT) From: WEN Pingbo To: linux-input@vger.kernel.org Cc: Dmitry Torokhov , linux-kernel@vger.kernel.org, arnd@arndb.de, WEN Pingbo , Y2038 Subject: [PATCH V2] hp_sdc_rtc: fixed y2038 problem in proc_show Date: Wed, 16 Sep 2015 21:45:38 +0800 Message-Id: <1442411138-773-1-git-send-email-pingbo.wen@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <3021182.6jgkaVHA9u@wuerfel> References: <3021182.6jgkaVHA9u@wuerfel> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP hp_sdc_rtc_proc_show() use timeval to store the time, which will overflowed in 2038. This patch fixes this problem by replacing timeval with timespec64. hp_sdc_rtc_proc_show() only output string, so that userspace will work normally if we apply this patch. Not all timer in i8042 have y2038 risk(handshake, match timer, etc), Replacements in those timer are just for consistency. Version 2 Updates: - compiled in m68k gcc cross compiler(4.6.3), no extra warnings - placed s64 type cast in tv.tv_sec, making sure it work properly in both 32bit and 64bit platform. Signed-off-by: WEN Pingbo Cc: Y2038 Reviewed-by: Arnd Bergmann --- drivers/input/misc/hp_sdc_rtc.c | 52 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 45e0e3e..1c8c56e 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -198,7 +198,7 @@ static int64_t hp_sdc_rtc_read_i8042timer (uint8_t loadcmd, int numreg) /* Read the i8042 real-time clock */ -static inline int hp_sdc_rtc_read_rt(struct timeval *res) { +static inline int hp_sdc_rtc_read_rt(struct timespec64 *res) { int64_t raw; uint32_t tenms; unsigned int days; @@ -209,15 +209,15 @@ static inline int hp_sdc_rtc_read_rt(struct timeval *res) { tenms = (uint32_t)raw & 0xffffff; days = (unsigned int)(raw >> 24) & 0xffff; - res->tv_usec = (suseconds_t)(tenms % 100) * 10000; - res->tv_sec = (time_t)(tenms / 100) + days * 86400; + res->tv_nsec = (long)(tenms % 100) * 10000 * 1000; + res->tv_sec = (tenms / 100) + (time64_t)days * 86400; return 0; } /* Read the i8042 fast handshake timer */ -static inline int hp_sdc_rtc_read_fhs(struct timeval *res) { +static inline int hp_sdc_rtc_read_fhs(struct timespec64 *res) { int64_t raw; unsigned int tenms; @@ -226,15 +226,15 @@ static inline int hp_sdc_rtc_read_fhs(struct timeval *res) { tenms = (unsigned int)raw & 0xffff; - res->tv_usec = (suseconds_t)(tenms % 100) * 10000; - res->tv_sec = (time_t)(tenms / 100); + res->tv_nsec = (long)(tenms % 100) * 10000 * 1000; + res->tv_sec = (time64_t)(tenms / 100); return 0; } /* Read the i8042 match timer (a.k.a. alarm) */ -static inline int hp_sdc_rtc_read_mt(struct timeval *res) { +static inline int hp_sdc_rtc_read_mt(struct timespec64 *res) { int64_t raw; uint32_t tenms; @@ -243,15 +243,15 @@ static inline int hp_sdc_rtc_read_mt(struct timeval *res) { tenms = (uint32_t)raw & 0xffffff; - res->tv_usec = (suseconds_t)(tenms % 100) * 10000; - res->tv_sec = (time_t)(tenms / 100); + res->tv_nsec = (long)(tenms % 100) * 10000 * 1000; + res->tv_sec = (time64_t)(tenms / 100); return 0; } /* Read the i8042 delay timer */ -static inline int hp_sdc_rtc_read_dt(struct timeval *res) { +static inline int hp_sdc_rtc_read_dt(struct timespec64 *res) { int64_t raw; uint32_t tenms; @@ -260,15 +260,15 @@ static inline int hp_sdc_rtc_read_dt(struct timeval *res) { tenms = (uint32_t)raw & 0xffffff; - res->tv_usec = (suseconds_t)(tenms % 100) * 10000; - res->tv_sec = (time_t)(tenms / 100); + res->tv_nsec = (long)(tenms % 100) * 10000 * 1000; + res->tv_sec = (time64_t)(tenms / 100); return 0; } /* Read the i8042 cycle timer (a.k.a. periodic) */ -static inline int hp_sdc_rtc_read_ct(struct timeval *res) { +static inline int hp_sdc_rtc_read_ct(struct timespec64 *res) { int64_t raw; uint32_t tenms; @@ -277,8 +277,8 @@ static inline int hp_sdc_rtc_read_ct(struct timeval *res) { tenms = (uint32_t)raw & 0xffffff; - res->tv_usec = (suseconds_t)(tenms % 100) * 10000; - res->tv_sec = (time_t)(tenms / 100); + res->tv_nsec = (long)(tenms % 100) * 10000 * 1000; + res->tv_sec = (time64_t)(tenms / 100); return 0; } @@ -433,7 +433,7 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) #define YN(bit) ("no") #define NY(bit) ("yes") struct rtc_time tm; - struct timeval tv; + struct timespec64 tv; memset(&tm, 0, sizeof(struct rtc_time)); @@ -452,36 +452,36 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) if (hp_sdc_rtc_read_rt(&tv)) { seq_puts(m, "i8042 rtc\t: READ FAILED!\n"); } else { - seq_printf(m, "i8042 rtc\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + seq_printf(m, "i8042 rtc\t: %lld.%02ld seconds\n", + (s64)tv.tv_sec, (long)tv.tv_nsec/1000000L); } if (hp_sdc_rtc_read_fhs(&tv)) { seq_puts(m, "handshake\t: READ FAILED!\n"); } else { - seq_printf(m, "handshake\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + seq_printf(m, "handshake\t: %lld.%02ld seconds\n", + (s64)tv.tv_sec, (long)tv.tv_nsec/1000000L); } if (hp_sdc_rtc_read_mt(&tv)) { seq_puts(m, "alarm\t\t: READ FAILED!\n"); } else { - seq_printf(m, "alarm\t\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + seq_printf(m, "alarm\t\t: %lld.%02ld seconds\n", + (s64)tv.tv_sec, (long)tv.tv_nsec/1000000L); } if (hp_sdc_rtc_read_dt(&tv)) { seq_puts(m, "delay\t\t: READ FAILED!\n"); } else { - seq_printf(m, "delay\t\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + seq_printf(m, "delay\t\t: %lld.%02ld seconds\n", + (s64)tv.tv_sec, (long)tv.tv_nsec/1000000L); } if (hp_sdc_rtc_read_ct(&tv)) { seq_puts(m, "periodic\t: READ FAILED!\n"); } else { - seq_printf(m, "periodic\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + seq_printf(m, "periodic\t: %lld.%02ld seconds\n", + (s64)tv.tv_sec, (long)tv.tv_nsec/1000000L); } seq_printf(m,