aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/pageattr.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 6c55fbdbd7e..a629cea5e46 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -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: