Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Tony Breeds <tony@bakeyournoodle.com>
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Tony Breeds and committed by
Benjamin Herrenschmidt
41dd03a9 66f9af83

+11 -11
+11 -11
arch/powerpc/platforms/pseries/hotplug-cpu.c
··· 35 35 #include "offline_states.h" 36 36 37 37 /* This version can't take the spinlock, because it never returns */ 38 - static struct rtas_args rtas_stop_self_args = { 39 - .token = RTAS_UNKNOWN_SERVICE, 40 - .nargs = 0, 41 - .nret = 1, 42 - .rets = &rtas_stop_self_args.args[0], 43 - }; 38 + static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE; 44 39 45 40 static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) = 46 41 CPU_STATE_OFFLINE; ··· 88 93 89 94 static void rtas_stop_self(void) 90 95 { 91 - struct rtas_args *args = &rtas_stop_self_args; 96 + struct rtas_args args = { 97 + .token = cpu_to_be32(rtas_stop_self_token), 98 + .nargs = 0, 99 + .nret = 1, 100 + .rets = &args.args[0], 101 + }; 92 102 93 103 local_irq_disable(); 94 104 95 - BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); 105 + BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); 96 106 97 107 printk("cpu %u (hwid %u) Ready to die...\n", 98 108 smp_processor_id(), hard_smp_processor_id()); 99 - enter_rtas(__pa(args)); 109 + enter_rtas(__pa(&args)); 100 110 101 111 panic("Alas, I survived.\n"); 102 112 } ··· 392 392 } 393 393 } 394 394 395 - rtas_stop_self_args.token = rtas_token("stop-self"); 395 + rtas_stop_self_token = rtas_token("stop-self"); 396 396 qcss_tok = rtas_token("query-cpu-stopped-state"); 397 397 398 - if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || 398 + if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE || 399 399 qcss_tok == RTAS_UNKNOWN_SERVICE) { 400 400 printk(KERN_INFO "CPU Hotplug not supported by firmware " 401 401 "- disabling.\n");