direct-io.hg

changeset 15453:0900fb1a3693

xen: Fix kexec_crash_area reservation/allocation.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Jul 03 11:24:40 2007 +0100 (2007-07-03)
parents 647f9671dc44
children 83cbda5c1e1b
files xen/arch/x86/setup.c
line diff
     1.1 --- a/xen/arch/x86/setup.c	Tue Jul 03 10:31:13 2007 +0100
     1.2 +++ b/xen/arch/x86/setup.c	Tue Jul 03 11:24:40 2007 +0100
     1.3 @@ -172,9 +172,10 @@ static unsigned long __initdata initial_
     1.4  
     1.5  unsigned long __init initial_images_nrpages(void)
     1.6  {
     1.7 -    unsigned long s = initial_images_start + PAGE_SIZE - 1;
     1.8 -    unsigned long e = initial_images_end;
     1.9 -    return ((e >> PAGE_SHIFT) - (s >> PAGE_SHIFT));
    1.10 +    ASSERT(!(initial_images_start & ~PAGE_MASK));
    1.11 +    ASSERT(!(initial_images_end   & ~PAGE_MASK));
    1.12 +    return ((initial_images_end >> PAGE_SHIFT) -
    1.13 +            (initial_images_start >> PAGE_SHIFT));
    1.14  }
    1.15  
    1.16  void __init discard_initial_images(void)
    1.17 @@ -293,7 +294,7 @@ static void __init move_memory(
    1.18  static struct e820map __initdata boot_e820;
    1.19  
    1.20  /* Reserve area (@s,@e) in the temporary bootstrap e820 map. */
    1.21 -static void __init reserve_in_boot_e820(unsigned long s, unsigned long e)
    1.22 +static int __init reserve_in_boot_e820(unsigned long s, unsigned long e)
    1.23  {
    1.24      uint64_t rs, re;
    1.25      int i;
    1.26 @@ -303,23 +304,28 @@ static void __init reserve_in_boot_e820(
    1.27          /* Have we found the e820 region that includes the specified range? */
    1.28          rs = boot_e820.map[i].addr;
    1.29          re = rs + boot_e820.map[i].size;
    1.30 -        if ( (s < rs) || (e > re) )
    1.31 -            continue;
    1.32 -
    1.33 -        /* Start fragment. */
    1.34 -        boot_e820.map[i].size = s - rs;
    1.35 +        if ( (s >= rs) && (e <= re) )
    1.36 +            goto found;
    1.37 +    }
    1.38  
    1.39 -        /* End fragment. */
    1.40 -        if ( e < re )
    1.41 -        {
    1.42 -            memmove(&boot_e820.map[i+1], &boot_e820.map[i],
    1.43 -                    (boot_e820.nr_map-i) * sizeof(boot_e820.map[0]));
    1.44 -            boot_e820.nr_map++;
    1.45 -            i++;
    1.46 -            boot_e820.map[i].addr = e;
    1.47 -            boot_e820.map[i].size = re - e;
    1.48 -        }
    1.49 +    return 0;
    1.50 +
    1.51 + found:
    1.52 +    /* Start fragment. */
    1.53 +    boot_e820.map[i].size = s - rs;
    1.54 +
    1.55 +    /* End fragment. */
    1.56 +    if ( e < re )
    1.57 +    {
    1.58 +        memmove(&boot_e820.map[i+1], &boot_e820.map[i],
    1.59 +                (boot_e820.nr_map-i) * sizeof(boot_e820.map[0]));
    1.60 +        boot_e820.nr_map++;
    1.61 +        i++;
    1.62 +        boot_e820.map[i].addr = e;
    1.63 +        boot_e820.map[i].size = re - e;
    1.64      }
    1.65 +
    1.66 +    return 1;
    1.67  }
    1.68  
    1.69  struct boot_video_info {
    1.70 @@ -740,12 +746,19 @@ void __init __start_xen(unsigned long mb
    1.71          /* Is the region suitable for relocating the multiboot modules? */
    1.72          if ( !initial_images_start && (s < e) && ((e-s) >= modules_length) )
    1.73          {
    1.74 -            e -= modules_length;
    1.75 +            initial_images_end = e;
    1.76 +            e = (e - modules_length) & PAGE_MASK;
    1.77              initial_images_start = e;
    1.78 -            initial_images_end = initial_images_start + modules_length;
    1.79              move_memory(initial_images_start, 
    1.80                          mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
    1.81          }
    1.82 +
    1.83 +        if ( !kexec_crash_area.start && (s < e) &&
    1.84 +             ((e-s) >= kexec_crash_area.size) )
    1.85 +        {
    1.86 +            e = (e - kexec_crash_area.size) & PAGE_MASK;
    1.87 +            kexec_crash_area.start = e;
    1.88 +        }
    1.89      }
    1.90  
    1.91      if ( !initial_images_start )
    1.92 @@ -769,6 +782,26 @@ void __init __start_xen(unsigned long mb
    1.93      init_boot_pages(xenheap_phys_end, 16<<20); /* Initial seed: 4MB */
    1.94  #endif
    1.95  
    1.96 +    if ( kexec_crash_area.size != 0 )
    1.97 +    {
    1.98 +        unsigned long kdump_start = kexec_crash_area.start;
    1.99 +        unsigned long kdump_size  = kexec_crash_area.size;
   1.100 +
   1.101 +        kdump_size = (kdump_size + PAGE_SIZE - 1) & PAGE_MASK;
   1.102 +
   1.103 +        if ( !reserve_in_boot_e820(kdump_start, kdump_size) )
   1.104 +        {
   1.105 +            printk("Kdump: DISABLED (failed to reserve %luMB (%lukB) at 0x%lx)"
   1.106 +                   "\n", kdump_size >> 20, kdump_size >> 10, kdump_start);
   1.107 +            kexec_crash_area.start = kexec_crash_area.size = 0;
   1.108 +        }
   1.109 +        else
   1.110 +        {
   1.111 +            printk("Kdump: %luMB (%lukB) at 0x%lx\n",
   1.112 +                   kdump_size >> 20, kdump_size >> 10, kdump_start);
   1.113 +        }
   1.114 +    }
   1.115 +
   1.116      /*
   1.117       * With the boot allocator now seeded, we can walk every RAM region and
   1.118       * map it in its entirety (on x86/64, at least) and notify it to the
   1.119 @@ -797,51 +830,6 @@ void __init __start_xen(unsigned long mb
   1.120          init_boot_pages(s, e);
   1.121      }
   1.122  
   1.123 -    if ( (kexec_crash_area.size > 0) && (kexec_crash_area.start > 0) )
   1.124 -    {
   1.125 -        unsigned long kdump_start, kdump_size, k;
   1.126 -
   1.127 -        /* Mark images pages as free for now. */
   1.128 -        init_boot_pages(initial_images_start, initial_images_end);
   1.129 -
   1.130 -        kdump_start = kexec_crash_area.start;
   1.131 -        kdump_size = kexec_crash_area.size;
   1.132 -
   1.133 -        printk("Kdump: %luMB (%lukB) at 0x%lx\n",
   1.134 -               kdump_size >> 20,
   1.135 -               kdump_size >> 10,
   1.136 -               kdump_start);
   1.137 -
   1.138 -        if ( (kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK) )
   1.139 -            panic("Kdump parameters not page aligned\n");
   1.140 -
   1.141 -        kdump_start >>= PAGE_SHIFT;
   1.142 -        kdump_size >>= PAGE_SHIFT;
   1.143 -
   1.144 -        /* Allocate pages for Kdump memory area. */
   1.145 -        if ( !reserve_boot_pages(kdump_start, kdump_size) )
   1.146 -            panic("Unable to reserve Kdump memory\n");
   1.147 -
   1.148 -        /* Allocate pages for relocated initial images. */
   1.149 -        k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
   1.150 -        k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
   1.151 -
   1.152 -#if defined(CONFIG_X86_32)
   1.153 -        /* Must allocate within bootstrap 1:1 limits. */
   1.154 -        k = alloc_boot_low_pages(k, 1); /* 0x0 - BOOTSTRAP_DIRECTMAP_END */
   1.155 -#else
   1.156 -        k = alloc_boot_pages(k, 1);
   1.157 -#endif
   1.158 -        if ( k == 0 )
   1.159 -            panic("Unable to allocate initial images memory\n");
   1.160 -
   1.161 -        move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
   1.162 -
   1.163 -        initial_images_end -= initial_images_start;
   1.164 -        initial_images_start = k << PAGE_SHIFT;
   1.165 -        initial_images_end += initial_images_start;
   1.166 -    }
   1.167 -
   1.168      memguard_init();
   1.169  
   1.170      nr_pages = 0;