Commit 3f9c08f7 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 1f260946 6bf755db
...@@ -313,7 +313,7 @@ config ARCH_MULTIPLATFORM ...@@ -313,7 +313,7 @@ config ARCH_MULTIPLATFORM
config ARCH_INTEGRATOR config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family" bool "ARM Ltd. Integrator family"
select ARM_AMBA select ARM_AMBA
select ARM_PATCH_PHYS_VIRT select ARM_PATCH_PHYS_VIRT if MMU
select AUTO_ZRELADDR select AUTO_ZRELADDR
select COMMON_CLK select COMMON_CLK
select COMMON_CLK_VERSATILE select COMMON_CLK_VERSATILE
...@@ -659,7 +659,7 @@ config ARCH_MSM ...@@ -659,7 +659,7 @@ config ARCH_MSM
config ARCH_SHMOBILE_LEGACY config ARCH_SHMOBILE_LEGACY
bool "Renesas ARM SoCs (non-multiplatform)" bool "Renesas ARM SoCs (non-multiplatform)"
select ARCH_SHMOBILE select ARCH_SHMOBILE
select ARM_PATCH_PHYS_VIRT select ARM_PATCH_PHYS_VIRT if MMU
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU if SMP select HAVE_ARM_SCU if SMP
......
...@@ -94,13 +94,19 @@ ENTRY(iwmmxt_task_enable) ...@@ -94,13 +94,19 @@ ENTRY(iwmmxt_task_enable)
mrc p15, 0, r2, c2, c0, 0 mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait mov r2, r2 @ cpwait
bl concan_save
teq r1, #0 @ test for last ownership #ifdef CONFIG_PREEMPT_COUNT
mov lr, r9 @ normal exit from exception get_thread_info r10
beq concan_load @ no owner, skip save #endif
4: dec_preempt_count r10, r3
mov pc, r9 @ normal exit from exception
concan_save: concan_save:
teq r1, #0 @ test for last ownership
beq concan_load @ no owner, skip save
tmrc r2, wCon tmrc r2, wCon
@ CUP? wCx @ CUP? wCx
...@@ -138,7 +144,7 @@ concan_dump: ...@@ -138,7 +144,7 @@ concan_dump:
wstrd wR15, [r1, #MMX_WR15] wstrd wR15, [r1, #MMX_WR15]
2: teq r0, #0 @ anything to load? 2: teq r0, #0 @ anything to load?
beq 3f moveq pc, lr @ if not, return
concan_load: concan_load:
...@@ -171,14 +177,9 @@ concan_load: ...@@ -171,14 +177,9 @@ concan_load:
@ clear CUP/MUP (only if r1 != 0) @ clear CUP/MUP (only if r1 != 0)
teq r1, #0 teq r1, #0
mov r2, #0 mov r2, #0
beq 3f moveq pc, lr
tmcr wCon, r2
3: tmcr wCon, r2
#ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10
#endif
4: dec_preempt_count r10, r3
mov pc, lr mov pc, lr
/* /*
......
...@@ -160,12 +160,16 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr) ...@@ -160,12 +160,16 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
static struct undef_hook kgdb_brkpt_hook = { static struct undef_hook kgdb_brkpt_hook = {
.instr_mask = 0xffffffff, .instr_mask = 0xffffffff,
.instr_val = KGDB_BREAKINST, .instr_val = KGDB_BREAKINST,
.cpsr_mask = MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_brk_fn .fn = kgdb_brk_fn
}; };
static struct undef_hook kgdb_compiled_brkpt_hook = { static struct undef_hook kgdb_compiled_brkpt_hook = {
.instr_mask = 0xffffffff, .instr_mask = 0xffffffff,
.instr_val = KGDB_COMPILED_BREAK, .instr_val = KGDB_COMPILED_BREAK,
.cpsr_mask = MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_compiled_brk_fn .fn = kgdb_compiled_brk_fn
}; };
......
...@@ -461,12 +461,21 @@ void __init dma_contiguous_remap(void) ...@@ -461,12 +461,21 @@ void __init dma_contiguous_remap(void)
map.type = MT_MEMORY_DMA_READY; map.type = MT_MEMORY_DMA_READY;
/* /*
* Clear previous low-memory mapping * Clear previous low-memory mapping to ensure that the
* TLB does not see any conflicting entries, then flush
* the TLB of the old entries before creating new mappings.
*
* This ensures that any speculatively loaded TLB entries
* (even though they may be rare) can not cause any problems,
* and ensures that this code is architecturally compliant.
*/ */
for (addr = __phys_to_virt(start); addr < __phys_to_virt(end); for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
addr += PMD_SIZE) addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr)); pmd_clear(pmd_off_k(addr));
flush_tlb_kernel_range(__phys_to_virt(start),
__phys_to_virt(end));
iotable_init(&map, 1); iotable_init(&map, 1);
} }
} }
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/system_info.h> #include <asm/system_info.h>
/*
* Note: accesses outside of the kernel image and the identity map area
* are not supported on any CPU using the idmap tables as its current
* page tables.
*/
pgd_t *idmap_pgd; pgd_t *idmap_pgd;
phys_addr_t (*arch_virt_to_idmap) (unsigned long x); phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
...@@ -25,6 +30,13 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, ...@@ -25,6 +30,13 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
pr_warning("Failed to allocate identity pmd.\n"); pr_warning("Failed to allocate identity pmd.\n");
return; return;
} }
/*
* Copy the original PMD to ensure that the PMD entries for
* the kernel image are preserved.
*/
if (!pud_none(*pud))
memcpy(pmd, pmd_offset(pud, 0),
PTRS_PER_PMD * sizeof(pmd_t));
pud_populate(&init_mm, pud, pmd); pud_populate(&init_mm, pud, pmd);
pmd += pmd_index(addr); pmd += pmd_index(addr);
} else } else
......
...@@ -1406,8 +1406,8 @@ void __init early_paging_init(const struct machine_desc *mdesc, ...@@ -1406,8 +1406,8 @@ void __init early_paging_init(const struct machine_desc *mdesc,
return; return;
/* remap kernel code and data */ /* remap kernel code and data */
map_start = init_mm.start_code; map_start = init_mm.start_code & PMD_MASK;
map_end = init_mm.brk; map_end = ALIGN(init_mm.brk, PMD_SIZE);
/* get a handle on things... */ /* get a handle on things... */
pgd0 = pgd_offset_k(0); pgd0 = pgd_offset_k(0);
...@@ -1442,7 +1442,7 @@ void __init early_paging_init(const struct machine_desc *mdesc, ...@@ -1442,7 +1442,7 @@ void __init early_paging_init(const struct machine_desc *mdesc,
} }
/* remap pmds for kernel mapping */ /* remap pmds for kernel mapping */
phys = __pa(map_start) & PMD_MASK; phys = __pa(map_start);
do { do {
*pmdk++ = __pmd(phys | pmdprot); *pmdk++ = __pmd(phys | pmdprot);
phys += PMD_SIZE; phys += PMD_SIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment