diff options
-rw-r--r-- | arch/arm/mm/mmu.c | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6870805c31dd..ab511d94d917 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -651,44 +651,62 @@ __early_param("vmalloc=", early_vmalloc); | |||
651 | 651 | ||
652 | #define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve) | 652 | #define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve) |
653 | 653 | ||
654 | static int __init check_membank_valid(struct membank *mb) | ||
655 | { | ||
656 | /* | ||
657 | * Check whether this memory region would entirely overlap | ||
658 | * the vmalloc area. | ||
659 | */ | ||
660 | if (phys_to_virt(mb->start) >= VMALLOC_MIN) { | ||
661 | printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " | ||
662 | "(vmalloc region overlap).\n", | ||
663 | mb->start, mb->start + mb->size - 1); | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * Check whether this memory region would partially overlap | ||
669 | * the vmalloc area. | ||
670 | */ | ||
671 | if (phys_to_virt(mb->start + mb->size) < phys_to_virt(mb->start) || | ||
672 | phys_to_virt(mb->start + mb->size) > VMALLOC_MIN) { | ||
673 | unsigned long newsize = VMALLOC_MIN - phys_to_virt(mb->start); | ||
674 | |||
675 | printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx " | ||
676 | "to -%.8lx (vmalloc region overlap).\n", | ||
677 | mb->start, mb->start + mb->size - 1, | ||
678 | mb->start + newsize - 1); | ||
679 | mb->size = newsize; | ||
680 | } | ||
681 | |||
682 | return 1; | ||
683 | } | ||
684 | |||
685 | static void __init sanity_check_meminfo(void) | 654 | static void __init sanity_check_meminfo(void) |
686 | { | 655 | { |
687 | int i, j; | 656 | int i, j; |
688 | 657 | ||
689 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { | 658 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { |
690 | if (check_membank_valid(&meminfo.bank[i])) | 659 | struct membank *bank = &meminfo.bank[j]; |
691 | meminfo.bank[j++] = meminfo.bank[i]; | 660 | *bank = meminfo.bank[i]; |
661 | |||
662 | #ifdef CONFIG_HIGHMEM | ||
663 | /* | ||
664 | * Split those memory banks which are partially overlapping | ||
665 | * the vmalloc area greatly simplifying things later. | ||
666 | */ | ||
667 | if (__va(bank->start) < VMALLOC_MIN && | ||
668 | bank->size > VMALLOC_MIN - __va(bank->start)) { | ||
669 | if (meminfo.nr_banks >= NR_BANKS) { | ||
670 | printk(KERN_CRIT "NR_BANKS too low, " | ||
671 | "ignoring high memory\n"); | ||
672 | } else { | ||
673 | memmove(bank + 1, bank, | ||
674 | (meminfo.nr_banks - i) * sizeof(*bank)); | ||
675 | meminfo.nr_banks++; | ||
676 | i++; | ||
677 | bank[1].size -= VMALLOC_MIN - __va(bank->start); | ||
678 | bank[1].start = __pa(VMALLOC_MIN - 1) + 1; | ||
679 | j++; | ||
680 | } | ||
681 | bank->size = VMALLOC_MIN - __va(bank->start); | ||
682 | } | ||
683 | #else | ||
684 | /* | ||
685 | * Check whether this memory bank would entirely overlap | ||
686 | * the vmalloc area. | ||
687 | */ | ||
688 | if (__va(bank->start) >= VMALLOC_MIN) { | ||
689 | printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " | ||
690 | "(vmalloc region overlap).\n", | ||
691 | bank->start, bank->start + bank->size - 1); | ||
692 | continue; | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * Check whether this memory bank would partially overlap | ||
697 | * the vmalloc area. | ||
698 | */ | ||
699 | if (__va(bank->start + bank->size) > VMALLOC_MIN || | ||
700 | __va(bank->start + bank->size) < __va(bank->start)) { | ||
701 | unsigned long newsize = VMALLOC_MIN - __va(bank->start); | ||
702 | printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx " | ||
703 | "to -%.8lx (vmalloc region overlap).\n", | ||
704 | bank->start, bank->start + bank->size - 1, | ||
705 | bank->start + newsize - 1); | ||
706 | bank->size = newsize; | ||
707 | } | ||
708 | #endif | ||
709 | j++; | ||
692 | } | 710 | } |
693 | meminfo.nr_banks = j; | 711 | meminfo.nr_banks = j; |
694 | } | 712 | } |