diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:57 -0500 |
commit | 7afe15b9d888050435cd154906828df88d4e667d (patch) | |
tree | b037a32fe517627380a811b814db57a9d911f3de /arch/x86/mm/pageattr_32.c | |
parent | 5508a7489659f1eed108d3ae7c2d36c8794ee330 (diff) |
x86: simplify cpa largepage split, #3
simplify cpa largepage split: push the reference protection bits
into the largepage-splitting function.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/mm/pageattr_32.c')
-rw-r--r-- | arch/x86/mm/pageattr_32.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c index ad0868bfa374..0966023dfd70 100644 --- a/arch/x86/mm/pageattr_32.c +++ b/arch/x86/mm/pageattr_32.c | |||
@@ -61,13 +61,13 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) | |||
61 | spin_unlock_irqrestore(&pgd_lock, flags); | 61 | spin_unlock_irqrestore(&pgd_lock, flags); |
62 | } | 62 | } |
63 | 63 | ||
64 | static int | 64 | static int split_large_page(pte_t *kpte, unsigned long address) |
65 | split_large_page(pte_t *kpte, unsigned long address, pgprot_t ref_prot) | ||
66 | { | 65 | { |
67 | int i, level; | 66 | pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte)); |
68 | unsigned long addr; | 67 | unsigned long addr; |
69 | pte_t *pbase, *tmp; | 68 | pte_t *pbase, *tmp; |
70 | struct page *base; | 69 | struct page *base; |
70 | int i, level; | ||
71 | 71 | ||
72 | base = alloc_pages(GFP_KERNEL, 0); | 72 | base = alloc_pages(GFP_KERNEL, 0); |
73 | if (!base) | 73 | if (!base) |
@@ -109,11 +109,9 @@ out_unlock: | |||
109 | 109 | ||
110 | static int __change_page_attr(struct page *page, pgprot_t prot) | 110 | static int __change_page_attr(struct page *page, pgprot_t prot) |
111 | { | 111 | { |
112 | pgprot_t ref_prot = PAGE_KERNEL; | ||
113 | struct page *kpte_page; | 112 | struct page *kpte_page; |
114 | unsigned long address; | 113 | unsigned long address; |
115 | int level, err = 0; | 114 | int level, err = 0; |
116 | pgprot_t oldprot; | ||
117 | pte_t *kpte; | 115 | pte_t *kpte; |
118 | 116 | ||
119 | BUG_ON(PageHighMem(page)); | 117 | BUG_ON(PageHighMem(page)); |
@@ -124,7 +122,6 @@ repeat: | |||
124 | if (!kpte) | 122 | if (!kpte) |
125 | return -EINVAL; | 123 | return -EINVAL; |
126 | 124 | ||
127 | oldprot = pte_pgprot(*kpte); | ||
128 | kpte_page = virt_to_page(kpte); | 125 | kpte_page = virt_to_page(kpte); |
129 | BUG_ON(PageLRU(kpte_page)); | 126 | BUG_ON(PageLRU(kpte_page)); |
130 | BUG_ON(PageCompound(kpte_page)); | 127 | BUG_ON(PageCompound(kpte_page)); |
@@ -137,16 +134,10 @@ repeat: | |||
137 | address < (unsigned long)&_etext && | 134 | address < (unsigned long)&_etext && |
138 | (pgprot_val(prot) & _PAGE_NX)); | 135 | (pgprot_val(prot) & _PAGE_NX)); |
139 | 136 | ||
140 | if ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext) | ||
141 | ref_prot = PAGE_KERNEL_EXEC; | ||
142 | |||
143 | ref_prot = canon_pgprot(ref_prot); | ||
144 | prot = canon_pgprot(prot); | ||
145 | |||
146 | if (level == 3) { | 137 | if (level == 3) { |
147 | set_pte_atomic(kpte, mk_pte(page, prot)); | 138 | set_pte_atomic(kpte, mk_pte(page, canon_pgprot(prot))); |
148 | } else { | 139 | } else { |
149 | err = split_large_page(kpte, address, ref_prot); | 140 | err = split_large_page(kpte, address); |
150 | if (!err) | 141 | if (!err) |
151 | goto repeat; | 142 | goto repeat; |
152 | } | 143 | } |