Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42959
b: refs/heads/master
c: 85916f8
h: refs/heads/master
i:
  42957: 4555b4e
  42955: 99f1779
  42951: f90646f
  42943: 4d2bc73
v: v3
  • Loading branch information
Magnus Damm authored and Linus Torvalds committed Dec 7, 2006
1 parent 4cdae2b commit ccdf1d0
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 189 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d4df677f8a60ea6bc0ef1a596c1a3a79b1d4882
refs/heads/master: 85916f8166b59eeac63d2b4f7f1df8de849334b4
66 changes: 2 additions & 64 deletions trunk/arch/i386/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,68 +31,6 @@
/* This keeps a track of which one is crashing cpu. */
static int crashing_cpu;

static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
size_t data_len)
{
struct elf_note note;

note.n_namesz = strlen(name) + 1;
note.n_descsz = data_len;
note.n_type = type;
memcpy(buf, &note, sizeof(note));
buf += (sizeof(note) +3)/4;
memcpy(buf, name, note.n_namesz);
buf += (note.n_namesz + 3)/4;
memcpy(buf, data, note.n_descsz);
buf += (note.n_descsz + 3)/4;

return buf;
}

static void final_note(u32 *buf)
{
struct elf_note note;

note.n_namesz = 0;
note.n_descsz = 0;
note.n_type = 0;
memcpy(buf, &note, sizeof(note));
}

static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
{
struct elf_prstatus prstatus;
u32 *buf;

if ((cpu < 0) || (cpu >= NR_CPUS))
return;

/* Using ELF notes here is opportunistic.
* I need a well defined structure format
* for the data I pass, and I need tags
* on the data to indicate what information I have
* squirrelled away. ELF notes happen to provide
* all of that, so there is no need to invent something new.
*/
buf = (u32*)per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;
memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
sizeof(prstatus));
final_note(buf);
}

static void crash_save_self(struct pt_regs *regs)
{
int cpu;

cpu = safe_smp_processor_id();
crash_save_this_cpu(regs, cpu);
}

#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
static atomic_t waiting_for_crash_ipi;

Expand Down Expand Up @@ -121,7 +59,7 @@ static int crash_nmi_callback(struct notifier_block *self,
crash_fixup_ss_esp(&fixed_regs, regs);
regs = &fixed_regs;
}
crash_save_this_cpu(regs, cpu);
crash_save_cpu(regs, cpu);
disable_local_APIC();
atomic_dec(&waiting_for_crash_ipi);
/* Assume hlt works */
Expand Down Expand Up @@ -195,5 +133,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
#if defined(CONFIG_X86_IO_APIC)
disable_IO_APIC();
#endif
crash_save_self(regs);
crash_save_cpu(regs, safe_smp_processor_id());
}
59 changes: 2 additions & 57 deletions trunk/arch/powerpc/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,61 +46,6 @@ int crashing_cpu = -1;
static cpumask_t cpus_in_crash = CPU_MASK_NONE;
cpumask_t cpus_in_sr = CPU_MASK_NONE;

static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
size_t data_len)
{
struct elf_note note;

note.n_namesz = strlen(name) + 1;
note.n_descsz = data_len;
note.n_type = type;
memcpy(buf, &note, sizeof(note));
buf += (sizeof(note) +3)/4;
memcpy(buf, name, note.n_namesz);
buf += (note.n_namesz + 3)/4;
memcpy(buf, data, note.n_descsz);
buf += (note.n_descsz + 3)/4;

return buf;
}

static void final_note(u32 *buf)
{
struct elf_note note;

note.n_namesz = 0;
note.n_descsz = 0;
note.n_type = 0;
memcpy(buf, &note, sizeof(note));
}

static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
{
struct elf_prstatus prstatus;
u32 *buf;

if ((cpu < 0) || (cpu >= NR_CPUS))
return;

/* Using ELF notes here is opportunistic.
* I need a well defined structure format
* for the data I pass, and I need tags
* on the data to indicate what information I have
* squirrelled away. ELF notes happen to provide
* all of that that no need to invent something new.
*/
buf = (u32*)per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;

memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
sizeof(prstatus));
final_note(buf);
}

#ifdef CONFIG_SMP
static atomic_t enter_on_soft_reset = ATOMIC_INIT(0);

Expand All @@ -113,7 +58,7 @@ void crash_ipi_callback(struct pt_regs *regs)

hard_irq_disable();
if (!cpu_isset(cpu, cpus_in_crash))
crash_save_this_cpu(regs, cpu);
crash_save_cpu(regs, cpu);
cpu_set(cpu, cpus_in_crash);

/*
Expand Down Expand Up @@ -306,7 +251,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
* such that another IPI will not be sent.
*/
crashing_cpu = smp_processor_id();
crash_save_this_cpu(regs, crashing_cpu);
crash_save_cpu(regs, crashing_cpu);
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
if (ppc_md.kexec_cpu_down)
Expand Down
69 changes: 2 additions & 67 deletions trunk/arch/x86_64/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,71 +28,6 @@
/* This keeps a track of which one is crashing cpu. */
static int crashing_cpu;

static u32 *append_elf_note(u32 *buf, char *name, unsigned type,
void *data, size_t data_len)
{
struct elf_note note;

note.n_namesz = strlen(name) + 1;
note.n_descsz = data_len;
note.n_type = type;
memcpy(buf, &note, sizeof(note));
buf += (sizeof(note) +3)/4;
memcpy(buf, name, note.n_namesz);
buf += (note.n_namesz + 3)/4;
memcpy(buf, data, note.n_descsz);
buf += (note.n_descsz + 3)/4;

return buf;
}

static void final_note(u32 *buf)
{
struct elf_note note;

note.n_namesz = 0;
note.n_descsz = 0;
note.n_type = 0;
memcpy(buf, &note, sizeof(note));
}

static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
{
struct elf_prstatus prstatus;
u32 *buf;

if ((cpu < 0) || (cpu >= NR_CPUS))
return;

/* Using ELF notes here is opportunistic.
* I need a well defined structure format
* for the data I pass, and I need tags
* on the data to indicate what information I have
* squirrelled away. ELF notes happen to provide
* all of that, no need to invent something new.
*/

buf = (u32*)per_cpu_ptr(crash_notes, cpu);

if (!buf)
return;

memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
sizeof(prstatus));
final_note(buf);
}

static void crash_save_self(struct pt_regs *regs)
{
int cpu;

cpu = smp_processor_id();
crash_save_this_cpu(regs, cpu);
}

#ifdef CONFIG_SMP
static atomic_t waiting_for_crash_ipi;

Expand All @@ -117,7 +52,7 @@ static int crash_nmi_callback(struct notifier_block *self,
return NOTIFY_STOP;
local_irq_disable();

crash_save_this_cpu(regs, cpu);
crash_save_cpu(regs, cpu);
disable_local_APIC();
atomic_dec(&waiting_for_crash_ipi);
/* Assume hlt works */
Expand Down Expand Up @@ -196,5 +131,5 @@ void machine_crash_shutdown(struct pt_regs *regs)

disable_IO_APIC();

crash_save_self(regs);
crash_save_cpu(regs, smp_processor_id());
}
1 change: 1 addition & 0 deletions trunk/include/linux/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ extern struct page *kimage_alloc_control_pages(struct kimage *image,
unsigned int order);
extern void crash_kexec(struct pt_regs *);
int kexec_should_crash(struct task_struct *);
void crash_save_cpu(struct pt_regs *regs, int cpu);
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;

Expand Down
56 changes: 56 additions & 0 deletions trunk/kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <linux/syscalls.h>
#include <linux/ioport.h>
#include <linux/hardirq.h>
#include <linux/elf.h>
#include <linux/elfcore.h>

#include <asm/page.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -1066,6 +1068,60 @@ void crash_kexec(struct pt_regs *regs)
}
}

static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
size_t data_len)
{
struct elf_note note;

note.n_namesz = strlen(name) + 1;
note.n_descsz = data_len;
note.n_type = type;
memcpy(buf, &note, sizeof(note));
buf += (sizeof(note) + 3)/4;
memcpy(buf, name, note.n_namesz);
buf += (note.n_namesz + 3)/4;
memcpy(buf, data, note.n_descsz);
buf += (note.n_descsz + 3)/4;

return buf;
}

static void final_note(u32 *buf)
{
struct elf_note note;

note.n_namesz = 0;
note.n_descsz = 0;
note.n_type = 0;
memcpy(buf, &note, sizeof(note));
}

void crash_save_cpu(struct pt_regs *regs, int cpu)
{
struct elf_prstatus prstatus;
u32 *buf;

if ((cpu < 0) || (cpu >= NR_CPUS))
return;

/* Using ELF notes here is opportunistic.
* I need a well defined structure format
* for the data I pass, and I need tags
* on the data to indicate what information I have
* squirrelled away. ELF notes happen to provide
* all of that, so there is no need to invent something new.
*/
buf = (u32*)per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;
memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
sizeof(prstatus));
final_note(buf);
}

static int __init crash_notes_memory_init(void)
{
/* Allocate memory for saving cpu registers. */
Expand Down

0 comments on commit ccdf1d0

Please sign in to comment.