Commit 41dd03a9 authored by Tony Breeds's avatar Tony Breeds Committed by Benjamin Herrenschmidt

powerpc/le: Ensure that the 'stop-self' RTAS token is handled correctly

Currently we're storing a host endian RTAS token in
rtas_stop_self_args.token.  We then pass that directly to rtas.  This is
fine on big endian however on little endian the token is not what we
expect.

This will typically result in hitting:
	panic("Alas, I survived.\n");

To fix this we always use the stop-self token in host order and always
convert it to be32 before passing this to rtas.
Signed-off-by: default avatarTony Breeds <tony@bakeyournoodle.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 66f9af83
...@@ -35,12 +35,7 @@ ...@@ -35,12 +35,7 @@
#include "offline_states.h" #include "offline_states.h"
/* This version can't take the spinlock, because it never returns */ /* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = { static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
.token = RTAS_UNKNOWN_SERVICE,
.nargs = 0,
.nret = 1,
.rets = &rtas_stop_self_args.args[0],
};
static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) = static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
CPU_STATE_OFFLINE; CPU_STATE_OFFLINE;
...@@ -93,15 +88,20 @@ void set_default_offline_state(int cpu) ...@@ -93,15 +88,20 @@ void set_default_offline_state(int cpu)
static void rtas_stop_self(void) static void rtas_stop_self(void)
{ {
struct rtas_args *args = &rtas_stop_self_args; struct rtas_args args = {
.token = cpu_to_be32(rtas_stop_self_token),
.nargs = 0,
.nret = 1,
.rets = &args.args[0],
};
local_irq_disable(); local_irq_disable();
BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
printk("cpu %u (hwid %u) Ready to die...\n", printk("cpu %u (hwid %u) Ready to die...\n",
smp_processor_id(), hard_smp_processor_id()); smp_processor_id(), hard_smp_processor_id());
enter_rtas(__pa(args)); enter_rtas(__pa(&args));
panic("Alas, I survived.\n"); panic("Alas, I survived.\n");
} }
...@@ -392,10 +392,10 @@ static int __init pseries_cpu_hotplug_init(void) ...@@ -392,10 +392,10 @@ static int __init pseries_cpu_hotplug_init(void)
} }
} }
rtas_stop_self_args.token = rtas_token("stop-self"); rtas_stop_self_token = rtas_token("stop-self");
qcss_tok = rtas_token("query-cpu-stopped-state"); qcss_tok = rtas_token("query-cpu-stopped-state");
if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
qcss_tok == RTAS_UNKNOWN_SERVICE) { qcss_tok == RTAS_UNKNOWN_SERVICE) {
printk(KERN_INFO "CPU Hotplug not supported by firmware " printk(KERN_INFO "CPU Hotplug not supported by firmware "
"- disabling.\n"); "- disabling.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment