diff -urN 2.4.19pre2/Documentation/cachetlb.txt icache/Documentation/cachetlb.txt --- 2.4.19pre2/Documentation/cachetlb.txt Tue Jan 22 18:56:11 2002 +++ icache/Documentation/cachetlb.txt Wed Mar 6 04:49:51 2002 @@ -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.19pre2/arch/alpha/kernel/smp.c icache/arch/alpha/kernel/smp.c --- 2.4.19pre2/arch/alpha/kernel/smp.c Fri Mar 1 00:09:31 2002 +++ icache/arch/alpha/kernel/smp.c Wed Mar 6 04:49:51 2002 @@ -1079,7 +1079,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.19pre2/arch/ppc/mm/init.c icache/arch/ppc/mm/init.c --- 2.4.19pre2/arch/ppc/mm/init.c Mon Feb 25 22:05:04 2002 +++ icache/arch/ppc/mm/init.c Wed Mar 6 04:49:51 2002 @@ -616,3 +616,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.19pre2/include/asm-alpha/pgalloc.h icache/include/asm-alpha/pgalloc.h --- 2.4.19pre2/include/asm-alpha/pgalloc.h Tue Jan 22 18:51:12 2002 +++ icache/include/asm-alpha/pgalloc.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-cris/pgtable.h icache/include/asm-cris/pgtable.h --- 2.4.19pre2/include/asm-cris/pgtable.h Fri Mar 1 00:09:38 2002 +++ icache/include/asm-cris/pgtable.h Wed Mar 6 04:49:51 2002 @@ -125,6 +125,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.19pre2/include/asm-i386/pgtable.h icache/include/asm-i386/pgtable.h --- 2.4.19pre2/include/asm-i386/pgtable.h Fri Mar 1 00:09:38 2002 +++ icache/include/asm-i386/pgtable.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-m68k/pgalloc.h icache/include/asm-m68k/pgalloc.h --- 2.4.19pre2/include/asm-m68k/pgalloc.h Tue Jan 22 18:55:26 2002 +++ icache/include/asm-m68k/pgalloc.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-mips/pgtable.h icache/include/asm-mips/pgtable.h --- 2.4.19pre2/include/asm-mips/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-mips/pgtable.h Wed Mar 6 04:49:51 2002 @@ -56,6 +56,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)) #define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr) #ifdef CONFIG_VTAG_ICACHE diff -urN 2.4.19pre2/include/asm-mips64/pgtable.h icache/include/asm-mips64/pgtable.h --- 2.4.19pre2/include/asm-mips64/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-mips64/pgtable.h Wed Mar 6 04:50:30 2002 @@ -66,6 +66,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) \ @@ -79,6 +81,8 @@ #define flush_cache_page(vma,page) _flush_cache_page(vma, page) #define flush_page_to_ram(page) _flush_page_to_ram(page) #define flush_icache_range(start, end) _flush_icache_range(start, end) +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page((vma), (page)) #define flush_icache_page(vma, page) _flush_icache_page(vma, page) #endif /* !CONFIG_CPU_R10000 */ diff -urN 2.4.19pre2/include/asm-parisc/pgalloc.h icache/include/asm-parisc/pgalloc.h --- 2.4.19pre2/include/asm-parisc/pgalloc.h Tue May 1 19:35:31 2001 +++ icache/include/asm-parisc/pgalloc.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-ppc/pgtable.h icache/include/asm-ppc/pgtable.h --- 2.4.19pre2/include/asm-ppc/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-ppc/pgtable.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-s390/pgtable.h icache/include/asm-s390/pgtable.h --- 2.4.19pre2/include/asm-s390/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-s390/pgtable.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-s390x/pgtable.h icache/include/asm-s390x/pgtable.h --- 2.4.19pre2/include/asm-s390x/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-s390x/pgtable.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-sh/pgtable.h icache/include/asm-sh/pgtable.h --- 2.4.19pre2/include/asm-sh/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-sh/pgtable.h Wed Mar 6 04:49:51 2002 @@ -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.19pre2/include/asm-sparc/pgtable.h icache/include/asm-sparc/pgtable.h --- 2.4.19pre2/include/asm-sparc/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-sparc/pgtable.h Wed Mar 6 04:49:51 2002 @@ -345,6 +345,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.19pre2/include/asm-sparc64/pgtable.h icache/include/asm-sparc64/pgtable.h --- 2.4.19pre2/include/asm-sparc64/pgtable.h Fri Mar 1 00:09:39 2002 +++ icache/include/asm-sparc64/pgtable.h Wed Mar 6 04:49:51 2002 @@ -276,6 +276,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.19pre2/kernel/ptrace.c icache/kernel/ptrace.c --- 2.4.19pre2/kernel/ptrace.c Mon Feb 25 22:05:09 2002 +++ icache/kernel/ptrace.c Wed Mar 6 04:49:51 2002 @@ -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);