x86: CPA use the existing pfn in split as well
authorThomas Gleixner <tglx@linutronix.de>
Mon, 4 Feb 2008 15:48:05 +0000 (16:48 +0100)
committerIngo Molnar <mingo@elte.hu>
Mon, 4 Feb 2008 15:48:05 +0000 (16:48 +0100)
When splitting large pages, we ge the pfn from the existing entry
instead of calculating it ourself.

This removes the last remaining range restriction of the cpa code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/mm/pageattr.c

index 6c55fbd..a629cea 100644 (file)
@@ -221,8 +221,7 @@ static int split_large_page(pte_t *kpte, unsigned long address)
 {
        pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte));
        gfp_t gfp_flags = GFP_KERNEL;
-       unsigned long flags;
-       unsigned long addr;
+       unsigned long flags, addr, pfn;
        pte_t *pbase, *tmp;
        struct page *base;
        unsigned int i, level;
@@ -253,8 +252,12 @@ static int split_large_page(pte_t *kpte, unsigned long address)
        paravirt_alloc_pt(&init_mm, page_to_pfn(base));
 #endif
 
-       for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE)
-               set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT, ref_prot));
+       /*
+        * Get the target pfn from the original entry:
+        */
+       pfn = pte_pfn(*kpte);
+       for (i = 0; i < PTRS_PER_PTE; i++, pfn++)
+               set_pte(&pbase[i], pfn_pte(pfn, ref_prot));
 
        /*
         * Install the new, split up pagetable. Important detail here: