ia64/xen-unstable
changeset 13346:91b9c6eae6e8
[XEN] Kexec: Clean up ELF note construction to avoid multiply nested
struct/unions and the packed keyword.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
struct/unions and the packed keyword.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Tue Jan 09 17:15:28 2007 +0000 (2007-01-09) |
parents | 79b5090c791f |
children | f653919e069a |
files | xen/common/kexec.c xen/include/xen/elfcore.h |
line diff
1.1 --- a/xen/common/kexec.c Tue Jan 09 17:14:28 2007 +0000 1.2 +++ b/xen/common/kexec.c Tue Jan 09 17:15:28 2007 +0000 1.3 @@ -26,7 +26,15 @@ 1.4 1.5 typedef long ret_t; 1.6 1.7 -DEFINE_PER_CPU (crash_note_t, crash_notes); 1.8 +#define ELFNOTE_ALIGN(_n_) (((_n_)+3)&~3) 1.9 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) 1.10 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz)) 1.11 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz)) 1.12 + 1.13 +DEFINE_PER_CPU(void *, crash_notes); 1.14 + 1.15 +Elf_Note *xen_crash_note; 1.16 + 1.17 cpumask_t crash_saved_cpus; 1.18 1.19 xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; 1.20 @@ -70,40 +78,29 @@ static void one_cpu_only(void) 1.21 void kexec_crash_save_cpu(void) 1.22 { 1.23 int cpu = smp_processor_id(); 1.24 - crash_note_t *cntp; 1.25 + Elf_Note *note = per_cpu(crash_notes, cpu); 1.26 + ELF_Prstatus *prstatus; 1.27 + crash_xen_core_t *xencore; 1.28 1.29 if ( cpu_test_and_set(cpu, crash_saved_cpus) ) 1.30 return; 1.31 1.32 - cntp = &per_cpu(crash_notes, cpu); 1.33 - elf_core_save_regs(&cntp->core.desc.desc.pr_reg, 1.34 - &cntp->xen_regs.desc.desc); 1.35 + prstatus = ELFNOTE_DESC(note); 1.36 1.37 - /* Set up crash "CORE" note. */ 1.38 - setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS); 1.39 + note = ELFNOTE_NEXT(note); 1.40 + xencore = ELFNOTE_DESC(note); 1.41 1.42 - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */ 1.43 - setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN, 1.44 - XEN_ELFNOTE_CRASH_REGS); 1.45 + elf_core_save_regs(&prstatus->pr_reg, xencore); 1.46 } 1.47 1.48 /* Set up the single Xen-specific-info crash note. */ 1.49 crash_xen_info_t *kexec_crash_save_info(void) 1.50 { 1.51 int cpu = smp_processor_id(); 1.52 - crash_note_t *cntp; 1.53 - crash_xen_info_t *info; 1.54 + crash_xen_info_t *info = ELFNOTE_DESC(xen_crash_note); 1.55 1.56 BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus)); 1.57 1.58 - cntp = &per_cpu(crash_notes, cpu); 1.59 - 1.60 - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */ 1.61 - setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN, 1.62 - XEN_ELFNOTE_CRASH_INFO); 1.63 - 1.64 - info = &cntp->xen_info.desc.desc; 1.65 - 1.66 info->xen_major_version = xen_major_version(); 1.67 info->xen_minor_version = xen_minor_version(); 1.68 info->xen_extra_version = __pa(xen_extra_version()); 1.69 @@ -147,6 +144,14 @@ static __init int register_crashdump_tri 1.70 } 1.71 __initcall(register_crashdump_trigger); 1.72 1.73 +static void setup_note(Elf_Note *n, const char *name, int type, int descsz) 1.74 +{ 1.75 + strcpy(ELFNOTE_NAME(n), name); 1.76 + n->namesz = strlen(name); 1.77 + n->descsz = descsz; 1.78 + n->type = type; 1.79 +} 1.80 + 1.81 #define kexec_get(x) kexec_get_##x 1.82 1.83 #endif 1.84 @@ -167,11 +172,44 @@ static int kexec_get(xen)(xen_kexec_rang 1.85 1.86 static int kexec_get(cpu)(xen_kexec_range_t *range) 1.87 { 1.88 - if ( range->nr < 0 || range->nr >= num_present_cpus() ) 1.89 + int nr = range->nr; 1.90 + int nr_bytes = sizeof(Elf_Note) * 2 1.91 + + ELFNOTE_ALIGN(sizeof(ELF_Prstatus)) 1.92 + + ELFNOTE_ALIGN(sizeof(crash_xen_core_t)); 1.93 + 1.94 + if ( nr < 0 || nr >= num_present_cpus() ) 1.95 return -EINVAL; 1.96 1.97 - range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr)); 1.98 - range->size = sizeof(crash_note_t); 1.99 + /* The Xen info note is included in CPU0's range. */ 1.100 + if ( nr == 0 ) 1.101 + nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t)); 1.102 + 1.103 + if ( per_cpu(crash_notes, nr) == NULL ) 1.104 + { 1.105 + Elf_Note *note; 1.106 + 1.107 + note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes); 1.108 + 1.109 + if ( note == NULL ) 1.110 + return -ENOMEM; 1.111 + 1.112 + /* Setup CORE note. */ 1.113 + setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus)); 1.114 + 1.115 + /* Setup Xen CORE note. */ 1.116 + note = ELFNOTE_NEXT(note); 1.117 + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS, sizeof(crash_xen_core_t)); 1.118 + 1.119 + if (nr == 0) 1.120 + { 1.121 + /* Setup system wide Xen info note. */ 1.122 + xen_crash_note = note = ELFNOTE_NEXT(note); 1.123 + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO, sizeof(crash_xen_info_t)); 1.124 + } 1.125 + } 1.126 + 1.127 + range->start = __pa((unsigned long)per_cpu(crash_notes, nr)); 1.128 + range->size = nr_bytes; 1.129 return 0; 1.130 } 1.131
2.1 --- a/xen/include/xen/elfcore.h Tue Jan 09 17:14:28 2007 +0000 2.2 +++ b/xen/include/xen/elfcore.h Tue Jan 09 17:15:28 2007 +0000 2.3 @@ -56,49 +56,6 @@ typedef struct 2.4 int pr_fpvalid; /* True if math co-processor being used. */ 2.5 } ELF_Prstatus; 2.6 2.7 -/* 2.8 - * The following data structures provide 64-bit ELF notes. In theory it should 2.9 - * be possible to support both 64-bit and 32-bit ELF files, but to keep it 2.10 - * simple we only do 64-bit. 2.11 - * 2.12 - * Please note that the current code aligns the 64-bit notes in the same 2.13 - * way as Linux does. We are not following the 64-bit ELF spec, no one does. 2.14 - * 2.15 - * We are avoiding two problems by restricting us to 64-bit notes only: 2.16 - * - Alignment of notes change with the word size. Ick. 2.17 - * - We would need to tell kexec-tools which format we are using in the 2.18 - * hypervisor to make sure the right ELF format is generated. 2.19 - * That requires infrastructure. Let's not. 2.20 - */ 2.21 - 2.22 -#define NOTE_ALIGN(x, n) ((x + ((1 << n) - 1)) / (1 << n)) 2.23 -#define PAD32(x) u32 pad_data[NOTE_ALIGN(x, 2)] 2.24 - 2.25 -#define TYPEDEF_NOTE(type, strlen, desctype) \ 2.26 - typedef struct { \ 2.27 - union { \ 2.28 - struct { \ 2.29 - Elf_Note note; \ 2.30 - unsigned char name[strlen]; \ 2.31 - } note; \ 2.32 - PAD32(sizeof(Elf_Note) + strlen); \ 2.33 - } note; \ 2.34 - union { \ 2.35 - desctype desc; \ 2.36 - PAD32(sizeof(desctype)); \ 2.37 - } desc; \ 2.38 - } __attribute__ ((packed)) type 2.39 - 2.40 -#define CORE_STR "CORE" 2.41 -#define CORE_STR_LEN 5 /* including terminating zero */ 2.42 - 2.43 -TYPEDEF_NOTE(crash_note_core_t, CORE_STR_LEN, ELF_Prstatus); 2.44 - 2.45 -#define XEN_STR "Xen" 2.46 -#define XEN_STR_LEN 4 /* including terminating zero */ 2.47 - 2.48 -TYPEDEF_NOTE(crash_note_xen_core_t, XEN_STR_LEN, crash_xen_core_t); 2.49 - 2.50 typedef struct { 2.51 unsigned long xen_major_version; 2.52 unsigned long xen_minor_version; 2.53 @@ -113,20 +70,6 @@ typedef struct { 2.54 #endif 2.55 } crash_xen_info_t; 2.56 2.57 -TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t); 2.58 - 2.59 -typedef struct { 2.60 - crash_note_core_t core; 2.61 - crash_note_xen_core_t xen_regs; 2.62 - crash_note_xen_info_t xen_info; 2.63 -} __attribute__ ((packed)) crash_note_t; 2.64 - 2.65 -#define setup_crash_note(np, member, str, str_len, id) \ 2.66 - np->member.note.note.note.namesz = str_len; \ 2.67 - np->member.note.note.note.descsz = sizeof(np->member.desc.desc); \ 2.68 - np->member.note.note.note.type = id; \ 2.69 - memcpy(np->member.note.note.name, str, str_len) 2.70 - 2.71 #endif /* __ELFCOREC_H__ */ 2.72 2.73 /*