diff options
-rw-r--r-- | arch/arm/include/asm/mach/map.h | 1 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 55 |
2 files changed, 51 insertions, 5 deletions
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index 447be0744a85..f98c7f32c9c8 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h | |||
@@ -29,6 +29,7 @@ enum { | |||
29 | MT_LOW_VECTORS, | 29 | MT_LOW_VECTORS, |
30 | MT_HIGH_VECTORS, | 30 | MT_HIGH_VECTORS, |
31 | MT_MEMORY_RWX, | 31 | MT_MEMORY_RWX, |
32 | MT_MEMORY_RW, | ||
32 | MT_ROM, | 33 | MT_ROM, |
33 | MT_MEMORY_RWX_NONCACHED, | 34 | MT_MEMORY_RWX_NONCACHED, |
34 | MT_MEMORY_RW_DTCM, | 35 | MT_MEMORY_RW_DTCM, |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index fce2e7388098..9ec715f12224 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/cputype.h> | 22 | #include <asm/cputype.h> |
23 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
24 | #include <asm/cachetype.h> | 24 | #include <asm/cachetype.h> |
25 | #include <asm/sections.h> | ||
25 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
26 | #include <asm/smp_plat.h> | 27 | #include <asm/smp_plat.h> |
27 | #include <asm/tlb.h> | 28 | #include <asm/tlb.h> |
@@ -293,6 +294,13 @@ static struct mem_type mem_types[] = { | |||
293 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 294 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
294 | .domain = DOMAIN_KERNEL, | 295 | .domain = DOMAIN_KERNEL, |
295 | }, | 296 | }, |
297 | [MT_MEMORY_RW] = { | ||
298 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
299 | L_PTE_XN, | ||
300 | .prot_l1 = PMD_TYPE_TABLE, | ||
301 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | ||
302 | .domain = DOMAIN_KERNEL, | ||
303 | }, | ||
296 | [MT_ROM] = { | 304 | [MT_ROM] = { |
297 | .prot_sect = PMD_TYPE_SECT, | 305 | .prot_sect = PMD_TYPE_SECT, |
298 | .domain = DOMAIN_KERNEL, | 306 | .domain = DOMAIN_KERNEL, |
@@ -410,6 +418,9 @@ static void __init build_mem_type_table(void) | |||
410 | mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN; | 418 | mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN; |
411 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN; | 419 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN; |
412 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN; | 420 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN; |
421 | |||
422 | /* Also setup NX memory mapping */ | ||
423 | mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN; | ||
413 | } | 424 | } |
414 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { | 425 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { |
415 | /* | 426 | /* |
@@ -489,6 +500,8 @@ static void __init build_mem_type_table(void) | |||
489 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | 500 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; |
490 | mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S; | 501 | mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S; |
491 | mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED; | 502 | mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED; |
503 | mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S; | ||
504 | mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED; | ||
492 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; | 505 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; |
493 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S; | 506 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S; |
494 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED; | 507 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED; |
@@ -545,6 +558,8 @@ static void __init build_mem_type_table(void) | |||
545 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 558 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
546 | mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd; | 559 | mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd; |
547 | mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot; | 560 | mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot; |
561 | mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd; | ||
562 | mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot; | ||
548 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; | 563 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; |
549 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask; | 564 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask; |
550 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 565 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
@@ -1296,6 +1311,8 @@ static void __init kmap_init(void) | |||
1296 | static void __init map_lowmem(void) | 1311 | static void __init map_lowmem(void) |
1297 | { | 1312 | { |
1298 | struct memblock_region *reg; | 1313 | struct memblock_region *reg; |
1314 | unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); | ||
1315 | unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); | ||
1299 | 1316 | ||
1300 | /* Map all the lowmem memory banks. */ | 1317 | /* Map all the lowmem memory banks. */ |
1301 | for_each_memblock(memory, reg) { | 1318 | for_each_memblock(memory, reg) { |
@@ -1308,12 +1325,40 @@ static void __init map_lowmem(void) | |||
1308 | if (start >= end) | 1325 | if (start >= end) |
1309 | break; | 1326 | break; |
1310 | 1327 | ||
1311 | map.pfn = __phys_to_pfn(start); | 1328 | if (end < kernel_x_start || start >= kernel_x_end) { |
1312 | map.virtual = __phys_to_virt(start); | 1329 | map.pfn = __phys_to_pfn(start); |
1313 | map.length = end - start; | 1330 | map.virtual = __phys_to_virt(start); |
1314 | map.type = MT_MEMORY; | 1331 | map.length = end - start; |
1332 | map.type = MT_MEMORY_RWX; | ||
1315 | 1333 | ||
1316 | create_mapping(&map); | 1334 | create_mapping(&map); |
1335 | } else { | ||
1336 | /* This better cover the entire kernel */ | ||
1337 | if (start < kernel_x_start) { | ||
1338 | map.pfn = __phys_to_pfn(start); | ||
1339 | map.virtual = __phys_to_virt(start); | ||
1340 | map.length = kernel_x_start - start; | ||
1341 | map.type = MT_MEMORY_RW; | ||
1342 | |||
1343 | create_mapping(&map); | ||
1344 | } | ||
1345 | |||
1346 | map.pfn = __phys_to_pfn(kernel_x_start); | ||
1347 | map.virtual = __phys_to_virt(kernel_x_start); | ||
1348 | map.length = kernel_x_end - kernel_x_start; | ||
1349 | map.type = MT_MEMORY_RWX; | ||
1350 | |||
1351 | create_mapping(&map); | ||
1352 | |||
1353 | if (kernel_x_end < end) { | ||
1354 | map.pfn = __phys_to_pfn(kernel_x_end); | ||
1355 | map.virtual = __phys_to_virt(kernel_x_end); | ||
1356 | map.length = end - kernel_x_end; | ||
1357 | map.type = MT_MEMORY_RW; | ||
1358 | |||
1359 | create_mapping(&map); | ||
1360 | } | ||
1361 | } | ||
1317 | } | 1362 | } |
1318 | } | 1363 | } |
1319 | 1364 | ||