linux/arch/powerpc/platforms/pseries/hotplug-cpu.c
<<
>>
Prefs
   1/*
   2 * pseries CPU Hotplug infrastructure.
   3 *
   4 * Split out from arch/powerpc/platforms/pseries/setup.c
   5 *  arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c
   6 *
   7 * Peter Bergner, IBM   March 2001.
   8 * Copyright (C) 2001 IBM.
   9 * Dave Engebretsen, Peter Bergner, and
  10 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
  11 * Plus various changes from other IBM teams...
  12 *
  13 * Copyright (C) 2006 Michael Ellerman, IBM Corporation
  14 *
  15 *      This program is free software; you can redistribute it and/or
  16 *      modify it under the terms of the GNU General Public License
  17 *      as published by the Free Software Foundation; either version
  18 *      2 of the License, or (at your option) any later version.
  19 */
  20
  21#define pr_fmt(fmt)     "pseries-hotplug-cpu: " fmt
  22
  23#include <linux/kernel.h>
  24#include <linux/interrupt.h>
  25#include <linux/delay.h>
  26#include <linux/sched.h>        /* for idle_task_exit */
  27#include <linux/cpu.h>
  28#include <linux/of.h>
  29#include <linux/slab.h>
  30#include <asm/prom.h>
  31#include <asm/rtas.h>
  32#include <asm/firmware.h>
  33#include <asm/machdep.h>
  34#include <asm/vdso_datapage.h>
  35#include <asm/xics.h>
  36#include <asm/plpar_wrappers.h>
  37
  38#include "pseries.h"
  39#include "offline_states.h"
  40
  41/* This version can't take the spinlock, because it never returns */
  42static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
  43
  44static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
  45                                                        CPU_STATE_OFFLINE;
  46static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE;
  47
  48static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
  49
  50static bool cede_offline_enabled __read_mostly = true;
  51
  52/*
  53 * Enable/disable cede_offline when available.
  54 */
  55static int __init setup_cede_offline(char *str)
  56{
  57        return (kstrtobool(str, &cede_offline_enabled) == 0);
  58}
  59
  60__setup("cede_offline=", setup_cede_offline);
  61
  62enum cpu_state_vals get_cpu_current_state(int cpu)
  63{
  64        return per_cpu(current_state, cpu);
  65}
  66
  67void set_cpu_current_state(int cpu, enum cpu_state_vals state)
  68{
  69        per_cpu(current_state, cpu) = state;
  70}
  71
  72enum cpu_state_vals get_preferred_offline_state(int cpu)
  73{
  74        return per_cpu(preferred_offline_state, cpu);
  75}
  76
  77void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
  78{
  79        per_cpu(preferred_offline_state, cpu) = state;
  80}
  81
  82void set_default_offline_state(int cpu)
  83{
  84        per_cpu(preferred_offline_state, cpu) = default_offline_state;
  85}
  86
  87static void rtas_stop_self(void)
  88{
  89        static struct rtas_args args;
  90
  91        local_irq_disable();
  92
  93        BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
  94
  95        printk("cpu %u (hwid %u) Ready to die...\n",
  96               smp_processor_id(), hard_smp_processor_id());
  97
  98        rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
  99
 100        panic("Alas, I survived.\n");
 101}
 102
 103static void pseries_mach_cpu_die(void)
 104{
 105        unsigned int cpu = smp_processor_id();
 106        unsigned int hwcpu = hard_smp_processor_id();
 107        u8 cede_latency_hint = 0;
 108
 109        local_irq_disable();
 110        idle_task_exit();
 111        xics_teardown_cpu();
 112
 113        if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 114                set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
 115                if (ppc_md.suspend_disable_cpu)
 116                        ppc_md.suspend_disable_cpu();
 117
 118                cede_latency_hint = 2;
 119
 120                get_lppaca()->idle = 1;
 121                if (!lppaca_shared_proc(get_lppaca()))
 122                        get_lppaca()->donate_dedicated_cpu = 1;
 123
 124                while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 125                        while (!prep_irq_for_idle()) {
 126                                local_irq_enable();
 127                                local_irq_disable();
 128                        }
 129
 130                        extended_cede_processor(cede_latency_hint);
 131                }
 132
 133                local_irq_disable();
 134
 135                if (!lppaca_shared_proc(get_lppaca()))
 136                        get_lppaca()->donate_dedicated_cpu = 0;
 137                get_lppaca()->idle = 0;
 138
 139                if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
 140                        unregister_slb_shadow(hwcpu);
 141
 142                        hard_irq_disable();
 143                        /*
 144                         * Call to start_secondary_resume() will not return.
 145                         * Kernel stack will be reset and start_secondary()
 146                         * will be called to continue the online operation.
 147                         */
 148                        start_secondary_resume();
 149                }
 150        }
 151
 152        /* Requested state is CPU_STATE_OFFLINE at this point */
 153        WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
 154
 155        set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
 156        unregister_slb_shadow(hwcpu);
 157        rtas_stop_self();
 158
 159        /* Should never get here... */
 160        BUG();
 161        for(;;);
 162}
 163
 164static int pseries_cpu_disable(void)
 165{
 166        int cpu = smp_processor_id();
 167
 168        set_cpu_online(cpu, false);
 169        vdso_data->processorCount--;
 170
 171        /*fix boot_cpuid here*/
 172        if (cpu == boot_cpuid)
 173                boot_cpuid = cpumask_any(cpu_online_mask);
 174
 175        /* FIXME: abstract this to not be platform specific later on */
 176        xics_migrate_irqs_away();
 177        return 0;
 178}
 179
 180/*
 181 * pseries_cpu_die: Wait for the cpu to die.
 182 * @cpu: logical processor id of the CPU whose death we're awaiting.
 183 *
 184 * This function is called from the context of the thread which is performing
 185 * the cpu-offline. Here we wait for long enough to allow the cpu in question
 186 * to self-destroy so that the cpu-offline thread can send the CPU_DEAD
 187 * notifications.
 188 *
 189 * OTOH, pseries_mach_cpu_die() is called by the @cpu when it wants to
 190 * self-destruct.
 191 */
 192static void pseries_cpu_die(unsigned int cpu)
 193{
 194        int tries;
 195        int cpu_status = 1;
 196        unsigned int pcpu = get_hard_smp_processor_id(cpu);
 197
 198        if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 199                cpu_status = 1;
 200                for (tries = 0; tries < 5000; tries++) {
 201                        if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) {
 202                                cpu_status = 0;
 203                                break;
 204                        }
 205                        msleep(1);
 206                }
 207        } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
 208
 209                for (tries = 0; tries < 25; tries++) {
 210                        cpu_status = smp_query_cpu_stopped(pcpu);
 211                        if (cpu_status == QCSS_STOPPED ||
 212                            cpu_status == QCSS_HARDWARE_ERROR)
 213                                break;
 214                        cpu_relax();
 215                }
 216        }
 217
 218        if (cpu_status != 0) {
 219                printk("Querying DEAD? cpu %i (%i) shows %i\n",
 220                       cpu, pcpu, cpu_status);
 221        }
 222
 223        /* Isolation and deallocation are definitely done by
 224         * drslot_chrp_cpu.  If they were not they would be
 225         * done here.  Change isolate state to Isolate and
 226         * change allocation-state to Unusable.
 227         */
 228        paca[cpu].cpu_start = 0;
 229}
 230
 231/*
 232 * Update cpu_present_mask and paca(s) for a new cpu node.  The wrinkle
 233 * here is that a cpu device node may represent up to two logical cpus
 234 * in the SMT case.  We must honor the assumption in other code that
 235 * the logical ids for sibling SMT threads x and y are adjacent, such
 236 * that x^1 == y and y^1 == x.
 237 */
 238static int pseries_add_processor(struct device_node *np)
 239{
 240        unsigned int cpu;
 241        cpumask_var_t candidate_mask, tmp;
 242        int err = -ENOSPC, len, nthreads, i;
 243        const __be32 *intserv;
 244
 245        intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
 246        if (!intserv)
 247                return 0;
 248
 249        zalloc_cpumask_var(&candidate_mask, GFP_KERNEL);
 250        zalloc_cpumask_var(&tmp, GFP_KERNEL);
 251
 252        nthreads = len / sizeof(u32);
 253        for (i = 0; i < nthreads; i++)
 254                cpumask_set_cpu(i, tmp);
 255
 256        cpu_maps_update_begin();
 257
 258        BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask));
 259
 260        /* Get a bitmap of unoccupied slots. */
 261        cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask);
 262        if (cpumask_empty(candidate_mask)) {
 263                /* If we get here, it most likely means that NR_CPUS is
 264                 * less than the partition's max processors setting.
 265                 */
 266                printk(KERN_ERR "Cannot add cpu %s; this system configuration"
 267                       " supports %d logical cpus.\n", np->full_name,
 268                       num_possible_cpus());
 269                goto out_unlock;
 270        }
 271
 272        while (!cpumask_empty(tmp))
 273                if (cpumask_subset(tmp, candidate_mask))
 274                        /* Found a range where we can insert the new cpu(s) */
 275                        break;
 276                else
 277                        cpumask_shift_left(tmp, tmp, nthreads);
 278
 279        if (cpumask_empty(tmp)) {
 280                printk(KERN_ERR "Unable to find space in cpu_present_mask for"
 281                       " processor %s with %d thread(s)\n", np->name,
 282                       nthreads);
 283                goto out_unlock;
 284        }
 285
 286        for_each_cpu(cpu, tmp) {
 287                BUG_ON(cpu_present(cpu));
 288                set_cpu_present(cpu, true);
 289                set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++));
 290        }
 291        err = 0;
 292out_unlock:
 293        cpu_maps_update_done();
 294        free_cpumask_var(candidate_mask);
 295        free_cpumask_var(tmp);
 296        return err;
 297}
 298
 299/*
 300 * Update the present map for a cpu node which is going away, and set
 301 * the hard id in the paca(s) to -1 to be consistent with boot time
 302 * convention for non-present cpus.
 303 */
 304static void pseries_remove_processor(struct device_node *np)
 305{
 306        unsigned int cpu;
 307        int len, nthreads, i;
 308        const __be32 *intserv;
 309        u32 thread;
 310
 311        intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
 312        if (!intserv)
 313                return;
 314
 315        nthreads = len / sizeof(u32);
 316
 317        cpu_maps_update_begin();
 318        for (i = 0; i < nthreads; i++) {
 319                thread = be32_to_cpu(intserv[i]);
 320                for_each_present_cpu(cpu) {
 321                        if (get_hard_smp_processor_id(cpu) != thread)
 322                                continue;
 323                        BUG_ON(cpu_online(cpu));
 324                        set_cpu_present(cpu, false);
 325                        set_hard_smp_processor_id(cpu, -1);
 326                        break;
 327                }
 328                if (cpu >= nr_cpu_ids)
 329                        printk(KERN_WARNING "Could not find cpu to remove "
 330                               "with physical id 0x%x\n", thread);
 331        }
 332        cpu_maps_update_done();
 333}
 334
 335static int dlpar_online_cpu(struct device_node *dn)
 336{
 337        int rc = 0;
 338        unsigned int cpu;
 339        int len, nthreads, i;
 340        const __be32 *intserv;
 341        u32 thread;
 342
 343        intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
 344        if (!intserv)
 345                return -EINVAL;
 346
 347        nthreads = len / sizeof(u32);
 348
 349        cpu_maps_update_begin();
 350        for (i = 0; i < nthreads; i++) {
 351                thread = be32_to_cpu(intserv[i]);
 352                for_each_present_cpu(cpu) {
 353                        if (get_hard_smp_processor_id(cpu) != thread)
 354                                continue;
 355                        BUG_ON(get_cpu_current_state(cpu)
 356                                        != CPU_STATE_OFFLINE);
 357                        cpu_maps_update_done();
 358                        rc = device_online(get_cpu_device(cpu));
 359                        if (rc)
 360                                goto out;
 361                        cpu_maps_update_begin();
 362
 363                        break;
 364                }
 365                if (cpu == num_possible_cpus())
 366                        printk(KERN_WARNING "Could not find cpu to online "
 367                               "with physical id 0x%x\n", thread);
 368        }
 369        cpu_maps_update_done();
 370
 371out:
 372        return rc;
 373
 374}
 375
 376static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index)
 377{
 378        struct device_node *child = NULL;
 379        u32 my_drc_index;
 380        bool found;
 381        int rc;
 382
 383        /* Assume cpu doesn't exist */
 384        found = false;
 385
 386        for_each_child_of_node(parent, child) {
 387                rc = of_property_read_u32(child, "ibm,my-drc-index",
 388                                          &my_drc_index);
 389                if (rc)
 390                        continue;
 391
 392                if (my_drc_index == drc_index) {
 393                        of_node_put(child);
 394                        found = true;
 395                        break;
 396                }
 397        }
 398
 399        return found;
 400}
 401
 402static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
 403{
 404        bool found = false;
 405        int rc, index;
 406
 407        index = 0;
 408        while (!found) {
 409                u32 drc;
 410
 411                rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
 412                                                index++, &drc);
 413                if (rc)
 414                        break;
 415
 416                if (drc == drc_index)
 417                        found = true;
 418        }
 419
 420        return found;
 421}
 422
 423static ssize_t dlpar_cpu_add(u32 drc_index)
 424{
 425        struct device_node *dn, *parent;
 426        int rc, saved_rc;
 427
 428        pr_debug("Attempting to add CPU, drc index: %x\n", drc_index);
 429
 430        parent = of_find_node_by_path("/cpus");
 431        if (!parent) {
 432                pr_warn("Failed to find CPU root node \"/cpus\"\n");
 433                return -ENODEV;
 434        }
 435
 436        if (dlpar_cpu_exists(parent, drc_index)) {
 437                of_node_put(parent);
 438                pr_warn("CPU with drc index %x already exists\n", drc_index);
 439                return -EINVAL;
 440        }
 441
 442        if (!valid_cpu_drc_index(parent, drc_index)) {
 443                of_node_put(parent);
 444                pr_warn("Cannot find CPU (drc index %x) to add.\n", drc_index);
 445                return -EINVAL;
 446        }
 447
 448        rc = dlpar_acquire_drc(drc_index);
 449        if (rc) {
 450                pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
 451                        rc, drc_index);
 452                of_node_put(parent);
 453                return -EINVAL;
 454        }
 455
 456        dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
 457        of_node_put(parent);
 458        if (!dn) {
 459                pr_warn("Failed call to configure-connector, drc index: %x\n",
 460                        drc_index);
 461                dlpar_release_drc(drc_index);
 462                return -EINVAL;
 463        }
 464
 465        rc = dlpar_attach_node(dn);
 466        if (rc) {
 467                saved_rc = rc;
 468                pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n",
 469                        dn->name, rc, drc_index);
 470
 471                rc = dlpar_release_drc(drc_index);
 472                if (!rc)
 473                        dlpar_free_cc_nodes(dn);
 474
 475                return saved_rc;
 476        }
 477
 478        rc = dlpar_online_cpu(dn);
 479        if (rc) {
 480                saved_rc = rc;
 481                pr_warn("Failed to online cpu %s, rc: %d, drc index: %x\n",
 482                        dn->name, rc, drc_index);
 483
 484                rc = dlpar_detach_node(dn);
 485                if (!rc)
 486                        dlpar_release_drc(drc_index);
 487
 488                return saved_rc;
 489        }
 490
 491        pr_debug("Successfully added CPU %s, drc index: %x\n", dn->name,
 492                 drc_index);
 493        return rc;
 494}
 495
 496static int dlpar_offline_cpu(struct device_node *dn)
 497{
 498        int rc = 0;
 499        unsigned int cpu;
 500        int len, nthreads, i;
 501        const __be32 *intserv;
 502        u32 thread;
 503
 504        intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
 505        if (!intserv)
 506                return -EINVAL;
 507
 508        nthreads = len / sizeof(u32);
 509
 510        cpu_maps_update_begin();
 511        for (i = 0; i < nthreads; i++) {
 512                thread = be32_to_cpu(intserv[i]);
 513                for_each_present_cpu(cpu) {
 514                        if (get_hard_smp_processor_id(cpu) != thread)
 515                                continue;
 516
 517                        if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
 518                                break;
 519
 520                        if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
 521                                set_preferred_offline_state(cpu,
 522                                                            CPU_STATE_OFFLINE);
 523                                cpu_maps_update_done();
 524                                rc = device_offline(get_cpu_device(cpu));
 525                                if (rc)
 526                                        goto out;
 527                                cpu_maps_update_begin();
 528                                break;
 529
 530                        }
 531
 532                        /*
 533                         * The cpu is in CPU_STATE_INACTIVE.
 534                         * Upgrade it's state to CPU_STATE_OFFLINE.
 535                         */
 536                        set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
 537                        BUG_ON(plpar_hcall_norets(H_PROD, thread)
 538                                                                != H_SUCCESS);
 539                        __cpu_die(cpu);
 540                        break;
 541                }
 542                if (cpu == num_possible_cpus())
 543                        printk(KERN_WARNING "Could not find cpu to offline with physical id 0x%x\n", thread);
 544        }
 545        cpu_maps_update_done();
 546
 547out:
 548        return rc;
 549
 550}
 551
 552static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
 553{
 554        int rc;
 555
 556        pr_debug("Attemping to remove CPU %s, drc index: %x\n",
 557                 dn->name, drc_index);
 558
 559        rc = dlpar_offline_cpu(dn);
 560        if (rc) {
 561                pr_warn("Failed to offline CPU %s, rc: %d\n", dn->name, rc);
 562                return -EINVAL;
 563        }
 564
 565        rc = dlpar_release_drc(drc_index);
 566        if (rc) {
 567                pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
 568                        drc_index, dn->name, rc);
 569                dlpar_online_cpu(dn);
 570                return rc;
 571        }
 572
 573        rc = dlpar_detach_node(dn);
 574        if (rc) {
 575                int saved_rc = rc;
 576
 577                pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc);
 578
 579                rc = dlpar_acquire_drc(drc_index);
 580                if (!rc)
 581                        dlpar_online_cpu(dn);
 582
 583                return saved_rc;
 584        }
 585
 586        pr_debug("Successfully removed CPU, drc index: %x\n", drc_index);
 587        return 0;
 588}
 589
 590static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
 591{
 592        struct device_node *dn;
 593        u32 my_index;
 594        int rc;
 595
 596        for_each_node_by_type(dn, "cpu") {
 597                rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index);
 598                if (rc)
 599                        continue;
 600
 601                if (my_index == drc_index)
 602                        break;
 603        }
 604
 605        return dn;
 606}
 607
 608static int dlpar_cpu_remove_by_index(u32 drc_index)
 609{
 610        struct device_node *dn;
 611        int rc;
 612
 613        dn = cpu_drc_index_to_dn(drc_index);
 614        if (!dn) {
 615                pr_warn("Cannot find CPU (drc index %x) to remove\n",
 616                        drc_index);
 617                return -ENODEV;
 618        }
 619
 620        rc = dlpar_cpu_remove(dn, drc_index);
 621        of_node_put(dn);
 622        return rc;
 623}
 624
 625static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
 626{
 627        struct device_node *dn;
 628        int cpus_found = 0;
 629        int rc;
 630
 631        /* We want to find cpus_to_remove + 1 CPUs to ensure we do not
 632         * remove the last CPU.
 633         */
 634        for_each_node_by_type(dn, "cpu") {
 635                cpus_found++;
 636
 637                if (cpus_found > cpus_to_remove) {
 638                        of_node_put(dn);
 639                        break;
 640                }
 641
 642                /* Note that cpus_found is always 1 ahead of the index
 643                 * into the cpu_drcs array, so we use cpus_found - 1
 644                 */
 645                rc = of_property_read_u32(dn, "ibm,my-drc-index",
 646                                          &cpu_drcs[cpus_found - 1]);
 647                if (rc) {
 648                        pr_warn("Error occurred getting drc-index for %s\n",
 649                                dn->name);
 650                        of_node_put(dn);
 651                        return -1;
 652                }
 653        }
 654
 655        if (cpus_found < cpus_to_remove) {
 656                pr_warn("Failed to find enough CPUs (%d of %d) to remove\n",
 657                        cpus_found, cpus_to_remove);
 658        } else if (cpus_found == cpus_to_remove) {
 659                pr_warn("Cannot remove all CPUs\n");
 660        }
 661
 662        return cpus_found;
 663}
 664
 665static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
 666{
 667        u32 *cpu_drcs;
 668        int cpus_found;
 669        int cpus_removed = 0;
 670        int i, rc;
 671
 672        pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove);
 673
 674        cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL);
 675        if (!cpu_drcs)
 676                return -EINVAL;
 677
 678        cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove);
 679        if (cpus_found <= cpus_to_remove) {
 680                kfree(cpu_drcs);
 681                return -EINVAL;
 682        }
 683
 684        for (i = 0; i < cpus_to_remove; i++) {
 685                rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
 686                if (rc)
 687                        break;
 688
 689                cpus_removed++;
 690        }
 691
 692        if (cpus_removed != cpus_to_remove) {
 693                pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
 694
 695                for (i = 0; i < cpus_removed; i++)
 696                        dlpar_cpu_add(cpu_drcs[i]);
 697
 698                rc = -EINVAL;
 699        } else {
 700                rc = 0;
 701        }
 702
 703        kfree(cpu_drcs);
 704        return rc;
 705}
 706
 707static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add)
 708{
 709        struct device_node *parent;
 710        int cpus_found = 0;
 711        int index, rc;
 712
 713        parent = of_find_node_by_path("/cpus");
 714        if (!parent) {
 715                pr_warn("Could not find CPU root node in device tree\n");
 716                kfree(cpu_drcs);
 717                return -1;
 718        }
 719
 720        /* Search the ibm,drc-indexes array for possible CPU drcs to
 721         * add. Note that the format of the ibm,drc-indexes array is
 722         * the number of entries in the array followed by the array
 723         * of drc values so we start looking at index = 1.
 724         */
 725        index = 1;
 726        while (cpus_found < cpus_to_add) {
 727                u32 drc;
 728
 729                rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
 730                                                index++, &drc);
 731                if (rc)
 732                        break;
 733
 734                if (dlpar_cpu_exists(parent, drc))
 735                        continue;
 736
 737                cpu_drcs[cpus_found++] = drc;
 738        }
 739
 740        of_node_put(parent);
 741        return cpus_found;
 742}
 743
 744static int dlpar_cpu_add_by_count(u32 cpus_to_add)
 745{
 746        u32 *cpu_drcs;
 747        int cpus_added = 0;
 748        int cpus_found;
 749        int i, rc;
 750
 751        pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
 752
 753        cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
 754        if (!cpu_drcs)
 755                return -EINVAL;
 756
 757        cpus_found = find_dlpar_cpus_to_add(cpu_drcs, cpus_to_add);
 758        if (cpus_found < cpus_to_add) {
 759                pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
 760                        cpus_found, cpus_to_add);
 761                kfree(cpu_drcs);
 762                return -EINVAL;
 763        }
 764
 765        for (i = 0; i < cpus_to_add; i++) {
 766                rc = dlpar_cpu_add(cpu_drcs[i]);
 767                if (rc)
 768                        break;
 769
 770                cpus_added++;
 771        }
 772
 773        if (cpus_added < cpus_to_add) {
 774                pr_warn("CPU hot-add failed, removing any added CPUs\n");
 775
 776                for (i = 0; i < cpus_added; i++)
 777                        dlpar_cpu_remove_by_index(cpu_drcs[i]);
 778
 779                rc = -EINVAL;
 780        } else {
 781                rc = 0;
 782        }
 783
 784        kfree(cpu_drcs);
 785        return rc;
 786}
 787
 788int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
 789{
 790        u32 count, drc_index;
 791        int rc;
 792
 793        count = hp_elog->_drc_u.drc_count;
 794        drc_index = hp_elog->_drc_u.drc_index;
 795
 796        lock_device_hotplug();
 797
 798        switch (hp_elog->action) {
 799        case PSERIES_HP_ELOG_ACTION_REMOVE:
 800                if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
 801                        rc = dlpar_cpu_remove_by_count(count);
 802                else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
 803                        rc = dlpar_cpu_remove_by_index(drc_index);
 804                else
 805                        rc = -EINVAL;
 806                break;
 807        case PSERIES_HP_ELOG_ACTION_ADD:
 808                if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
 809                        rc = dlpar_cpu_add_by_count(count);
 810                else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
 811                        rc = dlpar_cpu_add(drc_index);
 812                else
 813                        rc = -EINVAL;
 814                break;
 815        default:
 816                pr_err("Invalid action (%d) specified\n", hp_elog->action);
 817                rc = -EINVAL;
 818                break;
 819        }
 820
 821        unlock_device_hotplug();
 822        return rc;
 823}
 824
 825#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 826
 827static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
 828{
 829        u32 drc_index;
 830        int rc;
 831
 832        rc = kstrtou32(buf, 0, &drc_index);
 833        if (rc)
 834                return -EINVAL;
 835
 836        rc = dlpar_cpu_add(drc_index);
 837
 838        return rc ? rc : count;
 839}
 840
 841static ssize_t dlpar_cpu_release(const char *buf, size_t count)
 842{
 843        struct device_node *dn;
 844        u32 drc_index;
 845        int rc;
 846
 847        dn = of_find_node_by_path(buf);
 848        if (!dn)
 849                return -EINVAL;
 850
 851        rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
 852        if (rc) {
 853                of_node_put(dn);
 854                return -EINVAL;
 855        }
 856
 857        rc = dlpar_cpu_remove(dn, drc_index);
 858        of_node_put(dn);
 859
 860        return rc ? rc : count;
 861}
 862
 863#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 864
 865static int pseries_smp_notifier(struct notifier_block *nb,
 866                                unsigned long action, void *data)
 867{
 868        struct of_reconfig_data *rd = data;
 869        int err = 0;
 870
 871        switch (action) {
 872        case OF_RECONFIG_ATTACH_NODE:
 873                err = pseries_add_processor(rd->dn);
 874                break;
 875        case OF_RECONFIG_DETACH_NODE:
 876                pseries_remove_processor(rd->dn);
 877                break;
 878        }
 879        return notifier_from_errno(err);
 880}
 881
 882static struct notifier_block pseries_smp_nb = {
 883        .notifier_call = pseries_smp_notifier,
 884};
 885
 886#define MAX_CEDE_LATENCY_LEVELS         4
 887#define CEDE_LATENCY_PARAM_LENGTH       10
 888#define CEDE_LATENCY_PARAM_MAX_LENGTH   \
 889        (MAX_CEDE_LATENCY_LEVELS * CEDE_LATENCY_PARAM_LENGTH * sizeof(char))
 890#define CEDE_LATENCY_TOKEN              45
 891
 892static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH];
 893
 894static int parse_cede_parameters(void)
 895{
 896        memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
 897        return rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
 898                         NULL,
 899                         CEDE_LATENCY_TOKEN,
 900                         __pa(cede_parameters),
 901                         CEDE_LATENCY_PARAM_MAX_LENGTH);
 902}
 903
 904static int __init pseries_cpu_hotplug_init(void)
 905{
 906        int cpu;
 907        int qcss_tok;
 908
 909#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 910        ppc_md.cpu_probe = dlpar_cpu_probe;
 911        ppc_md.cpu_release = dlpar_cpu_release;
 912#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 913
 914        rtas_stop_self_token = rtas_token("stop-self");
 915        qcss_tok = rtas_token("query-cpu-stopped-state");
 916
 917        if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
 918                        qcss_tok == RTAS_UNKNOWN_SERVICE) {
 919                printk(KERN_INFO "CPU Hotplug not supported by firmware "
 920                                "- disabling.\n");
 921                return 0;
 922        }
 923
 924        ppc_md.cpu_die = pseries_mach_cpu_die;
 925        smp_ops->cpu_disable = pseries_cpu_disable;
 926        smp_ops->cpu_die = pseries_cpu_die;
 927
 928        /* Processors can be added/removed only on LPAR */
 929        if (firmware_has_feature(FW_FEATURE_LPAR)) {
 930                of_reconfig_notifier_register(&pseries_smp_nb);
 931                cpu_maps_update_begin();
 932                if (cede_offline_enabled && parse_cede_parameters() == 0) {
 933                        default_offline_state = CPU_STATE_INACTIVE;
 934                        for_each_online_cpu(cpu)
 935                                set_default_offline_state(cpu);
 936                }
 937                cpu_maps_update_done();
 938        }
 939
 940        return 0;
 941}
 942machine_arch_initcall(pseries, pseries_cpu_hotplug_init);
 943