From patchwork Tue Jun 19 14:02:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 139126 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp5248338lji; Tue, 19 Jun 2018 07:04:19 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKnV69U2Ynb4HYPpbikCQCWO7xYjucHHx27JOYlAZx+UaCp75PcHp4x5JkrwKEWk6faFUBF X-Received: by 2002:a17:902:784d:: with SMTP id e13-v6mr18717392pln.197.1529417059083; Tue, 19 Jun 2018 07:04:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529417059; cv=none; d=google.com; s=arc-20160816; b=H7DHrQD6lP4P9E9zgstf7nkCRurNz2rfYGGsycA5ydSCg8ZoKos3S/lOpsAWawanNw ldxX1TPTnaue/wdRgPWpASNrsaIpheJ47kIK6ijRaUvgZ+h/+Kp0E4xjXUb3zyFQv7af OKiwTacthmuNJr+mQqDuGsGJsXw9fEyV0TJxDi751mzEVhqGnyG5E93IOLXtHrpZST01 xw7jn03OXMBCz6JVOndPJ2H6YD/EhVu+Os36iQPFDfh+BEKCzuln3oF5M2zvS2wbbdwY eD+3ulssqMuIbOGxyH4OMbvmvEGcvVEDoHJneB1Yh2CimhvT4fKsCIxjXjD8hJQnI1Ku qZUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=q1+/09T+nlWGIKYqejjXalUxnWWqKIiz6GDB0ud/Jck=; b=lu9JiCmzh7kPfMN7Q8ikKKZtMB/0VXnfIz8AXCHehqQPcZHbGrwvMIaKOMoGpVc65z OOUJkhYZ5/8kdXvKlXmNVbHMB039tmpnZ3IycpAWY5HnvVrGS5NS15dUK/z/nk6Ex/TR PJUAIMIR9HMG/wUYOF20Au+ndkKeWm3K/AiQADrR1FZLtYQyGrzpPRF9+GIgVFrCrF4m UmM6H5La/PQd2arrED5/+UPdgO5cft60/pW6QVsf4psBuq5gWhQTiNyp5+Ox5Ma05+3H yZey1U23UnHJqbeuV1f6RrYbgeyFjcwg1g3kUpcqUPuNKO0TRXwGQSis/gm0ly7z1bpH zUFA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f3-v6si13965945pgp.496.2018.06.19.07.04.18; Tue, 19 Jun 2018 07:04:19 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756613AbeFSOEQ (ORCPT + 30 others); Tue, 19 Jun 2018 10:04:16 -0400 Received: from mout.kundenserver.de ([212.227.126.133]:41145 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965978AbeFSOEK (ORCPT ); Tue, 19 Jun 2018 10:04:10 -0400 Received: from wuerfel.lan ([95.208.111.237]) by mrelayeu.kundenserver.de (mreue001 [212.227.15.129]) with ESMTPA (Nemesis) id 0MZ5db-1fisAf3cKR-00VfJS; Tue, 19 Jun 2018 16:02:54 +0200 From: Arnd Bergmann To: Paul Mackerras , Michael Ellerman , Geert Uytterhoeven , Joshua Thompson Cc: Mathieu Malaterre , Benjamin Herrenschmidt , Greg Ungerer , linux-m68k@lists.linux-m68k.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, y2038@lists.linaro.org, Meelis Roos , Andreas Schwab , Arnd Bergmann Subject: [PATCH 2/3] [v2] m68k: mac: use time64_t in RTC handling Date: Tue, 19 Jun 2018 16:02:28 +0200 Message-Id: <20180619140229.3615110-2-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20180619140229.3615110-1-arnd@arndb.de> References: <20180619140229.3615110-1-arnd@arndb.de> X-Provags-ID: V03:K1:VHjC0uYkHauenmwHCCfCUzcKGf8oIogO8BdSZoKS4lDiBvwPOUq DmVMz9G2Yf0RmtYl2sLcdE5ZMPaYWwqFi2cKKORMeC9piq9q6ekiU01dcHTW/HbjA6hpsXf hJHKxMkQ1rw3nG7+AEOmgN33+8ab/X93cKd5VoqyhQ9/6D0ej2kcf0EQv1RRfI19wp+bYhC 5gfyqbUDpjt9yR1jCLocw== X-UI-Out-Filterresults: notjunk:1; V01:K0:zhO/DQIPP9c=:6BnvwIt5v+9XMcfO9Hqog3 QQHgp7fw2+eiVKHcxlxy1wVlsJILKIFu37yFtV3ukqKSDkH7FIBp3n27P5HkPUEf4iHdZ4u84 hgaPL7/Qas3uG6dBUTs/hyEEaaQIz5wGooRd3KtOyrSbzqFB+6R8miboHLWdNnJjUgTHJjARw Drp3Mz0IIes6DPoZhVIaIqj+rlXOu2aitKIN8kT1zMQU9uqVcb/ZCvi2WyytPTdHELQ0I/3xx b3O7CXeR7fF0Z0tBlWuwDhyrO1UoN1ZNln2wMGYoTJfFaHNNMp3zQbvtjjdNSp+swBC8N9/oo gShgNI20WpI9oqPEkfcKSvAPTP5SPjj0PZQlVBIFyuh8uhRI2vX2bF2nosDm4rdiq5JOo1Rpi wS3BnucaJOmPLboDRIbqjPePbAGbGjqhnCBbZcOhJP6crlwW34aROmtq3p8NN8xHFvxGVtpaC Vx6ZkqaRpXar6rjjDTWHrJgpARjx1V3YeNpRiaHIzowp3ZUynYRtEvswRnh5Q/ylFCYuEQV9q 0vjI6zMwF6xNmiaF63PKBob/jn9dRBH6AWVmuinuNNvW9+i1PP3zBMMqGGPIcvQjzhYUnQkK5 uDg4ASxF9kpnEH827vtAGNnZtOadiQLX6ivNBquC0aY+wtWaWIAwxCmqHmkp2f2bkc4ANxDs3 BJ1UqiPAFfFslarNjoJFeIOhLwSSTpNf5KAHMcDlAcjMo8M385eoQFuKJCdeCnb3DYNM= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion. Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable). This brings it in line with the corresponding code that we have on powerpc macintosh. Signed-off-by: Arnd Bergmann --- v2: Fix varargs passing bug pointed out by Andreas Schwab Fix a typo that caused a build regression --- arch/m68k/mac/misc.c | 62 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) -- 2.9.0 diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index c68054361615..0a2572a6bfe5 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -26,33 +26,39 @@ #include -/* Offset between Unix time (1970-based) and Mac time (1904-based) */ +/* Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU + * times wrap in 2040. If we need to handle later times, the read_time functions + * need to be changed to interpret wrapped times as post-2040. */ #define RTC_OFFSET 2082844800 static void (*rom_reset)(void); #ifdef CONFIG_ADB_CUDA -static long cuda_read_time(void) +static time64_t cuda_read_time(void) { struct adb_request req; - long time; + time64_t time; if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) return 0; while (!req.complete) cuda_poll(); - time = (req.reply[3] << 24) | (req.reply[4] << 16) | - (req.reply[5] << 8) | req.reply[6]; + time = (u32)((req.reply[3] << 24) | (req.reply[4] << 16) | + (req.reply[5] << 8) | req.reply[6]); + + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(time < RTC_OFFSET); + return time - RTC_OFFSET; } -static void cuda_write_time(long data) +static void cuda_write_time(time64_t time) { struct adb_request req; + u32 data = lower_32_bits(time + RTC_OFFSET); - data += RTC_OFFSET; if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF) < 0) @@ -86,26 +92,30 @@ static void cuda_write_pram(int offset, __u8 data) #endif /* CONFIG_ADB_CUDA */ #ifdef CONFIG_ADB_PMU68K -static long pmu_read_time(void) +static time64_t pmu_read_time(void) { struct adb_request req; - long time; + time64_t time; if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) return 0; while (!req.complete) pmu_poll(); - time = (req.reply[1] << 24) | (req.reply[2] << 16) | - (req.reply[3] << 8) | req.reply[4]; + time = (u32)((req.reply[1] << 24) | (req.reply[2] << 16) | + (req.reply[3] << 8) | req.reply[4]); + + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(time < RTC_OFFSET); + return time - RTC_OFFSET; } -static void pmu_write_time(long data) +static void pmu_write_time(time64_t time) { struct adb_request req; + u32 data = lower_32_bits(time + RTC_OFFSET); - data += RTC_OFFSET; if (pmu_request(&req, NULL, 5, PMU_SET_RTC, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF) < 0) @@ -269,8 +279,12 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]); - if (result.idata == last_result.idata) + if (result.idata == last_result.idata) { + if (result.idata < RTC_OFFSET) + result.idata += 0x100000000ull; + return result.idata - RTC_OFFSET; + } if (++count > 10) break; @@ -291,11 +305,11 @@ static long via_read_time(void) * is basically any machine with Mac II-style ADB. */ -static void via_write_time(long time) +static void via_write_time(time64_t time) { union { __u8 cdata[4]; - long idata; + __u32 idata; } data; __u8 temp; @@ -585,12 +599,15 @@ void mac_reset(void) * This function translates seconds since 1970 into a proper date. * * Algorithm cribbed from glibc2.1, __offtime(). + * + * This is roughly same as rtc_time64_to_tm(), which we should probably + * use here, but it's only available when CONFIG_RTC_LIB is enabled. */ #define SECS_PER_MINUTE (60) #define SECS_PER_HOUR (SECS_PER_MINUTE * 60) #define SECS_PER_DAY (SECS_PER_HOUR * 24) -static void unmktime(unsigned long time, long offset, +static void unmktime(time64_t time, long offset, int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp) { @@ -602,11 +619,10 @@ static void unmktime(unsigned long time, long offset, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; - long int days, rem, y, wday, yday; + int days, rem, y, wday, yday; const unsigned short int *ip; - days = time / SECS_PER_DAY; - rem = time % SECS_PER_DAY; + days = div_u64_rem(time, SECS_PER_DAY, &rem); rem += offset; while (rem < 0) { rem += SECS_PER_DAY; @@ -657,7 +673,7 @@ static void unmktime(unsigned long time, long offset, int mac_hwclk(int op, struct rtc_time *t) { - unsigned long now; + time64_t now; if (!op) { /* read */ switch (macintosh_config->adb_type) { @@ -693,8 +709,8 @@ int mac_hwclk(int op, struct rtc_time *t) __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); - now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec); + now = mktime64(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); switch (macintosh_config->adb_type) { case MAC_ADB_IOP: