Use the same calling and rets return convention with the raw rtas
call rather than requiring callers to load and byteswap return
values out of rtas_args.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/include/asm/rtas.h              |  4 +-
 arch/powerpc/kernel/rtas.c                   | 53 +++++++++++---------
 arch/powerpc/platforms/pseries/hotplug-cpu.c |  2 +-
 arch/powerpc/platforms/pseries/ras.c         |  7 +--
 arch/powerpc/xmon/xmon.c                     |  2 +-
 5 files changed, 33 insertions(+), 35 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 82e5b055fa2a..1014ff140cf8 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -241,8 +241,8 @@ extern int rtas_token(const char *service);
 extern int rtas_service_present(const char *service);
 extern int rtas_call(int token, int, int, int *, ...);
 int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...);
-void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
-                       int nret, ...);
+int raw_rtas_call(struct rtas_args *args, int token,
+                       int nargs, int nret, int *outputs, ...);
 extern void __noreturn rtas_restart(char *cmd);
 extern void rtas_power_off(void);
 extern void __noreturn rtas_halt(void);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index fece066115f0..751a20669669 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -123,7 +123,7 @@ static void call_rtas_display_status(unsigned char c)
                return;
 
        s = lock_rtas();
-       rtas_call_unlocked(&rtas.args, 10, 1, 1, NULL, c);
+       raw_rtas_call(&rtas.args, 10, 1, 1, NULL, c);
        unlock_rtas(s);
 }
 
@@ -434,10 +434,9 @@ static char *__fetch_rtas_last_error(char *altbuf)
 #define get_errorlog_buffer()          NULL
 #endif
 
-
-static void
-va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret,
-                     va_list list)
+static int notrace va_raw_rtas_call(struct rtas_args *args, int token,
+                               int nargs, int nret, int *outputs,
+                               va_list list)
 {
        int i;
 
@@ -453,21 +452,37 @@ va_rtas_call_unlocked(struct rtas_args *args, int token, 
int nargs, int nret,
                args->rets[i] = 0;
 
        do_enter_rtas(__pa(args));
+
+       if (nret > 1 && outputs != NULL) {
+               for (i = 0; i < nret-1; ++i)
+                       outputs[i] = be32_to_cpu(args->rets[i+1]);
+       }
+
+       return (nret > 0) ? be32_to_cpu(args->rets[0]) : 0;
 }
 
-void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int 
nret, ...)
+/*
+ * Like rtas_call but no kmalloc or printk etc in error handling, so
+ * error won't go through log_error. No tracing, may be called in real mode.
+ * rtas_args must be supplied, and appropriate synchronization for the rtas
+ * call being made has to be performed by the caller.
+ */
+int notrace raw_rtas_call(struct rtas_args *args, int token,
+                       int nargs, int nret, int *outputs, ...)
 {
        va_list list;
+       int ret;
 
-       va_start(list, nret);
-       va_rtas_call_unlocked(args, token, nargs, nret, list);
+       va_start(list, outputs);
+       ret = va_raw_rtas_call(args, token, nargs, nret, outputs, list);
        va_end(list);
+
+       return ret;
 }
 
 int rtas_call(int token, int nargs, int nret, int *outputs, ...)
 {
        va_list list;
-       int i;
        unsigned long s;
        struct rtas_args *rtas_args;
        char *buff_copy = NULL;
@@ -482,19 +497,14 @@ int rtas_call(int token, int nargs, int nret, int 
*outputs, ...)
        rtas_args = &rtas.args;
 
        va_start(list, outputs);
-       va_rtas_call_unlocked(rtas_args, token, nargs, nret, list);
+       ret = va_raw_rtas_call(rtas_args, token, nargs, nret, outputs, list);
        va_end(list);
 
        /* A -1 return code indicates that the last command couldn't
           be completed due to a hardware error. */
-       if (be32_to_cpu(rtas_args->rets[0]) == -1)
+       if (ret == -1)
                buff_copy = __fetch_rtas_last_error(NULL);
 
-       if (nret > 1 && outputs != NULL)
-               for (i = 0; i < nret-1; ++i)
-                       outputs[i] = be32_to_cpu(rtas_args->rets[i+1]);
-       ret = (nret > 0)? be32_to_cpu(rtas_args->rets[0]): 0;
-
        unlock_rtas(s);
 
        if (buff_copy) {
@@ -950,7 +960,7 @@ int rtas_call_reentrant(int token, int nargs, int nret, int 
*outputs, ...)
        va_list list;
        struct rtas_args *args;
        unsigned long flags;
-       int i, ret = 0;
+       int ret;
 
        if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
                return -1;
@@ -962,16 +972,9 @@ int rtas_call_reentrant(int token, int nargs, int nret, 
int *outputs, ...)
        args = local_paca->rtas_args_reentrant;
 
        va_start(list, outputs);
-       va_rtas_call_unlocked(args, token, nargs, nret, list);
+       ret = va_raw_rtas_call(args, token, nargs, nret, outputs, list);
        va_end(list);
 
-       if (nret > 1 && outputs)
-               for (i = 0; i < nret - 1; ++i)
-                       outputs[i] = be32_to_cpu(args->rets[i + 1]);
-
-       if (nret > 0)
-               ret = be32_to_cpu(args->rets[0]);
-
        local_irq_restore(flags);
        preempt_enable();
 
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index b81fc846d99c..17c05650b6b9 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -53,7 +53,7 @@ static void rtas_stop_self(void)
 
        BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
 
-       rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
+       raw_rtas_call(&args, rtas_stop_self_token, 0, 1, NULL);
 
        panic("Alas, I survived.\n");
 }
diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index 74c9b1b5bc66..b009ed7de1ee 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -465,12 +465,7 @@ static void fwnmi_release_errinfo(void)
        struct rtas_args rtas_args;
        int ret;
 
-       /*
-        * On pseries, the machine check stack is limited to under 4GB, so
-        * args can be on-stack.
-        */
-       rtas_call_unlocked(&rtas_args, ibm_nmi_interlock_token, 0, 1, NULL);
-       ret = be32_to_cpu(rtas_args.rets[0]);
+       ret = raw_rtas_call(&rtas_args, ibm_nmi_interlock_token, 0, 1, NULL);
        if (ret != 0)
                printk(KERN_ERR "FWNMI: nmi-interlock failed: %d\n", ret);
 }
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index fd72753e8ad5..6f53e8bccc33 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -410,7 +410,7 @@ static inline void disable_surveillance(void)
        if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
                return;
 
-       rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
+       raw_rtas_call(&args, set_indicator_token, 3, 1, NULL,
                           SURVEILLANCE_TOKEN, 0, 0);
 
 #endif /* CONFIG_PPC_PSERIES */
-- 
2.23.0

Reply via email to