direct-io.hg

changeset 15534:da4c76340184 tip

NativeDom 1:1 support for x86_64, 32bitbios reloc bug fix
author Guy Zana <guy@neocleus.com>
date Wed Sep 19 10:51:46 2007 +0200 (2007-09-19)
parents ef0a4a57523c
children
files tools/firmware/hvmloader/32bitbios_support.c tools/ioemu/vl.c tools/libxc/xc_hvm_build.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py xen/arch/x86/hvm/hvm.c xen/arch/x86/io_apic.c xen/arch/x86/mm/p2m.c xen/arch/x86/pt/mm_early.c xen/arch/x86/setup.c xen/common/memory.c xen/common/page_alloc.c xen/include/xen/mm_early.h
line diff
     1.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Wed Aug 29 12:50:02 2007 -0700
     1.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Wed Sep 19 10:51:46 2007 +0200
     1.3 @@ -76,7 +76,7 @@ static void relocate_32bitbios(char *elf
     1.4       */
     1.5      reloc_size = reloc_off;
     1.6      printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
     1.7 -    highbiosarea = (char *)(long)e820_malloc(reloc_size*20); /* Neocleus - ugly hack */
     1.8 +    highbiosarea = (char *)(long)e820_malloc(reloc_size);
     1.9      BUG_ON(highbiosarea == NULL);
    1.10      printf("  Relocating to 0x%x-0x%x ... ",
    1.11             (uint32_t)&highbiosarea[0],
     2.1 --- a/tools/ioemu/vl.c	Wed Aug 29 12:50:02 2007 -0700
     2.2 +++ b/tools/ioemu/vl.c	Wed Sep 19 10:51:46 2007 +0200
     2.3 @@ -7636,7 +7636,8 @@ int main(int argc, char **argv)
     2.4      {
     2.5          if ( !xc_is_nativedom_enabled(xc_handle) )
     2.6          {
     2.7 -            fprintf(logfile, "Error: NativeDom is not enabled. Use the enable_nativedom=1 boot parameter\n");
     2.8 +            fprintf(logfile, "Error: NativeDom is not enabled. "
     2.9 +                "Use the 'nativedom' boolean boot parameter\n");
    2.10              exit(1);
    2.11          }
    2.12  
     3.1 --- a/tools/libxc/xc_hvm_build.c	Wed Aug 29 12:50:02 2007 -0700
     3.2 +++ b/tools/libxc/xc_hvm_build.c	Wed Sep 19 10:51:46 2007 +0200
     3.3 @@ -208,6 +208,9 @@ static int setup_guest(int xc_handle,
     3.4      int rc;
     3.5      xen_capabilities_info_t caps;
     3.6  
     3.7 +    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IS_NATIVEDOM,
     3.8 +        is_nativedom); 
     3.9 +
    3.10      /* An HVM guest must be initialised with at least 2MB memory. */
    3.11      if ( memsize < 2 )
    3.12          goto error_out;
    3.13 @@ -285,7 +288,8 @@ static int setup_guest(int xc_handle,
    3.14      }
    3.15      else
    3.16      {
    3.17 -        rc = xc_domain_1to1_memory_populate_physmap(xc_handle, dom, nr_pages, 0, 0, &page_array[0x00]);
    3.18 +        rc = xc_domain_1to1_memory_populate_physmap(
    3.19 +            xc_handle, dom, nr_pages, 0, 0, &page_array[0x00]);
    3.20          if ( rc != 0 )
    3.21          {
    3.22              PERROR("NativeDom: Couldn't populate 1:1 mapping.\n");
    3.23 @@ -440,7 +444,8 @@ int xc_hvm_build(int xc_handle,
    3.24  
    3.25      if ( (is_nativedom)  && (!xc_is_nativedom_enabled(xc_handle)) )
    3.26      {
    3.27 -        ERROR("Couldn't start NativeDom since it's not enabled. Add enable_nativedom=1 as a boot parameter");
    3.28 +        ERROR("Couldn't start NativeDom since it's not enabled. Add "
    3.29 +            "nativedom=1 to Xen's boot parameters");
    3.30          return -1;
    3.31      }
    3.32      
     4.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Aug 29 12:50:02 2007 -0700
     4.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Sep 19 10:51:46 2007 +0200
     4.3 @@ -536,7 +536,8 @@ static PyObject *pyxc_hvm_build(XcObject
     4.4      int i;
     4.5  #endif
     4.6      char *image;
     4.7 -    int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1, is_nativedom = 0;
     4.8 +    int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1,
     4.9 +        is_nativedom = 0;
    4.10      unsigned long store_mfn;
    4.11  
    4.12      static char *kwd_list[] = { "domid", "store_evtchn",
    4.13 @@ -544,10 +545,12 @@ static PyObject *pyxc_hvm_build(XcObject
    4.14  				"apic", "nativedom", NULL };
    4.15      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiiii", kwd_list,
    4.16                                        &dom, &store_evtchn, &memsize,
    4.17 -                                      &image, &vcpus, &pae, &acpi, &apic, &is_nativedom) )
    4.18 +                                      &image, &vcpus, &pae, &acpi,
    4.19 +                                      &apic, &is_nativedom) )
    4.20          return NULL;
    4.21  
    4.22 -    if ( xc_hvm_build(self->xc_handle, dom, memsize, image, is_nativedom) != 0 )
    4.23 +    if ( xc_hvm_build(self->xc_handle, dom, memsize, image, 
    4.24 +                      is_nativedom) != 0 )
    4.25          return pyxc_error_to_exception();
    4.26  
    4.27  #if !defined(__ia64__)
    4.28 @@ -577,8 +580,6 @@ static PyObject *pyxc_hvm_build(XcObject
    4.29      xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
    4.30                       store_evtchn);
    4.31  
    4.32 -    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_IS_NATIVEDOM, is_nativedom);
    4.33 -
    4.34      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
    4.35  }
    4.36  
     5.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 29 12:50:02 2007 -0700
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Sep 19 10:51:46 2007 +0200
     5.3 @@ -1528,7 +1528,7 @@ class XendDomainInfo:
     5.4              maxmem = self.image.getRequiredAvailableMemory(
     5.5                  self.info['memory_static_max'] / 1024)
     5.6              shadow = self.image.getRequiredShadowMemory(
     5.7 -                self.info['shadow_memory'] / 1024,
     5.8 +                self.info['shadow_memory'] * 1024,
     5.9                  self.info['memory_static_max'] / 1024)
    5.10  
    5.11              log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],)
     6.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Aug 29 12:50:02 2007 -0700
     6.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Sep 19 10:51:46 2007 +0200
     6.3 @@ -1122,12 +1122,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
     6.4          unsigned long mfn;
     6.5          void *p;
     6.6  
     6.7 -        if ( !opt_nativedom ) 
     6.8 +        if ( !opt_nativedom )
     6.9              return -EFAULT;
    6.10 -
    6.11          if ( copy_from_guest(&a, arg, 1) )
    6.12              return -EFAULT;
    6.13 -            
    6.14          if ( IS_PRIV(current->domain) ) 
    6.15          {
    6.16              d = get_domain_by_id(a.domid);
    6.17 @@ -1152,18 +1150,19 @@ long do_hvm_op(unsigned long op, XEN_GUE
    6.18          }
    6.19  
    6.20          /* Copy e820 map */
    6.21 -        gdprintk(XENLOG_INFO, "Writing NativeDom E820...\n");
    6.22 -        *(unsigned char *)(p + HVM_E820_NR_OFFSET) = (unsigned char) e820_nativedom.nr_map;
    6.23 -        memcpy(p + HVM_E820_OFFSET,  (void*)&e820_nativedom.map[0],  
    6.24 +        *(unsigned char *)(p + HVM_E820_NR_OFFSET) = 
    6.25 +            (unsigned char) e820_nativedom.nr_map;
    6.26 +        memcpy(p + HVM_E820_OFFSET,  (void*)&e820_nativedom.map[0],
    6.27              sizeof(struct e820entry) * e820_nativedom.nr_map);
    6.28 -
    6.29 +        
    6.30          unmap_domain_page_global(p);
    6.31          rc = 0;
    6.32  
    6.33  copy_nativedom_e820_end:
    6.34          rcu_unlock_domain(d);
    6.35 +        gdprintk(XENLOG_INFO, "NativeDom E820's successfuly written!\n");
    6.36          break;
    6.37 -    }        
    6.38 +    }
    6.39  
    6.40      default:
    6.41      {
     7.1 --- a/xen/arch/x86/io_apic.c	Wed Aug 29 12:50:02 2007 -0700
     7.2 +++ b/xen/arch/x86/io_apic.c	Wed Sep 19 10:51:46 2007 +0200
     7.3 @@ -2289,7 +2289,10 @@ void dump_ioapic_irq_info(void)
     7.4      }
     7.5  }
     7.6  
     7.7 -/* Pass-through level-triggered interrupts */
     7.8 +/*
     7.9 +    Pass-through level-triggered interrupts,
    7.10 +    - switching polarity idea by Guy Zana.
    7.11 +*/
    7.12  static void change_vector_polarity(unsigned int irq)
    7.13  {
    7.14      short apic, pin;
     8.1 --- a/xen/arch/x86/mm/p2m.c	Wed Aug 29 12:50:02 2007 -0700
     8.2 +++ b/xen/arch/x86/mm/p2m.c	Wed Sep 19 10:51:46 2007 +0200
     8.3 @@ -744,7 +744,8 @@ guest_physmap_add_page(struct domain *d,
     8.4          }
     8.5      }
     8.6  
     8.7 -    set_p2m_entry(d, gfn, _mfn(mfn), __PAGE_HYPERVISOR|_PAGE_USER);
     8.8 +    if ( !set_p2m_entry(d, gfn, _mfn(mfn), __PAGE_HYPERVISOR|_PAGE_USER) )
     8.9 +        P2M_ERROR("Unable to set p2m entry %08lx->%08lx\n", gfn, mfn);
    8.10      set_gpfn_from_mfn(mfn, gfn);
    8.11  
    8.12      audit_p2m(d);
     9.1 --- a/xen/arch/x86/pt/mm_early.c	Wed Aug 29 12:50:02 2007 -0700
     9.2 +++ b/xen/arch/x86/pt/mm_early.c	Wed Sep 19 10:51:46 2007 +0200
     9.3 @@ -12,15 +12,16 @@ extern struct e820map e820;
     9.4  uint64_t dup_addr_base;
     9.5  uint64_t total_dup_size;
     9.6  
     9.7 +extern unsigned int opt_nativedom_mem;
     9.8  extern unsigned long max_page_nativedom;
     9.9  extern unsigned long max_page;
    9.10  extern unsigned long max_dma_mfn;
    9.11  extern void print_e820_memory_map(struct e820entry *map, int entries);
    9.12  
    9.13  int __init nd_duplicate_e820_entry(struct e820map * a_e820, 
    9.14 -                                       uint32_t index, uint32_t dups_nr)
    9.15 +                                   int index, int dups_nr)
    9.16  {
    9.17 -    uint32_t j;
    9.18 +    int j;
    9.19  
    9.20      if ( 0 == dups_nr )
    9.21          return -1;
    9.22 @@ -32,7 +33,8 @@ int __init nd_duplicate_e820_entry(struc
    9.23          return -1; 
    9.24      } 
    9.25  
    9.26 -    for (j=(a_e820->nr_map+dups_nr-1); j > index; j--)
    9.27 +    /* Make space for additional chunks */
    9.28 +    for ( j = (a_e820->nr_map+dups_nr-1); j > index; j-- )
    9.29      {
    9.30          memcpy(&a_e820->map[j], &a_e820->map[max((j-dups_nr), index)],
    9.31              sizeof(a_e820->map[0]));
    9.32 @@ -43,88 +45,113 @@ int __init nd_duplicate_e820_entry(struc
    9.33      return 0;
    9.34  }
    9.35  
    9.36 -
    9.37 -int __init nd_alloc_domdma(void)
    9.38 +int __init nd_del_e820_entry(struct e820map * a_e820, uint32_t pos)
    9.39  {
    9.40 -    int i, rc;
    9.41 -    uint64_t pe=0, ps=0, fe=0, fs=0, len=0;
    9.42 -    unsigned long max_dma_addr = (max_dma_mfn << PAGE_SHIFT);
    9.43 +    int i=0;
    9.44  
    9.45 -    /*
    9.46 -        Find or create an extent of size equal to MM_DMADOM_FOR_XEN.
    9.47 -        The extent address must be above 16MB, because NativeDom 
    9.48 -        Will have to use the upper 4MB of the lowest 16MB. 
    9.49 -        The memory between 0 to 12MB will be marked as reserved for NativeDom.
    9.50 -    */
    9.51 -    for (i=0; i<e820.nr_map; i++)
    9.52 +    if ( a_e820->nr_map == 0 )
    9.53 +        return -1;
    9.54 +        
    9.55 +    a_e820->nr_map--;
    9.56 +    for ( i = pos; i < a_e820->nr_map; i++ )
    9.57 +        memcpy(&a_e820->map[i], &a_e820->map[i+1], sizeof(struct e820entry));
    9.58 +
    9.59 +    memset(&a_e820->map[i], 0, sizeof(struct e820entry));
    9.60 +    return 0;
    9.61 +}
    9.62 +
    9.63 +/* 
    9.64 +    Punch a chunk in the given e820 table, at the specified place,
    9.65 +    An assumption that this function does is that the new chunk fits
    9.66 +    inside an existing chunk (exactly or smaller) and might not be 
    9.67 +    spreaded across several existing chunks.
    9.68 +*/
    9.69 +int __init nd_punch_e820_entry(struct e820map * a_e820, 
    9.70 +                               uint64_t a_address, 
    9.71 +                               uint64_t a_size, 
    9.72 +                               uint32_t type)
    9.73 +{
    9.74 +    int i;
    9.75 +    int rc;
    9.76 +    u64 ps=0, pe=0;
    9.77 +    u64 s = a_address;
    9.78 +    u64 e = a_address + a_size;
    9.79 +
    9.80 +    /* Find the container chunk */
    9.81 +    for ( i = 0; i < a_e820->nr_map; i++ )
    9.82      {
    9.83 -        ps = e820.map[i].addr;
    9.84 -        pe = e820.map[i].addr + e820.map[i].size;
    9.85 -        fe = min_t(u64, pe, max_dma_addr);
    9.86 -        fs = max_t(u64, ps, MM_16MB);
    9.87 -        len = e820.map[i].size;	
    9.88 -
    9.89 -        /* Minimum requirements */
    9.90 -        if ( (e820.map[i].type == E820_1TO1) &&
    9.91 -             ((fe-fs) >= MM_DMADOM_FOR_XEN) ) 
    9.92 +        ps = a_e820->map[i].addr;
    9.93 +        pe = a_e820->map[i].addr + a_e820->map[i].size;
    9.94 +        if ( (ps <= s) && (pe >= e) )
    9.95              break;
    9.96      }
    9.97  
    9.98 -    if ( i == e820.nr_map )
    9.99 -    {
   9.100 -        printk("Couldn't allocate memory for MEMZONE_DMADOM of size = %lu\n", 
   9.101 -            (unsigned long)MM_DMADOM_FOR_XEN);
   9.102 +    if ( i == a_e820->nr_map )
   9.103          return -1;
   9.104 -    }
   9.105  
   9.106 -    if ( fe == pe ) 
   9.107 +    /* There are 4 cases */
   9.108 +    if ( (ps == s) && (pe == e) )
   9.109 +        a_e820->map[i].type = type;
   9.110 +    else if ( (ps == s) && (pe > e) )
   9.111      {
   9.112 -        if (len == MM_DMADOM_FOR_XEN)
   9.113 -            e820.map[i].type = E820_RAM;
   9.114 -        else 
   9.115 -        {
   9.116 -            /* Split region, second part is RAM */
   9.117 -            rc = nd_duplicate_e820_entry(&e820, i, 1);
   9.118 -            if ( rc < 0 )
   9.119 -                return -1;
   9.120 +        /* Split to two, new chunk is the first */
   9.121 +        rc = nd_duplicate_e820_entry(a_e820, i, 1);
   9.122 +        if ( rc < 0 )
   9.123 +            return -1;
   9.124 +            
   9.125 +        a_e820->map[i].type = type;
   9.126 +        a_e820->map[i].size = a_size;
   9.127 +        a_e820->map[i+1].size -= a_size;
   9.128 +        a_e820->map[i+1].addr += a_size;
   9.129 +    }
   9.130 +    else if ( (ps < s) && (pe == e) )
   9.131 +    {
   9.132 +        /* Split to two, new chunk is the second */
   9.133 +        rc = nd_duplicate_e820_entry(a_e820, i, 1);
   9.134 +        if ( rc < 0 )
   9.135 +            return -1;
   9.136  
   9.137 -            e820.map[i].size -= MM_DMADOM_FOR_XEN;
   9.138 -            e820.map[i+1].type = E820_RAM;
   9.139 -            e820.map[i+1].size = MM_DMADOM_FOR_XEN;
   9.140 -            e820.map[i+1].addr = e820.map[i].addr + e820.map[i].size;
   9.141 -        }
   9.142 +        a_e820->map[i].size -= a_size;
   9.143 +        a_e820->map[i+1].type = type;
   9.144 +        a_e820->map[i+1].size = a_size;
   9.145 +        a_e820->map[i+1].addr = a_e820->map[i].addr + a_e820->map[i].size;
   9.146 +    }
   9.147 +    else
   9.148 +    {
   9.149 +        /* Split to three, new chunk is in the middle */
   9.150 +        rc = nd_duplicate_e820_entry(a_e820, i, 2);
   9.151 +        if ( rc < 0 )
   9.152 +            return -1;
   9.153 +
   9.154 +        a_e820->map[i].size = a_address - ps;
   9.155 +        a_e820->map[i+1].type = type;
   9.156 +        a_e820->map[i+1].size = a_size;
   9.157 +        a_e820->map[i+1].addr = a_address;
   9.158 +        a_e820->map[i+2].addr = a_address + a_size;
   9.159 +        a_e820->map[i+2].size -= (a_e820->map[i].size + a_e820->map[i+1].size);
   9.160      } 
   9.161 -    else /* pe > max_dma_addr */
   9.162 +
   9.163 +    return 0;
   9.164 +}
   9.165 +
   9.166 +void __init merge_e820(struct e820map * a_e820)
   9.167 +{
   9.168 +    int i;
   9.169 +
   9.170 +    for ( i=0; i< a_e820->nr_map-1; i++ )
   9.171      {
   9.172 -        if ( fs > ps ) /* ps < 16MB */
   9.173 -        { 
   9.174 -            /* Split to 3 parts. RAM is in the middle */
   9.175 -            rc = nd_duplicate_e820_entry(&e820, i, 2);
   9.176 -            if ( rc < 0 )
   9.177 -                return -1;
   9.178 -                
   9.179 -            e820.map[i].size = MM_16MB - ps;
   9.180 -            e820.map[i+1].type = E820_RAM;
   9.181 -            e820.map[i+1].size = MM_DMADOM_FOR_XEN;
   9.182 -            e820.map[i+1].addr = MM_16MB;
   9.183 -            e820.map[i+2].addr = MM_16MB + MM_DMADOM_FOR_XEN;
   9.184 -            e820.map[i+2].size -= MM_DMADOM_FOR_XEN + MM_16MB - ps;	
   9.185 -        } 
   9.186 -        else /* ps == 16MB*/
   9.187 +        /* Matching chunks? */
   9.188 +        if ( (a_e820->map[i].type == a_e820->map[i+1].type) &&
   9.189 +             (a_e820->map[i].addr + a_e820->map[i].size ==  a_e820->map[i+1].addr) )
   9.190          {
   9.191 -            /* Split region, first part is RAM */
   9.192 -            rc = nd_duplicate_e820_entry(&e820, i, 1);
   9.193 -            if ( rc < 0 )
   9.194 -                return -1;
   9.195 +            /* Merge */
   9.196 +            a_e820->map[i].size += a_e820->map[i+1].size;
   9.197 +            nd_del_e820_entry(a_e820, i+1);
   9.198  
   9.199 -            e820.map[i].type = E820_RAM;
   9.200 -            e820.map[i].size = MM_DMADOM_FOR_XEN;
   9.201 -            e820.map[i+1].size -= MM_DMADOM_FOR_XEN;
   9.202 -            e820.map[i+1].addr += MM_DMADOM_FOR_XEN;
   9.203 +            /* Check again */
   9.204 +            i--;
   9.205          }
   9.206      }
   9.207 -
   9.208 -    return 0;
   9.209  }
   9.210  
   9.211  int __init nd_alloc_xen_portion(void)
   9.212 @@ -144,20 +171,27 @@ int __init nd_alloc_xen_portion(void)
   9.213          }
   9.214      }
   9.215  
   9.216 -    /* Allocate a portion for memzone xen heap */
   9.217 -    xen_portion = (avail_ram / 100) *  MM_XEN_PORTION_OF_RAM;
   9.218 +    /* Validate RAM size, no more than 2GB, at least 384 MB for XEN */
   9.219 +    if ( (opt_nativedom_mem < MM_ND_MIN_SIZE) ||
   9.220 +         (opt_nativedom_mem > MM_ND_MAX_SIZE) ||
   9.221 +         ((avail_ram >> 20) - opt_nativedom_mem) < MM_XEN_MIN_SIZE )
   9.222 +    {
   9.223 +        printk("NativeDom: The 'nativedom_mem' boot parameter should be "
   9.224 +            "specified correctly: NativeDomain mem size must be between %dMB "
   9.225 +            "to %dMB, and Xen must be left with at least %dMB.\n",
   9.226 +            MM_ND_MIN_SIZE, MM_ND_MAX_SIZE, MM_XEN_MIN_SIZE);
   9.227 +        return -1;
   9.228 +    }
   9.229 +
   9.230 +    /* Compute the size of memory that handed  to Xen */
   9.231 +    xen_portion = avail_ram - (opt_nativedom_mem << 20);
   9.232      xen_portion = (xen_portion+PAGE_SIZE-1)&PAGE_MASK;
   9.233 -    if ( xen_portion < (MM_XEN_PORTION_OF_RAM_MINIMUM_MB<<20) )
   9.234 -        xen_portion = (MM_XEN_PORTION_OF_RAM_MINIMUM_MB<<20);
   9.235 -
   9.236 -    if ( xen_portion > (MM_XEN_PORTION_OF_RAM_MAXIMUM_MB<<20) )
   9.237 -        xen_portion = (MM_XEN_PORTION_OF_RAM_MAXIMUM_MB<<20);
   9.238  
   9.239      printk("NativeDom: Machine Available RAM: %" PRId64 "\n", avail_ram);
   9.240      printk("NativeDom: RAM Available for Xen: %" PRId64 "\n", xen_portion);
   9.241  
   9.242      /* Walk the e820 table (top down) and allocate portions for Xen */
   9.243 -    for (i=(e820.nr_map-1); i >= 0 , xen_portion > 0; i--)
   9.244 +    for ( i=(e820.nr_map-1); i >= 0 , xen_portion > 0; i--)
   9.245      {
   9.246          if ( e820.map[i].type != E820_1TO1 )
   9.247              continue;
   9.248 @@ -183,7 +217,6 @@ int __init nd_alloc_xen_portion(void)
   9.249              e820.map[i].type = E820_RAM;
   9.250              xen_portion -= e820.map[i].size;
   9.251          }
   9.252 -
   9.253      }
   9.254  
   9.255      /* Check for errors */
   9.256 @@ -243,19 +276,47 @@ int __init nd_alloc_xenheap(void)
   9.257      return 0;
   9.258  }
   9.259  
   9.260 +/* Align to a super page */
   9.261 +int __init nd_e820_align(void)
   9.262 +{
   9.263 +    int i;
   9.264 +    uint32_t size = (1UL << L2_PAGETABLE_SHIFT);
   9.265 +    uint32_t mask = ~(size-1);
   9.266 +    uint64_t pe;
   9.267 +
   9.268 +    /* Find the first 1TO1 chunk and align it downward */
   9.269 +    for ( i=e820.nr_map-1; i >= 0, e820.map[i].type != E820_1TO1; i-- );
   9.270 +    if ( i < 0 )
   9.271 +        return -1;
   9.272 +
   9.273 +    pe = e820.map[i].addr + e820.map[i].size;
   9.274 +
   9.275 +    /* Can't handle */
   9.276 +    if ( (e820.map[i].size < size) ||
   9.277 +         ((i != e820.nr_map-1) && (pe != e820.map[i+1].addr)) )
   9.278 +        return -1;
   9.279 +
   9.280 +    e820.map[i].size &= mask;
   9.281 +
   9.282 +    if ( i != e820.nr_map-1 )
   9.283 +    {
   9.284 +        e820.map[i+1].addr = e820.map[i].size + e820.map[i].addr;
   9.285 +        e820.map[i+1].size += (pe - e820.map[i+1].addr);
   9.286 +    }
   9.287 +    return 0;
   9.288 +}
   9.289 +
   9.290  int __init nd_remap_areas(void)
   9.291  {
   9.292      int i;
   9.293  
   9.294      /* Init globals */
   9.295      dup_addr_base = 0;
   9.296 -    total_dup_size = MM_12MB;
   9.297 +    total_dup_size = MM_DUP_SIZE;
   9.298      nd_areas.dups.nr = 0;
   9.299 -
   9.300 +    
   9.301      /*
   9.302 -        Find enough E820_1TO1 available memory *ABOVE* MM_16MB for all of the
   9.303 -        duplicated areas, we must ensure that NativeDom will have enough memory
   9.304 -        below the MM_16MB for ISA/EISA DMA usage (if it'll be supported in the future).
   9.305 +        Find enough E820_1TO1 available memory *ABOVE* MM_16MB.
   9.306      */
   9.307      for (i=0; i < e820.nr_map; ++i)
   9.308      {
   9.309 @@ -271,7 +332,7 @@ int __init nd_remap_areas(void)
   9.310          break;
   9.311      }
   9.312  
   9.313 -    /* check for errors */
   9.314 +    /* Check for errors */
   9.315      if ( 0 == dup_addr_base )
   9.316      {
   9.317          printk("nd_remap_areas: couldn't find a contiguous chunk to store duplicated regions in the e820 table\n");
   9.318 @@ -280,17 +341,17 @@ int __init nd_remap_areas(void)
   9.319  
   9.320      printk("NativeDom: Remapped region address: 0x%016" PRIx64 "\n", dup_addr_base);
   9.321  
   9.322 -    /* First 12MB of memory */
   9.323      nd_areas.dups.nr++;
   9.324 -    nd_areas.dups.areas[0].real_addr = 0;
   9.325 +    nd_areas.dups.areas[0].real_addr = MM_DUP_ADDR;
   9.326      nd_areas.dups.areas[0].duplicated_addr = dup_addr_base;
   9.327 -    nd_areas.dups.areas[0].size = MM_12MB;
   9.328 +    nd_areas.dups.areas[0].size = MM_DUP_SIZE;
   9.329      nd_areas.dups.areas[0].is_duplicated = 0;
   9.330  
   9.331      return 0;
   9.332  } 
   9.333  
   9.334  
   9.335 +
   9.336  int __init nd_init_mmio_areas(void) 
   9.337  {
   9.338      nd_areas.mmio.areas[0].addr = 0xA0000;
   9.339 @@ -321,93 +382,20 @@ uint32_t __init nd_get_last_ram_pfn(stru
   9.340  
   9.341      return max_pfn;
   9.342  } /* end of nd_get_last_ram_pfn */
   9.343 -
   9.344 -/* 
   9.345 -    Moves through the e820 table and adds a chunk in the specified,
   9.346 -    An assumption that this function does is that the new chunk fits
   9.347 -    inside an existing chunk (exactly or smaller) and might not be 
   9.348 -    spreaded across several existing chunks.
   9.349 -*/
   9.350 -int __init 
   9.351 -nd_insert_e820_chunk(struct e820map * a_e820, 
   9.352 -                     uint64_t a_address, 
   9.353 -                     uint64_t a_size, 
   9.354 -                     uint32_t type)
   9.355 -{
   9.356 -    unsigned long i;
   9.357 -    int rc;
   9.358 -    u64 ps, pe;
   9.359 -    u64 s = a_address;
   9.360 -    u64 e = a_address + a_size;
   9.361 -
   9.362 -    /* Find the container chunk */
   9.363 -    for (i=0; i<a_e820->nr_map; i++)
   9.364 -    {
   9.365 -        ps = a_e820->map[i].addr;
   9.366 -        pe = a_e820->map[i].addr + a_e820->map[i].size;
   9.367 -        if ( (ps <= s) && (pe >= e) )
   9.368 -            break;
   9.369 -    }
   9.370 -
   9.371 -    if ( i == a_e820->nr_map )
   9.372 -        return -1;
   9.373 -
   9.374 -    /* There are 4 cases */
   9.375 -    if ( (ps == s) && (pe == e) )
   9.376 -        a_e820->map[i].type = type;
   9.377 -    else if ( (ps == s) && (pe > e) )
   9.378 -    {
   9.379 -        /* Split to two, new chunk is the first */
   9.380 -        rc = nd_duplicate_e820_entry(a_e820, i, 1);
   9.381 -        if ( rc < 0 )
   9.382 -            return -1;
   9.383 -            
   9.384 -        a_e820->map[i].type = type;
   9.385 -        a_e820->map[i].size = a_size;
   9.386 -        a_e820->map[i+1].size -= a_size;
   9.387 -        a_e820->map[i+1].addr += a_size;
   9.388 -    }
   9.389 -    else if ( (ps < s) && (pe == e) )
   9.390 -    {
   9.391 -        /* Split to two, new chunk is the second */
   9.392 -        rc = nd_duplicate_e820_entry(a_e820, i, 1);
   9.393 -        if ( rc < 0 )
   9.394 -            return -1;
   9.395 -
   9.396 -        a_e820->map[i].size -= a_size;
   9.397 -        a_e820->map[i+1].type = type;
   9.398 -        a_e820->map[i+1].size = a_size;
   9.399 -        a_e820->map[i+1].addr = a_e820->map[i].addr + a_e820->map[i].size;
   9.400 -    }
   9.401 -    else
   9.402 -    {
   9.403 -        /* Split to three, new chunk is in the middle */
   9.404 -        rc = nd_duplicate_e820_entry(a_e820, i, 2);
   9.405 -        if ( rc < 0 )
   9.406 -            return -1;
   9.407 -
   9.408 -        a_e820->map[i].size = a_address - ps;
   9.409 -        a_e820->map[i+1].type = type;
   9.410 -        a_e820->map[i+1].size = a_size;
   9.411 -        a_e820->map[i+1].addr = a_address;
   9.412 -        a_e820->map[i+2].addr = a_address + a_size;
   9.413 -        a_e820->map[i+2].size -= (a_e820->map[i].size + a_e820->map[i+1].size);
   9.414 -    } 
   9.415 -
   9.416 -    return 0;
   9.417 -}
   9.418  	
   9.419  int __init nd_build_nativedom_e820(void)
   9.420  {
   9.421      int rc,i;
   9.422 +    int last_idx;
   9.423 +    uint64_t last_addr;
   9.424  
   9.425      printk("NativeDom: Building e820 map for NativeDom...\n");
   9.426      memset((void *)&e820_nativedom, 0, sizeof(struct e820map));
   9.427      memcpy((void *)&e820_nativedom, (void *)&e820, sizeof(struct e820map));
   9.428  
   9.429 -    for (i=0; i<e820_nativedom.nr_map; i++)
   9.430 +    for ( i=0; i<e820_nativedom.nr_map; i++ )
   9.431      {
   9.432 -        if (e820_nativedom.map[i].addr < 0xc00000)
   9.433 +        if ( e820_nativedom.map[i].addr < MM_DUP_SIZE )
   9.434              continue;
   9.435  
   9.436          switch (e820_nativedom.map[i].type) 
   9.437 @@ -421,10 +409,10 @@ int __init nd_build_nativedom_e820(void)
   9.438          }
   9.439      }
   9.440  
   9.441 -    /* Duplicated area are marked as reserved */
   9.442 -    for (i=0; i < nd_areas.dups.nr; i++)
   9.443 +    /* Duplicated area (machine addresses) are marked as reserved */
   9.444 +    for ( i=0; i < nd_areas.dups.nr; i++ )
   9.445      {
   9.446 -        rc = nd_insert_e820_chunk(&e820_nativedom, 
   9.447 +        rc = nd_punch_e820_entry(&e820_nativedom, 
   9.448                      nd_areas.dups.areas[i].duplicated_addr,
   9.449                      nd_areas.dups.areas[i].size,
   9.450                      E820_RESERVED);
   9.451 @@ -436,13 +424,82 @@ int __init nd_build_nativedom_e820(void)
   9.452          }
   9.453      }
   9.454  
   9.455 -    /* The hybrid e820 should end with a RAM extent */
   9.456 -    for (i=e820_nativedom.nr_map-1; e820_nativedom.map[i].type != E820_RAM; i--)
   9.457 +#if defined(CONFIG_X86_64)
   9.458 +
   9.459 +    /* Assure that 0-512KB are usable */
   9.460 +    if ( (e820.map[0].type != E820_1TO1) ||
   9.461 +         (e820.map[0].addr != 0) ||
   9.462 +         (e820.map[0].size < MM_512KB) )
   9.463 +    {
   9.464 +        printk("Error: 0-512KB is not usable!\n");
   9.465 +        return -1;
   9.466 +    }
   9.467 +    
   9.468 +    /* 
   9.469 +        Mark 512KB-1MB as reserved: remove all regions below 1MB 
   9.470 +        and add a new reserved one.
   9.471 +    */
   9.472 +    for ( i=0; i < e820_nativedom.nr_map; i++ )
   9.473 +    {
   9.474 +        uint64_t ps = e820_nativedom.map[i].addr;
   9.475 +        uint64_t pe = e820_nativedom.map[i].addr + e820_nativedom.map[i].size;
   9.476 +        
   9.477 +        if ( ps < MM_1MB )
   9.478 +        {
   9.479 +            /* Crossing chunk? there could be only a single one */
   9.480 +            if ( pe > MM_1MB )
   9.481 +            {
   9.482 +                e820_nativedom.map[i].size -= (MM_1MB - ps);
   9.483 +                e820_nativedom.map[i].addr = MM_1MB;
   9.484 +            }
   9.485 +            else 
   9.486 +            {
   9.487 +                nd_del_e820_entry(&e820_nativedom, i);
   9.488 +                /* Check again */
   9.489 +                i--;
   9.490 +            }
   9.491 +        }
   9.492 +    }
   9.493 +    
   9.494 +    /* Add two new chunks (0-512KB, 512-1MB) */
   9.495 +    nd_duplicate_e820_entry(&e820_nativedom, 0, 2);
   9.496 +    e820_nativedom.map[0].addr = 0;
   9.497 +    e820_nativedom.map[0].size = 0x80000;
   9.498 +    e820_nativedom.map[0].type = E820_RAM;
   9.499 +    e820_nativedom.map[1].addr = 0x80000;
   9.500 +    e820_nativedom.map[1].size = 0x80000;
   9.501 +    e820_nativedom.map[1].type = E820_RESERVED;
   9.502 +    
   9.503 +    /* Make the Xen seed area reserved */
   9.504 +    rc = nd_punch_e820_entry(&e820_nativedom, 
   9.505 +                (uint64_t)MM_12MB,
   9.506 +                (uint64_t)MM_4MB,
   9.507 +                E820_RESERVED);    
   9.508 +
   9.509 +    if ( rc < 0 )
   9.510 +    {
   9.511 +        printk("Error: Couldn't mark all duplicated areas as reserved for NativeDom\n");
   9.512 +        return -1;
   9.513 +    }
   9.514 +    
   9.515 +#endif
   9.516 +
   9.517 +    /* NativeDom's e820 should end with a RAM extent */
   9.518 +    for ( i=e820_nativedom.nr_map-1; e820_nativedom.map[i].type != E820_RAM; i-- )
   9.519      {
   9.520          memset(&e820_nativedom.map[i], 0, sizeof(struct e820entry));
   9.521          e820_nativedom.nr_map--;
   9.522      }
   9.523  
   9.524 +    /* Explicitly reserve space for special pages (ioreq and xenstore). */
   9.525 +    last_idx = e820_nativedom.nr_map-1;
   9.526 +    last_addr = e820_nativedom.map[last_idx].addr + e820_nativedom.map[last_idx].size;
   9.527 +    rc = nd_punch_e820_entry(&e820_nativedom, 
   9.528 +                last_addr -PAGE_SIZE * MM_NR_SPECIAL_PAGES,
   9.529 +                (uint64_t)(PAGE_SIZE * MM_NR_SPECIAL_PAGES),
   9.530 +                E820_RESERVED);      
   9.531 +
   9.532 +    merge_e820(&e820_nativedom);
   9.533      printk("NativeDom: NativeDom's E820 Memory Map:\n");
   9.534      print_e820_memory_map(e820_nativedom.map, e820_nativedom.nr_map);
   9.535  
   9.536 @@ -469,7 +526,7 @@ int  __init nd_init_protected_areas(void
   9.537      int rc,i;
   9.538  
   9.539      /* All usable (RAM) areas of dom0 are protected for NativeDom */
   9.540 -    for (i=0; i<e820.nr_map; i++)
   9.541 +    for ( i=0; i<e820.nr_map; i++ )
   9.542      {
   9.543          if ( (e820.map[i].type == E820_RAM) &&
   9.544               (e820.map[i].addr >= MM_16MB) )
   9.545 @@ -495,37 +552,26 @@ int  __init nd_init_protected_areas(void
   9.546      printk("NativeDom: Protected Area: %016" PRIx64 " - %016" PRIx64 " (remapped)\n", 
   9.547          dup_addr_base, dup_addr_base+total_dup_size);
   9.548  
   9.549 -    return 0;
   9.550 -}
   9.551 -
   9.552 -void __init merge_e820(void)
   9.553 -{
   9.554 -    int i,j;
   9.555 +#if defined(CONFIG_X86_64)
   9.556 +    /* Initial Xen's seed */
   9.557 +    rc = nd_add_protected_area(MM_12MB, MM_4MB);
   9.558 +    if ( rc < 0 ) {
   9.559 +        printk("Error: maximum protected areas reached!\n");
   9.560 +        return -1;
   9.561 +    }
   9.562  
   9.563 -    for ( i=0; i< e820.nr_map-1; i++ )
   9.564 -    {
   9.565 -        /* Matching chunks? */
   9.566 -        if ( (e820.map[i].type == e820.map[i+1].type) &&
   9.567 -             (e820.map[i].addr + e820.map[i].size ==  e820.map[i+1].addr) )
   9.568 -        {
   9.569 -            /* Merge */
   9.570 -            e820.map[i].size += e820.map[i+1].size;
   9.571 -            e820.nr_map--;
   9.572 -            for ( j=i+1; j < e820.nr_map; j++ )
   9.573 -                memcpy(&e820.map[j], &e820.map[j+1], sizeof(struct e820entry));
   9.574 +    printk("NativeDom: Protected Area: %016" PRIx64 " - %016" PRIx64 " (xen seed)\n", 
   9.575 +        (uint64_t)MM_12MB, (uint64_t)MM_16MB);
   9.576 +#endif
   9.577  
   9.578 -            /* Check again */
   9.579 -            i--;
   9.580 -        }
   9.581 -    }
   9.582 +    return 0;
   9.583  }
   9.584  
   9.585  int __init nd_setup_e820(void)
   9.586  {
   9.587 +    int rc;
   9.588  
   9.589 -    unsigned rc;
   9.590 -
   9.591 -    /* Portion of memory goes for Xen */
   9.592 +    /* Portion of memory that goes for Xen */
   9.593      rc = nd_alloc_xen_portion();
   9.594      if ( rc < 0 ) 
   9.595      {
   9.596 @@ -533,30 +579,22 @@ int __init nd_setup_e820(void)
   9.597          return -1;
   9.598      }
   9.599  
   9.600 -    /* First 12MB are allocated to xenheap, this is going to be changed when 
   9.601 -       xen will be relocated up to high memory */
   9.602 +#if defined(CONFIG_X86_32)
   9.603 +    /* First 12MB belongs to xenheap, and marked as resered for NativeDom */
   9.604      rc = nd_alloc_xenheap();
   9.605      if ( rc < 0 ) 
   9.606      {
   9.607          printk("Error: Unabled to allocate enough xenheap space in e820\n");
   9.608          return -1;
   9.609      }
   9.610 +#endif
   9.611  
   9.612 -    /* 
   9.613 -        Allocate another chunk for DMADOM.
   9.614 -        We are going to give Xen a portion from that region, 
   9.615 -        but not below the 16MB border (order of 24 bits).
   9.616 -    */
   9.617 -    rc = nd_alloc_domdma();
   9.618 -    if ( rc < 0 ) 
   9.619 -    {
   9.620 -        printk("Error: Unabled to allocate a DMADOM-region chunk in e820\n");
   9.621 +    merge_e820(&e820);
   9.622 +    rc = nd_e820_align();
   9.623 +    if ( rc < 0 )
   9.624          return -1;
   9.625 -    }
   9.626 -
   9.627 -    merge_e820();
   9.628 -
   9.629 -    printk("NativeDom: After manipuations:\n");
   9.630 +        
   9.631 +    printk("NativeDom: Xen's E820 After manipuations:\n");
   9.632      print_e820_memory_map(e820.map, e820.nr_map);
   9.633  
   9.634      return 0;
   9.635 @@ -588,9 +626,11 @@ int __init nativedom_init(void)
   9.636      if ( rc < 0 )
   9.637          return -1;
   9.638  
   9.639 -    max_page_nativedom = nd_get_last_ram_pfn(&e820_nativedom);
   9.640 +    max_page_nativedom = nd_get_last_ram_pfn(&e820_nativedom) + 
   9.641 +        MM_NR_SPECIAL_PAGES;
   9.642      printk("NativeDom: max_page_nativedom=0x%08lx\n", max_page_nativedom);
   9.643  
   9.644      return 0;
   9.645  }
   9.646  
   9.647 +
    10.1 --- a/xen/arch/x86/setup.c	Wed Aug 29 12:50:02 2007 -0700
    10.2 +++ b/xen/arch/x86/setup.c	Wed Sep 19 10:51:46 2007 +0200
    10.3 @@ -95,7 +95,10 @@ boolean_param("noapic", skip_ioapic_setu
    10.4  
    10.5  /* Nativedom enabled boot */
    10.6  int opt_nativedom = 0;
    10.7 -boolean_param("enable_nativedom", opt_nativedom);
    10.8 +boolean_param("nativedom", opt_nativedom);
    10.9 +/* Nativedom's size of RAM in MB */
   10.10 +unsigned int opt_nativedom_mem = 256;
   10.11 +integer_param("nativedom_mem", opt_nativedom_mem);
   10.12  
   10.13  /* will set if vt-d HW is found */
   10.14  int vtd_enabled = 0;
   10.15 @@ -632,18 +635,12 @@ void __init __start_xen(unsigned long mb
   10.16      /* Sanitise the raw E820 map to produce a final clean version. */
   10.17      max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
   10.18  
   10.19 -#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
   10.20 -    /* This is made temporary for x86_32 (Non PAE) */
   10.21 -    if ( opt_nativedom ) 
   10.22 +    if ( opt_nativedom )
   10.23      {
   10.24          rc = nativedom_init();
   10.25          if ( rc < 0 )
   10.26              EARLY_FAIL("Error: NativeDom failed to initialize!\n");
   10.27      }
   10.28 -#else
   10.29 -    rc = 0;
   10.30 -    opt_nativedom = 0;
   10.31 -#endif
   10.32  
   10.33      /*
   10.34       * Create a temporary copy of the E820 map. Truncate it to above 16MB
   10.35 @@ -700,15 +697,7 @@ void __init __start_xen(unsigned long mb
   10.36          e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask;
   10.37          e = min_t(uint64_t, e, BOOTSTRAP_DIRECTMAP_END);
   10.38          if ( (boot_e820.map[i].type != E820_RAM) || (s >= e) )
   10.39 -        {
   10.40 -            /* Map 1:1 chunks as well */
   10.41 -            if ( boot_e820.map[i].type == E820_1TO1 )
   10.42 -                map_pages_to_xen(
   10.43 -                    (unsigned long)maddr_to_bootstrap_virt(s),
   10.44 -                    s >> PAGE_SHIFT, (e-s) >> PAGE_SHIFT, PAGE_HYPERVISOR);
   10.45 -
   10.46              continue;
   10.47 -        }
   10.48              
   10.49          /* Map the chunk. No memory will need to be allocated to do this. */
   10.50          map_pages_to_xen(
   10.51 @@ -820,7 +809,10 @@ void __init __start_xen(unsigned long mb
   10.52      xenheap_phys_end += xen_phys_start;
   10.53      reserve_in_boot_e820(xen_phys_start,
   10.54                           xen_phys_start + (opt_xenheap_megabytes<<20));
   10.55 -    init_boot_pages(1<<20, 16<<20); /* Initial seed: 15MB */
   10.56 +    if ( !opt_nativedom )
   10.57 +        init_boot_pages(1<<20, 16<<20); /* Initial seed: 15MB */
   10.58 +    else
   10.59 +        init_boot_pages(12<<20, 16<<20); /* Initial seed:  4MB */
   10.60  #else
   10.61      init_boot_pages(xenheap_phys_end, 16<<20); /* Initial seed: 4MB */
   10.62  #endif
   10.63 @@ -857,7 +849,9 @@ void __init __start_xen(unsigned long mb
   10.64          /* Only page alignment required now. */
   10.65          s = (boot_e820.map[i].addr + mask) & ~mask;
   10.66          e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask;
   10.67 -        if ( (boot_e820.map[i].type != E820_RAM) || (s >= e) )
   10.68 +        if ( ((boot_e820.map[i].type != E820_RAM) &&
   10.69 +              (boot_e820.map[i].type != E820_1TO1)) ||
   10.70 +             (s >= e) )
   10.71              continue;
   10.72  
   10.73          /* Perform the mapping (truncated in 32-bit mode). */
   10.74 @@ -870,7 +864,8 @@ void __init __start_xen(unsigned long mb
   10.75                  (unsigned long)maddr_to_bootstrap_virt(s),
   10.76                  s >> PAGE_SHIFT, (map_e-s) >> PAGE_SHIFT, PAGE_HYPERVISOR);
   10.77  
   10.78 -        init_boot_pages(s, e);
   10.79 +        if ( boot_e820.map[i].type == E820_RAM )
   10.80 +            init_boot_pages(s, e);
   10.81      }
   10.82  
   10.83      memguard_init();
    11.1 --- a/xen/common/memory.c	Wed Aug 29 12:50:02 2007 -0700
    11.2 +++ b/xen/common/memory.c	Wed Sep 19 10:51:46 2007 +0200
    11.3 @@ -155,18 +155,22 @@ static void populate_1to1_physmap(struct
    11.4      xen_pfn_t gpfn, mfn;
    11.5      struct domain *d = a->domain;
    11.6  
    11.7 +    if ( a->nr_done == 0 && !a->preempted )
    11.8 +        gdprintk(XENLOG_INFO, "NativeDom: Populating 1:1 physmap "
    11.9 +            "(domid=%d mfns=0x%x)\n", d->domain_id, a->nr_extents);
   11.10 +
   11.11      if ( !guest_handle_okay(a->extent_list, a->nr_extents) )
   11.12          return;
   11.13  
   11.14      if ( unlikely(!shadow_mode_translate(d)) )
   11.15      {
   11.16 -        gdprintk(XENLOG_ERR, "populate_1to1_physmap: not in shadow mode translate\n");
   11.17 +        gdprintk(XENLOG_ERR, "Not in shadow mode translate\n");
   11.18          goto out;
   11.19      }
   11.20  
   11.21      if ( 0 != a->extent_order ) 
   11.22      {
   11.23 -        gdprintk(XENLOG_ERR, "populate_1to1_physmap: extent_order is not 0 (%d)\n", a->extent_order);
   11.24 +        gdprintk(XENLOG_ERR, "extent_order is not 0 (%d)\n", a->extent_order);
   11.25          goto out;
   11.26      }
   11.27  
   11.28 @@ -192,6 +196,9 @@ static void populate_1to1_physmap(struct
   11.29  
   11.30   out:
   11.31      a->nr_done = i;
   11.32 +    
   11.33 +    if ( i == a->nr_extents )
   11.34 +        gdprintk(XENLOG_INFO, "NativeDom: Done populating phymap!\n");
   11.35  }
   11.36  
   11.37  int guest_remove_page(struct domain *d, unsigned long gmfn)
    12.1 --- a/xen/common/page_alloc.c	Wed Aug 29 12:50:02 2007 -0700
    12.2 +++ b/xen/common/page_alloc.c	Wed Sep 19 10:51:46 2007 +0200
    12.3 @@ -328,7 +328,7 @@ unsigned long __init alloc_boot_pages(
    12.4  #define NR_ZONES    (BITS_PER_LONG - PAGE_SHIFT)
    12.5  #endif
    12.6  
    12.7 -#define pfn_dom_zone_type(_pfn) (fls(_pfn) - 1)
    12.8 +#define pfn_dom_zone_type(_pfn) (fls(_pfn | 1) - 1)
    12.9  
   12.10  typedef struct list_head heap_by_zone_and_order_t[NR_ZONES][MAX_ORDER+1];
   12.11  static heap_by_zone_and_order_t *_heap[MAX_NUMNODES];
   12.12 @@ -1053,9 +1053,13 @@ unsigned long alloc_1to1_page(unsigned l
   12.13  
   12.14      ASSERT(!in_irq());
   12.15  
   12.16 -    if ( gpfn > max_page_nativedom )
   12.17 +    if ( gpfn >= max_page_nativedom )
   12.18 +    {
   12.19 +        gdprintk(XENLOG_ERR, "NativeDom: Request to allocate a page above "
   12.20 +            "max_page_nativedom\n");
   12.21          return INVALID_MFN;
   12.22 -
   12.23 +    }
   12.24 +    
   12.25      /* check for protected pseudo pfns */
   12.26      for (i=0; i < nd_areas.protected.nr; i++)
   12.27      {
    13.1 --- a/xen/include/xen/mm_early.h	Wed Aug 29 12:50:02 2007 -0700
    13.2 +++ b/xen/include/xen/mm_early.h	Wed Sep 19 10:51:46 2007 +0200
    13.3 @@ -1,9 +1,27 @@
    13.4  /*****************************************************************************
    13.5  
    13.6 -    Altering the memory map at the Xen early boot process,
    13.7 -    Relevant for booting NativeDom properly.
    13.8 +    Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com)
    13.9      
   13.10 -    Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com)
   13.11 +    Provide NativeDom 1:1 support, contains functions for altering the memory
   13.12 +    map at Xen's early boot process, crucial for booting NativeDom properly.
   13.13 +
   13.14 +    x86-64
   13.15 +    =====
   13.16 +    
   13.17 +    The 512KB-1MB region is remapped (because of the ROMs) to an address
   13.18 +    above 16MB.
   13.19 +
   13.20 +    As far as NativeDom can see:
   13.21 +        1. The 0-512KB region is marked as USABLE
   13.22 +        2. The 512KB-1MB region is marked as RESERVED
   13.23 +
   13.24 +    x86-32
   13.25 +    =====
   13.26 +    
   13.27 +    The 0-12MB region is remapped because it contains the ROMs and xen itself.
   13.28 +    Drawback - If a guest allocates a DMA buffer in this region, there is a
   13.29 +    chance that the machine would crash.
   13.30 +
   13.31  
   13.32  ******************************************************************************/
   13.33  #ifndef __MM_EARLY_H__
   13.34 @@ -16,18 +34,17 @@
   13.35  extern struct e820map e820_nativedom;
   13.36  
   13.37  /*
   13.38 -    Remapped/Duplicated areas are machine addresses that contains memory that should be
   13.39 -    duplicated or just remapped for NativeDom. The first 12MB of the machine memory are being
   13.40 -    duplicated on the x86_32 platform.
   13.41 +    Remapped/Duplicated areas are machine regions that contains memory
   13.42 +    that should be duplicated or just remapped for NativeDom.
   13.43  */
   13.44  #define MAX_NR_DUPAREAS         (10)
   13.45  typedef struct nd_duplicated_area_s {
   13.46      uint64_t real_addr;
   13.47      uint64_t duplicated_addr;
   13.48      uint64_t size;
   13.49 -    /* can be 1 or 0, we distinguish between two types of regions that we protect,
   13.50 -       those that are duplicated and those that are just remapped */
   13.51 -    unsigned char is_duplicated;
   13.52 +    /* can be 1 or 0, we distinguish between two types of regions that we
   13.53 +       protect, those that are duplicated and those that are just remapped */
   13.54 +    uint8_t is_duplicated;
   13.55  } nd_duplicated_area_t;
   13.56  
   13.57  #define MAX_NR_MMIOAREAS        (10)
   13.58 @@ -61,27 +78,29 @@ typedef struct nd_areas_s {
   13.59      } protected;
   13.60  } nd_areas_t;
   13.61  
   13.62 -/* percentage of E820_RAM that goes for Xen/Dom0 */
   13.63 -#define MM_XEN_PORTION_OF_RAM               (20)
   13.64 -#define MM_XEN_PORTION_OF_RAM_MINIMUM_MB    (350)
   13.65 -#define MM_XEN_PORTION_OF_RAM_MAXIMUM_MB    (512)
   13.66 -#define MM_DMADOM_FOR_XEN                   (300 * 1024 * 1024)
   13.67 +/* NativeDom / Xen memory portions (in MB) */
   13.68 +#define MM_ND_MIN_SIZE      (256)
   13.69 +#define MM_ND_MAX_SIZE      (2048)
   13.70 +#define MM_XEN_MIN_SIZE     (384)
   13.71  
   13.72 -#define MM_12MB                 (0x00C00000)
   13.73 -#define MM_16MB	                (0x01000000)
   13.74 +#define MM_512KB            (0x00080000)
   13.75 +#define MM_1MB              (1<<20)
   13.76 +#define MM_4MB              (4<<20)
   13.77 +#define MM_12MB             (12<<20)
   13.78 +#define MM_16MB             (16<<20)
   13.79  
   13.80 -/* The ROMs are duplicated for security reasons, 
   13.81 -   The 1-12MB Region is mapped on x86_32 platofrms, since Xen resides at 1MB */
   13.82 -#define MM_DUP_1MB_ADDR         (0x00000000)
   13.83 -#define MM_DUP_1MB_SIZE         (0x00100000)
   13.84 -#define MM_REMAP_XEN_ADDR	    (0x00100000)
   13.85 -#define MM_REMAP_XEN_SIZE       (0x00100000)
   13.86 -#define MM_DUP_12MB_ADDR        (0x00200000)
   13.87 -#define MM_DUP_12MB_SIZE        (MM_12MB - MM_DUP_12MB_ADDR)
   13.88 +#if defined(CONFIG_X86_64)
   13.89 +#define MM_DUP_ADDR         MM_512KB
   13.90 +#define MM_DUP_SIZE         MM_512KB
   13.91 +#else
   13.92 +#define MM_DUP_ADDR         (0)
   13.93 +#define MM_DUP_SIZE         MM_12MB
   13.94 +#endif
   13.95 +
   13.96 +/* Special pages (ioreq and xenstore) */
   13.97 +#define MM_NR_SPECIAL_PAGES    (3)
   13.98  
   13.99  /* E820 Handy functions */
  13.100 -int __init nd_duplicate_e820_entry(struct e820map * a_e820, 
  13.101 -                                       uint32_t index, uint32_t dups_nr);
  13.102  int __init nd_setup_e820(void);
  13.103  int __init nd_remap_areas(void);
  13.104  int __init nd_init_mmio_areas(void);