Commit 5e6b0bfe5b452957b7be4b6ef181cd41880f8359
Committed by
Andi Kleen
1 parent
df992848f5
Exists in
master
and in
4 other branches
[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>
Showing 2 changed files with 7 additions and 10 deletions Side-by-side Diff
arch/x86_64/mm/pageattr.c
| ... | ... | @@ -108,8 +108,8 @@ |
| 108 | 108 | BUG_ON(pud_none(*pud)); |
| 109 | 109 | pmd = pmd_offset(pud, address); |
| 110 | 110 | BUG_ON(pmd_val(*pmd) & _PAGE_PSE); |
| 111 | - pgprot_val(ref_prot) |= _PAGE_PSE; | |
| 112 | 111 | large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); |
| 112 | + large_pte = pte_mkhuge(large_pte); | |
| 113 | 113 | set_pte((pte_t *)pmd, large_pte); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | |
| 117 | 117 | |
| 118 | 118 | |
| 119 | 119 | |
| 120 | 120 | |
| 121 | 121 | |
| 122 | 122 | |
| ... | ... | @@ -119,32 +119,28 @@ |
| 119 | 119 | { |
| 120 | 120 | pte_t *kpte; |
| 121 | 121 | struct page *kpte_page; |
| 122 | - unsigned kpte_flags; | |
| 123 | 122 | pgprot_t ref_prot2; |
| 124 | 123 | kpte = lookup_address(address); |
| 125 | 124 | if (!kpte) return 0; |
| 126 | 125 | kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); |
| 127 | - kpte_flags = pte_val(*kpte); | |
| 128 | 126 | if (pgprot_val(prot) != pgprot_val(ref_prot)) { |
| 129 | - if ((kpte_flags & _PAGE_PSE) == 0) { | |
| 127 | + if (!pte_huge(*kpte)) { | |
| 130 | 128 | set_pte(kpte, pfn_pte(pfn, prot)); |
| 131 | 129 | } else { |
| 132 | 130 | /* |
| 133 | 131 | * split_large_page will take the reference for this |
| 134 | 132 | * change_page_attr on the split page. |
| 135 | 133 | */ |
| 136 | - | |
| 137 | 134 | struct page *split; |
| 138 | - ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); | |
| 139 | - | |
| 135 | + ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); | |
| 140 | 136 | split = split_large_page(address, prot, ref_prot2); |
| 141 | 137 | if (!split) |
| 142 | 138 | return -ENOMEM; |
| 143 | - set_pte(kpte,mk_pte(split, ref_prot2)); | |
| 139 | + set_pte(kpte, mk_pte(split, ref_prot2)); | |
| 144 | 140 | kpte_page = split; |
| 145 | - } | |
| 141 | + } | |
| 146 | 142 | page_private(kpte_page)++; |
| 147 | - } else if ((kpte_flags & _PAGE_PSE) == 0) { | |
| 143 | + } else if (!pte_huge(*kpte)) { | |
| 148 | 144 | set_pte(kpte, pfn_pte(pfn, ref_prot)); |
| 149 | 145 | BUG_ON(page_private(kpte_page) == 0); |
| 150 | 146 | page_private(kpte_page)--; |
include/asm-x86_64/pgtable.h
| ... | ... | @@ -283,6 +283,7 @@ |
| 283 | 283 | static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } |
| 284 | 284 | static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } |
| 285 | 285 | static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_PSE)); return pte; } |
| 286 | +static inline pte_t pte_clrhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_PSE)); return pte; } | |
| 286 | 287 | |
| 287 | 288 | struct vm_area_struct; |
| 288 | 289 |