aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 18:13:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 18:13:47 -0500
commit527d1511310a89650000081869260394e20c7013 (patch)
treef23f76433f3b67de5eb64ec0963f18737f677b06 /arch/powerpc/kernel
parentd5bdaf4f68f0590fc481bca54bcaffeb27b75fca (diff)
parent280270828f108be56f0c486def58acabb070244f (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc LE updates from Ben Herrenschmidt: "With my previous pull request I mentioned some remaining Little Endian patches, notably support for our new ABI, which I was sitting on making sure it was all finalized. The toolchain folks confirmed it now, the new ABI is stable and merged with gcc, so we are all good. Oh and we actually missed the actual Kconfig switch for LE so here it is, along with a couple more bug fixes. I have more fixes but not related to LE so I'll send them as a separate pull request tomorrow, let's get this one out of the way. Note that this supports running user space binaries using the new ABI, but the kernel itself still needs to be built with the old one. We'll bring fixes for that after -rc1. Here's Anton log that goes with this series: This patch series adds support for the new ABI, LPAR support for H_SET_MODE and finally adds a kconfig option and defconfig. ABIv2 support was recently committed to binutils and gcc, and should be merged into glibc soon. There are a number of very nice improvements including the removal of function descriptors. Rusty's kernel patches allow binaries of either ABI to work, easing the transition" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc: Wrong DWARF CFI in the kernel vdso for little-endian / ELFv2 powerpc: Add pseries_le_defconfig powerpc: Add CONFIG_CPU_LITTLE_ENDIAN kernel config option. powerpc: Don't use ELFv2 ABI to build the kernel powerpc: ELF2 binaries signal handling powerpc: ELF2 binaries launched directly. powerpc: Set eflags correctly for ELF ABIv2 core dumps. powerpc: Add TIF_ELF2ABI flag. pseries: Add H_SET_MODE to change exception endianness powerpc/pseries: Fix endian issues in pseries EEH code
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/process.c50
-rw-r--r--arch/powerpc/kernel/signal_64.c25
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S16
3 files changed, 66 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 75c2d1009985..0650e18169f8 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1086,25 +1086,45 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
1086 regs->msr = MSR_USER; 1086 regs->msr = MSR_USER;
1087#else 1087#else
1088 if (!is_32bit_task()) { 1088 if (!is_32bit_task()) {
1089 unsigned long entry, toc; 1089 unsigned long entry;
1090 1090
1091 /* start is a relocated pointer to the function descriptor for 1091 if (is_elf2_task()) {
1092 * the elf _start routine. The first entry in the function 1092 /* Look ma, no function descriptors! */
1093 * descriptor is the entry address of _start and the second 1093 entry = start;
1094 * entry is the TOC value we need to use.
1095 */
1096 __get_user(entry, (unsigned long __user *)start);
1097 __get_user(toc, (unsigned long __user *)start+1);
1098 1094
1099 /* Check whether the e_entry function descriptor entries 1095 /*
1100 * need to be relocated before we can use them. 1096 * Ulrich says:
1101 */ 1097 * The latest iteration of the ABI requires that when
1102 if (load_addr != 0) { 1098 * calling a function (at its global entry point),
1103 entry += load_addr; 1099 * the caller must ensure r12 holds the entry point
1104 toc += load_addr; 1100 * address (so that the function can quickly
1101 * establish addressability).
1102 */
1103 regs->gpr[12] = start;
1104 /* Make sure that's restored on entry to userspace. */
1105 set_thread_flag(TIF_RESTOREALL);
1106 } else {
1107 unsigned long toc;
1108
1109 /* start is a relocated pointer to the function
1110 * descriptor for the elf _start routine. The first
1111 * entry in the function descriptor is the entry
1112 * address of _start and the second entry is the TOC
1113 * value we need to use.
1114 */
1115 __get_user(entry, (unsigned long __user *)start);
1116 __get_user(toc, (unsigned long __user *)start+1);
1117
1118 /* Check whether the e_entry function descriptor entries
1119 * need to be relocated before we can use them.
1120 */
1121 if (load_addr != 0) {
1122 entry += load_addr;
1123 toc += load_addr;
1124 }
1125 regs->gpr[2] = toc;
1105 } 1126 }
1106 regs->nip = entry; 1127 regs->nip = entry;
1107 regs->gpr[2] = toc;
1108 regs->msr = MSR_USER64; 1128 regs->msr = MSR_USER64;
1109 } else { 1129 } else {
1110 regs->nip = start; 1130 regs->nip = start;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index b3c615764c9b..e66f67b8b9e6 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -701,12 +701,6 @@ badframe:
701int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, 701int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
702 sigset_t *set, struct pt_regs *regs) 702 sigset_t *set, struct pt_regs *regs)
703{ 703{
704 /* Handler is *really* a pointer to the function descriptor for
705 * the signal routine. The first entry in the function
706 * descriptor is the entry address of signal and the second
707 * entry is the TOC value we need to use.
708 */
709 func_descr_t __user *funct_desc_ptr;
710 struct rt_sigframe __user *frame; 704 struct rt_sigframe __user *frame;
711 unsigned long newsp = 0; 705 unsigned long newsp = 0;
712 long err = 0; 706 long err = 0;
@@ -766,19 +760,32 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
766 goto badframe; 760 goto badframe;
767 regs->link = (unsigned long) &frame->tramp[0]; 761 regs->link = (unsigned long) &frame->tramp[0];
768 } 762 }
769 funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
770 763
771 /* Allocate a dummy caller frame for the signal handler. */ 764 /* Allocate a dummy caller frame for the signal handler. */
772 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; 765 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
773 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); 766 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
774 767
775 /* Set up "regs" so we "return" to the signal handler. */ 768 /* Set up "regs" so we "return" to the signal handler. */
776 err |= get_user(regs->nip, &funct_desc_ptr->entry); 769 if (is_elf2_task()) {
770 regs->nip = (unsigned long) ka->sa.sa_handler;
771 regs->gpr[12] = regs->nip;
772 } else {
773 /* Handler is *really* a pointer to the function descriptor for
774 * the signal routine. The first entry in the function
775 * descriptor is the entry address of signal and the second
776 * entry is the TOC value we need to use.
777 */
778 func_descr_t __user *funct_desc_ptr =
779 (func_descr_t __user *) ka->sa.sa_handler;
780
781 err |= get_user(regs->nip, &funct_desc_ptr->entry);
782 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
783 }
784
777 /* enter the signal handler in native-endian mode */ 785 /* enter the signal handler in native-endian mode */
778 regs->msr &= ~MSR_LE; 786 regs->msr &= ~MSR_LE;
779 regs->msr |= (MSR_KERNEL & MSR_LE); 787 regs->msr |= (MSR_KERNEL & MSR_LE);
780 regs->gpr[1] = newsp; 788 regs->gpr[1] = newsp;
781 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
782 regs->gpr[3] = signr; 789 regs->gpr[3] = signr;
783 regs->result = 0; 790 regs->result = 0;
784 if (ka->sa.sa_flags & SA_SIGINFO) { 791 if (ka->sa.sa_flags & SA_SIGINFO) {
diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 45ea281e9a21..542c6f422e4d 100644
--- a/arch/powerpc/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
@@ -142,6 +142,13 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
142/* Size of CR reg in DWARF unwind info. */ 142/* Size of CR reg in DWARF unwind info. */
143#define CRSIZE 4 143#define CRSIZE 4
144 144
145/* Offset of CR reg within a full word. */
146#ifdef __LITTLE_ENDIAN__
147#define CROFF 0
148#else
149#define CROFF (RSIZE - CRSIZE)
150#endif
151
145/* This is the offset of the VMX reg pointer. */ 152/* This is the offset of the VMX reg pointer. */
146#define VREGS 48*RSIZE+33*8 153#define VREGS 48*RSIZE+33*8
147 154
@@ -181,7 +188,14 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
181 rsave (31, 31*RSIZE); \ 188 rsave (31, 31*RSIZE); \
182 rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \ 189 rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
183 rsave (65, 36*RSIZE); /* lr */ \ 190 rsave (65, 36*RSIZE); /* lr */ \
184 rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */ 191 rsave (68, 38*RSIZE + CROFF); /* cr fields */ \
192 rsave (69, 38*RSIZE + CROFF); \
193 rsave (70, 38*RSIZE + CROFF); \
194 rsave (71, 38*RSIZE + CROFF); \
195 rsave (72, 38*RSIZE + CROFF); \
196 rsave (73, 38*RSIZE + CROFF); \
197 rsave (74, 38*RSIZE + CROFF); \
198 rsave (75, 38*RSIZE + CROFF)
185 199
186/* Describe where the FP regs are saved. */ 200/* Describe where the FP regs are saved. */
187#define EH_FRAME_FP \ 201#define EH_FRAME_FP \