diff options
| author | David S. Miller <davem@nuts.davemloft.net> | 2005-02-25 00:36:06 -0800 |
|---|---|---|
| committer | David S. Miller <davem@nuts.davemloft.net> | 2005-02-25 00:36:06 -0800 |
| commit | 8f2a2e2e4041d036bf77f404171bc5396806decf (patch) | |
| tree | 80ae77934bc5f57cd259d3b5e656c9bbe8db7fc4 | |
| parent | d6d29b7df443ac7057992ecb3aca88cba17431bb (diff) | |
[MM]: Add 'pfn' arg to flush_cache_page().
Based almost entirely upon a patch by Russell King.
Signed-off-by: David S. Miller <davem@davemloft.net>
41 files changed, 107 insertions, 161 deletions
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 9e2f988a8009..b8faf93d3826 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt @@ -155,7 +155,7 @@ the sequence will be in one of the following forms: change_range_of_page_tables(mm, start, end); flush_tlb_range(vma, start, end); - 3) flush_cache_page(vma, addr); + 3) flush_cache_page(vma, addr, pfn); set_pte(pte_pointer, new_pte_val); flush_tlb_page(vma, addr); @@ -203,7 +203,7 @@ Here are the routines, one by one: call flush_cache_page (see below) for each entry which may be modified. -3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) This time we need to remove a PAGE_SIZE sized range from the cache. The 'vma' is the backing structure used by @@ -213,8 +213,14 @@ Here are the routines, one by one: executable (and thus could be in the 'instruction cache' in "Harvard" type cache layouts). + The 'pfn' indicates the physical page frame (shift this value + left by PAGE_SHIFT to get the physical address) that 'addr' + translates to. It is this mapping which should be removed from + the cache. + After running, there will be no entries in the cache for - 'vma->vm_mm' for virtual address 'addr'. + 'vma->vm_mm' for virtual address 'addr' which translates + to 'pfn'. This is used primarily during fault processing. diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 5f0a790940ef..01967ddeef53 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -54,7 +54,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address) * fault (ie, is old), we can safely ignore any issues. */ if (pte_present(entry) && pte_val(entry) & shared_pte_mask) { - flush_cache_page(vma, address); + flush_cache_page(vma, address, pte_pfn(entry)); pte_val(entry) &= ~shared_pte_mask; set_pte(pte, entry); flush_tlb_page(vma, address); @@ -115,7 +115,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, if (aliases) adjust_pte(vma, addr); else - flush_cache_page(vma, addr); + flush_cache_page(vma, addr, page_to_pfn(page)); } /* diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index ff5f62ce4293..c6de48d89503 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -56,7 +56,7 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page if (!(mpnt->vm_flags & VM_MAYSHARE)) continue; offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; - flush_cache_page(mpnt, mpnt->vm_start + offset); + flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); if (cache_is_vipt()) break; } diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 887683b3cc40..c659f99eb39a 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -254,8 +254,7 @@ static void r3k_flush_cache_range(struct vm_area_struct *vma, { } -static void r3k_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) +static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) { } diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index b2808cea6fd7..a03ebb2cba67 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -426,8 +426,7 @@ static inline void local_r4k_flush_cache_page(void *args) } } -static void r4k_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) { struct flush_cache_page_args args; diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index ad41b2b46004..ab30afd63b32 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -160,8 +160,7 @@ static inline void __sb1_flush_icache_all(void) * dcache first, then invalidate the icache. If the page isn't * executable, nothing is required. */ -static void local_sb1_flush_cache_page(struct vm_area_struct *vma, - unsigned long addr) +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { int cpu = smp_processor_id(); @@ -183,17 +182,18 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, struct flush_cache_page_args { struct vm_area_struct *vma; unsigned long addr; + unsigned long pfn; }; static void sb1_flush_cache_page_ipi(void *info) { struct flush_cache_page_args *args = info; - local_sb1_flush_cache_page(args->vma, args->addr); + local_sb1_flush_cache_page(args->vma, args->addr, args->pfn); } /* Dirty dcache could be on another CPU, so do the IPIs */ -static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { struct flush_cache_page_args args; @@ -203,10 +203,11 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) addr &= PAGE_MASK; args.vma = vma; args.addr = addr; + args.pfn = pfn; on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); } #else -void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) __attribute__((alias("local_sb1_flush_cache_page"))); #endif diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 9b0592dffb1a..ff5afab64b2f 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -178,8 +178,7 @@ static void tx39_flush_cache_range(struct vm_area_struct *vma, } } -static void tx39_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) +static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) { int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index e51ae38ddaf5..eacbd2201ede 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -23,7 +23,7 @@ void (*__flush_cache_all)(void); void (*flush_cache_mm)(struct mm_struct *mm); void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, unsigned long end); -void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page); +void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index a877087d00da..1153e7599b84 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -258,10 +258,16 @@ void flush_cache_mm(struct mm_struct *mm) flush_cache_all(); } -static void __flush_cache_page(struct vm_area_struct *vma, - unsigned long address, - unsigned long phys) +/* + * Write back and invalidate I/D-caches for the page. + * + * ADDR: Virtual Address (U0 address) + * PFN: Physical page number + */ +void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { + unsigned long phys = pfn << PAGE_SHIFT; + /* We only need to flush D-cache when we have alias */ if ((address^phys) & CACHE_ALIAS) { /* Loop 4K of the D-cache */ @@ -342,32 +348,6 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, } /* - * Write back and invalidate I/D-caches for the page. - * - * ADDR: Virtual Address (U0 address) - */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long address) -{ - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - unsigned long phys; - - dir = pgd_offset(vma->vm_mm, address); - pmd = pmd_offset(dir, address); - if (pmd_none(*pmd) || pmd_bad(*pmd)) - return; - pte = pte_offset_kernel(pmd, address); - entry = *pte; - if (!(pte_val(entry) & _PAGE_PRESENT)) - return; - - phys = pte_val(entry)&PTE_PHYS_MASK; - __flush_cache_page(vma, address, phys); -} - -/* * flush_icache_user_range * @vma: VMA of the process * @page: page @@ -377,6 +357,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address) void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len) { - __flush_cache_page(vma, addr, PHYSADDR(page_address(page))); + __flush_cache_page(vma, addr, + PHYSADDR(page_address(page)) >> PAGE_SHIFT); } diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c index 3a0508bb46c7..ad8ed7d41e16 100644 --- a/arch/sh/mm/cache-sh7705.c +++ b/arch/sh/mm/cache-sh7705.c @@ -186,25 +186,9 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, * * ADDRESS: Virtual Address (U0 address) */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long address) +void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - unsigned long phys; - - dir = pgd_offset(vma->vm_mm, address); - pmd = pmd_offset(dir, address); - if (pmd_none(*pmd) || pmd_bad(*pmd)) - return; - pte = pte_offset(pmd, address); - entry = *pte; - if (pte_none(entry) || !pte_present(entry)) - return; - - phys = pte_val(entry)&PTE_PHYS_MASK; - __flush_dcache_page(phys); + __flush_dcache_page(pfn << PAGE_SHIFT); } /* diff --git a/arch/sh64/mm/cache.c b/arch/sh64/mm/cache.c index 56fbbff5c1ab..6c0507dff835 100644 --- a/arch/sh64/mm/cache.c +++ b/arch/sh64/mm/cache.c @@ -573,29 +573,9 @@ static void sh64_dcache_purge_phy_page(unsigned long paddr) } } -static void sh64_dcache_purge_virt_page(struct mm_struct *mm, unsigned long eaddr) +static inline void sh64_dcache_purge_virt_page(struct mm_struct *mm, unsigned long eaddr, unsigned long pfn) { - unsigned long phys; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - - pgd = pgd_offset(mm, eaddr); - pmd = pmd_offset(pgd, eaddr); - - if (pmd_none(*pmd) || pmd_bad(*pmd)) - return; - - pte = pte_offset_kernel(pmd, eaddr); - entry = *pte; - - if (pte_none(entry) || !pte_present(entry)) - return; - - phys = pte_val(entry) & PAGE_MASK; - - sh64_dcache_purge_phy_page(phys); + sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT); } static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr) @@ -904,7 +884,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, /****************************************************************************/ -void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr) +void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr, unsigned long pfn) { /* Invalidate any entries in either cache for the vma within the user address space vma->vm_mm for the page starting at virtual address @@ -915,7 +895,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr) Note(1), this is called with mm->page_table_lock held. */ - sh64_dcache_purge_virt_page(vma->vm_mm, eaddr); + sh64_dcache_purge_virt_page(vma->vm_mm, eaddr, pfn); if (vma->vm_flags & VM_EXEC) { sh64_icache_inv_user_page(vma, eaddr); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 533946c574c7..150c6a0cc9fe 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1003,8 +1003,7 @@ extern void viking_flush_cache_all(void); extern void viking_flush_cache_mm(struct mm_struct *mm); extern void viking_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void viking_flush_cache_page(struct vm_area_struct *vma, - unsigned long page); +extern void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page); extern void viking_flush_page_to_ram(unsigned long page); extern void viking_flush_page_for_dma(unsigned long page); extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3be133aa4a79..df5e18939c98 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1585,7 +1585,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { void *kaddr; - flush_cache_page(vma, addr); + flush_cache_page(vma, addr, page_to_pfn(page)); kaddr = kmap(page); if ((size += PAGE_SIZE) > limit || !dump_write(file, kaddr, diff --git a/include/asm-alpha/cacheflush.h b/include/asm-alpha/cacheflush.h index 40a11e4cfff3..3fc6ef726d8c 100644 --- a/include/asm-alpha/cacheflush.h +++ b/include/asm-alpha/cacheflush.h @@ -8,7 +8,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index d38a1cadf0b7..63f483d46426 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -237,16 +237,16 @@ extern void dmac_flush_range(unsigned long, unsigned long); * space" model to handle this. */ #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ - flush_dcache_page(page); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ + flush_dcache_page(page); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) /* @@ -269,7 +269,7 @@ flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long } static inline void -flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr) +flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) { if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { unsigned long addr = user_addr & PAGE_MASK; diff --git a/include/asm-arm26/cacheflush.h b/include/asm-arm26/cacheflush.h index eb887710735a..9c1b9c7f2ebd 100644 --- a/include/asm-arm26/cacheflush.h +++ b/include/asm-arm26/cacheflush.h @@ -23,7 +23,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma,start,end) do { } while (0) -#define flush_cache_page(vma,vmaddr) do { } while (0) +#define flush_cache_page(vma,vmaddr,pfn) do { } while (0) #define flush_cache_vmap(start, end) do { } while (0) #define flush_cache_vunmap(start, end) do { } while (0) diff --git a/include/asm-cris/cacheflush.h b/include/asm-cris/cacheflush.h index 793fea286006..72cc71dffe70 100644 --- a/include/asm-cris/cacheflush.h +++ b/include/asm-cris/cacheflush.h @@ -10,7 +10,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-frv/cacheflush.h b/include/asm-frv/cacheflush.h index 85adcf7e79c1..3007deccb490 100644 --- a/include/asm-frv/cacheflush.h +++ b/include/asm-frv/cacheflush.h @@ -21,7 +21,7 @@ #define flush_cache_all() do {} while(0) #define flush_cache_mm(mm) do {} while(0) #define flush_cache_range(mm, start, end) do {} while(0) -#define flush_cache_page(vma, vmaddr) do {} while(0) +#define flush_cache_page(vma, vmaddr, pfn) do {} while(0) #define flush_cache_vmap(start, end) do {} while(0) #define flush_cache_vunmap(start, end) do {} while(0) #define flush_dcache_mmap_lock(mapping) do {} while(0) diff --git a/include/asm-h8300/cacheflush.h b/include/asm-h8300/cacheflush.h index d9583676f5d5..1e4d95bb5ec9 100644 --- a/include/asm-h8300/cacheflush.h +++ b/include/asm-h8300/cacheflush.h @@ -13,7 +13,7 @@ #define flush_cache_all() #define flush_cache_mm(mm) #define flush_cache_range(vma,a,b) -#define flush_cache_page(vma,p) +#define flush_cache_page(vma,p,pfn) #define flush_dcache_page(page) #define flush_dcache_mmap_lock(mapping) #define flush_dcache_mmap_unlock(mapping) diff --git a/include/asm-i386/cacheflush.h b/include/asm-i386/cacheflush.h index 183361ebe0bc..2ea36dea37d9 100644 --- a/include/asm-i386/cacheflush.h +++ b/include/asm-i386/cacheflush.h @@ -8,7 +8,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-ia64/cacheflush.h b/include/asm-ia64/cacheflush.h index ef0e256f2355..f2dacb4245ec 100644 --- a/include/asm-ia64/cacheflush.h +++ b/include/asm-ia64/cacheflush.h @@ -19,7 +19,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_icache_page(vma,page) do { } while (0) #define flush_cache_vmap(start, end) do { } while (0) #define flush_cache_vunmap(start, end) do { } while (0) diff --git a/include/asm-m32r/cacheflush.h b/include/asm-m32r/cacheflush.h index cf65b7463411..46fc4c325108 100644 --- a/include/asm-m32r/cacheflush.h +++ b/include/asm-m32r/cacheflush.h @@ -11,7 +11,7 @@ extern void _flush_cache_copyback_all(void); #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) @@ -31,7 +31,7 @@ extern void smp_flush_cache_all(void); #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) @@ -43,7 +43,7 @@ extern void smp_flush_cache_all(void); #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-m68k/cacheflush.h b/include/asm-m68k/cacheflush.h index 3b2e5205b50c..e4773946f10d 100644 --- a/include/asm-m68k/cacheflush.h +++ b/include/asm-m68k/cacheflush.h @@ -99,8 +99,7 @@ static inline void flush_cache_range(struct vm_area_struct *vma, __flush_cache_030(); } -static inline void flush_cache_page(struct vm_area_struct *vma, - unsigned long vmaddr) +static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) { if (vma->vm_mm == current->mm) __flush_cache_030(); @@ -134,15 +133,15 @@ static inline void __flush_page_to_ram(void *vaddr) #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) extern void flush_icache_range(unsigned long address, unsigned long endaddr); diff --git a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h index f7182c4c876f..aa7a2ffa41af 100644 --- a/include/asm-m68knommu/cacheflush.h +++ b/include/asm-m68knommu/cacheflush.h @@ -9,7 +9,7 @@ #define flush_cache_all() __flush_cache_all() #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_range(start,len) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h index c08c486a2f2a..635f1bfb403e 100644 --- a/include/asm-mips/cacheflush.h +++ b/include/asm-mips/cacheflush.h @@ -17,7 +17,7 @@ * * - flush_cache_all() flushes entire cache * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_page(mm, vmaddr, pfn) flushes a single page * - flush_cache_range(vma, start, end) flushes a range of pages * - flush_icache_range(start, end) flush a range of instructions * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache @@ -34,8 +34,7 @@ extern void (*__flush_cache_all)(void); extern void (*flush_cache_mm)(struct mm_struct *mm); extern void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void (*flush_cache_page)(struct vm_area_struct *vma, - unsigned long page); +extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); extern void __flush_dcache_page(struct page *page); static inline void flush_dcache_page(struct page *page) diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index a3132a28a8f2..282d6a844340 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h @@ -67,14 +67,14 @@ extern void flush_dcache_page(struct page *page); #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page)); \ memcpy(dst, src, len); \ flush_kernel_dcache_range_asm((unsigned long)dst, (unsigned long)dst + len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page)); \ memcpy(dst, src, len); \ } while (0) @@ -170,7 +170,7 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) } static inline void -flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) +flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) { BUG_ON(!vma->vm_mm->context); diff --git a/include/asm-ppc/cacheflush.h b/include/asm-ppc/cacheflush.h index 7848d7130f33..6a243efb3317 100644 --- a/include/asm-ppc/cacheflush.h +++ b/include/asm-ppc/cacheflush.h @@ -22,7 +22,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, a, b) do { } while (0) -#define flush_cache_page(vma, p) do { } while (0) +#define flush_cache_page(vma, p, pfn) do { } while (0) #define flush_icache_page(vma, page) do { } while (0) #define flush_cache_vmap(start, end) do { } while (0) #define flush_cache_vunmap(start, end) do { } while (0) diff --git a/include/asm-ppc64/cacheflush.h b/include/asm-ppc64/cacheflush.h index d0f0dfd263d6..a7db4e4de2cc 100644 --- a/include/asm-ppc64/cacheflush.h +++ b/include/asm-ppc64/cacheflush.h @@ -12,7 +12,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_icache_page(vma, page) do { } while (0) #define flush_cache_vmap(start, end) do { } while (0) #define flush_cache_vunmap(start, end) do { } while (0) diff --git a/include/asm-s390/cacheflush.h b/include/asm-s390/cacheflush.h index 3c613c8e6234..e399a8ba2ed7 100644 --- a/include/asm-s390/cacheflush.h +++ b/include/asm-s390/cacheflush.h @@ -8,7 +8,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h index beb860ae79cc..27b005af91d2 100644 --- a/include/asm-sh/cacheflush.h +++ b/include/asm-sh/cacheflush.h @@ -15,14 +15,14 @@ extern void __flush_invalidate_region(void *start, int size); #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ flush_icache_user_range(vma, page, vaddr, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ } while (0) diff --git a/include/asm-sh/cpu-sh2/cacheflush.h b/include/asm-sh/cpu-sh2/cacheflush.h index 98cb67f37481..f556fa80ea97 100644 --- a/include/asm-sh/cpu-sh2/cacheflush.h +++ b/include/asm-sh/cpu-sh2/cacheflush.h @@ -15,7 +15,7 @@ * * - flush_cache_all() flushes entire cache * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_page(mm, vmaddr, pfn) flushes a single page * - flush_cache_range(vma, start, end) flushes a range of pages * * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache @@ -28,7 +28,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-sh/cpu-sh3/cacheflush.h b/include/asm-sh/cpu-sh3/cacheflush.h index ff4cc7425827..f51aed00c68f 100644 --- a/include/asm-sh/cpu-sh3/cacheflush.h +++ b/include/asm-sh/cpu-sh3/cacheflush.h @@ -15,7 +15,7 @@ * * - flush_cache_all() flushes entire cache * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_page(mm, vmaddr, pfn) flushes a single page * - flush_cache_range(vma, start, end) flushes a range of pages * * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache @@ -43,7 +43,7 @@ extern void flush_cache_all(void); extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); extern void flush_dcache_page(struct page *pg); extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); @@ -68,7 +68,7 @@ extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/include/asm-sh/cpu-sh4/cacheflush.h b/include/asm-sh/cpu-sh4/cacheflush.h index 9910dfaed943..f323567e085f 100644 --- a/include/asm-sh/cpu-sh4/cacheflush.h +++ b/include/asm-sh/cpu-sh4/cacheflush.h @@ -28,7 +28,7 @@ extern void flush_cache_all(void); extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); extern void flush_dcache_page(struct page *pg); #define flush_dcache_mmap_lock(mapping) do { } while (0) diff --git a/include/asm-sh64/cacheflush.h b/include/asm-sh64/cacheflush.h index 877c12fcd067..55f71aa0aa6b 100644 --- a/include/asm-sh64/cacheflush.h +++ b/include/asm-sh64/cacheflush.h @@ -14,7 +14,7 @@ extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_sigtramp(unsigned long start, unsigned long end); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); extern void flush_dcache_page(struct page *pg); extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_icache_user_range(struct vm_area_struct *vma, @@ -31,14 +31,14 @@ extern void flush_icache_user_range(struct vm_area_struct *vma, #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ flush_icache_user_range(vma, page, vaddr, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr); \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ } while (0) diff --git a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h index a91fe62b33c4..4901217008c0 100644 --- a/include/asm-sparc/cacheflush.h +++ b/include/asm-sparc/cacheflush.h @@ -50,21 +50,21 @@ BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long) #define flush_cache_all() BTFIXUP_CALL(flush_cache_all)() #define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm) #define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end) -#define flush_cache_page(vma,addr) BTFIXUP_CALL(flush_cache_page)(vma,addr) +#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr) #define flush_icache_range(start, end) do { } while (0) #define flush_icache_page(vma, pg) do { } while (0) #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long) diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h index f4b1df6a56e9..f1f8661cf83a 100644 --- a/include/asm-sparc64/cacheflush.h +++ b/include/asm-sparc64/cacheflush.h @@ -11,7 +11,7 @@ do { if ((__mm) == current->mm) flushw_user(); } while(0) #define flush_cache_range(vma, start, end) \ flush_cache_mm((vma)->vm_mm) -#define flush_cache_page(vma, page) \ +#define flush_cache_page(vma, page, pfn) \ flush_cache_mm((vma)->vm_mm) /* @@ -38,15 +38,15 @@ extern void __flush_dcache_range(unsigned long start, unsigned long end); #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr); \ - memcpy(dst, src, len); \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ } while (0) extern void flush_dcache_page(struct page *page); diff --git a/include/asm-v850/cacheflush.h b/include/asm-v850/cacheflush.h index 17d7d893424f..e1a87f82f1a4 100644 --- a/include/asm-v850/cacheflush.h +++ b/include/asm-v850/cacheflush.h @@ -25,7 +25,7 @@ #define flush_cache_all() ((void)0) #define flush_cache_mm(mm) ((void)0) #define flush_cache_range(vma, start, end) ((void)0) -#define flush_cache_page(vma, vmaddr) ((void)0) +#define flush_cache_page(vma, vmaddr, pfn) ((void)0) #define flush_dcache_page(page) ((void)0) #define flush_dcache_mmap_lock(mapping) ((void)0) #define flush_dcache_mmap_unlock(mapping) ((void)0) diff --git a/include/asm-x86_64/cacheflush.h b/include/asm-x86_64/cacheflush.h index dd6d3abfd2bb..b3189fb229d1 100644 --- a/include/asm-x86_64/cacheflush.h +++ b/include/asm-x86_64/cacheflush.h @@ -8,7 +8,7 @@ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/mm/fremap.c b/mm/fremap.c index bab48f238623..5d59d467c1c4 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -30,7 +30,7 @@ static inline void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, if (pte_present(pte)) { unsigned long pfn = pte_pfn(pte); - flush_cache_page(vma, addr); + flush_cache_page(vma, addr, pfn); pte = ptep_clear_flush(vma, addr, ptep); if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); diff --git a/mm/memory.c b/mm/memory.c index 48cbd6b7b98b..4d9a087d24bf 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1247,7 +1247,6 @@ static inline void break_cow(struct vm_area_struct * vma, struct page * new_page { pte_t entry; - flush_cache_page(vma, address); entry = maybe_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)), vma); ptep_establish(vma, address, page_table, entry); @@ -1299,7 +1298,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, int reuse = can_share_swap_page(old_page); unlock_page(old_page); if (reuse) { - flush_cache_page(vma, address); + flush_cache_page(vma, address, pfn); entry = maybe_mkwrite(pte_mkyoung(pte_mkdirty(pte)), vma); ptep_set_access_flags(vma, address, page_table, entry, 1); @@ -1344,6 +1343,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, update_mem_hiwater(); } else page_remove_rmap(old_page); + flush_cache_page(vma, address, pfn); break_cow(vma, new_page, address, page_table); lru_cache_add_active(new_page); page_add_anon_rmap(new_page, vma, address); diff --git a/mm/rmap.c b/mm/rmap.c index 4ff8183fa18e..8ca17bd0930d 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -574,7 +574,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) } /* Nuke the page table entry. */ - flush_cache_page(vma, address); + flush_cache_page(vma, address, page_to_pfn(page)); pteval = ptep_clear_flush(vma, address, pte); /* Move the dirty bit to the physical page now the pte is gone. */ @@ -692,7 +692,7 @@ static void try_to_unmap_cluster(unsigned long cursor, continue; /* Nuke the page table entry. */ - flush_cache_page(vma, address); + flush_cache_page(vma, address, pfn); pteval = ptep_clear_flush(vma, address, pte); /* If nonlinear, store the file page offset in the pte. */ |
