Merge remote-tracking branch 'kspp/for-next/kspp'
[deliverable/linux.git] / mm / page_alloc.c
index a2214c64ed3cd04dceaed7a579f593852e458df1..41940f6e3c1c07eec3467f41de4e5337e5d4b654 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/page_owner.h>
 #include <linux/kthread.h>
 #include <linux/memcontrol.h>
+#include <linux/random.h>
 
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
@@ -91,6 +92,11 @@ EXPORT_PER_CPU_SYMBOL(_numa_mem_);
 int _node_numa_mem_[MAX_NUMNODES];
 #endif
 
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+volatile u64 latent_entropy __latent_entropy;
+EXPORT_SYMBOL(latent_entropy);
+#endif
+
 /*
  * Array of node states.
  */
@@ -1234,6 +1240,15 @@ static void __free_pages_ok(struct page *page, unsigned int order)
        local_irq_restore(flags);
 }
 
+bool __meminitdata ram_latent_entropy;
+
+static int __init setup_ram_latent_entropy(char *str)
+{
+       ram_latent_entropy = true;
+       return 0;
+}
+early_param("ram_latent_entropy", setup_ram_latent_entropy);
+
 static void __init __free_pages_boot_core(struct page *page, unsigned int order)
 {
        unsigned int nr_pages = 1 << order;
@@ -1249,6 +1264,17 @@ static void __init __free_pages_boot_core(struct page *page, unsigned int order)
        __ClearPageReserved(p);
        set_page_count(p, 0);
 
+       if (ram_latent_entropy && !PageHighMem(page) &&
+               page_to_pfn(page) < 0x100000) {
+               u64 hash = 0;
+               size_t index, end = PAGE_SIZE * nr_pages / sizeof(hash);
+               const u64 *data = lowmem_page_address(page);
+
+               for (index = 0; index < end; index++)
+                       hash ^= hash + data[index];
+               add_device_randomness((const void *)&hash, sizeof(hash));
+       }
+
        page_zone(page)->managed_pages += nr_pages;
        set_page_refcounted(page);
        __free_pages(page, order);
This page took 0.02537 seconds and 5 git commands to generate.