You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
[MIPS] Fix aliasing bug in copy_to_user_page / copy_from_user_page
The current implementation uses a sequence of a cacheflush and a copy. This is racy in case of a multithreaded debuggee and renders GDB virtually unusable. Aside this fixes a performance hog rendering access to /proc/cmdline very slow and resulting in a enough cache stalls for the 34K AP/SP programming model to make the bare metal code on the non-Linux VPE miss RT deadlines. The main part of this patch was originally written by Ralf Baechle; Atushi Nemoto did the the debugging. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
@@ -55,24 +55,13 @@ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||
|
||||
static inline void copy_to_user_page(struct vm_area_struct *vma,
|
||||
extern void copy_to_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
if (cpu_has_dc_aliases)
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));
|
||||
memcpy(dst, src, len);
|
||||
__flush_icache_page(vma, page);
|
||||
}
|
||||
unsigned long len);
|
||||
|
||||
static inline void copy_from_user_page(struct vm_area_struct *vma,
|
||||
extern void copy_from_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
if (cpu_has_dc_aliases)
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
unsigned long len);
|
||||
|
||||
extern void (*flush_cache_sigtramp)(unsigned long addr);
|
||||
extern void (*flush_icache_all)(void);
|
||||
|
||||
@@ -45,8 +45,16 @@
|
||||
* fix-mapped?
|
||||
*/
|
||||
enum fixed_addresses {
|
||||
#define FIX_N_COLOURS 8
|
||||
FIX_CMAP_BEGIN,
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
|
||||
#else
|
||||
FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
|
||||
#endif
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
|
||||
/* reserved pte's for temporary kernel mappings */
|
||||
FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
|
||||
#endif
|
||||
__end_of_fixed_addresses
|
||||
@@ -70,9 +78,9 @@ extern void __set_fixmap (enum fixed_addresses idx,
|
||||
* at the top of mem..
|
||||
*/
|
||||
#if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
|
||||
#define FIXADDR_TOP (0xff000000UL - 0x2000)
|
||||
#define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000))
|
||||
#else
|
||||
#define FIXADDR_TOP (0xffffe000UL)
|
||||
#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
|
||||
#endif
|
||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||
|
||||
Reference in New Issue
Block a user