Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+39 -39
+6 -3
arch/parisc/include/asm/elf.h
··· 235 235 #define SET_PERSONALITY(ex) \ 236 236 ({ \ 237 237 set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ 238 + clear_thread_flag(TIF_32BIT); \ 238 239 current->thread.map_base = DEFAULT_MAP_BASE; \ 239 240 current->thread.task_size = DEFAULT_TASK_SIZE; \ 240 241 }) ··· 244 243 245 244 #define COMPAT_SET_PERSONALITY(ex) \ 246 245 ({ \ 247 - set_thread_flag(TIF_32BIT); \ 248 - current->thread.map_base = DEFAULT_MAP_BASE32; \ 249 - current->thread.task_size = DEFAULT_TASK_SIZE32; \ 246 + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ 247 + set_thread_flag(TIF_32BIT); \ 248 + current->thread.map_base = DEFAULT_MAP_BASE32; \ 249 + current->thread.task_size = DEFAULT_TASK_SIZE32; \ 250 + } else clear_thread_flag(TIF_32BIT); \ 250 251 }) 251 252 252 253 /*
+1 -5
arch/parisc/include/asm/processor.h
··· 256 256 * it in here from the current->personality 257 257 */ 258 258 259 - #ifdef CONFIG_64BIT 260 - #define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT)) 261 - #else 262 - #define USER_WIDE_MODE 0 263 - #endif 259 + #define USER_WIDE_MODE (!is_32bit_task()) 264 260 265 261 #define start_thread(regs, new_pc, new_sp) do { \ 266 262 elf_addr_t *sp = (elf_addr_t *)new_sp; \
+3 -1
arch/parisc/include/asm/traps.h
··· 2 2 #ifndef __ASM_TRAPS_H 3 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 8 struct pt_regs; 7 9 8 10 /* traps.c */
+28 -24
arch/parisc/kernel/entry.S
··· 36 36 #include <asm/signal.h> 37 37 #include <asm/unistd.h> 38 38 #include <asm/ldcw.h> 39 + #include <asm/traps.h> 39 40 #include <asm/thread_info.h> 40 41 41 42 #include <linux/linkage.h> ··· 693 692 def 3 694 693 extint 4 695 694 def 5 696 - itlb_20 6 695 + itlb_20 PARISC_ITLB_TRAP 697 696 def 7 698 697 def 8 699 698 def 9 ··· 736 735 def 3 737 736 extint 4 738 737 def 5 739 - itlb_11 6 738 + itlb_11 PARISC_ITLB_TRAP 740 739 def 7 741 740 def 8 742 741 def 9 ··· 1069 1068 save_specials %r29 1070 1069 1071 1070 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */ 1072 - 1073 - /* 1074 - * FIXME: 1) Use a #define for the hardwired "6" below (and in 1075 - * traps.c. 1076 - * 2) Once we start executing code above 4 Gb, we need 1077 - * to adjust iasq/iaoq here in the same way we 1078 - * adjust isr/ior below. 1079 - */ 1080 - 1081 - cmpib,COND(=),n 6,%r26,skip_save_ior 1071 + cmpib,COND(=),n PARISC_ITLB_TRAP,%r26,skip_save_ior 1082 1072 1083 1073 1084 - mfctl %cr20, %r16 /* isr */ 1074 + mfctl %isr, %r16 1085 1075 nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ 1086 - mfctl %cr21, %r17 /* ior */ 1076 + mfctl %ior, %r17 1087 1077 1088 1078 1089 1079 #ifdef CONFIG_64BIT ··· 1086 1094 extrd,u,*<> %r8,PSW_W_BIT,1,%r0 1087 1095 depdi 0,1,2,%r17 1088 1096 1089 - /* 1090 - * FIXME: This code has hardwired assumptions about the split 1091 - * between space bits and offset bits. This will change 1092 - * when we allow alternate page sizes. 1093 - */ 1094 - 1095 - /* adjust isr/ior. */ 1096 - extrd,u %r16,63,SPACEID_SHIFT,%r1 /* get high bits from isr for ior */ 1097 - depd %r1,31,SPACEID_SHIFT,%r17 /* deposit them into ior */ 1098 - depdi 0,63,SPACEID_SHIFT,%r16 /* clear them from isr */ 1097 + /* adjust isr/ior: get high bits from isr and deposit in ior */ 1098 + space_adjust %r16,%r17,%r1 1099 1099 #endif 1100 1100 STREG %r16, PT_ISR(%r29) 1101 1101 STREG %r17, PT_IOR(%r29) 1102 1102 1103 + #if 0 && defined(CONFIG_64BIT) 1104 + /* Revisit when we have 64-bit code above 4Gb */ 1105 + b,n intr_save2 1103 1106 1104 1107 skip_save_ior: 1108 + /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we 1109 + * need to adjust iasq/iaoq here in the same way we adjusted isr/ior 1110 + * above. 1111 + */ 1112 + extrd,u,* %r8,PSW_W_BIT,1,%r1 1113 + cmpib,COND(=),n 1,%r1,intr_save2 1114 + LDREG PT_IASQ0(%r29), %r16 1115 + LDREG PT_IAOQ0(%r29), %r17 1116 + /* adjust iasq/iaoq */ 1117 + space_adjust %r16,%r17,%r1 1118 + STREG %r16, PT_IASQ0(%r29) 1119 + STREG %r17, PT_IAOQ0(%r29) 1120 + #else 1121 + skip_save_ior: 1122 + #endif 1123 + 1124 + intr_save2: 1105 1125 virt_map 1106 1126 save_general %r29 1107 1127
-5
arch/parisc/kernel/sys_parisc.c
··· 156 156 int do_color_align, last_mmap; 157 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 159 /* requested length too big for entire address space */ 165 160 if (len > TASK_SIZE) 166 161 return -ENOMEM;
+1 -1
arch/parisc/kernel/traps.c
··· 557 557 cpu_lpmc(5, regs); 558 558 return; 559 559 560 - case 6: 560 + case PARISC_ITLB_TRAP: 561 561 /* Instruction TLB miss fault/Instruction page fault */ 562 562 fault_address = regs->iaoq[0]; 563 563 fault_space = regs->iasq[0];