aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2018-08-16 16:39:50 -0400
committerHelge Deller <deller@gmx.de>2018-08-17 10:45:24 -0400
commit5b00ca0b8035e49ef7c466e959c5cb457a654351 (patch)
tree960ff146c537f96aa4da21030960c7981bd86ae0
parentc8921d72e390cb6fca3fb2b0c2badfda851647eb (diff)
parisc: Restore possibility to execute 64-bit applications
Executing 64-bit applications was broken. This patch restores this support and cleans up some code paths. Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/include/asm/elf.h9
-rw-r--r--arch/parisc/include/asm/processor.h6
-rw-r--r--arch/parisc/include/asm/traps.h4
-rw-r--r--arch/parisc/kernel/entry.S52
-rw-r--r--arch/parisc/kernel/sys_parisc.c5
-rw-r--r--arch/parisc/kernel/traps.c2
6 files changed, 39 insertions, 39 deletions
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index f019d3ec0c1c..d00973aab7f1 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -235,6 +235,7 @@ typedef unsigned long elf_greg_t;
235#define SET_PERSONALITY(ex) \ 235#define SET_PERSONALITY(ex) \
236({ \ 236({ \
237 set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ 237 set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
238 clear_thread_flag(TIF_32BIT); \
238 current->thread.map_base = DEFAULT_MAP_BASE; \ 239 current->thread.map_base = DEFAULT_MAP_BASE; \
239 current->thread.task_size = DEFAULT_TASK_SIZE; \ 240 current->thread.task_size = DEFAULT_TASK_SIZE; \
240 }) 241 })
@@ -243,9 +244,11 @@ typedef unsigned long elf_greg_t;
243 244
244#define COMPAT_SET_PERSONALITY(ex) \ 245#define COMPAT_SET_PERSONALITY(ex) \
245({ \ 246({ \
246 set_thread_flag(TIF_32BIT); \ 247 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
247 current->thread.map_base = DEFAULT_MAP_BASE32; \ 248 set_thread_flag(TIF_32BIT); \
248 current->thread.task_size = DEFAULT_TASK_SIZE32; \ 249 current->thread.map_base = DEFAULT_MAP_BASE32; \
250 current->thread.task_size = DEFAULT_TASK_SIZE32; \
251 } else clear_thread_flag(TIF_32BIT); \
249 }) 252 })
250 253
251/* 254/*
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 2dbe5580a1a4..2bd5e695bdad 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -256,11 +256,7 @@ on downward growing arches, it looks like this:
256 * it in here from the current->personality 256 * it in here from the current->personality
257 */ 257 */
258 258
259#ifdef CONFIG_64BIT 259#define USER_WIDE_MODE (!is_32bit_task())
260#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
261#else
262#define USER_WIDE_MODE 0
263#endif
264 260
265#define start_thread(regs, new_pc, new_sp) do { \ 261#define start_thread(regs, new_pc, new_sp) do { \
266 elf_addr_t *sp = (elf_addr_t *)new_sp; \ 262 elf_addr_t *sp = (elf_addr_t *)new_sp; \
diff --git a/arch/parisc/include/asm/traps.h b/arch/parisc/include/asm/traps.h
index e00013248907..8ecc1f0c0483 100644
--- a/arch/parisc/include/asm/traps.h
+++ b/arch/parisc/include/asm/traps.h
@@ -2,7 +2,9 @@
2#ifndef __ASM_TRAPS_H 2#ifndef __ASM_TRAPS_H
3#define __ASM_TRAPS_H 3#define __ASM_TRAPS_H
4 4
5#ifdef __KERNEL__ 5#define PARISC_ITLB_TRAP 6 /* defined by architecture. Do not change. */
6
7#if !defined(__ASSEMBLY__)
6struct pt_regs; 8struct pt_regs;
7 9
8/* traps.c */ 10/* traps.c */
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c7508f5717fb..e170365941f8 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -36,6 +36,7 @@
36#include <asm/signal.h> 36#include <asm/signal.h>
37#include <asm/unistd.h> 37#include <asm/unistd.h>
38#include <asm/ldcw.h> 38#include <asm/ldcw.h>
39#include <asm/traps.h>
39#include <asm/thread_info.h> 40#include <asm/thread_info.h>
40 41
41#include <linux/linkage.h> 42#include <linux/linkage.h>
@@ -692,7 +693,7 @@ ENTRY(fault_vector_20)
692 def 3 693 def 3
693 extint 4 694 extint 4
694 def 5 695 def 5
695 itlb_20 6 696 itlb_20 PARISC_ITLB_TRAP
696 def 7 697 def 7
697 def 8 698 def 8
698 def 9 699 def 9
@@ -735,7 +736,7 @@ ENTRY(fault_vector_11)
735 def 3 736 def 3
736 extint 4 737 extint 4
737 def 5 738 def 5
738 itlb_11 6 739 itlb_11 PARISC_ITLB_TRAP
739 def 7 740 def 7
740 def 8 741 def 8
741 def 9 742 def 9
@@ -1068,21 +1069,12 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
1068 save_specials %r29 1069 save_specials %r29
1069 1070
1070 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */ 1071 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1072 cmpib,COND(=),n PARISC_ITLB_TRAP,%r26,skip_save_ior
1071 1073
1072 /*
1073 * FIXME: 1) Use a #define for the hardwired "6" below (and in
1074 * traps.c.
1075 * 2) Once we start executing code above 4 Gb, we need
1076 * to adjust iasq/iaoq here in the same way we
1077 * adjust isr/ior below.
1078 */
1079
1080 cmpib,COND(=),n 6,%r26,skip_save_ior
1081 1074
1082 1075 mfctl %isr, %r16
1083 mfctl %cr20, %r16 /* isr */
1084 nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ 1076 nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1085 mfctl %cr21, %r17 /* ior */ 1077 mfctl %ior, %r17
1086 1078
1087 1079
1088#ifdef CONFIG_64BIT 1080#ifdef CONFIG_64BIT
@@ -1094,22 +1086,34 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
1094 extrd,u,*<> %r8,PSW_W_BIT,1,%r0 1086 extrd,u,*<> %r8,PSW_W_BIT,1,%r0
1095 depdi 0,1,2,%r17 1087 depdi 0,1,2,%r17
1096 1088
1097 /* 1089 /* adjust isr/ior: get high bits from isr and deposit in ior */
1098 * FIXME: This code has hardwired assumptions about the split 1090 space_adjust %r16,%r17,%r1
1099 * between space bits and offset bits. This will change
1100 * when we allow alternate page sizes.
1101 */
1102
1103 /* adjust isr/ior. */
1104 extrd,u %r16,63,SPACEID_SHIFT,%r1 /* get high bits from isr for ior */
1105 depd %r1,31,SPACEID_SHIFT,%r17 /* deposit them into ior */
1106 depdi 0,63,SPACEID_SHIFT,%r16 /* clear them from isr */
1107#endif 1091#endif
1108 STREG %r16, PT_ISR(%r29) 1092 STREG %r16, PT_ISR(%r29)
1109 STREG %r17, PT_IOR(%r29) 1093 STREG %r17, PT_IOR(%r29)
1110 1094
1095#if 0 && defined(CONFIG_64BIT)
1096 /* Revisit when we have 64-bit code above 4Gb */
1097 b,n intr_save2
1111 1098
1112skip_save_ior: 1099skip_save_ior:
1100 /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we
1101 * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
1102 * above.
1103 */
1104 extrd,u,* %r8,PSW_W_BIT,1,%r1
1105 cmpib,COND(=),n 1,%r1,intr_save2
1106 LDREG PT_IASQ0(%r29), %r16
1107 LDREG PT_IAOQ0(%r29), %r17
1108 /* adjust iasq/iaoq */
1109 space_adjust %r16,%r17,%r1
1110 STREG %r16, PT_IASQ0(%r29)
1111 STREG %r17, PT_IAOQ0(%r29)
1112#else
1113skip_save_ior:
1114#endif
1115
1116intr_save2:
1113 virt_map 1117 virt_map
1114 save_general %r29 1118 save_general %r29
1115 1119
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 43b308cfdf53..376ea0d1b275 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -156,11 +156,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
156 int do_color_align, last_mmap; 156 int do_color_align, last_mmap;
157 struct vm_unmapped_area_info info; 157 struct vm_unmapped_area_info info;
158 158
159#ifdef CONFIG_64BIT
160 /* This should only ever run for 32-bit processes. */
161 BUG_ON(!test_thread_flag(TIF_32BIT));
162#endif
163
164 /* requested length too big for entire address space */ 159 /* requested length too big for entire address space */
165 if (len > TASK_SIZE) 160 if (len > TASK_SIZE)
166 return -ENOMEM; 161 return -ENOMEM;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 318815212518..9372a41c8812 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -557,7 +557,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
557 cpu_lpmc(5, regs); 557 cpu_lpmc(5, regs);
558 return; 558 return;
559 559
560 case 6: 560 case PARISC_ITLB_TRAP:
561 /* Instruction TLB miss fault/Instruction page fault */ 561 /* Instruction TLB miss fault/Instruction page fault */
562 fault_address = regs->iaoq[0]; 562 fault_address = regs->iaoq[0];
563 fault_space = regs->iasq[0]; 563 fault_space = regs->iasq[0];