diff --git a/target/linux/generic/patches-3.10/063-arm-fix-fiq-vivt.patch b/target/linux/generic/patches-3.10/063-arm-fix-fiq-vivt.patch new file mode 100644 index 0000000000..88c3f6b63e --- /dev/null +++ b/target/linux/generic/patches-3.10/063-arm-fix-fiq-vivt.patch @@ -0,0 +1,55 @@ +From 2ba85e7af4c639d933c9a87a6d7363f2983d5ada Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Thu, 08 Aug 2013 10:51:21 +0000 +Subject: ARM: Fix FIQ code on VIVT CPUs + +Aaro Koskinen reports the following oops: +Installing fiq handler from c001b110, length 0x164 +Unable to handle kernel paging request at virtual address ffff1224 +pgd = c0004000 +[ffff1224] *pgd=00000000, *pte=11fff0cb, *ppte=11fff00a +... +[] (set_fiq_handler+0x0/0x6c) from [] (ams_delta_init_fiq+0xa8/0x160) + r6:00000164 r5:c001b110 r4:00000000 r3:fefecb4c +[] (ams_delta_init_fiq+0x0/0x160) from [] (ams_delta_init+0xd4/0x114) + r6:00000000 r5:fffece10 r4:c037a9e0 +[] (ams_delta_init+0x0/0x114) from [] (customize_machine+0x24/0x30) + +This is because the vectors page is now write-protected, and to change +code in there we must write to its original alias. Make that change, +and adjust the cache flushing such that the code will become visible +to the instruction stream on VIVT CPUs. + +Reported-by: Aaro Koskinen +Tested-by: Aaro Koskinen +Signed-off-by: Russell King +--- +(limited to 'arch/arm/kernel/fiq.c') + +diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c +index 25442f4..fc79202 100644 +--- a/arch/arm/kernel/fiq.c ++++ b/arch/arm/kernel/fiq.c +@@ -84,17 +84,13 @@ int show_fiq_list(struct seq_file *p, int prec) + + void set_fiq_handler(void *start, unsigned int length) + { +-#if defined(CONFIG_CPU_USE_DOMAINS) +- void *base = (void *)0xffff0000; +-#else + void *base = vectors_page; +-#endif + unsigned offset = FIQ_OFFSET; + + memcpy(base + offset, start, length); ++ if (!cache_is_vipt_nonaliasing()) ++ flush_icache_range(base + offset, offset + length); + flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length); +- if (!vectors_high()) +- flush_icache_range(offset, offset + length); + } + + int claim_fiq(struct fiq_handler *f) +-- +cgit v0.9.2 +