ia64/xen-unstable
changeset 13348:761f695043ff
merge
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Tue Jan 09 17:17:05 2007 +0000 (2007-01-09) |
parents | ddea7363fa41 f653919e069a |
children | fb38d0794f50 |
files |
line diff
1.1 --- a/linux-2.6-xen-sparse/kernel/kexec.c Tue Jan 09 17:11:46 2007 +0000 1.2 +++ b/linux-2.6-xen-sparse/kernel/kexec.c Tue Jan 09 17:17:05 2007 +0000 1.3 @@ -1012,9 +1012,11 @@ asmlinkage long sys_kexec_load(unsigned 1.4 goto out; 1.5 } 1.6 #ifdef CONFIG_XEN 1.7 - result = xen_machine_kexec_load(image); 1.8 - if (result) 1.9 - goto out; 1.10 + if (image) { 1.11 + result = xen_machine_kexec_load(image); 1.12 + if (result) 1.13 + goto out; 1.14 + } 1.15 #endif 1.16 /* Install the new kernel, and Uninstall the old */ 1.17 image = xchg(dest_image, image);
2.1 --- a/xen/common/kexec.c Tue Jan 09 17:11:46 2007 +0000 2.2 +++ b/xen/common/kexec.c Tue Jan 09 17:17:05 2007 +0000 2.3 @@ -26,18 +26,26 @@ 2.4 2.5 typedef long ret_t; 2.6 2.7 -DEFINE_PER_CPU (crash_note_t, crash_notes); 2.8 -cpumask_t crash_saved_cpus; 2.9 +#define ELFNOTE_ALIGN(_n_) (((_n_)+3)&~3) 2.10 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) 2.11 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz)) 2.12 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz)) 2.13 2.14 -xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; 2.15 +static DEFINE_PER_CPU(void *, crash_notes); 2.16 + 2.17 +static Elf_Note *xen_crash_note; 2.18 + 2.19 +static cpumask_t crash_saved_cpus; 2.20 + 2.21 +static xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; 2.22 2.23 #define KEXEC_FLAG_DEFAULT_POS (KEXEC_IMAGE_NR + 0) 2.24 #define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1) 2.25 #define KEXEC_FLAG_IN_PROGRESS (KEXEC_IMAGE_NR + 2) 2.26 2.27 -unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */ 2.28 +static unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */ 2.29 2.30 -spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED; 2.31 +static spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED; 2.32 2.33 xen_kexec_reserve_t kexec_crash_area; 2.34 2.35 @@ -70,40 +78,29 @@ static void one_cpu_only(void) 2.36 void kexec_crash_save_cpu(void) 2.37 { 2.38 int cpu = smp_processor_id(); 2.39 - crash_note_t *cntp; 2.40 + Elf_Note *note = per_cpu(crash_notes, cpu); 2.41 + ELF_Prstatus *prstatus; 2.42 + crash_xen_core_t *xencore; 2.43 2.44 if ( cpu_test_and_set(cpu, crash_saved_cpus) ) 2.45 return; 2.46 2.47 - cntp = &per_cpu(crash_notes, cpu); 2.48 - elf_core_save_regs(&cntp->core.desc.desc.pr_reg, 2.49 - &cntp->xen_regs.desc.desc); 2.50 + prstatus = ELFNOTE_DESC(note); 2.51 2.52 - /* Set up crash "CORE" note. */ 2.53 - setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS); 2.54 + note = ELFNOTE_NEXT(note); 2.55 + xencore = ELFNOTE_DESC(note); 2.56 2.57 - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */ 2.58 - setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN, 2.59 - XEN_ELFNOTE_CRASH_REGS); 2.60 + elf_core_save_regs(&prstatus->pr_reg, xencore); 2.61 } 2.62 2.63 /* Set up the single Xen-specific-info crash note. */ 2.64 crash_xen_info_t *kexec_crash_save_info(void) 2.65 { 2.66 int cpu = smp_processor_id(); 2.67 - crash_note_t *cntp; 2.68 - crash_xen_info_t *info; 2.69 + crash_xen_info_t *info = ELFNOTE_DESC(xen_crash_note); 2.70 2.71 BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus)); 2.72 2.73 - cntp = &per_cpu(crash_notes, cpu); 2.74 - 2.75 - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */ 2.76 - setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN, 2.77 - XEN_ELFNOTE_CRASH_INFO); 2.78 - 2.79 - info = &cntp->xen_info.desc.desc; 2.80 - 2.81 info->xen_major_version = xen_major_version(); 2.82 info->xen_minor_version = xen_minor_version(); 2.83 info->xen_extra_version = __pa(xen_extra_version()); 2.84 @@ -147,6 +144,14 @@ static __init int register_crashdump_tri 2.85 } 2.86 __initcall(register_crashdump_trigger); 2.87 2.88 +static void setup_note(Elf_Note *n, const char *name, int type, int descsz) 2.89 +{ 2.90 + strcpy(ELFNOTE_NAME(n), name); 2.91 + n->namesz = strlen(name); 2.92 + n->descsz = descsz; 2.93 + n->type = type; 2.94 +} 2.95 + 2.96 #define kexec_get(x) kexec_get_##x 2.97 2.98 #endif 2.99 @@ -167,11 +172,44 @@ static int kexec_get(xen)(xen_kexec_rang 2.100 2.101 static int kexec_get(cpu)(xen_kexec_range_t *range) 2.102 { 2.103 - if ( range->nr < 0 || range->nr >= num_present_cpus() ) 2.104 + int nr = range->nr; 2.105 + int nr_bytes = sizeof(Elf_Note) * 2 2.106 + + ELFNOTE_ALIGN(sizeof(ELF_Prstatus)) 2.107 + + ELFNOTE_ALIGN(sizeof(crash_xen_core_t)); 2.108 + 2.109 + if ( nr < 0 || nr >= num_present_cpus() ) 2.110 return -EINVAL; 2.111 2.112 - range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr)); 2.113 - range->size = sizeof(crash_note_t); 2.114 + /* The Xen info note is included in CPU0's range. */ 2.115 + if ( nr == 0 ) 2.116 + nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t)); 2.117 + 2.118 + if ( per_cpu(crash_notes, nr) == NULL ) 2.119 + { 2.120 + Elf_Note *note; 2.121 + 2.122 + note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes); 2.123 + 2.124 + if ( note == NULL ) 2.125 + return -ENOMEM; 2.126 + 2.127 + /* Setup CORE note. */ 2.128 + setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus)); 2.129 + 2.130 + /* Setup Xen CORE note. */ 2.131 + note = ELFNOTE_NEXT(note); 2.132 + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS, sizeof(crash_xen_core_t)); 2.133 + 2.134 + if (nr == 0) 2.135 + { 2.136 + /* Setup system wide Xen info note. */ 2.137 + xen_crash_note = note = ELFNOTE_NEXT(note); 2.138 + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO, sizeof(crash_xen_info_t)); 2.139 + } 2.140 + } 2.141 + 2.142 + range->start = __pa((unsigned long)per_cpu(crash_notes, nr)); 2.143 + range->size = nr_bytes; 2.144 return 0; 2.145 } 2.146
3.1 --- a/xen/include/xen/elfcore.h Tue Jan 09 17:11:46 2007 +0000 3.2 +++ b/xen/include/xen/elfcore.h Tue Jan 09 17:17:05 2007 +0000 3.3 @@ -56,49 +56,6 @@ typedef struct 3.4 int pr_fpvalid; /* True if math co-processor being used. */ 3.5 } ELF_Prstatus; 3.6 3.7 -/* 3.8 - * The following data structures provide 64-bit ELF notes. In theory it should 3.9 - * be possible to support both 64-bit and 32-bit ELF files, but to keep it 3.10 - * simple we only do 64-bit. 3.11 - * 3.12 - * Please note that the current code aligns the 64-bit notes in the same 3.13 - * way as Linux does. We are not following the 64-bit ELF spec, no one does. 3.14 - * 3.15 - * We are avoiding two problems by restricting us to 64-bit notes only: 3.16 - * - Alignment of notes change with the word size. Ick. 3.17 - * - We would need to tell kexec-tools which format we are using in the 3.18 - * hypervisor to make sure the right ELF format is generated. 3.19 - * That requires infrastructure. Let's not. 3.20 - */ 3.21 - 3.22 -#define NOTE_ALIGN(x, n) ((x + ((1 << n) - 1)) / (1 << n)) 3.23 -#define PAD32(x) u32 pad_data[NOTE_ALIGN(x, 2)] 3.24 - 3.25 -#define TYPEDEF_NOTE(type, strlen, desctype) \ 3.26 - typedef struct { \ 3.27 - union { \ 3.28 - struct { \ 3.29 - Elf_Note note; \ 3.30 - unsigned char name[strlen]; \ 3.31 - } note; \ 3.32 - PAD32(sizeof(Elf_Note) + strlen); \ 3.33 - } note; \ 3.34 - union { \ 3.35 - desctype desc; \ 3.36 - PAD32(sizeof(desctype)); \ 3.37 - } desc; \ 3.38 - } __attribute__ ((packed)) type 3.39 - 3.40 -#define CORE_STR "CORE" 3.41 -#define CORE_STR_LEN 5 /* including terminating zero */ 3.42 - 3.43 -TYPEDEF_NOTE(crash_note_core_t, CORE_STR_LEN, ELF_Prstatus); 3.44 - 3.45 -#define XEN_STR "Xen" 3.46 -#define XEN_STR_LEN 4 /* including terminating zero */ 3.47 - 3.48 -TYPEDEF_NOTE(crash_note_xen_core_t, XEN_STR_LEN, crash_xen_core_t); 3.49 - 3.50 typedef struct { 3.51 unsigned long xen_major_version; 3.52 unsigned long xen_minor_version; 3.53 @@ -113,20 +70,6 @@ typedef struct { 3.54 #endif 3.55 } crash_xen_info_t; 3.56 3.57 -TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t); 3.58 - 3.59 -typedef struct { 3.60 - crash_note_core_t core; 3.61 - crash_note_xen_core_t xen_regs; 3.62 - crash_note_xen_info_t xen_info; 3.63 -} __attribute__ ((packed)) crash_note_t; 3.64 - 3.65 -#define setup_crash_note(np, member, str, str_len, id) \ 3.66 - np->member.note.note.note.namesz = str_len; \ 3.67 - np->member.note.note.note.descsz = sizeof(np->member.desc.desc); \ 3.68 - np->member.note.note.note.type = id; \ 3.69 - memcpy(np->member.note.note.name, str, str_len) 3.70 - 3.71 #endif /* __ELFCOREC_H__ */ 3.72 3.73 /*