]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/memremap.c
cfg80211: prevent speculation on cfg80211_classify8021d() return
[mirror_ubuntu-bionic-kernel.git] / kernel / memremap.c
index 403ab9cdb949a0483bd82c811a3383eed77e5246..8edd223eb81c3426a032fbe64d22d8091cfb79bd 100644 (file)
@@ -301,7 +301,8 @@ static void devm_memremap_pages_release(struct device *dev, void *data)
 
        /* pages are dead and unused, undo the arch mapping */
        align_start = res->start & ~(SECTION_SIZE - 1);
-       align_size = ALIGN(resource_size(res), SECTION_SIZE);
+       align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
+               - align_start;
 
        mem_hotplug_begin();
        arch_remove_memory(align_start, align_size);
@@ -351,10 +352,27 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
        struct dev_pagemap *pgmap;
        struct page_map *page_map;
        int error, nid, is_ram, i = 0;
+       struct dev_pagemap *conflict_pgmap;
 
        align_start = res->start & ~(SECTION_SIZE - 1);
        align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
                - align_start;
+       align_end = align_start + align_size - 1;
+
+       conflict_pgmap = get_dev_pagemap(PHYS_PFN(align_start), NULL);
+       if (conflict_pgmap) {
+               dev_WARN(dev, "Conflicting mapping in same section\n");
+               put_dev_pagemap(conflict_pgmap);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       conflict_pgmap = get_dev_pagemap(PHYS_PFN(align_end), NULL);
+       if (conflict_pgmap) {
+               dev_WARN(dev, "Conflicting mapping in same section\n");
+               put_dev_pagemap(conflict_pgmap);
+               return ERR_PTR(-ENOMEM);
+       }
+
        is_ram = region_intersects(align_start, align_size,
                IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
 
@@ -392,7 +410,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
 
        mutex_lock(&pgmap_lock);
        error = 0;
-       align_end = align_start + align_size - 1;
 
        foreach_order_pgoff(res, order, pgoff) {
                struct dev_pagemap *dup;