Commit 5b00ca0b authored by Helge Deller's avatar Helge Deller

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: default avatarHelge Deller <deller@gmx.de>
parent c8921d72
...@@ -235,6 +235,7 @@ typedef unsigned long elf_greg_t; ...@@ -235,6 +235,7 @@ typedef unsigned long elf_greg_t;
#define SET_PERSONALITY(ex) \ #define SET_PERSONALITY(ex) \
({ \ ({ \
set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
clear_thread_flag(TIF_32BIT); \
current->thread.map_base = DEFAULT_MAP_BASE; \ current->thread.map_base = DEFAULT_MAP_BASE; \
current->thread.task_size = DEFAULT_TASK_SIZE; \ current->thread.task_size = DEFAULT_TASK_SIZE; \
}) })
...@@ -243,9 +244,11 @@ typedef unsigned long elf_greg_t; ...@@ -243,9 +244,11 @@ typedef unsigned long elf_greg_t;
#define COMPAT_SET_PERSONALITY(ex) \ #define COMPAT_SET_PERSONALITY(ex) \
({ \ ({ \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
set_thread_flag(TIF_32BIT); \ set_thread_flag(TIF_32BIT); \
current->thread.map_base = DEFAULT_MAP_BASE32; \ current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32; \ current->thread.task_size = DEFAULT_TASK_SIZE32; \
} else clear_thread_flag(TIF_32BIT); \
}) })
/* /*
......
...@@ -256,11 +256,7 @@ on downward growing arches, it looks like this: ...@@ -256,11 +256,7 @@ on downward growing arches, it looks like this:
* it in here from the current->personality * it in here from the current->personality
*/ */
#ifdef CONFIG_64BIT #define USER_WIDE_MODE (!is_32bit_task())
#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
#else
#define USER_WIDE_MODE 0
#endif
#define start_thread(regs, new_pc, new_sp) do { \ #define start_thread(regs, new_pc, new_sp) do { \
elf_addr_t *sp = (elf_addr_t *)new_sp; \ elf_addr_t *sp = (elf_addr_t *)new_sp; \
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
#ifndef __ASM_TRAPS_H #ifndef __ASM_TRAPS_H
#define __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; struct pt_regs;
/* traps.c */ /* traps.c */
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/signal.h> #include <asm/signal.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/ldcw.h> #include <asm/ldcw.h>
#include <asm/traps.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <linux/linkage.h> #include <linux/linkage.h>
...@@ -692,7 +693,7 @@ ENTRY(fault_vector_20) ...@@ -692,7 +693,7 @@ ENTRY(fault_vector_20)
def 3 def 3
extint 4 extint 4
def 5 def 5
itlb_20 6 itlb_20 PARISC_ITLB_TRAP
def 7 def 7
def 8 def 8
def 9 def 9
...@@ -735,7 +736,7 @@ ENTRY(fault_vector_11) ...@@ -735,7 +736,7 @@ ENTRY(fault_vector_11)
def 3 def 3
extint 4 extint 4
def 5 def 5
itlb_11 6 itlb_11 PARISC_ITLB_TRAP
def 7 def 7
def 8 def 8
def 9 def 9
...@@ -1068,21 +1069,12 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ ...@@ -1068,21 +1069,12 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
save_specials %r29 save_specials %r29
/* If this trap is a itlb miss, skip saving/adjusting isr/ior */ /* 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 %isr, %r16
mfctl %cr20, %r16 /* isr */
nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
mfctl %cr21, %r17 /* ior */ mfctl %ior, %r17
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
...@@ -1094,22 +1086,34 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ ...@@ -1094,22 +1086,34 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
extrd,u,*<> %r8,PSW_W_BIT,1,%r0 extrd,u,*<> %r8,PSW_W_BIT,1,%r0
depdi 0,1,2,%r17 depdi 0,1,2,%r17
/* /* adjust isr/ior: get high bits from isr and deposit in ior */
* FIXME: This code has hardwired assumptions about the split space_adjust %r16,%r17,%r1
* 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 */
#endif #endif
STREG %r16, PT_ISR(%r29) STREG %r16, PT_ISR(%r29)
STREG %r17, PT_IOR(%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: 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 virt_map
save_general %r29 save_general %r29
......
...@@ -156,11 +156,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -156,11 +156,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
int do_color_align, last_mmap; int do_color_align, last_mmap;
struct vm_unmapped_area_info info; 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 */ /* requested length too big for entire address space */
if (len > TASK_SIZE) if (len > TASK_SIZE)
return -ENOMEM; return -ENOMEM;
......
...@@ -557,7 +557,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) ...@@ -557,7 +557,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
cpu_lpmc(5, regs); cpu_lpmc(5, regs);
return; return;
case 6: case PARISC_ITLB_TRAP:
/* Instruction TLB miss fault/Instruction page fault */ /* Instruction TLB miss fault/Instruction page fault */
fault_address = regs->iaoq[0]; fault_address = regs->iaoq[0];
fault_space = regs->iasq[0]; fault_space = regs->iasq[0];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment