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

Reply via email to