From f4757fbfcf616365c74b1aa6508b2ab27480cdd0 Mon Sep 17 00:00:00 2001 From: Vasant Hegde Date: Tue, 13 Jun 2017 15:52:34 +0530 Subject: FSP/RTC: Fix possible FSP R/R issue in rtc write path fsp_opal_rtc_write() checks FSP status before queueing message to FSP. But if FSP R/R starts before getting response to queued message then we will continue to return OPAL_BUSY_EVENT to host. In some extreme condition host may experience hang. Once FSP is back we will repost message, get response from FSP and return OPAL_SUCCES to host. This patch caches new values and returns OPAL_SUCCESS if FSP R/R is happening. And once FSP is back we will send cached value to FSP. Signed-off-by: Vasant Hegde Signed-off-by: Stewart Smith --- hw/fsp/fsp-rtc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'hw/fsp') diff --git a/hw/fsp/fsp-rtc.c b/hw/fsp/fsp-rtc.c index b41e295..8ee0f5a 100644 --- a/hw/fsp/fsp-rtc.c +++ b/hw/fsp/fsp-rtc.c @@ -342,7 +342,6 @@ static int64_t fsp_rtc_send_write_request(uint32_t year_month_day, { struct fsp_msg *msg; uint32_t w0, w1, w2; - struct tm tm; assert(lock_held_by_me(&rtc_lock)); assert(rtc_write_request_state == RTC_WRITE_NO_REQUEST); @@ -362,14 +361,7 @@ static int64_t fsp_rtc_send_write_request(uint32_t year_month_day, } prlog(PR_TRACE, " -> req at %p\n", msg); - if (fsp_in_rr()) { - datetime_to_tm(msg->data.words[0], - (u64) msg->data.words[1] << 32, &tm); - rtc_cache_update(&tm); - rtc_tod_cache_dirty = true; - fsp_freemsg(msg); - return OPAL_SUCCESS; - } else if (fsp_queue_msg(msg, fsp_rtc_req_complete)) { + if (fsp_queue_msg(msg, fsp_rtc_req_complete)) { prlog(PR_TRACE, " -> queueing failed !\n"); fsp_freemsg(msg); return OPAL_INTERNAL_ERROR; @@ -384,6 +376,7 @@ static int64_t fsp_opal_rtc_write(uint32_t year_month_day, uint64_t hour_minute_second_millisecond) { int rc; + struct tm tm; lock(&rtc_lock); if (rtc_tod_state == RTC_TOD_PERMANENT_ERROR) { @@ -391,6 +384,15 @@ static int64_t fsp_opal_rtc_write(uint32_t year_month_day, goto out; } + if (fsp_in_rr()) { + datetime_to_tm(year_month_day, + hour_minute_second_millisecond, &tm); + rtc_cache_update(&tm); + rtc_tod_cache_dirty = true; + rc = OPAL_SUCCESS; + goto out; + } + if (rtc_write_request_state == RTC_WRITE_NO_REQUEST) { prlog(PR_TRACE, "Sending new RTC write request\n"); rc = fsp_rtc_send_write_request(year_month_day, -- cgit v1.1