[PATCH] x86-64: Fix harmless off by one in e820 code
[pandora-kernel.git] / arch / x86_64 / kernel / e820.c
index 6ded3a5..eb7929e 100644 (file)
@@ -85,7 +85,7 @@ int __init e820_mapped(unsigned long start, unsigned long end, unsigned type)
                struct e820entry *ei = &e820.map[i]; 
                if (type && ei->type != type) 
                        continue;
-               if (ei->addr >= end || ei->addr + ei->size < start) 
+               if (ei->addr >= end || ei->addr + ei->size <= start)
                        continue; 
                return 1; 
        } 
@@ -131,7 +131,7 @@ void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned lon
 
                if (ei->type != E820_RAM || 
                    ei->addr+ei->size <= start || 
-                   ei->addr > end)
+                   ei->addr >= end)
                        continue;
 
                addr = round_up(ei->addr, PAGE_SIZE);
@@ -185,6 +185,40 @@ unsigned long __init e820_end_of_ram(void)
 }
 
 /* 
+ * Compute how much memory is missing in a range.
+ * Unlike the other functions in this file the arguments are in page numbers.
+ */
+unsigned long __init
+e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
+{
+       unsigned long ram = 0;
+       unsigned long start = start_pfn << PAGE_SHIFT;
+       unsigned long end = end_pfn << PAGE_SHIFT;
+       int i;
+       for (i = 0; i < e820.nr_map; i++) {
+               struct e820entry *ei = &e820.map[i];
+               unsigned long last, addr;
+
+               if (ei->type != E820_RAM ||
+                   ei->addr+ei->size <= start ||
+                   ei->addr >= end)
+                       continue;
+
+               addr = round_up(ei->addr, PAGE_SIZE);
+               if (addr < start)
+                       addr = start;
+
+               last = round_down(ei->addr + ei->size, PAGE_SIZE);
+               if (last >= end)
+                       last = end;
+
+               if (last > addr)
+                       ram += last - addr;
+       }
+       return ((end - start) - ram) >> PAGE_SHIFT;
+}
+
+/*
  * Mark e820 reserved areas as busy for the resource manager.
  */
 void __init e820_reserve_resources(void)
@@ -533,7 +567,7 @@ unsigned long pci_mem_start = 0xaeedbabe;
  */
 __init void e820_setup_gap(void)
 {
-       unsigned long gapstart, gapsize;
+       unsigned long gapstart, gapsize, round;
        unsigned long last;
        int i;
        int found = 0;
@@ -570,14 +604,14 @@ __init void e820_setup_gap(void)
        }
 
        /*
-        * Start allocating dynamic PCI memory a bit into the gap,
-        * aligned up to the nearest megabyte.
-        *
-        * Question: should we try to pad it up a bit (do something
-        * like " + (gapsize >> 3)" in there too?). We now have the
-        * technology.
+        * See how much we want to round up: start off with
+        * rounding to the next 1MB area.
         */
-       pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+       round = 0x100000;
+       while ((gapsize >> 4) > round)
+               round += round;
+       /* Fun with two's complement */
+       pci_mem_start = (gapstart + round) & -round;
 
        printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
                pci_mem_start, gapstart, gapsize);