mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
[MIPS] local_r4k_flush_cache_page fix
If dcache_size != icache_size or dcache_size != scache_size, or set-associative cache, icache/scache does not flushed properly. Make blast_?cache_page_indexed() masks its index value correctly. Also, use physical address for physically indexed pcache/scache. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
a3c4946db4
commit
de62893bc0
@ -375,6 +375,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
|
|||||||
struct flush_cache_page_args {
|
struct flush_cache_page_args {
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
unsigned long pfn;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void local_r4k_flush_cache_page(void *args)
|
static inline void local_r4k_flush_cache_page(void *args)
|
||||||
@ -382,6 +383,7 @@ 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;
|
||||||
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;
|
||||||
@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache_page(void *args)
|
|||||||
* Do indexed flush, too much work to get the (possible) TLB refills
|
* Do indexed flush, too much work to get the (possible) TLB refills
|
||||||
* to work correctly.
|
* to work correctly.
|
||||||
*/
|
*/
|
||||||
addr = INDEX_BASE + (addr & (dcache_size - 1));
|
|
||||||
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_indexed(addr);
|
r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
|
||||||
if (exec && !cpu_icache_snoops_remote_store)
|
paddr : addr);
|
||||||
r4k_blast_scache_page_indexed(addr);
|
if (exec && !cpu_icache_snoops_remote_store) {
|
||||||
|
r4k_blast_scache_page_indexed(paddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (exec) {
|
if (exec) {
|
||||||
if (cpu_has_vtag_icache) {
|
if (cpu_has_vtag_icache) {
|
||||||
@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
|
|||||||
|
|
||||||
args.vma = vma;
|
args.vma = vma;
|
||||||
args.addr = addr;
|
args.addr = addr;
|
||||||
|
args.pfn = pfn;
|
||||||
|
|
||||||
on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
|
on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
|
||||||
}
|
}
|
||||||
@ -956,6 +960,7 @@ static void __init probe_pcache(void)
|
|||||||
switch (c->cputype) {
|
switch (c->cputype) {
|
||||||
case CPU_20KC:
|
case CPU_20KC:
|
||||||
case CPU_25KF:
|
case CPU_25KF:
|
||||||
|
c->dcache.flags |= MIPS_CACHE_PINDEX;
|
||||||
case CPU_R10000:
|
case CPU_R10000:
|
||||||
case CPU_R12000:
|
case CPU_R12000:
|
||||||
case CPU_SB1:
|
case CPU_SB1:
|
||||||
|
@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
|
|||||||
* Do indexed flush, too much work to get the (possible) TLB refills
|
* Do indexed flush, too much work to get the (possible) TLB refills
|
||||||
* to work correctly.
|
* to work correctly.
|
||||||
*/
|
*/
|
||||||
page = (KSEG0 + (page & (dcache_size - 1)));
|
|
||||||
if (cpu_has_dc_aliases || exec)
|
if (cpu_has_dc_aliases || exec)
|
||||||
tx39_blast_dcache_page_indexed(page);
|
tx39_blast_dcache_page_indexed(page);
|
||||||
if (exec)
|
if (exec)
|
||||||
|
@ -96,6 +96,9 @@
|
|||||||
#ifndef cpu_has_ic_fills_f_dc
|
#ifndef cpu_has_ic_fills_f_dc
|
||||||
#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
|
#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef cpu_has_pindexed_dcache
|
||||||
|
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
|
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
|
||||||
|
@ -39,6 +39,7 @@ struct cache_desc {
|
|||||||
#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
|
#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
|
||||||
#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
|
#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
|
||||||
#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
|
#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
|
||||||
|
#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
|
||||||
|
|
||||||
struct cpuinfo_mips {
|
struct cpuinfo_mips {
|
||||||
unsigned long udelay_val;
|
unsigned long udelay_val;
|
||||||
|
@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
|
|||||||
\
|
\
|
||||||
static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
|
static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
|
||||||
{ \
|
{ \
|
||||||
unsigned long start = page; \
|
unsigned long indexmask = current_cpu_data.desc.waysize - 1; \
|
||||||
|
unsigned long start = INDEX_BASE + (page & indexmask); \
|
||||||
unsigned long end = start + PAGE_SIZE; \
|
unsigned long end = start + PAGE_SIZE; \
|
||||||
unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
|
unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
|
||||||
unsigned long ws_end = current_cpu_data.desc.ways << \
|
unsigned long ws_end = current_cpu_data.desc.ways << \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user