diff options
author | Andi Kleen <ak@suse.de> | 2006-09-26 04:52:37 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:37 -0400 |
commit | 5e6b0bfe5b452957b7be4b6ef181cd41880f8359 (patch) | |
tree | 58fe6fa071e8a6870f4241217b18e181481c5c1e /arch | |
parent | df992848f5aa803fcacd2c5e7d67034bb89e3fa3 (diff) |
[PATCH] Use proper accessors to change PSE bits in change_page_attr()
Use normal pte accessors in change_page_attr() to access the PSE
bits.
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/mm/pageattr.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 01591b649f4e..3e231d762aaa 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c | |||
@@ -108,8 +108,8 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) | |||
108 | BUG_ON(pud_none(*pud)); | 108 | BUG_ON(pud_none(*pud)); |
109 | pmd = pmd_offset(pud, address); | 109 | pmd = pmd_offset(pud, address); |
110 | BUG_ON(pmd_val(*pmd) & _PAGE_PSE); | 110 | BUG_ON(pmd_val(*pmd) & _PAGE_PSE); |
111 | pgprot_val(ref_prot) |= _PAGE_PSE; | ||
112 | large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); | 111 | large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); |
112 | large_pte = pte_mkhuge(large_pte); | ||
113 | set_pte((pte_t *)pmd, large_pte); | 113 | set_pte((pte_t *)pmd, large_pte); |
114 | } | 114 | } |
115 | 115 | ||
@@ -119,32 +119,28 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, | |||
119 | { | 119 | { |
120 | pte_t *kpte; | 120 | pte_t *kpte; |
121 | struct page *kpte_page; | 121 | struct page *kpte_page; |
122 | unsigned kpte_flags; | ||
123 | pgprot_t ref_prot2; | 122 | pgprot_t ref_prot2; |
124 | kpte = lookup_address(address); | 123 | kpte = lookup_address(address); |
125 | if (!kpte) return 0; | 124 | if (!kpte) return 0; |
126 | kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); | 125 | kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); |
127 | kpte_flags = pte_val(*kpte); | ||
128 | if (pgprot_val(prot) != pgprot_val(ref_prot)) { | 126 | if (pgprot_val(prot) != pgprot_val(ref_prot)) { |
129 | if ((kpte_flags & _PAGE_PSE) == 0) { | 127 | if (!pte_huge(*kpte)) { |
130 | set_pte(kpte, pfn_pte(pfn, prot)); | 128 | set_pte(kpte, pfn_pte(pfn, prot)); |
131 | } else { | 129 | } else { |
132 | /* | 130 | /* |
133 | * split_large_page will take the reference for this | 131 | * split_large_page will take the reference for this |
134 | * change_page_attr on the split page. | 132 | * change_page_attr on the split page. |
135 | */ | 133 | */ |
136 | |||
137 | struct page *split; | 134 | struct page *split; |
138 | ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); | 135 | ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); |
139 | |||
140 | split = split_large_page(address, prot, ref_prot2); | 136 | split = split_large_page(address, prot, ref_prot2); |
141 | if (!split) | 137 | if (!split) |
142 | return -ENOMEM; | 138 | return -ENOMEM; |
143 | set_pte(kpte,mk_pte(split, ref_prot2)); | 139 | set_pte(kpte, mk_pte(split, ref_prot2)); |
144 | kpte_page = split; | 140 | kpte_page = split; |
145 | } | 141 | } |
146 | page_private(kpte_page)++; | 142 | page_private(kpte_page)++; |
147 | } else if ((kpte_flags & _PAGE_PSE) == 0) { | 143 | } else if (!pte_huge(*kpte)) { |
148 | set_pte(kpte, pfn_pte(pfn, ref_prot)); | 144 | set_pte(kpte, pfn_pte(pfn, ref_prot)); |
149 | BUG_ON(page_private(kpte_page) == 0); | 145 | BUG_ON(page_private(kpte_page) == 0); |
150 | page_private(kpte_page)--; | 146 | page_private(kpte_page)--; |