Commit 5d2e3213 authored by Bernd Schmidt's avatar Bernd Schmidt Committed by Bryan Wu

Blackfin arch: fixing bug - under IRQ stress, running applications may wrongly...

Blackfin arch: fixing bug - under IRQ stress, running applications may wrongly trigger an ICPLB miss and be killed

Disable IRQs while frobbing the CPLB registers, to avoid accessing the
data in current_rwx_mask while it isn't covered by CPLBs.
Signed-off-by: default avatarBernd Schmidt <bernds_cb1@t-online.de>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
parent 0c7a6b21
...@@ -322,9 +322,11 @@ int cplb_hdr(int seqstat, struct pt_regs *regs) ...@@ -322,9 +322,11 @@ int cplb_hdr(int seqstat, struct pt_regs *regs)
void flush_switched_cplbs(void) void flush_switched_cplbs(void)
{ {
int i; int i;
unsigned long flags;
nr_cplb_flush++; nr_cplb_flush++;
local_irq_save(flags);
disable_icplb(); disable_icplb();
for (i = first_switched_icplb; i < MAX_CPLBS; i++) { for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
icplb_tbl[i].data = 0; icplb_tbl[i].data = 0;
...@@ -338,6 +340,8 @@ void flush_switched_cplbs(void) ...@@ -338,6 +340,8 @@ void flush_switched_cplbs(void)
bfin_write32(DCPLB_DATA0 + i * 4, 0); bfin_write32(DCPLB_DATA0 + i * 4, 0);
} }
enable_dcplb(); enable_dcplb();
local_irq_restore(flags);
} }
void set_mask_dcplbs(unsigned long *masks) void set_mask_dcplbs(unsigned long *masks)
...@@ -345,10 +349,15 @@ void set_mask_dcplbs(unsigned long *masks) ...@@ -345,10 +349,15 @@ void set_mask_dcplbs(unsigned long *masks)
int i; int i;
unsigned long addr = (unsigned long)masks; unsigned long addr = (unsigned long)masks;
unsigned long d_data; unsigned long d_data;
current_rwx_mask = masks; unsigned long flags;
if (!masks) if (!masks) {
current_rwx_mask = masks;
return; return;
}
local_irq_save(flags);
current_rwx_mask = masks;
d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_DCACHE #ifdef CONFIG_BFIN_DCACHE
...@@ -367,4 +376,5 @@ void set_mask_dcplbs(unsigned long *masks) ...@@ -367,4 +376,5 @@ void set_mask_dcplbs(unsigned long *masks)
addr += PAGE_SIZE; addr += PAGE_SIZE;
} }
enable_dcplb(); enable_dcplb();
local_irq_restore(flags);
} }
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