applications Reply-To: Executing 64-bit applications was broken. This patch restores this support and cleans up some code paths. Signed-off-by: Helge Deller <deller@xxxxxx> diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h index f019d3e..d00973a 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; #define SET_PERSONALITY(ex) \ ({ \ set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ + clear_thread_flag(TIF_32BIT); \ current->thread.map_base = DEFAULT_MAP_BASE; \ current->thread.task_size = DEFAULT_TASK_SIZE; \ }) @@ -243,9 +244,11 @@ typedef unsigned long elf_greg_t; #define COMPAT_SET_PERSONALITY(ex) \ ({ \ - set_thread_flag(TIF_32BIT); \ - current->thread.map_base = DEFAULT_MAP_BASE32; \ - current->thread.task_size = DEFAULT_TASK_SIZE32; \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ + set_thread_flag(TIF_32BIT); \ + current->thread.map_base = DEFAULT_MAP_BASE32; \ + current->thread.task_size = DEFAULT_TASK_SIZE32; \ + } else clear_thread_flag(TIF_32BIT); \ }) /* diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 2dbe558..2bd5e69 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: * it in here from the current->personality */ -#ifdef CONFIG_64BIT -#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT)) -#else -#define USER_WIDE_MODE 0 -#endif +#define USER_WIDE_MODE (!is_32bit_task()) #define start_thread(regs, new_pc, new_sp) do { \ 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 e000132..8ecc1f0 100644 --- a/arch/parisc/include/asm/traps.h +++ b/arch/parisc/include/asm/traps.h @@ -2,7 +2,9 @@ #ifndef __ASM_TRAPS_H #define __ASM_TRAPS_H -#ifdef __KERNEL__ +#define PARISC_ITLB_TRAP 6 /* defined by architecture. Do not change. */ + +#if !defined(__ASSEMBLY__) struct pt_regs; /* traps.c */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 1b4732e..ef1402c 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -36,6 +36,7 @@ #include <asm/signal.h> #include <asm/unistd.h> #include <asm/ldcw.h> +#include <asm/traps.h> #include <asm/thread_info.h> #include <linux/linkage.h> @@ -692,7 +693,7 @@ ENTRY(fault_vector_20) def 3 extint 4 def 5 - itlb_20 6 + itlb_20 PARISC_ITLB_TRAP def 7 def 8 def 9 @@ -735,7 +736,7 @@ ENTRY(fault_vector_11) def 3 extint 4 def 5 - itlb_11 6 + itlb_11 PARISC_ITLB_TRAP def 7 def 8 def 9 @@ -1068,21 +1069,12 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ save_specials %r29 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */ + cmpib,COND(=),n PARISC_ITLB_TRAP,%r26,skip_save_ior - /* - * FIXME: 1) Use a #define for the hardwired "6" below (and in - * traps.c. - * 2) Once we start executing code above 4 Gb, we need - * to adjust iasq/iaoq here in the same way we - * adjust isr/ior below. - */ - - cmpib,COND(=),n 6,%r26,skip_save_ior - - mfctl %cr20, %r16 /* isr */ + mfctl %isr, %r16 nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ - mfctl %cr21, %r17 /* ior */ + mfctl %ior, %r17 #ifdef CONFIG_64BIT @@ -1094,22 +1086,34 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ extrd,u,*<> %r8,PSW_W_BIT,1,%r0 depdi 0,1,2,%r17 - /* - * FIXME: This code has hardwired assumptions about the split - * between space bits and offset bits. This will change - * when we allow alternate page sizes. - */ - - /* adjust isr/ior. */ - extrd,u %r16,63,SPACEID_SHIFT,%r1 /* get high bits from isr for ior */ - depd %r1,31,SPACEID_SHIFT,%r17 /* deposit them into ior */ - depdi 0,63,SPACEID_SHIFT,%r16 /* clear them from isr */ + /* adjust isr/ior: get high bits from isr and deposit in ior */ + space_adjust %r16,%r17,%r1 #endif STREG %r16, PT_ISR(%r29) STREG %r17, PT_IOR(%r29) +#if 0 && defined(CONFIG_64BIT) + /* Revisit when we have 64-bit code above 4Gb */ + b,n intr_save2 skip_save_ior: + /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we + * need to adjust iasq/iaoq here in the same way we adjusted isr/ior + * above. + */ + extrd,u,* %r8,PSW_W_BIT,1,%r1 + cmpib,COND(=),n 1,%r1,intr_save2 + LDREG PT_IASQ0(%r29), %r16 + LDREG PT_IAOQ0(%r29), %r17 + /* adjust iasq/iaoq */ + space_adjust %r16,%r17,%r1 + STREG %r16, PT_IASQ0(%r29) + STREG %r17, PT_IAOQ0(%r29) +#else +skip_save_ior: +#endif + +intr_save2: virt_map save_general %r29 diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 43b308c..376ea0d 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, int do_color_align, last_mmap; struct vm_unmapped_area_info info; -#ifdef CONFIG_64BIT - /* This should only ever run for 32-bit processes. */ - BUG_ON(!test_thread_flag(TIF_32BIT)); -#endif - /* requested length too big for entire address space */ if (len > TASK_SIZE) return -ENOMEM; diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 4309ad3..ebef30a 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -557,7 +560,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) cpu_lpmc(5, regs); return; - case 6: + case PARISC_ITLB_TRAP: /* Instruction TLB miss fault/Instruction page fault */ fault_address = regs->iaoq[0]; fault_space = regs->iasq[0];