return -1;
 
        do {
-               unsigned long start = biosmap->addr;
-               unsigned long size = biosmap->size;
-               unsigned long end = start + size;
-               unsigned long type = biosmap->type;
+               u64 start = biosmap->addr;
+               u64 size = biosmap->size;
+               u64 end = start + size;
+               u32 type = biosmap->type;
 
                /* Overflow in 64 bits? Ignore the memory map. */
                if (start > end)
 
 /*
  * The BIOS places the EBDA/XBDA at the top of conventional
  * memory, and usually decreases the reported amount of
- * conventional memory (int 0x12) too.
+ * conventional memory (int 0x12) too. This also contains a
+ * workaround for Dell systems that neglect to reserve EBDA.
+ * The same workaround also avoids a problem with the AMD768MPX
+ * chipset: reserve a page before VGA to prevent PCI prefetch
+ * into it (errata #56). Usually the page is reserved anyways,
+ * unless you have no PS/2 mouse plugged in.
  */
-static __init void reserve_ebda(void)
+static void __init reserve_ebda_region(void)
 {
        unsigned int lowmem, ebda_addr;
 
+       /* To determine the position of the EBDA and the */
+       /* end of conventional memory, we need to look at */
+       /* the BIOS data area. In a paravirtual environment */
+       /* that area is absent. We'll just have to assume */
+       /* that the paravirt case can handle memory setup */
+       /* correctly, without our help. */
+#ifdef CONFIG_PARAVIRT
+       if ((boot_params.hdr.version >= 0x207) &&
+                       (boot_params.hdr.hardware_subarch != 0)) {
+               return;
+       }
+#endif
+
        /* end of low (conventional) memory */
        lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
        lowmem <<= 10;
                lowmem = 0x9f000;
 
        /* Paranoia: should never happen, but... */
-       if (lowmem >= 0x100000)
-               lowmem = 0xa0000;
+       if ((lowmem == 0) || (lowmem >= 0x100000))
+               lowmem = 0x9f000;
 
        /* reserve all memory between lowmem and the 1MB mark */
        reserve_early(lowmem, 0x100000, "BIOS reserved");
                reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
        }
 
-       reserve_ebda();
+       reserve_ebda_region();
 
        /*
         * At this point everything still needed from the boot loader