summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.davemloft.net>2005-02-25 00:36:06 -0800
committerDavid S. Miller <davem@nuts.davemloft.net>2005-02-25 00:36:06 -0800
commit8f2a2e2e4041d036bf77f404171bc5396806decf (patch)
tree80ae77934bc5f57cd259d3b5e656c9bbe8db7fc4
parentd6d29b7df443ac7057992ecb3aca88cba17431bb (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>
-rw-r--r--Documentation/cachetlb.txt12
-rw-r--r--arch/arm/mm/fault-armv.c4
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/mips/mm/c-r3k.c3
-rw-r--r--arch/mips/mm/c-r4k.c3
-rw-r--r--arch/mips/mm/c-sb1.c11
-rw-r--r--arch/mips/mm/c-tx39.c3
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/sh/mm/cache-sh4.c41
-rw-r--r--arch/sh/mm/cache-sh7705.c20
-rw-r--r--arch/sh64/mm/cache.c28
-rw-r--r--arch/sparc/mm/srmmu.c3
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--include/asm-alpha/cacheflush.h2
-rw-r--r--include/asm-arm/cacheflush.h16
-rw-r--r--include/asm-arm26/cacheflush.h2
-rw-r--r--include/asm-cris/cacheflush.h2
-rw-r--r--include/asm-frv/cacheflush.h2
-rw-r--r--include/asm-h8300/cacheflush.h2
-rw-r--r--include/asm-i386/cacheflush.h2
-rw-r--r--include/asm-ia64/cacheflush.h2
-rw-r--r--include/asm-m32r/cacheflush.h6
-rw-r--r--include/asm-m68k/cacheflush.h15
-rw-r--r--include/asm-m68knommu/cacheflush.h2
-rw-r--r--include/asm-mips/cacheflush.h5
-rw-r--r--include/asm-parisc/cacheflush.h6
-rw-r--r--include/asm-ppc/cacheflush.h2
-rw-r--r--include/asm-ppc64/cacheflush.h2
-rw-r--r--include/asm-s390/cacheflush.h2
-rw-r--r--include/asm-sh/cacheflush.h4
-rw-r--r--include/asm-sh/cpu-sh2/cacheflush.h4
-rw-r--r--include/asm-sh/cpu-sh3/cacheflush.h6
-rw-r--r--include/asm-sh/cpu-sh4/cacheflush.h2
-rw-r--r--include/asm-sh64/cacheflush.h6
-rw-r--r--include/asm-sparc/cacheflush.h14
-rw-r--r--include/asm-sparc64/cacheflush.h14
-rw-r--r--include/asm-v850/cacheflush.h2
-rw-r--r--include/asm-x86_64/cacheflush.h2
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/memory.c4
-rw-r--r--mm/rmap.c4
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. */