All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v19 02/13] arm64: Add back cpu reset routines
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

Commit 68234df4ea79 ("arm64: kill flush_cache_all()") removed the global
arm64 routines cpu_reset() and cpu_soft_restart() needed by the arm64
kexec and kdump support.  Add simplified versions of those two routines
back with some changes needed for kexec in the new files cpu_reset.S,
and cpu_reset.h.

When a CPU is reset it needs to be put into the exception level it had when
it entered the kernel. Update cpu_soft_restart() to accept an argument
which signals if the reset address needs to be entered at EL1 or EL2, and
add a new hypercall HVC_SOFT_RESTART which is used for the EL2 switch.

Signed-off-by: Geoff Levand <geoff@infradead.org>
Reviewed-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/virt.h |  5 ++++
 arch/arm64/kernel/cpu-reset.S | 54 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cpu-reset.h | 34 +++++++++++++++++++++++++++
 arch/arm64/kernel/hyp-stub.S  | 10 +++++++-
 4 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kernel/cpu-reset.S
 create mode 100644 arch/arm64/kernel/cpu-reset.h

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index dcbcf8d..bbc6a8c 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -34,6 +34,11 @@
  */
 #define HVC_SET_VECTORS 1
 
+/*
+ * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
+ */
+#define HVC_SOFT_RESTART 2
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
new file mode 100644
index 0000000..65f42d2
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -0,0 +1,54 @@
+/*
+ * CPU reset routines
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 Huawei Futurewei Technologies.
+ *
+ * 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 <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/sysreg.h>
+#include <asm/virt.h>
+
+.text
+.pushsection    .idmap.text, "ax"
+
+/*
+ * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for
+ * cpu_soft_restart.
+ *
+ * @el2_switch: Flag to indicate a swich to EL2 is needed.
+ * @entry: Location to jump to for soft reset.
+ * arg0: First argument passed to @entry.
+ * arg1: Second argument passed to @entry.
+ * arg2: Third argument passed to @entry.
+ *
+ * Put the CPU into the same state as it would be if it had been reset, and
+ * branch to what would be the reset vector. It must be executed with the
+ * flat identity mapping.
+ */
+ENTRY(__cpu_soft_restart)
+	/* Clear sctlr_el1 flags. */
+	mrs	x12, sctlr_el1
+	ldr	x13, =SCTLR_ELx_FLAGS
+	bic	x12, x12, x13
+	msr	sctlr_el1, x12
+	isb
+
+	cbz	x0, 1f				// el2_switch?
+	mov	x0, #HVC_SOFT_RESTART
+	hvc	#0				// no return
+
+1:	mov	x18, x1				// entry
+	mov	x0, x2				// arg0
+	mov	x1, x3				// arg1
+	mov	x2, x4				// arg2
+	br	x18
+ENDPROC(__cpu_soft_restart)
+
+.popsection
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
new file mode 100644
index 0000000..d4e9ecb
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -0,0 +1,34 @@
+/*
+ * CPU reset routines
+ *
+ * Copyright (C) 2015 Huawei Futurewei Technologies.
+ *
+ * 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.
+ */
+
+#ifndef _ARM64_CPU_RESET_H
+#define _ARM64_CPU_RESET_H
+
+#include <asm/virt.h>
+
+void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
+	unsigned long arg0, unsigned long arg1, unsigned long arg2);
+
+static inline void __noreturn cpu_soft_restart(unsigned long el2_switch,
+	unsigned long entry, unsigned long arg0, unsigned long arg1,
+	unsigned long arg2)
+{
+	typeof(__cpu_soft_restart) *restart;
+
+	el2_switch = el2_switch && !is_kernel_in_hyp_mode() &&
+		is_hyp_mode_available();
+	restart = (void *)virt_to_phys(__cpu_soft_restart);
+
+	cpu_install_idmap();
+	restart(el2_switch, entry, arg0, arg1, arg2);
+	unreachable();
+}
+
+#endif
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 8727f44..d3b5f75 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -71,8 +71,16 @@ el1_sync:
 	msr	vbar_el2, x1
 	b	9f
 
+2:	cmp	x0, #HVC_SOFT_RESTART
+	b.ne	3f
+	mov	x0, x2
+	mov	x2, x4
+	mov	x4, x1
+	mov	x1, x3
+	br	x4				// no return
+
 	/* Someone called kvm_call_hyp() against the hyp-stub... */
-2:	mov     x0, #ARM_EXCEPTION_HYP_GONE
+3:	mov	x0, #ARM_EXCEPTION_HYP_GONE
 
 9:	eret
 ENDPROC(el1_sync)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 01/13] arm64: Add cpus_are_stuck_in_kernel
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: James Morse <james.morse@arm.com>

kernel/smp.c has a fancy counter that keeps track of the number of CPUs
it marked as not-present and left in cpu_park_loop(). If there are any
CPUs spinning in here, kexec will release them once the memory is re-used
by the new kernel.

Provide a function to expose whether this counter is non-zero, so we can
use this when loading a new kexec image, and when calling machine_kexec().

Signed-off-by: James Morse <james.morse@arm.com>
[Split off from a larger patch]
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/include/asm/smp.h | 10 ++++++++++
 arch/arm64/kernel/smp.c      |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 433e504..38712f4 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -124,6 +124,16 @@ static inline void cpu_panic_kernel(void)
 	cpu_park_loop();
 }
 
+/*
+ * If a secondary CPU fails to come online, (e.g. due to mismatched features),
+ * it will try to call cpu_die(). If this fails, it updates
+ * cpus_stuck_in_kernel and sits in cpu_park_loop().
+ *
+ * Kexec checks this counter and refuses to load/kexec if it is non-zero, as
+ * cpu_park_loop() would be overwritten releasing the parked cpus.
+ */
+bool cpus_are_stuck_in_kernel(void);
+
 #endif /* ifndef __ASSEMBLY__ */
 
 #endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 678e084..d0bcd55 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -909,3 +909,8 @@ int setup_profiling_timer(unsigned int multiplier)
 {
 	return -EINVAL;
 }
+
+bool cpus_are_stuck_in_kernel(void)
+{
+	return !!cpus_stuck_in_kernel;
+}
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 00/13] arm64 kexec kernel patches
@ 2016-06-16 23:48 ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds the core support for kexec re-boot and kdump on ARM64.  This
version of the series combines Takahiro's kdump patches with my kexec patches.
Please consider all patches for inclusion.

Takahiro has done some extensive testing for this version with various
configurations af endian, image format, memory options and layouts, etc.

To load a second stage kernel and execute a kexec re-boot or to work with kdump
on ARM64 systems a series of patches to kexec-tools [2], which have not yet been
merged upstream, are needed.  Please update to the latest if you have been using
an older version.

To examine vmcore (/proc/vmcore), you should use
  - gdb v7.7 or later
  - crash v7.1.1 or later.
    For crash KASLR/CONFIG_RANDOMIZE_BASE support see [3].

[1]  https://git.kernel.org/cgit/linux/kernel/git/geoff/linux-kexec.git
[2]  https://git.kernel.org/cgit/linux/kernel/git/geoff/kexec-tools.git
[3]  https://www.redhat.com/archives/crash-utility/2016-May/msg00078.html

Changes for v19 (June 16, 2016, 25m):

  o Rebase to Linux-4.7-rc3.
  o Added more VMCOREINFO's (VA_BITS, PHYS_OFFSET).
  o Remove some unneeded included files.
  o Remove kmap() usage.
  o Remove kexec_is_dtb() routine.
  o Change #ifdef to IS_ENABLED(CONFIG_HOTPLUG_CPU).
  o Fix kexec_list_flush() to flush all list entries.
  o Use ENTRY(arm64_relocate_new_kernel).
  o Remove unused segment start in arm64_relocate_new_kernel.

Changes for v18 (June 9, 2016, 25m):

  o Rebase to Linux-4.7-rc2.
  o Change ret to br in __cpu_soft_restart().
  o Add cpu_install_idmap() call and hyp checks to cpu_soft_restart().
  o Don't return from HVC_SOFT_RESTART.

Changes for v17 (June 9, 2016, 25m):

  o Rebase to Linux-4.7-rc2.
  o Change ret to br in __cpu_soft_restart().
  o Add cpu_install_idmap() call to cpu_soft_restart().

Changes for v17 (June 3, 2016, 25m):

  o Rebase to Linux-4.7-rc1.
  o Added one VMCOREINFO parameter to vmcore for crash utility.
  o Added a check for CPUs stuck in kernel.
  o Re-implemented cpu_soft_restart() to be executed only in hyp-stub.
  o Added some kernel documentation about added device tree properties.
  o Fixed a returned value of pstate in crash_setup_regs(). Now return
    a faked pstate since we have no way to get the current pstate.

Changes for v16 (Apr 14, 2016, 23m):

  o Rebase to Linux-4.6-rc3.
  o Don't try to explicitly enter EL2 at machine_kexec() when VHE in use
  o Add unreachable() in case of ipi_cpu_crash_stop()
  o Add more "#ifdef" to eliminate code unused when !CONFIG_KEXEC_CORE
  o Fix a build error around ipi_cpu_crash_stop() when !CONFIG_HOTPLUG_CPU
  o Revert "arm64: Add new hcall HVC_CALL_FUNC"
  o Revert "Convert hcalls to use HVC immediate value"
    (replaced by James' "hyp/kvm: Extend hyp-stub API to allow function calls
     at EL2")

  Modified by James:
  o Add missing icache maintenance + isb to __kvm_hyp_reset()
  o Rework kvm cpu hotplug for VHE

  Added by James:
  o arm64: head.S: el2_setup() to accept sctlr_el1 as an argument
  o arm64: hyp/kvm: Extend hyp-stub API to allow function calls at EL2
  o arm64: kvm: Move lr save/restore from do_el2_call into EL1
  o arm64: kvm: Move the do_el2_call macro to a header file

Changes for v15 (Mar 14, 2016, 22m):

  o Rebase to Linux-4.5.
  o Remove DEBUG conditional in 'Add pr_debug output'.

Changes for v14 (Mar 4, 2016, 22m):

  o Rebase to Linux-4.5-rc6.
  o Rename setup_mm_for_reboot to cpu_install_idmap.
  o kdump: leave non-boot cpus online at crash dump
    As we don't have to make non-boot (crashed) cpus offline at crash dump,
    this patch adds a variant of smp_send_stop().
  o kdump: use a new device-tree property, "linux,elfcorehdr", instead of
    traditional "elfcorehdr=" kernel parameter
  o limit memory regions based on DT property, "usable-memory", instead of
    "mem=" kernel parameter
  o kdump: fix a build error when !CONFIG_KEXEC_CORE
  o kvm: use generic kvm_call_hyp() interface instead of kvm_cpu_reset()
  o kvm: initialize only a primary cpu at init_hyp_mode()

Changes for v13 (Jan 15, 2016, 20m):

  o Rebase to Linux-4.4.
  o Remove align directive from cpu_reset.c.
  o Use inline C wrapper for cpu_soft_restart.
  o Revert the new image d-cache flush changes of v10.
  o Add SCTLR cleanup patch.
  o Change pr_devel to pr_debug.
  o Call flush_icache_range() for reboot_code_buffer.
  o Add .ltorg directive to arm64_relocate_new_kernel.
  o Make new asm macro copy_page.
  o Change cache maintenence from inner-shareable to non-shareable.
  o Rename KEXEC_ARCH_ARM64 to KEXEC_ARCH_AARCH64.

  o arm64: kvm: allows kvm cpu hotplug
    - remove some garbage code from kvm_host.h
  o arm64: kdump: reserve memory for crash dump kernel
    - change CONFIG_KEXEC to CONFIG_KEXEC_CORE
    - don't panic on crash kernel alloc failure
      (thanks to Mark Salter, RH)
  o arm64: kdump: implement machine_crash_shutdown()
    - change "boot/non-boot cpu" to "crashing/non-crashing cpu"
    - introduce is_in_crash_kexec() for readability
    - re-introduce machine_kexec_mask_interrupts(), as arch/arm has,
      to discard unexpected interrupts
    - call crash_save_cpu() before making cpus offline to avoid a possible race
      (thanks to Pratyush Anand/Mark Salter, RH)
  o arm64: kdump: update a kernel doc
    - clarify that we support "Image" format as well as vmlinux in kdump.txt
  o arm64: kdump: relax BUG_ON() if more than one cpus are still active
    - change a warning message at the failure of shooting down non-crahsing cpus

Changes for v12 (Nov 24, 2015, 18m):

  o No changes, rebase to Linux-4.4-rc2.

Changes for v11 (Nov 6, 2015, 18m):

  o Rebase to Linux-4.3.
  o Move the new image d-cache flush from arm64_relocate_new_kernel to machine_kexec.
  o Pass values to arm64_relocate_new_kernel in registers, not in global variables.
  o Fixups to setting the sctlr_el1 and sctlr_el2 flags.

Changes for v10 (Oct 18, 2015, 17m):

  o Rebase to Linux-4.3-rc6.
  o Move tcr_set_idmap_t0sz to assembler.h.
  o Add back simplified cpu_reset routines.
  o Combine kexec + kdump patches.

Changes for v9 (Apr 7, 2015, 11m):

  o Use new upstream flag IND_FLAGS.

Changes for v8 (Mar 19, 2015, 10m):

  o Rebase to Linux-4.0-rc4.
  o Re-boot using purgatory only.

Changes for v7 (Jan 16, 2015, 8m):

  o Rebase to Linux-3.19-rc4.
  o Change from ESR_EL2_ to ESR_ELx_.
  o Remove work-arounds for EFI systems.
  
Changes for v6 (Dec 2, 2014, 7m):

  o Rebase to Linux-3.18-rc2

Changes for v5 (Nov 16, 2014, 6m):

Changes for v4 (Oct 3, 2014, 5m):

Changes for v3 (Sept 23, 2014, 4m):

Changes for v2 (Sep 9, 2014, 4m):

  o Rebase to Linux-3.17-rc4.
  o Move macros from proc-macros.S to assembler.h.
  o Convert hcalls to use ISS field.
  o Add new hcall HVC_CALL_FUNC.
  o Add EL2 switch to soft_restart.

First submission v1 (May 13, 2014):

  o Based on Linux-3.15-rc4.

-Geoff

The following changes since commit 5edb56491d4812c42175980759da53388e5d86f5:

  Linux 4.7-rc3 (2016-06-12 07:20:35 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geoff/linux-kexec.git kexec-v19

for you to fetch changes up to eedcb4f4fde3530a1a6745bf18a716330e077eba:

  Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec (2016-06-16 16:23:29 -0700)

----------------------------------------------------------------
AKASHI Takahiro (7):
      arm64: kdump: reserve memory for crash dump kernel
      arm64: limit memory regions based on DT property, usable-memory
      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

Geoff Levand (4):
      arm64: Add back cpu reset routines
      arm64/kexec: Add core kexec support
      arm64/kexec: Enable kexec in the arm64 defconfig
      arm64/kexec: Add pr_debug output

James Morse (2):
      arm64: Add cpus_are_stuck_in_kernel
      Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec

 Documentation/devicetree/bindings/chosen.txt |  28 +++
 Documentation/kdump/kdump.txt                |  15 +-
 arch/arm64/Kconfig                           |  21 ++
 arch/arm64/configs/defconfig                 |   2 +
 arch/arm64/include/asm/hardirq.h             |   2 +-
 arch/arm64/include/asm/kexec.h               |  87 ++++++++
 arch/arm64/include/asm/smp.h                 |  14 ++
 arch/arm64/include/asm/virt.h                |   5 +
 arch/arm64/kernel/Makefile                   |   3 +
 arch/arm64/kernel/cpu-reset.S                |  54 +++++
 arch/arm64/kernel/cpu-reset.h                |  34 ++++
 arch/arm64/kernel/crash_dump.c               |  71 +++++++
 arch/arm64/kernel/hyp-stub.S                 |  10 +-
 arch/arm64/kernel/machine_kexec.c            | 291 +++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S          | 130 ++++++++++++
 arch/arm64/kernel/setup.c                    |   7 +-
 arch/arm64/kernel/smp.c                      |  66 ++++++
 arch/arm64/mm/init.c                         | 154 ++++++++++++++
 include/uapi/linux/kexec.h                   |   1 +
 19 files changed, 991 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/include/asm/kexec.h
 create mode 100644 arch/arm64/kernel/cpu-reset.S
 create mode 100644 arch/arm64/kernel/cpu-reset.h
 create mode 100644 arch/arm64/kernel/crash_dump.c
 create mode 100644 arch/arm64/kernel/machine_kexec.c
 create mode 100644 arch/arm64/kernel/relocate_kernel.S

-- 
2.5.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 05/13] arm64/kexec: Add pr_debug output
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

To aid in debugging kexec problems or when adding new functionality to
kexec add a new routine kexec_image_info() and several inline pr_debug
statements.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/kernel/machine_kexec.c | 48 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index a6dcb9c..7372e58 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -11,6 +11,7 @@
 
 #include <linux/kexec.h>
 #include <linux/smp.h>
+#include <linux/uaccess.h>
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
@@ -24,6 +25,32 @@ extern const unsigned long arm64_relocate_new_kernel_size;
 
 static unsigned long kimage_start;
 
+/**
+ * kexec_image_info - For debugging output.
+ */
+#define kexec_image_info(_i) _kexec_image_info(__func__, __LINE__, _i)
+static void _kexec_image_info(const char *func, int line,
+	const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_debug("%s:%d:\n", func, line);
+	pr_debug("  kexec kimage info:\n");
+	pr_debug("    type:        %d\n", kimage->type);
+	pr_debug("    start:       %lx\n", kimage->start);
+	pr_debug("    head:        %lx\n", kimage->head);
+	pr_debug("    nr_segments: %lu\n", kimage->nr_segments);
+
+	for (i = 0; i < kimage->nr_segments; i++) {
+		pr_debug("      segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+			i,
+			kimage->segment[i].mem,
+			kimage->segment[i].mem + kimage->segment[i].memsz,
+			kimage->segment[i].memsz,
+			kimage->segment[i].memsz /  PAGE_SIZE);
+	}
+}
+
 void machine_kexec_cleanup(struct kimage *kimage)
 {
 	/* Empty routine needed to avoid build errors. */
@@ -40,6 +67,8 @@ int machine_kexec_prepare(struct kimage *kimage)
 {
 	kimage_start = kimage->start;
 
+	kexec_image_info(kimage);
+
 	if (kimage->type != KEXEC_TYPE_CRASH) {
 		if (cpus_are_stuck_in_kernel()) {
 			pr_err("Can't kexec: failed CPUs are stuck in the kernel.\n");
@@ -137,6 +166,25 @@ void machine_kexec(struct kimage *kimage)
 	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
 	reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
 
+	kexec_image_info(kimage);
+
+	pr_debug("%s:%d: control_code_page:        %p\n", __func__, __LINE__,
+		kimage->control_code_page);
+	pr_debug("%s:%d: reboot_code_buffer_phys:  %pa\n", __func__, __LINE__,
+		&reboot_code_buffer_phys);
+	pr_debug("%s:%d: reboot_code_buffer:       %p\n", __func__, __LINE__,
+		reboot_code_buffer);
+	pr_debug("%s:%d: relocate_new_kernel:      %p\n", __func__, __LINE__,
+		arm64_relocate_new_kernel);
+	pr_debug("%s:%d: relocate_new_kernel_size: 0x%lx(%lu) bytes\n",
+		__func__, __LINE__, arm64_relocate_new_kernel_size,
+		arm64_relocate_new_kernel_size);
+
+	pr_debug("%s:%d: kimage_head:              %lx\n", __func__, __LINE__,
+		kimage->head);
+	pr_debug("%s:%d: kimage_start:             %lx\n", __func__, __LINE__,
+		kimage_start);
+
 	/*
 	 * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use
 	 * after the kernel is shut down.
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 04/13] arm64/kexec: Enable kexec in the arm64 defconfig
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd2d74d..4ed4756 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -70,6 +70,7 @@ CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_XEN=y
+CONFIG_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
 CONFIG_CPU_IDLE=y
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 03/13] arm64/kexec: Add core kexec support
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

Add three new files, kexec.h, machine_kexec.c and relocate_kernel.S to the
arm64 architecture that add support for the kexec re-boot mechanism
(CONFIG_KEXEC) on arm64 platforms.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/Kconfig                  |  10 ++
 arch/arm64/include/asm/kexec.h      |  48 ++++++++++
 arch/arm64/kernel/Makefile          |   2 +
 arch/arm64/kernel/machine_kexec.c   | 182 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S | 130 ++++++++++++++++++++++++++
 include/uapi/linux/kexec.h          |   1 +
 6 files changed, 373 insertions(+)
 create mode 100644 arch/arm64/include/asm/kexec.h
 create mode 100644 arch/arm64/kernel/machine_kexec.c
 create mode 100644 arch/arm64/kernel/relocate_kernel.S

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5a0a691..330786d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -664,6 +664,16 @@ config PARAVIRT_TIME_ACCOUNTING
 
 	  If in doubt, say N here.
 
+config KEXEC
+	depends on PM_SLEEP_SMP
+	select KEXEC_CORE
+	bool "kexec system call"
+	---help---
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is independent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
 config XEN_DOM0
 	def_bool y
 	depends on XEN
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
new file mode 100644
index 0000000..04744dc
--- /dev/null
+++ b/arch/arm64/include/asm/kexec.h
@@ -0,0 +1,48 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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.
+ */
+
+#ifndef _ARM64_KEXEC_H
+#define _ARM64_KEXEC_H
+
+/* Maximum physical address we can use pages from */
+
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control code buffer */
+
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+#define KEXEC_CONTROL_PAGE_SIZE 4096
+
+#define KEXEC_ARCH KEXEC_ARCH_AARCH64
+
+#ifndef __ASSEMBLY__
+
+/**
+ * crash_setup_regs() - save registers for the panic kernel
+ *
+ * @newregs: registers are saved here
+ * @oldregs: registers to be saved (may be %NULL)
+ */
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+				    struct pt_regs *oldregs)
+{
+	/* Empty routine needed to avoid build errors. */
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2173149..7700c0c 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -46,6 +46,8 @@ arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
 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
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
new file mode 100644
index 0000000..a6dcb9c
--- /dev/null
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -0,0 +1,182 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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 <linux/kexec.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cpu_ops.h>
+#include <asm/mmu_context.h>
+
+#include "cpu-reset.h"
+
+/* Global variables for the arm64_relocate_new_kernel routine. */
+extern const unsigned char arm64_relocate_new_kernel[];
+extern const unsigned long arm64_relocate_new_kernel_size;
+
+static unsigned long kimage_start;
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+	/* Empty routine needed to avoid build errors. */
+}
+
+/**
+ * machine_kexec_prepare - Prepare for a kexec reboot.
+ *
+ * Called from the core kexec code when a kernel image is loaded.
+ * Forbid loading a kexec kernel if we have no way of hotplugging cpus or cpus
+ * are stuck in the kernel. This avoids a panic once we hit machine_kexec().
+ */
+int machine_kexec_prepare(struct kimage *kimage)
+{
+	kimage_start = kimage->start;
+
+	if (kimage->type != KEXEC_TYPE_CRASH) {
+		if (cpus_are_stuck_in_kernel()) {
+			pr_err("Can't kexec: failed CPUs are stuck in the kernel.\n");
+			return -EBUSY;
+		}
+
+		if (num_online_cpus() > 1) {
+			if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
+				/* any_cpu as we don't mind being preempted */
+				int any_cpu = raw_smp_processor_id();
+
+				if (cpu_ops[any_cpu]->cpu_die)
+					return 0;
+			}
+
+			pr_err("Can't kexec: no mechanism to offline secondary CPUs.\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * kexec_list_flush - Helper to flush the kimage list and source pages to PoC.
+ */
+static void kexec_list_flush(struct kimage *kimage)
+{
+	kimage_entry_t *entry;
+
+	for (entry = &kimage->head; ; entry++) {
+		unsigned int flag;
+		void *addr;
+
+		__flush_dcache_area(entry, sizeof(kimage_entry_t));
+
+		flag = *entry & IND_FLAGS;
+		if (flag == IND_DONE)
+			break;
+
+		addr = phys_to_virt(*entry & PAGE_MASK);
+
+		switch (flag) {
+		case IND_INDIRECTION:
+			/* Set entry point just before the new list page. */
+			entry = (kimage_entry_t *)addr - 1;
+		case IND_SOURCE:
+			__flush_dcache_area(addr, PAGE_SIZE);
+			break;
+		case IND_DESTINATION:
+			break;
+		default:
+			BUG();
+		}
+	}
+}
+
+/**
+ * kexec_segment_flush - Helper to flush the kimage segments to PoC.
+ */
+static void kexec_segment_flush(const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_debug("%s:\n", __func__);
+
+	for (i = 0; i < kimage->nr_segments; i++) {
+		pr_debug("  segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+			i,
+			kimage->segment[i].mem,
+			kimage->segment[i].mem + kimage->segment[i].memsz,
+			kimage->segment[i].memsz,
+			kimage->segment[i].memsz /  PAGE_SIZE);
+
+		__flush_dcache_area(phys_to_virt(kimage->segment[i].mem),
+			kimage->segment[i].memsz);
+	}
+}
+
+/**
+ * machine_kexec - Do the kexec reboot.
+ *
+ * Called from the core kexec code for a sys_reboot with LINUX_REBOOT_CMD_KEXEC.
+ */
+void machine_kexec(struct kimage *kimage)
+{
+	phys_addr_t reboot_code_buffer_phys;
+	void *reboot_code_buffer;
+
+	/*
+	 * New cpus may have become stuck_in_kernel after we loaded the image.
+	 */
+	BUG_ON(cpus_are_stuck_in_kernel() && (num_online_cpus() > 1));
+
+	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
+	reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
+
+	/*
+	 * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use
+	 * after the kernel is shut down.
+	 */
+	memcpy(reboot_code_buffer, arm64_relocate_new_kernel,
+		arm64_relocate_new_kernel_size);
+
+	/* Flush the reboot_code_buffer in preparation for its execution. */
+	__flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size);
+	flush_icache_range((uintptr_t)reboot_code_buffer,
+		arm64_relocate_new_kernel_size);
+
+	/* Flush the kimage list. */
+	kexec_list_flush(kimage);
+
+	/* Flush the new image if already in place. */
+	if (kimage->head & IND_DONE)
+		kexec_segment_flush(kimage);
+
+	pr_info("Bye!\n");
+
+	/* Disable all DAIF exceptions. */
+	asm volatile ("msr daifset, #0xf" : : : "memory");
+
+	/*
+	 * cpu_soft_restart will shutdown the MMU, disable data caches, then
+	 * transfer control to the reboot_code_buffer which contains a copy of
+	 * the arm64_relocate_new_kernel routine.  arm64_relocate_new_kernel
+	 * uses physical addressing to relocate the new image to its final
+	 * position and transfers control to the image entry point when the
+	 * relocation is complete.
+	 */
+
+	cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
+		kimage_start, 0);
+
+	BUG(); /* Should never get here. */
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* Empty routine needed to avoid build errors. */
+}
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
new file mode 100644
index 0000000..51b73cd
--- /dev/null
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -0,0 +1,130 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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 <linux/kexec.h>
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/kexec.h>
+#include <asm/page.h>
+#include <asm/sysreg.h>
+
+/*
+ * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
+ *
+ * The memory that the old kernel occupies may be overwritten when coping the
+ * new image to its final location.  To assure that the
+ * arm64_relocate_new_kernel routine which does that copy is not overwritten,
+ * all code and data needed by arm64_relocate_new_kernel must be between the
+ * symbols arm64_relocate_new_kernel and arm64_relocate_new_kernel_end.  The
+ * machine_kexec() routine will copy arm64_relocate_new_kernel to the kexec
+ * control_code_page, a special page which has been set up to be preserved
+ * during the copy operation.
+ */
+ENTRY(arm64_relocate_new_kernel)
+
+	/* Setup the list loop variables. */
+	mov	x17, x1				/* x17 = kimage_start */
+	mov	x16, x0				/* x16 = kimage_head */
+	dcache_line_size x15, x0		/* x15 = dcache line size */
+	mov	x14, xzr			/* x14 = entry ptr */
+	mov	x13, xzr			/* x13 = copy dest */
+
+	/* Clear the sctlr_el2 flags. */
+	mrs	x0, CurrentEL
+	cmp	x0, #CurrentEL_EL2
+	b.ne	1f
+	mrs	x0, sctlr_el2
+	ldr	x1, =SCTLR_ELx_FLAGS
+	bic	x0, x0, x1
+	msr	sctlr_el2, x0
+	isb
+1:
+
+	/* Check if the new image needs relocation. */
+	tbnz	x16, IND_DONE_BIT, .Ldone
+
+.Lloop:
+	and	x12, x16, PAGE_MASK		/* x12 = addr */
+
+	/* Test the entry flags. */
+.Ltest_source:
+	tbz	x16, IND_SOURCE_BIT, .Ltest_indirection
+
+	/* Invalidate dest page to PoC. */
+	mov     x0, x13
+	add     x20, x0, #PAGE_SIZE
+	sub     x1, x15, #1
+	bic     x0, x0, x1
+2:	dc      ivac, x0
+	add     x0, x0, x15
+	cmp     x0, x20
+	b.lo    2b
+	dsb     sy
+
+	mov x20, x13
+	mov x21, x12
+	copy_page x20, x21, x0, x1, x2, x3, x4, x5, x6, x7
+
+	/* dest += PAGE_SIZE */
+	add	x13, x13, PAGE_SIZE
+	b	.Lnext
+
+.Ltest_indirection:
+	tbz	x16, IND_INDIRECTION_BIT, .Ltest_destination
+
+	/* ptr = addr */
+	mov	x14, x12
+	b	.Lnext
+
+.Ltest_destination:
+	tbz	x16, IND_DESTINATION_BIT, .Lnext
+
+	/* dest = addr */
+	mov	x13, x12
+
+.Lnext:
+	/* entry = *ptr++ */
+	ldr	x16, [x14], #8
+
+	/* while (!(entry & DONE)) */
+	tbz	x16, IND_DONE_BIT, .Lloop
+
+.Ldone:
+	/* wait for writes from copy_page to finish */
+	dsb	nsh
+	ic	iallu
+	dsb	nsh
+	isb
+
+	/* Start new image. */
+	mov	x0, xzr
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+	br	x17
+
+ENDPROC(arm64_relocate_new_kernel)
+
+.ltorg
+
+.align 3	/* To keep the 64-bit values below naturally aligned. */
+
+.Lcopy_end:
+.org	KEXEC_CONTROL_PAGE_SIZE
+
+/*
+ * arm64_relocate_new_kernel_size - Number of bytes to copy to the
+ * control_code_page.
+ */
+.globl arm64_relocate_new_kernel_size
+arm64_relocate_new_kernel_size:
+	.quad	.Lcopy_end - arm64_relocate_new_kernel
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 99048e5..aae5ebf 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -39,6 +39,7 @@
 #define KEXEC_ARCH_SH      (42 << 16)
 #define KEXEC_ARCH_MIPS_LE (10 << 16)
 #define KEXEC_ARCH_MIPS    ( 8 << 16)
+#define KEXEC_ARCH_AARCH64 (183 << 16)
 
 /* The artificial cap on the number of segments passed to kexec_load. */
 #define KEXEC_SEGMENT_MAX 16
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 05/13] arm64/kexec: Add pr_debug output
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

To aid in debugging kexec problems or when adding new functionality to
kexec add a new routine kexec_image_info() and several inline pr_debug
statements.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/kernel/machine_kexec.c | 48 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index a6dcb9c..7372e58 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -11,6 +11,7 @@
 
 #include <linux/kexec.h>
 #include <linux/smp.h>
+#include <linux/uaccess.h>
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
@@ -24,6 +25,32 @@ extern const unsigned long arm64_relocate_new_kernel_size;
 
 static unsigned long kimage_start;
 
+/**
+ * kexec_image_info - For debugging output.
+ */
+#define kexec_image_info(_i) _kexec_image_info(__func__, __LINE__, _i)
+static void _kexec_image_info(const char *func, int line,
+	const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_debug("%s:%d:\n", func, line);
+	pr_debug("  kexec kimage info:\n");
+	pr_debug("    type:        %d\n", kimage->type);
+	pr_debug("    start:       %lx\n", kimage->start);
+	pr_debug("    head:        %lx\n", kimage->head);
+	pr_debug("    nr_segments: %lu\n", kimage->nr_segments);
+
+	for (i = 0; i < kimage->nr_segments; i++) {
+		pr_debug("      segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+			i,
+			kimage->segment[i].mem,
+			kimage->segment[i].mem + kimage->segment[i].memsz,
+			kimage->segment[i].memsz,
+			kimage->segment[i].memsz /  PAGE_SIZE);
+	}
+}
+
 void machine_kexec_cleanup(struct kimage *kimage)
 {
 	/* Empty routine needed to avoid build errors. */
@@ -40,6 +67,8 @@ int machine_kexec_prepare(struct kimage *kimage)
 {
 	kimage_start = kimage->start;
 
+	kexec_image_info(kimage);
+
 	if (kimage->type != KEXEC_TYPE_CRASH) {
 		if (cpus_are_stuck_in_kernel()) {
 			pr_err("Can't kexec: failed CPUs are stuck in the kernel.\n");
@@ -137,6 +166,25 @@ void machine_kexec(struct kimage *kimage)
 	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
 	reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
 
+	kexec_image_info(kimage);
+
+	pr_debug("%s:%d: control_code_page:        %p\n", __func__, __LINE__,
+		kimage->control_code_page);
+	pr_debug("%s:%d: reboot_code_buffer_phys:  %pa\n", __func__, __LINE__,
+		&reboot_code_buffer_phys);
+	pr_debug("%s:%d: reboot_code_buffer:       %p\n", __func__, __LINE__,
+		reboot_code_buffer);
+	pr_debug("%s:%d: relocate_new_kernel:      %p\n", __func__, __LINE__,
+		arm64_relocate_new_kernel);
+	pr_debug("%s:%d: relocate_new_kernel_size: 0x%lx(%lu) bytes\n",
+		__func__, __LINE__, arm64_relocate_new_kernel_size,
+		arm64_relocate_new_kernel_size);
+
+	pr_debug("%s:%d: kimage_head:              %lx\n", __func__, __LINE__,
+		kimage->head);
+	pr_debug("%s:%d: kimage_start:             %lx\n", __func__, __LINE__,
+		kimage_start);
+
 	/*
 	 * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use
 	 * after the kernel is shut down.
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 02/13] arm64: Add back cpu reset routines
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

Commit 68234df4ea79 ("arm64: kill flush_cache_all()") removed the global
arm64 routines cpu_reset() and cpu_soft_restart() needed by the arm64
kexec and kdump support.  Add simplified versions of those two routines
back with some changes needed for kexec in the new files cpu_reset.S,
and cpu_reset.h.

When a CPU is reset it needs to be put into the exception level it had when
it entered the kernel. Update cpu_soft_restart() to accept an argument
which signals if the reset address needs to be entered at EL1 or EL2, and
add a new hypercall HVC_SOFT_RESTART which is used for the EL2 switch.

Signed-off-by: Geoff Levand <geoff@infradead.org>
Reviewed-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/virt.h |  5 ++++
 arch/arm64/kernel/cpu-reset.S | 54 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cpu-reset.h | 34 +++++++++++++++++++++++++++
 arch/arm64/kernel/hyp-stub.S  | 10 +++++++-
 4 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kernel/cpu-reset.S
 create mode 100644 arch/arm64/kernel/cpu-reset.h

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index dcbcf8d..bbc6a8c 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -34,6 +34,11 @@
  */
 #define HVC_SET_VECTORS 1
 
+/*
+ * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
+ */
+#define HVC_SOFT_RESTART 2
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
new file mode 100644
index 0000000..65f42d2
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -0,0 +1,54 @@
+/*
+ * CPU reset routines
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 Huawei Futurewei Technologies.
+ *
+ * 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 <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/sysreg.h>
+#include <asm/virt.h>
+
+.text
+.pushsection    .idmap.text, "ax"
+
+/*
+ * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for
+ * cpu_soft_restart.
+ *
+ * @el2_switch: Flag to indicate a swich to EL2 is needed.
+ * @entry: Location to jump to for soft reset.
+ * arg0: First argument passed to @entry.
+ * arg1: Second argument passed to @entry.
+ * arg2: Third argument passed to @entry.
+ *
+ * Put the CPU into the same state as it would be if it had been reset, and
+ * branch to what would be the reset vector. It must be executed with the
+ * flat identity mapping.
+ */
+ENTRY(__cpu_soft_restart)
+	/* Clear sctlr_el1 flags. */
+	mrs	x12, sctlr_el1
+	ldr	x13, =SCTLR_ELx_FLAGS
+	bic	x12, x12, x13
+	msr	sctlr_el1, x12
+	isb
+
+	cbz	x0, 1f				// el2_switch?
+	mov	x0, #HVC_SOFT_RESTART
+	hvc	#0				// no return
+
+1:	mov	x18, x1				// entry
+	mov	x0, x2				// arg0
+	mov	x1, x3				// arg1
+	mov	x2, x4				// arg2
+	br	x18
+ENDPROC(__cpu_soft_restart)
+
+.popsection
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
new file mode 100644
index 0000000..d4e9ecb
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -0,0 +1,34 @@
+/*
+ * CPU reset routines
+ *
+ * Copyright (C) 2015 Huawei Futurewei Technologies.
+ *
+ * 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.
+ */
+
+#ifndef _ARM64_CPU_RESET_H
+#define _ARM64_CPU_RESET_H
+
+#include <asm/virt.h>
+
+void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
+	unsigned long arg0, unsigned long arg1, unsigned long arg2);
+
+static inline void __noreturn cpu_soft_restart(unsigned long el2_switch,
+	unsigned long entry, unsigned long arg0, unsigned long arg1,
+	unsigned long arg2)
+{
+	typeof(__cpu_soft_restart) *restart;
+
+	el2_switch = el2_switch && !is_kernel_in_hyp_mode() &&
+		is_hyp_mode_available();
+	restart = (void *)virt_to_phys(__cpu_soft_restart);
+
+	cpu_install_idmap();
+	restart(el2_switch, entry, arg0, arg1, arg2);
+	unreachable();
+}
+
+#endif
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 8727f44..d3b5f75 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -71,8 +71,16 @@ el1_sync:
 	msr	vbar_el2, x1
 	b	9f
 
+2:	cmp	x0, #HVC_SOFT_RESTART
+	b.ne	3f
+	mov	x0, x2
+	mov	x2, x4
+	mov	x4, x1
+	mov	x1, x3
+	br	x4				// no return
+
 	/* Someone called kvm_call_hyp() against the hyp-stub... */
-2:	mov     x0, #ARM_EXCEPTION_HYP_GONE
+3:	mov	x0, #ARM_EXCEPTION_HYP_GONE
 
 9:	eret
 ENDPROC(el1_sync)
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 04/13] arm64/kexec: Enable kexec in the arm64 defconfig
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd2d74d..4ed4756 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -70,6 +70,7 @@ CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_XEN=y
+CONFIG_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
 CONFIG_CPU_IDLE=y
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 00/13] arm64 kexec kernel patches
@ 2016-06-16 23:48 ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

This series adds the core support for kexec re-boot and kdump on ARM64.  This
version of the series combines Takahiro's kdump patches with my kexec patches.
Please consider all patches for inclusion.

Takahiro has done some extensive testing for this version with various
configurations af endian, image format, memory options and layouts, etc.

To load a second stage kernel and execute a kexec re-boot or to work with kdump
on ARM64 systems a series of patches to kexec-tools [2], which have not yet been
merged upstream, are needed.  Please update to the latest if you have been using
an older version.

To examine vmcore (/proc/vmcore), you should use
  - gdb v7.7 or later
  - crash v7.1.1 or later.
    For crash KASLR/CONFIG_RANDOMIZE_BASE support see [3].

[1]  https://git.kernel.org/cgit/linux/kernel/git/geoff/linux-kexec.git
[2]  https://git.kernel.org/cgit/linux/kernel/git/geoff/kexec-tools.git
[3]  https://www.redhat.com/archives/crash-utility/2016-May/msg00078.html

Changes for v19 (June 16, 2016, 25m):

  o Rebase to Linux-4.7-rc3.
  o Added more VMCOREINFO's (VA_BITS, PHYS_OFFSET).
  o Remove some unneeded included files.
  o Remove kmap() usage.
  o Remove kexec_is_dtb() routine.
  o Change #ifdef to IS_ENABLED(CONFIG_HOTPLUG_CPU).
  o Fix kexec_list_flush() to flush all list entries.
  o Use ENTRY(arm64_relocate_new_kernel).
  o Remove unused segment start in arm64_relocate_new_kernel.

Changes for v18 (June 9, 2016, 25m):

  o Rebase to Linux-4.7-rc2.
  o Change ret to br in __cpu_soft_restart().
  o Add cpu_install_idmap() call and hyp checks to cpu_soft_restart().
  o Don't return from HVC_SOFT_RESTART.

Changes for v17 (June 9, 2016, 25m):

  o Rebase to Linux-4.7-rc2.
  o Change ret to br in __cpu_soft_restart().
  o Add cpu_install_idmap() call to cpu_soft_restart().

Changes for v17 (June 3, 2016, 25m):

  o Rebase to Linux-4.7-rc1.
  o Added one VMCOREINFO parameter to vmcore for crash utility.
  o Added a check for CPUs stuck in kernel.
  o Re-implemented cpu_soft_restart() to be executed only in hyp-stub.
  o Added some kernel documentation about added device tree properties.
  o Fixed a returned value of pstate in crash_setup_regs(). Now return
    a faked pstate since we have no way to get the current pstate.

Changes for v16 (Apr 14, 2016, 23m):

  o Rebase to Linux-4.6-rc3.
  o Don't try to explicitly enter EL2 at machine_kexec() when VHE in use
  o Add unreachable() in case of ipi_cpu_crash_stop()
  o Add more "#ifdef" to eliminate code unused when !CONFIG_KEXEC_CORE
  o Fix a build error around ipi_cpu_crash_stop() when !CONFIG_HOTPLUG_CPU
  o Revert "arm64: Add new hcall HVC_CALL_FUNC"
  o Revert "Convert hcalls to use HVC immediate value"
    (replaced by James' "hyp/kvm: Extend hyp-stub API to allow function calls
     at EL2")

  Modified by James:
  o Add missing icache maintenance + isb to __kvm_hyp_reset()
  o Rework kvm cpu hotplug for VHE

  Added by James:
  o arm64: head.S: el2_setup() to accept sctlr_el1 as an argument
  o arm64: hyp/kvm: Extend hyp-stub API to allow function calls at EL2
  o arm64: kvm: Move lr save/restore from do_el2_call into EL1
  o arm64: kvm: Move the do_el2_call macro to a header file

Changes for v15 (Mar 14, 2016, 22m):

  o Rebase to Linux-4.5.
  o Remove DEBUG conditional in 'Add pr_debug output'.

Changes for v14 (Mar 4, 2016, 22m):

  o Rebase to Linux-4.5-rc6.
  o Rename setup_mm_for_reboot to cpu_install_idmap.
  o kdump: leave non-boot cpus online at crash dump
    As we don't have to make non-boot (crashed) cpus offline at crash dump,
    this patch adds a variant of smp_send_stop().
  o kdump: use a new device-tree property, "linux,elfcorehdr", instead of
    traditional "elfcorehdr=" kernel parameter
  o limit memory regions based on DT property, "usable-memory", instead of
    "mem=" kernel parameter
  o kdump: fix a build error when !CONFIG_KEXEC_CORE
  o kvm: use generic kvm_call_hyp() interface instead of kvm_cpu_reset()
  o kvm: initialize only a primary cpu at init_hyp_mode()

Changes for v13 (Jan 15, 2016, 20m):

  o Rebase to Linux-4.4.
  o Remove align directive from cpu_reset.c.
  o Use inline C wrapper for cpu_soft_restart.
  o Revert the new image d-cache flush changes of v10.
  o Add SCTLR cleanup patch.
  o Change pr_devel to pr_debug.
  o Call flush_icache_range() for reboot_code_buffer.
  o Add .ltorg directive to arm64_relocate_new_kernel.
  o Make new asm macro copy_page.
  o Change cache maintenence from inner-shareable to non-shareable.
  o Rename KEXEC_ARCH_ARM64 to KEXEC_ARCH_AARCH64.

  o arm64: kvm: allows kvm cpu hotplug
    - remove some garbage code from kvm_host.h
  o arm64: kdump: reserve memory for crash dump kernel
    - change CONFIG_KEXEC to CONFIG_KEXEC_CORE
    - don't panic on crash kernel alloc failure
      (thanks to Mark Salter, RH)
  o arm64: kdump: implement machine_crash_shutdown()
    - change "boot/non-boot cpu" to "crashing/non-crashing cpu"
    - introduce is_in_crash_kexec() for readability
    - re-introduce machine_kexec_mask_interrupts(), as arch/arm has,
      to discard unexpected interrupts
    - call crash_save_cpu() before making cpus offline to avoid a possible race
      (thanks to Pratyush Anand/Mark Salter, RH)
  o arm64: kdump: update a kernel doc
    - clarify that we support "Image" format as well as vmlinux in kdump.txt
  o arm64: kdump: relax BUG_ON() if more than one cpus are still active
    - change a warning message at the failure of shooting down non-crahsing cpus

Changes for v12 (Nov 24, 2015, 18m):

  o No changes, rebase to Linux-4.4-rc2.

Changes for v11 (Nov 6, 2015, 18m):

  o Rebase to Linux-4.3.
  o Move the new image d-cache flush from arm64_relocate_new_kernel to machine_kexec.
  o Pass values to arm64_relocate_new_kernel in registers, not in global variables.
  o Fixups to setting the sctlr_el1 and sctlr_el2 flags.

Changes for v10 (Oct 18, 2015, 17m):

  o Rebase to Linux-4.3-rc6.
  o Move tcr_set_idmap_t0sz to assembler.h.
  o Add back simplified cpu_reset routines.
  o Combine kexec + kdump patches.

Changes for v9 (Apr 7, 2015, 11m):

  o Use new upstream flag IND_FLAGS.

Changes for v8 (Mar 19, 2015, 10m):

  o Rebase to Linux-4.0-rc4.
  o Re-boot using purgatory only.

Changes for v7 (Jan 16, 2015, 8m):

  o Rebase to Linux-3.19-rc4.
  o Change from ESR_EL2_ to ESR_ELx_.
  o Remove work-arounds for EFI systems.
  
Changes for v6 (Dec 2, 2014, 7m):

  o Rebase to Linux-3.18-rc2

Changes for v5 (Nov 16, 2014, 6m):

Changes for v4 (Oct 3, 2014, 5m):

Changes for v3 (Sept 23, 2014, 4m):

Changes for v2 (Sep 9, 2014, 4m):

  o Rebase to Linux-3.17-rc4.
  o Move macros from proc-macros.S to assembler.h.
  o Convert hcalls to use ISS field.
  o Add new hcall HVC_CALL_FUNC.
  o Add EL2 switch to soft_restart.

First submission v1 (May 13, 2014):

  o Based on Linux-3.15-rc4.

-Geoff

The following changes since commit 5edb56491d4812c42175980759da53388e5d86f5:

  Linux 4.7-rc3 (2016-06-12 07:20:35 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geoff/linux-kexec.git kexec-v19

for you to fetch changes up to eedcb4f4fde3530a1a6745bf18a716330e077eba:

  Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec (2016-06-16 16:23:29 -0700)

----------------------------------------------------------------
AKASHI Takahiro (7):
      arm64: kdump: reserve memory for crash dump kernel
      arm64: limit memory regions based on DT property, usable-memory
      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

Geoff Levand (4):
      arm64: Add back cpu reset routines
      arm64/kexec: Add core kexec support
      arm64/kexec: Enable kexec in the arm64 defconfig
      arm64/kexec: Add pr_debug output

James Morse (2):
      arm64: Add cpus_are_stuck_in_kernel
      Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec

 Documentation/devicetree/bindings/chosen.txt |  28 +++
 Documentation/kdump/kdump.txt                |  15 +-
 arch/arm64/Kconfig                           |  21 ++
 arch/arm64/configs/defconfig                 |   2 +
 arch/arm64/include/asm/hardirq.h             |   2 +-
 arch/arm64/include/asm/kexec.h               |  87 ++++++++
 arch/arm64/include/asm/smp.h                 |  14 ++
 arch/arm64/include/asm/virt.h                |   5 +
 arch/arm64/kernel/Makefile                   |   3 +
 arch/arm64/kernel/cpu-reset.S                |  54 +++++
 arch/arm64/kernel/cpu-reset.h                |  34 ++++
 arch/arm64/kernel/crash_dump.c               |  71 +++++++
 arch/arm64/kernel/hyp-stub.S                 |  10 +-
 arch/arm64/kernel/machine_kexec.c            | 291 +++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S          | 130 ++++++++++++
 arch/arm64/kernel/setup.c                    |   7 +-
 arch/arm64/kernel/smp.c                      |  66 ++++++
 arch/arm64/mm/init.c                         | 154 ++++++++++++++
 include/uapi/linux/kexec.h                   |   1 +
 19 files changed, 991 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/include/asm/kexec.h
 create mode 100644 arch/arm64/kernel/cpu-reset.S
 create mode 100644 arch/arm64/kernel/cpu-reset.h
 create mode 100644 arch/arm64/kernel/crash_dump.c
 create mode 100644 arch/arm64/kernel/machine_kexec.c
 create mode 100644 arch/arm64/kernel/relocate_kernel.S

-- 
2.5.0


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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 01/13] arm64: Add cpus_are_stuck_in_kernel
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: James Morse <james.morse@arm.com>

kernel/smp.c has a fancy counter that keeps track of the number of CPUs
it marked as not-present and left in cpu_park_loop(). If there are any
CPUs spinning in here, kexec will release them once the memory is re-used
by the new kernel.

Provide a function to expose whether this counter is non-zero, so we can
use this when loading a new kexec image, and when calling machine_kexec().

Signed-off-by: James Morse <james.morse@arm.com>
[Split off from a larger patch]
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/include/asm/smp.h | 10 ++++++++++
 arch/arm64/kernel/smp.c      |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 433e504..38712f4 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -124,6 +124,16 @@ static inline void cpu_panic_kernel(void)
 	cpu_park_loop();
 }
 
+/*
+ * If a secondary CPU fails to come online, (e.g. due to mismatched features),
+ * it will try to call cpu_die(). If this fails, it updates
+ * cpus_stuck_in_kernel and sits in cpu_park_loop().
+ *
+ * Kexec checks this counter and refuses to load/kexec if it is non-zero, as
+ * cpu_park_loop() would be overwritten releasing the parked cpus.
+ */
+bool cpus_are_stuck_in_kernel(void);
+
 #endif /* ifndef __ASSEMBLY__ */
 
 #endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 678e084..d0bcd55 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -909,3 +909,8 @@ int setup_profiling_timer(unsigned int multiplier)
 {
 	return -EINVAL;
 }
+
+bool cpus_are_stuck_in_kernel(void)
+{
+	return !!cpus_stuck_in_kernel;
+}
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 03/13] arm64/kexec: Add core kexec support
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

Add three new files, kexec.h, machine_kexec.c and relocate_kernel.S to the
arm64 architecture that add support for the kexec re-boot mechanism
(CONFIG_KEXEC) on arm64 platforms.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/Kconfig                  |  10 ++
 arch/arm64/include/asm/kexec.h      |  48 ++++++++++
 arch/arm64/kernel/Makefile          |   2 +
 arch/arm64/kernel/machine_kexec.c   | 182 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S | 130 ++++++++++++++++++++++++++
 include/uapi/linux/kexec.h          |   1 +
 6 files changed, 373 insertions(+)
 create mode 100644 arch/arm64/include/asm/kexec.h
 create mode 100644 arch/arm64/kernel/machine_kexec.c
 create mode 100644 arch/arm64/kernel/relocate_kernel.S

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5a0a691..330786d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -664,6 +664,16 @@ config PARAVIRT_TIME_ACCOUNTING
 
 	  If in doubt, say N here.
 
+config KEXEC
+	depends on PM_SLEEP_SMP
+	select KEXEC_CORE
+	bool "kexec system call"
+	---help---
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is independent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
 config XEN_DOM0
 	def_bool y
 	depends on XEN
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
new file mode 100644
index 0000000..04744dc
--- /dev/null
+++ b/arch/arm64/include/asm/kexec.h
@@ -0,0 +1,48 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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.
+ */
+
+#ifndef _ARM64_KEXEC_H
+#define _ARM64_KEXEC_H
+
+/* Maximum physical address we can use pages from */
+
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control code buffer */
+
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+#define KEXEC_CONTROL_PAGE_SIZE 4096
+
+#define KEXEC_ARCH KEXEC_ARCH_AARCH64
+
+#ifndef __ASSEMBLY__
+
+/**
+ * crash_setup_regs() - save registers for the panic kernel
+ *
+ * @newregs: registers are saved here
+ * @oldregs: registers to be saved (may be %NULL)
+ */
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+				    struct pt_regs *oldregs)
+{
+	/* Empty routine needed to avoid build errors. */
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2173149..7700c0c 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -46,6 +46,8 @@ arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
 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
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
new file mode 100644
index 0000000..a6dcb9c
--- /dev/null
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -0,0 +1,182 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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 <linux/kexec.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cpu_ops.h>
+#include <asm/mmu_context.h>
+
+#include "cpu-reset.h"
+
+/* Global variables for the arm64_relocate_new_kernel routine. */
+extern const unsigned char arm64_relocate_new_kernel[];
+extern const unsigned long arm64_relocate_new_kernel_size;
+
+static unsigned long kimage_start;
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+	/* Empty routine needed to avoid build errors. */
+}
+
+/**
+ * machine_kexec_prepare - Prepare for a kexec reboot.
+ *
+ * Called from the core kexec code when a kernel image is loaded.
+ * Forbid loading a kexec kernel if we have no way of hotplugging cpus or cpus
+ * are stuck in the kernel. This avoids a panic once we hit machine_kexec().
+ */
+int machine_kexec_prepare(struct kimage *kimage)
+{
+	kimage_start = kimage->start;
+
+	if (kimage->type != KEXEC_TYPE_CRASH) {
+		if (cpus_are_stuck_in_kernel()) {
+			pr_err("Can't kexec: failed CPUs are stuck in the kernel.\n");
+			return -EBUSY;
+		}
+
+		if (num_online_cpus() > 1) {
+			if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
+				/* any_cpu as we don't mind being preempted */
+				int any_cpu = raw_smp_processor_id();
+
+				if (cpu_ops[any_cpu]->cpu_die)
+					return 0;
+			}
+
+			pr_err("Can't kexec: no mechanism to offline secondary CPUs.\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * kexec_list_flush - Helper to flush the kimage list and source pages to PoC.
+ */
+static void kexec_list_flush(struct kimage *kimage)
+{
+	kimage_entry_t *entry;
+
+	for (entry = &kimage->head; ; entry++) {
+		unsigned int flag;
+		void *addr;
+
+		__flush_dcache_area(entry, sizeof(kimage_entry_t));
+
+		flag = *entry & IND_FLAGS;
+		if (flag == IND_DONE)
+			break;
+
+		addr = phys_to_virt(*entry & PAGE_MASK);
+
+		switch (flag) {
+		case IND_INDIRECTION:
+			/* Set entry point just before the new list page. */
+			entry = (kimage_entry_t *)addr - 1;
+		case IND_SOURCE:
+			__flush_dcache_area(addr, PAGE_SIZE);
+			break;
+		case IND_DESTINATION:
+			break;
+		default:
+			BUG();
+		}
+	}
+}
+
+/**
+ * kexec_segment_flush - Helper to flush the kimage segments to PoC.
+ */
+static void kexec_segment_flush(const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_debug("%s:\n", __func__);
+
+	for (i = 0; i < kimage->nr_segments; i++) {
+		pr_debug("  segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+			i,
+			kimage->segment[i].mem,
+			kimage->segment[i].mem + kimage->segment[i].memsz,
+			kimage->segment[i].memsz,
+			kimage->segment[i].memsz /  PAGE_SIZE);
+
+		__flush_dcache_area(phys_to_virt(kimage->segment[i].mem),
+			kimage->segment[i].memsz);
+	}
+}
+
+/**
+ * machine_kexec - Do the kexec reboot.
+ *
+ * Called from the core kexec code for a sys_reboot with LINUX_REBOOT_CMD_KEXEC.
+ */
+void machine_kexec(struct kimage *kimage)
+{
+	phys_addr_t reboot_code_buffer_phys;
+	void *reboot_code_buffer;
+
+	/*
+	 * New cpus may have become stuck_in_kernel after we loaded the image.
+	 */
+	BUG_ON(cpus_are_stuck_in_kernel() && (num_online_cpus() > 1));
+
+	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
+	reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
+
+	/*
+	 * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use
+	 * after the kernel is shut down.
+	 */
+	memcpy(reboot_code_buffer, arm64_relocate_new_kernel,
+		arm64_relocate_new_kernel_size);
+
+	/* Flush the reboot_code_buffer in preparation for its execution. */
+	__flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size);
+	flush_icache_range((uintptr_t)reboot_code_buffer,
+		arm64_relocate_new_kernel_size);
+
+	/* Flush the kimage list. */
+	kexec_list_flush(kimage);
+
+	/* Flush the new image if already in place. */
+	if (kimage->head & IND_DONE)
+		kexec_segment_flush(kimage);
+
+	pr_info("Bye!\n");
+
+	/* Disable all DAIF exceptions. */
+	asm volatile ("msr daifset, #0xf" : : : "memory");
+
+	/*
+	 * cpu_soft_restart will shutdown the MMU, disable data caches, then
+	 * transfer control to the reboot_code_buffer which contains a copy of
+	 * the arm64_relocate_new_kernel routine.  arm64_relocate_new_kernel
+	 * uses physical addressing to relocate the new image to its final
+	 * position and transfers control to the image entry point when the
+	 * relocation is complete.
+	 */
+
+	cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
+		kimage_start, 0);
+
+	BUG(); /* Should never get here. */
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* Empty routine needed to avoid build errors. */
+}
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
new file mode 100644
index 0000000..51b73cd
--- /dev/null
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -0,0 +1,130 @@
+/*
+ * kexec for arm64
+ *
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ *
+ * 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 <linux/kexec.h>
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/kexec.h>
+#include <asm/page.h>
+#include <asm/sysreg.h>
+
+/*
+ * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
+ *
+ * The memory that the old kernel occupies may be overwritten when coping the
+ * new image to its final location.  To assure that the
+ * arm64_relocate_new_kernel routine which does that copy is not overwritten,
+ * all code and data needed by arm64_relocate_new_kernel must be between the
+ * symbols arm64_relocate_new_kernel and arm64_relocate_new_kernel_end.  The
+ * machine_kexec() routine will copy arm64_relocate_new_kernel to the kexec
+ * control_code_page, a special page which has been set up to be preserved
+ * during the copy operation.
+ */
+ENTRY(arm64_relocate_new_kernel)
+
+	/* Setup the list loop variables. */
+	mov	x17, x1				/* x17 = kimage_start */
+	mov	x16, x0				/* x16 = kimage_head */
+	dcache_line_size x15, x0		/* x15 = dcache line size */
+	mov	x14, xzr			/* x14 = entry ptr */
+	mov	x13, xzr			/* x13 = copy dest */
+
+	/* Clear the sctlr_el2 flags. */
+	mrs	x0, CurrentEL
+	cmp	x0, #CurrentEL_EL2
+	b.ne	1f
+	mrs	x0, sctlr_el2
+	ldr	x1, =SCTLR_ELx_FLAGS
+	bic	x0, x0, x1
+	msr	sctlr_el2, x0
+	isb
+1:
+
+	/* Check if the new image needs relocation. */
+	tbnz	x16, IND_DONE_BIT, .Ldone
+
+.Lloop:
+	and	x12, x16, PAGE_MASK		/* x12 = addr */
+
+	/* Test the entry flags. */
+.Ltest_source:
+	tbz	x16, IND_SOURCE_BIT, .Ltest_indirection
+
+	/* Invalidate dest page to PoC. */
+	mov     x0, x13
+	add     x20, x0, #PAGE_SIZE
+	sub     x1, x15, #1
+	bic     x0, x0, x1
+2:	dc      ivac, x0
+	add     x0, x0, x15
+	cmp     x0, x20
+	b.lo    2b
+	dsb     sy
+
+	mov x20, x13
+	mov x21, x12
+	copy_page x20, x21, x0, x1, x2, x3, x4, x5, x6, x7
+
+	/* dest += PAGE_SIZE */
+	add	x13, x13, PAGE_SIZE
+	b	.Lnext
+
+.Ltest_indirection:
+	tbz	x16, IND_INDIRECTION_BIT, .Ltest_destination
+
+	/* ptr = addr */
+	mov	x14, x12
+	b	.Lnext
+
+.Ltest_destination:
+	tbz	x16, IND_DESTINATION_BIT, .Lnext
+
+	/* dest = addr */
+	mov	x13, x12
+
+.Lnext:
+	/* entry = *ptr++ */
+	ldr	x16, [x14], #8
+
+	/* while (!(entry & DONE)) */
+	tbz	x16, IND_DONE_BIT, .Lloop
+
+.Ldone:
+	/* wait for writes from copy_page to finish */
+	dsb	nsh
+	ic	iallu
+	dsb	nsh
+	isb
+
+	/* Start new image. */
+	mov	x0, xzr
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+	br	x17
+
+ENDPROC(arm64_relocate_new_kernel)
+
+.ltorg
+
+.align 3	/* To keep the 64-bit values below naturally aligned. */
+
+.Lcopy_end:
+.org	KEXEC_CONTROL_PAGE_SIZE
+
+/*
+ * arm64_relocate_new_kernel_size - Number of bytes to copy to the
+ * control_code_page.
+ */
+.globl arm64_relocate_new_kernel_size
+arm64_relocate_new_kernel_size:
+	.quad	.Lcopy_end - arm64_relocate_new_kernel
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 99048e5..aae5ebf 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -39,6 +39,7 @@
 #define KEXEC_ARCH_SH      (42 << 16)
 #define KEXEC_ARCH_MIPS_LE (10 << 16)
 #define KEXEC_ARCH_MIPS    ( 8 << 16)
+#define KEXEC_ARCH_AARCH64 (183 << 16)
 
 /* The artificial cap on the number of segments passed to kexec_load. */
 #define KEXEC_SEGMENT_MAX 16
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 08/13] arm64: kdump: implement machine_crash_shutdown()
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 arch/arm64/include/asm/hardirq.h  |  2 +-
 arch/arm64/include/asm/kexec.h    | 41 +++++++++++++++++++++++++-
 arch/arm64/include/asm/smp.h      |  4 +++
 arch/arm64/kernel/machine_kexec.c | 56 +++++++++++++++++++++++++++++++++--
 arch/arm64/kernel/smp.c           | 61 +++++++++++++++++++++++++++++++++++++++
 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 <linux/threads.h>
 #include <asm/irq.h>
 
-#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"
+			"stp	x10,  x11, [%2, #16 *  5]\n"
+			"stp	x12,  x13, [%2, #16 *  6]\n"
+			"stp	x14,  x15, [%2, #16 *  7]\n"
+			"stp	x16,  x17, [%2, #16 *  8]\n"
+			"stp	x18,  x19, [%2, #16 *  9]\n"
+			"stp	x20,  x21, [%2, #16 * 10]\n"
+			"stp	x22,  x23, [%2, #16 * 11]\n"
+			"stp	x24,  x25, [%2, #16 * 12]\n"
+			"stp	x26,  x27, [%2, #16 * 13]\n"
+			"stp	x28,  x29, [%2, #16 * 14]\n"
+			"mov	 %0,  sp\n"
+			"stp	x30,  %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 38712f4..979154a 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -134,6 +134,10 @@ static inline void cpu_panic_kernel(void)
  */
 bool cpus_are_stuck_in_kernel(void);
 
+#ifdef CONFIG_KEXEC_CORE
+extern void smp_send_crash_stop(void);
+#endif
+
 #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 7372e58..f270967 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 <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/kexec.h>
 #include <linux/smp.h>
 #include <linux/uaccess.h>
@@ -23,6 +26,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;
 
 /**
@@ -161,7 +165,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);
@@ -218,13 +223,58 @@ void machine_kexec(struct kimage *kimage)
 	 * relocation is complete.
 	 */
 
-	cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
+	cpu_soft_restart(!in_crash_kexec, reboot_code_buffer_phys, kimage->head,
 		kimage_start, 0);
 
 	BUG(); /* Should never get here. */
 }
 
+static void machine_kexec_mask_interrupts(void)
+{
+	unsigned int i;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int ret;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		/*
+		 * First try to remove the active state. If this
+		 * fails, try to EOI the interrupt.
+		 */
+		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+
+		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
+		    chip->irq_eoi)
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
+
+/**
+ * machine_crash_shutdown - shutdown non-crashing cpus and save registers
+ */
 void machine_crash_shutdown(struct pt_regs *regs)
 {
-	/* Empty routine needed to avoid build errors. */
+	local_irq_disable();
+
+	in_crash_kexec = true;
+
+	/* shutdown non-crashing cpus */
+	smp_send_crash_stop();
+
+	/* for crashing cpu */
+	crash_save_cpu(regs, smp_processor_id());
+	machine_kexec_mask_interrupts();
+
+	pr_info("Starting crashdump kernel...\n");
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d0bcd55..f6461ef 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -37,6 +37,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/kexec.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -71,6 +72,7 @@ enum ipi_msg_type {
 	IPI_RESCHEDULE,
 	IPI_CALL_FUNC,
 	IPI_CPU_STOP,
+	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
 	IPI_WAKEUP
@@ -726,6 +728,7 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
 	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
 	S(IPI_CALL_FUNC, "Function call interrupts"),
 	S(IPI_CPU_STOP, "CPU stop interrupts"),
+	S(IPI_CPU_CRASH_STOP, "CPU stop (for crash dump) interrupts"),
 	S(IPI_TIMER, "Timer broadcast interrupts"),
 	S(IPI_IRQ_WORK, "IRQ work interrupts"),
 	S(IPI_WAKEUP, "CPU wake-up interrupts"),
@@ -800,6 +803,28 @@ static void ipi_cpu_stop(unsigned int cpu)
 		cpu_relax();
 }
 
+#ifdef CONFIG_KEXEC_CORE
+static atomic_t waiting_for_crash_ipi;
+
+static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+{
+	crash_save_cpu(regs, cpu);
+
+	atomic_dec(&waiting_for_crash_ipi);
+
+	local_irq_disable();
+
+#ifdef CONFIG_HOTPLUG_CPU
+	if (cpu_ops[cpu]->cpu_die)
+		cpu_ops[cpu]->cpu_die(cpu);
+#endif
+
+	/* just in case */
+	while (1)
+		wfi();
+}
+#endif
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -830,6 +855,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		irq_exit();
 		break;
 
+#ifdef CONFIG_KEXEC_CORE
+	case IPI_CPU_CRASH_STOP:
+		irq_enter();
+		ipi_cpu_crash_stop(cpu, regs);
+
+		unreachable();
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 	case IPI_TIMER:
 		irq_enter();
@@ -902,6 +935,34 @@ void smp_send_stop(void)
 			   cpumask_pr_args(cpu_online_mask));
 }
 
+#ifdef CONFIG_KEXEC_CORE
+void smp_send_crash_stop(void)
+{
+	cpumask_t mask;
+	unsigned long timeout;
+
+	if (num_online_cpus() == 1)
+		return;
+
+	cpumask_copy(&mask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &mask);
+
+	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+
+	pr_crit("SMP: stopping secondary CPUs\n");
+	smp_cross_call(&mask, IPI_CPU_CRASH_STOP);
+
+	/* Wait up to one second for other CPUs to stop */
+	timeout = USEC_PER_SEC;
+	while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
+		udelay(1);
+
+	if (atomic_read(&waiting_for_crash_ipi) > 0)
+		pr_warning("SMP: failed to stop secondary CPUs %*pbl\n",
+			   cpumask_pr_args(cpu_online_mask));
+}
+#endif
+
 /*
  * not supported here
  */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 marked
as "Crash kernel" in /proc/iomem.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/arm64/kernel/setup.c |  7 +++++-
 arch/arm64/mm/init.c      | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 3279def..e411957 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -31,7 +31,6 @@
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
-#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
@@ -222,6 +221,12 @@ static void __init request_standard_resources(void)
 		    kernel_data.end <= res->end)
 			request_resource(res, &kernel_data);
 	}
+
+#ifdef CONFIG_KEXEC_CORE
+	/* User space tools will find "Crash kernel" region in /proc/iomem. */
+	if (crashk_res.end)
+		insert_resource(&iomem_resource, &crashk_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 d45f862..45f1319 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -34,6 +34,7 @@
 #include <linux/dma-contiguous.h>
 #include <linux/efi.h>
 #include <linux/swiotlb.h>
+#include <linux/kexec.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
 early_param("initrd", early_initrd);
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+/*
+ * reserve_crashkernel() - reserves memory for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long crash_size = 0, crash_base = 0;
+	int ret;
+
+	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
+				&crash_size, &crash_base);
+	/* no crashkernel= or invalid value specified */
+	if (!crash_size)
+		return;
+
+	if (crash_base == 0) {
+		/* Current arm64 boot protocol requires 2MB alignment */
+		crash_base = memblock_find_in_range(0,
+				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
+		if (crash_base == 0) {
+			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
+				crash_size);
+			return;
+		}
+		memblock_reserve(crash_base, crash_size);
+
+	} 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 aligned\n");
+			return;
+		}
+
+		memblock_reserve(crash_base, crash_size);
+	}
+
+	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
+		crash_size >> 20, crash_base >> 20);
+
+	crashk_res.start = crash_base;
+	crashk_res.end = crash_base + crash_size - 1;
+}
+#else
+static void __init reserve_crashkernel(void)
+{
+	;
+}
+#endif /* CONFIG_KEXEC_CORE */
+
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
 	}
 #endif
 
+	reserve_crashkernel();
+
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 12/13] arm64: kdump: update a kernel doc
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

This patch adds arch specific descriptions about kdump usage on arm64
to kdump.txt.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 Documentation/kdump/kdump.txt | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 88ff63d..5d6da09 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,12 @@ Dump-capture kernel config options (Arch Dependent, arm)
 
     AUTO_ZRELADDR=y
 
+Dump-capture kernel config options (Arch Dependent, arm64)
+----------------------------------------------------------
+
+1) Currently, kvm will not be enabled on the dump-capture kernel even
+   if it is configured.
+
 Extended crashkernel syntax
 ===========================
 
@@ -305,6 +311,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 (0x200000).
 
 Load the Dump-capture Kernel
 ============================
@@ -327,6 +335,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 +380,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.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 09/13] arm64: kdump: add kdump support
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 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 330786d..b5e0eb4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -674,6 +674,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 7700c0c..c13d3eb 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/
 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 0000000..2dc54d1
--- /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 <takahiro.akashi@linaro.org>
+ *
+ * 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 <linux/crash_dump.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+#include <linux/uaccess.h>
+#include <asm/memory.h>
+
+/**
+ * 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 = ioremap_cache(__pfn_to_phys(pfn), PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		if (copy_to_user(buf, vaddr + offset, csize)) {
+			iounmap(vaddr);
+			return -EFAULT;
+		}
+	} else {
+		memcpy(buf, vaddr + offset, csize);
+	}
+
+	iounmap(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 f679918..0c38528 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include <linux/efi.h>
 #include <linux/swiotlb.h>
 #include <linux/kexec.h>
+#include <linux/crash_dump.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -136,6 +137,57 @@ static void __init reserve_crashkernel(void)
 }
 #endif /* CONFIG_KEXEC_CORE */
 
+#ifdef CONFIG_CRASH_DUMP
+static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
+		const char *uname, int depth, void *data)
+{
+	const __be32 *reg;
+	int len;
+
+	if (depth != 1 || strcmp(uname, "chosen") != 0)
+		return 0;
+
+	reg = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
+	if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+		return 1;
+
+	elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &reg);
+	elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+	return 1;
+}
+
+/*
+ * reserve_elfcorehdr() - reserves memory for elf core header
+ *
+ * This function reserves elf core header given in "elfcorehdr=" kernel
+ * command line parameter. This region contains all the information about
+ * primary kernel's core image and is used by a dump capture kernel to
+ * access the system memory on primary kernel.
+ */
+static void __init reserve_elfcorehdr(void)
+{
+	of_scan_flat_dt(early_init_dt_scan_elfcorehdr, NULL);
+
+	if (!elfcorehdr_size)
+		return;
+
+	if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
+		pr_warn("elfcorehdr is overlapped\n");
+		return;
+	}
+
+	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
+
+	pr_info("Reserving %lldKB of memory@0x%llx for elfcorehdr\n",
+		elfcorehdr_size >> 10, elfcorehdr_addr);
+}
+#else
+static void __init reserve_elfcorehdr(void)
+{
+	;
+}
+#endif /* CONFIG_CRASH_DUMP */
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -391,6 +443,8 @@ void __init arm64_memblock_init(void)
 
 	reserve_crashkernel();
 
+	reserve_elfcorehdr();
+
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 11/13] arm64: kdump: enable kdump in the arm64 defconfig
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4ed4756..aa3e1dd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -71,6 +71,7 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=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.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 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 f270967..57a30fb 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -18,6 +18,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
+#include <asm/memory.h>
 #include <asm/mmu_context.h>
 
 #include "cpu-reset.h"
@@ -278,3 +279,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.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 07/13] arm64: limit memory regions based on DT property, usable-memory
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

Crash dump kernel will be run with a limited range of memory as System
RAM.

On arm64, we will use a device-tree property under /chosen,
   linux,usable-memory = <BASE SIZE>
in order for primary kernel either on uefi or non-uefi (device tree only)
system to hand over the information about usable memory region to crash
dump kernel. This property will supercede entries in uefi memory map table
and "memory" nodes in a device tree.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 arch/arm64/mm/init.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 13/13] Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec
  2016-06-16 23:48 ` Geoff Levand
@ 2016-06-16 23:48   ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: James Morse <james.morse@arm.com>

Add documentation for linux,usable-memory and linux,elfcorehdr chosen nodes
used by arm64 kexec to decribe the kdump reserved area, and the elfcorehdr's
location within it.

Signed-off-by: James Morse <james.morse@arm.com>
---
 Documentation/devicetree/bindings/chosen.txt | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt
index 6ae9d82..443f88b 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -52,3 +52,31 @@ 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,usable-memory
+-------------------
+
+This property is set on PowerPC and arm64 by kexec-tools during kdump
+to tell the crash kernel the base address of its reserved area of memory, and
+the size. e.g.
+
+/ {
+	chosen {
+		linux,usable-memory = <0x9 0xf0000000 0x0 0x10000000>;
+	};
+};
+
+linux,elfcorehdr
+----------------
+
+This property is set (currently only on arm64) by kexec-tools during kdump
+to tell the crash kernel the address and size of the elfcorehdr that describes
+the old kernel's memory as an elf file. This memory must reside within the area
+described by 'linux,usable-memory'. e.g.
+
+/ {
+	chosen {
+		linux,usable-memory = <0x9 0xf0000000 0x0 0x10000000>;
+		linux,elfcorehdr = <0x9 0xfffff000 0x0 0x800>;
+	};
+};
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 08/13] arm64: kdump: implement machine_crash_shutdown()
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 arch/arm64/include/asm/hardirq.h  |  2 +-
 arch/arm64/include/asm/kexec.h    | 41 +++++++++++++++++++++++++-
 arch/arm64/include/asm/smp.h      |  4 +++
 arch/arm64/kernel/machine_kexec.c | 56 +++++++++++++++++++++++++++++++++--
 arch/arm64/kernel/smp.c           | 61 +++++++++++++++++++++++++++++++++++++++
 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 <linux/threads.h>
 #include <asm/irq.h>
 
-#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"
+			"stp	x10,  x11, [%2, #16 *  5]\n"
+			"stp	x12,  x13, [%2, #16 *  6]\n"
+			"stp	x14,  x15, [%2, #16 *  7]\n"
+			"stp	x16,  x17, [%2, #16 *  8]\n"
+			"stp	x18,  x19, [%2, #16 *  9]\n"
+			"stp	x20,  x21, [%2, #16 * 10]\n"
+			"stp	x22,  x23, [%2, #16 * 11]\n"
+			"stp	x24,  x25, [%2, #16 * 12]\n"
+			"stp	x26,  x27, [%2, #16 * 13]\n"
+			"stp	x28,  x29, [%2, #16 * 14]\n"
+			"mov	 %0,  sp\n"
+			"stp	x30,  %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 38712f4..979154a 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -134,6 +134,10 @@ static inline void cpu_panic_kernel(void)
  */
 bool cpus_are_stuck_in_kernel(void);
 
+#ifdef CONFIG_KEXEC_CORE
+extern void smp_send_crash_stop(void);
+#endif
+
 #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 7372e58..f270967 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 <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/kexec.h>
 #include <linux/smp.h>
 #include <linux/uaccess.h>
@@ -23,6 +26,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;
 
 /**
@@ -161,7 +165,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);
@@ -218,13 +223,58 @@ void machine_kexec(struct kimage *kimage)
 	 * relocation is complete.
 	 */
 
-	cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head,
+	cpu_soft_restart(!in_crash_kexec, reboot_code_buffer_phys, kimage->head,
 		kimage_start, 0);
 
 	BUG(); /* Should never get here. */
 }
 
+static void machine_kexec_mask_interrupts(void)
+{
+	unsigned int i;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int ret;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		/*
+		 * First try to remove the active state. If this
+		 * fails, try to EOI the interrupt.
+		 */
+		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+
+		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
+		    chip->irq_eoi)
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
+
+/**
+ * machine_crash_shutdown - shutdown non-crashing cpus and save registers
+ */
 void machine_crash_shutdown(struct pt_regs *regs)
 {
-	/* Empty routine needed to avoid build errors. */
+	local_irq_disable();
+
+	in_crash_kexec = true;
+
+	/* shutdown non-crashing cpus */
+	smp_send_crash_stop();
+
+	/* for crashing cpu */
+	crash_save_cpu(regs, smp_processor_id());
+	machine_kexec_mask_interrupts();
+
+	pr_info("Starting crashdump kernel...\n");
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d0bcd55..f6461ef 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -37,6 +37,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/kexec.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -71,6 +72,7 @@ enum ipi_msg_type {
 	IPI_RESCHEDULE,
 	IPI_CALL_FUNC,
 	IPI_CPU_STOP,
+	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
 	IPI_WAKEUP
@@ -726,6 +728,7 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
 	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
 	S(IPI_CALL_FUNC, "Function call interrupts"),
 	S(IPI_CPU_STOP, "CPU stop interrupts"),
+	S(IPI_CPU_CRASH_STOP, "CPU stop (for crash dump) interrupts"),
 	S(IPI_TIMER, "Timer broadcast interrupts"),
 	S(IPI_IRQ_WORK, "IRQ work interrupts"),
 	S(IPI_WAKEUP, "CPU wake-up interrupts"),
@@ -800,6 +803,28 @@ static void ipi_cpu_stop(unsigned int cpu)
 		cpu_relax();
 }
 
+#ifdef CONFIG_KEXEC_CORE
+static atomic_t waiting_for_crash_ipi;
+
+static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+{
+	crash_save_cpu(regs, cpu);
+
+	atomic_dec(&waiting_for_crash_ipi);
+
+	local_irq_disable();
+
+#ifdef CONFIG_HOTPLUG_CPU
+	if (cpu_ops[cpu]->cpu_die)
+		cpu_ops[cpu]->cpu_die(cpu);
+#endif
+
+	/* just in case */
+	while (1)
+		wfi();
+}
+#endif
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -830,6 +855,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		irq_exit();
 		break;
 
+#ifdef CONFIG_KEXEC_CORE
+	case IPI_CPU_CRASH_STOP:
+		irq_enter();
+		ipi_cpu_crash_stop(cpu, regs);
+
+		unreachable();
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 	case IPI_TIMER:
 		irq_enter();
@@ -902,6 +935,34 @@ void smp_send_stop(void)
 			   cpumask_pr_args(cpu_online_mask));
 }
 
+#ifdef CONFIG_KEXEC_CORE
+void smp_send_crash_stop(void)
+{
+	cpumask_t mask;
+	unsigned long timeout;
+
+	if (num_online_cpus() == 1)
+		return;
+
+	cpumask_copy(&mask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &mask);
+
+	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+
+	pr_crit("SMP: stopping secondary CPUs\n");
+	smp_cross_call(&mask, IPI_CPU_CRASH_STOP);
+
+	/* Wait up to one second for other CPUs to stop */
+	timeout = USEC_PER_SEC;
+	while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
+		udelay(1);
+
+	if (atomic_read(&waiting_for_crash_ipi) > 0)
+		pr_warning("SMP: failed to stop secondary CPUs %*pbl\n",
+			   cpumask_pr_args(cpu_online_mask));
+}
+#endif
+
 /*
  * not supported here
  */
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 marked
as "Crash kernel" in /proc/iomem.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/arm64/kernel/setup.c |  7 +++++-
 arch/arm64/mm/init.c      | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 3279def..e411957 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -31,7 +31,6 @@
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
-#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
@@ -222,6 +221,12 @@ static void __init request_standard_resources(void)
 		    kernel_data.end <= res->end)
 			request_resource(res, &kernel_data);
 	}
+
+#ifdef CONFIG_KEXEC_CORE
+	/* User space tools will find "Crash kernel" region in /proc/iomem. */
+	if (crashk_res.end)
+		insert_resource(&iomem_resource, &crashk_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 d45f862..45f1319 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -34,6 +34,7 @@
 #include <linux/dma-contiguous.h>
 #include <linux/efi.h>
 #include <linux/swiotlb.h>
+#include <linux/kexec.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
 early_param("initrd", early_initrd);
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+/*
+ * reserve_crashkernel() - reserves memory for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long crash_size = 0, crash_base = 0;
+	int ret;
+
+	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
+				&crash_size, &crash_base);
+	/* no crashkernel= or invalid value specified */
+	if (!crash_size)
+		return;
+
+	if (crash_base == 0) {
+		/* Current arm64 boot protocol requires 2MB alignment */
+		crash_base = memblock_find_in_range(0,
+				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
+		if (crash_base == 0) {
+			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
+				crash_size);
+			return;
+		}
+		memblock_reserve(crash_base, crash_size);
+
+	} 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 aligned\n");
+			return;
+		}
+
+		memblock_reserve(crash_base, crash_size);
+	}
+
+	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
+		crash_size >> 20, crash_base >> 20);
+
+	crashk_res.start = crash_base;
+	crashk_res.end = crash_base + crash_size - 1;
+}
+#else
+static void __init reserve_crashkernel(void)
+{
+	;
+}
+#endif /* CONFIG_KEXEC_CORE */
+
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
 	}
 #endif
 
+	reserve_crashkernel();
+
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 09/13] arm64: kdump: add kdump support
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 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 330786d..b5e0eb4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -674,6 +674,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 7700c0c..c13d3eb 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/
 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 0000000..2dc54d1
--- /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 <takahiro.akashi@linaro.org>
+ *
+ * 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 <linux/crash_dump.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+#include <linux/uaccess.h>
+#include <asm/memory.h>
+
+/**
+ * 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 = ioremap_cache(__pfn_to_phys(pfn), PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		if (copy_to_user(buf, vaddr + offset, csize)) {
+			iounmap(vaddr);
+			return -EFAULT;
+		}
+	} else {
+		memcpy(buf, vaddr + offset, csize);
+	}
+
+	iounmap(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 f679918..0c38528 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include <linux/efi.h>
 #include <linux/swiotlb.h>
 #include <linux/kexec.h>
+#include <linux/crash_dump.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -136,6 +137,57 @@ static void __init reserve_crashkernel(void)
 }
 #endif /* CONFIG_KEXEC_CORE */
 
+#ifdef CONFIG_CRASH_DUMP
+static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
+		const char *uname, int depth, void *data)
+{
+	const __be32 *reg;
+	int len;
+
+	if (depth != 1 || strcmp(uname, "chosen") != 0)
+		return 0;
+
+	reg = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
+	if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+		return 1;
+
+	elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &reg);
+	elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+	return 1;
+}
+
+/*
+ * reserve_elfcorehdr() - reserves memory for elf core header
+ *
+ * This function reserves elf core header given in "elfcorehdr=" kernel
+ * command line parameter. This region contains all the information about
+ * primary kernel's core image and is used by a dump capture kernel to
+ * access the system memory on primary kernel.
+ */
+static void __init reserve_elfcorehdr(void)
+{
+	of_scan_flat_dt(early_init_dt_scan_elfcorehdr, NULL);
+
+	if (!elfcorehdr_size)
+		return;
+
+	if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
+		pr_warn("elfcorehdr is overlapped\n");
+		return;
+	}
+
+	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
+
+	pr_info("Reserving %lldKB of memory at 0x%llx for elfcorehdr\n",
+		elfcorehdr_size >> 10, elfcorehdr_addr);
+}
+#else
+static void __init reserve_elfcorehdr(void)
+{
+	;
+}
+#endif /* CONFIG_CRASH_DUMP */
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -391,6 +443,8 @@ void __init arm64_memblock_init(void)
 
 	reserve_crashkernel();
 
+	reserve_elfcorehdr();
+
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
-- 
2.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 12/13] arm64: kdump: update a kernel doc
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

This patch adds arch specific descriptions about kdump usage on arm64
to kdump.txt.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 Documentation/kdump/kdump.txt | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 88ff63d..5d6da09 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,12 @@ Dump-capture kernel config options (Arch Dependent, arm)
 
     AUTO_ZRELADDR=y
 
+Dump-capture kernel config options (Arch Dependent, arm64)
+----------------------------------------------------------
+
+1) Currently, kvm will not be enabled on the dump-capture kernel even
+   if it is configured.
+
 Extended crashkernel syntax
 ===========================
 
@@ -305,6 +311,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 (0x200000).
 
 Load the Dump-capture Kernel
 ============================
@@ -327,6 +335,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 +380,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.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 11/13] arm64: kdump: enable kdump in the arm64 defconfig
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4ed4756..aa3e1dd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -71,6 +71,7 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=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.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

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 <takahiro.akashi@linaro.org>
---
 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 f270967..57a30fb 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -18,6 +18,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
+#include <asm/memory.h>
 #include <asm/mmu_context.h>
 
 #include "cpu-reset.h"
@@ -278,3 +279,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.5.0



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 07/13] arm64: limit memory regions based on DT property, usable-memory
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: AKASHI Takahiro <takahiro.akashi@linaro.org>

Crash dump kernel will be run with a limited range of memory as System
RAM.

On arm64, we will use a device-tree property under /chosen,
   linux,usable-memory = <BASE SIZE>
in order for primary kernel either on uefi or non-uefi (device tree only)
system to hand over the information about usable memory region to crash
dump kernel. This property will supercede entries in uefi memory map table
and "memory" nodes in a device tree.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 arch/arm64/mm/init.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

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



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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 13/13] Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec
@ 2016-06-16 23:48   ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-16 23:48 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Mark Rutland, marc.zyngier, kexec, AKASHI Takahiro, James Morse,
	linux-arm-kernel

From: James Morse <james.morse@arm.com>

Add documentation for linux,usable-memory and linux,elfcorehdr chosen nodes
used by arm64 kexec to decribe the kdump reserved area, and the elfcorehdr's
location within it.

Signed-off-by: James Morse <james.morse@arm.com>
---
 Documentation/devicetree/bindings/chosen.txt | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt
index 6ae9d82..443f88b 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -52,3 +52,31 @@ 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,usable-memory
+-------------------
+
+This property is set on PowerPC and arm64 by kexec-tools during kdump
+to tell the crash kernel the base address of its reserved area of memory, and
+the size. e.g.
+
+/ {
+	chosen {
+		linux,usable-memory = <0x9 0xf0000000 0x0 0x10000000>;
+	};
+};
+
+linux,elfcorehdr
+----------------
+
+This property is set (currently only on arm64) by kexec-tools during kdump
+to tell the crash kernel the address and size of the elfcorehdr that describes
+the old kernel's memory as an elf file. This memory must reside within the area
+described by 'linux,usable-memory'. e.g.
+
+/ {
+	chosen {
+		linux,usable-memory = <0x9 0xf0000000 0x0 0x10000000>;
+		linux,elfcorehdr = <0x9 0xfffff000 0x0 0x800>;
+	};
+};
-- 
2.5.0


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

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-16 23:48   ` Geoff Levand
@ 2016-06-20  5:32     ` Pratyush Anand
  -1 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-20  5:32 UTC (permalink / raw)
  To: linux-arm-kernel

+Atsushi

Hi Takahiro,

On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> 
> 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.

Thanks for adding them. They are quite helpful for makedumpfile as well.

> More VMCOREINFO's may be added later.

Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
in order to work with makedumpfile.

I already have makedumpfile patches [1]  which uses _text and _end, but not
sending them to makedumpfile upstream, until you will be agreeing to take [2] in
future. Please let me know your opinion about it. If it would be acceptable then
I may send aarch64 makedumpfile improvements to upstream.

[1] https://github.com/pratyushanand/makedumpfile/commit/d9590fec049976b8fee0d6b4e66e6f3e99ff1113
[2] https://github.com/pratyushanand/linux/commit/1d94df20c575c725910c9c29a129b9f14e7e900b

~Pratyush

> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
>  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 f270967..57a30fb 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -18,6 +18,7 @@
>  
>  #include <asm/cacheflush.h>
>  #include <asm/cpu_ops.h>
> +#include <asm/memory.h>
>  #include <asm/mmu_context.h>
>  
>  #include "cpu-reset.h"
> @@ -278,3 +279,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.5.0
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-20  5:32     ` Pratyush Anand
  0 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-20  5:32 UTC (permalink / raw)
  To: Geoff Levand, AKASHI Takahiro
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Atsushi Kumagai,
	Will Deacon, James Morse, kexec, linux-arm-kernel

+Atsushi

Hi Takahiro,

On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> 
> 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.

Thanks for adding them. They are quite helpful for makedumpfile as well.

> More VMCOREINFO's may be added later.

Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
in order to work with makedumpfile.

I already have makedumpfile patches [1]  which uses _text and _end, but not
sending them to makedumpfile upstream, until you will be agreeing to take [2] in
future. Please let me know your opinion about it. If it would be acceptable then
I may send aarch64 makedumpfile improvements to upstream.

[1] https://github.com/pratyushanand/makedumpfile/commit/d9590fec049976b8fee0d6b4e66e6f3e99ff1113
[2] https://github.com/pratyushanand/linux/commit/1d94df20c575c725910c9c29a129b9f14e7e900b

~Pratyush

> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
>  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 f270967..57a30fb 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -18,6 +18,7 @@
>  
>  #include <asm/cacheflush.h>
>  #include <asm/cpu_ops.h>
> +#include <asm/memory.h>
>  #include <asm/mmu_context.h>
>  
>  #include "cpu-reset.h"
> @@ -278,3 +279,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.5.0
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 03/13] arm64/kexec: Add core kexec support
  2016-06-16 23:48   ` Geoff Levand
@ 2016-06-20 15:36     ` James Morse
  -1 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Geoff,

On 17/06/16 00:48, Geoff Levand wrote:
> Add three new files, kexec.h, machine_kexec.c and relocate_kernel.S to the
> arm64 architecture that add support for the kexec re-boot mechanism
> (CONFIG_KEXEC) on arm64 platforms.

> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> new file mode 100644
> index 0000000..a6dcb9c
> --- /dev/null
> +++ b/arch/arm64/kernel/machine_kexec.c

[ ... ]

> +
> +/**
> + * kexec_list_flush - Helper to flush the kimage list and source pages to PoC.
> + */
> +static void kexec_list_flush(struct kimage *kimage)
> +{
> +	kimage_entry_t *entry;
> +
> +	for (entry = &kimage->head; ; entry++) {
> +		unsigned int flag;
> +		void *addr;
> +
> +		__flush_dcache_area(entry, sizeof(kimage_entry_t));
> +
> +		flag = *entry & IND_FLAGS;
> +		if (flag == IND_DONE)
> +			break;
> +
> +		addr = phys_to_virt(*entry & PAGE_MASK);
> +
> +		switch (flag) {
> +		case IND_INDIRECTION:
> +			/* Set entry point just before the new list page. */
> +			entry = (kimage_entry_t *)addr - 1;

Ah, after this restructuring we end up cleaning this page as we fall-through,
and one kimage_entry_t at a time as we walk the list.

			break;
?

> +		case IND_SOURCE:
> +			__flush_dcache_area(addr, PAGE_SIZE);
> +			break;
> +		case IND_DESTINATION:
> +			break;
> +		default:
> +			BUG();
> +		}
> +	}
> +}


> diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
> new file mode 100644
> index 0000000..51b73cd
> --- /dev/null
> +++ b/arch/arm64/kernel/relocate_kernel.S

[ ... ]

> +.ltorg
> +
> +.align 3	/* To keep the 64-bit values below naturally aligned. */
> +
> +.Lcopy_end:
> +.org	KEXEC_CONTROL_PAGE_SIZE


On 16/06/16 23:41, Geoff Levand wrote:
> This is to check if arm64_relocate_new_kernel gets too
> big.  The assembler should give an error if the location
> counter is set backwards.

Cunning. (probably worth a comment).

This looks like it is need because we hard-coded KEXEC_CONTROL_PAGE_SIZE in
kexec.h, so the code must be smaller than that size.
It looks like this value is only ever passed to get_order(), could we just pass
the actual size? It shouldn't matter if it grows >4K, as the core code will
allocate enough memory, and the memcpy() in machine_kexec() uses the size too.


Reviewed-by: James Morse <james.morse@arm.com>

Thanks,


James

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 03/13] arm64/kexec: Add core kexec support
@ 2016-06-20 15:36     ` James Morse
  0 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 15:36 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Will Deacon,
	AKASHI Takahiro, kexec, linux-arm-kernel

Hi Geoff,

On 17/06/16 00:48, Geoff Levand wrote:
> Add three new files, kexec.h, machine_kexec.c and relocate_kernel.S to the
> arm64 architecture that add support for the kexec re-boot mechanism
> (CONFIG_KEXEC) on arm64 platforms.

> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> new file mode 100644
> index 0000000..a6dcb9c
> --- /dev/null
> +++ b/arch/arm64/kernel/machine_kexec.c

[ ... ]

> +
> +/**
> + * kexec_list_flush - Helper to flush the kimage list and source pages to PoC.
> + */
> +static void kexec_list_flush(struct kimage *kimage)
> +{
> +	kimage_entry_t *entry;
> +
> +	for (entry = &kimage->head; ; entry++) {
> +		unsigned int flag;
> +		void *addr;
> +
> +		__flush_dcache_area(entry, sizeof(kimage_entry_t));
> +
> +		flag = *entry & IND_FLAGS;
> +		if (flag == IND_DONE)
> +			break;
> +
> +		addr = phys_to_virt(*entry & PAGE_MASK);
> +
> +		switch (flag) {
> +		case IND_INDIRECTION:
> +			/* Set entry point just before the new list page. */
> +			entry = (kimage_entry_t *)addr - 1;

Ah, after this restructuring we end up cleaning this page as we fall-through,
and one kimage_entry_t at a time as we walk the list.

			break;
?

> +		case IND_SOURCE:
> +			__flush_dcache_area(addr, PAGE_SIZE);
> +			break;
> +		case IND_DESTINATION:
> +			break;
> +		default:
> +			BUG();
> +		}
> +	}
> +}


> diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
> new file mode 100644
> index 0000000..51b73cd
> --- /dev/null
> +++ b/arch/arm64/kernel/relocate_kernel.S

[ ... ]

> +.ltorg
> +
> +.align 3	/* To keep the 64-bit values below naturally aligned. */
> +
> +.Lcopy_end:
> +.org	KEXEC_CONTROL_PAGE_SIZE


On 16/06/16 23:41, Geoff Levand wrote:
> This is to check if arm64_relocate_new_kernel gets too
> big.  The assembler should give an error if the location
> counter is set backwards.

Cunning. (probably worth a comment).

This looks like it is need because we hard-coded KEXEC_CONTROL_PAGE_SIZE in
kexec.h, so the code must be smaller than that size.
It looks like this value is only ever passed to get_order(), could we just pass
the actual size? It shouldn't matter if it grows >4K, as the core code will
allocate enough memory, and the memcpy() in machine_kexec() uses the size too.


Reviewed-by: James Morse <james.morse@arm.com>

Thanks,


James


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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 05/13] arm64/kexec: Add pr_debug output
  2016-06-16 23:48   ` Geoff Levand
@ 2016-06-20 16:06     ` James Morse
  -1 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Geoff,

On 17/06/16 00:48, Geoff Levand wrote:
> To aid in debugging kexec problems or when adding new functionality to
> kexec add a new routine kexec_image_info() and several inline pr_debug
> statements.
> 
> Signed-off-by: Geoff Levand <geoff@infradead.org>

> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> index a6dcb9c..7372e58 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -11,6 +11,7 @@
>  
>  #include <linux/kexec.h>
>  #include <linux/smp.h>
> +#include <linux/uaccess.h>

Now that the get_user(maybe_dtb_addr,.. has gone, I don't think we need this header.

>  
>  #include <asm/cacheflush.h>
>  #include <asm/cpu_ops.h>


Reviewed-by: James Morse <james.morse@arm.com>


Thanks,

James

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 05/13] arm64/kexec: Add pr_debug output
@ 2016-06-20 16:06     ` James Morse
  0 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 16:06 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Will Deacon,
	AKASHI Takahiro, kexec, linux-arm-kernel

Hi Geoff,

On 17/06/16 00:48, Geoff Levand wrote:
> To aid in debugging kexec problems or when adding new functionality to
> kexec add a new routine kexec_image_info() and several inline pr_debug
> statements.
> 
> Signed-off-by: Geoff Levand <geoff@infradead.org>

> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> index a6dcb9c..7372e58 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -11,6 +11,7 @@
>  
>  #include <linux/kexec.h>
>  #include <linux/smp.h>
> +#include <linux/uaccess.h>

Now that the get_user(maybe_dtb_addr,.. has gone, I don't think we need this header.

>  
>  #include <asm/cacheflush.h>
>  #include <asm/cpu_ops.h>


Reviewed-by: James Morse <james.morse@arm.com>


Thanks,

James

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
  2016-06-16 23:48   ` Geoff Levand
@ 2016-06-20 16:07     ` James Morse
  -1 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 17/06/16 00:48, Geoff Levand wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> 
> 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 marked
> as "Crash kernel" in /proc/iomem.

> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index d45f862..45f1319 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -34,6 +34,7 @@
>  #include <linux/dma-contiguous.h>
>  #include <linux/efi.h>
>  #include <linux/swiotlb.h>
> +#include <linux/kexec.h>
>  
>  #include <asm/boot.h>
>  #include <asm/fixmap.h>
> @@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
>  early_param("initrd", early_initrd);
>  #endif
>  
> +#ifdef CONFIG_KEXEC_CORE
> +/*
> + * reserve_crashkernel() - reserves memory for crash kernel
> + *
> + * This function reserves memory area given in "crashkernel=" kernel command
> + * line parameter. The memory reserved is used by dump capture kernel when
> + * primary kernel is crashing.
> + */
> +static void __init reserve_crashkernel(void)
> +{
> +	unsigned long long crash_size = 0, crash_base = 0;
> +	int ret;
> +
> +	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> +				&crash_size, &crash_base);
> +	/* no crashkernel= or invalid value specified */
> +	if (!crash_size)
> +		return;

Should we check ret too?


> +
> +	if (crash_base == 0) {
> +		/* Current arm64 boot protocol requires 2MB alignment */
> +		crash_base = memblock_find_in_range(0,
> +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
> +		if (crash_base == 0) {
> +			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
> +				crash_size);
> +			return;
> +		}
> +		memblock_reserve(crash_base, crash_size);

What if memblock_reserve() fails?


> +
> +	} 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)) {

!IS_ALIGNED()...


> +			pr_warn("crashkernel base address is not 2MB aligned\n");
> +			return;
> +		}
> +
> +		memblock_reserve(crash_base, crash_size);

What if memblock_reserve() fails?


> +	}
> +
> +	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
> +		crash_size >> 20, crash_base >> 20);
> +
> +	crashk_res.start = crash_base;
> +	crashk_res.end = crash_base + crash_size - 1;
> +}
> +#else
> +static void __init reserve_crashkernel(void)
> +{
> +	;
> +}
> +#endif /* CONFIG_KEXEC_CORE */
> +
>  /*
>   * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
>   * currently assumes that for memory starting above 4G, 32-bit devices will
> @@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
>  	}
>  #endif
>  
> +	reserve_crashkernel();
> +
>  	early_init_fdt_scan_reserved_mem();
>  
>  	/* 4GB maximum for 32-bit only capable devices */
> 


With those,
Reviewed-by: James Morse <james.morse@arm.com>


Thanks,

James

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
@ 2016-06-20 16:07     ` James Morse
  0 siblings, 0 replies; 52+ messages in thread
From: James Morse @ 2016-06-20 16:07 UTC (permalink / raw)
  To: Geoff Levand, AKASHI Takahiro
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Will Deacon, kexec,
	linux-arm-kernel

Hi,

On 17/06/16 00:48, Geoff Levand wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> 
> 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 marked
> as "Crash kernel" in /proc/iomem.

> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index d45f862..45f1319 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -34,6 +34,7 @@
>  #include <linux/dma-contiguous.h>
>  #include <linux/efi.h>
>  #include <linux/swiotlb.h>
> +#include <linux/kexec.h>
>  
>  #include <asm/boot.h>
>  #include <asm/fixmap.h>
> @@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
>  early_param("initrd", early_initrd);
>  #endif
>  
> +#ifdef CONFIG_KEXEC_CORE
> +/*
> + * reserve_crashkernel() - reserves memory for crash kernel
> + *
> + * This function reserves memory area given in "crashkernel=" kernel command
> + * line parameter. The memory reserved is used by dump capture kernel when
> + * primary kernel is crashing.
> + */
> +static void __init reserve_crashkernel(void)
> +{
> +	unsigned long long crash_size = 0, crash_base = 0;
> +	int ret;
> +
> +	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> +				&crash_size, &crash_base);
> +	/* no crashkernel= or invalid value specified */
> +	if (!crash_size)
> +		return;

Should we check ret too?


> +
> +	if (crash_base == 0) {
> +		/* Current arm64 boot protocol requires 2MB alignment */
> +		crash_base = memblock_find_in_range(0,
> +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
> +		if (crash_base == 0) {
> +			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
> +				crash_size);
> +			return;
> +		}
> +		memblock_reserve(crash_base, crash_size);

What if memblock_reserve() fails?


> +
> +	} 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)) {

!IS_ALIGNED()...


> +			pr_warn("crashkernel base address is not 2MB aligned\n");
> +			return;
> +		}
> +
> +		memblock_reserve(crash_base, crash_size);

What if memblock_reserve() fails?


> +	}
> +
> +	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
> +		crash_size >> 20, crash_base >> 20);
> +
> +	crashk_res.start = crash_base;
> +	crashk_res.end = crash_base + crash_size - 1;
> +}
> +#else
> +static void __init reserve_crashkernel(void)
> +{
> +	;
> +}
> +#endif /* CONFIG_KEXEC_CORE */
> +
>  /*
>   * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
>   * currently assumes that for memory starting above 4G, 32-bit devices will
> @@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
>  	}
>  #endif
>  
> +	reserve_crashkernel();
> +
>  	early_init_fdt_scan_reserved_mem();
>  
>  	/* 4GB maximum for 32-bit only capable devices */
> 


With those,
Reviewed-by: James Morse <james.morse@arm.com>


Thanks,

James


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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 03/13] arm64/kexec: Add core kexec support
  2016-06-20 15:36     ` James Morse
@ 2016-06-20 16:49       ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-20 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, 2016-06-20 at 16:36 +0100, James Morse wrote:
> +> 	> 	> switch (flag) {
> > +> > 	> > 	> > case IND_INDIRECTION:
> > +> > 	> > 	> > 	> > /* Set entry point just before the new list page. */
> > +> > 	> > 	> > 	> > entry = (kimage_entry_t *)addr - 1;
> 
> Ah, after this restructuring we end up cleaning this page as we fall-through,
> and one kimage_entry_t at a time as we walk the list.
> 
> 	> 	> 	> break;
> ?

I added this in, but that missing break shouldn't cause any problems.


> > +> > 	> > 	> > case IND_SOURCE:
> > +> > 	> > 	> > 	> > __flush_dcache_area(addr, PAGE_SIZE);
> > +> > 	> > 	> > 	> > break;
> > +> > 	> > 	> > case IND_DESTINATION:
> > +> > 	> > 	> > 	> > break;
> > +> > 	> > 	> > default:
> > +> > 	> > 	> > 	> > BUG();
> > +> > 	> > 	> > }
> > +> > 	> > }
> > +}
> 
> 
> > diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
> > new file mode 100644
> > index 0000000..51b73cd
> > --- /dev/null
> > +++ b/arch/arm64/kernel/relocate_kernel.S
> 
> [ ... ]
> 
> > +.ltorg
> > +
> > +.align 3> > 	> > /* To keep the 64-bit values below naturally aligned. */
> > +
> > +.Lcopy_end:
> > +.org> > 	> > KEXEC_CONTROL_PAGE_SIZE
> 
> 
> On 16/06/16 23:41, Geoff Levand wrote:
> > This is to check if arm64_relocate_new_kernel gets too
> > big.  The assembler should give an error if the location
> > counter is set backwards.
> 
> Cunning. (probably worth a comment).

I thought this was the standard way to do it...

> This looks like it is need because we hard-coded KEXEC_CONTROL_PAGE_SIZE in
> kexec.h, so the code must be smaller than that size.
> It looks like this value is only ever passed to get_order(), could we just pass
> the actual size? It shouldn't matter if it grows >4K, as the core code will
> allocate enough memory, and the memcpy() in machine_kexec() uses the size too.

I thought 4K would be enough, but if some debugging code is
added it could get too big.

> Reviewed-by: James Morse <james.morse@arm.com>

Thanks for your comments.

-Geoff

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 03/13] arm64/kexec: Add core kexec support
@ 2016-06-20 16:49       ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-20 16:49 UTC (permalink / raw)
  To: James Morse
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Will Deacon,
	AKASHI Takahiro, kexec, linux-arm-kernel

Hi,

On Mon, 2016-06-20 at 16:36 +0100, James Morse wrote:
> +> 	> 	> switch (flag) {
> > +> > 	> > 	> > case IND_INDIRECTION:
> > +> > 	> > 	> > 	> > /* Set entry point just before the new list page. */
> > +> > 	> > 	> > 	> > entry = (kimage_entry_t *)addr - 1;
> 
> Ah, after this restructuring we end up cleaning this page as we fall-through,
> and one kimage_entry_t at a time as we walk the list.
> 
> 	> 	> 	> break;
> ?

I added this in, but that missing break shouldn't cause any problems.


> > +> > 	> > 	> > case IND_SOURCE:
> > +> > 	> > 	> > 	> > __flush_dcache_area(addr, PAGE_SIZE);
> > +> > 	> > 	> > 	> > break;
> > +> > 	> > 	> > case IND_DESTINATION:
> > +> > 	> > 	> > 	> > break;
> > +> > 	> > 	> > default:
> > +> > 	> > 	> > 	> > BUG();
> > +> > 	> > 	> > }
> > +> > 	> > }
> > +}
> 
> 
> > diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
> > new file mode 100644
> > index 0000000..51b73cd
> > --- /dev/null
> > +++ b/arch/arm64/kernel/relocate_kernel.S
> 
> [ ... ]
> 
> > +.ltorg
> > +
> > +.align 3> > 	> > /* To keep the 64-bit values below naturally aligned. */
> > +
> > +.Lcopy_end:
> > +.org> > 	> > KEXEC_CONTROL_PAGE_SIZE
> 
> 
> On 16/06/16 23:41, Geoff Levand wrote:
> > This is to check if arm64_relocate_new_kernel gets too
> > big.  The assembler should give an error if the location
> > counter is set backwards.
> 
> Cunning. (probably worth a comment).

I thought this was the standard way to do it...

> This looks like it is need because we hard-coded KEXEC_CONTROL_PAGE_SIZE in
> kexec.h, so the code must be smaller than that size.
> It looks like this value is only ever passed to get_order(), could we just pass
> the actual size? It shouldn't matter if it grows >4K, as the core code will
> allocate enough memory, and the memcpy() in machine_kexec() uses the size too.

I thought 4K would be enough, but if some debugging code is
added it could get too big.

> Reviewed-by: James Morse <james.morse@arm.com>

Thanks for your comments.

-Geoff

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 05/13] arm64/kexec: Add pr_debug output
  2016-06-20 16:06     ` James Morse
@ 2016-06-20 16:50       ` Geoff Levand
  -1 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-20 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2016-06-20 at 17:06 +0100, James Morse wrote:
> --- a/arch/arm64/kernel/machine_kexec.c
> > +++ b/arch/arm64/kernel/machine_kexec.c
> > @@ -11,6 +11,7 @@
> >  
> >  #include 
> >  #include 
> > +#include 
> 
> Now that the get_user(maybe_dtb_addr,.. has gone, I don't think we need this header.

No, we don't.  I have already fixed that in my master branch.

> >  
> >  #include 
> >  #include 
> 
> 
> Reviewed-by: James Morse <james.morse@arm.com>

Thanks again.

-Geoff

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 05/13] arm64/kexec: Add pr_debug output
@ 2016-06-20 16:50       ` Geoff Levand
  0 siblings, 0 replies; 52+ messages in thread
From: Geoff Levand @ 2016-06-20 16:50 UTC (permalink / raw)
  To: James Morse
  Cc: Mark Rutland, marc.zyngier, Catalin Marinas, Will Deacon,
	AKASHI Takahiro, kexec, linux-arm-kernel

On Mon, 2016-06-20 at 17:06 +0100, James Morse wrote:
> --- a/arch/arm64/kernel/machine_kexec.c
> > +++ b/arch/arm64/kernel/machine_kexec.c
> > @@ -11,6 +11,7 @@
> >  
> >  #include 
> >  #include 
> > +#include 
> 
> Now that the get_user(maybe_dtb_addr,.. has gone, I don't think we need this header.

No, we don't.  I have already fixed that in my master branch.

> >  
> >  #include 
> >  #include 
> 
> 
> Reviewed-by: James Morse <james.morse@arm.com>

Thanks again.

-Geoff


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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
  2016-06-20 16:07     ` James Morse
@ 2016-06-21  1:23       ` AKASHI Takahiro
  -1 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-21  1:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 20, 2016 at 05:07:11PM +0100, James Morse wrote:
> Hi,
> 
> On 17/06/16 00:48, Geoff Levand wrote:
> > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > 
> > 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 marked
> > as "Crash kernel" in /proc/iomem.
> 
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index d45f862..45f1319 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -34,6 +34,7 @@
> >  #include <linux/dma-contiguous.h>
> >  #include <linux/efi.h>
> >  #include <linux/swiotlb.h>
> > +#include <linux/kexec.h>
> >  
> >  #include <asm/boot.h>
> >  #include <asm/fixmap.h>
> > @@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
> >  early_param("initrd", early_initrd);
> >  #endif
> >  
> > +#ifdef CONFIG_KEXEC_CORE
> > +/*
> > + * reserve_crashkernel() - reserves memory for crash kernel
> > + *
> > + * This function reserves memory area given in "crashkernel=" kernel command
> > + * line parameter. The memory reserved is used by dump capture kernel when
> > + * primary kernel is crashing.
> > + */
> > +static void __init reserve_crashkernel(void)
> > +{
> > +	unsigned long long crash_size = 0, crash_base = 0;
> > +	int ret;
> > +
> > +	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> > +				&crash_size, &crash_base);
> > +	/* no crashkernel= or invalid value specified */
> > +	if (!crash_size)
> > +		return;
> 
> Should we check ret too?

I thought that it was almost OK, but there is the only erroneous case,
"crashkernel=SIZE@". Will fix it.

> 
> > +
> > +	if (crash_base == 0) {
> > +		/* Current arm64 boot protocol requires 2MB alignment */
> > +		crash_base = memblock_find_in_range(0,
> > +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
> > +		if (crash_base == 0) {
> > +			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
> > +				crash_size);
> > +			return;
> > +		}
> > +		memblock_reserve(crash_base, crash_size);
> 
> What if memblock_reserve() fails?

I don't think it fails because the region has been allocated
by memblock_find_in_range() just before.
> 
> > +
> > +	} 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)) {
> 
> !IS_ALIGNED()...

Oops, will fix it.

> 
> > +			pr_warn("crashkernel base address is not 2MB aligned\n");
> > +			return;
> > +		}
> > +
> > +		memblock_reserve(crash_base, crash_size);
> 
> What if memblock_reserve() fails?

The region has been checked with memblock_is_region_reserved().

> 
> > +	}
> > +
> > +	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
> > +		crash_size >> 20, crash_base >> 20);
> > +
> > +	crashk_res.start = crash_base;
> > +	crashk_res.end = crash_base + crash_size - 1;
> > +}
> > +#else
> > +static void __init reserve_crashkernel(void)
> > +{
> > +	;
> > +}
> > +#endif /* CONFIG_KEXEC_CORE */
> > +
> >  /*
> >   * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
> >   * currently assumes that for memory starting above 4G, 32-bit devices will
> > @@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
> >  	}
> >  #endif
> >  
> > +	reserve_crashkernel();
> > +
> >  	early_init_fdt_scan_reserved_mem();
> >  
> >  	/* 4GB maximum for 32-bit only capable devices */
> > 
> 
> 
> With those,
> Reviewed-by: James Morse <james.morse@arm.com>

Thanks,
-Takahiro AKASHI

> 
> Thanks,
> 
> James
> 

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel
@ 2016-06-21  1:23       ` AKASHI Takahiro
  0 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-21  1:23 UTC (permalink / raw)
  To: James Morse
  Cc: Mark Rutland, Geoff Levand, Catalin Marinas, Will Deacon,
	marc.zyngier, kexec, linux-arm-kernel

On Mon, Jun 20, 2016 at 05:07:11PM +0100, James Morse wrote:
> Hi,
> 
> On 17/06/16 00:48, Geoff Levand wrote:
> > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > 
> > 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 marked
> > as "Crash kernel" in /proc/iomem.
> 
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index d45f862..45f1319 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -34,6 +34,7 @@
> >  #include <linux/dma-contiguous.h>
> >  #include <linux/efi.h>
> >  #include <linux/swiotlb.h>
> > +#include <linux/kexec.h>
> >  
> >  #include <asm/boot.h>
> >  #include <asm/fixmap.h>
> > @@ -76,6 +77,65 @@ static int __init early_initrd(char *p)
> >  early_param("initrd", early_initrd);
> >  #endif
> >  
> > +#ifdef CONFIG_KEXEC_CORE
> > +/*
> > + * reserve_crashkernel() - reserves memory for crash kernel
> > + *
> > + * This function reserves memory area given in "crashkernel=" kernel command
> > + * line parameter. The memory reserved is used by dump capture kernel when
> > + * primary kernel is crashing.
> > + */
> > +static void __init reserve_crashkernel(void)
> > +{
> > +	unsigned long long crash_size = 0, crash_base = 0;
> > +	int ret;
> > +
> > +	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> > +				&crash_size, &crash_base);
> > +	/* no crashkernel= or invalid value specified */
> > +	if (!crash_size)
> > +		return;
> 
> Should we check ret too?

I thought that it was almost OK, but there is the only erroneous case,
"crashkernel=SIZE@". Will fix it.

> 
> > +
> > +	if (crash_base == 0) {
> > +		/* Current arm64 boot protocol requires 2MB alignment */
> > +		crash_base = memblock_find_in_range(0,
> > +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, SZ_2M);
> > +		if (crash_base == 0) {
> > +			pr_warn("Unable to allocate crashkernel (size:%llx)\n",
> > +				crash_size);
> > +			return;
> > +		}
> > +		memblock_reserve(crash_base, crash_size);
> 
> What if memblock_reserve() fails?

I don't think it fails because the region has been allocated
by memblock_find_in_range() just before.
> 
> > +
> > +	} 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)) {
> 
> !IS_ALIGNED()...

Oops, will fix it.

> 
> > +			pr_warn("crashkernel base address is not 2MB aligned\n");
> > +			return;
> > +		}
> > +
> > +		memblock_reserve(crash_base, crash_size);
> 
> What if memblock_reserve() fails?

The region has been checked with memblock_is_region_reserved().

> 
> > +	}
> > +
> > +	pr_info("Reserving %lldMB of memory at %lldMB for crashkernel\n",
> > +		crash_size >> 20, crash_base >> 20);
> > +
> > +	crashk_res.start = crash_base;
> > +	crashk_res.end = crash_base + crash_size - 1;
> > +}
> > +#else
> > +static void __init reserve_crashkernel(void)
> > +{
> > +	;
> > +}
> > +#endif /* CONFIG_KEXEC_CORE */
> > +
> >  /*
> >   * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
> >   * currently assumes that for memory starting above 4G, 32-bit devices will
> > @@ -291,6 +351,8 @@ void __init arm64_memblock_init(void)
> >  	}
> >  #endif
> >  
> > +	reserve_crashkernel();
> > +
> >  	early_init_fdt_scan_reserved_mem();
> >  
> >  	/* 4GB maximum for 32-bit only capable devices */
> > 
> 
> 
> With those,
> Reviewed-by: James Morse <james.morse@arm.com>

Thanks,
-Takahiro AKASHI

> 
> Thanks,
> 
> James
> 

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-20  5:32     ` Pratyush Anand
@ 2016-06-22  5:59       ` AKASHI Takahiro
  -1 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-22  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> +Atsushi
> 
> Hi Takahiro,
> 
> On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > 
> > 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.
> 
> Thanks for adding them. They are quite helpful for makedumpfile as well.
> 
> > More VMCOREINFO's may be added later.
> 
> Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> in order to work with makedumpfile.

I know that adding those symbols is the easiest way, but
theoretically, if we know the physical address of "swapper_pg_dir",
instead of its virtual address, we can access all the memory pointed to
by any kernel virtual address.
How do you rationalize that we need to know "_text" and "_end"?

Thanks,
-Takahiro AKASHI

> I already have makedumpfile patches [1]  which uses _text and _end, but not
> sending them to makedumpfile upstream, until you will be agreeing to take [2] in
> future. Please let me know your opinion about it. If it would be acceptable then
> I may send aarch64 makedumpfile improvements to upstream.
> 
> [1] https://github.com/pratyushanand/makedumpfile/commit/d9590fec049976b8fee0d6b4e66e6f3e99ff1113
> [2] https://github.com/pratyushanand/linux/commit/1d94df20c575c725910c9c29a129b9f14e7e900b
> 
> ~Pratyush
> 
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  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 f270967..57a30fb 100644
> > --- a/arch/arm64/kernel/machine_kexec.c
> > +++ b/arch/arm64/kernel/machine_kexec.c
> > @@ -18,6 +18,7 @@
> >  
> >  #include <asm/cacheflush.h>
> >  #include <asm/cpu_ops.h>
> > +#include <asm/memory.h>
> >  #include <asm/mmu_context.h>
> >  
> >  #include "cpu-reset.h"
> > @@ -278,3 +279,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.5.0
> > 
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-22  5:59       ` AKASHI Takahiro
  0 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-22  5:59 UTC (permalink / raw)
  To: Pratyush Anand
  Cc: Mark Rutland, Geoff Levand, Catalin Marinas, Atsushi Kumagai,
	Will Deacon, marc.zyngier, James Morse, kexec, linux-arm-kernel

On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> +Atsushi
> 
> Hi Takahiro,
> 
> On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > 
> > 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.
> 
> Thanks for adding them. They are quite helpful for makedumpfile as well.
> 
> > More VMCOREINFO's may be added later.
> 
> Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> in order to work with makedumpfile.

I know that adding those symbols is the easiest way, but
theoretically, if we know the physical address of "swapper_pg_dir",
instead of its virtual address, we can access all the memory pointed to
by any kernel virtual address.
How do you rationalize that we need to know "_text" and "_end"?

Thanks,
-Takahiro AKASHI

> I already have makedumpfile patches [1]  which uses _text and _end, but not
> sending them to makedumpfile upstream, until you will be agreeing to take [2] in
> future. Please let me know your opinion about it. If it would be acceptable then
> I may send aarch64 makedumpfile improvements to upstream.
> 
> [1] https://github.com/pratyushanand/makedumpfile/commit/d9590fec049976b8fee0d6b4e66e6f3e99ff1113
> [2] https://github.com/pratyushanand/linux/commit/1d94df20c575c725910c9c29a129b9f14e7e900b
> 
> ~Pratyush
> 
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  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 f270967..57a30fb 100644
> > --- a/arch/arm64/kernel/machine_kexec.c
> > +++ b/arch/arm64/kernel/machine_kexec.c
> > @@ -18,6 +18,7 @@
> >  
> >  #include <asm/cacheflush.h>
> >  #include <asm/cpu_ops.h>
> > +#include <asm/memory.h>
> >  #include <asm/mmu_context.h>
> >  
> >  #include "cpu-reset.h"
> > @@ -278,3 +279,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.5.0
> > 
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-22  5:59       ` AKASHI Takahiro
@ 2016-06-23  7:14         ` Pratyush Anand
  -1 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-23  7:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Takahiro,

Thanks for your reply.

On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > +Atsushi
> > 
> > Hi Takahiro,
> > 
> > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > 
> > > 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.
> > 
> > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > 
> > > More VMCOREINFO's may be added later.
> > 
> > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > in order to work with makedumpfile.
> 
> I know that adding those symbols is the easiest way, but
> theoretically, if we know the physical address of "swapper_pg_dir",

But, we know only it's virtual address. 

> instead of its virtual address, we can access all the memory pointed to
> by any kernel virtual address.
> How do you rationalize that we need to know "_text" and "_end"?

Well, we need some mechanism so that we can decide if an address can be
translated using linear mapping of virt_to_phys(). 

Alternatively, probably we can do like this:
-- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
 + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
 dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
-- PTE values may lie out side this range, however that address should still be
linearly translatable. We can use virt_to_phys() macro from them as well.

In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
and rest all can be translated using page table entries.

~Pratyush

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-23  7:14         ` Pratyush Anand
  0 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-23  7:14 UTC (permalink / raw)
  To: AKASHI Takahiro, Geoff Levand, Catalin Marinas, Will Deacon,
	Mark Rutland, marc.zyngier, kexec, James Morse, linux-arm-kernel,
	Atsushi Kumagai

Hi Takahiro,

Thanks for your reply.

On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > +Atsushi
> > 
> > Hi Takahiro,
> > 
> > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > 
> > > 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.
> > 
> > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > 
> > > More VMCOREINFO's may be added later.
> > 
> > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > in order to work with makedumpfile.
> 
> I know that adding those symbols is the easiest way, but
> theoretically, if we know the physical address of "swapper_pg_dir",

But, we know only it's virtual address. 

> instead of its virtual address, we can access all the memory pointed to
> by any kernel virtual address.
> How do you rationalize that we need to know "_text" and "_end"?

Well, we need some mechanism so that we can decide if an address can be
translated using linear mapping of virt_to_phys(). 

Alternatively, probably we can do like this:
-- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
 + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
 dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
-- PTE values may lie out side this range, however that address should still be
linearly translatable. We can use virt_to_phys() macro from them as well.

In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
and rest all can be translated using page table entries.

~Pratyush

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-23  7:14         ` Pratyush Anand
@ 2016-06-23  8:42           ` AKASHI Takahiro
  -1 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-23  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> Hi Takahiro,
> 
> Thanks for your reply.
> 
> On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > +Atsushi
> > > 
> > > Hi Takahiro,
> > > 
> > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > 
> > > > 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.
> > > 
> > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > 
> > > > More VMCOREINFO's may be added later.
> > > 
> > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > in order to work with makedumpfile.
> > 
> > I know that adding those symbols is the easiest way, but
> > theoretically, if we know the physical address of "swapper_pg_dir",
> 
> But, we know only it's virtual address. 

What I meant here is that, if we know the physical address of "swapper_pg_dir",
we don't have to know neither of "_text", "_end", "kimage_voffset" nor
"PHYS_OFFSET".
I just wanted to ask you whether you thought of this possibility.
> 
> > instead of its virtual address, we can access all the memory pointed to
> > by any kernel virtual address.
> > How do you rationalize that we need to know "_text" and "_end"?
> 
> Well, we need some mechanism so that we can decide if an address can be
> translated using linear mapping of virt_to_phys(). 

All the entries in MMU tables are based on "physical" addresses,
and so we don't care whether a given address is in linear mapping or not
in walking through MMU.
See what I mean?

Thanks,
-Takahiro AKASHI

> Alternatively, probably we can do like this:
> -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
>  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
>  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> -- PTE values may lie out side this range, however that address should still be
> linearly translatable. We can use virt_to_phys() macro from them as well.
> 
> In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> and rest all can be translated using page table entries.
> 
> ~Pratyush

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-23  8:42           ` AKASHI Takahiro
  0 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-23  8:42 UTC (permalink / raw)
  To: Pratyush Anand
  Cc: Mark Rutland, Geoff Levand, Catalin Marinas, Atsushi Kumagai,
	Will Deacon, marc.zyngier, James Morse, kexec, linux-arm-kernel

On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> Hi Takahiro,
> 
> Thanks for your reply.
> 
> On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > +Atsushi
> > > 
> > > Hi Takahiro,
> > > 
> > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > 
> > > > 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.
> > > 
> > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > 
> > > > More VMCOREINFO's may be added later.
> > > 
> > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > in order to work with makedumpfile.
> > 
> > I know that adding those symbols is the easiest way, but
> > theoretically, if we know the physical address of "swapper_pg_dir",
> 
> But, we know only it's virtual address. 

What I meant here is that, if we know the physical address of "swapper_pg_dir",
we don't have to know neither of "_text", "_end", "kimage_voffset" nor
"PHYS_OFFSET".
I just wanted to ask you whether you thought of this possibility.
> 
> > instead of its virtual address, we can access all the memory pointed to
> > by any kernel virtual address.
> > How do you rationalize that we need to know "_text" and "_end"?
> 
> Well, we need some mechanism so that we can decide if an address can be
> translated using linear mapping of virt_to_phys(). 

All the entries in MMU tables are based on "physical" addresses,
and so we don't care whether a given address is in linear mapping or not
in walking through MMU.
See what I mean?

Thanks,
-Takahiro AKASHI

> Alternatively, probably we can do like this:
> -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
>  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
>  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> -- PTE values may lie out side this range, however that address should still be
> linearly translatable. We can use virt_to_phys() macro from them as well.
> 
> In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> and rest all can be translated using page table entries.
> 
> ~Pratyush

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-23  8:42           ` AKASHI Takahiro
@ 2016-06-23 15:46             ` Pratyush Anand
  -1 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-23 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 23/06/2016:05:42:28 PM, AKASHI Takahiro wrote:
> On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> > Hi Takahiro,
> > 
> > Thanks for your reply.
> > 
> > On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > > +Atsushi
> > > > 
> > > > Hi Takahiro,
> > > > 
> > > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > > 
> > > > > 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.
> > > > 
> > > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > > 
> > > > > More VMCOREINFO's may be added later.
> > > > 
> > > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > > in order to work with makedumpfile.
> > > 
> > > I know that adding those symbols is the easiest way, but
> > > theoretically, if we know the physical address of "swapper_pg_dir",
> > 
> > But, we know only it's virtual address. 
> 
> What I meant here is that, if we know the physical address of "swapper_pg_dir",
> we don't have to know neither of "_text", "_end", "kimage_voffset" nor
> "PHYS_OFFSET".
> I just wanted to ask you whether you thought of this possibility.

OK, Let me clarify the needs from makedumpfile perspective. Atsushi can correct
me if I am wrong:

- As a minimal we need some way of reading page table entries. Currently vmcore
  has only virtual address of swapper_pg_dir, but if you can provide
  __pa(swapper_pg_dir) in vmcore, then we do not need either "_text", "_end" or
  "kimage_voffset". 
- However, "PHYS_OFFSET" might still be needed. makedumpfile core code needs to
  know phys_base. Currently we find it from the PT_LOAD segments. We treat the
  lowest start of segment's LMAs as the physical base. I am not sure, if that is
  still true with latest KASAN changes.
- Further, if you do not provide "_text" and "_end", then we will have to translate
  each address with complex page table read process, which would slow
  makedumpfile execution significantly.

Now, please let us know that what will be the kernel strategy, so that I can
re-organise makedumpfile accordingly.

> > 
> > > instead of its virtual address, we can access all the memory pointed to
> > > by any kernel virtual address.
> > > How do you rationalize that we need to know "_text" and "_end"?
> > 
> > Well, we need some mechanism so that we can decide if an address can be
> > translated using linear mapping of virt_to_phys(). 
> 
> All the entries in MMU tables are based on "physical" addresses,
> and so we don't care whether a given address is in linear mapping or not
> in walking through MMU.
> See what I mean?

Yes, yes, I thought, we have only virtual swapper_pg_dir, so I was looking for a
way to translate *atleast* that into physical.

Thanks for your input. Those are helpful.

~Pratyush

> 
> Thanks,
> -Takahiro AKASHI
> 
> > Alternatively, probably we can do like this:
> > -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
> >  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
> >  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> > -- PTE values may lie out side this range, however that address should still be
> > linearly translatable. We can use virt_to_phys() macro from them as well.
> > 
> > In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> > and rest all can be translated using page table entries.
> > 
> > ~Pratyush

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-23 15:46             ` Pratyush Anand
  0 siblings, 0 replies; 52+ messages in thread
From: Pratyush Anand @ 2016-06-23 15:46 UTC (permalink / raw)
  To: AKASHI Takahiro, Atsushi Kumagai
  Cc: Mark Rutland, Geoff Levand, Catalin Marinas, Will Deacon,
	marc.zyngier, James Morse, kexec, linux-arm-kernel

On 23/06/2016:05:42:28 PM, AKASHI Takahiro wrote:
> On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> > Hi Takahiro,
> > 
> > Thanks for your reply.
> > 
> > On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > > +Atsushi
> > > > 
> > > > Hi Takahiro,
> > > > 
> > > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > > 
> > > > > 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.
> > > > 
> > > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > > 
> > > > > More VMCOREINFO's may be added later.
> > > > 
> > > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > > in order to work with makedumpfile.
> > > 
> > > I know that adding those symbols is the easiest way, but
> > > theoretically, if we know the physical address of "swapper_pg_dir",
> > 
> > But, we know only it's virtual address. 
> 
> What I meant here is that, if we know the physical address of "swapper_pg_dir",
> we don't have to know neither of "_text", "_end", "kimage_voffset" nor
> "PHYS_OFFSET".
> I just wanted to ask you whether you thought of this possibility.

OK, Let me clarify the needs from makedumpfile perspective. Atsushi can correct
me if I am wrong:

- As a minimal we need some way of reading page table entries. Currently vmcore
  has only virtual address of swapper_pg_dir, but if you can provide
  __pa(swapper_pg_dir) in vmcore, then we do not need either "_text", "_end" or
  "kimage_voffset". 
- However, "PHYS_OFFSET" might still be needed. makedumpfile core code needs to
  know phys_base. Currently we find it from the PT_LOAD segments. We treat the
  lowest start of segment's LMAs as the physical base. I am not sure, if that is
  still true with latest KASAN changes.
- Further, if you do not provide "_text" and "_end", then we will have to translate
  each address with complex page table read process, which would slow
  makedumpfile execution significantly.

Now, please let us know that what will be the kernel strategy, so that I can
re-organise makedumpfile accordingly.

> > 
> > > instead of its virtual address, we can access all the memory pointed to
> > > by any kernel virtual address.
> > > How do you rationalize that we need to know "_text" and "_end"?
> > 
> > Well, we need some mechanism so that we can decide if an address can be
> > translated using linear mapping of virt_to_phys(). 
> 
> All the entries in MMU tables are based on "physical" addresses,
> and so we don't care whether a given address is in linear mapping or not
> in walking through MMU.
> See what I mean?

Yes, yes, I thought, we have only virtual swapper_pg_dir, so I was looking for a
way to translate *atleast* that into physical.

Thanks for your input. Those are helpful.

~Pratyush

> 
> Thanks,
> -Takahiro AKASHI
> 
> > Alternatively, probably we can do like this:
> > -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
> >  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
> >  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> > -- PTE values may lie out side this range, however that address should still be
> > linearly translatable. We can use virt_to_phys() macro from them as well.
> > 
> > In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> > and rest all can be translated using page table entries.
> > 
> > ~Pratyush

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
  2016-06-23 15:46             ` Pratyush Anand
@ 2016-06-30  0:44               ` AKASHI Takahiro
  -1 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-30  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

Pratyush,

On Thu, Jun 23, 2016 at 09:16:24PM +0530, Pratyush Anand wrote:
> On 23/06/2016:05:42:28 PM, AKASHI Takahiro wrote:
> > On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> > > Hi Takahiro,
> > > 
> > > Thanks for your reply.
> > > 
> > > On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > > > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > > > +Atsushi
> > > > > 
> > > > > Hi Takahiro,
> > > > > 
> > > > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > > > 
> > > > > > 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.
> > > > > 
> > > > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > > > 
> > > > > > More VMCOREINFO's may be added later.
> > > > > 
> > > > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > > > in order to work with makedumpfile.
> > > > 
> > > > I know that adding those symbols is the easiest way, but
> > > > theoretically, if we know the physical address of "swapper_pg_dir",
> > > 
> > > But, we know only it's virtual address. 
> > 
> > What I meant here is that, if we know the physical address of "swapper_pg_dir",
> > we don't have to know neither of "_text", "_end", "kimage_voffset" nor
> > "PHYS_OFFSET".
> > I just wanted to ask you whether you thought of this possibility.
> 
> OK, Let me clarify the needs from makedumpfile perspective. Atsushi can correct
> me if I am wrong:
> 
> - As a minimal we need some way of reading page table entries. Currently vmcore
>   has only virtual address of swapper_pg_dir, but if you can provide
>   __pa(swapper_pg_dir) in vmcore, then we do not need either "_text", "_end" or
>   "kimage_voffset". 
> - However, "PHYS_OFFSET" might still be needed. makedumpfile core code needs to
>   know phys_base. Currently we find it from the PT_LOAD segments. We treat the
>   lowest start of segment's LMAs as the physical base. I am not sure, if that is
>   still true with latest KASAN changes.

PHYS_OFFSET is now there in patch 10/13.

> - Further, if you do not provide "_text" and "_end", then we will have to translate
>   each address with complex page table read process, which would slow
>   makedumpfile execution significantly.

I believe that this is the only reason that you want both symbols
though I don't know how much performance penalty it may cause.

> Now, please let us know that what will be the kernel strategy, so that I can
> re-organise makedumpfile accordingly.

Given that I'm not a user nor author of makedumpfile command for arm64,
as we discussed locally before, I'm now convinced that you'd better post
your own kernel patch based on your requirements as you like.

Thanks,
-Takahiro AKASHI

> > > 
> > > > instead of its virtual address, we can access all the memory pointed to
> > > > by any kernel virtual address.
> > > > How do you rationalize that we need to know "_text" and "_end"?
> > > 
> > > Well, we need some mechanism so that we can decide if an address can be
> > > translated using linear mapping of virt_to_phys(). 
> > 
> > All the entries in MMU tables are based on "physical" addresses,
> > and so we don't care whether a given address is in linear mapping or not
> > in walking through MMU.
> > See what I mean?
> 
> Yes, yes, I thought, we have only virtual swapper_pg_dir, so I was looking for a
> way to translate *atleast* that into physical.
> 
> Thanks for your input. Those are helpful.
> 
> ~Pratyush
> 
> > 
> > Thanks,
> > -Takahiro AKASHI
> > 
> > > Alternatively, probably we can do like this:
> > > -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
> > >  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
> > >  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> > > -- PTE values may lie out side this range, however that address should still be
> > > linearly translatable. We can use virt_to_phys() macro from them as well.
> > > 
> > > In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> > > and rest all can be translated using page table entries.
> > > 
> > > ~Pratyush

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools
@ 2016-06-30  0:44               ` AKASHI Takahiro
  0 siblings, 0 replies; 52+ messages in thread
From: AKASHI Takahiro @ 2016-06-30  0:44 UTC (permalink / raw)
  To: Pratyush Anand
  Cc: Mark Rutland, Geoff Levand, Catalin Marinas, Atsushi Kumagai,
	Will Deacon, marc.zyngier, James Morse, kexec, linux-arm-kernel

Pratyush,

On Thu, Jun 23, 2016 at 09:16:24PM +0530, Pratyush Anand wrote:
> On 23/06/2016:05:42:28 PM, AKASHI Takahiro wrote:
> > On Thu, Jun 23, 2016 at 12:44:12PM +0530, Pratyush Anand wrote:
> > > Hi Takahiro,
> > > 
> > > Thanks for your reply.
> > > 
> > > On 22/06/2016:02:59:41 PM, AKASHI Takahiro wrote:
> > > > On Mon, Jun 20, 2016 at 11:02:22AM +0530, Pratyush Anand wrote:
> > > > > +Atsushi
> > > > > 
> > > > > Hi Takahiro,
> > > > > 
> > > > > On 16/06/2016:11:48:28 PM, Geoff Levand wrote:
> > > > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > > > 
> > > > > > 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.
> > > > > 
> > > > > Thanks for adding them. They are quite helpful for makedumpfile as well.
> > > > > 
> > > > > > More VMCOREINFO's may be added later.
> > > > > 
> > > > > Yes, we will need to pass VMCOREINFO_SYMBOL(_text) and VMCOREINFO_SYMBOL(_end)
> > > > > in order to work with makedumpfile.
> > > > 
> > > > I know that adding those symbols is the easiest way, but
> > > > theoretically, if we know the physical address of "swapper_pg_dir",
> > > 
> > > But, we know only it's virtual address. 
> > 
> > What I meant here is that, if we know the physical address of "swapper_pg_dir",
> > we don't have to know neither of "_text", "_end", "kimage_voffset" nor
> > "PHYS_OFFSET".
> > I just wanted to ask you whether you thought of this possibility.
> 
> OK, Let me clarify the needs from makedumpfile perspective. Atsushi can correct
> me if I am wrong:
> 
> - As a minimal we need some way of reading page table entries. Currently vmcore
>   has only virtual address of swapper_pg_dir, but if you can provide
>   __pa(swapper_pg_dir) in vmcore, then we do not need either "_text", "_end" or
>   "kimage_voffset". 
> - However, "PHYS_OFFSET" might still be needed. makedumpfile core code needs to
>   know phys_base. Currently we find it from the PT_LOAD segments. We treat the
>   lowest start of segment's LMAs as the physical base. I am not sure, if that is
>   still true with latest KASAN changes.

PHYS_OFFSET is now there in patch 10/13.

> - Further, if you do not provide "_text" and "_end", then we will have to translate
>   each address with complex page table read process, which would slow
>   makedumpfile execution significantly.

I believe that this is the only reason that you want both symbols
though I don't know how much performance penalty it may cause.

> Now, please let us know that what will be the kernel strategy, so that I can
> re-organise makedumpfile accordingly.

Given that I'm not a user nor author of makedumpfile command for arm64,
as we discussed locally before, I'm now convinced that you'd better post
your own kernel patch based on your requirements as you like.

Thanks,
-Takahiro AKASHI

> > > 
> > > > instead of its virtual address, we can access all the memory pointed to
> > > > by any kernel virtual address.
> > > > How do you rationalize that we need to know "_text" and "_end"?
> > > 
> > > Well, we need some mechanism so that we can decide if an address can be
> > > translated using linear mapping of virt_to_phys(). 
> > 
> > All the entries in MMU tables are based on "physical" addresses,
> > and so we don't care whether a given address is in linear mapping or not
> > in walking through MMU.
> > See what I mean?
> 
> Yes, yes, I thought, we have only virtual swapper_pg_dir, so I was looking for a
> way to translate *atleast* that into physical.
> 
> Thanks for your input. Those are helpful.
> 
> ~Pratyush
> 
> > 
> > Thanks,
> > -Takahiro AKASHI
> > 
> > > Alternatively, probably we can do like this:
> > > -- Translate all address between "SYMBOL(swapper_pg_dir)"  and "SYMBOL(swapper_pg_dir)
> > >  + SWAPPER_DIR_SIZE" using virt_to_phys() and now we can read values from
> > >  dumpfile using that physical address. This way we can get PGD/PMD/PUD values.
> > > -- PTE values may lie out side this range, however that address should still be
> > > linearly translatable. We can use virt_to_phys() macro from them as well.
> > > 
> > > In summary, we can translate address of PGD/PMD/PUD/PTE using virt_to_phys()
> > > and rest all can be translated using page table entries.
> > > 
> > > ~Pratyush

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

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2016-06-30  0:44 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-16 23:48 [PATCH v19 00/13] arm64 kexec kernel patches Geoff Levand
2016-06-16 23:48 ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 05/13] arm64/kexec: Add pr_debug output Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-20 16:06   ` James Morse
2016-06-20 16:06     ` James Morse
2016-06-20 16:50     ` Geoff Levand
2016-06-20 16:50       ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 02/13] arm64: Add back cpu reset routines Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 04/13] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 01/13] arm64: Add cpus_are_stuck_in_kernel Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 03/13] arm64/kexec: Add core kexec support Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-20 15:36   ` James Morse
2016-06-20 15:36     ` James Morse
2016-06-20 16:49     ` Geoff Levand
2016-06-20 16:49       ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 11/13] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 13/13] Documentation: dt: usable-memory and elfcorehdr nodes for arm64 kexec Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 12/13] arm64: kdump: update a kernel doc Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 10/13] arm64: kdump: add VMCOREINFO's for user-space coredump tools Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-20  5:32   ` Pratyush Anand
2016-06-20  5:32     ` Pratyush Anand
2016-06-22  5:59     ` AKASHI Takahiro
2016-06-22  5:59       ` AKASHI Takahiro
2016-06-23  7:14       ` Pratyush Anand
2016-06-23  7:14         ` Pratyush Anand
2016-06-23  8:42         ` AKASHI Takahiro
2016-06-23  8:42           ` AKASHI Takahiro
2016-06-23 15:46           ` Pratyush Anand
2016-06-23 15:46             ` Pratyush Anand
2016-06-30  0:44             ` AKASHI Takahiro
2016-06-30  0:44               ` AKASHI Takahiro
2016-06-16 23:48 ` [PATCH v19 07/13] arm64: limit memory regions based on DT property, usable-memory Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 08/13] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-16 23:48 ` [PATCH v19 06/13] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
2016-06-16 23:48   ` Geoff Levand
2016-06-20 16:07   ` James Morse
2016-06-20 16:07     ` James Morse
2016-06-21  1:23     ` AKASHI Takahiro
2016-06-21  1:23       ` AKASHI Takahiro
2016-06-16 23:48 ` [PATCH v19 09/13] arm64: kdump: add kdump support Geoff Levand
2016-06-16 23:48   ` Geoff Levand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.