Skip to content

Commit 3f9c08f

Browse files
committed
Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King: "A few fixes for ARM. Some of these are correctness issues: - TLBs must be flushed after the old mappings are removed by the DMA mapping code, but before the new mappings are established. - An off-by-one entry error in the Keystone LPAE setup code. Fixes include: - ensuring that the identity mapping for LPAE does not remove the kernel image from the identity map. - preventing userspace from trapping into kgdb. - fixing a preemption issue in the Intel iwmmxt code. - fixing a build error with nommu. Other changes include: - Adding a note about which areas of memory are expected to be accessible while the identity mapping tables are in place" * 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: ARM: 8124/1: don't enter kgdb when userspace executes a kgdb break instruction ARM: idmap: add identity mapping usage note ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory layout ARM: fix alignment of keystone page table fixup ARM: 8112/1: only select ARM_PATCH_PHYS_VIRT if MMU is enabled ARM: 8100/1: Fix preemption disable in iwmmxt_task_enable() ARM: DMA: ensure that old section mappings are flushed from the TLB
2 parents 1f26094 + 6bf755d commit 3f9c08f

File tree

6 files changed

+43
-17
lines changed

6 files changed

+43
-17
lines changed

arch/arm/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ config ARCH_MULTIPLATFORM
313313
config ARCH_INTEGRATOR
314314
bool "ARM Ltd. Integrator family"
315315
select ARM_AMBA
316-
select ARM_PATCH_PHYS_VIRT
316+
select ARM_PATCH_PHYS_VIRT if MMU
317317
select AUTO_ZRELADDR
318318
select COMMON_CLK
319319
select COMMON_CLK_VERSATILE
@@ -659,7 +659,7 @@ config ARCH_MSM
659659
config ARCH_SHMOBILE_LEGACY
660660
bool "Renesas ARM SoCs (non-multiplatform)"
661661
select ARCH_SHMOBILE
662-
select ARM_PATCH_PHYS_VIRT
662+
select ARM_PATCH_PHYS_VIRT if MMU
663663
select CLKDEV_LOOKUP
664664
select GENERIC_CLOCKEVENTS
665665
select HAVE_ARM_SCU if SMP

arch/arm/kernel/iwmmxt.S

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,19 @@ ENTRY(iwmmxt_task_enable)
9494

9595
mrc p15, 0, r2, c2, c0, 0
9696
mov r2, r2 @ cpwait
97+
bl concan_save
9798

98-
teq r1, #0 @ test for last ownership
99-
mov lr, r9 @ normal exit from exception
100-
beq concan_load @ no owner, skip save
99+
#ifdef CONFIG_PREEMPT_COUNT
100+
get_thread_info r10
101+
#endif
102+
4: dec_preempt_count r10, r3
103+
mov pc, r9 @ normal exit from exception
101104

102105
concan_save:
103106

107+
teq r1, #0 @ test for last ownership
108+
beq concan_load @ no owner, skip save
109+
104110
tmrc r2, wCon
105111

106112
@ CUP? wCx
@@ -138,7 +144,7 @@ concan_dump:
138144
wstrd wR15, [r1, #MMX_WR15]
139145

140146
2: teq r0, #0 @ anything to load?
141-
beq 3f
147+
moveq pc, lr @ if not, return
142148

143149
concan_load:
144150

@@ -171,14 +177,9 @@ concan_load:
171177
@ clear CUP/MUP (only if r1 != 0)
172178
teq r1, #0
173179
mov r2, #0
174-
beq 3f
175-
tmcr wCon, r2
180+
moveq pc, lr
176181

177-
3:
178-
#ifdef CONFIG_PREEMPT_COUNT
179-
get_thread_info r10
180-
#endif
181-
4: dec_preempt_count r10, r3
182+
tmcr wCon, r2
182183
mov pc, lr
183184

184185
/*

arch/arm/kernel/kgdb.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,16 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
160160
static struct undef_hook kgdb_brkpt_hook = {
161161
.instr_mask = 0xffffffff,
162162
.instr_val = KGDB_BREAKINST,
163+
.cpsr_mask = MODE_MASK,
164+
.cpsr_val = SVC_MODE,
163165
.fn = kgdb_brk_fn
164166
};
165167

166168
static struct undef_hook kgdb_compiled_brkpt_hook = {
167169
.instr_mask = 0xffffffff,
168170
.instr_val = KGDB_COMPILED_BREAK,
171+
.cpsr_mask = MODE_MASK,
172+
.cpsr_val = SVC_MODE,
169173
.fn = kgdb_compiled_brk_fn
170174
};
171175

arch/arm/mm/dma-mapping.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,21 @@ void __init dma_contiguous_remap(void)
461461
map.type = MT_MEMORY_DMA_READY;
462462

463463
/*
464-
* Clear previous low-memory mapping
464+
* Clear previous low-memory mapping to ensure that the
465+
* TLB does not see any conflicting entries, then flush
466+
* the TLB of the old entries before creating new mappings.
467+
*
468+
* This ensures that any speculatively loaded TLB entries
469+
* (even though they may be rare) can not cause any problems,
470+
* and ensures that this code is architecturally compliant.
465471
*/
466472
for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
467473
addr += PMD_SIZE)
468474
pmd_clear(pmd_off_k(addr));
469475

476+
flush_tlb_kernel_range(__phys_to_virt(start),
477+
__phys_to_virt(end));
478+
470479
iotable_init(&map, 1);
471480
}
472481
}

arch/arm/mm/idmap.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
#include <asm/sections.h>
1010
#include <asm/system_info.h>
1111

12+
/*
13+
* Note: accesses outside of the kernel image and the identity map area
14+
* are not supported on any CPU using the idmap tables as its current
15+
* page tables.
16+
*/
1217
pgd_t *idmap_pgd;
1318
phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
1419

@@ -25,6 +30,13 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
2530
pr_warning("Failed to allocate identity pmd.\n");
2631
return;
2732
}
33+
/*
34+
* Copy the original PMD to ensure that the PMD entries for
35+
* the kernel image are preserved.
36+
*/
37+
if (!pud_none(*pud))
38+
memcpy(pmd, pmd_offset(pud, 0),
39+
PTRS_PER_PMD * sizeof(pmd_t));
2840
pud_populate(&init_mm, pud, pmd);
2941
pmd += pmd_index(addr);
3042
} else

arch/arm/mm/mmu.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,8 +1406,8 @@ void __init early_paging_init(const struct machine_desc *mdesc,
14061406
return;
14071407

14081408
/* remap kernel code and data */
1409-
map_start = init_mm.start_code;
1410-
map_end = init_mm.brk;
1409+
map_start = init_mm.start_code & PMD_MASK;
1410+
map_end = ALIGN(init_mm.brk, PMD_SIZE);
14111411

14121412
/* get a handle on things... */
14131413
pgd0 = pgd_offset_k(0);
@@ -1442,7 +1442,7 @@ void __init early_paging_init(const struct machine_desc *mdesc,
14421442
}
14431443

14441444
/* remap pmds for kernel mapping */
1445-
phys = __pa(map_start) & PMD_MASK;
1445+
phys = __pa(map_start);
14461446
do {
14471447
*pmdk++ = __pmd(phys | pmdprot);
14481448
phys += PMD_SIZE;

0 commit comments

Comments
 (0)