From: geoff@infradead.org (Geoff Levand) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v10.1 12/16] arm64: kdump: implement machine_crash_shutdown() Date: Tue, 20 Oct 2015 11:54:06 -0700 [thread overview] Message-ID: <1445367246.30908.78.camel@infradead.org> (raw) In-Reply-To: <10adbaf4a069aabc3d774963cf6613dfa46f923d.1445297709.git.geoff@infradead.org> From: AKASHI Takahiro <takahiro.akashi@linaro.org> kdump calls machine_crash_shutdown() to shut down non-boot cpus and save registers' status in per-cpu ELF notes before starting the crash dump kernel. See kernel_kexec(). ipi_cpu_stop() is a bit modified and used to support this behavior. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> --- v10.1: Fixed: crash dump kernel won't be able to boot if a kvm guest is running at crash. This is because we don't have any chance to reset EL2 mode at crash and so "switch to EL2" in cpu_reset fails. arch/arm64/include/asm/kexec.h | 34 +++++++++++++++++++++++++++++++++- arch/arm64/kernel/machine_kexec.c | 32 ++++++++++++++++++++++++++++++-- arch/arm64/kernel/smp.c | 16 ++++++++++++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index 46d63cd..555a955 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -30,6 +30,8 @@ #if !defined(__ASSEMBLY__) +extern bool in_crash_kexec; + /** * crash_setup_regs() - save registers for the panic kernel * @@ -40,7 +42,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 /* !defined(__ASSEMBLY__) */ diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 362f719..8595d43 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include <linux/kernel.h> #include <linux/kexec.h> #include <linux/of_fdt.h> #include <linux/slab.h> @@ -28,6 +29,8 @@ extern unsigned long arm64_kexec_kimage_start_offset; static unsigned long kimage_head; static unsigned long kimage_start; +bool in_crash_kexec; + /** * kexec_is_dtb - Helper routine to check the device tree header signature. */ @@ -121,7 +124,7 @@ static void soft_restart(unsigned long addr) { setup_mm_for_reboot(); cpu_soft_restart(virt_to_phys(cpu_reset), addr, - is_hyp_mode_available()); + (in_crash_kexec ? 0 : is_hyp_mode_available())); BUG(); /* Should never get here. */ } @@ -198,7 +201,32 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_code_buffer_phys); } +/** + * machine_crash_shutdown - shutdown non-boot cpus and save registers + */ void machine_crash_shutdown(struct pt_regs *regs) { - /* Empty routine needed to avoid build errors. */ + struct pt_regs dummy_regs; + int cpu; + + local_irq_disable(); + + in_crash_kexec = true; + + /* + * clear and initialize the per-cpu info. This is necessary + * because, otherwise, slots for offline cpus would never be + * filled up. See smp_send_stop(). + */ + memset(&dummy_regs, 0, sizeof(dummy_regs)); + for_each_possible_cpu(cpu) + crash_save_cpu(&dummy_regs, cpu); + + /* shutdown non-boot cpus */ + smp_send_stop(); + + /* for boot cpu */ + crash_save_cpu(regs, smp_processor_id()); + + pr_info("Loading crashdump kernel...\n"); } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index dbdaacd..88aec66 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> @@ -54,6 +55,8 @@ #include <asm/ptrace.h> #include <asm/virt.h> +#include "cpu-reset.h" + #define CREATE_TRACE_POINTS #include <trace/events/ipi.h> @@ -679,8 +682,12 @@ static DEFINE_RAW_SPINLOCK(stop_lock); /* * ipi_cpu_stop - handle IPI from smp_send_stop() */ -static void ipi_cpu_stop(unsigned int cpu) +static void ipi_cpu_stop(unsigned int cpu, struct pt_regs *regs) { +#ifdef CONFIG_KEXEC + /* printing messages may slow down the shutdown. */ + if (!in_crash_kexec) +#endif if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { raw_spin_lock(&stop_lock); @@ -693,6 +700,11 @@ static void ipi_cpu_stop(unsigned int cpu) local_irq_disable(); +#ifdef CONFIG_KEXEC + if (in_crash_kexec) + crash_save_cpu(regs, cpu); +#endif /* CONFIG_KEXEC */ + while (1) cpu_relax(); } @@ -723,7 +735,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) case IPI_CPU_STOP: irq_enter(); - ipi_cpu_stop(cpu); + ipi_cpu_stop(cpu, regs); irq_exit(); break; -- 2.5.0
WARNING: multiple messages have this Message-ID (diff)
From: Geoff Levand <geoff@infradead.org> To: Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will.deacon@arm.com> Cc: Mark Rutland <mark.rutland@arm.com>, AKASHI@infradead.org, marc.zyngier@arm.com, kexec@lists.infradead.org, Takahiro <takahiro.akashi@linaro.org>, christoffer.dall@linaro.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v10.1 12/16] arm64: kdump: implement machine_crash_shutdown() Date: Tue, 20 Oct 2015 11:54:06 -0700 [thread overview] Message-ID: <1445367246.30908.78.camel@infradead.org> (raw) In-Reply-To: <10adbaf4a069aabc3d774963cf6613dfa46f923d.1445297709.git.geoff@infradead.org> From: AKASHI Takahiro <takahiro.akashi@linaro.org> kdump calls machine_crash_shutdown() to shut down non-boot cpus and save registers' status in per-cpu ELF notes before starting the crash dump kernel. See kernel_kexec(). ipi_cpu_stop() is a bit modified and used to support this behavior. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> --- v10.1: Fixed: crash dump kernel won't be able to boot if a kvm guest is running at crash. This is because we don't have any chance to reset EL2 mode at crash and so "switch to EL2" in cpu_reset fails. arch/arm64/include/asm/kexec.h | 34 +++++++++++++++++++++++++++++++++- arch/arm64/kernel/machine_kexec.c | 32 ++++++++++++++++++++++++++++++-- arch/arm64/kernel/smp.c | 16 ++++++++++++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index 46d63cd..555a955 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -30,6 +30,8 @@ #if !defined(__ASSEMBLY__) +extern bool in_crash_kexec; + /** * crash_setup_regs() - save registers for the panic kernel * @@ -40,7 +42,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 /* !defined(__ASSEMBLY__) */ diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 362f719..8595d43 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include <linux/kernel.h> #include <linux/kexec.h> #include <linux/of_fdt.h> #include <linux/slab.h> @@ -28,6 +29,8 @@ extern unsigned long arm64_kexec_kimage_start_offset; static unsigned long kimage_head; static unsigned long kimage_start; +bool in_crash_kexec; + /** * kexec_is_dtb - Helper routine to check the device tree header signature. */ @@ -121,7 +124,7 @@ static void soft_restart(unsigned long addr) { setup_mm_for_reboot(); cpu_soft_restart(virt_to_phys(cpu_reset), addr, - is_hyp_mode_available()); + (in_crash_kexec ? 0 : is_hyp_mode_available())); BUG(); /* Should never get here. */ } @@ -198,7 +201,32 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_code_buffer_phys); } +/** + * machine_crash_shutdown - shutdown non-boot cpus and save registers + */ void machine_crash_shutdown(struct pt_regs *regs) { - /* Empty routine needed to avoid build errors. */ + struct pt_regs dummy_regs; + int cpu; + + local_irq_disable(); + + in_crash_kexec = true; + + /* + * clear and initialize the per-cpu info. This is necessary + * because, otherwise, slots for offline cpus would never be + * filled up. See smp_send_stop(). + */ + memset(&dummy_regs, 0, sizeof(dummy_regs)); + for_each_possible_cpu(cpu) + crash_save_cpu(&dummy_regs, cpu); + + /* shutdown non-boot cpus */ + smp_send_stop(); + + /* for boot cpu */ + crash_save_cpu(regs, smp_processor_id()); + + pr_info("Loading crashdump kernel...\n"); } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index dbdaacd..88aec66 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> @@ -54,6 +55,8 @@ #include <asm/ptrace.h> #include <asm/virt.h> +#include "cpu-reset.h" + #define CREATE_TRACE_POINTS #include <trace/events/ipi.h> @@ -679,8 +682,12 @@ static DEFINE_RAW_SPINLOCK(stop_lock); /* * ipi_cpu_stop - handle IPI from smp_send_stop() */ -static void ipi_cpu_stop(unsigned int cpu) +static void ipi_cpu_stop(unsigned int cpu, struct pt_regs *regs) { +#ifdef CONFIG_KEXEC + /* printing messages may slow down the shutdown. */ + if (!in_crash_kexec) +#endif if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { raw_spin_lock(&stop_lock); @@ -693,6 +700,11 @@ static void ipi_cpu_stop(unsigned int cpu) local_irq_disable(); +#ifdef CONFIG_KEXEC + if (in_crash_kexec) + crash_save_cpu(regs, cpu); +#endif /* CONFIG_KEXEC */ + while (1) cpu_relax(); } @@ -723,7 +735,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) case IPI_CPU_STOP: irq_enter(); - ipi_cpu_stop(cpu); + ipi_cpu_stop(cpu, regs); irq_exit(); break; -- 2.5.0 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2015-10-20 18:54 UTC|newest] Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-10-19 23:38 [PATCH 00/16] arm64 kexec kernel patches v10 Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 07/16] Revert "arm64: remove dead code" Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 01/16] arm64: Fold proc-macros.S into assembler.h Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 03/16] arm64: Add new hcall HVC_CALL_FUNC Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 02/16] arm64: Convert hcalls to use HVC immediate value Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 08/16] arm64/kexec: Add core kexec support Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-20 8:56 ` Pratyush Anand 2015-10-20 8:56 ` Pratyush Anand 2015-10-20 17:19 ` Geoff Levand 2015-10-20 17:19 ` Geoff Levand 2015-10-23 7:29 ` Pratyush Anand 2015-10-23 7:29 ` Pratyush Anand 2015-10-21 18:30 ` [PATCH v10.2 " Geoff Levand 2015-10-21 18:30 ` Geoff Levand 2015-10-30 16:29 ` [PATCH " James Morse 2015-10-30 16:29 ` James Morse 2015-10-30 16:54 ` Mark Rutland 2015-10-30 16:54 ` Mark Rutland 2015-11-02 9:26 ` Pratyush Anand 2015-11-02 9:26 ` Pratyush Anand 2015-11-03 0:30 ` Geoff Levand 2015-11-03 0:30 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 06/16] arm64: Add EL2 switch to cpu_reset Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 04/16] arm64: kvm: allows kvm cpu hotplug Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-20 18:57 ` [PATCH v10.1 " Geoff Levand 2015-10-20 18:57 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 05/16] arm64: Add back cpu_reset routines Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 15/16] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 11/16] arm64: kdump: reserve memory for crash dump kernel Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 14/16] arm64: kdump: update a kernel doc Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 09/16] arm64/kexec: Add pr_devel output Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 16/16] arm64: kdump: relax BUG_ON() if more than one cpus are still active Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 13/16] arm64: kdump: add kdump support Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-22 3:25 ` Dave Young 2015-10-22 3:25 ` Dave Young 2015-10-22 4:29 ` AKASHI Takahiro 2015-10-22 4:29 ` AKASHI Takahiro 2015-10-22 5:15 ` Dave Young 2015-10-22 5:15 ` Dave Young 2015-10-22 9:57 ` AKASHI Takahiro 2015-10-22 9:57 ` AKASHI Takahiro 2015-10-23 9:50 ` Dave Young 2015-10-23 9:50 ` Dave Young 2015-10-29 5:55 ` AKASHI Takahiro 2015-10-29 5:55 ` AKASHI Takahiro 2015-10-29 6:40 ` Dave Young 2015-10-29 6:40 ` Dave Young 2015-10-29 6:53 ` AKASHI Takahiro 2015-10-29 6:53 ` AKASHI Takahiro 2015-10-29 7:01 ` Dave Young 2015-10-29 7:01 ` Dave Young 2015-10-19 23:38 ` [PATCH 10/16] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-19 23:38 ` [PATCH 12/16] arm64: kdump: implement machine_crash_shutdown() Geoff Levand 2015-10-19 23:38 ` Geoff Levand 2015-10-20 18:54 ` Geoff Levand [this message] 2015-10-20 18:54 ` [PATCH v10.1 " Geoff Levand
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1445367246.30908.78.camel@infradead.org \ --to=geoff@infradead.org \ --cc=linux-arm-kernel@lists.infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.