ia64/xen-unstable

changeset 6111:2f75dac09365

Fix handling of memory holes for Xen heap and domain 0
kernel image and ramdisk.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Aug 11 18:03:22 2005 +0000 (2005-08-11)
parents 9d0120a5aa45
children a5994e258f77 c589ca6d292b
files xen/arch/x86/setup.c xen/common/page_alloc.c
line diff
     1.1 --- a/xen/arch/x86/setup.c	Thu Aug 11 16:48:36 2005 +0000
     1.2 +++ b/xen/arch/x86/setup.c	Thu Aug 11 18:03:22 2005 +0000
     1.3 @@ -248,10 +248,11 @@ void __init __start_xen(multiboot_info_t
     1.4  {
     1.5      char *cmdline;
     1.6      module_t *mod = (module_t *)__va(mbi->mods_addr);
     1.7 -    unsigned long firsthole_start, nr_pages;
     1.8 +    unsigned long nr_pages, modules_length;
     1.9      unsigned long initial_images_start, initial_images_end;
    1.10      unsigned long _initrd_start = 0, _initrd_len = 0;
    1.11      unsigned int initrdidx = 1;
    1.12 +    physaddr_t s, e;
    1.13      struct e820entry e820_raw[E820MAX];
    1.14      int i, e820_raw_nr = 0, bytes = 0;
    1.15      struct ns16550_defaults ns16550 = {
    1.16 @@ -330,22 +331,31 @@ void __init __start_xen(multiboot_info_t
    1.17  
    1.18      max_page = init_e820(e820_raw, &e820_raw_nr);
    1.19  
    1.20 -    /* Find the first high-memory RAM hole. */
    1.21 -    for ( i = 0; i < e820.nr_map; i++ )
    1.22 -        if ( (e820.map[i].type == E820_RAM) &&
    1.23 -             (e820.map[i].addr >= 0x100000) )
    1.24 -            break;
    1.25 -    firsthole_start = e820.map[i].addr + e820.map[i].size;
    1.26 +    modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
    1.27  
    1.28 -    /* Relocate the Multiboot modules. */
    1.29 -    initial_images_start = xenheap_phys_end;
    1.30 -    initial_images_end   = initial_images_start + 
    1.31 -        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    1.32 -    if ( initial_images_end > firsthole_start )
    1.33 +    /* Find a large enough RAM extent to stash the DOM0 modules. */
    1.34 +    for ( i = 0; ; i++ )
    1.35      {
    1.36 -        printk("Not enough memory to stash the DOM0 kernel image.\n");
    1.37 -        for ( ; ; ) ;
    1.38 +        if ( (e820.map[i].type == E820_RAM) &&
    1.39 +             (e820.map[i].size >= modules_length) &&
    1.40 +             ((e820.map[i].addr + e820.map[i].size) >=
    1.41 +              (xenheap_phys_end + modules_length)) )
    1.42 +        {
    1.43 +            /* Stash as near as possible to the beginning of the RAM extent. */
    1.44 +            initial_images_start = e820.map[i].addr;
    1.45 +            if ( initial_images_start < xenheap_phys_end )
    1.46 +                initial_images_start = xenheap_phys_end;
    1.47 +            initial_images_end = initial_images_start + modules_length;
    1.48 +            break;
    1.49 +        }
    1.50 +
    1.51 +        if ( i == e820.nr_map )
    1.52 +        {
    1.53 +            printk("Not enough memory to stash the DOM0 kernel image.\n");
    1.54 +            for ( ; ; ) ;
    1.55 +        }
    1.56      }
    1.57 +
    1.58  #if defined(CONFIG_X86_32)
    1.59      memmove((void *)initial_images_start,  /* use low mapping */
    1.60              (void *)mod[0].mod_start,      /* use low mapping */
    1.61 @@ -358,16 +368,23 @@ void __init __start_xen(multiboot_info_t
    1.62  
    1.63      /* Initialise boot-time allocator with all RAM situated after modules. */
    1.64      xenheap_phys_start = init_boot_allocator(__pa(&_end));
    1.65 -    nr_pages   = 0;
    1.66 +    nr_pages = 0;
    1.67      for ( i = 0; i < e820.nr_map; i++ )
    1.68      {
    1.69          if ( e820.map[i].type != E820_RAM )
    1.70              continue;
    1.71 +
    1.72          nr_pages += e820.map[i].size >> PAGE_SHIFT;
    1.73 -        if ( (e820.map[i].addr + e820.map[i].size) >= initial_images_end )
    1.74 -            init_boot_pages((e820.map[i].addr < initial_images_end) ?
    1.75 -                            initial_images_end : e820.map[i].addr,
    1.76 -                            e820.map[i].addr + e820.map[i].size);
    1.77 +
    1.78 +        /* Initialise boot heap, skipping Xen heap and dom0 modules. */
    1.79 +        s = e820.map[i].addr;
    1.80 +        e = s + e820.map[i].size;
    1.81 +        if ( s < xenheap_phys_end )
    1.82 +            s = xenheap_phys_end;
    1.83 +        if ( (s < initial_images_end) && (e > initial_images_start) )
    1.84 +            s = initial_images_end;
    1.85 +        init_boot_pages(s, e);
    1.86 +
    1.87  #if defined (CONFIG_X86_64)
    1.88          /*
    1.89           * x86/64 maps all registered RAM. Points to note:
    1.90 @@ -404,10 +421,30 @@ void __init __start_xen(multiboot_info_t
    1.91  
    1.92      end_boot_allocator();
    1.93  
    1.94 -    init_xenheap_pages(xenheap_phys_start, xenheap_phys_end);
    1.95 -    printk("Xen heap: %luMB (%lukB)\n",
    1.96 -           (xenheap_phys_end-xenheap_phys_start) >> 20,
    1.97 -           (xenheap_phys_end-xenheap_phys_start) >> 10);
    1.98 +    /* Initialise the Xen heap, skipping RAM holes. */
    1.99 +    nr_pages = 0;
   1.100 +    for ( i = 0; i < e820.nr_map; i++ )
   1.101 +    {
   1.102 +        if ( e820.map[i].type != E820_RAM )
   1.103 +            continue;
   1.104 +
   1.105 +        s = e820.map[i].addr;
   1.106 +        e = s + e820.map[i].size;
   1.107 +        if ( s < xenheap_phys_start )
   1.108 +            s = xenheap_phys_start;
   1.109 +        if ( e > xenheap_phys_end )
   1.110 +            e = xenheap_phys_end;
   1.111 + 
   1.112 +        if ( s < e )
   1.113 +        {
   1.114 +            nr_pages += (e - s) >> PAGE_SHIFT;
   1.115 +            init_xenheap_pages(s, e);
   1.116 +        }
   1.117 +    }
   1.118 +
   1.119 +    printk("Xen heap: %luMB (%lukB)\n", 
   1.120 +           nr_pages >> (20 - PAGE_SHIFT),
   1.121 +           nr_pages << (PAGE_SHIFT - 10));
   1.122  
   1.123      early_boot = 0;
   1.124  
     2.1 --- a/xen/common/page_alloc.c	Thu Aug 11 16:48:36 2005 +0000
     2.2 +++ b/xen/common/page_alloc.c	Thu Aug 11 18:03:22 2005 +0000
     2.3 @@ -418,6 +418,8 @@ void init_xenheap_pages(physaddr_t ps, p
     2.4  
     2.5      ps = round_pgup(ps);
     2.6      pe = round_pgdown(pe);
     2.7 +    if ( pe <= ps )
     2.8 +        return;
     2.9  
    2.10      memguard_guard_range(phys_to_virt(ps), pe - ps);
    2.11  
    2.12 @@ -487,19 +489,25 @@ void init_domheap_pages(physaddr_t ps, p
    2.13  
    2.14      ps = round_pgup(ps) >> PAGE_SHIFT;
    2.15      pe = round_pgdown(pe) >> PAGE_SHIFT;
    2.16 +    if ( pe <= ps )
    2.17 +        return;
    2.18  
    2.19 -    if (ps < MAX_DMADOM_PFN && pe > MAX_DMADOM_PFN) {
    2.20 -        init_heap_pages(MEMZONE_DMADOM, pfn_to_page(ps), MAX_DMADOM_PFN - ps);
    2.21 -        init_heap_pages(MEMZONE_DOM, pfn_to_page(MAX_DMADOM_PFN),
    2.22 -                        pe - MAX_DMADOM_PFN);
    2.23 +    if ( (ps < MAX_DMADOM_PFN) && (pe > MAX_DMADOM_PFN) )
    2.24 +    {
    2.25 +        init_heap_pages(
    2.26 +            MEMZONE_DMADOM, pfn_to_page(ps), MAX_DMADOM_PFN - ps);
    2.27 +        init_heap_pages(
    2.28 +            MEMZONE_DOM, pfn_to_page(MAX_DMADOM_PFN), pe - MAX_DMADOM_PFN);
    2.29      }
    2.30      else
    2.31 +    {
    2.32          init_heap_pages(pfn_dom_zone_type(ps), pfn_to_page(ps), pe - ps);
    2.33 +    }
    2.34  }
    2.35  
    2.36  
    2.37 -struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order,
    2.38 -                                     unsigned int flags)
    2.39 +struct pfn_info *alloc_domheap_pages(
    2.40 +    struct domain *d, unsigned int order, unsigned int flags)
    2.41  {
    2.42      struct pfn_info *pg;
    2.43      cpumask_t mask;