lkml.org 
[lkml]   [2013]   [Jun]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 057/105] ARM: 7755/1: handle user space mapped pages in flush_kernel_dcache_page
    Date
    3.8.13.4 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Simon Baatz <gmbnomis@gmail.com>

    commit 1bc39742aab09248169ef9d3727c9def3528b3f3 upstream.

    Commit f8b63c1 made flush_kernel_dcache_page a no-op assuming that
    the pages it needs to handle are kernel mapped only. However, for
    example when doing direct I/O, pages with user space mappings may
    occur.

    Thus, continue to do lazy flushing if there are no user space
    mappings. Otherwise, flush the kernel cache lines directly.

    Signed-off-by: Simon Baatz <gmbnomis@gmail.com>
    Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    arch/arm/include/asm/cacheflush.h | 4 +---
    arch/arm/mm/flush.c | 33 +++++++++++++++++++++++++++++++++
    2 files changed, 34 insertions(+), 3 deletions(-)

    diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
    index e1489c5..738fcba 100644
    --- a/arch/arm/include/asm/cacheflush.h
    +++ b/arch/arm/include/asm/cacheflush.h
    @@ -320,9 +320,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
    }

    #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
    -static inline void flush_kernel_dcache_page(struct page *page)
    -{
    -}
    +extern void flush_kernel_dcache_page(struct page *);

    #define flush_dcache_mmap_lock(mapping) \
    spin_lock_irq(&(mapping)->tree_lock)
    diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
    index 1c8f7f5..b5ae9fd 100644
    --- a/arch/arm/mm/flush.c
    +++ b/arch/arm/mm/flush.c
    @@ -298,6 +298,39 @@ void flush_dcache_page(struct page *page)
    EXPORT_SYMBOL(flush_dcache_page);

    /*
    + * Ensure cache coherency for the kernel mapping of this page. We can
    + * assume that the page is pinned via kmap.
    + *
    + * If the page only exists in the page cache and there are no user
    + * space mappings, this is a no-op since the page was already marked
    + * dirty at creation. Otherwise, we need to flush the dirty kernel
    + * cache lines directly.
    + */
    +void flush_kernel_dcache_page(struct page *page)
    +{
    + if (cache_is_vivt() || cache_is_vipt_aliasing()) {
    + struct address_space *mapping;
    +
    + mapping = page_mapping(page);
    +
    + if (!mapping || mapping_mapped(mapping)) {
    + void *addr;
    +
    + addr = page_address(page);
    + /*
    + * kmap_atomic() doesn't set the page virtual
    + * address for highmem pages, and
    + * kunmap_atomic() takes care of cache
    + * flushing already.
    + */
    + if (!IS_ENABLED(CONFIG_HIGHMEM) || addr)
    + __cpuc_flush_dcache_area(addr, PAGE_SIZE);
    + }
    + }
    +}
    +EXPORT_SYMBOL(flush_kernel_dcache_page);
    +
    +/*
    * Flush an anonymous page so that users of get_user_pages()
    * can safely access the data. The expected sequence is:
    *
    --
    1.8.1.2


    \
     
     \ /
      Last update: 2013-06-28 21:41    [W:2.164 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site