Skip to content

Commit 7bb4970

Browse files
arndbIngo Molnar
authored andcommitted
efi/cper: Avoid using get_seconds()
get_seconds() is deprecated because of the 32-bit time overflow in y2038/y2106 on 32-bit architectures. The way it is used in cper_next_record_id() causes an overflow in 2106 when unsigned UTC seconds overflow, even on 64-bit architectures. This starts using ktime_get_real_seconds() to give us more than 32 bits of timestamp on all architectures, and then changes the algorithm to use 39 bits for the timestamp after the y2038 wrap date, plus an always-1 bit at the top. This gives us another 127 epochs of 136 years, with strictly monotonically increasing sequence numbers across boots. This is almost certainly overkill, but seems better than just extending the deadline from 2038 to 2106. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20180711094040.12506-5-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 3eb420e commit 7bb4970

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/firmware/efi/cper.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,21 @@ u64 cper_next_record_id(void)
4848
{
4949
static atomic64_t seq;
5050

51-
if (!atomic64_read(&seq))
52-
atomic64_set(&seq, ((u64)get_seconds()) << 32);
51+
if (!atomic64_read(&seq)) {
52+
time64_t time = ktime_get_real_seconds();
53+
54+
/*
55+
* This code is unlikely to still be needed in year 2106,
56+
* but just in case, let's use a few more bits for timestamps
57+
* after y2038 to be sure they keep increasing monotonically
58+
* for the next few hundred years...
59+
*/
60+
if (time < 0x80000000)
61+
atomic64_set(&seq, (ktime_get_real_seconds()) << 32);
62+
else
63+
atomic64_set(&seq, 0x8000000000000000ull |
64+
ktime_get_real_seconds() << 24);
65+
}
5366

5467
return atomic64_inc_return(&seq);
5568
}

0 commit comments

Comments
 (0)