[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.