diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-07-10 23:38:26 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-11 04:24:04 -0400 |
commit | f361a450bf1ad14e2b003217dbf3958638631265 (patch) | |
tree | 10c1e4dcc0047f6c37387cada6a0bceba088d2d2 /arch/x86/mm | |
parent | f302a5bbe5eb95f3d4227d5bd0e9b92b1b125f4f (diff) |
x86: introduce max_low_pfn_mapped for 64-bit
when more than 4g memory is installed, don't map the big hole below 4g.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/init_32.c | 1 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 1 | ||||
-rw-r--r-- | arch/x86/mm/pageattr.c | 19 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 3 |
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 | ||
51 | unsigned int __VMALLOC_RESERVE = 128 << 20; | 51 | unsigned int __VMALLOC_RESERVE = 128 << 20; |
52 | 52 | ||
53 | unsigned long max_low_pfn_mapped; | ||
53 | unsigned long max_pfn_mapped; | 54 | unsigned long max_pfn_mapped; |
54 | 55 | ||
55 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 56 | DEFINE_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 | */ |
56 | unsigned long max_low_pfn_mapped; | ||
56 | unsigned long max_pfn_mapped; | 57 | unsigned long max_pfn_mapped; |
57 | 58 | ||
58 | static unsigned long dma_reserve __initdata; | 59 | static 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 |