[S390] implement is_compat_task
Implement is_compat_task and use it all over the place. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
d90cbd469c
Коммит
7757591ab4
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
|
||||||
#define PSW32_MASK_PER 0x40000000UL
|
#define PSW32_MASK_PER 0x40000000UL
|
||||||
#define PSW32_MASK_DAT 0x04000000UL
|
#define PSW32_MASK_DAT 0x04000000UL
|
||||||
|
@ -163,12 +164,28 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
||||||
return (u32)(unsigned long)uptr;
|
return (u32)(unsigned long)uptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
|
||||||
|
static inline int is_compat_task(void)
|
||||||
|
{
|
||||||
|
return test_thread_flag(TIF_31BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int is_compat_task(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void __user *compat_alloc_user_space(long len)
|
static inline void __user *compat_alloc_user_space(long len)
|
||||||
{
|
{
|
||||||
unsigned long stack;
|
unsigned long stack;
|
||||||
|
|
||||||
stack = KSTK_ESP(current);
|
stack = KSTK_ESP(current);
|
||||||
if (test_thread_flag(TIF_31BIT))
|
if (is_compat_task())
|
||||||
stack &= 0x7fffffffUL;
|
stack &= 0x7fffffffUL;
|
||||||
return (void __user *) (stack - len);
|
return (void __user *) (stack - len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/elfcore.h>
|
#include <linux/elfcore.h>
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
#include <asm/compat.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
@ -204,7 +205,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
|
||||||
save_fp_regs(&p->thread.fp_regs);
|
save_fp_regs(&p->thread.fp_regs);
|
||||||
/* Set a new TLS ? */
|
/* Set a new TLS ? */
|
||||||
if (clone_flags & CLONE_SETTLS) {
|
if (clone_flags & CLONE_SETTLS) {
|
||||||
if (test_thread_flag(TIF_31BIT)) {
|
if (is_compat_task()) {
|
||||||
p->thread.acrs[0] = (unsigned int) regs->gprs[6];
|
p->thread.acrs[0] = (unsigned int) regs->gprs[6];
|
||||||
} else {
|
} else {
|
||||||
p->thread.acrs[0] = (unsigned int)(regs->gprs[6] >> 32);
|
p->thread.acrs[0] = (unsigned int)(regs->gprs[6] >> 32);
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include <linux/elf.h>
|
#include <linux/elf.h>
|
||||||
#include <linux/regset.h>
|
#include <linux/regset.h>
|
||||||
#include <linux/tracehook.h>
|
#include <linux/tracehook.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <asm/segment.h>
|
#include <asm/segment.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
|
@ -69,7 +69,7 @@ FixPerRegisters(struct task_struct *task)
|
||||||
if (per_info->single_step) {
|
if (per_info->single_step) {
|
||||||
per_info->control_regs.bits.starting_addr = 0;
|
per_info->control_regs.bits.starting_addr = 0;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (test_thread_flag(TIF_31BIT))
|
if (is_compat_task())
|
||||||
per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
|
per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -482,8 +482,7 @@ static int peek_user_compat(struct task_struct *child,
|
||||||
{
|
{
|
||||||
__u32 tmp;
|
__u32 tmp;
|
||||||
|
|
||||||
if (!test_thread_flag(TIF_31BIT) ||
|
if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3)
|
||||||
(addr & 3) || addr > sizeof(struct user) - 3)
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
tmp = __peek_user_compat(child, addr);
|
tmp = __peek_user_compat(child, addr);
|
||||||
|
@ -584,8 +583,7 @@ static int __poke_user_compat(struct task_struct *child,
|
||||||
static int poke_user_compat(struct task_struct *child,
|
static int poke_user_compat(struct task_struct *child,
|
||||||
addr_t addr, addr_t data)
|
addr_t addr, addr_t data)
|
||||||
{
|
{
|
||||||
if (!test_thread_flag(TIF_31BIT) ||
|
if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user32) - 3)
|
||||||
(addr & 3) || addr > sizeof(struct user32) - 3)
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
return __poke_user_compat(child, addr, data);
|
return __poke_user_compat(child, addr, data);
|
||||||
|
@ -660,7 +658,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(current->audit_context))
|
if (unlikely(current->audit_context))
|
||||||
audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
|
audit_syscall_entry(is_compat_task() ?
|
||||||
AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
|
AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
|
||||||
regs->gprs[2], regs->orig_gpr2,
|
regs->gprs[2], regs->orig_gpr2,
|
||||||
regs->gprs[3], regs->gprs[4],
|
regs->gprs[3], regs->gprs[4],
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/binfmts.h>
|
#include <linux/binfmts.h>
|
||||||
#include <linux/tracehook.h>
|
#include <linux/tracehook.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <asm/ucontext.h>
|
#include <asm/ucontext.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/lowcore.h>
|
#include <asm/lowcore.h>
|
||||||
|
@ -482,7 +483,7 @@ void do_signal(struct pt_regs *regs)
|
||||||
/* Whee! Actually deliver the signal. */
|
/* Whee! Actually deliver the signal. */
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (test_thread_flag(TIF_31BIT)) {
|
if (is_compat_task()) {
|
||||||
ret = handle_signal32(signr, &ka, &info, oldset, regs);
|
ret = handle_signal32(signr, &ka, &info, oldset, regs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <linux/elf.h>
|
#include <linux/elf.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
@ -214,7 +214,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
vdso_pagelist = vdso64_pagelist;
|
vdso_pagelist = vdso64_pagelist;
|
||||||
vdso_pages = vdso64_pages;
|
vdso_pages = vdso64_pages;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (test_thread_flag(TIF_31BIT)) {
|
if (is_compat_task()) {
|
||||||
vdso_pagelist = vdso32_pagelist;
|
vdso_pagelist = vdso32_pagelist;
|
||||||
vdso_pages = vdso32_pages;
|
vdso_pages = vdso32_pages;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
|
@ -239,7 +240,7 @@ static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
|
clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
compat = test_tsk_thread_flag(current, TIF_31BIT);
|
compat = is_compat_task();
|
||||||
if (compat && instruction == 0x0a77)
|
if (compat && instruction == 0x0a77)
|
||||||
sys32_sigreturn();
|
sys32_sigreturn();
|
||||||
else if (compat && instruction == 0x0aad)
|
else if (compat && instruction == 0x0aad)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <asm/pgalloc.h>
|
#include <asm/pgalloc.h>
|
||||||
|
#include <asm/compat.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Top of mmap area (just below the process stack).
|
* Top of mmap area (just below the process stack).
|
||||||
|
@ -55,7 +56,7 @@ static inline int mmap_is_legacy(void)
|
||||||
/*
|
/*
|
||||||
* Force standard allocation for 64 bit programs.
|
* Force standard allocation for 64 bit programs.
|
||||||
*/
|
*/
|
||||||
if (!test_thread_flag(TIF_31BIT))
|
if (!is_compat_task())
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
return sysctl_legacy_va_layout ||
|
return sysctl_legacy_va_layout ||
|
||||||
|
@ -91,7 +92,7 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
|
||||||
|
|
||||||
int s390_mmap_check(unsigned long addr, unsigned long len)
|
int s390_mmap_check(unsigned long addr, unsigned long len)
|
||||||
{
|
{
|
||||||
if (!test_thread_flag(TIF_31BIT) &&
|
if (!is_compat_task() &&
|
||||||
len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
|
len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
|
||||||
return crst_table_upgrade(current->mm, 1UL << 53);
|
return crst_table_upgrade(current->mm, 1UL << 53);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -108,8 +109,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||||
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
|
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
|
||||||
if (!(area & ~PAGE_MASK))
|
if (!(area & ~PAGE_MASK))
|
||||||
return area;
|
return area;
|
||||||
if (area == -ENOMEM &&
|
if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
|
||||||
!test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
|
|
||||||
/* Upgrade the page table to 4 levels and retry. */
|
/* Upgrade the page table to 4 levels and retry. */
|
||||||
rc = crst_table_upgrade(mm, 1UL << 53);
|
rc = crst_table_upgrade(mm, 1UL << 53);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -131,8 +131,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
|
||||||
area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
|
area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
|
||||||
if (!(area & ~PAGE_MASK))
|
if (!(area & ~PAGE_MASK))
|
||||||
return area;
|
return area;
|
||||||
if (area == -ENOMEM &&
|
if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
|
||||||
!test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
|
|
||||||
/* Upgrade the page table to 4 levels and retry. */
|
/* Upgrade the page table to 4 levels and retry. */
|
||||||
rc = crst_table_upgrade(mm, 1UL << 53);
|
rc = crst_table_upgrade(mm, 1UL << 53);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче