diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2016-09-29 11:39:31 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2016-09-29 11:39:31 +1000 |
commit | 4d8759d644731cd0bc5c52352498c2bca2d928e3 (patch) | |
tree | cea3e8a08d8a851546e972bdbfeffa7668af1678 /mm | |
parent | 657d91dac15f0e758ce5a78608c70c68f5a836a9 (diff) | |
parent | 09dd109d8241cd570391d4488337b77a4525f24e (diff) |
Merge remote-tracking branch 'kspp/for-next/kspp'
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a2214c64ed3c..41940f6e3c1c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -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); |