Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/54914 )
Change subject: drivers/pc80/mc146818rtc: Check date and time for sanity ......................................................................
drivers/pc80/mc146818rtc: Check date and time for sanity
There are cases where the RTC_VRT bit in register D stays set after a power failure while the real date and time registers can contain rubbish values (can happen when RTC is not buffered). If we do not detect this invalid date and/or time here and keep it, Linux will use these bad values for the initial timekeeper init. This in turn can lead to dates before 1970 in user land which can break a lot assumptions.
To fix this, check date and time sanity when the RTC is initialized and reset the values if needed.
Change-Id: I5bc600c78bab50c70372600347f63156df127012 Signed-off-by: Werner Zeh werner.zeh@siemens.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/54914 Reviewed-by: Arthur Heymans arthur@aheymans.xyz Reviewed-by: Paul Menzel paulepanter@mailbox.org Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/drivers/pc80/rtc/mc146818rtc.c M src/lib/Makefile.inc 2 files changed, 14 insertions(+), 4 deletions(-)
Approvals: build bot (Jenkins): Verified Paul Menzel: Looks good to me, but someone else must approve Arthur Heymans: Looks good to me, approved
diff --git a/src/drivers/pc80/rtc/mc146818rtc.c b/src/drivers/pc80/rtc/mc146818rtc.c index 21d3c00..42671a9 100644 --- a/src/drivers/pc80/rtc/mc146818rtc.c +++ b/src/drivers/pc80/rtc/mc146818rtc.c @@ -175,6 +175,15 @@ ; }
+/* Perform a sanity check of current date and time. */ +static int cmos_date_invalid(void) +{ + struct rtc_time now; + + rtc_get(&now); + return rtc_invalid(&now); +} + /* * If the CMOS is cleared, the rtc_reg has the invalid date. That * hurts some OSes. Even if we don't set USE_OPTION_TABLE, we need @@ -190,11 +199,11 @@ year = cmos_read(RTC_CLK_YEAR);
/* - * TODO: If century is 0xFF, 100% that the CMOS is cleared. - * Other than that, so far rtc_year is the only entry to check - * if the date is valid. + * If century is 0xFF, 100% that the CMOS is cleared. + * In addition, check the sanity of all values and reset the date in case of + * insane values. */ - if (century > 0x99 || year > 0x99) /* Invalid date */ + if (century > 0x99 || year > 0x99 || cmos_date_invalid()) /* Invalid date */ cmos_reset_date(); }
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 358035d..baf9c4d 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -59,6 +59,7 @@ bootblock-y += memcmp.c bootblock-y += boot_device.c bootblock-y += fmap.c +bootblcok-y += rtc.c
verstage-y += prog_loaders.c verstage-y += prog_ops.c