diff -urN 2.4.17pre6/Documentation/cachetlb.txt icache/Documentation/cachetlb.txt --- 2.4.17pre6/Documentation/cachetlb.txt Thu Dec 6 20:07:25 2001 +++ icache/Documentation/cachetlb.txt Sat Dec 8 12:35:43 2001 @@ -339,6 +339,17 @@ If the icache does not snoop stores then this routine will need to flush it. + void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len) + This is called when the kernel stores into addresses that are + part of the address space of a user process (which may be some + other process than the current process). The addr argument + gives the virtual address in that process's address space, + page is the page which is being modified, and len indicates + how many bytes have been modified. The modified region must + not cross a page boundary. Currently this is only called from + kernel/ptrace.c. + void flush_icache_page(struct vm_area_struct *vma, struct page *page) All the functionality of flush_icache_page can be implemented in flush_dcache_page and update_mmu_cache. In 2.5 the hope is to diff -urN 2.4.17pre6/arch/alpha/kernel/smp.c icache/arch/alpha/kernel/smp.c --- 2.4.17pre6/arch/alpha/kernel/smp.c Sat Dec 8 12:34:29 2001 +++ icache/arch/alpha/kernel/smp.c Sat Dec 8 12:35:43 2001 @@ -1065,7 +1065,8 @@ } void -flush_icache_page(struct vm_area_struct *vma, struct page *page) +flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) { struct mm_struct *mm = vma->vm_mm; diff -urN 2.4.17pre6/arch/ppc/mm/init.c icache/arch/ppc/mm/init.c --- 2.4.17pre6/arch/ppc/mm/init.c Wed Oct 10 02:14:58 2001 +++ icache/arch/ppc/mm/init.c Sat Dec 8 12:35:43 2001 @@ -601,3 +601,13 @@ *ptep = pte; #endif } + +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) +{ + unsigned long maddr; + + maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + flush_icache_range(maddr, maddr + len); + kunmap(page); +} diff -urN 2.4.17pre6/include/asm-alpha/pgalloc.h icache/include/asm-alpha/pgalloc.h --- 2.4.17pre6/include/asm-alpha/pgalloc.h Sat May 26 04:03:47 2001 +++ icache/include/asm-alpha/pgalloc.h Sat Dec 8 12:35:43 2001 @@ -70,8 +70,7 @@ } /* We need to flush the userspace icache after setting breakpoints in - ptrace. I don't think it's needed in do_swap_page, or do_no_page, - but I don't know how to get rid of it either. + ptrace. Instead of indiscriminately using imb, take advantage of the fact that icache entries are tagged with the ASN and load a new mm context. */ @@ -79,7 +78,8 @@ #ifndef CONFIG_SMP static inline void -flush_icache_page(struct vm_area_struct *vma, struct page *page) +flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) { if (vma->vm_flags & VM_EXEC) { struct mm_struct *mm = vma->vm_mm; @@ -90,8 +90,12 @@ } } #else -extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); +extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len); #endif + +/* this is used only in do_no_page and do_swap_page */ +#define flush_icache_page(vma, page) do { } while (0) /* * Flush just one page in the current TLB set. diff -urN 2.4.17pre6/include/asm-cris/pgtable.h icache/include/asm-cris/pgtable.h --- 2.4.17pre6/include/asm-cris/pgtable.h Fri Nov 23 08:21:02 2001 +++ icache/include/asm-cris/pgtable.h Sat Dec 8 12:35:43 2001 @@ -117,6 +117,7 @@ #define flush_dcache_page(page) do { } while (0) #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) /* * TLB flushing (implemented in arch/cris/mm/tlb.c): diff -urN 2.4.17pre6/include/asm-i386/pgtable.h icache/include/asm-i386/pgtable.h --- 2.4.17pre6/include/asm-i386/pgtable.h Fri Nov 23 08:21:02 2001 +++ icache/include/asm-i386/pgtable.h Sat Dec 8 12:35:43 2001 @@ -33,6 +33,7 @@ #define flush_dcache_page(page) do { } while (0) #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 __flush_tlb() \ do { \ diff -urN 2.4.17pre6/include/asm-m68k/pgalloc.h icache/include/asm-m68k/pgalloc.h --- 2.4.17pre6/include/asm-m68k/pgalloc.h Tue Nov 6 02:04:52 2001 +++ icache/include/asm-m68k/pgalloc.h Sat Dec 8 12:35:43 2001 @@ -127,6 +127,7 @@ #define flush_dcache_page(page) do { } while (0) #define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) /* Push n pages at kernel virtual address and clear the icache */ /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ diff -urN 2.4.17pre6/include/asm-mips/pgtable.h icache/include/asm-mips/pgtable.h --- 2.4.17pre6/include/asm-mips/pgtable.h Sun Sep 23 21:11:41 2001 +++ icache/include/asm-mips/pgtable.h Sat Dec 8 12:35:43 2001 @@ -51,6 +51,8 @@ #define flush_icache_range(start, end) _flush_icache_range(start,end) #define flush_icache_page(vma, page) _flush_icache_page(vma, page) +#define flush_icache_user_range(vma, page, addr, len) \ + _flush_icache_page((vma), (page)) /* diff -urN 2.4.17pre6/include/asm-mips64/pgtable.h icache/include/asm-mips64/pgtable.h --- 2.4.17pre6/include/asm-mips64/pgtable.h Sun Sep 23 21:11:41 2001 +++ icache/include/asm-mips64/pgtable.h Sat Dec 8 12:35:43 2001 @@ -43,6 +43,8 @@ #define flush_page_to_ram(page) _flush_page_to_ram(page) #define flush_icache_range(start, end) _flush_cache_l1() +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page((vma), (page)) #define flush_icache_page(vma, page) \ do { \ @@ -66,6 +68,8 @@ #define flush_cache_page(vma,page) do { } while(0) #define flush_page_to_ram(page) do { } while(0) #define flush_icache_range(start, end) _flush_cache_l1() +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page((vma), (page)) #define flush_icache_page(vma, page) \ do { \ if ((vma)->vm_flags & VM_EXEC) \ diff -urN 2.4.17pre6/include/asm-parisc/pgalloc.h icache/include/asm-parisc/pgalloc.h --- 2.4.17pre6/include/asm-parisc/pgalloc.h Tue May 1 19:35:31 2001 +++ icache/include/asm-parisc/pgalloc.h Sat Dec 8 12:35:43 2001 @@ -106,6 +106,9 @@ #define flush_icache_range(start, end) \ __flush_icache_range(start, end - start) +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page((vma), (page)) + #define flush_icache_page(vma, page) \ __flush_icache_range(page_address(page), PAGE_SIZE) diff -urN 2.4.17pre6/include/asm-ppc/pgtable.h icache/include/asm-ppc/pgtable.h --- 2.4.17pre6/include/asm-ppc/pgtable.h Fri Nov 23 08:21:03 2001 +++ icache/include/asm-ppc/pgtable.h Sat Dec 8 12:35:43 2001 @@ -84,6 +84,8 @@ #define flush_cache_page(vma, p) do { } while (0) #define flush_icache_page(vma, page) do { } while (0) +extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len); extern void flush_icache_range(unsigned long, unsigned long); extern void __flush_page_to_ram(unsigned long page_va); extern void flush_page_to_ram(struct page *page); diff -urN 2.4.17pre6/include/asm-s390/pgtable.h icache/include/asm-s390/pgtable.h --- 2.4.17pre6/include/asm-s390/pgtable.h Wed Oct 24 08:04:25 2001 +++ icache/include/asm-s390/pgtable.h Sat Dec 8 12:35:43 2001 @@ -42,6 +42,7 @@ #define flush_dcache_page(page) do { } while (0) #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) /* * The S390 doesn't have any external MMU info: the kernel page diff -urN 2.4.17pre6/include/asm-s390x/pgtable.h icache/include/asm-s390x/pgtable.h --- 2.4.17pre6/include/asm-s390x/pgtable.h Wed Oct 24 08:04:25 2001 +++ icache/include/asm-s390x/pgtable.h Sat Dec 8 12:35:43 2001 @@ -38,6 +38,7 @@ #define flush_dcache_page(page) do { } while (0) #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) /* * The S390 doesn't have any external MMU info: the kernel page diff -urN 2.4.17pre6/include/asm-sh/pgtable.h icache/include/asm-sh/pgtable.h --- 2.4.17pre6/include/asm-sh/pgtable.h Fri Nov 23 08:21:03 2001 +++ icache/include/asm-sh/pgtable.h Sat Dec 8 12:35:43 2001 @@ -41,6 +41,7 @@ #define flush_dcache_page(page) do { } while (0) #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 flush_cache_sigtramp(vaddr) do { } while (0) #define p3_cache_init() do { } while (0) @@ -64,6 +65,7 @@ #define flush_page_to_ram(page) do { } while (0) #define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) /* Initialization of P3 area for copy_user_page */ extern void p3_cache_init(void); diff -urN 2.4.17pre6/include/asm-sparc/pgtable.h icache/include/asm-sparc/pgtable.h --- 2.4.17pre6/include/asm-sparc/pgtable.h Fri Nov 23 08:21:03 2001 +++ icache/include/asm-sparc/pgtable.h Sat Dec 8 12:35:43 2001 @@ -348,6 +348,7 @@ extern unsigned int pg_iobits; #define flush_icache_page(vma, pg) do { } while(0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following diff -urN 2.4.17pre6/include/asm-sparc64/pgtable.h icache/include/asm-sparc64/pgtable.h --- 2.4.17pre6/include/asm-sparc64/pgtable.h Thu Dec 6 20:08:09 2001 +++ icache/include/asm-sparc64/pgtable.h Sat Dec 8 12:35:43 2001 @@ -277,6 +277,7 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); #define flush_icache_page(vma, pg) do { } while(0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) /* Make a non-present pseudo-TTE. */ extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) diff -urN 2.4.17pre6/kernel/ptrace.c icache/kernel/ptrace.c --- 2.4.17pre6/kernel/ptrace.c Sat Dec 8 12:34:34 2001 +++ icache/kernel/ptrace.c Sat Dec 8 13:05:19 2001 @@ -164,7 +164,7 @@ if (write) { memcpy(maddr + offset, buf, bytes); flush_page_to_ram(page); - flush_icache_page(vma, page); + flush_icache_user_range(vma, page, addr, len); } else { memcpy(buf, maddr + offset, bytes); flush_page_to_ram(page);