Merge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / drivers / xen / balloon.c
index 77b5dc3597e31d6c543e9c8cd5959cca53d5c375..43f9f02c7db0671668343fc19bed043fbbe61fad 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
+#include <asm/e820.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
@@ -391,7 +392,7 @@ static struct notifier_block xenstore_notifier;
 
 static int __init balloon_init(void)
 {
-       unsigned long pfn;
+       unsigned long pfn, extra_pfn_end;
        struct page *page;
 
        if (!xen_pv_domain())
@@ -411,9 +412,19 @@ static int __init balloon_init(void)
 
        register_balloon(&balloon_sysdev);
 
-       /* Initialise the balloon with excess memory space. */
+       /*
+        * Initialise the balloon with excess memory space.  We need
+        * to make sure we don't add memory which doesn't exist or
+        * logically exist.  The E820 map can be trimmed to be smaller
+        * than the amount of physical memory due to the mem= command
+        * line parameter.  And if this is a 32-bit non-HIGHMEM kernel
+        * on a system with memory which requires highmem to access,
+        * don't try to use it.
+        */
+       extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
+                           (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
        for (pfn = PFN_UP(xen_extra_mem_start);
-            pfn < PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size);
+            pfn < extra_pfn_end;
             pfn++) {
                page = pfn_to_page(pfn);
                /* totalram_pages doesn't include the boot-time