提交 db813fe5 编写于 作者: R Ralf Baechle

[MIPS] Avoid indexed cacheops.

On MP configurations it's highly dubious what this code will actually
affect since blasting away cachelines may or may not do the right
thing wrt. cache coherency.
Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 e58d95ab
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/highmem.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void) ...@@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void)
r4k_blast_scache = blast_scache128; r4k_blast_scache = blast_scache128;
} }
/*
* This is former mm's flush_cache_all() which really should be
* flush_cache_vunmap these days ...
*/
static inline void local_r4k_flush_cache_all(void * args)
{
r4k_blast_dcache();
}
static void r4k_flush_cache_all(void)
{
if (!cpu_has_dc_aliases)
return;
r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
}
static inline void local_r4k___flush_cache_all(void * args) static inline void local_r4k___flush_cache_all(void * args)
{ {
#if defined(CONFIG_CPU_LOONGSON2) #if defined(CONFIG_CPU_LOONGSON2)
...@@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args) ...@@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args)
struct flush_cache_page_args *fcp_args = args; struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma; struct vm_area_struct *vma = fcp_args->vma;
unsigned long addr = fcp_args->addr; unsigned long addr = fcp_args->addr;
unsigned long paddr = fcp_args->pfn << PAGE_SHIFT; struct page *page = pfn_to_page(fcp_args->pfn);
int exec = vma->vm_flags & VM_EXEC; int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm; struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp; pgd_t *pgdp;
pud_t *pudp; pud_t *pudp;
pmd_t *pmdp; pmd_t *pmdp;
pte_t *ptep; pte_t *ptep;
void *vaddr;
/* /*
* If ownes no valid ASID yet, cannot possibly have gotten * If ownes no valid ASID yet, cannot possibly have gotten
...@@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args) ...@@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args)
if (!(pte_val(*ptep) & _PAGE_PRESENT)) if (!(pte_val(*ptep) & _PAGE_PRESENT))
return; return;
if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
vaddr = NULL;
else {
/* /*
* Doing flushes for another ASID than the current one is * Use kmap_coherent or kmap_atomic to do flushes for
* too difficult since stupid R4k caches do a TLB translation * another ASID than the current one.
* for every cache flush operation. So we do indexed flushes
* in that case, which doesn't overly flush the cache too much.
*/ */
if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { if (cpu_has_dc_aliases)
vaddr = kmap_coherent(page, addr);
else
vaddr = kmap_atomic(page, KM_USER0);
addr = (unsigned long)vaddr;
}
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
r4k_blast_dcache_page(addr); r4k_blast_dcache_page(addr);
if (exec && !cpu_icache_snoops_remote_store) if (exec && !cpu_icache_snoops_remote_store)
r4k_blast_scache_page(addr); r4k_blast_scache_page(addr);
} }
if (exec)
r4k_blast_icache_page(addr);
return;
}
/*
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
paddr : addr);
if (exec && !cpu_icache_snoops_remote_store) {
r4k_blast_scache_page_indexed(paddr);
}
}
if (exec) { if (exec) {
if (cpu_has_vtag_icache && mm == current->active_mm) { if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (cpu_context(cpu, mm) != 0) if (cpu_context(cpu, mm) != 0)
drop_mmu_context(mm, cpu); drop_mmu_context(mm, cpu);
} else } else
r4k_blast_icache_page_indexed(addr); r4k_blast_icache_page(addr);
}
if (vaddr) {
if (cpu_has_dc_aliases)
kunmap_coherent();
else
kunmap_atomic(vaddr, KM_USER0);
} }
} }
...@@ -1279,7 +1261,7 @@ void __init r4k_cache_init(void) ...@@ -1279,7 +1261,7 @@ void __init r4k_cache_init(void)
PAGE_SIZE - 1); PAGE_SIZE - 1);
else else
shm_align_mask = PAGE_SIZE-1; shm_align_mask = PAGE_SIZE-1;
flush_cache_all = r4k_flush_cache_all; flush_cache_all = cache_noop;
__flush_cache_all = r4k___flush_cache_all; __flush_cache_all = r4k___flush_cache_all;
flush_cache_mm = r4k_flush_cache_mm; flush_cache_mm = r4k_flush_cache_mm;
flush_cache_page = r4k_flush_cache_page; flush_cache_page = r4k_flush_cache_page;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册