MIPS: c-r4k: Split user/kernel flush_icache_range()
flush_icache_range() is used for both user addresses (i.e. cacheflush(2)), and kernel addresses (as the API documentation describes). This isn't really suitable however for Enhanced Virtual Addressing (EVA) where cache operations on usermode addresses must use a different instruction, and the protected cache ops assume user addresses, making flush_icache_range() ineffective on kernel addresses. Split out a new __flush_icache_user_range() and __local_flush_icache_user_range() for users which actually want to flush usermode addresses (note that flush_icache_user_range() already exists on various architectures but with different arguments). The implementation of flush_icache_range() will be changed in an upcoming commit to use unprotected normal cache ops so as to always work on the kernel mode address space. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14152/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
d260d97e64
commit
01882b4d5e
@ -28,6 +28,7 @@
|
||||
* - flush_cache_sigtramp() flush signal trampoline
|
||||
* - flush_icache_all() flush the entire instruction cache
|
||||
* - flush_data_cache_page() flushes a page from the data cache
|
||||
* - __flush_icache_user_range(start, end) flushes range of user instructions
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -80,6 +81,10 @@ static inline void flush_icache_page(struct vm_area_struct *vma,
|
||||
|
||||
extern void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
extern void (*local_flush_icache_range)(unsigned long start, unsigned long end);
|
||||
extern void (*__flush_icache_user_range)(unsigned long start,
|
||||
unsigned long end);
|
||||
extern void (*__local_flush_icache_user_range)(unsigned long start,
|
||||
unsigned long end);
|
||||
|
||||
extern void (*__flush_cache_vmap)(void);
|
||||
|
||||
|
@ -294,6 +294,8 @@ void octeon_cache_init(void)
|
||||
flush_data_cache_page = octeon_flush_data_cache_page;
|
||||
flush_icache_range = octeon_flush_icache_range;
|
||||
local_flush_icache_range = local_octeon_flush_icache_range;
|
||||
__flush_icache_user_range = octeon_flush_icache_range;
|
||||
__local_flush_icache_user_range = local_octeon_flush_icache_range;
|
||||
|
||||
__flush_kernel_vmap_range = octeon_flush_kernel_vmap_range;
|
||||
|
||||
|
@ -325,6 +325,8 @@ void r3k_cache_init(void)
|
||||
flush_cache_page = r3k_flush_cache_page;
|
||||
flush_icache_range = r3k_flush_icache_range;
|
||||
local_flush_icache_range = r3k_flush_icache_range;
|
||||
__flush_icache_user_range = r3k_flush_icache_range;
|
||||
__local_flush_icache_user_range = r3k_flush_icache_range;
|
||||
|
||||
__flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
|
||||
|
||||
|
@ -1904,6 +1904,8 @@ void r4k_cache_init(void)
|
||||
flush_data_cache_page = r4k_flush_data_cache_page;
|
||||
flush_icache_range = r4k_flush_icache_range;
|
||||
local_flush_icache_range = local_r4k_flush_icache_range;
|
||||
__flush_icache_user_range = r4k_flush_icache_range;
|
||||
__local_flush_icache_user_range = local_r4k_flush_icache_range;
|
||||
|
||||
#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
|
||||
if (coherentio) {
|
||||
|
@ -411,6 +411,9 @@ void tx39_cache_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
__flush_icache_user_range = flush_icache_range;
|
||||
__local_flush_icache_user_range = local_flush_icache_range;
|
||||
|
||||
current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways;
|
||||
current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways;
|
||||
|
||||
|
@ -33,6 +33,10 @@ void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
EXPORT_SYMBOL_GPL(flush_icache_range);
|
||||
void (*local_flush_icache_range)(unsigned long start, unsigned long end);
|
||||
EXPORT_SYMBOL_GPL(local_flush_icache_range);
|
||||
void (*__flush_icache_user_range)(unsigned long start, unsigned long end);
|
||||
EXPORT_SYMBOL_GPL(__flush_icache_user_range);
|
||||
void (*__local_flush_icache_user_range)(unsigned long start, unsigned long end);
|
||||
EXPORT_SYMBOL_GPL(__local_flush_icache_user_range);
|
||||
|
||||
void (*__flush_cache_vmap)(void);
|
||||
void (*__flush_cache_vunmap)(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user