diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-05-25 04:34:25 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-05-25 04:45:55 -0400 |
commit | 7bb66f6e6eecdd8e10ed3a63bd28c1e9105adc79 (patch) | |
tree | 091ca0ef40c1f116b9b2da09148cb1f09158be2f /arch/arc | |
parent | 006dfb3c9c44192f06093d65b3a876fa5ad1319a (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.h | 9 | ||||
-rw-r--r-- | arch/arc/mm/cache_arc700.c | 21 |
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 | |||
29 | struct vm_area_struct; | 22 | struct vm_area_struct; |
30 | struct page; | 23 | struct 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); |
36 | void clear_user_page(void *to, unsigned long u_vaddr, struct page *page); | 29 | void 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 | ||
679 | void 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 | |||
679 | void copy_user_highpage(struct page *to, struct page *from, | 690 | void 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 | ||
728 | void 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 |