From: Nathan Lynch <nath...@linux.ibm.com>

The ibm,get-system-parameter RTAS function may return -2 or 990x,
which indicate that the caller should try again.

pseries_lpar_read_hblkrm_characteristics() ignores this, making it
possible to incorrectly detect TLB block invalidation characteristics
at boot.

Move the RTAS call into a coventional rtas_busy_delay()-based loop.

Signed-off-by: Nathan Lynch <nath...@linux.ibm.com>
Fixes: 1211ee61b4a8 ("powerpc/pseries: Read TLB Block Invalidate 
Characteristics")
---
 arch/powerpc/platforms/pseries/lpar.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lpar.c 
b/arch/powerpc/platforms/pseries/lpar.c
index 97ef6499e501..6597b2126ebb 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1481,22 +1481,22 @@ static inline void __init check_lp_set_hblkrm(unsigned 
int lp,
 
 void __init pseries_lpar_read_hblkrm_characteristics(void)
 {
+       const s32 token = rtas_token("ibm,get-system-parameter");
        unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
        int call_status, len, idx, bpsize;
 
        if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
                return;
 
-       spin_lock(&rtas_data_buf_lock);
-       memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
-       call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-                               NULL,
-                               SPLPAR_TLB_BIC_TOKEN,
-                               __pa(rtas_data_buf),
-                               RTAS_DATA_BUF_SIZE);
-       memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
-       local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
-       spin_unlock(&rtas_data_buf_lock);
+       do {
+               spin_lock(&rtas_data_buf_lock);
+               memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
+               call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN,
+                                       __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
+               memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
+               local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
+               spin_unlock(&rtas_data_buf_lock);
+       } while (rtas_busy_delay(call_status));
 
        if (call_status != 0) {
                pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",

-- 
2.39.1

Reply via email to