|
@@ -15,6 +15,7 @@
|
|
|
#include <linux/nodemask.h>
|
|
|
#include <linux/memblock.h>
|
|
|
#include <linux/fs.h>
|
|
|
+#include <linux/vmalloc.h>
|
|
|
|
|
|
#include <asm/cputype.h>
|
|
|
#include <asm/sections.h>
|
|
@@ -529,13 +530,18 @@ EXPORT_SYMBOL(phys_mem_access_prot);
|
|
|
|
|
|
#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
|
|
|
|
|
|
-static void __init *early_alloc(unsigned long sz)
|
|
|
+static void __init *early_alloc_aligned(unsigned long sz, unsigned long align)
|
|
|
{
|
|
|
- void *ptr = __va(memblock_alloc(sz, sz));
|
|
|
+ void *ptr = __va(memblock_alloc(sz, align));
|
|
|
memset(ptr, 0, sz);
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
+static void __init *early_alloc(unsigned long sz)
|
|
|
+{
|
|
|
+ return early_alloc_aligned(sz, sz);
|
|
|
+}
|
|
|
+
|
|
|
static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
|
|
|
{
|
|
|
if (pmd_none(*pmd)) {
|
|
@@ -685,9 +691,10 @@ static void __init create_mapping(struct map_desc *md)
|
|
|
}
|
|
|
|
|
|
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
|
|
|
- md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
|
|
|
+ md->virtual >= PAGE_OFFSET &&
|
|
|
+ (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
|
|
|
printk(KERN_WARNING "BUG: mapping for 0x%08llx"
|
|
|
- " at 0x%08lx overlaps vmalloc space\n",
|
|
|
+ " at 0x%08lx out of vmalloc space\n",
|
|
|
(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
|
|
|
}
|
|
|
|
|
@@ -729,18 +736,32 @@ static void __init create_mapping(struct map_desc *md)
|
|
|
*/
|
|
|
void __init iotable_init(struct map_desc *io_desc, int nr)
|
|
|
{
|
|
|
- int i;
|
|
|
+ struct map_desc *md;
|
|
|
+ struct vm_struct *vm;
|
|
|
+
|
|
|
+ if (!nr)
|
|
|
+ return;
|
|
|
|
|
|
- for (i = 0; i < nr; i++)
|
|
|
- create_mapping(io_desc + i);
|
|
|
+ vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm));
|
|
|
+
|
|
|
+ for (md = io_desc; nr; md++, nr--) {
|
|
|
+ create_mapping(md);
|
|
|
+ vm->addr = (void *)(md->virtual & PAGE_MASK);
|
|
|
+ vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
|
|
|
+ vm->phys_addr = __pfn_to_phys(md->pfn);
|
|
|
+ vm->flags = VM_IOREMAP;
|
|
|
+ vm->caller = iotable_init;
|
|
|
+ vm_area_add_early(vm++);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
|
|
|
+static void * __initdata vmalloc_min =
|
|
|
+ (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
|
|
|
|
|
|
/*
|
|
|
* vmalloc=size forces the vmalloc area to be exactly 'size'
|
|
|
* bytes. This can be used to increase (or decrease) the vmalloc
|
|
|
- * area - the default is 128m.
|
|
|
+ * area - the default is 240m.
|
|
|
*/
|
|
|
static int __init early_vmalloc(char *arg)
|
|
|
{
|
|
@@ -891,10 +912,10 @@ static inline void prepare_page_table(void)
|
|
|
|
|
|
/*
|
|
|
* Clear out all the kernel space mappings, except for the first
|
|
|
- * memory bank, up to the end of the vmalloc region.
|
|
|
+ * memory bank, up to the vmalloc region.
|
|
|
*/
|
|
|
for (addr = __phys_to_virt(end);
|
|
|
- addr < VMALLOC_END; addr += PMD_SIZE)
|
|
|
+ addr < VMALLOC_START; addr += PMD_SIZE)
|
|
|
pmd_clear(pmd_off_k(addr));
|
|
|
}
|
|
|
|
|
@@ -921,8 +942,8 @@ void __init arm_mm_memblock_reserve(void)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Set up device the mappings. Since we clear out the page tables for all
|
|
|
- * mappings above VMALLOC_END, we will remove any debug device mappings.
|
|
|
+ * Set up the device mappings. Since we clear out the page tables for all
|
|
|
+ * mappings above VMALLOC_START, we will remove any debug device mappings.
|
|
|
* This means you have to be careful how you debug this function, or any
|
|
|
* called function. This means you can't use any function or debugging
|
|
|
* method which may touch any device, otherwise the kernel _will_ crash.
|
|
@@ -937,7 +958,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
|
|
|
*/
|
|
|
vectors_page = early_alloc(PAGE_SIZE);
|
|
|
|
|
|
- for (addr = VMALLOC_END; addr; addr += PMD_SIZE)
|
|
|
+ for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
|
|
|
pmd_clear(pmd_off_k(addr));
|
|
|
|
|
|
/*
|