powerpc64/powernv: re-read RTC after polling

If OPAL_RTC_READ is busy and does not return the information on the first run,
as returning OPAL_BUSY_EVENT, the system will crash since ymd and hmsm variable
will contain junk values.

This is happening because we were not calling OPAL_RTC_READ again after
OPAL_POLL_EVENTS' return, which would finally replace the old/junk hmsm and ymd
values.

The code was also mixing OPAL_RTC_READ and OPAL_POLL_EVENTS return values.

This patch fix this logic and guarantee that we call OPAL_RTC_READ after
OPAL_POLL_EVENTS return, and guarantee the code will only proceed if
OPAL_RTC_READ returns OPAL_SUCCESS.

Reviewed by: jhibbits
Approved by: jhibbits (mentor)
Differential Revision: https://reviews.freebsd.org/D16617
This commit is contained in:
Breno Leitao 2018-08-08 21:19:07 +00:00
parent 928ab9c625
commit 78f4e2fea0

View File

@ -218,13 +218,12 @@ opal_gettime(device_t dev, struct timespec *ts)
uint32_t ymd; uint32_t ymd;
uint64_t hmsm; uint64_t hmsm;
do { rv = opal_call(OPAL_RTC_READ, vtophys(&ymd), vtophys(&hmsm));
while (rv == OPAL_BUSY_EVENT) {
opal_call(OPAL_POLL_EVENTS, 0);
pause("opalrtc", 1);
rv = opal_call(OPAL_RTC_READ, vtophys(&ymd), vtophys(&hmsm)); rv = opal_call(OPAL_RTC_READ, vtophys(&ymd), vtophys(&hmsm));
if (rv == OPAL_BUSY_EVENT) { }
rv = opal_call(OPAL_POLL_EVENTS, 0);
pause("opalrtc", 1);
}
} while (rv == OPAL_BUSY_EVENT);
if (rv != OPAL_SUCCESS) if (rv != OPAL_SUCCESS)
return (ENXIO); return (ENXIO);