diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-10-22 00:17:35 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-10-22 00:17:35 +0200 |
commit | f8829caee311207afbc882794bdc5aa0db5caf33 (patch) | |
tree | dbadd9fa746a1a4f091bc7e240ca8d787188a913 /arch/mips/mm/pgtable-64.c | |
parent | [MIPS] Cleanup remaining references to mips_counter_frequency. (diff) | |
download | linux-f8829caee311207afbc882794bdc5aa0db5caf33.tar.xz linux-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-64.c')
-rw-r--r-- | arch/mips/mm/pgtable-64.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 44b5e97fff65..8d600d307d5d 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -8,6 +8,7 @@ */ #include <linux/init.h> #include <linux/mm.h> +#include <asm/fixmap.h> #include <asm/pgtable.h> void pgd_init(unsigned long page) @@ -52,7 +53,17 @@ void pmd_init(unsigned long addr, unsigned long pagetable) void __init pagetable_init(void) { + unsigned long vaddr; + pgd_t *pgd_base; + /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); + + pgd_base = swapper_pg_dir; + /* + * Fixed mappings: + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + fixrange_init(vaddr, 0, pgd_base); } |