diff options
author | Anton Wöllert <a.woellert@gmail.com> | 2005-07-27 03:45:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-27 19:34:34 -0400 |
commit | bf85fa6c878aa3968df47d7f70a2b506c3e53b99 (patch) | |
tree | f7e4c5c03b053a629f3bc8206b70fae34424ffab /arch/ppc/mm | |
parent | 59904159c316f7bc02d00ff7b0dc3f9d3afd07fd (diff) |
[PATCH] ppc32: 8xx avoid icbi misbehaviour in __flush_dcache_icache_phys
On 8xx, in the case where a pagefault happens for a process who's not
the owner of the vma in question (ptrace for instance), the flush
operation is performed via the physical address.
Unfortunately, that results in a strange, unexplainable "icbi"
instruction fault, most likely due to a CPU bug (see oops below).
Avoid that by flushing the page via its kernel virtual address.
Oops: kernel access of bad area, sig: 11 [#2]
NIP: C000543C LR: C000B060 SP: C0F35DF0 REGS: c0f35d40 TRAP: 0300 Not tainted
MSR: 00009022 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 10
DAR: 00000010, DSISR: C2000000
TASK = c0ea8430[761] 'gdbserver' THREAD: c0f34000
Last syscall: 26
GPR00: 00009022 C0F35DF0 C0EA8430 00F59000 00000100 FFFFFFFF 00F58000
00000001
GPR08: C021DAEF C0270000 00009032 C0270000 22044024 10025428 01000800
00000001
GPR16: 007FFF3F 00000001 00000000 7FBC6AC0 00F61022 00000001 C0839300
C01E0000
GPR24: 00CD0889 C082F568 3000AC18 C02A7A00 C0EA15C8 00F588A9 C02ACB00
C02ACB00
NIP [c000543c] __flush_dcache_icache_phys+0x38/0x54
LR [c000b060] flush_dcache_icache_page+0x20/0x30
Call trace:
[c000b154] update_mmu_cache+0x7c/0xa4
[c005ae98] do_wp_page+0x460/0x5ec
[c005c8a0] handle_mm_fault+0x7cc/0x91c
[c005ccec] get_user_pages+0x2fc/0x65c
[c0027104] access_process_vm+0x9c/0x1d4
[c00076e0] sys_ptrace+0x240/0x4a4
[c0002bd0] ret_from_syscall+0x0/0x44
Signed-off-by: Marcelo Tosatti <marcelo.tosatti@cyclades.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/mm')
-rw-r--r-- | arch/ppc/mm/init.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 6164a2b34733..33ada72c7330 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c | |||
@@ -562,6 +562,9 @@ void flush_dcache_icache_page(struct page *page) | |||
562 | #ifdef CONFIG_BOOKE | 562 | #ifdef CONFIG_BOOKE |
563 | __flush_dcache_icache(kmap(page)); | 563 | __flush_dcache_icache(kmap(page)); |
564 | kunmap(page); | 564 | kunmap(page); |
565 | #elif CONFIG_8xx | ||
566 | /* On 8xx there is no need to kmap since highmem is not supported */ | ||
567 | __flush_dcache_icache(page_address(page)); | ||
565 | #else | 568 | #else |
566 | __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); | 569 | __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); |
567 | #endif | 570 | #endif |