diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/mmu.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 0aa8b7d5b21..c61481577ae 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/vmalloc.h> | ||
18 | 19 | ||
19 | #include <asm/cputype.h> | 20 | #include <asm/cputype.h> |
20 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
@@ -529,13 +530,18 @@ EXPORT_SYMBOL(phys_mem_access_prot); | |||
529 | 530 | ||
530 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) | 531 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) |
531 | 532 | ||
532 | static void __init *early_alloc(unsigned long sz) | 533 | static void __init *early_alloc_aligned(unsigned long sz, unsigned long align) |
533 | { | 534 | { |
534 | void *ptr = __va(memblock_alloc(sz, sz)); | 535 | void *ptr = __va(memblock_alloc(sz, align)); |
535 | memset(ptr, 0, sz); | 536 | memset(ptr, 0, sz); |
536 | return ptr; | 537 | return ptr; |
537 | } | 538 | } |
538 | 539 | ||
540 | static void __init *early_alloc(unsigned long sz) | ||
541 | { | ||
542 | return early_alloc_aligned(sz, sz); | ||
543 | } | ||
544 | |||
539 | static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) | 545 | static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) |
540 | { | 546 | { |
541 | if (pmd_none(*pmd)) { | 547 | if (pmd_none(*pmd)) { |
@@ -685,9 +691,10 @@ static void __init create_mapping(struct map_desc *md) | |||
685 | } | 691 | } |
686 | 692 | ||
687 | if ((md->type == MT_DEVICE || md->type == MT_ROM) && | 693 | if ((md->type == MT_DEVICE || md->type == MT_ROM) && |
688 | md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { | 694 | md->virtual >= PAGE_OFFSET && |
695 | (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { | ||
689 | printk(KERN_WARNING "BUG: mapping for 0x%08llx" | 696 | printk(KERN_WARNING "BUG: mapping for 0x%08llx" |
690 | " at 0x%08lx overlaps vmalloc space\n", | 697 | " at 0x%08lx out of vmalloc space\n", |
691 | (long long)__pfn_to_phys((u64)md->pfn), md->virtual); | 698 | (long long)__pfn_to_phys((u64)md->pfn), md->virtual); |
692 | } | 699 | } |
693 | 700 | ||
@@ -729,18 +736,32 @@ static void __init create_mapping(struct map_desc *md) | |||
729 | */ | 736 | */ |
730 | void __init iotable_init(struct map_desc *io_desc, int nr) | 737 | void __init iotable_init(struct map_desc *io_desc, int nr) |
731 | { | 738 | { |
732 | int i; | 739 | struct map_desc *md; |
740 | struct vm_struct *vm; | ||
741 | |||
742 | if (!nr) | ||
743 | return; | ||
733 | 744 | ||
734 | for (i = 0; i < nr; i++) | 745 | vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm)); |
735 | create_mapping(io_desc + i); | 746 | |
747 | for (md = io_desc; nr; md++, nr--) { | ||
748 | create_mapping(md); | ||
749 | vm->addr = (void *)(md->virtual & PAGE_MASK); | ||
750 | vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); | ||
751 | vm->phys_addr = __pfn_to_phys(md->pfn); | ||
752 | vm->flags = VM_IOREMAP; | ||
753 | vm->caller = iotable_init; | ||
754 | vm_area_add_early(vm++); | ||
755 | } | ||
736 | } | 756 | } |
737 | 757 | ||
738 | static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M); | 758 | static void * __initdata vmalloc_min = |
759 | (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); | ||
739 | 760 | ||
740 | /* | 761 | /* |
741 | * vmalloc=size forces the vmalloc area to be exactly 'size' | 762 | * vmalloc=size forces the vmalloc area to be exactly 'size' |
742 | * bytes. This can be used to increase (or decrease) the vmalloc | 763 | * bytes. This can be used to increase (or decrease) the vmalloc |
743 | * area - the default is 128m. | 764 | * area - the default is 240m. |
744 | */ | 765 | */ |
745 | static int __init early_vmalloc(char *arg) | 766 | static int __init early_vmalloc(char *arg) |
746 | { | 767 | { |
@@ -891,10 +912,10 @@ static inline void prepare_page_table(void) | |||
891 | 912 | ||
892 | /* | 913 | /* |
893 | * Clear out all the kernel space mappings, except for the first | 914 | * Clear out all the kernel space mappings, except for the first |
894 | * memory bank, up to the end of the vmalloc region. | 915 | * memory bank, up to the vmalloc region. |
895 | */ | 916 | */ |
896 | for (addr = __phys_to_virt(end); | 917 | for (addr = __phys_to_virt(end); |
897 | addr < VMALLOC_END; addr += PMD_SIZE) | 918 | addr < VMALLOC_START; addr += PMD_SIZE) |
898 | pmd_clear(pmd_off_k(addr)); | 919 | pmd_clear(pmd_off_k(addr)); |
899 | } | 920 | } |
900 | 921 | ||
@@ -921,8 +942,8 @@ void __init arm_mm_memblock_reserve(void) | |||
921 | } | 942 | } |
922 | 943 | ||
923 | /* | 944 | /* |
924 | * Set up device the mappings. Since we clear out the page tables for all | 945 | * Set up the device mappings. Since we clear out the page tables for all |
925 | * mappings above VMALLOC_END, we will remove any debug device mappings. | 946 | * mappings above VMALLOC_START, we will remove any debug device mappings. |
926 | * This means you have to be careful how you debug this function, or any | 947 | * This means you have to be careful how you debug this function, or any |
927 | * called function. This means you can't use any function or debugging | 948 | * called function. This means you can't use any function or debugging |
928 | * method which may touch any device, otherwise the kernel _will_ crash. | 949 | * method which may touch any device, otherwise the kernel _will_ crash. |
@@ -937,7 +958,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
937 | */ | 958 | */ |
938 | vectors_page = early_alloc(PAGE_SIZE); | 959 | vectors_page = early_alloc(PAGE_SIZE); |
939 | 960 | ||
940 | for (addr = VMALLOC_END; addr; addr += PMD_SIZE) | 961 | for (addr = VMALLOC_START; addr; addr += PMD_SIZE) |
941 | pmd_clear(pmd_off_k(addr)); | 962 | pmd_clear(pmd_off_k(addr)); |
942 | 963 | ||
943 | /* | 964 | /* |