ia64/xen-unstable

changeset 5770:57b2fa8bf11d

Initial tools support for 32-bit x86 pae.
Signed-off-by: Gerd Knorr <kraxel@suse.de>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jul 13 15:04:49 2005 +0000 (2005-07-13)
parents 87cfe3f76045
children 09be5b1bdeb0
files tools/libxc/xc_linux_build.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.h
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Wed Jul 13 15:02:49 2005 +0000
     1.2 +++ b/tools/libxc/xc_linux_build.c	Wed Jul 13 15:04:49 2005 +0000
     1.3 @@ -21,6 +21,7 @@
     1.4  #if defined(__i386__)
     1.5  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
     1.6  #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
     1.7 +#define L3_PROT (_PAGE_PRESENT)
     1.8  #endif
     1.9  
    1.10  #if defined(__x86_64__)
    1.11 @@ -49,6 +50,214 @@ static int probeimageformat(char *image,
    1.12      return 0;
    1.13  }
    1.14  
    1.15 +#define alloc_pt(ltab, vltab) \
    1.16 +        ltab = page_array[ppt_alloc++] << PAGE_SHIFT; \
    1.17 +        if (vltab != NULL) { \
    1.18 +            munmap(vltab, PAGE_SIZE); \
    1.19 +        } \
    1.20 +        if ((vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \
    1.21 +                          PROT_READ|PROT_WRITE, \
    1.22 +                          ltab >> PAGE_SHIFT)) == NULL) { \
    1.23 +            goto error_out; \
    1.24 +        } \
    1.25 +        memset(vltab, 0, PAGE_SIZE);
    1.26 +
    1.27 +#if defined(__i386__)
    1.28 +
    1.29 +static int setup_pg_tables(int xc_handle, u32 dom,
    1.30 +			   vcpu_guest_context_t *ctxt,
    1.31 +			   unsigned long dsi_v_start,
    1.32 +			   unsigned long v_end,
    1.33 +			   unsigned long *page_array,
    1.34 +			   unsigned long vpt_start,
    1.35 +			   unsigned long vpt_end)
    1.36 +{
    1.37 +    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    1.38 +    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    1.39 +    unsigned long l1tab = 0;
    1.40 +    unsigned long l2tab = 0;
    1.41 +    unsigned long ppt_alloc;
    1.42 +    unsigned long count;
    1.43 +
    1.44 +    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
    1.45 +    alloc_pt(l2tab, vl2tab);
    1.46 +    vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
    1.47 +    ctxt->ctrlreg[3] = l2tab;
    1.48 +
    1.49 +    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++ )
    1.50 +    {    
    1.51 +        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
    1.52 +        {
    1.53 +	    alloc_pt(l1tab, vl1tab);
    1.54 +            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
    1.55 +            *vl2e++ = l1tab | L2_PROT;
    1.56 +        }
    1.57 +
    1.58 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
    1.59 +        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 
    1.60 +             (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
    1.61 +            *vl1e &= ~_PAGE_RW;
    1.62 +        vl1e++;
    1.63 +    }
    1.64 +    munmap(vl1tab, PAGE_SIZE);
    1.65 +    munmap(vl2tab, PAGE_SIZE);
    1.66 +    return 0;
    1.67 +
    1.68 + error_out:
    1.69 +    if (vl1tab)
    1.70 +	munmap(vl1tab, PAGE_SIZE);
    1.71 +    if (vl2tab)
    1.72 +	munmap(vl2tab, PAGE_SIZE);
    1.73 +    return -1;
    1.74 +}
    1.75 +
    1.76 +static int setup_pg_tables_pae(int xc_handle, u32 dom,
    1.77 +			       vcpu_guest_context_t *ctxt,
    1.78 +			       unsigned long dsi_v_start,
    1.79 +			       unsigned long v_end,
    1.80 +			       unsigned long *page_array,
    1.81 +			       unsigned long vpt_start,
    1.82 +			       unsigned long vpt_end)
    1.83 +{
    1.84 +    l1_pgentry_64_t *vl1tab=NULL, *vl1e=NULL;
    1.85 +    l2_pgentry_64_t *vl2tab=NULL, *vl2e=NULL;
    1.86 +    l3_pgentry_64_t *vl3tab=NULL, *vl3e=NULL;
    1.87 +    unsigned long l1tab = 0;
    1.88 +    unsigned long l2tab = 0;
    1.89 +    unsigned long l3tab = 0;
    1.90 +    unsigned long ppt_alloc;
    1.91 +    unsigned long count;
    1.92 +
    1.93 +    /* First allocate page for page dir. */
    1.94 +    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
    1.95 +    alloc_pt(l3tab, vl3tab);
    1.96 +    vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
    1.97 +    ctxt->ctrlreg[3] = l3tab;
    1.98 +    
    1.99 +    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
   1.100 +    {
   1.101 +        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
   1.102 +        {
   1.103 +            alloc_pt(l1tab, vl1tab);
   1.104 +            
   1.105 +                if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
   1.106 +                {
   1.107 +                    alloc_pt(l2tab, vl2tab);
   1.108 +                    vl2e = &vl2tab[l2_table_offset_pae(dsi_v_start + (count<<PAGE_SHIFT))];
   1.109 +                    *vl3e = l2tab | L3_PROT;
   1.110 +                    vl3e++;
   1.111 +                }
   1.112 +            vl1e = &vl1tab[l1_table_offset_pae(dsi_v_start + (count<<PAGE_SHIFT))];
   1.113 +            *vl2e = l1tab | L2_PROT;
   1.114 +            vl2e++;
   1.115 +        }
   1.116 +        
   1.117 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   1.118 +        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
   1.119 +	     (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
   1.120 +        {
   1.121 +	    *vl1e &= ~_PAGE_RW;
   1.122 +        }
   1.123 +	vl1e++;
   1.124 +    }
   1.125 +     
   1.126 +    munmap(vl1tab, PAGE_SIZE);
   1.127 +    munmap(vl2tab, PAGE_SIZE);
   1.128 +    munmap(vl3tab, PAGE_SIZE);
   1.129 +    return 0;
   1.130 +
   1.131 + error_out:
   1.132 +    if (vl1tab)
   1.133 +	munmap(vl1tab, PAGE_SIZE);
   1.134 +    if (vl2tab)
   1.135 +	munmap(vl2tab, PAGE_SIZE);
   1.136 +    if (vl3tab)
   1.137 +	munmap(vl3tab, PAGE_SIZE);
   1.138 +    return -1;
   1.139 +}
   1.140 +
   1.141 +#endif
   1.142 +
   1.143 +#if defined(__x86_64__)
   1.144 +
   1.145 +static int setup_pg_tables_64(int xc_handle, u32 dom,
   1.146 +			      vcpu_guest_context_t *ctxt,
   1.147 +			      unsigned long dsi_v_start,
   1.148 +			      unsigned long v_end,
   1.149 +			      unsigned long *page_array,
   1.150 +			      unsigned long vpt_start,
   1.151 +			      unsigned long vpt_end)
   1.152 +{
   1.153 +    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
   1.154 +    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
   1.155 +    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
   1.156 +    l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
   1.157 +    unsigned long l2tab = 0;
   1.158 +    unsigned long l1tab = 0;
   1.159 +    unsigned long l3tab = 0;
   1.160 +    unsigned long l4tab = 0;
   1.161 +    unsigned long ppt_alloc;
   1.162 +    unsigned long count;
   1.163 +
   1.164 +    /* First allocate page for page dir. */
   1.165 +    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
   1.166 +    alloc_pt(l4tab, vl4tab);
   1.167 +    vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
   1.168 +    ctxt->ctrlreg[3] = l4tab;
   1.169 +    
   1.170 +    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
   1.171 +    {
   1.172 +        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
   1.173 +        {
   1.174 +            alloc_pt(l1tab, vl1tab);
   1.175 +            
   1.176 +                if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
   1.177 +                {
   1.178 +                    alloc_pt(l2tab, vl2tab);
   1.179 +                    if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
   1.180 +                    {
   1.181 +                        alloc_pt(l3tab, vl3tab);
   1.182 +                        vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   1.183 +                        *vl4e = l3tab | L4_PROT;
   1.184 +                        vl4e++;
   1.185 +                    }
   1.186 +                    vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   1.187 +                    *vl3e = l2tab | L3_PROT;
   1.188 +                    vl3e++;
   1.189 +                }
   1.190 +            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   1.191 +            *vl2e = l1tab | L2_PROT;
   1.192 +            vl2e++;
   1.193 +        }
   1.194 +        
   1.195 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   1.196 +        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
   1.197 +            (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
   1.198 +        {
   1.199 +                *vl1e &= ~_PAGE_RW;
   1.200 +        }
   1.201 +            vl1e++;
   1.202 +    }
   1.203 +     
   1.204 +    munmap(vl1tab, PAGE_SIZE);
   1.205 +    munmap(vl2tab, PAGE_SIZE);
   1.206 +    munmap(vl3tab, PAGE_SIZE);
   1.207 +    munmap(vl4tab, PAGE_SIZE);
   1.208 +    return 0;
   1.209 +
   1.210 + error_out:
   1.211 +    if (vl1tab)
   1.212 +	munmap(vl1tab, PAGE_SIZE);
   1.213 +    if (vl2tab)
   1.214 +	munmap(vl2tab, PAGE_SIZE);
   1.215 +    if (vl3tab)
   1.216 +	munmap(vl3tab, PAGE_SIZE);
   1.217 +    if (vl4tab)
   1.218 +	munmap(vl4tab, PAGE_SIZE);
   1.219 +    return -1;
   1.220 +}
   1.221 +#endif
   1.222 +
   1.223  static int setup_guest(int xc_handle,
   1.224                         u32 dom,
   1.225                         char *image, unsigned long image_size,
   1.226 @@ -63,19 +272,7 @@ static int setup_guest(int xc_handle,
   1.227                         unsigned int vcpus,
   1.228  		       unsigned int store_evtchn, unsigned long *store_mfn)
   1.229  {
   1.230 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
   1.231 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
   1.232 -#if defined(__x86_64__)
   1.233 -    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
   1.234 -    l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
   1.235 -#endif
   1.236      unsigned long *page_array = NULL;
   1.237 -    unsigned long l2tab = 0;
   1.238 -    unsigned long l1tab = 0;
   1.239 -#if defined(__x86_64__)
   1.240 -    unsigned long l3tab = 0;
   1.241 -    unsigned long l4tab = 0;
   1.242 -#endif
   1.243      unsigned long count, i;
   1.244      start_info_t *start_info;
   1.245      shared_info_t *shared_info;
   1.246 @@ -83,7 +280,7 @@ static int setup_guest(int xc_handle,
   1.247      int rc;
   1.248  
   1.249      unsigned long nr_pt_pages;
   1.250 -    unsigned long ppt_alloc, physmap_pfn;
   1.251 +    unsigned long physmap_pfn;
   1.252      u32 *physmap, *physmap_e;
   1.253  
   1.254      struct load_funcs load_funcs;
   1.255 @@ -144,9 +341,16 @@ static int setup_guest(int xc_handle,
   1.256          if ( (v_end - vstack_end) < (512UL << 10) )
   1.257              v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
   1.258  #if defined(__i386__)
   1.259 -        if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
   1.260 -               L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
   1.261 -            break;
   1.262 +	if (dsi.pae_kernel) {
   1.263 +	    /* FIXME: assumes one L2 pgtable @ 0xc0000000 */
   1.264 +	    if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT_PAE)-1)) >> 
   1.265 +		   L2_PAGETABLE_SHIFT_PAE) + 2) <= nr_pt_pages )
   1.266 +		break;
   1.267 +	} else {
   1.268 +	    if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
   1.269 +		   L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
   1.270 +		break;
   1.271 +	}
   1.272  #endif
   1.273  #if defined(__x86_64__)
   1.274  #define NR(_l,_h,_s) \
   1.275 @@ -225,114 +429,25 @@ static int setup_guest(int xc_handle,
   1.276      if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
   1.277          goto error_out;
   1.278  
   1.279 +    /* setup page tables */
   1.280  #if defined(__i386__)
   1.281 -    /* First allocate page for page dir. */
   1.282 -    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
   1.283 -    l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   1.284 -    ctxt->ctrlreg[3] = l2tab;
   1.285 -
   1.286 -    /* Initialise the page tables. */
   1.287 -    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
   1.288 -                                        PROT_READ|PROT_WRITE, 
   1.289 -                                        l2tab >> PAGE_SHIFT)) == NULL )
   1.290 -        goto error_out;
   1.291 -    memset(vl2tab, 0, PAGE_SIZE);
   1.292 -    vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
   1.293 -    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
   1.294 -    {    
   1.295 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   1.296 -        {
   1.297 -            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   1.298 -            if ( vl1tab != NULL )
   1.299 -                munmap(vl1tab, PAGE_SIZE);
   1.300 -            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   1.301 -                                                PROT_READ|PROT_WRITE,
   1.302 -                                                l1tab >> PAGE_SHIFT)) == NULL )
   1.303 -            {
   1.304 -                munmap(vl2tab, PAGE_SIZE);
   1.305 -                goto error_out;
   1.306 -            }
   1.307 -            memset(vl1tab, 0, PAGE_SIZE);
   1.308 -            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   1.309 -            *vl2e++ = l1tab | L2_PROT;
   1.310 -        }
   1.311 -
   1.312 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   1.313 -        if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && 
   1.314 -             (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) )
   1.315 -            *vl1e &= ~_PAGE_RW;
   1.316 -        vl1e++;
   1.317 +    if (dsi.pae_kernel)
   1.318 +	rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
   1.319 +				 dsi.v_start, v_end,
   1.320 +				 page_array, vpt_start, vpt_end);
   1.321 +    else {
   1.322 +	rc = setup_pg_tables(xc_handle, dom, ctxt,
   1.323 +			     dsi.v_start, v_end,
   1.324 +			     page_array, vpt_start, vpt_end);
   1.325      }
   1.326 -    munmap(vl1tab, PAGE_SIZE);
   1.327 -    munmap(vl2tab, PAGE_SIZE);
   1.328  #endif
   1.329  #if defined(__x86_64__)
   1.330 -
   1.331 -#define alloc_pt(ltab, vltab) \
   1.332 -        ltab = page_array[ppt_alloc++] << PAGE_SHIFT; \
   1.333 -        if (vltab != NULL) { \
   1.334 -            munmap(vltab, PAGE_SIZE); \
   1.335 -        } \
   1.336 -        if ((vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \
   1.337 -                          PROT_READ|PROT_WRITE, \
   1.338 -                          ltab >> PAGE_SHIFT)) == NULL) { \
   1.339 -            munmap(vltab, PAGE_SIZE); \
   1.340 -            goto error_out; \
   1.341 -        } \
   1.342 -        memset(vltab, 0, PAGE_SIZE);
   1.343 -
   1.344 -    /* First allocate page for page dir. */
   1.345 -    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
   1.346 -    l4tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   1.347 -    ctxt->ctrlreg[3] = l4tab;
   1.348 -    
   1.349 -    /* Intiliaize page table */
   1.350 -    if ( (vl4tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   1.351 -                                        PROT_READ|PROT_WRITE,
   1.352 -                                        l4tab >> PAGE_SHIFT)) == NULL )
   1.353 -            goto error_out;
   1.354 -    memset(vl4tab, 0, PAGE_SIZE);
   1.355 -    vl4e = &vl4tab[l4_table_offset(dsi.v_start)];
   1.356 -    
   1.357 -    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++)
   1.358 -    {
   1.359 -        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
   1.360 -        {
   1.361 -            alloc_pt(l1tab, vl1tab);
   1.362 -            
   1.363 -                if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
   1.364 -                {
   1.365 -                    alloc_pt(l2tab, vl2tab);
   1.366 -                    if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
   1.367 -                    {
   1.368 -                        alloc_pt(l3tab, vl3tab);
   1.369 -                        vl3e = &vl3tab[l3_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   1.370 -                        *vl4e = l3tab | L4_PROT;
   1.371 -                        vl4e++;
   1.372 -                    }
   1.373 -                    vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   1.374 -                    *vl3e = l2tab | L3_PROT;
   1.375 -                    vl3e++;
   1.376 -                }
   1.377 -            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   1.378 -            *vl2e = l1tab | L2_PROT;
   1.379 -            vl2e++;
   1.380 -        }
   1.381 -        
   1.382 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   1.383 -        if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) &&
   1.384 -            (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) ) 
   1.385 -        {
   1.386 -                *vl1e &= ~_PAGE_RW;
   1.387 -        }
   1.388 -            vl1e++;
   1.389 -    }
   1.390 -     
   1.391 -    munmap(vl1tab, PAGE_SIZE);
   1.392 -    munmap(vl2tab, PAGE_SIZE);
   1.393 -    munmap(vl3tab, PAGE_SIZE);
   1.394 -    munmap(vl4tab, PAGE_SIZE);
   1.395 +    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
   1.396 +			    dsi.v_start, v_end,
   1.397 +			    page_array, vpt_start, vpt_end);
   1.398  #endif
   1.399 +    if (0 != rc)
   1.400 +	goto error_out;
   1.401  
   1.402      /* Write the phys->machine and machine->phys table entries. */
   1.403      physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
   1.404 @@ -363,9 +478,16 @@ static int setup_guest(int xc_handle,
   1.405      /*
   1.406       * Pin down l2tab addr as page dir page - causes hypervisor to provide
   1.407       * correct protection for the page
   1.408 -     */ 
   1.409 -    if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, l2tab>>PAGE_SHIFT, dom) )
   1.410 -        goto error_out;
   1.411 +     */
   1.412 +    if (dsi.pae_kernel) {
   1.413 +	if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
   1.414 +		       ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
   1.415 +	    goto error_out;
   1.416 +    } else {
   1.417 +	if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
   1.418 +		       ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
   1.419 +	    goto error_out;
   1.420 +    }
   1.421  #endif
   1.422  
   1.423  #if defined(__x86_64__)
   1.424 @@ -373,9 +495,11 @@ static int setup_guest(int xc_handle,
   1.425       * Pin down l4tab addr as page dir page - causes hypervisor to  provide
   1.426       * correct protection for the page
   1.427       */
   1.428 -     if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE, l4tab>>PAGE_SHIFT, dom) )
   1.429 +     if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
   1.430 +		    ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
   1.431          goto error_out;
   1.432  #endif
   1.433 +
   1.434      start_info = xc_map_foreign_range(
   1.435          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   1.436          page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
     2.1 --- a/tools/libxc/xc_load_elf.c	Wed Jul 13 15:02:49 2005 +0000
     2.2 +++ b/tools/libxc/xc_load_elf.c	Wed Jul 13 15:04:49 2005 +0000
     2.3 @@ -115,6 +115,8 @@ static int parseelfimage(char *image,
     2.4              ERROR("Actually saw: '%s'", guestinfo);
     2.5              return -EINVAL;
     2.6          }
     2.7 +        if ( (strstr(guestinfo, "PAE=yes") != NULL) )
     2.8 +	    dsi->pae_kernel = 1;
     2.9  
    2.10          break;
    2.11      }
     3.1 --- a/tools/libxc/xc_private.h	Wed Jul 13 15:02:49 2005 +0000
     3.2 +++ b/tools/libxc/xc_private.h	Wed Jul 13 15:04:49 2005 +0000
     3.3 @@ -32,6 +32,9 @@
     3.4  #if defined(__i386__)
     3.5  #define L1_PAGETABLE_SHIFT       12
     3.6  #define L2_PAGETABLE_SHIFT       22
     3.7 +#define L1_PAGETABLE_SHIFT_PAE   12
     3.8 +#define L2_PAGETABLE_SHIFT_PAE   21
     3.9 +#define L3_PAGETABLE_SHIFT_PAE   30
    3.10  #elif defined(__x86_64__)
    3.11  #define L1_PAGETABLE_SHIFT      12
    3.12  #define L2_PAGETABLE_SHIFT      21
    3.13 @@ -42,6 +45,9 @@
    3.14  #if defined(__i386__) 
    3.15  #define ENTRIES_PER_L1_PAGETABLE 1024
    3.16  #define ENTRIES_PER_L2_PAGETABLE 1024
    3.17 +#define L1_PAGETABLE_ENTRIES_PAE  512
    3.18 +#define L2_PAGETABLE_ENTRIES_PAE  512
    3.19 +#define L3_PAGETABLE_ENTRIES_PAE    4
    3.20  #elif defined(__x86_64__)
    3.21  #define L1_PAGETABLE_ENTRIES    512
    3.22  #define L2_PAGETABLE_ENTRIES    512
    3.23 @@ -55,6 +61,9 @@
    3.24  
    3.25  typedef u32 l1_pgentry_32_t;
    3.26  typedef u32 l2_pgentry_32_t;
    3.27 +typedef u64 l1_pgentry_64_t;
    3.28 +typedef u64 l2_pgentry_64_t;
    3.29 +typedef u64 l3_pgentry_64_t;
    3.30  typedef unsigned long l1_pgentry_t;
    3.31  typedef unsigned long l2_pgentry_t;
    3.32  #if defined(__x86_64__)
    3.33 @@ -67,6 +76,12 @@ typedef unsigned long l4_pgentry_t;
    3.34            (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
    3.35  #define l2_table_offset(_a) \
    3.36            ((_a) >> L2_PAGETABLE_SHIFT)
    3.37 +#define l1_table_offset_pae(_a) \
    3.38 +  (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
    3.39 +#define l2_table_offset_pae(_a) \
    3.40 +  (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
    3.41 +#define l3_table_offset_pae(_a) \
    3.42 +	(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
    3.43  #elif defined(__x86_64__)
    3.44  #define l1_table_offset(_a) \
    3.45    (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
    3.46 @@ -87,6 +102,7 @@ struct domain_setup_info
    3.47      unsigned long v_kernentry;
    3.48  
    3.49      unsigned int  load_symtab;
    3.50 +    unsigned int  pae_kernel;
    3.51      unsigned long symtab_addr;
    3.52      unsigned long symtab_len;
    3.53  };