Re: [PATCH v34 06/14] arm64: kdump: protect crash dump kernel memory

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 12:07, AKASHI Takahiro  wrote:
> Ard,
>
> On Tue, Mar 28, 2017 at 11:07:05AM +0100, Ard Biesheuvel wrote:
>> On 28 March 2017 at 07:51, AKASHI Takahiro  
>> wrote:
>> > arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres()
>> > are meant to be called by kexec_load() in order to protect the memory
>> > allocated for crash dump kernel once the image is loaded.
>> >
>> > The protection is implemented by unmapping the relevant segments in crash
>> > dump kernel memory, rather than making it read-only as other archs do,
>> > to prevent any corruption due to potential cache alias (with different
>> > attributes) problem.
>> >
>>
>> I think it would be more accurate to replace 'corruption' with
>> 'coherency issues', given that this patch does not solve the issue of
>> writable aliases that may be used to modify the contents of the
>> region, but it does prevent issues related to mismatched attributes
>> (which are arguably a bigger concern)
>
> OK
>
>> > Page-level mappings are consistently used here so that we can change
>> > the attributes of segments in page granularity as well as shrink the region
>> > also in page granularity through /sys/kernel/kexec_crash_size, putting
>> > the freed memory back to buddy system.
>> >
>> > Signed-off-by: AKASHI Takahiro 
>>
>> As a head's up, this patch is going to conflict heavily with patches
>> that are queued up in arm64/for-next/core atm.
>
> I'll look into it later, but
>
>> Some questions below.
>>
>> > ---
>> >  arch/arm64/kernel/machine_kexec.c | 32 +++---
>> >  arch/arm64/mm/mmu.c   | 90 
>> > ---
>> >  2 files changed, 72 insertions(+), 50 deletions(-)
>> >
>> > diff --git a/arch/arm64/kernel/machine_kexec.c 
>> > b/arch/arm64/kernel/machine_kexec.c
>> > index bc96c8a7fc79..b63baa749609 100644
>> > --- a/arch/arm64/kernel/machine_kexec.c
>> > +++ b/arch/arm64/kernel/machine_kexec.c
>> > @@ -14,7 +14,9 @@
>> >
>> >  #include 
>> >  #include 
>> > +#include 
>> >  #include 
>> > +#include 
>> >
>> >  #include "cpu-reset.h"
>> >
>> > @@ -22,8 +24,6 @@
>> >  extern const unsigned char arm64_relocate_new_kernel[];
>> >  extern const unsigned long arm64_relocate_new_kernel_size;
>> >
>> > -static unsigned long kimage_start;
>> > -
>> >  /**
>> >   * kexec_image_info - For debugging output.
>> >   */
>> > @@ -64,8 +64,6 @@ void machine_kexec_cleanup(struct kimage *kimage)
>> >   */
>> >  int machine_kexec_prepare(struct kimage *kimage)
>> >  {
>> > -   kimage_start = kimage->start;
>> > -
>> > kexec_image_info(kimage);
>> >
>> > if (kimage->type != KEXEC_TYPE_CRASH && 
>> > cpus_are_stuck_in_kernel()) {
>> > @@ -183,7 +181,7 @@ void machine_kexec(struct kimage *kimage)
>> > kexec_list_flush(kimage);
>> >
>> > /* Flush the new image if already in place. */
>> > -   if (kimage->head & IND_DONE)
>> > +   if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE))
>> > kexec_segment_flush(kimage);
>> >
>> > pr_info("Bye!\n");
>> > @@ -201,7 +199,7 @@ void machine_kexec(struct kimage *kimage)
>> >  */
>> >
>> > cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
>> > -   kimage_start, 0);
>> > +   kimage->start, 0);
>> >
>> > BUG(); /* Should never get here. */
>> >  }
>> > @@ -210,3 +208,25 @@ void machine_crash_shutdown(struct pt_regs *regs)
>> >  {
>> > /* Empty routine needed to avoid build errors. */
>> >  }
>> > +
>> > +void arch_kexec_protect_crashkres(void)
>> > +{
>> > +   int i;
>> > +
>> > +   kexec_segment_flush(kexec_crash_image);
>> > +
>> > +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
>> > +   set_memory_valid(
>> > +   __phys_to_virt(kexec_crash_image->segment[i].mem),
>> > +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 
>> > 0);
>> > +}
>> > +
>> > +void arch_kexec_unprotect_crashkres(void)
>> > +{
>> > +   int i;
>> > +
>> > +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
>> > +   set_memory_valid(
>> > +   __phys_to_virt(kexec_crash_image->segment[i].mem),
>> > +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 
>> > 1);
>> > +}
>> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> > index d28dbcf596b6..f6a3c0e9d37f 100644
>> > --- a/arch/arm64/mm/mmu.c
>> > +++ b/arch/arm64/mm/mmu.c
>> > @@ -22,6 +22,8 @@
>> >  #include 
>> >  #include 
>> >  #include 
>> > +#include 
>> > +#include 
>> >  #include 
>> >  #include 
>> >  #include 
>> > @@ -332,56 +334,31 @@ static void create_mapping_late(phys_addr_t phys, 
>> > unsigned long virt,
>> >  NULL, debug_pagealloc_enabled());
>> >  }
>> >
>> > -static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, 
>> > phys_addr_t end)
>> > +static void __init __map_memblock(pgd_t *pgd, phys_addr_t star

Re: [PATCH v34 06/14] arm64: kdump: protect crash dump kernel memory

2017-03-28 Thread AKASHI Takahiro
Ard,

On Tue, Mar 28, 2017 at 11:07:05AM +0100, Ard Biesheuvel wrote:
> On 28 March 2017 at 07:51, AKASHI Takahiro  wrote:
> > arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres()
> > are meant to be called by kexec_load() in order to protect the memory
> > allocated for crash dump kernel once the image is loaded.
> >
> > The protection is implemented by unmapping the relevant segments in crash
> > dump kernel memory, rather than making it read-only as other archs do,
> > to prevent any corruption due to potential cache alias (with different
> > attributes) problem.
> >
> 
> I think it would be more accurate to replace 'corruption' with
> 'coherency issues', given that this patch does not solve the issue of
> writable aliases that may be used to modify the contents of the
> region, but it does prevent issues related to mismatched attributes
> (which are arguably a bigger concern)

OK

> > Page-level mappings are consistently used here so that we can change
> > the attributes of segments in page granularity as well as shrink the region
> > also in page granularity through /sys/kernel/kexec_crash_size, putting
> > the freed memory back to buddy system.
> >
> > Signed-off-by: AKASHI Takahiro 
> 
> As a head's up, this patch is going to conflict heavily with patches
> that are queued up in arm64/for-next/core atm.

I'll look into it later, but

> Some questions below.
> 
> > ---
> >  arch/arm64/kernel/machine_kexec.c | 32 +++---
> >  arch/arm64/mm/mmu.c   | 90 
> > ---
> >  2 files changed, 72 insertions(+), 50 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/machine_kexec.c 
> > b/arch/arm64/kernel/machine_kexec.c
> > index bc96c8a7fc79..b63baa749609 100644
> > --- a/arch/arm64/kernel/machine_kexec.c
> > +++ b/arch/arm64/kernel/machine_kexec.c
> > @@ -14,7 +14,9 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> > +#include 
> >
> >  #include "cpu-reset.h"
> >
> > @@ -22,8 +24,6 @@
> >  extern const unsigned char arm64_relocate_new_kernel[];
> >  extern const unsigned long arm64_relocate_new_kernel_size;
> >
> > -static unsigned long kimage_start;
> > -
> >  /**
> >   * kexec_image_info - For debugging output.
> >   */
> > @@ -64,8 +64,6 @@ void machine_kexec_cleanup(struct kimage *kimage)
> >   */
> >  int machine_kexec_prepare(struct kimage *kimage)
> >  {
> > -   kimage_start = kimage->start;
> > -
> > kexec_image_info(kimage);
> >
> > if (kimage->type != KEXEC_TYPE_CRASH && cpus_are_stuck_in_kernel()) 
> > {
> > @@ -183,7 +181,7 @@ void machine_kexec(struct kimage *kimage)
> > kexec_list_flush(kimage);
> >
> > /* Flush the new image if already in place. */
> > -   if (kimage->head & IND_DONE)
> > +   if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE))
> > kexec_segment_flush(kimage);
> >
> > pr_info("Bye!\n");
> > @@ -201,7 +199,7 @@ void machine_kexec(struct kimage *kimage)
> >  */
> >
> > cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
> > -   kimage_start, 0);
> > +   kimage->start, 0);
> >
> > BUG(); /* Should never get here. */
> >  }
> > @@ -210,3 +208,25 @@ void machine_crash_shutdown(struct pt_regs *regs)
> >  {
> > /* Empty routine needed to avoid build errors. */
> >  }
> > +
> > +void arch_kexec_protect_crashkres(void)
> > +{
> > +   int i;
> > +
> > +   kexec_segment_flush(kexec_crash_image);
> > +
> > +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
> > +   set_memory_valid(
> > +   __phys_to_virt(kexec_crash_image->segment[i].mem),
> > +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 
> > 0);
> > +}
> > +
> > +void arch_kexec_unprotect_crashkres(void)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
> > +   set_memory_valid(
> > +   __phys_to_virt(kexec_crash_image->segment[i].mem),
> > +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 
> > 1);
> > +}
> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> > index d28dbcf596b6..f6a3c0e9d37f 100644
> > --- a/arch/arm64/mm/mmu.c
> > +++ b/arch/arm64/mm/mmu.c
> > @@ -22,6 +22,8 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -332,56 +334,31 @@ static void create_mapping_late(phys_addr_t phys, 
> > unsigned long virt,
> >  NULL, debug_pagealloc_enabled());
> >  }
> >
> > -static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, 
> > phys_addr_t end)
> > +static void __init __map_memblock(pgd_t *pgd, phys_addr_t start,
> > + phys_addr_t end, pgprot_t prot,
> > + bool page_mappings_only)
> > +{
> > +   __create_pgd_mapping(pgd, start, __phys_to_v

Re: [PATCH v34 14/14] efi/libstub/arm*: Set default address and size cells values for an empty dtb

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:53, AKASHI Takahiro  wrote:
> From: Sameer Goel 
>
> In cases where a device tree is not provided (ie ACPI based system), an
> empty fdt is generated by efistub.  #address-cells and #size-cells are not
> set in the empty fdt, so they default to 1 (4 byte wide).  This can be an
> issue on 64-bit systems where values representing addresses, etc may be
> 8 bytes wide as the default value does not align with the general
> requirements for an empty DTB, and is fragile when passed to other agents
> as extra care is required to read the entire width of a value.
>
> This issue is observed on Qualcomm Technologies QDF24XX platforms when
> kexec-tools inserts 64-bit addresses into the "linux,elfcorehdr" and
> "linux,usable-memory-range" properties of the fdt.  When the values are
> later consumed, they are truncated to 32-bit.
>
> Setting #address-cells and #size-cells to 2 at creation of the empty fdt
> resolves the observed issue, and makes the fdt less fragile.
>
> Signed-off-by: Sameer Goel 
> Signed-off-by: Jeffrey Hugo 

Reviewed-by: Ard Biesheuvel 

> ---
>  drivers/firmware/efi/libstub/fdt.c | 28 ++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/firmware/efi/libstub/fdt.c 
> b/drivers/firmware/efi/libstub/fdt.c
> index 260c4b4b492e..82973b86efe4 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -16,6 +16,22 @@
>
>  #include "efistub.h"
>
> +#define EFI_DT_ADDR_CELLS_DEFAULT 2
> +#define EFI_DT_SIZE_CELLS_DEFAULT 2
> +
> +static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt)
> +{
> +   int offset;
> +
> +   offset = fdt_path_offset(fdt, "/");
> +   /* Set the #address-cells and #size-cells values for an empty tree */
> +
> +   fdt_setprop_u32(fdt, offset, "#address-cells",
> +   EFI_DT_ADDR_CELLS_DEFAULT);
> +
> +   fdt_setprop_u32(fdt, offset, "#size-cells", 
> EFI_DT_SIZE_CELLS_DEFAULT);
> +}
> +
>  static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>unsigned long orig_fdt_size,
>void *fdt, int new_fdt_size, char *cmdline_ptr,
> @@ -42,10 +58,18 @@ static efi_status_t update_fdt(efi_system_table_t 
> *sys_table, void *orig_fdt,
> }
> }
>
> -   if (orig_fdt)
> +   if (orig_fdt) {
> status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
> -   else
> +   } else {
> status = fdt_create_empty_tree(fdt, new_fdt_size);
> +   if (status == 0) {
> +   /*
> +* Any failure from the following function is non
> +* critical
> +*/
> +   fdt_update_cell_size(sys_table, fdt);
> +   }
> +   }
>
> if (status != 0)
> goto fdt_set_fail;
> --
> 2.11.1
>

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v34 06/14] arm64: kdump: protect crash dump kernel memory

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:51, AKASHI Takahiro  wrote:
> arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres()
> are meant to be called by kexec_load() in order to protect the memory
> allocated for crash dump kernel once the image is loaded.
>
> The protection is implemented by unmapping the relevant segments in crash
> dump kernel memory, rather than making it read-only as other archs do,
> to prevent any corruption due to potential cache alias (with different
> attributes) problem.
>

I think it would be more accurate to replace 'corruption' with
'coherency issues', given that this patch does not solve the issue of
writable aliases that may be used to modify the contents of the
region, but it does prevent issues related to mismatched attributes
(which are arguably a bigger concern)

> Page-level mappings are consistently used here so that we can change
> the attributes of segments in page granularity as well as shrink the region
> also in page granularity through /sys/kernel/kexec_crash_size, putting
> the freed memory back to buddy system.
>
> Signed-off-by: AKASHI Takahiro 

As a head's up, this patch is going to conflict heavily with patches
that are queued up in arm64/for-next/core atm.

Some questions below.

> ---
>  arch/arm64/kernel/machine_kexec.c | 32 +++---
>  arch/arm64/mm/mmu.c   | 90 
> ---
>  2 files changed, 72 insertions(+), 50 deletions(-)
>
> diff --git a/arch/arm64/kernel/machine_kexec.c 
> b/arch/arm64/kernel/machine_kexec.c
> index bc96c8a7fc79..b63baa749609 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -14,7 +14,9 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>
>  #include "cpu-reset.h"
>
> @@ -22,8 +24,6 @@
>  extern const unsigned char arm64_relocate_new_kernel[];
>  extern const unsigned long arm64_relocate_new_kernel_size;
>
> -static unsigned long kimage_start;
> -
>  /**
>   * kexec_image_info - For debugging output.
>   */
> @@ -64,8 +64,6 @@ void machine_kexec_cleanup(struct kimage *kimage)
>   */
>  int machine_kexec_prepare(struct kimage *kimage)
>  {
> -   kimage_start = kimage->start;
> -
> kexec_image_info(kimage);
>
> if (kimage->type != KEXEC_TYPE_CRASH && cpus_are_stuck_in_kernel()) {
> @@ -183,7 +181,7 @@ void machine_kexec(struct kimage *kimage)
> kexec_list_flush(kimage);
>
> /* Flush the new image if already in place. */
> -   if (kimage->head & IND_DONE)
> +   if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE))
> kexec_segment_flush(kimage);
>
> pr_info("Bye!\n");
> @@ -201,7 +199,7 @@ void machine_kexec(struct kimage *kimage)
>  */
>
> cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
> -   kimage_start, 0);
> +   kimage->start, 0);
>
> BUG(); /* Should never get here. */
>  }
> @@ -210,3 +208,25 @@ void machine_crash_shutdown(struct pt_regs *regs)
>  {
> /* Empty routine needed to avoid build errors. */
>  }
> +
> +void arch_kexec_protect_crashkres(void)
> +{
> +   int i;
> +
> +   kexec_segment_flush(kexec_crash_image);
> +
> +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
> +   set_memory_valid(
> +   __phys_to_virt(kexec_crash_image->segment[i].mem),
> +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 0);
> +}
> +
> +void arch_kexec_unprotect_crashkres(void)
> +{
> +   int i;
> +
> +   for (i = 0; i < kexec_crash_image->nr_segments; i++)
> +   set_memory_valid(
> +   __phys_to_virt(kexec_crash_image->segment[i].mem),
> +   kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 1);
> +}
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index d28dbcf596b6..f6a3c0e9d37f 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -22,6 +22,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -332,56 +334,31 @@ static void create_mapping_late(phys_addr_t phys, 
> unsigned long virt,
>  NULL, debug_pagealloc_enabled());
>  }
>
> -static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t 
> end)
> +static void __init __map_memblock(pgd_t *pgd, phys_addr_t start,
> + phys_addr_t end, pgprot_t prot,
> + bool page_mappings_only)
> +{
> +   __create_pgd_mapping(pgd, start, __phys_to_virt(start), end - start,
> +prot, early_pgtable_alloc,
> +page_mappings_only);
> +}
> +
> +static void __init map_mem(pgd_t *pgd)
>  {
> phys_addr_t kernel_start = __pa_symbol(_text);
> phys_addr_t kernel_end = __pa_symbol(__init_begin);
> +   struct memblock_region *reg;
>
> /*
> -* Take care no

Re: [PATCH v34 05/14] arm64: mm: add set_memory_valid()

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:51, AKASHI Takahiro  wrote:
> This function validates and invalidates PTE entries, and will be utilized
> in kdump to protect loaded crash dump kernel image.
>
> Signed-off-by: AKASHI Takahiro 

Reviewed-by: Ard Biesheuvel 

> ---
>  arch/arm64/include/asm/cacheflush.h |  1 +
>  arch/arm64/mm/pageattr.c| 15 +--
>  2 files changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cacheflush.h 
> b/arch/arm64/include/asm/cacheflush.h
> index 5a2a6ee65f65..728f933cef8c 100644
> --- a/arch/arm64/include/asm/cacheflush.h
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -154,5 +154,6 @@ int set_memory_ro(unsigned long addr, int numpages);
>  int set_memory_rw(unsigned long addr, int numpages);
>  int set_memory_x(unsigned long addr, int numpages);
>  int set_memory_nx(unsigned long addr, int numpages);
> +int set_memory_valid(unsigned long addr, unsigned long size, int enable);
>
>  #endif
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index 8def55e7249b..3212ee0558f6 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -125,20 +125,23 @@ int set_memory_x(unsigned long addr, int numpages)
>  }
>  EXPORT_SYMBOL_GPL(set_memory_x);
>
> -#ifdef CONFIG_DEBUG_PAGEALLOC
> -void __kernel_map_pages(struct page *page, int numpages, int enable)
> +int set_memory_valid(unsigned long addr, int numpages, int enable)
>  {
> -   unsigned long addr = (unsigned long) page_address(page);
> -
> if (enable)
> -   __change_memory_common(addr, PAGE_SIZE * numpages,
> +   return __change_memory_common(addr, PAGE_SIZE * numpages,
> __pgprot(PTE_VALID),
> __pgprot(0));
> else
> -   __change_memory_common(addr, PAGE_SIZE * numpages,
> +   return __change_memory_common(addr, PAGE_SIZE * numpages,
> __pgprot(0),
> __pgprot(PTE_VALID));
>  }
> +
> +#ifdef CONFIG_DEBUG_PAGEALLOC
> +void __kernel_map_pages(struct page *page, int numpages, int enable)
> +{
> +   set_memory_valid((unsigned long)page_address(page), numpages, enable);
> +}
>  #ifdef CONFIG_HIBERNATION
>  /*
>   * When built with CONFIG_DEBUG_PAGEALLOC and CONFIG_HIBERNATION, this 
> function
> --
> 2.11.1
>

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v34 04/14] arm64: kdump: reserve memory for crash dump kernel

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:51, AKASHI Takahiro  wrote:
> "crashkernel=" kernel parameter specifies the size (and optionally
> the start address) of the system ram to be used by crash dump kernel.
> reserve_crashkernel() will allocate and reserve that memory at boot time
> of primary kernel.
>
> The memory range will be exposed to userspace as a resource named
> "Crash kernel" in /proc/iomem.
>
> Signed-off-by: AKASHI Takahiro 
> Signed-off-by: Mark Salter 
> Signed-off-by: Pratyush Anand 
> Reviewed-by: James Morse 
> Acked-by: Catalin Marinas 

Reviewed-by: Ard Biesheuvel 

> ---
>  arch/arm64/kernel/setup.c |  7 -
>  arch/arm64/mm/init.c  | 66 
> +++
>  2 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 42274bda0ccb..28855ec1be95 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -31,7 +31,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -226,6 +225,12 @@ static void __init request_standard_resources(void)
> if (kernel_data.start >= res->start &&
> kernel_data.end <= res->end)
> request_resource(res, &kernel_data);
> +#ifdef CONFIG_KEXEC_CORE
> +   /* Userspace will find "Crash kernel" region in /proc/iomem. 
> */
> +   if (crashk_res.end && crashk_res.start >= res->start &&
> +   crashk_res.end <= res->end)
> +   request_resource(res, &crashk_res);
> +#endif
> }
>  }
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 290794b1a0f1..09d19207362d 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -37,6 +38,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include 
>  #include 
> @@ -77,6 +79,67 @@ static int __init early_initrd(char *p)
>  early_param("initrd", early_initrd);
>  #endif
>
> +#ifdef CONFIG_KEXEC_CORE
> +/*
> + * reserve_crashkernel() - reserves memory for crash kernel
> + *
> + * This function reserves memory area given in "crashkernel=" kernel command
> + * line parameter. The memory reserved is used by dump capture kernel when
> + * primary kernel is crashing.
> + */
> +static void __init reserve_crashkernel(void)
> +{
> +   unsigned long long crash_base, crash_size;
> +   int ret;
> +
> +   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> +   &crash_size, &crash_base);
> +   /* no crashkernel= or invalid value specified */
> +   if (ret || !crash_size)
> +   return;
> +
> +   crash_size = PAGE_ALIGN(crash_size);
> +
> +   if (crash_base == 0) {
> +   /* Current arm64 boot protocol requires 2MB alignment */
> +   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
> +   crash_size, SZ_2M);
> +   if (crash_base == 0) {
> +   pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +   crash_size);
> +   return;
> +   }
> +   } else {
> +   /* User specifies base address explicitly. */
> +   if (!memblock_is_region_memory(crash_base, crash_size)) {
> +   pr_warn("cannot reserve crashkernel: region is not 
> memory\n");
> +   return;
> +   }
> +
> +   if (memblock_is_region_reserved(crash_base, crash_size)) {
> +   pr_warn("cannot reserve crashkernel: region overlaps 
> reserved memory\n");
> +   return;
> +   }
> +
> +   if (!IS_ALIGNED(crash_base, SZ_2M)) {
> +   pr_warn("cannot reserve crashkernel: base address is 
> not 2MB aligned\n");
> +   return;
> +   }
> +   }
> +   memblock_reserve(crash_base, crash_size);
> +
> +   pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
> +   crash_base, crash_base + crash_size, crash_size >> 20);
> +
> +   crashk_res.start = crash_base;
> +   crashk_res.end = crash_base + crash_size - 1;
> +}
> +#else
> +static void __init reserve_crashkernel(void)
> +{
> +}
> +#endif /* CONFIG_KEXEC_CORE */
> +
>  /*
>   * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
>   * currently assumes that for memory starting above 4G, 32-bit devices will
> @@ -332,6 +395,9 @@ void __init arm64_memblock_init(void)
> arm64_dma_phys_limit = max_zone_dma_phys();
> else
> arm64_dma_phys_limit = PHYS_MASK + 1;
> +
> +   reserve_crashkernel();
> +
> dma_contiguous_reserve(arm64_dma_phys_limit);
>
> memblock_allow_resize()

Re: [PATCH v34 03/14] arm64: limit memory regions based on DT property, usable-memory-range

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:51, AKASHI Takahiro  wrote:
> Crash dump kernel uses only a limited range of available memory as System
> RAM. On arm64 kdump, This memory range is advertised to crash dump kernel
> via a device-tree property under /chosen,
>linux,usable-memory-range = 
>
> Crash dump kernel reads this property at boot time and calls
> memblock_cap_memory_range() to limit usable memory which are listed either
> in UEFI memory map table or "memory" nodes of a device tree blob.
>
> Signed-off-by: AKASHI Takahiro 
> Reviewed-by: Geoff Levand 
> Acked-by: Catalin Marinas 
> Acked-by: Mark Rutland 

Reviewed-by: Ard Biesheuvel 

> ---
>  arch/arm64/mm/init.c | 35 +++
>  1 file changed, 35 insertions(+)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index e19e06593e37..290794b1a0f1 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -188,10 +188,45 @@ static int __init early_mem(char *p)
>  }
>  early_param("mem", early_mem);
>
> +static int __init early_init_dt_scan_usablemem(unsigned long node,
> +   const char *uname, int depth, void *data)
> +{
> +   struct memblock_region *usablemem = data;
> +   const __be32 *reg;
> +   int len;
> +
> +   if (depth != 1 || strcmp(uname, "chosen") != 0)
> +   return 0;
> +
> +   reg = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
> +   if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
> +   return 1;
> +
> +   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, ®);
> +   usablemem->size = dt_mem_next_cell(dt_root_size_cells, ®);
> +
> +   return 1;
> +}
> +
> +static void __init fdt_enforce_memory_region(void)
> +{
> +   struct memblock_region reg = {
> +   .size = 0,
> +   };
> +
> +   of_scan_flat_dt(early_init_dt_scan_usablemem, ®);
> +
> +   if (reg.size)
> +   memblock_cap_memory_range(reg.base, reg.size);
> +}
> +
>  void __init arm64_memblock_init(void)
>  {
> const s64 linear_region_size = -(s64)PAGE_OFFSET;
>
> +   /* Handle linux,usable-memory-range property */
> +   fdt_enforce_memory_region();
> +
> /*
>  * Ensure that the linear region takes up exactly half of the kernel
>  * virtual address space. This way, we can distinguish a linear 
> address
> --
> 2.11.1
>

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v34 01/14] memblock: add memblock_clear_nomap()

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:50, AKASHI Takahiro  wrote:
> This function, with a combination of memblock_mark_nomap(), will be used
> in a later kdump patch for arm64 when it temporarily isolates some range
> of memory from the other memory blocks in order to create a specific
> kernel mapping at boot time.
>
> Signed-off-by: AKASHI Takahiro 

Reviewed-by: Ard Biesheuvel 

> ---
>  include/linux/memblock.h |  1 +
>  mm/memblock.c| 12 
>  2 files changed, 13 insertions(+)
>
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index bdfc65af4152..e82daffcfc44 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -93,6 +93,7 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t 
> size);
>  int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
>  int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
>  int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
> +int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
>  ulong choose_memblock_flags(void);
>
>  /* Low level functions */
> diff --git a/mm/memblock.c b/mm/memblock.c
> index 696f06d17c4e..2f4ca8104ea4 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -805,6 +805,18 @@ int __init_memblock memblock_mark_nomap(phys_addr_t 
> base, phys_addr_t size)
>  }
>
>  /**
> + * memblock_clear_nomap - Clear flag MEMBLOCK_NOMAP for a specified region.
> + * @base: the base phys addr of the region
> + * @size: the size of the region
> + *
> + * Return 0 on success, -errno on failure.
> + */
> +int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size)
> +{
> +   return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
> +}
> +
> +/**
>   * __next_reserved_mem_region - next function for for_each_reserved_region()
>   * @idx: pointer to u64 loop variable
>   * @out_start: ptr to phys_addr_t for start address of the region, can be 
> %NULL
> --
> 2.11.1
>

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v34 02/14] memblock: add memblock_cap_memory_range()

2017-03-28 Thread Ard Biesheuvel
On 28 March 2017 at 07:50, AKASHI Takahiro  wrote:
> Add memblock_cap_memory_range() which will remove all the memblock regions
> except the memory range specified in the arguments. In addition, rework is
> done on memblock_mem_limit_remove_map() to re-implement it using
> memblock_cap_memory_range().
>
> This function, like memblock_mem_limit_remove_map(), will not remove
> memblocks with MEMMAP_NOMAP attribute as they may be mapped and accessed
> later as "device memory."
> See the commit a571d4eb55d8 ("mm/memblock.c: add new infrastructure to
> address the mem limit issue").
>
> This function is used, in a succeeding patch in the series of arm64 kdump
> suuport, to limit the range of usable memory, or System RAM, on crash dump
> kernel.
> (Please note that "mem=" parameter is of little use for this purpose.)
>
> Signed-off-by: AKASHI Takahiro 
> Reviewed-by: Will Deacon 
> Acked-by: Catalin Marinas 
> Acked-by: Dennis Chen 
> Cc: linux...@kvack.org
> Cc: Andrew Morton 

Reviewed-by: Ard Biesheuvel 

> ---
>  include/linux/memblock.h |  1 +
>  mm/memblock.c| 44 +---
>  2 files changed, 30 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index e82daffcfc44..4ce24a376262 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -336,6 +336,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
>  phys_addr_t memblock_start_of_DRAM(void);
>  phys_addr_t memblock_end_of_DRAM(void);
>  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> +void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
>  void memblock_mem_limit_remove_map(phys_addr_t limit);
>  bool memblock_is_memory(phys_addr_t addr);
>  int memblock_is_map_memory(phys_addr_t addr);
> diff --git a/mm/memblock.c b/mm/memblock.c
> index 2f4ca8104ea4..b049c9b2dba8 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -1543,11 +1543,37 @@ void __init memblock_enforce_memory_limit(phys_addr_t 
> limit)
>   (phys_addr_t)ULLONG_MAX);
>  }
>
> +void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
> +{
> +   int start_rgn, end_rgn;
> +   int i, ret;
> +
> +   if (!size)
> +   return;
> +
> +   ret = memblock_isolate_range(&memblock.memory, base, size,
> +   &start_rgn, &end_rgn);
> +   if (ret)
> +   return;
> +
> +   /* remove all the MAP regions */
> +   for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
> +   if (!memblock_is_nomap(&memblock.memory.regions[i]))
> +   memblock_remove_region(&memblock.memory, i);
> +
> +   for (i = start_rgn - 1; i >= 0; i--)
> +   if (!memblock_is_nomap(&memblock.memory.regions[i]))
> +   memblock_remove_region(&memblock.memory, i);
> +
> +   /* truncate the reserved regions */
> +   memblock_remove_range(&memblock.reserved, 0, base);
> +   memblock_remove_range(&memblock.reserved,
> +   base + size, (phys_addr_t)ULLONG_MAX);
> +}
> +
>  void __init memblock_mem_limit_remove_map(phys_addr_t limit)
>  {
> -   struct memblock_type *type = &memblock.memory;
> phys_addr_t max_addr;
> -   int i, ret, start_rgn, end_rgn;
>
> if (!limit)
> return;
> @@ -1558,19 +1584,7 @@ void __init memblock_mem_limit_remove_map(phys_addr_t 
> limit)
> if (max_addr == (phys_addr_t)ULLONG_MAX)
> return;
>
> -   ret = memblock_isolate_range(type, max_addr, (phys_addr_t)ULLONG_MAX,
> -   &start_rgn, &end_rgn);
> -   if (ret)
> -   return;
> -
> -   /* remove all the MAP regions above the limit */
> -   for (i = end_rgn - 1; i >= start_rgn; i--) {
> -   if (!memblock_is_nomap(&type->regions[i]))
> -   memblock_remove_region(type, i);
> -   }
> -   /* truncate the reserved regions */
> -   memblock_remove_range(&memblock.reserved, max_addr,
> - (phys_addr_t)ULLONG_MAX);
> +   memblock_cap_memory_range(0, max_addr);
>  }
>
>  static int __init_memblock memblock_search(struct memblock_type *type, 
> phys_addr_t addr)
> --
> 2.11.1
>

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v34 14/14] efi/libstub/arm*: Set default address and size cells values for an empty dtb

2017-03-28 Thread AKASHI Takahiro
From: Sameer Goel 

In cases where a device tree is not provided (ie ACPI based system), an
empty fdt is generated by efistub.  #address-cells and #size-cells are not
set in the empty fdt, so they default to 1 (4 byte wide).  This can be an
issue on 64-bit systems where values representing addresses, etc may be
8 bytes wide as the default value does not align with the general
requirements for an empty DTB, and is fragile when passed to other agents
as extra care is required to read the entire width of a value.

This issue is observed on Qualcomm Technologies QDF24XX platforms when
kexec-tools inserts 64-bit addresses into the "linux,elfcorehdr" and
"linux,usable-memory-range" properties of the fdt.  When the values are
later consumed, they are truncated to 32-bit.

Setting #address-cells and #size-cells to 2 at creation of the empty fdt
resolves the observed issue, and makes the fdt less fragile.

Signed-off-by: Sameer Goel 
Signed-off-by: Jeffrey Hugo 
---
 drivers/firmware/efi/libstub/fdt.c | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/libstub/fdt.c 
b/drivers/firmware/efi/libstub/fdt.c
index 260c4b4b492e..82973b86efe4 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -16,6 +16,22 @@
 
 #include "efistub.h"
 
+#define EFI_DT_ADDR_CELLS_DEFAULT 2
+#define EFI_DT_SIZE_CELLS_DEFAULT 2
+
+static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt)
+{
+   int offset;
+
+   offset = fdt_path_offset(fdt, "/");
+   /* Set the #address-cells and #size-cells values for an empty tree */
+
+   fdt_setprop_u32(fdt, offset, "#address-cells",
+   EFI_DT_ADDR_CELLS_DEFAULT);
+
+   fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT);
+}
+
 static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
   unsigned long orig_fdt_size,
   void *fdt, int new_fdt_size, char *cmdline_ptr,
@@ -42,10 +58,18 @@ static efi_status_t update_fdt(efi_system_table_t 
*sys_table, void *orig_fdt,
}
}
 
-   if (orig_fdt)
+   if (orig_fdt) {
status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
-   else
+   } else {
status = fdt_create_empty_tree(fdt, new_fdt_size);
+   if (status == 0) {
+   /*
+* Any failure from the following function is non
+* critical
+*/
+   fdt_update_cell_size(sys_table, fdt);
+   }
+   }
 
if (status != 0)
goto fdt_set_fail;
-- 
2.11.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v34 04/14] arm64: kdump: reserve memory for crash dump kernel

2017-03-28 Thread AKASHI Takahiro
"crashkernel=" kernel parameter specifies the size (and optionally
the start address) of the system ram to be used by crash dump kernel.
reserve_crashkernel() will allocate and reserve that memory at boot time
of primary kernel.

The memory range will be exposed to userspace as a resource named
"Crash kernel" in /proc/iomem.

Signed-off-by: AKASHI Takahiro 
Signed-off-by: Mark Salter 
Signed-off-by: Pratyush Anand 
Reviewed-by: James Morse 
Acked-by: Catalin Marinas 
---
 arch/arm64/kernel/setup.c |  7 -
 arch/arm64/mm/init.c  | 66 +++
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42274bda0ccb..28855ec1be95 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -31,7 +31,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -226,6 +225,12 @@ static void __init request_standard_resources(void)
if (kernel_data.start >= res->start &&
kernel_data.end <= res->end)
request_resource(res, &kernel_data);
+#ifdef CONFIG_KEXEC_CORE
+   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   if (crashk_res.end && crashk_res.start >= res->start &&
+   crashk_res.end <= res->end)
+   request_resource(res, &crashk_res);
+#endif
}
 }
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 290794b1a0f1..09d19207362d 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -77,6 +79,67 @@ static int __init early_initrd(char *p)
 early_param("initrd", early_initrd);
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+/*
+ * reserve_crashkernel() - reserves memory for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+   unsigned long long crash_base, crash_size;
+   int ret;
+
+   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
+   &crash_size, &crash_base);
+   /* no crashkernel= or invalid value specified */
+   if (ret || !crash_size)
+   return;
+
+   crash_size = PAGE_ALIGN(crash_size);
+
+   if (crash_base == 0) {
+   /* Current arm64 boot protocol requires 2MB alignment */
+   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
+   crash_size, SZ_2M);
+   if (crash_base == 0) {
+   pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+   crash_size);
+   return;
+   }
+   } else {
+   /* User specifies base address explicitly. */
+   if (!memblock_is_region_memory(crash_base, crash_size)) {
+   pr_warn("cannot reserve crashkernel: region is not 
memory\n");
+   return;
+   }
+
+   if (memblock_is_region_reserved(crash_base, crash_size)) {
+   pr_warn("cannot reserve crashkernel: region overlaps 
reserved memory\n");
+   return;
+   }
+
+   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
+   return;
+   }
+   }
+   memblock_reserve(crash_base, crash_size);
+
+   pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
+   crash_base, crash_base + crash_size, crash_size >> 20);
+
+   crashk_res.start = crash_base;
+   crashk_res.end = crash_base + crash_size - 1;
+}
+#else
+static void __init reserve_crashkernel(void)
+{
+}
+#endif /* CONFIG_KEXEC_CORE */
+
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -332,6 +395,9 @@ void __init arm64_memblock_init(void)
arm64_dma_phys_limit = max_zone_dma_phys();
else
arm64_dma_phys_limit = PHYS_MASK + 1;
+
+   reserve_crashkernel();
+
dma_contiguous_reserve(arm64_dma_phys_limit);
 
memblock_allow_resize();
-- 
2.11.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v34 12/14] Documentation: kdump: describe arm64 port

2017-03-28 Thread AKASHI Takahiro
Add arch specific descriptions about kdump usage on arm64 to kdump.txt.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Baoquan He 
Acked-by: Dave Young 
Acked-by: Catalin Marinas 
---
 Documentation/kdump/kdump.txt | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index b0eb27b956d9..615434d81108 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -18,7 +18,7 @@ memory image to a dump file on the local disk, or across the 
network to
 a remote system.
 
 Kdump and kexec are currently supported on the x86, x86_64, ppc64, ia64,
-s390x and arm architectures.
+s390x, arm and arm64 architectures.
 
 When the system kernel boots, it reserves a small section of memory for
 the dump-capture kernel. This ensures that ongoing Direct Memory Access
@@ -249,6 +249,13 @@ Dump-capture kernel config options (Arch Dependent, arm)
 
 AUTO_ZRELADDR=y
 
+Dump-capture kernel config options (Arch Dependent, arm64)
+--
+
+- Please note that kvm of the dump-capture kernel will not be enabled
+  on non-VHE systems even if it is configured. This is because the CPU
+  will not be reset to EL2 on panic.
+
 Extended crashkernel syntax
 ===
 
@@ -305,6 +312,8 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
+   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
 
 Load the Dump-capture Kernel
 
@@ -327,6 +336,8 @@ For s390x:
- Use image or bzImage
 For arm:
- Use zImage
+For arm64:
+   - Use vmlinux or Image
 
 If you are using a uncompressed vmlinux image then use following command
 to load dump-capture kernel.
@@ -370,6 +381,9 @@ For s390x:
 For arm:
"1 maxcpus=1 reset_devices"
 
+For arm64:
+   "1 maxcpus=1 reset_devices"
+
 Notes on loading the dump-capture kernel:
 
 * By default, the ELF headers are stored in ELF64 format to support
-- 
2.11.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v34 05/14] arm64: mm: add set_memory_valid()

2017-03-28 Thread AKASHI Takahiro
This function validates and invalidates PTE entries, and will be utilized
in kdump to protect loaded crash dump kernel image.

Signed-off-by: AKASHI Takahiro 
---
 arch/arm64/include/asm/cacheflush.h |  1 +
 arch/arm64/mm/pageattr.c| 15 +--
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/cacheflush.h 
b/arch/arm64/include/asm/cacheflush.h
index 5a2a6ee65f65..728f933cef8c 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -154,5 +154,6 @@ int set_memory_ro(unsigned long addr, int numpages);
 int set_memory_rw(unsigned long addr, int numpages);
 int set_memory_x(unsigned long addr, int numpages);
 int set_memory_nx(unsigned long addr, int numpages);
+int set_memory_valid(unsigned long addr, unsigned long size, int enable);
 
 #endif
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 8def55e7249b..3212ee0558f6 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -125,20 +125,23 @@ int set_memory_x(unsigned long addr, int numpages)
 }
 EXPORT_SYMBOL_GPL(set_memory_x);
 
-#ifdef CONFIG_DEBUG_PAGEALLOC
-void __kernel_map_pages(struct page *page, int numpages, int enable)
+int set_memory_valid(unsigned long addr, int numpages, int enable)
 {
-   unsigned long addr = (unsigned long) page_address(page);
-
if (enable)
-   __change_memory_common(addr, PAGE_SIZE * numpages,
+   return __change_memory_common(addr, PAGE_SIZE * numpages,
__pgprot(PTE_VALID),
__pgprot(0));
else
-   __change_memory_common(addr, PAGE_SIZE * numpages,
+   return __change_memory_common(addr, PAGE_SIZE * numpages,
__pgprot(0),
__pgprot(PTE_VALID));
 }
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+void __kernel_map_pages(struct page *page, int numpages, int enable)
+{
+   set_memory_valid((unsigned long)page_address(page), numpages, enable);
+}
 #ifdef CONFIG_HIBERNATION
 /*
  * When built with CONFIG_DEBUG_PAGEALLOC and CONFIG_HIBERNATION, this function
-- 
2.11.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec