diff options
Diffstat (limited to 'arch/powerpc/kernel/process.c')
| -rw-r--r-- | arch/powerpc/kernel/process.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 75c2d1009985..3386d8ab7eb0 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -858,17 +858,21 @@ void show_regs(struct pt_regs * regs) | |||
| 858 | printk("MSR: "REG" ", regs->msr); | 858 | printk("MSR: "REG" ", regs->msr); |
| 859 | printbits(regs->msr, msr_bits); | 859 | printbits(regs->msr, msr_bits); |
| 860 | printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); | 860 | printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); |
| 861 | #ifdef CONFIG_PPC64 | ||
| 862 | printk("SOFTE: %ld\n", regs->softe); | ||
| 863 | #endif | ||
| 864 | trap = TRAP(regs); | 861 | trap = TRAP(regs); |
| 865 | if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) | 862 | if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) |
| 866 | printk("CFAR: "REG"\n", regs->orig_gpr3); | 863 | printk("CFAR: "REG" ", regs->orig_gpr3); |
| 867 | if (trap == 0x300 || trap == 0x600) | 864 | if (trap == 0x200 || trap == 0x300 || trap == 0x600) |
| 868 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | 865 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) |
| 869 | printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); | 866 | printk("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); |
| 870 | #else | 867 | #else |
| 871 | printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr); | 868 | printk("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); |
| 869 | #endif | ||
| 870 | #ifdef CONFIG_PPC64 | ||
| 871 | printk("SOFTE: %ld ", regs->softe); | ||
| 872 | #endif | ||
| 873 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
| 874 | if (MSR_TM_ACTIVE(regs->msr)) | ||
| 875 | printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); | ||
| 872 | #endif | 876 | #endif |
| 873 | 877 | ||
| 874 | for (i = 0; i < 32; i++) { | 878 | for (i = 0; i < 32; i++) { |
| @@ -887,9 +891,6 @@ void show_regs(struct pt_regs * regs) | |||
| 887 | printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); | 891 | printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); |
| 888 | printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); | 892 | printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); |
| 889 | #endif | 893 | #endif |
| 890 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
| 891 | printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch); | ||
| 892 | #endif | ||
| 893 | show_stack(current, (unsigned long *) regs->gpr[1]); | 894 | show_stack(current, (unsigned long *) regs->gpr[1]); |
| 894 | if (!user_mode(regs)) | 895 | if (!user_mode(regs)) |
| 895 | show_instructions(regs); | 896 | show_instructions(regs); |
| @@ -1086,25 +1087,45 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
| 1086 | regs->msr = MSR_USER; | 1087 | regs->msr = MSR_USER; |
| 1087 | #else | 1088 | #else |
| 1088 | if (!is_32bit_task()) { | 1089 | if (!is_32bit_task()) { |
| 1089 | unsigned long entry, toc; | 1090 | unsigned long entry; |
| 1090 | 1091 | ||
| 1091 | /* start is a relocated pointer to the function descriptor for | 1092 | if (is_elf2_task()) { |
| 1092 | * the elf _start routine. The first entry in the function | 1093 | /* Look ma, no function descriptors! */ |
| 1093 | * descriptor is the entry address of _start and the second | 1094 | 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 | 1095 | ||
| 1099 | /* Check whether the e_entry function descriptor entries | 1096 | /* |
| 1100 | * need to be relocated before we can use them. | 1097 | * Ulrich says: |
| 1101 | */ | 1098 | * The latest iteration of the ABI requires that when |
| 1102 | if (load_addr != 0) { | 1099 | * calling a function (at its global entry point), |
| 1103 | entry += load_addr; | 1100 | * the caller must ensure r12 holds the entry point |
| 1104 | toc += load_addr; | 1101 | * address (so that the function can quickly |
| 1102 | * establish addressability). | ||
| 1103 | */ | ||
| 1104 | regs->gpr[12] = start; | ||
| 1105 | /* Make sure that's restored on entry to userspace. */ | ||
| 1106 | set_thread_flag(TIF_RESTOREALL); | ||
| 1107 | } else { | ||
| 1108 | unsigned long toc; | ||
| 1109 | |||
| 1110 | /* start is a relocated pointer to the function | ||
| 1111 | * descriptor for the elf _start routine. The first | ||
| 1112 | * entry in the function descriptor is the entry | ||
| 1113 | * address of _start and the second entry is the TOC | ||
| 1114 | * value we need to use. | ||
| 1115 | */ | ||
| 1116 | __get_user(entry, (unsigned long __user *)start); | ||
| 1117 | __get_user(toc, (unsigned long __user *)start+1); | ||
| 1118 | |||
| 1119 | /* Check whether the e_entry function descriptor entries | ||
| 1120 | * need to be relocated before we can use them. | ||
| 1121 | */ | ||
| 1122 | if (load_addr != 0) { | ||
| 1123 | entry += load_addr; | ||
| 1124 | toc += load_addr; | ||
| 1125 | } | ||
| 1126 | regs->gpr[2] = toc; | ||
| 1105 | } | 1127 | } |
| 1106 | regs->nip = entry; | 1128 | regs->nip = entry; |
| 1107 | regs->gpr[2] = toc; | ||
| 1108 | regs->msr = MSR_USER64; | 1129 | regs->msr = MSR_USER64; |
| 1109 | } else { | 1130 | } else { |
| 1110 | regs->nip = start; | 1131 | regs->nip = start; |
