Skip to content

Commit 01882b4

Browse files
James Hoganralfbaechle
authored andcommitted
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 <[email protected]> Cc: Leonid Yegoshin <[email protected]> Cc: [email protected] Patchwork: https://patchwork.linux-mips.org/patch/14152/ Signed-off-by: Ralf Baechle <[email protected]>
1 parent d260d97 commit 01882b4

File tree

6 files changed

+18
-0
lines changed

6 files changed

+18
-0
lines changed

arch/mips/include/asm/cacheflush.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* - flush_cache_sigtramp() flush signal trampoline
2929
* - flush_icache_all() flush the entire instruction cache
3030
* - flush_data_cache_page() flushes a page from the data cache
31+
* - __flush_icache_user_range(start, end) flushes range of user instructions
3132
*/
3233

3334
/*
@@ -80,6 +81,10 @@ static inline void flush_icache_page(struct vm_area_struct *vma,
8081

8182
extern void (*flush_icache_range)(unsigned long start, unsigned long end);
8283
extern void (*local_flush_icache_range)(unsigned long start, unsigned long end);
84+
extern void (*__flush_icache_user_range)(unsigned long start,
85+
unsigned long end);
86+
extern void (*__local_flush_icache_user_range)(unsigned long start,
87+
unsigned long end);
8388

8489
extern void (*__flush_cache_vmap)(void);
8590

arch/mips/mm/c-octeon.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ void octeon_cache_init(void)
294294
flush_data_cache_page = octeon_flush_data_cache_page;
295295
flush_icache_range = octeon_flush_icache_range;
296296
local_flush_icache_range = local_octeon_flush_icache_range;
297+
__flush_icache_user_range = octeon_flush_icache_range;
298+
__local_flush_icache_user_range = local_octeon_flush_icache_range;
297299

298300
__flush_kernel_vmap_range = octeon_flush_kernel_vmap_range;
299301

arch/mips/mm/c-r3k.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ void r3k_cache_init(void)
325325
flush_cache_page = r3k_flush_cache_page;
326326
flush_icache_range = r3k_flush_icache_range;
327327
local_flush_icache_range = r3k_flush_icache_range;
328+
__flush_icache_user_range = r3k_flush_icache_range;
329+
__local_flush_icache_user_range = r3k_flush_icache_range;
328330

329331
__flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
330332

arch/mips/mm/c-r4k.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,8 @@ void r4k_cache_init(void)
19041904
flush_data_cache_page = r4k_flush_data_cache_page;
19051905
flush_icache_range = r4k_flush_icache_range;
19061906
local_flush_icache_range = local_r4k_flush_icache_range;
1907+
__flush_icache_user_range = r4k_flush_icache_range;
1908+
__local_flush_icache_user_range = local_r4k_flush_icache_range;
19071909

19081910
#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
19091911
if (coherentio) {

arch/mips/mm/c-tx39.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ void tx39_cache_init(void)
411411
break;
412412
}
413413

414+
__flush_icache_user_range = flush_icache_range;
415+
__local_flush_icache_user_range = local_flush_icache_range;
416+
414417
current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways;
415418
current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways;
416419

arch/mips/mm/cache.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ void (*flush_icache_range)(unsigned long start, unsigned long end);
3333
EXPORT_SYMBOL_GPL(flush_icache_range);
3434
void (*local_flush_icache_range)(unsigned long start, unsigned long end);
3535
EXPORT_SYMBOL_GPL(local_flush_icache_range);
36+
void (*__flush_icache_user_range)(unsigned long start, unsigned long end);
37+
EXPORT_SYMBOL_GPL(__flush_icache_user_range);
38+
void (*__local_flush_icache_user_range)(unsigned long start, unsigned long end);
39+
EXPORT_SYMBOL_GPL(__local_flush_icache_user_range);
3640

3741
void (*__flush_cache_vmap)(void);
3842
void (*__flush_cache_vunmap)(void);

0 commit comments

Comments
 (0)