diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2008-02-16 17:34:25 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-02-19 12:01:31 -0500 |
commit | 9a74b3eb22f2d67a5681301f52aca5b7703382c8 (patch) | |
tree | 3ef7b8713edfccc96ad1ce57a431828656d92d82 /arch/mips/mm/cache.c | |
parent | c42d95d6c49ce9c678a9d10aeb3f526c850d66dc (diff) |
[MIPS] Fix buggy invocations of kmap_coherent()
kmap_coherent will only work correctly if the page it is called on is
not marked dirty. If it's dirty the kernel address of the page should
be used instead of a temporary mapping.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/cache.c')
-rw-r--r-- | arch/mips/mm/cache.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 81f30ac2bff9..6a24651971df 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -92,12 +92,17 @@ EXPORT_SYMBOL(__flush_dcache_page); | |||
92 | 92 | ||
93 | void __flush_anon_page(struct page *page, unsigned long vmaddr) | 93 | void __flush_anon_page(struct page *page, unsigned long vmaddr) |
94 | { | 94 | { |
95 | if (pages_do_alias((unsigned long)page_address(page), vmaddr)) { | 95 | unsigned long addr = (unsigned long) page_address(page); |
96 | void *kaddr; | ||
97 | 96 | ||
98 | kaddr = kmap_coherent(page, vmaddr); | 97 | if (pages_do_alias(addr, vmaddr)) { |
99 | flush_data_cache_page((unsigned long)kaddr); | 98 | if (page_mapped(page) && !Page_dcache_dirty(page)) { |
100 | kunmap_coherent(); | 99 | void *kaddr; |
100 | |||
101 | kaddr = kmap_coherent(page, vmaddr); | ||
102 | flush_data_cache_page((unsigned long)kaddr); | ||
103 | kunmap_coherent(); | ||
104 | } else | ||
105 | flush_data_cache_page(addr); | ||
101 | } | 106 | } |
102 | } | 107 | } |
103 | 108 | ||