# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1168363025 0
# Node ID 761f695043ffa30b9928b6557b80d6814a27e192
# Parent ddea7363fa41a57adb6453c9594fd4e8fb6e9a20
# Parent f653919e069aa3c56fe545eba5084d9ec78c0a24
merge
---
linux-2.6-xen-sparse/kernel/kexec.c | 8 +-
xen/common/kexec.c | 100 ++++++++++++++++++++++++------------
xen/include/xen/elfcore.h | 57 --------------------
3 files changed, 74 insertions(+), 91 deletions(-)
diff -r ddea7363fa41 -r 761f695043ff linux-2.6-xen-sparse/kernel/kexec.c
--- a/linux-2.6-xen-sparse/kernel/kexec.c Tue Jan 09 17:11:46 2007 +0000
+++ b/linux-2.6-xen-sparse/kernel/kexec.c Tue Jan 09 17:17:05 2007 +0000
@@ -1012,9 +1012,11 @@ asmlinkage long sys_kexec_load(unsigned
goto out;
}
#ifdef CONFIG_XEN
- result = xen_machine_kexec_load(image);
- if (result)
- goto out;
+ if (image) {
+ result = xen_machine_kexec_load(image);
+ if (result)
+ goto out;
+ }
#endif
/* Install the new kernel, and Uninstall the old */
image = xchg(dest_image, image);
diff -r ddea7363fa41 -r 761f695043ff xen/common/kexec.c
--- a/xen/common/kexec.c Tue Jan 09 17:11:46 2007 +0000
+++ b/xen/common/kexec.c Tue Jan 09 17:17:05 2007 +0000
@@ -26,18 +26,26 @@
typedef long ret_t;
-DEFINE_PER_CPU (crash_note_t, crash_notes);
-cpumask_t crash_saved_cpus;
-
-xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
+#define ELFNOTE_ALIGN(_n_) (((_n_)+3)&~3)
+#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_)))
+#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz))
+#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz))
+
+static DEFINE_PER_CPU(void *, crash_notes);
+
+static Elf_Note *xen_crash_note;
+
+static cpumask_t crash_saved_cpus;
+
+static xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
#define KEXEC_FLAG_DEFAULT_POS (KEXEC_IMAGE_NR + 0)
#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
#define KEXEC_FLAG_IN_PROGRESS (KEXEC_IMAGE_NR + 2)
-unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */
-
-spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long kexec_flags = 0; /* the lowest bits are for
KEXEC_IMAGE... */
+
+static spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
xen_kexec_reserve_t kexec_crash_area;
@@ -70,39 +78,28 @@ void kexec_crash_save_cpu(void)
void kexec_crash_save_cpu(void)
{
int cpu = smp_processor_id();
- crash_note_t *cntp;
+ Elf_Note *note = per_cpu(crash_notes, cpu);
+ ELF_Prstatus *prstatus;
+ crash_xen_core_t *xencore;
if ( cpu_test_and_set(cpu, crash_saved_cpus) )
return;
- cntp = &per_cpu(crash_notes, cpu);
- elf_core_save_regs(&cntp->core.desc.desc.pr_reg,
- &cntp->xen_regs.desc.desc);
-
- /* Set up crash "CORE" note. */
- setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS);
-
- /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */
- setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN,
- XEN_ELFNOTE_CRASH_REGS);
+ prstatus = ELFNOTE_DESC(note);
+
+ note = ELFNOTE_NEXT(note);
+ xencore = ELFNOTE_DESC(note);
+
+ elf_core_save_regs(&prstatus->pr_reg, xencore);
}
/* Set up the single Xen-specific-info crash note. */
crash_xen_info_t *kexec_crash_save_info(void)
{
int cpu = smp_processor_id();
- crash_note_t *cntp;
- crash_xen_info_t *info;
+ crash_xen_info_t *info = ELFNOTE_DESC(xen_crash_note);
BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus));
-
- cntp = &per_cpu(crash_notes, cpu);
-
- /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */
- setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN,
- XEN_ELFNOTE_CRASH_INFO);
-
- info = &cntp->xen_info.desc.desc;
info->xen_major_version = xen_major_version();
info->xen_minor_version = xen_minor_version();
@@ -147,6 +144,14 @@ static __init int register_crashdump_tri
}
__initcall(register_crashdump_trigger);
+static void setup_note(Elf_Note *n, const char *name, int type, int descsz)
+{
+ strcpy(ELFNOTE_NAME(n), name);
+ n->namesz = strlen(name);
+ n->descsz = descsz;
+ n->type = type;
+}
+
#define kexec_get(x) kexec_get_##x
#endif
@@ -167,11 +172,44 @@ static int kexec_get(xen)(xen_kexec_rang
static int kexec_get(cpu)(xen_kexec_range_t *range)
{
- if ( range->nr < 0 || range->nr >= num_present_cpus() )
+ int nr = range->nr;
+ int nr_bytes = sizeof(Elf_Note) * 2
+ + ELFNOTE_ALIGN(sizeof(ELF_Prstatus))
+ + ELFNOTE_ALIGN(sizeof(crash_xen_core_t));
+
+ if ( nr < 0 || nr >= num_present_cpus() )
return -EINVAL;
- range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr));
- range->size = sizeof(crash_note_t);
+ /* The Xen info note is included in CPU0's range. */
+ if ( nr == 0 )
+ nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t));
+
+ if ( per_cpu(crash_notes, nr) == NULL )
+ {
+ Elf_Note *note;
+
+ note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes);
+
+ if ( note == NULL )
+ return -ENOMEM;
+
+ /* Setup CORE note. */
+ setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus));
+
+ /* Setup Xen CORE note. */
+ note = ELFNOTE_NEXT(note);
+ setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS,
sizeof(crash_xen_core_t));
+
+ if (nr == 0)
+ {
+ /* Setup system wide Xen info note. */
+ xen_crash_note = note = ELFNOTE_NEXT(note);
+ setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO,
sizeof(crash_xen_info_t));
+ }
+ }
+
+ range->start = __pa((unsigned long)per_cpu(crash_notes, nr));
+ range->size = nr_bytes;
return 0;
}
diff -r ddea7363fa41 -r 761f695043ff xen/include/xen/elfcore.h
--- a/xen/include/xen/elfcore.h Tue Jan 09 17:11:46 2007 +0000
+++ b/xen/include/xen/elfcore.h Tue Jan 09 17:17:05 2007 +0000
@@ -56,49 +56,6 @@ typedef struct
int pr_fpvalid; /* True if math co-processor being used. */
} ELF_Prstatus;
-/*
- * The following data structures provide 64-bit ELF notes. In theory it should
- * be possible to support both 64-bit and 32-bit ELF files, but to keep it
- * simple we only do 64-bit.
- *
- * Please note that the current code aligns the 64-bit notes in the same
- * way as Linux does. We are not following the 64-bit ELF spec, no one does.
- *
- * We are avoiding two problems by restricting us to 64-bit notes only:
- * - Alignment of notes change with the word size. Ick.
- * - We would need to tell kexec-tools which format we are using in the
- * hypervisor to make sure the right ELF format is generated.
- * That requires infrastructure. Let's not.
- */
-
-#define NOTE_ALIGN(x, n) ((x + ((1 << n) - 1)) / (1 << n))
-#define PAD32(x) u32 pad_data[NOTE_ALIGN(x, 2)]
-
-#define TYPEDEF_NOTE(type, strlen, desctype) \
- typedef struct { \
- union { \
- struct { \
- Elf_Note note; \
- unsigned char name[strlen]; \
- } note; \
- PAD32(sizeof(Elf_Note) + strlen); \
- } note; \
- union { \
- desctype desc; \
- PAD32(sizeof(desctype)); \
- } desc; \
- } __attribute__ ((packed)) type
-
-#define CORE_STR "CORE"
-#define CORE_STR_LEN 5 /* including terminating zero */
-
-TYPEDEF_NOTE(crash_note_core_t, CORE_STR_LEN, ELF_Prstatus);
-
-#define XEN_STR "Xen"
-#define XEN_STR_LEN 4 /* including terminating zero */
-
-TYPEDEF_NOTE(crash_note_xen_core_t, XEN_STR_LEN, crash_xen_core_t);
-
typedef struct {
unsigned long xen_major_version;
unsigned long xen_minor_version;
@@ -113,20 +70,6 @@ typedef struct {
#endif
} crash_xen_info_t;
-TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t);
-
-typedef struct {
- crash_note_core_t core;
- crash_note_xen_core_t xen_regs;
- crash_note_xen_info_t xen_info;
-} __attribute__ ((packed)) crash_note_t;
-
-#define setup_crash_note(np, member, str, str_len, id) \
- np->member.note.note.note.namesz = str_len; \
- np->member.note.note.note.descsz = sizeof(np->member.desc.desc); \
- np->member.note.note.note.type = id; \
- memcpy(np->member.note.note.name, str, str_len)
-
#endif /* __ELFCOREC_H__ */
/*
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|