From patchwork Mon Jun 8 19:26:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 481995 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-qk0-x237.google.com (mail-qk0-x237.google.com [IPv6:2607:f8b0:400d:c09::237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 469C414031D for ; Tue, 9 Jun 2015 05:26:36 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b=U6Qn9Wd3; dkim-atps=neutral Received: by qkby64 with SMTP id y64sf34281931qkb.0 for ; Mon, 08 Jun 2015 12:26:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=message-id:subject:from:to:cc:date:in-reply-to:references :content-type:mime-version:x-original-sender :x-original-authentication-results:reply-to:precedence:mailing-list :list-id:list-post:list-help:list-archive:sender:list-subscribe :list-unsubscribe; bh=l/FV9nl/hWiHov1ItH/wpgK1dcL51SHUa/mBVI1F7rU=; b=U6Qn9Wd3ikAe9EDSFsxHq8xY7uILOVEukSN7wTZ2U7fnxc+Dznqd43QCCLzmPTKl7V Rs2CEbg+SFaRrECgeMBXDwEgYuNMjuyXy7nT+Err+APJ8m6J4c1+l1RHEgXiM0htx74U d1GVRvjgwbwCCsrNBWQtZwXpxVhhnvaR6WQ/45CLUOmgEsaTVhfav0V3e01wIirxUjCD Yys/H2LnlzFKNtmLY7tAgUaR0sRXin3HnErKRgYpCaTWsbDdwwDECRX6qOOVd0sYWgOw LdJQ6xbq3fxVUqhftS10toYuV/UDFUNx/CratNn0uU+761bdKRrwepR1bK+vweaT95JT c+VQ== X-Received: by 10.140.94.166 with SMTP id g35mr160028qge.1.1433791594638; Mon, 08 Jun 2015 12:26:34 -0700 (PDT) X-BeenThere: rtc-linux@googlegroups.com Received: by 10.140.37.100 with SMTP id q91ls2943804qgq.33.gmail; Mon, 08 Jun 2015 12:26:34 -0700 (PDT) X-Received: by 10.13.221.151 with SMTP id g145mr20038863ywe.39.1433791594439; Mon, 08 Jun 2015 12:26:34 -0700 (PDT) Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com. [66.63.167.143]) by gmr-mx.google.com with ESMTP id xv6si426351pab.2.2015.06.08.12.26.34 for ; Mon, 08 Jun 2015 12:26:34 -0700 (PDT) Received-SPF: pass (google.com: domain of James.Bottomley@hansenpartnership.com designates 66.63.167.143 as permitted sender) client-ip=66.63.167.143; Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 6AC0C8EE0FB; Mon, 8 Jun 2015 12:26:33 -0700 (PDT) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VJBOplx6qkKy; Mon, 8 Jun 2015 12:26:33 -0700 (PDT) Received: from [153.66.254.242] (unknown [184.11.141.41]) by bedivere.hansenpartnership.com (Postfix) with ESMTPSA id CF3D68EE0E0; Mon, 8 Jun 2015 12:26:32 -0700 (PDT) Message-ID: <1433791592.2291.83.camel@HansenPartnership.com> Subject: [rtc-linux] Re: [PATCH] efi: rtc-efi: use correct EFI 'epoch' From: James Bottomley To: Ard Biesheuvel Cc: matt.fleming@intel.com, linux-efi@vger.kernel.org, roy.franz@linaro.org, leif.lindholm@linaro.org, Alessandro Zummo , Alexandre Belloni , rtc-linux@googlegroups.com Date: Mon, 08 Jun 2015 12:26:32 -0700 In-Reply-To: <1433762834-17961-1-git-send-email-ard.biesheuvel@linaro.org> References: <1433762834-17961-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: Evolution 3.12.11 Mime-Version: 1.0 X-Original-Sender: james.bottomley@hansenpartnership.com X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of James.Bottomley@hansenpartnership.com designates 66.63.167.143 as permitted sender) smtp.mail=James.Bottomley@hansenpartnership.com Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: X-Google-Group-Id: 712029733259 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , On Mon, 2015-06-08 at 13:27 +0200, Ard Biesheuvel wrote: > The rtc-efi driver declares that the EFI 'epoch' is 1/1/1998, but > the UEFI spec does not define it at all. It does define a minimum > of 1900 for the 'Year' member of the EFI_TIME struct, so let's use > 1900 as the minimum year and not 1998. > > This prevents rtc_read_time() failures when the RTC that backs the > EFI time services is set to a date before 1998. > > Cc: Alessandro Zummo > Cc: Alexandre Belloni > Cc: rtc-linux@googlegroups.com > Signed-off-by: Ard Biesheuvel > --- > drivers/rtc/rtc-efi.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c > index cb989cd00b14..4a93b0bbf22c 100644 > --- a/drivers/rtc/rtc-efi.c > +++ b/drivers/rtc/rtc-efi.c > @@ -25,9 +25,12 @@ > > #define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT) > /* > - * EFI Epoch is 1/1/1998 > + * The UEFI spec does not literally define an epoch, but it does > + * define EFI_TIME::Year as having a value between 1900 and 9999. > + * (UEFI spec v2.5 paragraph 7.3) > + * So let's use 1900 as the EFI epoch year. > */ > -#define EFI_RTC_EPOCH 1998 > +#define EFI_RTC_EPOCH 1900 > > /* > * returns day of the year [0-365] > @@ -40,8 +43,6 @@ compute_yday(efi_time_t *eft) > } > /* > * returns day of the week [0-6] 0=Sunday > - * > - * Don't try to provide a year that's before 1998, please ! > */ > static int > compute_wday(efi_time_t *eft) > @@ -60,9 +61,9 @@ compute_wday(efi_time_t *eft) > ndays += compute_yday(eft); > > /* > - * 4=1/1/1998 was a Thursday > + * 1=1/1/1900 was a Monday > */ > - return (ndays + 4) % 7; > + return (ndays + 1) % 7; > } This is a bit nuts: increasing the for loop by a huge amount every time we call the date just so we can cope with the odd early date. Why not just count backwards for the exception case? That way the epoch becomes an optimisation point, every year actually works, but years far before the epoch get penalised in the loop, while our current "efficiency" remains ... perhaps plus points if we want to move the epoch to 2015? James diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index cb989cd..73f1ba6 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -40,8 +40,6 @@ compute_yday(efi_time_t *eft) } /* * returns day of the week [0-6] 0=Sunday - * - * Don't try to provide a year that's before 1998, please ! */ static int compute_wday(efi_time_t *eft) @@ -49,16 +47,25 @@ compute_wday(efi_time_t *eft) int y; int ndays = 0; - if (eft->year < EFI_RTC_EPOCH) { - pr_err("EFI year < " __stringify(EFI_RTC_EPOCH) ", invalid date\n"); - return -1; + if (unlikely(eft->year < EFI_RTC_EPOCH)) { + /* unlikely event, just count backwards */ + for (y = eft->year; y < EFI_RTC_EPOCH; y++) + ndays -= 365 + (is_leap_year(y) ? 1 : 0); + } else { + for (y = EFI_RTC_EPOCH; y < eft->year; y++) + ndays += 365 + (is_leap_year(y) ? 1 : 0); } - for (y = EFI_RTC_EPOCH; y < eft->year; y++) - ndays += 365 + (is_leap_year(y) ? 1 : 0); - ndays += compute_yday(eft); + if (ndays < 0) + /* + * make ndays positive by adding a multiple of seven because + * clock arithmetic using % doesn't work with negative + * numbers + */ + ndays += ((-ndays)/7 + 1)*7; + /* * 4=1/1/1998 was a Thursday */