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>
This commit is contained in:
@ -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;
|
|||||||
|
|
||||||
#define COMPAT_SET_PERSONALITY(ex) \
|
#define COMPAT_SET_PERSONALITY(ex) \
|
||||||
({ \
|
({ \
|
||||||
set_thread_flag(TIF_32BIT); \
|
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
|
||||||
current->thread.map_base = DEFAULT_MAP_BASE32; \
|
set_thread_flag(TIF_32BIT); \
|
||||||
current->thread.task_size = DEFAULT_TASK_SIZE32; \
|
current->thread.map_base = DEFAULT_MAP_BASE32; \
|
||||||
|
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:
|
|||||||
* 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 @@
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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 */
|
|||||||
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 %cr20, %r16 /* isr */
|
mfctl %isr, %r16
|
||||||
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 */
|
|||||||
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,
|
|||||||
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)
|
|||||||
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];
|
||||||
|
Reference in New Issue
Block a user