Skip to content

Commit

Permalink
ARM: update FIQ support for relocation of vectors
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King committed Jul 31, 2013
1 parent b9b32bf commit e39e3f3
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
3 changes: 3 additions & 0 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,9 @@ vector_addrexcptn:
vector_fiq:
subs pc, lr, #4

.globl vector_fiq_offset
.equ vector_fiq_offset, vector_fiq

.section .vectors, "ax", %progbits
__vectors_start:
W(b) vector_rst
Expand Down
19 changes: 14 additions & 5 deletions arch/arm/kernel/fiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
#include <asm/irq.h>
#include <asm/traps.h>

#define FIQ_OFFSET ({ \
extern void *vector_fiq_offset; \
(unsigned)&vector_fiq_offset; \
})

static unsigned long no_fiq_insn;

/* Default reacquire function
Expand Down Expand Up @@ -80,13 +85,16 @@ 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)
memcpy((void *)0xffff001c, start, length);
void *base = (void *)0xffff0000;
#else
memcpy(vectors_page + 0x1c, start, length);
void *base = vectors_page;
#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())
flush_icache_range(0x1c, 0x1c + length);
flush_icache_range(offset, offset + length);
}

int claim_fiq(struct fiq_handler *f)
Expand Down Expand Up @@ -144,6 +152,7 @@ EXPORT_SYMBOL(disable_fiq);

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;
}

0 comments on commit e39e3f3

Please sign in to comment.