Commit db813fe5 authored by Ralf Baechle's avatar 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent e58d95ab
......@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/init.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/sched.h>
......@@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void)
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)
{
#if defined(CONFIG_CPU_LOONGSON2)
......@@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args)
struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma;
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;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
void *vaddr;
/*
* If ownes no valid ASID yet, cannot possibly have gotten
......@@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args)
if (!(pte_val(*ptep) & _PAGE_PRESENT))
return;
if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
vaddr = NULL;
else {
/*
* Doing flushes for another ASID than the current one is
* too difficult since stupid R4k caches do a TLB translation
* for every cache flush operation. So we do indexed flushes
* in that case, which doesn't overly flush the cache too much.
* Use kmap_coherent or kmap_atomic to do flushes for
* another ASID than the current one.
*/
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)) {
r4k_blast_dcache_page(addr);
if (exec && !cpu_icache_snoops_remote_store)
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 (cpu_has_vtag_icache && mm == current->active_mm) {
if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
int cpu = smp_processor_id();
if (cpu_context(cpu, mm) != 0)
drop_mmu_context(mm, cpu);
} 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)
PAGE_SIZE - 1);
else
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_mm = r4k_flush_cache_mm;
flush_cache_page = r4k_flush_cache_page;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment