Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/kexec: move *_memory_ranges functions to ranges.c

Move the following functions form kexec/{file_load_64.c => ranges.c} and
make them public so that components other than KEXEC_FILE can also use
these functions.
1. get_exclude_memory_ranges
2. get_reserved_memory_ranges
3. get_crash_memory_ranges
4. get_usable_memory_ranges

Later in the series get_crash_memory_ranges function is utilized for
in-kernel updates to kdump image during CPU/Memory hotplug or
online/offline events for both kexec_load and kexec_file_load syscalls.

Since the above functions are moved to ranges.c, some of the helper
functions in ranges.c are no longer required to be public. Mark them as
static and removed them from kexec_ranges.h header file.

Finally, remove the CONFIG_KEXEC_FILE build dependency for range.c
because it is required for other config, such as CONFIG_CRASH_DUMP.

No functional changes are intended.

Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Acked-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20240326055413.186534-4-sourabhjain@linux.ibm.com

authored by

Sourabh Jain and committed by
Michael Ellerman
f5f0da5a 79365026

+224 -216
+4 -15
arch/powerpc/include/asm/kexec_ranges.h
··· 7 7 void sort_memory_ranges(struct crash_mem *mrngs, bool merge); 8 8 struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges); 9 9 int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size); 10 - int add_tce_mem_ranges(struct crash_mem **mem_ranges); 11 - int add_initrd_mem_range(struct crash_mem **mem_ranges); 12 - #ifdef CONFIG_PPC_64S_HASH_MMU 13 - int add_htab_mem_range(struct crash_mem **mem_ranges); 14 - #else 15 - static inline int add_htab_mem_range(struct crash_mem **mem_ranges) 16 - { 17 - return 0; 18 - } 19 - #endif 20 - int add_kernel_mem_range(struct crash_mem **mem_ranges); 21 - int add_rtas_mem_range(struct crash_mem **mem_ranges); 22 - int add_opal_mem_range(struct crash_mem **mem_ranges); 23 - int add_reserved_mem_ranges(struct crash_mem **mem_ranges); 24 - 10 + int get_exclude_memory_ranges(struct crash_mem **mem_ranges); 11 + int get_reserved_memory_ranges(struct crash_mem **mem_ranges); 12 + int get_crash_memory_ranges(struct crash_mem **mem_ranges); 13 + int get_usable_memory_ranges(struct crash_mem **mem_ranges); 25 14 #endif /* _ASM_POWERPC_KEXEC_RANGES_H */
+2 -2
arch/powerpc/kexec/Makefile
··· 3 3 # Makefile for the linux kernel. 4 4 # 5 5 6 - obj-y += core.o core_$(BITS).o 6 + obj-y += core.o core_$(BITS).o ranges.o 7 7 8 8 obj-$(CONFIG_PPC32) += relocate_32.o 9 9 10 - obj-$(CONFIG_KEXEC_FILE) += file_load.o ranges.o file_load_$(BITS).o elf_$(BITS).o 10 + obj-$(CONFIG_KEXEC_FILE) += file_load.o file_load_$(BITS).o elf_$(BITS).o 11 11 obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o 12 12 obj-$(CONFIG_CRASH_DUMP) += crash.o 13 13
-190
arch/powerpc/kexec/file_load_64.c
··· 48 48 }; 49 49 50 50 /** 51 - * get_exclude_memory_ranges - Get exclude memory ranges. This list includes 52 - * regions like opal/rtas, tce-table, initrd, 53 - * kernel, htab which should be avoided while 54 - * setting up kexec load segments. 55 - * @mem_ranges: Range list to add the memory ranges to. 56 - * 57 - * Returns 0 on success, negative errno on error. 58 - */ 59 - static int get_exclude_memory_ranges(struct crash_mem **mem_ranges) 60 - { 61 - int ret; 62 - 63 - ret = add_tce_mem_ranges(mem_ranges); 64 - if (ret) 65 - goto out; 66 - 67 - ret = add_initrd_mem_range(mem_ranges); 68 - if (ret) 69 - goto out; 70 - 71 - ret = add_htab_mem_range(mem_ranges); 72 - if (ret) 73 - goto out; 74 - 75 - ret = add_kernel_mem_range(mem_ranges); 76 - if (ret) 77 - goto out; 78 - 79 - ret = add_rtas_mem_range(mem_ranges); 80 - if (ret) 81 - goto out; 82 - 83 - ret = add_opal_mem_range(mem_ranges); 84 - if (ret) 85 - goto out; 86 - 87 - ret = add_reserved_mem_ranges(mem_ranges); 88 - if (ret) 89 - goto out; 90 - 91 - /* exclude memory ranges should be sorted for easy lookup */ 92 - sort_memory_ranges(*mem_ranges, true); 93 - out: 94 - if (ret) 95 - pr_err("Failed to setup exclude memory ranges\n"); 96 - return ret; 97 - } 98 - 99 - /** 100 - * get_reserved_memory_ranges - Get reserve memory ranges. This list includes 101 - * memory regions that should be added to the 102 - * memory reserve map to ensure the region is 103 - * protected from any mischief. 104 - * @mem_ranges: Range list to add the memory ranges to. 105 - * 106 - * Returns 0 on success, negative errno on error. 107 - */ 108 - static int get_reserved_memory_ranges(struct crash_mem **mem_ranges) 109 - { 110 - int ret; 111 - 112 - ret = add_rtas_mem_range(mem_ranges); 113 - if (ret) 114 - goto out; 115 - 116 - ret = add_tce_mem_ranges(mem_ranges); 117 - if (ret) 118 - goto out; 119 - 120 - ret = add_reserved_mem_ranges(mem_ranges); 121 - out: 122 - if (ret) 123 - pr_err("Failed to setup reserved memory ranges\n"); 124 - return ret; 125 - } 126 - 127 - /** 128 51 * __locate_mem_hole_top_down - Looks top down for a large enough memory hole 129 52 * in the memory regions between buf_min & buf_max 130 53 * for the buffer. If found, sets kbuf->mem. ··· 245 322 } 246 323 247 324 #ifdef CONFIG_CRASH_DUMP 248 - /** 249 - * get_usable_memory_ranges - Get usable memory ranges. This list includes 250 - * regions like crashkernel, opal/rtas & tce-table, 251 - * that kdump kernel could use. 252 - * @mem_ranges: Range list to add the memory ranges to. 253 - * 254 - * Returns 0 on success, negative errno on error. 255 - */ 256 - static int get_usable_memory_ranges(struct crash_mem **mem_ranges) 257 - { 258 - int ret; 259 - 260 - /* 261 - * Early boot failure observed on guests when low memory (first memory 262 - * block?) is not added to usable memory. So, add [0, crashk_res.end] 263 - * instead of [crashk_res.start, crashk_res.end] to workaround it. 264 - * Also, crashed kernel's memory must be added to reserve map to 265 - * avoid kdump kernel from using it. 266 - */ 267 - ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1); 268 - if (ret) 269 - goto out; 270 - 271 - ret = add_rtas_mem_range(mem_ranges); 272 - if (ret) 273 - goto out; 274 - 275 - ret = add_opal_mem_range(mem_ranges); 276 - if (ret) 277 - goto out; 278 - 279 - ret = add_tce_mem_ranges(mem_ranges); 280 - out: 281 - if (ret) 282 - pr_err("Failed to setup usable memory ranges\n"); 283 - return ret; 284 - } 285 - 286 - /** 287 - * get_crash_memory_ranges - Get crash memory ranges. This list includes 288 - * first/crashing kernel's memory regions that 289 - * would be exported via an elfcore. 290 - * @mem_ranges: Range list to add the memory ranges to. 291 - * 292 - * Returns 0 on success, negative errno on error. 293 - */ 294 - static int get_crash_memory_ranges(struct crash_mem **mem_ranges) 295 - { 296 - phys_addr_t base, end; 297 - struct crash_mem *tmem; 298 - u64 i; 299 - int ret; 300 - 301 - for_each_mem_range(i, &base, &end) { 302 - u64 size = end - base; 303 - 304 - /* Skip backup memory region, which needs a separate entry */ 305 - if (base == BACKUP_SRC_START) { 306 - if (size > BACKUP_SRC_SIZE) { 307 - base = BACKUP_SRC_END + 1; 308 - size -= BACKUP_SRC_SIZE; 309 - } else 310 - continue; 311 - } 312 - 313 - ret = add_mem_range(mem_ranges, base, size); 314 - if (ret) 315 - goto out; 316 - 317 - /* Try merging adjacent ranges before reallocation attempt */ 318 - if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges) 319 - sort_memory_ranges(*mem_ranges, true); 320 - } 321 - 322 - /* Reallocate memory ranges if there is no space to split ranges */ 323 - tmem = *mem_ranges; 324 - if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) { 325 - tmem = realloc_mem_ranges(mem_ranges); 326 - if (!tmem) 327 - goto out; 328 - } 329 - 330 - /* Exclude crashkernel region */ 331 - ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end); 332 - if (ret) 333 - goto out; 334 - 335 - /* 336 - * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL 337 - * regions are exported to save their context at the time of 338 - * crash, they should actually be backed up just like the 339 - * first 64K bytes of memory. 340 - */ 341 - ret = add_rtas_mem_range(mem_ranges); 342 - if (ret) 343 - goto out; 344 - 345 - ret = add_opal_mem_range(mem_ranges); 346 - if (ret) 347 - goto out; 348 - 349 - /* create a separate program header for the backup region */ 350 - ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE); 351 - if (ret) 352 - goto out; 353 - 354 - sort_memory_ranges(*mem_ranges, false); 355 - out: 356 - if (ret) 357 - pr_err("Failed to setup crash memory ranges\n"); 358 - return ret; 359 - } 360 - 361 325 /** 362 326 * check_realloc_usable_mem - Reallocate buffer if it can't accommodate entries 363 327 * @um_info: Usable memory buffer and ranges info.
+218 -9
arch/powerpc/kexec/ranges.c
··· 20 20 #include <linux/kexec.h> 21 21 #include <linux/of.h> 22 22 #include <linux/slab.h> 23 + #include <linux/memblock.h> 24 + #include <linux/crash_core.h> 23 25 #include <asm/sections.h> 24 26 #include <asm/kexec_ranges.h> 27 + #include <asm/crashdump-ppc64.h> 25 28 29 + #if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP) 26 30 /** 27 31 * get_max_nr_ranges - Get the max no. of ranges crash_mem structure 28 32 * could hold, given the size allocated for it. ··· 238 234 return __add_mem_range(mem_ranges, base, size); 239 235 } 240 236 237 + #endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */ 238 + 239 + #ifdef CONFIG_KEXEC_FILE 241 240 /** 242 241 * add_tce_mem_ranges - Adds tce-table range to the given memory ranges list. 243 242 * @mem_ranges: Range list to add the memory range(s) to. 244 243 * 245 244 * Returns 0 on success, negative errno on error. 246 245 */ 247 - int add_tce_mem_ranges(struct crash_mem **mem_ranges) 246 + static int add_tce_mem_ranges(struct crash_mem **mem_ranges) 248 247 { 249 248 struct device_node *dn = NULL; 250 249 int ret = 0; ··· 286 279 * 287 280 * Returns 0 on success, negative errno on error. 288 281 */ 289 - int add_initrd_mem_range(struct crash_mem **mem_ranges) 282 + static int add_initrd_mem_range(struct crash_mem **mem_ranges) 290 283 { 291 284 u64 base, end; 292 285 int ret; ··· 303 296 return ret; 304 297 } 305 298 306 - #ifdef CONFIG_PPC_64S_HASH_MMU 307 299 /** 308 300 * add_htab_mem_range - Adds htab range to the given memory ranges list, 309 301 * if it exists ··· 310 304 * 311 305 * Returns 0 on success, negative errno on error. 312 306 */ 313 - int add_htab_mem_range(struct crash_mem **mem_ranges) 307 + static int add_htab_mem_range(struct crash_mem **mem_ranges) 314 308 { 309 + 310 + #ifdef CONFIG_PPC_64S_HASH_MMU 315 311 if (!htab_address) 316 312 return 0; 317 313 318 314 return add_mem_range(mem_ranges, __pa(htab_address), htab_size_bytes); 319 - } 315 + #else 316 + return 0; 320 317 #endif 318 + } 321 319 322 320 /** 323 321 * add_kernel_mem_range - Adds kernel text region to the given ··· 330 320 * 331 321 * Returns 0 on success, negative errno on error. 332 322 */ 333 - int add_kernel_mem_range(struct crash_mem **mem_ranges) 323 + static int add_kernel_mem_range(struct crash_mem **mem_ranges) 334 324 { 335 325 return add_mem_range(mem_ranges, 0, __pa(_end)); 336 326 } 327 + #endif /* CONFIG_KEXEC_FILE */ 337 328 329 + #if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP) 338 330 /** 339 331 * add_rtas_mem_range - Adds RTAS region to the given memory ranges list. 340 332 * @mem_ranges: Range list to add the memory range to. 341 333 * 342 334 * Returns 0 on success, negative errno on error. 343 335 */ 344 - int add_rtas_mem_range(struct crash_mem **mem_ranges) 336 + static int add_rtas_mem_range(struct crash_mem **mem_ranges) 345 337 { 346 338 struct device_node *dn; 347 339 u32 base, size; ··· 368 356 * 369 357 * Returns 0 on success, negative errno on error. 370 358 */ 371 - int add_opal_mem_range(struct crash_mem **mem_ranges) 359 + static int add_opal_mem_range(struct crash_mem **mem_ranges) 372 360 { 373 361 struct device_node *dn; 374 362 u64 base, size; ··· 386 374 of_node_put(dn); 387 375 return ret; 388 376 } 377 + #endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */ 389 378 379 + #ifdef CONFIG_KEXEC_FILE 390 380 /** 391 381 * add_reserved_mem_ranges - Adds "/reserved-ranges" regions exported by f/w 392 382 * to the given memory ranges list. ··· 396 382 * 397 383 * Returns 0 on success, negative errno on error. 398 384 */ 399 - int add_reserved_mem_ranges(struct crash_mem **mem_ranges) 385 + static int add_reserved_mem_ranges(struct crash_mem **mem_ranges) 400 386 { 401 387 int n_mem_addr_cells, n_mem_size_cells, i, len, cells, ret = 0; 402 388 struct device_node *root = of_find_node_by_path("/"); ··· 426 412 427 413 return ret; 428 414 } 415 + 416 + /** 417 + * get_reserved_memory_ranges - Get reserve memory ranges. This list includes 418 + * memory regions that should be added to the 419 + * memory reserve map to ensure the region is 420 + * protected from any mischief. 421 + * @mem_ranges: Range list to add the memory ranges to. 422 + * 423 + * Returns 0 on success, negative errno on error. 424 + */ 425 + int get_reserved_memory_ranges(struct crash_mem **mem_ranges) 426 + { 427 + int ret; 428 + 429 + ret = add_rtas_mem_range(mem_ranges); 430 + if (ret) 431 + goto out; 432 + 433 + ret = add_tce_mem_ranges(mem_ranges); 434 + if (ret) 435 + goto out; 436 + 437 + ret = add_reserved_mem_ranges(mem_ranges); 438 + out: 439 + if (ret) 440 + pr_err("Failed to setup reserved memory ranges\n"); 441 + return ret; 442 + } 443 + 444 + /** 445 + * get_exclude_memory_ranges - Get exclude memory ranges. This list includes 446 + * regions like opal/rtas, tce-table, initrd, 447 + * kernel, htab which should be avoided while 448 + * setting up kexec load segments. 449 + * @mem_ranges: Range list to add the memory ranges to. 450 + * 451 + * Returns 0 on success, negative errno on error. 452 + */ 453 + int get_exclude_memory_ranges(struct crash_mem **mem_ranges) 454 + { 455 + int ret; 456 + 457 + ret = add_tce_mem_ranges(mem_ranges); 458 + if (ret) 459 + goto out; 460 + 461 + ret = add_initrd_mem_range(mem_ranges); 462 + if (ret) 463 + goto out; 464 + 465 + ret = add_htab_mem_range(mem_ranges); 466 + if (ret) 467 + goto out; 468 + 469 + ret = add_kernel_mem_range(mem_ranges); 470 + if (ret) 471 + goto out; 472 + 473 + ret = add_rtas_mem_range(mem_ranges); 474 + if (ret) 475 + goto out; 476 + 477 + ret = add_opal_mem_range(mem_ranges); 478 + if (ret) 479 + goto out; 480 + 481 + ret = add_reserved_mem_ranges(mem_ranges); 482 + if (ret) 483 + goto out; 484 + 485 + /* exclude memory ranges should be sorted for easy lookup */ 486 + sort_memory_ranges(*mem_ranges, true); 487 + out: 488 + if (ret) 489 + pr_err("Failed to setup exclude memory ranges\n"); 490 + return ret; 491 + } 492 + 493 + #ifdef CONFIG_CRASH_DUMP 494 + /** 495 + * get_usable_memory_ranges - Get usable memory ranges. This list includes 496 + * regions like crashkernel, opal/rtas & tce-table, 497 + * that kdump kernel could use. 498 + * @mem_ranges: Range list to add the memory ranges to. 499 + * 500 + * Returns 0 on success, negative errno on error. 501 + */ 502 + int get_usable_memory_ranges(struct crash_mem **mem_ranges) 503 + { 504 + int ret; 505 + 506 + /* 507 + * Early boot failure observed on guests when low memory (first memory 508 + * block?) is not added to usable memory. So, add [0, crashk_res.end] 509 + * instead of [crashk_res.start, crashk_res.end] to workaround it. 510 + * Also, crashed kernel's memory must be added to reserve map to 511 + * avoid kdump kernel from using it. 512 + */ 513 + ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1); 514 + if (ret) 515 + goto out; 516 + 517 + ret = add_rtas_mem_range(mem_ranges); 518 + if (ret) 519 + goto out; 520 + 521 + ret = add_opal_mem_range(mem_ranges); 522 + if (ret) 523 + goto out; 524 + 525 + ret = add_tce_mem_ranges(mem_ranges); 526 + out: 527 + if (ret) 528 + pr_err("Failed to setup usable memory ranges\n"); 529 + return ret; 530 + } 531 + #endif /* CONFIG_CRASH_DUMP */ 532 + #endif /* CONFIG_KEXEC_FILE */ 533 + 534 + #ifdef CONFIG_CRASH_DUMP 535 + /** 536 + * get_crash_memory_ranges - Get crash memory ranges. This list includes 537 + * first/crashing kernel's memory regions that 538 + * would be exported via an elfcore. 539 + * @mem_ranges: Range list to add the memory ranges to. 540 + * 541 + * Returns 0 on success, negative errno on error. 542 + */ 543 + int get_crash_memory_ranges(struct crash_mem **mem_ranges) 544 + { 545 + phys_addr_t base, end; 546 + struct crash_mem *tmem; 547 + u64 i; 548 + int ret; 549 + 550 + for_each_mem_range(i, &base, &end) { 551 + u64 size = end - base; 552 + 553 + /* Skip backup memory region, which needs a separate entry */ 554 + if (base == BACKUP_SRC_START) { 555 + if (size > BACKUP_SRC_SIZE) { 556 + base = BACKUP_SRC_END + 1; 557 + size -= BACKUP_SRC_SIZE; 558 + } else 559 + continue; 560 + } 561 + 562 + ret = add_mem_range(mem_ranges, base, size); 563 + if (ret) 564 + goto out; 565 + 566 + /* Try merging adjacent ranges before reallocation attempt */ 567 + if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges) 568 + sort_memory_ranges(*mem_ranges, true); 569 + } 570 + 571 + /* Reallocate memory ranges if there is no space to split ranges */ 572 + tmem = *mem_ranges; 573 + if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) { 574 + tmem = realloc_mem_ranges(mem_ranges); 575 + if (!tmem) 576 + goto out; 577 + } 578 + 579 + /* Exclude crashkernel region */ 580 + ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end); 581 + if (ret) 582 + goto out; 583 + 584 + /* 585 + * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL 586 + * regions are exported to save their context at the time of 587 + * crash, they should actually be backed up just like the 588 + * first 64K bytes of memory. 589 + */ 590 + ret = add_rtas_mem_range(mem_ranges); 591 + if (ret) 592 + goto out; 593 + 594 + ret = add_opal_mem_range(mem_ranges); 595 + if (ret) 596 + goto out; 597 + 598 + /* create a separate program header for the backup region */ 599 + ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE); 600 + if (ret) 601 + goto out; 602 + 603 + sort_memory_ranges(*mem_ranges, false); 604 + out: 605 + if (ret) 606 + pr_err("Failed to setup crash memory ranges\n"); 607 + return ret; 608 + } 609 + #endif /* CONFIG_CRASH_DUMP */