diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/elf.h | 2 | ||||
-rw-r--r-- | arch/x86/mm/mmap.c | 17 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 12 |
3 files changed, 19 insertions, 12 deletions
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 83c1bc8d2e8..456a304b817 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -299,6 +299,8 @@ do { \ #ifdef CONFIG_X86_32 +#define STACK_RND_MASK (0x7ff) + #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) #define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled) diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 16582960056..c8191defc38 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -29,13 +29,26 @@ #include <linux/random.h> #include <linux/limits.h> #include <linux/sched.h> +#include <asm/elf.h> + +static unsigned int stack_maxrandom_size(void) +{ + unsigned int max = 0; + if ((current->flags & PF_RANDOMIZE) && + !(current->personality & ADDR_NO_RANDOMIZE)) { + max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT; + } + + return max; +} + /* * Top of mmap area (just below the process stack). * - * Leave an at least ~128 MB hole. + * Leave an at least ~128 MB hole with possible stack randomization. */ -#define MIN_GAP (128*1024*1024) +#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size()) #define MAX_GAP (TASK_SIZE/6*5) /* diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index d7ebc3a10f2..7257cf3decf 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -424,17 +424,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, spin_lock(&memtype_lock); - entry = memtype_rb_search(&memtype_rbroot, new->start); - if (likely(entry != NULL)) { - /* To work correctly with list_for_each_entry_continue */ - entry = list_entry(entry->nd.prev, struct memtype, nd); - } else { - entry = list_entry(&memtype_list, struct memtype, nd); - } - /* Search for existing mapping that overlaps the current range */ where = NULL; - list_for_each_entry_continue(entry, &memtype_list, nd) { + list_for_each_entry(entry, &memtype_list, nd) { if (end <= entry->start) { where = entry->nd.prev; break; @@ -532,7 +524,7 @@ int free_memtype(u64 start, u64 end) * in sorted start address */ saved_entry = entry; - list_for_each_entry(entry, &memtype_list, nd) { + list_for_each_entry_from(entry, &memtype_list, nd) { if (entry->start == start && entry->end == end) { rb_erase(&entry->rb, &memtype_rbroot); list_del(&entry->nd); |