aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-05-25 04:34:25 -0400
committerVineet Gupta <vgupta@synopsys.com>2013-05-25 04:45:55 -0400
commit7bb66f6e6eecdd8e10ed3a63bd28c1e9105adc79 (patch)
tree091ca0ef40c1f116b9b2da09148cb1f09158be2f /arch/arc
parent006dfb3c9c44192f06093d65b3a876fa5ad1319a (diff)
ARC: lazy dcache flush broke gdb in non-aliasing configs
gdbserver inserting a breakpoint ends up calling copy_user_page() for a code page. The generic version of which (non-aliasing config) didn't set the PG_arch_1 bit hence update_mmu_cache() didn't sync dcache/icache for corresponding dynamic loader code page - causing garbade to be executed. So now aliasing versions of copy_user_highpage()/clear_page() are made default. There is no significant overhead since all of special alias handling code is compiled out for non-aliasing build Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/include/asm/page.h9
-rw-r--r--arch/arc/mm/cache_arc700.c21
2 files changed, 11 insertions, 19 deletions
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 374a35514116..ab84bf131fe1 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -19,13 +19,6 @@
19#define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) 19#define clear_page(paddr) memset((paddr), 0, PAGE_SIZE)
20#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) 20#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
21 21
22#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING
23
24#define clear_user_page(addr, vaddr, pg) clear_page(addr)
25#define copy_user_page(vto, vfrom, vaddr, pg) copy_page(vto, vfrom)
26
27#else /* VIPT aliasing dcache */
28
29struct vm_area_struct; 22struct vm_area_struct;
30struct page; 23struct page;
31 24
@@ -35,8 +28,6 @@ void copy_user_highpage(struct page *to, struct page *from,
35 unsigned long u_vaddr, struct vm_area_struct *vma); 28 unsigned long u_vaddr, struct vm_area_struct *vma);
36void clear_user_page(void *to, unsigned long u_vaddr, struct page *page); 29void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
37 30
38#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
39
40#undef STRICT_MM_TYPECHECKS 31#undef STRICT_MM_TYPECHECKS
41 32
42#ifdef STRICT_MM_TYPECHECKS 33#ifdef STRICT_MM_TYPECHECKS
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index d4b7bb616840..aedce1905441 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -676,6 +676,17 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
676 flush_cache_all(); 676 flush_cache_all();
677} 677}
678 678
679void flush_anon_page(struct vm_area_struct *vma, struct page *page,
680 unsigned long u_vaddr)
681{
682 /* TBD: do we really need to clear the kernel mapping */
683 __flush_dcache_page(page_address(page), u_vaddr);
684 __flush_dcache_page(page_address(page), page_address(page));
685
686}
687
688#endif
689
679void copy_user_highpage(struct page *to, struct page *from, 690void copy_user_highpage(struct page *to, struct page *from,
680 unsigned long u_vaddr, struct vm_area_struct *vma) 691 unsigned long u_vaddr, struct vm_area_struct *vma)
681{ 692{
@@ -725,16 +736,6 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
725 set_bit(PG_arch_1, &page->flags); 736 set_bit(PG_arch_1, &page->flags);
726} 737}
727 738
728void flush_anon_page(struct vm_area_struct *vma, struct page *page,
729 unsigned long u_vaddr)
730{
731 /* TBD: do we really need to clear the kernel mapping */
732 __flush_dcache_page(page_address(page), u_vaddr);
733 __flush_dcache_page(page_address(page), page_address(page));
734
735}
736
737#endif
738 739
739/********************************************************************** 740/**********************************************************************
740 * Explicit Cache flush request from user space via syscall 741 * Explicit Cache flush request from user space via syscall