x86/32on64: fix physical address restriction
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Jun 2008 15:05:35 +0000 (16:05 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Jun 2008 15:05:35 +0000 (16:05 +0100)
The allocation bit size setting wasn't working anymore after the
recent fix to properly use PAGE_SHIFT instead of PAGE_SIZE. This was
because the bit size implies a power-of-two range that's accessible,
but if all memory is accessible anyway (and its upper boundary is not
a power of two), the domain would either be needlessly restricted or
wouldn't be able to allocate as much memory as was intended for it
(specifically the case for Dom0 without dom0_mem= boot
parameter). Consequently, don't restrict the bit width if all memory
can be accessed.

To avoid needing to adjust this code in two places in the future (it
may need further touching when memory hotplug gets supported), fold
the logic into a function.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/x86_64/mm.c
xen/include/asm-x86/mm.h

index 81c5ab6319a3f430cd59cc30747a1e395a8579d0..53fea021011ef1a54021d9ec532a883bacada53a 100644 (file)
@@ -254,11 +254,7 @@ int switch_compat(struct domain *d)
                                  FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
     }
 
-    d->arch.physaddr_bitsize =
-        /* 2^n entries can be contained in guest's p2m mapping space */
-        fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 3
-        /* 2^n pages -> 2^(n+PAGE_SHIFT) bits */
-        + PAGE_SHIFT;
+    domain_set_alloc_bitsize(d);
 
     return 0;
 
index bf990a5ec619b5774a93391ba048bf1866364dda..8fce1eb90740122c8a19e20040a56038c34c6476 100644 (file)
@@ -353,14 +353,7 @@ int __init construct_dom0(
 #endif
     }
 
-#if defined(__x86_64__)
-    if ( is_pv_32on64_domain(d) )
-        d->arch.physaddr_bitsize =
-            /* 2^n entries can be contained in guest's p2m mapping space */
-            fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 3
-            /* 2^n pages -> 2^(n+PAGE_SHIFT) bits */
-            + PAGE_SHIFT;
-#endif
+    domain_set_alloc_bitsize(d);
 
     /*
      * Why do we need this? The number of page-table frames depends on the 
index 666d2dde7849212ea4106bcea78ccb582c0d7e9f..febca9f45518ece443da5262bbe2cea6d73f22b9 100644 (file)
@@ -168,7 +168,7 @@ void __init paging_init(void)
     if ( mpt_size > RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START )
         mpt_size = RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START;
     mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL);
-    if ( m2p_compat_vstart + mpt_size < MACH2PHYS_COMPAT_VIRT_END )
+    if ( (m2p_compat_vstart + mpt_size) < MACH2PHYS_COMPAT_VIRT_END )
         m2p_compat_vstart = MACH2PHYS_COMPAT_VIRT_END - mpt_size;
     for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
     {
@@ -472,9 +472,21 @@ int check_descriptor(const struct domain *dom, struct desc_struct *d)
     return 0;
 }
 
+void domain_set_alloc_bitsize(struct domain *d)
+{
+    if ( !is_pv_32on64_domain(d) ||
+         (MACH2PHYS_COMPAT_NR_ENTRIES(d) >= max_page) )
+        return;
+    d->arch.physaddr_bitsize =
+        /* 2^n entries can be contained in guest's p2m mapping space */
+        fls(MACH2PHYS_COMPAT_NR_ENTRIES(d)) - 1
+        /* 2^n pages -> 2^(n+PAGE_SHIFT) bits */
+        + PAGE_SHIFT;
+}
+
 unsigned int domain_clamp_alloc_bitsize(struct domain *d, unsigned int bits)
 {
-    if ( (d == NULL) || !is_pv_32on64_domain(d) )
+    if ( (d == NULL) || (d->arch.physaddr_bitsize == 0) )
         return bits;
     return min(d->arch.physaddr_bitsize, bits);
 }
index e6b63e6772b415346414e1a6f8cbe8dc95900d7c..43ec82cf2c89c9634df55985a4cce530d2cfabb4 100644 (file)
@@ -342,8 +342,10 @@ int steal_page(
 int map_ldt_shadow_page(unsigned int);
 
 #ifdef CONFIG_COMPAT
+void domain_set_alloc_bitsize(struct domain *d);
 unsigned int domain_clamp_alloc_bitsize(struct domain *d, unsigned int bits);
 #else
+# define domain_set_alloc_bitsize(d) ((void)0)
 # define domain_clamp_alloc_bitsize(d, b) (b)
 #endif