diff options
Diffstat (limited to 'arch/powerpc')
54 files changed, 898 insertions, 679 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 31b96942c0a7..68cde2f8a12c 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -113,8 +113,13 @@ else | |||
113 | endif | 113 | endif |
114 | endif | 114 | endif |
115 | 115 | ||
116 | CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc | 116 | CFLAGS-$(CONFIG_PPC64) := -mtraceback=no |
117 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1) | 117 | ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) |
118 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,-mcall-aixdesc) | ||
119 | AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2) | ||
120 | else | ||
121 | CFLAGS-$(CONFIG_PPC64) += -mcall-aixdesc | ||
122 | endif | ||
118 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) | 123 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) |
119 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) | 124 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) |
120 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) | 125 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) |
@@ -151,7 +156,7 @@ endif | |||
151 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) | 156 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) |
152 | 157 | ||
153 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) | 158 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) |
154 | KBUILD_AFLAGS += -Iarch/$(ARCH) | 159 | KBUILD_AFLAGS += -Iarch/$(ARCH) $(AFLAGS-y) |
155 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) | 160 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) |
156 | CPP = $(CC) -E $(KBUILD_CFLAGS) | 161 | CPP = $(CC) -E $(KBUILD_CFLAGS) |
157 | 162 | ||
diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 6636b1d7821b..243b8497d58b 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S | |||
@@ -45,7 +45,7 @@ udelay: | |||
45 | mfspr r4,SPRN_PVR | 45 | mfspr r4,SPRN_PVR |
46 | srwi r4,r4,16 | 46 | srwi r4,r4,16 |
47 | cmpwi 0,r4,1 /* 601 ? */ | 47 | cmpwi 0,r4,1 /* 601 ? */ |
48 | bne .udelay_not_601 | 48 | bne .Ludelay_not_601 |
49 | 00: li r0,86 /* Instructions / microsecond? */ | 49 | 00: li r0,86 /* Instructions / microsecond? */ |
50 | mtctr r0 | 50 | mtctr r0 |
51 | 10: addi r0,r0,0 /* NOP */ | 51 | 10: addi r0,r0,0 /* NOP */ |
@@ -54,7 +54,7 @@ udelay: | |||
54 | bne 00b | 54 | bne 00b |
55 | blr | 55 | blr |
56 | 56 | ||
57 | .udelay_not_601: | 57 | .Ludelay_not_601: |
58 | mulli r4,r3,1000 /* nanoseconds */ | 58 | mulli r4,r3,1000 /* nanoseconds */ |
59 | /* Change r4 to be the number of ticks using: | 59 | /* Change r4 to be the number of ticks using: |
60 | * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns | 60 | * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns |
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 97e02f985df8..37991e154ef8 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h | |||
@@ -42,15 +42,47 @@ void __patch_exception(int exc, unsigned long addr); | |||
42 | } while (0) | 42 | } while (0) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | #define OP_RT_RA_MASK 0xffff0000UL | ||
46 | #define LIS_R2 0x3c020000UL | ||
47 | #define ADDIS_R2_R12 0x3c4c0000UL | ||
48 | #define ADDI_R2_R2 0x38420000UL | ||
49 | |||
45 | static inline unsigned long ppc_function_entry(void *func) | 50 | static inline unsigned long ppc_function_entry(void *func) |
46 | { | 51 | { |
47 | #ifdef CONFIG_PPC64 | 52 | #if defined(CONFIG_PPC64) |
53 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
54 | u32 *insn = func; | ||
55 | |||
56 | /* | ||
57 | * A PPC64 ABIv2 function may have a local and a global entry | ||
58 | * point. We need to use the local entry point when patching | ||
59 | * functions, so identify and step over the global entry point | ||
60 | * sequence. | ||
61 | * | ||
62 | * The global entry point sequence is always of the form: | ||
63 | * | ||
64 | * addis r2,r12,XXXX | ||
65 | * addi r2,r2,XXXX | ||
66 | * | ||
67 | * A linker optimisation may convert the addis to lis: | ||
68 | * | ||
69 | * lis r2,XXXX | ||
70 | * addi r2,r2,XXXX | ||
71 | */ | ||
72 | if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) || | ||
73 | ((*insn & OP_RT_RA_MASK) == LIS_R2)) && | ||
74 | ((*(insn+1) & OP_RT_RA_MASK) == ADDI_R2_R2)) | ||
75 | return (unsigned long)(insn + 2); | ||
76 | else | ||
77 | return (unsigned long)func; | ||
78 | #else | ||
48 | /* | 79 | /* |
49 | * On PPC64 the function pointer actually points to the function's | 80 | * On PPC64 ABIv1 the function pointer actually points to the |
50 | * descriptor. The first entry in the descriptor is the address | 81 | * function's descriptor. The first entry in the descriptor is the |
51 | * of the function text. | 82 | * address of the function text. |
52 | */ | 83 | */ |
53 | return ((func_descr_t *)func)->entry; | 84 | return ((func_descr_t *)func)->entry; |
85 | #endif | ||
54 | #else | 86 | #else |
55 | return (unsigned long)func; | 87 | return (unsigned long)func; |
56 | #endif | 88 | #endif |
diff --git a/arch/powerpc/include/asm/context_tracking.h b/arch/powerpc/include/asm/context_tracking.h index b6f5a33b8ee2..40014921ffff 100644 --- a/arch/powerpc/include/asm/context_tracking.h +++ b/arch/powerpc/include/asm/context_tracking.h | |||
@@ -2,9 +2,9 @@ | |||
2 | #define _ASM_POWERPC_CONTEXT_TRACKING_H | 2 | #define _ASM_POWERPC_CONTEXT_TRACKING_H |
3 | 3 | ||
4 | #ifdef CONFIG_CONTEXT_TRACKING | 4 | #ifdef CONFIG_CONTEXT_TRACKING |
5 | #define SCHEDULE_USER bl .schedule_user | 5 | #define SCHEDULE_USER bl schedule_user |
6 | #else | 6 | #else |
7 | #define SCHEDULE_USER bl .schedule | 7 | #define SCHEDULE_USER bl schedule |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #endif | 10 | #endif |
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h index a563d9afd179..a8b52b61043f 100644 --- a/arch/powerpc/include/asm/exception-64e.h +++ b/arch/powerpc/include/asm/exception-64e.h | |||
@@ -174,10 +174,10 @@ exc_##label##_book3e: | |||
174 | mtlr r16; | 174 | mtlr r16; |
175 | #define TLB_MISS_STATS_D(name) \ | 175 | #define TLB_MISS_STATS_D(name) \ |
176 | addi r9,r13,MMSTAT_DSTATS+name; \ | 176 | addi r9,r13,MMSTAT_DSTATS+name; \ |
177 | bl .tlb_stat_inc; | 177 | bl tlb_stat_inc; |
178 | #define TLB_MISS_STATS_I(name) \ | 178 | #define TLB_MISS_STATS_I(name) \ |
179 | addi r9,r13,MMSTAT_ISTATS+name; \ | 179 | addi r9,r13,MMSTAT_ISTATS+name; \ |
180 | bl .tlb_stat_inc; | 180 | bl tlb_stat_inc; |
181 | #define TLB_MISS_STATS_X(name) \ | 181 | #define TLB_MISS_STATS_X(name) \ |
182 | ld r8,PACA_EXTLB+EX_TLB_ESR(r13); \ | 182 | ld r8,PACA_EXTLB+EX_TLB_ESR(r13); \ |
183 | cmpdi cr2,r8,-1; \ | 183 | cmpdi cr2,r8,-1; \ |
@@ -185,7 +185,7 @@ exc_##label##_book3e: | |||
185 | addi r9,r13,MMSTAT_DSTATS+name; \ | 185 | addi r9,r13,MMSTAT_DSTATS+name; \ |
186 | b 62f; \ | 186 | b 62f; \ |
187 | 61: addi r9,r13,MMSTAT_ISTATS+name; \ | 187 | 61: addi r9,r13,MMSTAT_ISTATS+name; \ |
188 | 62: bl .tlb_stat_inc; | 188 | 62: bl tlb_stat_inc; |
189 | #define TLB_MISS_STATS_SAVE_INFO \ | 189 | #define TLB_MISS_STATS_SAVE_INFO \ |
190 | std r14,EX_TLB_ESR(r12); /* save ESR */ | 190 | std r14,EX_TLB_ESR(r12); /* save ESR */ |
191 | #define TLB_MISS_STATS_SAVE_INFO_BOLTED \ | 191 | #define TLB_MISS_STATS_SAVE_INFO_BOLTED \ |
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index aeaa56cd9b54..8f35cd7d59cc 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -517,7 +517,7 @@ label##_relon_hv: \ | |||
517 | #define DISABLE_INTS RECONCILE_IRQ_STATE(r10,r11) | 517 | #define DISABLE_INTS RECONCILE_IRQ_STATE(r10,r11) |
518 | 518 | ||
519 | #define ADD_NVGPRS \ | 519 | #define ADD_NVGPRS \ |
520 | bl .save_nvgprs | 520 | bl save_nvgprs |
521 | 521 | ||
522 | #define RUNLATCH_ON \ | 522 | #define RUNLATCH_ON \ |
523 | BEGIN_FTR_SECTION \ | 523 | BEGIN_FTR_SECTION \ |
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index 169d039ed402..e3661872fbea 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h | |||
@@ -61,6 +61,7 @@ struct dyn_arch_ftrace { | |||
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) | 63 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) |
64 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
64 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME | 65 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME |
65 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | 66 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) |
66 | { | 67 | { |
@@ -72,6 +73,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name | |||
72 | */ | 73 | */ |
73 | return !strcmp(sym + 4, name + 3); | 74 | return !strcmp(sym + 4, name + 3); |
74 | } | 75 | } |
76 | #endif | ||
75 | #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ | 77 | #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ |
76 | 78 | ||
77 | #endif /* _ASM_POWERPC_FTRACE */ | 79 | #endif /* _ASM_POWERPC_FTRACE */ |
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h index f51a5580bfd0..e20eb95429a8 100644 --- a/arch/powerpc/include/asm/irqflags.h +++ b/arch/powerpc/include/asm/irqflags.h | |||
@@ -20,9 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | #define TRACE_WITH_FRAME_BUFFER(func) \ | 21 | #define TRACE_WITH_FRAME_BUFFER(func) \ |
22 | mflr r0; \ | 22 | mflr r0; \ |
23 | stdu r1, -32(r1); \ | 23 | stdu r1, -STACK_FRAME_OVERHEAD(r1); \ |
24 | std r0, 16(r1); \ | 24 | std r0, 16(r1); \ |
25 | stdu r1, -32(r1); \ | 25 | stdu r1, -STACK_FRAME_OVERHEAD(r1); \ |
26 | bl func; \ | 26 | bl func; \ |
27 | ld r1, 0(r1); \ | 27 | ld r1, 0(r1); \ |
28 | ld r1, 0(r1); | 28 | ld r1, 0(r1); |
@@ -36,8 +36,8 @@ | |||
36 | * have to call a C function so call a wrapper that saves all the | 36 | * have to call a C function so call a wrapper that saves all the |
37 | * C-clobbered registers. | 37 | * C-clobbered registers. |
38 | */ | 38 | */ |
39 | #define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on) | 39 | #define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on) |
40 | #define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off) | 40 | #define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off) |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * This is used by assembly code to soft-disable interrupts first and | 43 | * This is used by assembly code to soft-disable interrupts first and |
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index 7b6feab6fd26..af15d4d8d604 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
31 | #include <linux/percpu.h> | 31 | #include <linux/percpu.h> |
32 | #include <asm/probes.h> | 32 | #include <asm/probes.h> |
33 | #include <asm/code-patching.h> | ||
33 | 34 | ||
34 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 35 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
35 | 36 | ||
@@ -56,9 +57,9 @@ typedef ppc_opcode_t kprobe_opcode_t; | |||
56 | if ((colon = strchr(name, ':')) != NULL) { \ | 57 | if ((colon = strchr(name, ':')) != NULL) { \ |
57 | colon++; \ | 58 | colon++; \ |
58 | if (*colon != '\0' && *colon != '.') \ | 59 | if (*colon != '\0' && *colon != '.') \ |
59 | addr = *(kprobe_opcode_t **)addr; \ | 60 | addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ |
60 | } else if (name[0] != '.') \ | 61 | } else if (name[0] != '.') \ |
61 | addr = *(kprobe_opcode_t **)addr; \ | 62 | addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ |
62 | } else { \ | 63 | } else { \ |
63 | char dot_name[KSYM_NAME_LEN]; \ | 64 | char dot_name[KSYM_NAME_LEN]; \ |
64 | dot_name[0] = '.'; \ | 65 | dot_name[0] = '.'; \ |
diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h index b36f650a13ff..e3ad5c72724a 100644 --- a/arch/powerpc/include/asm/linkage.h +++ b/arch/powerpc/include/asm/linkage.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_POWERPC_LINKAGE_H | 2 | #define _ASM_POWERPC_LINKAGE_H |
3 | 3 | ||
4 | #ifdef CONFIG_PPC64 | 4 | #ifdef CONFIG_PPC64 |
5 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
5 | #define cond_syscall(x) \ | 6 | #define cond_syscall(x) \ |
6 | asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ | 7 | asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ |
7 | "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") | 8 | "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") |
@@ -9,5 +10,6 @@ | |||
9 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ | 10 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ |
10 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) | 11 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) |
11 | #endif | 12 | #endif |
13 | #endif | ||
12 | 14 | ||
13 | #endif /* _ASM_POWERPC_LINKAGE_H */ | 15 | #endif /* _ASM_POWERPC_LINKAGE_H */ |
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index 49fa55bfbac4..dcfcad139bcc 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h | |||
@@ -35,6 +35,7 @@ struct mod_arch_specific { | |||
35 | #ifdef __powerpc64__ | 35 | #ifdef __powerpc64__ |
36 | unsigned int stubs_section; /* Index of stubs section in module */ | 36 | unsigned int stubs_section; /* Index of stubs section in module */ |
37 | unsigned int toc_section; /* What section is the TOC? */ | 37 | unsigned int toc_section; /* What section is the TOC? */ |
38 | bool toc_fixed; /* Have we fixed up .TOC.? */ | ||
38 | #ifdef CONFIG_DYNAMIC_FTRACE | 39 | #ifdef CONFIG_DYNAMIC_FTRACE |
39 | unsigned long toc; | 40 | unsigned long toc; |
40 | unsigned long tramp; | 41 | unsigned long tramp; |
@@ -77,6 +78,9 @@ struct mod_arch_specific { | |||
77 | # endif /* MODULE */ | 78 | # endif /* MODULE */ |
78 | #endif | 79 | #endif |
79 | 80 | ||
81 | bool is_module_trampoline(u32 *insns); | ||
82 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
83 | unsigned long *target); | ||
80 | 84 | ||
81 | struct exception_table_entry; | 85 | struct exception_table_entry; |
82 | void sort_ex_table(struct exception_table_entry *start, | 86 | void sort_ex_table(struct exception_table_entry *start, |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 6586a40a46ce..6400f1814fe8 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -57,7 +57,7 @@ BEGIN_FW_FTR_SECTION; \ | |||
57 | LDX_BE r10,0,r10; /* get log write index */ \ | 57 | LDX_BE r10,0,r10; /* get log write index */ \ |
58 | cmpd cr1,r11,r10; \ | 58 | cmpd cr1,r11,r10; \ |
59 | beq+ cr1,33f; \ | 59 | beq+ cr1,33f; \ |
60 | bl .accumulate_stolen_time; \ | 60 | bl accumulate_stolen_time; \ |
61 | ld r12,_MSR(r1); \ | 61 | ld r12,_MSR(r1); \ |
62 | andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ | 62 | andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ |
63 | 33: \ | 63 | 33: \ |
@@ -189,57 +189,53 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
189 | #define __STK_REG(i) (112 + ((i)-14)*8) | 189 | #define __STK_REG(i) (112 + ((i)-14)*8) |
190 | #define STK_REG(i) __STK_REG(__REG_##i) | 190 | #define STK_REG(i) __STK_REG(__REG_##i) |
191 | 191 | ||
192 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
193 | #define STK_GOT 24 | ||
194 | #define __STK_PARAM(i) (32 + ((i)-3)*8) | ||
195 | #else | ||
196 | #define STK_GOT 40 | ||
192 | #define __STK_PARAM(i) (48 + ((i)-3)*8) | 197 | #define __STK_PARAM(i) (48 + ((i)-3)*8) |
198 | #endif | ||
193 | #define STK_PARAM(i) __STK_PARAM(__REG_##i) | 199 | #define STK_PARAM(i) __STK_PARAM(__REG_##i) |
194 | 200 | ||
195 | #define XGLUE(a,b) a##b | 201 | #if defined(_CALL_ELF) && _CALL_ELF == 2 |
196 | #define GLUE(a,b) XGLUE(a,b) | ||
197 | 202 | ||
198 | #define _GLOBAL(name) \ | 203 | #define _GLOBAL(name) \ |
199 | .section ".text"; \ | 204 | .section ".text"; \ |
200 | .align 2 ; \ | 205 | .align 2 ; \ |
206 | .type name,@function; \ | ||
201 | .globl name; \ | 207 | .globl name; \ |
202 | .globl GLUE(.,name); \ | 208 | name: |
203 | .section ".opd","aw"; \ | ||
204 | name: \ | ||
205 | .quad GLUE(.,name); \ | ||
206 | .quad .TOC.@tocbase; \ | ||
207 | .quad 0; \ | ||
208 | .previous; \ | ||
209 | .type GLUE(.,name),@function; \ | ||
210 | GLUE(.,name): | ||
211 | 209 | ||
212 | #define _INIT_GLOBAL(name) \ | 210 | #define _GLOBAL_TOC(name) \ |
213 | __REF; \ | 211 | .section ".text"; \ |
214 | .align 2 ; \ | 212 | .align 2 ; \ |
213 | .type name,@function; \ | ||
215 | .globl name; \ | 214 | .globl name; \ |
216 | .globl GLUE(.,name); \ | ||
217 | .section ".opd","aw"; \ | ||
218 | name: \ | 215 | name: \ |
219 | .quad GLUE(.,name); \ | 216 | 0: addis r2,r12,(.TOC.-0b)@ha; \ |
220 | .quad .TOC.@tocbase; \ | 217 | addi r2,r2,(.TOC.-0b)@l; \ |
221 | .quad 0; \ | 218 | .localentry name,.-name |
222 | .previous; \ | ||
223 | .type GLUE(.,name),@function; \ | ||
224 | GLUE(.,name): | ||
225 | 219 | ||
226 | #define _KPROBE(name) \ | 220 | #define _KPROBE(name) \ |
227 | .section ".kprobes.text","a"; \ | 221 | .section ".kprobes.text","a"; \ |
228 | .align 2 ; \ | 222 | .align 2 ; \ |
223 | .type name,@function; \ | ||
229 | .globl name; \ | 224 | .globl name; \ |
230 | .globl GLUE(.,name); \ | 225 | name: |
231 | .section ".opd","aw"; \ | 226 | |
232 | name: \ | 227 | #define DOTSYM(a) a |
233 | .quad GLUE(.,name); \ | 228 | |
234 | .quad .TOC.@tocbase; \ | 229 | #else |
235 | .quad 0; \ | 230 | |
236 | .previous; \ | 231 | #define XGLUE(a,b) a##b |
237 | .type GLUE(.,name),@function; \ | 232 | #define GLUE(a,b) XGLUE(a,b) |
238 | GLUE(.,name): | ||
239 | 233 | ||
240 | #define _STATIC(name) \ | 234 | #define _GLOBAL(name) \ |
241 | .section ".text"; \ | 235 | .section ".text"; \ |
242 | .align 2 ; \ | 236 | .align 2 ; \ |
237 | .globl name; \ | ||
238 | .globl GLUE(.,name); \ | ||
243 | .section ".opd","aw"; \ | 239 | .section ".opd","aw"; \ |
244 | name: \ | 240 | name: \ |
245 | .quad GLUE(.,name); \ | 241 | .quad GLUE(.,name); \ |
@@ -249,9 +245,13 @@ name: \ | |||
249 | .type GLUE(.,name),@function; \ | 245 | .type GLUE(.,name),@function; \ |
250 | GLUE(.,name): | 246 | GLUE(.,name): |
251 | 247 | ||
252 | #define _INIT_STATIC(name) \ | 248 | #define _GLOBAL_TOC(name) _GLOBAL(name) |
253 | __REF; \ | 249 | |
250 | #define _KPROBE(name) \ | ||
251 | .section ".kprobes.text","a"; \ | ||
254 | .align 2 ; \ | 252 | .align 2 ; \ |
253 | .globl name; \ | ||
254 | .globl GLUE(.,name); \ | ||
255 | .section ".opd","aw"; \ | 255 | .section ".opd","aw"; \ |
256 | name: \ | 256 | name: \ |
257 | .quad GLUE(.,name); \ | 257 | .quad GLUE(.,name); \ |
@@ -261,6 +261,10 @@ name: \ | |||
261 | .type GLUE(.,name),@function; \ | 261 | .type GLUE(.,name),@function; \ |
262 | GLUE(.,name): | 262 | GLUE(.,name): |
263 | 263 | ||
264 | #define DOTSYM(a) GLUE(.,a) | ||
265 | |||
266 | #endif | ||
267 | |||
264 | #else /* 32-bit */ | 268 | #else /* 32-bit */ |
265 | 269 | ||
266 | #define _ENTRY(n) \ | 270 | #define _ENTRY(n) \ |
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index d0e784e0ff48..d1bb96d5a298 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h | |||
@@ -39,6 +39,7 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end) | |||
39 | (unsigned long)_stext < end; | 39 | (unsigned long)_stext < end; |
40 | } | 40 | } |
41 | 41 | ||
42 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
42 | #undef dereference_function_descriptor | 43 | #undef dereference_function_descriptor |
43 | static inline void *dereference_function_descriptor(void *ptr) | 44 | static inline void *dereference_function_descriptor(void *ptr) |
44 | { | 45 | { |
@@ -49,6 +50,7 @@ static inline void *dereference_function_descriptor(void *ptr) | |||
49 | ptr = p; | 50 | ptr = p; |
50 | return ptr; | 51 | return ptr; |
51 | } | 52 | } |
53 | #endif | ||
52 | 54 | ||
53 | #endif | 55 | #endif |
54 | 56 | ||
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 3ddf70276706..ac062f504736 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -62,7 +62,7 @@ COMPAT_SYS_SPU(fcntl) | |||
62 | SYSCALL(ni_syscall) | 62 | SYSCALL(ni_syscall) |
63 | SYSCALL_SPU(setpgid) | 63 | SYSCALL_SPU(setpgid) |
64 | SYSCALL(ni_syscall) | 64 | SYSCALL(ni_syscall) |
65 | SYSX(sys_ni_syscall,sys_olduname, sys_olduname) | 65 | SYSX(sys_ni_syscall,sys_olduname,sys_olduname) |
66 | SYSCALL_SPU(umask) | 66 | SYSCALL_SPU(umask) |
67 | SYSCALL_SPU(chroot) | 67 | SYSCALL_SPU(chroot) |
68 | COMPAT_SYS(ustat) | 68 | COMPAT_SYS(ustat) |
@@ -258,7 +258,7 @@ SYSCALL_SPU(tgkill) | |||
258 | COMPAT_SYS_SPU(utimes) | 258 | COMPAT_SYS_SPU(utimes) |
259 | COMPAT_SYS_SPU(statfs64) | 259 | COMPAT_SYS_SPU(statfs64) |
260 | COMPAT_SYS_SPU(fstatfs64) | 260 | COMPAT_SYS_SPU(fstatfs64) |
261 | SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) | 261 | SYSX(sys_ni_syscall,ppc_fadvise64_64,ppc_fadvise64_64) |
262 | PPC_SYS_SPU(rtas) | 262 | PPC_SYS_SPU(rtas) |
263 | OLDSYS(debug_setcontext) | 263 | OLDSYS(debug_setcontext) |
264 | SYSCALL(ni_syscall) | 264 | SYSCALL(ni_syscall) |
@@ -295,7 +295,7 @@ SYSCALL_SPU(mkdirat) | |||
295 | SYSCALL_SPU(mknodat) | 295 | SYSCALL_SPU(mknodat) |
296 | SYSCALL_SPU(fchownat) | 296 | SYSCALL_SPU(fchownat) |
297 | COMPAT_SYS_SPU(futimesat) | 297 | COMPAT_SYS_SPU(futimesat) |
298 | SYSX_SPU(sys_newfstatat, sys_fstatat64, sys_fstatat64) | 298 | SYSX_SPU(sys_newfstatat,sys_fstatat64,sys_fstatat64) |
299 | SYSCALL_SPU(unlinkat) | 299 | SYSCALL_SPU(unlinkat) |
300 | SYSCALL_SPU(renameat) | 300 | SYSCALL_SPU(renameat) |
301 | SYSCALL_SPU(linkat) | 301 | SYSCALL_SPU(linkat) |
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index 7e39c9146a71..59dad113897b 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h | |||
@@ -291,9 +291,17 @@ do { \ | |||
291 | #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ | 291 | #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ |
292 | #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ | 292 | #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ |
293 | #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ | 293 | #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ |
294 | #define R_PPC64_TLSGD 107 | ||
295 | #define R_PPC64_TLSLD 108 | ||
296 | #define R_PPC64_TOCSAVE 109 | ||
297 | |||
298 | #define R_PPC64_REL16 249 | ||
299 | #define R_PPC64_REL16_LO 250 | ||
300 | #define R_PPC64_REL16_HI 251 | ||
301 | #define R_PPC64_REL16_HA 252 | ||
294 | 302 | ||
295 | /* Keep this the last entry. */ | 303 | /* Keep this the last entry. */ |
296 | #define R_PPC64_NUM 107 | 304 | #define R_PPC64_NUM 253 |
297 | 305 | ||
298 | /* There's actually a third entry here, but it's unused */ | 306 | /* There's actually a third entry here, but it's unused */ |
299 | struct ppc64_opd_entry | 307 | struct ppc64_opd_entry |
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index cc2d8962e090..4f1393d20079 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S | |||
@@ -94,12 +94,12 @@ _GLOBAL(setup_altivec_idle) | |||
94 | _GLOBAL(__setup_cpu_e6500) | 94 | _GLOBAL(__setup_cpu_e6500) |
95 | mflr r6 | 95 | mflr r6 |
96 | #ifdef CONFIG_PPC64 | 96 | #ifdef CONFIG_PPC64 |
97 | bl .setup_altivec_ivors | 97 | bl setup_altivec_ivors |
98 | /* Touch IVOR42 only if the CPU supports E.HV category */ | 98 | /* Touch IVOR42 only if the CPU supports E.HV category */ |
99 | mfspr r10,SPRN_MMUCFG | 99 | mfspr r10,SPRN_MMUCFG |
100 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 100 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
101 | beq 1f | 101 | beq 1f |
102 | bl .setup_lrat_ivor | 102 | bl setup_lrat_ivor |
103 | 1: | 103 | 1: |
104 | #endif | 104 | #endif |
105 | bl setup_pw20_idle | 105 | bl setup_pw20_idle |
@@ -164,15 +164,15 @@ _GLOBAL(__setup_cpu_e5500) | |||
164 | #ifdef CONFIG_PPC_BOOK3E_64 | 164 | #ifdef CONFIG_PPC_BOOK3E_64 |
165 | _GLOBAL(__restore_cpu_e6500) | 165 | _GLOBAL(__restore_cpu_e6500) |
166 | mflr r5 | 166 | mflr r5 |
167 | bl .setup_altivec_ivors | 167 | bl setup_altivec_ivors |
168 | /* Touch IVOR42 only if the CPU supports E.HV category */ | 168 | /* Touch IVOR42 only if the CPU supports E.HV category */ |
169 | mfspr r10,SPRN_MMUCFG | 169 | mfspr r10,SPRN_MMUCFG |
170 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 170 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
171 | beq 1f | 171 | beq 1f |
172 | bl .setup_lrat_ivor | 172 | bl setup_lrat_ivor |
173 | 1: | 173 | 1: |
174 | bl .setup_pw20_idle | 174 | bl setup_pw20_idle |
175 | bl .setup_altivec_idle | 175 | bl setup_altivec_idle |
176 | bl __restore_cpu_e5500 | 176 | bl __restore_cpu_e5500 |
177 | mtlr r5 | 177 | mtlr r5 |
178 | blr | 178 | blr |
@@ -181,9 +181,9 @@ _GLOBAL(__restore_cpu_e5500) | |||
181 | mflr r4 | 181 | mflr r4 |
182 | bl __e500_icache_setup | 182 | bl __e500_icache_setup |
183 | bl __e500_dcache_setup | 183 | bl __e500_dcache_setup |
184 | bl .__setup_base_ivors | 184 | bl __setup_base_ivors |
185 | bl .setup_perfmon_ivor | 185 | bl setup_perfmon_ivor |
186 | bl .setup_doorbell_ivors | 186 | bl setup_doorbell_ivors |
187 | /* | 187 | /* |
188 | * We only want to touch IVOR38-41 if we're running on hardware | 188 | * We only want to touch IVOR38-41 if we're running on hardware |
189 | * that supports category E.HV. The architectural way to determine | 189 | * that supports category E.HV. The architectural way to determine |
@@ -192,7 +192,7 @@ _GLOBAL(__restore_cpu_e5500) | |||
192 | mfspr r10,SPRN_MMUCFG | 192 | mfspr r10,SPRN_MMUCFG |
193 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 193 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
194 | beq 1f | 194 | beq 1f |
195 | bl .setup_ehv_ivors | 195 | bl setup_ehv_ivors |
196 | 1: | 196 | 1: |
197 | mtlr r4 | 197 | mtlr r4 |
198 | blr | 198 | blr |
@@ -201,9 +201,9 @@ _GLOBAL(__setup_cpu_e5500) | |||
201 | mflr r5 | 201 | mflr r5 |
202 | bl __e500_icache_setup | 202 | bl __e500_icache_setup |
203 | bl __e500_dcache_setup | 203 | bl __e500_dcache_setup |
204 | bl .__setup_base_ivors | 204 | bl __setup_base_ivors |
205 | bl .setup_perfmon_ivor | 205 | bl setup_perfmon_ivor |
206 | bl .setup_doorbell_ivors | 206 | bl setup_doorbell_ivors |
207 | /* | 207 | /* |
208 | * We only want to touch IVOR38-41 if we're running on hardware | 208 | * We only want to touch IVOR38-41 if we're running on hardware |
209 | * that supports category E.HV. The architectural way to determine | 209 | * that supports category E.HV. The architectural way to determine |
@@ -212,7 +212,7 @@ _GLOBAL(__setup_cpu_e5500) | |||
212 | mfspr r10,SPRN_MMUCFG | 212 | mfspr r10,SPRN_MMUCFG |
213 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 213 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
214 | beq 1f | 214 | beq 1f |
215 | bl .setup_ehv_ivors | 215 | bl setup_ehv_ivors |
216 | b 2f | 216 | b 2f |
217 | 1: | 217 | 1: |
218 | ld r10,CPU_SPEC_FEATURES(r4) | 218 | ld r10,CPU_SPEC_FEATURES(r4) |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 662c6dd98072..9fde8a1bf1e1 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -39,8 +39,8 @@ | |||
39 | * System calls. | 39 | * System calls. |
40 | */ | 40 | */ |
41 | .section ".toc","aw" | 41 | .section ".toc","aw" |
42 | .SYS_CALL_TABLE: | 42 | SYS_CALL_TABLE: |
43 | .tc .sys_call_table[TC],.sys_call_table | 43 | .tc sys_call_table[TC],sys_call_table |
44 | 44 | ||
45 | /* This value is used to mark exception frames on the stack. */ | 45 | /* This value is used to mark exception frames on the stack. */ |
46 | exception_marker: | 46 | exception_marker: |
@@ -106,7 +106,7 @@ BEGIN_FW_FTR_SECTION | |||
106 | LDX_BE r10,0,r10 /* get log write index */ | 106 | LDX_BE r10,0,r10 /* get log write index */ |
107 | cmpd cr1,r11,r10 | 107 | cmpd cr1,r11,r10 |
108 | beq+ cr1,33f | 108 | beq+ cr1,33f |
109 | bl .accumulate_stolen_time | 109 | bl accumulate_stolen_time |
110 | REST_GPR(0,r1) | 110 | REST_GPR(0,r1) |
111 | REST_4GPRS(3,r1) | 111 | REST_4GPRS(3,r1) |
112 | REST_2GPRS(7,r1) | 112 | REST_2GPRS(7,r1) |
@@ -143,7 +143,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
143 | std r10,SOFTE(r1) | 143 | std r10,SOFTE(r1) |
144 | 144 | ||
145 | #ifdef SHOW_SYSCALLS | 145 | #ifdef SHOW_SYSCALLS |
146 | bl .do_show_syscall | 146 | bl do_show_syscall |
147 | REST_GPR(0,r1) | 147 | REST_GPR(0,r1) |
148 | REST_4GPRS(3,r1) | 148 | REST_4GPRS(3,r1) |
149 | REST_2GPRS(7,r1) | 149 | REST_2GPRS(7,r1) |
@@ -162,7 +162,7 @@ system_call: /* label this so stack traces look sane */ | |||
162 | * Need to vector to 32 Bit or default sys_call_table here, | 162 | * Need to vector to 32 Bit or default sys_call_table here, |
163 | * based on caller's run-mode / personality. | 163 | * based on caller's run-mode / personality. |
164 | */ | 164 | */ |
165 | ld r11,.SYS_CALL_TABLE@toc(2) | 165 | ld r11,SYS_CALL_TABLE@toc(2) |
166 | andi. r10,r10,_TIF_32BIT | 166 | andi. r10,r10,_TIF_32BIT |
167 | beq 15f | 167 | beq 15f |
168 | addi r11,r11,8 /* use 32-bit syscall entries */ | 168 | addi r11,r11,8 /* use 32-bit syscall entries */ |
@@ -174,14 +174,14 @@ system_call: /* label this so stack traces look sane */ | |||
174 | clrldi r8,r8,32 | 174 | clrldi r8,r8,32 |
175 | 15: | 175 | 15: |
176 | slwi r0,r0,4 | 176 | slwi r0,r0,4 |
177 | ldx r10,r11,r0 /* Fetch system call handler [ptr] */ | 177 | ldx r12,r11,r0 /* Fetch system call handler [ptr] */ |
178 | mtctr r10 | 178 | mtctr r12 |
179 | bctrl /* Call handler */ | 179 | bctrl /* Call handler */ |
180 | 180 | ||
181 | syscall_exit: | 181 | syscall_exit: |
182 | std r3,RESULT(r1) | 182 | std r3,RESULT(r1) |
183 | #ifdef SHOW_SYSCALLS | 183 | #ifdef SHOW_SYSCALLS |
184 | bl .do_show_syscall_exit | 184 | bl do_show_syscall_exit |
185 | ld r3,RESULT(r1) | 185 | ld r3,RESULT(r1) |
186 | #endif | 186 | #endif |
187 | CURRENT_THREAD_INFO(r12, r1) | 187 | CURRENT_THREAD_INFO(r12, r1) |
@@ -248,9 +248,9 @@ syscall_error: | |||
248 | 248 | ||
249 | /* Traced system call support */ | 249 | /* Traced system call support */ |
250 | syscall_dotrace: | 250 | syscall_dotrace: |
251 | bl .save_nvgprs | 251 | bl save_nvgprs |
252 | addi r3,r1,STACK_FRAME_OVERHEAD | 252 | addi r3,r1,STACK_FRAME_OVERHEAD |
253 | bl .do_syscall_trace_enter | 253 | bl do_syscall_trace_enter |
254 | /* | 254 | /* |
255 | * Restore argument registers possibly just changed. | 255 | * Restore argument registers possibly just changed. |
256 | * We use the return value of do_syscall_trace_enter | 256 | * We use the return value of do_syscall_trace_enter |
@@ -308,7 +308,7 @@ syscall_exit_work: | |||
308 | 4: /* Anything else left to do? */ | 308 | 4: /* Anything else left to do? */ |
309 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ | 309 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ |
310 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) | 310 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) |
311 | beq .ret_from_except_lite | 311 | beq ret_from_except_lite |
312 | 312 | ||
313 | /* Re-enable interrupts */ | 313 | /* Re-enable interrupts */ |
314 | #ifdef CONFIG_PPC_BOOK3E | 314 | #ifdef CONFIG_PPC_BOOK3E |
@@ -319,10 +319,10 @@ syscall_exit_work: | |||
319 | mtmsrd r10,1 | 319 | mtmsrd r10,1 |
320 | #endif /* CONFIG_PPC_BOOK3E */ | 320 | #endif /* CONFIG_PPC_BOOK3E */ |
321 | 321 | ||
322 | bl .save_nvgprs | 322 | bl save_nvgprs |
323 | addi r3,r1,STACK_FRAME_OVERHEAD | 323 | addi r3,r1,STACK_FRAME_OVERHEAD |
324 | bl .do_syscall_trace_leave | 324 | bl do_syscall_trace_leave |
325 | b .ret_from_except | 325 | b ret_from_except |
326 | 326 | ||
327 | /* Save non-volatile GPRs, if not already saved. */ | 327 | /* Save non-volatile GPRs, if not already saved. */ |
328 | _GLOBAL(save_nvgprs) | 328 | _GLOBAL(save_nvgprs) |
@@ -345,42 +345,44 @@ _GLOBAL(save_nvgprs) | |||
345 | */ | 345 | */ |
346 | 346 | ||
347 | _GLOBAL(ppc_fork) | 347 | _GLOBAL(ppc_fork) |
348 | bl .save_nvgprs | 348 | bl save_nvgprs |
349 | bl .sys_fork | 349 | bl sys_fork |
350 | b syscall_exit | 350 | b syscall_exit |
351 | 351 | ||
352 | _GLOBAL(ppc_vfork) | 352 | _GLOBAL(ppc_vfork) |
353 | bl .save_nvgprs | 353 | bl save_nvgprs |
354 | bl .sys_vfork | 354 | bl sys_vfork |
355 | b syscall_exit | 355 | b syscall_exit |
356 | 356 | ||
357 | _GLOBAL(ppc_clone) | 357 | _GLOBAL(ppc_clone) |
358 | bl .save_nvgprs | 358 | bl save_nvgprs |
359 | bl .sys_clone | 359 | bl sys_clone |
360 | b syscall_exit | 360 | b syscall_exit |
361 | 361 | ||
362 | _GLOBAL(ppc32_swapcontext) | 362 | _GLOBAL(ppc32_swapcontext) |
363 | bl .save_nvgprs | 363 | bl save_nvgprs |
364 | bl .compat_sys_swapcontext | 364 | bl compat_sys_swapcontext |
365 | b syscall_exit | 365 | b syscall_exit |
366 | 366 | ||
367 | _GLOBAL(ppc64_swapcontext) | 367 | _GLOBAL(ppc64_swapcontext) |
368 | bl .save_nvgprs | 368 | bl save_nvgprs |
369 | bl .sys_swapcontext | 369 | bl sys_swapcontext |
370 | b syscall_exit | 370 | b syscall_exit |
371 | 371 | ||
372 | _GLOBAL(ret_from_fork) | 372 | _GLOBAL(ret_from_fork) |
373 | bl .schedule_tail | 373 | bl schedule_tail |
374 | REST_NVGPRS(r1) | 374 | REST_NVGPRS(r1) |
375 | li r3,0 | 375 | li r3,0 |
376 | b syscall_exit | 376 | b syscall_exit |
377 | 377 | ||
378 | _GLOBAL(ret_from_kernel_thread) | 378 | _GLOBAL(ret_from_kernel_thread) |
379 | bl .schedule_tail | 379 | bl schedule_tail |
380 | REST_NVGPRS(r1) | 380 | REST_NVGPRS(r1) |
381 | ld r14, 0(r14) | ||
382 | mtlr r14 | 381 | mtlr r14 |
383 | mr r3,r15 | 382 | mr r3,r15 |
383 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
384 | mr r12,r14 | ||
385 | #endif | ||
384 | blrl | 386 | blrl |
385 | li r3,0 | 387 | li r3,0 |
386 | b syscall_exit | 388 | b syscall_exit |
@@ -611,7 +613,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) | |||
611 | _GLOBAL(ret_from_except) | 613 | _GLOBAL(ret_from_except) |
612 | ld r11,_TRAP(r1) | 614 | ld r11,_TRAP(r1) |
613 | andi. r0,r11,1 | 615 | andi. r0,r11,1 |
614 | bne .ret_from_except_lite | 616 | bne ret_from_except_lite |
615 | REST_NVGPRS(r1) | 617 | REST_NVGPRS(r1) |
616 | 618 | ||
617 | _GLOBAL(ret_from_except_lite) | 619 | _GLOBAL(ret_from_except_lite) |
@@ -661,23 +663,23 @@ _GLOBAL(ret_from_except_lite) | |||
661 | #endif | 663 | #endif |
662 | 1: andi. r0,r4,_TIF_NEED_RESCHED | 664 | 1: andi. r0,r4,_TIF_NEED_RESCHED |
663 | beq 2f | 665 | beq 2f |
664 | bl .restore_interrupts | 666 | bl restore_interrupts |
665 | SCHEDULE_USER | 667 | SCHEDULE_USER |
666 | b .ret_from_except_lite | 668 | b ret_from_except_lite |
667 | 2: | 669 | 2: |
668 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 670 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
669 | andi. r0,r4,_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM | 671 | andi. r0,r4,_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM |
670 | bne 3f /* only restore TM if nothing else to do */ | 672 | bne 3f /* only restore TM if nothing else to do */ |
671 | addi r3,r1,STACK_FRAME_OVERHEAD | 673 | addi r3,r1,STACK_FRAME_OVERHEAD |
672 | bl .restore_tm_state | 674 | bl restore_tm_state |
673 | b restore | 675 | b restore |
674 | 3: | 676 | 3: |
675 | #endif | 677 | #endif |
676 | bl .save_nvgprs | 678 | bl save_nvgprs |
677 | bl .restore_interrupts | 679 | bl restore_interrupts |
678 | addi r3,r1,STACK_FRAME_OVERHEAD | 680 | addi r3,r1,STACK_FRAME_OVERHEAD |
679 | bl .do_notify_resume | 681 | bl do_notify_resume |
680 | b .ret_from_except | 682 | b ret_from_except |
681 | 683 | ||
682 | resume_kernel: | 684 | resume_kernel: |
683 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ | 685 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ |
@@ -730,7 +732,7 @@ resume_kernel: | |||
730 | * sure we are soft-disabled first and reconcile irq state. | 732 | * sure we are soft-disabled first and reconcile irq state. |
731 | */ | 733 | */ |
732 | RECONCILE_IRQ_STATE(r3,r4) | 734 | RECONCILE_IRQ_STATE(r3,r4) |
733 | 1: bl .preempt_schedule_irq | 735 | 1: bl preempt_schedule_irq |
734 | 736 | ||
735 | /* Re-test flags and eventually loop */ | 737 | /* Re-test flags and eventually loop */ |
736 | CURRENT_THREAD_INFO(r9, r1) | 738 | CURRENT_THREAD_INFO(r9, r1) |
@@ -792,7 +794,7 @@ restore_no_replay: | |||
792 | */ | 794 | */ |
793 | do_restore: | 795 | do_restore: |
794 | #ifdef CONFIG_PPC_BOOK3E | 796 | #ifdef CONFIG_PPC_BOOK3E |
795 | b .exception_return_book3e | 797 | b exception_return_book3e |
796 | #else | 798 | #else |
797 | /* | 799 | /* |
798 | * Clear the reservation. If we know the CPU tracks the address of | 800 | * Clear the reservation. If we know the CPU tracks the address of |
@@ -907,7 +909,7 @@ restore_check_irq_replay: | |||
907 | * | 909 | * |
908 | * Still, this might be useful for things like hash_page | 910 | * Still, this might be useful for things like hash_page |
909 | */ | 911 | */ |
910 | bl .__check_irq_replay | 912 | bl __check_irq_replay |
911 | cmpwi cr0,r3,0 | 913 | cmpwi cr0,r3,0 |
912 | beq restore_no_replay | 914 | beq restore_no_replay |
913 | 915 | ||
@@ -928,13 +930,13 @@ restore_check_irq_replay: | |||
928 | cmpwi cr0,r3,0x500 | 930 | cmpwi cr0,r3,0x500 |
929 | bne 1f | 931 | bne 1f |
930 | addi r3,r1,STACK_FRAME_OVERHEAD; | 932 | addi r3,r1,STACK_FRAME_OVERHEAD; |
931 | bl .do_IRQ | 933 | bl do_IRQ |
932 | b .ret_from_except | 934 | b ret_from_except |
933 | 1: cmpwi cr0,r3,0x900 | 935 | 1: cmpwi cr0,r3,0x900 |
934 | bne 1f | 936 | bne 1f |
935 | addi r3,r1,STACK_FRAME_OVERHEAD; | 937 | addi r3,r1,STACK_FRAME_OVERHEAD; |
936 | bl .timer_interrupt | 938 | bl timer_interrupt |
937 | b .ret_from_except | 939 | b ret_from_except |
938 | #ifdef CONFIG_PPC_DOORBELL | 940 | #ifdef CONFIG_PPC_DOORBELL |
939 | 1: | 941 | 1: |
940 | #ifdef CONFIG_PPC_BOOK3E | 942 | #ifdef CONFIG_PPC_BOOK3E |
@@ -948,14 +950,14 @@ restore_check_irq_replay: | |||
948 | #endif /* CONFIG_PPC_BOOK3E */ | 950 | #endif /* CONFIG_PPC_BOOK3E */ |
949 | bne 1f | 951 | bne 1f |
950 | addi r3,r1,STACK_FRAME_OVERHEAD; | 952 | addi r3,r1,STACK_FRAME_OVERHEAD; |
951 | bl .doorbell_exception | 953 | bl doorbell_exception |
952 | b .ret_from_except | 954 | b ret_from_except |
953 | #endif /* CONFIG_PPC_DOORBELL */ | 955 | #endif /* CONFIG_PPC_DOORBELL */ |
954 | 1: b .ret_from_except /* What else to do here ? */ | 956 | 1: b ret_from_except /* What else to do here ? */ |
955 | 957 | ||
956 | unrecov_restore: | 958 | unrecov_restore: |
957 | addi r3,r1,STACK_FRAME_OVERHEAD | 959 | addi r3,r1,STACK_FRAME_OVERHEAD |
958 | bl .unrecoverable_exception | 960 | bl unrecoverable_exception |
959 | b unrecov_restore | 961 | b unrecov_restore |
960 | 962 | ||
961 | #ifdef CONFIG_PPC_RTAS | 963 | #ifdef CONFIG_PPC_RTAS |
@@ -1021,7 +1023,7 @@ _GLOBAL(enter_rtas) | |||
1021 | std r6,PACASAVEDMSR(r13) | 1023 | std r6,PACASAVEDMSR(r13) |
1022 | 1024 | ||
1023 | /* Setup our real return addr */ | 1025 | /* Setup our real return addr */ |
1024 | LOAD_REG_ADDR(r4,.rtas_return_loc) | 1026 | LOAD_REG_ADDR(r4,rtas_return_loc) |
1025 | clrldi r4,r4,2 /* convert to realmode address */ | 1027 | clrldi r4,r4,2 /* convert to realmode address */ |
1026 | mtlr r4 | 1028 | mtlr r4 |
1027 | 1029 | ||
@@ -1045,7 +1047,7 @@ _GLOBAL(enter_rtas) | |||
1045 | rfid | 1047 | rfid |
1046 | b . /* prevent speculative execution */ | 1048 | b . /* prevent speculative execution */ |
1047 | 1049 | ||
1048 | _STATIC(rtas_return_loc) | 1050 | rtas_return_loc: |
1049 | FIXUP_ENDIAN | 1051 | FIXUP_ENDIAN |
1050 | 1052 | ||
1051 | /* relocation is off at this point */ | 1053 | /* relocation is off at this point */ |
@@ -1054,7 +1056,7 @@ _STATIC(rtas_return_loc) | |||
1054 | 1056 | ||
1055 | bcl 20,31,$+4 | 1057 | bcl 20,31,$+4 |
1056 | 0: mflr r3 | 1058 | 0: mflr r3 |
1057 | ld r3,(1f-0b)(r3) /* get &.rtas_restore_regs */ | 1059 | ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */ |
1058 | 1060 | ||
1059 | mfmsr r6 | 1061 | mfmsr r6 |
1060 | li r0,MSR_RI | 1062 | li r0,MSR_RI |
@@ -1071,9 +1073,9 @@ _STATIC(rtas_return_loc) | |||
1071 | b . /* prevent speculative execution */ | 1073 | b . /* prevent speculative execution */ |
1072 | 1074 | ||
1073 | .align 3 | 1075 | .align 3 |
1074 | 1: .llong .rtas_restore_regs | 1076 | 1: .llong rtas_restore_regs |
1075 | 1077 | ||
1076 | _STATIC(rtas_restore_regs) | 1078 | rtas_restore_regs: |
1077 | /* relocation is on at this point */ | 1079 | /* relocation is on at this point */ |
1078 | REST_GPR(2, r1) /* Restore the TOC */ | 1080 | REST_GPR(2, r1) /* Restore the TOC */ |
1079 | REST_GPR(13, r1) /* Restore paca */ | 1081 | REST_GPR(13, r1) /* Restore paca */ |
@@ -1173,7 +1175,7 @@ _GLOBAL(mcount) | |||
1173 | _GLOBAL(_mcount) | 1175 | _GLOBAL(_mcount) |
1174 | blr | 1176 | blr |
1175 | 1177 | ||
1176 | _GLOBAL(ftrace_caller) | 1178 | _GLOBAL_TOC(ftrace_caller) |
1177 | /* Taken from output of objdump from lib64/glibc */ | 1179 | /* Taken from output of objdump from lib64/glibc */ |
1178 | mflr r3 | 1180 | mflr r3 |
1179 | ld r11, 0(r1) | 1181 | ld r11, 0(r1) |
@@ -1197,10 +1199,7 @@ _GLOBAL(ftrace_graph_stub) | |||
1197 | _GLOBAL(ftrace_stub) | 1199 | _GLOBAL(ftrace_stub) |
1198 | blr | 1200 | blr |
1199 | #else | 1201 | #else |
1200 | _GLOBAL(mcount) | 1202 | _GLOBAL_TOC(_mcount) |
1201 | blr | ||
1202 | |||
1203 | _GLOBAL(_mcount) | ||
1204 | /* Taken from output of objdump from lib64/glibc */ | 1203 | /* Taken from output of objdump from lib64/glibc */ |
1205 | mflr r3 | 1204 | mflr r3 |
1206 | ld r11, 0(r1) | 1205 | ld r11, 0(r1) |
@@ -1238,7 +1237,7 @@ _GLOBAL(ftrace_graph_caller) | |||
1238 | ld r11, 112(r1) | 1237 | ld r11, 112(r1) |
1239 | addi r3, r11, 16 | 1238 | addi r3, r11, 16 |
1240 | 1239 | ||
1241 | bl .prepare_ftrace_return | 1240 | bl prepare_ftrace_return |
1242 | nop | 1241 | nop |
1243 | 1242 | ||
1244 | ld r0, 128(r1) | 1243 | ld r0, 128(r1) |
@@ -1254,7 +1253,7 @@ _GLOBAL(return_to_handler) | |||
1254 | mr r31, r1 | 1253 | mr r31, r1 |
1255 | stdu r1, -112(r1) | 1254 | stdu r1, -112(r1) |
1256 | 1255 | ||
1257 | bl .ftrace_return_to_handler | 1256 | bl ftrace_return_to_handler |
1258 | nop | 1257 | nop |
1259 | 1258 | ||
1260 | /* return value has real return address */ | 1259 | /* return value has real return address */ |
@@ -1284,7 +1283,7 @@ _GLOBAL(mod_return_to_handler) | |||
1284 | */ | 1283 | */ |
1285 | ld r2, PACATOC(r13) | 1284 | ld r2, PACATOC(r13) |
1286 | 1285 | ||
1287 | bl .ftrace_return_to_handler | 1286 | bl ftrace_return_to_handler |
1288 | nop | 1287 | nop |
1289 | 1288 | ||
1290 | /* return value has real return address */ | 1289 | /* return value has real return address */ |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index c1bee3ce9d1f..771b4e92e5d9 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -499,7 +499,7 @@ exc_##n##_bad_stack: \ | |||
499 | CHECK_NAPPING(); \ | 499 | CHECK_NAPPING(); \ |
500 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 500 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
501 | bl hdlr; \ | 501 | bl hdlr; \ |
502 | b .ret_from_except_lite; | 502 | b ret_from_except_lite; |
503 | 503 | ||
504 | /* This value is used to mark exception frames on the stack. */ | 504 | /* This value is used to mark exception frames on the stack. */ |
505 | .section ".toc","aw" | 505 | .section ".toc","aw" |
@@ -550,11 +550,11 @@ interrupt_end_book3e: | |||
550 | CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, | 550 | CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, |
551 | PROLOG_ADDITION_NONE) | 551 | PROLOG_ADDITION_NONE) |
552 | EXCEPTION_COMMON_CRIT(0x100) | 552 | EXCEPTION_COMMON_CRIT(0x100) |
553 | bl .save_nvgprs | 553 | bl save_nvgprs |
554 | bl special_reg_save | 554 | bl special_reg_save |
555 | CHECK_NAPPING(); | 555 | CHECK_NAPPING(); |
556 | addi r3,r1,STACK_FRAME_OVERHEAD | 556 | addi r3,r1,STACK_FRAME_OVERHEAD |
557 | bl .unknown_exception | 557 | bl unknown_exception |
558 | b ret_from_crit_except | 558 | b ret_from_crit_except |
559 | 559 | ||
560 | /* Machine Check Interrupt */ | 560 | /* Machine Check Interrupt */ |
@@ -562,11 +562,11 @@ interrupt_end_book3e: | |||
562 | MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK, | 562 | MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK, |
563 | PROLOG_ADDITION_NONE) | 563 | PROLOG_ADDITION_NONE) |
564 | EXCEPTION_COMMON_MC(0x000) | 564 | EXCEPTION_COMMON_MC(0x000) |
565 | bl .save_nvgprs | 565 | bl save_nvgprs |
566 | bl special_reg_save | 566 | bl special_reg_save |
567 | CHECK_NAPPING(); | 567 | CHECK_NAPPING(); |
568 | addi r3,r1,STACK_FRAME_OVERHEAD | 568 | addi r3,r1,STACK_FRAME_OVERHEAD |
569 | bl .machine_check_exception | 569 | bl machine_check_exception |
570 | b ret_from_mc_except | 570 | b ret_from_mc_except |
571 | 571 | ||
572 | /* Data Storage Interrupt */ | 572 | /* Data Storage Interrupt */ |
@@ -591,7 +591,7 @@ interrupt_end_book3e: | |||
591 | 591 | ||
592 | /* External Input Interrupt */ | 592 | /* External Input Interrupt */ |
593 | MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, | 593 | MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, |
594 | external_input, .do_IRQ, ACK_NONE) | 594 | external_input, do_IRQ, ACK_NONE) |
595 | 595 | ||
596 | /* Alignment */ | 596 | /* Alignment */ |
597 | START_EXCEPTION(alignment); | 597 | START_EXCEPTION(alignment); |
@@ -612,9 +612,9 @@ interrupt_end_book3e: | |||
612 | std r14,_DSISR(r1) | 612 | std r14,_DSISR(r1) |
613 | addi r3,r1,STACK_FRAME_OVERHEAD | 613 | addi r3,r1,STACK_FRAME_OVERHEAD |
614 | ld r14,PACA_EXGEN+EX_R14(r13) | 614 | ld r14,PACA_EXGEN+EX_R14(r13) |
615 | bl .save_nvgprs | 615 | bl save_nvgprs |
616 | bl .program_check_exception | 616 | bl program_check_exception |
617 | b .ret_from_except | 617 | b ret_from_except |
618 | 618 | ||
619 | /* Floating Point Unavailable Interrupt */ | 619 | /* Floating Point Unavailable Interrupt */ |
620 | START_EXCEPTION(fp_unavailable); | 620 | START_EXCEPTION(fp_unavailable); |
@@ -625,13 +625,13 @@ interrupt_end_book3e: | |||
625 | ld r12,_MSR(r1) | 625 | ld r12,_MSR(r1) |
626 | andi. r0,r12,MSR_PR; | 626 | andi. r0,r12,MSR_PR; |
627 | beq- 1f | 627 | beq- 1f |
628 | bl .load_up_fpu | 628 | bl load_up_fpu |
629 | b fast_exception_return | 629 | b fast_exception_return |
630 | 1: INTS_DISABLE | 630 | 1: INTS_DISABLE |
631 | bl .save_nvgprs | 631 | bl save_nvgprs |
632 | addi r3,r1,STACK_FRAME_OVERHEAD | 632 | addi r3,r1,STACK_FRAME_OVERHEAD |
633 | bl .kernel_fp_unavailable_exception | 633 | bl kernel_fp_unavailable_exception |
634 | b .ret_from_except | 634 | b ret_from_except |
635 | 635 | ||
636 | /* Altivec Unavailable Interrupt */ | 636 | /* Altivec Unavailable Interrupt */ |
637 | START_EXCEPTION(altivec_unavailable); | 637 | START_EXCEPTION(altivec_unavailable); |
@@ -644,16 +644,16 @@ BEGIN_FTR_SECTION | |||
644 | ld r12,_MSR(r1) | 644 | ld r12,_MSR(r1) |
645 | andi. r0,r12,MSR_PR; | 645 | andi. r0,r12,MSR_PR; |
646 | beq- 1f | 646 | beq- 1f |
647 | bl .load_up_altivec | 647 | bl load_up_altivec |
648 | b fast_exception_return | 648 | b fast_exception_return |
649 | 1: | 649 | 1: |
650 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 650 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
651 | #endif | 651 | #endif |
652 | INTS_DISABLE | 652 | INTS_DISABLE |
653 | bl .save_nvgprs | 653 | bl save_nvgprs |
654 | addi r3,r1,STACK_FRAME_OVERHEAD | 654 | addi r3,r1,STACK_FRAME_OVERHEAD |
655 | bl .altivec_unavailable_exception | 655 | bl altivec_unavailable_exception |
656 | b .ret_from_except | 656 | b ret_from_except |
657 | 657 | ||
658 | /* AltiVec Assist */ | 658 | /* AltiVec Assist */ |
659 | START_EXCEPTION(altivec_assist); | 659 | START_EXCEPTION(altivec_assist); |
@@ -662,39 +662,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
662 | PROLOG_ADDITION_NONE) | 662 | PROLOG_ADDITION_NONE) |
663 | EXCEPTION_COMMON(0x220) | 663 | EXCEPTION_COMMON(0x220) |
664 | INTS_DISABLE | 664 | INTS_DISABLE |
665 | bl .save_nvgprs | 665 | bl save_nvgprs |
666 | addi r3,r1,STACK_FRAME_OVERHEAD | 666 | addi r3,r1,STACK_FRAME_OVERHEAD |
667 | #ifdef CONFIG_ALTIVEC | 667 | #ifdef CONFIG_ALTIVEC |
668 | BEGIN_FTR_SECTION | 668 | BEGIN_FTR_SECTION |
669 | bl .altivec_assist_exception | 669 | bl altivec_assist_exception |
670 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 670 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
671 | #else | 671 | #else |
672 | bl .unknown_exception | 672 | bl unknown_exception |
673 | #endif | 673 | #endif |
674 | b .ret_from_except | 674 | b ret_from_except |
675 | 675 | ||
676 | 676 | ||
677 | /* Decrementer Interrupt */ | 677 | /* Decrementer Interrupt */ |
678 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, | 678 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, |
679 | decrementer, .timer_interrupt, ACK_DEC) | 679 | decrementer, timer_interrupt, ACK_DEC) |
680 | 680 | ||
681 | /* Fixed Interval Timer Interrupt */ | 681 | /* Fixed Interval Timer Interrupt */ |
682 | MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, | 682 | MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, |
683 | fixed_interval, .unknown_exception, ACK_FIT) | 683 | fixed_interval, unknown_exception, ACK_FIT) |
684 | 684 | ||
685 | /* Watchdog Timer Interrupt */ | 685 | /* Watchdog Timer Interrupt */ |
686 | START_EXCEPTION(watchdog); | 686 | START_EXCEPTION(watchdog); |
687 | CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, | 687 | CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, |
688 | PROLOG_ADDITION_NONE) | 688 | PROLOG_ADDITION_NONE) |
689 | EXCEPTION_COMMON_CRIT(0x9f0) | 689 | EXCEPTION_COMMON_CRIT(0x9f0) |
690 | bl .save_nvgprs | 690 | bl save_nvgprs |
691 | bl special_reg_save | 691 | bl special_reg_save |
692 | CHECK_NAPPING(); | 692 | CHECK_NAPPING(); |
693 | addi r3,r1,STACK_FRAME_OVERHEAD | 693 | addi r3,r1,STACK_FRAME_OVERHEAD |
694 | #ifdef CONFIG_BOOKE_WDT | 694 | #ifdef CONFIG_BOOKE_WDT |
695 | bl .WatchdogException | 695 | bl WatchdogException |
696 | #else | 696 | #else |
697 | bl .unknown_exception | 697 | bl unknown_exception |
698 | #endif | 698 | #endif |
699 | b ret_from_crit_except | 699 | b ret_from_crit_except |
700 | 700 | ||
@@ -712,10 +712,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
712 | PROLOG_ADDITION_NONE) | 712 | PROLOG_ADDITION_NONE) |
713 | EXCEPTION_COMMON(0xf20) | 713 | EXCEPTION_COMMON(0xf20) |
714 | INTS_DISABLE | 714 | INTS_DISABLE |
715 | bl .save_nvgprs | 715 | bl save_nvgprs |
716 | addi r3,r1,STACK_FRAME_OVERHEAD | 716 | addi r3,r1,STACK_FRAME_OVERHEAD |
717 | bl .unknown_exception | 717 | bl unknown_exception |
718 | b .ret_from_except | 718 | b ret_from_except |
719 | 719 | ||
720 | /* Debug exception as a critical interrupt*/ | 720 | /* Debug exception as a critical interrupt*/ |
721 | START_EXCEPTION(debug_crit); | 721 | START_EXCEPTION(debug_crit); |
@@ -774,9 +774,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
774 | mr r4,r14 | 774 | mr r4,r14 |
775 | ld r14,PACA_EXCRIT+EX_R14(r13) | 775 | ld r14,PACA_EXCRIT+EX_R14(r13) |
776 | ld r15,PACA_EXCRIT+EX_R15(r13) | 776 | ld r15,PACA_EXCRIT+EX_R15(r13) |
777 | bl .save_nvgprs | 777 | bl save_nvgprs |
778 | bl .DebugException | 778 | bl DebugException |
779 | b .ret_from_except | 779 | b ret_from_except |
780 | 780 | ||
781 | kernel_dbg_exc: | 781 | kernel_dbg_exc: |
782 | b . /* NYI */ | 782 | b . /* NYI */ |
@@ -839,9 +839,9 @@ kernel_dbg_exc: | |||
839 | mr r4,r14 | 839 | mr r4,r14 |
840 | ld r14,PACA_EXDBG+EX_R14(r13) | 840 | ld r14,PACA_EXDBG+EX_R14(r13) |
841 | ld r15,PACA_EXDBG+EX_R15(r13) | 841 | ld r15,PACA_EXDBG+EX_R15(r13) |
842 | bl .save_nvgprs | 842 | bl save_nvgprs |
843 | bl .DebugException | 843 | bl DebugException |
844 | b .ret_from_except | 844 | b ret_from_except |
845 | 845 | ||
846 | START_EXCEPTION(perfmon); | 846 | START_EXCEPTION(perfmon); |
847 | NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, | 847 | NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, |
@@ -850,23 +850,23 @@ kernel_dbg_exc: | |||
850 | INTS_DISABLE | 850 | INTS_DISABLE |
851 | CHECK_NAPPING() | 851 | CHECK_NAPPING() |
852 | addi r3,r1,STACK_FRAME_OVERHEAD | 852 | addi r3,r1,STACK_FRAME_OVERHEAD |
853 | bl .performance_monitor_exception | 853 | bl performance_monitor_exception |
854 | b .ret_from_except_lite | 854 | b ret_from_except_lite |
855 | 855 | ||
856 | /* Doorbell interrupt */ | 856 | /* Doorbell interrupt */ |
857 | MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, | 857 | MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, |
858 | doorbell, .doorbell_exception, ACK_NONE) | 858 | doorbell, doorbell_exception, ACK_NONE) |
859 | 859 | ||
860 | /* Doorbell critical Interrupt */ | 860 | /* Doorbell critical Interrupt */ |
861 | START_EXCEPTION(doorbell_crit); | 861 | START_EXCEPTION(doorbell_crit); |
862 | CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, | 862 | CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, |
863 | PROLOG_ADDITION_NONE) | 863 | PROLOG_ADDITION_NONE) |
864 | EXCEPTION_COMMON_CRIT(0x2a0) | 864 | EXCEPTION_COMMON_CRIT(0x2a0) |
865 | bl .save_nvgprs | 865 | bl save_nvgprs |
866 | bl special_reg_save | 866 | bl special_reg_save |
867 | CHECK_NAPPING(); | 867 | CHECK_NAPPING(); |
868 | addi r3,r1,STACK_FRAME_OVERHEAD | 868 | addi r3,r1,STACK_FRAME_OVERHEAD |
869 | bl .unknown_exception | 869 | bl unknown_exception |
870 | b ret_from_crit_except | 870 | b ret_from_crit_except |
871 | 871 | ||
872 | /* | 872 | /* |
@@ -878,21 +878,21 @@ kernel_dbg_exc: | |||
878 | PROLOG_ADDITION_NONE) | 878 | PROLOG_ADDITION_NONE) |
879 | EXCEPTION_COMMON(0x2c0) | 879 | EXCEPTION_COMMON(0x2c0) |
880 | addi r3,r1,STACK_FRAME_OVERHEAD | 880 | addi r3,r1,STACK_FRAME_OVERHEAD |
881 | bl .save_nvgprs | 881 | bl save_nvgprs |
882 | INTS_RESTORE_HARD | 882 | INTS_RESTORE_HARD |
883 | bl .unknown_exception | 883 | bl unknown_exception |
884 | b .ret_from_except | 884 | b ret_from_except |
885 | 885 | ||
886 | /* Guest Doorbell critical Interrupt */ | 886 | /* Guest Doorbell critical Interrupt */ |
887 | START_EXCEPTION(guest_doorbell_crit); | 887 | START_EXCEPTION(guest_doorbell_crit); |
888 | CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, | 888 | CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, |
889 | PROLOG_ADDITION_NONE) | 889 | PROLOG_ADDITION_NONE) |
890 | EXCEPTION_COMMON_CRIT(0x2e0) | 890 | EXCEPTION_COMMON_CRIT(0x2e0) |
891 | bl .save_nvgprs | 891 | bl save_nvgprs |
892 | bl special_reg_save | 892 | bl special_reg_save |
893 | CHECK_NAPPING(); | 893 | CHECK_NAPPING(); |
894 | addi r3,r1,STACK_FRAME_OVERHEAD | 894 | addi r3,r1,STACK_FRAME_OVERHEAD |
895 | bl .unknown_exception | 895 | bl unknown_exception |
896 | b ret_from_crit_except | 896 | b ret_from_crit_except |
897 | 897 | ||
898 | /* Hypervisor call */ | 898 | /* Hypervisor call */ |
@@ -901,10 +901,10 @@ kernel_dbg_exc: | |||
901 | PROLOG_ADDITION_NONE) | 901 | PROLOG_ADDITION_NONE) |
902 | EXCEPTION_COMMON(0x310) | 902 | EXCEPTION_COMMON(0x310) |
903 | addi r3,r1,STACK_FRAME_OVERHEAD | 903 | addi r3,r1,STACK_FRAME_OVERHEAD |
904 | bl .save_nvgprs | 904 | bl save_nvgprs |
905 | INTS_RESTORE_HARD | 905 | INTS_RESTORE_HARD |
906 | bl .unknown_exception | 906 | bl unknown_exception |
907 | b .ret_from_except | 907 | b ret_from_except |
908 | 908 | ||
909 | /* Embedded Hypervisor priviledged */ | 909 | /* Embedded Hypervisor priviledged */ |
910 | START_EXCEPTION(ehpriv); | 910 | START_EXCEPTION(ehpriv); |
@@ -912,10 +912,10 @@ kernel_dbg_exc: | |||
912 | PROLOG_ADDITION_NONE) | 912 | PROLOG_ADDITION_NONE) |
913 | EXCEPTION_COMMON(0x320) | 913 | EXCEPTION_COMMON(0x320) |
914 | addi r3,r1,STACK_FRAME_OVERHEAD | 914 | addi r3,r1,STACK_FRAME_OVERHEAD |
915 | bl .save_nvgprs | 915 | bl save_nvgprs |
916 | INTS_RESTORE_HARD | 916 | INTS_RESTORE_HARD |
917 | bl .unknown_exception | 917 | bl unknown_exception |
918 | b .ret_from_except | 918 | b ret_from_except |
919 | 919 | ||
920 | /* LRAT Error interrupt */ | 920 | /* LRAT Error interrupt */ |
921 | START_EXCEPTION(lrat_error); | 921 | START_EXCEPTION(lrat_error); |
@@ -1014,16 +1014,16 @@ storage_fault_common: | |||
1014 | mr r5,r15 | 1014 | mr r5,r15 |
1015 | ld r14,PACA_EXGEN+EX_R14(r13) | 1015 | ld r14,PACA_EXGEN+EX_R14(r13) |
1016 | ld r15,PACA_EXGEN+EX_R15(r13) | 1016 | ld r15,PACA_EXGEN+EX_R15(r13) |
1017 | bl .do_page_fault | 1017 | bl do_page_fault |
1018 | cmpdi r3,0 | 1018 | cmpdi r3,0 |
1019 | bne- 1f | 1019 | bne- 1f |
1020 | b .ret_from_except_lite | 1020 | b ret_from_except_lite |
1021 | 1: bl .save_nvgprs | 1021 | 1: bl save_nvgprs |
1022 | mr r5,r3 | 1022 | mr r5,r3 |
1023 | addi r3,r1,STACK_FRAME_OVERHEAD | 1023 | addi r3,r1,STACK_FRAME_OVERHEAD |
1024 | ld r4,_DAR(r1) | 1024 | ld r4,_DAR(r1) |
1025 | bl .bad_page_fault | 1025 | bl bad_page_fault |
1026 | b .ret_from_except | 1026 | b ret_from_except |
1027 | 1027 | ||
1028 | /* | 1028 | /* |
1029 | * Alignment exception doesn't fit entirely in the 0x100 bytes so it | 1029 | * Alignment exception doesn't fit entirely in the 0x100 bytes so it |
@@ -1035,10 +1035,10 @@ alignment_more: | |||
1035 | addi r3,r1,STACK_FRAME_OVERHEAD | 1035 | addi r3,r1,STACK_FRAME_OVERHEAD |
1036 | ld r14,PACA_EXGEN+EX_R14(r13) | 1036 | ld r14,PACA_EXGEN+EX_R14(r13) |
1037 | ld r15,PACA_EXGEN+EX_R15(r13) | 1037 | ld r15,PACA_EXGEN+EX_R15(r13) |
1038 | bl .save_nvgprs | 1038 | bl save_nvgprs |
1039 | INTS_RESTORE_HARD | 1039 | INTS_RESTORE_HARD |
1040 | bl .alignment_exception | 1040 | bl alignment_exception |
1041 | b .ret_from_except | 1041 | b ret_from_except |
1042 | 1042 | ||
1043 | /* | 1043 | /* |
1044 | * We branch here from entry_64.S for the last stage of the exception | 1044 | * We branch here from entry_64.S for the last stage of the exception |
@@ -1172,7 +1172,7 @@ bad_stack_book3e: | |||
1172 | std r12,0(r11) | 1172 | std r12,0(r11) |
1173 | ld r2,PACATOC(r13) | 1173 | ld r2,PACATOC(r13) |
1174 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1174 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1175 | bl .kernel_bad_stack | 1175 | bl kernel_bad_stack |
1176 | b 1b | 1176 | b 1b |
1177 | 1177 | ||
1178 | /* | 1178 | /* |
@@ -1521,13 +1521,13 @@ _GLOBAL(start_initialization_book3e) | |||
1521 | * and always use AS 0, so we just set it up to match our link | 1521 | * and always use AS 0, so we just set it up to match our link |
1522 | * address and never use 0 based addresses. | 1522 | * address and never use 0 based addresses. |
1523 | */ | 1523 | */ |
1524 | bl .initial_tlb_book3e | 1524 | bl initial_tlb_book3e |
1525 | 1525 | ||
1526 | /* Init global core bits */ | 1526 | /* Init global core bits */ |
1527 | bl .init_core_book3e | 1527 | bl init_core_book3e |
1528 | 1528 | ||
1529 | /* Init per-thread bits */ | 1529 | /* Init per-thread bits */ |
1530 | bl .init_thread_book3e | 1530 | bl init_thread_book3e |
1531 | 1531 | ||
1532 | /* Return to common init code */ | 1532 | /* Return to common init code */ |
1533 | tovirt(r28,r28) | 1533 | tovirt(r28,r28) |
@@ -1548,7 +1548,7 @@ _GLOBAL(start_initialization_book3e) | |||
1548 | */ | 1548 | */ |
1549 | _GLOBAL(book3e_secondary_core_init_tlb_set) | 1549 | _GLOBAL(book3e_secondary_core_init_tlb_set) |
1550 | li r4,1 | 1550 | li r4,1 |
1551 | b .generic_secondary_smp_init | 1551 | b generic_secondary_smp_init |
1552 | 1552 | ||
1553 | _GLOBAL(book3e_secondary_core_init) | 1553 | _GLOBAL(book3e_secondary_core_init) |
1554 | mflr r28 | 1554 | mflr r28 |
@@ -1558,18 +1558,18 @@ _GLOBAL(book3e_secondary_core_init) | |||
1558 | bne 2f | 1558 | bne 2f |
1559 | 1559 | ||
1560 | /* Setup TLB for this core */ | 1560 | /* Setup TLB for this core */ |
1561 | bl .initial_tlb_book3e | 1561 | bl initial_tlb_book3e |
1562 | 1562 | ||
1563 | /* We can return from the above running at a different | 1563 | /* We can return from the above running at a different |
1564 | * address, so recalculate r2 (TOC) | 1564 | * address, so recalculate r2 (TOC) |
1565 | */ | 1565 | */ |
1566 | bl .relative_toc | 1566 | bl relative_toc |
1567 | 1567 | ||
1568 | /* Init global core bits */ | 1568 | /* Init global core bits */ |
1569 | 2: bl .init_core_book3e | 1569 | 2: bl init_core_book3e |
1570 | 1570 | ||
1571 | /* Init per-thread bits */ | 1571 | /* Init per-thread bits */ |
1572 | 3: bl .init_thread_book3e | 1572 | 3: bl init_thread_book3e |
1573 | 1573 | ||
1574 | /* Return to common init code at proper virtual address. | 1574 | /* Return to common init code at proper virtual address. |
1575 | * | 1575 | * |
@@ -1596,14 +1596,14 @@ _GLOBAL(book3e_secondary_thread_init) | |||
1596 | mflr r28 | 1596 | mflr r28 |
1597 | b 3b | 1597 | b 3b |
1598 | 1598 | ||
1599 | _STATIC(init_core_book3e) | 1599 | init_core_book3e: |
1600 | /* Establish the interrupt vector base */ | 1600 | /* Establish the interrupt vector base */ |
1601 | LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e) | 1601 | LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e) |
1602 | mtspr SPRN_IVPR,r3 | 1602 | mtspr SPRN_IVPR,r3 |
1603 | sync | 1603 | sync |
1604 | blr | 1604 | blr |
1605 | 1605 | ||
1606 | _STATIC(init_thread_book3e) | 1606 | init_thread_book3e: |
1607 | lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h | 1607 | lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h |
1608 | mtspr SPRN_EPCR,r3 | 1608 | mtspr SPRN_EPCR,r3 |
1609 | 1609 | ||
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3afd3915921a..20f11eb4dff7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -132,12 +132,12 @@ BEGIN_FTR_SECTION | |||
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | beq cr1,2f | 134 | beq cr1,2f |
135 | b .power7_wakeup_noloss | 135 | b power7_wakeup_noloss |
136 | 2: b .power7_wakeup_loss | 136 | 2: b power7_wakeup_loss |
137 | 137 | ||
138 | /* Fast Sleep wakeup on PowerNV */ | 138 | /* Fast Sleep wakeup on PowerNV */ |
139 | 8: GET_PACA(r13) | 139 | 8: GET_PACA(r13) |
140 | b .power7_wakeup_tb_loss | 140 | b power7_wakeup_tb_loss |
141 | 141 | ||
142 | 9: | 142 | 9: |
143 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) | 143 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) |
@@ -211,16 +211,16 @@ data_access_slb_pSeries: | |||
211 | #endif /* __DISABLED__ */ | 211 | #endif /* __DISABLED__ */ |
212 | mfspr r12,SPRN_SRR1 | 212 | mfspr r12,SPRN_SRR1 |
213 | #ifndef CONFIG_RELOCATABLE | 213 | #ifndef CONFIG_RELOCATABLE |
214 | b .slb_miss_realmode | 214 | b slb_miss_realmode |
215 | #else | 215 | #else |
216 | /* | 216 | /* |
217 | * We can't just use a direct branch to .slb_miss_realmode | 217 | * We can't just use a direct branch to slb_miss_realmode |
218 | * because the distance from here to there depends on where | 218 | * because the distance from here to there depends on where |
219 | * the kernel ends up being put. | 219 | * the kernel ends up being put. |
220 | */ | 220 | */ |
221 | mfctr r11 | 221 | mfctr r11 |
222 | ld r10,PACAKBASE(r13) | 222 | ld r10,PACAKBASE(r13) |
223 | LOAD_HANDLER(r10, .slb_miss_realmode) | 223 | LOAD_HANDLER(r10, slb_miss_realmode) |
224 | mtctr r10 | 224 | mtctr r10 |
225 | bctr | 225 | bctr |
226 | #endif | 226 | #endif |
@@ -243,11 +243,11 @@ instruction_access_slb_pSeries: | |||
243 | #endif /* __DISABLED__ */ | 243 | #endif /* __DISABLED__ */ |
244 | mfspr r12,SPRN_SRR1 | 244 | mfspr r12,SPRN_SRR1 |
245 | #ifndef CONFIG_RELOCATABLE | 245 | #ifndef CONFIG_RELOCATABLE |
246 | b .slb_miss_realmode | 246 | b slb_miss_realmode |
247 | #else | 247 | #else |
248 | mfctr r11 | 248 | mfctr r11 |
249 | ld r10,PACAKBASE(r13) | 249 | ld r10,PACAKBASE(r13) |
250 | LOAD_HANDLER(r10, .slb_miss_realmode) | 250 | LOAD_HANDLER(r10, slb_miss_realmode) |
251 | mtctr r10 | 251 | mtctr r10 |
252 | bctr | 252 | bctr |
253 | #endif | 253 | #endif |
@@ -524,7 +524,7 @@ do_stab_bolted_pSeries: | |||
524 | std r12,PACA_EXSLB+EX_R12(r13) | 524 | std r12,PACA_EXSLB+EX_R12(r13) |
525 | GET_SCRATCH0(r10) | 525 | GET_SCRATCH0(r10) |
526 | std r10,PACA_EXSLB+EX_R13(r13) | 526 | std r10,PACA_EXSLB+EX_R13(r13) |
527 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) | 527 | EXCEPTION_PROLOG_PSERIES_1(do_stab_bolted, EXC_STD) |
528 | 528 | ||
529 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) | 529 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) |
530 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) | 530 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) |
@@ -769,38 +769,38 @@ kvmppc_skip_Hinterrupt: | |||
769 | 769 | ||
770 | /*** Common interrupt handlers ***/ | 770 | /*** Common interrupt handlers ***/ |
771 | 771 | ||
772 | STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception) | 772 | STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception) |
773 | 773 | ||
774 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) | 774 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) |
775 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) | 775 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt) |
776 | STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt) | 776 | STD_EXCEPTION_COMMON(0x980, hdecrementer, hdec_interrupt) |
777 | #ifdef CONFIG_PPC_DOORBELL | 777 | #ifdef CONFIG_PPC_DOORBELL |
778 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .doorbell_exception) | 778 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, doorbell_exception) |
779 | #else | 779 | #else |
780 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .unknown_exception) | 780 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, unknown_exception) |
781 | #endif | 781 | #endif |
782 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 782 | STD_EXCEPTION_COMMON(0xb00, trap_0b, unknown_exception) |
783 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 783 | STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception) |
784 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 784 | STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception) |
785 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) | 785 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt) |
786 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) | 786 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, unknown_exception) |
787 | #ifdef CONFIG_PPC_DOORBELL | 787 | #ifdef CONFIG_PPC_DOORBELL |
788 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) | 788 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception) |
789 | #else | 789 | #else |
790 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .unknown_exception) | 790 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, unknown_exception) |
791 | #endif | 791 | #endif |
792 | STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception) | 792 | STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, performance_monitor_exception) |
793 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 793 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, instruction_breakpoint_exception) |
794 | STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception) | 794 | STD_EXCEPTION_COMMON(0x1502, denorm, unknown_exception) |
795 | #ifdef CONFIG_ALTIVEC | 795 | #ifdef CONFIG_ALTIVEC |
796 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 796 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, altivec_assist_exception) |
797 | #else | 797 | #else |
798 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception) | 798 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, unknown_exception) |
799 | #endif | 799 | #endif |
800 | #ifdef CONFIG_CBE_RAS | 800 | #ifdef CONFIG_CBE_RAS |
801 | STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception) | 801 | STD_EXCEPTION_COMMON(0x1200, cbe_system_error, cbe_system_error_exception) |
802 | STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception) | 802 | STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, cbe_maintenance_exception) |
803 | STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) | 803 | STD_EXCEPTION_COMMON(0x1800, cbe_thermal, cbe_thermal_exception) |
804 | #endif /* CONFIG_CBE_RAS */ | 804 | #endif /* CONFIG_CBE_RAS */ |
805 | 805 | ||
806 | /* | 806 | /* |
@@ -829,16 +829,16 @@ data_access_slb_relon_pSeries: | |||
829 | mfspr r3,SPRN_DAR | 829 | mfspr r3,SPRN_DAR |
830 | mfspr r12,SPRN_SRR1 | 830 | mfspr r12,SPRN_SRR1 |
831 | #ifndef CONFIG_RELOCATABLE | 831 | #ifndef CONFIG_RELOCATABLE |
832 | b .slb_miss_realmode | 832 | b slb_miss_realmode |
833 | #else | 833 | #else |
834 | /* | 834 | /* |
835 | * We can't just use a direct branch to .slb_miss_realmode | 835 | * We can't just use a direct branch to slb_miss_realmode |
836 | * because the distance from here to there depends on where | 836 | * because the distance from here to there depends on where |
837 | * the kernel ends up being put. | 837 | * the kernel ends up being put. |
838 | */ | 838 | */ |
839 | mfctr r11 | 839 | mfctr r11 |
840 | ld r10,PACAKBASE(r13) | 840 | ld r10,PACAKBASE(r13) |
841 | LOAD_HANDLER(r10, .slb_miss_realmode) | 841 | LOAD_HANDLER(r10, slb_miss_realmode) |
842 | mtctr r10 | 842 | mtctr r10 |
843 | bctr | 843 | bctr |
844 | #endif | 844 | #endif |
@@ -854,11 +854,11 @@ instruction_access_slb_relon_pSeries: | |||
854 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ | 854 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ |
855 | mfspr r12,SPRN_SRR1 | 855 | mfspr r12,SPRN_SRR1 |
856 | #ifndef CONFIG_RELOCATABLE | 856 | #ifndef CONFIG_RELOCATABLE |
857 | b .slb_miss_realmode | 857 | b slb_miss_realmode |
858 | #else | 858 | #else |
859 | mfctr r11 | 859 | mfctr r11 |
860 | ld r10,PACAKBASE(r13) | 860 | ld r10,PACAKBASE(r13) |
861 | LOAD_HANDLER(r10, .slb_miss_realmode) | 861 | LOAD_HANDLER(r10, slb_miss_realmode) |
862 | mtctr r10 | 862 | mtctr r10 |
863 | bctr | 863 | bctr |
864 | #endif | 864 | #endif |
@@ -966,7 +966,7 @@ system_call_entry: | |||
966 | b system_call_common | 966 | b system_call_common |
967 | 967 | ||
968 | ppc64_runlatch_on_trampoline: | 968 | ppc64_runlatch_on_trampoline: |
969 | b .__ppc64_runlatch_on | 969 | b __ppc64_runlatch_on |
970 | 970 | ||
971 | /* | 971 | /* |
972 | * Here we have detected that the kernel stack pointer is bad. | 972 | * Here we have detected that the kernel stack pointer is bad. |
@@ -1025,7 +1025,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) | |||
1025 | std r12,RESULT(r1) | 1025 | std r12,RESULT(r1) |
1026 | std r11,STACK_FRAME_OVERHEAD-16(r1) | 1026 | std r11,STACK_FRAME_OVERHEAD-16(r1) |
1027 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1027 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1028 | bl .kernel_bad_stack | 1028 | bl kernel_bad_stack |
1029 | b 1b | 1029 | b 1b |
1030 | 1030 | ||
1031 | /* | 1031 | /* |
@@ -1046,7 +1046,7 @@ data_access_common: | |||
1046 | ld r3,PACA_EXGEN+EX_DAR(r13) | 1046 | ld r3,PACA_EXGEN+EX_DAR(r13) |
1047 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1047 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1048 | li r5,0x300 | 1048 | li r5,0x300 |
1049 | b .do_hash_page /* Try to handle as hpte fault */ | 1049 | b do_hash_page /* Try to handle as hpte fault */ |
1050 | 1050 | ||
1051 | .align 7 | 1051 | .align 7 |
1052 | .globl h_data_storage_common | 1052 | .globl h_data_storage_common |
@@ -1056,11 +1056,11 @@ h_data_storage_common: | |||
1056 | mfspr r10,SPRN_HDSISR | 1056 | mfspr r10,SPRN_HDSISR |
1057 | stw r10,PACA_EXGEN+EX_DSISR(r13) | 1057 | stw r10,PACA_EXGEN+EX_DSISR(r13) |
1058 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) | 1058 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) |
1059 | bl .save_nvgprs | 1059 | bl save_nvgprs |
1060 | DISABLE_INTS | 1060 | DISABLE_INTS |
1061 | addi r3,r1,STACK_FRAME_OVERHEAD | 1061 | addi r3,r1,STACK_FRAME_OVERHEAD |
1062 | bl .unknown_exception | 1062 | bl unknown_exception |
1063 | b .ret_from_except | 1063 | b ret_from_except |
1064 | 1064 | ||
1065 | .align 7 | 1065 | .align 7 |
1066 | .globl instruction_access_common | 1066 | .globl instruction_access_common |
@@ -1071,9 +1071,9 @@ instruction_access_common: | |||
1071 | ld r3,_NIP(r1) | 1071 | ld r3,_NIP(r1) |
1072 | andis. r4,r12,0x5820 | 1072 | andis. r4,r12,0x5820 |
1073 | li r5,0x400 | 1073 | li r5,0x400 |
1074 | b .do_hash_page /* Try to handle as hpte fault */ | 1074 | b do_hash_page /* Try to handle as hpte fault */ |
1075 | 1075 | ||
1076 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception) | 1076 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, unknown_exception) |
1077 | 1077 | ||
1078 | /* | 1078 | /* |
1079 | * Here is the common SLB miss user that is used when going to virtual | 1079 | * Here is the common SLB miss user that is used when going to virtual |
@@ -1088,7 +1088,7 @@ slb_miss_user_common: | |||
1088 | stw r9,PACA_EXGEN+EX_CCR(r13) | 1088 | stw r9,PACA_EXGEN+EX_CCR(r13) |
1089 | std r10,PACA_EXGEN+EX_LR(r13) | 1089 | std r10,PACA_EXGEN+EX_LR(r13) |
1090 | std r11,PACA_EXGEN+EX_SRR0(r13) | 1090 | std r11,PACA_EXGEN+EX_SRR0(r13) |
1091 | bl .slb_allocate_user | 1091 | bl slb_allocate_user |
1092 | 1092 | ||
1093 | ld r10,PACA_EXGEN+EX_LR(r13) | 1093 | ld r10,PACA_EXGEN+EX_LR(r13) |
1094 | ld r3,PACA_EXGEN+EX_R3(r13) | 1094 | ld r3,PACA_EXGEN+EX_R3(r13) |
@@ -1131,9 +1131,9 @@ slb_miss_fault: | |||
1131 | unrecov_user_slb: | 1131 | unrecov_user_slb: |
1132 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) | 1132 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) |
1133 | DISABLE_INTS | 1133 | DISABLE_INTS |
1134 | bl .save_nvgprs | 1134 | bl save_nvgprs |
1135 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1135 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1136 | bl .unrecoverable_exception | 1136 | bl unrecoverable_exception |
1137 | b 1b | 1137 | b 1b |
1138 | 1138 | ||
1139 | #endif /* __DISABLED__ */ | 1139 | #endif /* __DISABLED__ */ |
@@ -1158,10 +1158,10 @@ machine_check_common: | |||
1158 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1158 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1159 | std r3,_DAR(r1) | 1159 | std r3,_DAR(r1) |
1160 | std r4,_DSISR(r1) | 1160 | std r4,_DSISR(r1) |
1161 | bl .save_nvgprs | 1161 | bl save_nvgprs |
1162 | addi r3,r1,STACK_FRAME_OVERHEAD | 1162 | addi r3,r1,STACK_FRAME_OVERHEAD |
1163 | bl .machine_check_exception | 1163 | bl machine_check_exception |
1164 | b .ret_from_except | 1164 | b ret_from_except |
1165 | 1165 | ||
1166 | .align 7 | 1166 | .align 7 |
1167 | .globl alignment_common | 1167 | .globl alignment_common |
@@ -1175,31 +1175,31 @@ alignment_common: | |||
1175 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1175 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1176 | std r3,_DAR(r1) | 1176 | std r3,_DAR(r1) |
1177 | std r4,_DSISR(r1) | 1177 | std r4,_DSISR(r1) |
1178 | bl .save_nvgprs | 1178 | bl save_nvgprs |
1179 | DISABLE_INTS | 1179 | DISABLE_INTS |
1180 | addi r3,r1,STACK_FRAME_OVERHEAD | 1180 | addi r3,r1,STACK_FRAME_OVERHEAD |
1181 | bl .alignment_exception | 1181 | bl alignment_exception |
1182 | b .ret_from_except | 1182 | b ret_from_except |
1183 | 1183 | ||
1184 | .align 7 | 1184 | .align 7 |
1185 | .globl program_check_common | 1185 | .globl program_check_common |
1186 | program_check_common: | 1186 | program_check_common: |
1187 | EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) | 1187 | EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) |
1188 | bl .save_nvgprs | 1188 | bl save_nvgprs |
1189 | DISABLE_INTS | 1189 | DISABLE_INTS |
1190 | addi r3,r1,STACK_FRAME_OVERHEAD | 1190 | addi r3,r1,STACK_FRAME_OVERHEAD |
1191 | bl .program_check_exception | 1191 | bl program_check_exception |
1192 | b .ret_from_except | 1192 | b ret_from_except |
1193 | 1193 | ||
1194 | .align 7 | 1194 | .align 7 |
1195 | .globl fp_unavailable_common | 1195 | .globl fp_unavailable_common |
1196 | fp_unavailable_common: | 1196 | fp_unavailable_common: |
1197 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) | 1197 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) |
1198 | bne 1f /* if from user, just load it up */ | 1198 | bne 1f /* if from user, just load it up */ |
1199 | bl .save_nvgprs | 1199 | bl save_nvgprs |
1200 | DISABLE_INTS | 1200 | DISABLE_INTS |
1201 | addi r3,r1,STACK_FRAME_OVERHEAD | 1201 | addi r3,r1,STACK_FRAME_OVERHEAD |
1202 | bl .kernel_fp_unavailable_exception | 1202 | bl kernel_fp_unavailable_exception |
1203 | BUG_OPCODE | 1203 | BUG_OPCODE |
1204 | 1: | 1204 | 1: |
1205 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1205 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
@@ -1211,15 +1211,15 @@ BEGIN_FTR_SECTION | |||
1211 | bne- 2f | 1211 | bne- 2f |
1212 | END_FTR_SECTION_IFSET(CPU_FTR_TM) | 1212 | END_FTR_SECTION_IFSET(CPU_FTR_TM) |
1213 | #endif | 1213 | #endif |
1214 | bl .load_up_fpu | 1214 | bl load_up_fpu |
1215 | b fast_exception_return | 1215 | b fast_exception_return |
1216 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1216 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1217 | 2: /* User process was in a transaction */ | 1217 | 2: /* User process was in a transaction */ |
1218 | bl .save_nvgprs | 1218 | bl save_nvgprs |
1219 | DISABLE_INTS | 1219 | DISABLE_INTS |
1220 | addi r3,r1,STACK_FRAME_OVERHEAD | 1220 | addi r3,r1,STACK_FRAME_OVERHEAD |
1221 | bl .fp_unavailable_tm | 1221 | bl fp_unavailable_tm |
1222 | b .ret_from_except | 1222 | b ret_from_except |
1223 | #endif | 1223 | #endif |
1224 | .align 7 | 1224 | .align 7 |
1225 | .globl altivec_unavailable_common | 1225 | .globl altivec_unavailable_common |
@@ -1237,24 +1237,24 @@ BEGIN_FTR_SECTION | |||
1237 | bne- 2f | 1237 | bne- 2f |
1238 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) | 1238 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) |
1239 | #endif | 1239 | #endif |
1240 | bl .load_up_altivec | 1240 | bl load_up_altivec |
1241 | b fast_exception_return | 1241 | b fast_exception_return |
1242 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1242 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1243 | 2: /* User process was in a transaction */ | 1243 | 2: /* User process was in a transaction */ |
1244 | bl .save_nvgprs | 1244 | bl save_nvgprs |
1245 | DISABLE_INTS | 1245 | DISABLE_INTS |
1246 | addi r3,r1,STACK_FRAME_OVERHEAD | 1246 | addi r3,r1,STACK_FRAME_OVERHEAD |
1247 | bl .altivec_unavailable_tm | 1247 | bl altivec_unavailable_tm |
1248 | b .ret_from_except | 1248 | b ret_from_except |
1249 | #endif | 1249 | #endif |
1250 | 1: | 1250 | 1: |
1251 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 1251 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
1252 | #endif | 1252 | #endif |
1253 | bl .save_nvgprs | 1253 | bl save_nvgprs |
1254 | DISABLE_INTS | 1254 | DISABLE_INTS |
1255 | addi r3,r1,STACK_FRAME_OVERHEAD | 1255 | addi r3,r1,STACK_FRAME_OVERHEAD |
1256 | bl .altivec_unavailable_exception | 1256 | bl altivec_unavailable_exception |
1257 | b .ret_from_except | 1257 | b ret_from_except |
1258 | 1258 | ||
1259 | .align 7 | 1259 | .align 7 |
1260 | .globl vsx_unavailable_common | 1260 | .globl vsx_unavailable_common |
@@ -1272,26 +1272,26 @@ BEGIN_FTR_SECTION | |||
1272 | bne- 2f | 1272 | bne- 2f |
1273 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) | 1273 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) |
1274 | #endif | 1274 | #endif |
1275 | b .load_up_vsx | 1275 | b load_up_vsx |
1276 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1276 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1277 | 2: /* User process was in a transaction */ | 1277 | 2: /* User process was in a transaction */ |
1278 | bl .save_nvgprs | 1278 | bl save_nvgprs |
1279 | DISABLE_INTS | 1279 | DISABLE_INTS |
1280 | addi r3,r1,STACK_FRAME_OVERHEAD | 1280 | addi r3,r1,STACK_FRAME_OVERHEAD |
1281 | bl .vsx_unavailable_tm | 1281 | bl vsx_unavailable_tm |
1282 | b .ret_from_except | 1282 | b ret_from_except |
1283 | #endif | 1283 | #endif |
1284 | 1: | 1284 | 1: |
1285 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) | 1285 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) |
1286 | #endif | 1286 | #endif |
1287 | bl .save_nvgprs | 1287 | bl save_nvgprs |
1288 | DISABLE_INTS | 1288 | DISABLE_INTS |
1289 | addi r3,r1,STACK_FRAME_OVERHEAD | 1289 | addi r3,r1,STACK_FRAME_OVERHEAD |
1290 | bl .vsx_unavailable_exception | 1290 | bl vsx_unavailable_exception |
1291 | b .ret_from_except | 1291 | b ret_from_except |
1292 | 1292 | ||
1293 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception) | 1293 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, facility_unavailable_exception) |
1294 | STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, .facility_unavailable_exception) | 1294 | STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, facility_unavailable_exception) |
1295 | 1295 | ||
1296 | .align 7 | 1296 | .align 7 |
1297 | .globl __end_handlers | 1297 | .globl __end_handlers |
@@ -1386,9 +1386,9 @@ _GLOBAL(opal_mc_secondary_handler) | |||
1386 | machine_check_handle_early: | 1386 | machine_check_handle_early: |
1387 | std r0,GPR0(r1) /* Save r0 */ | 1387 | std r0,GPR0(r1) /* Save r0 */ |
1388 | EXCEPTION_PROLOG_COMMON_3(0x200) | 1388 | EXCEPTION_PROLOG_COMMON_3(0x200) |
1389 | bl .save_nvgprs | 1389 | bl save_nvgprs |
1390 | addi r3,r1,STACK_FRAME_OVERHEAD | 1390 | addi r3,r1,STACK_FRAME_OVERHEAD |
1391 | bl .machine_check_early | 1391 | bl machine_check_early |
1392 | ld r12,_MSR(r1) | 1392 | ld r12,_MSR(r1) |
1393 | #ifdef CONFIG_PPC_P7_NAP | 1393 | #ifdef CONFIG_PPC_P7_NAP |
1394 | /* | 1394 | /* |
@@ -1408,11 +1408,11 @@ machine_check_handle_early: | |||
1408 | /* Supervisor state loss */ | 1408 | /* Supervisor state loss */ |
1409 | li r0,1 | 1409 | li r0,1 |
1410 | stb r0,PACA_NAPSTATELOST(r13) | 1410 | stb r0,PACA_NAPSTATELOST(r13) |
1411 | 3: bl .machine_check_queue_event | 1411 | 3: bl machine_check_queue_event |
1412 | MACHINE_CHECK_HANDLER_WINDUP | 1412 | MACHINE_CHECK_HANDLER_WINDUP |
1413 | GET_PACA(r13) | 1413 | GET_PACA(r13) |
1414 | ld r1,PACAR1(r13) | 1414 | ld r1,PACAR1(r13) |
1415 | b .power7_enter_nap_mode | 1415 | b power7_enter_nap_mode |
1416 | 4: | 1416 | 4: |
1417 | #endif | 1417 | #endif |
1418 | /* | 1418 | /* |
@@ -1444,7 +1444,7 @@ machine_check_handle_early: | |||
1444 | andi. r11,r12,MSR_RI | 1444 | andi. r11,r12,MSR_RI |
1445 | bne 2f | 1445 | bne 2f |
1446 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1446 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1447 | bl .unrecoverable_exception | 1447 | bl unrecoverable_exception |
1448 | b 1b | 1448 | b 1b |
1449 | 2: | 1449 | 2: |
1450 | /* | 1450 | /* |
@@ -1452,7 +1452,7 @@ machine_check_handle_early: | |||
1452 | * Queue up the MCE event so that we can log it later, while | 1452 | * Queue up the MCE event so that we can log it later, while |
1453 | * returning from kernel or opal call. | 1453 | * returning from kernel or opal call. |
1454 | */ | 1454 | */ |
1455 | bl .machine_check_queue_event | 1455 | bl machine_check_queue_event |
1456 | MACHINE_CHECK_HANDLER_WINDUP | 1456 | MACHINE_CHECK_HANDLER_WINDUP |
1457 | rfid | 1457 | rfid |
1458 | 9: | 1458 | 9: |
@@ -1468,7 +1468,7 @@ machine_check_handle_early: | |||
1468 | * r3 is saved in paca->slb_r3 | 1468 | * r3 is saved in paca->slb_r3 |
1469 | * We assume we aren't going to take any exceptions during this procedure. | 1469 | * We assume we aren't going to take any exceptions during this procedure. |
1470 | */ | 1470 | */ |
1471 | _GLOBAL(slb_miss_realmode) | 1471 | slb_miss_realmode: |
1472 | mflr r10 | 1472 | mflr r10 |
1473 | #ifdef CONFIG_RELOCATABLE | 1473 | #ifdef CONFIG_RELOCATABLE |
1474 | mtctr r11 | 1474 | mtctr r11 |
@@ -1477,7 +1477,7 @@ _GLOBAL(slb_miss_realmode) | |||
1477 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 1477 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
1478 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | 1478 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ |
1479 | 1479 | ||
1480 | bl .slb_allocate_realmode | 1480 | bl slb_allocate_realmode |
1481 | 1481 | ||
1482 | /* All done -- return from exception. */ | 1482 | /* All done -- return from exception. */ |
1483 | 1483 | ||
@@ -1517,9 +1517,9 @@ _GLOBAL(slb_miss_realmode) | |||
1517 | unrecov_slb: | 1517 | unrecov_slb: |
1518 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) | 1518 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) |
1519 | DISABLE_INTS | 1519 | DISABLE_INTS |
1520 | bl .save_nvgprs | 1520 | bl save_nvgprs |
1521 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1521 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1522 | bl .unrecoverable_exception | 1522 | bl unrecoverable_exception |
1523 | b 1b | 1523 | b 1b |
1524 | 1524 | ||
1525 | 1525 | ||
@@ -1536,7 +1536,7 @@ power4_fixup_nap: | |||
1536 | * Hash table stuff | 1536 | * Hash table stuff |
1537 | */ | 1537 | */ |
1538 | .align 7 | 1538 | .align 7 |
1539 | _STATIC(do_hash_page) | 1539 | do_hash_page: |
1540 | std r3,_DAR(r1) | 1540 | std r3,_DAR(r1) |
1541 | std r4,_DSISR(r1) | 1541 | std r4,_DSISR(r1) |
1542 | 1542 | ||
@@ -1573,7 +1573,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) | |||
1573 | * | 1573 | * |
1574 | * at return r3 = 0 for success, 1 for page fault, negative for error | 1574 | * at return r3 = 0 for success, 1 for page fault, negative for error |
1575 | */ | 1575 | */ |
1576 | bl .hash_page /* build HPTE if possible */ | 1576 | bl hash_page /* build HPTE if possible */ |
1577 | cmpdi r3,0 /* see if hash_page succeeded */ | 1577 | cmpdi r3,0 /* see if hash_page succeeded */ |
1578 | 1578 | ||
1579 | /* Success */ | 1579 | /* Success */ |
@@ -1587,35 +1587,35 @@ handle_page_fault: | |||
1587 | 11: ld r4,_DAR(r1) | 1587 | 11: ld r4,_DAR(r1) |
1588 | ld r5,_DSISR(r1) | 1588 | ld r5,_DSISR(r1) |
1589 | addi r3,r1,STACK_FRAME_OVERHEAD | 1589 | addi r3,r1,STACK_FRAME_OVERHEAD |
1590 | bl .do_page_fault | 1590 | bl do_page_fault |
1591 | cmpdi r3,0 | 1591 | cmpdi r3,0 |
1592 | beq+ 12f | 1592 | beq+ 12f |
1593 | bl .save_nvgprs | 1593 | bl save_nvgprs |
1594 | mr r5,r3 | 1594 | mr r5,r3 |
1595 | addi r3,r1,STACK_FRAME_OVERHEAD | 1595 | addi r3,r1,STACK_FRAME_OVERHEAD |
1596 | lwz r4,_DAR(r1) | 1596 | lwz r4,_DAR(r1) |
1597 | bl .bad_page_fault | 1597 | bl bad_page_fault |
1598 | b .ret_from_except | 1598 | b ret_from_except |
1599 | 1599 | ||
1600 | /* We have a data breakpoint exception - handle it */ | 1600 | /* We have a data breakpoint exception - handle it */ |
1601 | handle_dabr_fault: | 1601 | handle_dabr_fault: |
1602 | bl .save_nvgprs | 1602 | bl save_nvgprs |
1603 | ld r4,_DAR(r1) | 1603 | ld r4,_DAR(r1) |
1604 | ld r5,_DSISR(r1) | 1604 | ld r5,_DSISR(r1) |
1605 | addi r3,r1,STACK_FRAME_OVERHEAD | 1605 | addi r3,r1,STACK_FRAME_OVERHEAD |
1606 | bl .do_break | 1606 | bl do_break |
1607 | 12: b .ret_from_except_lite | 1607 | 12: b ret_from_except_lite |
1608 | 1608 | ||
1609 | 1609 | ||
1610 | /* We have a page fault that hash_page could handle but HV refused | 1610 | /* We have a page fault that hash_page could handle but HV refused |
1611 | * the PTE insertion | 1611 | * the PTE insertion |
1612 | */ | 1612 | */ |
1613 | 13: bl .save_nvgprs | 1613 | 13: bl save_nvgprs |
1614 | mr r5,r3 | 1614 | mr r5,r3 |
1615 | addi r3,r1,STACK_FRAME_OVERHEAD | 1615 | addi r3,r1,STACK_FRAME_OVERHEAD |
1616 | ld r4,_DAR(r1) | 1616 | ld r4,_DAR(r1) |
1617 | bl .low_hash_fault | 1617 | bl low_hash_fault |
1618 | b .ret_from_except | 1618 | b ret_from_except |
1619 | 1619 | ||
1620 | /* | 1620 | /* |
1621 | * We come here as a result of a DSI at a point where we don't want | 1621 | * We come here as a result of a DSI at a point where we don't want |
@@ -1624,16 +1624,16 @@ handle_dabr_fault: | |||
1624 | * were soft-disabled. We want to invoke the exception handler for | 1624 | * were soft-disabled. We want to invoke the exception handler for |
1625 | * the access, or panic if there isn't a handler. | 1625 | * the access, or panic if there isn't a handler. |
1626 | */ | 1626 | */ |
1627 | 77: bl .save_nvgprs | 1627 | 77: bl save_nvgprs |
1628 | mr r4,r3 | 1628 | mr r4,r3 |
1629 | addi r3,r1,STACK_FRAME_OVERHEAD | 1629 | addi r3,r1,STACK_FRAME_OVERHEAD |
1630 | li r5,SIGSEGV | 1630 | li r5,SIGSEGV |
1631 | bl .bad_page_fault | 1631 | bl bad_page_fault |
1632 | b .ret_from_except | 1632 | b ret_from_except |
1633 | 1633 | ||
1634 | /* here we have a segment miss */ | 1634 | /* here we have a segment miss */ |
1635 | do_ste_alloc: | 1635 | do_ste_alloc: |
1636 | bl .ste_allocate /* try to insert stab entry */ | 1636 | bl ste_allocate /* try to insert stab entry */ |
1637 | cmpdi r3,0 | 1637 | cmpdi r3,0 |
1638 | bne- handle_page_fault | 1638 | bne- handle_page_fault |
1639 | b fast_exception_return | 1639 | b fast_exception_return |
@@ -1646,7 +1646,7 @@ do_ste_alloc: | |||
1646 | * We assume (DAR >> 60) == 0xc. | 1646 | * We assume (DAR >> 60) == 0xc. |
1647 | */ | 1647 | */ |
1648 | .align 7 | 1648 | .align 7 |
1649 | _GLOBAL(do_stab_bolted) | 1649 | do_stab_bolted: |
1650 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 1650 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
1651 | std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ | 1651 | std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ |
1652 | mfspr r11,SPRN_DAR /* ea */ | 1652 | mfspr r11,SPRN_DAR /* ea */ |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 6a014c763cc7..f202d0731b06 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -105,11 +105,9 @@ __ftrace_make_nop(struct module *mod, | |||
105 | struct dyn_ftrace *rec, unsigned long addr) | 105 | struct dyn_ftrace *rec, unsigned long addr) |
106 | { | 106 | { |
107 | unsigned int op; | 107 | unsigned int op; |
108 | unsigned int jmp[5]; | ||
109 | unsigned long ptr; | 108 | unsigned long ptr; |
110 | unsigned long ip = rec->ip; | 109 | unsigned long ip = rec->ip; |
111 | unsigned long tramp; | 110 | void *tramp; |
112 | int offset; | ||
113 | 111 | ||
114 | /* read where this goes */ | 112 | /* read where this goes */ |
115 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) | 113 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) |
@@ -122,96 +120,41 @@ __ftrace_make_nop(struct module *mod, | |||
122 | } | 120 | } |
123 | 121 | ||
124 | /* lets find where the pointer goes */ | 122 | /* lets find where the pointer goes */ |
125 | tramp = find_bl_target(ip, op); | 123 | tramp = (void *)find_bl_target(ip, op); |
126 | |||
127 | /* | ||
128 | * On PPC64 the trampoline looks like: | ||
129 | * 0x3d, 0x82, 0x00, 0x00, addis r12,r2, <high> | ||
130 | * 0x39, 0x8c, 0x00, 0x00, addi r12,r12, <low> | ||
131 | * Where the bytes 2,3,6 and 7 make up the 32bit offset | ||
132 | * to the TOC that holds the pointer. | ||
133 | * to jump to. | ||
134 | * 0xf8, 0x41, 0x00, 0x28, std r2,40(r1) | ||
135 | * 0xe9, 0x6c, 0x00, 0x20, ld r11,32(r12) | ||
136 | * The actually address is 32 bytes from the offset | ||
137 | * into the TOC. | ||
138 | * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) | ||
139 | */ | ||
140 | |||
141 | pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); | ||
142 | |||
143 | /* Find where the trampoline jumps to */ | ||
144 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { | ||
145 | printk(KERN_ERR "Failed to read %lx\n", tramp); | ||
146 | return -EFAULT; | ||
147 | } | ||
148 | 124 | ||
149 | pr_devel(" %08x %08x", jmp[0], jmp[1]); | 125 | pr_devel("ip:%lx jumps to %p", ip, tramp); |
150 | 126 | ||
151 | /* verify that this is what we expect it to be */ | 127 | if (!is_module_trampoline(tramp)) { |
152 | if (((jmp[0] & 0xffff0000) != 0x3d820000) || | ||
153 | ((jmp[1] & 0xffff0000) != 0x398c0000) || | ||
154 | (jmp[2] != 0xf8410028) || | ||
155 | (jmp[3] != 0xe96c0020) || | ||
156 | (jmp[4] != 0xe84c0028)) { | ||
157 | printk(KERN_ERR "Not a trampoline\n"); | 128 | printk(KERN_ERR "Not a trampoline\n"); |
158 | return -EINVAL; | 129 | return -EINVAL; |
159 | } | 130 | } |
160 | 131 | ||
161 | /* The bottom half is signed extended */ | 132 | if (module_trampoline_target(mod, tramp, &ptr)) { |
162 | offset = ((unsigned)((unsigned short)jmp[0]) << 16) + | 133 | printk(KERN_ERR "Failed to get trampoline target\n"); |
163 | (int)((short)jmp[1]); | ||
164 | |||
165 | pr_devel(" %x ", offset); | ||
166 | |||
167 | /* get the address this jumps too */ | ||
168 | tramp = mod->arch.toc + offset + 32; | ||
169 | pr_devel("toc: %lx", tramp); | ||
170 | |||
171 | if (probe_kernel_read(jmp, (void *)tramp, 8)) { | ||
172 | printk(KERN_ERR "Failed to read %lx\n", tramp); | ||
173 | return -EFAULT; | 134 | return -EFAULT; |
174 | } | 135 | } |
175 | 136 | ||
176 | pr_devel(" %08x %08x\n", jmp[0], jmp[1]); | 137 | pr_devel("trampoline target %lx", ptr); |
177 | |||
178 | #ifdef __LITTLE_ENDIAN__ | ||
179 | ptr = ((unsigned long)jmp[1] << 32) + jmp[0]; | ||
180 | #else | ||
181 | ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; | ||
182 | #endif | ||
183 | 138 | ||
184 | /* This should match what was called */ | 139 | /* This should match what was called */ |
185 | if (ptr != ppc_function_entry((void *)addr)) { | 140 | if (ptr != ppc_function_entry((void *)addr)) { |
186 | printk(KERN_ERR "addr does not match %lx\n", ptr); | 141 | printk(KERN_ERR "addr %lx does not match expected %lx\n", |
142 | ptr, ppc_function_entry((void *)addr)); | ||
187 | return -EINVAL; | 143 | return -EINVAL; |
188 | } | 144 | } |
189 | 145 | ||
190 | /* | 146 | /* |
191 | * We want to nop the line, but the next line is | 147 | * Our original call site looks like: |
192 | * 0xe8, 0x41, 0x00, 0x28 ld r2,40(r1) | 148 | * |
193 | * This needs to be turned to a nop too. | 149 | * bl <tramp> |
194 | */ | 150 | * ld r2,XX(r1) |
195 | if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) | 151 | * |
196 | return -EFAULT; | 152 | * Milton Miller pointed out that we can not simply nop the branch. |
197 | 153 | * If a task was preempted when calling a trace function, the nops | |
198 | if (op != 0xe8410028) { | 154 | * will remove the way to restore the TOC in r2 and the r2 TOC will |
199 | printk(KERN_ERR "Next line is not ld! (%08x)\n", op); | 155 | * get corrupted. |
200 | return -EINVAL; | 156 | * |
201 | } | 157 | * Use a b +8 to jump over the load. |
202 | |||
203 | /* | ||
204 | * Milton Miller pointed out that we can not blindly do nops. | ||
205 | * If a task was preempted when calling a trace function, | ||
206 | * the nops will remove the way to restore the TOC in r2 | ||
207 | * and the r2 TOC will get corrupted. | ||
208 | */ | ||
209 | |||
210 | /* | ||
211 | * Replace: | ||
212 | * bl <tramp> <==== will be replaced with "b 1f" | ||
213 | * ld r2,40(r1) | ||
214 | * 1: | ||
215 | */ | 158 | */ |
216 | op = 0x48000008; /* b +8 */ | 159 | op = 0x48000008; /* b +8 */ |
217 | 160 | ||
@@ -349,19 +292,24 @@ static int | |||
349 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 292 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
350 | { | 293 | { |
351 | unsigned int op[2]; | 294 | unsigned int op[2]; |
352 | unsigned long ip = rec->ip; | 295 | void *ip = (void *)rec->ip; |
353 | 296 | ||
354 | /* read where this goes */ | 297 | /* read where this goes */ |
355 | if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2)) | 298 | if (probe_kernel_read(op, ip, sizeof(op))) |
356 | return -EFAULT; | 299 | return -EFAULT; |
357 | 300 | ||
358 | /* | 301 | /* |
359 | * It should be pointing to two nops or | 302 | * We expect to see: |
360 | * b +8; ld r2,40(r1) | 303 | * |
304 | * b +8 | ||
305 | * ld r2,XX(r1) | ||
306 | * | ||
307 | * The load offset is different depending on the ABI. For simplicity | ||
308 | * just mask it out when doing the compare. | ||
361 | */ | 309 | */ |
362 | if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && | 310 | if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) { |
363 | ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) { | 311 | printk(KERN_ERR "Unexpected call sequence: %x %x\n", |
364 | printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); | 312 | op[0], op[1]); |
365 | return -EINVAL; | 313 | return -EINVAL; |
366 | } | 314 | } |
367 | 315 | ||
@@ -371,23 +319,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
371 | return -EINVAL; | 319 | return -EINVAL; |
372 | } | 320 | } |
373 | 321 | ||
374 | /* create the branch to the trampoline */ | 322 | /* Ensure branch is within 24 bits */ |
375 | op[0] = create_branch((unsigned int *)ip, | 323 | if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) { |
376 | rec->arch.mod->arch.tramp, BRANCH_SET_LINK); | 324 | printk(KERN_ERR "Branch out of range"); |
377 | if (!op[0]) { | ||
378 | printk(KERN_ERR "REL24 out of range!\n"); | ||
379 | return -EINVAL; | 325 | return -EINVAL; |
380 | } | 326 | } |
381 | 327 | ||
382 | /* ld r2,40(r1) */ | 328 | if (patch_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) { |
383 | op[1] = 0xe8410028; | 329 | printk(KERN_ERR "REL24 out of range!\n"); |
384 | 330 | return -EINVAL; | |
385 | pr_devel("write to %lx\n", rec->ip); | 331 | } |
386 | |||
387 | if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) | ||
388 | return -EPERM; | ||
389 | |||
390 | flush_icache_range(ip, ip + 8); | ||
391 | 332 | ||
392 | return 0; | 333 | return 0; |
393 | } | 334 | } |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index b7363bd42452..a95145d7f61b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -70,16 +70,15 @@ _GLOBAL(__start) | |||
70 | /* NOP this out unconditionally */ | 70 | /* NOP this out unconditionally */ |
71 | BEGIN_FTR_SECTION | 71 | BEGIN_FTR_SECTION |
72 | FIXUP_ENDIAN | 72 | FIXUP_ENDIAN |
73 | b .__start_initialization_multiplatform | 73 | b __start_initialization_multiplatform |
74 | END_FTR_SECTION(0, 1) | 74 | END_FTR_SECTION(0, 1) |
75 | 75 | ||
76 | /* Catch branch to 0 in real mode */ | 76 | /* Catch branch to 0 in real mode */ |
77 | trap | 77 | trap |
78 | 78 | ||
79 | /* Secondary processors spin on this value until it becomes nonzero. | 79 | /* Secondary processors spin on this value until it becomes non-zero. |
80 | * When it does it contains the real address of the descriptor | 80 | * When non-zero, it contains the real address of the function the cpu |
81 | * of the function that the cpu should jump to to continue | 81 | * should jump to. |
82 | * initialization. | ||
83 | */ | 82 | */ |
84 | .balign 8 | 83 | .balign 8 |
85 | .globl __secondary_hold_spinloop | 84 | .globl __secondary_hold_spinloop |
@@ -140,16 +139,15 @@ __secondary_hold: | |||
140 | tovirt(r26,r26) | 139 | tovirt(r26,r26) |
141 | #endif | 140 | #endif |
142 | /* All secondary cpus wait here until told to start. */ | 141 | /* All secondary cpus wait here until told to start. */ |
143 | 100: ld r4,__secondary_hold_spinloop-_stext(r26) | 142 | 100: ld r12,__secondary_hold_spinloop-_stext(r26) |
144 | cmpdi 0,r4,0 | 143 | cmpdi 0,r12,0 |
145 | beq 100b | 144 | beq 100b |
146 | 145 | ||
147 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) | 146 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) |
148 | #ifdef CONFIG_PPC_BOOK3E | 147 | #ifdef CONFIG_PPC_BOOK3E |
149 | tovirt(r4,r4) | 148 | tovirt(r12,r12) |
150 | #endif | 149 | #endif |
151 | ld r4,0(r4) /* deref function descriptor */ | 150 | mtctr r12 |
152 | mtctr r4 | ||
153 | mr r3,r24 | 151 | mr r3,r24 |
154 | /* | 152 | /* |
155 | * it may be the case that other platforms have r4 right to | 153 | * it may be the case that other platforms have r4 right to |
@@ -186,16 +184,16 @@ _GLOBAL(generic_secondary_thread_init) | |||
186 | mr r24,r3 | 184 | mr r24,r3 |
187 | 185 | ||
188 | /* turn on 64-bit mode */ | 186 | /* turn on 64-bit mode */ |
189 | bl .enable_64b_mode | 187 | bl enable_64b_mode |
190 | 188 | ||
191 | /* get a valid TOC pointer, wherever we're mapped at */ | 189 | /* get a valid TOC pointer, wherever we're mapped at */ |
192 | bl .relative_toc | 190 | bl relative_toc |
193 | tovirt(r2,r2) | 191 | tovirt(r2,r2) |
194 | 192 | ||
195 | #ifdef CONFIG_PPC_BOOK3E | 193 | #ifdef CONFIG_PPC_BOOK3E |
196 | /* Book3E initialization */ | 194 | /* Book3E initialization */ |
197 | mr r3,r24 | 195 | mr r3,r24 |
198 | bl .book3e_secondary_thread_init | 196 | bl book3e_secondary_thread_init |
199 | #endif | 197 | #endif |
200 | b generic_secondary_common_init | 198 | b generic_secondary_common_init |
201 | 199 | ||
@@ -214,17 +212,17 @@ _GLOBAL(generic_secondary_smp_init) | |||
214 | mr r25,r4 | 212 | mr r25,r4 |
215 | 213 | ||
216 | /* turn on 64-bit mode */ | 214 | /* turn on 64-bit mode */ |
217 | bl .enable_64b_mode | 215 | bl enable_64b_mode |
218 | 216 | ||
219 | /* get a valid TOC pointer, wherever we're mapped at */ | 217 | /* get a valid TOC pointer, wherever we're mapped at */ |
220 | bl .relative_toc | 218 | bl relative_toc |
221 | tovirt(r2,r2) | 219 | tovirt(r2,r2) |
222 | 220 | ||
223 | #ifdef CONFIG_PPC_BOOK3E | 221 | #ifdef CONFIG_PPC_BOOK3E |
224 | /* Book3E initialization */ | 222 | /* Book3E initialization */ |
225 | mr r3,r24 | 223 | mr r3,r24 |
226 | mr r4,r25 | 224 | mr r4,r25 |
227 | bl .book3e_secondary_core_init | 225 | bl book3e_secondary_core_init |
228 | #endif | 226 | #endif |
229 | 227 | ||
230 | generic_secondary_common_init: | 228 | generic_secondary_common_init: |
@@ -236,7 +234,7 @@ generic_secondary_common_init: | |||
236 | ld r13,0(r13) /* Get base vaddr of paca array */ | 234 | ld r13,0(r13) /* Get base vaddr of paca array */ |
237 | #ifndef CONFIG_SMP | 235 | #ifndef CONFIG_SMP |
238 | addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ | 236 | addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ |
239 | b .kexec_wait /* wait for next kernel if !SMP */ | 237 | b kexec_wait /* wait for next kernel if !SMP */ |
240 | #else | 238 | #else |
241 | LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ | 239 | LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ |
242 | lwz r7,0(r7) /* also the max paca allocated */ | 240 | lwz r7,0(r7) /* also the max paca allocated */ |
@@ -250,7 +248,7 @@ generic_secondary_common_init: | |||
250 | blt 1b | 248 | blt 1b |
251 | 249 | ||
252 | mr r3,r24 /* not found, copy phys to r3 */ | 250 | mr r3,r24 /* not found, copy phys to r3 */ |
253 | b .kexec_wait /* next kernel might do better */ | 251 | b kexec_wait /* next kernel might do better */ |
254 | 252 | ||
255 | 2: SET_PACA(r13) | 253 | 2: SET_PACA(r13) |
256 | #ifdef CONFIG_PPC_BOOK3E | 254 | #ifdef CONFIG_PPC_BOOK3E |
@@ -264,11 +262,13 @@ generic_secondary_common_init: | |||
264 | /* See if we need to call a cpu state restore handler */ | 262 | /* See if we need to call a cpu state restore handler */ |
265 | LOAD_REG_ADDR(r23, cur_cpu_spec) | 263 | LOAD_REG_ADDR(r23, cur_cpu_spec) |
266 | ld r23,0(r23) | 264 | ld r23,0(r23) |
267 | ld r23,CPU_SPEC_RESTORE(r23) | 265 | ld r12,CPU_SPEC_RESTORE(r23) |
268 | cmpdi 0,r23,0 | 266 | cmpdi 0,r12,0 |
269 | beq 3f | 267 | beq 3f |
270 | ld r23,0(r23) | 268 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
271 | mtctr r23 | 269 | ld r12,0(r12) |
270 | #endif | ||
271 | mtctr r12 | ||
272 | bctrl | 272 | bctrl |
273 | 273 | ||
274 | 3: LOAD_REG_ADDR(r3, spinning_secondaries) /* Decrement spinning_secondaries */ | 274 | 3: LOAD_REG_ADDR(r3, spinning_secondaries) /* Decrement spinning_secondaries */ |
@@ -299,7 +299,7 @@ generic_secondary_common_init: | |||
299 | * Assumes we're mapped EA == RA if the MMU is on. | 299 | * Assumes we're mapped EA == RA if the MMU is on. |
300 | */ | 300 | */ |
301 | #ifdef CONFIG_PPC_BOOK3S | 301 | #ifdef CONFIG_PPC_BOOK3S |
302 | _STATIC(__mmu_off) | 302 | __mmu_off: |
303 | mfmsr r3 | 303 | mfmsr r3 |
304 | andi. r0,r3,MSR_IR|MSR_DR | 304 | andi. r0,r3,MSR_IR|MSR_DR |
305 | beqlr | 305 | beqlr |
@@ -324,12 +324,12 @@ _STATIC(__mmu_off) | |||
324 | * DT block, r4 is a physical pointer to the kernel itself | 324 | * DT block, r4 is a physical pointer to the kernel itself |
325 | * | 325 | * |
326 | */ | 326 | */ |
327 | _GLOBAL(__start_initialization_multiplatform) | 327 | __start_initialization_multiplatform: |
328 | /* Make sure we are running in 64 bits mode */ | 328 | /* Make sure we are running in 64 bits mode */ |
329 | bl .enable_64b_mode | 329 | bl enable_64b_mode |
330 | 330 | ||
331 | /* Get TOC pointer (current runtime address) */ | 331 | /* Get TOC pointer (current runtime address) */ |
332 | bl .relative_toc | 332 | bl relative_toc |
333 | 333 | ||
334 | /* find out where we are now */ | 334 | /* find out where we are now */ |
335 | bcl 20,31,$+4 | 335 | bcl 20,31,$+4 |
@@ -342,7 +342,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
342 | */ | 342 | */ |
343 | cmpldi cr0,r5,0 | 343 | cmpldi cr0,r5,0 |
344 | beq 1f | 344 | beq 1f |
345 | b .__boot_from_prom /* yes -> prom */ | 345 | b __boot_from_prom /* yes -> prom */ |
346 | 1: | 346 | 1: |
347 | /* Save parameters */ | 347 | /* Save parameters */ |
348 | mr r31,r3 | 348 | mr r31,r3 |
@@ -354,8 +354,8 @@ _GLOBAL(__start_initialization_multiplatform) | |||
354 | #endif | 354 | #endif |
355 | 355 | ||
356 | #ifdef CONFIG_PPC_BOOK3E | 356 | #ifdef CONFIG_PPC_BOOK3E |
357 | bl .start_initialization_book3e | 357 | bl start_initialization_book3e |
358 | b .__after_prom_start | 358 | b __after_prom_start |
359 | #else | 359 | #else |
360 | /* Setup some critical 970 SPRs before switching MMU off */ | 360 | /* Setup some critical 970 SPRs before switching MMU off */ |
361 | mfspr r0,SPRN_PVR | 361 | mfspr r0,SPRN_PVR |
@@ -368,15 +368,15 @@ _GLOBAL(__start_initialization_multiplatform) | |||
368 | beq 1f | 368 | beq 1f |
369 | cmpwi r0,0x45 /* 970GX */ | 369 | cmpwi r0,0x45 /* 970GX */ |
370 | bne 2f | 370 | bne 2f |
371 | 1: bl .__cpu_preinit_ppc970 | 371 | 1: bl __cpu_preinit_ppc970 |
372 | 2: | 372 | 2: |
373 | 373 | ||
374 | /* Switch off MMU if not already off */ | 374 | /* Switch off MMU if not already off */ |
375 | bl .__mmu_off | 375 | bl __mmu_off |
376 | b .__after_prom_start | 376 | b __after_prom_start |
377 | #endif /* CONFIG_PPC_BOOK3E */ | 377 | #endif /* CONFIG_PPC_BOOK3E */ |
378 | 378 | ||
379 | _INIT_STATIC(__boot_from_prom) | 379 | __boot_from_prom: |
380 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE | 380 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE |
381 | /* Save parameters */ | 381 | /* Save parameters */ |
382 | mr r31,r3 | 382 | mr r31,r3 |
@@ -395,7 +395,7 @@ _INIT_STATIC(__boot_from_prom) | |||
395 | #ifdef CONFIG_RELOCATABLE | 395 | #ifdef CONFIG_RELOCATABLE |
396 | /* Relocate code for where we are now */ | 396 | /* Relocate code for where we are now */ |
397 | mr r3,r26 | 397 | mr r3,r26 |
398 | bl .relocate | 398 | bl relocate |
399 | #endif | 399 | #endif |
400 | 400 | ||
401 | /* Restore parameters */ | 401 | /* Restore parameters */ |
@@ -407,14 +407,14 @@ _INIT_STATIC(__boot_from_prom) | |||
407 | 407 | ||
408 | /* Do all of the interaction with OF client interface */ | 408 | /* Do all of the interaction with OF client interface */ |
409 | mr r8,r26 | 409 | mr r8,r26 |
410 | bl .prom_init | 410 | bl prom_init |
411 | #endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */ | 411 | #endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */ |
412 | 412 | ||
413 | /* We never return. We also hit that trap if trying to boot | 413 | /* We never return. We also hit that trap if trying to boot |
414 | * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ | 414 | * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ |
415 | trap | 415 | trap |
416 | 416 | ||
417 | _STATIC(__after_prom_start) | 417 | __after_prom_start: |
418 | #ifdef CONFIG_RELOCATABLE | 418 | #ifdef CONFIG_RELOCATABLE |
419 | /* process relocations for the final address of the kernel */ | 419 | /* process relocations for the final address of the kernel */ |
420 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ | 420 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ |
@@ -424,7 +424,7 @@ _STATIC(__after_prom_start) | |||
424 | bne 1f | 424 | bne 1f |
425 | add r25,r25,r26 | 425 | add r25,r25,r26 |
426 | 1: mr r3,r25 | 426 | 1: mr r3,r25 |
427 | bl .relocate | 427 | bl relocate |
428 | #endif | 428 | #endif |
429 | 429 | ||
430 | /* | 430 | /* |
@@ -464,12 +464,12 @@ _STATIC(__after_prom_start) | |||
464 | lis r5,(copy_to_here - _stext)@ha | 464 | lis r5,(copy_to_here - _stext)@ha |
465 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ | 465 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ |
466 | 466 | ||
467 | bl .copy_and_flush /* copy the first n bytes */ | 467 | bl copy_and_flush /* copy the first n bytes */ |
468 | /* this includes the code being */ | 468 | /* this includes the code being */ |
469 | /* executed here. */ | 469 | /* executed here. */ |
470 | addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ | 470 | addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ |
471 | addi r8,r8,(4f - _stext)@l /* that we just made */ | 471 | addi r12,r8,(4f - _stext)@l /* that we just made */ |
472 | mtctr r8 | 472 | mtctr r12 |
473 | bctr | 473 | bctr |
474 | 474 | ||
475 | .balign 8 | 475 | .balign 8 |
@@ -478,9 +478,9 @@ p_end: .llong _end - _stext | |||
478 | 4: /* Now copy the rest of the kernel up to _end */ | 478 | 4: /* Now copy the rest of the kernel up to _end */ |
479 | addis r5,r26,(p_end - _stext)@ha | 479 | addis r5,r26,(p_end - _stext)@ha |
480 | ld r5,(p_end - _stext)@l(r5) /* get _end */ | 480 | ld r5,(p_end - _stext)@l(r5) /* get _end */ |
481 | 5: bl .copy_and_flush /* copy the rest */ | 481 | 5: bl copy_and_flush /* copy the rest */ |
482 | 482 | ||
483 | 9: b .start_here_multiplatform | 483 | 9: b start_here_multiplatform |
484 | 484 | ||
485 | /* | 485 | /* |
486 | * Copy routine used to copy the kernel to start at physical address 0 | 486 | * Copy routine used to copy the kernel to start at physical address 0 |
@@ -544,7 +544,7 @@ __secondary_start_pmac_0: | |||
544 | 544 | ||
545 | _GLOBAL(pmac_secondary_start) | 545 | _GLOBAL(pmac_secondary_start) |
546 | /* turn on 64-bit mode */ | 546 | /* turn on 64-bit mode */ |
547 | bl .enable_64b_mode | 547 | bl enable_64b_mode |
548 | 548 | ||
549 | li r0,0 | 549 | li r0,0 |
550 | mfspr r3,SPRN_HID4 | 550 | mfspr r3,SPRN_HID4 |
@@ -556,11 +556,11 @@ _GLOBAL(pmac_secondary_start) | |||
556 | slbia | 556 | slbia |
557 | 557 | ||
558 | /* get TOC pointer (real address) */ | 558 | /* get TOC pointer (real address) */ |
559 | bl .relative_toc | 559 | bl relative_toc |
560 | tovirt(r2,r2) | 560 | tovirt(r2,r2) |
561 | 561 | ||
562 | /* Copy some CPU settings from CPU 0 */ | 562 | /* Copy some CPU settings from CPU 0 */ |
563 | bl .__restore_cpu_ppc970 | 563 | bl __restore_cpu_ppc970 |
564 | 564 | ||
565 | /* pSeries do that early though I don't think we really need it */ | 565 | /* pSeries do that early though I don't think we really need it */ |
566 | mfmsr r3 | 566 | mfmsr r3 |
@@ -619,7 +619,7 @@ __secondary_start: | |||
619 | std r14,PACAKSAVE(r13) | 619 | std r14,PACAKSAVE(r13) |
620 | 620 | ||
621 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | 621 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ |
622 | bl .early_setup_secondary | 622 | bl early_setup_secondary |
623 | 623 | ||
624 | /* | 624 | /* |
625 | * setup the new stack pointer, but *don't* use this until | 625 | * setup the new stack pointer, but *don't* use this until |
@@ -639,7 +639,7 @@ __secondary_start: | |||
639 | stb r0,PACAIRQHAPPENED(r13) | 639 | stb r0,PACAIRQHAPPENED(r13) |
640 | 640 | ||
641 | /* enable MMU and jump to start_secondary */ | 641 | /* enable MMU and jump to start_secondary */ |
642 | LOAD_REG_ADDR(r3, .start_secondary_prolog) | 642 | LOAD_REG_ADDR(r3, start_secondary_prolog) |
643 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) | 643 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
644 | 644 | ||
645 | mtspr SPRN_SRR0,r3 | 645 | mtspr SPRN_SRR0,r3 |
@@ -652,11 +652,11 @@ __secondary_start: | |||
652 | * zero the stack back-chain pointer and get the TOC virtual address | 652 | * zero the stack back-chain pointer and get the TOC virtual address |
653 | * before going into C code. | 653 | * before going into C code. |
654 | */ | 654 | */ |
655 | _GLOBAL(start_secondary_prolog) | 655 | start_secondary_prolog: |
656 | ld r2,PACATOC(r13) | 656 | ld r2,PACATOC(r13) |
657 | li r3,0 | 657 | li r3,0 |
658 | std r3,0(r1) /* Zero the stack frame pointer */ | 658 | std r3,0(r1) /* Zero the stack frame pointer */ |
659 | bl .start_secondary | 659 | bl start_secondary |
660 | b . | 660 | b . |
661 | /* | 661 | /* |
662 | * Reset stack pointer and call start_secondary | 662 | * Reset stack pointer and call start_secondary |
@@ -667,14 +667,14 @@ _GLOBAL(start_secondary_resume) | |||
667 | ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ | 667 | ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ |
668 | li r3,0 | 668 | li r3,0 |
669 | std r3,0(r1) /* Zero the stack frame pointer */ | 669 | std r3,0(r1) /* Zero the stack frame pointer */ |
670 | bl .start_secondary | 670 | bl start_secondary |
671 | b . | 671 | b . |
672 | #endif | 672 | #endif |
673 | 673 | ||
674 | /* | 674 | /* |
675 | * This subroutine clobbers r11 and r12 | 675 | * This subroutine clobbers r11 and r12 |
676 | */ | 676 | */ |
677 | _GLOBAL(enable_64b_mode) | 677 | enable_64b_mode: |
678 | mfmsr r11 /* grab the current MSR */ | 678 | mfmsr r11 /* grab the current MSR */ |
679 | #ifdef CONFIG_PPC_BOOK3E | 679 | #ifdef CONFIG_PPC_BOOK3E |
680 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ | 680 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ |
@@ -715,9 +715,9 @@ p_toc: .llong __toc_start + 0x8000 - 0b | |||
715 | /* | 715 | /* |
716 | * This is where the main kernel code starts. | 716 | * This is where the main kernel code starts. |
717 | */ | 717 | */ |
718 | _INIT_STATIC(start_here_multiplatform) | 718 | start_here_multiplatform: |
719 | /* set up the TOC */ | 719 | /* set up the TOC */ |
720 | bl .relative_toc | 720 | bl relative_toc |
721 | tovirt(r2,r2) | 721 | tovirt(r2,r2) |
722 | 722 | ||
723 | /* Clear out the BSS. It may have been done in prom_init, | 723 | /* Clear out the BSS. It may have been done in prom_init, |
@@ -776,9 +776,9 @@ _INIT_STATIC(start_here_multiplatform) | |||
776 | 776 | ||
777 | /* Restore parameters passed from prom_init/kexec */ | 777 | /* Restore parameters passed from prom_init/kexec */ |
778 | mr r3,r31 | 778 | mr r3,r31 |
779 | bl .early_setup /* also sets r13 and SPRG_PACA */ | 779 | bl early_setup /* also sets r13 and SPRG_PACA */ |
780 | 780 | ||
781 | LOAD_REG_ADDR(r3, .start_here_common) | 781 | LOAD_REG_ADDR(r3, start_here_common) |
782 | ld r4,PACAKMSR(r13) | 782 | ld r4,PACAKMSR(r13) |
783 | mtspr SPRN_SRR0,r3 | 783 | mtspr SPRN_SRR0,r3 |
784 | mtspr SPRN_SRR1,r4 | 784 | mtspr SPRN_SRR1,r4 |
@@ -786,7 +786,8 @@ _INIT_STATIC(start_here_multiplatform) | |||
786 | b . /* prevent speculative execution */ | 786 | b . /* prevent speculative execution */ |
787 | 787 | ||
788 | /* This is where all platforms converge execution */ | 788 | /* This is where all platforms converge execution */ |
789 | _INIT_GLOBAL(start_here_common) | 789 | |
790 | start_here_common: | ||
790 | /* relocation is on at this point */ | 791 | /* relocation is on at this point */ |
791 | std r1,PACAKSAVE(r13) | 792 | std r1,PACAKSAVE(r13) |
792 | 793 | ||
@@ -794,7 +795,7 @@ _INIT_GLOBAL(start_here_common) | |||
794 | ld r2,PACATOC(r13) | 795 | ld r2,PACATOC(r13) |
795 | 796 | ||
796 | /* Do more system initializations in virtual mode */ | 797 | /* Do more system initializations in virtual mode */ |
797 | bl .setup_system | 798 | bl setup_system |
798 | 799 | ||
799 | /* Mark interrupts soft and hard disabled (they might be enabled | 800 | /* Mark interrupts soft and hard disabled (they might be enabled |
800 | * in the PACA when doing hotplug) | 801 | * in the PACA when doing hotplug) |
@@ -805,7 +806,7 @@ _INIT_GLOBAL(start_here_common) | |||
805 | stb r0,PACAIRQHAPPENED(r13) | 806 | stb r0,PACAIRQHAPPENED(r13) |
806 | 807 | ||
807 | /* Generic kernel entry */ | 808 | /* Generic kernel entry */ |
808 | bl .start_kernel | 809 | bl start_kernel |
809 | 810 | ||
810 | /* Not reached */ | 811 | /* Not reached */ |
811 | BUG_OPCODE | 812 | BUG_OPCODE |
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S index bfb73cc209ce..48c21acef915 100644 --- a/arch/powerpc/kernel/idle_book3e.S +++ b/arch/powerpc/kernel/idle_book3e.S | |||
@@ -43,7 +43,7 @@ _GLOBAL(\name) | |||
43 | */ | 43 | */ |
44 | #ifdef CONFIG_TRACE_IRQFLAGS | 44 | #ifdef CONFIG_TRACE_IRQFLAGS |
45 | stdu r1,-128(r1) | 45 | stdu r1,-128(r1) |
46 | bl .trace_hardirqs_on | 46 | bl trace_hardirqs_on |
47 | addi r1,r1,128 | 47 | addi r1,r1,128 |
48 | #endif | 48 | #endif |
49 | li r0,1 | 49 | li r0,1 |
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index e3edaa189911..f57a19348bdd 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -46,7 +46,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | |||
46 | mflr r0 | 46 | mflr r0 |
47 | std r0,16(r1) | 47 | std r0,16(r1) |
48 | stdu r1,-128(r1) | 48 | stdu r1,-128(r1) |
49 | bl .trace_hardirqs_on | 49 | bl trace_hardirqs_on |
50 | addi r1,r1,128 | 50 | addi r1,r1,128 |
51 | ld r0,16(r1) | 51 | ld r0,16(r1) |
52 | mtlr r0 | 52 | mtlr r0 |
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index c3ab86975614..dca6e16c2436 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S | |||
@@ -58,7 +58,7 @@ _GLOBAL(power7_powersave_common) | |||
58 | /* Make sure FPU, VSX etc... are flushed as we may lose | 58 | /* Make sure FPU, VSX etc... are flushed as we may lose |
59 | * state when going to nap mode | 59 | * state when going to nap mode |
60 | */ | 60 | */ |
61 | bl .discard_lazy_cpu_state | 61 | bl discard_lazy_cpu_state |
62 | #endif /* CONFIG_SMP */ | 62 | #endif /* CONFIG_SMP */ |
63 | 63 | ||
64 | /* Hard disable interrupts */ | 64 | /* Hard disable interrupts */ |
@@ -168,7 +168,7 @@ _GLOBAL(power7_wakeup_loss) | |||
168 | _GLOBAL(power7_wakeup_noloss) | 168 | _GLOBAL(power7_wakeup_noloss) |
169 | lbz r0,PACA_NAPSTATELOST(r13) | 169 | lbz r0,PACA_NAPSTATELOST(r13) |
170 | cmpwi r0,0 | 170 | cmpwi r0,0 |
171 | bne .power7_wakeup_loss | 171 | bne power7_wakeup_loss |
172 | ld r1,PACAR1(r13) | 172 | ld r1,PACAR1(r13) |
173 | ld r4,_MSR(r1) | 173 | ld r4,_MSR(r1) |
174 | ld r5,_NIP(r1) | 174 | ld r5,_NIP(r1) |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 3d0249599d52..4e314b90c75d 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -34,7 +34,7 @@ _GLOBAL(call_do_softirq) | |||
34 | std r0,16(r1) | 34 | std r0,16(r1) |
35 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) | 35 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) |
36 | mr r1,r3 | 36 | mr r1,r3 |
37 | bl .__do_softirq | 37 | bl __do_softirq |
38 | ld r1,0(r1) | 38 | ld r1,0(r1) |
39 | ld r0,16(r1) | 39 | ld r0,16(r1) |
40 | mtlr r0 | 40 | mtlr r0 |
@@ -45,7 +45,7 @@ _GLOBAL(call_do_irq) | |||
45 | std r0,16(r1) | 45 | std r0,16(r1) |
46 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) | 46 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) |
47 | mr r1,r4 | 47 | mr r1,r4 |
48 | bl .__do_irq | 48 | bl __do_irq |
49 | ld r1,0(r1) | 49 | ld r1,0(r1) |
50 | ld r0,16(r1) | 50 | ld r0,16(r1) |
51 | mtlr r0 | 51 | mtlr r0 |
@@ -506,7 +506,7 @@ _GLOBAL(kexec_smp_wait) | |||
506 | stb r4,PACAKEXECSTATE(r13) | 506 | stb r4,PACAKEXECSTATE(r13) |
507 | SYNC | 507 | SYNC |
508 | 508 | ||
509 | b .kexec_wait | 509 | b kexec_wait |
510 | 510 | ||
511 | /* | 511 | /* |
512 | * switch to real mode (turn mmu off) | 512 | * switch to real mode (turn mmu off) |
@@ -576,7 +576,7 @@ _GLOBAL(kexec_sequence) | |||
576 | 576 | ||
577 | /* copy dest pages, flush whole dest image */ | 577 | /* copy dest pages, flush whole dest image */ |
578 | mr r3,r29 | 578 | mr r3,r29 |
579 | bl .kexec_copy_flush /* (image) */ | 579 | bl kexec_copy_flush /* (image) */ |
580 | 580 | ||
581 | /* turn off mmu */ | 581 | /* turn off mmu */ |
582 | bl real_mode | 582 | bl real_mode |
@@ -586,7 +586,7 @@ _GLOBAL(kexec_sequence) | |||
586 | mr r4,r30 /* start, aka phys mem offset */ | 586 | mr r4,r30 /* start, aka phys mem offset */ |
587 | li r5,0x100 | 587 | li r5,0x100 |
588 | li r6,0 | 588 | li r6,0 |
589 | bl .copy_and_flush /* (dest, src, copy limit, start offset) */ | 589 | bl copy_and_flush /* (dest, src, copy limit, start offset) */ |
590 | 1: /* assume normal blr return */ | 590 | 1: /* assume normal blr return */ |
591 | 591 | ||
592 | /* release other cpus to the new kernel secondary start at 0x60 */ | 592 | /* release other cpus to the new kernel secondary start at 0x60 */ |
@@ -595,8 +595,12 @@ _GLOBAL(kexec_sequence) | |||
595 | stw r6,kexec_flag-1b(5) | 595 | stw r6,kexec_flag-1b(5) |
596 | 596 | ||
597 | /* clear out hardware hash page table and tlb */ | 597 | /* clear out hardware hash page table and tlb */ |
598 | ld r5,0(r27) /* deref function descriptor */ | 598 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
599 | mtctr r5 | 599 | ld r12,0(r27) /* deref function descriptor */ |
600 | #else | ||
601 | mr r12,r27 | ||
602 | #endif | ||
603 | mtctr r12 | ||
600 | bctrl /* ppc_md.hpte_clear_all(void); */ | 604 | bctrl /* ppc_md.hpte_clear_all(void); */ |
601 | 605 | ||
602 | /* | 606 | /* |
@@ -630,3 +634,31 @@ _GLOBAL(kexec_sequence) | |||
630 | li r5,0 | 634 | li r5,0 |
631 | blr /* image->start(physid, image->start, 0); */ | 635 | blr /* image->start(physid, image->start, 0); */ |
632 | #endif /* CONFIG_KEXEC */ | 636 | #endif /* CONFIG_KEXEC */ |
637 | |||
638 | #ifdef CONFIG_MODULES | ||
639 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
640 | |||
641 | #ifdef CONFIG_MODVERSIONS | ||
642 | .weak __crc_TOC. | ||
643 | .section "___kcrctab+TOC.","a" | ||
644 | .globl __kcrctab_TOC. | ||
645 | __kcrctab_TOC.: | ||
646 | .llong __crc_TOC. | ||
647 | #endif | ||
648 | |||
649 | /* | ||
650 | * Export a fake .TOC. since both modpost and depmod will complain otherwise. | ||
651 | * Both modpost and depmod strip the leading . so we do the same here. | ||
652 | */ | ||
653 | .section "__ksymtab_strings","a" | ||
654 | __kstrtab_TOC.: | ||
655 | .asciz "TOC." | ||
656 | |||
657 | .section "___ksymtab+TOC.","a" | ||
658 | /* This symbol name is important: it's used by modpost to find exported syms */ | ||
659 | .globl __ksymtab_TOC. | ||
660 | __ksymtab_TOC.: | ||
661 | .llong 0 /* .value */ | ||
662 | .llong __kstrtab_TOC. | ||
663 | #endif /* ELFv2 */ | ||
664 | #endif /* MODULES */ | ||
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 12664c130d73..ef349d077129 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <linux/ftrace.h> | 23 | #include <linux/ftrace.h> |
24 | #include <linux/bug.h> | 24 | #include <linux/bug.h> |
25 | #include <linux/uaccess.h> | ||
25 | #include <asm/module.h> | 26 | #include <asm/module.h> |
26 | #include <asm/firmware.h> | 27 | #include <asm/firmware.h> |
27 | #include <asm/code-patching.h> | 28 | #include <asm/code-patching.h> |
@@ -41,46 +42,170 @@ | |||
41 | #define DEBUGP(fmt , ...) | 42 | #define DEBUGP(fmt , ...) |
42 | #endif | 43 | #endif |
43 | 44 | ||
45 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
46 | #define R2_STACK_OFFSET 24 | ||
47 | |||
48 | /* An address is simply the address of the function. */ | ||
49 | typedef unsigned long func_desc_t; | ||
50 | |||
51 | static func_desc_t func_desc(unsigned long addr) | ||
52 | { | ||
53 | return addr; | ||
54 | } | ||
55 | static unsigned long func_addr(unsigned long addr) | ||
56 | { | ||
57 | return addr; | ||
58 | } | ||
59 | static unsigned long stub_func_addr(func_desc_t func) | ||
60 | { | ||
61 | return func; | ||
62 | } | ||
63 | |||
64 | /* PowerPC64 specific values for the Elf64_Sym st_other field. */ | ||
65 | #define STO_PPC64_LOCAL_BIT 5 | ||
66 | #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) | ||
67 | #define PPC64_LOCAL_ENTRY_OFFSET(other) \ | ||
68 | (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) | ||
69 | |||
70 | static unsigned int local_entry_offset(const Elf64_Sym *sym) | ||
71 | { | ||
72 | /* sym->st_other indicates offset to local entry point | ||
73 | * (otherwise it will assume r12 is the address of the start | ||
74 | * of function and try to derive r2 from it). */ | ||
75 | return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); | ||
76 | } | ||
77 | #else | ||
78 | #define R2_STACK_OFFSET 40 | ||
79 | |||
80 | /* An address is address of the OPD entry, which contains address of fn. */ | ||
81 | typedef struct ppc64_opd_entry func_desc_t; | ||
82 | |||
83 | static func_desc_t func_desc(unsigned long addr) | ||
84 | { | ||
85 | return *(struct ppc64_opd_entry *)addr; | ||
86 | } | ||
87 | static unsigned long func_addr(unsigned long addr) | ||
88 | { | ||
89 | return func_desc(addr).funcaddr; | ||
90 | } | ||
91 | static unsigned long stub_func_addr(func_desc_t func) | ||
92 | { | ||
93 | return func.funcaddr; | ||
94 | } | ||
95 | static unsigned int local_entry_offset(const Elf64_Sym *sym) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | #endif | ||
100 | |||
44 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into | 101 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into |
45 | the kernel itself). But on PPC64, these need to be used for every | 102 | the kernel itself). But on PPC64, these need to be used for every |
46 | jump, actually, to reset r2 (TOC+0x8000). */ | 103 | jump, actually, to reset r2 (TOC+0x8000). */ |
47 | struct ppc64_stub_entry | 104 | struct ppc64_stub_entry |
48 | { | 105 | { |
49 | /* 28 byte jump instruction sequence (7 instructions) */ | 106 | /* 28 byte jump instruction sequence (7 instructions). We only |
50 | unsigned char jump[28]; | 107 | * need 6 instructions on ABIv2 but we always allocate 7 so |
51 | unsigned char unused[4]; | 108 | * so we don't have to modify the trampoline load instruction. */ |
109 | u32 jump[7]; | ||
110 | u32 unused; | ||
52 | /* Data for the above code */ | 111 | /* Data for the above code */ |
53 | struct ppc64_opd_entry opd; | 112 | func_desc_t funcdata; |
54 | }; | 113 | }; |
55 | 114 | ||
56 | /* We use a stub to fix up r2 (TOC ptr) and to jump to the (external) | 115 | /* |
57 | function which may be more than 24-bits away. We could simply | 116 | * PPC64 uses 24 bit jumps, but we need to jump into other modules or |
58 | patch the new r2 value and function pointer into the stub, but it's | 117 | * the kernel which may be further. So we jump to a stub. |
59 | significantly shorter to put these values at the end of the stub | 118 | * |
60 | code, and patch the stub address (32-bits relative to the TOC ptr, | 119 | * For ELFv1 we need to use this to set up the new r2 value (aka TOC |
61 | r2) into the stub. */ | 120 | * pointer). For ELFv2 it's the callee's responsibility to set up the |
62 | static struct ppc64_stub_entry ppc64_stub = | 121 | * new r2, but for both we need to save the old r2. |
63 | { .jump = { | 122 | * |
64 | #ifdef __LITTLE_ENDIAN__ | 123 | * We could simply patch the new r2 value and function pointer into |
65 | 0x00, 0x00, 0x82, 0x3d, /* addis r12,r2, <high> */ | 124 | * the stub, but it's significantly shorter to put these values at the |
66 | 0x00, 0x00, 0x8c, 0x39, /* addi r12,r12, <low> */ | 125 | * end of the stub code, and patch the stub address (32-bits relative |
67 | /* Save current r2 value in magic place on the stack. */ | 126 | * to the TOC ptr, r2) into the stub. |
68 | 0x28, 0x00, 0x41, 0xf8, /* std r2,40(r1) */ | 127 | */ |
69 | 0x20, 0x00, 0x6c, 0xe9, /* ld r11,32(r12) */ | 128 | |
70 | 0x28, 0x00, 0x4c, 0xe8, /* ld r2,40(r12) */ | 129 | static u32 ppc64_stub_insns[] = { |
71 | 0xa6, 0x03, 0x69, 0x7d, /* mtctr r11 */ | 130 | 0x3d620000, /* addis r11,r2, <high> */ |
72 | 0x20, 0x04, 0x80, 0x4e /* bctr */ | 131 | 0x396b0000, /* addi r11,r11, <low> */ |
73 | #else | ||
74 | 0x3d, 0x82, 0x00, 0x00, /* addis r12,r2, <high> */ | ||
75 | 0x39, 0x8c, 0x00, 0x00, /* addi r12,r12, <low> */ | ||
76 | /* Save current r2 value in magic place on the stack. */ | 132 | /* Save current r2 value in magic place on the stack. */ |
77 | 0xf8, 0x41, 0x00, 0x28, /* std r2,40(r1) */ | 133 | 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */ |
78 | 0xe9, 0x6c, 0x00, 0x20, /* ld r11,32(r12) */ | 134 | 0xe98b0020, /* ld r12,32(r11) */ |
79 | 0xe8, 0x4c, 0x00, 0x28, /* ld r2,40(r12) */ | 135 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
80 | 0x7d, 0x69, 0x03, 0xa6, /* mtctr r11 */ | 136 | /* Set up new r2 from function descriptor */ |
81 | 0x4e, 0x80, 0x04, 0x20 /* bctr */ | 137 | 0xe84b0026, /* ld r2,40(r11) */ |
138 | #endif | ||
139 | 0x7d8903a6, /* mtctr r12 */ | ||
140 | 0x4e800420 /* bctr */ | ||
141 | }; | ||
142 | |||
143 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
144 | |||
145 | static u32 ppc64_stub_mask[] = { | ||
146 | 0xffff0000, | ||
147 | 0xffff0000, | ||
148 | 0xffffffff, | ||
149 | 0xffffffff, | ||
150 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
151 | 0xffffffff, | ||
152 | #endif | ||
153 | 0xffffffff, | ||
154 | 0xffffffff | ||
155 | }; | ||
156 | |||
157 | bool is_module_trampoline(u32 *p) | ||
158 | { | ||
159 | unsigned int i; | ||
160 | u32 insns[ARRAY_SIZE(ppc64_stub_insns)]; | ||
161 | |||
162 | BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask)); | ||
163 | |||
164 | if (probe_kernel_read(insns, p, sizeof(insns))) | ||
165 | return -EFAULT; | ||
166 | |||
167 | for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { | ||
168 | u32 insna = insns[i]; | ||
169 | u32 insnb = ppc64_stub_insns[i]; | ||
170 | u32 mask = ppc64_stub_mask[i]; | ||
171 | |||
172 | if ((insna & mask) != (insnb & mask)) | ||
173 | return false; | ||
174 | } | ||
175 | |||
176 | return true; | ||
177 | } | ||
178 | |||
179 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
180 | unsigned long *target) | ||
181 | { | ||
182 | u32 buf[2]; | ||
183 | u16 upper, lower; | ||
184 | long offset; | ||
185 | void *toc_entry; | ||
186 | |||
187 | if (probe_kernel_read(buf, trampoline, sizeof(buf))) | ||
188 | return -EFAULT; | ||
189 | |||
190 | upper = buf[0] & 0xffff; | ||
191 | lower = buf[1] & 0xffff; | ||
192 | |||
193 | /* perform the addis/addi, both signed */ | ||
194 | offset = ((short)upper << 16) + (short)lower; | ||
195 | |||
196 | /* | ||
197 | * Now get the address this trampoline jumps to. This | ||
198 | * is always 32 bytes into our trampoline stub. | ||
199 | */ | ||
200 | toc_entry = (void *)mod->arch.toc + offset + 32; | ||
201 | |||
202 | if (probe_kernel_read(target, toc_entry, sizeof(*target))) | ||
203 | return -EFAULT; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
82 | #endif | 208 | #endif |
83 | } }; | ||
84 | 209 | ||
85 | /* Count how many different 24-bit relocations (different symbol, | 210 | /* Count how many different 24-bit relocations (different symbol, |
86 | different addend) */ | 211 | different addend) */ |
@@ -183,6 +308,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, | |||
183 | return relocs * sizeof(struct ppc64_stub_entry); | 308 | return relocs * sizeof(struct ppc64_stub_entry); |
184 | } | 309 | } |
185 | 310 | ||
311 | /* Still needed for ELFv2, for .TOC. */ | ||
186 | static void dedotify_versions(struct modversion_info *vers, | 312 | static void dedotify_versions(struct modversion_info *vers, |
187 | unsigned long size) | 313 | unsigned long size) |
188 | { | 314 | { |
@@ -193,7 +319,7 @@ static void dedotify_versions(struct modversion_info *vers, | |||
193 | memmove(vers->name, vers->name+1, strlen(vers->name)); | 319 | memmove(vers->name, vers->name+1, strlen(vers->name)); |
194 | } | 320 | } |
195 | 321 | ||
196 | /* Undefined symbols which refer to .funcname, hack to funcname */ | 322 | /* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */ |
197 | static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) | 323 | static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) |
198 | { | 324 | { |
199 | unsigned int i; | 325 | unsigned int i; |
@@ -207,6 +333,24 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) | |||
207 | } | 333 | } |
208 | } | 334 | } |
209 | 335 | ||
336 | static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs, | ||
337 | const char *strtab, | ||
338 | unsigned int symindex) | ||
339 | { | ||
340 | unsigned int i, numsyms; | ||
341 | Elf64_Sym *syms; | ||
342 | |||
343 | syms = (Elf64_Sym *)sechdrs[symindex].sh_addr; | ||
344 | numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym); | ||
345 | |||
346 | for (i = 1; i < numsyms; i++) { | ||
347 | if (syms[i].st_shndx == SHN_UNDEF | ||
348 | && strcmp(strtab + syms[i].st_name, "TOC.") == 0) | ||
349 | return &syms[i]; | ||
350 | } | ||
351 | return NULL; | ||
352 | } | ||
353 | |||
210 | int module_frob_arch_sections(Elf64_Ehdr *hdr, | 354 | int module_frob_arch_sections(Elf64_Ehdr *hdr, |
211 | Elf64_Shdr *sechdrs, | 355 | Elf64_Shdr *sechdrs, |
212 | char *secstrings, | 356 | char *secstrings, |
@@ -271,21 +415,12 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) | |||
271 | /* Patch stub to reference function and correct r2 value. */ | 415 | /* Patch stub to reference function and correct r2 value. */ |
272 | static inline int create_stub(Elf64_Shdr *sechdrs, | 416 | static inline int create_stub(Elf64_Shdr *sechdrs, |
273 | struct ppc64_stub_entry *entry, | 417 | struct ppc64_stub_entry *entry, |
274 | struct ppc64_opd_entry *opd, | 418 | unsigned long addr, |
275 | struct module *me) | 419 | struct module *me) |
276 | { | 420 | { |
277 | Elf64_Half *loc1, *loc2; | ||
278 | long reladdr; | 421 | long reladdr; |
279 | 422 | ||
280 | *entry = ppc64_stub; | 423 | memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns)); |
281 | |||
282 | #ifdef __LITTLE_ENDIAN__ | ||
283 | loc1 = (Elf64_Half *)&entry->jump[0]; | ||
284 | loc2 = (Elf64_Half *)&entry->jump[4]; | ||
285 | #else | ||
286 | loc1 = (Elf64_Half *)&entry->jump[2]; | ||
287 | loc2 = (Elf64_Half *)&entry->jump[6]; | ||
288 | #endif | ||
289 | 424 | ||
290 | /* Stub uses address relative to r2. */ | 425 | /* Stub uses address relative to r2. */ |
291 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); | 426 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); |
@@ -296,35 +431,33 @@ static inline int create_stub(Elf64_Shdr *sechdrs, | |||
296 | } | 431 | } |
297 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); | 432 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); |
298 | 433 | ||
299 | *loc1 = PPC_HA(reladdr); | 434 | entry->jump[0] |= PPC_HA(reladdr); |
300 | *loc2 = PPC_LO(reladdr); | 435 | entry->jump[1] |= PPC_LO(reladdr); |
301 | entry->opd.funcaddr = opd->funcaddr; | 436 | entry->funcdata = func_desc(addr); |
302 | entry->opd.r2 = opd->r2; | ||
303 | return 1; | 437 | return 1; |
304 | } | 438 | } |
305 | 439 | ||
306 | /* Create stub to jump to function described in this OPD: we need the | 440 | /* Create stub to jump to function described in this OPD/ptr: we need the |
307 | stub to set up the TOC ptr (r2) for the function. */ | 441 | stub to set up the TOC ptr (r2) for the function. */ |
308 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | 442 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, |
309 | unsigned long opdaddr, | 443 | unsigned long addr, |
310 | struct module *me) | 444 | struct module *me) |
311 | { | 445 | { |
312 | struct ppc64_stub_entry *stubs; | 446 | struct ppc64_stub_entry *stubs; |
313 | struct ppc64_opd_entry *opd = (void *)opdaddr; | ||
314 | unsigned int i, num_stubs; | 447 | unsigned int i, num_stubs; |
315 | 448 | ||
316 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); | 449 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); |
317 | 450 | ||
318 | /* Find this stub, or if that fails, the next avail. entry */ | 451 | /* Find this stub, or if that fails, the next avail. entry */ |
319 | stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; | 452 | stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; |
320 | for (i = 0; stubs[i].opd.funcaddr; i++) { | 453 | for (i = 0; stub_func_addr(stubs[i].funcdata); i++) { |
321 | BUG_ON(i >= num_stubs); | 454 | BUG_ON(i >= num_stubs); |
322 | 455 | ||
323 | if (stubs[i].opd.funcaddr == opd->funcaddr) | 456 | if (stub_func_addr(stubs[i].funcdata) == func_addr(addr)) |
324 | return (unsigned long)&stubs[i]; | 457 | return (unsigned long)&stubs[i]; |
325 | } | 458 | } |
326 | 459 | ||
327 | if (!create_stub(sechdrs, &stubs[i], opd, me)) | 460 | if (!create_stub(sechdrs, &stubs[i], addr, me)) |
328 | return 0; | 461 | return 0; |
329 | 462 | ||
330 | return (unsigned long)&stubs[i]; | 463 | return (unsigned long)&stubs[i]; |
@@ -339,7 +472,8 @@ static int restore_r2(u32 *instruction, struct module *me) | |||
339 | me->name, *instruction); | 472 | me->name, *instruction); |
340 | return 0; | 473 | return 0; |
341 | } | 474 | } |
342 | *instruction = 0xe8410028; /* ld r2,40(r1) */ | 475 | /* ld r2,R2_STACK_OFFSET(r1) */ |
476 | *instruction = 0xe8410000 | R2_STACK_OFFSET; | ||
343 | return 1; | 477 | return 1; |
344 | } | 478 | } |
345 | 479 | ||
@@ -357,6 +491,17 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
357 | 491 | ||
358 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, | 492 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, |
359 | sechdrs[relsec].sh_info); | 493 | sechdrs[relsec].sh_info); |
494 | |||
495 | /* First time we're called, we can fix up .TOC. */ | ||
496 | if (!me->arch.toc_fixed) { | ||
497 | sym = find_dot_toc(sechdrs, strtab, symindex); | ||
498 | /* It's theoretically possible that a module doesn't want a | ||
499 | * .TOC. so don't fail it just for that. */ | ||
500 | if (sym) | ||
501 | sym->st_value = my_r2(sechdrs, me); | ||
502 | me->arch.toc_fixed = true; | ||
503 | } | ||
504 | |||
360 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { | 505 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { |
361 | /* This is where to make the change */ | 506 | /* This is where to make the change */ |
362 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | 507 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
@@ -453,7 +598,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
453 | return -ENOENT; | 598 | return -ENOENT; |
454 | if (!restore_r2((u32 *)location + 1, me)) | 599 | if (!restore_r2((u32 *)location + 1, me)) |
455 | return -ENOEXEC; | 600 | return -ENOEXEC; |
456 | } | 601 | } else |
602 | value += local_entry_offset(sym); | ||
457 | 603 | ||
458 | /* Convert value to relative */ | 604 | /* Convert value to relative */ |
459 | value -= (unsigned long)location; | 605 | value -= (unsigned long)location; |
@@ -474,6 +620,31 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
474 | *location = value - (unsigned long)location; | 620 | *location = value - (unsigned long)location; |
475 | break; | 621 | break; |
476 | 622 | ||
623 | case R_PPC64_TOCSAVE: | ||
624 | /* | ||
625 | * Marker reloc indicates we don't have to save r2. | ||
626 | * That would only save us one instruction, so ignore | ||
627 | * it. | ||
628 | */ | ||
629 | break; | ||
630 | |||
631 | case R_PPC64_REL16_HA: | ||
632 | /* Subtract location pointer */ | ||
633 | value -= (unsigned long)location; | ||
634 | value = ((value + 0x8000) >> 16); | ||
635 | *((uint16_t *) location) | ||
636 | = (*((uint16_t *) location) & ~0xffff) | ||
637 | | (value & 0xffff); | ||
638 | break; | ||
639 | |||
640 | case R_PPC64_REL16_LO: | ||
641 | /* Subtract location pointer */ | ||
642 | value -= (unsigned long)location; | ||
643 | *((uint16_t *) location) | ||
644 | = (*((uint16_t *) location) & ~0xffff) | ||
645 | | (value & 0xffff); | ||
646 | break; | ||
647 | |||
477 | default: | 648 | default: |
478 | printk("%s: Unknown ADD relocation: %lu\n", | 649 | printk("%s: Unknown ADD relocation: %lu\n", |
479 | me->name, | 650 | me->name, |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 31d021506d21..2ae1b99166c6 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #ifdef CONFIG_PPC64 | 54 | #ifdef CONFIG_PPC64 |
55 | #include <asm/firmware.h> | 55 | #include <asm/firmware.h> |
56 | #endif | 56 | #endif |
57 | #include <asm/code-patching.h> | ||
57 | #include <linux/kprobes.h> | 58 | #include <linux/kprobes.h> |
58 | #include <linux/kdebug.h> | 59 | #include <linux/kdebug.h> |
59 | 60 | ||
@@ -1108,7 +1109,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
1108 | struct thread_info *ti = (void *)task_stack_page(p); | 1109 | struct thread_info *ti = (void *)task_stack_page(p); |
1109 | memset(childregs, 0, sizeof(struct pt_regs)); | 1110 | memset(childregs, 0, sizeof(struct pt_regs)); |
1110 | childregs->gpr[1] = sp + sizeof(struct pt_regs); | 1111 | childregs->gpr[1] = sp + sizeof(struct pt_regs); |
1111 | childregs->gpr[14] = usp; /* function */ | 1112 | /* function */ |
1113 | if (usp) | ||
1114 | childregs->gpr[14] = ppc_function_entry((void *)usp); | ||
1112 | #ifdef CONFIG_PPC64 | 1115 | #ifdef CONFIG_PPC64 |
1113 | clear_tsk_thread_flag(p, TIF_32BIT); | 1116 | clear_tsk_thread_flag(p, TIF_32BIT); |
1114 | childregs->softe = 1; | 1117 | childregs->softe = 1; |
@@ -1187,17 +1190,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
1187 | if (cpu_has_feature(CPU_FTR_HAS_PPR)) | 1190 | if (cpu_has_feature(CPU_FTR_HAS_PPR)) |
1188 | p->thread.ppr = INIT_PPR; | 1191 | p->thread.ppr = INIT_PPR; |
1189 | #endif | 1192 | #endif |
1190 | /* | 1193 | kregs->nip = ppc_function_entry(f); |
1191 | * The PPC64 ABI makes use of a TOC to contain function | ||
1192 | * pointers. The function (ret_from_except) is actually a pointer | ||
1193 | * to the TOC entry. The first entry is a pointer to the actual | ||
1194 | * function. | ||
1195 | */ | ||
1196 | #ifdef CONFIG_PPC64 | ||
1197 | kregs->nip = *((unsigned long *)f); | ||
1198 | #else | ||
1199 | kregs->nip = (unsigned long)f; | ||
1200 | #endif | ||
1201 | return 0; | 1194 | return 0; |
1202 | } | 1195 | } |
1203 | 1196 | ||
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index b0c263da219a..77aa1e95e904 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
@@ -23,7 +23,7 @@ strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 | |||
23 | reloc_got2 kernstart_addr memstart_addr linux_banner _stext | 23 | reloc_got2 kernstart_addr memstart_addr linux_banner _stext |
24 | opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry | 24 | opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry |
25 | boot_command_line __prom_init_toc_start __prom_init_toc_end | 25 | boot_command_line __prom_init_toc_start __prom_init_toc_end |
26 | btext_setup_display" | 26 | btext_setup_display TOC." |
27 | 27 | ||
28 | NM="$1" | 28 | NM="$1" |
29 | OBJ="$2" | 29 | OBJ="$2" |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fbe24377eda3..90b532ace0d5 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -341,7 +341,7 @@ void smp_release_cpus(void) | |||
341 | 341 | ||
342 | ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop | 342 | ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop |
343 | - PHYSICAL_START); | 343 | - PHYSICAL_START); |
344 | *ptr = __pa(generic_secondary_smp_init); | 344 | *ptr = ppc_function_entry(generic_secondary_smp_init); |
345 | 345 | ||
346 | /* And wait a bit for them to catch up */ | 346 | /* And wait a bit for them to catch up */ |
347 | for (i = 0; i < 100000; i++) { | 347 | for (i = 0; i < 100000; i++) { |
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 93219c34af32..895c50ca943c 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
@@ -17,12 +17,12 @@ | |||
17 | #include <asm/ppc_asm.h> | 17 | #include <asm/ppc_asm.h> |
18 | 18 | ||
19 | #ifdef CONFIG_PPC64 | 19 | #ifdef CONFIG_PPC64 |
20 | #define SYSCALL(func) .llong .sys_##func,.sys_##func | 20 | #define SYSCALL(func) .llong DOTSYM(sys_##func),DOTSYM(sys_##func) |
21 | #define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func | 21 | #define COMPAT_SYS(func) .llong DOTSYM(sys_##func),DOTSYM(compat_sys_##func) |
22 | #define PPC_SYS(func) .llong .ppc_##func,.ppc_##func | 22 | #define PPC_SYS(func) .llong DOTSYM(ppc_##func),DOTSYM(ppc_##func) |
23 | #define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall | 23 | #define OLDSYS(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) |
24 | #define SYS32ONLY(func) .llong .sys_ni_syscall,.compat_sys_##func | 24 | #define SYS32ONLY(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) |
25 | #define SYSX(f, f3264, f32) .llong .f,.f3264 | 25 | #define SYSX(f, f3264, f32) .llong DOTSYM(f),DOTSYM(f3264) |
26 | #else | 26 | #else |
27 | #define SYSCALL(func) .long sys_##func | 27 | #define SYSCALL(func) .long sys_##func |
28 | #define COMPAT_SYS(func) .long sys_##func | 28 | #define COMPAT_SYS(func) .long sys_##func |
@@ -36,6 +36,8 @@ | |||
36 | #define PPC_SYS_SPU(func) PPC_SYS(func) | 36 | #define PPC_SYS_SPU(func) PPC_SYS(func) |
37 | #define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) | 37 | #define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) |
38 | 38 | ||
39 | .section .rodata,"a" | ||
40 | |||
39 | #ifdef CONFIG_PPC64 | 41 | #ifdef CONFIG_PPC64 |
40 | #define sys_sigpending sys_ni_syscall | 42 | #define sys_sigpending sys_ni_syscall |
41 | #define sys_old_getrlimit sys_ni_syscall | 43 | #define sys_old_getrlimit sys_ni_syscall |
@@ -43,5 +45,7 @@ | |||
43 | .p2align 3 | 45 | .p2align 3 |
44 | #endif | 46 | #endif |
45 | 47 | ||
46 | _GLOBAL(sys_call_table) | 48 | .globl sys_call_table |
49 | sys_call_table: | ||
50 | |||
47 | #include <asm/systbl.h> | 51 | #include <asm/systbl.h> |
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 508c54b92fa6..ee061c3715de 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -42,7 +42,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | |||
42 | /* Stack frame offsets for local variables. */ | 42 | /* Stack frame offsets for local variables. */ |
43 | #define TM_FRAME_L0 TM_FRAME_SIZE-16 | 43 | #define TM_FRAME_L0 TM_FRAME_SIZE-16 |
44 | #define TM_FRAME_L1 TM_FRAME_SIZE-8 | 44 | #define TM_FRAME_L1 TM_FRAME_SIZE-8 |
45 | #define STACK_PARAM(x) (48+((x)*8)) | ||
46 | 45 | ||
47 | 46 | ||
48 | /* In order to access the TM SPRs, TM must be enabled. So, do so: */ | 47 | /* In order to access the TM SPRs, TM must be enabled. So, do so: */ |
@@ -109,12 +108,12 @@ _GLOBAL(tm_reclaim) | |||
109 | mflr r0 | 108 | mflr r0 |
110 | stw r6, 8(r1) | 109 | stw r6, 8(r1) |
111 | std r0, 16(r1) | 110 | std r0, 16(r1) |
112 | std r2, 40(r1) | 111 | std r2, STK_GOT(r1) |
113 | stdu r1, -TM_FRAME_SIZE(r1) | 112 | stdu r1, -TM_FRAME_SIZE(r1) |
114 | 113 | ||
115 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */ | 114 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */ |
116 | 115 | ||
117 | std r3, STACK_PARAM(0)(r1) | 116 | std r3, STK_PARAM(R3)(r1) |
118 | SAVE_NVGPRS(r1) | 117 | SAVE_NVGPRS(r1) |
119 | 118 | ||
120 | /* We need to setup MSR for VSX register save instructions. Here we | 119 | /* We need to setup MSR for VSX register save instructions. Here we |
@@ -210,7 +209,7 @@ dont_backup_fp: | |||
210 | /* Now get some more GPRS free */ | 209 | /* Now get some more GPRS free */ |
211 | std r7, GPR7(r1) /* Temporary stash */ | 210 | std r7, GPR7(r1) /* Temporary stash */ |
212 | std r12, GPR12(r1) /* '' '' '' */ | 211 | std r12, GPR12(r1) /* '' '' '' */ |
213 | ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ | 212 | ld r12, STK_PARAM(R3)(r1) /* Param 0, thread_struct * */ |
214 | 213 | ||
215 | std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ | 214 | std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ |
216 | 215 | ||
@@ -297,7 +296,7 @@ dont_backup_fp: | |||
297 | ld r0, 16(r1) | 296 | ld r0, 16(r1) |
298 | mtcr r4 | 297 | mtcr r4 |
299 | mtlr r0 | 298 | mtlr r0 |
300 | ld r2, 40(r1) | 299 | ld r2, STK_GOT(r1) |
301 | 300 | ||
302 | /* Load system default DSCR */ | 301 | /* Load system default DSCR */ |
303 | ld r4, DSCR_DEFAULT@toc(r2) | 302 | ld r4, DSCR_DEFAULT@toc(r2) |
@@ -320,7 +319,7 @@ _GLOBAL(__tm_recheckpoint) | |||
320 | mflr r0 | 319 | mflr r0 |
321 | stw r5, 8(r1) | 320 | stw r5, 8(r1) |
322 | std r0, 16(r1) | 321 | std r0, 16(r1) |
323 | std r2, 40(r1) | 322 | std r2, STK_GOT(r1) |
324 | stdu r1, -TM_FRAME_SIZE(r1) | 323 | stdu r1, -TM_FRAME_SIZE(r1) |
325 | 324 | ||
326 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. | 325 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. |
@@ -478,7 +477,7 @@ restore_gprs: | |||
478 | ld r0, 16(r1) | 477 | ld r0, 16(r1) |
479 | mtcr r4 | 478 | mtcr r4 |
480 | mtlr r0 | 479 | mtlr r0 |
481 | ld r2, 40(r1) | 480 | ld r2, STK_GOT(r1) |
482 | 481 | ||
483 | /* Load system default DSCR */ | 482 | /* Load system default DSCR */ |
484 | ld r4, DSCR_DEFAULT@toc(r2) | 483 | ld r4, DSCR_DEFAULT@toc(r2) |
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index e18e3cfc32de..8c86422a1e37 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S | |||
@@ -171,7 +171,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
171 | #endif /* CONFIG_SMP */ | 171 | #endif /* CONFIG_SMP */ |
172 | 172 | ||
173 | /* Jump to partition switch code */ | 173 | /* Jump to partition switch code */ |
174 | bl .kvmppc_hv_entry_trampoline | 174 | bl kvmppc_hv_entry_trampoline |
175 | nop | 175 | nop |
176 | 176 | ||
177 | /* | 177 | /* |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b031f932c0cc..9f0ad718e476 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -1658,7 +1658,7 @@ kvmppc_hdsi: | |||
1658 | /* Search the hash table. */ | 1658 | /* Search the hash table. */ |
1659 | mr r3, r9 /* vcpu pointer */ | 1659 | mr r3, r9 /* vcpu pointer */ |
1660 | li r7, 1 /* data fault */ | 1660 | li r7, 1 /* data fault */ |
1661 | bl .kvmppc_hpte_hv_fault | 1661 | bl kvmppc_hpte_hv_fault |
1662 | ld r9, HSTATE_KVM_VCPU(r13) | 1662 | ld r9, HSTATE_KVM_VCPU(r13) |
1663 | ld r10, VCPU_PC(r9) | 1663 | ld r10, VCPU_PC(r9) |
1664 | ld r11, VCPU_MSR(r9) | 1664 | ld r11, VCPU_MSR(r9) |
@@ -1732,7 +1732,7 @@ kvmppc_hisi: | |||
1732 | mr r4, r10 | 1732 | mr r4, r10 |
1733 | mr r6, r11 | 1733 | mr r6, r11 |
1734 | li r7, 0 /* instruction fault */ | 1734 | li r7, 0 /* instruction fault */ |
1735 | bl .kvmppc_hpte_hv_fault | 1735 | bl kvmppc_hpte_hv_fault |
1736 | ld r9, HSTATE_KVM_VCPU(r13) | 1736 | ld r9, HSTATE_KVM_VCPU(r13) |
1737 | ld r10, VCPU_PC(r9) | 1737 | ld r10, VCPU_PC(r9) |
1738 | ld r11, VCPU_MSR(r9) | 1738 | ld r11, VCPU_MSR(r9) |
@@ -1806,16 +1806,16 @@ hcall_real_fallback: | |||
1806 | .globl hcall_real_table | 1806 | .globl hcall_real_table |
1807 | hcall_real_table: | 1807 | hcall_real_table: |
1808 | .long 0 /* 0 - unused */ | 1808 | .long 0 /* 0 - unused */ |
1809 | .long .kvmppc_h_remove - hcall_real_table | 1809 | .long DOTSYM(kvmppc_h_remove) - hcall_real_table |
1810 | .long .kvmppc_h_enter - hcall_real_table | 1810 | .long DOTSYM(kvmppc_h_enter) - hcall_real_table |
1811 | .long .kvmppc_h_read - hcall_real_table | 1811 | .long DOTSYM(kvmppc_h_read) - hcall_real_table |
1812 | .long 0 /* 0x10 - H_CLEAR_MOD */ | 1812 | .long 0 /* 0x10 - H_CLEAR_MOD */ |
1813 | .long 0 /* 0x14 - H_CLEAR_REF */ | 1813 | .long 0 /* 0x14 - H_CLEAR_REF */ |
1814 | .long .kvmppc_h_protect - hcall_real_table | 1814 | .long DOTSYM(kvmppc_h_protect) - hcall_real_table |
1815 | .long .kvmppc_h_get_tce - hcall_real_table | 1815 | .long DOTSYM(kvmppc_h_get_tce) - hcall_real_table |
1816 | .long .kvmppc_h_put_tce - hcall_real_table | 1816 | .long DOTSYM(kvmppc_h_put_tce) - hcall_real_table |
1817 | .long 0 /* 0x24 - H_SET_SPRG0 */ | 1817 | .long 0 /* 0x24 - H_SET_SPRG0 */ |
1818 | .long .kvmppc_h_set_dabr - hcall_real_table | 1818 | .long DOTSYM(kvmppc_h_set_dabr) - hcall_real_table |
1819 | .long 0 /* 0x2c */ | 1819 | .long 0 /* 0x2c */ |
1820 | .long 0 /* 0x30 */ | 1820 | .long 0 /* 0x30 */ |
1821 | .long 0 /* 0x34 */ | 1821 | .long 0 /* 0x34 */ |
@@ -1831,11 +1831,11 @@ hcall_real_table: | |||
1831 | .long 0 /* 0x5c */ | 1831 | .long 0 /* 0x5c */ |
1832 | .long 0 /* 0x60 */ | 1832 | .long 0 /* 0x60 */ |
1833 | #ifdef CONFIG_KVM_XICS | 1833 | #ifdef CONFIG_KVM_XICS |
1834 | .long .kvmppc_rm_h_eoi - hcall_real_table | 1834 | .long DOTSYM(kvmppc_rm_h_eoi) - hcall_real_table |
1835 | .long .kvmppc_rm_h_cppr - hcall_real_table | 1835 | .long DOTSYM(kvmppc_rm_h_cppr) - hcall_real_table |
1836 | .long .kvmppc_rm_h_ipi - hcall_real_table | 1836 | .long DOTSYM(kvmppc_rm_h_ipi) - hcall_real_table |
1837 | .long 0 /* 0x70 - H_IPOLL */ | 1837 | .long 0 /* 0x70 - H_IPOLL */ |
1838 | .long .kvmppc_rm_h_xirr - hcall_real_table | 1838 | .long DOTSYM(kvmppc_rm_h_xirr) - hcall_real_table |
1839 | #else | 1839 | #else |
1840 | .long 0 /* 0x64 - H_EOI */ | 1840 | .long 0 /* 0x64 - H_EOI */ |
1841 | .long 0 /* 0x68 - H_CPPR */ | 1841 | .long 0 /* 0x68 - H_CPPR */ |
@@ -1869,7 +1869,7 @@ hcall_real_table: | |||
1869 | .long 0 /* 0xd4 */ | 1869 | .long 0 /* 0xd4 */ |
1870 | .long 0 /* 0xd8 */ | 1870 | .long 0 /* 0xd8 */ |
1871 | .long 0 /* 0xdc */ | 1871 | .long 0 /* 0xdc */ |
1872 | .long .kvmppc_h_cede - hcall_real_table | 1872 | .long DOTSYM(kvmppc_h_cede) - hcall_real_table |
1873 | .long 0 /* 0xe4 */ | 1873 | .long 0 /* 0xe4 */ |
1874 | .long 0 /* 0xe8 */ | 1874 | .long 0 /* 0xe8 */ |
1875 | .long 0 /* 0xec */ | 1875 | .long 0 /* 0xec */ |
@@ -1886,11 +1886,11 @@ hcall_real_table: | |||
1886 | .long 0 /* 0x118 */ | 1886 | .long 0 /* 0x118 */ |
1887 | .long 0 /* 0x11c */ | 1887 | .long 0 /* 0x11c */ |
1888 | .long 0 /* 0x120 */ | 1888 | .long 0 /* 0x120 */ |
1889 | .long .kvmppc_h_bulk_remove - hcall_real_table | 1889 | .long DOTSYM(kvmppc_h_bulk_remove) - hcall_real_table |
1890 | .long 0 /* 0x128 */ | 1890 | .long 0 /* 0x128 */ |
1891 | .long 0 /* 0x12c */ | 1891 | .long 0 /* 0x12c */ |
1892 | .long 0 /* 0x130 */ | 1892 | .long 0 /* 0x130 */ |
1893 | .long .kvmppc_h_set_xdabr - hcall_real_table | 1893 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table |
1894 | hcall_real_table_end: | 1894 | hcall_real_table_end: |
1895 | 1895 | ||
1896 | ignore_hdec: | 1896 | ignore_hdec: |
@@ -2115,7 +2115,7 @@ kvm_cede_exit: | |||
2115 | /* Try to handle a machine check in real mode */ | 2115 | /* Try to handle a machine check in real mode */ |
2116 | machine_check_realmode: | 2116 | machine_check_realmode: |
2117 | mr r3, r9 /* get vcpu pointer */ | 2117 | mr r3, r9 /* get vcpu pointer */ |
2118 | bl .kvmppc_realmode_machine_check | 2118 | bl kvmppc_realmode_machine_check |
2119 | nop | 2119 | nop |
2120 | cmpdi r3, 0 /* continue exiting from guest? */ | 2120 | cmpdi r3, 0 /* continue exiting from guest? */ |
2121 | ld r9, HSTATE_KVM_VCPU(r13) | 2121 | ld r9, HSTATE_KVM_VCPU(r13) |
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S index 9f9434a85264..e59c9c2ebe98 100644 --- a/arch/powerpc/lib/copypage_64.S +++ b/arch/powerpc/lib/copypage_64.S | |||
@@ -20,7 +20,7 @@ _GLOBAL(copy_page) | |||
20 | BEGIN_FTR_SECTION | 20 | BEGIN_FTR_SECTION |
21 | lis r5,PAGE_SIZE@h | 21 | lis r5,PAGE_SIZE@h |
22 | FTR_SECTION_ELSE | 22 | FTR_SECTION_ELSE |
23 | b .copypage_power7 | 23 | b copypage_power7 |
24 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) | 24 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) |
25 | ori r5,r5,PAGE_SIZE@l | 25 | ori r5,r5,PAGE_SIZE@l |
26 | BEGIN_FTR_SECTION | 26 | BEGIN_FTR_SECTION |
diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index 395c594722a2..d7dafb3777ac 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S | |||
@@ -56,15 +56,15 @@ _GLOBAL(copypage_power7) | |||
56 | 56 | ||
57 | #ifdef CONFIG_ALTIVEC | 57 | #ifdef CONFIG_ALTIVEC |
58 | mflr r0 | 58 | mflr r0 |
59 | std r3,48(r1) | 59 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
60 | std r4,56(r1) | 60 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
61 | std r0,16(r1) | 61 | std r0,16(r1) |
62 | stdu r1,-STACKFRAMESIZE(r1) | 62 | stdu r1,-STACKFRAMESIZE(r1) |
63 | bl .enter_vmx_copy | 63 | bl enter_vmx_copy |
64 | cmpwi r3,0 | 64 | cmpwi r3,0 |
65 | ld r0,STACKFRAMESIZE+16(r1) | 65 | ld r0,STACKFRAMESIZE+16(r1) |
66 | ld r3,STACKFRAMESIZE+48(r1) | 66 | ld r3,STK_REG(R31)(r1) |
67 | ld r4,STACKFRAMESIZE+56(r1) | 67 | ld r4,STK_REG(R30)(r1) |
68 | mtlr r0 | 68 | mtlr r0 |
69 | 69 | ||
70 | li r0,(PAGE_SIZE/128) | 70 | li r0,(PAGE_SIZE/128) |
@@ -103,7 +103,7 @@ _GLOBAL(copypage_power7) | |||
103 | addi r3,r3,128 | 103 | addi r3,r3,128 |
104 | bdnz 1b | 104 | bdnz 1b |
105 | 105 | ||
106 | b .exit_vmx_copy /* tail call optimise */ | 106 | b exit_vmx_copy /* tail call optimise */ |
107 | 107 | ||
108 | #else | 108 | #else |
109 | li r0,(PAGE_SIZE/128) | 109 | li r0,(PAGE_SIZE/128) |
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 596a285c0755..0860ee46013c 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S | |||
@@ -18,7 +18,7 @@ | |||
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | .align 7 | 20 | .align 7 |
21 | _GLOBAL(__copy_tofrom_user) | 21 | _GLOBAL_TOC(__copy_tofrom_user) |
22 | BEGIN_FTR_SECTION | 22 | BEGIN_FTR_SECTION |
23 | nop | 23 | nop |
24 | FTR_SECTION_ELSE | 24 | FTR_SECTION_ELSE |
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index e8e9c36dc784..c46c876ac96a 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S | |||
@@ -66,7 +66,7 @@ | |||
66 | ld r15,STK_REG(R15)(r1) | 66 | ld r15,STK_REG(R15)(r1) |
67 | ld r14,STK_REG(R14)(r1) | 67 | ld r14,STK_REG(R14)(r1) |
68 | .Ldo_err3: | 68 | .Ldo_err3: |
69 | bl .exit_vmx_usercopy | 69 | bl exit_vmx_usercopy |
70 | ld r0,STACKFRAMESIZE+16(r1) | 70 | ld r0,STACKFRAMESIZE+16(r1) |
71 | mtlr r0 | 71 | mtlr r0 |
72 | b .Lexit | 72 | b .Lexit |
@@ -85,9 +85,9 @@ | |||
85 | .Lexit: | 85 | .Lexit: |
86 | addi r1,r1,STACKFRAMESIZE | 86 | addi r1,r1,STACKFRAMESIZE |
87 | .Ldo_err1: | 87 | .Ldo_err1: |
88 | ld r3,48(r1) | 88 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
89 | ld r4,56(r1) | 89 | ld r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
90 | ld r5,64(r1) | 90 | ld r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
91 | b __copy_tofrom_user_base | 91 | b __copy_tofrom_user_base |
92 | 92 | ||
93 | 93 | ||
@@ -96,18 +96,18 @@ _GLOBAL(__copy_tofrom_user_power7) | |||
96 | cmpldi r5,16 | 96 | cmpldi r5,16 |
97 | cmpldi cr1,r5,4096 | 97 | cmpldi cr1,r5,4096 |
98 | 98 | ||
99 | std r3,48(r1) | 99 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
100 | std r4,56(r1) | 100 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
101 | std r5,64(r1) | 101 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
102 | 102 | ||
103 | blt .Lshort_copy | 103 | blt .Lshort_copy |
104 | bgt cr1,.Lvmx_copy | 104 | bgt cr1,.Lvmx_copy |
105 | #else | 105 | #else |
106 | cmpldi r5,16 | 106 | cmpldi r5,16 |
107 | 107 | ||
108 | std r3,48(r1) | 108 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
109 | std r4,56(r1) | 109 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
110 | std r5,64(r1) | 110 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
111 | 111 | ||
112 | blt .Lshort_copy | 112 | blt .Lshort_copy |
113 | #endif | 113 | #endif |
@@ -295,12 +295,12 @@ err1; stb r0,0(r3) | |||
295 | mflr r0 | 295 | mflr r0 |
296 | std r0,16(r1) | 296 | std r0,16(r1) |
297 | stdu r1,-STACKFRAMESIZE(r1) | 297 | stdu r1,-STACKFRAMESIZE(r1) |
298 | bl .enter_vmx_usercopy | 298 | bl enter_vmx_usercopy |
299 | cmpwi cr1,r3,0 | 299 | cmpwi cr1,r3,0 |
300 | ld r0,STACKFRAMESIZE+16(r1) | 300 | ld r0,STACKFRAMESIZE+16(r1) |
301 | ld r3,STACKFRAMESIZE+48(r1) | 301 | ld r3,STK_REG(R31)(r1) |
302 | ld r4,STACKFRAMESIZE+56(r1) | 302 | ld r4,STK_REG(R30)(r1) |
303 | ld r5,STACKFRAMESIZE+64(r1) | 303 | ld r5,STK_REG(R29)(r1) |
304 | mtlr r0 | 304 | mtlr r0 |
305 | 305 | ||
306 | /* | 306 | /* |
@@ -514,7 +514,7 @@ err3; lbz r0,0(r4) | |||
514 | err3; stb r0,0(r3) | 514 | err3; stb r0,0(r3) |
515 | 515 | ||
516 | 15: addi r1,r1,STACKFRAMESIZE | 516 | 15: addi r1,r1,STACKFRAMESIZE |
517 | b .exit_vmx_usercopy /* tail call optimise */ | 517 | b exit_vmx_usercopy /* tail call optimise */ |
518 | 518 | ||
519 | .Lvmx_unaligned_copy: | 519 | .Lvmx_unaligned_copy: |
520 | /* Get the destination 16B aligned */ | 520 | /* Get the destination 16B aligned */ |
@@ -717,5 +717,5 @@ err3; lbz r0,0(r4) | |||
717 | err3; stb r0,0(r3) | 717 | err3; stb r0,0(r3) |
718 | 718 | ||
719 | 15: addi r1,r1,STACKFRAMESIZE | 719 | 15: addi r1,r1,STACKFRAMESIZE |
720 | b .exit_vmx_usercopy /* tail call optimise */ | 720 | b exit_vmx_usercopy /* tail call optimise */ |
721 | #endif /* CONFiG_ALTIVEC */ | 721 | #endif /* CONFiG_ALTIVEC */ |
diff --git a/arch/powerpc/lib/hweight_64.S b/arch/powerpc/lib/hweight_64.S index 9b96ff2ecd4d..19e66001a4f9 100644 --- a/arch/powerpc/lib/hweight_64.S +++ b/arch/powerpc/lib/hweight_64.S | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | _GLOBAL(__arch_hweight8) | 25 | _GLOBAL(__arch_hweight8) |
26 | BEGIN_FTR_SECTION | 26 | BEGIN_FTR_SECTION |
27 | b .__sw_hweight8 | 27 | b __sw_hweight8 |
28 | nop | 28 | nop |
29 | nop | 29 | nop |
30 | FTR_SECTION_ELSE | 30 | FTR_SECTION_ELSE |
@@ -35,7 +35,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
35 | 35 | ||
36 | _GLOBAL(__arch_hweight16) | 36 | _GLOBAL(__arch_hweight16) |
37 | BEGIN_FTR_SECTION | 37 | BEGIN_FTR_SECTION |
38 | b .__sw_hweight16 | 38 | b __sw_hweight16 |
39 | nop | 39 | nop |
40 | nop | 40 | nop |
41 | nop | 41 | nop |
@@ -57,7 +57,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
57 | 57 | ||
58 | _GLOBAL(__arch_hweight32) | 58 | _GLOBAL(__arch_hweight32) |
59 | BEGIN_FTR_SECTION | 59 | BEGIN_FTR_SECTION |
60 | b .__sw_hweight32 | 60 | b __sw_hweight32 |
61 | nop | 61 | nop |
62 | nop | 62 | nop |
63 | nop | 63 | nop |
@@ -82,7 +82,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
82 | 82 | ||
83 | _GLOBAL(__arch_hweight64) | 83 | _GLOBAL(__arch_hweight64) |
84 | BEGIN_FTR_SECTION | 84 | BEGIN_FTR_SECTION |
85 | b .__sw_hweight64 | 85 | b __sw_hweight64 |
86 | nop | 86 | nop |
87 | nop | 87 | nop |
88 | nop | 88 | nop |
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index f4fcb0bc6563..0738f96befbf 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S | |||
@@ -79,8 +79,8 @@ _GLOBAL(memset) | |||
79 | 79 | ||
80 | _GLOBAL(memmove) | 80 | _GLOBAL(memmove) |
81 | cmplw 0,r3,r4 | 81 | cmplw 0,r3,r4 |
82 | bgt .backwards_memcpy | 82 | bgt backwards_memcpy |
83 | b .memcpy | 83 | b memcpy |
84 | 84 | ||
85 | _GLOBAL(backwards_memcpy) | 85 | _GLOBAL(backwards_memcpy) |
86 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | 86 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ |
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index dc4ba7953b92..32a06ec395d2 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S | |||
@@ -10,12 +10,12 @@ | |||
10 | #include <asm/ppc_asm.h> | 10 | #include <asm/ppc_asm.h> |
11 | 11 | ||
12 | .align 7 | 12 | .align 7 |
13 | _GLOBAL(memcpy) | 13 | _GLOBAL_TOC(memcpy) |
14 | BEGIN_FTR_SECTION | 14 | BEGIN_FTR_SECTION |
15 | #ifdef __LITTLE_ENDIAN__ | 15 | #ifdef __LITTLE_ENDIAN__ |
16 | cmpdi cr7,r5,0 | 16 | cmpdi cr7,r5,0 |
17 | #else | 17 | #else |
18 | std r3,48(r1) /* save destination pointer for return value */ | 18 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* save destination pointer for return value */ |
19 | #endif | 19 | #endif |
20 | FTR_SECTION_ELSE | 20 | FTR_SECTION_ELSE |
21 | #ifndef SELFTEST | 21 | #ifndef SELFTEST |
@@ -88,7 +88,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
88 | 2: bf cr7*4+3,3f | 88 | 2: bf cr7*4+3,3f |
89 | lbz r9,8(r4) | 89 | lbz r9,8(r4) |
90 | stb r9,0(r3) | 90 | stb r9,0(r3) |
91 | 3: ld r3,48(r1) /* return dest pointer */ | 91 | 3: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
92 | blr | 92 | blr |
93 | 93 | ||
94 | .Lsrc_unaligned: | 94 | .Lsrc_unaligned: |
@@ -171,7 +171,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
171 | 2: bf cr7*4+3,3f | 171 | 2: bf cr7*4+3,3f |
172 | rotldi r9,r9,8 | 172 | rotldi r9,r9,8 |
173 | stb r9,0(r3) | 173 | stb r9,0(r3) |
174 | 3: ld r3,48(r1) /* return dest pointer */ | 174 | 3: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
175 | blr | 175 | blr |
176 | 176 | ||
177 | .Ldst_unaligned: | 177 | .Ldst_unaligned: |
@@ -216,6 +216,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
216 | 3: bf cr7*4+3,4f | 216 | 3: bf cr7*4+3,4f |
217 | lbz r0,0(r4) | 217 | lbz r0,0(r4) |
218 | stb r0,0(r3) | 218 | stb r0,0(r3) |
219 | 4: ld r3,48(r1) /* return dest pointer */ | 219 | 4: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
220 | blr | 220 | blr |
221 | #endif | 221 | #endif |
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index e4177dbea6bd..2ff5c142f87b 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S | |||
@@ -33,14 +33,14 @@ _GLOBAL(memcpy_power7) | |||
33 | cmpldi r5,16 | 33 | cmpldi r5,16 |
34 | cmpldi cr1,r5,4096 | 34 | cmpldi cr1,r5,4096 |
35 | 35 | ||
36 | std r3,48(r1) | 36 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
37 | 37 | ||
38 | blt .Lshort_copy | 38 | blt .Lshort_copy |
39 | bgt cr1,.Lvmx_copy | 39 | bgt cr1,.Lvmx_copy |
40 | #else | 40 | #else |
41 | cmpldi r5,16 | 41 | cmpldi r5,16 |
42 | 42 | ||
43 | std r3,48(r1) | 43 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
44 | 44 | ||
45 | blt .Lshort_copy | 45 | blt .Lshort_copy |
46 | #endif | 46 | #endif |
@@ -216,7 +216,7 @@ _GLOBAL(memcpy_power7) | |||
216 | lbz r0,0(r4) | 216 | lbz r0,0(r4) |
217 | stb r0,0(r3) | 217 | stb r0,0(r3) |
218 | 218 | ||
219 | 15: ld r3,48(r1) | 219 | 15: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
220 | blr | 220 | blr |
221 | 221 | ||
222 | .Lunwind_stack_nonvmx_copy: | 222 | .Lunwind_stack_nonvmx_copy: |
@@ -226,16 +226,16 @@ _GLOBAL(memcpy_power7) | |||
226 | #ifdef CONFIG_ALTIVEC | 226 | #ifdef CONFIG_ALTIVEC |
227 | .Lvmx_copy: | 227 | .Lvmx_copy: |
228 | mflr r0 | 228 | mflr r0 |
229 | std r4,56(r1) | 229 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
230 | std r5,64(r1) | 230 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
231 | std r0,16(r1) | 231 | std r0,16(r1) |
232 | stdu r1,-STACKFRAMESIZE(r1) | 232 | stdu r1,-STACKFRAMESIZE(r1) |
233 | bl .enter_vmx_copy | 233 | bl enter_vmx_copy |
234 | cmpwi cr1,r3,0 | 234 | cmpwi cr1,r3,0 |
235 | ld r0,STACKFRAMESIZE+16(r1) | 235 | ld r0,STACKFRAMESIZE+16(r1) |
236 | ld r3,STACKFRAMESIZE+48(r1) | 236 | ld r3,STK_REG(R31)(r1) |
237 | ld r4,STACKFRAMESIZE+56(r1) | 237 | ld r4,STK_REG(R30)(r1) |
238 | ld r5,STACKFRAMESIZE+64(r1) | 238 | ld r5,STK_REG(R29)(r1) |
239 | mtlr r0 | 239 | mtlr r0 |
240 | 240 | ||
241 | /* | 241 | /* |
@@ -447,8 +447,8 @@ _GLOBAL(memcpy_power7) | |||
447 | stb r0,0(r3) | 447 | stb r0,0(r3) |
448 | 448 | ||
449 | 15: addi r1,r1,STACKFRAMESIZE | 449 | 15: addi r1,r1,STACKFRAMESIZE |
450 | ld r3,48(r1) | 450 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
451 | b .exit_vmx_copy /* tail call optimise */ | 451 | b exit_vmx_copy /* tail call optimise */ |
452 | 452 | ||
453 | .Lvmx_unaligned_copy: | 453 | .Lvmx_unaligned_copy: |
454 | /* Get the destination 16B aligned */ | 454 | /* Get the destination 16B aligned */ |
@@ -651,6 +651,6 @@ _GLOBAL(memcpy_power7) | |||
651 | stb r0,0(r3) | 651 | stb r0,0(r3) |
652 | 652 | ||
653 | 15: addi r1,r1,STACKFRAMESIZE | 653 | 15: addi r1,r1,STACKFRAMESIZE |
654 | ld r3,48(r1) | 654 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
655 | b .exit_vmx_copy /* tail call optimise */ | 655 | b exit_vmx_copy /* tail call optimise */ |
656 | #endif /* CONFiG_ALTIVEC */ | 656 | #endif /* CONFiG_ALTIVEC */ |
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 1136d26a95ae..057cbbb4c576 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S | |||
@@ -159,7 +159,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
159 | BEGIN_FTR_SECTION | 159 | BEGIN_FTR_SECTION |
160 | mr r4,r30 | 160 | mr r4,r30 |
161 | mr r5,r7 | 161 | mr r5,r7 |
162 | bl .hash_page_do_lazy_icache | 162 | bl hash_page_do_lazy_icache |
163 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 163 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
164 | 164 | ||
165 | /* At this point, r3 contains new PP bits, save them in | 165 | /* At this point, r3 contains new PP bits, save them in |
@@ -201,7 +201,8 @@ htab_insert_pte: | |||
201 | li r8,MMU_PAGE_4K /* page size */ | 201 | li r8,MMU_PAGE_4K /* page size */ |
202 | li r9,MMU_PAGE_4K /* actual page size */ | 202 | li r9,MMU_PAGE_4K /* actual page size */ |
203 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 203 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
204 | _GLOBAL(htab_call_hpte_insert1) | 204 | .globl htab_call_hpte_insert1 |
205 | htab_call_hpte_insert1: | ||
205 | bl . /* Patched by htab_finish_init() */ | 206 | bl . /* Patched by htab_finish_init() */ |
206 | cmpdi 0,r3,0 | 207 | cmpdi 0,r3,0 |
207 | bge htab_pte_insert_ok /* Insertion successful */ | 208 | bge htab_pte_insert_ok /* Insertion successful */ |
@@ -225,7 +226,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
225 | li r8,MMU_PAGE_4K /* page size */ | 226 | li r8,MMU_PAGE_4K /* page size */ |
226 | li r9,MMU_PAGE_4K /* actual page size */ | 227 | li r9,MMU_PAGE_4K /* actual page size */ |
227 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 228 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
228 | _GLOBAL(htab_call_hpte_insert2) | 229 | .globl htab_call_hpte_insert2 |
230 | htab_call_hpte_insert2: | ||
229 | bl . /* Patched by htab_finish_init() */ | 231 | bl . /* Patched by htab_finish_init() */ |
230 | cmpdi 0,r3,0 | 232 | cmpdi 0,r3,0 |
231 | bge+ htab_pte_insert_ok /* Insertion successful */ | 233 | bge+ htab_pte_insert_ok /* Insertion successful */ |
@@ -242,7 +244,8 @@ _GLOBAL(htab_call_hpte_insert2) | |||
242 | 2: and r0,r5,r27 | 244 | 2: and r0,r5,r27 |
243 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 245 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
244 | /* Call ppc_md.hpte_remove */ | 246 | /* Call ppc_md.hpte_remove */ |
245 | _GLOBAL(htab_call_hpte_remove) | 247 | .globl htab_call_hpte_remove |
248 | htab_call_hpte_remove: | ||
246 | bl . /* Patched by htab_finish_init() */ | 249 | bl . /* Patched by htab_finish_init() */ |
247 | 250 | ||
248 | /* Try all again */ | 251 | /* Try all again */ |
@@ -296,7 +299,8 @@ htab_modify_pte: | |||
296 | li r7,MMU_PAGE_4K /* actual page size */ | 299 | li r7,MMU_PAGE_4K /* actual page size */ |
297 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 300 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
298 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 301 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
299 | _GLOBAL(htab_call_hpte_updatepp) | 302 | .globl htab_call_hpte_updatepp |
303 | htab_call_hpte_updatepp: | ||
300 | bl . /* Patched by htab_finish_init() */ | 304 | bl . /* Patched by htab_finish_init() */ |
301 | 305 | ||
302 | /* if we failed because typically the HPTE wasn't really here | 306 | /* if we failed because typically the HPTE wasn't really here |
@@ -471,7 +475,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
471 | BEGIN_FTR_SECTION | 475 | BEGIN_FTR_SECTION |
472 | mr r4,r30 | 476 | mr r4,r30 |
473 | mr r5,r7 | 477 | mr r5,r7 |
474 | bl .hash_page_do_lazy_icache | 478 | bl hash_page_do_lazy_icache |
475 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 479 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
476 | 480 | ||
477 | /* At this point, r3 contains new PP bits, save them in | 481 | /* At this point, r3 contains new PP bits, save them in |
@@ -526,7 +530,8 @@ htab_special_pfn: | |||
526 | li r8,MMU_PAGE_4K /* page size */ | 530 | li r8,MMU_PAGE_4K /* page size */ |
527 | li r9,MMU_PAGE_4K /* actual page size */ | 531 | li r9,MMU_PAGE_4K /* actual page size */ |
528 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 532 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
529 | _GLOBAL(htab_call_hpte_insert1) | 533 | .globl htab_call_hpte_insert1 |
534 | htab_call_hpte_insert1: | ||
530 | bl . /* patched by htab_finish_init() */ | 535 | bl . /* patched by htab_finish_init() */ |
531 | cmpdi 0,r3,0 | 536 | cmpdi 0,r3,0 |
532 | bge htab_pte_insert_ok /* Insertion successful */ | 537 | bge htab_pte_insert_ok /* Insertion successful */ |
@@ -554,7 +559,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
554 | li r8,MMU_PAGE_4K /* page size */ | 559 | li r8,MMU_PAGE_4K /* page size */ |
555 | li r9,MMU_PAGE_4K /* actual page size */ | 560 | li r9,MMU_PAGE_4K /* actual page size */ |
556 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 561 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
557 | _GLOBAL(htab_call_hpte_insert2) | 562 | .globl htab_call_hpte_insert2 |
563 | htab_call_hpte_insert2: | ||
558 | bl . /* patched by htab_finish_init() */ | 564 | bl . /* patched by htab_finish_init() */ |
559 | cmpdi 0,r3,0 | 565 | cmpdi 0,r3,0 |
560 | bge+ htab_pte_insert_ok /* Insertion successful */ | 566 | bge+ htab_pte_insert_ok /* Insertion successful */ |
@@ -571,7 +577,8 @@ _GLOBAL(htab_call_hpte_insert2) | |||
571 | 2: and r0,r5,r27 | 577 | 2: and r0,r5,r27 |
572 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 578 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
573 | /* Call ppc_md.hpte_remove */ | 579 | /* Call ppc_md.hpte_remove */ |
574 | _GLOBAL(htab_call_hpte_remove) | 580 | .globl htab_call_hpte_remove |
581 | htab_call_hpte_remove: | ||
575 | bl . /* patched by htab_finish_init() */ | 582 | bl . /* patched by htab_finish_init() */ |
576 | 583 | ||
577 | /* Try all again */ | 584 | /* Try all again */ |
@@ -588,7 +595,7 @@ htab_inval_old_hpte: | |||
588 | li r6,MMU_PAGE_64K /* psize */ | 595 | li r6,MMU_PAGE_64K /* psize */ |
589 | ld r7,STK_PARAM(R9)(r1) /* ssize */ | 596 | ld r7,STK_PARAM(R9)(r1) /* ssize */ |
590 | ld r8,STK_PARAM(R8)(r1) /* local */ | 597 | ld r8,STK_PARAM(R8)(r1) /* local */ |
591 | bl .flush_hash_page | 598 | bl flush_hash_page |
592 | /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ | 599 | /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ |
593 | lis r0,_PAGE_HPTE_SUB@h | 600 | lis r0,_PAGE_HPTE_SUB@h |
594 | ori r0,r0,_PAGE_HPTE_SUB@l | 601 | ori r0,r0,_PAGE_HPTE_SUB@l |
@@ -660,7 +667,8 @@ htab_modify_pte: | |||
660 | li r7,MMU_PAGE_4K /* actual page size */ | 667 | li r7,MMU_PAGE_4K /* actual page size */ |
661 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 668 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
662 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 669 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
663 | _GLOBAL(htab_call_hpte_updatepp) | 670 | .globl htab_call_hpte_updatepp |
671 | htab_call_hpte_updatepp: | ||
664 | bl . /* patched by htab_finish_init() */ | 672 | bl . /* patched by htab_finish_init() */ |
665 | 673 | ||
666 | /* if we failed because typically the HPTE wasn't really here | 674 | /* if we failed because typically the HPTE wasn't really here |
@@ -812,7 +820,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
812 | BEGIN_FTR_SECTION | 820 | BEGIN_FTR_SECTION |
813 | mr r4,r30 | 821 | mr r4,r30 |
814 | mr r5,r7 | 822 | mr r5,r7 |
815 | bl .hash_page_do_lazy_icache | 823 | bl hash_page_do_lazy_icache |
816 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 824 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
817 | 825 | ||
818 | /* At this point, r3 contains new PP bits, save them in | 826 | /* At this point, r3 contains new PP bits, save them in |
@@ -857,7 +865,8 @@ ht64_insert_pte: | |||
857 | li r8,MMU_PAGE_64K | 865 | li r8,MMU_PAGE_64K |
858 | li r9,MMU_PAGE_64K /* actual page size */ | 866 | li r9,MMU_PAGE_64K /* actual page size */ |
859 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 867 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
860 | _GLOBAL(ht64_call_hpte_insert1) | 868 | .globl ht64_call_hpte_insert1 |
869 | ht64_call_hpte_insert1: | ||
861 | bl . /* patched by htab_finish_init() */ | 870 | bl . /* patched by htab_finish_init() */ |
862 | cmpdi 0,r3,0 | 871 | cmpdi 0,r3,0 |
863 | bge ht64_pte_insert_ok /* Insertion successful */ | 872 | bge ht64_pte_insert_ok /* Insertion successful */ |
@@ -881,7 +890,8 @@ _GLOBAL(ht64_call_hpte_insert1) | |||
881 | li r8,MMU_PAGE_64K | 890 | li r8,MMU_PAGE_64K |
882 | li r9,MMU_PAGE_64K /* actual page size */ | 891 | li r9,MMU_PAGE_64K /* actual page size */ |
883 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 892 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
884 | _GLOBAL(ht64_call_hpte_insert2) | 893 | .globl ht64_call_hpte_insert2 |
894 | ht64_call_hpte_insert2: | ||
885 | bl . /* patched by htab_finish_init() */ | 895 | bl . /* patched by htab_finish_init() */ |
886 | cmpdi 0,r3,0 | 896 | cmpdi 0,r3,0 |
887 | bge+ ht64_pte_insert_ok /* Insertion successful */ | 897 | bge+ ht64_pte_insert_ok /* Insertion successful */ |
@@ -898,7 +908,8 @@ _GLOBAL(ht64_call_hpte_insert2) | |||
898 | 2: and r0,r5,r27 | 908 | 2: and r0,r5,r27 |
899 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 909 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
900 | /* Call ppc_md.hpte_remove */ | 910 | /* Call ppc_md.hpte_remove */ |
901 | _GLOBAL(ht64_call_hpte_remove) | 911 | .globl ht64_call_hpte_remove |
912 | ht64_call_hpte_remove: | ||
902 | bl . /* patched by htab_finish_init() */ | 913 | bl . /* patched by htab_finish_init() */ |
903 | 914 | ||
904 | /* Try all again */ | 915 | /* Try all again */ |
@@ -952,7 +963,8 @@ ht64_modify_pte: | |||
952 | li r7,MMU_PAGE_64K /* actual page size */ | 963 | li r7,MMU_PAGE_64K /* actual page size */ |
953 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 964 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
954 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 965 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
955 | _GLOBAL(ht64_call_hpte_updatepp) | 966 | .globl ht64_call_hpte_updatepp |
967 | ht64_call_hpte_updatepp: | ||
956 | bl . /* patched by htab_finish_init() */ | 968 | bl . /* patched by htab_finish_init() */ |
957 | 969 | ||
958 | /* if we failed because typically the HPTE wasn't really here | 970 | /* if we failed because typically the HPTE wasn't really here |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 12f1a397f502..91666f07e60a 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -622,47 +622,43 @@ int remove_section_mapping(unsigned long start, unsigned long end) | |||
622 | } | 622 | } |
623 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 623 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
624 | 624 | ||
625 | #define FUNCTION_TEXT(A) ((*(unsigned long *)(A))) | 625 | extern u32 htab_call_hpte_insert1[]; |
626 | extern u32 htab_call_hpte_insert2[]; | ||
627 | extern u32 htab_call_hpte_remove[]; | ||
628 | extern u32 htab_call_hpte_updatepp[]; | ||
629 | extern u32 ht64_call_hpte_insert1[]; | ||
630 | extern u32 ht64_call_hpte_insert2[]; | ||
631 | extern u32 ht64_call_hpte_remove[]; | ||
632 | extern u32 ht64_call_hpte_updatepp[]; | ||
626 | 633 | ||
627 | static void __init htab_finish_init(void) | 634 | static void __init htab_finish_init(void) |
628 | { | 635 | { |
629 | extern unsigned int *htab_call_hpte_insert1; | ||
630 | extern unsigned int *htab_call_hpte_insert2; | ||
631 | extern unsigned int *htab_call_hpte_remove; | ||
632 | extern unsigned int *htab_call_hpte_updatepp; | ||
633 | |||
634 | #ifdef CONFIG_PPC_HAS_HASH_64K | 636 | #ifdef CONFIG_PPC_HAS_HASH_64K |
635 | extern unsigned int *ht64_call_hpte_insert1; | ||
636 | extern unsigned int *ht64_call_hpte_insert2; | ||
637 | extern unsigned int *ht64_call_hpte_remove; | ||
638 | extern unsigned int *ht64_call_hpte_updatepp; | ||
639 | |||
640 | patch_branch(ht64_call_hpte_insert1, | 637 | patch_branch(ht64_call_hpte_insert1, |
641 | FUNCTION_TEXT(ppc_md.hpte_insert), | 638 | ppc_function_entry(ppc_md.hpte_insert), |
642 | BRANCH_SET_LINK); | 639 | BRANCH_SET_LINK); |
643 | patch_branch(ht64_call_hpte_insert2, | 640 | patch_branch(ht64_call_hpte_insert2, |
644 | FUNCTION_TEXT(ppc_md.hpte_insert), | 641 | ppc_function_entry(ppc_md.hpte_insert), |
645 | BRANCH_SET_LINK); | 642 | BRANCH_SET_LINK); |
646 | patch_branch(ht64_call_hpte_remove, | 643 | patch_branch(ht64_call_hpte_remove, |
647 | FUNCTION_TEXT(ppc_md.hpte_remove), | 644 | ppc_function_entry(ppc_md.hpte_remove), |
648 | BRANCH_SET_LINK); | 645 | BRANCH_SET_LINK); |
649 | patch_branch(ht64_call_hpte_updatepp, | 646 | patch_branch(ht64_call_hpte_updatepp, |
650 | FUNCTION_TEXT(ppc_md.hpte_updatepp), | 647 | ppc_function_entry(ppc_md.hpte_updatepp), |
651 | BRANCH_SET_LINK); | 648 | BRANCH_SET_LINK); |
652 | |||
653 | #endif /* CONFIG_PPC_HAS_HASH_64K */ | 649 | #endif /* CONFIG_PPC_HAS_HASH_64K */ |
654 | 650 | ||
655 | patch_branch(htab_call_hpte_insert1, | 651 | patch_branch(htab_call_hpte_insert1, |
656 | FUNCTION_TEXT(ppc_md.hpte_insert), | 652 | ppc_function_entry(ppc_md.hpte_insert), |
657 | BRANCH_SET_LINK); | 653 | BRANCH_SET_LINK); |
658 | patch_branch(htab_call_hpte_insert2, | 654 | patch_branch(htab_call_hpte_insert2, |
659 | FUNCTION_TEXT(ppc_md.hpte_insert), | 655 | ppc_function_entry(ppc_md.hpte_insert), |
660 | BRANCH_SET_LINK); | 656 | BRANCH_SET_LINK); |
661 | patch_branch(htab_call_hpte_remove, | 657 | patch_branch(htab_call_hpte_remove, |
662 | FUNCTION_TEXT(ppc_md.hpte_remove), | 658 | ppc_function_entry(ppc_md.hpte_remove), |
663 | BRANCH_SET_LINK); | 659 | BRANCH_SET_LINK); |
664 | patch_branch(htab_call_hpte_updatepp, | 660 | patch_branch(htab_call_hpte_updatepp, |
665 | FUNCTION_TEXT(ppc_md.hpte_updatepp), | 661 | ppc_function_entry(ppc_md.hpte_updatepp), |
666 | BRANCH_SET_LINK); | 662 | BRANCH_SET_LINK); |
667 | } | 663 | } |
668 | 664 | ||
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 9d1d33cd2be5..4623366f82e9 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
@@ -256,10 +256,14 @@ static inline void patch_slb_encoding(unsigned int *insn_addr, | |||
256 | patch_instruction(insn_addr, insn); | 256 | patch_instruction(insn_addr, insn); |
257 | } | 257 | } |
258 | 258 | ||
259 | extern u32 slb_compare_rr_to_size[]; | ||
260 | extern u32 slb_miss_kernel_load_linear[]; | ||
261 | extern u32 slb_miss_kernel_load_io[]; | ||
262 | extern u32 slb_compare_rr_to_size[]; | ||
263 | extern u32 slb_miss_kernel_load_vmemmap[]; | ||
264 | |||
259 | void slb_set_size(u16 size) | 265 | void slb_set_size(u16 size) |
260 | { | 266 | { |
261 | extern unsigned int *slb_compare_rr_to_size; | ||
262 | |||
263 | if (mmu_slb_size == size) | 267 | if (mmu_slb_size == size) |
264 | return; | 268 | return; |
265 | 269 | ||
@@ -272,11 +276,7 @@ void slb_initialize(void) | |||
272 | unsigned long linear_llp, vmalloc_llp, io_llp; | 276 | unsigned long linear_llp, vmalloc_llp, io_llp; |
273 | unsigned long lflags, vflags; | 277 | unsigned long lflags, vflags; |
274 | static int slb_encoding_inited; | 278 | static int slb_encoding_inited; |
275 | extern unsigned int *slb_miss_kernel_load_linear; | ||
276 | extern unsigned int *slb_miss_kernel_load_io; | ||
277 | extern unsigned int *slb_compare_rr_to_size; | ||
278 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 279 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
279 | extern unsigned int *slb_miss_kernel_load_vmemmap; | ||
280 | unsigned long vmemmap_llp; | 280 | unsigned long vmemmap_llp; |
281 | #endif | 281 | #endif |
282 | 282 | ||
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index e0b3cf42b053..736d18b3cefd 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S | |||
@@ -59,7 +59,8 @@ _GLOBAL(slb_allocate_realmode) | |||
59 | /* Linear mapping encoding bits, the "li" instruction below will | 59 | /* Linear mapping encoding bits, the "li" instruction below will |
60 | * be patched by the kernel at boot | 60 | * be patched by the kernel at boot |
61 | */ | 61 | */ |
62 | _GLOBAL(slb_miss_kernel_load_linear) | 62 | .globl slb_miss_kernel_load_linear |
63 | slb_miss_kernel_load_linear: | ||
63 | li r11,0 | 64 | li r11,0 |
64 | /* | 65 | /* |
65 | * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 | 66 | * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 |
@@ -79,7 +80,8 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) | |||
79 | /* Check virtual memmap region. To be patches at kernel boot */ | 80 | /* Check virtual memmap region. To be patches at kernel boot */ |
80 | cmpldi cr0,r9,0xf | 81 | cmpldi cr0,r9,0xf |
81 | bne 1f | 82 | bne 1f |
82 | _GLOBAL(slb_miss_kernel_load_vmemmap) | 83 | .globl slb_miss_kernel_load_vmemmap |
84 | slb_miss_kernel_load_vmemmap: | ||
83 | li r11,0 | 85 | li r11,0 |
84 | b 6f | 86 | b 6f |
85 | 1: | 87 | 1: |
@@ -95,7 +97,8 @@ _GLOBAL(slb_miss_kernel_load_vmemmap) | |||
95 | b 6f | 97 | b 6f |
96 | 5: | 98 | 5: |
97 | /* IO mapping */ | 99 | /* IO mapping */ |
98 | _GLOBAL(slb_miss_kernel_load_io) | 100 | .globl slb_miss_kernel_load_io |
101 | slb_miss_kernel_load_io: | ||
99 | li r11,0 | 102 | li r11,0 |
100 | 6: | 103 | 6: |
101 | /* | 104 | /* |
@@ -250,7 +253,8 @@ slb_finish_load: | |||
250 | 7: ld r10,PACASTABRR(r13) | 253 | 7: ld r10,PACASTABRR(r13) |
251 | addi r10,r10,1 | 254 | addi r10,r10,1 |
252 | /* This gets soft patched on boot. */ | 255 | /* This gets soft patched on boot. */ |
253 | _GLOBAL(slb_compare_rr_to_size) | 256 | .globl slb_compare_rr_to_size |
257 | slb_compare_rr_to_size: | ||
254 | cmpldi r10,0 | 258 | cmpldi r10,0 |
255 | 259 | ||
256 | blt+ 4f | 260 | blt+ 4f |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6382098d6f8d..ba093f553678 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
28 | #include <asm/dbell.h> | 28 | #include <asm/dbell.h> |
29 | #include <asm/fsl_guts.h> | 29 | #include <asm/fsl_guts.h> |
30 | #include <asm/code-patching.h> | ||
30 | 31 | ||
31 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
32 | #include <sysdev/mpic.h> | 33 | #include <sysdev/mpic.h> |
@@ -267,7 +268,7 @@ out: | |||
267 | flush_spin_table(spin_table); | 268 | flush_spin_table(spin_table); |
268 | out_be32(&spin_table->pir, hw_cpu); | 269 | out_be32(&spin_table->pir, hw_cpu); |
269 | out_be64((u64 *)(&spin_table->addr_h), | 270 | out_be64((u64 *)(&spin_table->addr_h), |
270 | __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); | 271 | __pa(ppc_function_entry(generic_secondary_smp_init))); |
271 | flush_spin_table(spin_table); | 272 | flush_spin_table(spin_table); |
272 | #endif | 273 | #endif |
273 | 274 | ||
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index 90745eaa45fe..c8017a7bcabd 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/firmware.h> | 40 | #include <asm/firmware.h> |
41 | #include <asm/rtas.h> | 41 | #include <asm/rtas.h> |
42 | #include <asm/cputhreads.h> | 42 | #include <asm/cputhreads.h> |
43 | #include <asm/code-patching.h> | ||
43 | 44 | ||
44 | #include "interrupt.h" | 45 | #include "interrupt.h" |
45 | #include <asm/udbg.h> | 46 | #include <asm/udbg.h> |
@@ -70,8 +71,8 @@ static cpumask_t of_spin_map; | |||
70 | static inline int smp_startup_cpu(unsigned int lcpu) | 71 | static inline int smp_startup_cpu(unsigned int lcpu) |
71 | { | 72 | { |
72 | int status; | 73 | int status; |
73 | unsigned long start_here = __pa((u32)*((unsigned long *) | 74 | unsigned long start_here = |
74 | generic_secondary_smp_init)); | 75 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
75 | unsigned int pcpu; | 76 | unsigned int pcpu; |
76 | int start_cpu; | 77 | int start_cpu; |
77 | 78 | ||
diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S index 56f45adcd089..81ab555aa491 100644 --- a/arch/powerpc/platforms/pasemi/powersave.S +++ b/arch/powerpc/platforms/pasemi/powersave.S | |||
@@ -66,7 +66,7 @@ sleep_common: | |||
66 | std r3, 48(r1) | 66 | std r3, 48(r1) |
67 | 67 | ||
68 | /* Only do power savings when in astate 0 */ | 68 | /* Only do power savings when in astate 0 */ |
69 | bl .check_astate | 69 | bl check_astate |
70 | cmpwi r3,0 | 70 | cmpwi r3,0 |
71 | bne 1f | 71 | bne 1f |
72 | 72 | ||
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S index 3cd262897c27..11a3169ee583 100644 --- a/arch/powerpc/platforms/powernv/opal-takeover.S +++ b/arch/powerpc/platforms/powernv/opal-takeover.S | |||
@@ -21,11 +21,13 @@ | |||
21 | _GLOBAL(opal_query_takeover) | 21 | _GLOBAL(opal_query_takeover) |
22 | mfcr r0 | 22 | mfcr r0 |
23 | stw r0,8(r1) | 23 | stw r0,8(r1) |
24 | stdu r1,-STACKFRAMESIZE(r1) | ||
24 | std r3,STK_PARAM(R3)(r1) | 25 | std r3,STK_PARAM(R3)(r1) |
25 | std r4,STK_PARAM(R4)(r1) | 26 | std r4,STK_PARAM(R4)(r1) |
26 | li r3,H_HAL_TAKEOVER | 27 | li r3,H_HAL_TAKEOVER |
27 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC | 28 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC |
28 | HVSC | 29 | HVSC |
30 | addi r1,r1,STACKFRAMESIZE | ||
29 | ld r10,STK_PARAM(R3)(r1) | 31 | ld r10,STK_PARAM(R3)(r1) |
30 | std r4,0(r10) | 32 | std r4,0(r10) |
31 | ld r10,STK_PARAM(R4)(r1) | 33 | ld r10,STK_PARAM(R4)(r1) |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index f531ffe35b3e..b5ebc545a373 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -32,7 +32,7 @@ | |||
32 | std r12,PACASAVEDMSR(r13); \ | 32 | std r12,PACASAVEDMSR(r13); \ |
33 | andc r12,r12,r0; \ | 33 | andc r12,r12,r0; \ |
34 | mtmsrd r12,1; \ | 34 | mtmsrd r12,1; \ |
35 | LOAD_REG_ADDR(r0,.opal_return); \ | 35 | LOAD_REG_ADDR(r0,opal_return); \ |
36 | mtlr r0; \ | 36 | mtlr r0; \ |
37 | li r0,MSR_DR|MSR_IR|MSR_LE;\ | 37 | li r0,MSR_DR|MSR_IR|MSR_LE;\ |
38 | andc r12,r12,r0; \ | 38 | andc r12,r12,r0; \ |
@@ -44,7 +44,7 @@ | |||
44 | mtspr SPRN_HSRR0,r12; \ | 44 | mtspr SPRN_HSRR0,r12; \ |
45 | hrfid | 45 | hrfid |
46 | 46 | ||
47 | _STATIC(opal_return) | 47 | opal_return: |
48 | /* | 48 | /* |
49 | * Fixup endian on OPAL return... we should be able to simplify | 49 | * Fixup endian on OPAL return... we should be able to simplify |
50 | * this by instead converting the below trampoline to a set of | 50 | * this by instead converting the below trampoline to a set of |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index bf5fcd452168..1601a1ea02c4 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/xics.h> | 31 | #include <asm/xics.h> |
32 | #include <asm/opal.h> | 32 | #include <asm/opal.h> |
33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
34 | #include <asm/code-patching.h> | ||
34 | 35 | ||
35 | #include "powernv.h" | 36 | #include "powernv.h" |
36 | 37 | ||
@@ -50,8 +51,8 @@ static void pnv_smp_setup_cpu(int cpu) | |||
50 | int pnv_smp_kick_cpu(int nr) | 51 | int pnv_smp_kick_cpu(int nr) |
51 | { | 52 | { |
52 | unsigned int pcpu = get_hard_smp_processor_id(nr); | 53 | unsigned int pcpu = get_hard_smp_processor_id(nr); |
53 | unsigned long start_here = __pa(*((unsigned long *) | 54 | unsigned long start_here = |
54 | generic_secondary_smp_init)); | 55 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
55 | long rc; | 56 | long rc; |
56 | 57 | ||
57 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 58 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 444fe7759e55..7891a86066e8 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -49,7 +49,7 @@ END_FTR_SECTION(0, 1); \ | |||
49 | std r0,16(r1); \ | 49 | std r0,16(r1); \ |
50 | addi r4,r1,STK_PARAM(FIRST_REG); \ | 50 | addi r4,r1,STK_PARAM(FIRST_REG); \ |
51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | 51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
52 | bl .__trace_hcall_entry; \ | 52 | bl __trace_hcall_entry; \ |
53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
54 | ld r0,16(r1); \ | 54 | ld r0,16(r1); \ |
55 | ld r3,STK_PARAM(R3)(r1); \ | 55 | ld r3,STK_PARAM(R3)(r1); \ |
@@ -83,7 +83,7 @@ END_FTR_SECTION(0, 1); \ | |||
83 | mr r3,r6; \ | 83 | mr r3,r6; \ |
84 | std r0,16(r1); \ | 84 | std r0,16(r1); \ |
85 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | 85 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
86 | bl .__trace_hcall_exit; \ | 86 | bl __trace_hcall_exit; \ |
87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
88 | ld r0,16(r1); \ | 88 | ld r0,16(r1); \ |
89 | ld r3,STK_PARAM(R3)(r1); \ | 89 | ld r3,STK_PARAM(R3)(r1); \ |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 24f58cb0a543..a3555b10c1a5 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/xics.h> | 44 | #include <asm/xics.h> |
45 | #include <asm/dbell.h> | 45 | #include <asm/dbell.h> |
46 | #include <asm/plpar_wrappers.h> | 46 | #include <asm/plpar_wrappers.h> |
47 | #include <asm/code-patching.h> | ||
47 | 48 | ||
48 | #include "pseries.h" | 49 | #include "pseries.h" |
49 | #include "offline_states.h" | 50 | #include "offline_states.h" |
@@ -96,8 +97,8 @@ int smp_query_cpu_stopped(unsigned int pcpu) | |||
96 | static inline int smp_startup_cpu(unsigned int lcpu) | 97 | static inline int smp_startup_cpu(unsigned int lcpu) |
97 | { | 98 | { |
98 | int status; | 99 | int status; |
99 | unsigned long start_here = __pa((u32)*((unsigned long *) | 100 | unsigned long start_here = |
100 | generic_secondary_smp_init)); | 101 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
101 | unsigned int pcpu; | 102 | unsigned int pcpu; |
102 | int start_cpu; | 103 | int start_cpu; |
103 | 104 | ||
diff --git a/arch/powerpc/platforms/wsp/scom_smp.c b/arch/powerpc/platforms/wsp/scom_smp.c index 268bc899c1f7..8c79ce016cf1 100644 --- a/arch/powerpc/platforms/wsp/scom_smp.c +++ b/arch/powerpc/platforms/wsp/scom_smp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/reg_a2.h> | 20 | #include <asm/reg_a2.h> |
21 | #include <asm/scom.h> | 21 | #include <asm/scom.h> |
22 | #include <asm/udbg.h> | 22 | #include <asm/udbg.h> |
23 | #include <asm/code-patching.h> | ||
23 | 24 | ||
24 | #include "wsp.h" | 25 | #include "wsp.h" |
25 | 26 | ||
@@ -405,7 +406,7 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np) | |||
405 | goto fail; | 406 | goto fail; |
406 | } | 407 | } |
407 | 408 | ||
408 | start_here = *(unsigned long *)(core_setup ? generic_secondary_smp_init | 409 | start_here = ppc_function_entry(core_setup ? generic_secondary_smp_init |
409 | : generic_secondary_thread_init); | 410 | : generic_secondary_thread_init); |
410 | pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); | 411 | pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); |
411 | 412 | ||