aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-02-11 15:07:00 +0000
committerMichael Brown <mcb30@ipxe.org>2023-02-11 15:11:51 +0000
commit3c83843e111ece30d3dfb5143d5e6aed6164d587 (patch)
tree157d81c6cb2df8f6d086b9189a40837f79de7565
parentbe8ecaf8059a34f27ed34bbc2e95806537802108 (diff)
downloadipxe-3c83843e111ece30d3dfb5143d5e6aed6164d587.zip
ipxe-3c83843e111ece30d3dfb5143d5e6aed6164d587.tar.gz
ipxe-3c83843e111ece30d3dfb5143d5e6aed6164d587.tar.bz2
[rng] Check for several functioning RTC interrupts
Commit 74222cd ("[rng] Check for functioning RTC interrupt") added a check that the RTC is capable of generating interrupts via the legacy PIC, since this mechanism appears to be broken in some Hyper-V virtual machines. Experimentation shows that the RTC is sometimes capable of generating a single interrupt, but will then generate no subsequent interrupts. This currently causes rtc_entropy_check() to falsely detect that the entropy gathering mechanism is functional. Fix by checking for several RTC interrupts before declaring that it is a functional entropy source. Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/x86/interface/pcbios/rtc_entropy.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/arch/x86/interface/pcbios/rtc_entropy.c b/src/arch/x86/interface/pcbios/rtc_entropy.c
index e0c1756..c400d8a 100644
--- a/src/arch/x86/interface/pcbios/rtc_entropy.c
+++ b/src/arch/x86/interface/pcbios/rtc_entropy.c
@@ -42,6 +42,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Maximum time to wait for an RTC interrupt, in milliseconds */
#define RTC_MAX_WAIT_MS 100
+/** Number of RTC interrupts to check for */
+#define RTC_CHECK_COUNT 3
+
/** RTC interrupt handler */
extern void rtc_isr ( void );
@@ -145,6 +148,7 @@ static void rtc_disable_int ( void ) {
* @ret rc Return status code
*/
static int rtc_entropy_check ( void ) {
+ unsigned int count = 0;
unsigned int i;
/* Check that RTC interrupts are working */
@@ -158,14 +162,18 @@ static int rtc_entropy_check ( void ) {
"cli\n\t" );
/* Check for RTC interrupt flag */
- if ( rtc_flag )
- return 0;
+ if ( rtc_flag ) {
+ rtc_flag = 0;
+ if ( ++count >= RTC_CHECK_COUNT )
+ return 0;
+ }
/* Delay */
mdelay ( 1 );
}
- DBGC ( &rtc_flag, "RTC timed out waiting for interrupt\n" );
+ DBGC ( &rtc_flag, "RTC timed out waiting for interrupt %d/%d\n",
+ ( count + 1 ), RTC_CHECK_COUNT );
return -ETIMEDOUT;
}