linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v15 00/20] arm64 kexec kernel patches v15
@ 2016-03-14 17:47 Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 07/20] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file Geoff Levand
                   ` (20 more replies)
  0 siblings, 21 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:47 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.

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

[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

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 b562e44f507e863c6792946e4e1b1449fbbac85d:

  Linux 4.5 (2016-03-13 21:28:54 -0700)

are available in the git repository at:

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

for you to fetch changes up to 906d185a6451d3349669bcf4b080129dfaa7359f:

  arm64: kdump: update a kernel doc (2016-03-14 10:29:13 -0700)

----------------------------------------------------------------
AKASHI Takahiro (7):
      arm64: kvm: allows kvm cpu hotplug
      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: enable kdump in the arm64 defconfig
      arm64: kdump: update a kernel doc

Geoff Levand (11):
      arm64: Fold proc-macros.S into assembler.h
      arm64: Cleanup SCTLR flags
      arm64: Convert hcalls to use HVC immediate value
      arm64: Add new hcall HVC_CALL_FUNC
      arm64: Add new asm macro copy_page
      arm64: Add back cpu_reset routines
      Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function"
      Revert "arm64: remove dead code"
      arm64/kexec: Add core kexec support
      arm64/kexec: Enable kexec in the arm64 defconfig
      arm64/kexec: Add pr_debug output

James Morse (2):
      arm64: kernel: Include _AC definition in page.h
      arm64: Promote KERNEL_START/KERNEL_END definitions to a header file

 Documentation/kdump/kdump.txt        |  15 +-
 arch/arm/include/asm/kvm_host.h      |  10 +-
 arch/arm/include/asm/kvm_mmu.h       |   1 +
 arch/arm/kvm/arm.c                   | 104 +++++++++-----
 arch/arm/kvm/mmu.c                   |   5 +
 arch/arm64/Kconfig                   |  21 +++
 arch/arm64/configs/defconfig         |   2 +
 arch/arm64/include/asm/assembler.h   | 101 ++++++++++++-
 arch/arm64/include/asm/hardirq.h     |   2 +-
 arch/arm64/include/asm/kexec.h       |  82 +++++++++++
 arch/arm64/include/asm/kvm_arm.h     |  11 --
 arch/arm64/include/asm/kvm_asm.h     |   1 +
 arch/arm64/include/asm/kvm_host.h    |  12 +-
 arch/arm64/include/asm/kvm_mmu.h     |   1 +
 arch/arm64/include/asm/memory.h      |   3 +
 arch/arm64/include/asm/mmu.h         |   1 +
 arch/arm64/include/asm/mmu_context.h |  35 +++--
 arch/arm64/include/asm/page.h        |   2 +
 arch/arm64/include/asm/smp.h         |   5 +
 arch/arm64/include/asm/sysreg.h      |  19 ++-
 arch/arm64/include/asm/virt.h        |  40 ++++++
 arch/arm64/kernel/Makefile           |   3 +
 arch/arm64/kernel/cpu-reset.S        |  57 ++++++++
 arch/arm64/kernel/cpu-reset.h        |  29 ++++
 arch/arm64/kernel/crash_dump.c       |  71 +++++++++
 arch/arm64/kernel/head.S             |   3 -
 arch/arm64/kernel/hyp-stub.S         |  49 +++++--
 arch/arm64/kernel/machine_kexec.c    | 270 +++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S  | 131 +++++++++++++++++
 arch/arm64/kernel/setup.c            |   7 +-
 arch/arm64/kernel/smp.c              |  56 ++++++++
 arch/arm64/kvm/hyp-init.S            |  47 +++++-
 arch/arm64/kvm/hyp.S                 |   3 +-
 arch/arm64/kvm/hyp/hyp-entry.S       |   9 +-
 arch/arm64/kvm/reset.c               |  14 ++
 arch/arm64/mm/cache.S                |   2 -
 arch/arm64/mm/init.c                 | 151 ++++++++++++++++++++
 arch/arm64/mm/mmu.c                  |  11 ++
 arch/arm64/mm/proc-macros.S          |  98 -------------
 arch/arm64/mm/proc.S                 |   3 -
 include/uapi/linux/kexec.h           |   1 +
 41 files changed, 1291 insertions(+), 197 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
 delete mode 100644 arch/arm64/mm/proc-macros.S

-- 
2.5.0

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 07/20] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-15 13:50   ` Dave Martin
  2016-03-14 17:48 ` [PATCH v15 12/20] arm64/kexec: Add core kexec support Geoff Levand
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

The existing arm64 hcall implementations are limited in that they only
allow for two distinct hcalls; with the x0 register either zero or not
zero.  Also, the API of the hyp-stub exception vector routines and the
KVM exception vector routines differ; hyp-stub uses a non-zero value in
x0 to implement __hyp_set_vectors, whereas KVM uses it to implement
kvm_call_hyp.

To allow for additional hcalls to be defined and to make the arm64 hcall
API more consistent across exception vector routines, change the hcall
implementations to use the 16 bit immediate value of the HVC instruction
to specify the hcall type.

Define three new preprocessor macros HVC_CALL_HYP, HVC_GET_VECTORS, and
HVC_SET_VECTORS to be used as hcall type specifiers and convert the
existing __hyp_get_vectors(), __hyp_set_vectors() and kvm_call_hyp()
routines to use these new macros when executing an HVC call.  Also,
change the corresponding hyp-stub and KVM el1_sync exception vector
routines to use these new macros.

Signed-off-by: Geoff Levand <geoff@infradead.org>
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/virt.h  | 27 +++++++++++++++++++++++++++
 arch/arm64/kernel/hyp-stub.S   | 32 +++++++++++++++++++++-----------
 arch/arm64/kvm/hyp.S           |  3 ++-
 arch/arm64/kvm/hyp/hyp-entry.S |  9 ++++++---
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 7a5df52..eb10368 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -18,6 +18,33 @@
 #ifndef __ASM__VIRT_H
 #define __ASM__VIRT_H
 
+/*
+ * The arm64 hcall implementation uses the ISS field of the ESR_EL2 register to
+ * specify the hcall type.  The exception handlers are allowed to use registers
+ * x17 and x18 in their implementation.  Any routine issuing an hcall must not
+ * expect these registers to be preserved.
+ */
+
+/*
+ * HVC_CALL_HYP - Execute a hyp routine.
+ */
+
+#define HVC_CALL_HYP 0
+
+/*
+ * HVC_GET_VECTORS - Return the value of the vbar_el2 register.
+ */
+
+#define HVC_GET_VECTORS 1
+
+/*
+ * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
+ *
+ * @x0: Physical address of the new vector table.
+ */
+
+#define HVC_SET_VECTORS 2
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index a272f33..017ab519 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -22,6 +22,7 @@
 #include <linux/irqchip/arm-gic-v3.h>
 
 #include <asm/assembler.h>
+#include <asm/kvm_arm.h>
 #include <asm/ptrace.h>
 #include <asm/virt.h>
 
@@ -53,14 +54,22 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	mrs	x1, esr_el2
-	lsr	x1, x1, #26
-	cmp	x1, #0x16
+	mrs	x18, esr_el2
+	lsr	x17, x18, #ESR_ELx_EC_SHIFT
+	and	x18, x18, #ESR_ELx_ISS_MASK
+
+	cmp	x17, #ESR_ELx_EC_HVC64
 	b.ne	2f				// Not an HVC trap
-	cbz	x0, 1f
-	msr	vbar_el2, x0			// Set vbar_el2
+
+	cmp	x18, #HVC_GET_VECTORS
+	b.ne	1f
+	mrs	x0, vbar_el2
 	b	2f
-1:	mrs	x0, vbar_el2			// Return vbar_el2
+
+1:	cmp	x18, #HVC_SET_VECTORS
+	b.ne	2f
+	msr	vbar_el2, x0
+
 2:	eret
 ENDPROC(el1_sync)
 
@@ -100,11 +109,12 @@ ENDPROC(\label)
  * initialisation entry point.
  */
 
-ENTRY(__hyp_get_vectors)
-	mov	x0, xzr
-	// fall through
 ENTRY(__hyp_set_vectors)
-	hvc	#0
+	hvc	#HVC_SET_VECTORS
 	ret
-ENDPROC(__hyp_get_vectors)
 ENDPROC(__hyp_set_vectors)
+
+ENTRY(__hyp_get_vectors)
+	hvc	#HVC_GET_VECTORS
+	ret
+ENDPROC(__hyp_get_vectors)
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 0ccdcbb..a598f9e 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -18,6 +18,7 @@
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
+#include <asm/virt.h>
 
 /*
  * u64 kvm_call_hyp(void *hypfn, ...);
@@ -38,6 +39,6 @@
  * arch/arm64/kernel/hyp_stub.S.
  */
 ENTRY(kvm_call_hyp)
-	hvc	#0
+	hvc	#HVC_CALL_HYP
 	ret
 ENDPROC(kvm_call_hyp)
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 93e8d983..a1edf77 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -43,6 +43,7 @@ el1_sync:				// Guest trapped into EL2
 
 	mrs	x1, esr_el2
 	lsr	x2, x1, #ESR_ELx_EC_SHIFT
+	and	x0, x1, #ESR_ELx_ISS_MASK
 
 	cmp	x2, #ESR_ELx_EC_HVC64
 	b.ne	el1_trap
@@ -51,14 +52,16 @@ el1_sync:				// Guest trapped into EL2
 	cbnz	x3, el1_trap		// called HVC
 
 	/* Here, we're pretty sure the host called HVC. */
+	mov	x18, x0
 	restore_x0_to_x3
 
-	/* Check for __hyp_get_vectors */
-	cbnz	x0, 1f
+	cmp	x18, #HVC_GET_VECTORS
+	b.ne	1f
 	mrs	x0, vbar_el2
 	b	2f
 
-1:	stp	lr, xzr, [sp, #-16]!
+1:     /* Default to HVC_CALL_HYP. */
+	push	lr, xzr
 
 	/*
 	 * Compute the function address in EL2, and shuffle the parameters.
-- 
2.5.0

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

* [PATCH v15 11/20] Revert "arm64: remove dead code"
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (2 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 12/20] arm64/kexec: Add core kexec support Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 05/20] arm64: kvm: allows kvm cpu hotplug Geoff Levand
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

This reverts commit b08d4640a3dca68670fc5af2fe9205b395a02388.

Add back the setup_mm_for_reboot() needed for kexec.
Rename setup_mm_for_reboot() to cpu_install_idmap() in preparation
for the pagetable rework series.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/include/asm/mmu.h |  1 +
 arch/arm64/mm/mmu.c          | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 990124a..ce63a20 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -29,6 +29,7 @@ typedef struct {
 #define ASID(mm)	((mm)->context.id.counter & 0xffff)
 
 extern void paging_init(void);
+extern void cpu_install_idmap(void);
 extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
 extern void init_mem_pgprot(void);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 58faeaa..e43d060 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -479,6 +479,17 @@ void __init paging_init(void)
 }
 
 /*
+ * Enable the identity mapping to allow the MMU disabling.
+ */
+void cpu_install_idmap(void)
+{
+	cpu_set_reserved_ttbr0();
+	flush_tlb_all();
+	cpu_set_idmap_tcr_t0sz();
+	cpu_switch_mm(idmap_pg_dir, &init_mm);
+}
+
+/*
  * Check whether a kernel address is valid (derived from arch/x86/).
  */
 int kern_addr_valid(unsigned long addr)
-- 
2.5.0

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

* [PATCH v15 07/20] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value Geoff Levand
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

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

KERNEL_START and KERNEL_END are useful outside head.S, move them to a
header file.

Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/include/asm/memory.h | 3 +++
 arch/arm64/kernel/head.S        | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 853953c..5773a66 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -70,6 +70,9 @@
 
 #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 4))
 
+#define KERNEL_START      _text
+#define KERNEL_END        _end
+
 /*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 917d981..21bfb5d 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -48,9 +48,6 @@
 #error TEXT_OFFSET must be less than 2MB
 #endif
 
-#define KERNEL_START	_text
-#define KERNEL_END	_end
-
 /*
  * Kernel startup entry point.
  * ---------------------------
-- 
2.5.0

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

* [PATCH v15 01/20] arm64: Fold proc-macros.S into assembler.h
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (9 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 06/20] arm64: kernel: Include _AC definition in page.h Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 09/20] arm64: Add back cpu_reset routines Geoff Levand
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

To allow the assembler macros defined in arch/arm64/mm/proc-macros.S to
be used outside the mm code move the contents of proc-macros.S to
asm/assembler.h.  Also, delete proc-macros.S, and fix up all references
to proc-macros.S.

Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
[rebased, included dcache_by_line_op]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/assembler.h | 82 ++++++++++++++++++++++++++++++-
 arch/arm64/mm/cache.S              |  2 -
 arch/arm64/mm/proc-macros.S        | 98 --------------------------------------
 arch/arm64/mm/proc.S               |  3 --
 4 files changed, 81 insertions(+), 104 deletions(-)
 delete mode 100644 arch/arm64/mm/proc-macros.S

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index bb7b727..ec4e37c 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -1,5 +1,5 @@
 /*
- * Based on arch/arm/include/asm/assembler.h
+ * Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
  *
  * Copyright (C) 1996-2000 Russell King
  * Copyright (C) 2012 ARM Ltd.
@@ -23,6 +23,8 @@
 #ifndef __ASM_ASSEMBLER_H
 #define __ASM_ASSEMBLER_H
 
+#include <asm/asm-offsets.h>
+#include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
 
@@ -205,6 +207,84 @@ lr	.req	x30		// link register
 	.endm
 
 /*
+ * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
+ */
+	.macro	vma_vm_mm, rd, rn
+	ldr	\rd, [\rn, #VMA_VM_MM]
+	.endm
+
+/*
+ * mmid - get context id from mm pointer (mm->context.id)
+ */
+	.macro	mmid, rd, rn
+	ldr	\rd, [\rn, #MM_CONTEXT_ID]
+	.endm
+
+/*
+ * dcache_line_size - get the minimum D-cache line size from the CTR register.
+ */
+	.macro	dcache_line_size, reg, tmp
+	mrs	\tmp, ctr_el0			// read CTR
+	ubfm	\tmp, \tmp, #16, #19		// cache line size encoding
+	mov	\reg, #4			// bytes per word
+	lsl	\reg, \reg, \tmp		// actual cache line size
+	.endm
+
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register.
+ */
+	.macro	icache_line_size, reg, tmp
+	mrs	\tmp, ctr_el0			// read CTR
+	and	\tmp, \tmp, #0xf		// cache line size encoding
+	mov	\reg, #4			// bytes per word
+	lsl	\reg, \reg, \tmp		// actual cache line size
+	.endm
+
+/*
+ * tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
+ */
+	.macro	tcr_set_idmap_t0sz, valreg, tmpreg
+#ifndef CONFIG_ARM64_VA_BITS_48
+	ldr_l	\tmpreg, idmap_t0sz
+	bfi	\valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
+#endif
+	.endm
+
+/*
+ * Macro to perform a data cache maintenance for the interval
+ * [kaddr, kaddr + size)
+ *
+ * 	op:		operation passed to dc instruction
+ * 	domain:		domain used in dsb instruciton
+ * 	kaddr:		starting virtual address of the region
+ * 	size:		size of the region
+ * 	Corrupts:	kaddr, size, tmp1, tmp2
+ */
+	.macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
+	dcache_line_size \tmp1, \tmp2
+	add	\size, \kaddr, \size
+	sub	\tmp2, \tmp1, #1
+	bic	\kaddr, \kaddr, \tmp2
+9998:	dc	\op, \kaddr
+	add	\kaddr, \kaddr, \tmp1
+	cmp	\kaddr, \size
+	b.lo	9998b
+	dsb	\domain
+	.endm
+
+/*
+ * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
+ */
+	.macro	reset_pmuserenr_el0, tmpreg
+	mrs	\tmpreg, id_aa64dfr0_el1	// Check ID_AA64DFR0_EL1 PMUVer
+	sbfx	\tmpreg, \tmpreg, #8, #4
+	cmp	\tmpreg, #1			// Skip if no PMU present
+	b.lt	9000f
+	msr	pmuserenr_el0, xzr		// Disable PMU access from EL0
+9000:
+	.endm
+
+/*
  * Annotate a function as position independent, i.e., safe to be called before
  * the kernel virtual mapping is activated.
  */
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 6df0706..50ff9ba 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -24,8 +24,6 @@
 #include <asm/cpufeature.h>
 #include <asm/alternative.h>
 
-#include "proc-macros.S"
-
 /*
  *	flush_icache_range(start,end)
  *
diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S
deleted file mode 100644
index e6a30e1..0000000
--- a/arch/arm64/mm/proc-macros.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Based on arch/arm/mm/proc-macros.S
- *
- * Copyright (C) 2012 ARM Ltd.
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-
-/*
- * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
- */
-	.macro	vma_vm_mm, rd, rn
-	ldr	\rd, [\rn, #VMA_VM_MM]
-	.endm
-
-/*
- * mmid - get context id from mm pointer (mm->context.id)
- */
-	.macro	mmid, rd, rn
-	ldr	\rd, [\rn, #MM_CONTEXT_ID]
-	.endm
-
-/*
- * dcache_line_size - get the minimum D-cache line size from the CTR register.
- */
-	.macro	dcache_line_size, reg, tmp
-	mrs	\tmp, ctr_el0			// read CTR
-	ubfm	\tmp, \tmp, #16, #19		// cache line size encoding
-	mov	\reg, #4			// bytes per word
-	lsl	\reg, \reg, \tmp		// actual cache line size
-	.endm
-
-/*
- * icache_line_size - get the minimum I-cache line size from the CTR register.
- */
-	.macro	icache_line_size, reg, tmp
-	mrs	\tmp, ctr_el0			// read CTR
-	and	\tmp, \tmp, #0xf		// cache line size encoding
-	mov	\reg, #4			// bytes per word
-	lsl	\reg, \reg, \tmp		// actual cache line size
-	.endm
-
-/*
- * tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
- */
-	.macro	tcr_set_idmap_t0sz, valreg, tmpreg
-#ifndef CONFIG_ARM64_VA_BITS_48
-	ldr_l	\tmpreg, idmap_t0sz
-	bfi	\valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
-#endif
-	.endm
-
-/*
- * Macro to perform a data cache maintenance for the interval
- * [kaddr, kaddr + size)
- *
- * 	op:		operation passed to dc instruction
- * 	domain:		domain used in dsb instruciton
- * 	kaddr:		starting virtual address of the region
- * 	size:		size of the region
- * 	Corrupts: 	kaddr, size, tmp1, tmp2
- */
-	.macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
-	dcache_line_size \tmp1, \tmp2
-	add	\size, \kaddr, \size
-	sub	\tmp2, \tmp1, #1
-	bic	\kaddr, \kaddr, \tmp2
-9998:	dc	\op, \kaddr
-	add	\kaddr, \kaddr, \tmp1
-	cmp	\kaddr, \size
-	b.lo	9998b
-	dsb	\domain
-	.endm
-
-/*
- * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
- */
-	.macro	reset_pmuserenr_el0, tmpreg
-	mrs	\tmpreg, id_aa64dfr0_el1	// Check ID_AA64DFR0_EL1 PMUVer
-	sbfx	\tmpreg, \tmpreg, #8, #4
-	cmp	\tmpreg, #1			// Skip if no PMU present
-	b.lt	9000f
-	msr	pmuserenr_el0, xzr		// Disable PMU access from EL0
-9000:
-	.endm
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index c164d2c..5e01309 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -23,11 +23,8 @@
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 #include <asm/hwcap.h>
-#include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
-#include "proc-macros.S"
-
 #ifdef CONFIG_ARM64_64K_PAGES
 #define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
 #elif defined(CONFIG_ARM64_16K_PAGES)
-- 
2.5.0

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

* [PATCH v15 12/20] arm64/kexec: Add core kexec support
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 07/20] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 11/20] Revert "arm64: remove dead code" Geoff Levand
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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   | 158 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/relocate_kernel.S | 131 ++++++++++++++++++++++++++++++
 include/uapi/linux/kexec.h          |   1 +
 6 files changed, 350 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 8cc6228..3001c51 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -603,6 +603,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 83cd7e6..c0aa90d 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -42,6 +42,8 @@ arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.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..6fd0f0c
--- /dev/null
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -0,0 +1,158 @@
+/*
+ * 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/highmem.h>
+#include <linux/kexec.h>
+#include <linux/of_fdt.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include <asm/cacheflush.h>
+#include <asm/system_misc.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.
+ */
+int machine_kexec_prepare(struct kimage *kimage)
+{
+	kimage_start = kimage->start;
+	return 0;
+}
+
+/**
+ * kexec_list_flush - Helper to flush the kimage list to PoC.
+ */
+static void kexec_list_flush(struct kimage *kimage)
+{
+	kimage_entry_t *entry;
+	unsigned int flag;
+
+	for (entry = &kimage->head, flag = 0; flag != IND_DONE; entry++) {
+		void *addr = kmap(phys_to_page(*entry & PAGE_MASK));
+
+		flag = *entry & IND_FLAGS;
+
+		switch (flag) {
+		case IND_INDIRECTION:
+			entry = (kimage_entry_t *)addr - 1;
+			__flush_dcache_area(addr, PAGE_SIZE);
+			break;
+		case IND_DESTINATION:
+			break;
+		case IND_SOURCE:
+			__flush_dcache_area(addr, PAGE_SIZE);
+			break;
+		case IND_DONE:
+			break;
+		default:
+			BUG();
+		}
+		kunmap(addr);
+	}
+}
+
+/**
+ * kexec_segment_flush - Helper to flush the kimage segments to PoC.
+ */
+static void kexec_segment_flush(const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_devel("%s:\n", __func__);
+
+	for (i = 0; i < kimage->nr_segments; i++) {
+		pr_devel("  segment[%lu]: %016lx - %016lx, %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;
+
+	BUG_ON(num_online_cpus() > 1);
+
+	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
+	reboot_code_buffer = kmap(kimage->control_code_page);
+
+	/*
+	 * 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_install_idmap();
+
+	/*
+	 * 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(is_hyp_mode_available(),
+		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..e380db3
--- /dev/null
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -0,0 +1,131 @@
+/*
+ * 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 <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.
+ */
+.globl arm64_relocate_new_kernel
+arm64_relocate_new_kernel:
+
+	/* Setup the list loop variables. */
+	mov	x18, x1				/* x18 = kimage_start */
+	mov	x17, x0				/* x17 = kimage_head */
+	dcache_line_size x16, x0		/* x16 = dcache line size */
+	mov	x15, xzr			/* x15 = segment start */
+	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. */
+	cbz	x17, .Ldone
+	tbnz	x17, IND_DONE_BIT, .Ldone
+
+.Lloop:
+	and	x12, x17, PAGE_MASK		/* x12 = addr */
+
+	/* Test the entry flags. */
+.Ltest_source:
+	tbz	x17, IND_SOURCE_BIT, .Ltest_indirection
+
+	/* Invalidate dest page to PoC. */
+	mov     x0, x13
+	add     x20, x0, #PAGE_SIZE
+	sub     x1, x16, #1
+	bic     x0, x0, x1
+2:	dc      ivac, x0
+	add     x0, x0, x16
+	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	x17, IND_INDIRECTION_BIT, .Ltest_destination
+
+	/* ptr = addr */
+	mov	x14, x12
+	b	.Lnext
+
+.Ltest_destination:
+	tbz	x17, IND_DESTINATION_BIT, .Lnext
+
+	mov	x15, x12
+
+	/* dest = addr */
+	mov	x13, x12
+
+.Lnext:
+	/* entry = *ptr++ */
+	ldr	x17, [x14], #8
+
+	/* while (!(entry & DONE)) */
+	tbz	x17, IND_DONE_BIT, .Lloop
+
+.Ldone:
+	dsb	nsh
+	ic	iallu
+	dsb	nsh
+	isb
+
+	/* Start new image. */
+	mov	x0, xzr
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+	br	x18
+
+.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] 45+ messages in thread

* [PATCH v15 13/20] arm64/kexec: Enable kexec in the arm64 defconfig
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (5 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 10/20] Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function" Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 02/20] arm64: Cleanup SCTLR flags Geoff Levand
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 86581f7..288cbd6 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -64,6 +64,7 @@ CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_XEN=y
+CONFIG_KEXEC=y
 CONFIG_CMDLINE="console=ttyAMA0"
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
-- 
2.5.0

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

* [PATCH v15 08/20] arm64: Add new asm macro copy_page
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (7 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 02/20] arm64: Cleanup SCTLR flags Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 06/20] arm64: kernel: Include _AC definition in page.h Geoff Levand
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Kexec and hibernate need to copy pages of memory, but may not have all
of the kernel mapped, and are unable to call copy_page().

Add a simplistic copy_page() macro, that can be inlined in these
situations. lib/copy_page.S provides a bigger better version, but
uses more registers.

Signed-off-by: Geoff Levand <geoff@infradead.org>
[Changed asm label to 9998, added commit message]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/assembler.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ec4e37c..f3854d9 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -24,6 +24,7 @@
 #define __ASM_ASSEMBLER_H
 
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
@@ -285,6 +286,24 @@ lr	.req	x30		// link register
 	.endm
 
 /*
+ * copy_page - copy src to dest using temp registers t1-t8
+ */
+	.macro copy_page dest:req src:req t1:req t2:req t3:req t4:req t5:req t6:req t7:req t8:req
+9998:	ldp	\t1, \t2, [\src]
+	ldp	\t3, \t4, [\src, #16]
+	ldp	\t5, \t6, [\src, #32]
+	ldp	\t7, \t8, [\src, #48]
+	add	\src, \src, #64
+	stnp	\t1, \t2, [\dest]
+	stnp	\t3, \t4, [\dest, #16]
+	stnp	\t5, \t6, [\dest, #32]
+	stnp	\t7, \t8, [\dest, #48]
+	add	\dest, \dest, #64
+	tst	\src, #(PAGE_SIZE - 1)
+	b.ne	9998b
+	.endm
+
+/*
  * Annotate a function as position independent, i.e., safe to be called before
  * the kernel virtual mapping is activated.
  */
-- 
2.5.0

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

* [PATCH v15 06/20] arm64: kernel: Include _AC definition in page.h
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (8 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 08/20] arm64: Add new asm macro copy_page Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 01/20] arm64: Fold proc-macros.S into assembler.h Geoff Levand
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

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

page.h uses '_AC' in the definition of PAGE_SIZE, but doesn't include
linux/const.h where this is defined. This produces build warnings when only
asm/page.h is included by asm code.

Signed-off-by: James Morse <james.morse@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/include/asm/page.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index ae615b9..17b45f7 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -19,6 +19,8 @@
 #ifndef __ASM_PAGE_H
 #define __ASM_PAGE_H
 
+#include <linux/const.h>
+
 /* PAGE_SHIFT determines the page size */
 /* CONT_SHIFT determines the number of pages which can be tracked together  */
 #ifdef CONFIG_ARM64_64K_PAGES
-- 
2.5.0

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

* [PATCH v15 04/20] arm64: Add new hcall HVC_CALL_FUNC
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (11 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 09/20] arm64: Add back cpu_reset routines Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 20/20] arm64: kdump: update a kernel doc Geoff Levand
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Add the new hcall HVC_CALL_FUNC that allows execution of a function at EL2.
During CPU reset the CPU must be brought to the exception level it had on
entry to the kernel.  The HVC_CALL_FUNC hcall will provide the mechanism
needed for this exception level switch.

To allow the HVC_CALL_FUNC exception vector to work without a stack, which
is needed to support an hcall at CPU reset, this implementation uses
register x18 to store the link register across the caller provided
function.  This dictates that the caller provided function must preserve
the contents of register x18.

Signed-off-by: Geoff Levand <geoff@infradead.org>
[Renumbered labels in el1_sync()]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/virt.h | 13 +++++++++++++
 arch/arm64/kernel/hyp-stub.S  | 19 +++++++++++++++----
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index eb10368..3070096 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -45,6 +45,19 @@
 
 #define HVC_SET_VECTORS 2
 
+/*
+ * HVC_CALL_FUNC - Execute a function at EL2.
+ *
+ * @x0: Physical address of the function to be executed.
+ * @x1: Passed as the first argument to the function.
+ * @x2: Passed as the second argument to the function.
+ * @x3: Passed as the third argument to the function.
+ *
+ * The called function must preserve the contents of register x18.
+ */
+
+#define HVC_CALL_FUNC 3
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 017ab519..cfacfe5 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -59,18 +59,29 @@ el1_sync:
 	and	x18, x18, #ESR_ELx_ISS_MASK
 
 	cmp	x17, #ESR_ELx_EC_HVC64
-	b.ne	2f				// Not an HVC trap
+	b.ne	9f				// Not an HVC trap
 
 	cmp	x18, #HVC_GET_VECTORS
 	b.ne	1f
 	mrs	x0, vbar_el2
-	b	2f
+	b	9f
 
 1:	cmp	x18, #HVC_SET_VECTORS
 	b.ne	2f
 	msr	vbar_el2, x0
-
-2:	eret
+	b	9f
+
+2:	cmp	x18, #HVC_CALL_FUNC
+	b.ne	9f
+	mov	x18, lr
+	mov	lr, x0
+	mov	x0, x1
+	mov	x1, x2
+	mov	x2, x3
+	blr	lr
+	mov	lr, x18
+
+9:	eret
 ENDPROC(el1_sync)
 
 .macro invalid_vector	label
-- 
2.5.0

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

* [PATCH v15 02/20] arm64: Cleanup SCTLR flags
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (6 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 13/20] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 08/20] arm64: Add new asm macro copy_page Geoff Levand
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

We currently have macros defining flags for the arm64 sctlr registers in
both kvm_arm.h and sysreg.h.  To clean things up and simplify move the
definitions of the SCTLR_EL2 flags from kvm_arm.h to sysreg.h, rename any
SCTLR_EL1 or SCTLR_EL2 flags that are common to both registers to be
SCTLR_ELx, with 'x' indicating a common flag, and fixup all files to
include the proper header or to use the new macro names.

Signed-off-by: Geoff Levand <geoff@infradead.org>
[Restored pgtable-hwdef.h include]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_arm.h | 11 -----------
 arch/arm64/include/asm/sysreg.h  | 19 +++++++++++++++----
 arch/arm64/kvm/hyp-init.S        |  5 +++--
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index d201d4b..fbd5dbd 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -83,17 +83,6 @@
 #define HCR_INT_OVERRIDE   (HCR_FMO | HCR_IMO)
 
 
-/* Hyp System Control Register (SCTLR_EL2) bits */
-#define SCTLR_EL2_EE	(1 << 25)
-#define SCTLR_EL2_WXN	(1 << 19)
-#define SCTLR_EL2_I	(1 << 12)
-#define SCTLR_EL2_SA	(1 << 3)
-#define SCTLR_EL2_C	(1 << 2)
-#define SCTLR_EL2_A	(1 << 1)
-#define SCTLR_EL2_M	1
-#define SCTLR_EL2_FLAGS	(SCTLR_EL2_M | SCTLR_EL2_A | SCTLR_EL2_C |	\
-			 SCTLR_EL2_SA | SCTLR_EL2_I)
-
 /* TCR_EL2 Registers bits */
 #define TCR_EL2_RES1	((1 << 31) | (1 << 23))
 #define TCR_EL2_TBI	(1 << 20)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4aeebec..99dac2f 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -82,10 +82,21 @@
 #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
 				     (!!x)<<8 | 0x1f)
 
-/* SCTLR_EL1 */
-#define SCTLR_EL1_CP15BEN	(0x1 << 5)
-#define SCTLR_EL1_SED		(0x1 << 8)
-#define SCTLR_EL1_SPAN		(0x1 << 23)
+/* Common SCTLR_ELx flags. */
+#define SCTLR_ELx_EE    (1 << 25)
+#define SCTLR_ELx_I	(1 << 12)
+#define SCTLR_ELx_SA	(1 << 3)
+#define SCTLR_ELx_C	(1 << 2)
+#define SCTLR_ELx_A	(1 << 1)
+#define SCTLR_ELx_M	1
+
+#define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
+			 SCTLR_ELx_SA | SCTLR_ELx_I)
+
+/* SCTLR_EL1 specific flags. */
+#define SCTLR_EL1_SPAN		(1 << 23)
+#define SCTLR_EL1_SED		(1 << 8)
+#define SCTLR_EL1_CP15BEN	(1 << 5)
 
 
 /* id_aa64isar0 */
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index d073b5a..034d152c 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -21,6 +21,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
 #include <asm/pgtable-hwdef.h>
+#include <asm/sysreg.h>
 
 	.text
 	.pushsection	.hyp.idmap.text, "ax"
@@ -116,8 +117,8 @@ __do_hyp_init:
 	dsb	sy
 
 	mrs	x4, sctlr_el2
-	and	x4, x4, #SCTLR_EL2_EE	// preserve endianness of EL2
-	ldr	x5, =SCTLR_EL2_FLAGS
+	and	x4, x4, #SCTLR_ELx_EE	// preserve endianness of EL2
+	ldr	x5, =SCTLR_ELx_FLAGS
 	orr	x4, x4, x5
 	msr	sctlr_el2, x4
 	isb
-- 
2.5.0

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

* [PATCH v15 05/20] arm64: kvm: allows kvm cpu hotplug
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (3 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 11/20] Revert "arm64: remove dead code" Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 10/20] Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function" Geoff Levand
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

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

The current kvm implementation on arm64 does cpu-specific initialization
at system boot, and has no way to gracefully shutdown a core in terms of
kvm. This prevents kexec from rebooting the system at EL2.

This patch adds a cpu tear-down function and also puts an existing cpu-init
code into a separate function, kvm_arch_hardware_disable() and
kvm_arch_hardware_enable() respectively.
We don't need the arm64 specific cpu hotplug hook any more.

Since this patch modifies common code between arm and arm64, one stub
definition, __cpu_reset_hyp_mode(), is added on arm side to avoid
compilation errors.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
[Moved __kvm_hyp_reset() to use kvm_call_hyp(), instead of having its own
 dedicated entry point in el1_sync. Added some comments and a tlbi.]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm/include/asm/kvm_host.h   |  10 +++-
 arch/arm/include/asm/kvm_mmu.h    |   1 +
 arch/arm/kvm/arm.c                | 104 ++++++++++++++++++++++++--------------
 arch/arm/kvm/mmu.c                |   5 ++
 arch/arm64/include/asm/kvm_asm.h  |   1 +
 arch/arm64/include/asm/kvm_host.h |  12 ++++-
 arch/arm64/include/asm/kvm_mmu.h  |   1 +
 arch/arm64/kvm/hyp-init.S         |  42 +++++++++++++++
 arch/arm64/kvm/reset.c            |  14 +++++
 9 files changed, 150 insertions(+), 40 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index f9f2779..8af531d 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -220,6 +220,15 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
 	kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
 }
 
+static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
+					phys_addr_t phys_idmap_start)
+{
+	/*
+	 * TODO
+	 * kvm_call_reset(boot_pgd_ptr, phys_idmap_start);
+	 */
+}
+
 static inline int kvm_arch_dev_ioctl_check_extension(long ext)
 {
 	return 0;
@@ -232,7 +241,6 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
-static inline void kvm_arch_hardware_disable(void) {}
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index a520b79..4fd9ddb 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -66,6 +66,7 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_mmu_get_boot_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
+phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index dda1959..0aad49f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -16,7 +16,6 @@
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-#include <linux/cpu.h>
 #include <linux/cpu_pm.h>
 #include <linux/errno.h>
 #include <linux/err.h>
@@ -65,6 +64,8 @@ static DEFINE_SPINLOCK(kvm_vmid_lock);
 
 static bool vgic_present;
 
+static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
+
 static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
 {
 	BUG_ON(preemptible());
@@ -89,11 +90,6 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
 	return &kvm_arm_running_vcpu;
 }
 
-int kvm_arch_hardware_enable(void)
-{
-	return 0;
-}
-
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
@@ -585,7 +581,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		/*
 		 * Re-check atomic conditions
 		 */
-		if (signal_pending(current)) {
+		if (unlikely(!__this_cpu_read(kvm_arm_hardware_enabled))) {
+			/* cpu has been torn down */
+			ret = 0;
+			run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+			run->fail_entry.hardware_entry_failure_reason
+					= (u64)-ENOEXEC;
+		} else if (signal_pending(current)) {
 			ret = -EINTR;
 			run->exit_reason = KVM_EXIT_INTR;
 		}
@@ -967,7 +969,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
 	}
 }
 
-static void cpu_init_hyp_mode(void *dummy)
+static void cpu_init_hyp_mode(void)
 {
 	phys_addr_t boot_pgd_ptr;
 	phys_addr_t pgd_ptr;
@@ -989,36 +991,67 @@ static void cpu_init_hyp_mode(void *dummy)
 	kvm_arm_init_debug();
 }
 
-static int hyp_init_cpu_notify(struct notifier_block *self,
-			       unsigned long action, void *cpu)
+static void cpu_reset_hyp_mode(void)
 {
-	switch (action) {
-	case CPU_STARTING:
-	case CPU_STARTING_FROZEN:
-		if (__hyp_get_vectors() == hyp_default_vectors)
-			cpu_init_hyp_mode(NULL);
-		break;
+	phys_addr_t boot_pgd_ptr;
+	phys_addr_t phys_idmap_start;
+
+	boot_pgd_ptr = kvm_mmu_get_boot_httbr();
+	phys_idmap_start = kvm_get_idmap_start();
+
+	__cpu_reset_hyp_mode(boot_pgd_ptr, phys_idmap_start);
+}
+
+int kvm_arch_hardware_enable(void)
+{
+	if (!__this_cpu_read(kvm_arm_hardware_enabled)) {
+		cpu_init_hyp_mode();
+		__this_cpu_write(kvm_arm_hardware_enabled, 1);
 	}
 
-	return NOTIFY_OK;
+	return 0;
 }
 
-static struct notifier_block hyp_init_cpu_nb = {
-	.notifier_call = hyp_init_cpu_notify,
-};
+void kvm_arch_hardware_disable(void)
+{
+	if (!__this_cpu_read(kvm_arm_hardware_enabled))
+		return;
+
+	cpu_reset_hyp_mode();
+	__this_cpu_write(kvm_arm_hardware_enabled, 0);
+}
 
 #ifdef CONFIG_CPU_PM
 static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
 				    unsigned long cmd,
 				    void *v)
 {
-	if (cmd == CPU_PM_EXIT &&
-	    __hyp_get_vectors() == hyp_default_vectors) {
-		cpu_init_hyp_mode(NULL);
+	/*
+	 * kvm_arm_hardware_enabled is left with its old value over
+	 * PM_ENTER->PM_EXIT. It is used to indicate PM_EXIT should
+	 * re-enable hyp.
+	 */
+	switch (cmd) {
+	case CPU_PM_ENTER:
+		if (__this_cpu_read(kvm_arm_hardware_enabled))
+			/*
+			 * don't update kvm_arm_hardware_enabled here
+			 * so that the hardware will be re-enabled
+			 * when we resume. See below.
+			 */
+			cpu_reset_hyp_mode();
+
+		return NOTIFY_OK;
+	case CPU_PM_EXIT:
+		if (__this_cpu_read(kvm_arm_hardware_enabled))
+			/* The hardware was enabled before suspend. */
+			cpu_init_hyp_mode();
+
 		return NOTIFY_OK;
-	}
 
-	return NOTIFY_DONE;
+	default:
+		return NOTIFY_DONE;
+	}
 }
 
 static struct notifier_block hyp_init_cpu_pm_nb = {
@@ -1122,14 +1155,20 @@ static int init_hyp_mode(void)
 	}
 
 	/*
-	 * Execute the init code on each CPU.
+	 * Init this CPU temporarily to execute kvm_hyp_call()
+	 * during kvm_vgic_hyp_init().
 	 */
-	on_each_cpu(cpu_init_hyp_mode, NULL, 1);
+	preempt_disable();
+	cpu_init_hyp_mode();
 
 	/*
 	 * Init HYP view of VGIC
 	 */
 	err = kvm_vgic_hyp_init();
+
+	cpu_reset_hyp_mode();
+	preempt_enable();
+
 	switch (err) {
 	case 0:
 		vgic_present = true;
@@ -1213,26 +1252,15 @@ int kvm_arch_init(void *opaque)
 		}
 	}
 
-	cpu_notifier_register_begin();
-
 	err = init_hyp_mode();
 	if (err)
 		goto out_err;
 
-	err = __register_cpu_notifier(&hyp_init_cpu_nb);
-	if (err) {
-		kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
-		goto out_err;
-	}
-
-	cpu_notifier_register_done();
-
 	hyp_cpu_pm_init();
 
 	kvm_coproc_table_init();
 	return 0;
 out_err:
-	cpu_notifier_register_done();
 	return err;
 }
 
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index aba61fd..7a3aed6 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1643,6 +1643,11 @@ phys_addr_t kvm_get_idmap_vector(void)
 	return hyp_idmap_vector;
 }
 
+phys_addr_t kvm_get_idmap_start(void)
+{
+	return hyp_idmap_start;
+}
+
 int kvm_mmu_init(void)
 {
 	int err;
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 52b777b..4191d12 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -32,6 +32,7 @@ struct kvm_vcpu;
 
 extern char __kvm_hyp_init[];
 extern char __kvm_hyp_init_end[];
+extern char __kvm_hyp_reset[];
 
 extern char __kvm_hyp_vector[];
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 689d4c9..b218211 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,6 +44,7 @@
 int __attribute_const__ kvm_target_cpu(void);
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
 int kvm_arch_dev_ioctl_check_extension(long ext);
+phys_addr_t kvm_hyp_reset_entry(void);
 
 struct kvm_arch {
 	/* The VMID generation used for the virt. memory system */
@@ -332,7 +333,16 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
 		     hyp_stack_ptr, vector_ptr);
 }
 
-static inline void kvm_arch_hardware_disable(void) {}
+static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
+					phys_addr_t phys_idmap_start)
+{
+	/*
+	 * Call reset code, and switch back to stub hyp vectors.
+	 */
+	kvm_call_hyp((void *)kvm_hyp_reset_entry(),
+		     boot_pgd_ptr, phys_idmap_start);
+}
+
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 7364339..7ee6824 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -99,6 +99,7 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_mmu_get_boot_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
+phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 034d152c..a19a7ef 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -152,6 +152,48 @@ merged:
 	eret
 ENDPROC(__kvm_hyp_init)
 
+	/*
+	 * x0: HYP boot pgd
+	 * x1: HYP phys_idmap_start
+	 */
+ENTRY(__kvm_hyp_reset)
+	/*
+	 * Retrieve lr from the stack (pushed by el1_sync()), so we can eret
+	 * from here.
+	 */
+	ldp	lr, xzr, [sp], #16
+
+	/* We're in trampoline code in VA, switch back to boot page tables */
+	msr	ttbr0_el2, x0
+	isb
+
+	/* Ensure the PA branch doesn't find a stale tlb entry. */
+	tlbi	alle2
+	dsb	sy
+
+	/* Branch into PA space */
+	adr	x0, 1f
+	bfi	x1, x0, #0, #PAGE_SHIFT
+	br	x1
+
+	/* We're now in idmap, disable MMU */
+1:	mrs	x0, sctlr_el2
+	ldr	x1, =SCTLR_ELx_FLAGS
+	bic	x0, x0, x1		// Clear SCTL_M and etc
+	msr	sctlr_el2, x0
+	isb
+
+	/* Invalidate the old TLBs */
+	tlbi	alle2
+	dsb	sy
+
+	/* Install stub vectors */
+	adr_l	x0, __hyp_stub_vectors
+	msr	vbar_el2, x0
+
+	eret
+ENDPROC(__kvm_hyp_reset)
+
 	.ltorg
 
 	.popsection
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index f34745c..d6e155a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -29,7 +29,9 @@
 #include <asm/cputype.h>
 #include <asm/ptrace.h>
 #include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
 #include <asm/kvm_coproc.h>
+#include <asm/kvm_mmu.h>
 
 /*
  * ARMv8 Reset Values
@@ -123,3 +125,15 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	/* Reset timer */
 	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
+
+extern char __hyp_idmap_text_start[];
+
+phys_addr_t kvm_hyp_reset_entry(void)
+{
+	unsigned long offset;
+
+	offset = (unsigned long)__kvm_hyp_reset
+		 - ((unsigned long)__hyp_idmap_text_start & PAGE_MASK);
+
+	return TRAMPOLINE_VA + offset;
+}
-- 
2.5.0

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

* [PATCH v15 09/20] arm64: Add back cpu_reset routines
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (10 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 01/20] arm64: Fold proc-macros.S into assembler.h Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 04/20] arm64: Add new hcall HVC_CALL_FUNC Geoff Levand
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Commit 68234df4ea7939f98431aa81113fbdce10c4a84b (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_reset() to accept an argument
which signals if the reset address needs to be entered at EL1 or EL2.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/arm64/kernel/cpu-reset.S | 57 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cpu-reset.h | 29 ++++++++++++++++++++++
 2 files changed, 86 insertions(+)
 create mode 100644 arch/arm64/kernel/cpu-reset.S
 create mode 100644 arch/arm64/kernel/cpu-reset.h

diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
new file mode 100644
index 0000000..f8d00d5
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -0,0 +1,57 @@
+/*
+ * 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, x1				// entry
+	mov	x1, x2				// arg0
+	mov	x2, x3				// arg1
+	mov	x3, x4				// arg2
+	hvc	#HVC_CALL_FUNC			// no return
+
+1:	mov	x18, x1				// entry
+	mov	x0, x2				// arg0
+	mov	x1, x3				// arg1
+	mov	x2, x4				// arg2
+	ret	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..5a5ea0a
--- /dev/null
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -0,0 +1,29 @@
+/*
+ * 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;
+	restart = (void *)virt_to_phys(__cpu_soft_restart);
+	restart(el2_switch, entry, arg0, arg1, arg2);
+	unreachable();
+}
+
+#endif
-- 
2.5.0

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

* [PATCH v15 10/20] Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function"
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (4 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 05/20] arm64: kvm: allows kvm cpu hotplug Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 13/20] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

This reverts commit c51e97d89e526368eb697f87cd4d391b9e19f369.

Add back the cpu_set_idmap_tcr_t0sz function needed by setup_mmu_for_reboot.
---
 arch/arm64/include/asm/mmu_context.h | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 2416578..7567030 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -70,23 +70,34 @@ static inline bool __cpu_uses_extended_idmap(void)
 		unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)));
 }
 
+static inline void __cpu_set_tcr_t0sz(u64 t0sz)
+{
+	unsigned long tcr;
+
+	if (__cpu_uses_extended_idmap())
+		asm volatile (
+		"	mrs	%0, tcr_el1	;"
+		"	bfi	%0, %1, %2, %3	;"
+		"	msr	tcr_el1, %0	;"
+		"	isb"
+		: "=&r" (tcr)
+		: "r"(t0sz), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
+}
+
+/*
+ * Set TCR.T0SZ to the value appropriate for activating the identity map.
+ */
+static inline void cpu_set_idmap_tcr_t0sz(void)
+{
+	__cpu_set_tcr_t0sz(idmap_t0sz);
+}
+
 /*
  * Set TCR.T0SZ to its default value (based on VA_BITS)
  */
 static inline void cpu_set_default_tcr_t0sz(void)
 {
-	unsigned long tcr;
-
-	if (!__cpu_uses_extended_idmap())
-		return;
-
-	asm volatile (
-	"	mrs	%0, tcr_el1	;"
-	"	bfi	%0, %1, %2, %3	;"
-	"	msr	tcr_el1, %0	;"
-	"	isb"
-	: "=&r" (tcr)
-	: "r"(TCR_T0SZ(VA_BITS)), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
+	__cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS));
 }
 
 /*
-- 
2.5.0

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (16 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 14/20] arm64/kexec: Add pr_debug output Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-18 18:08   ` James Morse
  2016-03-14 17:48 ` [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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    | 36 ++++++++++++++++++++++++-
 arch/arm64/include/asm/smp.h      |  5 ++++
 arch/arm64/kernel/machine_kexec.c | 55 +++++++++++++++++++++++++++++++++++---
 arch/arm64/kernel/smp.c           | 56 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 149 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index a57601f..8740297 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	5
+#define NR_IPI	6
 
 typedef struct {
 	unsigned int __softirq_pending;
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 04744dc..2f089b3 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -30,6 +30,10 @@
 
 #ifndef __ASSEMBLY__
 
+#ifndef CONFIG_KEXEC_CORE
+#define crash_save_cpu(regs, cpu)
+#endif
+
 /**
  * crash_setup_regs() - save registers for the panic kernel
  *
@@ -40,7 +44,37 @@
 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 {
+		__asm__ __volatile__ (
+			"stp	 x0,   x1, [%3, #16 *  0]\n"
+			"stp	 x2,   x3, [%3, #16 *  1]\n"
+			"stp	 x4,   x5, [%3, #16 *  2]\n"
+			"stp	 x6,   x7, [%3, #16 *  3]\n"
+			"stp	 x8,   x9, [%3, #16 *  4]\n"
+			"stp	x10,  x11, [%3, #16 *  5]\n"
+			"stp	x12,  x13, [%3, #16 *  6]\n"
+			"stp	x14,  x15, [%3, #16 *  7]\n"
+			"stp	x16,  x17, [%3, #16 *  8]\n"
+			"stp	x18,  x19, [%3, #16 *  9]\n"
+			"stp	x20,  x21, [%3, #16 * 10]\n"
+			"stp	x22,  x23, [%3, #16 * 11]\n"
+			"stp	x24,  x25, [%3, #16 * 12]\n"
+			"stp	x26,  x27, [%3, #16 * 13]\n"
+			"stp	x28,  x29, [%3, #16 * 14]\n"
+			"str	x30,	   [%3, #16 * 15]\n"
+			"mov	%0, sp\n"
+			"adr	%1, 1f\n"
+			"mrs	%2, spsr_el1\n"
+		"1:"
+			: "=r" (newregs->sp),
+			  "=r" (newregs->pc),
+			  "=r" (newregs->pstate)
+			: "r"  (&newregs->regs)
+			: "memory"
+		);
+	}
 }
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index d9c3d6a..0e42ece 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -69,4 +69,9 @@ extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
 extern void cpu_die(void);
 
+/*
+ * for crash dump
+ */
+extern void smp_send_crash_stop(void);
+
 #endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 75f6696..8651b27 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -10,6 +10,9 @@
  */
 
 #include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/kexec.h>
 #include <linux/libfdt_env.h>
 #include <linux/of_fdt.h>
@@ -25,6 +28,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;
 
 /**
@@ -150,7 +154,7 @@ void machine_kexec(struct kimage *kimage)
 	phys_addr_t reboot_code_buffer_phys;
 	void *reboot_code_buffer;
 
-	BUG_ON(num_online_cpus() > 1);
+	BUG_ON((num_online_cpus() > 1) && !WARN_ON(in_crash_kexec));
 
 	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
 	reboot_code_buffer = kmap(kimage->control_code_page);
@@ -209,13 +213,58 @@ void machine_kexec(struct kimage *kimage)
 	 * relocation is complete.
 	 */
 
-	cpu_soft_restart(is_hyp_mode_available(),
+	cpu_soft_restart(in_crash_kexec ? 0 : is_hyp_mode_available(),
 		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 b1adc51..76402c6cd 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>
@@ -44,6 +45,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
+#include <asm/kexec.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -68,6 +70,7 @@ enum ipi_msg_type {
 	IPI_RESCHEDULE,
 	IPI_CALL_FUNC,
 	IPI_CPU_STOP,
+	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
 };
@@ -625,6 +628,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"),
 };
@@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
 		cpu_relax();
 }
 
+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);
+
+	raw_spin_lock(&stop_lock);
+	pr_debug("CPU%u: stopping\n", cpu);
+	raw_spin_unlock(&stop_lock);
+
+	atomic_dec(&waiting_for_crash_ipi);
+
+	local_irq_disable();
+
+	if (cpu_ops[cpu]->cpu_die)
+		cpu_ops[cpu]->cpu_die(cpu);
+
+	/* just in case */
+	while (1)
+		wfi();
+}
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -731,6 +757,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		irq_exit();
 		break;
 
+	case IPI_CPU_CRASH_STOP:
+		irq_enter();
+		ipi_cpu_crash_stop(cpu, regs);
+		irq_exit();
+		break;
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 	case IPI_TIMER:
 		irq_enter();
@@ -791,6 +823,30 @@ void smp_send_stop(void)
 		pr_warning("SMP: failed to stop secondary CPUs\n");
 }
 
+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);
+
+	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_warn("SMP: failed to stop secondary CPUs\n");
+}
+
 /*
  * not supported here
  */
-- 
2.5.0

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

* [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (17 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-18 18:08   ` James Morse
  2016-03-14 17:48 ` [PATCH v15 16/20] arm64: limit memory regions based on DT property, usable-memory Geoff Levand
  2016-04-01  1:59 ` [PATCH v15 00/20] arm64 kexec kernel patches v15 Dave Young
  20 siblings, 1 reply; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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      | 60 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 8119479..293cee2 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>
@@ -221,6 +220,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
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 7802f21..4edf181 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/fixmap.h>
 #include <asm/memory.h>
@@ -66,6 +67,63 @@ 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);
+	if (ret)
+		return;
+
+	if (crash_base == 0) {
+		crash_base = memblock_find_in_range(0,
+				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, 1 << 21);
+		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 (crash_base & ((1 << 21) - 1)) {
+			pr_warn("crashkernel base address is not 2MB aligned\n");
+			return;
+		}
+
+		memblock_reserve(crash_base, crash_size);
+	}
+
+	pr_info("Reserving %lldMB of memory@%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
@@ -171,6 +229,8 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #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] 45+ messages in thread

* [PATCH v15 19/20] arm64: kdump: enable kdump in the arm64 defconfig
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (13 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 20/20] arm64: kdump: update a kernel doc Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 18/20] arm64: kdump: add kdump support Geoff Levand
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 288cbd6..16bf6dc 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -65,6 +65,7 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_XEN=y
 CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
 CONFIG_CMDLINE="console=ttyAMA0"
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
-- 
2.5.0

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

* [PATCH v15 20/20] arm64: kdump: update a kernel doc
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (12 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 04/20] arm64: Add new hcall HVC_CALL_FUNC Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 19/20] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 bc4bd5a..acc4d98 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
 ===========================
 
@@ -312,6 +318,8 @@ Boot into System Kernel
    any space below the alignment point may be overwritten by the dump-capture kernel,
    which means it is possible that the vmcore is not that precise as expected.
 
+   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
 ============================
@@ -334,6 +342,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.
@@ -377,6 +387,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] 45+ messages in thread

* [PATCH v15 14/20] arm64/kexec: Add pr_debug output
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (15 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 18/20] arm64: kdump: add kdump support Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 | 67 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 6fd0f0c..75f6696 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -11,6 +11,7 @@
 
 #include <linux/highmem.h>
 #include <linux/kexec.h>
+#include <linux/libfdt_env.h>
 #include <linux/of_fdt.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
@@ -26,6 +27,47 @@ extern const unsigned long arm64_relocate_new_kernel_size;
 
 static unsigned long kimage_start;
 
+/**
+ * kexec_is_dtb - Helper routine to check the device tree header signature.
+ */
+static bool kexec_is_dtb(const void *dtb)
+{
+	__be32 magic;
+
+	if (get_user(magic, (__be32 *)dtb))
+		return false;
+
+	return fdt32_to_cpu(magic) == OF_DT_HEADER;
+}
+
+/**
+ * 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%s\n",
+			i,
+			kimage->segment[i].mem,
+			kimage->segment[i].mem + kimage->segment[i].memsz,
+			kimage->segment[i].memsz,
+			kimage->segment[i].memsz /  PAGE_SIZE,
+			(kexec_is_dtb(kimage->segment[i].buf) ?
+				", dtb segment" : ""));
+	}
+}
+
 void machine_kexec_cleanup(struct kimage *kimage)
 {
 	/* Empty routine needed to avoid build errors. */
@@ -39,6 +81,8 @@ void machine_kexec_cleanup(struct kimage *kimage)
 int machine_kexec_prepare(struct kimage *kimage)
 {
 	kimage_start = kimage->start;
+	kexec_image_info(kimage);
+
 	return 0;
 }
 
@@ -81,10 +125,10 @@ static void kexec_segment_flush(const struct kimage *kimage)
 {
 	unsigned long i;
 
-	pr_devel("%s:\n", __func__);
+	pr_debug("%s:\n", __func__);
 
 	for (i = 0; i < kimage->nr_segments; i++) {
-		pr_devel("  segment[%lu]: %016lx - %016lx, %lx bytes, %lu pages\n",
+		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,
@@ -111,6 +155,25 @@ void machine_kexec(struct kimage *kimage)
 	reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
 	reboot_code_buffer = kmap(kimage->control_code_page);
 
+	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] 45+ messages in thread

* [PATCH v15 18/20] arm64: kdump: add kdump support
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (14 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 19/20] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-03-14 17:48 ` [PATCH v15 14/20] arm64/kexec: Add pr_debug output Geoff Levand
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 3001c51..0780e4c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -613,6 +613,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 c0aa90d..804ecd4 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -44,6 +44,7 @@ arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.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 82527da..f5e21a4 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/fixmap.h>
 #include <asm/memory.h>
@@ -124,6 +125,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
@@ -268,6 +320,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] 45+ messages in thread

* [PATCH v15 16/20] arm64: limit memory regions based on DT property, usable-memory
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (18 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
@ 2016-03-14 17:48 ` Geoff Levand
  2016-04-01  1:59 ` [PATCH v15 00/20] arm64 kexec kernel patches v15 Dave Young
  20 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-14 17: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 | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 4edf181..82527da 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -215,8 +215,45 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init early_init_dt_scan_usablemem(unsigned long node,
+		const char *uname, int depth, void *data)
+{
+	struct memblock_region *usablemem = (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)
 {
+	fdt_enforce_memory_region();
+
 	memblock_enforce_memory_limit(memory_limit);
 
 	/*
-- 
2.5.0

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-14 17:48 ` [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value Geoff Levand
@ 2016-03-15 13:50   ` Dave Martin
  2016-03-15 18:15     ` Geoff Levand
  0 siblings, 1 reply; 45+ messages in thread
From: Dave Martin @ 2016-03-15 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Mon, Mar 14, 2016 at 05:48:00PM +0000, Geoff Levand wrote:
> The existing arm64 hcall implementations are limited in that they only
> allow for two distinct hcalls; with the x0 register either zero or not
> zero.  Also, the API of the hyp-stub exception vector routines and the
> KVM exception vector routines differ; hyp-stub uses a non-zero value in
> x0 to implement __hyp_set_vectors, whereas KVM uses it to implement
> kvm_call_hyp.
> 
> To allow for additional hcalls to be defined and to make the arm64 hcall
> API more consistent across exception vector routines, change the hcall
> implementations to use the 16 bit immediate value of the HVC instruction
> to specify the hcall type.

I'm a bit concerned about namespace pollution on the HVC immediate here.
Existing users tend allocate a single "random" number to identify the
API -- Xen and Jailhouse do this for example.

If we start using the HVC immediate to select functions, not just APIs,
the space is going to fill up a lot faster, if we have a multiplex
multiple APIs through it.

(We don't currently seem to multiplex APIs much here, except that we
do use HVC for PSCI calls from the guest, and it could be used for
additional paravirtualised services in the future).

> Define three new preprocessor macros HVC_CALL_HYP, HVC_GET_VECTORS, and
> HVC_SET_VECTORS to be used as hcall type specifiers and convert the
> existing __hyp_get_vectors(), __hyp_set_vectors() and kvm_call_hyp()
> routines to use these new macros when executing an HVC call.  Also,
> change the corresponding hyp-stub and KVM el1_sync exception vector
> routines to use these new macros.

It would also be preferable to keep the 32-bit and 64-bit APIs the same;
we should avoid having them different unless there's a clinching
technical reason...


There may be some historical context for this that I'm missing...

Cheers
---Dave

> 
> Signed-off-by: Geoff Levand <geoff@infradead.org>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/virt.h  | 27 +++++++++++++++++++++++++++
>  arch/arm64/kernel/hyp-stub.S   | 32 +++++++++++++++++++++-----------
>  arch/arm64/kvm/hyp.S           |  3 ++-
>  arch/arm64/kvm/hyp/hyp-entry.S |  9 ++++++---
>  4 files changed, 56 insertions(+), 15 deletions(-)
> 

[...]

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-15 13:50   ` Dave Martin
@ 2016-03-15 18:15     ` Geoff Levand
  2016-03-16 13:50       ` Dave Martin
  0 siblings, 1 reply; 45+ messages in thread
From: Geoff Levand @ 2016-03-15 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, 2016-03-15 at 13:50 +0000, Dave Martin wrote:
> On Mon, Mar 14, 2016 at 05:48:00PM +0000, Geoff Levand wrote:
> > The existing arm64 hcall implementations are limited in that they only
> > allow for two distinct hcalls; with the x0 register either zero or not
> > zero.  Also, the API of the hyp-stub exception vector routines and the
> > KVM exception vector routines differ; hyp-stub uses a non-zero value in
> > x0 to implement __hyp_set_vectors, whereas KVM uses it to implement
> > kvm_call_hyp.
> > 
> > To allow for additional hcalls to be defined and to make the arm64 hcall
> > API more consistent across exception vector routines, change the hcall
> > implementations to use the 16 bit immediate value of the HVC instruction
> > to specify the hcall type.
> 
> I'm a bit concerned about namespace pollution on the HVC immediate here.
> Existing users tend allocate a single "random" number to identify the
> API -- Xen and Jailhouse do this for example.
> 
> If we start using the HVC immediate to select functions, not just APIs,
> the space is going to fill up a lot faster, if we have a multiplex
> multiple APIs through it.

This was discussed and concluded that we have 16 bits to fill up,
and that is enough.  Functions can still be multiplexed through a
single HVC immediate if the user chooses to do so.

> 
> (We don't currently seem to multiplex APIs much here, except that we
> do use HVC for PSCI calls from the guest, and it could be used for
> additional paravirtualised services in the future).
> 
> > Define three new preprocessor macros HVC_CALL_HYP, HVC_GET_VECTORS, and
> > HVC_SET_VECTORS to be used as hcall type specifiers and convert the
> > existing __hyp_get_vectors(), __hyp_set_vectors() and kvm_call_hyp()
> > routines to use these new macros when executing an HVC call.  Also,
> > change the corresponding hyp-stub and KVM el1_sync exception vector
> > routines to use these new macros.
> 
> It would also be preferable to keep the 32-bit and 64-bit APIs the same;
> we should avoid having them different unless there's a clinching
> technical reason...

Please expand on why you see it as preferable.  What problems do
you see?

-Geoff

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-15 18:15     ` Geoff Levand
@ 2016-03-16 13:50       ` Dave Martin
  2016-03-16 14:09         ` Marc Zyngier
  0 siblings, 1 reply; 45+ messages in thread
From: Dave Martin @ 2016-03-16 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 15, 2016 at 11:15:10AM -0700, Geoff Levand wrote:
> Hi,
> 
> On Tue, 2016-03-15 at 13:50 +0000, Dave Martin wrote:
> > On Mon, Mar 14, 2016 at 05:48:00PM +0000, Geoff Levand wrote:
> > > The existing arm64 hcall implementations are limited in that they only
> > > allow for two distinct hcalls; with the x0 register either zero or not
> > > zero.  Also, the API of the hyp-stub exception vector routines and the
> > > KVM exception vector routines differ; hyp-stub uses a non-zero value in
> > > x0 to implement __hyp_set_vectors, whereas KVM uses it to implement
> > > kvm_call_hyp.
> > > 
> > > To allow for additional hcalls to be defined and to make the arm64 hcall
> > > API more consistent across exception vector routines, change the hcall
> > > implementations to use the 16 bit immediate value of the HVC instruction
> > > to specify the hcall type.
> > 
> > I'm a bit concerned about namespace pollution on the HVC immediate here.
> > Existing users tend allocate a single "random" number to identify the
> > API -- Xen and Jailhouse do this for example.
> > 
> > If we start using the HVC immediate to select functions, not just APIs,
> > the space is going to fill up a lot faster, if we have a multiplex
> > multiple APIs through it.
> 
> This was discussed and concluded that we have 16 bits to fill up,
> and that is enough.  Functions can still be multiplexed through a

Enough for what?

> single HVC immediate if the user chooses to do so.

But KVM can't?

The HVC #imm space doesn't seem to be managed, which implies that
discovery and/or renumbering mechanisms would be needed if we end up
wanting to mux multiple ABIs through there.  The tighter limitation
on immediate size, and the need for code patching if translation of
HVC numbers is needed, mean that this can be harder when using the HVC
immediate for demux rather than an ordinary register.

Currently, the only other ABI muxed through HVC is PSCI, but it
already looks like there is a potential collision -- HVC #0 from EL1 is
already KVM_CALL_HYP or a PSCI call, and we rely on knowing whether
the call came from the host or guest to demux it properly.

This kind of problem is likely to proliferate over time.

> > (We don't currently seem to multiplex APIs much here, except that we
> > do use HVC for PSCI calls from the guest, and it could be used for
> > additional paravirtualised services in the future).
> > 
> > > Define three new preprocessor macros HVC_CALL_HYP, HVC_GET_VECTORS, and
> > > HVC_SET_VECTORS to be used as hcall type specifiers and convert the
> > > existing __hyp_get_vectors(), __hyp_set_vectors() and kvm_call_hyp()
> > > routines to use these new macros when executing an HVC call.  Also,
> > > change the corresponding hyp-stub and KVM el1_sync exception vector
> > > routines to use these new macros.
> > 
> > It would also be preferable to keep the 32-bit and 64-bit APIs the same;
> > we should avoid having them different unless there's a clinching
> > technical reason...
> 
> Please expand on why you see it as preferable.  What problems do
> you see?

Fragmentation avoidance is the main argument I see.  The architectural
constraints and the problem to be solved are basically the same between
32- and 64-bit, AFAICT.

Cheers
---Dave

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-16 13:50       ` Dave Martin
@ 2016-03-16 14:09         ` Marc Zyngier
  2016-03-17 16:47           ` Geoff Levand
  0 siblings, 1 reply; 45+ messages in thread
From: Marc Zyngier @ 2016-03-16 14:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 16/03/16 13:50, Dave Martin wrote:
> On Tue, Mar 15, 2016 at 11:15:10AM -0700, Geoff Levand wrote:
>> Hi,
>>
>> On Tue, 2016-03-15 at 13:50 +0000, Dave Martin wrote:
>>> On Mon, Mar 14, 2016 at 05:48:00PM +0000, Geoff Levand wrote:
>>>> The existing arm64 hcall implementations are limited in that they only
>>>> allow for two distinct hcalls; with the x0 register either zero or not
>>>> zero.  Also, the API of the hyp-stub exception vector routines and the
>>>> KVM exception vector routines differ; hyp-stub uses a non-zero value in
>>>> x0 to implement __hyp_set_vectors, whereas KVM uses it to implement
>>>> kvm_call_hyp.
>>>>
>>>> To allow for additional hcalls to be defined and to make the arm64 hcall
>>>> API more consistent across exception vector routines, change the hcall
>>>> implementations to use the 16 bit immediate value of the HVC instruction
>>>> to specify the hcall type.
>>>
>>> I'm a bit concerned about namespace pollution on the HVC immediate here.
>>> Existing users tend allocate a single "random" number to identify the
>>> API -- Xen and Jailhouse do this for example.
>>>
>>> If we start using the HVC immediate to select functions, not just APIs,
>>> the space is going to fill up a lot faster, if we have a multiplex
>>> multiple APIs through it.
>>
>> This was discussed and concluded that we have 16 bits to fill up,
>> and that is enough.  Functions can still be multiplexed through a
> 
> Enough for what?
> 
>> single HVC immediate if the user chooses to do so.
> 
> But KVM can't?
> 
> The HVC #imm space doesn't seem to be managed, which implies that
> discovery and/or renumbering mechanisms would be needed if we end up
> wanting to mux multiple ABIs through there.  The tighter limitation
> on immediate size, and the need for code patching if translation of
> HVC numbers is needed, mean that this can be harder when using the HVC
> immediate for demux rather than an ordinary register.
> 
> Currently, the only other ABI muxed through HVC is PSCI, but it
> already looks like there is a potential collision -- HVC #0 from EL1 is
> already KVM_CALL_HYP or a PSCI call, and we rely on knowing whether
> the call came from the host or guest to demux it properly.
> 
> This kind of problem is likely to proliferate over time.
> 
>>> (We don't currently seem to multiplex APIs much here, except that we
>>> do use HVC for PSCI calls from the guest, and it could be used for
>>> additional paravirtualised services in the future).
>>>
>>>> Define three new preprocessor macros HVC_CALL_HYP, HVC_GET_VECTORS, and
>>>> HVC_SET_VECTORS to be used as hcall type specifiers and convert the
>>>> existing __hyp_get_vectors(), __hyp_set_vectors() and kvm_call_hyp()
>>>> routines to use these new macros when executing an HVC call.  Also,
>>>> change the corresponding hyp-stub and KVM el1_sync exception vector
>>>> routines to use these new macros.
>>>
>>> It would also be preferable to keep the 32-bit and 64-bit APIs the same;
>>> we should avoid having them different unless there's a clinching
>>> technical reason...
>>
>> Please expand on why you see it as preferable.  What problems do
>> you see?
> 
> Fragmentation avoidance is the main argument I see.  The architectural
> constraints and the problem to be solved are basically the same between
> 32- and 64-bit, AFAICT.

+1. I never quite understood why we went from a single HVC immediate + a
register indicating the operation to a proliferation of immediate values
(and still the need for a register to indicate the operation in most cases).

This seems to go in a direction that is diametrically opposite the the
"normal" ARM way. That doesn't make it an invalid approach, but
uniformity with other APIs (PSCI for example) and the 32bit KVM code
seems a highly desirable feature (given that I'll end up maintaining
that code).

Thanks,

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

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

* [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value
  2016-03-16 14:09         ` Marc Zyngier
@ 2016-03-17 16:47           ` Geoff Levand
  0 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2016-03-17 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On Wed, 2016-03-16 at 14:09 +0000, Marc Zyngier wrote:
> This seems to go in a direction that is diametrically opposite the
> the
> "normal" ARM way. That doesn't make it an invalid approach, but
> uniformity with other APIs (PSCI for example) and the 32bit KVM code
> seems a highly desirable feature (given that I'll end up maintaining
> that code).

We need a way to get the CPU back to the exception level it had on
entry to the kernel, and this hcall change is part of my proposed
solution.  If you could outline something you think would be a better
fit, I'll take that and work on an implementation of it.

-Geoff

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-14 17:48 ` [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
@ 2016-03-18 18:08   ` James Morse
  2016-03-21 13:29     ` James Morse
  2016-03-31  7:46     ` AKASHI Takahiro
  0 siblings, 2 replies; 45+ messages in thread
From: James Morse @ 2016-03-18 18:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

On 14/03/16 17:48, Geoff Levand wrote:
> 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>

> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index b1adc51..76402c6cd 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
>  		cpu_relax();
>  }
>  
> +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);
> +
> +	raw_spin_lock(&stop_lock);
> +	pr_debug("CPU%u: stopping\n", cpu);
> +	raw_spin_unlock(&stop_lock);
> +
> +	atomic_dec(&waiting_for_crash_ipi);
> +
> +	local_irq_disable();

Aren't irqs already disabled here? - or is this a 'just make sure'....


> +
> +	if (cpu_ops[cpu]->cpu_die)
> +		cpu_ops[cpu]->cpu_die(cpu);
> +
> +	/* just in case */
> +	while (1)
> +		wfi();
> +}
> +
>  /*
>   * Main handler for inter-processor interrupts
>   */
> @@ -731,6 +757,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  		irq_exit();
>  		break;
>  
> +	case IPI_CPU_CRASH_STOP:
> +		irq_enter();
> +		ipi_cpu_crash_stop(cpu, regs);
> +		irq_exit();

This made me jump: irq_exit() may end up in the __do_softirq() (with irqs turned
back on!) ... but these lines are impossible to reach. Maybe get the compiler to
enforce this with an unreachable() instead?


> +		break;
> +
>  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
>  	case IPI_TIMER:
>  		irq_enter();
> @@ -791,6 +823,30 @@ void smp_send_stop(void)
>  		pr_warning("SMP: failed to stop secondary CPUs\n");
>  }
>  
> +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);
> +
> +	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_warn("SMP: failed to stop secondary CPUs\n");
> +}
> +
>  /*
>   * not supported here
>   */
> 


Thanks,

James

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

* [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel
  2016-03-14 17:48 ` [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
@ 2016-03-18 18:08   ` James Morse
  2016-03-31  7:19     ` AKASHI Takahiro
  0 siblings, 1 reply; 45+ messages in thread
From: James Morse @ 2016-03-18 18:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

On 14/03/16 17: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.

[NB: Re-ordered diff hunks ]

> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 7802f21..4edf181 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -171,6 +229,8 @@ void __init arm64_memblock_init(void)
>  		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
>  #endif
>
> +	reserve_crashkernel();
> +
>  	early_init_fdt_scan_reserved_mem();
>
>  	/* 4GB maximum for 32-bit only capable devices */
>


This is 'nit' territory, but if you were to make this:
>	if (IS_ENABLED(CONFIG_KEXEC_CORE))
>		reserve_crashkernel();

then the #ifdefs around reserve_crashkernel() can go, and the compiler will work
out that this static function can be optimised out. It also means the
compiler performs its checks, even if CONFIG_KEXEC_CORE isn't selected. The same
trick can be applied in patch 18 (around reserve_elfcorehdr()).


> @@ -66,6 +67,63 @@ 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);
> +	if (ret)
> +		return;
> +
> +	if (crash_base == 0) {
> +		crash_base = memblock_find_in_range(0,
> +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, 1 << 21);
> +		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 (crash_base & ((1 << 21) - 1)) {
> +			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


Thanks,

James

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-18 18:08   ` James Morse
@ 2016-03-21 13:29     ` James Morse
  2016-03-31  7:57       ` AKASHI Takahiro
  2016-03-31  7:46     ` AKASHI Takahiro
  1 sibling, 1 reply; 45+ messages in thread
From: James Morse @ 2016-03-21 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

On 18/03/16 18:08, James Morse wrote:
> On 14/03/16 17:48, Geoff Levand wrote:
>> 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().

>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index b1adc51..76402c6cd 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
>>  		cpu_relax();
>>  }
>>  
>> +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);
>> +
>> +	raw_spin_lock(&stop_lock);
>> +	pr_debug("CPU%u: stopping\n", cpu);
>> +	raw_spin_unlock(&stop_lock);
>> +
>> +	atomic_dec(&waiting_for_crash_ipi);
>> +
>> +	local_irq_disable();
>> +
>> +	if (cpu_ops[cpu]->cpu_die)
>> +		cpu_ops[cpu]->cpu_die(cpu);
>> +
>> +	/* just in case */
>> +	while (1)
>> +		wfi();

Having thought about this some more: I don't think spinning like this is safe.
We need to spin with the MMU turned off, otherwise this core will pollute the
kdump kernel with TLB entries from the old page tables. Suzuki added code to
catch this happening with cpu hotplug (grep CPU_STUCK_IN_KERNEL in
arm64/for-next/core), but that won't help here. If 'CPU_STUCK_IN_KERNEL' was set
by a core, I don't think we can kexec/kdump for this reason.

Something like cpu_die() for spin-table is needed, naively I think it should
turn the MMU off, and jump back into the secondary_holding_pen, but the core
would still be stuck in the kernel, and the memory addresses associated with
secondary_holding_pen can't be re-used. (which is fine for kdump, but not kexec)


Thanks,

James

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

* [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel
  2016-03-18 18:08   ` James Morse
@ 2016-03-31  7:19     ` AKASHI Takahiro
  2016-04-01  6:16       ` AKASHI Takahiro
  0 siblings, 1 reply; 45+ messages in thread
From: AKASHI Takahiro @ 2016-03-31  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 18, 2016 at 06:08:30PM +0000, James Morse wrote:
> Hi!
> 
> On 14/03/16 17: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.
> 
> [NB: Re-ordered diff hunks ]
> 
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 7802f21..4edf181 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -171,6 +229,8 @@ void __init arm64_memblock_init(void)
> >  		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
> >  #endif
> >
> > +	reserve_crashkernel();
> > +
> >  	early_init_fdt_scan_reserved_mem();
> >
> >  	/* 4GB maximum for 32-bit only capable devices */
> >
> 
> 
> This is 'nit' territory, but if you were to make this:
> >	if (IS_ENABLED(CONFIG_KEXEC_CORE))
> >		reserve_crashkernel();
> 
> then the #ifdefs around reserve_crashkernel() can go, and the compiler will work
> out that this static function can be optimised out. It also means the
> compiler performs its checks, even if CONFIG_KEXEC_CORE isn't selected. The same
> trick can be applied in patch 18 (around reserve_elfcorehdr()).

It will also make the code more understandable.

Thanks,
-Takahiro AKASHI

> > @@ -66,6 +67,63 @@ 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);
> > +	if (ret)
> > +		return;
> > +
> > +	if (crash_base == 0) {
> > +		crash_base = memblock_find_in_range(0,
> > +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, 1 << 21);
> > +		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 (crash_base & ((1 << 21) - 1)) {
> > +			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
> 
> 
> Thanks,
> 
> James
> 

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-18 18:08   ` James Morse
  2016-03-21 13:29     ` James Morse
@ 2016-03-31  7:46     ` AKASHI Takahiro
  2016-03-31 10:22       ` James Morse
  1 sibling, 1 reply; 45+ messages in thread
From: AKASHI Takahiro @ 2016-03-31  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 18, 2016 at 06:08:15PM +0000, James Morse wrote:
> Hi!
> 
> On 14/03/16 17:48, Geoff Levand wrote:
> > 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>
> 
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index b1adc51..76402c6cd 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
> >  		cpu_relax();
> >  }
> >  
> > +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);
> > +
> > +	raw_spin_lock(&stop_lock);
> > +	pr_debug("CPU%u: stopping\n", cpu);
> > +	raw_spin_unlock(&stop_lock);
> > +
> > +	atomic_dec(&waiting_for_crash_ipi);
> > +
> > +	local_irq_disable();
> 
> Aren't irqs already disabled here? - or is this a 'just make sure'....

Well, it also exists in ipi_cpu_stop() ...

> > +
> > +	if (cpu_ops[cpu]->cpu_die)
> > +		cpu_ops[cpu]->cpu_die(cpu);
> > +
> > +	/* just in case */
> > +	while (1)
> > +		wfi();
> > +}
> > +
> >  /*
> >   * Main handler for inter-processor interrupts
> >   */
> > @@ -731,6 +757,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
> >  		irq_exit();
> >  		break;
> >  
> > +	case IPI_CPU_CRASH_STOP:
> > +		irq_enter();
> > +		ipi_cpu_crash_stop(cpu, regs);
> > +		irq_exit();
> 
> This made me jump: irq_exit() may end up in the __do_softirq() (with irqs turned
> back on!) ... but these lines are impossible to reach. Maybe get the compiler to
> enforce this with an unreachable() instead?

I'm not sure how effective unreachable() is here, but OK I will add it.

Thanks,
-Takahiro AKASHI

> > +		break;
> > +
> >  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> >  	case IPI_TIMER:
> >  		irq_enter();
> > @@ -791,6 +823,30 @@ void smp_send_stop(void)
> >  		pr_warning("SMP: failed to stop secondary CPUs\n");
> >  }
> >  
> > +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);
> > +
> > +	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_warn("SMP: failed to stop secondary CPUs\n");
> > +}
> > +
> >  /*
> >   * not supported here
> >   */
> > 
> 
> 
> Thanks,
> 
> James
> 
> 

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-21 13:29     ` James Morse
@ 2016-03-31  7:57       ` AKASHI Takahiro
  2016-03-31  8:12         ` Marc Zyngier
  0 siblings, 1 reply; 45+ messages in thread
From: AKASHI Takahiro @ 2016-03-31  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
> Hi!
> 
> On 18/03/16 18:08, James Morse wrote:
> > On 14/03/16 17:48, Geoff Levand wrote:
> >> 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().
> 
> >> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> >> index b1adc51..76402c6cd 100644
> >> --- a/arch/arm64/kernel/smp.c
> >> +++ b/arch/arm64/kernel/smp.c
> >> @@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
> >>  		cpu_relax();
> >>  }
> >>  
> >> +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);
> >> +
> >> +	raw_spin_lock(&stop_lock);
> >> +	pr_debug("CPU%u: stopping\n", cpu);
> >> +	raw_spin_unlock(&stop_lock);
> >> +
> >> +	atomic_dec(&waiting_for_crash_ipi);
> >> +
> >> +	local_irq_disable();
> >> +
> >> +	if (cpu_ops[cpu]->cpu_die)
> >> +		cpu_ops[cpu]->cpu_die(cpu);
> >> +
> >> +	/* just in case */
> >> +	while (1)
> >> +		wfi();
> 
> Having thought about this some more: I don't think spinning like this is safe.
> We need to spin with the MMU turned off, otherwise this core will pollute the
> kdump kernel with TLB entries from the old page tables.

I think that wfi() will never wake up since local interrupts are disabled
here. So how can it pollute the kdump kernel?

> Suzuki added code to
> catch this happening with cpu hotplug (grep CPU_STUCK_IN_KERNEL in
> arm64/for-next/core), but that won't help here. If 'CPU_STUCK_IN_KERNEL' was set
> by a core, I don't think we can kexec/kdump for this reason.

I will need to look into Suzuki's code.

> Something like cpu_die() for spin-table is needed, naively I think it should
> turn the MMU off, and jump back into the secondary_holding_pen, but the core
> would still be stuck in the kernel, and the memory addresses associated with
> secondary_holding_pen can't be re-used. (which is fine for kdump, but not kexec)

Please note that the code is exercised only in kdump case
through machine_crash_shutdown().

Thanks,
-Takahiro AKASHI

> 
> Thanks,
> 
> James
> 

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-31  7:57       ` AKASHI Takahiro
@ 2016-03-31  8:12         ` Marc Zyngier
  2016-03-31 10:10           ` Mark Rutland
  0 siblings, 1 reply; 45+ messages in thread
From: Marc Zyngier @ 2016-03-31  8:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 31/03/16 08:57, AKASHI Takahiro wrote:
> On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
>> Hi!
>>
>> On 18/03/16 18:08, James Morse wrote:
>>> On 14/03/16 17:48, Geoff Levand wrote:
>>>> 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().
>>
>>>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>>>> index b1adc51..76402c6cd 100644
>>>> --- a/arch/arm64/kernel/smp.c
>>>> +++ b/arch/arm64/kernel/smp.c
>>>> @@ -701,6 +705,28 @@ static void ipi_cpu_stop(unsigned int cpu)
>>>>  		cpu_relax();
>>>>  }
>>>>  
>>>> +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);
>>>> +
>>>> +	raw_spin_lock(&stop_lock);
>>>> +	pr_debug("CPU%u: stopping\n", cpu);
>>>> +	raw_spin_unlock(&stop_lock);
>>>> +
>>>> +	atomic_dec(&waiting_for_crash_ipi);
>>>> +
>>>> +	local_irq_disable();
>>>> +
>>>> +	if (cpu_ops[cpu]->cpu_die)
>>>> +		cpu_ops[cpu]->cpu_die(cpu);
>>>> +
>>>> +	/* just in case */
>>>> +	while (1)
>>>> +		wfi();
>>
>> Having thought about this some more: I don't think spinning like this is safe.
>> We need to spin with the MMU turned off, otherwise this core will pollute the
>> kdump kernel with TLB entries from the old page tables.
> 
> I think that wfi() will never wake up since local interrupts are disabled
> here. So how can it pollute the kdump kernel?

Having interrupts disabled doesn't prevent an exit from WFI. Quite the
opposite, actually. It is designed to wake-up the core when something
happens on the external interface.

Thanks,

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

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-31  8:12         ` Marc Zyngier
@ 2016-03-31 10:10           ` Mark Rutland
  2016-04-01  8:45             ` AKASHI Takahiro
  0 siblings, 1 reply; 45+ messages in thread
From: Mark Rutland @ 2016-03-31 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 31, 2016 at 09:12:32AM +0100, Marc Zyngier wrote:
> On 31/03/16 08:57, AKASHI Takahiro wrote:
> > On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
> >> On 18/03/16 18:08, James Morse wrote:
> >>> On 14/03/16 17:48, Geoff Levand wrote:
> >>>> +	/* just in case */
> >>>> +	while (1)
> >>>> +		wfi();
> >>
> >> Having thought about this some more: I don't think spinning like this is safe.
> >> We need to spin with the MMU turned off, otherwise this core will pollute the
> >> kdump kernel with TLB entries from the old page tables.
> > 
> > I think that wfi() will never wake up since local interrupts are disabled
> > here. So how can it pollute the kdump kernel?
> 
> Having interrupts disabled doesn't prevent an exit from WFI. Quite the
> opposite, actually. It is designed to wake-up the core when something
> happens on the external interface.

Further, WFI is a hint, and may simply act as a NOP. 

The ARM ARM calls this out (see "D1.17.2" Wait For Interrupt in ARM DDI
0487A.i):

	Because the architecture permits a PE to leave the low-power
	state for any reason, it is permissible for a PE to treat WFI as
	a NOP , but this is not recommended for lowest power operation.

Thanks,
Mark.

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-31  7:46     ` AKASHI Takahiro
@ 2016-03-31 10:22       ` James Morse
  0 siblings, 0 replies; 45+ messages in thread
From: James Morse @ 2016-03-31 10:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 31/03/16 08:46, AKASHI Takahiro wrote:
> James Morse wrote:
> > This made me jump: irq_exit() may end up in the __do_softirq() (with irqs turned
> > back on!) ... but these lines are impossible to reach. Maybe get the compiler to
> > enforce this with an unreachable() instead?
>
> I'm not sure how effective unreachable() is here, but OK I will add it.

I thought '__builtin_unreachable()' would generate a warning if it was
reachable, but from [0] it looks like it just suppresses warnings.

You're right, it won't help.

Thanks,


James

[0] https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
                   ` (19 preceding siblings ...)
  2016-03-14 17:48 ` [PATCH v15 16/20] arm64: limit memory regions based on DT property, usable-memory Geoff Levand
@ 2016-04-01  1:59 ` Dave Young
  2016-04-01 18:39   ` Geoff Levand
  20 siblings, 1 reply; 45+ messages in thread
From: Dave Young @ 2016-04-01  1:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/14/16 at 05:47pm, Geoff Levand wrote:
> 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.
> 
> 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
> 
> [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
> 

Geoff, for easier to review maybe you can send kexec patches first then AKASHI Takahiro
can send the kdump patches as a standalone patchset?

Thanks
Dave

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

* [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel
  2016-03-31  7:19     ` AKASHI Takahiro
@ 2016-04-01  6:16       ` AKASHI Takahiro
  0 siblings, 0 replies; 45+ messages in thread
From: AKASHI Takahiro @ 2016-04-01  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/31/2016 02:19 PM, AKASHI Takahiro wrote:
> On Fri, Mar 18, 2016 at 06:08:30PM +0000, James Morse wrote:
>> Hi!
>>
>> On 14/03/16 17: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.
>>
>> [NB: Re-ordered diff hunks ]
>>
>>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>>> index 7802f21..4edf181 100644
>>> --- a/arch/arm64/mm/init.c
>>> +++ b/arch/arm64/mm/init.c
>>> @@ -171,6 +229,8 @@ void __init arm64_memblock_init(void)
>>>   		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
>>>   #endif
>>>
>>> +	reserve_crashkernel();
>>> +
>>>   	early_init_fdt_scan_reserved_mem();
>>>
>>>   	/* 4GB maximum for 32-bit only capable devices */
>>>
>>
>>
>> This is 'nit' territory, but if you were to make this:
>>> 	if (IS_ENABLED(CONFIG_KEXEC_CORE))
>>> 		reserve_crashkernel();
>>
>> then the #ifdefs around reserve_crashkernel() can go, and the compiler will work
>> out that this static function can be optimised out. It also means the
>> compiler performs its checks, even if CONFIG_KEXEC_CORE isn't selected. The same
>> trick can be applied in patch 18 (around reserve_elfcorehdr()).
> 
> It will also make the code more understandable.

I tried this change, but
unfortunately, preserve_crashkernel() calls an external function, parse_crashkernel(),
which is defined only if CONFIG_KEXEC_CORE. So we will see a compiler error in !CONFIG_KEXEC_CORE
if we take #ifdef out around perserve_crashkernel().

-Takahiro AKASHI


> Thanks,
> -Takahiro AKASHI
> 
>>> @@ -66,6 +67,63 @@ 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);
>>> +	if (ret)
>>> +		return;
>>> +
>>> +	if (crash_base == 0) {
>>> +		crash_base = memblock_find_in_range(0,
>>> +				MEMBLOCK_ALLOC_ACCESSIBLE, crash_size, 1 << 21);
>>> +		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 (crash_base & ((1 << 21) - 1)) {
>>> +			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
>>
>>
>> Thanks,
>>
>> James
>>

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-03-31 10:10           ` Mark Rutland
@ 2016-04-01  8:45             ` AKASHI Takahiro
  2016-04-01  9:36               ` Mark Rutland
  0 siblings, 1 reply; 45+ messages in thread
From: AKASHI Takahiro @ 2016-04-01  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 31, 2016 at 11:10:38AM +0100, Mark Rutland wrote:
> On Thu, Mar 31, 2016 at 09:12:32AM +0100, Marc Zyngier wrote:
> > On 31/03/16 08:57, AKASHI Takahiro wrote:
> > > On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
> > >> On 18/03/16 18:08, James Morse wrote:
> > >>> On 14/03/16 17:48, Geoff Levand wrote:
> > >>>> +	/* just in case */
> > >>>> +	while (1)
> > >>>> +		wfi();
> > >>
> > >> Having thought about this some more: I don't think spinning like this is safe.
> > >> We need to spin with the MMU turned off, otherwise this core will pollute the
> > >> kdump kernel with TLB entries from the old page tables.
> > > 
> > > I think that wfi() will never wake up since local interrupts are disabled
> > > here. So how can it pollute the kdump kernel?
> > 
> > Having interrupts disabled doesn't prevent an exit from WFI. Quite the
> > opposite, actually. It is designed to wake-up the core when something
> > happens on the external interface.
> 
> Further, WFI is a hint, and may simply act as a NOP. 

Ah, OK. But even so, none of interrupt handlers (nor other code) will be
executed after cpu wakes up, and the memory won't be polluted.
Or do I still miss something?

-Takahiro AKASHI
 
> The ARM ARM calls this out (see "D1.17.2" Wait For Interrupt in ARM DDI
> 0487A.i):
> 
> 	Because the architecture permits a PE to leave the low-power
> 	state for any reason, it is permissible for a PE to treat WFI as
> 	a NOP , but this is not recommended for lowest power operation.
> 
> Thanks,
> Mark.

-- 
Thanks,
-Takahiro AKASHI

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-04-01  8:45             ` AKASHI Takahiro
@ 2016-04-01  9:36               ` Mark Rutland
  2016-04-04  9:27                 ` AKASHI Takahiro
  0 siblings, 1 reply; 45+ messages in thread
From: Mark Rutland @ 2016-04-01  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 01, 2016 at 05:45:09PM +0900, AKASHI Takahiro wrote:
> On Thu, Mar 31, 2016 at 11:10:38AM +0100, Mark Rutland wrote:
> > On Thu, Mar 31, 2016 at 09:12:32AM +0100, Marc Zyngier wrote:
> > > On 31/03/16 08:57, AKASHI Takahiro wrote:
> > > > On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
> > > >> On 18/03/16 18:08, James Morse wrote:
> > > >>> On 14/03/16 17:48, Geoff Levand wrote:
> > > >>>> +	/* just in case */
> > > >>>> +	while (1)
> > > >>>> +		wfi();
> > > >>
> > > >> Having thought about this some more: I don't think spinning like this is safe.
> > > >> We need to spin with the MMU turned off, otherwise this core will pollute the
> > > >> kdump kernel with TLB entries from the old page tables.
> > > > 
> > > > I think that wfi() will never wake up since local interrupts are disabled
> > > > here. So how can it pollute the kdump kernel?
> > > 
> > > Having interrupts disabled doesn't prevent an exit from WFI. Quite the
> > > opposite, actually. It is designed to wake-up the core when something
> > > happens on the external interface.
> > 
> > Further, WFI is a hint, and may simply act as a NOP. 
> 
> Ah, OK. But even so, none of interrupt handlers (nor other code) will
> be executed after cpu wakes up, and the memory won't be polluted.

The code comprising the while(1) loop will be executed, and TLB walks,
speculative fetches, etc may occur regardless.

We don't share TLB entries between cores (we don't have support for
ARMv8.2s CnP), and the kdump kernel should be running in a carveout from
main memory (which IIUC is not mapped by the original kernel). So
normally, this would not be a problem.

However, if there is a problem with the page tables (e.g. entries
erroneously point into a PA range the kdump kernel is using), then
unavoidable background memory traffic from the CPU may cause problems
for the kdump kernel.

Thanks,
Mark.

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-04-01  1:59 ` [PATCH v15 00/20] arm64 kexec kernel patches v15 Dave Young
@ 2016-04-01 18:39   ` Geoff Levand
  2016-05-17  5:42     ` Dave Young
  0 siblings, 1 reply; 45+ messages in thread
From: Geoff Levand @ 2016-04-01 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Fri, 2016-04-01 at 09:59 +0800, Dave Young wrote:
> Geoff, for easier to review maybe you can send kexec patches first
> then AKASHI Takahiro
> can send the kdump patches as a standalone patchset?

Marc Zyngier specifically asked for an integrated set
of patches for easier review.  I will keep it that way
for now.

-Geoff

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

* [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown()
  2016-04-01  9:36               ` Mark Rutland
@ 2016-04-04  9:27                 ` AKASHI Takahiro
  0 siblings, 0 replies; 45+ messages in thread
From: AKASHI Takahiro @ 2016-04-04  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

Mark,

On Fri, Apr 01, 2016 at 10:36:35AM +0100, Mark Rutland wrote:
> On Fri, Apr 01, 2016 at 05:45:09PM +0900, AKASHI Takahiro wrote:
> > On Thu, Mar 31, 2016 at 11:10:38AM +0100, Mark Rutland wrote:
> > > On Thu, Mar 31, 2016 at 09:12:32AM +0100, Marc Zyngier wrote:
> > > > On 31/03/16 08:57, AKASHI Takahiro wrote:
> > > > > On Mon, Mar 21, 2016 at 01:29:28PM +0000, James Morse wrote:
> > > > >> On 18/03/16 18:08, James Morse wrote:
> > > > >>> On 14/03/16 17:48, Geoff Levand wrote:
> > > > >>>> +	/* just in case */
> > > > >>>> +	while (1)
> > > > >>>> +		wfi();
> > > > >>
> > > > >> Having thought about this some more: I don't think spinning like this is safe.
> > > > >> We need to spin with the MMU turned off, otherwise this core will pollute the
> > > > >> kdump kernel with TLB entries from the old page tables.
> > > > > 
> > > > > I think that wfi() will never wake up since local interrupts are disabled
> > > > > here. So how can it pollute the kdump kernel?
> > > > 
> > > > Having interrupts disabled doesn't prevent an exit from WFI. Quite the
> > > > opposite, actually. It is designed to wake-up the core when something
> > > > happens on the external interface.
> > > 
> > > Further, WFI is a hint, and may simply act as a NOP. 
> > 
> > Ah, OK. But even so, none of interrupt handlers (nor other code) will
> > be executed after cpu wakes up, and the memory won't be polluted.
> 
> The code comprising the while(1) loop will be executed, and TLB walks,
> speculative fetches, etc may occur regardless.
> 
> We don't share TLB entries between cores (we don't have support for
> ARMv8.2s CnP), and the kdump kernel should be running in a carveout from
> main memory (which IIUC is not mapped by the original kernel). So
> normally, this would not be a problem.

In fact, the memory region for crash kernel will be just memblock_reserve()'d.
We can't do memblock_remove() here because that region is expected to
exist as part of system memory.
(For details, see kimage_load_crash_segment() in kexec_core.c.)
Should we remove it from kernel mapping?
 
> However, if there is a problem with the page tables (e.g. entries
> erroneously point into a PA range the kdump kernel is using), then
> unavoidable background memory traffic from the CPU may cause problems
> for the kdump kernel.

But the traffic generated by the cpu will concentrate on the area around
the while loop, ipi_cpu_crash_stop(), in the *crashed* kernel's memory.
(I'm not sure about speculative behaviors.)

So I don't think it will hurt kdump kernel.

Thanks,
-Takahiro AKASHI

 
> Thanks,
> Mark.

-- 
Thanks,
-Takahiro AKASHI

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-04-01 18:39   ` Geoff Levand
@ 2016-05-17  5:42     ` Dave Young
  2016-05-17  8:06       ` Marc Zyngier
  0 siblings, 1 reply; 45+ messages in thread
From: Dave Young @ 2016-05-17  5:42 UTC (permalink / raw)
  To: linux-arm-kernel

Marc, it has been discussed for long time, I think kdump code can be
logically splitted from this series so that we can get the kexec
done first? 

On 04/01/16 at 11:39am, Geoff Levand wrote:
> Hi,
> 
> On Fri, 2016-04-01 at 09:59 +0800, Dave Young wrote:
> > Geoff, for easier to review maybe you can send kexec patches first
> > then AKASHI Takahiro
> > can send the kdump patches as a standalone patchset?
> 
> Marc Zyngier specifically asked for an integrated set
> of patches for easier review.  I will keep it that way
> for now.
> 
> -Geoff

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-05-17  5:42     ` Dave Young
@ 2016-05-17  8:06       ` Marc Zyngier
  2016-05-17  9:07         ` AKASHI Takahiro
  2016-05-18  2:09         ` Dave Young
  0 siblings, 2 replies; 45+ messages in thread
From: Marc Zyngier @ 2016-05-17  8:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dave,

On 17/05/16 06:42, Dave Young wrote:
> Marc, it has been discussed for long time, I think kdump code can be
> logically splitted from this series so that we can get the kexec
> done first? 

The basis for kexec are already on their way to mainline, as part of the
hibernate series that James has put together.

I'd expect someone to:

1) rebase the remaining kexec/kdump patches based on the current
arm64/for-next/core,
2) post these patches when -rc1 gets cut in two weeks from now,
3) address the review comments in a timely manner,
4) update the series once a week so that we see some actual progress

If this happens, I can't see any reason why this code wouldn't get
merged. But keeping kexec and kdump together is not what has prevented
the code from getting merged until now.

Thanks,

	M.
> 
> On 04/01/16 at 11:39am, Geoff Levand wrote:
>> Hi,
>>
>> On Fri, 2016-04-01 at 09:59 +0800, Dave Young wrote:
>>> Geoff, for easier to review maybe you can send kexec patches first
>>> then AKASHI Takahiro
>>> can send the kdump patches as a standalone patchset?
>>
>> Marc Zyngier specifically asked for an integrated set
>> of patches for easier review.  I will keep it that way
>> for now.
>>
>> -Geoff
> 


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

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-05-17  8:06       ` Marc Zyngier
@ 2016-05-17  9:07         ` AKASHI Takahiro
  2016-05-18  2:09         ` Dave Young
  1 sibling, 0 replies; 45+ messages in thread
From: AKASHI Takahiro @ 2016-05-17  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

Marc, Dave

On Tue, May 17, 2016 at 09:06:54AM +0100, Marc Zyngier wrote:
> Hi Dave,
> 
> On 17/05/16 06:42, Dave Young wrote:
> > Marc, it has been discussed for long time, I think kdump code can be
> > logically splitted from this series so that we can get the kexec
> > done first? 
> 
> The basis for kexec are already on their way to mainline, as part of the
> hibernate series that James has put together.
> 
> I'd expect someone to:
> 
> 1) rebase the remaining kexec/kdump patches based on the current
> arm64/for-next/core,

Done. At the time of last week.
The only issue that I have now is a support for KASLR, but this is not
a kernel issue, but tool's. I'm now talking with Dave Anderson (RedHat)
about how we should fix it.

> 2) post these patches when -rc1 gets cut in two weeks from now,

Yes, we are planning to do so.

> 3) address the review comments in a timely manner,

I'd like to expect the code to be reviewed in a timely manner, too.
In v4.6, we have not got any comments (nor ack's) on kexec/kdump-specific
part of patches. If this happens again, it will make the turnaround of our
re-spinning even longer.

> 4) update the series once a week so that we see some actual progress

Yes if we have updates.

> If this happens, I can't see any reason why this code wouldn't get
> merged. But keeping kexec and kdump together is not what has prevented
> the code from getting merged until now.

Yeah, agree.

Thanks,
-Takahiro AKASHI

> 
> Thanks,
> 
> 	M.
> > 
> > On 04/01/16 at 11:39am, Geoff Levand wrote:
> >> Hi,
> >>
> >> On Fri, 2016-04-01 at 09:59 +0800, Dave Young wrote:
> >>> Geoff, for easier to review maybe you can send kexec patches first
> >>> then AKASHI Takahiro
> >>> can send the kdump patches as a standalone patchset?
> >>
> >> Marc Zyngier specifically asked for an integrated set
> >> of patches for easier review.  I will keep it that way
> >> for now.
> >>
> >> -Geoff
> > 
> 
> 
> -- 
> Jazz is not dead. It just smells funny...

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

* [PATCH v15 00/20] arm64 kexec kernel patches v15
  2016-05-17  8:06       ` Marc Zyngier
  2016-05-17  9:07         ` AKASHI Takahiro
@ 2016-05-18  2:09         ` Dave Young
  1 sibling, 0 replies; 45+ messages in thread
From: Dave Young @ 2016-05-18  2:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc

On 05/17/16 at 09:06am, Marc Zyngier wrote:
> Hi Dave,
> 
> On 17/05/16 06:42, Dave Young wrote:
> > Marc, it has been discussed for long time, I think kdump code can be
> > logically splitted from this series so that we can get the kexec
> > done first? 
> 
> The basis for kexec are already on their way to mainline, as part of the
> hibernate series that James has put together.
> 
> I'd expect someone to:
> 
> 1) rebase the remaining kexec/kdump patches based on the current
> arm64/for-next/core,
> 2) post these patches when -rc1 gets cut in two weeks from now,
> 3) address the review comments in a timely manner,
> 4) update the series once a week so that we see some actual progress
> 
> If this happens, I can't see any reason why this code wouldn't get
> merged. But keeping kexec and kdump together is not what has prevented
> the code from getting merged until now.

Cool, thanks a lot for the clarification about the situation.

Dave

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

end of thread, other threads:[~2016-05-18  2:09 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-14 17:47 [PATCH v15 00/20] arm64 kexec kernel patches v15 Geoff Levand
2016-03-14 17:48 ` [PATCH v15 07/20] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file Geoff Levand
2016-03-14 17:48 ` [PATCH v15 03/20] arm64: Convert hcalls to use HVC immediate value Geoff Levand
2016-03-15 13:50   ` Dave Martin
2016-03-15 18:15     ` Geoff Levand
2016-03-16 13:50       ` Dave Martin
2016-03-16 14:09         ` Marc Zyngier
2016-03-17 16:47           ` Geoff Levand
2016-03-14 17:48 ` [PATCH v15 12/20] arm64/kexec: Add core kexec support Geoff Levand
2016-03-14 17:48 ` [PATCH v15 11/20] Revert "arm64: remove dead code" Geoff Levand
2016-03-14 17:48 ` [PATCH v15 05/20] arm64: kvm: allows kvm cpu hotplug Geoff Levand
2016-03-14 17:48 ` [PATCH v15 10/20] Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function" Geoff Levand
2016-03-14 17:48 ` [PATCH v15 13/20] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand
2016-03-14 17:48 ` [PATCH v15 02/20] arm64: Cleanup SCTLR flags Geoff Levand
2016-03-14 17:48 ` [PATCH v15 08/20] arm64: Add new asm macro copy_page Geoff Levand
2016-03-14 17:48 ` [PATCH v15 06/20] arm64: kernel: Include _AC definition in page.h Geoff Levand
2016-03-14 17:48 ` [PATCH v15 01/20] arm64: Fold proc-macros.S into assembler.h Geoff Levand
2016-03-14 17:48 ` [PATCH v15 09/20] arm64: Add back cpu_reset routines Geoff Levand
2016-03-14 17:48 ` [PATCH v15 04/20] arm64: Add new hcall HVC_CALL_FUNC Geoff Levand
2016-03-14 17:48 ` [PATCH v15 20/20] arm64: kdump: update a kernel doc Geoff Levand
2016-03-14 17:48 ` [PATCH v15 19/20] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand
2016-03-14 17:48 ` [PATCH v15 18/20] arm64: kdump: add kdump support Geoff Levand
2016-03-14 17:48 ` [PATCH v15 14/20] arm64/kexec: Add pr_debug output Geoff Levand
2016-03-14 17:48 ` [PATCH v15 17/20] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
2016-03-18 18:08   ` James Morse
2016-03-21 13:29     ` James Morse
2016-03-31  7:57       ` AKASHI Takahiro
2016-03-31  8:12         ` Marc Zyngier
2016-03-31 10:10           ` Mark Rutland
2016-04-01  8:45             ` AKASHI Takahiro
2016-04-01  9:36               ` Mark Rutland
2016-04-04  9:27                 ` AKASHI Takahiro
2016-03-31  7:46     ` AKASHI Takahiro
2016-03-31 10:22       ` James Morse
2016-03-14 17:48 ` [PATCH v15 15/20] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
2016-03-18 18:08   ` James Morse
2016-03-31  7:19     ` AKASHI Takahiro
2016-04-01  6:16       ` AKASHI Takahiro
2016-03-14 17:48 ` [PATCH v15 16/20] arm64: limit memory regions based on DT property, usable-memory Geoff Levand
2016-04-01  1:59 ` [PATCH v15 00/20] arm64 kexec kernel patches v15 Dave Young
2016-04-01 18:39   ` Geoff Levand
2016-05-17  5:42     ` Dave Young
2016-05-17  8:06       ` Marc Zyngier
2016-05-17  9:07         ` AKASHI Takahiro
2016-05-18  2:09         ` Dave Young

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).