From patchwork Fri Jun 27 17:27:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 32629 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f199.google.com (mail-vc0-f199.google.com [209.85.220.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2CA02200B9 for ; Fri, 27 Jun 2014 17:27:24 +0000 (UTC) Received: by mail-vc0-f199.google.com with SMTP id ij19sf9983747vcb.2 for ; Fri, 27 Jun 2014 10:27:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=1ha/pevJTVvQS8sRKypYDmtfh50/yaYOSppST4420ow=; b=azMwqWGKPifxUypXURyQ8tR3AdRBVjOHnNqLrJHNvqkmkeEecFyGg5VuXKxV4emmid hr46ZXNYeKC3yJPWFOy0q1WNXk8sdbH46fu8qxtKEuchk6Q5BmRUDaSQVrXIzF1IsVm8 VV8Lhtucjvlnaoh5rwquUk1Bz/HbYFvbrNfWnYydt68Swl5jJmWdRv/bC+KFknrr8feC u14x9KNX4RoduFMBnF2F92s4d1YDzYcUCU74G7IA8HP5bVMgE478m2Whn/8Pw6ZGL1AW LYSxJejfmpqJ67qcihl+VxMLPZKbmRpQPlvSAxKSTAhZkBcgsxI7SKzZYj9SKvL9fHL/ 892Q== X-Gm-Message-State: ALoCoQlBFtio/1Xlmk5N5Zol3KUJgqoHmfbgV0oaALX/R8NlFvU3YFnb57zGIv2LF9roVccNFJAD X-Received: by 10.52.230.71 with SMTP id sw7mr10848421vdc.9.1403890043975; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.22.198 with SMTP id 64ls341214qgn.8.gmail; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) X-Received: by 10.58.30.15 with SMTP id o15mr21296084veh.34.1403890043885; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id f2si4671845vej.7.2014.06.27.10.27.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 27 Jun 2014 10:27:23 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.170 as permitted sender) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id i13so5638171veh.1 for ; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) X-Received: by 10.52.101.168 with SMTP id fh8mr17662626vdb.34.1403890043724; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp124426vcb; Fri, 27 Jun 2014 10:27:23 -0700 (PDT) X-Received: by 10.68.239.73 with SMTP id vq9mr31767607pbc.99.1403890042921; Fri, 27 Jun 2014 10:27:22 -0700 (PDT) Received: from mail-pa0-f53.google.com (mail-pa0-f53.google.com [209.85.220.53]) by mx.google.com with ESMTPS id yf6si14697803pbc.37.2014.06.27.10.27.22 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 27 Jun 2014 10:27:22 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.53 as permitted sender) client-ip=209.85.220.53; Received: by mail-pa0-f53.google.com with SMTP id ey11so4791381pad.26 for ; Fri, 27 Jun 2014 10:27:22 -0700 (PDT) X-Received: by 10.66.179.111 with SMTP id df15mr32522768pac.52.1403890042492; Fri, 27 Jun 2014 10:27:22 -0700 (PDT) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id ln2sm54326979pab.35.2014.06.27.10.27.21 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 27 Jun 2014 10:27:22 -0700 (PDT) From: John Stultz To: Linux Kernel Mailing List Cc: John Stultz , John Whitmore , Alessandro Zummo , Alexander Holler Subject: [PATCH 1/2][RFC] time: Introduce do_first_settimeofday() Date: Fri, 27 Jun 2014 10:27:10 -0700 Message-Id: <1403890031-26419-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1403890031-26419-1-git-send-email-john.stultz@linaro.org> References: <1403890031-26419-1-git-send-email-john.stultz@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.170 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There's some cases in the kernel, particuarly with RTC drivers, where we want to set the time, but only if no one else has already set it. This is useful for systems where the RTC driver is a module, and is loaded late in initialization. However, we want to be sure we don't override the time that may have been set by userspace. Cc: John Whitmore Cc: Alessandro Zummo Cc: Alexander Holler Signed-off-by: John Stultz --- include/linux/time.h | 2 ++ kernel/time/timekeeping.c | 54 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/linux/time.h b/include/linux/time.h index d5d229b..7379291 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -157,6 +157,8 @@ extern void do_gettimeofday(struct timeval *tv); extern int do_settimeofday(const struct timespec *tv); extern int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz); +extern int do_first_settimeofday(const struct timespec *ts); + #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); struct itimerval; diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 32d8d6a..45c2642 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -487,6 +487,25 @@ void do_gettimeofday(struct timeval *tv) } EXPORT_SYMBOL(do_gettimeofday); + +static void __do_settimeofday(struct timekeeper *tk, const struct timespec *tv) +{ + struct timespec ts_delta, xt; + + timekeeping_forward_now(tk); + + xt = tk_xtime(tk); + ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; + ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; + + tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta)); + + tk_set_xtime(tk, tv); + + timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); +} + + /** * do_settimeofday - Sets the time of day * @tv: pointer to the timespec variable containing the new time @@ -496,7 +515,6 @@ EXPORT_SYMBOL(do_gettimeofday); int do_settimeofday(const struct timespec *tv) { struct timekeeper *tk = &timekeeper; - struct timespec ts_delta, xt; unsigned long flags; if (!timespec_valid_strict(tv)) @@ -505,27 +523,43 @@ int do_settimeofday(const struct timespec *tv) raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&timekeeper_seq); - timekeeping_forward_now(tk); + __do_settimeofday(tk, tv); - xt = tk_xtime(tk); - ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; - ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; + write_seqcount_end(&timekeeper_seq); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags); - tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta)); + /* signal hrtimers about time change */ + clock_was_set(); - tk_set_xtime(tk, tv); + return 0; +} +EXPORT_SYMBOL(do_settimeofday); - timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); +int do_first_settimeofday(const struct timespec *tv) +{ + struct timekeeper *tk = &timekeeper; + unsigned long flags; + int ret = 0; + + if (!timespec_valid_strict(tv)) + return -EINVAL; + + raw_spin_lock_irqsave(&timekeeper_lock, flags); + write_seqcount_begin(&timekeeper_seq); + + if (!tk->wall_to_monotonic.tv_sec && !tk->wall_to_monotonic.tv_nsec) + __do_settimeofday(tk, tv); + else + ret = -EACCES; write_seqcount_end(&timekeeper_seq); raw_spin_unlock_irqrestore(&timekeeper_lock, flags); /* signal hrtimers about time change */ clock_was_set(); - return 0; + return ret; } -EXPORT_SYMBOL(do_settimeofday); /** * timekeeping_inject_offset - Adds or subtracts from the current time.