Merge tag 'loadpin-security-next' of https://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / mm / madvise.c
index 4d3c922ea1a1cb7558e1b69a3e32000833442489..972a9eaa898b6ad889a4647ed207ad82bd5d0f4b 100644 (file)
@@ -631,11 +631,13 @@ static int madvise_inject_error(int behavior,
 
 
        for (; start < end; start += PAGE_SIZE << order) {
+               unsigned long pfn;
                int ret;
 
                ret = get_user_pages_fast(start, 1, 0, &page);
                if (ret != 1)
                        return ret;
+               pfn = page_to_pfn(page);
 
                /*
                 * When soft offlining hugepages, after migrating the page
@@ -651,17 +653,25 @@ static int madvise_inject_error(int behavior,
 
                if (behavior == MADV_SOFT_OFFLINE) {
                        pr_info("Soft offlining pfn %#lx at process virtual address %#lx\n",
-                                               page_to_pfn(page), start);
+                                       pfn, start);
 
                        ret = soft_offline_page(page, MF_COUNT_INCREASED);
                        if (ret)
                                return ret;
                        continue;
                }
+
                pr_info("Injecting memory failure for pfn %#lx at process virtual address %#lx\n",
-                                               page_to_pfn(page), start);
+                               pfn, start);
 
-               ret = memory_failure(page_to_pfn(page), MF_COUNT_INCREASED);
+               /*
+                * Drop the page reference taken by get_user_pages_fast(). In
+                * the absence of MF_COUNT_INCREASED the memory_failure()
+                * routine is responsible for pinning the page to prevent it
+                * from being released back to the page allocator.
+                */
+               put_page(page);
+               ret = memory_failure(pfn, 0);
                if (ret)
                        return ret;
        }