kexec-tools: Introduce crashdump-xen.c and Xen support

This patch adds the new file crashdump-xen.c that implements Xen support. The
Xen support is not complete yet in the sense that a special program header
for the hypervisor isn't created. Crash notes for physical cpus are created
so basic support is at least provided by this patch.

Signed-off-by: Magnus Damm <[EMAIL PROTECTED]>
---

 kexec/Makefile        |    1
 kexec/crashdump-elf.c |   24 ++++++++++----
 kexec/crashdump-xen.c |   82 +++++++++++++++++++++++++++++++++++++++++++++++++
 kexec/crashdump.h     |    4 ++
 kexec/kexec-iomem.c   |   14 ++++----
 kexec/kexec.h         |    7 ++++
 6 files changed, 119 insertions(+), 13 deletions(-)

--- 0010/kexec/Makefile
+++ work/kexec/Makefile 2006-11-17 17:34:32.000000000 +0900
@@ -18,6 +18,7 @@ KEXEC_C_SRCS+= kexec/kexec-elf-rel.c 
 KEXEC_C_SRCS+= kexec/kexec-elf-boot.c 
 KEXEC_C_SRCS+= kexec/kexec-iomem.c 
 KEXEC_C_SRCS+= kexec/crashdump.c
+KEXEC_C_SRCS+= kexec/crashdump-xen.c
 KEXEC_C_GENERATED_SRCS+= $(PURGATORY_HEX_C)
 KEXEC_S_SRCS:= 
 KEXEC_S_GENERATED_SRCS:=
--- 0005/kexec/crashdump-elf.c
+++ work/kexec/crashdump-elf.c  2006-11-17 17:37:35.000000000 +0900
@@ -16,14 +16,18 @@ int FUNCTION(struct kexec_info *info,
        long int nr_cpus = 0;
        uint64_t notes_addr, notes_len;
 
-       nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+       if (xen_present())
+               nr_cpus = xen_get_nr_phys_cpus();
+       else
+               nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
        if (nr_cpus < 0) {
                return -1;
        }
 
        sz = sizeof(EHDR) + nr_cpus * sizeof(PHDR) + ranges * sizeof(PHDR);
 
-       if (info->kern_size) {
+       if (info->kern_size && !xen_present()) {
                sz += sizeof(PHDR);
        }
 
@@ -64,9 +68,17 @@ int FUNCTION(struct kexec_info *info,
        /* PT_NOTE program headers. One per cpu */
 
        for (i = 0; i < nr_cpus; i++) {
-               if (elf_info->get_note_info(i, &notes_addr, &notes_len) < 0) {
-                       /* This cpu is not present. Skip it. */
-                       continue;
+               if (xen_present()) {
+                       if (xen_get_note(i, &notes_addr, &notes_len) < 0) {
+                               /* This cpu is not present. Skip it. */
+                               continue;
+                       }
+               }
+               else {
+                       if (elf_info->get_note_info(i, &notes_addr, &notes_len) 
< 0) {
+                               /* This cpu is not present. Skip it. */
+                               continue;
+                       }
                }
 
                phdr = (PHDR *) bufp;
@@ -94,7 +106,7 @@ int FUNCTION(struct kexec_info *info,
         * Kernel is mapped if info->kern_size is non-zero.
         */
 
-       if (info->kern_size) {
+       if (info->kern_size && !xen_present()) {
                phdr = (PHDR *) bufp;
                bufp += sizeof(PHDR);
                phdr->p_type    = PT_LOAD;
--- /dev/null
+++ work/kexec/crashdump-xen.c  2006-11-17 17:34:33.000000000 +0900
@@ -0,0 +1,82 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "kexec.h"
+#include "crashdump.h"
+
+struct crash_note_info {
+       unsigned long base;
+       unsigned long length;
+};
+
+int xen_phys_cpus = 0;
+struct crash_note_info *xen_phys_notes;
+
+int xen_present(void)
+{
+       struct stat buf;
+
+       return stat("/proc/xen", &buf) == 0;
+}
+
+static int xen_crash_note_callback(void *data, int nr,
+                                  char *str,
+                                  unsigned long base,
+                                  unsigned long length)
+{
+       struct crash_note_info *note = xen_phys_notes + nr;
+
+       note->base = base;
+       note->length = length;
+
+       return 0;
+}
+
+int xen_get_nr_phys_cpus(void)
+{
+       char *match = "Crash note\n";
+       int cpus, n;
+  
+       if (xen_phys_cpus)
+               return xen_phys_cpus;
+
+       if ((cpus = kexec_iomem_for_each_line(match, NULL, NULL))) {
+               n = sizeof(struct crash_note_info) * cpus;
+               xen_phys_notes = malloc(n);
+               if (xen_phys_notes) {
+                       memset(xen_phys_notes, 0, n);
+                       kexec_iomem_for_each_line(match, NULL, 
+                                                 xen_crash_note_callback);
+               }
+
+               xen_phys_cpus = cpus;
+       }
+
+       return cpus;
+}
+
+int xen_get_note(int cpu, uint64_t *basep, uint64_t *lenp)
+{
+       struct crash_note_info *note;
+
+       if (xen_phys_cpus <= 0)
+               return -1;
+
+       note = xen_phys_notes + cpu;
+
+       if (basep)
+               *basep = note->base;
+
+       if (lenp)
+               *lenp = note->length;
+
+       return 0;
+}
--- 0005/kexec/crashdump.h
+++ work/kexec/crashdump.h      2006-11-17 17:34:32.000000000 +0900
@@ -36,4 +36,8 @@ int crash_create_elf64_headers(struct ke
                               struct memory_range *range, int ranges,
                               void **buf, unsigned long *size);
 
+int xen_present(void);
+int xen_get_nr_phys_cpus(void);
+int xen_get_note(int cpu, uint64_t *addr, uint64_t *len);
+
 #endif /* CRASHDUMP_H */
--- 0010/kexec/kexec-iomem.c
+++ work/kexec/kexec-iomem.c    2006-11-17 17:34:32.000000000 +0900
@@ -12,13 +12,13 @@
 #include "kexec.h"
 #include "crashdump.h"
 
-static int kexec_iomem_for_each_line(char *match, 
-                                    int (*callback)(void *data, 
-                                                    int nr,
-                                                    char *str,
-                                                    unsigned long base,
-                                                    unsigned long length),
-                                    void *data)
+int kexec_iomem_for_each_line(char *match, 
+                             int (*callback)(void *data, 
+                                             int nr,
+                                             char *str,
+                                             unsigned long base,
+                                             unsigned long length),
+                             void *data)
 {
        const char iomem[]= "/proc/iomem";
        char line[MAX_LINE];
--- 0010/kexec/kexec.h
+++ work/kexec/kexec.h  2006-11-17 17:34:32.000000000 +0900
@@ -201,6 +201,13 @@ int arch_compat_trampoline(struct kexec_
 void arch_update_purgatory(struct kexec_info *info);
 int is_crashkernel_mem_reserved(void);
 
+int kexec_iomem_for_each_line(char *match, 
+                             int (*callback)(void *data, 
+                                             int nr,
+                                             char *str,
+                                             unsigned long base,
+                                             unsigned long length),
+                             void *data);
 int kexec_iomem_single(char *str, uint64_t *start, uint64_t *end);
 
 
_______________________________________________
fastboot mailing list
fastboot@lists.osdl.org
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to