Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Sep 2009 03:58:11 +0000 (20:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Sep 2009 03:58:11 +0000 (20:58 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, pat: don't use rb-tree based lookup in reserve_memtype()
  x86: Increase MIN_GAP to include randomized stack

arch/x86/include/asm/elf.h
arch/x86/mm/mmap.c
arch/x86/mm/pat.c

index 83c1bc8d2e8a7ba071cdd591050bbd45e7cf678a..456a304b817266320ad59d6f6b49419ea4e1aa15 100644 (file)
@@ -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)
index 1658296005668d7cb1013751d45cac1e4a22b15d..c8191defc38a36f16ae60245a60f781229169d06 100644 (file)
 #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)
 
 /*
index d7ebc3a10f2f1aa96aa00913e4b3f2472149facc..7257cf3decf9455ccb52f8f06bd28bc84a7f57ec 100644 (file)
@@ -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);