From patchwork Fri Apr 24 07:53:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 47551 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 64B6521550 for ; Fri, 24 Apr 2015 07:54:19 +0000 (UTC) Received: by wiun10 with SMTP id n10sf2216355wiu.1 for ; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=Sm6g+jgFBwCzfuEk8Wu8+0W3lIMgWNHdBdqrTpjEd5Y=; b=DDulyM22FU3h6zDYi9fJ4ur4smxfONW/Tev6XXYoTIpzPNenFOx5NBf0b0C5BhpMyt K+dSLMrUw9fSorLlmFdAY40q1DfIS3Wp7niD9Br14pskw/bs9wy8rZVEvjMdMIDgqL+2 C35XjjHM40VG2zlrlRRSN691DWNeKKwfbNxrRURQ+tXc9zgLyXHFlyUB/DETdmUFpam/ 2jYDOEKqiAWiqo5xm0x2UOa7GGdr49EjcdiHAidEHgGJb2WFS/kwSDd/jUFaGLYYycJc u0xfSQDHgcpt8NY+TnYaHA/msRCbw8y+S8y+Ue4atpnuBFyjIDlwU0/EqHKXMvNAppBS tvUQ== X-Gm-Message-State: ALoCoQm4Ee7NblqUQrDzSO9ccjeKVqBTtL9g3eb0GGWvsfRwIhPIXMY3pbWUVKQrg/jEF6sx6MXo X-Received: by 10.112.42.236 with SMTP id r12mr3559940lbl.2.1429862058588; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.202.133 with SMTP id ki5ls464208lac.90.gmail; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) X-Received: by 10.153.4.43 with SMTP id cb11mr5956460lad.122.1429862058416; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id sj5si7692830lbb.44.2015.04.24.00.54.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2015 00:54:18 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by lbbuc2 with SMTP id uc2so30543052lbb.2 for ; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) X-Received: by 10.112.16.196 with SMTP id i4mr5766832lbd.72.1429862058060; Fri, 24 Apr 2015 00:54:18 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.67.65 with SMTP id l1csp1032419lbt; Fri, 24 Apr 2015 00:54:17 -0700 (PDT) X-Received: by 10.68.57.143 with SMTP id i15mr12739069pbq.9.1429862055736; Fri, 24 Apr 2015 00:54:15 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id qx4si16280099pbb.19.2015.04.24.00.54.14; Fri, 24 Apr 2015 00:54:15 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933972AbbDXHyK (ORCPT + 27 others); Fri, 24 Apr 2015 03:54:10 -0400 Received: from mail-pd0-f169.google.com ([209.85.192.169]:35811 "EHLO mail-pd0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933681AbbDXHyD (ORCPT ); Fri, 24 Apr 2015 03:54:03 -0400 Received: by pdbqd1 with SMTP id qd1so42005535pdb.2 for ; Fri, 24 Apr 2015 00:54:02 -0700 (PDT) X-Received: by 10.66.232.8 with SMTP id tk8mr12407122pac.5.1429862042693; Fri, 24 Apr 2015 00:54:02 -0700 (PDT) Received: from localhost.localdomain (61-205-1-167m5.grp1.mineo.jp. [61.205.1.167]) by mx.google.com with ESMTPSA id ry2sm10154199pbb.83.2015.04.24.00.53.57 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 24 Apr 2015 00:54:01 -0700 (PDT) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, vgoyal@redhat.com, hbabus@us.ibm.com Cc: geoff@infradead.org, broonie@kernel.org, david.griego@linaro.org, kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [v2 2/5] arm64: kdump: implement machine_crash_shutdown() Date: Fri, 24 Apr 2015 16:53:05 +0900 Message-Id: <1429861989-8417-3-git-send-email-takahiro.akashi@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1429861989-8417-1-git-send-email-takahiro.akashi@linaro.org> References: <1429861989-8417-1-git-send-email-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: takahiro.akashi@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , kdump calls machine_crash_shutdown() to shut down non-boot cpus and save per-cpu general-purpose registers before restarting the crash dump kernel. See kernel_kexec(). ipi_cpu_stop() is used and a bit modified to support this behavior. Signed-off-by: AKASHI Takahiro --- arch/arm64/include/asm/kexec.h | 34 ++++++++++++++++++++++- arch/arm64/kernel/machine_kexec.c | 55 ++++++++++++++++++++++++++++++++++++- arch/arm64/kernel/smp.c | 12 ++++++-- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index 3530ff5..eaf3fcb 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]\n\t" + "stp x2, x3, [%3, 0x10]\n\t" + "stp x4, x5, [%3, 0x20]\n\t" + "stp x6, x7, [%3, 0x30]\n\t" + "stp x8, x9, [%3, 0x40]\n\t" + "stp x10, x11, [%3, 0x50]\n\t" + "stp x12, x13, [%3, 0x60]\n\t" + "stp x14, x15, [%3, 0x70]\n\t" + "stp x16, x17, [%3, 0x80]\n\t" + "stp x18, x19, [%3, 0x90]\n\t" + "stp x20, x21, [%3, 0xa0]\n\t" + "stp x22, x23, [%3, 0xb0]\n\t" + "stp x24, x25, [%3, 0xc0]\n\t" + "stp x26, x27, [%3, 0xd0]\n\t" + "stp x28, x29, [%3, 0xe0]\n\t" + "str x30, [%3, 0xf0]\n\t" + "mov %0, sp\n\t" + "adr %1, 1f\n\t" + "mrs %2, spsr_el1\n\t" + "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 fd6b742..6f7887b 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -9,6 +9,8 @@ * published by the Free Software Foundation. */ +#include +#include #include #include #include @@ -24,6 +26,8 @@ extern unsigned long arm64_kexec_dtb_addr; extern unsigned long arm64_kexec_kimage_head; extern unsigned long arm64_kexec_kimage_start; +bool in_crash_kexec = false; + /** * kexec_is_dtb - Helper routine to check the device tree header signature. */ @@ -178,7 +182,56 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_code_buffer_phys); } +static void machine_kexec_mask_interrupts(void) +{ + unsigned int i; + struct irq_desc *desc; + + for_each_irq_desc(i, desc) { + struct irq_chip *chip; + + chip = irq_desc_get_chip(desc); + if (!chip) + continue; + + if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) + 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-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 not 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 this cpu */ + crash_save_cpu(regs, smp_processor_id()); + machine_kexec_mask_interrupts(); + + pr_info("Loading crashdump kernel...\n"); } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index ffe8e1b..cf7f361 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -542,7 +543,7 @@ 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) { if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { @@ -556,6 +557,13 @@ static void ipi_cpu_stop(unsigned int cpu) local_irq_disable(); +#ifdef CONFIG_KEXEC + if (in_crash_kexec) { + crash_save_cpu(regs, cpu); + flush_cache_all(); + } +#endif /* CONFIG_KEXEC */ + while (1) cpu_relax(); } @@ -586,7 +594,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;