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