diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2008-11-06 08:23:08 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2008-11-06 08:23:08 -0500 |
commit | 376e14218d3d791127e9b9bfbe2f99c44c2a19c2 (patch) | |
tree | 227ff719a9b4092a610c51f15a00a599ed072cc5 /arch/arm/include | |
parent | 24b647a042b988b017e6cdf60b47a0bfecd1dc41 (diff) |
Do not flush the cache in flush_cache_v(un)map for VIPT caches
In case of non-aliasing VIPT caches, there is no need to flush the whole
cache when new mapping is created. The patch introduces this condition
check. In the non-aliasing VIPT case flush_cache_vmap() needs a DSB
since the set_pte_at() function called from vmap_pte_range() does not
have such barrier (done usually via TLB flushing functions).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/cacheflush.h | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index de6c59f814a1..85a2514cbffc 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <asm/glue.h> | 16 | #include <asm/glue.h> |
17 | #include <asm/shmparam.h> | 17 | #include <asm/shmparam.h> |
18 | #include <asm/cachetype.h> | ||
18 | 19 | ||
19 | #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) | 20 | #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) |
20 | 21 | ||
@@ -296,16 +297,6 @@ static inline void outer_flush_range(unsigned long start, unsigned long end) | |||
296 | #endif | 297 | #endif |
297 | 298 | ||
298 | /* | 299 | /* |
299 | * flush_cache_vmap() is used when creating mappings (eg, via vmap, | ||
300 | * vmalloc, ioremap etc) in kernel space for pages. Since the | ||
301 | * direct-mappings of these pages may contain cached data, we need | ||
302 | * to do a full cache flush to ensure that writebacks don't corrupt | ||
303 | * data placed into these pages via the new mappings. | ||
304 | */ | ||
305 | #define flush_cache_vmap(start, end) flush_cache_all() | ||
306 | #define flush_cache_vunmap(start, end) flush_cache_all() | ||
307 | |||
308 | /* | ||
309 | * Copy user data from/to a page which is mapped into a different | 300 | * Copy user data from/to a page which is mapped into a different |
310 | * processes address space. Really, we want to allow our "user | 301 | * processes address space. Really, we want to allow our "user |
311 | * space" model to handle this. | 302 | * space" model to handle this. |
@@ -444,4 +435,29 @@ static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, | |||
444 | dmac_inv_range(start, start + size); | 435 | dmac_inv_range(start, start + size); |
445 | } | 436 | } |
446 | 437 | ||
438 | /* | ||
439 | * flush_cache_vmap() is used when creating mappings (eg, via vmap, | ||
440 | * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT | ||
441 | * caches, since the direct-mappings of these pages may contain cached | ||
442 | * data, we need to do a full cache flush to ensure that writebacks | ||
443 | * don't corrupt data placed into these pages via the new mappings. | ||
444 | */ | ||
445 | static inline void flush_cache_vmap(unsigned long start, unsigned long end) | ||
446 | { | ||
447 | if (!cache_is_vipt_nonaliasing()) | ||
448 | flush_cache_all(); | ||
449 | else | ||
450 | /* | ||
451 | * set_pte_at() called from vmap_pte_range() does not | ||
452 | * have a DSB after cleaning the cache line. | ||
453 | */ | ||
454 | dsb(); | ||
455 | } | ||
456 | |||
457 | static inline void flush_cache_vunmap(unsigned long start, unsigned long end) | ||
458 | { | ||
459 | if (!cache_is_vipt_nonaliasing()) | ||
460 | flush_cache_all(); | ||
461 | } | ||
462 | |||
447 | #endif | 463 | #endif |