diff options
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 124 |
1 files changed, 4 insertions, 120 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index d0b64df51eb2..5166e38cd1c6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -540,6 +540,9 @@ static inline int has_valid_asid(const struct mm_struct *mm, unsigned int type) unsigned int i; const cpumask_t *mask = cpu_present_mask; + if (cpu_has_mmid) + return cpu_context(0, mm) != 0; + /* cpu_sibling_map[] undeclared when !CONFIG_SMP */ #ifdef CONFIG_SMP /* @@ -697,10 +700,7 @@ static inline void local_r4k_flush_cache_page(void *args) } if (exec) { 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); + drop_mmu_context(mm); } else vaddr ? r4k_blast_icache_page(addr) : r4k_blast_icache_user_page(addr); @@ -937,119 +937,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) } #endif /* CONFIG_DMA_NONCOHERENT */ -struct flush_cache_sigtramp_args { - struct mm_struct *mm; - struct page *page; - unsigned long addr; -}; - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void local_r4k_flush_cache_sigtramp(void *args) -{ - struct flush_cache_sigtramp_args *fcs_args = args; - unsigned long addr = fcs_args->addr; - struct page *page = fcs_args->page; - struct mm_struct *mm = fcs_args->mm; - int map_coherent = 0; - void *vaddr; - - unsigned long ic_lsize = cpu_icache_line_size(); - unsigned long dc_lsize = cpu_dcache_line_size(); - unsigned long sc_lsize = cpu_scache_line_size(); - - /* - * If owns no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (!has_valid_asid(mm, R4K_HIT)) - return; - - if (mm == current->active_mm) { - vaddr = NULL; - } else { - /* - * Use kmap_coherent or kmap_atomic to do flushes for - * another ASID than the current one. - */ - map_coherent = (cpu_has_dc_aliases && - page_mapcount(page) && - !Page_dcache_dirty(page)); - if (map_coherent) - vaddr = kmap_coherent(page, addr); - else - vaddr = kmap_atomic(page); - addr = (unsigned long)vaddr + (addr & ~PAGE_MASK); - } - - R4600_HIT_CACHEOP_WAR_IMPL; - if (!cpu_has_ic_fills_f_dc) { - if (dc_lsize) - vaddr ? flush_dcache_line(addr & ~(dc_lsize - 1)) - : protected_writeback_dcache_line( - addr & ~(dc_lsize - 1)); - if (!cpu_icache_snoops_remote_store && scache_size) - vaddr ? flush_scache_line(addr & ~(sc_lsize - 1)) - : protected_writeback_scache_line( - addr & ~(sc_lsize - 1)); - } - if (ic_lsize) - vaddr ? flush_icache_line(addr & ~(ic_lsize - 1)) - : protected_flush_icache_line(addr & ~(ic_lsize - 1)); - - if (vaddr) { - if (map_coherent) - kunmap_coherent(); - else - kunmap_atomic(vaddr); - } - - if (MIPS4K_ICACHE_REFILL_WAR) { - __asm__ __volatile__ ( - ".set push\n\t" - ".set noat\n\t" - ".set "MIPS_ISA_LEVEL"\n\t" -#ifdef CONFIG_32BIT - "la $at,1f\n\t" -#endif -#ifdef CONFIG_64BIT - "dla $at,1f\n\t" -#endif - "cache %0,($at)\n\t" - "nop; nop; nop\n" - "1:\n\t" - ".set pop" - : - : "i" (Hit_Invalidate_I)); - } - if (MIPS_CACHE_SYNC_WAR) - __asm__ __volatile__ ("sync"); -} - -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - struct flush_cache_sigtramp_args args; - int npages; - - down_read(¤t->mm->mmap_sem); - - npages = get_user_pages_fast(addr, 1, 0, &args.page); - if (npages < 1) - goto out; - - args.mm = current->mm; - args.addr = addr; - - r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args); - - put_page(args.page); -out: - up_read(¤t->mm->mmap_sem); -} - static void r4k_flush_icache_all(void) { if (cpu_has_vtag_icache) @@ -1978,7 +1865,6 @@ void r4k_cache_init(void) __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; - flush_cache_sigtramp = r4k_flush_cache_sigtramp; flush_icache_all = r4k_flush_icache_all; local_flush_data_cache_page = local_r4k_flush_data_cache_page; flush_data_cache_page = r4k_flush_data_cache_page; @@ -2033,7 +1919,6 @@ void r4k_cache_init(void) /* I$ fills from D$ just by emptying the write buffers */ flush_cache_page = (void *)b5k_instruction_hazard; flush_cache_range = (void *)b5k_instruction_hazard; - flush_cache_sigtramp = (void *)b5k_instruction_hazard; local_flush_data_cache_page = (void *)b5k_instruction_hazard; flush_data_cache_page = (void *)b5k_instruction_hazard; flush_icache_range = (void *)b5k_instruction_hazard; @@ -2052,7 +1937,6 @@ void r4k_cache_init(void) flush_cache_mm = (void *)cache_noop; flush_cache_page = (void *)cache_noop; flush_cache_range = (void *)cache_noop; - flush_cache_sigtramp = (void *)cache_noop; flush_icache_all = (void *)cache_noop; flush_data_cache_page = (void *)cache_noop; local_flush_data_cache_page = (void *)cache_noop; |