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