summaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/pgtable-32.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-10-21 23:17:35 +0100
committerRalf Baechle <ralf@linux-mips.org>2006-10-21 23:17:35 +0100
commitf8829caee311207afbc882794bdc5aa0db5caf33 (patch)
treedbadd9fa746a1a4f091bc7e240ca8d787188a913 /arch/mips/mm/pgtable-32.c
parent224dc50ece1b40f8cff5ecadd42a6b2691e231de (diff)
downloadlinux-stable-f8829caee311207afbc882794bdc5aa0db5caf33.tar.gz
linux-stable-f8829caee311207afbc882794bdc5aa0db5caf33.tar.bz2
linux-stable-f8829caee311207afbc882794bdc5aa0db5caf33.zip
[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>
Diffstat (limited to 'arch/mips/mm/pgtable-32.c')
-rw-r--r--arch/mips/mm/pgtable-32.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4bdaa05f485b..4a61e624b0ec 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -31,9 +31,10 @@ void pgd_init(unsigned long page)
void __init pagetable_init(void)
{
-#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
- pgd_t *pgd, *pgd_base;
+ pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+ pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
@@ -44,7 +45,6 @@ void __init pagetable_init(void)
pgd_init((unsigned long)swapper_pg_dir
+ sizeof(pgd_t) * USER_PTRS_PER_PGD);
-#ifdef CONFIG_HIGHMEM
pgd_base = swapper_pg_dir;
/*
@@ -53,6 +53,7 @@ void __init pagetable_init(void)
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, 0, pgd_base);
+#ifdef CONFIG_HIGHMEM
/*
* Permanent kmaps:
*/