Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01882b4d authored by James Hogan's avatar James Hogan Committed by Ralf Baechle
Browse files

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: default avatarJames 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent d260d97e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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;

+2 −0
Original line number Diff line number Diff line
@@ -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;

+2 −0
Original line number Diff line number Diff line
@@ -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) {
+3 −0
Original line number Diff line number Diff line
@@ -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;

Loading