diff options
| -rw-r--r-- | 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 74446ea23ffb..72880993af89 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -336,7 +336,7 @@ out_unlock: | |||
| 336 | 336 | ||
| 337 | static int split_large_page(pte_t *kpte, unsigned long address) | 337 | static int split_large_page(pte_t *kpte, unsigned long address) |
| 338 | { | 338 | { |
| 339 | pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte)); | 339 | pgprot_t ref_prot; |
| 340 | gfp_t gfp_flags = GFP_KERNEL; | 340 | gfp_t gfp_flags = GFP_KERNEL; |
| 341 | unsigned long flags, addr, pfn; | 341 | unsigned long flags, addr, pfn; |
| 342 | pte_t *pbase, *tmp; | 342 | pte_t *pbase, *tmp; |
| @@ -344,7 +344,6 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 344 | unsigned int i, level; | 344 | unsigned int i, level; |
| 345 | 345 | ||
| 346 | #ifdef CONFIG_DEBUG_PAGEALLOC | 346 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 347 | gfp_flags = __GFP_HIGH | __GFP_NOFAIL | __GFP_NOWARN; | ||
| 348 | gfp_flags = GFP_ATOMIC | __GFP_NOWARN; | 347 | gfp_flags = GFP_ATOMIC | __GFP_NOWARN; |
| 349 | #endif | 348 | #endif |
| 350 | base = alloc_pages(gfp_flags, 0); | 349 | base = alloc_pages(gfp_flags, 0); |
| @@ -368,6 +367,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 368 | #ifdef CONFIG_X86_32 | 367 | #ifdef CONFIG_X86_32 |
| 369 | paravirt_alloc_pt(&init_mm, page_to_pfn(base)); | 368 | paravirt_alloc_pt(&init_mm, page_to_pfn(base)); |
| 370 | #endif | 369 | #endif |
| 370 | ref_prot = pte_pgprot(pte_clrhuge(*kpte)); | ||
| 371 | 371 | ||
| 372 | /* | 372 | /* |
| 373 | * Get the target pfn from the original entry: | 373 | * Get the target pfn from the original entry: |
| @@ -377,13 +377,17 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 377 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); | 377 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); |
| 378 | 378 | ||
| 379 | /* | 379 | /* |
| 380 | * Install the new, split up pagetable. Important detail here: | 380 | * Install the new, split up pagetable. Important details here: |
| 381 | * | 381 | * |
| 382 | * On Intel the NX bit of all levels must be cleared to make a | 382 | * On Intel the NX bit of all levels must be cleared to make a |
| 383 | * page executable. See section 4.13.2 of Intel 64 and IA-32 | 383 | * page executable. See section 4.13.2 of Intel 64 and IA-32 |
| 384 | * Architectures Software Developer's Manual). | 384 | * Architectures Software Developer's Manual). |
| 385 | * | ||
| 386 | * Mark the entry present. The current mapping might be | ||
| 387 | * set to not present, which we preserved above. | ||
| 385 | */ | 388 | */ |
| 386 | ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); | 389 | ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); |
| 390 | pgprot_val(ref_prot) |= _PAGE_PRESENT; | ||
| 387 | __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); | 391 | __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); |
| 388 | base = NULL; | 392 | base = NULL; |
| 389 | 393 | ||
