From owner-freebsd-i386@FreeBSD.ORG Mon Apr 2 00:30:05 2007 Return-Path: X-Original-To: freebsd-i386@hub.freebsd.org Delivered-To: freebsd-i386@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A84E316A407 for ; Mon, 2 Apr 2007 00:30:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 8818813C46E for ; Mon, 2 Apr 2007 00:30:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l320U5bu099599 for ; Mon, 2 Apr 2007 00:30:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l320U5ch099597; Mon, 2 Apr 2007 00:30:05 GMT (envelope-from gnats) Resent-Date: Mon, 2 Apr 2007 00:30:05 GMT Resent-Message-Id: <200704020030.l320U5ch099597@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-i386@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ted Faber Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 56F1616A402 for ; Mon, 2 Apr 2007 00:28:22 +0000 (UTC) (envelope-from faber@ylum.lunabase.org) Received: from lunabase.org (adsl-63-200-244-106.dsl.lsan03.pacbell.net [63.200.244.106]) by mx1.freebsd.org (Postfix) with ESMTP id D843613C458 for ; Mon, 2 Apr 2007 00:28:21 +0000 (UTC) (envelope-from faber@ylum.lunabase.org) Received: from ylum.lunabase.org (localhost [127.0.0.1]) by lunabase.org (8.13.8/8.13.8) with ESMTP id l31NqLiE024645; Sun, 1 Apr 2007 16:52:22 -0700 (PDT) (envelope-from faber@ylum.lunabase.org) Received: (from faber@localhost) by ylum.lunabase.org (8.13.8/8.13.8/Submit) id l31NqLCs024644; Sun, 1 Apr 2007 16:52:21 -0700 (PDT) (envelope-from faber) Message-Id: <200704012352.l31NqLCs024644@ylum.lunabase.org> Date: Sun, 1 Apr 2007 16:52:21 -0700 (PDT) From: Ted Faber To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: faber@lunabase.org Subject: i386/111117: kernel clock unset if RTC day of week wrong (patch included) X-BeenThere: freebsd-i386@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Ted Faber List-Id: I386-specific issues for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Apr 2007 00:30:05 -0000 >Number: 111117 >Category: i386 >Synopsis: kernel clock unset if RTC day of week wrong (patch included) >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-i386 >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Apr 02 00:30:04 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Ted Faber >Release: FreeBSD 7.0-CURRENT i386 >Organization: None >Environment: System: FreeBSD ylum.lunabase.org 7.0-CURRENT FreeBSD 7.0-CURRENT #5: Thu Mar 29 22:26:12 PDT 2007 root@ylum.lunabase.org:/usr/obj/usr/src/sys/YLUM i386 >Description: clock_ct_to_ts() in sys/kern/subr_clock.c leaves the stuct timespec it's initializing unchanged if the day of the week passed in is inconsistent with the other values. The dow is not used in the initialization of the struct. The routine does properly set an error code (EINVAL) to let the caller know that the struct is uninitialized, and there is a "don't care" value (-1) for day of the week that overrides the check. However, sys/i386/isa/clock.c does not check the error code, so i386 systems that have a wrongly set or calculated day of the week in their RTC have their time silently set to a random value. Of course this happened to me. The patch changed sys/i386/isa/clock.c to check the error code and retry the call to clock_ct_to_ts() with the day of the week set to -1 if the call failed and the day of the week was not -1. I put a couple diagnostics in so the admin is aware that something's fishy, even if the second call succeeds. The patch is relative to /usr/src against a recent CURRENT. >How-To-Repeat: Get a buggy RTC on an i386. Alternatively, if your BIOS allows setting the day of the week independently, you could do that. My buggy BIOS is on an EPIA ME6000 board. >Fix: Patch attached. --- sys/i386/isa/clock.c.orig Sun Apr 1 16:20:43 2007 +++ sys/i386/isa/clock.c Sun Apr 1 16:34:37 2007 @@ -665,6 +665,7 @@ int s; struct timespec ts; struct clocktime ct; + int conv_error = 0; if (base) { printf("base %d\n", base); @@ -702,7 +703,25 @@ #else ct.year += 2000; #endif - clock_ct_to_ts(&ct, &ts); + if ( clock_ct_to_ts(&ct, &ts) ) { + if ( ct.dow != -1 ) { + /* Retry in case only the day of the week was wrong */ + ct.dow = -1; + if ( clock_ct_to_ts(&ct, &ts)) conv_error = 1; + else { + printf("Real time clock day of week is " + "wrong\n"); + printf("Kernel time should be correct.\n"); + } + } + else conv_error = 1; + } + + if ( conv_error ) { + printf("Real time clock values fail sanity check\n"); + printf("Kernel time of day is probably wrong\n"); + } + ts.tv_sec += utc_offset(); tc_setclock(&ts); } >Release-Note: >Audit-Trail: >Unformatted: