All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hariprasad Nellitheertha <hari@in.ibm.com>
To: akpm@osdl.org, linux-kernel@vger.kernel.org, fastboot@osdl.org
Cc: Suparna Bhattacharya <suparna@in.ibm.com>,
	mbligh@aracnet.com, ebiederm@xmission.com, litke@us.ibm.com
Subject: Re: [PATCH][4/6]Register snapshotting before kexec boot
Date: Wed, 15 Sep 2004 18:25:25 +0530	[thread overview]
Message-ID: <20040915125525.GE15450@in.ibm.com> (raw)
In-Reply-To: <20040915125422.GD15450@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-269rc1-mm5.patch --]
[-- Type: text/plain, Size: 9803 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.9-rc1-hari/arch/i386/kernel/Makefile                   |    1 
 linux-2.6.9-rc1-hari/arch/i386/kernel/crash_dump.c               |  101 ++++++++++
 linux-2.6.9-rc1-hari/arch/i386/kernel/machine_kexec.c            |    4 
 linux-2.6.9-rc1-hari/arch/i386/kernel/smp.c                      |   13 +
 linux-2.6.9-rc1-hari/include/asm-i386/crash_dump.h               |   41 +++-
 linux-2.6.9-rc1-hari/include/asm-i386/mach-default/irq_vectors.h |    1 
 linux-2.6.9-rc1-hari/include/asm-i386/smp.h                      |    1 
 7 files changed, 160 insertions(+), 2 deletions(-)

diff -puN arch/i386/kernel/Makefile~kd-reg-269rc1-mm5 arch/i386/kernel/Makefile
--- linux-2.6.9-rc1/arch/i386/kernel/Makefile~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/arch/i386/kernel/Makefile	2004-09-15 17:36:37.000000000 +0530
@@ -25,6 +25,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_KPROBES)		+= kprobes.o
diff -puN /dev/null arch/i386/kernel/crash_dump.c
--- /dev/null	2003-01-30 15:54:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/arch/i386/kernel/crash_dump.c	2004-09-15 17:36:37.000000000 +0530
@@ -0,0 +1,101 @@
+/*
+ * 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>
+
+struct pt_regs crash_smp_regs[NR_CPUS];
+long crash_smp_current_task[NR_CPUS];
+
+#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] = (long)current;
+	crash_smp_regs[cpu] = *regs;
+}
+
diff -puN arch/i386/kernel/machine_kexec.c~kd-reg-269rc1-mm5 arch/i386/kernel/machine_kexec.c
--- linux-2.6.9-rc1/arch/i386/kernel/machine_kexec.c~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/arch/i386/kernel/machine_kexec.c	2004-09-15 17:36:37.000000000 +0530
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/delay.h>
+#include <linux/crash_dump.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
@@ -194,6 +195,9 @@ void machine_kexec(struct kimage *image)
 	unsigned long reboot_code_buffer;
 	relocate_new_kernel_t rnk;
 
+	crash_dump_stop_cpus();
+	crash_dump_save_registers();
+
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
diff -puN arch/i386/kernel/smp.c~kd-reg-269rc1-mm5 arch/i386/kernel/smp.c
--- linux-2.6.9-rc1/arch/i386/kernel/smp.c~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/arch/i386/kernel/smp.c	2004-09-15 17:36:37.000000000 +0530
@@ -143,6 +143,9 @@ void __send_IPI_shortcut(unsigned int sh
 	 */
 	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.
 			 */
@@ -489,6 +495,11 @@ void smp_send_reschedule(int cpu)
 	send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
 }
 
+void crash_dump_send_ipi(void)
+{
+	send_IPI_allbutself(CRASH_DUMP_VECTOR);
+}
+
 /*
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
@@ -565,7 +576,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-269rc1-mm5 include/asm-i386/crash_dump.h
--- linux-2.6.9-rc1/include/asm-i386/crash_dump.h~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/include/asm-i386/crash_dump.h	2004-09-15 17:36:37.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 @@ unsigned long __init find_max_low_pfn(vo
 void __init find_max_pfn(void);
 
 extern unsigned int crashed;
+extern struct pt_regs crash_smp_regs[NR_CPUS];
+extern long 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)
@@ -32,13 +39,45 @@ static inline void crash_reserve_bootmem
 	if (!dump_enabled) {
 		reserve_bootmem(0, CRASH_RELOCATE_SIZE);
 		reserve_bootmem(CRASH_BACKUP_BASE,
-			CRASH_BACKUP_SIZE + CRASH_RELOCATE_SIZE);
+			CRASH_BACKUP_SIZE + CRASH_RELOCATE_SIZE + PAGE_SIZE);
 	}
 }
+
+static inline void crash_dump_stop_cpus(void)
+{
+	if (!crashed)
+		return;
+
+	int cpu = smp_processor_id();
+
+	crash_smp_current_task[cpu] = (long)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
+#if defined(CONFIG_X86_LOCAL_APIC)
+	disconnect_bsp_APIC();
+#endif
+}
+
+static inline void crash_dump_save_registers(void)
+{
+	void *addr;
+
+	addr = __va(CRASH_BACKUP_BASE + CRASH_BACKUP_SIZE + CRASH_RELOCATE_SIZE);
+	memcpy(addr, crash_smp_regs, (sizeof(struct pt_regs)*NR_CPUS));
+	addr += sizeof(struct pt_regs)*NR_CPUS;
+	memcpy(addr, crash_smp_current_task, (sizeof(long)*NR_CPUS));
+}
 #else
 #define CRASH_BACKUP_BASE 0x6000000
 #define CRASH_BACKUP_SIZE 0x1000000
 #define crash_relocate_mem() do { } while(0)
 #define set_saved_max_pfn() do { } while(0)
 #define crash_reserve_bootmem() do { } while(0)
+#define crash_dump_stop_cpus() do { } while(0)
+#define crash_dump_save_registers() do { } while(0)
 #endif
diff -puN include/asm-i386/mach-default/irq_vectors.h~kd-reg-269rc1-mm5 include/asm-i386/mach-default/irq_vectors.h
--- linux-2.6.9-rc1/include/asm-i386/mach-default/irq_vectors.h~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/include/asm-i386/mach-default/irq_vectors.h	2004-09-15 17:36:37.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-269rc1-mm5 include/asm-i386/smp.h
--- linux-2.6.9-rc1/include/asm-i386/smp.h~kd-reg-269rc1-mm5	2004-09-15 17:36:37.000000000 +0530
+++ linux-2.6.9-rc1-hari/include/asm-i386/smp.h	2004-09-15 17:36:37.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
 extern u8 x86_cpu_to_apicid[];

_

  reply	other threads:[~2004-09-15 13:13 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-15 12:50 kexec based crash dumping Hariprasad Nellitheertha
2004-09-15 12:51 ` [PATCH][1/6]Documentation Hariprasad Nellitheertha
2004-09-15 12:53   ` [PATCH][2/6]Memory preserving reboot using kexec Hariprasad Nellitheertha
2004-09-15 12:54     ` [PATCH][3/6]Routines for copying the dump pages Hariprasad Nellitheertha
2004-09-15 12:55       ` Hariprasad Nellitheertha [this message]
2004-09-15 12:56         ` [PATCH][5/6]ELF format dump file access Hariprasad Nellitheertha
2004-09-15 12:57           ` [PATCH][6/6]Linear/raw " Hariprasad Nellitheertha
2004-09-15 21:28           ` [PATCH][5/6]ELF " Andrew Morton
2004-09-15 21:29           ` Andrew Morton
2004-09-15 21:31           ` Andrew Morton
2004-09-15 21:27         ` [PATCH][4/6]Register snapshotting before kexec boot Andrew Morton
2004-09-16  8:11           ` [Fastboot] " Dipankar Sarma
2004-09-17 14:53             ` Srivatsa Vaddagiri
2004-09-19 20:17               ` Eric W. Biederman
2004-09-15 21:23       ` [PATCH][3/6]Routines for copying the dump pages Andrew Morton
2004-09-15 21:22     ` [PATCH][2/6]Memory preserving reboot using kexec Andrew Morton
2004-09-19 20:37     ` [Fastboot] " Eric W. Biederman
2004-09-20 13:49       ` Hariprasad Nellitheertha
2004-09-20 19:53         ` Eric W. Biederman
2004-09-15 17:33 ` [Fastboot] kexec based crash dumping Eric W. Biederman

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=20040915125525.GE15450@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.