diff options
author | AKASHI Takahiro <takahiro.akashi@linaro.org> | 2018-11-15 00:52:43 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2018-12-06 09:38:50 -0500 |
commit | 735c2f90e333b3d0adee52a8e7e855a0c0eca284 (patch) | |
tree | e665fc78903edfe09b27ad0eb356a5aef6051740 /kernel/kexec_file.c | |
parent | b6664ba42f1424d2768b605dd60cecc4428d9364 (diff) |
powerpc, kexec_file: factor out memblock-based arch_kexec_walk_mem()
Memblock list is another source for usable system memory layout.
So move powerpc's arch_kexec_walk_mem() to common code so that other
memblock-based architectures, particularly arm64, can also utilise it.
A moved function is now renamed to kexec_walk_memblock() and integrated
into kexec_locate_mem_hole(), which will now be usable for all
architectures with no need for overriding arch_kexec_walk_mem().
With this change, arch_kexec_walk_mem() need no longer be a weak function,
and was now renamed to kexec_walk_resources().
Since powerpc doesn't support kdump in its kexec_file_load(), the current
kexec_walk_memblock() won't work for kdump either in this form, this will
be fixed in the next patch.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: Dave Young <dyoung@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Acked-by: James Morse <james.morse@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'kernel/kexec_file.c')
-rw-r--r-- | kernel/kexec_file.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 9e6529da12ed..d03195a8cb6e 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/file.h> | 16 | #include <linux/file.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/kexec.h> | 18 | #include <linux/kexec.h> |
19 | #include <linux/memblock.h> | ||
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
20 | #include <linux/list.h> | 21 | #include <linux/list.h> |
21 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
@@ -499,8 +500,57 @@ static int locate_mem_hole_callback(struct resource *res, void *arg) | |||
499 | return locate_mem_hole_bottom_up(start, end, kbuf); | 500 | return locate_mem_hole_bottom_up(start, end, kbuf); |
500 | } | 501 | } |
501 | 502 | ||
503 | #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK | ||
504 | static int kexec_walk_memblock(struct kexec_buf *kbuf, | ||
505 | int (*func)(struct resource *, void *)) | ||
506 | { | ||
507 | return 0; | ||
508 | } | ||
509 | #else | ||
510 | static int kexec_walk_memblock(struct kexec_buf *kbuf, | ||
511 | int (*func)(struct resource *, void *)) | ||
512 | { | ||
513 | int ret = 0; | ||
514 | u64 i; | ||
515 | phys_addr_t mstart, mend; | ||
516 | struct resource res = { }; | ||
517 | |||
518 | if (kbuf->top_down) { | ||
519 | for_each_free_mem_range_reverse(i, NUMA_NO_NODE, 0, | ||
520 | &mstart, &mend, NULL) { | ||
521 | /* | ||
522 | * In memblock, end points to the first byte after the | ||
523 | * range while in kexec, end points to the last byte | ||
524 | * in the range. | ||
525 | */ | ||
526 | res.start = mstart; | ||
527 | res.end = mend - 1; | ||
528 | ret = func(&res, kbuf); | ||
529 | if (ret) | ||
530 | break; | ||
531 | } | ||
532 | } else { | ||
533 | for_each_free_mem_range(i, NUMA_NO_NODE, 0, &mstart, &mend, | ||
534 | NULL) { | ||
535 | /* | ||
536 | * In memblock, end points to the first byte after the | ||
537 | * range while in kexec, end points to the last byte | ||
538 | * in the range. | ||
539 | */ | ||
540 | res.start = mstart; | ||
541 | res.end = mend - 1; | ||
542 | ret = func(&res, kbuf); | ||
543 | if (ret) | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | return ret; | ||
549 | } | ||
550 | #endif | ||
551 | |||
502 | /** | 552 | /** |
503 | * arch_kexec_walk_mem - call func(data) on free memory regions | 553 | * kexec_walk_resources - call func(data) on free memory regions |
504 | * @kbuf: Context info for the search. Also passed to @func. | 554 | * @kbuf: Context info for the search. Also passed to @func. |
505 | * @func: Function to call for each memory region. | 555 | * @func: Function to call for each memory region. |
506 | * | 556 | * |
@@ -508,8 +558,8 @@ static int locate_mem_hole_callback(struct resource *res, void *arg) | |||
508 | * and that value will be returned. If all free regions are visited without | 558 | * and that value will be returned. If all free regions are visited without |
509 | * func returning non-zero, then zero will be returned. | 559 | * func returning non-zero, then zero will be returned. |
510 | */ | 560 | */ |
511 | int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, | 561 | static int kexec_walk_resources(struct kexec_buf *kbuf, |
512 | int (*func)(struct resource *, void *)) | 562 | int (*func)(struct resource *, void *)) |
513 | { | 563 | { |
514 | if (kbuf->image->type == KEXEC_TYPE_CRASH) | 564 | if (kbuf->image->type == KEXEC_TYPE_CRASH) |
515 | return walk_iomem_res_desc(crashk_res.desc, | 565 | return walk_iomem_res_desc(crashk_res.desc, |
@@ -536,7 +586,10 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf) | |||
536 | if (kbuf->mem != KEXEC_BUF_MEM_UNKNOWN) | 586 | if (kbuf->mem != KEXEC_BUF_MEM_UNKNOWN) |
537 | return 0; | 587 | return 0; |
538 | 588 | ||
539 | ret = arch_kexec_walk_mem(kbuf, locate_mem_hole_callback); | 589 | if (IS_ENABLED(CONFIG_ARCH_DISCARD_MEMBLOCK)) |
590 | ret = kexec_walk_resources(kbuf, locate_mem_hole_callback); | ||
591 | else | ||
592 | ret = kexec_walk_memblock(kbuf, locate_mem_hole_callback); | ||
540 | 593 | ||
541 | return ret == 1 ? 0 : -EADDRNOTAVAIL; | 594 | return ret == 1 ? 0 : -EADDRNOTAVAIL; |
542 | } | 595 | } |