From patchwork Thu Mar 26 08:28:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 46350 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 52B3721584 for ; Thu, 26 Mar 2015 08:30:03 +0000 (UTC) Received: by labow10 with SMTP id ow10sf3882207lab.1 for ; Thu, 26 Mar 2015 01:30:02 -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=4ZwNEpOTYCadOIGQmOF9mEw2GEauhJKHIIKB0CjA/kE=; b=cvTGeJZKG6LrPGebJENk7wW6vcw5qlTz3M40Gky1P8LoWWHIJ9dExbDQrMM0iPFfQC 7+7YmIiNWTgIUIIaYywHGOQd6LHgX/B4EIQxWDDyH6Q5DT3F0H0uw1PCnW+2SbpbdRJD wHbrj/V2CIHM1BvTPNfP/GmuF9pus6tLfY5hQUedqg+/uezOCBIU/d31cHrlRp++a4o2 ImZsqq26/zfJ9zpG6xk8RbtT6z+aHOU6Fgl9GErpNySNu02YiZe4BtQudjIfRsmXEDIC NskE8NnY1zhjTcQdxxXB/pstVYVwGJyf9fpSlzVbBrbulbGyTi43cVztheCgXAmutV73 /23A== X-Gm-Message-State: ALoCoQlqfPVwJHORxC1XApk7i8g9EYMTQ6CgSgBhL3A89tCV++VJYla8k8xdgEHPHcH3RB/Yu0Ec X-Received: by 10.180.81.134 with SMTP id a6mr5262270wiy.1.1427358602277; Thu, 26 Mar 2015 01:30:02 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.163.36 with SMTP id yf4ls209483lab.43.gmail; Thu, 26 Mar 2015 01:30:01 -0700 (PDT) X-Received: by 10.112.91.165 with SMTP id cf5mr12195360lbb.121.1427358601901; Thu, 26 Mar 2015 01:30:01 -0700 (PDT) Received: from mail-la0-f41.google.com (mail-la0-f41.google.com. [209.85.215.41]) by mx.google.com with ESMTPS id m7si4023695lbp.19.2015.03.26.01.30.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Mar 2015 01:30:01 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.41 as permitted sender) client-ip=209.85.215.41; Received: by lahp7 with SMTP id p7so20647608lah.2 for ; Thu, 26 Mar 2015 01:30:01 -0700 (PDT) X-Received: by 10.112.185.66 with SMTP id fa2mr11945490lbc.117.1427358601795; Thu, 26 Mar 2015 01:30:01 -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.57.201 with SMTP id k9csp456554lbq; Thu, 26 Mar 2015 01:30:00 -0700 (PDT) X-Received: by 10.68.96.33 with SMTP id dp1mr24665701pbb.4.1427358598829; Thu, 26 Mar 2015 01:29:58 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t9si7357063pbs.40.2015.03.26.01.29.56; Thu, 26 Mar 2015 01:29:58 -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 S1752501AbbCZI3v (ORCPT + 27 others); Thu, 26 Mar 2015 04:29:51 -0400 Received: from mail-pa0-f42.google.com ([209.85.220.42]:35915 "EHLO mail-pa0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751615AbbCZI3q (ORCPT ); Thu, 26 Mar 2015 04:29:46 -0400 Received: by padcy3 with SMTP id cy3so56343994pad.3 for ; Thu, 26 Mar 2015 01:29:45 -0700 (PDT) X-Received: by 10.68.190.228 with SMTP id gt4mr25055547pbc.6.1427358585823; Thu, 26 Mar 2015 01:29:45 -0700 (PDT) Received: from localhost.localdomain (61-205-2-129m5.grp1.mineo.jp. [61.205.2.129]) by mx.google.com with ESMTPSA id sf6sm4716526pbb.82.2015.03.26.01.29.40 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 26 Mar 2015 01:29:44 -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: [PATCH 2/5] arm64: kdump: implement machine_crash_shutdown() Date: Thu, 26 Mar 2015 17:28:50 +0900 Message-Id: <1427358533-3754-3-git-send-email-takahiro.akashi@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1427358533-3754-1-git-send-email-takahiro.akashi@linaro.org> References: <1427358533-3754-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.215.41 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 | 10 +++++-- 3 files changed, 95 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 7aa2fa2..375dd1f 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. */ @@ -183,7 +187,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 328b8ce..593d969 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -541,7 +542,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) { @@ -555,6 +556,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(); } @@ -585,7 +591,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;