Skip to content

Commit

Permalink
x86, pat: add large-PAT check to split_large_page()
Browse files Browse the repository at this point in the history
Impact: future-proof the split_large_page() function

Linus noticed that split_large_page() is not safe wrt. the
PAT bit: it is bit 12 on the 1GB and 2MB page table level
(_PAGE_BIT_PAT_LARGE), and it is bit 7 on the 4K page
table level (_PAGE_BIT_PAT).

Currently it is not a problem because we never set
_PAGE_BIT_PAT_LARGE on any of the large-page mappings - but
should this happen in the future the split_large_page() would
silently lift bit 12 into the lowlevel 4K pte and would start
corrupting the physical page frame offset. Not fun.

So add a debug warning, to make sure if something ever sets
the PAT bit then this function gets updated too.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Ingo Molnar committed Feb 20, 2009
1 parent 6091628 commit 7a5714e
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions arch/x86/mm/pageattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,13 @@ static int split_large_page(pte_t *kpte, unsigned long address)
pbase = (pte_t *)page_address(base);
paravirt_alloc_pte(&init_mm, page_to_pfn(base));
ref_prot = pte_pgprot(pte_clrhuge(*kpte));
/*
* If we ever want to utilize the PAT bit, we need to
* update this function to make sure it's converted from
* bit 12 to bit 7 when we cross from the 2MB level to
* the 4K level:
*/
WARN_ON_ONCE(pgprot_val(ref_prot) & _PAGE_PAT_LARGE);

#ifdef CONFIG_X86_64
if (level == PG_LEVEL_1G) {
Expand Down

0 comments on commit 7a5714e

Please sign in to comment.