diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb.c | 2 | ||||
-rw-r--r-- | mm/mmap.c | 8 | ||||
-rw-r--r-- | mm/nommu.c | 30 |
3 files changed, 34 insertions, 6 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bbf953eeb58b..ab171274ef21 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -785,7 +785,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
785 | continue; | 785 | continue; |
786 | 786 | ||
787 | spin_lock(&dst->page_table_lock); | 787 | spin_lock(&dst->page_table_lock); |
788 | spin_lock(&src->page_table_lock); | 788 | spin_lock_nested(&src->page_table_lock, SINGLE_DEPTH_NESTING); |
789 | if (!huge_pte_none(huge_ptep_get(src_pte))) { | 789 | if (!huge_pte_none(huge_ptep_get(src_pte))) { |
790 | if (cow) | 790 | if (cow) |
791 | huge_ptep_set_wrprotect(src, addr, src_pte); | 791 | huge_ptep_set_wrprotect(src, addr, src_pte); |
@@ -245,10 +245,16 @@ asmlinkage unsigned long sys_brk(unsigned long brk) | |||
245 | unsigned long rlim, retval; | 245 | unsigned long rlim, retval; |
246 | unsigned long newbrk, oldbrk; | 246 | unsigned long newbrk, oldbrk; |
247 | struct mm_struct *mm = current->mm; | 247 | struct mm_struct *mm = current->mm; |
248 | unsigned long min_brk; | ||
248 | 249 | ||
249 | down_write(&mm->mmap_sem); | 250 | down_write(&mm->mmap_sem); |
250 | 251 | ||
251 | if (brk < mm->start_brk) | 252 | #ifdef CONFIG_COMPAT_BRK |
253 | min_brk = mm->end_code; | ||
254 | #else | ||
255 | min_brk = mm->start_brk; | ||
256 | #endif | ||
257 | if (brk < min_brk) | ||
252 | goto out; | 258 | goto out; |
253 | 259 | ||
254 | /* | 260 | /* |
diff --git a/mm/nommu.c b/mm/nommu.c index dca93fcb8b7a..3abd0845bda4 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -104,21 +104,43 @@ EXPORT_SYMBOL(vmtruncate); | |||
104 | unsigned int kobjsize(const void *objp) | 104 | unsigned int kobjsize(const void *objp) |
105 | { | 105 | { |
106 | struct page *page; | 106 | struct page *page; |
107 | int order = 0; | ||
107 | 108 | ||
108 | /* | 109 | /* |
109 | * If the object we have should not have ksize performed on it, | 110 | * If the object we have should not have ksize performed on it, |
110 | * return size of 0 | 111 | * return size of 0 |
111 | */ | 112 | */ |
112 | if (!objp || (unsigned long)objp >= memory_end || !((page = virt_to_page(objp)))) | 113 | if (!objp) |
113 | return 0; | 114 | return 0; |
114 | 115 | ||
116 | if ((unsigned long)objp >= memory_end) | ||
117 | return 0; | ||
118 | |||
119 | page = virt_to_head_page(objp); | ||
120 | if (!page) | ||
121 | return 0; | ||
122 | |||
123 | /* | ||
124 | * If the allocator sets PageSlab, we know the pointer came from | ||
125 | * kmalloc(). | ||
126 | */ | ||
115 | if (PageSlab(page)) | 127 | if (PageSlab(page)) |
116 | return ksize(objp); | 128 | return ksize(objp); |
117 | 129 | ||
118 | BUG_ON(page->index < 0); | 130 | /* |
119 | BUG_ON(page->index >= MAX_ORDER); | 131 | * The ksize() function is only guaranteed to work for pointers |
132 | * returned by kmalloc(). So handle arbitrary pointers, that we expect | ||
133 | * always to be compound pages, here. | ||
134 | */ | ||
135 | if (PageCompound(page)) | ||
136 | order = compound_order(page); | ||
120 | 137 | ||
121 | return (PAGE_SIZE << page->index); | 138 | /* |
139 | * Finally, handle arbitrary pointers that don't set PageSlab. | ||
140 | * Default to 0-order in the case when we're unable to ksize() | ||
141 | * the object. | ||
142 | */ | ||
143 | return PAGE_SIZE << order; | ||
122 | } | 144 | } |
123 | 145 | ||
124 | /* | 146 | /* |