[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Kexec: Clean up ELF note construction to avoid multiply nested
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxxxxx> # Date 1168362928 0 # Node ID 91b9c6eae6e8cbd639b04588dbf48f70673c6729 # Parent 79b5090c791fb9db9b5c4e7d3b5fe8b736da1533 [XEN] Kexec: Clean up ELF note construction to avoid multiply nested struct/unions and the packed keyword. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> --- xen/common/kexec.c | 88 ++++++++++++++++++++++++++++++++-------------- xen/include/xen/elfcore.h | 57 ----------------------------- 2 files changed, 63 insertions(+), 82 deletions(-) diff -r 79b5090c791f -r 91b9c6eae6e8 xen/common/kexec.c --- a/xen/common/kexec.c Tue Jan 09 17:14:28 2007 +0000 +++ b/xen/common/kexec.c Tue Jan 09 17:15:28 2007 +0000 @@ -26,7 +26,15 @@ typedef long ret_t; -DEFINE_PER_CPU (crash_note_t, crash_notes); +#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)) + +DEFINE_PER_CPU(void *, crash_notes); + +Elf_Note *xen_crash_note; + cpumask_t crash_saved_cpus; xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; @@ -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 79b5090c791f -r 91b9c6eae6e8 xen/include/xen/elfcore.h --- a/xen/include/xen/elfcore.h Tue Jan 09 17:14:28 2007 +0000 +++ b/xen/include/xen/elfcore.h Tue Jan 09 17:15:28 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |