aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/memory.txt11
-rw-r--r--arch/arm/include/asm/pgtable.h8
-rw-r--r--arch/arm/mm/mmu.c49
3 files changed, 41 insertions, 27 deletions
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 771d48d3b335..208a2d465b92 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -51,15 +51,14 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned
51ff000000 ffbfffff Reserved for future expansion of DMA 51ff000000 ffbfffff Reserved for future expansion of DMA
52 mapping region. 52 mapping region.
53 53
54VMALLOC_END feffffff Free for platform use, recommended.
55 VMALLOC_END must be aligned to a 2MB
56 boundary.
57
58VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. 54VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
59 Memory returned by vmalloc/ioremap will 55 Memory returned by vmalloc/ioremap will
60 be dynamically placed in this region. 56 be dynamically placed in this region.
61 VMALLOC_START may be based upon the value 57 Machine specific static mappings are also
62 of the high_memory variable. 58 located here through iotable_init().
59 VMALLOC_START is based upon the value
60 of the high_memory variable, and VMALLOC_END
61 is equal to 0xff000000.
63 62
64PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region. 63PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region.
65 This maps the platforms RAM, and typically 64 This maps the platforms RAM, and typically
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 9451dce3a553..6cdd55cb0b8c 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -21,7 +21,6 @@
21#else 21#else
22 22
23#include <asm/memory.h> 23#include <asm/memory.h>
24#include <mach/vmalloc.h>
25#include <asm/pgtable-hwdef.h> 24#include <asm/pgtable-hwdef.h>
26 25
27#include <asm/pgtable-2level.h> 26#include <asm/pgtable-2level.h>
@@ -33,15 +32,10 @@
33 * any out-of-bounds memory accesses will hopefully be caught. 32 * any out-of-bounds memory accesses will hopefully be caught.
34 * The vmalloc() routines leaves a hole of 4kB between each vmalloced 33 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
35 * area for the same reason. ;) 34 * area for the same reason. ;)
36 *
37 * Note that platforms may override VMALLOC_START, but they must provide
38 * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space,
39 * which may not overlap IO space.
40 */ 35 */
41#ifndef VMALLOC_START
42#define VMALLOC_OFFSET (8*1024*1024) 36#define VMALLOC_OFFSET (8*1024*1024)
43#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) 37#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
44#endif 38#define VMALLOC_END 0xff000000UL
45 39
46#define LIBRARY_TEXT_START 0x0c000000 40#define LIBRARY_TEXT_START 0x0c000000
47 41
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 0aa8b7d5b21d..c61481577ae1 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
532static void __init *early_alloc(unsigned long sz) 533static 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
540static void __init *early_alloc(unsigned long sz)
541{
542 return early_alloc_aligned(sz, sz);
543}
544
539static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) 545static 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 */
730void __init iotable_init(struct map_desc *io_desc, int nr) 737void __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
738static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M); 758static 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 */
745static int __init early_vmalloc(char *arg) 766static 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 /*