Title: [7942] trunk/arch/blackfin: bug [#5704], fix memory overflow of page permission masks when vma is located in async memory
- Revision
- 7942
- Author
- bhsong
- Date
- 2009-12-07 05:05:58 -0500 (Mon, 07 Dec 2009)
Log Message
bug [#5704], fix memory overflow of page permission masks when vma is located in async memory
Modified Paths
Diff
Modified: trunk/arch/blackfin/include/asm/mmu_context.h (7941 => 7942)
--- trunk/arch/blackfin/include/asm/mmu_context.h 2009-12-07 09:36:28 UTC (rev 7941)
+++ trunk/arch/blackfin/include/asm/mmu_context.h 2009-12-07 10:05:58 UTC (rev 7942)
@@ -13,6 +13,7 @@
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/cplbinit.h>
+#include <asm/sections.h>
/* Note: L1 stacks are CPU-private things, so we bluntly disable this
feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -117,10 +118,17 @@
unsigned long flags)
{
unsigned long *mask = mm->context.page_rwx_mask;
- unsigned long page = addr >> 12;
- unsigned long idx = page >> 5;
- unsigned long bit = 1 << (page & 31);
+ unsigned long page;
+ unsigned long idx;
+ unsigned long bit;
+ if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
+ page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
+ else
+ page = addr >> 12;
+ idx = page >> 5;
+ bit = 1 << (page & 31);
+
if (flags & VM_READ)
mask[idx] |= bit;
else
Modified: trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c (7941 => 7942)
--- trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c 2009-12-07 09:36:28 UTC (rev 7941)
+++ trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c 2009-12-07 10:05:58 UTC (rev 7942)
@@ -114,10 +114,15 @@
d_data = L2_DMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
- addr &= ~(4 * 1024 * 1024 - 1);
- d_data &= ~PAGE_SIZE_4KB;
- d_data |= PAGE_SIZE_4MB;
- d_data |= CPLB_USER_RD | CPLB_USER_WR;
+ mask = current_rwx_mask[cpu];
+ if (mask) {
+ int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+ int idx = page >> 5;
+ int bit = 1 << (page & 31);
+
+ if (mask[idx] & bit)
+ d_data |= CPLB_USER_RD;
+ }
} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
&& (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
addr &= ~(1 * 1024 * 1024 - 1);
@@ -204,10 +209,19 @@
i_data = L2_IMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
- addr &= ~(4 * 1024 * 1024 - 1);
- i_data &= ~PAGE_SIZE_4KB;
- i_data |= PAGE_SIZE_4MB;
- i_data |= CPLB_USER_RD;
+ if (!(status & FAULT_USERSUPV)) {
+ unsigned long *mask = current_rwx_mask[cpu];
+
+ if (mask) {
+ int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+ int idx = page >> 5;
+ int bit = 1 << (page & 31);
+
+ mask += 2 * page_mask_nelts;
+ if (mask[idx] & bit)
+ i_data |= CPLB_USER_RD;
+ }
+ }
} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
&& (status & FAULT_USERSUPV)) {
addr &= ~(1 * 1024 * 1024 - 1);
Modified: trunk/arch/blackfin/kernel/setup.c (7941 => 7942)
--- trunk/arch/blackfin/kernel/setup.c 2009-12-07 09:36:28 UTC (rev 7941)
+++ trunk/arch/blackfin/kernel/setup.c 2009-12-07 10:05:58 UTC (rev 7942)
@@ -597,7 +597,12 @@
}
#ifdef CONFIG_MPU
+#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
+ page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE -
+ ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32;
+#else
page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
+#endif
page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
#endif
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits