I spent the last a few days to track down a problem where /sbin/init
hangs forever. It turns out, I believe, to be a bug introduced in the
recent cache code change.
A new function, r4k_flush_icache_page_i32(), was added recently. It
calls blast_icache32_page(), which uses Hit cache operations to flush
cache. Unfortunately, that will generate TLB fault if virtual address
is not present in TLB. Under certain conditions,
r4k_flush_icache_page_i32() will be called in the middle of handling a
page fault, and it will then generate the same page fault again with
cache hit operation. This causes a deadlock (on current->mm->mmap_sem).
I read the previous version of code. The fix seems to be using the
indexed cache operation. Here is the fix, and apparently it fixes the
problem on my board.
r4k_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page,
unsigned long address)
if (!(vma->vm_flags & VM_EXEC))
+ address = KSEG0 + (address & PAGE_MASK & (dcache_size - 1));