diff options
-rw-r--r-- | arch/blackfin/include/asm/mmu_context.h | 14 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbmgr.c | 30 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 5 |
3 files changed, 38 insertions, 11 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; |
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 930c01c06813..d4cc53a0ef89 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c | |||
@@ -114,10 +114,15 @@ static noinline int dcplb_miss(unsigned int cpu) | |||
114 | d_data = L2_DMEMORY; | 114 | d_data = L2_DMEMORY; |
115 | } else if (addr >= physical_mem_end) { | 115 | } else if (addr >= physical_mem_end) { |
116 | if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { | 116 | if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { |
117 | addr &= ~(4 * 1024 * 1024 - 1); | 117 | mask = current_rwx_mask[cpu]; |
118 | d_data &= ~PAGE_SIZE_4KB; | 118 | if (mask) { |
119 | d_data |= PAGE_SIZE_4MB; | 119 | int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; |
120 | d_data |= CPLB_USER_RD | CPLB_USER_WR; | 120 | int idx = page >> 5; |
121 | int bit = 1 << (page & 31); | ||
122 | |||
123 | if (mask[idx] & bit) | ||
124 | d_data |= CPLB_USER_RD; | ||
125 | } | ||
121 | } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH | 126 | } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH |
122 | && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { | 127 | && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { |
123 | addr &= ~(1 * 1024 * 1024 - 1); | 128 | addr &= ~(1 * 1024 * 1024 - 1); |
@@ -204,10 +209,19 @@ static noinline int icplb_miss(unsigned int cpu) | |||
204 | i_data = L2_IMEMORY; | 209 | i_data = L2_IMEMORY; |
205 | } else if (addr >= physical_mem_end) { | 210 | } else if (addr >= physical_mem_end) { |
206 | if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { | 211 | if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { |
207 | addr &= ~(4 * 1024 * 1024 - 1); | 212 | if (!(status & FAULT_USERSUPV)) { |
208 | i_data &= ~PAGE_SIZE_4KB; | 213 | unsigned long *mask = current_rwx_mask[cpu]; |
209 | i_data |= PAGE_SIZE_4MB; | 214 | |
210 | i_data |= CPLB_USER_RD; | 215 | if (mask) { |
216 | int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; | ||
217 | int idx = page >> 5; | ||
218 | int bit = 1 << (page & 31); | ||
219 | |||
220 | mask += 2 * page_mask_nelts; | ||
221 | if (mask[idx] & bit) | ||
222 | i_data |= CPLB_USER_RD; | ||
223 | } | ||
224 | } | ||
211 | } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH | 225 | } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH |
212 | && (status & FAULT_USERSUPV)) { | 226 | && (status & FAULT_USERSUPV)) { |
213 | addr &= ~(1 * 1024 * 1024 - 1); | 227 | addr &= ~(1 * 1024 * 1024 - 1); |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 69cbc1a81201..8dc7ee1ef336 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -597,7 +597,12 @@ static __init void memory_setup(void) | |||
597 | } | 597 | } |
598 | 598 | ||
599 | #ifdef CONFIG_MPU | 599 | #ifdef CONFIG_MPU |
600 | #if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM) | ||
601 | page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE - | ||
602 | ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32; | ||
603 | #else | ||
600 | page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; | 604 | page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; |
605 | #endif | ||
601 | page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); | 606 | page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); |
602 | #endif | 607 | #endif |
603 | 608 | ||