aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNathan Lynch2023-02-10 12:41:53 -0600
committerMichael Ellerman2023-02-13 22:35:01 +1100
commitb7d5333c48a21fd6a20f54b6887bcc191d21c273 (patch)
treeb3386f3e7141bb4df2b9917437becbff528cc287 /arch/powerpc
parent5d08633e5f6564b60f1cbe09af3af40a74d66431 (diff)
powerpc/pseries/setup: add missing RTAS retry status handling
The ibm,get-system-parameter RTAS function may return -2 or 990x, which indicate that the caller should try again. pSeries_cmo_feature_init() ignores this, making it possible to fail to detect cooperative memory overcommit capabilities during boot. Move the RTAS call into a conventional rtas_busy_delay()-based loop, dropping unnecessary clearing of rtas_data_buf. Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-5-26929c8cce78@linux.ibm.com
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/pseries/setup.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8ef3270515a9..74e50b6b28d4 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -941,21 +941,25 @@ void pSeries_coalesce_init(void)
*/
static void __init pSeries_cmo_feature_init(void)
{
+ const s32 token = rtas_token("ibm,get-system-parameter");
char *ptr, *key, *value, *end;
int call_status;
int page_order = IOMMU_PAGE_SHIFT_4K;
pr_debug(" -> fw_cmo_feature_init()\n");
- 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,
- CMO_CHARACTERISTICS_TOKEN,
- __pa(rtas_data_buf),
- RTAS_DATA_BUF_SIZE);
- if (call_status != 0) {
+ do {
+ spin_lock(&rtas_data_buf_lock);
+ call_status = rtas_call(token, 3, 1, NULL,
+ CMO_CHARACTERISTICS_TOKEN,
+ __pa(rtas_data_buf),
+ RTAS_DATA_BUF_SIZE);
+ if (call_status == 0)
+ break;
spin_unlock(&rtas_data_buf_lock);
+ } while (rtas_busy_delay(call_status));
+
+ if (call_status != 0) {
pr_debug("CMO not available\n");
pr_debug(" <- fw_cmo_feature_init()\n");
return;