aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r--arch/arm/mm/mmu.c84
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
654static 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
685static void __init sanity_check_meminfo(void) 654static 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}