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>
This commit is contained in:
@@ -19,13 +19,6 @@
|
|||||||
#define clear_page(paddr) memset((paddr), 0, PAGE_SIZE)
|
#define clear_page(paddr) memset((paddr), 0, PAGE_SIZE)
|
||||||
#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
|
#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
|
||||||
|
|
||||||
#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING
|
|
||||||
|
|
||||||
#define clear_user_page(addr, vaddr, pg) clear_page(addr)
|
|
||||||
#define copy_user_page(vto, vfrom, vaddr, pg) copy_page(vto, vfrom)
|
|
||||||
|
|
||||||
#else /* VIPT aliasing dcache */
|
|
||||||
|
|
||||||
struct vm_area_struct;
|
struct vm_area_struct;
|
||||||
struct page;
|
struct page;
|
||||||
|
|
||||||
@@ -35,8 +28,6 @@ void copy_user_highpage(struct page *to, struct page *from,
|
|||||||
unsigned long u_vaddr, struct vm_area_struct *vma);
|
unsigned long u_vaddr, struct vm_area_struct *vma);
|
||||||
void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
|
void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
|
||||||
|
|
||||||
#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
|
|
||||||
|
|
||||||
#undef STRICT_MM_TYPECHECKS
|
#undef STRICT_MM_TYPECHECKS
|
||||||
|
|
||||||
#ifdef STRICT_MM_TYPECHECKS
|
#ifdef STRICT_MM_TYPECHECKS
|
||||||
|
@@ -676,6 +676,17 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
|
|||||||
flush_cache_all();
|
flush_cache_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
||||||
|
unsigned long u_vaddr)
|
||||||
|
{
|
||||||
|
/* TBD: do we really need to clear the kernel mapping */
|
||||||
|
__flush_dcache_page(page_address(page), u_vaddr);
|
||||||
|
__flush_dcache_page(page_address(page), page_address(page));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void copy_user_highpage(struct page *to, struct page *from,
|
void copy_user_highpage(struct page *to, struct page *from,
|
||||||
unsigned long u_vaddr, struct vm_area_struct *vma)
|
unsigned long u_vaddr, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
@@ -725,16 +736,6 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
|
|||||||
set_bit(PG_arch_1, &page->flags);
|
set_bit(PG_arch_1, &page->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
|
||||||
unsigned long u_vaddr)
|
|
||||||
{
|
|
||||||
/* TBD: do we really need to clear the kernel mapping */
|
|
||||||
__flush_dcache_page(page_address(page), u_vaddr);
|
|
||||||
__flush_dcache_page(page_address(page), page_address(page));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Explicit Cache flush request from user space via syscall
|
* Explicit Cache flush request from user space via syscall
|
||||||
|
Reference in New Issue
Block a user