diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index cab094c234ee..ab517fcce21b 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -35,8 +35,6 @@ | |||
35 | #include <asm/tls.h> | 35 | #include <asm/tls.h> |
36 | #include <asm/system_misc.h> | 36 | #include <asm/system_misc.h> |
37 | 37 | ||
38 | #include "signal.h" | ||
39 | |||
40 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; | 38 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; |
41 | 39 | ||
42 | void *vectors_page; | 40 | void *vectors_page; |
@@ -800,15 +798,26 @@ void __init trap_init(void) | |||
800 | return; | 798 | return; |
801 | } | 799 | } |
802 | 800 | ||
803 | static void __init kuser_get_tls_init(unsigned long vectors) | 801 | #ifdef CONFIG_KUSER_HELPERS |
802 | static void __init kuser_init(void *vectors) | ||
804 | { | 803 | { |
804 | extern char __kuser_helper_start[], __kuser_helper_end[]; | ||
805 | int kuser_sz = __kuser_helper_end - __kuser_helper_start; | ||
806 | |||
807 | memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); | ||
808 | |||
805 | /* | 809 | /* |
806 | * vectors + 0xfe0 = __kuser_get_tls | 810 | * vectors + 0xfe0 = __kuser_get_tls |
807 | * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 | 811 | * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 |
808 | */ | 812 | */ |
809 | if (tls_emu || has_tls_reg) | 813 | if (tls_emu || has_tls_reg) |
810 | memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); | 814 | memcpy(vectors + 0xfe0, vectors + 0xfe8, 4); |
811 | } | 815 | } |
816 | #else | ||
817 | static void __init kuser_init(void *vectors) | ||
818 | { | ||
819 | } | ||
820 | #endif | ||
812 | 821 | ||
813 | void __init early_trap_init(void *vectors_base) | 822 | void __init early_trap_init(void *vectors_base) |
814 | { | 823 | { |
@@ -816,33 +825,30 @@ void __init early_trap_init(void *vectors_base) | |||
816 | unsigned long vectors = (unsigned long)vectors_base; | 825 | unsigned long vectors = (unsigned long)vectors_base; |
817 | extern char __stubs_start[], __stubs_end[]; | 826 | extern char __stubs_start[], __stubs_end[]; |
818 | extern char __vectors_start[], __vectors_end[]; | 827 | extern char __vectors_start[], __vectors_end[]; |
819 | extern char __kuser_helper_start[], __kuser_helper_end[]; | 828 | unsigned i; |
820 | int kuser_sz = __kuser_helper_end - __kuser_helper_start; | ||
821 | 829 | ||
822 | vectors_page = vectors_base; | 830 | vectors_page = vectors_base; |
823 | 831 | ||
824 | /* | 832 | /* |
833 | * Poison the vectors page with an undefined instruction. This | ||
834 | * instruction is chosen to be undefined for both ARM and Thumb | ||
835 | * ISAs. The Thumb version is an undefined instruction with a | ||
836 | * branch back to the undefined instruction. | ||
837 | */ | ||
838 | for (i = 0; i < PAGE_SIZE / sizeof(u32); i++) | ||
839 | ((u32 *)vectors_base)[i] = 0xe7fddef1; | ||
840 | |||
841 | /* | ||
825 | * Copy the vectors, stubs and kuser helpers (in entry-armv.S) | 842 | * Copy the vectors, stubs and kuser helpers (in entry-armv.S) |
826 | * into the vector page, mapped at 0xffff0000, and ensure these | 843 | * into the vector page, mapped at 0xffff0000, and ensure these |
827 | * are visible to the instruction stream. | 844 | * are visible to the instruction stream. |
828 | */ | 845 | */ |
829 | memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); | 846 | memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); |
830 | memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); | 847 | memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); |
831 | memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); | ||
832 | 848 | ||
833 | /* | 849 | kuser_init(vectors_base); |
834 | * Do processor specific fixups for the kuser helpers | ||
835 | */ | ||
836 | kuser_get_tls_init(vectors); | ||
837 | |||
838 | /* | ||
839 | * Copy signal return handlers into the vector page, and | ||
840 | * set sigreturn to be a pointer to these. | ||
841 | */ | ||
842 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), | ||
843 | sigreturn_codes, sizeof(sigreturn_codes)); | ||
844 | 850 | ||
845 | flush_icache_range(vectors, vectors + PAGE_SIZE); | 851 | flush_icache_range(vectors, vectors + PAGE_SIZE * 2); |
846 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 852 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
847 | #else /* ifndef CONFIG_CPU_V7M */ | 853 | #else /* ifndef CONFIG_CPU_V7M */ |
848 | /* | 854 | /* |