diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/mm/memory.c b/mm/memory.c index 692ad810263d..95a4553c75f7 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -307,28 +307,22 @@ out: | |||
307 | return pte_offset_map(pmd, address); | 307 | return pte_offset_map(pmd, address); |
308 | } | 308 | } |
309 | 309 | ||
310 | pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address) | 310 | pte_t fastcall * pte_alloc_kernel(pmd_t *pmd, unsigned long address) |
311 | { | 311 | { |
312 | if (!pmd_present(*pmd)) { | 312 | if (!pmd_present(*pmd)) { |
313 | pte_t *new; | 313 | pte_t *new; |
314 | 314 | ||
315 | spin_unlock(&mm->page_table_lock); | 315 | new = pte_alloc_one_kernel(&init_mm, address); |
316 | new = pte_alloc_one_kernel(mm, address); | ||
317 | spin_lock(&mm->page_table_lock); | ||
318 | if (!new) | 316 | if (!new) |
319 | return NULL; | 317 | return NULL; |
320 | 318 | ||
321 | /* | 319 | spin_lock(&init_mm.page_table_lock); |
322 | * Because we dropped the lock, we should re-check the | 320 | if (pmd_present(*pmd)) |
323 | * entry, as somebody else could have populated it.. | ||
324 | */ | ||
325 | if (pmd_present(*pmd)) { | ||
326 | pte_free_kernel(new); | 321 | pte_free_kernel(new); |
327 | goto out; | 322 | else |
328 | } | 323 | pmd_populate_kernel(&init_mm, pmd, new); |
329 | pmd_populate_kernel(mm, pmd, new); | 324 | spin_unlock(&init_mm.page_table_lock); |
330 | } | 325 | } |
331 | out: | ||
332 | return pte_offset_kernel(pmd, address); | 326 | return pte_offset_kernel(pmd, address); |
333 | } | 327 | } |
334 | 328 | ||
@@ -2097,30 +2091,30 @@ int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2097 | #ifndef __PAGETABLE_PUD_FOLDED | 2091 | #ifndef __PAGETABLE_PUD_FOLDED |
2098 | /* | 2092 | /* |
2099 | * Allocate page upper directory. | 2093 | * Allocate page upper directory. |
2100 | * | 2094 | * We've already handled the fast-path in-line. |
2101 | * We've already handled the fast-path in-line, and we own the | ||
2102 | * page table lock. | ||
2103 | */ | 2095 | */ |
2104 | pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) | 2096 | pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) |
2105 | { | 2097 | { |
2106 | pud_t *new; | 2098 | pud_t *new; |
2107 | 2099 | ||
2108 | spin_unlock(&mm->page_table_lock); | 2100 | if (mm != &init_mm) /* Temporary bridging hack */ |
2101 | spin_unlock(&mm->page_table_lock); | ||
2109 | new = pud_alloc_one(mm, address); | 2102 | new = pud_alloc_one(mm, address); |
2110 | spin_lock(&mm->page_table_lock); | 2103 | if (!new) { |
2111 | if (!new) | 2104 | if (mm != &init_mm) /* Temporary bridging hack */ |
2105 | spin_lock(&mm->page_table_lock); | ||
2112 | return NULL; | 2106 | return NULL; |
2107 | } | ||
2113 | 2108 | ||
2114 | /* | 2109 | spin_lock(&mm->page_table_lock); |
2115 | * Because we dropped the lock, we should re-check the | ||
2116 | * entry, as somebody else could have populated it.. | ||
2117 | */ | ||
2118 | if (pgd_present(*pgd)) { | 2110 | if (pgd_present(*pgd)) { |
2119 | pud_free(new); | 2111 | pud_free(new); |
2120 | goto out; | 2112 | goto out; |
2121 | } | 2113 | } |
2122 | pgd_populate(mm, pgd, new); | 2114 | pgd_populate(mm, pgd, new); |
2123 | out: | 2115 | out: |
2116 | if (mm == &init_mm) /* Temporary bridging hack */ | ||
2117 | spin_unlock(&mm->page_table_lock); | ||
2124 | return pud_offset(pgd, address); | 2118 | return pud_offset(pgd, address); |
2125 | } | 2119 | } |
2126 | #endif /* __PAGETABLE_PUD_FOLDED */ | 2120 | #endif /* __PAGETABLE_PUD_FOLDED */ |
@@ -2128,24 +2122,22 @@ pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long addr | |||
2128 | #ifndef __PAGETABLE_PMD_FOLDED | 2122 | #ifndef __PAGETABLE_PMD_FOLDED |
2129 | /* | 2123 | /* |
2130 | * Allocate page middle directory. | 2124 | * Allocate page middle directory. |
2131 | * | 2125 | * We've already handled the fast-path in-line. |
2132 | * We've already handled the fast-path in-line, and we own the | ||
2133 | * page table lock. | ||
2134 | */ | 2126 | */ |
2135 | pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) | 2127 | pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) |
2136 | { | 2128 | { |
2137 | pmd_t *new; | 2129 | pmd_t *new; |
2138 | 2130 | ||
2139 | spin_unlock(&mm->page_table_lock); | 2131 | if (mm != &init_mm) /* Temporary bridging hack */ |
2132 | spin_unlock(&mm->page_table_lock); | ||
2140 | new = pmd_alloc_one(mm, address); | 2133 | new = pmd_alloc_one(mm, address); |
2141 | spin_lock(&mm->page_table_lock); | 2134 | if (!new) { |
2142 | if (!new) | 2135 | if (mm != &init_mm) /* Temporary bridging hack */ |
2136 | spin_lock(&mm->page_table_lock); | ||
2143 | return NULL; | 2137 | return NULL; |
2138 | } | ||
2144 | 2139 | ||
2145 | /* | 2140 | spin_lock(&mm->page_table_lock); |
2146 | * Because we dropped the lock, we should re-check the | ||
2147 | * entry, as somebody else could have populated it.. | ||
2148 | */ | ||
2149 | #ifndef __ARCH_HAS_4LEVEL_HACK | 2141 | #ifndef __ARCH_HAS_4LEVEL_HACK |
2150 | if (pud_present(*pud)) { | 2142 | if (pud_present(*pud)) { |
2151 | pmd_free(new); | 2143 | pmd_free(new); |
@@ -2161,6 +2153,8 @@ pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr | |||
2161 | #endif /* __ARCH_HAS_4LEVEL_HACK */ | 2153 | #endif /* __ARCH_HAS_4LEVEL_HACK */ |
2162 | 2154 | ||
2163 | out: | 2155 | out: |
2156 | if (mm == &init_mm) /* Temporary bridging hack */ | ||
2157 | spin_unlock(&mm->page_table_lock); | ||
2164 | return pmd_offset(pud, address); | 2158 | return pmd_offset(pud, address); |
2165 | } | 2159 | } |
2166 | #endif /* __PAGETABLE_PMD_FOLDED */ | 2160 | #endif /* __PAGETABLE_PMD_FOLDED */ |