xen: avoid another early crash of memory limited dom0
[firefly-linux-kernel-4.4.55.git] / arch / x86 / xen / setup.c
index ead0d363bfba8fd86009e6c2bd23b8010ed45881..7a5d5666677f0175b30229ae3c0b102a0b526e75 100644 (file)
@@ -593,20 +593,27 @@ static void __init xen_ignore_unusable(void)
 static unsigned long __init xen_count_remap_pages(unsigned long max_pfn)
 {
        unsigned long extra = 0;
+       unsigned long start_pfn, end_pfn;
        const struct e820entry *entry = xen_e820_map;
        int i;
 
+       end_pfn = 0;
        for (i = 0; i < xen_e820_map_entries; i++, entry++) {
-               unsigned long start_pfn = PFN_DOWN(entry->addr);
-               unsigned long end_pfn = PFN_UP(entry->addr + entry->size);
+               start_pfn = PFN_DOWN(entry->addr);
+               /* Adjacent regions on non-page boundaries handling! */
+               end_pfn = min(end_pfn, start_pfn);
 
                if (start_pfn >= max_pfn)
-                       break;
-               if (entry->type == E820_RAM)
-                       continue;
-               if (end_pfn >= max_pfn)
-                       end_pfn = max_pfn;
-               extra += end_pfn - start_pfn;
+                       return extra + max_pfn - end_pfn;
+
+               /* Add any holes in map to result. */
+               extra += start_pfn - end_pfn;
+
+               end_pfn = PFN_UP(entry->addr + entry->size);
+               end_pfn = min(end_pfn, max_pfn);
+
+               if (entry->type != E820_RAM)
+                       extra += end_pfn - start_pfn;
        }
 
        return extra;