From: Hariprasad Nellitheertha <hari@in.ibm.com>
To: linux-kernel@vger.kernel.org, fastboot@osdl.org
Cc: akpm@osdl.org, Suparna Bhattacharya <suparna@in.ibm.com>,
mbligh@aracnet.com, litke@us.ibm.com, ebiederm@xmission.com
Subject: Re: [PATCH][4/6]Register snapshotting before kexec-boot
Date: Tue, 17 Aug 2004 17:39:11 +0530 [thread overview]
Message-ID: <20040817120911.GE3916@in.ibm.com> (raw)
In-Reply-To: <20040817120809.GD3916@in.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 108 bytes --]
Regards, Hari
--
Hariprasad Nellitheertha
Linux Technology Center
India Software Labs
IBM India, Bangalore
[-- Attachment #2: kd-reg-268.patch --]
[-- Type: text/plain, Size: 9739 bytes --]
This patch contains the code for stopping the other cpus and snapshotting
their register values before doing the kexec reboot.
Signed off by Hariprasad Nellitheertha <hari@in.ibm.com>
---
linux-2.6.8.1-hari/arch/i386/kernel/Makefile | 1
linux-2.6.8.1-hari/arch/i386/kernel/crash_dump.c | 98 ++++++++++
linux-2.6.8.1-hari/arch/i386/kernel/machine_kexec.c | 14 +
linux-2.6.8.1-hari/arch/i386/kernel/smp.c | 13 +
linux-2.6.8.1-hari/include/asm-i386/crash_dump.h | 32 +++
linux-2.6.8.1-hari/include/asm-i386/mach-default/irq_vectors.h | 1
linux-2.6.8.1-hari/include/asm-i386/smp.h | 1
7 files changed, 156 insertions(+), 4 deletions(-)
diff -puN arch/i386/kernel/Makefile~kd-reg-268 arch/i386/kernel/Makefile
--- linux-2.6.8.1/arch/i386/kernel/Makefile~kd-reg-268 2004-08-17 17:08:08.000000000 +0530
+++ linux-2.6.8.1-hari/arch/i386/kernel/Makefile 2004-08-17 17:08:18.000000000 +0530
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
obj-$(CONFIG_MODULES) += module.o
diff -puN /dev/null arch/i386/kernel/crash_dump.c
--- /dev/null 2003-01-30 15:54:37.000000000 +0530
+++ linux-2.6.8.1-hari/arch/i386/kernel/crash_dump.c 2004-08-17 17:08:34.000000000 +0530
@@ -0,0 +1,98 @@
+/*
+ * Architecture specific (i386) functions for kexec based crash dumps.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *
+ * Copyright (C) IBM Corporation, 2004. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/crash_dump.h>
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+#include <asm/nmi.h>
+#include <asm/hw_irq.h>
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_dump_ipi;
+static int crash_dump_expect_ipi[NR_CPUS];
+extern void crash_dump_send_ipi(void);
+extern void stop_this_cpu(void *);
+
+static int crash_dump_nmi_callback(struct pt_regs *regs, int cpu)
+{
+ if (!crash_dump_expect_ipi[cpu])
+ return 0;
+
+ crash_dump_expect_ipi[cpu] = 0;
+ crash_dump_save_this_cpu(regs, cpu);
+ atomic_dec(&waiting_for_dump_ipi);
+
+ stop_this_cpu(NULL);
+
+ return 1;
+}
+
+void __crash_dump_stop_cpus(void)
+{
+ int i, cpu = smp_processor_id();
+ int other_cpus = num_online_cpus()-1;
+
+ if (other_cpus > 0) {
+ atomic_set(&waiting_for_dump_ipi, other_cpus);
+
+ for (i = 0; i < NR_CPUS; i++)
+ crash_dump_expect_ipi[i] = (i != cpu && cpu_online(i));
+
+ set_nmi_callback(crash_dump_nmi_callback);
+ /* Ensure the new callback function is set before sending
+ * out the IPI
+ */
+ wmb();
+
+ crash_dump_send_ipi();
+ while (atomic_read(&waiting_for_dump_ipi) > 0)
+ cpu_relax();
+
+ unset_nmi_callback();
+ } else {
+ local_irq_disable();
+ disable_local_APIC();
+ local_irq_enable();
+ }
+}
+#else
+void __crash_dump_stop_cpus(void) {}
+#endif
+
+void crash_get_current_regs(struct pt_regs *regs)
+{
+ __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
+ __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
+ __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
+ __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
+ __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
+ __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
+ __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
+ __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
+ __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
+ __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
+ __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
+ __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
+ __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
+
+ regs->eip = (unsigned long)current_text_addr();
+}
+
+void crash_dump_save_this_cpu(struct pt_regs *regs, int cpu)
+{
+ crash_smp_current_task[cpu] = (int)current;
+ crash_smp_regs[cpu] = *regs;
+}
+
diff -puN arch/i386/kernel/machine_kexec.c~kd-reg-268 arch/i386/kernel/machine_kexec.c
--- linux-2.6.8.1/arch/i386/kernel/machine_kexec.c~kd-reg-268 2004-08-17 17:08:08.000000000 +0530
+++ linux-2.6.8.1-hari/arch/i386/kernel/machine_kexec.c 2004-08-17 17:08:18.000000000 +0530
@@ -17,8 +17,9 @@
#include <asm/io.h>
#include <asm/apic.h>
#include <asm/cpufeature.h>
-#include <asm/hw_irq.h>
+struct pt_regs crash_smp_regs[NR_CPUS];
+u32 crash_smp_current_task[NR_CPUS];
static void set_idt(void *newidt, __u16 limit)
{
@@ -97,6 +98,14 @@ void __relocate_base_mem(unsigned long b
if (PageReserved(page))
copy_page(dest_addr, src_addr);
}
+
+ /* Now copy over the saved task pointers and the registers
+ * to the end of the reserved area
+ */
+ dest_addr = (void *)(__va(CRASH_BACKUP_BASE + CRASH_BACKUP_SIZE));
+ memcpy(dest_addr, crash_smp_regs, (sizeof(struct pt_regs)*NR_CPUS));
+ dest_addr += sizeof(struct pt_regs)*NR_CPUS;
+ memcpy(dest_addr, crash_smp_current_task, (sizeof(u32)*NR_CPUS));
}
/*
@@ -111,7 +120,8 @@ void machine_kexec(struct kimage *image)
/* switch to an mm where the reboot_code_buffer is identity mapped */
use_mm(&init_mm);
- stop_apics();
+
+ crash_dump_stop_cpus();
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
diff -puN arch/i386/kernel/smp.c~kd-reg-268 arch/i386/kernel/smp.c
--- linux-2.6.8.1/arch/i386/kernel/smp.c~kd-reg-268 2004-08-17 17:08:08.000000000 +0530
+++ linux-2.6.8.1-hari/arch/i386/kernel/smp.c 2004-08-17 17:08:18.000000000 +0530
@@ -143,6 +143,9 @@ inline void __send_IPI_shortcut(unsigned
*/
cfg = __prepare_ICR(shortcut, vector);
+ if (vector == CRASH_DUMP_VECTOR)
+ cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI;
+
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
@@ -221,6 +224,9 @@ inline void send_IPI_mask_sequence(cpuma
*/
cfg = __prepare_ICR(0, vector);
+ if (vector == CRASH_DUMP_VECTOR)
+ cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI;
+
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
@@ -467,6 +473,11 @@ void flush_tlb_all(void)
on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
}
+void crash_dump_send_ipi(void)
+{
+ send_IPI_allbutself(CRASH_DUMP_VECTOR);
+}
+
/*
* this function sends a 'reschedule' IPI to another CPU.
* it goes straight through and wastes no time serializing
@@ -548,7 +559,7 @@ int smp_call_function (void (*func) (voi
return 0;
}
-static void stop_this_cpu (void * dummy)
+void stop_this_cpu (void * dummy)
{
/*
* Remove this CPU:
diff -puN include/asm-i386/crash_dump.h~kd-reg-268 include/asm-i386/crash_dump.h
--- linux-2.6.8.1/include/asm-i386/crash_dump.h~kd-reg-268 2004-08-17 17:08:09.000000000 +0530
+++ linux-2.6.8.1-hari/include/asm-i386/crash_dump.h 2004-08-17 17:08:18.000000000 +0530
@@ -1,5 +1,7 @@
/* asm-i386/crash_dump.h */
#include <linux/bootmem.h>
+#include <asm/hw_irq.h>
+#include <asm/apic.h>
extern unsigned int dump_enabled;
@@ -8,6 +10,11 @@ void __init find_max_pfn(void);
void __relocate_base_mem(unsigned long, unsigned long);
extern unsigned int crashed;
+extern struct pt_regs crash_smp_regs[NR_CPUS];
+extern u32 crash_smp_current_task[NR_CPUS];
+extern void crash_dump_save_this_cpu(struct pt_regs *, int);
+extern void __crash_dump_stop_cpus(void);
+extern void crash_get_current_regs(struct pt_regs *regs);
#ifdef CONFIG_CRASH_DUMP
#define CRASH_BACKUP_BASE ((unsigned long)CONFIG_BACKUP_BASE * 0x100000)
@@ -28,7 +35,26 @@ static inline void set_saved_max_pfn(voi
static inline void crash_reserve_bootmem(void)
{
if (!dump_enabled)
- reserve_bootmem(CRASH_BACKUP_BASE, CRASH_BACKUP_SIZE);
+ reserve_bootmem(CRASH_BACKUP_BASE, CRASH_BACKUP_SIZE + PAGE_SIZE);
+}
+
+static inline void crash_dump_stop_cpus(void)
+{
+ if (!crashed)
+ stop_apics();
+ else {
+ int cpu = smp_processor_id();
+
+ crash_smp_current_task[cpu] = (int)current;
+ crash_get_current_regs(&crash_smp_regs[cpu]);
+
+ /* This also captures the register states of the other cpus */
+ __crash_dump_stop_cpus();
+#if defined(CONFIG_X86_IO_APIC)
+ disable_IO_APIC();
+#endif
+ disconnect_bsp_APIC();
+ }
}
#else
#define CRASH_BACKUP_BASE 0x08000000
@@ -36,4 +62,8 @@ static inline void crash_reserve_bootmem
static inline void relocate_base_mem(void) {}
static inline void set_saved_max_pfn(void) {}
static inline void crash_reserve_bootmem(void) {}
+static inline void crash_dump_stop_cpus(void)
+{
+ stop_apics();
+}
#endif
diff -puN include/asm-i386/mach-default/irq_vectors.h~kd-reg-268 include/asm-i386/mach-default/irq_vectors.h
--- linux-2.6.8.1/include/asm-i386/mach-default/irq_vectors.h~kd-reg-268 2004-08-17 17:08:09.000000000 +0530
+++ linux-2.6.8.1-hari/include/asm-i386/mach-default/irq_vectors.h 2004-08-17 17:08:18.000000000 +0530
@@ -48,6 +48,7 @@
#define INVALIDATE_TLB_VECTOR 0xfd
#define RESCHEDULE_VECTOR 0xfc
#define CALL_FUNCTION_VECTOR 0xfb
+#define CRASH_DUMP_VECTOR 0xfa
#define THERMAL_APIC_VECTOR 0xf0
/*
diff -puN include/asm-i386/smp.h~kd-reg-268 include/asm-i386/smp.h
--- linux-2.6.8.1/include/asm-i386/smp.h~kd-reg-268 2004-08-17 17:08:09.000000000 +0530
+++ linux-2.6.8.1-hari/include/asm-i386/smp.h 2004-08-17 17:08:18.000000000 +0530
@@ -41,6 +41,7 @@ extern void smp_message_irq(int cpl, voi
extern void smp_invalidate_rcv(void); /* Process an NMI */
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
+extern void stop_this_cpu(void *);
#define MAX_APICID 256
_
next prev parent reply other threads:[~2004-08-17 12:29 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-17 12:04 [RFC]Kexec based crash dumping Hariprasad Nellitheertha
2004-08-17 12:05 ` [PATCH][1/6]Documentation Hariprasad Nellitheertha
2004-08-17 12:07 ` [PATCH][2/6]Memory preserving reboot using kexec Hariprasad Nellitheertha
2004-08-17 12:08 ` [PATCH][3/6]Interface for copying the dump pages Hariprasad Nellitheertha
2004-08-17 12:09 ` Hariprasad Nellitheertha [this message]
2004-08-17 12:10 ` [PATCH][5/6]ELF format interface for the dump Hariprasad Nellitheertha
2004-08-17 12:13 ` [PATCH][6/6]Device abstraction for linear/raw view of " Hariprasad Nellitheertha
2004-08-17 22:53 ` Martin J. Bligh
2004-08-18 12:29 ` Hariprasad Nellitheertha
2004-08-17 16:27 ` [PATCH][4/6]Register snapshotting before kexec-boot Dave Hansen
2004-08-18 13:43 ` Theodore Ts'o
2004-08-19 11:59 ` Hariprasad Nellitheertha
2004-08-17 16:17 ` [PATCH][3/6]Interface for copying the dump pages Dave Hansen
2004-08-17 16:01 ` [PATCH][2/6]Memory preserving reboot using kexec Dave Hansen
2004-08-17 22:44 ` [RFC]Kexec based crash dumping Andrew Morton
2004-08-18 12:28 ` Hariprasad Nellitheertha
2004-08-20 8:17 ` [Fastboot] " Eric W. Biederman
2004-08-20 8:05 ` [Fastboot] " Eric W. Biederman
2004-08-20 8:27 ` Hariprasad Nellitheertha
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=20040817120911.GE3916@in.ibm.com \
--to=hari@in.ibm.com \
--cc=akpm@osdl.org \
--cc=ebiederm@xmission.com \
--cc=fastboot@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=litke@us.ibm.com \
--cc=mbligh@aracnet.com \
--cc=suparna@in.ibm.com \
/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: link
Be 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.