aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include
diff options
context:
space:
mode:
authorBarry Song <barry.song@analog.com>2009-12-07 05:05:58 -0500
committerMike Frysinger <vapier@gentoo.org>2010-03-09 00:30:46 -0500
commite18e7dd33454f277b9438af66d25984362278021 (patch)
tree3c809ab2ebf8ad6276570f7eab238bd45e7216e8 /arch/blackfin/include
parentc9784ebb23be1e2ef23f537d6df04e0ea0206802 (diff)
Blackfin: fix MPU page permission masks overflow when dealing with async memory
Attempting to use the MPU while doing XIP out of parallel flash hooked up to the async memory bus would often result in random crashes as the MPU slowly corrupted memory. The fallout here is that the async banks gain MPU protection from user space too. So any accesses have to go through the mmap() interface rather than just using hardcoded pointers. Signed-off-by: Barry Song <barry.song@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/include')
-rw-r--r--arch/blackfin/include/asm/mmu_context.h14
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index ae8ef4ffd806..7f363d7e43a5 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -13,6 +13,7 @@
13#include <asm/page.h> 13#include <asm/page.h>
14#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
15#include <asm/cplbinit.h> 15#include <asm/cplbinit.h>
16#include <asm/sections.h>
16 17
17/* Note: L1 stacks are CPU-private things, so we bluntly disable this 18/* Note: L1 stacks are CPU-private things, so we bluntly disable this
18 feature in SMP mode, and use the per-CPU scratch SRAM bank only to 19 feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -117,9 +118,16 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
117 unsigned long flags) 118 unsigned long flags)
118{ 119{
119 unsigned long *mask = mm->context.page_rwx_mask; 120 unsigned long *mask = mm->context.page_rwx_mask;
120 unsigned long page = addr >> 12; 121 unsigned long page;
121 unsigned long idx = page >> 5; 122 unsigned long idx;
122 unsigned long bit = 1 << (page & 31); 123 unsigned long bit;
124
125 if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
126 page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
127 else
128 page = addr >> 12;
129 idx = page >> 5;
130 bit = 1 << (page & 31);
123 131
124 if (flags & VM_READ) 132 if (flags & VM_READ)
125 mask[idx] |= bit; 133 mask[idx] |= bit;