[Skiboot] [PATCH] FSP/RTC: Fix possible FSP R/R issue in rtc write path

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Tue Jun 13 20:22:34 AEST 2017


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 <hegdevasant at linux.vnet.ibm.com>
---
 hw/fsp/fsp-rtc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

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,
-- 
2.9.3



More information about the Skiboot mailing list