hvmloader: Fix memory relocation loop.
authorKeir Fraser <keir@xen.org>
Mon, 21 Nov 2011 21:28:34 +0000 (21:28 +0000)
committerKeir Fraser <keir@xen.org>
Mon, 21 Nov 2011 21:28:34 +0000 (21:28 +0000)
Signed-off-by: Keir Fraser <keir@xen.org>
tools/firmware/hvmloader/pci.c
tools/firmware/hvmloader/util.h

index 62aeff2fac93ab49ed17a7308fa696d530953b53..00490f184e7ff3767bb62bcfc4281f83fa60e321 100644 (file)
@@ -50,7 +50,6 @@ void pci_setup(void)
         uint32_t devfn, bar_reg, bar_sz;
     } *bars = (struct bars *)scratch_start;
     unsigned int i, nr_bars = 0;
-    unsigned long pci_mem_reloc_pg;
 
     /* Program PCI-ISA bridge with appropriate link routes. */
     isa_irq = 0;
@@ -186,25 +185,26 @@ void pci_setup(void)
             ((pci_mem_start << 1) != 0) )
         pci_mem_start <<= 1;
 
-    /* Relocate RAM that overlaps (in 64K chunks) */
-    pci_mem_reloc_pg = (pci_mem_start >> PAGE_SHIFT);
-    while (pci_mem_reloc_pg < hvm_info->low_mem_pgend)
+    /* Relocate RAM that overlaps PCI space (in 64k-page chunks). */
+    while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
     {
         struct xen_add_to_physmap xatp;
-        unsigned int size = hvm_info->low_mem_pgend - pci_mem_reloc_pg;
+        unsigned int nr_pages = min_t(
+            unsigned int,
+            hvm_info->low_mem_pgend - (pci_mem_start >> PAGE_SHIFT),
+            (1u << 16) - 1);
+        if ( hvm_info->high_mem_pgend == 0 )
+            hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
+        hvm_info->low_mem_pgend -= nr_pages;
         xatp.domid = DOMID_SELF;
         xatp.space = XENMAPSPACE_gmfn_range;
-        xatp.idx = pci_mem_reloc_pg;
-        xatp.gpfn = hvm_info->high_mem_pgend;
-        size = size > ((1 << 16) - 1) ? ((1 << 16) - 1) : size;
-        xatp.size = size;
-
+        xatp.idx   = hvm_info->low_mem_pgend;
+        xatp.gpfn  = hvm_info->high_mem_pgend;
+        xatp.size  = nr_pages;
         if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
             BUG();
-        pci_mem_reloc_pg += size;
-        hvm_info->high_mem_pgend += size;
+        hvm_info->high_mem_pgend += nr_pages;
     }
-    hvm_info->low_mem_pgend = pci_mem_start >> PAGE_SHIFT;
 
     mem_resource.base = pci_mem_start;
     mem_resource.max = pci_mem_end;
index 464cf98f613526ad04b747aa91927e14923e69c8..ac2b0d33d99ae0902a662c71e0c73b27ee8277d9 100644 (file)
@@ -31,6 +31,11 @@ void __bug(char *file, int line) __attribute__((noreturn));
 #define BUG_ON(p) do { if (p) BUG(); } while (0)
 #define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
 
+#define min_t(type,x,y) \
+        ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#define max_t(type,x,y) \
+        ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+
 static inline int test_bit(unsigned int b, void *p)
 {
     return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7)));