mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
[S390] Introduce user_regset accessors for s390
Add the user_regset definitions for normal and compat processes, replace the dump_regs core dump cruft with the generic CORE_DUMP_USER_REGSET and replace binfmt_elf32.c with the generic compat_binfmt_elf.c implementation. Signed-off-by: Martin Schwidefsky <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
This commit is contained in:
parent
ae437a452e
commit
63506c4198
8 changed files with 365 additions and 304 deletions
|
|
@ -113,6 +113,9 @@
|
|||
typedef s390_fp_regs elf_fpregset_t;
|
||||
typedef s390_regs elf_gregset_t;
|
||||
|
||||
typedef s390_fp_regs compat_elf_fpregset_t;
|
||||
typedef s390_compat_regs compat_elf_gregset_t;
|
||||
|
||||
#include <linux/sched.h> /* for task_struct */
|
||||
#include <asm/system.h> /* for save_access_regs */
|
||||
#include <asm/mmu_context.h>
|
||||
|
|
@ -123,6 +126,10 @@ typedef s390_regs elf_gregset_t;
|
|||
#define elf_check_arch(x) \
|
||||
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
|
||||
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
|
||||
#define compat_elf_check_arch(x) \
|
||||
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
|
||||
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
|
||||
#define compat_start_thread start_thread31
|
||||
|
||||
/* For SVR4/S390 the function pointer to be registered with `atexit` is
|
||||
passed in R14. */
|
||||
|
|
@ -131,6 +138,7 @@ typedef s390_regs elf_gregset_t;
|
|||
_r->gprs[14] = 0; \
|
||||
} while (0)
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
|
|
@ -140,44 +148,6 @@ typedef s390_regs elf_gregset_t;
|
|||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
#define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2)
|
||||
|
||||
/* Wow, the "main" arch needs arch dependent functions too.. :) */
|
||||
|
||||
/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
|
||||
now struct_user_regs, they are different) */
|
||||
|
||||
static inline int dump_regs(struct pt_regs *ptregs, elf_gregset_t *regs)
|
||||
{
|
||||
memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs));
|
||||
save_access_regs(regs->acrs);
|
||||
regs->orig_gpr2 = ptregs->orig_gpr2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define ELF_CORE_COPY_REGS(pr_reg, regs) dump_regs(regs, &pr_reg);
|
||||
|
||||
static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
|
||||
{
|
||||
struct pt_regs *ptregs = task_pt_regs(tsk);
|
||||
memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs));
|
||||
memcpy(regs->acrs, tsk->thread.acrs, sizeof(regs->acrs));
|
||||
regs->orig_gpr2 = ptregs->orig_gpr2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define ELF_CORE_COPY_TASK_REGS(tsk, regs) dump_task_regs(tsk, regs)
|
||||
|
||||
static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
|
||||
{
|
||||
if (tsk == current)
|
||||
save_fp_regs(fpregs);
|
||||
else
|
||||
memcpy(fpregs, &tsk->thread.fp_regs, sizeof(elf_fpregset_t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define ELF_CORE_COPY_FPREGS(tsk, fpregs) dump_task_fpu(tsk, fpregs)
|
||||
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this CPU supports. */
|
||||
|
||||
|
|
@ -204,7 +174,10 @@ do { \
|
|||
set_personality(PER_SVR4); \
|
||||
else if (current->personality != PER_LINUX32) \
|
||||
set_personality(PER_LINUX); \
|
||||
clear_thread_flag(TIF_31BIT); \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
set_thread_flag(TIF_31BIT); \
|
||||
else \
|
||||
clear_thread_flag(TIF_31BIT); \
|
||||
} while (0)
|
||||
#endif /* __s390x__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -143,11 +143,19 @@ struct stack_frame {
|
|||
/*
|
||||
* Do necessary setup to start up a new thread.
|
||||
*/
|
||||
#define start_thread(regs, new_psw, new_stackp) do { \
|
||||
#define start_thread(regs, new_psw, new_stackp) do { \
|
||||
set_fs(USER_DS); \
|
||||
regs->psw.mask = psw_user_bits; \
|
||||
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
|
||||
regs->gprs[15] = new_stackp ; \
|
||||
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
|
||||
regs->gprs[15] = new_stackp; \
|
||||
} while (0)
|
||||
|
||||
#define start_thread31(regs, new_psw, new_stackp) do { \
|
||||
set_fs(USER_DS); \
|
||||
regs->psw.mask = psw_user32_bits; \
|
||||
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
|
||||
regs->gprs[15] = new_stackp; \
|
||||
crst_table_downgrade(current->mm, 1UL << 31); \
|
||||
} while (0)
|
||||
|
||||
/* Forward declaration, a strange C thing */
|
||||
|
|
|
|||
|
|
@ -215,6 +215,12 @@ typedef struct
|
|||
unsigned long addr;
|
||||
} __attribute__ ((aligned(8))) psw_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__u32 mask;
|
||||
__u32 addr;
|
||||
} __attribute__ ((aligned(8))) psw_compat_t;
|
||||
|
||||
#ifndef __s390x__
|
||||
|
||||
#define PSW_MASK_PER 0x40000000UL
|
||||
|
|
@ -292,6 +298,15 @@ typedef struct
|
|||
unsigned long orig_gpr2;
|
||||
} s390_regs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
psw_compat_t psw;
|
||||
__u32 gprs[NUM_GPRS];
|
||||
__u32 acrs[NUM_ACRS];
|
||||
__u32 orig_gpr2;
|
||||
} s390_compat_regs;
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/setup.h>
|
||||
#include <asm/page.h>
|
||||
|
|
|
|||
Loading…
Reference in a new issue