linux-mips
[Top] [All Lists]

Re: [BUG] R5000 failure in kmap_coherent on Lasat board, bug that has be

To: Thomas Horsten <thomas@horsten.com>
Subject: Re: [BUG] R5000 failure in kmap_coherent on Lasat board, bug that has been there for a while?
From: Ralf Baechle <ralf@linux-mips.org>
Date: Sat, 14 Jun 2008 13:59:03 +0100
Cc: linux-mips@linux-mips.org
In-reply-to: <Pine.LNX.4.40.0806131600540.25629-100000@jehova.dsm.dk>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <Pine.LNX.4.40.0806131600540.25629-100000@jehova.dsm.dk>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mutt/1.5.17 (2007-11-01)
On Fri, Jun 13, 2008 at 04:06:03PM +0100, Thomas Horsten wrote:

Only compile tested - can you try this one?

  Ralf

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index c41ea22..2709675 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -446,6 +446,7 @@ static inline void local_r4k_flush_cache_page(void *args)
        struct page *page = pfn_to_page(fcp_args->pfn);
        int exec = vma->vm_flags & VM_EXEC;
        struct mm_struct *mm = vma->vm_mm;
+       int map_coherent = 0;
        pgd_t *pgdp;
        pud_t *pudp;
        pmd_t *pmdp;
@@ -479,7 +480,9 @@ static inline void local_r4k_flush_cache_page(void *args)
                 * Use kmap_coherent or kmap_atomic to do flushes for
                 * another ASID than the current one.
                 */
-               if (cpu_has_dc_aliases)
+               map_coherent = (cpu_has_dc_aliases &&
+                               page_mapped(page) && !Page_dcache_dirty(page));
+               if (map_coherent)
                        vaddr = kmap_coherent(page, addr);
                else
                        vaddr = kmap_atomic(page, KM_USER0);
@@ -502,7 +505,7 @@ static inline void local_r4k_flush_cache_page(void *args)
        }
 
        if (vaddr) {
-               if (cpu_has_dc_aliases)
+               if (map_coherent)
                        kunmap_coherent();
                else
                        kunmap_atomic(vaddr, KM_USER0);

<Prev in Thread] Current Thread [Next in Thread>