From patchwork Sun Jan 21 23:12:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 10177177 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5274D604D4 for ; Sun, 21 Jan 2018 23:13:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43F6026E56 for ; Sun, 21 Jan 2018 23:13:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 36DC726E69; Sun, 21 Jan 2018 23:13:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D017B26E56 for ; Sun, 21 Jan 2018 23:13:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750945AbeAUXNU (ORCPT ); Sun, 21 Jan 2018 18:13:20 -0500 Received: from mout.kundenserver.de ([217.72.192.75]:52473 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750882AbeAUXNT (ORCPT ); Sun, 21 Jan 2018 18:13:19 -0500 Received: from wuerfel.lan ([95.208.111.237]) by mrelayeu.kundenserver.de (mreue104 [212.227.15.145]) with ESMTPA (Nemesis) id 0Mgw4G-1eQFfS1hRY-00M04F; Mon, 22 Jan 2018 00:13:10 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" , Ching Huang Cc: y2038@lists.linaro.org, Arnd Bergmann , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] scsi: arcmsr: avoid do_gettimeofday Date: Mon, 22 Jan 2018 00:12:26 +0100 Message-Id: <20180121231308.2169692-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:q9TIv5XuDsZG0TMdXiS/9lYb+reRLMNZ/Cq2X++AhP08NNFJ/HA R62t4UsN0YNhKflAda3C9ENfMHLL555n0d1V0GzFqs0Kgfsy3ktpWmvsapdmMaBJ2o0udP+ fWAIiztj6VqQ/ENDUEymBCLa07GdAQDlnbU6Y3G/17gVeoYGWDg/dfrB+IY4NohNa6HFqQ9 0iy1YlYnLEqsMYyw6/foA== X-UI-Out-Filterresults: notjunk:1; V01:K0:2GmvDZqlSTE=:aZLDLfvNXS2a0qsjn3ujQm 3Xd0WcYw88Q/nikSHH83mQIRqdNKphDBtejWAukNWs9xccnT74EuqV+eRaFQJinAzzszT01kN uEU7/uNv9CV4v0cCMbUZ3VYY5HzzU+oJ4FwQ0cMJEtfLcS2GIZrD7m1bc14GcufjHmRMA/8Ps djjfn1sZwfbPNc7PWubJDUxnRd1TTBBQwoJRcB7fLmVGgQZWXJfSnQHbXu93S/wxdY6rd4wtg DjZKu7mZESt6qE7LRQ63uxYtj59t/OA7oBFy5xUbp6DJXq2NZAh5okRY7szdubOjLqR1T9sh4 FtAkdkqQPDTC4FCBxrd+8CuMC9OuYKMbrbGOftPDkLwx2y+yh45h6K2GE+FuQubIg9Se5PxEW ARjhmISZ3BM91Ul7wcT6pgYoCa+O3e/m4uZSNaMtrqWFVLoVD6vrta3f/qvJykxUwYJ37OcXT fWRVvjs+AzbcXXw05FtZ8FCy4qegEwK6Jkp2ncOXAqj09EKh6mFtThXWcQbS89+bQws46AfUo 8YCnHenG3Io5zYC5m7UM49bziyQfzVH80kYIhtLMpEsIsa2XlC6k/sklXpA7zVX/iuj61FkC2 Sovp46qHQ9nJxk7Jt1nWv25QNJ2dMdAbh3e9Pn8vcvU2KOIALWONcaQaZXx2FCDwwFwVHA0vk 9MeXoMZqPuQRpG+wtZ8BOuTSYzMQfkTOtjp+zlsdxJpoBNuAEYRS1OO49vqZJioyRd1ol4Sp+ xp6ze9iEYn4KCo/hYyfJPGeBqrjMIN3xqHs97A== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The arcmsr uses its own implementation of time_to_tm(), along with do_gettimeofday() to read the current time. While the algoritm used here is fine in principle, it suffers from two problems: - it assigns the seconds portion of the timeval to a 32-bit unsigned integer that overflows in 2106 even on 64-bit architectures. - do_gettimeofday() returns a time_t that overflows in 2038 on all 32-bit systems. This changes the time retrieval function to ktime_get_real_seconds(), which returns a proper 64-bit value, and replaces the open-coded time_to_tm() algorithm with a call to the safe time64_to_tm(). I checked way all numbers are indexed and found that months are given in range 0..11 while the days are in range 1..31, same as 'struct tm', but the year value that the firmware expects starts in 2000 while 'struct tm' is based on year 1900, so it needs a small adjustment. Fixes: b416c099472a ("scsi: arcmsr: Add a function to set date and time to firmware") Signed-off-by: Arnd Bergmann --- drivers/scsi/arcmsr/arcmsr_hba.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 47745592cff4..75e828bd30e3 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3489,8 +3489,9 @@ static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, static void arcmsr_set_iop_datetime(struct timer_list *t) { struct AdapterControlBlock *pacb = from_timer(pacb, t, refresh_timer); - unsigned int days, j, i, a, b, c, d, e, m, year, mon, day, hour, min, sec, secs, next_time; - struct timeval tv; + unsigned int next_time; + struct tm tm; + union { struct { uint16_t signature; @@ -3506,33 +3507,15 @@ static void arcmsr_set_iop_datetime(struct timer_list *t) } b; } datetime; - do_gettimeofday(&tv); - secs = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); - days = secs / 86400; - secs = secs - 86400 * days; - j = days / 146097; - i = days - 146097 * j; - a = i + 719468; - b = ( 4 * a + 3 ) / 146097; - c = a - ( 146097 * b ) / 4; - d = ( 4 * c + 3 ) / 1461 ; - e = c - ( 1461 * d ) / 4 ; - m = ( 5 * e + 2 ) / 153 ; - year = 400 * j + 100 * b + d + m / 10 - 2000; - mon = m + 3 - 12 * ( m /10 ); - day = e - ( 153 * m + 2 ) / 5 + 1; - hour = secs / 3600; - secs = secs - 3600 * hour; - min = secs / 60; - sec = secs - 60 * min; + time64_to_tm(ktime_get_real_seconds(), -sys_tz.tz_minuteswest * 60, &tm); datetime.a.signature = 0x55AA; - datetime.a.year = year; - datetime.a.month = mon; - datetime.a.date = day; - datetime.a.hour = hour; - datetime.a.minute = min; - datetime.a.second = sec; + datetime.a.year = tm.tm_year - 100; /* base 2000 instead of 1900 */ + datetime.a.month = tm.tm_mon; + datetime.a.date = tm.tm_mday; + datetime.a.hour = tm.tm_hour; + datetime.a.minute = tm.tm_min; + datetime.a.second = tm.tm_sec; switch (pacb->adapter_type) { case ACB_ADAPTER_TYPE_A: {