1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * pseries Memory Hotplug infrastructure. 4 * 5 * Copyright (C) 2008 Badari Pulavarty, IBM Corporation 6 */ 7 8 #define pr_fmt(fmt) "pseries-hotplug-mem: " fmt 9 10 #include <linux/of.h> 11 #include <linux/of_address.h> 12 #include <linux/memblock.h> 13 #include <linux/memory.h> 14 #include <linux/memory_hotplug.h> 15 #include <linux/slab.h> 16 17 #include <asm/firmware.h> 18 #include <asm/machdep.h> 19 #include <asm/prom.h> 20 #include <asm/sparsemem.h> 21 #include <asm/fadump.h> 22 #include <asm/drmem.h> 23 #include "pseries.h" 24 25 unsigned long pseries_memory_block_size(void) 26 { 27 struct device_node *np; 28 u64 memblock_size = MIN_MEMORY_BLOCK_SIZE; 29 struct resource r; 30 31 np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 32 if (np) { 33 int len; 34 int size_cells; 35 const __be32 *prop; 36 37 size_cells = of_n_size_cells(np); 38 39 prop = of_get_property(np, "ibm,lmb-size", &len); 40 if (prop && len >= size_cells * sizeof(__be32)) 41 memblock_size = of_read_number(prop, size_cells); 42 of_node_put(np); 43 44 } else if (machine_is(pseries)) { 45 /* This fallback really only applies to pseries */ 46 unsigned int memzero_size = 0; 47 48 np = of_find_node_by_path("/memory@0"); 49 if (np) { 50 if (!of_address_to_resource(np, 0, &r)) 51 memzero_size = resource_size(&r); 52 of_node_put(np); 53 } 54 55 if (memzero_size) { 56 /* We now know the size of memory@0, use this to find 57 * the first memoryblock and get its size. 58 */ 59 char buf[64]; 60 61 sprintf(buf, "/memory@%x", memzero_size); 62 np = of_find_node_by_path(buf); 63 if (np) { 64 if (!of_address_to_resource(np, 0, &r)) 65 memblock_size = resource_size(&r); 66 of_node_put(np); 67 } 68 } 69 } 70 return memblock_size; 71 } 72 73 static void dlpar_free_property(struct property *prop) 74 { 75 kfree(prop->name); 76 kfree(prop->value); 77 kfree(prop); 78 } 79 80 static struct property *dlpar_clone_property(struct property *prop, 81 u32 prop_size) 82 { 83 struct property *new_prop; 84 85 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); 86 if (!new_prop) 87 return NULL; 88 89 new_prop->name = kstrdup(prop->name, GFP_KERNEL); 90 new_prop->value = kzalloc(prop_size, GFP_KERNEL); 91 if (!new_prop->name || !new_prop->value) { 92 dlpar_free_property(new_prop); 93 return NULL; 94 } 95 96 memcpy(new_prop->value, prop->value, prop->length); 97 new_prop->length = prop_size; 98 99 of_property_set_flag(new_prop, OF_DYNAMIC); 100 return new_prop; 101 } 102 103 static bool find_aa_index(struct device_node *dr_node, 104 struct property *ala_prop, 105 const u32 *lmb_assoc, u32 *aa_index) 106 { 107 u32 *assoc_arrays, new_prop_size; 108 struct property *new_prop; 109 int aa_arrays, aa_array_entries, aa_array_sz; 110 int i, index; 111 112 /* 113 * The ibm,associativity-lookup-arrays property is defined to be 114 * a 32-bit value specifying the number of associativity arrays 115 * followed by a 32-bitvalue specifying the number of entries per 116 * array, followed by the associativity arrays. 117 */ 118 assoc_arrays = ala_prop->value; 119 120 aa_arrays = be32_to_cpu(assoc_arrays[0]); 121 aa_array_entries = be32_to_cpu(assoc_arrays[1]); 122 aa_array_sz = aa_array_entries * sizeof(u32); 123 124 for (i = 0; i < aa_arrays; i++) { 125 index = (i * aa_array_entries) + 2; 126 127 if (memcmp(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz)) 128 continue; 129 130 *aa_index = i; 131 return true; 132 } 133 134 new_prop_size = ala_prop->length + aa_array_sz; 135 new_prop = dlpar_clone_property(ala_prop, new_prop_size); 136 if (!new_prop) 137 return false; 138 139 assoc_arrays = new_prop->value; 140 141 /* increment the number of entries in the lookup array */ 142 assoc_arrays[0] = cpu_to_be32(aa_arrays + 1); 143 144 /* copy the new associativity into the lookup array */ 145 index = aa_arrays * aa_array_entries + 2; 146 memcpy(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz); 147 148 of_update_property(dr_node, new_prop); 149 150 /* 151 * The associativity lookup array index for this lmb is 152 * number of entries - 1 since we added its associativity 153 * to the end of the lookup array. 154 */ 155 *aa_index = be32_to_cpu(assoc_arrays[0]) - 1; 156 return true; 157 } 158 159 static int update_lmb_associativity_index(struct drmem_lmb *lmb) 160 { 161 struct device_node *parent, *lmb_node, *dr_node; 162 struct property *ala_prop; 163 const u32 *lmb_assoc; 164 u32 aa_index; 165 bool found; 166 167 parent = of_find_node_by_path("/"); 168 if (!parent) 169 return -ENODEV; 170 171 lmb_node = dlpar_configure_connector(cpu_to_be32(lmb->drc_index), 172 parent); 173 of_node_put(parent); 174 if (!lmb_node) 175 return -EINVAL; 176 177 lmb_assoc = of_get_property(lmb_node, "ibm,associativity", NULL); 178 if (!lmb_assoc) { 179 dlpar_free_cc_nodes(lmb_node); 180 return -ENODEV; 181 } 182 183 dr_node = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 184 if (!dr_node) { 185 dlpar_free_cc_nodes(lmb_node); 186 return -ENODEV; 187 } 188 189 ala_prop = of_find_property(dr_node, "ibm,associativity-lookup-arrays", 190 NULL); 191 if (!ala_prop) { 192 of_node_put(dr_node); 193 dlpar_free_cc_nodes(lmb_node); 194 return -ENODEV; 195 } 196 197 found = find_aa_index(dr_node, ala_prop, lmb_assoc, &aa_index); 198 199 of_node_put(dr_node); 200 dlpar_free_cc_nodes(lmb_node); 201 202 if (!found) { 203 pr_err("Could not find LMB associativity\n"); 204 return -1; 205 } 206 207 lmb->aa_index = aa_index; 208 return 0; 209 } 210 211 static struct memory_block *lmb_to_memblock(struct drmem_lmb *lmb) 212 { 213 unsigned long section_nr; 214 struct mem_section *mem_sect; 215 struct memory_block *mem_block; 216 217 section_nr = pfn_to_section_nr(PFN_DOWN(lmb->base_addr)); 218 mem_sect = __nr_to_section(section_nr); 219 220 mem_block = find_memory_block(mem_sect); 221 return mem_block; 222 } 223 224 static int get_lmb_range(u32 drc_index, int n_lmbs, 225 struct drmem_lmb **start_lmb, 226 struct drmem_lmb **end_lmb) 227 { 228 struct drmem_lmb *lmb, *start, *end; 229 struct drmem_lmb *limit; 230 231 start = NULL; 232 for_each_drmem_lmb(lmb) { 233 if (lmb->drc_index == drc_index) { 234 start = lmb; 235 break; 236 } 237 } 238 239 if (!start) 240 return -EINVAL; 241 242 end = &start[n_lmbs]; 243 244 limit = &drmem_info->lmbs[drmem_info->n_lmbs]; 245 if (end > limit) 246 return -EINVAL; 247 248 *start_lmb = start; 249 *end_lmb = end; 250 return 0; 251 } 252 253 static int dlpar_change_lmb_state(struct drmem_lmb *lmb, bool online) 254 { 255 struct memory_block *mem_block; 256 int rc; 257 258 mem_block = lmb_to_memblock(lmb); 259 if (!mem_block) 260 return -EINVAL; 261 262 if (online && mem_block->dev.offline) 263 rc = device_online(&mem_block->dev); 264 else if (!online && !mem_block->dev.offline) 265 rc = device_offline(&mem_block->dev); 266 else 267 rc = 0; 268 269 put_device(&mem_block->dev); 270 271 return rc; 272 } 273 274 static int dlpar_online_lmb(struct drmem_lmb *lmb) 275 { 276 return dlpar_change_lmb_state(lmb, true); 277 } 278 279 #ifdef CONFIG_MEMORY_HOTREMOVE 280 static int dlpar_offline_lmb(struct drmem_lmb *lmb) 281 { 282 return dlpar_change_lmb_state(lmb, false); 283 } 284 285 static int pseries_remove_memblock(unsigned long base, unsigned long memblock_size) 286 { 287 unsigned long block_sz, start_pfn; 288 int sections_per_block; 289 int i, nid; 290 291 start_pfn = base >> PAGE_SHIFT; 292 293 lock_device_hotplug(); 294 295 if (!pfn_valid(start_pfn)) 296 goto out; 297 298 block_sz = pseries_memory_block_size(); 299 sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; 300 nid = memory_add_physaddr_to_nid(base); 301 302 for (i = 0; i < sections_per_block; i++) { 303 __remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE); 304 base += MIN_MEMORY_BLOCK_SIZE; 305 } 306 307 out: 308 /* Update memory regions for memory remove */ 309 memblock_remove(base, memblock_size); 310 unlock_device_hotplug(); 311 return 0; 312 } 313 314 static int pseries_remove_mem_node(struct device_node *np) 315 { 316 const __be32 *prop; 317 unsigned long base; 318 unsigned long lmb_size; 319 int ret = -EINVAL; 320 int addr_cells, size_cells; 321 322 /* 323 * Check to see if we are actually removing memory 324 */ 325 if (!of_node_is_type(np, "memory")) 326 return 0; 327 328 /* 329 * Find the base address and size of the memblock 330 */ 331 prop = of_get_property(np, "reg", NULL); 332 if (!prop) 333 return ret; 334 335 addr_cells = of_n_addr_cells(np); 336 size_cells = of_n_size_cells(np); 337 338 /* 339 * "reg" property represents (addr,size) tuple. 340 */ 341 base = of_read_number(prop, addr_cells); 342 prop += addr_cells; 343 lmb_size = of_read_number(prop, size_cells); 344 345 pseries_remove_memblock(base, lmb_size); 346 return 0; 347 } 348 349 static bool lmb_is_removable(struct drmem_lmb *lmb) 350 { 351 if ((lmb->flags & DRCONF_MEM_RESERVED) || 352 !(lmb->flags & DRCONF_MEM_ASSIGNED)) 353 return false; 354 355 #ifdef CONFIG_FA_DUMP 356 /* 357 * Don't hot-remove memory that falls in fadump boot memory area 358 * and memory that is reserved for capturing old kernel memory. 359 */ 360 if (is_fadump_memory_area(lmb->base_addr, memory_block_size_bytes())) 361 return false; 362 #endif 363 /* device_offline() will determine if we can actually remove this lmb */ 364 return true; 365 } 366 367 static int dlpar_add_lmb(struct drmem_lmb *); 368 369 static int dlpar_remove_lmb(struct drmem_lmb *lmb) 370 { 371 struct memory_block *mem_block; 372 unsigned long block_sz; 373 int rc; 374 375 if (!lmb_is_removable(lmb)) 376 return -EINVAL; 377 378 mem_block = lmb_to_memblock(lmb); 379 if (mem_block == NULL) 380 return -EINVAL; 381 382 rc = dlpar_offline_lmb(lmb); 383 if (rc) { 384 put_device(&mem_block->dev); 385 return rc; 386 } 387 388 block_sz = pseries_memory_block_size(); 389 390 __remove_memory(mem_block->nid, lmb->base_addr, block_sz); 391 put_device(&mem_block->dev); 392 393 /* Update memory regions for memory remove */ 394 memblock_remove(lmb->base_addr, block_sz); 395 396 invalidate_lmb_associativity_index(lmb); 397 lmb->flags &= ~DRCONF_MEM_ASSIGNED; 398 399 return 0; 400 } 401 402 static int dlpar_memory_remove_by_count(u32 lmbs_to_remove) 403 { 404 struct drmem_lmb *lmb; 405 int lmbs_reserved = 0; 406 int lmbs_available = 0; 407 int rc; 408 409 pr_info("Attempting to hot-remove %d LMB(s)\n", lmbs_to_remove); 410 411 if (lmbs_to_remove == 0) 412 return -EINVAL; 413 414 /* Validate that there are enough LMBs to satisfy the request */ 415 for_each_drmem_lmb(lmb) { 416 if (lmb_is_removable(lmb)) 417 lmbs_available++; 418 419 if (lmbs_available == lmbs_to_remove) 420 break; 421 } 422 423 if (lmbs_available < lmbs_to_remove) { 424 pr_info("Not enough LMBs available (%d of %d) to satisfy request\n", 425 lmbs_available, lmbs_to_remove); 426 return -EINVAL; 427 } 428 429 for_each_drmem_lmb(lmb) { 430 rc = dlpar_remove_lmb(lmb); 431 if (rc) 432 continue; 433 434 /* Mark this lmb so we can add it later if all of the 435 * requested LMBs cannot be removed. 436 */ 437 drmem_mark_lmb_reserved(lmb); 438 439 lmbs_reserved++; 440 if (lmbs_reserved == lmbs_to_remove) 441 break; 442 } 443 444 if (lmbs_reserved != lmbs_to_remove) { 445 pr_err("Memory hot-remove failed, adding LMB's back\n"); 446 447 for_each_drmem_lmb(lmb) { 448 if (!drmem_lmb_reserved(lmb)) 449 continue; 450 451 rc = dlpar_add_lmb(lmb); 452 if (rc) 453 pr_err("Failed to add LMB back, drc index %x\n", 454 lmb->drc_index); 455 456 drmem_remove_lmb_reservation(lmb); 457 458 lmbs_reserved--; 459 if (lmbs_reserved == 0) 460 break; 461 } 462 463 rc = -EINVAL; 464 } else { 465 for_each_drmem_lmb(lmb) { 466 if (!drmem_lmb_reserved(lmb)) 467 continue; 468 469 dlpar_release_drc(lmb->drc_index); 470 pr_info("Memory at %llx was hot-removed\n", 471 lmb->base_addr); 472 473 drmem_remove_lmb_reservation(lmb); 474 475 lmbs_reserved--; 476 if (lmbs_reserved == 0) 477 break; 478 } 479 rc = 0; 480 } 481 482 return rc; 483 } 484 485 static int dlpar_memory_remove_by_index(u32 drc_index) 486 { 487 struct drmem_lmb *lmb; 488 int lmb_found; 489 int rc; 490 491 pr_debug("Attempting to hot-remove LMB, drc index %x\n", drc_index); 492 493 lmb_found = 0; 494 for_each_drmem_lmb(lmb) { 495 if (lmb->drc_index == drc_index) { 496 lmb_found = 1; 497 rc = dlpar_remove_lmb(lmb); 498 if (!rc) 499 dlpar_release_drc(lmb->drc_index); 500 501 break; 502 } 503 } 504 505 if (!lmb_found) 506 rc = -EINVAL; 507 508 if (rc) 509 pr_debug("Failed to hot-remove memory at %llx\n", 510 lmb->base_addr); 511 else 512 pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); 513 514 return rc; 515 } 516 517 static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index) 518 { 519 struct drmem_lmb *lmb, *start_lmb, *end_lmb; 520 int rc; 521 522 pr_info("Attempting to hot-remove %u LMB(s) at %x\n", 523 lmbs_to_remove, drc_index); 524 525 if (lmbs_to_remove == 0) 526 return -EINVAL; 527 528 rc = get_lmb_range(drc_index, lmbs_to_remove, &start_lmb, &end_lmb); 529 if (rc) 530 return -EINVAL; 531 532 /* 533 * Validate that all LMBs in range are not reserved. Note that it 534 * is ok if they are !ASSIGNED since our goal here is to remove the 535 * LMB range, regardless of whether some LMBs were already removed 536 * by any other reason. 537 * 538 * This is a contrast to what is done in remove_by_count() where we 539 * check for both RESERVED and !ASSIGNED (via lmb_is_removable()), 540 * because we want to remove a fixed amount of LMBs in that function. 541 */ 542 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 543 if (lmb->flags & DRCONF_MEM_RESERVED) { 544 pr_err("Memory at %llx (drc index %x) is reserved\n", 545 lmb->base_addr, lmb->drc_index); 546 return -EINVAL; 547 } 548 } 549 550 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 551 /* 552 * dlpar_remove_lmb() will error out if the LMB is already 553 * !ASSIGNED, but this case is a no-op for us. 554 */ 555 if (!(lmb->flags & DRCONF_MEM_ASSIGNED)) 556 continue; 557 558 rc = dlpar_remove_lmb(lmb); 559 if (rc) 560 break; 561 562 drmem_mark_lmb_reserved(lmb); 563 } 564 565 if (rc) { 566 pr_err("Memory indexed-count-remove failed, adding any removed LMBs\n"); 567 568 569 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 570 if (!drmem_lmb_reserved(lmb)) 571 continue; 572 573 /* 574 * Setting the isolation state of an UNISOLATED/CONFIGURED 575 * device to UNISOLATE is a no-op, but the hypervisor can 576 * use it as a hint that the LMB removal failed. 577 */ 578 dlpar_unisolate_drc(lmb->drc_index); 579 580 rc = dlpar_add_lmb(lmb); 581 if (rc) 582 pr_err("Failed to add LMB, drc index %x\n", 583 lmb->drc_index); 584 585 drmem_remove_lmb_reservation(lmb); 586 } 587 rc = -EINVAL; 588 } else { 589 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 590 if (!drmem_lmb_reserved(lmb)) 591 continue; 592 593 dlpar_release_drc(lmb->drc_index); 594 pr_info("Memory at %llx (drc index %x) was hot-removed\n", 595 lmb->base_addr, lmb->drc_index); 596 597 drmem_remove_lmb_reservation(lmb); 598 } 599 } 600 601 return rc; 602 } 603 604 #else 605 static inline int pseries_remove_memblock(unsigned long base, 606 unsigned long memblock_size) 607 { 608 return -EOPNOTSUPP; 609 } 610 static inline int pseries_remove_mem_node(struct device_node *np) 611 { 612 return 0; 613 } 614 static int dlpar_remove_lmb(struct drmem_lmb *lmb) 615 { 616 return -EOPNOTSUPP; 617 } 618 static int dlpar_memory_remove_by_count(u32 lmbs_to_remove) 619 { 620 return -EOPNOTSUPP; 621 } 622 static int dlpar_memory_remove_by_index(u32 drc_index) 623 { 624 return -EOPNOTSUPP; 625 } 626 627 static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index) 628 { 629 return -EOPNOTSUPP; 630 } 631 #endif /* CONFIG_MEMORY_HOTREMOVE */ 632 633 static int dlpar_add_lmb(struct drmem_lmb *lmb) 634 { 635 unsigned long block_sz; 636 int nid, rc; 637 638 if (lmb->flags & DRCONF_MEM_ASSIGNED) 639 return -EINVAL; 640 641 rc = update_lmb_associativity_index(lmb); 642 if (rc) { 643 dlpar_release_drc(lmb->drc_index); 644 return rc; 645 } 646 647 block_sz = memory_block_size_bytes(); 648 649 /* Find the node id for this LMB. Fake one if necessary. */ 650 nid = of_drconf_to_nid_single(lmb); 651 if (nid < 0 || !node_possible(nid)) 652 nid = first_online_node; 653 654 /* Add the memory */ 655 rc = __add_memory(nid, lmb->base_addr, block_sz, MHP_NONE); 656 if (rc) { 657 invalidate_lmb_associativity_index(lmb); 658 return rc; 659 } 660 661 rc = dlpar_online_lmb(lmb); 662 if (rc) { 663 __remove_memory(nid, lmb->base_addr, block_sz); 664 invalidate_lmb_associativity_index(lmb); 665 } else { 666 lmb->flags |= DRCONF_MEM_ASSIGNED; 667 } 668 669 return rc; 670 } 671 672 static int dlpar_memory_add_by_count(u32 lmbs_to_add) 673 { 674 struct drmem_lmb *lmb; 675 int lmbs_available = 0; 676 int lmbs_reserved = 0; 677 int rc; 678 679 pr_info("Attempting to hot-add %d LMB(s)\n", lmbs_to_add); 680 681 if (lmbs_to_add == 0) 682 return -EINVAL; 683 684 /* Validate that there are enough LMBs to satisfy the request */ 685 for_each_drmem_lmb(lmb) { 686 if (lmb->flags & DRCONF_MEM_RESERVED) 687 continue; 688 689 if (!(lmb->flags & DRCONF_MEM_ASSIGNED)) 690 lmbs_available++; 691 692 if (lmbs_available == lmbs_to_add) 693 break; 694 } 695 696 if (lmbs_available < lmbs_to_add) 697 return -EINVAL; 698 699 for_each_drmem_lmb(lmb) { 700 if (lmb->flags & DRCONF_MEM_ASSIGNED) 701 continue; 702 703 rc = dlpar_acquire_drc(lmb->drc_index); 704 if (rc) 705 continue; 706 707 rc = dlpar_add_lmb(lmb); 708 if (rc) { 709 dlpar_release_drc(lmb->drc_index); 710 continue; 711 } 712 713 /* Mark this lmb so we can remove it later if all of the 714 * requested LMBs cannot be added. 715 */ 716 drmem_mark_lmb_reserved(lmb); 717 lmbs_reserved++; 718 if (lmbs_reserved == lmbs_to_add) 719 break; 720 } 721 722 if (lmbs_reserved != lmbs_to_add) { 723 pr_err("Memory hot-add failed, removing any added LMBs\n"); 724 725 for_each_drmem_lmb(lmb) { 726 if (!drmem_lmb_reserved(lmb)) 727 continue; 728 729 rc = dlpar_remove_lmb(lmb); 730 if (rc) 731 pr_err("Failed to remove LMB, drc index %x\n", 732 lmb->drc_index); 733 else 734 dlpar_release_drc(lmb->drc_index); 735 736 drmem_remove_lmb_reservation(lmb); 737 lmbs_reserved--; 738 739 if (lmbs_reserved == 0) 740 break; 741 } 742 rc = -EINVAL; 743 } else { 744 for_each_drmem_lmb(lmb) { 745 if (!drmem_lmb_reserved(lmb)) 746 continue; 747 748 pr_debug("Memory at %llx (drc index %x) was hot-added\n", 749 lmb->base_addr, lmb->drc_index); 750 drmem_remove_lmb_reservation(lmb); 751 lmbs_reserved--; 752 753 if (lmbs_reserved == 0) 754 break; 755 } 756 rc = 0; 757 } 758 759 return rc; 760 } 761 762 static int dlpar_memory_add_by_index(u32 drc_index) 763 { 764 struct drmem_lmb *lmb; 765 int rc, lmb_found; 766 767 pr_info("Attempting to hot-add LMB, drc index %x\n", drc_index); 768 769 lmb_found = 0; 770 for_each_drmem_lmb(lmb) { 771 if (lmb->drc_index == drc_index) { 772 lmb_found = 1; 773 rc = dlpar_acquire_drc(lmb->drc_index); 774 if (!rc) { 775 rc = dlpar_add_lmb(lmb); 776 if (rc) 777 dlpar_release_drc(lmb->drc_index); 778 } 779 780 break; 781 } 782 } 783 784 if (!lmb_found) 785 rc = -EINVAL; 786 787 if (rc) 788 pr_info("Failed to hot-add memory, drc index %x\n", drc_index); 789 else 790 pr_info("Memory at %llx (drc index %x) was hot-added\n", 791 lmb->base_addr, drc_index); 792 793 return rc; 794 } 795 796 static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index) 797 { 798 struct drmem_lmb *lmb, *start_lmb, *end_lmb; 799 int rc; 800 801 pr_info("Attempting to hot-add %u LMB(s) at index %x\n", 802 lmbs_to_add, drc_index); 803 804 if (lmbs_to_add == 0) 805 return -EINVAL; 806 807 rc = get_lmb_range(drc_index, lmbs_to_add, &start_lmb, &end_lmb); 808 if (rc) 809 return -EINVAL; 810 811 /* Validate that the LMBs in this range are not reserved */ 812 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 813 /* Fail immediately if the whole range can't be hot-added */ 814 if (lmb->flags & DRCONF_MEM_RESERVED) { 815 pr_err("Memory at %llx (drc index %x) is reserved\n", 816 lmb->base_addr, lmb->drc_index); 817 return -EINVAL; 818 } 819 } 820 821 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 822 if (lmb->flags & DRCONF_MEM_ASSIGNED) 823 continue; 824 825 rc = dlpar_acquire_drc(lmb->drc_index); 826 if (rc) 827 break; 828 829 rc = dlpar_add_lmb(lmb); 830 if (rc) { 831 dlpar_release_drc(lmb->drc_index); 832 break; 833 } 834 835 drmem_mark_lmb_reserved(lmb); 836 } 837 838 if (rc) { 839 pr_err("Memory indexed-count-add failed, removing any added LMBs\n"); 840 841 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 842 if (!drmem_lmb_reserved(lmb)) 843 continue; 844 845 rc = dlpar_remove_lmb(lmb); 846 if (rc) 847 pr_err("Failed to remove LMB, drc index %x\n", 848 lmb->drc_index); 849 else 850 dlpar_release_drc(lmb->drc_index); 851 852 drmem_remove_lmb_reservation(lmb); 853 } 854 rc = -EINVAL; 855 } else { 856 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) { 857 if (!drmem_lmb_reserved(lmb)) 858 continue; 859 860 pr_info("Memory at %llx (drc index %x) was hot-added\n", 861 lmb->base_addr, lmb->drc_index); 862 drmem_remove_lmb_reservation(lmb); 863 } 864 } 865 866 return rc; 867 } 868 869 int dlpar_memory(struct pseries_hp_errorlog *hp_elog) 870 { 871 u32 count, drc_index; 872 int rc; 873 874 lock_device_hotplug(); 875 876 switch (hp_elog->action) { 877 case PSERIES_HP_ELOG_ACTION_ADD: 878 switch (hp_elog->id_type) { 879 case PSERIES_HP_ELOG_ID_DRC_COUNT: 880 count = hp_elog->_drc_u.drc_count; 881 rc = dlpar_memory_add_by_count(count); 882 break; 883 case PSERIES_HP_ELOG_ID_DRC_INDEX: 884 drc_index = hp_elog->_drc_u.drc_index; 885 rc = dlpar_memory_add_by_index(drc_index); 886 break; 887 case PSERIES_HP_ELOG_ID_DRC_IC: 888 count = hp_elog->_drc_u.ic.count; 889 drc_index = hp_elog->_drc_u.ic.index; 890 rc = dlpar_memory_add_by_ic(count, drc_index); 891 break; 892 default: 893 rc = -EINVAL; 894 break; 895 } 896 897 break; 898 case PSERIES_HP_ELOG_ACTION_REMOVE: 899 switch (hp_elog->id_type) { 900 case PSERIES_HP_ELOG_ID_DRC_COUNT: 901 count = hp_elog->_drc_u.drc_count; 902 rc = dlpar_memory_remove_by_count(count); 903 break; 904 case PSERIES_HP_ELOG_ID_DRC_INDEX: 905 drc_index = hp_elog->_drc_u.drc_index; 906 rc = dlpar_memory_remove_by_index(drc_index); 907 break; 908 case PSERIES_HP_ELOG_ID_DRC_IC: 909 count = hp_elog->_drc_u.ic.count; 910 drc_index = hp_elog->_drc_u.ic.index; 911 rc = dlpar_memory_remove_by_ic(count, drc_index); 912 break; 913 default: 914 rc = -EINVAL; 915 break; 916 } 917 918 break; 919 default: 920 pr_err("Invalid action (%d) specified\n", hp_elog->action); 921 rc = -EINVAL; 922 break; 923 } 924 925 if (!rc) 926 rc = drmem_update_dt(); 927 928 unlock_device_hotplug(); 929 return rc; 930 } 931 932 static int pseries_add_mem_node(struct device_node *np) 933 { 934 const __be32 *prop; 935 unsigned long base; 936 unsigned long lmb_size; 937 int ret = -EINVAL; 938 int addr_cells, size_cells; 939 940 /* 941 * Check to see if we are actually adding memory 942 */ 943 if (!of_node_is_type(np, "memory")) 944 return 0; 945 946 /* 947 * Find the base and size of the memblock 948 */ 949 prop = of_get_property(np, "reg", NULL); 950 if (!prop) 951 return ret; 952 953 addr_cells = of_n_addr_cells(np); 954 size_cells = of_n_size_cells(np); 955 /* 956 * "reg" property represents (addr,size) tuple. 957 */ 958 base = of_read_number(prop, addr_cells); 959 prop += addr_cells; 960 lmb_size = of_read_number(prop, size_cells); 961 962 /* 963 * Update memory region to represent the memory add 964 */ 965 ret = memblock_add(base, lmb_size); 966 return (ret < 0) ? -EINVAL : 0; 967 } 968 969 static int pseries_memory_notifier(struct notifier_block *nb, 970 unsigned long action, void *data) 971 { 972 struct of_reconfig_data *rd = data; 973 int err = 0; 974 975 switch (action) { 976 case OF_RECONFIG_ATTACH_NODE: 977 err = pseries_add_mem_node(rd->dn); 978 break; 979 case OF_RECONFIG_DETACH_NODE: 980 err = pseries_remove_mem_node(rd->dn); 981 break; 982 } 983 return notifier_from_errno(err); 984 } 985 986 static struct notifier_block pseries_mem_nb = { 987 .notifier_call = pseries_memory_notifier, 988 }; 989 990 static int __init pseries_memory_hotplug_init(void) 991 { 992 if (firmware_has_feature(FW_FEATURE_LPAR)) 993 of_reconfig_notifier_register(&pseries_mem_nb); 994 995 return 0; 996 } 997 machine_device_initcall(pseries, pseries_memory_hotplug_init); 998