Re: [PATCH 0/2][RFC] Better handling of insane CMOS values

John Stultz
2012-07-31T17:15:14Z

On 07/31/2012 02:54 AM, James Courtier-Dutton wrote:
> On 31 July 2012 07:35, John Stultz <john.stultz@linaro.org> wrote:
>> So CAI Qian noticed recent boot trouble on a machine that had its CMOS
>> clock configured for the year 8200.
>> See: http://lkml.org/lkml/2012/7/29/188
>>
>> While running with a crazy CMOS clock isn't advised, and a simple
>> "don't do that" might be reasonable, the behavior has in effect
>> regressed recently due to changes in the hrtimer/timekeeping
>> interactions.
>>
> Would it not be easier to work out which CMOS clock values we can
> handle correctly, and then do input value validation on the CMOS
> values, and if a value is outside the acceptable range, assume a value
> equal to the minimum acceptable value.

I believe patch 2/2 does exactly this.

> Also, surely all timer use within the kernel should use the monotonic
> time source for timer expiry, and not depend on CMOS time.
> I.e. If we want a thread to wake up once every 30 seconds, use the
> monotonic time source for that.
> conversion to local time should only be needed for timestamps.
Timers can also be specified against various clockids like
CLOCK_REALTIME (and absolute time values, like expire this timer at
11:55 GMT, Oct 5 2012). So while the kernel does manage most things
internally with CLOCK_MONOTONIC, it still has to manage some timers
against other clockids.

> We might need a compile/boot time option to assign useable ranges to
> local time values.
> E.g. For this boot, local time is between year 2000 and 2100
> For next boot, local time is between year 2050 and 2150.
> Obviously, make the range as wide as we can sensibly handle, so the
> setting does not need to be changed very often.
> The range will be determined by the amount of bits in the time values.
> User space can work on much wider ranges for historical date storage,
> but for accessing the current time, smaller ranges are workable.
Right. So one way to handle the range difference between the ktime_t and
timespec values would be to have kernel internal ktime_t epochs that we
remove and readd as needed. So instead of using 1970, we pick some
close value to the boot time like 2010, and then subtract 40 years off
all the inputs, and it back on to the outputs. Aside from the extra
computation, the problem is that if a system booted up like the one in
this case w/ a year of 8200, and we selected that as this kernel epoch,
we then would have problems setting the time back to 2012, as there may
be CLOCK_REALTIME timers set for 8200 that we could not store within the
292 year epoch. We probably could decide that timers larger then the
ktime_t epoch will expire "never" and then re-calculate if needed when
the time is set.

Even so, I suspect the extra complication, along with the extra overhead
required will make such a plan unpopular until its actually needed
(around the year 2264). So I suspect the input sanitation is really the
most likely approach for now.

thanks
-john