[PATCH v3 5/8] arm64: kdump: set up kernel image segment

2016-09-06 Thread AKASHI Takahiro
On arm64, we can use the same kernel image as 1st kernel, but
we have to modify the entry point as well as segments' addresses
in the kernel's elf header in order to load them into correct places.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/crashdump-arm64.c | 23 +++
 kexec/arch/arm64/crashdump-arm64.h |  1 +
 kexec/arch/arm64/kexec-arm64.c | 25 -
 kexec/arch/arm64/kexec-elf-arm64.c | 10 +-
 4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index 8346131..9517329 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -213,3 +213,26 @@ int load_crashdump_segments(struct kexec_info *info)
 
return 0;
 }
+
+/*
+ * e_entry and p_paddr are actually in virtual address space.
+ * Those values will be translated to physcal addresses by
+ * using virt_to_phys().
+ * So let's get ready for later use so the memory base (phys_offset)
+ * will be correctly replaced with crash_reserved_mem.start.
+ */
+void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr)
+{
+   struct mem_phdr *phdr;
+   int i;
+
+   ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start;
+
+   for (i = 0; i < ehdr->e_phnum; i++) {
+   phdr = >e_phdr[i];
+   if (phdr->p_type != PT_LOAD)
+   continue;
+   phdr->p_paddr +=
+   (-arm64_mem.phys_offset + crash_reserved_mem.start);
+   }
+}
diff --git a/kexec/arch/arm64/crashdump-arm64.h 
b/kexec/arch/arm64/crashdump-arm64.h
index da75a2d..382f571 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -21,5 +21,6 @@ extern struct memory_range crash_reserved_mem;
 extern struct memory_range elfcorehdr_mem;
 
 extern int load_crashdump_segments(struct kexec_info *info);
+extern void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr);
 
 #endif /* CRASHDUMP_ARM64_H */
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index bc96c76..498b218 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -305,12 +305,27 @@ unsigned long arm64_locate_kernel_segment(struct 
kexec_info *info)
 {
unsigned long hole;
 
-   hole = locate_hole(info,
-   arm64_mem.text_offset + arm64_mem.image_size,
-   MiB(2), 0, ULONG_MAX, 1);
+   if (info->kexec_flags & KEXEC_ON_CRASH) {
+   unsigned long hole_end;
+
+   hole = (crash_reserved_mem.start < mem_min ?
+   mem_min : crash_reserved_mem.start);
+   hole = _ALIGN_UP(hole, MiB(2));
+   hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
+
+   if ((hole_end > mem_max) ||
+   (hole_end > crash_reserved_mem.end)) {
+   dbgprintf("%s: Crash kernel out of range\n", __func__);
+   hole = ULONG_MAX;
+   }
+   } else {
+   hole = locate_hole(info,
+   arm64_mem.text_offset + arm64_mem.image_size,
+   MiB(2), 0, ULONG_MAX, 1);
 
-   if (hole == ULONG_MAX)
-   dbgprintf("%s: locate_hole failed\n", __func__);
+   if (hole == ULONG_MAX)
+   dbgprintf("%s: locate_hole failed\n", __func__);
+   }
 
return hole;
 }
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c 
b/kexec/arch/arm64/kexec-elf-arm64.c
index c70a37a..842ce21 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 
+#include "crashdump-arm64.h"
 #include "kexec-arm64.h"
 #include "kexec-elf.h"
 #include "kexec-syscall.h"
@@ -105,7 +106,8 @@ int elf_arm64_load(int argc, char **argv, const char 
*kernel_buf,
}
 
arm64_mem.vp_offset = _ALIGN_DOWN(ehdr.e_entry, MiB(2));
-   arm64_mem.vp_offset -= kernel_segment - get_phys_offset();
+   if (!(info->kexec_flags & KEXEC_ON_CRASH))
+   arm64_mem.vp_offset -= kernel_segment - get_phys_offset();
 
dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
dbgprintf("%s: text_offset:%016lx\n", __func__,
@@ -127,6 +129,12 @@ int elf_arm64_load(int argc, char **argv, const char 
*kernel_buf,
__func__);
goto exit;
}
+
+   /*
+* offset addresses in order to fit vmlinux
+* (elf_exec) into crash kernel's memory
+*/
+   modify_ehdr_for_crashdump();
}
 
/* load the kernel */
-- 
2.9.0


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


Re: [PATCH v26 0/7] arm64: add kdump support

2016-09-06 Thread AKASHI Takahiro
On Wed, Sep 07, 2016 at 01:29:02PM +0900, AKASHI Takahiro wrote:
> v26-specific note: After a comment from Rob[0], an idea of adding
> "linux,usable-memory-range" was dropped. Instead, an existing
> "reserved-memory" node will be used to limit usable memory ranges
> on crash dump kernel.
> This works not only on UEFI/ACPI systems but also on DT-only systems,
> but if he really insists on using DT-specific "usable-memory" property,
> I will post additional patches for kexec-tools. Those would be
> redundant, though.
> Even in that case, the kernel will not have to be changed.
> 
> This patch series adds kdump support on arm64.
> There are some prerequisite patches [1],[2].
> 
> To load a crash-dump kernel to the systems, a series of patches to
> kexec-tools, which have not yet been merged upstream, are needed.
> Please always use my latest kdump patches, v3 [3].
> 
> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
>   - crash utility (coming v7.1.6 or later) [4]
> (Necessary patches have already been queued in the master.)
> 
> 
> [0] 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/452582.html
> [1] "arm64: mark reserved memblock regions explicitly in iomem"
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/450433.html
> [2] "efi: arm64: treat regions with WT/WC set but WB cleared as memory"
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/451491.html
> [3] T.B.D.

For kexec-tools, see:
http://lists.infradead.org/pipermail/kexec/2016-September/017158.html

-Takahiro AKASHI

> [4] https://github.com/crash-utility/crash.git
> 
> 
> Changes for v26 (Sep 7, 2016):
>   o Use /reserved-memory instead of "linux,usable-memory-range" property
> (dropping v25's patch#2 and #3, updating ex-patch#9.)
> 
> Changes for v25 (Aug 29, 2016):
>   o Rebase to Linux-4.8-rc4
>   o Use memremap() instead of ioremap_cache() [patch#5]
> 
> Changes for v24 (Aug 9, 2016):
>   o Rebase to Linux-4.8-rc1
>   o Update descriptions about newly added DT proerties
> 
> Changes for v23 (July 26, 2016):
> 
>   o Move memblock_reserve() to a single place in reserve_crashkernel()
>   o Use  cpu_park_loop() in ipi_cpu_crash_stop()
>   o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash kernel
>   o Re-implement fdt_enforce_memory_region() to remove non-reserve regions
> (for ACPI) from usable memory at crash kernel
> 
> Changes for v22 (July 12, 2016):
> 
>   o Export "crashkernel-base" and "crashkernel-size" via device-tree,
> and add some descriptions about them in chosen.txt
>   o Rename "usable-memory" to "usable-memory-range" to avoid inconsistency
> with powerpc's "usable-memory"
>   o Make cosmetic changes regarding "ifdef" usage
>   o Correct some wordings in kdump.txt
> 
> Changes for v21 (July 6, 2016):
> 
>   o Remove kexec patches.
>   o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
>   o Clarify the description about kvm in kdump.txt.
> 
> See the following link [3] for older changes:
> [3]  
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html
> 
> AKASHI Takahiro (8):
>   arm64: kdump: reserve memory for crash dump kernel
>   memblock: add memblock_cap_memory_range()
>   arm64: limit memory regions based on DT property, usable-memory-range
>   arm64: kdump: implement machine_crash_shutdown()
>   arm64: kdump: add kdump support
>   arm64: kdump: add VMCOREINFO's for user-space coredump tools
>   arm64: kdump: enable kdump in the arm64 defconfig
>   arm64: kdump: update a kernel doc
> 
> James Morse (1):
>   Documentation: dt: chosen properties for arm64 kdump
> 
>  Documentation/devicetree/bindings/chosen.txt |  45 ++
>  Documentation/kdump/kdump.txt|  16 ++-
>  arch/arm64/Kconfig   |  11 ++
>  arch/arm64/configs/defconfig |   1 +
>  arch/arm64/include/asm/hardirq.h |   2 +-
>  arch/arm64/include/asm/kexec.h   |  41 +-
>  arch/arm64/include/asm/smp.h |   2 +
>  arch/arm64/kernel/Makefile   |   1 +
>  arch/arm64/kernel/crash_dump.c   |  71 ++
>  arch/arm64/kernel/machine_kexec.c|  67 -
>  arch/arm64/kernel/setup.c|   7 +-
>  arch/arm64/kernel/smp.c  |  63 +
>  arch/arm64/mm/init.c | 202 
> +++
>  include/linux/memblock.h |   1 +
>  mm/memblock.c|  28 
>  15 files changed, 551 insertions(+), 7 deletions(-)
>  create mode 100644 arch/arm64/kernel/crash_dump.c
> 
> -- 
> 2.9.0
> 
> 
> AKASHI Takahiro (6):
>   arm64: kdump: reserve memory for crash dump kernel
>   arm64: kdump: implement machine_crash_shutdown()
>   arm64: kdump: add kdump support
>   arm64: kdump: add VMCOREINFO's for user-space coredump tools
>   arm64: kdump: 

[PATCH v3 4/8] arm64: kdump: add elf core header segment

2016-09-06 Thread AKASHI Takahiro
Elf core header contains the information necessary for the coredump of
the 1st kernel, including its physcal memory layout as well as cpu register
states at the panic.
The segment is allocated inside the reserved memory of crash dump kernel.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/crashdump-arm64.c | 96 ++
 kexec/arch/arm64/crashdump-arm64.h |  3 ++
 kexec/arch/arm64/iomem.h   |  2 +
 kexec/arch/arm64/kexec-elf-arm64.c | 10 
 4 files changed, 111 insertions(+)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index dcaca43..8346131 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -39,6 +39,39 @@ struct memory_ranges usablemem_rgns = {
.ranges = _reserved_mem,
 };
 
+struct memory_range elfcorehdr_mem;
+
+static struct crash_elf_info elf_info = {
+   .class  = ELFCLASS64,
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+   .data   = ELFDATA2LSB,
+#else
+   .data   = ELFDATA2MSB,
+#endif
+   .machine= EM_AARCH64,
+};
+
+/*
+ * Note: The returned value is correct only if !CONFIG_RANDOMIZE_BASE.
+ */
+static uint64_t get_kernel_page_offset(void)
+{
+   int i;
+
+   if (elf_info.kern_vaddr_start == UINT64_MAX)
+   return UINT64_MAX;
+
+   /* Current max virtual memory range is 48-bits. */
+   for (i = 48; i > 0; i--)
+   if (!(elf_info.kern_vaddr_start & (1UL << i)))
+   break;
+
+   if (i <= 0)
+   return UINT64_MAX;
+   else
+   return UINT64_MAX << i;
+}
+
 /*
  * iomem_range_callback() - callback called for each iomem region
  * @data: not used
@@ -62,6 +95,10 @@ static int iomem_range_callback(void *UNUSED(data), int 
UNUSED(nr),
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
return mem_regions_add(_memory_rgns,
   base, length, RANGE_RAM);
+   else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
+   elf_info.kern_paddr_start = base;
+   else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
+   elf_info.kern_size = base + length - elf_info.kern_paddr_start;
 
return 0;
 }
@@ -115,5 +152,64 @@ static int crash_get_memory_ranges(void)
dbgprint_mem_range("Coredump memory ranges",
   crash_memory_rgns.ranges, crash_memory_rgns.size);
 
+   /*
+* For additional kernel code/data segment.
+* kern_paddr_start/kern_size are determined in iomem_range_callback
+*/
+   elf_info.kern_vaddr_start = get_kernel_sym("_text");
+   if (!elf_info.kern_vaddr_start)
+   elf_info.kern_vaddr_start = UINT64_MAX;
+
+   return 0;
+}
+
+/*
+ * load_crashdump_segments() - load the elf core header
+ * @info: kexec info structure
+ *
+ * This function creates and loads an additional segment of elf core header
+ : which is used to construct /proc/vmcore on crash dump kernel.
+ *
+ * Return 0 in case of success and -1 in case of error.
+ */
+
+int load_crashdump_segments(struct kexec_info *info)
+{
+   unsigned long elfcorehdr;
+   unsigned long bufsz;
+   void *buf;
+   int err;
+
+   /*
+* First fetch all the memory (RAM) ranges that we are going to
+* pass to the crash dump kernel during panic.
+*/
+
+   err = crash_get_memory_ranges();
+
+   if (err)
+   return err;
+
+   elf_info.page_offset = get_kernel_page_offset();
+   dbgprintf("%s: page_offset:   %016llx\n", __func__,
+   elf_info.page_offset);
+
+   err = crash_create_elf64_headers(info, _info,
+   crash_memory_rgns.ranges, crash_memory_rgns.size,
+   , , ELF_CORE_HEADER_ALIGN);
+
+   if (err)
+   return err;
+
+   elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
+   crash_reserved_mem.start, crash_reserved_mem.end,
+   -1, 0);
+
+   elfcorehdr_mem.start = elfcorehdr;
+   elfcorehdr_mem.end = elfcorehdr + bufsz - 1;
+
+   dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__,
+   elfcorehdr_mem.start, elfcorehdr_mem.end);
+
return 0;
 }
diff --git a/kexec/arch/arm64/crashdump-arm64.h 
b/kexec/arch/arm64/crashdump-arm64.h
index 07a0ed0..da75a2d 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -18,5 +18,8 @@
 
 extern struct memory_ranges usablemem_rgns;
 extern struct memory_range crash_reserved_mem;
+extern struct memory_range elfcorehdr_mem;
+
+extern int load_crashdump_segments(struct kexec_info *info);
 
 #endif /* CRASHDUMP_ARM64_H */
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
index 20cda87..d4864bb 100644
--- a/kexec/arch/arm64/iomem.h
+++ b/kexec/arch/arm64/iomem.h

[PATCH v3 3/8] arm64: kdump: identify memory regions

2016-09-06 Thread AKASHI Takahiro
The following regions need to be identified for later use:
 a) memory regions which belong to the 1st kernel
 b) usable memory reserved for crash dump kernel

We go through /proc/iomem to find out a) and b) which are marked
as "System RAM" and "Crash kernel", respectively.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/Makefile  |   2 +
 kexec/arch/arm64/crashdump-arm64.c | 100 -
 kexec/arch/arm64/crashdump-arm64.h |  14 +-
 kexec/arch/arm64/iomem.h   |   1 +
 4 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index 37414dc..c2535c6 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -5,6 +5,8 @@ arm64_FS2DT_INCLUDE += -include 
$(srcdir)/kexec/arch/arm64/kexec-arm64.h \
 
 arm64_DT_OPS += kexec/dt-ops.c
 
+arm64_MEM_REGIONS = kexec/mem_regions.c
+
 arm64_CPPFLAGS += -I $(srcdir)/kexec/
 
 arm64_KEXEC_SRCS += \
diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index d2272c8..dcaca43 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -1,5 +1,13 @@
 /*
  * ARM64 crashdump.
+ * partly derived from arm implementation
+ *
+ * Copyright (c) 2014-2016 Linaro Limited
+ * Author: AKASHI Takahiro 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #define _GNU_SOURCE
@@ -10,12 +18,102 @@
 #include "kexec.h"
 #include "crashdump.h"
 #include "crashdump-arm64.h"
+#include "iomem.h"
 #include "kexec-arm64.h"
 #include "kexec-elf.h"
+#include "mem_regions.h"
 
-struct memory_ranges usablemem_rgns = {};
+/* memory ranges on crashed kernel */
+static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
+static struct memory_ranges crash_memory_rgns = {
+   .size = 0,
+   .max_size = CRASH_MAX_MEMORY_RANGES,
+   .ranges = crash_memory_ranges,
+};
+
+/* memory range reserved for crashkernel */
+struct memory_range crash_reserved_mem;
+struct memory_ranges usablemem_rgns = {
+   .size = 0,
+   .max_size = 1,
+   .ranges = _reserved_mem,
+};
+
+/*
+ * iomem_range_callback() - callback called for each iomem region
+ * @data: not used
+ * @nr: not used
+ * @str: name of the memory region
+ * @base: start address of the memory region
+ * @length: size of the memory region
+ *
+ * This function is called once for each memory region found in /proc/iomem.
+ * It locates system RAM and crashkernel reserved memory and places these to
+ * variables, respectively, crash_memory_ranges and crash_reserved_mem.
+ */
+
+static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
+   char *str, unsigned long long base,
+   unsigned long long length)
+{
+   if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+   return mem_regions_add(_rgns,
+  base, length, RANGE_RAM);
+   else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
+   return mem_regions_add(_memory_rgns,
+  base, length, RANGE_RAM);
+
+   return 0;
+}
 
 int is_crashkernel_mem_reserved(void)
 {
+   if (!crash_reserved_mem.end)
+   kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
+
+   return crash_reserved_mem.start != crash_reserved_mem.end;
+}
+
+/*
+ * crash_get_memory_ranges() - read system physical memory
+ *
+ * Function reads through system physical memory and stores found memory
+ * regions in crash_memory_ranges.
+ * Regions are sorted in ascending order.
+ *
+ * Returns 0 in case of success and -1 otherwise (errno is set).
+ */
+static int crash_get_memory_ranges(void)
+{
+   /*
+* First read all memory regions that can be considered as
+* system memory including the crash area.
+*/
+   if (!usablemem_rgns.size)
+   kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
+
+   /* allow only a single region for crash dump kernel */
+   if (usablemem_rgns.size != 1) {
+   errno = EINVAL;
+   return -1;
+   }
+
+   dbgprint_mem_range("Reserved memory range", _reserved_mem, 1);
+
+   if (mem_regions_exclude(_memory_rgns, _reserved_mem)) {
+   fprintf(stderr,
+   "Error: Number of crash memory ranges excedeed the max 
limit\n");
+   errno = ENOMEM;
+   return -1;
+   }
+
+   /*
+* Make sure that the memory regions are sorted.
+*/
+   mem_regions_sort(_memory_rgns);
+
+   dbgprint_mem_range("Coredump memory ranges",
+  crash_memory_rgns.ranges, crash_memory_rgns.size);
+
return 0;
 }

[PATCH v3 2/8] kexec: generalize and rename get_kernel_stext_sym()

2016-09-06 Thread AKASHI Takahiro
From: Pratyush Anand 

get_kernel_stext_sym() has been defined for both arm and i386. Other
architecture might need some other kernel symbol address. Therefore rewrite
this function as generic function to get any kernel symbol address.

More over, kallsyms is not arch specific representation, therefore have
common function for all arches.

Signed-off-by: Pratyush Anand 
[created symbols.c]
Signed-off-by: AKASHI Takahiro 
---
 kexec/Makefile  |  1 +
 kexec/arch/arm/crashdump-arm.c  | 40 +---
 kexec/arch/i386/crashdump-x86.c | 32 +---
 kexec/kexec.h   |  2 ++
 kexec/symbols.c | 41 +
 5 files changed, 46 insertions(+), 70 deletions(-)
 create mode 100644 kexec/symbols.c

diff --git a/kexec/Makefile b/kexec/Makefile
index 39f365f..2b4fb3d 100644
--- a/kexec/Makefile
+++ b/kexec/Makefile
@@ -26,6 +26,7 @@ KEXEC_SRCS_base += kexec/kernel_version.c
 KEXEC_SRCS_base += kexec/lzma.c
 KEXEC_SRCS_base += kexec/zlib.c
 KEXEC_SRCS_base += kexec/kexec-xen.c
+KEXEC_SRCS_base += kexec/symbols.c
 
 KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C)
 
diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c
index 4a89b5e..2bc898b 100644
--- a/kexec/arch/arm/crashdump-arm.c
+++ b/kexec/arch/arm/crashdump-arm.c
@@ -73,48 +73,10 @@ static struct crash_elf_info elf_info = {
 
 extern unsigned long long user_page_offset;
 
-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
-static unsigned long long get_kernel_stext_sym(void)
-{
-   const char *kallsyms = "/proc/kallsyms";
-   const char *stext = "_stext";
-   char sym[128];
-   char line[128];
-   FILE *fp;
-   unsigned long long vaddr = 0;
-   char type;
-
-   fp = fopen(kallsyms, "r");
-   if (!fp) {
-   fprintf(stderr, "Cannot open %s\n", kallsyms);
-   return 0;
-   }
-
-   while(fgets(line, sizeof(line), fp) != NULL) {
-   unsigned long long addr;
-
-   if (sscanf(line, "%Lx %c %s", , , sym) != 3)
-   continue;
-
-   if (strcmp(sym, stext) == 0) {
-   dbgprintf("kernel symbol %s vaddr = %#llx\n", stext, 
addr);
-   vaddr = addr;
-   break;
-   }
-   }
-
-   fclose(fp);
-
-   if (vaddr == 0)
-   fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
-
-   return vaddr;
-}
-
 static int get_kernel_page_offset(struct kexec_info *info,
struct crash_elf_info *elf_info)
 {
-   unsigned long long stext_sym_addr = get_kernel_stext_sym();
+   unsigned long long stext_sym_addr = get_kernel_sym("stext");
if (stext_sym_addr == 0) {
if (user_page_offset != (-1ULL)) {
elf_info->page_offset = user_page_offset;
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index bbc0f35..664eb3b 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -102,36 +102,6 @@ static int get_kernel_paddr(struct kexec_info 
*UNUSED(info),
return -1;
 }
 
-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
-static unsigned long long get_kernel_stext_sym(void)
-{
-   const char *kallsyms = "/proc/kallsyms";
-   const char *stext = "_stext";
-   char sym[128];
-   char line[128];
-   FILE *fp;
-   unsigned long long vaddr;
-   char type;
-
-   fp = fopen(kallsyms, "r");
-   if (!fp) {
-   fprintf(stderr, "Cannot open %s\n", kallsyms);
-   return 0;
-   }
-
-   while(fgets(line, sizeof(line), fp) != NULL) {
-   if (sscanf(line, "%Lx %c %s", , , sym) != 3)
-   continue;
-   if (strcmp(sym, stext) == 0) {
-   dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, 
vaddr);
-   return vaddr;
-   }
-   }
-
-   fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
-   return 0;
-}
-
 /* Retrieve info regarding virtual address kernel has been compiled for and
  * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
  * from kexec-tools fails because of malformed elf notes. A kernel patch has
@@ -182,7 +152,7 @@ static int get_kernel_vaddr_and_size(struct kexec_info 
*UNUSED(info),
 
/* Traverse through the Elf headers and find the region where
 * _stext symbol is located in. That's where kernel is mapped */
-   stext_sym = get_kernel_stext_sym();
+   stext_sym = get_kernel_sym("stext");
for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
if (phdr->p_type == PT_LOAD) {
unsigned long long saddr = 

[PATCH v3 8/8] arm64: kdump: Add support for binary image files

2016-09-06 Thread AKASHI Takahiro
From: Pratyush Anand 

This patch adds support to use binary image ie arch/arm64/boot/Image with
kdump.

Signed-off-by: Pratyush Anand 
[takahiro.aka...@linaro.org: a bit reworked]
Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/kexec-image-arm64.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/kexec/arch/arm64/kexec-image-arm64.c 
b/kexec/arch/arm64/kexec-image-arm64.c
index 960ed96..982e431 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -4,7 +4,9 @@
 
 #define _GNU_SOURCE
 
+#include "crashdump-arm64.h"
 #include "kexec-arm64.h"
+#include "kexec-syscall.h"
 #include 
 
 int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
@@ -58,6 +60,16 @@ int image_arm64_load(int argc, char **argv, const char 
*kernel_buf,
dbgprintf("%s: PE format:  %s\n", __func__,
(arm64_header_check_pe_sig(header) ? "yes" : "no"));
 
+   if (info->kexec_flags & KEXEC_ON_CRASH) {
+   /* create and initialize elf core header segment */
+   result = load_crashdump_segments(info);
+   if (result) {
+   dbgprintf("%s: Creating eflcorehdr failed.\n",
+   __func__);
+   goto exit;
+   }
+   }
+
/* load the kernel */
add_segment_phys_virt(info, kernel_buf, kernel_size,
kernel_segment + arm64_mem.text_offset,
-- 
2.9.0


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


[PATCH v3 7/8] arm64: kdump: add DT properties to crash dump kernel's dtb

2016-09-06 Thread AKASHI Takahiro
We pass the following properties to crash dump kernel:
/chosen/linux,elfcorehdr: elf core header segment,
same as "elfcorehdr=" as on other archs
/reserved-memory/crash_dump@xx: any memory regions to be dumped
into /proc/vmcore

Then, we are ready to support kdump.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/crashdump-arm64.c | 141 -
 kexec/arch/arm64/crashdump-arm64.h |   2 +
 kexec/arch/arm64/kexec-arm64.c |  34 +++--
 kexec/arch/arm64/kexec-elf-arm64.c |   5 --
 4 files changed, 171 insertions(+), 11 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index 9517329..01b9716 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -13,6 +13,7 @@
 #define _GNU_SOURCE
 
 #include 
+#include 
 #include 
 
 #include "kexec.h"
@@ -21,11 +22,12 @@
 #include "iomem.h"
 #include "kexec-arm64.h"
 #include "kexec-elf.h"
+#include "libfdt.h"
 #include "mem_regions.h"
 
 /* memory ranges on crashed kernel */
 static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
-static struct memory_ranges crash_memory_rgns = {
+struct memory_ranges crash_memory_rgns = {
.size = 0,
.max_size = CRASH_MAX_MEMORY_RANGES,
.ranges = crash_memory_ranges,
@@ -236,3 +238,140 @@ void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr)
(-arm64_mem.phys_offset + crash_reserved_mem.start);
}
 }
+
+static int dtb_add_reserved_memory(void *dtb_buf)
+{
+   int nodeoffset, rsvmem_node;
+   uint32_t cell_size;
+   uint64_t range[2];
+   char name[30];
+   int i, result = 0;
+
+   rsvmem_node = fdt_path_offset(dtb_buf, "reserved-memory");
+   if (rsvmem_node < 0) {
+   nodeoffset = fdt_path_offset(dtb_buf, "/");
+   rsvmem_node = fdt_add_subnode(dtb_buf, nodeoffset,
+   "reserved-memory");
+   if (rsvmem_node < 0) {
+   result = rsvmem_node;
+   goto on_error;
+   }
+
+   cell_size = cpu_to_fdt32(2);
+   fdt_setprop(dtb_buf, rsvmem_node, "#address-cells",
+   _size, sizeof(cell_size));
+   fdt_setprop(dtb_buf, rsvmem_node, "#size-cells",
+   _size, sizeof(cell_size));
+   fdt_setprop(dtb_buf, rsvmem_node, "ranges", NULL, 0);
+   }
+
+   for (i = 0; i < crash_memory_rgns.size; i++) {
+   sprintf(name, "crash_dump@%llx",
+   crash_memory_rgns.ranges[i].start);
+   nodeoffset = fdt_add_subnode(dtb_buf, rsvmem_node, name);
+   if (nodeoffset < 0) {
+   result = nodeoffset;
+   goto on_error;
+   }
+
+   range[0] = cpu_to_fdt64(crash_memory_rgns.ranges[i].start);
+   range[1] = cpu_to_fdt64(crash_memory_rgns.ranges[i].end
+   - crash_memory_rgns.ranges[i].start + 
1);
+   fdt_setprop(dtb_buf, nodeoffset, "reg", , sizeof(range));
+   fdt_setprop(dtb_buf, nodeoffset, "no-map", NULL, 0);
+   }
+
+on_error:
+   return result;
+}
+
+/*
+ * Increased size for extra properties:
+ * - linux,elfcorehdr
+ *  linux,elfcoredhr = ;
+ * - reserved-memory node
+ *  reserved-memory {
+ * #address-cells = <2>;
+ * #size-cells = <2>;
+ * ranges;
+ * crash_dump@xx {
+ *reg = ;
+ *no-map;
+ * };
+ * ...
+ *  }
+ */
+#define DTB_ELFCOREHDR_PROP_SIZE \
+(sizeof(struct fdt_property)   \
+   + FDT_TAGALIGN(sizeof(uint64_t) * 2)\
+   + strlen("linux,elfcorehdr") + 1)
+#define DTB_RESVMEM_NODE_SIZE \
+(sizeof(struct fdt_node_header)\
+   + strlen("reserved-memory") + 1 \
+   + sizeof(struct fdt_property)   \
+   + FDT_TAGALIGN(sizeof(uint32_t))\
+   + strlen("#address-cells") + 1  \
+   + sizeof(struct fdt_property)   \
+   + FDT_TAGALIGN(sizeof(uint32_t))\
+   + strlen("#size-cells") + 1 \
+   + sizeof(struct fdt_property)   \
+   + strlen("ranges") + 1)
+#define DTB_RESVMEM_SUBNODE_SIZE \
+(sizeof(struct fdt_node_header)\
+   + strlen("crash_dump@") + 1 \
+   + sizeof(struct fdt_property)   \
+   + FDT_TAGALIGN(sizeof(uint64_t) * 2)\
+   + strlen("reg") + 1 \
+   + sizeof(struct 

[PATCH v3 0/8] (kexec-tools) arm64: add kdump support

2016-09-06 Thread AKASHI Takahiro
My kernel patches of kdump suport on arm64 are currently under reviews.

This patchset is synced with them (v26 [1]) and provides necessary changes
for kexec-tools. It should be applied on top of Geoff's kexec-tools patches
v5[2] along with a bugfix[3].

[1] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-September/454588.html
[2] http://lists.infradead.org/pipermail/kexec/2016-September/017110.html
[3] http://lists.infradead.org/pipermail/kexec/2016-July/016664.html

Changes for v3:
 - rebased on Geoff's v5
 - fix a value of estimated PHYS_OFFSET
 - add a kernel code/data segment because they now reside out of linear
   mapping due to KASLR introduction
 - remove "linux,usable-memory-range" dependency, instead using
   "reserved-memory" node
 - add -mem-min/-mem-max support

Changes for v2:
 - trim a temoprary buffer in setup_2nd_dtb()
 - add patch#6("kexec: generalize and rename get_kernel_stext_sym()")
 - update patch#7 from Pratyush
   (re-worked by akashi)

AKASHI Takahiro (6):
  arm64: identify PHYS_OFFSET correctly
  arm64: kdump: identify memory regions
  arm64: kdump: add elf core header segment
  arm64: kdump: set up kernel image segment
  arm64: kdump: set up other segments
  arm64: kdump: add DT properties to crash dump kernel's dtb

Pratyush Anand (2):
  kexec: generalize and rename get_kernel_stext_sym()
  arm64: kdump: Add support for binary image files

 kexec/Makefile   |   1 +
 kexec/arch/arm/crashdump-arm.c   |  40 +---
 kexec/arch/arm64/Makefile|   2 +
 kexec/arch/arm64/crashdump-arm64.c   | 358 ++-
 kexec/arch/arm64/crashdump-arm64.h   |  20 +-
 kexec/arch/arm64/iomem.h |  10 +
 kexec/arch/arm64/kexec-arm64.c   |  86 +++--
 kexec/arch/arm64/kexec-elf-arm64.c   |  25 ++-
 kexec/arch/arm64/kexec-image-arm64.c |  12 ++
 kexec/arch/i386/crashdump-x86.c  |  32 +---
 kexec/kexec.h|   2 +
 kexec/symbols.c  |  41 
 12 files changed, 534 insertions(+), 95 deletions(-)
 create mode 100644 kexec/arch/arm64/iomem.h
 create mode 100644 kexec/symbols.c

-- 
2.9.0


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


[PATCH v3 6/8] arm64: kdump: set up other segments

2016-09-06 Thread AKASHI Takahiro
We make sure that all the other segments, initrd and device-tree blob,
also be loaded into the reserved memory of crash dump kernel.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/kexec-arm64.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 498b218..bcb4e76 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -373,7 +373,10 @@ int arm64_load_other_segments(struct kexec_info *info,
/* Put the other segments after the image. */
 
hole_min = image_base + arm64_mem.image_size;
-   hole_max = ULONG_MAX;
+   if (info->kexec_flags & KEXEC_ON_CRASH)
+   hole_max = crash_reserved_mem.end;
+   else
+   hole_max = ULONG_MAX;
 
if (arm64_opts.initrd) {
initrd_buf = slurp_file(arm64_opts.initrd, _size);
-- 
2.9.0


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


[PATCH v3 1/8] arm64: identify PHYS_OFFSET correctly

2016-09-06 Thread AKASHI Takahiro
Due to the kernel patch[1], the current code will not be able to identify
the correct value of PHYS_OFFSET if some "reserved" memory region, which
is likely to be UEFI runtime services code/data, exists at an address below
the first "System RAM" regions.

This patch fixes this issue.

Signed-off-by: AKASHI Takahiro 
---
 kexec/arch/arm64/iomem.h   |  7 +++
 kexec/arch/arm64/kexec-arm64.c | 22 +-
 2 files changed, 24 insertions(+), 5 deletions(-)
 create mode 100644 kexec/arch/arm64/iomem.h

diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
new file mode 100644
index 000..7fd66eb
--- /dev/null
+++ b/kexec/arch/arm64/iomem.h
@@ -0,0 +1,7 @@
+#ifndef IOMEM_H
+#define IOMEM_H
+
+#define SYSTEM_RAM "System RAM\n"
+#define IOMEM_RESERVED "reserved\n"
+
+#endif
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 7183dac..bc96c76 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -21,6 +21,7 @@
 #include "crashdump-arm64.h"
 #include "dt-ops.h"
 #include "fs2dt.h"
+#include "iomem.h"
 #include "kexec-syscall.h"
 #include "arch/options.h"
 
@@ -465,18 +466,28 @@ void add_segment(struct kexec_info *info, const void 
*buf, size_t bufsz,
  * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
  */
 
+static int count_memory_ranges;
+
 static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
unsigned long long base, unsigned long long length)
 {
struct memory_range *r;
 
-   if (nr >= KEXEC_SEGMENT_MAX)
+   if (count_memory_ranges >= KEXEC_SEGMENT_MAX)
return -1;
 
-   r = (struct memory_range *)data + nr;
-   r->type = RANGE_RAM;
+   r = (struct memory_range *)data + count_memory_ranges;
+
+   if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
+   r->type = RANGE_RAM;
+   else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
+   r->type = RANGE_RESERVED;
+   else
+   return 0;
+
r->start = base;
r->end = base + length - 1;
+   count_memory_ranges++;
 
set_phys_offset(r->start);
 
@@ -493,9 +504,10 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, 
char *str,
 static int get_memory_ranges_iomem(struct memory_range *array,
unsigned int *count)
 {
-   *count = kexec_iomem_for_each_line("System RAM\n",
-   get_memory_ranges_iomem_cb, array);
+   count_memory_ranges = 0;
+   kexec_iomem_for_each_line(NULL, get_memory_ranges_iomem_cb, array);
 
+   *count = count_memory_ranges;
if (!*count) {
dbgprintf("%s: failed: No RAM found.\n", __func__);
return -EFAILED;
-- 
2.9.0


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


[PATCH v26 7/7] Documentation: dt: chosen properties for arm64 kdump

2016-09-06 Thread AKASHI Takahiro
From: James Morse 

Add documentation for
linux,crashkernel-base and crashkernel-size,
linux,elfcorehdr
used by arm64 kexec/kdump to decribe the kdump reserved area, and
the elfcorehdr's location within it.

Signed-off-by: James Morse 
[takahiro.aka...@linaro.org: added "linux,crashkernel-base" and "-size" ]
Signed-off-by: AKASHI Takahiro 
---
 Documentation/devicetree/bindings/chosen.txt | 30 
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/chosen.txt 
b/Documentation/devicetree/bindings/chosen.txt
index 6ae9d82..6257ee7 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -52,3 +52,33 @@ This property is set (currently only on PowerPC, and only 
needed on
 book3e) by some versions of kexec-tools to tell the new kernel that it
 is being booted by kexec, as the booting environment may differ (e.g.
 a different secondary CPU release mechanism)
+
+linux,crashkernel-base
+linux,crashkernel-size
+--
+
+These properties (currently used on PowerPC and arm64) indicates
+the base address and the size, respectively, of the reserved memory
+range for crash dump kernel.
+e.g.
+
+/ {
+   chosen {
+   linux,crashkernel-base = <0x9 0xf000>;
+   linux,crashkernel-size = <0x0 0x1000>;
+   };
+};
+
+linux,elfcorehdr
+
+
+This property (currently used only on arm64) holds the memory range,
+the address and the size, of the elf core header which mainly describes
+the panicked kernel's memory layout as PT_LOAD segments of elf format.
+e.g.
+
+/ {
+   chosen {
+   linux,elfcorehdr = <0x9 0xf000 0x0 0x800>;
+   };
+};
-- 
2.9.0


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


[PATCH v26 6/7] arm64: kdump: update a kernel doc

2016-09-06 Thread AKASHI Takahiro
This patch adds arch specific descriptions about kdump usage on arm64
to kdump.txt.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Baoquan He 
Acked-by: Dave Young 
---
 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 88ff63d..c090531 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
+  cannot 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.9.0


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


[PATCH v26 5/7] arm64: kdump: enable kdump in the arm64 defconfig

2016-09-06 Thread AKASHI Takahiro
Signed-off-by: AKASHI Takahiro 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index eadf485..e181132 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -77,6 +77,7 @@ CONFIG_CMA=y
 CONFIG_SECCOMP=y
 CONFIG_XEN=y
 CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
 CONFIG_CPU_IDLE=y
-- 
2.9.0


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


[PATCH v26 4/7] arm64: kdump: add VMCOREINFO's for user-space coredump tools

2016-09-06 Thread AKASHI Takahiro
For the current crash utility, we need to know, at least,
  - kimage_voffset
  - PHYS_OFFSET
to handle the contents of core dump file (/proc/vmcore) correctly due to
the introduction of KASLR (CONFIG_RANDOMIZE_BASE) in v4.6.
This patch puts them as VMCOREINFO's into the file.

  - VA_BITS
is also added for makedumpfile command.
More VMCOREINFO's may be added later.

Signed-off-by: AKASHI Takahiro 
---
 arch/arm64/kernel/machine_kexec.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/kernel/machine_kexec.c 
b/arch/arm64/kernel/machine_kexec.c
index 8ac9dba8..38b4411 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -17,6 +17,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include "cpu-reset.h"
@@ -260,3 +261,13 @@ void machine_crash_shutdown(struct pt_regs *regs)
 
pr_info("Starting crashdump kernel...\n");
 }
+
+void arch_crash_save_vmcoreinfo(void)
+{
+   VMCOREINFO_NUMBER(VA_BITS);
+   /* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
+   vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
+   kimage_voffset);
+   vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
+   PHYS_OFFSET);
+}
-- 
2.9.0


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


[PATCH v26 3/7] arm64: kdump: add kdump support

2016-09-06 Thread AKASHI Takahiro
On crash dump kernel, all the information about primary kernel's system
memory (core image) is available in elf core header.
The primary kernel will set aside this header with reserve_elfcorehdr()
at boot time and inform crash dump kernel of its location via a new
device-tree property, "linux,elfcorehdr".

Please note that all other architectures use traditional "elfcorehdr="
kernel parameter for this purpose.

Then crash dump kernel will access the primary kernel's memory with
copy_oldmem_page(), which reads one page by ioremap'ing it since it does
not reside in linear mapping on crash dump kernel.

We also need our own elfcorehdr_read() here since the header is placed
within crash dump kernel's usable memory.

Signed-off-by: AKASHI Takahiro 
---
 arch/arm64/Kconfig | 11 +++
 arch/arm64/kernel/Makefile |  1 +
 arch/arm64/kernel/crash_dump.c | 71 ++
 arch/arm64/mm/init.c   | 54 
 4 files changed, 137 insertions(+)
 create mode 100644 arch/arm64/kernel/crash_dump.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc3f00f..9c15c66 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -683,6 +683,17 @@ config KEXEC
  but it is independent of the system firmware.   And like a reboot
  you can start any kernel with it, not just Linux.
 
+config CRASH_DUMP
+   bool "Build kdump crash kernel"
+   help
+ Generate crash dump after being started by kexec. This should
+ be normally only set in special crash dump kernels which are
+ loaded in the main kernel with kexec-tools into a specially
+ reserved region and then later executed after a crash by
+ kdump/kexec.
+
+ For more details see Documentation/kdump/kdump.txt
+
 config XEN_DOM0
def_bool y
depends on XEN
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 14f7b65..f1cbfc8 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -48,6 +48,7 @@ arm64-obj-$(CONFIG_RANDOMIZE_BASE)+= kaslr.o
 arm64-obj-$(CONFIG_HIBERNATION)+= hibernate.o hibernate-asm.o
 arm64-obj-$(CONFIG_KEXEC)  += machine_kexec.o relocate_kernel.o
\
   cpu-reset.o
+arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 
 obj-y  += $(arm64-obj-y) vdso/ probes/
 obj-m  += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c
new file mode 100644
index 000..bc5b932
--- /dev/null
+++ b/arch/arm64/kernel/crash_dump.c
@@ -0,0 +1,71 @@
+/*
+ * Routines for doing kexec-based kdump
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: AKASHI Takahiro 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * copy_oldmem_page() - copy one page from old kernel memory
+ * @pfn: page frame number to be copied
+ * @buf: buffer where the copied page is placed
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page
+ * @userbuf: if set, @buf is in a user address space
+ *
+ * This function copies one page from old kernel memory into buffer pointed by
+ * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
+ * copied or negative error in case of failure.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+size_t csize, unsigned long offset,
+int userbuf)
+{
+   void *vaddr;
+
+   if (!csize)
+   return 0;
+
+   vaddr = memremap(__pfn_to_phys(pfn), PAGE_SIZE, MEMREMAP_WB);
+   if (!vaddr)
+   return -ENOMEM;
+
+   if (userbuf) {
+   if (copy_to_user(buf, vaddr + offset, csize)) {
+   memunmap(vaddr);
+   return -EFAULT;
+   }
+   } else {
+   memcpy(buf, vaddr + offset, csize);
+   }
+
+   memunmap(vaddr);
+
+   return csize;
+}
+
+/**
+ * elfcorehdr_read - read from ELF core header
+ * @buf: buffer where the data is placed
+ * @csize: number of bytes to read
+ * @ppos: address in the memory
+ *
+ * This function reads @count bytes from elf core header which exists
+ * on crash dump kernel's memory.
+ */
+ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
+{
+   memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count);
+   return count;
+}
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index dd273ec..e4d9c38 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -186,6 

[PATCH v26 1/7] arm64: kdump: reserve memory for crash dump kernel

2016-09-06 Thread AKASHI Takahiro
On the startup of primary kernel, the memory region used by crash dump
kernel must be specified by "crashkernel=" kernel parameter.
reserve_crashkernel() will allocate and reserve the region for later use.

User space tools, like kexec-tools, will be able to find that region as
- "Crash kernel" in /proc/iomem, or
- "linux,crashkernel-base" and "linux,crashkernel-size" under
  /sys/firmware/devicetree/base/chosen

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

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 514b4e3..38589b5 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -31,7 +31,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -225,6 +224,12 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
}
+
+#ifdef CONFIG_KEXEC_CORE
+   /* User space tools will find "Crash kernel" region in /proc/iomem. */
+   if (crashk_res.end)
+   insert_resource(_resource, _res);
+#endif
 }
 
 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index bbb7ee7..dd273ec 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -29,11 +29,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -76,6 +78,114 @@ static int __init early_initrd(char *p)
 early_param("initrd", early_initrd);
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+static unsigned long long crash_size, crash_base;
+static struct property crash_base_prop = {
+   .name = "linux,crashkernel-base",
+   .length = sizeof(u64),
+   .value = _base
+};
+static struct property crash_size_prop = {
+   .name = "linux,crashkernel-size",
+   .length = sizeof(u64),
+   .value = _size,
+};
+
+static int __init export_crashkernel(void)
+{
+   struct device_node *node;
+   int ret;
+
+   if (!crashk_res.end)
+   return 0;
+
+   crash_base = cpu_to_be64(crashk_res.start);
+   crash_size = cpu_to_be64(crashk_res.end - crashk_res.start + 1);
+
+   /* Add /chosen/linux,crashkernel-* properties */
+   node = of_find_node_by_path("/chosen");
+   if (!node)
+   return -ENOENT;
+
+   /*
+* There might be existing crash kernel properties, but we can't
+* be sure what's in them, so remove them.
+*/
+   of_remove_property(node, of_find_property(node,
+   "linux,crashkernel-base", NULL));
+   of_remove_property(node, of_find_property(node,
+   "linux,crashkernel-size", NULL));
+
+   ret = of_add_property(node, _base_prop);
+   if (ret)
+   goto ret_err;
+
+   ret = of_add_property(node, _size_prop);
+   if (ret)
+   goto ret_err;
+
+   return 0;
+
+ret_err:
+   pr_warn("Exporting crashkernel region to device tree failed\n");
+   return ret;
+}
+late_initcall(export_crashkernel);
+
+/*
+ * 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)
+{
+   int ret;
+
+   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
+   _size, _base);
+   /* no crashkernel= or invalid value specified */
+   if (ret || !crash_size)
+   return;
+
+   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("Unable to allocate crashkernel (size:%llx)\n",
+   crash_size);
+   return;
+   }
+   } else {
+   /* User specifies base address explicitly. */
+   if (!memblock_is_region_memory(crash_base, crash_size) ||
+   memblock_is_region_reserved(crash_base, crash_size)) {
+   pr_warn("crashkernel has wrong address or size\n");
+   return;
+   }
+
+   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   pr_warn("crashkernel base address is not 2MB 

[PATCH v26 2/7] arm64: kdump: implement machine_crash_shutdown()

2016-09-06 Thread AKASHI Takahiro
Primary kernel calls machine_crash_shutdown() to shut down non-boot cpus
and save registers' status in per-cpu ELF notes before starting crash
dump kernel. See kernel_kexec().
Even if not all secondary cpus have shut down, we do kdump anyway.

As we don't have to make non-boot(crashed) cpus offline (to preserve
correct status of cpus at crash dump) before shutting down, this patch
also adds a variant of smp_send_stop().

Signed-off-by: AKASHI Takahiro 
---
 arch/arm64/include/asm/hardirq.h  |  2 +-
 arch/arm64/include/asm/kexec.h| 41 -
 arch/arm64/include/asm/smp.h  |  2 ++
 arch/arm64/kernel/machine_kexec.c | 56 --
 arch/arm64/kernel/smp.c   | 63 +++
 5 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index 8740297..1473fc2 100644
--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -20,7 +20,7 @@
 #include 
 #include 
 
-#define NR_IPI 6
+#define NR_IPI 7
 
 typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 04744dc..a908958 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -40,7 +40,46 @@
 static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
 {
-   /* Empty routine needed to avoid build errors. */
+   if (oldregs) {
+   memcpy(newregs, oldregs, sizeof(*newregs));
+   } else {
+   u64 tmp1, tmp2;
+
+   __asm__ __volatile__ (
+   "stp x0,   x1, [%2, #16 *  0]\n"
+   "stp x2,   x3, [%2, #16 *  1]\n"
+   "stp x4,   x5, [%2, #16 *  2]\n"
+   "stp x6,   x7, [%2, #16 *  3]\n"
+   "stp x8,   x9, [%2, #16 *  4]\n"
+   "stpx10,  x11, [%2, #16 *  5]\n"
+   "stpx12,  x13, [%2, #16 *  6]\n"
+   "stpx14,  x15, [%2, #16 *  7]\n"
+   "stpx16,  x17, [%2, #16 *  8]\n"
+   "stpx18,  x19, [%2, #16 *  9]\n"
+   "stpx20,  x21, [%2, #16 * 10]\n"
+   "stpx22,  x23, [%2, #16 * 11]\n"
+   "stpx24,  x25, [%2, #16 * 12]\n"
+   "stpx26,  x27, [%2, #16 * 13]\n"
+   "stpx28,  x29, [%2, #16 * 14]\n"
+   "mov %0,  sp\n"
+   "stpx30,  %0,  [%2, #16 * 15]\n"
+
+   "/* faked current PSTATE */\n"
+   "mrs %0, CurrentEL\n"
+   "mrs %1, DAIF\n"
+   "orr %0, %0, %1\n"
+   "mrs %1, NZCV\n"
+   "orr %0, %0, %1\n"
+
+   /* pc */
+   "adr %1, 1f\n"
+   "1:\n"
+   "stp %1, %0,   [%2, #16 * 16]\n"
+   : "=r" (tmp1), "=r" (tmp2), "+r" (newregs)
+   :
+   : "memory"
+   );
+   }
 }
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..6b0f2c7 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -136,6 +136,8 @@ static inline void cpu_panic_kernel(void)
  */
 bool cpus_are_stuck_in_kernel(void);
 
+extern void smp_send_crash_stop(void);
+
 #endif /* ifndef __ASSEMBLY__ */
 
 #endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/kernel/machine_kexec.c 
b/arch/arm64/kernel/machine_kexec.c
index bc96c8a..8ac9dba8 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -9,6 +9,9 @@
  * published by the Free Software Foundation.
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 
@@ -22,6 +25,7 @@
 extern const unsigned char arm64_relocate_new_kernel[];
 extern const unsigned long arm64_relocate_new_kernel_size;
 
+bool in_crash_kexec;
 static unsigned long kimage_start;
 
 /**
@@ -148,7 +152,8 @@ void machine_kexec(struct kimage *kimage)
/*
 * New cpus may have become stuck_in_kernel after we loaded the image.
 */
-   BUG_ON(cpus_are_stuck_in_kernel() || (num_online_cpus() > 1));
+   BUG_ON((cpus_are_stuck_in_kernel() || (num_online_cpus() > 1)) &&
+   !WARN_ON(in_crash_kexec));
 
reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
@@ -200,13 +205,58 @@ void machine_kexec(struct kimage *kimage)
 * relocation is complete.
 */
 
-   cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
+   

[PATCH v26 0/7] arm64: add kdump support

2016-09-06 Thread AKASHI Takahiro
v26-specific note: After a comment from Rob[0], an idea of adding
"linux,usable-memory-range" was dropped. Instead, an existing
"reserved-memory" node will be used to limit usable memory ranges
on crash dump kernel.
This works not only on UEFI/ACPI systems but also on DT-only systems,
but if he really insists on using DT-specific "usable-memory" property,
I will post additional patches for kexec-tools. Those would be
redundant, though.
Even in that case, the kernel will not have to be changed.

This patch series adds kdump support on arm64.
There are some prerequisite patches [1],[2].

To load a crash-dump kernel to the systems, a series of patches to
kexec-tools, which have not yet been merged upstream, are needed.
Please always use my latest kdump patches, v3 [3].

To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
  - crash utility (coming v7.1.6 or later) [4]
(Necessary patches have already been queued in the master.)


[0] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/452582.html
[1] "arm64: mark reserved memblock regions explicitly in iomem"

http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/450433.html
[2] "efi: arm64: treat regions with WT/WC set but WB cleared as memory"

http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/451491.html
[3] T.B.D.
[4] https://github.com/crash-utility/crash.git


Changes for v26 (Sep 7, 2016):
  o Use /reserved-memory instead of "linux,usable-memory-range" property
(dropping v25's patch#2 and #3, updating ex-patch#9.)

Changes for v25 (Aug 29, 2016):
  o Rebase to Linux-4.8-rc4
  o Use memremap() instead of ioremap_cache() [patch#5]

Changes for v24 (Aug 9, 2016):
  o Rebase to Linux-4.8-rc1
  o Update descriptions about newly added DT proerties

Changes for v23 (July 26, 2016):

  o Move memblock_reserve() to a single place in reserve_crashkernel()
  o Use  cpu_park_loop() in ipi_cpu_crash_stop()
  o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash kernel
  o Re-implement fdt_enforce_memory_region() to remove non-reserve regions
(for ACPI) from usable memory at crash kernel

Changes for v22 (July 12, 2016):

  o Export "crashkernel-base" and "crashkernel-size" via device-tree,
and add some descriptions about them in chosen.txt
  o Rename "usable-memory" to "usable-memory-range" to avoid inconsistency
with powerpc's "usable-memory"
  o Make cosmetic changes regarding "ifdef" usage
  o Correct some wordings in kdump.txt

Changes for v21 (July 6, 2016):

  o Remove kexec patches.
  o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
  o Clarify the description about kvm in kdump.txt.

See the following link [3] for older changes:
[3]  http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html

AKASHI Takahiro (8):
  arm64: kdump: reserve memory for crash dump kernel
  memblock: add memblock_cap_memory_range()
  arm64: limit memory regions based on DT property, usable-memory-range
  arm64: kdump: implement machine_crash_shutdown()
  arm64: kdump: add kdump support
  arm64: kdump: add VMCOREINFO's for user-space coredump tools
  arm64: kdump: enable kdump in the arm64 defconfig
  arm64: kdump: update a kernel doc

James Morse (1):
  Documentation: dt: chosen properties for arm64 kdump

 Documentation/devicetree/bindings/chosen.txt |  45 ++
 Documentation/kdump/kdump.txt|  16 ++-
 arch/arm64/Kconfig   |  11 ++
 arch/arm64/configs/defconfig |   1 +
 arch/arm64/include/asm/hardirq.h |   2 +-
 arch/arm64/include/asm/kexec.h   |  41 +-
 arch/arm64/include/asm/smp.h |   2 +
 arch/arm64/kernel/Makefile   |   1 +
 arch/arm64/kernel/crash_dump.c   |  71 ++
 arch/arm64/kernel/machine_kexec.c|  67 -
 arch/arm64/kernel/setup.c|   7 +-
 arch/arm64/kernel/smp.c  |  63 +
 arch/arm64/mm/init.c | 202 +++
 include/linux/memblock.h |   1 +
 mm/memblock.c|  28 
 15 files changed, 551 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm64/kernel/crash_dump.c

-- 
2.9.0


AKASHI Takahiro (6):
  arm64: kdump: reserve memory for crash dump kernel
  arm64: kdump: implement machine_crash_shutdown()
  arm64: kdump: add kdump support
  arm64: kdump: add VMCOREINFO's for user-space coredump tools
  arm64: kdump: enable kdump in the arm64 defconfig
  arm64: kdump: update a kernel doc

James Morse (1):
  Documentation: dt: chosen properties for arm64 kdump

 Documentation/devicetree/bindings/chosen.txt |  30 +
 Documentation/kdump/kdump.txt|  16 ++-
 arch/arm64/Kconfig   |  11 ++
 arch/arm64/configs/defconfig |   1 +
 arch/arm64/include/asm/hardirq.h   

Re: [PATCH v4 3/5] kexec_file: Allow skipping checksum calculation for some segments.

2016-09-06 Thread Eric W. Biederman
Thiago Jung Bauermann  writes:

2> Add skip_checksum member to struct kexec_buf to specify whether the
> corresponding segment should be part of the checksum calculation.
>
> The next patch will add a way to update segments after a kimage is loaded.
> Segments that will be updated in this way should not be checksummed,
> otherwise they will cause the purgatory checksum verification to fail
> when the machine is rebooted.
>
> As a bonus, we don't need to special-case the purgatory segment anymore
> to avoid checksumming it.
>
> Places using struct kexec_buf get false as the default value for
> skip_checksum since they all use designated initializers.  Therefore,
> there is no behavior change with this patch and all segments except the
> purgatory are checksummed.

What is the world.  This fundamentally makes kexec unsafe to use.  If
any updates need to be made they should be made before they are part of
the entire image checksum.

No way should this be merged anywhere ever.

Nacked-by: "Eric W. Biederman" 

>
> Signed-off-by: Thiago Jung Bauermann 
> ---
>  include/linux/kexec.h | 23 ++-
>  kernel/kexec_file.c   | 15 +++
>  2 files changed, 21 insertions(+), 17 deletions(-)
>
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 16561e96a6d7..edadff6c86ff 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -100,6 +100,9 @@ struct kexec_segment {
>   size_t bufsz;
>   unsigned long mem;
>   size_t memsz;
> +
> + /* Whether this segment is ignored in the checksum calculation. */
> + bool skip_checksum;
>  };
>  
>  #ifdef CONFIG_COMPAT
> @@ -151,15 +154,16 @@ struct kexec_file_ops {
>  
>  /**
>   * 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.
> + * @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.
> + * @skip_checksum:   Don't verify checksum for this buffer in purgatory.
>   */
>  struct kexec_buf {
>   struct kimage *image;
> @@ -171,6 +175,7 @@ struct kexec_buf {
>   unsigned long buf_min;
>   unsigned long buf_max;
>   bool top_down;
> + bool skip_checksum;
>  };
>  
>  int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index f5684adfad07..0e90d1446cb0 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -584,6 +584,7 @@ int kexec_add_buffer(struct kexec_buf *kbuf)
>   ksegment->bufsz = kbuf->bufsz;
>   ksegment->mem = kbuf->mem;
>   ksegment->memsz = kbuf->memsz;
> + ksegment->skip_checksum = kbuf->skip_checksum;
>   kbuf->image->nr_segments++;
>   return 0;
>  }
> @@ -598,7 +599,6 @@ static int kexec_calculate_store_digests(struct kimage 
> *image)
>   char *digest;
>   void *zero_buf;
>   struct kexec_sha_region *sha_regions;
> - struct purgatory_info *pi = >purgatory_info;
>  
>   zero_buf = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT);
>   zero_buf_sz = PAGE_SIZE;
> @@ -638,11 +638,7 @@ static int kexec_calculate_store_digests(struct kimage 
> *image)
>   struct kexec_segment *ksegment;
>  
>   ksegment = >segment[i];
> - /*
> -  * Skip purgatory as it will be modified once we put digest
> -  * info in purgatory.
> -  */
> - if (ksegment->kbuf == pi->purgatory_buf)
> + if (ksegment->skip_checksum)
>   continue;
>  
>   ret = crypto_shash_update(desc, ksegment->kbuf,
> @@ -714,7 +710,7 @@ static int __kexec_load_purgatory(struct kimage *image, 
> unsigned long min,
>   Elf_Shdr *sechdrs = NULL;
>   struct kexec_buf kbuf = { .image = image, .bufsz = 0, .buf_align = 1,
> .buf_min = min, .buf_max = max,
> -   .top_down = top_down };
> +   

Re: [PATCH v24 0/9] arm64: add kdump support

2016-09-06 Thread Marc Zyngier
On 06/09/16 17:15, Manish Jaggi wrote:
> 
>>> In my setup the GICD_CTRL[RWP] bit is not cleared in the
>>> crashkernels' distributor init function.
>>
>> Which instance is failing? The initial one (just after the initial
>> disable)? Or the one called from gic_dist_config()?
>>
> In crash kernel, when the GICD_CTRL is set to 0x0, RWP is not getting clear.
> And is never cleared for any subsequent writes.

That's weird. It means writes are still pending, and never drained. What
happens if you put a dsb(sy) in the wait_for_rwp() loop?

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...

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


Re: [PATCH v24 0/9] arm64: add kdump support

2016-09-06 Thread Manish Jaggi


On 09/06/2016 09:03 PM, Marc Zyngier wrote:
> On 05/09/16 13:42, Manish Jaggi wrote:
>>
>>
>> On 09/05/2016 01:45 PM, AKASHI Takahiro wrote:
>>> [Cc: Marc]
>>>
>>> On Fri, Sep 02, 2016 at 06:23:25PM +0530, Manish Jaggi wrote:


 On 08/31/2016 11:01 AM, AKASHI Takahiro wrote:
> Manish,
>
> Thank you for testing my kdump and reporting issues.
>
> On Wed, Aug 31, 2016 at 09:11:52AM +0530, Manish Jaggi wrote:
>> Hi Akashi,
>>
>> On 08/09/2016 07:22 AM, AKASHI Takahiro wrote:
>>> This patch series adds kdump support on arm64.
>>>
>>> To load a crash-dump kernel to the systems, a series of patches to
>>> kexec-tools, which have not yet been merged upstream, are needed.
>>> Please use my kdump patches [1].
>>>
>>> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
>>>   - crash utility (coming v7.1.6 or later) [2]
>>> (Necessary patches have already been queued in the master.)
>>>
>>> [1] T.B.D.
>>> [2] https://github.com/crash-utility/crash.git
>>>
>>> Changes for v24 (Aug 9, 2016):
>>>   o Rebase to Linux-4.8-rc1
>>>   o Update descriptions about newly added DT proerties
>>>
>>> Changes for v23 (July 26, 2016):
>>>
>>>   o Move memblock_reserve() to a single place in reserve_crashkernel()
>>>   o Use  cpu_park_loop() in ipi_cpu_crash_stop()
>>>   o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash 
>>> kernel
>>>   o Re-implement fdt_enforce_memory_region() to remove non-reserve 
>>> regions
>>> (for ACPI) from usable memory at crash kernel
>>>
>>> Changes for v22 (July 12, 2016):
>>>
>>>   o Export "crashkernel-base" and "crashkernel-size" via device-tree,
>>> and add some descriptions about them in chosen.txt
>>>   o Rename "usable-memory" to "usable-memory-range" to avoid 
>>> inconsistency
>>> with powerpc's "usable-memory"
>>>   o Make cosmetic changes regarding "ifdef" usage
>>>   o Correct some wordings in kdump.txt
>>>
>>> Changes for v21 (July 6, 2016):
>>>
>>>   o Remove kexec patches.
>>>   o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
>>>   o Clarify the description about kvm in kdump.txt.
>>>
>>> See the following link [3] for older changes:
>>> [3]  
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html
>>>
>>> AKASHI Takahiro (8):
>>>   arm64: kdump: reserve memory for crash dump kernel
>>>   memblock: add memblock_cap_memory_range()
>>>   arm64: limit memory regions based on DT property, usable-memory-range
>>>   arm64: kdump: implement machine_crash_shutdown()
>>>   arm64: kdump: add kdump support
>>>   arm64: kdump: add VMCOREINFO's for user-space coredump tools
>>>   arm64: kdump: enable kdump in the arm64 defconfig
>>>   arm64: kdump: update a kernel doc
>>>
>>> James Morse (1):
>>>   Documentation: dt: chosen properties for arm64 kdump
>>>
>>>  Documentation/devicetree/bindings/chosen.txt |  45 ++
>>>  Documentation/kdump/kdump.txt|  16 ++-
>>>  arch/arm64/Kconfig   |  11 ++
>>>  arch/arm64/configs/defconfig |   1 +
>>>  arch/arm64/include/asm/hardirq.h |   2 +-
>>>  arch/arm64/include/asm/kexec.h   |  41 +-
>>>  arch/arm64/include/asm/smp.h |   2 +
>>>  arch/arm64/kernel/Makefile   |   1 +
>>>  arch/arm64/kernel/crash_dump.c   |  71 ++
>>>  arch/arm64/kernel/machine_kexec.c|  67 -
>>>  arch/arm64/kernel/setup.c|   7 +-
>>>  arch/arm64/kernel/smp.c  |  63 +
>>>  arch/arm64/mm/init.c | 202 
>>> +++
>>>  include/linux/memblock.h |   1 +
>>>  mm/memblock.c|  28 
>>>  15 files changed, 551 insertions(+), 7 deletions(-)
>>>  create mode 100644 arch/arm64/kernel/crash_dump.c
>>>
>> Couple of points
>> a) Just a note, while testing, the crashkernel reserved memory should be 
>> less than ARCH_LOW_ADDRESS_LIMIT (=arm64_dma_phys_limit).
>
> I think that this is a common mistake not only for kdump, but also
> for general kernels.
> Since request_standard_resources() calls alloc_bootmem_low(),
> the kernel will panic if any of usable "System RAM" is located
> above ARCH_LOW_ADDRESS_LIMIT.
> For kdump, using "crashkernel=SS" notation is a convenient way
> to avoid this issue.
>
>> b) Has anyone tested this on a SoC with Gicv3 ITS ?
>> Should the GICD/R be reset prior to switching to crash kernel ?
>> I am seeing lot of GICv3: RWP timeout, gone fishing while crash kernel 
>> boots.
>

Re: [PATCH v24 0/9] arm64: add kdump support

2016-09-06 Thread Marc Zyngier
On 05/09/16 13:42, Manish Jaggi wrote:
> 
> 
> On 09/05/2016 01:45 PM, AKASHI Takahiro wrote:
>> [Cc: Marc]
>>
>> On Fri, Sep 02, 2016 at 06:23:25PM +0530, Manish Jaggi wrote:
>>>
>>>
>>> On 08/31/2016 11:01 AM, AKASHI Takahiro wrote:
 Manish,

 Thank you for testing my kdump and reporting issues.

 On Wed, Aug 31, 2016 at 09:11:52AM +0530, Manish Jaggi wrote:
> Hi Akashi,
>
> On 08/09/2016 07:22 AM, AKASHI Takahiro wrote:
>> This patch series adds kdump support on arm64.
>>
>> To load a crash-dump kernel to the systems, a series of patches to
>> kexec-tools, which have not yet been merged upstream, are needed.
>> Please use my kdump patches [1].
>>
>> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
>>   - crash utility (coming v7.1.6 or later) [2]
>> (Necessary patches have already been queued in the master.)
>>
>> [1] T.B.D.
>> [2] https://github.com/crash-utility/crash.git
>>
>> Changes for v24 (Aug 9, 2016):
>>   o Rebase to Linux-4.8-rc1
>>   o Update descriptions about newly added DT proerties
>>
>> Changes for v23 (July 26, 2016):
>>
>>   o Move memblock_reserve() to a single place in reserve_crashkernel()
>>   o Use  cpu_park_loop() in ipi_cpu_crash_stop()
>>   o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash 
>> kernel
>>   o Re-implement fdt_enforce_memory_region() to remove non-reserve 
>> regions
>> (for ACPI) from usable memory at crash kernel
>>
>> Changes for v22 (July 12, 2016):
>>
>>   o Export "crashkernel-base" and "crashkernel-size" via device-tree,
>> and add some descriptions about them in chosen.txt
>>   o Rename "usable-memory" to "usable-memory-range" to avoid 
>> inconsistency
>> with powerpc's "usable-memory"
>>   o Make cosmetic changes regarding "ifdef" usage
>>   o Correct some wordings in kdump.txt
>>
>> Changes for v21 (July 6, 2016):
>>
>>   o Remove kexec patches.
>>   o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
>>   o Clarify the description about kvm in kdump.txt.
>>
>> See the following link [3] for older changes:
>> [3]  
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html
>>
>> AKASHI Takahiro (8):
>>   arm64: kdump: reserve memory for crash dump kernel
>>   memblock: add memblock_cap_memory_range()
>>   arm64: limit memory regions based on DT property, usable-memory-range
>>   arm64: kdump: implement machine_crash_shutdown()
>>   arm64: kdump: add kdump support
>>   arm64: kdump: add VMCOREINFO's for user-space coredump tools
>>   arm64: kdump: enable kdump in the arm64 defconfig
>>   arm64: kdump: update a kernel doc
>>
>> James Morse (1):
>>   Documentation: dt: chosen properties for arm64 kdump
>>
>>  Documentation/devicetree/bindings/chosen.txt |  45 ++
>>  Documentation/kdump/kdump.txt|  16 ++-
>>  arch/arm64/Kconfig   |  11 ++
>>  arch/arm64/configs/defconfig |   1 +
>>  arch/arm64/include/asm/hardirq.h |   2 +-
>>  arch/arm64/include/asm/kexec.h   |  41 +-
>>  arch/arm64/include/asm/smp.h |   2 +
>>  arch/arm64/kernel/Makefile   |   1 +
>>  arch/arm64/kernel/crash_dump.c   |  71 ++
>>  arch/arm64/kernel/machine_kexec.c|  67 -
>>  arch/arm64/kernel/setup.c|   7 +-
>>  arch/arm64/kernel/smp.c  |  63 +
>>  arch/arm64/mm/init.c | 202 
>> +++
>>  include/linux/memblock.h |   1 +
>>  mm/memblock.c|  28 
>>  15 files changed, 551 insertions(+), 7 deletions(-)
>>  create mode 100644 arch/arm64/kernel/crash_dump.c
>>
> Couple of points
> a) Just a note, while testing, the crashkernel reserved memory should be 
> less than ARCH_LOW_ADDRESS_LIMIT (=arm64_dma_phys_limit).

 I think that this is a common mistake not only for kdump, but also
 for general kernels.
 Since request_standard_resources() calls alloc_bootmem_low(),
 the kernel will panic if any of usable "System RAM" is located
 above ARCH_LOW_ADDRESS_LIMIT.
 For kdump, using "crashkernel=SS" notation is a convenient way
 to avoid this issue.

> b) Has anyone tested this on a SoC with Gicv3 ITS ?
> Should the GICD/R be reset prior to switching to crash kernel ?
> I am seeing lot of GICv3: RWP timeout, gone fishing while crash kernel 
> boots.

 I've never seen this kind of messages.
 I usually do my testing on a fast model.
 "compatible" of interrupt-controller is "arm,gic-v3."

>>> I 

[PATCH v3 6/9] ima: store the builtin/custom template definitions in a list

2016-09-06 Thread Mimi Zohar
The builtin and single custom templates are currently stored in an
array.  In preparation for being able to restore a measurement list
containing multiple builtin/custom templates, this patch stores the
builtin and custom templates as a linked list.  This will permit
defining more than one custom template per boot.

Changelog v2:
- fix lookup_template_desc() preemption imbalance (kernel test robot)

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/ima.h  |  2 ++
 security/integrity/ima/ima_main.c |  1 +
 security/integrity/ima/ima_template.c | 43 +++
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 634d140..e8303c9 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -81,6 +81,7 @@ struct ima_template_field {
 
 /* IMA template descriptor definition */
 struct ima_template_desc {
+   struct list_head list;
char *name;
char *fmt;
int num_fields;
@@ -136,6 +137,7 @@ int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_measurements_show(struct seq_file *m, void *v);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
+void ima_init_template_list(void);
 
 #ifdef CONFIG_KEXEC_FILE
 void ima_load_kexec_buffer(void);
diff --git a/security/integrity/ima/ima_main.c 
b/security/integrity/ima/ima_main.c
index 596ef61..592f318 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -418,6 +418,7 @@ static int __init init_ima(void)
 {
int error;
 
+   ima_init_template_list();
hash_setup(CONFIG_IMA_DEFAULT_HASH);
error = ima_init();
if (!error) {
diff --git a/security/integrity/ima/ima_template.c 
b/security/integrity/ima/ima_template.c
index 7c90075..e1f9ce7 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -15,16 +15,20 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include 
 #include "ima.h"
 #include "ima_template_lib.h"
 
-static struct ima_template_desc defined_templates[] = {
+static struct ima_template_desc builtin_templates[] = {
{.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
{.name = "ima-ng", .fmt = "d-ng|n-ng"},
{.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
{.name = "", .fmt = ""},/* placeholder for a custom format */
 };
 
+static LIST_HEAD(defined_templates);
+spinlock_t template_list;
+
 static struct ima_template_field supported_fields[] = {
{.field_id = "d", .field_init = ima_eventdigest_init,
 .field_show = ima_show_template_digest},
@@ -81,7 +85,7 @@ __setup("ima_template=", ima_template_setup);
 
 static int __init ima_template_fmt_setup(char *str)
 {
-   int num_templates = ARRAY_SIZE(defined_templates);
+   int num_templates = ARRAY_SIZE(builtin_templates);
 
if (ima_template)
return 1;
@@ -92,22 +96,28 @@ static int __init ima_template_fmt_setup(char *str)
return 1;
}
 
-   defined_templates[num_templates - 1].fmt = str;
-   ima_template = defined_templates + num_templates - 1;
+   builtin_templates[num_templates - 1].fmt = str;
+   ima_template = builtin_templates + num_templates - 1;
+
return 1;
 }
 __setup("ima_template_fmt=", ima_template_fmt_setup);
 
 static struct ima_template_desc *lookup_template_desc(const char *name)
 {
-   int i;
+   struct ima_template_desc *template_desc;
+   int found = 0;
 
-   for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
-   if (strcmp(defined_templates[i].name, name) == 0)
-   return defined_templates + i;
+   rcu_read_lock();
+   list_for_each_entry_rcu(template_desc, _templates, list) {
+   if ((strcmp(template_desc->name, name) == 0) ||
+   (strcmp(template_desc->fmt, name) == 0)) {
+   found = 1;
+   break;
+   }
}
-
-   return NULL;
+   rcu_read_unlock();
+   return found ? template_desc : NULL;
 }
 
 static struct ima_template_field *lookup_template_field(const char *field_id)
@@ -183,6 +193,19 @@ static int template_desc_init_fields(const char 
*template_fmt,
return 0;
 }
 
+void __init ima_init_template_list(void)
+{
+   int i;
+
+   spin_lock(_list);
+   for (i = 0; i < ARRAY_SIZE(builtin_templates); i++) {
+   list_add_tail_rcu(_templates[i].list,
+ _templates);
+   }
+   spin_unlock(_list);
+   synchronize_rcu();
+}
+
 struct ima_template_desc *ima_template_desc_current(void)
 {
if (!ima_template)
-- 
2.1.0


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


[PATCH v3 8/9] ima: define a canonical binary_runtime_measurements list format

2016-09-06 Thread Mimi Zohar
The IMA binary_runtime_measurements list is currently in platform native
format.

To allow restoring a measurement list carried across kexec with a
different endianness than the targeted kernel, this patch defines
little-endian as the canonical format.  For big endian systems wanting
to save/restore the measurement list from a system with a different
endianness, a new boot command line parameter named "ima_canonical_fmt"
is defined.

Considerations: use of the "ima_canonical_fmt" boot command line
option will break existing userspace applications on big endian systems
expecting the binary_runtime_measurements list to be in platform native
format.

Changelog v3:
- restore PCR value properly

Signed-off-by: Mimi Zohar 
---
 Documentation/kernel-parameters.txt   |  4 
 security/integrity/ima/ima.h  |  6 ++
 security/integrity/ima/ima_fs.c   | 28 +---
 security/integrity/ima/ima_kexec.c| 11 +--
 security/integrity/ima/ima_template.c | 24 ++--
 security/integrity/ima/ima_template_lib.c |  7 +--
 6 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 46c030a..5e8037fc 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1580,6 +1580,10 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
The builtin appraise policy appraises all files
owned by uid=0.
 
+   ima_canonical_fmt [IMA]
+   Use the canonical format for the binary runtime
+   measurements, instead of host native format.
+
ima_hash=   [IMA]
Format: { md5 | sha1 | rmd160 | sha256 | sha384
   | sha512 | ... }
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e8303c9..eb0f4dd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -112,6 +112,12 @@ struct ima_kexec_hdr {
u64 count;
 };
 
+/*
+ * The default binary_runtime_measurements list format is defined as the
+ * platform native format.  The canonical format is defined as little-endian.
+ */
+extern bool ima_canonical_fmt;
+
 /* Internal IMA function definitions */
 int ima_init(void);
 int ima_fs_init(void);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 66e5dd5..2bcad99 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -28,6 +28,16 @@
 
 static DEFINE_MUTEX(ima_write_mutex);
 
+bool ima_canonical_fmt;
+static int __init default_canonical_fmt_setup(char *str)
+{
+#ifdef __BIG_ENDIAN
+   ima_canonical_fmt = 1;
+#endif
+   return 1;
+}
+__setup("ima_canonical_fmt", default_canonical_fmt_setup);
+
 static int valid_policy = 1;
 #define TMPBUFLEN 12
 static ssize_t ima_show_htable_value(char __user *buf, size_t count,
@@ -122,7 +132,7 @@ int ima_measurements_show(struct seq_file *m, void *v)
struct ima_queue_entry *qe = v;
struct ima_template_entry *e;
char *template_name;
-   int namelen;
+   u32 pcr, namelen, template_data_len; /* temporary fields */
bool is_ima_template = false;
int i;
 
@@ -139,25 +149,29 @@ int ima_measurements_show(struct seq_file *m, void *v)
 * PCR used defaults to the same (config option) in
 * little-endian format, unless set in policy
 */
-   ima_putc(m, >pcr, sizeof(e->pcr));
+   pcr = !ima_canonical_fmt ? e->pcr : cpu_to_le32(e->pcr);
+   ima_putc(m, , sizeof(e->pcr));
 
/* 2nd: template digest */
ima_putc(m, e->digest, TPM_DIGEST_SIZE);
 
/* 3rd: template name size */
-   namelen = strlen(template_name);
+   namelen = !ima_canonical_fmt ? strlen(template_name) :
+   cpu_to_le32(strlen(template_name));
ima_putc(m, , sizeof(namelen));
 
/* 4th:  template name */
-   ima_putc(m, template_name, namelen);
+   ima_putc(m, template_name, strlen(template_name));
 
/* 5th:  template length (except for 'ima' template) */
if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
is_ima_template = true;
 
-   if (!is_ima_template)
-   ima_putc(m, >template_data_len,
-sizeof(e->template_data_len));
+   if (!is_ima_template) {
+   template_data_len = !ima_canonical_fmt ? e->template_data_len :
+   cpu_to_le32(e->template_data_len);
+   ima_putc(m, _data_len, sizeof(e->template_data_len));
+   }
 
/* 6th:  template specific data */
for (i = 0; i < e->template_desc->num_fields; i++) {
diff --git a/security/integrity/ima/ima_kexec.c 
b/security/integrity/ima/ima_kexec.c
index 04a2e71..a76647e 100644
--- 

[PATCH v3 4/9] ima: serialize the binary_runtime_measurements

2016-09-06 Thread Mimi Zohar
The TPM PCRs are only reset on a hard reboot.  In order to validate a
TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
of the running kernel must be saved and restored on boot.  This patch
serializes the IMA measurement list in the binary_runtime_measurements
format.

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/ima.h   |  1 +
 security/integrity/ima/ima_fs.c|  2 +-
 security/integrity/ima/ima_kexec.c | 51 ++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index f9cd08e..634d140 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -133,6 +133,7 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 
size);
 struct ima_template_desc *ima_template_desc_current(void);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
+int ima_measurements_show(struct seq_file *m, void *v);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
 
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index c07a384..66e5dd5 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -116,7 +116,7 @@ void ima_putc(struct seq_file *m, void *data, int datalen)
  *   [eventdata length]
  *   eventdata[n]=template specific data
  */
-static int ima_measurements_show(struct seq_file *m, void *v)
+int ima_measurements_show(struct seq_file *m, void *v)
 {
/* the list never shrinks, so we don't need a lock here */
struct ima_queue_entry *qe = v;
diff --git a/security/integrity/ima/ima_kexec.c 
b/security/integrity/ima/ima_kexec.c
index 6a046ad..e77ca9d 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -23,6 +23,57 @@
 
 #include "ima.h"
 
+static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
+unsigned long segment_size)
+{
+   struct ima_queue_entry *qe;
+   struct seq_file file;
+   struct ima_kexec_hdr khdr = {
+   .version = 1, .buffer_size = 0, .count = 0};
+   int ret = 0;
+
+   /* segment size can't change between kexec load and execute */
+   file.buf = vmalloc(segment_size);
+   if (!file.buf) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   file.size = segment_size;
+   file.read_pos = 0;
+   file.count = sizeof(khdr);  /* reserved space */
+
+   list_for_each_entry_rcu(qe, _measurements, later) {
+   if (file.count < file.size) {
+   khdr.count++;
+   ima_measurements_show(, qe);
+   } else {
+   ret = -EINVAL;
+   break;
+   }
+   }
+
+   if (ret < 0)
+   goto out;
+
+   /*
+* fill in reserved space with some buffer details
+* (eg. version, buffer size, number of measurements)
+*/
+   khdr.buffer_size = file.count;
+   memcpy(file.buf, , sizeof(khdr));
+   print_hex_dump(KERN_DEBUG, "ima dump: ", DUMP_PREFIX_NONE,
+   16, 1, file.buf,
+   file.count < 100 ? file.count : 100, true);
+
+   *buffer_size = file.count;
+   *buffer = file.buf;
+out:
+   if (ret == -EINVAL)
+   vfree(file.buf);
+   return ret;
+}
+
 /*
  * Restore the measurement list from the previous kernel.
  */
-- 
2.1.0


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


[PATCH v3 9/9] ima: platform-independent hash value

2016-09-06 Thread Mimi Zohar
From: Andreas Steffen 

For remote attestion it is important for the ima measurement values
to be platform-independent. Therefore integer fields to be hashed
must be converted to canonical format.

Changelog:
- Define canonical format as little endian (Mimi)

Signed-off-by: Andreas Steffen 
Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/ima_crypto.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/security/integrity/ima/ima_crypto.c 
b/security/integrity/ima/ima_crypto.c
index 38f2ed8..802d5d2 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -477,11 +477,13 @@ static int ima_calc_field_array_hash_tfm(struct 
ima_field_data *field_data,
u8 buffer[IMA_EVENT_NAME_LEN_MAX + 1] = { 0 };
u8 *data_to_hash = field_data[i].data;
u32 datalen = field_data[i].len;
+   u32 datalen_to_hash =
+   !ima_canonical_fmt ? datalen : cpu_to_le32(datalen);
 
if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
rc = crypto_shash_update(shash,
-   (const u8 *) _data[i].len,
-   sizeof(field_data[i].len));
+   (const u8 *) _to_hash,
+   sizeof(datalen_to_hash));
if (rc)
break;
} else if (strcmp(td->fields[i]->field_id, "n") == 0) {
-- 
2.1.0


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


[PATCH v3 2/9] ima: permit duplicate measurement list entries

2016-09-06 Thread Mimi Zohar
Measurements carried across kexec need to be added to the IMA
measurement list, but should not prevent measurements of the newly
booted kernel from being added to the measurement list. This patch
adds support for allowing duplicate measurements.

The "boot_aggregate" measurement entry is the delimiter between soft
boots.

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/ima_queue.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima_queue.c 
b/security/integrity/ima/ima_queue.c
index 4b1bb77..12d1b04 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -65,11 +65,12 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 
*digest_value,
 }
 
 /* ima_add_template_entry helper function:
- * - Add template entry to measurement list and hash table.
+ * - Add template entry to the measurement list and hash table, for
+ *   all entries except those carried across kexec.
  *
  * (Called with ima_extend_list_mutex held.)
  */
-static int ima_add_digest_entry(struct ima_template_entry *entry)
+static int ima_add_digest_entry(struct ima_template_entry *entry, int flags)
 {
struct ima_queue_entry *qe;
unsigned int key;
@@ -85,8 +86,10 @@ static int ima_add_digest_entry(struct ima_template_entry 
*entry)
list_add_tail_rcu(>later, _measurements);
 
atomic_long_inc(_htable.len);
-   key = ima_hash_key(entry->digest);
-   hlist_add_head_rcu(>hnext, _htable.queue[key]);
+   if (flags) {
+   key = ima_hash_key(entry->digest);
+   hlist_add_head_rcu(>hnext, _htable.queue[key]);
+   }
return 0;
 }
 
@@ -126,7 +129,7 @@ int ima_add_template_entry(struct ima_template_entry 
*entry, int violation,
}
}
 
-   result = ima_add_digest_entry(entry);
+   result = ima_add_digest_entry(entry, 1);
if (result < 0) {
audit_cause = "ENOMEM";
audit_info = 0;
@@ -155,7 +158,7 @@ int ima_restore_measurement_entry(struct ima_template_entry 
*entry)
int result = 0;
 
mutex_lock(_extend_list_mutex);
-   result = ima_add_digest_entry(entry);
+   result = ima_add_digest_entry(entry, 0);
mutex_unlock(_extend_list_mutex);
return result;
 }
-- 
2.1.0


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


[PATCH v3 3/9] ima: maintain memory size needed for serializing the measurement list

2016-09-06 Thread Mimi Zohar
In preparation for serializing the binary_runtime_measurements, this patch
maintains the amount of memory required.

Changelog v3:
- include the ima_kexec_hdr size in the binary_runtime_measurement size.

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/Kconfig | 12 +
 security/integrity/ima/ima.h   |  1 +
 security/integrity/ima/ima_queue.c | 53 --
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 5487827..1c5a1c2 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -27,6 +27,18 @@ config IMA
  to learn more about IMA.
  If unsure, say N.
 
+config IMA_KEXEC
+   bool "Enable carrying the IMA measurement list across a soft boot"
+   depends on IMA && TCG_TPM && KEXEC_FILE
+   default n
+   help
+  TPM PCRs are only reset on a hard reboot.  In order to validate
+  a TPM's quote after a soft boot, the IMA measurement list of the
+  running kernel must be saved and restored on boot.
+
+  Depending on the IMA policy, the measurement list can grow to
+  be very large.
+
 config IMA_MEASURE_PCR_IDX
int
depends on IMA
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e7b3755..f9cd08e 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -133,6 +133,7 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 
size);
 struct ima_template_desc *ima_template_desc_current(void);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
+unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
 
 #ifdef CONFIG_KEXEC_FILE
diff --git a/security/integrity/ima/ima_queue.c 
b/security/integrity/ima/ima_queue.c
index 12d1b04..3a3cc2a 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -29,6 +29,11 @@
 #define AUDIT_CAUSE_LEN_MAX 32
 
 LIST_HEAD(ima_measurements);   /* list of all measurements */
+#ifdef CONFIG_IMA_KEXEC
+static unsigned long binary_runtime_size;
+#else
+static unsigned long binary_runtime_size = ULONG_MAX;
+#endif
 
 /* key: inode (before secure-hashing a file) */
 struct ima_h_table ima_htable = {
@@ -64,6 +69,24 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 
*digest_value,
return ret;
 }
 
+/*
+ * Calculate the memory required for serializing a single
+ * binary_runtime_measurement list entry, which contains a
+ * couple of variable length fields (e.g template name and data).
+ */
+static int get_binary_runtime_size(struct ima_template_entry *entry)
+{
+   int size = 0;
+
+   size += sizeof(u32);/* pcr */
+   size += sizeof(entry->digest);
+   size += sizeof(int);/* template name size field */
+   size += strlen(entry->template_desc->name);
+   size += sizeof(entry->template_data_len);
+   size += entry->template_data_len;
+   return size;
+}
+
 /* ima_add_template_entry helper function:
  * - Add template entry to the measurement list and hash table, for
  *   all entries except those carried across kexec.
@@ -90,9 +113,30 @@ static int ima_add_digest_entry(struct ima_template_entry 
*entry, int flags)
key = ima_hash_key(entry->digest);
hlist_add_head_rcu(>hnext, _htable.queue[key]);
}
+
+   if (binary_runtime_size != ULONG_MAX) {
+   int size;
+
+   size = get_binary_runtime_size(entry);
+   binary_runtime_size = (binary_runtime_size < ULONG_MAX - size) ?
+binary_runtime_size + size : ULONG_MAX;
+   }
return 0;
 }
 
+/*
+ * Return the amount of memory required for serializing the
+ * entire binary_runtime_measurement list, including the ima_kexec_hdr
+ * structure.
+ */
+unsigned long ima_get_binary_runtime_size(void)
+{
+   if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr)))
+   return ULONG_MAX;
+   else
+   return binary_runtime_size + sizeof(struct ima_kexec_hdr);
+};
+
 static int ima_pcr_extend(const u8 *hash, int pcr)
 {
int result = 0;
@@ -106,8 +150,13 @@ static int ima_pcr_extend(const u8 *hash, int pcr)
return result;
 }
 
-/* Add template entry to the measurement list and hash table,
- * and extend the pcr.
+/*
+ * Add template entry to the measurement list and hash table, and
+ * extend the pcr.
+ *
+ * On systems which support carrying the IMA measurement list across
+ * kexec, maintain the total memory size required for serializing the
+ * binary_runtime_measurements.
  */
 int ima_add_template_entry(struct ima_template_entry *entry, int violation,
   const char *op, struct inode *inode,
-- 
2.1.0


___
kexec 

[PATCH v3 0/9] ima: carry the measurement list across kexec

2016-09-06 Thread Mimi Zohar
The TPM PCRs are only reset on a hard reboot.  In order to validate a
TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
of the running kernel must be saved and then restored on the subsequent
boot, possibly of a different architecture.

The existing securityfs binary_runtime_measurements file conveniently
provides a serialized format of the IMA measurement list. This patch
set serializes the measurement list in this format and restores it.

Up to now, the binary_runtime_measurements was defined as architecture
native format.  The assumption being that userspace could and would
handle any architecture conversions.  With the ability of carrying the
measurement list across kexec, possibly from one architecture to a
different one, the per boot architecture information is lost and with it
the ability of recalculating the template digest hash.  To resolve this
problem, without breaking the existing ABI, this patch set introduces
the boot command line option "ima_canonical_fmt", which is arbitrarily
defined as little endian.

The need for this boot command line option will be limited to the
existing version 1 format of the binary_runtime_measurements.
Subsequent formats will be defined as canonical format (eg. TPM 2.0
support for larger digests).

This patch set pre-req's Thiago Bauermann's "kexec_file: Add buffer
hand-over for the next kernel" patch set. 

These patches can also be found in the next-kexec-restore branch of:
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git

Changelog v3:
- Cleaned up the code for calculating the requested kexec segment size
needed for the IMA measurement list, limiting the segment size to half
of the totalram_pages.
- Fixed kernel test robot reports as enumerated in the respective
patch changelog.

Changelog v2:
- Canonical measurement list support added
- Redefined the ima_kexec_hdr struct to use well defined sizes

Mimi

Andreas Steffen (1):
  ima: platform-independent hash value

Mimi Zohar (7):
  ima: on soft reboot, restore the measurement list
  ima: permit duplicate measurement list entries
  ima: maintain memory size needed for serializing the measurement list
  ima: serialize the binary_runtime_measurements
  ima: store the builtin/custom template definitions in a list
  ima: support restoring multiple template formats
  ima: define a canonical binary_runtime_measurements list format

Thiago Jung Bauermann (1):
  ima: on soft reboot, save the measurement list

 Documentation/kernel-parameters.txt   |   4 +
 include/linux/ima.h   |  12 ++
 kernel/kexec_file.c   |   4 +
 security/integrity/ima/Kconfig|  12 ++
 security/integrity/ima/Makefile   |   1 +
 security/integrity/ima/ima.h  |  28 +++
 security/integrity/ima/ima_crypto.c   |   6 +-
 security/integrity/ima/ima_fs.c   |  30 ++-
 security/integrity/ima/ima_init.c |   2 +
 security/integrity/ima/ima_kexec.c| 209 +
 security/integrity/ima/ima_main.c |   1 +
 security/integrity/ima/ima_queue.c|  76 +++-
 security/integrity/ima/ima_template.c | 293 --
 security/integrity/ima/ima_template_lib.c |   7 +-
 14 files changed, 653 insertions(+), 32 deletions(-)
 create mode 100644 security/integrity/ima/ima_kexec.c

-- 
2.1.0


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


[PATCH] Cleanup: Use a negative number for uninitialized file descriptors

2016-09-06 Thread Petr Tesarik
Do not use zero to denote an invalid file descriptor.

First, zero is a valid value, although quite unlikely to be used for
anything except standard input.

Second, open(2) returns a negative value on failure, so there are
already checks for a negative value in some places.

The purpose of this patch is not to allow running in an evil environment
(with closed stdin), but to aid in debugging by using a consistent value
for uninitialized file descriptors which is also regarded as invalid by
the kernel. For example, attempts to close a negative FD will fail
(unlike an attempt to close FD 0).

Signed-off-by: Petr Tesarik 
---
 makedumpfile.c | 68 +-
 makedumpfile.h |  2 +-
 2 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 21784e8..d168dfd 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -3730,10 +3730,10 @@ free_for_parallel()
return;
 
for (i = 0; i < info->num_threads; i++) {
-   if (FD_MEMORY_PARALLEL(i) > 0)
+   if (FD_MEMORY_PARALLEL(i) >= 0)
close(FD_MEMORY_PARALLEL(i));
 
-   if (FD_BITMAP_MEMORY_PARALLEL(i) > 0)
+   if (FD_BITMAP_MEMORY_PARALLEL(i) >= 0)
close(FD_BITMAP_MEMORY_PARALLEL(i));
}
 }
@@ -4038,13 +4038,13 @@ out:
 void
 initialize_bitmap(struct dump_bitmap *bitmap)
 {
-   if (info->fd_bitmap) {
+   if (info->fd_bitmap >= 0) {
bitmap->fd= info->fd_bitmap;
bitmap->file_name = info->name_bitmap;
bitmap->no_block  = -1;
memset(bitmap->buf, 0, BUFSIZE_BITMAP);
} else {
-   bitmap->fd= 0;
+   bitmap->fd= -1;
bitmap->file_name = NULL;
bitmap->no_block  = -1;
memset(bitmap->buf, 0, info->bufsize_cyclic);
@@ -4154,7 +4154,7 @@ set_bitmap_buffer(struct dump_bitmap *bitmap, mdf_pfn_t 
pfn, int val, struct cyc
 int
 set_bitmap(struct dump_bitmap *bitmap, mdf_pfn_t pfn, int val, struct cycle 
*cycle)
 {
-   if (bitmap->fd) {
+   if (bitmap->fd >= 0) {
return set_bitmap_file(bitmap, pfn, val);
} else {
return set_bitmap_buffer(bitmap, pfn, val, cycle);
@@ -4170,7 +4170,7 @@ sync_bitmap(struct dump_bitmap *bitmap)
/*
 * The bitmap doesn't have the fd, it's a on-memory bitmap.
 */
-   if (bitmap->fd == 0)
+   if (bitmap->fd < 0)
return TRUE;
/*
 * The bitmap buffer is not dirty, and it is not necessary
@@ -5403,7 +5403,7 @@ create_1st_bitmap_buffer(struct cycle *cycle)
 int
 create_1st_bitmap(struct cycle *cycle)
 {
-   if (info->bitmap1->fd) {
+   if (info->bitmap1->fd >= 0) {
return create_1st_bitmap_file();
} else {
return create_1st_bitmap_buffer(cycle);
@@ -5414,7 +5414,7 @@ static inline int
 is_in_segs(unsigned long long paddr)
 {
if (info->flag_refiltering || info->flag_sadump) {
-   if (info->bitmap1->fd == 0) {
+   if (info->bitmap1->fd < 0) {
initialize_1st_bitmap(info->bitmap1);
create_1st_bitmap_file();
}
@@ -5872,7 +5872,7 @@ copy_bitmap_file(void)
 int
 copy_bitmap(void)
 {
-   if (info->fd_bitmap) {
+   if (info->fd_bitmap >= 0) {
return copy_bitmap_file();
} else {
return copy_bitmap_buffer();
@@ -6313,7 +6313,7 @@ prepare_bitmap1_buffer(void)
return FALSE;
}
 
-   if (info->fd_bitmap) {
+   if (info->fd_bitmap >= 0) {
if ((info->bitmap1->buf = (char *)malloc(BUFSIZE_BITMAP)) == 
NULL) {
ERRMSG("Can't allocate memory for the 1st bitmaps's 
buffer. %s\n",
   strerror(errno));
@@ -6352,7 +6352,7 @@ prepare_bitmap2_buffer(void)
   strerror(errno));
return FALSE;
}
-   if (info->fd_bitmap) {
+   if (info->fd_bitmap >= 0) {
if ((info->bitmap2->buf = (char *)malloc(BUFSIZE_BITMAP)) == 
NULL) {
ERRMSG("Can't allocate memory for the 2nd bitmaps's 
buffer. %s\n",
   strerror(errno));
@@ -7582,7 +7582,7 @@ kdump_thread_function_cyclic(void *arg) {
 
fd_memory = FD_MEMORY_PARALLEL(kdump_thread_args->thread_num);
 
-   if (info->fd_bitmap) {
+   if (info->fd_bitmap >= 0) {
bitmap_parallel.buf = malloc(BUFSIZE_BITMAP);
if (bitmap_parallel.buf == NULL){
ERRMSG("Can't allocate memory for bitmap_parallel.buf. 
%s\n",
@@ -7628,7 +7628,7 @@ kdump_thread_function_cyclic(void *arg) {
pthread_mutex_lock(>current_pfn_mutex);
for (pfn = 

[PATCH v8 09/13] powerpc: Implement kexec_file_load.

2016-09-06 Thread Thiago Jung Bauermann
arch_kexec_walk_mem and arch_kexec_apply_relocations_add are used by
generic kexec code, while setup_purgatory is powerpc-specific and sets
runtime variables needed by the powerpc purgatory implementation.

Signed-off-by: Josh Sklar 
Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/Kconfig   |  13 ++
 arch/powerpc/include/asm/kexec.h   |   7 +
 arch/powerpc/include/asm/systbl.h  |   1 +
 arch/powerpc/include/asm/unistd.h  |   2 +-
 arch/powerpc/include/uapi/asm/unistd.h |   1 +
 arch/powerpc/kernel/Makefile   |   4 +-
 arch/powerpc/kernel/machine_kexec_64.c | 252 +
 7 files changed, 278 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 140a1b84019a..41300c3a1bfe 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -460,6 +460,19 @@ config KEXEC
  interface is strongly in flux, so no good recommendation can be
  made.
 
+config KEXEC_FILE
+   bool "kexec file based system call"
+   select KEXEC_CORE
+   select BUILD_BIN2C
+   depends on PPC64
+   depends on CRYPTO=y
+   depends on CRYPTO_SHA256=y
+   help
+ This is a new version of the kexec system call. This call is
+ file based and takes in file descriptors as system call arguments
+ for kernel and initramfs as opposed to a list of segments as is the
+ case for the older kexec call.
+
 config RELOCATABLE
bool "Build a relocatable kernel"
depends on (PPC64 && !COMPILE_TEST) || (FLATMEM && (44x || FSL_BOOKE))
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index eca2f975bf44..0c7e020d935a 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -91,6 +91,13 @@ static inline bool kdump_in_progress(void)
return crashing_cpu >= 0;
 }
 
+#ifdef CONFIG_KEXEC_FILE
+int setup_purgatory(struct kimage *image, const void *slave_code,
+   const void *fdt, unsigned long kernel_load_addr,
+   unsigned long fdt_load_addr, unsigned long stack_top,
+   int debug);
+#endif /* CONFIG_KEXEC_FILE */
+
 #else /* !CONFIG_KEXEC_CORE */
 static inline void crash_kexec_secondary(struct pt_regs *regs) { }
 
diff --git a/arch/powerpc/include/asm/systbl.h 
b/arch/powerpc/include/asm/systbl.h
index 2fc5d4db503c..4b369d83fe9c 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -386,3 +386,4 @@ SYSCALL(mlock2)
 SYSCALL(copy_file_range)
 COMPAT_SYS_SPU(preadv2)
 COMPAT_SYS_SPU(pwritev2)
+SYSCALL(kexec_file_load)
diff --git a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h
index cf12c580f6b2..a01e97d3f305 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
 #include 
 
 
-#define NR_syscalls382
+#define NR_syscalls383
 
 #define __NR__exit __NR_exit
 
diff --git a/arch/powerpc/include/uapi/asm/unistd.h 
b/arch/powerpc/include/uapi/asm/unistd.h
index e9f5f41aa55a..2f26335a3c42 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -392,5 +392,6 @@
 #define __NR_copy_file_range   379
 #define __NR_preadv2   380
 #define __NR_pwritev2  381
+#define __NR_kexec_file_load   382
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index fd6b7b96d93d..fef0d730acc4 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -123,9 +123,11 @@ ifneq ($(CONFIG_PPC_INDIRECT_PIO),y)
 obj-y  += iomap.o
 endif
 
-ifeq ($(CONFIG_MODULES)$(CONFIG_WORD_SIZE),y64)
+ifneq ($(CONFIG_MODULES)$(CONFIG_KEXEC_FILE),)
+ifeq ($(CONFIG_WORD_SIZE),64)
 obj-y  += elf_util.o elf_util_64.o
 endif
+endif
 
 obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM)  += tm.o
 
diff --git a/arch/powerpc/kernel/machine_kexec_64.c 
b/arch/powerpc/kernel/machine_kexec_64.c
index 4c780a342282..1e678dc5096a 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -18,6 +18,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -31,6 +33,12 @@
 #include 
 #include 
 
+#define SLAVE_CODE_SIZE256
+
+#ifdef CONFIG_KEXEC_FILE
+static struct kexec_file_ops *kexec_file_loaders[] = { };
+#endif
+
 #ifdef CONFIG_PPC_BOOK3E
 int default_machine_kexec_prepare(struct kimage *image)
 {
@@ -432,3 +440,247 @@ static int __init export_htab_values(void)
 }
 late_initcall(export_htab_values);
 #endif /* CONFIG_PPC_STD_MMU_64 */
+
+#ifdef CONFIG_KEXEC_FILE
+int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
+ unsigned long buf_len)
+{
+   int i, ret = -ENOEXEC;
+   struct kexec_file_ops *fops;
+
+   /* We 

[PATCH v8 02/13] kexec_file: Change kexec_add_buffer to take kexec_buf as argument.

2016-09-06 Thread Thiago Jung Bauermann
This is done to simplify the kexec_add_buffer argument list.
Adapt all callers to set up a kexec_buf to pass to kexec_add_buffer.

In addition, change the type of kexec_buf.buffer from char * to void *.
There is no particular reason for it to be a char *, and the change
allows us to get rid of 3 existing casts to char * in the code.

Signed-off-by: Thiago Jung Bauermann 
Acked-by: Dave Young 
Acked-by: Balbir Singh 
---
 arch/x86/kernel/crash.c   | 37 
 arch/x86/kernel/kexec-bzimage64.c | 48 +++--
 include/linux/kexec.h |  8 +---
 kernel/kexec_file.c   | 88 ++-
 4 files changed, 87 insertions(+), 94 deletions(-)

diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 9616cf76940c..38a1cdf6aa05 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -615,9 +615,9 @@ static int determine_backup_region(u64 start, u64 end, void 
*arg)
 
 int crash_load_segments(struct kimage *image)
 {
-   unsigned long src_start, src_sz, elf_sz;
-   void *elf_addr;
int ret;
+   struct kexec_buf kbuf = { .image = image, .buf_min = 0,
+ .buf_max = ULONG_MAX, .top_down = false };
 
/*
 * Determine and load a segment for backup area. First 640K RAM
@@ -631,43 +631,44 @@ int crash_load_segments(struct kimage *image)
if (ret < 0)
return ret;
 
-   src_start = image->arch.backup_src_start;
-   src_sz = image->arch.backup_src_sz;
-
/* Add backup segment. */
-   if (src_sz) {
+   if (image->arch.backup_src_sz) {
+   kbuf.buffer = _zero_bytes;
+   kbuf.bufsz = sizeof(crash_zero_bytes);
+   kbuf.memsz = image->arch.backup_src_sz;
+   kbuf.buf_align = PAGE_SIZE;
/*
 * Ideally there is no source for backup segment. This is
 * copied in purgatory after crash. Just add a zero filled
 * segment for now to make sure checksum logic works fine.
 */
-   ret = kexec_add_buffer(image, (char *)_zero_bytes,
-  sizeof(crash_zero_bytes), src_sz,
-  PAGE_SIZE, 0, -1, 0,
-  >arch.backup_load_addr);
+   ret = kexec_add_buffer();
if (ret)
return ret;
+   image->arch.backup_load_addr = kbuf.mem;
pr_debug("Loaded backup region at 0x%lx backup_start=0x%lx 
memsz=0x%lx\n",
-image->arch.backup_load_addr, src_start, src_sz);
+image->arch.backup_load_addr,
+image->arch.backup_src_start, kbuf.memsz);
}
 
/* Prepare elf headers and add a segment */
-   ret = prepare_elf_headers(image, _addr, _sz);
+   ret = prepare_elf_headers(image, , );
if (ret)
return ret;
 
-   image->arch.elf_headers = elf_addr;
-   image->arch.elf_headers_sz = elf_sz;
+   image->arch.elf_headers = kbuf.buffer;
+   image->arch.elf_headers_sz = kbuf.bufsz;
 
-   ret = kexec_add_buffer(image, (char *)elf_addr, elf_sz, elf_sz,
-   ELF_CORE_HEADER_ALIGN, 0, -1, 0,
-   >arch.elf_load_addr);
+   kbuf.memsz = kbuf.bufsz;
+   kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
+   ret = kexec_add_buffer();
if (ret) {
vfree((void *)image->arch.elf_headers);
return ret;
}
+   image->arch.elf_load_addr = kbuf.mem;
pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
-image->arch.elf_load_addr, elf_sz, elf_sz);
+image->arch.elf_load_addr, kbuf.bufsz, kbuf.bufsz);
 
return ret;
 }
diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index f2356bda2b05..4b3a75329fb6 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -331,17 +331,17 @@ static void *bzImage64_load(struct kimage *image, char 
*kernel,
 
struct setup_header *header;
int setup_sects, kern16_size, ret = 0;
-   unsigned long setup_header_size, params_cmdline_sz, params_misc_sz;
+   unsigned long setup_header_size, params_cmdline_sz;
struct boot_params *params;
unsigned long bootparam_load_addr, kernel_load_addr, initrd_load_addr;
unsigned long purgatory_load_addr;
-   unsigned long kernel_bufsz, kernel_memsz, kernel_align;
-   char *kernel_buf;
struct bzimage64_data *ldata;
struct kexec_entry64_regs regs64;
void *stack;
unsigned int setup_hdr_offset = offsetof(struct boot_params, hdr);
unsigned int efi_map_offset, efi_map_sz, efi_setup_data_offset;
+   struct 

[PATCH v8 08/13] powerpc: Add functions to read ELF files of any endianness.

2016-09-06 Thread Thiago Jung Bauermann
A little endian kernel might need to kexec a big endian kernel (the
opposite is less likely but could happen as well), so we can't just cast
the buffer with the binary to ELF structs and use them as is done
elsewhere.

This patch adds functions which do byte-swapping as necessary when
populating the ELF structs. These functions will be used in the next
patch in the series.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/include/asm/elf_util.h |  18 ++
 arch/powerpc/kernel/Makefile|   2 +-
 arch/powerpc/kernel/elf_util.c  | 476 
 3 files changed, 495 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/elf_util.h 
b/arch/powerpc/include/asm/elf_util.h
index 5a27e8ceb88a..18703d56eabd 100644
--- a/arch/powerpc/include/asm/elf_util.h
+++ b/arch/powerpc/include/asm/elf_util.h
@@ -20,7 +20,14 @@
 #include 
 
 struct elf_info {
+   /*
+* Where the ELF binary contents are kept.
+* Memory managed by the user of the struct.
+*/
+   const char *buffer;
+
const struct elfhdr *ehdr;
+   const struct elf_phdr *proghdrs;
struct elf_shdr *sechdrs;
 
/* Index of stubs section. */
@@ -64,6 +71,17 @@ static inline unsigned long my_r2(const struct elf_info 
*elf_info)
return elf_info->sechdrs[elf_info->toc_section].sh_addr + 0x8000;
 }
 
+static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
+{
+   return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
+}
+
+int elf_read_from_buffer(const char *buf, size_t len, struct elfhdr *ehdr,
+struct elf_info *elf_info);
+void elf_init_elf_info(const struct elfhdr *ehdr, struct elf_shdr *sechdrs,
+  struct elf_info *elf_info);
+void elf_free_info(struct elf_info *elf_info);
+
 int elf64_apply_relocate_add(const struct elf_info *elf_info,
 const char *strtab, const Elf64_Rela *rela,
 unsigned int num_rela, void *syms_base,
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 4ff806f6f3fd..fd6b7b96d93d 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -124,7 +124,7 @@ obj-y   += iomap.o
 endif
 
 ifeq ($(CONFIG_MODULES)$(CONFIG_WORD_SIZE),y64)
-obj-y  += elf_util_64.o
+obj-y  += elf_util.o elf_util_64.o
 endif
 
 obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM)  += tm.o
diff --git a/arch/powerpc/kernel/elf_util.c b/arch/powerpc/kernel/elf_util.c
new file mode 100644
index ..1df4a116ad90
--- /dev/null
+++ b/arch/powerpc/kernel/elf_util.c
@@ -0,0 +1,476 @@
+/*
+ * Utility functions to work with ELF files.
+ *
+ * Copyright (C) 2016, IBM Corporation
+ *
+ * Based on kexec-tools' kexec-elf.c. Heavily modified for the
+ * kernel by Thiago Jung Bauermann .
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+
+#if ELF_CLASS == ELFCLASS32
+#define elf_addr_to_cpuelf32_to_cpu
+
+#ifndef Elf_Rel
+#define Elf_RelElf32_Rel
+#endif /* Elf_Rel */
+#else /* ELF_CLASS == ELFCLASS32 */
+#define elf_addr_to_cpuelf64_to_cpu
+
+#ifndef Elf_Rel
+#define Elf_RelElf64_Rel
+#endif /* Elf_Rel */
+
+static uint64_t elf64_to_cpu(const struct elfhdr *ehdr, uint64_t value)
+{
+   if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+   value = le64_to_cpu(value);
+   else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+   value = be64_to_cpu(value);
+
+   return value;
+}
+#endif /* ELF_CLASS == ELFCLASS32 */
+
+static uint16_t elf16_to_cpu(const struct elfhdr *ehdr, uint16_t value)
+{
+   if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+   value = le16_to_cpu(value);
+   else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+   value = be16_to_cpu(value);
+
+   return value;
+}
+
+static uint32_t elf32_to_cpu(const struct elfhdr *ehdr, uint32_t value)
+{
+   if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+   value = le32_to_cpu(value);
+   else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+   value = be32_to_cpu(value);
+
+   return value;
+}
+
+/**
+ * elf_is_ehdr_sane - check that it is safe to use the ELF header
+ * @buf_len:   size of the buffer in which the ELF file is loaded.
+ */
+static bool elf_is_ehdr_sane(const struct elfhdr *ehdr, size_t buf_len)
+{
+   

[PATCH v8 01/13] kexec_file: Allow arch-specific memory walking for kexec_add_buffer

2016-09-06 Thread Thiago Jung Bauermann
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 
Acked-by: Dave Young 
Acked-by: Balbir Singh 
---
 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 d743baaa..2d6a1ab3b630 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) { }
-- 
1.9.1



[PATCH v8 04/13] powerpc: Change places using CONFIG_KEXEC to use CONFIG_KEXEC_CORE instead.

2016-09-06 Thread Thiago Jung Bauermann
Commit 2965faa5e03d ("kexec: split kexec_load syscall from kexec core
code") introduced CONFIG_KEXEC_CORE so that CONFIG_KEXEC means whether
the kexec_load system call should be compiled-in and CONFIG_KEXEC_FILE
means whether the kexec_file_load system call should be compiled-in.
These options can be set independently from each other.

Since until now powerpc only supported kexec_load, CONFIG_KEXEC and
CONFIG_KEXEC_CORE were synonyms. That is not the case anymore, so we
need to make a distinction. Almost all places where CONFIG_KEXEC was
being used should be using CONFIG_KEXEC_CORE instead, since
kexec_file_load also needs that code compiled in.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/Kconfig  | 2 +-
 arch/powerpc/include/asm/debug.h  | 2 +-
 arch/powerpc/include/asm/kexec.h  | 6 +++---
 arch/powerpc/include/asm/machdep.h| 4 ++--
 arch/powerpc/include/asm/smp.h| 2 +-
 arch/powerpc/kernel/Makefile  | 4 ++--
 arch/powerpc/kernel/head_64.S | 2 +-
 arch/powerpc/kernel/misc_32.S | 2 +-
 arch/powerpc/kernel/misc_64.S | 6 +++---
 arch/powerpc/kernel/prom.c| 2 +-
 arch/powerpc/kernel/setup_64.c| 4 ++--
 arch/powerpc/kernel/smp.c | 6 +++---
 arch/powerpc/kernel/traps.c   | 2 +-
 arch/powerpc/platforms/85xx/corenet_generic.c | 2 +-
 arch/powerpc/platforms/85xx/smp.c | 8 
 arch/powerpc/platforms/cell/spu_base.c| 2 +-
 arch/powerpc/platforms/powernv/setup.c| 6 +++---
 arch/powerpc/platforms/ps3/setup.c| 4 ++--
 arch/powerpc/platforms/pseries/Makefile   | 2 +-
 arch/powerpc/platforms/pseries/setup.c| 4 ++--
 20 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 927d2ab2ce08..140a1b84019a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -494,7 +494,7 @@ config CRASH_DUMP
 
 config FA_DUMP
bool "Firmware-assisted dump"
-   depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC
+   depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC_CORE
help
  A robust mechanism to get reliable kernel crash dump with
  assistance from firmware. This approach does not use kexec,
diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
index a954e4975049..86308f177f2d 100644
--- a/arch/powerpc/include/asm/debug.h
+++ b/arch/powerpc/include/asm/debug.h
@@ -10,7 +10,7 @@ struct pt_regs;
 
 extern struct dentry *powerpc_debugfs_root;
 
-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
+#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
 
 extern int (*__debugger)(struct pt_regs *regs);
 extern int (*__debugger_ipi)(struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index a46f5f45570c..eca2f975bf44 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -53,7 +53,7 @@
 
 typedef void (*crash_shutdown_t)(void);
 
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
 
 /*
  * This function is responsible for capturing register states if coming
@@ -91,7 +91,7 @@ static inline bool kdump_in_progress(void)
return crashing_cpu >= 0;
 }
 
-#else /* !CONFIG_KEXEC */
+#else /* !CONFIG_KEXEC_CORE */
 static inline void crash_kexec_secondary(struct pt_regs *regs) { }
 
 static inline int overlaps_crashkernel(unsigned long start, unsigned long size)
@@ -116,7 +116,7 @@ static inline bool kdump_in_progress(void)
return false;
 }
 
-#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_KEXEC_CORE */
 #endif /* ! __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KEXEC_H */
diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index 0420b388dd83..3200a4403de3 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -183,7 +183,7 @@ struct machdep_calls {
 */
void (*machine_shutdown)(void);
 
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
void (*kexec_cpu_down)(int crash_shutdown, int secondary);
 
/* Called to do what every setup is needed on image and the
@@ -198,7 +198,7 @@ struct machdep_calls {
 * no return.
 */
void (*machine_kexec)(struct kimage *image);
-#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_KEXEC_CORE */
 
 #ifdef CONFIG_SUSPEND
/* These are called to disable and enable, respectively, IRQs when
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 0d02c11dc331..32db16d2e7ad 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -176,7 +176,7 @@ static inline void set_hard_smp_processor_id(int cpu, int 
phys)
 #endif /* !CONFIG_SMP */
 #endif /* !CONFIG_PPC64 */
 
-#if defined(CONFIG_PPC64) && 

[PATCH v8 12/13] powerpc: Add purgatory for kexec_file_load implementation.

2016-09-06 Thread Thiago Jung Bauermann
This purgatory implementation comes from kexec-tools, almost unchanged.

The only changes were that the sha256_regions global variable was
renamed to sha_regions to match what kexec_file_load expects, and to
use the sha256.c file from x86's purgatory to avoid adding yet another
SHA-256 implementation.

Also, some formatting warnings found by checkpatch.pl were fixed.

In order to use boot/string.S in ppc64 big endian mode, the functions
defined in it need to have dot symbols so that they can be called
from C code. Therefore,  change the file to use a DOTSYM macro
if one is defined, so that the purgatory can add those dot symbols.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/Makefile |   1 +
 arch/powerpc/boot/string.S|  67 ++--
 arch/powerpc/purgatory/.gitignore |   2 +
 arch/powerpc/purgatory/Makefile   |  48 +
 arch/powerpc/purgatory/console-ppc64.c|  38 +++
 arch/powerpc/purgatory/crashdump-ppc64.h  |  42 
 arch/powerpc/purgatory/crashdump_backup.c |  36 +++
 arch/powerpc/purgatory/crtsavres.S|   5 +
 arch/powerpc/purgatory/hvCall.S   |  27 +
 arch/powerpc/purgatory/hvCall.h   |   8 ++
 arch/powerpc/purgatory/kexec-sha256.h |  11 ++
 arch/powerpc/purgatory/ppc64_asm.h|  20 
 arch/powerpc/purgatory/printf.c   | 164 ++
 arch/powerpc/purgatory/purgatory-ppc64.c  |  41 
 arch/powerpc/purgatory/purgatory-ppc64.h  |   6 ++
 arch/powerpc/purgatory/purgatory.c|  62 +++
 arch/powerpc/purgatory/purgatory.h|  11 ++
 arch/powerpc/purgatory/sha256.c   |   6 ++
 arch/powerpc/purgatory/sha256.h   |   1 +
 arch/powerpc/purgatory/string.S   |   2 +
 arch/powerpc/purgatory/v2wrap.S   | 134 
 21 files changed, 703 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 1934707bf321..0fb28cc8eb38 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -256,6 +256,7 @@ core-y  += arch/powerpc/kernel/ 
\
 core-$(CONFIG_XMON)+= arch/powerpc/xmon/
 core-$(CONFIG_KVM) += arch/powerpc/kvm/
 core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/
+core-$(CONFIG_KEXEC_FILE)  += arch/powerpc/purgatory/
 
 drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
 
diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S
index acc9428f2789..b54bbad5f83d 100644
--- a/arch/powerpc/boot/string.S
+++ b/arch/powerpc/boot/string.S
@@ -11,9 +11,18 @@
 
 #include "ppc_asm.h"
 
+/*
+ * The ppc64 kexec purgatory uses this file and packages it in ELF64,
+ * so it needs dot symbols for the ppc64 big endian ABI. This macro
+ * allows it to create those symbols.
+ */
+#ifndef DOTSYM
+#define DOTSYM(a)  a
+#endif
+
.text
-   .globl  strcpy
-strcpy:
+   .globl  DOTSYM(strcpy)
+DOTSYM(strcpy):
addir5,r3,-1
addir4,r4,-1
 1: lbzur0,1(r4)
@@ -22,8 +31,8 @@ strcpy:
bne 1b
blr
 
-   .globl  strncpy
-strncpy:
+   .globl  DOTSYM(strncpy)
+DOTSYM(strncpy):
cmpwi   0,r5,0
beqlr
mtctr   r5
@@ -35,8 +44,8 @@ strncpy:
bdnzf   2,1b/* dec ctr, branch if ctr != 0 && !cr0.eq */
blr
 
-   .globl  strcat
-strcat:
+   .globl  DOTSYM(strcat)
+DOTSYM(strcat):
addir5,r3,-1
addir4,r4,-1
 1: lbzur0,1(r5)
@@ -49,8 +58,8 @@ strcat:
bne 1b
blr
 
-   .globl  strchr
-strchr:
+   .globl  DOTSYM(strchr)
+DOTSYM(strchr):
addir3,r3,-1
 1: lbzur0,1(r3)
cmpw0,r0,r4
@@ -60,8 +69,8 @@ strchr:
li  r3,0
blr
 
-   .globl  strcmp
-strcmp:
+   .globl  DOTSYM(strcmp)
+DOTSYM(strcmp):
addir5,r3,-1
addir4,r4,-1
 1: lbzur3,1(r5)
@@ -72,8 +81,8 @@ strcmp:
beq 1b
blr
 
-   .globl  strncmp
-strncmp:
+   .globl  DOTSYM(strncmp)
+DOTSYM(strncmp):
mtctr   r5
addir5,r3,-1
addir4,r4,-1
@@ -85,8 +94,8 @@ strncmp:
bdnzt   eq,1b
blr
 
-   .globl  strlen
-strlen:
+   .globl  DOTSYM(strlen)
+DOTSYM(strlen):
addir4,r3,-1
 1: lbzur0,1(r4)
cmpwi   0,r0,0
@@ -94,8 +103,8 @@ strlen:
subfr3,r3,r4
blr
 
-   .globl  memset
-memset:
+   .globl  DOTSYM(memset)
+DOTSYM(memset):
rlwimi  r4,r4,8,16,23
rlwimi  r4,r4,16,0,15
addir6,r3,-4
@@ -120,14 +129,14 @@ memset:
bdnz8b
blr
 
-   .globl  memmove
-memmove:
+   .globl  DOTSYM(memmove)
+DOTSYM(memmove):
cmplw   0,r3,r4
-   bgt backwards_memcpy
+   bgt DOTSYM(backwards_memcpy)
/* fall through */
 
-   .globl  memcpy
-memcpy:
+   .globl  

[PATCH v8 10/13] powerpc: Add code to work with device trees in kexec_file_load.

2016-09-06 Thread Thiago Jung Bauermann
kexec_file_load needs to set up the device tree that will be used
by the next kernel and check whether it provides a console
that can be used by the purgatory.

[a...@linux-foundation.org: coding-style fixes]
Signed-off-by: Thiago Jung Bauermann 
Signed-off-by: Andrew Morton 
---
 arch/powerpc/include/asm/kexec.h   |   3 +
 arch/powerpc/kernel/machine_kexec_64.c | 221 +
 2 files changed, 224 insertions(+)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 0c7e020d935a..73f88b5f9bd1 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -96,6 +96,9 @@ int setup_purgatory(struct kimage *image, const void 
*slave_code,
const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr, unsigned long stack_top,
int debug);
+int setup_new_fdt(void *fdt, unsigned long initrd_load_addr,
+ unsigned long initrd_len, const char *cmdline);
+bool find_debug_console(const void *fdt);
 #endif /* CONFIG_KEXEC_FILE */
 
 #else /* !CONFIG_KEXEC_CORE */
diff --git a/arch/powerpc/kernel/machine_kexec_64.c 
b/arch/powerpc/kernel/machine_kexec_64.c
index 1e678dc5096a..31c5090705e0 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -683,4 +683,225 @@ int setup_purgatory(struct kimage *image, const void 
*slave_code,
return 0;
 }
 
+/*
+ * setup_new_fdt() - modify /chosen and memory reservation for the next kernel
+ * @fdt:
+ * @initrd_load_addr:  Address where the next initrd will be loaded.
+ * @initrd_len:Size of the next initrd, or 0 if there will be 
none.
+ * @cmdline:   Command line for the next kernel, or NULL if there will
+ * be none.
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+int setup_new_fdt(void *fdt, unsigned long initrd_load_addr,
+ unsigned long initrd_len, const char *cmdline)
+{
+   uint64_t oldfdt_addr;
+   int i, ret, chosen_node;
+   const void *prop;
+
+   /* Remove memory reservation for the current device tree. */
+   oldfdt_addr = __pa(initial_boot_params);
+   for (i = 0; i < fdt_num_mem_rsv(fdt); i++) {
+   uint64_t rsv_start, rsv_size;
+
+   ret = fdt_get_mem_rsv(fdt, i, _start, _size);
+   if (ret) {
+   pr_err("Malformed device tree.\n");
+   return -EINVAL;
+   }
+
+   if (rsv_start == oldfdt_addr &&
+   rsv_size == fdt_totalsize(initial_boot_params)) {
+   ret = fdt_del_mem_rsv(fdt, i);
+   if (ret) {
+   pr_err("Error deleting fdt reservation.\n");
+   return -EINVAL;
+   }
+
+   pr_debug("Removed old device tree reservation.\n");
+   break;
+   }
+   }
+
+   chosen_node = fdt_path_offset(fdt, "/chosen");
+   if (chosen_node == -FDT_ERR_NOTFOUND) {
+   chosen_node = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),
+ "chosen");
+   if (chosen_node < 0) {
+   pr_err("Error creating /chosen.\n");
+   return -EINVAL;
+   }
+   } else if (chosen_node < 0) {
+   pr_err("Malformed device tree: error reading /chosen.\n");
+   return -EINVAL;
+   }
+
+   /* Did we boot using an initrd? */
+   prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
+   if (prop) {
+   uint64_t tmp_start, tmp_end, tmp_size, tmp_sizepg;
+
+   tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+   prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
+   if (!prop) {
+   pr_err("Malformed device tree.\n");
+   return -EINVAL;
+   }
+   tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+   /*
+* kexec reserves exact initrd size, while firmware may
+* reserve a multiple of PAGE_SIZE, so check for both.
+*/
+   tmp_size = tmp_end - tmp_start;
+   tmp_sizepg = round_up(tmp_size, PAGE_SIZE);
+
+   /* Remove memory reservation for the current initrd. */
+   for (i = 0; i < fdt_num_mem_rsv(fdt); i++) {
+   uint64_t rsv_start, rsv_size;
+
+   ret = fdt_get_mem_rsv(fdt, i, _start, _size);
+   if (ret) {
+   pr_err("Malformed device tree.\n");
+   return -EINVAL;
+   }
+
+   if 

[PATCH v8 13/13] powerpc: Enable CONFIG_KEXEC_FILE in powerpc server defconfigs.

2016-09-06 Thread Thiago Jung Bauermann
Enable CONFIG_KEXEC_FILE in powernv_defconfig, ppc64_defconfig and
pseries_defconfig.

It depends on CONFIG_CRYPTO_SHA256=y, so add that as well.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/configs/powernv_defconfig | 2 ++
 arch/powerpc/configs/ppc64_defconfig   | 2 ++
 arch/powerpc/configs/pseries_defconfig | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/arch/powerpc/configs/powernv_defconfig 
b/arch/powerpc/configs/powernv_defconfig
index dce352e9153b..319e1fb7b0c9 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -47,6 +47,7 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PPC_TRANSACTIONAL_MEM=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_KEXEC=y
+CONFIG_KEXEC_FILE=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_NUMA=y
 CONFIG_MEMORY_HOTPLUG=y
@@ -298,6 +299,7 @@ CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_ANUBIS=m
diff --git a/arch/powerpc/configs/ppc64_defconfig 
b/arch/powerpc/configs/ppc64_defconfig
index 0a8d250cb97e..a0355ccc7f55 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -44,6 +44,7 @@ CONFIG_HZ_100=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PPC_TRANSACTIONAL_MEM=y
 CONFIG_KEXEC=y
+CONFIG_KEXEC_FILE=y
 CONFIG_CRASH_DUMP=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
@@ -333,6 +334,7 @@ CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_ANUBIS=m
diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index 654aeffc57ef..23af4a72930e 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -50,6 +50,7 @@ CONFIG_HZ_100=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PPC_TRANSACTIONAL_MEM=y
 CONFIG_KEXEC=y
+CONFIG_KEXEC_FILE=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
@@ -300,6 +301,7 @@ CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_ANUBIS=m
-- 
1.9.1


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


[PATCH v8 11/13] powerpc: Add support for loading ELF kernels with kexec_file_load.

2016-09-06 Thread Thiago Jung Bauermann
This uses all the infrastructure built up by the previous patches
in the series to load an ELF vmlinux file and an initrd. It uses the
flattened device tree at initial_boot_params as a base and adjusts memory
reservations and its /chosen node for the next kernel.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/include/asm/kexec_elf_64.h |  10 ++
 arch/powerpc/kernel/Makefile|   1 +
 arch/powerpc/kernel/kexec_elf_64.c  | 282 
 arch/powerpc/kernel/machine_kexec_64.c  |   5 +-
 4 files changed, 297 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kexec_elf_64.h 
b/arch/powerpc/include/asm/kexec_elf_64.h
new file mode 100644
index ..30da6bc0ccf8
--- /dev/null
+++ b/arch/powerpc/include/asm/kexec_elf_64.h
@@ -0,0 +1,10 @@
+#ifndef __POWERPC_KEXEC_ELF_64_H__
+#define __POWERPC_KEXEC_ELF_64_H__
+
+#ifdef CONFIG_KEXEC_FILE
+
+extern struct kexec_file_ops kexec_elf64_ops;
+
+#endif /* CONFIG_KEXEC_FILE */
+
+#endif /* __POWERPC_KEXEC_ELF_64_H__ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index fef0d730acc4..d12a84003283 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_PCI)   += pci_$(CONFIG_WORD_SIZE).o 
$(pci64-y) \
 obj-$(CONFIG_PCI_MSI)  += msi.o
 obj-$(CONFIG_KEXEC_CORE)   += machine_kexec.o crash.o \
   machine_kexec_$(CONFIG_WORD_SIZE).o
+obj-$(CONFIG_KEXEC_FILE)   += kexec_elf_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_AUDIT)+= audit.o
 obj64-$(CONFIG_AUDIT)  += compat_audit.o
 
diff --git a/arch/powerpc/kernel/kexec_elf_64.c 
b/arch/powerpc/kernel/kexec_elf_64.c
new file mode 100644
index ..3cc8ebce1a86
--- /dev/null
+++ b/arch/powerpc/kernel/kexec_elf_64.c
@@ -0,0 +1,282 @@
+/*
+ * Load ELF vmlinux file for the kexec_file_load syscall.
+ *
+ * Copyright (C) 2004  Adam Litke (a...@us.ibm.com)
+ * Copyright (C) 2004  IBM Corp.
+ * Copyright (C) 2005  R Sharada (shar...@in.ibm.com)
+ * Copyright (C) 2006  Mohan Kumar M (mo...@in.ibm.com)
+ * Copyright (C) 2016  IBM Corporation
+ *
+ * Based on kexec-tools' kexec-elf-exec.c and kexec-elf-ppc64.c.
+ * Heavily modified for the kernel by
+ * Thiago Jung Bauermann .
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)"kexec_elf: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+extern size_t kexec_purgatory_size;
+
+#define PURGATORY_STACK_SIZE   (16 * 1024)
+
+/**
+ * build_elf_exec_info - read ELF executable and check that we can use it
+ */
+static int build_elf_exec_info(const char *buf, size_t len, struct elfhdr 
*ehdr,
+  struct elf_info *elf_info)
+{
+   int i;
+   int ret;
+
+   ret = elf_read_from_buffer(buf, len, ehdr, elf_info);
+   if (ret)
+   return ret;
+
+   /* Big endian vmlinux has type ET_DYN. */
+   if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
+   pr_err("Not an ELF executable.\n");
+   goto error;
+   } else if (!elf_info->proghdrs) {
+   pr_err("No ELF program header.\n");
+   goto error;
+   }
+
+   for (i = 0; i < ehdr->e_phnum; i++) {
+   /*
+* Kexec does not support loading interpreters.
+* In addition this check keeps us from attempting
+* to kexec ordinay executables.
+*/
+   if (elf_info->proghdrs[i].p_type == PT_INTERP) {
+   pr_err("Requires an ELF interpreter.\n");
+   goto error;
+   }
+   }
+
+   return 0;
+error:
+   elf_free_info(elf_info);
+   return -ENOEXEC;
+}
+
+static int elf64_probe(const char *buf, unsigned long len)
+{
+   struct elfhdr ehdr;
+   struct elf_info elf_info;
+   int ret;
+
+   ret = build_elf_exec_info(buf, len, , _info);
+   if (ret)
+   return ret;
+
+   elf_free_info(_info);
+
+   return elf_check_arch() ? 0 : -ENOEXEC;
+}
+
+/**
+ * elf_exec_load - load ELF executable image
+ * @lowest_load_addr:  On return, will be the address where the first PT_LOAD
+ * section will be loaded in memory.
+ *
+ * Return:
+ * 0 on success, negative value on failure.
+ */
+static int elf_exec_load(struct kimage *image, struct elfhdr *ehdr,
+struct elf_info 

[PATCH v8 03/13] kexec_file: Factor out kexec_locate_mem_hole from kexec_add_buffer.

2016-09-06 Thread Thiago Jung Bauermann
kexec_locate_mem_hole will be used by the PowerPC kexec_file_load
implementation to find free memory for the purgatory stack.

Signed-off-by: Thiago Jung Bauermann 
Acked-by: Dave Young 
---
 include/linux/kexec.h |  1 +
 kernel/kexec_file.c   | 25 -
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index be39903edae1..d419d0e51fe5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -176,6 +176,7 @@ struct kexec_buf {
 int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
   int (*func)(u64, u64, void *));
 extern int kexec_add_buffer(struct kexec_buf *kbuf);
+int kexec_locate_mem_hole(struct kexec_buf *kbuf);
 #endif /* CONFIG_KEXEC_FILE */
 
 struct kimage {
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index efd2c094af7e..0c2df7f73792 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -450,6 +450,23 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
 }
 
 /**
+ * kexec_locate_mem_hole - find free memory for the purgatory or the next 
kernel
+ * @kbuf:  Parameters for the memory search.
+ *
+ * On success, kbuf->mem will have the start address of the memory region 
found.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int kexec_locate_mem_hole(struct kexec_buf *kbuf)
+{
+   int ret;
+
+   ret = arch_kexec_walk_mem(kbuf, locate_mem_hole_callback);
+
+   return ret == 1 ? 0 : -EADDRNOTAVAIL;
+}
+
+/**
  * kexec_add_buffer - place a buffer in a kexec segment
  * @kbuf:  Buffer contents and memory parameters.
  *
@@ -489,11 +506,9 @@ int kexec_add_buffer(struct kexec_buf *kbuf)
kbuf->buf_align = max(kbuf->buf_align, PAGE_SIZE);
 
/* Walk the RAM ranges and allocate a suitable range for the buffer */
-   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;
-   }
+   ret = kexec_locate_mem_hole(kbuf);
+   if (ret)
+   return ret;
 
/* Found a suitable memory range */
ksegment = >image->segment[kbuf->image->nr_segments];
-- 
1.9.1


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


[PATCH v8 07/13] powerpc: Adapt elf64_apply_relocate_add for kexec_file_load.

2016-09-06 Thread Thiago Jung Bauermann
Extend elf64_apply_relocate_add to support relative symbols. This is
necessary because there is a difference between how the module loading
mechanism and the kexec purgatory loading code use Elf64_Sym.st_value
at relocation time: the former changes st_value to point to the absolute
memory address before relocating the module, while the latter does that
adjustment during relocation of the purgatory.

Also, add a check_symbols argument so that the kexec code can be stricter
about undefined symbols.

Finally, add relocation types used by the purgatory.

[a...@linux-foundation.org: coding-style fixes]
Signed-off-by: Thiago Jung Bauermann 
Signed-off-by: Andrew Morton 
---
 arch/powerpc/include/asm/elf_util.h |   2 +
 arch/powerpc/kernel/elf_util_64.c   | 100 +---
 arch/powerpc/kernel/module_64.c |   6 ++-
 3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/elf_util.h 
b/arch/powerpc/include/asm/elf_util.h
index a012ba03282d..5a27e8ceb88a 100644
--- a/arch/powerpc/include/asm/elf_util.h
+++ b/arch/powerpc/include/asm/elf_util.h
@@ -20,6 +20,7 @@
 #include 
 
 struct elf_info {
+   const struct elfhdr *ehdr;
struct elf_shdr *sechdrs;
 
/* Index of stubs section. */
@@ -67,6 +68,7 @@ int elf64_apply_relocate_add(const struct elf_info *elf_info,
 const char *strtab, const Elf64_Rela *rela,
 unsigned int num_rela, void *syms_base,
 void *loc_base, Elf64_Addr addr_base,
+bool relative_symbols, bool check_symbols,
 const char *obj_name);
 
 #endif /* _ASM_POWERPC_ELF_UTIL_H */
diff --git a/arch/powerpc/kernel/elf_util_64.c 
b/arch/powerpc/kernel/elf_util_64.c
index 8e5d400ac9f2..1b17df71fb8d 100644
--- a/arch/powerpc/kernel/elf_util_64.c
+++ b/arch/powerpc/kernel/elf_util_64.c
@@ -74,6 +74,8 @@ static void squash_toc_save_inst(const char *name, unsigned 
long addr) { }
  * @syms_base: Contents of the associated symbol table.
  * @loc_base:  Contents of the section to which relocations apply.
  * @addr_base: The address where the section will be loaded in memory.
+ * @relative_symbols:  Are the symbols' st_value members relative?
+ * @check_symbols: Fail if an unexpected symbol is found?
  * @obj_name:  The name of the ELF binary, for information messages.
  *
  * Applies RELA relocations to an ELF file already at its final location
@@ -84,12 +86,15 @@ int elf64_apply_relocate_add(const struct elf_info 
*elf_info,
 const char *strtab, const Elf64_Rela *rela,
 unsigned int num_rela, void *syms_base,
 void *loc_base, Elf64_Addr addr_base,
+bool relative_symbols, bool check_symbols,
 const char *obj_name)
 {
unsigned int i;
unsigned long *location;
unsigned long address;
+   unsigned long sec_base;
unsigned long value;
+   int reloc_type;
const char *name;
Elf64_Sym *sym;
 
@@ -116,15 +121,44 @@ int elf64_apply_relocate_add(const struct elf_info 
*elf_info,
else
name = "";
 
-   pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n",
-  location, (long)ELF64_R_TYPE(rela[i].r_info),
-  name, (unsigned long)sym->st_value,
+   reloc_type = ELF64_R_TYPE(rela[i].r_info);
+
+   pr_debug("RELOC at %p: %i-type as %s (0x%lx) + %li\n",
+  location, reloc_type, name, (unsigned long)sym->st_value,
   (long)rela[i].r_addend);
 
+   if (check_symbols) {
+   /*
+* TOC symbols appear as undefined but should be
+* resolved as well, so allow them to be processed.
+*/
+   if (sym->st_shndx == SHN_UNDEF &&
+   strcmp(name, ".TOC.") != 0 &&
+   reloc_type != R_PPC64_TOC) {
+   pr_err("Undefined symbol: %s\n", name);
+   return -ENOEXEC;
+   } else if (sym->st_shndx == SHN_COMMON) {
+   pr_err("Symbol '%s' in common section.\n",
+  name);
+   return -ENOEXEC;
+   }
+   }
+
+   if (relative_symbols && sym->st_shndx != SHN_ABS) {
+   if (sym->st_shndx >= elf_info->ehdr->e_shnum) {
+   pr_err("Invalid section %d for symbol %s\n",
+  sym->st_shndx, name);
+   return 

[PATCH v8 05/13] powerpc: Factor out relocation code from module_64.c to elf_util_64.c.

2016-09-06 Thread Thiago Jung Bauermann
The kexec_file_load system call needs to relocate the purgatory, so
factor out the module relocation code so that it can be shared.

This patch's purpose is to move the ELF relocation logic from
apply_relocate_add to elf_util_64.c with as few changes as
possible. The following changes were needed:

To avoid having module-specific code in a general purpose utility
function, struct elf_info was created to contain the information
needed for ELF binaries manipulation.

my_r2, stub_for_addr and create_stub were changed to use it instead of
having to receive a struct module, since they are called from
elf64_apply_relocate_add.

local_entry_offset and squash_toc_save_inst were only used by
apply_rellocate_add, so they were moved to elf_util_64.c as well.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/include/asm/elf_util.h |  70 
 arch/powerpc/include/asm/module.h   |  14 +-
 arch/powerpc/kernel/Makefile|   4 +
 arch/powerpc/kernel/elf_util_64.c   | 269 +++
 arch/powerpc/kernel/module_64.c | 312 
 5 files changed, 386 insertions(+), 283 deletions(-)

diff --git a/arch/powerpc/include/asm/elf_util.h 
b/arch/powerpc/include/asm/elf_util.h
new file mode 100644
index ..37372559fe62
--- /dev/null
+++ b/arch/powerpc/include/asm/elf_util.h
@@ -0,0 +1,70 @@
+/*
+ * Utility functions to work with ELF files.
+ *
+ * Copyright (C) 2016, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ASM_POWERPC_ELF_UTIL_H
+#define _ASM_POWERPC_ELF_UTIL_H
+
+#include 
+
+struct elf_info {
+   struct elf_shdr *sechdrs;
+
+   /* Index of stubs section. */
+   unsigned int stubs_section;
+   /* Index of TOC section. */
+   unsigned int toc_section;
+};
+
+#ifdef __powerpc64__
+#ifdef PPC64_ELF_ABI_v2
+
+/* An address is simply the address of the function. */
+typedef unsigned long func_desc_t;
+#else
+
+/* An address is address of the OPD entry, which contains address of fn. */
+typedef struct ppc64_opd_entry func_desc_t;
+#endif /* PPC64_ELF_ABI_v2 */
+
+/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
+   the kernel itself).  But on PPC64, these need to be used for every
+   jump, actually, to reset r2 (TOC+0x8000). */
+struct ppc64_stub_entry
+{
+   /* 28 byte jump instruction sequence (7 instructions). We only
+* need 6 instructions on ABIv2 but we always allocate 7 so
+* so we don't have to modify the trampoline load instruction. */
+   u32 jump[7];
+   /* Used by ftrace to identify stubs */
+   u32 magic;
+   /* Data for the above code */
+   func_desc_t funcdata;
+};
+#endif
+
+/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
+   gives the value maximum span in an instruction which uses a signed
+   offset) */
+static inline unsigned long my_r2(const struct elf_info *elf_info)
+{
+   return elf_info->sechdrs[elf_info->toc_section].sh_addr + 0x8000;
+}
+
+int elf64_apply_relocate_add(const struct elf_info *elf_info,
+const char *strtab, unsigned int symindex,
+unsigned int relsec, const char *obj_name);
+
+#endif /* _ASM_POWERPC_ELF_UTIL_H */
diff --git a/arch/powerpc/include/asm/module.h 
b/arch/powerpc/include/asm/module.h
index cd4ffd86765f..f2073115d518 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -12,7 +12,14 @@
 #include 
 #include 
 #include 
+#include 
 
+/* Both low and high 16 bits are added as SIGNED additions, so if low
+   16 bits has high bit set, high 16 bits must be adjusted.  These
+   macros do that (stolen from binutils). */
+#define PPC_LO(v) ((v) & 0x)
+#define PPC_HI(v) (((v) >> 16) & 0x)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
 
 #ifndef __powerpc64__
 /*
@@ -33,8 +40,7 @@ struct ppc_plt_entry {
 
 struct mod_arch_specific {
 #ifdef __powerpc64__
-   unsigned int stubs_section; /* Index of stubs section in module */
-   unsigned int toc_section;   /* What section is the TOC? */
+   struct elf_info elf_info;
bool toc_fixed; /* Have we fixed up .TOC.? */
 #ifdef CONFIG_DYNAMIC_FTRACE
unsigned long toc;
@@ -90,6 +96,10 @@ static inline int module_finalize_ftrace(struct module *mod, 
const Elf_Shdr *sec
 }
 #endif
 
+unsigned long stub_for_addr(const struct elf_info *elf_info, unsigned long 
addr,
+   const char *obj_name);

[PATCH v8 00/13] kexec_file_load implementation for PowerPC

2016-09-06 Thread Thiago Jung Bauermann
When Stephen Rothwell added this patch series to the linux-next tree,
he found out that it fails to cross build a ppc64 LE kernel using a
ppc64 BE host. This version of the series fixes that problem with a
change in arch/powerpc/purgatory/Makefile.

While I was at it I noticed that it is not necessary to build the
purgatory during archprepare, so I was able to simplify the changes to
arch/powerpc/Makefile. Both changes are in patch 12. It is the only
patch that changed relative to v7, all others are exactly the same.

I tested building (and booting the resulting kernel) natively on ppc64 LE
and BE, cross-building from ppc64 BE to LE and vice-versa, and from x86 to
ppc64 LE and BE.

Original cover letter:

This patch series implements the kexec_file_load system call on PowerPC.

This system call moves the reading of the kernel, initrd and the device tree
from the userspace kexec tool to the kernel. This is needed if you want to
do one or both of the following:

1. only allow loading of signed kernels.
2. "measure" (i.e., record the hashes of) the kernel, initrd, kernel
   command line and other boot inputs for the Integrity Measurement
   Architecture subsystem.

The above are the functions kexec already has built into kexec_file_load.
Yesterday I posted a set of patches which allows a third feature:

3. have IMA pass-on its event log (where integrity measurements are
   registered) accross kexec to the second kernel, so that the event
   history is preserved.

Because OpenPower uses an intermediary Linux instance as a boot loader
(skiroot), feature 1 is needed to implement secure boot for the platform,
while features 2 and 3 are needed to implement trusted boot.

This patch series starts by removing an x86 assumption from kexec_file:
kexec_add_buffer uses iomem to find reserved memory ranges, but PowerPC
uses the memblock subsystem.  A hook is added so that each arch can
specify how memory ranges can be found.

Also, the memory-walking logic in kexec_add_buffer is useful in this
implementation to find a free area for the purgatory's stack, so the
next patch moves that logic to kexec_locate_mem_hole.

The kexec_file_load system call needs to apply relocations to the
purgatory but adding code for that would duplicate functionality with
the module loading mechanism, which also needs to apply relocations to
the kernel modules.  Therefore, this patch series factors out the module
relocation code so that it can be shared.

One thing that is still missing is crashkernel support, which I intend
to submit shortly. For now, arch_kexec_kernel_image_probe rejects crash
kernels.

This code is based on kexec-tools, but with many modifications to adapt
it to the kernel environment and facilities. Except the purgatory,
which only has minimal changes.

Changes for v8:
- Rebased on top of v4.8-rc5.
- Patch "powerpc: Add purgatory for kexec_file_load implementation."
  - Fix cross build from ppc64 LE to BE and vice-versa.
  - Don't build the purgatory during archprepare.

Changes for v7:
- Rebased on top of v4.8-rc4.
- Patch "powerpc: Change places using CONFIG_KEXEC to use CONFIG_KEXEC_CORE
  instead."
  - New patch. Fixes build when CONFIG_KEXEC=n and CONFIG_KEXEC_FILE=y.
- Patch "powerpc: Adapt elf64_apply_relocate_add for kexec_file_load."
  - Fixed checkpatch warning "else is not generally useful after a break
or return".
  - Fixed checkpatch warnings about line length. (Andrew Morton)
- Patch "powerpc: Add code to work with device trees in kexec_file_load."
  - Remove space before tabs in doc comment for setup_new_fdt. (Andrew Morton)
  - Fixed checkpatch warnings about line length.
- Patch "powerpc: Add support for loading ELF kernels with kexec_file_load."
  - Removed duplicate #include .

Changes for v6:
- Based directly on top of v4.8-rc1.
- Patch "powerpc: Adapt elf64_apply_relocate_add for kexec_file_load."
  - Allow undefined symbols if they are relocations for the TOC in the
big endian ABI.
  - Fixed build error in this patch by adding the ehdr member to elf_info
here instead of in the next patch.
  - Initialize elf_info.ehdr in module_64.c:module_frob_arch_sections.
- Patch "powerpc: Add code to work with device trees in kexec_file_load."
  - Changed find_debug_console to look for /chosen instead of receiving
its offset as an argument.
  - setup_new_fdt: no need to find /chosen again after deleting the memory
reservation for initrd.
- Patch "powerpc: Add support for loading ELF kernels with kexec_file_load."
  - Don't pass the offset to /chosen to find_debug_console.
- Patch "powerpc: Allow userspace to set device tree properties in 
kexec_file_load"
  - Dropped patch.
- Patch "powerpc: Add purgatory for kexec_file_load implementation."
  - Make boot/string.S use the DOTSYM macro so that it can be
used by the ppc64 big endian purgatory.
  - Use -mcall-aixdesc to compile the purgatory on big endian ppc64.

Changes for v5:
- Rebased series on v4.8-rc1 + the extend kexec_file_load series.

[PATCH v8 06/13] powerpc: Generalize elf64_apply_relocate_add.

2016-09-06 Thread Thiago Jung Bauermann
When apply_relocate_add is called, modules are already loaded at their
final location in memory so Elf64_Shdr.sh_addr can be used for accessing
the section contents as well as the base address for relocations.

This is not the case for kexec's purgatory, because it will only be
copied to its final location right before being executed. Therefore,
it needs to be relocated while it is still in a temporary buffer. In
this case, Elf64_Shdr.sh_addr can't be used to access the sections'
contents.

This patch allows elf64_apply_relocate_add to be used when the ELF
binary is not yet at its final location by adding an addr_base argument
to specify the address at which the section will be loaded, and rela,
loc_base and syms_base to point to the sections' contents.

Signed-off-by: Thiago Jung Bauermann 
---
 arch/powerpc/include/asm/elf_util.h |  6 ++--
 arch/powerpc/kernel/elf_util_64.c   | 63 +
 arch/powerpc/kernel/module_64.c | 17 --
 3 files changed, 61 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/elf_util.h 
b/arch/powerpc/include/asm/elf_util.h
index 37372559fe62..a012ba03282d 100644
--- a/arch/powerpc/include/asm/elf_util.h
+++ b/arch/powerpc/include/asm/elf_util.h
@@ -64,7 +64,9 @@ static inline unsigned long my_r2(const struct elf_info 
*elf_info)
 }
 
 int elf64_apply_relocate_add(const struct elf_info *elf_info,
-const char *strtab, unsigned int symindex,
-unsigned int relsec, const char *obj_name);
+const char *strtab, const Elf64_Rela *rela,
+unsigned int num_rela, void *syms_base,
+void *loc_base, Elf64_Addr addr_base,
+const char *obj_name);
 
 #endif /* _ASM_POWERPC_ELF_UTIL_H */
diff --git a/arch/powerpc/kernel/elf_util_64.c 
b/arch/powerpc/kernel/elf_util_64.c
index decad2c34f38..8e5d400ac9f2 100644
--- a/arch/powerpc/kernel/elf_util_64.c
+++ b/arch/powerpc/kernel/elf_util_64.c
@@ -69,33 +69,56 @@ static void squash_toc_save_inst(const char *name, unsigned 
long addr) { }
  * elf64_apply_relocate_add - apply 64 bit RELA relocations
  * @elf_info:  Support information for the ELF binary being relocated.
  * @strtab:String table for the associated symbol table.
- * @symindex:  Section header index for the associated symbol table.
- * @relsec:Section header index for the relocations to apply.
+ * @rela:  Contents of the section with the relocations to apply.
+ * @num_rela:  Number of relocation entries in the section.
+ * @syms_base: Contents of the associated symbol table.
+ * @loc_base:  Contents of the section to which relocations apply.
+ * @addr_base: The address where the section will be loaded in memory.
  * @obj_name:  The name of the ELF binary, for information messages.
+ *
+ * Applies RELA relocations to an ELF file already at its final location
+ * in memory (in which case loc_base == addr_base), or still in a temporary
+ * buffer.
  */
 int elf64_apply_relocate_add(const struct elf_info *elf_info,
-const char *strtab, unsigned int symindex,
-unsigned int relsec, const char *obj_name)
+const char *strtab, const Elf64_Rela *rela,
+unsigned int num_rela, void *syms_base,
+void *loc_base, Elf64_Addr addr_base,
+const char *obj_name)
 {
unsigned int i;
-   Elf64_Shdr *sechdrs = elf_info->sechdrs;
-   Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
-   Elf64_Sym *sym;
unsigned long *location;
+   unsigned long address;
unsigned long value;
+   const char *name;
+   Elf64_Sym *sym;
+
+   for (i = 0; i < num_rela; i++) {
+   /*
+* rels[i].r_offset contains the byte offset from the beginning
+* of section to the storage unit affected.
+*
+* This is the location to update in the temporary buffer where
+* the section is currently loaded. The section will finally
+* be loaded to a different address later, pointed to by
+* addr_base.
+*/
+   location = loc_base + rela[i].r_offset;
+
+   /* Final address of the location. */
+   address = addr_base + rela[i].r_offset;
 
+   /* This is the symbol the relocation is referring to. */
+   sym = (Elf64_Sym *) syms_base + ELF64_R_SYM(rela[i].r_info);
 
-   for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
-   /* This is where to make the change */
-   location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-   +