From: Toshi Kani <toshi.kani@hp.com>
To: hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com
Cc: akpm@linux-foundation.org, bp@alien8.de, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, x86@kernel.org, jgross@suse.com,
konrad.wilk@oracle.com, elliott@hp.com,
Toshi Kani <toshi.kani@hp.com>
Subject: [PATCH v4 10/11] x86/mm: Fix __split_large_page() to handle large PAT bit
Date: Tue, 25 Aug 2015 15:55:10 -0600 [thread overview]
Message-ID: <1440539711-2985-11-git-send-email-toshi.kani@hp.com> (raw)
In-Reply-To: <1440539711-2985-1-git-send-email-toshi.kani@hp.com>
__split_large_page() is called from __change_page_attr() to change
the mapping attribute by splitting a given large page into smaller
pages. This function uses pte_pfn() and pte_pgprot() for PUD/PMD,
which do not handle the large PAT bit properly.
Fix __split_large_page() by using the corresponding pud/pmd pfn/
pgprot interfaces.
Also remove '#ifdef CONFIG_X86_64', which is not necessary.
Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
arch/x86/mm/pageattr.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index d055557..b64a451 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -623,7 +623,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
struct page *base)
{
pte_t *pbase = (pte_t *)page_address(base);
- unsigned long pfn, pfninc = 1;
+ unsigned long ref_pfn, pfn, pfninc = 1;
unsigned int i, level;
pte_t *tmp;
pgprot_t ref_prot;
@@ -640,26 +640,33 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
}
paravirt_alloc_pte(&init_mm, page_to_pfn(base));
- ref_prot = pte_pgprot(pte_clrhuge(*kpte));
- /* promote PAT bit to correct position */
- if (level == PG_LEVEL_2M)
+ switch (level) {
+ case PG_LEVEL_2M:
+ ref_prot = pmd_pgprot(*(pmd_t *)kpte);
+ /* clear PSE and promote PAT bit to correct position */
ref_prot = pgprot_large_2_4k(ref_prot);
+ ref_pfn = pmd_pfn(*(pmd_t *)kpte);
+ break;
-#ifdef CONFIG_X86_64
- if (level == PG_LEVEL_1G) {
+ case PG_LEVEL_1G:
+ ref_prot = pud_pgprot(*(pud_t *)kpte);
+ ref_pfn = pud_pfn(*(pud_t *)kpte);
pfninc = PMD_PAGE_SIZE >> PAGE_SHIFT;
+
/*
- * Set the PSE flags only if the PRESENT flag is set
+ * Clear the PSE flags if the PRESENT flag is not set
* otherwise pmd_present/pmd_huge will return true
* even on a non present pmd.
*/
- if (pgprot_val(ref_prot) & _PAGE_PRESENT)
- pgprot_val(ref_prot) |= _PAGE_PSE;
- else
+ if (!(pgprot_val(ref_prot) & _PAGE_PRESENT))
pgprot_val(ref_prot) &= ~_PAGE_PSE;
+ break;
+
+ default:
+ spin_unlock(&pgd_lock);
+ return 1;
}
-#endif
/*
* Set the GLOBAL flags only if the PRESENT flag is set
@@ -675,7 +682,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
/*
* Get the target pfn from the original entry:
*/
- pfn = pte_pfn(*kpte);
+ pfn = ref_pfn;
for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc)
set_pte(&pbase[i], pfn_pte(pfn, canon_pgprot(ref_prot)));
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2015-08-25 21:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 21:55 [PATCH v4 0/11] x86/mm: Handle large PAT bit in pud/pmd interfaces Toshi Kani
2015-08-25 21:55 ` [PATCH v4 1/11] x86/vdso32: Define PGTABLE_LEVELS to 32bit VDSO Toshi Kani
2015-08-25 21:55 ` [PATCH v4 2/11] x86/asm: Move PUD_PAGE macros to page_types.h Toshi Kani
2015-08-25 21:55 ` [PATCH v4 3/11] x86/asm: Add pud/pmd mask interfaces to handle large PAT bit Toshi Kani
2015-08-25 21:55 ` [PATCH v4 4/11] x86/asm: Fix pud/pmd " Toshi Kani
2015-08-25 21:55 ` [PATCH v4 5/11] x86/asm: Add pud_pgprot() and pmd_pgprot() Toshi Kani
2015-08-25 21:55 ` [PATCH v4 6/11] x86/mm: Fix page table dump to show PAT bit Toshi Kani
2015-08-25 21:55 ` [PATCH v4 7/11] x86/mm: Fix slow_virt_to_phys() to handle large " Toshi Kani
2015-08-25 21:55 ` [PATCH v4 8/11] x86/mm: Fix gup_huge_p?d() " Toshi Kani
2015-08-25 21:55 ` [PATCH v4 9/11] x86/mm: Fix try_preserve_large_page() " Toshi Kani
2015-08-25 21:55 ` Toshi Kani [this message]
2015-08-25 21:55 ` [PATCH v4 11/11] x86/mm: Fix no-change case in try_preserve_large_page() Toshi Kani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1440539711-2985-11-git-send-email-toshi.kani@hp.com \
--to=toshi.kani@hp.com \
--cc=akpm@linux-foundation.org \
--cc=bp@alien8.de \
--cc=elliott@hp.com \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=konrad.wilk@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).