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  /*