diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-09-03 18:57:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:24 -0400 |
commit | 7ef939054139ef857cebbec07cbd12d7cf7beedd (patch) | |
tree | c6e1c0722336b6155b0f7cf985b2ea4eb9c5d9e1 | |
parent | f9dfefe423a7633d81310c7b06c5566c74f9167b (diff) |
[PATCH] uml: fix x86_64 page leak
We were leaking pmd pages when 3_LEVEL_PGTABLES was enabled. This fixes that.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/um/kernel/skas/include/mmu-skas.h | 4 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 9 | ||||
-rw-r--r-- | include/asm-um/pgalloc.h | 12 | ||||
-rw-r--r-- | include/asm-um/pgtable-3level.h | 9 |
4 files changed, 22 insertions, 12 deletions
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h index 278b72f1d9ad..09536f81ee42 100644 --- a/arch/um/kernel/skas/include/mmu-skas.h +++ b/arch/um/kernel/skas/include/mmu-skas.h | |||
@@ -6,11 +6,15 @@ | |||
6 | #ifndef __SKAS_MMU_H | 6 | #ifndef __SKAS_MMU_H |
7 | #define __SKAS_MMU_H | 7 | #define __SKAS_MMU_H |
8 | 8 | ||
9 | #include "linux/config.h" | ||
9 | #include "mm_id.h" | 10 | #include "mm_id.h" |
10 | 11 | ||
11 | struct mmu_context_skas { | 12 | struct mmu_context_skas { |
12 | struct mm_id id; | 13 | struct mm_id id; |
13 | unsigned long last_page_table; | 14 | unsigned long last_page_table; |
15 | #ifdef CONFIG_3_LEVEL_PGTABLES | ||
16 | unsigned long last_pmd; | ||
17 | #endif | ||
14 | }; | 18 | }; |
15 | 19 | ||
16 | extern void switch_mm_skas(struct mm_id * mm_idp); | 20 | extern void switch_mm_skas(struct mm_id * mm_idp); |
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index d837223e22af..240143b616a2 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
@@ -56,6 +56,9 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
56 | */ | 56 | */ |
57 | 57 | ||
58 | mm->context.skas.last_page_table = pmd_page_kernel(*pmd); | 58 | mm->context.skas.last_page_table = pmd_page_kernel(*pmd); |
59 | #ifdef CONFIG_3_LEVEL_PGTABLES | ||
60 | mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); | ||
61 | #endif | ||
59 | 62 | ||
60 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); | 63 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); |
61 | *pte = pte_mkexec(*pte); | 64 | *pte = pte_mkexec(*pte); |
@@ -144,6 +147,10 @@ void destroy_context_skas(struct mm_struct *mm) | |||
144 | 147 | ||
145 | if(!proc_mm || !ptrace_faultinfo){ | 148 | if(!proc_mm || !ptrace_faultinfo){ |
146 | free_page(mmu->id.stack); | 149 | free_page(mmu->id.stack); |
147 | free_page(mmu->last_page_table); | 150 | pte_free_kernel((pte_t *) mmu->last_page_table); |
151 | dec_page_state(nr_page_table_pages); | ||
152 | #ifdef CONFIG_3_LEVEL_PGTABLES | ||
153 | pmd_free((pmd_t *) mmu->last_pmd); | ||
154 | #endif | ||
148 | } | 155 | } |
149 | } | 156 | } |
diff --git a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h index 8fcb2fc0a892..ea49411236dc 100644 --- a/include/asm-um/pgalloc.h +++ b/include/asm-um/pgalloc.h | |||
@@ -42,11 +42,13 @@ static inline void pte_free(struct page *pte) | |||
42 | #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) | 42 | #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) |
43 | 43 | ||
44 | #ifdef CONFIG_3_LEVEL_PGTABLES | 44 | #ifdef CONFIG_3_LEVEL_PGTABLES |
45 | /* | 45 | |
46 | * In the 3-level case we free the pmds as part of the pgd. | 46 | extern __inline__ void pmd_free(pmd_t *pmd) |
47 | */ | 47 | { |
48 | #define pmd_free(x) do { } while (0) | 48 | free_page((unsigned long)pmd); |
49 | #define __pmd_free_tlb(tlb,x) do { } while (0) | 49 | } |
50 | |||
51 | #define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) | ||
50 | #endif | 52 | #endif |
51 | 53 | ||
52 | #define check_pgt_cache() do { } while (0) | 54 | #define check_pgt_cache() do { } while (0) |
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h index 32cd6236f245..786c25727289 100644 --- a/include/asm-um/pgtable-3level.h +++ b/include/asm-um/pgtable-3level.h | |||
@@ -69,14 +69,11 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |||
69 | return pmd; | 69 | return pmd; |
70 | } | 70 | } |
71 | 71 | ||
72 | static inline void pmd_free(pmd_t *pmd){ | 72 | extern inline void pud_clear (pud_t *pud) |
73 | free_page((unsigned long) pmd); | 73 | { |
74 | set_pud(pud, __pud(0)); | ||
74 | } | 75 | } |
75 | 76 | ||
76 | #define __pmd_free_tlb(tlb,x) do { } while (0) | ||
77 | |||
78 | static inline void pud_clear (pud_t * pud) { } | ||
79 | |||
80 | #define pud_page(pud) \ | 77 | #define pud_page(pud) \ |
81 | ((struct page *) __va(pud_val(pud) & PAGE_MASK)) | 78 | ((struct page *) __va(pud_val(pud) & PAGE_MASK)) |
82 | 79 | ||