Commit 895bdc29 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar

x86: c_p_a() make it more robust against use of PAT bits

Use the page table level instead of the PSE bit to check if the PTE
is for a 4K page or not. This makes the code more robust when the PAT
bit is changed because the PAT bit on 4K pages is in the same position
as the PSE bit.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Acked-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 3c868823
...@@ -172,7 +172,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) ...@@ -172,7 +172,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
BUG_ON(PageCompound(kpte_page)); BUG_ON(PageCompound(kpte_page));
if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
if (!pte_huge(*kpte)) { if (level == 3) {
set_pte_atomic(kpte, mk_pte(page, prot)); set_pte_atomic(kpte, mk_pte(page, prot));
} else { } else {
struct page *split; struct page *split;
...@@ -190,7 +190,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) ...@@ -190,7 +190,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
} }
page_private(kpte_page)++; page_private(kpte_page)++;
} else { } else {
if (!pte_huge(*kpte)) { if (level == 3) {
set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
BUG_ON(page_private(kpte_page) == 0); BUG_ON(page_private(kpte_page) == 0);
page_private(kpte_page)--; page_private(kpte_page)--;
......
...@@ -153,7 +153,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, ...@@ -153,7 +153,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
BUG_ON(PageLRU(kpte_page)); BUG_ON(PageLRU(kpte_page));
BUG_ON(PageCompound(kpte_page)); BUG_ON(PageCompound(kpte_page));
if (pgprot_val(prot) != pgprot_val(ref_prot)) { if (pgprot_val(prot) != pgprot_val(ref_prot)) {
if (!pte_huge(*kpte)) { if (level == 4) {
set_pte(kpte, pfn_pte(pfn, prot)); set_pte(kpte, pfn_pte(pfn, prot));
} else { } else {
/* /*
...@@ -172,7 +172,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, ...@@ -172,7 +172,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
} }
page_private(kpte_page)++; page_private(kpte_page)++;
} else { } else {
if (!pte_huge(*kpte)) { if (level == 4) {
set_pte(kpte, pfn_pte(pfn, ref_prot)); set_pte(kpte, pfn_pte(pfn, ref_prot));
BUG_ON(page_private(kpte_page) == 0); BUG_ON(page_private(kpte_page) == 0);
page_private(kpte_page)--; page_private(kpte_page)--;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment