aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-11-12 05:58:59 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-11-12 05:58:59 -0500
commitdf762eccbadf87850fbee444d729e0f1b1e946f1 (patch)
tree1bf47bbbd4ea91e343f983b3b50ec2ec73a739e1 /arch/arm/mm
parentec1e20a02fe33b767ffcca8920a32211492416d7 (diff)
parent70d42126877b9faa272d446a6de5917614c28dd9 (diff)
Merge branch 'devel-stable' into for-next
Conflicts: arch/arm/include/asm/atomic.h arch/arm/include/asm/hardirq.h arch/arm/kernel/smp.c
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/Kconfig6
-rw-r--r--arch/arm/mm/abort-ev6.S5
-rw-r--r--arch/arm/mm/alignment.c9
-rw-r--r--arch/arm/mm/idmap.c8
-rw-r--r--arch/arm/mm/mmu.c82
-rw-r--r--arch/arm/mm/nommu.c9
-rw-r--r--arch/arm/mm/proc-v6.S4
-rw-r--r--arch/arm/mm/proc-v7.S4
8 files changed, 112 insertions, 15 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index cd2c88e7a8f7..1f8fed94c2a4 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -952,3 +952,9 @@ config ARCH_HAS_BARRIERS
952 help 952 help
953 This option allows the use of custom mandatory barriers 953 This option allows the use of custom mandatory barriers
954 included via the mach/barriers.h file. 954 included via the mach/barriers.h file.
955
956config ARCH_SUPPORTS_BIG_ENDIAN
957 bool
958 help
959 This option specifies the architecture can support big endian
960 operation.
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 80741992a9fc..3815a8262af0 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -38,9 +38,8 @@ ENTRY(v6_early_abort)
38 bne do_DataAbort 38 bne do_DataAbort
39 bic r1, r1, #1 << 11 @ clear bit 11 of FSR 39 bic r1, r1, #1 << 11 @ clear bit 11 of FSR
40 ldr r3, [r4] @ read aborted ARM instruction 40 ldr r3, [r4] @ read aborted ARM instruction
41#ifdef CONFIG_CPU_ENDIAN_BE8 41 ARM_BE8(rev r3, r3)
42 rev r3, r3 42
43#endif
44 do_ldrd_abort tmp=ip, insn=r3 43 do_ldrd_abort tmp=ip, insn=r3
45 tst r3, #1 << 20 @ L = 0 -> write 44 tst r3, #1 << 20 @ L = 0 -> write
46 orreq r1, r1, #1 << 11 @ yes. 45 orreq r1, r1, #1 << 11 @ yes.
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 6f4585b89078..924036473b16 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -25,6 +25,7 @@
25#include <asm/cp15.h> 25#include <asm/cp15.h>
26#include <asm/system_info.h> 26#include <asm/system_info.h>
27#include <asm/unaligned.h> 27#include <asm/unaligned.h>
28#include <asm/opcodes.h>
28 29
29#include "fault.h" 30#include "fault.h"
30 31
@@ -762,21 +763,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
762 if (thumb_mode(regs)) { 763 if (thumb_mode(regs)) {
763 u16 *ptr = (u16 *)(instrptr & ~1); 764 u16 *ptr = (u16 *)(instrptr & ~1);
764 fault = probe_kernel_address(ptr, tinstr); 765 fault = probe_kernel_address(ptr, tinstr);
766 tinstr = __mem_to_opcode_thumb16(tinstr);
765 if (!fault) { 767 if (!fault) {
766 if (cpu_architecture() >= CPU_ARCH_ARMv7 && 768 if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
767 IS_T32(tinstr)) { 769 IS_T32(tinstr)) {
768 /* Thumb-2 32-bit */ 770 /* Thumb-2 32-bit */
769 u16 tinst2 = 0; 771 u16 tinst2 = 0;
770 fault = probe_kernel_address(ptr + 1, tinst2); 772 fault = probe_kernel_address(ptr + 1, tinst2);
771 instr = (tinstr << 16) | tinst2; 773 tinst2 = __mem_to_opcode_thumb16(tinst2);
774 instr = __opcode_thumb32_compose(tinstr, tinst2);
772 thumb2_32b = 1; 775 thumb2_32b = 1;
773 } else { 776 } else {
774 isize = 2; 777 isize = 2;
775 instr = thumb2arm(tinstr); 778 instr = thumb2arm(tinstr);
776 } 779 }
777 } 780 }
778 } else 781 } else {
779 fault = probe_kernel_address(instrptr, instr); 782 fault = probe_kernel_address(instrptr, instr);
783 instr = __mem_to_opcode_arm(instr);
784 }
780 785
781 if (fault) { 786 if (fault) {
782 type = TYPE_FAULT; 787 type = TYPE_FAULT;
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 83cb3ac27095..8e0e52eb76b5 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -10,6 +10,7 @@
10#include <asm/system_info.h> 10#include <asm/system_info.h>
11 11
12pgd_t *idmap_pgd; 12pgd_t *idmap_pgd;
13phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
13 14
14#ifdef CONFIG_ARM_LPAE 15#ifdef CONFIG_ARM_LPAE
15static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, 16static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
@@ -67,8 +68,9 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
67 unsigned long addr, end; 68 unsigned long addr, end;
68 unsigned long next; 69 unsigned long next;
69 70
70 addr = virt_to_phys(text_start); 71 addr = virt_to_idmap(text_start);
71 end = virt_to_phys(text_end); 72 end = virt_to_idmap(text_end);
73 pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
72 74
73 prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; 75 prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
74 76
@@ -90,8 +92,6 @@ static int __init init_static_idmap(void)
90 if (!idmap_pgd) 92 if (!idmap_pgd)
91 return -ENOMEM; 93 return -ENOMEM;
92 94
93 pr_info("Setting up static identity map for 0x%p - 0x%p\n",
94 __idmap_text_start, __idmap_text_end);
95 identity_mapping_add(idmap_pgd, __idmap_text_start, 95 identity_mapping_add(idmap_pgd, __idmap_text_start,
96 __idmap_text_end, 0); 96 __idmap_text_end, 0);
97 97
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b1d17eeb59b8..78eeeca78f5a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -28,6 +28,8 @@
28#include <asm/highmem.h> 28#include <asm/highmem.h>
29#include <asm/system_info.h> 29#include <asm/system_info.h>
30#include <asm/traps.h> 30#include <asm/traps.h>
31#include <asm/procinfo.h>
32#include <asm/memory.h>
31 33
32#include <asm/mach/arch.h> 34#include <asm/mach/arch.h>
33#include <asm/mach/map.h> 35#include <asm/mach/map.h>
@@ -1315,6 +1317,86 @@ static void __init map_lowmem(void)
1315 } 1317 }
1316} 1318}
1317 1319
1320#ifdef CONFIG_ARM_LPAE
1321/*
1322 * early_paging_init() recreates boot time page table setup, allowing machines
1323 * to switch over to a high (>4G) address space on LPAE systems
1324 */
1325void __init early_paging_init(const struct machine_desc *mdesc,
1326 struct proc_info_list *procinfo)
1327{
1328 pmdval_t pmdprot = procinfo->__cpu_mm_mmu_flags;
1329 unsigned long map_start, map_end;
1330 pgd_t *pgd0, *pgdk;
1331 pud_t *pud0, *pudk, *pud_start;
1332 pmd_t *pmd0, *pmdk;
1333 phys_addr_t phys;
1334 int i;
1335
1336 if (!(mdesc->init_meminfo))
1337 return;
1338
1339 /* remap kernel code and data */
1340 map_start = init_mm.start_code;
1341 map_end = init_mm.brk;
1342
1343 /* get a handle on things... */
1344 pgd0 = pgd_offset_k(0);
1345 pud_start = pud0 = pud_offset(pgd0, 0);
1346 pmd0 = pmd_offset(pud0, 0);
1347
1348 pgdk = pgd_offset_k(map_start);
1349 pudk = pud_offset(pgdk, map_start);
1350 pmdk = pmd_offset(pudk, map_start);
1351
1352 mdesc->init_meminfo();
1353
1354 /* Run the patch stub to update the constants */
1355 fixup_pv_table(&__pv_table_begin,
1356 (&__pv_table_end - &__pv_table_begin) << 2);
1357
1358 /*
1359 * Cache cleaning operations for self-modifying code
1360 * We should clean the entries by MVA but running a
1361 * for loop over every pv_table entry pointer would
1362 * just complicate the code.
1363 */
1364 flush_cache_louis();
1365 dsb();
1366 isb();
1367
1368 /* remap level 1 table */
1369 for (i = 0; i < PTRS_PER_PGD; pud0++, i++) {
1370 set_pud(pud0,
1371 __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
1372 pmd0 += PTRS_PER_PMD;
1373 }
1374
1375 /* remap pmds for kernel mapping */
1376 phys = __pa(map_start) & PMD_MASK;
1377 do {
1378 *pmdk++ = __pmd(phys | pmdprot);
1379 phys += PMD_SIZE;
1380 } while (phys < map_end);
1381
1382 flush_cache_all();
1383 cpu_switch_mm(pgd0, &init_mm);
1384 cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
1385 local_flush_bp_all();
1386 local_flush_tlb_all();
1387}
1388
1389#else
1390
1391void __init early_paging_init(const struct machine_desc *mdesc,
1392 struct proc_info_list *procinfo)
1393{
1394 if (mdesc->init_meminfo)
1395 mdesc->init_meminfo();
1396}
1397
1398#endif
1399
1318/* 1400/*
1319 * paging_init() sets up the page tables, initialises the zone memory 1401 * paging_init() sets up the page tables, initialises the zone memory
1320 * maps, and sets up the zero page, bad page and bad page tables. 1402 * maps, and sets up the zero page, bad page and bad page tables.
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 34d4ab217bab..5c668b7a31f9 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -296,6 +296,15 @@ void __init sanity_check_meminfo(void)
296} 296}
297 297
298/* 298/*
299 * early_paging_init() recreates boot time page table setup, allowing machines
300 * to switch over to a high (>4G) address space on LPAE systems
301 */
302void __init early_paging_init(const struct machine_desc *mdesc,
303 struct proc_info_list *procinfo)
304{
305}
306
307/*
299 * paging_init() sets up the page tables, initialises the zone memory 308 * paging_init() sets up the page tables, initialises the zone memory
300 * maps, and sets up the zero page, bad page and bad page tables. 309 * maps, and sets up the zero page, bad page and bad page tables.
301 */ 310 */
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 1128064fddcb..45dc29f85d56 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -220,9 +220,7 @@ __v6_setup:
220#endif /* CONFIG_MMU */ 220#endif /* CONFIG_MMU */
221 adr r5, v6_crval 221 adr r5, v6_crval
222 ldmia r5, {r5, r6} 222 ldmia r5, {r5, r6}
223#ifdef CONFIG_CPU_ENDIAN_BE8 223 ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables
224 orr r6, r6, #1 << 25 @ big-endian page tables
225#endif
226 mrc p15, 0, r0, c1, c0, 0 @ read control register 224 mrc p15, 0, r0, c1, c0, 0 @ read control register
227 bic r0, r0, r5 @ clear bits them 225 bic r0, r0, r5 @ clear bits them
228 orr r0, r0, r6 @ set them 226 orr r0, r0, r6 @ set them
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c63d9bdee51e..60920f62fdf5 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -367,9 +367,7 @@ __v7_setup:
367#endif 367#endif
368 adr r5, v7_crval 368 adr r5, v7_crval
369 ldmia r5, {r5, r6} 369 ldmia r5, {r5, r6}
370#ifdef CONFIG_CPU_ENDIAN_BE8 370 ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables
371 orr r6, r6, #1 << 25 @ big-endian page tables
372#endif
373#ifdef CONFIG_SWP_EMULATE 371#ifdef CONFIG_SWP_EMULATE
374 orr r5, r5, #(1 << 10) @ set SW bit in "clear" 372 orr r5, r5, #(1 << 10) @ set SW bit in "clear"
375 bic r6, r6, #(1 << 10) @ clear it in "mmuset" 373 bic r6, r6, #(1 << 10) @ clear it in "mmuset"