浏览代码

ARM: update FIQ support for relocation of vectors

FIQ should no longer copy the FIQ code into the user visible vector
page.  Instead, it should use the hidden page.  This change makes
that happen.

Cc: <stable@vger.kernel.org>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Russell King 12 年之前
父节点
当前提交
e39e3f3ebf
共有 2 个文件被更改,包括 17 次插入5 次删除
  1. 3 0
      arch/arm/kernel/entry-armv.S
  2. 14 5
      arch/arm/kernel/fiq.c

+ 3 - 0
arch/arm/kernel/entry-armv.S

@@ -1120,6 +1120,9 @@ vector_addrexcptn:
 vector_fiq:
 vector_fiq:
 	subs	pc, lr, #4
 	subs	pc, lr, #4
 
 
+	.globl	vector_fiq_offset
+	.equ	vector_fiq_offset, vector_fiq
+
 	.section .vectors, "ax", %progbits
 	.section .vectors, "ax", %progbits
 __vectors_start:
 __vectors_start:
 	W(b)	vector_rst
 	W(b)	vector_rst

+ 14 - 5
arch/arm/kernel/fiq.c

@@ -47,6 +47,11 @@
 #include <asm/irq.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
 #include <asm/traps.h>
 
 
+#define FIQ_OFFSET ({					\
+		extern void *vector_fiq_offset;		\
+		(unsigned)&vector_fiq_offset;		\
+	})
+
 static unsigned long no_fiq_insn;
 static unsigned long no_fiq_insn;
 
 
 /* Default reacquire function
 /* Default reacquire function
@@ -80,13 +85,16 @@ int show_fiq_list(struct seq_file *p, int prec)
 void set_fiq_handler(void *start, unsigned int length)
 void set_fiq_handler(void *start, unsigned int length)
 {
 {
 #if defined(CONFIG_CPU_USE_DOMAINS)
 #if defined(CONFIG_CPU_USE_DOMAINS)
-	memcpy((void *)0xffff001c, start, length);
+	void *base = (void *)0xffff0000;
 #else
 #else
-	memcpy(vectors_page + 0x1c, start, length);
+	void *base = vectors_page;
 #endif
 #endif
-	flush_icache_range(0xffff001c, 0xffff001c + length);
+	unsigned offset = FIQ_OFFSET;
+
+	memcpy(base + offset, start, length);
+	flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
 	if (!vectors_high())
 	if (!vectors_high())
-		flush_icache_range(0x1c, 0x1c + length);
+		flush_icache_range(offset, offset + length);
 }
 }
 
 
 int claim_fiq(struct fiq_handler *f)
 int claim_fiq(struct fiq_handler *f)
@@ -144,6 +152,7 @@ EXPORT_SYMBOL(disable_fiq);
 
 
 void __init init_FIQ(int start)
 void __init init_FIQ(int start)
 {
 {
-	no_fiq_insn = *(unsigned long *)0xffff001c;
+	unsigned offset = FIQ_OFFSET;
+	no_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
 	fiq_start = start;
 	fiq_start = start;
 }
 }