Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -35,12 +35,7 @@
#include "offline_states.h"

/* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = {
	.token = RTAS_UNKNOWN_SERVICE,
	.nargs = 0,
	.nret = 1,
	.rets = &rtas_stop_self_args.args[0],
};
static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;

static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
							CPU_STATE_OFFLINE;
@@ -93,15 +88,20 @@ void set_default_offline_state(int cpu)

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();

	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",
	       smp_processor_id(), hard_smp_processor_id());
	enter_rtas(__pa(args));
	enter_rtas(__pa(&args));

	panic("Alas, I survived.\n");
}
@@ -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");

	if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE ||
	if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
			qcss_tok == RTAS_UNKNOWN_SERVICE) {
		printk(KERN_INFO "CPU Hotplug not supported by firmware "
				"- disabling.\n");