Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / arch / mips / mm / cache.c
index aab218c..e87bccd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 
 #include <asm/cacheflush.h>
+#include <asm/highmem.h>
 #include <asm/processor.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
@@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *page)
        struct address_space *mapping = page_mapping(page);
        unsigned long addr;
 
-       if (PageHighMem(page))
-               return;
        if (mapping && !mapping_mapped(mapping)) {
                SetPageDcacheDirty(page);
                return;
@@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *page)
         * case is for exec env/arg pages and those are %99 certainly going to
         * get faulted into the tlb (and thus flushed) anyways.
         */
-       addr = (unsigned long) page_address(page);
+       if (PageHighMem(page))
+               addr = (unsigned long)kmap_atomic(page);
+       else
+               addr = (unsigned long)page_address(page);
+
        flush_data_cache_page(addr);
+
+       if (PageHighMem(page))
+               __kunmap_atomic((void *)addr);
 }
 
 EXPORT_SYMBOL(__flush_dcache_page);
@@ -119,33 +125,28 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
 
 EXPORT_SYMBOL(__flush_anon_page);
 
-void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-       unsigned long addr;
-
-       if (PageHighMem(page))
-               return;
-
-       addr = (unsigned long) page_address(page);
-       flush_data_cache_page(addr);
-}
-EXPORT_SYMBOL_GPL(__flush_icache_page);
-
-void __update_cache(struct vm_area_struct *vma, unsigned long address,
-       pte_t pte)
+void __update_cache(unsigned long address, pte_t pte)
 {
        struct page *page;
        unsigned long pfn, addr;
-       int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
+       int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc;
 
        pfn = pte_pfn(pte);
        if (unlikely(!pfn_valid(pfn)))
                return;
        page = pfn_to_page(pfn);
-       if (page_mapping(page) && Page_dcache_dirty(page)) {
-               addr = (unsigned long) page_address(page);
+       if (Page_dcache_dirty(page)) {
+               if (PageHighMem(page))
+                       addr = (unsigned long)kmap_atomic(page);
+               else
+                       addr = (unsigned long)page_address(page);
+
                if (exec || pages_do_alias(addr, address & PAGE_MASK))
                        flush_data_cache_page(addr);
+
+               if (PageHighMem(page))
+                       __kunmap_atomic((void *)addr);
+
                ClearPageDcacheDirty(page);
        }
 }