lkml.org 
[lkml]   [2016]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v10 01/10] kexec_file: Allow arch-specific memory walking for kexec_add_buffer
    Date
    Allow architectures to specify a different memory walking function for
    kexec_add_buffer. x86 uses iomem to track reserved memory ranges, but
    PowerPC uses the memblock subsystem.

    Signed-off-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
    Acked-by: Dave Young <dyoung@redhat.com>
    Acked-by: Balbir Singh <bsingharora@gmail.com>
    ---
    include/linux/kexec.h | 29 ++++++++++++++++++++++++++++-
    kernel/kexec_file.c | 30 ++++++++++++++++++++++--------
    kernel/kexec_internal.h | 16 ----------------
    3 files changed, 50 insertions(+), 25 deletions(-)

    diff --git a/include/linux/kexec.h b/include/linux/kexec.h
    index 406c33dcae13..5e320ddaaa82 100644
    --- a/include/linux/kexec.h
    +++ b/include/linux/kexec.h
    @@ -148,7 +148,34 @@ struct kexec_file_ops {
    kexec_verify_sig_t *verify_sig;
    #endif
    };
    -#endif
    +
    +/**
    + * struct kexec_buf - parameters for finding a place for a buffer in memory
    + * @image: kexec image in which memory to search.
    + * @buffer: Contents which will be copied to the allocated memory.
    + * @bufsz: Size of @buffer.
    + * @mem: On return will have address of the buffer in memory.
    + * @memsz: Size for the buffer in memory.
    + * @buf_align: Minimum alignment needed.
    + * @buf_min: The buffer can't be placed below this address.
    + * @buf_max: The buffer can't be placed above this address.
    + * @top_down: Allocate from top of memory.
    + */
    +struct kexec_buf {
    + struct kimage *image;
    + char *buffer;
    + unsigned long bufsz;
    + unsigned long mem;
    + unsigned long memsz;
    + unsigned long buf_align;
    + unsigned long buf_min;
    + unsigned long buf_max;
    + bool top_down;
    +};
    +
    +int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
    + int (*func)(u64, u64, void *));
    +#endif /* CONFIG_KEXEC_FILE */

    struct kimage {
    kimage_entry_t head;
    diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
    index 037c321c5618..f865674bff51 100644
    --- a/kernel/kexec_file.c
    +++ b/kernel/kexec_file.c
    @@ -428,6 +428,27 @@ static int locate_mem_hole_callback(u64 start, u64 end, void *arg)
    return locate_mem_hole_bottom_up(start, end, kbuf);
    }

    +/**
    + * arch_kexec_walk_mem - call func(data) on free memory regions
    + * @kbuf: Context info for the search. Also passed to @func.
    + * @func: Function to call for each memory region.
    + *
    + * Return: The memory walk will stop when func returns a non-zero value
    + * and that value will be returned. If all free regions are visited without
    + * func returning non-zero, then zero will be returned.
    + */
    +int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
    + int (*func)(u64, u64, void *))
    +{
    + if (kbuf->image->type == KEXEC_TYPE_CRASH)
    + return walk_iomem_res_desc(crashk_res.desc,
    + IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
    + crashk_res.start, crashk_res.end,
    + kbuf, func);
    + else
    + return walk_system_ram_res(0, ULONG_MAX, kbuf, func);
    +}
    +
    /*
    * Helper function for placing a buffer in a kexec segment. This assumes
    * that kexec_mutex is held.
    @@ -474,14 +495,7 @@ int kexec_add_buffer(struct kimage *image, char *buffer, unsigned long bufsz,
    kbuf->top_down = top_down;

    /* Walk the RAM ranges and allocate a suitable range for the buffer */
    - if (image->type == KEXEC_TYPE_CRASH)
    - ret = walk_iomem_res_desc(crashk_res.desc,
    - IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
    - crashk_res.start, crashk_res.end, kbuf,
    - locate_mem_hole_callback);
    - else
    - ret = walk_system_ram_res(0, -1, kbuf,
    - locate_mem_hole_callback);
    + ret = arch_kexec_walk_mem(kbuf, locate_mem_hole_callback);
    if (ret != 1) {
    /* A suitable memory range could not be found for buffer */
    return -EADDRNOTAVAIL;
    diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
    index 0a52315d9c62..4cef7e4706b0 100644
    --- a/kernel/kexec_internal.h
    +++ b/kernel/kexec_internal.h
    @@ -20,22 +20,6 @@ struct kexec_sha_region {
    unsigned long len;
    };

    -/*
    - * Keeps track of buffer parameters as provided by caller for requesting
    - * memory placement of buffer.
    - */
    -struct kexec_buf {
    - struct kimage *image;
    - char *buffer;
    - unsigned long bufsz;
    - unsigned long mem;
    - unsigned long memsz;
    - unsigned long buf_align;
    - unsigned long buf_min;
    - unsigned long buf_max;
    - bool top_down; /* allocate from top of memory hole */
    -};
    -
    void kimage_file_post_load_cleanup(struct kimage *image);
    #else /* CONFIG_KEXEC_FILE */
    static inline void kimage_file_post_load_cleanup(struct kimage *image) { }
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-11-10 04:31    [W:4.633 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site