aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2016-06-06 12:56:10 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-06-13 23:58:27 -0400
commitf55d966536034d33476fdd43c45d47225344469f (patch)
tree65437da4dfbe49e062ffb785c09e3748514a429f
parentac9cd1709c0be4334fbad4ab610ecb7acceac884 (diff)
powerpc: Define and use PPC64_ELF_ABI_v2/v1
We're approaching 20 locations where we need to check for ELF ABI v2. That's fine, except the logic is a bit awkward, because we have to check that _CALL_ELF is defined and then what its value is. So check it once in asm/types.h and define PPC64_ELF_ABI_v2 when ELF ABI v2 is detected. We also have a few places where what we're really trying to check is that we are using the 64-bit v1 ABI, ie. function descriptors. So also add a #define for that, which simplifies several checks. Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/code-patching.h10
-rw-r--r--arch/powerpc/include/asm/ftrace.h8
-rw-r--r--arch/powerpc/include/asm/kprobes.h8
-rw-r--r--arch/powerpc/include/asm/linkage.h6
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h4
-rw-r--r--arch/powerpc/include/asm/ptrace.h2
-rw-r--r--arch/powerpc/include/asm/sections.h4
-rw-r--r--arch/powerpc/include/asm/types.h8
-rw-r--r--arch/powerpc/kernel/entry_64.S2
-rw-r--r--arch/powerpc/kernel/ftrace.c4
-rw-r--r--arch/powerpc/kernel/head_64.S2
-rw-r--r--arch/powerpc/kernel/kprobes.c6
-rw-r--r--arch/powerpc/kernel/misc_64.S2
-rw-r--r--arch/powerpc/kernel/module_64.c4
-rw-r--r--arch/powerpc/kvm/book3s_interrupts.S2
-rw-r--r--arch/powerpc/kvm/book3s_rmhandlers.S2
16 files changed, 39 insertions, 35 deletions
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 994c60a857ce..2015b072422c 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -49,8 +49,7 @@ void __patch_exception(int exc, unsigned long addr);
49 49
50static inline unsigned long ppc_function_entry(void *func) 50static inline unsigned long ppc_function_entry(void *func)
51{ 51{
52#if defined(CONFIG_PPC64) 52#ifdef PPC64_ELF_ABI_v2
53#if defined(_CALL_ELF) && _CALL_ELF == 2
54 u32 *insn = func; 53 u32 *insn = func;
55 54
56 /* 55 /*
@@ -75,14 +74,13 @@ static inline unsigned long ppc_function_entry(void *func)
75 return (unsigned long)(insn + 2); 74 return (unsigned long)(insn + 2);
76 else 75 else
77 return (unsigned long)func; 76 return (unsigned long)func;
78#else 77#elif defined(PPC64_ELF_ABI_v1)
79 /* 78 /*
80 * On PPC64 ABIv1 the function pointer actually points to the 79 * On PPC64 ABIv1 the function pointer actually points to the
81 * function's descriptor. The first entry in the descriptor is the 80 * function's descriptor. The first entry in the descriptor is the
82 * address of the function text. 81 * address of the function text.
83 */ 82 */
84 return ((func_descr_t *)func)->entry; 83 return ((func_descr_t *)func)->entry;
85#endif
86#else 84#else
87 return (unsigned long)func; 85 return (unsigned long)func;
88#endif 86#endif
@@ -90,7 +88,7 @@ static inline unsigned long ppc_function_entry(void *func)
90 88
91static inline unsigned long ppc_global_function_entry(void *func) 89static inline unsigned long ppc_global_function_entry(void *func)
92{ 90{
93#if defined(CONFIG_PPC64) && defined(_CALL_ELF) && _CALL_ELF == 2 91#ifdef PPC64_ELF_ABI_v2
94 /* PPC64 ABIv2 the global entry point is at the address */ 92 /* PPC64 ABIv2 the global entry point is at the address */
95 return (unsigned long)func; 93 return (unsigned long)func;
96#else 94#else
@@ -106,7 +104,7 @@ static inline unsigned long ppc_global_function_entry(void *func)
106 */ 104 */
107 105
108/* This must match the definition of STK_GOT in <asm/ppc_asm.h> */ 106/* This must match the definition of STK_GOT in <asm/ppc_asm.h> */
109#if defined(_CALL_ELF) && _CALL_ELF == 2 107#ifdef PPC64_ELF_ABI_v2
110#define R2_STACK_OFFSET 24 108#define R2_STACK_OFFSET 24
111#else 109#else
112#define R2_STACK_OFFSET 40 110#define R2_STACK_OFFSET 40
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index 50ca7585abe2..686c5f70eb84 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -1,6 +1,8 @@
1#ifndef _ASM_POWERPC_FTRACE 1#ifndef _ASM_POWERPC_FTRACE
2#define _ASM_POWERPC_FTRACE 2#define _ASM_POWERPC_FTRACE
3 3
4#include <asm/types.h>
5
4#ifdef CONFIG_FUNCTION_TRACER 6#ifdef CONFIG_FUNCTION_TRACER
5#define MCOUNT_ADDR ((unsigned long)(_mcount)) 7#define MCOUNT_ADDR ((unsigned long)(_mcount))
6#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ 8#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
@@ -65,8 +67,8 @@ struct dyn_arch_ftrace {
65#endif 67#endif
66#endif 68#endif
67 69
68#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) 70#if defined(CONFIG_FTRACE_SYSCALLS) && !defined(__ASSEMBLY__)
69#if !defined(_CALL_ELF) || _CALL_ELF != 2 71#ifdef PPC64_ELF_ABI_v1
70#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME 72#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
71static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) 73static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
72{ 74{
@@ -79,6 +81,6 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
79 return !strcmp(sym + 4, name + 3); 81 return !strcmp(sym + 4, name + 3);
80} 82}
81#endif 83#endif
82#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ 84#endif /* CONFIG_FTRACE_SYSCALLS && !__ASSEMBLY__ */
83 85
84#endif /* _ASM_POWERPC_FTRACE */ 86#endif /* _ASM_POWERPC_FTRACE */
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h
index 039b583db029..2c9759bdb63b 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -40,8 +40,7 @@ struct kprobe;
40typedef ppc_opcode_t kprobe_opcode_t; 40typedef ppc_opcode_t kprobe_opcode_t;
41#define MAX_INSN_SIZE 1 41#define MAX_INSN_SIZE 1
42 42
43#ifdef CONFIG_PPC64 43#ifdef PPC64_ELF_ABI_v2
44#if defined(_CALL_ELF) && _CALL_ELF == 2
45/* PPC64 ABIv2 needs local entry point */ 44/* PPC64 ABIv2 needs local entry point */
46#define kprobe_lookup_name(name, addr) \ 45#define kprobe_lookup_name(name, addr) \
47{ \ 46{ \
@@ -49,7 +48,7 @@ typedef ppc_opcode_t kprobe_opcode_t;
49 if (addr) \ 48 if (addr) \
50 addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ 49 addr = (kprobe_opcode_t *)ppc_function_entry(addr); \
51} 50}
52#else 51#elif defined(PPC64_ELF_ABI_v1)
53/* 52/*
54 * 64bit powerpc ABIv1 uses function descriptors: 53 * 64bit powerpc ABIv1 uses function descriptors:
55 * - Check for the dot variant of the symbol first. 54 * - Check for the dot variant of the symbol first.
@@ -92,8 +91,7 @@ typedef ppc_opcode_t kprobe_opcode_t;
92 addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \ 91 addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \
93 } \ 92 } \
94} 93}
95#endif /* defined(_CALL_ELF) && _CALL_ELF == 2 */ 94#endif
96#endif /* CONFIG_PPC64 */
97 95
98#define flush_insn_slot(p) do { } while (0) 96#define flush_insn_slot(p) do { } while (0)
99#define kretprobe_blacklist_size 0 97#define kretprobe_blacklist_size 0
diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h
index e3ad5c72724a..0cf5e21179fc 100644
--- a/arch/powerpc/include/asm/linkage.h
+++ b/arch/powerpc/include/asm/linkage.h
@@ -1,8 +1,9 @@
1#ifndef _ASM_POWERPC_LINKAGE_H 1#ifndef _ASM_POWERPC_LINKAGE_H
2#define _ASM_POWERPC_LINKAGE_H 2#define _ASM_POWERPC_LINKAGE_H
3 3
4#ifdef CONFIG_PPC64 4#include <asm/types.h>
5#if !defined(_CALL_ELF) || _CALL_ELF != 2 5
6#ifdef PPC64_ELF_ABI_v1
6#define cond_syscall(x) \ 7#define cond_syscall(x) \
7 asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ 8 asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \
8 "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") 9 "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n")
@@ -10,6 +11,5 @@
10 asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ 11 asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \
11 "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) 12 "\t.globl ." #alias "\n\t.set ." #alias ", ." #name)
12#endif 13#endif
13#endif
14 14
15#endif /* _ASM_POWERPC_LINKAGE_H */ 15#endif /* _ASM_POWERPC_LINKAGE_H */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 2b31632376a5..7b591f98edcc 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -189,7 +189,7 @@ 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 192#ifdef PPC64_ELF_ABI_v2
193#define STK_GOT 24 193#define STK_GOT 24
194#define __STK_PARAM(i) (32 + ((i)-3)*8) 194#define __STK_PARAM(i) (32 + ((i)-3)*8)
195#else 195#else
@@ -198,7 +198,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
198#endif 198#endif
199#define STK_PARAM(i) __STK_PARAM(__REG_##i) 199#define STK_PARAM(i) __STK_PARAM(__REG_##i)
200 200
201#if defined(_CALL_ELF) && _CALL_ELF == 2 201#ifdef PPC64_ELF_ABI_v2
202 202
203#define _GLOBAL(name) \ 203#define _GLOBAL(name) \
204 .section ".text"; \ 204 .section ".text"; \
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index c0c61fa9cd9e..e4923686e43a 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -47,7 +47,7 @@
47 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE) 47 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
48#define STACK_FRAME_MARKER 12 48#define STACK_FRAME_MARKER 12
49 49
50#if defined(_CALL_ELF) && _CALL_ELF == 2 50#ifdef PPC64_ELF_ABI_v2
51#define STACK_FRAME_MIN_SIZE 32 51#define STACK_FRAME_MIN_SIZE 32
52#else 52#else
53#define STACK_FRAME_MIN_SIZE STACK_FRAME_OVERHEAD 53#define STACK_FRAME_MIN_SIZE STACK_FRAME_OVERHEAD
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index abf5866e08c6..7dc006b58369 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -62,7 +62,7 @@ static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end)
62#endif 62#endif
63} 63}
64 64
65#if !defined(_CALL_ELF) || _CALL_ELF != 2 65#ifdef PPC64_ELF_ABI_v1
66#undef dereference_function_descriptor 66#undef dereference_function_descriptor
67static inline void *dereference_function_descriptor(void *ptr) 67static inline void *dereference_function_descriptor(void *ptr)
68{ 68{
@@ -73,7 +73,7 @@ static inline void *dereference_function_descriptor(void *ptr)
73 ptr = p; 73 ptr = p;
74 return ptr; 74 return ptr;
75} 75}
76#endif 76#endif /* PPC64_ELF_ABI_v1 */
77 77
78#endif 78#endif
79 79
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index bfb6ded38ffa..49a0678a53fa 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -15,6 +15,14 @@
15 15
16#include <uapi/asm/types.h> 16#include <uapi/asm/types.h>
17 17
18#ifdef __powerpc64__
19#if defined(_CALL_ELF) && _CALL_ELF == 2
20#define PPC64_ELF_ABI_v2
21#else
22#define PPC64_ELF_ABI_v1
23#endif
24#endif /* __powerpc64__ */
25
18#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
19 27
20typedef __vector128 vector128; 28typedef __vector128 vector128;
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 73e461a3dfbb..2e0c565754aa 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -453,7 +453,7 @@ _GLOBAL(ret_from_kernel_thread)
453 REST_NVGPRS(r1) 453 REST_NVGPRS(r1)
454 mtlr r14 454 mtlr r14
455 mr r3,r15 455 mr r3,r15
456#if defined(_CALL_ELF) && _CALL_ELF == 2 456#ifdef PPC64_ELF_ABI_v2
457 mr r12,r14 457 mr r12,r14
458#endif 458#endif
459 blrl 459 blrl
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 1123a4d8d8dd..7af6c4de044b 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -608,7 +608,7 @@ unsigned long __init arch_syscall_addr(int nr)
608} 608}
609#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */ 609#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */
610 610
611#if defined(CONFIG_PPC64) && (!defined(_CALL_ELF) || _CALL_ELF != 2) 611#ifdef PPC64_ELF_ABI_v1
612char *arch_ftrace_match_adjust(char *str, const char *search) 612char *arch_ftrace_match_adjust(char *str, const char *search)
613{ 613{
614 if (str[0] == '.' && search[0] != '.') 614 if (str[0] == '.' && search[0] != '.')
@@ -616,4 +616,4 @@ char *arch_ftrace_match_adjust(char *str, const char *search)
616 else 616 else
617 return str; 617 return str;
618} 618}
619#endif /* defined(CONFIG_PPC64) && (!defined(_CALL_ELF) || _CALL_ELF != 2) */ 619#endif /* PPC64_ELF_ABI_v1 */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 2d14774af6b4..064cd9397836 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -401,7 +401,7 @@ generic_secondary_common_init:
401 ld r12,CPU_SPEC_RESTORE(r23) 401 ld r12,CPU_SPEC_RESTORE(r23)
402 cmpdi 0,r12,0 402 cmpdi 0,r12,0
403 beq 3f 403 beq 3f
404#if !defined(_CALL_ELF) || _CALL_ELF != 2 404#ifdef PPC64_ELF_ABI_v1
405 ld r12,0(r12) 405 ld r12,0(r12)
406#endif 406#endif
407 mtctr r12 407 mtctr r12
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 7c053f281406..7d48e3baa38b 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -506,13 +506,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
506 506
507 /* setup return addr to the jprobe handler routine */ 507 /* setup return addr to the jprobe handler routine */
508 regs->nip = arch_deref_entry_point(jp->entry); 508 regs->nip = arch_deref_entry_point(jp->entry);
509#ifdef CONFIG_PPC64 509#ifdef PPC64_ELF_ABI_v2
510#if defined(_CALL_ELF) && _CALL_ELF == 2
511 regs->gpr[12] = (unsigned long)jp->entry; 510 regs->gpr[12] = (unsigned long)jp->entry;
512#else 511#elif defined(PPC64_ELF_ABI_v1)
513 regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); 512 regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
514#endif 513#endif
515#endif
516 514
517 return 1; 515 return 1;
518} 516}
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index f28754c497e5..7a8519052b14 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -661,7 +661,7 @@ _GLOBAL(kexec_sequence)
661 661
662#ifndef CONFIG_PPC_BOOK3E 662#ifndef CONFIG_PPC_BOOK3E
663 /* clear out hardware hash page table and tlb */ 663 /* clear out hardware hash page table and tlb */
664#if !defined(_CALL_ELF) || _CALL_ELF != 2 664#ifdef PPC64_ELF_ABI_v1
665 ld r12,0(r27) /* deref function descriptor */ 665 ld r12,0(r27) /* deref function descriptor */
666#else 666#else
667 mr r12,r27 667 mr r12,r27
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 9ce9a25f58b5..f703f343358e 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -41,7 +41,7 @@
41 this, and makes other things simpler. Anton? 41 this, and makes other things simpler. Anton?
42 --RR. */ 42 --RR. */
43 43
44#if defined(_CALL_ELF) && _CALL_ELF == 2 44#ifdef PPC64_ELF_ABI_v2
45 45
46/* An address is simply the address of the function. */ 46/* An address is simply the address of the function. */
47typedef unsigned long func_desc_t; 47typedef unsigned long func_desc_t;
@@ -132,7 +132,7 @@ static u32 ppc64_stub_insns[] = {
132 /* Save current r2 value in magic place on the stack. */ 132 /* Save current r2 value in magic place on the stack. */
133 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */ 133 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */
134 0xe98b0020, /* ld r12,32(r11) */ 134 0xe98b0020, /* ld r12,32(r11) */
135#if !defined(_CALL_ELF) || _CALL_ELF != 2 135#ifdef PPC64_ELF_ABI_v1
136 /* Set up new r2 from function descriptor */ 136 /* Set up new r2 from function descriptor */
137 0xe84b0028, /* ld r2,40(r11) */ 137 0xe84b0028, /* ld r2,40(r11) */
138#endif 138#endif
diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S
index d044b8b7c69d..901e6fe00c39 100644
--- a/arch/powerpc/kvm/book3s_interrupts.S
+++ b/arch/powerpc/kvm/book3s_interrupts.S
@@ -25,7 +25,7 @@
25#include <asm/exception-64s.h> 25#include <asm/exception-64s.h>
26 26
27#if defined(CONFIG_PPC_BOOK3S_64) 27#if defined(CONFIG_PPC_BOOK3S_64)
28#if defined(_CALL_ELF) && _CALL_ELF == 2 28#ifdef PPC64_ELF_ABI_v2
29#define FUNC(name) name 29#define FUNC(name) name
30#else 30#else
31#define FUNC(name) GLUE(.,name) 31#define FUNC(name) GLUE(.,name)
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
index 16c4d88ba27d..42a4b237df5f 100644
--- a/arch/powerpc/kvm/book3s_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_rmhandlers.S
@@ -36,7 +36,7 @@
36 36
37#if defined(CONFIG_PPC_BOOK3S_64) 37#if defined(CONFIG_PPC_BOOK3S_64)
38 38
39#if defined(_CALL_ELF) && _CALL_ELF == 2 39#ifdef PPC64_ELF_ABI_v2
40#define FUNC(name) name 40#define FUNC(name) name
41#else 41#else
42#define FUNC(name) GLUE(.,name) 42#define FUNC(name) GLUE(.,name)