lkml.org 
[lkml]   [2014]   [Mar]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.11 129/131] powerpc/le: Ensure that the 'stop-self' RTAS token is handled correctly
    Date
    3.11.10.6 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tony Breeds <tony@bakeyournoodle.com>

    commit 41dd03a94c7d408d2ef32530545097f7d1befe5c upstream.

    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>
    Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/powerpc/platforms/pseries/hotplug-cpu.c | 22 +++++++++++-----------
    1 file changed, 11 insertions(+), 11 deletions(-)

    diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
    index 217ca5c..2882d61 100644
    --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
    +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
    @@ -34,12 +34,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;
    @@ -92,15 +87,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");
    }
    @@ -391,10 +391,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");
    --
    1.9.0


    \
     
     \ /
      Last update: 2014-03-09 16:21    [W:4.517 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site