ia64/xen-unstable

changeset 17853:8a0415fac759

extract vmcoreinfo from /proc/vmcore for Xen

- the machine address and the size of the vmcoreinfo area is returned
via the kexec_op(get_range) hypercall
- fill the vmcoreinfo data when the kexec_op(crash load) hypercall
is called

Signed-off-by: Itsuro Oda <oda@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 13 09:54:03 2008 +0100 (2008-06-13)
parents 09dd5999401b
children 02b6977de4b5
files xen/arch/ia64/xen/machine_kexec.c xen/arch/ia64/xen/mm.c xen/arch/x86/machine_kexec.c xen/arch/x86/mm.c xen/common/kexec.c xen/common/page_alloc.c xen/include/asm-ia64/config.h xen/include/asm-ia64/mm.h xen/include/asm-x86/config.h xen/include/asm-x86/mm.h xen/include/public/kexec.h xen/include/xen/mm.h
line diff
     1.1 --- a/xen/arch/ia64/xen/machine_kexec.c	Thu Jun 12 18:14:00 2008 +0100
     1.2 +++ b/xen/arch/ia64/xen/machine_kexec.c	Fri Jun 13 09:54:03 2008 +0100
     1.3 @@ -193,6 +193,15 @@ int machine_kexec_get(xen_kexec_range_t 
     1.4  	return -EINVAL;
     1.5  }
     1.6  
     1.7 +void arch_crash_save_vmcoreinfo(void)
     1.8 +{
     1.9 +	VMCOREINFO_SYMBOL(dom_xen);
    1.10 +	VMCOREINFO_SYMBOL(dom_io);
    1.11 +	VMCOREINFO_SYMBOL(xen_pstart);
    1.12 +	VMCOREINFO_SYMBOL(frametable_pg_dir);
    1.13 +	VMCOREINFO_SYMBOL_ALIAS(xen_heap_start, xen_pickle_offset);
    1.14 +}
    1.15 +
    1.16  /*
    1.17   * Local variables:
    1.18   * mode: C
     2.1 --- a/xen/arch/ia64/xen/mm.c	Thu Jun 12 18:14:00 2008 +0100
     2.2 +++ b/xen/arch/ia64/xen/mm.c	Fri Jun 13 09:54:03 2008 +0100
     2.3 @@ -189,7 +189,7 @@ static void domain_page_flush_and_put(st
     2.4  
     2.5  extern unsigned long ia64_iobase;
     2.6  
     2.7 -static struct domain *dom_xen, *dom_io;
     2.8 +struct domain *dom_xen, *dom_io;
     2.9  
    2.10  /*
    2.11   * This number is bigger than DOMID_SELF, DOMID_XEN and DOMID_IO.
     3.1 --- a/xen/arch/x86/machine_kexec.c	Thu Jun 12 18:14:00 2008 +0100
     3.2 +++ b/xen/arch/x86/machine_kexec.c	Fri Jun 13 09:54:03 2008 +0100
     3.3 @@ -145,6 +145,19 @@ int machine_kexec_get(xen_kexec_range_t 
     3.4  	return machine_kexec_get_xen(range);
     3.5  }
     3.6  
     3.7 +void arch_crash_save_vmcoreinfo(void)
     3.8 +{
     3.9 +	VMCOREINFO_SYMBOL(dom_xen);
    3.10 +	VMCOREINFO_SYMBOL(dom_io);
    3.11 +
    3.12 +#ifdef CONFIG_X86_PAE
    3.13 +	VMCOREINFO_SYMBOL_ALIAS(pgd_l3, idle_pg_table);
    3.14 +#endif
    3.15 +#ifdef CONFIG_X86_64
    3.16 +	VMCOREINFO_SYMBOL_ALIAS(pgd_l4, idle_pg_table);
    3.17 +#endif
    3.18 +}
    3.19 +
    3.20  /*
    3.21   * Local variables:
    3.22   * mode: C
     4.1 --- a/xen/arch/x86/mm.c	Thu Jun 12 18:14:00 2008 +0100
     4.2 +++ b/xen/arch/x86/mm.c	Fri Jun 13 09:54:03 2008 +0100
     4.3 @@ -151,7 +151,7 @@ static DEFINE_PER_CPU(struct percpu_mm_i
     4.4  #define FOREIGNDOM (this_cpu(percpu_mm_info).foreign ?: current->domain)
     4.5  
     4.6  /* Private domain structs for DOMID_XEN and DOMID_IO. */
     4.7 -static struct domain *dom_xen, *dom_io;
     4.8 +struct domain *dom_xen, *dom_io;
     4.9  
    4.10  /* Frame table and its size in pages. */
    4.11  struct page_info *frame_table;
     5.1 --- a/xen/common/kexec.c	Thu Jun 12 18:14:00 2008 +0100
     5.2 +++ b/xen/common/kexec.c	Fri Jun 13 09:54:03 2008 +0100
     5.3 @@ -43,6 +43,9 @@ static unsigned long kexec_flags = 0; /*
     5.4  
     5.5  static spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
     5.6  
     5.7 +static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
     5.8 +static size_t vmcoreinfo_size = 0;
     5.9 +
    5.10  xen_kexec_reserve_t kexec_crash_area;
    5.11  
    5.12  static void __init parse_crashkernel(const char *str)
    5.13 @@ -208,6 +211,13 @@ static int kexec_get_cpu(xen_kexec_range
    5.14      return 0;
    5.15  }
    5.16  
    5.17 +static int kexec_get_vmcoreinfo(xen_kexec_range_t *range)
    5.18 +{
    5.19 +    range->start = __pa((unsigned long)vmcoreinfo_data);
    5.20 +    range->size = VMCOREINFO_BYTES;
    5.21 +    return 0;
    5.22 +}
    5.23 +
    5.24  static int kexec_get_range_internal(xen_kexec_range_t *range)
    5.25  {
    5.26      int ret = -EINVAL;
    5.27 @@ -220,6 +230,9 @@ static int kexec_get_range_internal(xen_
    5.28      case KEXEC_RANGE_MA_CPU:
    5.29          ret = kexec_get_cpu(range);
    5.30          break;
    5.31 +    case KEXEC_RANGE_MA_VMCOREINFO:
    5.32 +        ret = kexec_get_vmcoreinfo(range);
    5.33 +        break;
    5.34      default:
    5.35          ret = machine_kexec_get(range);
    5.36          break;
    5.37 @@ -288,6 +301,56 @@ static int kexec_load_get_bits(int type,
    5.38      return 0;
    5.39  }
    5.40  
    5.41 +void vmcoreinfo_append_str(const char *fmt, ...)
    5.42 +{
    5.43 +    va_list args;
    5.44 +    char buf[0x50];
    5.45 +    int r;
    5.46 +    size_t note_size = sizeof(Elf_Note) + ELFNOTE_ALIGN(strlen(VMCOREINFO_NOTE_NAME) + 1);
    5.47 +
    5.48 +    if (vmcoreinfo_size + note_size + sizeof(buf) > VMCOREINFO_BYTES)
    5.49 +        return;
    5.50 +
    5.51 +    va_start(args, fmt);
    5.52 +    r = vsnprintf(buf, sizeof(buf), fmt, args);
    5.53 +    va_end(args);
    5.54 +
    5.55 +    memcpy(&vmcoreinfo_data[note_size + vmcoreinfo_size], buf, r);
    5.56 +
    5.57 +    vmcoreinfo_size += r;
    5.58 +}
    5.59 +
    5.60 +static void crash_save_vmcoreinfo(void)
    5.61 +{
    5.62 +    size_t data_size;
    5.63 +
    5.64 +    if (vmcoreinfo_size > 0)    /* already saved */
    5.65 +        return;
    5.66 +
    5.67 +    data_size = VMCOREINFO_BYTES - (sizeof(Elf_Note) + ELFNOTE_ALIGN(strlen(VMCOREINFO_NOTE_NAME) + 1));
    5.68 +    setup_note((Elf_Note *)vmcoreinfo_data, VMCOREINFO_NOTE_NAME, 0, data_size);
    5.69 +
    5.70 +    VMCOREINFO_PAGESIZE(PAGE_SIZE);
    5.71 +
    5.72 +    VMCOREINFO_SYMBOL(domain_list);
    5.73 +    VMCOREINFO_SYMBOL(frame_table);
    5.74 +    VMCOREINFO_SYMBOL(alloc_bitmap);
    5.75 +    VMCOREINFO_SYMBOL(max_page);
    5.76 +    VMCOREINFO_SYMBOL(xenheap_phys_end);
    5.77 +
    5.78 +    VMCOREINFO_STRUCT_SIZE(page_info);
    5.79 +    VMCOREINFO_STRUCT_SIZE(domain);
    5.80 +
    5.81 +    VMCOREINFO_OFFSET(page_info, count_info);
    5.82 +    VMCOREINFO_OFFSET_ALIAS(page_info, u, _domain);
    5.83 +    VMCOREINFO_OFFSET(domain, domain_id);
    5.84 +    VMCOREINFO_OFFSET(domain, next_in_list);
    5.85 +
    5.86 +#ifdef ARCH_CRASH_SAVE_VMCOREINFO
    5.87 +    arch_crash_save_vmcoreinfo();
    5.88 +#endif
    5.89 +}
    5.90 +
    5.91  static int kexec_load_unload_internal(unsigned long op, xen_kexec_load_t *load)
    5.92  {
    5.93      xen_kexec_image_t *image;
    5.94 @@ -316,6 +379,8 @@ static int kexec_load_unload_internal(un
    5.95              /* Make new image the active one */
    5.96              change_bit(bit, &kexec_flags);
    5.97          }
    5.98 +
    5.99 +        crash_save_vmcoreinfo();
   5.100      }
   5.101  
   5.102      /* Unload the old image if present and load successful */
     6.1 --- a/xen/common/page_alloc.c	Thu Jun 12 18:14:00 2008 +0100
     6.2 +++ b/xen/common/page_alloc.c	Fri Jun 13 09:54:03 2008 +0100
     6.3 @@ -102,7 +102,7 @@ static unsigned long scrub_pages;
     6.4   *  One bit per page of memory. Bit set => page is allocated.
     6.5   */
     6.6  
     6.7 -static unsigned long *alloc_bitmap;
     6.8 +unsigned long *alloc_bitmap;
     6.9  #define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
    6.10  
    6.11  #define allocated_in_map(_pn)                       \
     7.1 --- a/xen/include/asm-ia64/config.h	Thu Jun 12 18:14:00 2008 +0100
     7.2 +++ b/xen/include/asm-ia64/config.h	Fri Jun 13 09:54:03 2008 +0100
     7.3 @@ -295,4 +295,6 @@ struct screen_info { };
     7.4  
     7.5  #define CONFIG_XENCOMM_MARK_DIRTY 1
     7.6  
     7.7 +#define ARCH_CRASH_SAVE_VMCOREINFO
     7.8 +
     7.9  #endif	/* _IA64_CONFIG_H_ */
     8.1 --- a/xen/include/asm-ia64/mm.h	Thu Jun 12 18:14:00 2008 +0100
     8.2 +++ b/xen/include/asm-ia64/mm.h	Fri Jun 13 09:54:03 2008 +0100
     8.3 @@ -503,4 +503,6 @@ int steal_page(
     8.4  
     8.5  unsigned long domain_get_maximum_gpfn(struct domain *d);
     8.6  
     8.7 +extern struct domain *dom_xen, *dom_io;	/* for vmcoreinfo */
     8.8 +
     8.9  #endif /* __ASM_IA64_MM_H__ */
     9.1 --- a/xen/include/asm-x86/config.h	Thu Jun 12 18:14:00 2008 +0100
     9.2 +++ b/xen/include/asm-x86/config.h	Fri Jun 13 09:54:03 2008 +0100
     9.3 @@ -371,4 +371,6 @@ extern unsigned long xen_phys_start, xen
     9.4  #define ELFSIZE 32
     9.5  #endif
     9.6  
     9.7 +#define ARCH_CRASH_SAVE_VMCOREINFO
     9.8 +
     9.9  #endif /* __X86_CONFIG_H__ */
    10.1 --- a/xen/include/asm-x86/mm.h	Thu Jun 12 18:14:00 2008 +0100
    10.2 +++ b/xen/include/asm-x86/mm.h	Fri Jun 13 09:54:03 2008 +0100
    10.3 @@ -357,4 +357,6 @@ unsigned int domain_clamp_alloc_bitsize(
    10.4  
    10.5  unsigned long domain_get_maximum_gpfn(struct domain *d);
    10.6  
    10.7 +extern struct domain *dom_xen, *dom_io;	/* for vmcoreinfo */
    10.8 +
    10.9  #endif /* __ASM_X86_MM_H__ */
    11.1 --- a/xen/include/public/kexec.h	Thu Jun 12 18:14:00 2008 +0100
    11.2 +++ b/xen/include/public/kexec.h	Fri Jun 13 09:54:03 2008 +0100
    11.3 @@ -138,6 +138,7 @@ typedef struct xen_kexec_load {
    11.4                                       * the ia64_boot_param */
    11.5  #define KEXEC_RANGE_MA_EFI_MEMMAP 5 /* machine address and size of
    11.6                                       * of the EFI Memory Map */
    11.7 +#define KEXEC_RANGE_MA_VMCOREINFO 6 /* machine address and size of vmcoreinfo */
    11.8  
    11.9  /*
   11.10   * Find the address and size of certain memory areas
   11.11 @@ -154,6 +155,27 @@ typedef struct xen_kexec_range {
   11.12      unsigned long start;
   11.13  } xen_kexec_range_t;
   11.14  
   11.15 +/* vmcoreinfo stuff */
   11.16 +#define VMCOREINFO_BYTES           (4096)
   11.17 +#define VMCOREINFO_NOTE_NAME       "VMCOREINFO_XEN"
   11.18 +void arch_crash_save_vmcoreinfo(void);
   11.19 +void vmcoreinfo_append_str(const char *fmt, ...)
   11.20 +       __attribute__ ((format (printf, 1, 2)));
   11.21 +#define VMCOREINFO_PAGESIZE(value) \
   11.22 +       vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
   11.23 +#define VMCOREINFO_SYMBOL(name) \
   11.24 +       vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
   11.25 +#define VMCOREINFO_SYMBOL_ALIAS(alias, name) \
   11.26 +       vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #alias, (unsigned long)&name)
   11.27 +#define VMCOREINFO_STRUCT_SIZE(name) \
   11.28 +       vmcoreinfo_append_str("SIZE(%s)=%zu\n", #name, sizeof(struct name))
   11.29 +#define VMCOREINFO_OFFSET(name, field) \
   11.30 +       vmcoreinfo_append_str("OFFSET(%s.%s)=%zu\n", #name, #field, \
   11.31 +                             offsetof(struct name, field))
   11.32 +#define VMCOREINFO_OFFSET_ALIAS(name, field, alias) \
   11.33 +       vmcoreinfo_append_str("OFFSET(%s.%s)=%zu\n", #name, #alias, \
   11.34 +                             offsetof(struct name, field))
   11.35 +
   11.36  #endif /* _XEN_PUBLIC_KEXEC_H */
   11.37  
   11.38  /*
    12.1 --- a/xen/include/xen/mm.h	Thu Jun 12 18:14:00 2008 +0100
    12.2 +++ b/xen/include/xen/mm.h	Fri Jun 13 09:54:03 2008 +0100
    12.3 @@ -104,4 +104,6 @@ int guest_remove_page(struct domain *d, 
    12.4  /* Returns TRUE if the memory at address @p is ordinary RAM. */
    12.5  int memory_is_conventional_ram(paddr_t p);
    12.6  
    12.7 +extern unsigned long *alloc_bitmap;	/* for vmcoreinfo */
    12.8 +
    12.9  #endif /* __XEN_MM_H__ */