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 | |
| 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>
| -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 | } |
