One source of RTC weirdness is the fact that inb/outb to/from the RTC and other legacy parts of the ISA aren't protected by mutex on linux. So if you're unlucky enough to collide with some other program doing something innocuous with the RTC you can accidentally set bits that will never be set by the RTC. Many RTCs decide not to tick anymore when that happens.
If all your programs use /dev/rtc and ioctl()s you are probably a little safer because there will be coarse locks around the RTC itself, those will serialize the activity. But IIRC the inb/outb stuff can be done from user space (as superuser) and even if you're only reading you have to write to the address register which could break a write-in-progress by sending its output to the wrong RTC field.
I've been chasing exactly this issue for weeks!! The problem I'm seeing is that something changes the binary/BCD flag. It turns out that changing this flag doesn't convert the current representation of time inside the RTC; it just changes the logic used to advance the counter fields and apply the next tick.
So if you change that flag without also setting the time, then many of the fields are now invalid. But the tick logic doesn't care. It just sets the invalid fields back to zero and keeps on ticking.
The year 20 17 becomes 1 4 1 1.
The RTC clock is a 1984 part that is still getting embedded, more or less unchanged, into today's PCs. It is maddening.
> Many RTCs decide not to tick anymore when that happens.
Of course I laughed when I read that, but then I realized I was interpreting that line to mean "it declares shenanigans and stops reporting time so you realize something broke."
Just wanted to clarify - do you mean the above, or "of course software cannot kill hardware!!1" "won't tick anymore"?
Yeah, IIRC it really stopped ticking (until you write a valid value at which point it would resume).
Note that it doesn't stop reporting the time in this condition it will just give you back all the garbage fields that you wrote before. So an interesting thing happens when the system tries to transform that into a UTC wall clock basis and it usually ends up with a really wild interpretation of the date (decades/centuries off, similar to the problem described in TFA).
> So an interesting thing happens when the system tries to transform that into a UTC wall clock basis and it usually ends up with a really wild interpretation of the date (decades/centuries off, similar to the problem described in TFA).
If all your programs use /dev/rtc and ioctl()s you are probably a little safer because there will be coarse locks around the RTC itself, those will serialize the activity. But IIRC the inb/outb stuff can be done from user space (as superuser) and even if you're only reading you have to write to the address register which could break a write-in-progress by sending its output to the wrong RTC field.