Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=07cf89c05f2bbafa002401ac4e09ac31678513e4 Commit: 07cf89c05f2bbafa002401ac4e09ac31678513e4 Parent: 31422c51e0dc72532d82e80895932d430c3ed307 Author: Thomas Gleixner <[EMAIL PROTECTED]> AuthorDate: Mon Feb 4 16:48:08 2008 +0100 Committer: Ingo Molnar <[EMAIL PROTECTED]> CommitDate: Mon Feb 4 16:48:08 2008 +0100
x86: CPA fix pagetable split Move the readout of the large entry into the spinlock section to prevent an unlikely but possible race. Mark the pmd/pud entry present after the split. We preserved the non present bit in the new split mapping. Remove the stale gfp_flags double initialization. Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]> Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]> --- arch/x86/mm/pageattr.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 74446ea..7288099 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -336,7 +336,7 @@ out_unlock: static int split_large_page(pte_t *kpte, unsigned long address) { - pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte)); + pgprot_t ref_prot; gfp_t gfp_flags = GFP_KERNEL; unsigned long flags, addr, pfn; pte_t *pbase, *tmp; @@ -344,7 +344,6 @@ static int split_large_page(pte_t *kpte, unsigned long address) unsigned int i, level; #ifdef CONFIG_DEBUG_PAGEALLOC - gfp_flags = __GFP_HIGH | __GFP_NOFAIL | __GFP_NOWARN; gfp_flags = GFP_ATOMIC | __GFP_NOWARN; #endif base = alloc_pages(gfp_flags, 0); @@ -368,6 +367,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) #ifdef CONFIG_X86_32 paravirt_alloc_pt(&init_mm, page_to_pfn(base)); #endif + ref_prot = pte_pgprot(pte_clrhuge(*kpte)); /* * Get the target pfn from the original entry: @@ -377,13 +377,17 @@ static int split_large_page(pte_t *kpte, unsigned long address) set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); /* - * Install the new, split up pagetable. Important detail here: + * Install the new, split up pagetable. Important details here: * * On Intel the NX bit of all levels must be cleared to make a * page executable. See section 4.13.2 of Intel 64 and IA-32 * Architectures Software Developer's Manual). + * + * Mark the entry present. The current mapping might be + * set to not present, which we preserved above. */ ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); + pgprot_val(ref_prot) |= _PAGE_PRESENT; __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); base = NULL; - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html