diff options
author | Helge Deller <deller@gmx.de> | 2018-08-16 16:39:50 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2018-08-17 10:45:24 -0400 |
commit | 5b00ca0b8035e49ef7c466e959c5cb457a654351 (patch) | |
tree | 960ff146c537f96aa4da21030960c7981bd86ae0 | |
parent | c8921d72e390cb6fca3fb2b0c2badfda851647eb (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.h | 9 | ||||
-rw-r--r-- | arch/parisc/include/asm/processor.h | 6 | ||||
-rw-r--r-- | arch/parisc/include/asm/traps.h | 4 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 52 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 5 | ||||
-rw-r--r-- | arch/parisc/kernel/traps.c | 2 |
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__) | ||
6 | struct pt_regs; | 8 | struct 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 | ||
1112 | skip_save_ior: | 1099 | skip_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 | ||
1113 | skip_save_ior: | ||
1114 | #endif | ||
1115 | |||
1116 | intr_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]; |