aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/init_32.c1
-rw-r--r--arch/x86/mm/init_64.c1
-rw-r--r--arch/x86/mm/pageattr.c19
-rw-r--r--arch/x86/mm/pat.c3
4 files changed, 21 insertions, 3 deletions
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index b5a0fd5f4c5f..029e8cffca9e 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -50,6 +50,7 @@
50 50
51unsigned int __VMALLOC_RESERVE = 128 << 20; 51unsigned int __VMALLOC_RESERVE = 128 << 20;
52 52
53unsigned long max_low_pfn_mapped;
53unsigned long max_pfn_mapped; 54unsigned long max_pfn_mapped;
54 55
55DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 56DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 48548ef7ddf8..122bcef222fc 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -53,6 +53,7 @@
53 * The direct mapping extends to max_pfn_mapped, so that we can directly access 53 * The direct mapping extends to max_pfn_mapped, so that we can directly access
54 * apertures, ACPI and other tables without having to play with fixmaps. 54 * apertures, ACPI and other tables without having to play with fixmaps.
55 */ 55 */
56unsigned long max_low_pfn_mapped;
56unsigned long max_pfn_mapped; 57unsigned long max_pfn_mapped;
57 58
58static unsigned long dma_reserve __initdata; 59static unsigned long dma_reserve __initdata;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index afd40054d157..0389cb8f6b1a 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -536,8 +536,14 @@ static int split_large_page(pte_t *kpte, unsigned long address)
536 set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); 536 set_pte(&pbase[i], pfn_pte(pfn, ref_prot));
537 537
538 if (address >= (unsigned long)__va(0) && 538 if (address >= (unsigned long)__va(0) &&
539 address < (unsigned long)__va(max_low_pfn_mapped << PAGE_SHIFT))
540 split_page_count(level);
541
542#ifdef CONFIG_X86_64
543 if (address >= (unsigned long)__va(1UL<<32) &&
539 address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) 544 address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT))
540 split_page_count(level); 545 split_page_count(level);
546#endif
541 547
542 /* 548 /*
543 * Install the new, split up pagetable. Important details here: 549 * Install the new, split up pagetable. Important details here:
@@ -655,12 +661,21 @@ static int cpa_process_alias(struct cpa_data *cpa)
655 if (cpa->pfn > max_pfn_mapped) 661 if (cpa->pfn > max_pfn_mapped)
656 return 0; 662 return 0;
657 663
664#ifdef CONFIG_X86_64
665 if (cpa->pfn > max_low_pfn_mapped && cpa->pfn < (1UL<<(32-PAGE_SHIFT)))
666 return 0;
667#endif
658 /* 668 /*
659 * No need to redo, when the primary call touched the direct 669 * No need to redo, when the primary call touched the direct
660 * mapping already: 670 * mapping already:
661 */ 671 */
662 if (!within(cpa->vaddr, PAGE_OFFSET, 672 if (!(within(cpa->vaddr, PAGE_OFFSET,
663 PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) { 673 PAGE_OFFSET + (max_low_pfn_mapped << PAGE_SHIFT))
674#ifdef CONFIG_X86_64
675 || within(cpa->vaddr, PAGE_OFFSET + (1UL<<32),
676 PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))
677#endif
678 )) {
664 679
665 alias_cpa = *cpa; 680 alias_cpa = *cpa;
666 alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); 681 alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index a885a1019b8a..749766c3c5cd 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -449,7 +449,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
449 if (retval < 0) 449 if (retval < 0)
450 return 0; 450 return 0;
451 451
452 if (pfn <= max_pfn_mapped && 452 if (((pfn <= max_low_pfn_mapped) ||
453 (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn <= max_pfn_mapped)) &&
453 ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { 454 ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
454 free_memtype(offset, offset + size); 455 free_memtype(offset, offset + size);
455 printk(KERN_INFO 456 printk(KERN_INFO