mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Git pull request for linus
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIbBAABAgAGBQJQnM18AAoJENFylnOm3dTbxh8P92lymakR2CUNk7pJINluS9ay fbXHor+2KS31gWD6M1oqtdH9KLsiqDBNraTiyQwhzC5i6XeNnABN3KW6tJmi6ntl p8q3ZjflmoW9tMziulUmFKQ1nuDG8ii4OnGj2CShcAVU7BCRJeqT905epV2jRf6V AL2TpdAkYAWpjYI9JLOWCzu3WWxYvnnaDXDTsbNYMGE77zHSkAP76Or9fKo4jcj4 GORcgPumskB64W1RYqfGkvmhYCI5z0YaIVMTGLunrS+jXIbYsEsSyAP1zUudmkEI Mz/MQ3j8zyAXKGkGj2UW+LBs35T8UJeZVigkrieRS9trzWp9seNqx717CTVd1dro fwAj+pmeEYi1Z2NQ0DASBb/87t5QscWeeZU6k7FHhr1Ro84HJcZ16riknA3Zzd+i 1kWup/TyeApY2uecAYHykK2LaxM4qrn62B9Lg/fl/iU5mrHsrm8hrcSkX7FhmdrR N+/TeCte6RZwZnm4ZmnQPrNctdBYdp1pCmfBZbQcdhsTBDs0+UkQBeANHnxQJxmf +y84SoC4O2V+LC+ee/zHc3DuaOwcTnAlrf7APYUGf8Y9pOGvT5E5LG8otVrzfyeT 40YoN5fhddQfmKZksTvhTnBktg8eMr2MkBvg751qTgvX7zc7YpIvwc9T3k9fLy3M UAXx9XTmKGPLDPN1qvU= =de8m -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://github.com/gxt/linux Pull unicore32 update from Guan Xuetao. * tag 'for-linus' of git://github.com/gxt/linux: arch/unicore32: remove CONFIG_EXPERIMENTAL unicore32: switch to generic sys_execve() unicore32: switch to generic kernel_thread()/kernel_execve() unicore32: Use Kbuild infrastructure for kvm_para.h UAPI: (Scripted) Disintegrate arch/unicore32/include/asm UniCore32-bugfix: Remove definitions in asm/bug.h to solve difference between native and cross compiler UniCore32-bugfix: fix mismatch return value of __xchg_bad_pointer UniCore32 bugfix: add missed CONFIG_ZONE_DMA unicore32/mm/fault.c: Port OOM changes to do_pf
This commit is contained in:
commit
c5e35d6c51
17 changed files with 160 additions and 219 deletions
|
@ -16,6 +16,8 @@ config UNICORE32
|
||||||
select ARCH_WANT_FRAME_POINTERS
|
select ARCH_WANT_FRAME_POINTERS
|
||||||
select GENERIC_IOMAP
|
select GENERIC_IOMAP
|
||||||
select MODULES_USE_ELF_REL
|
select MODULES_USE_ELF_REL
|
||||||
|
select GENERIC_KERNEL_THREAD
|
||||||
|
select GENERIC_KERNEL_EXECVE
|
||||||
help
|
help
|
||||||
UniCore-32 is 32-bit Instruction Set Architecture,
|
UniCore-32 is 32-bit Instruction Set Architecture,
|
||||||
including a series of low-power-consumption RISC chip
|
including a series of low-power-consumption RISC chip
|
||||||
|
@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
config ARCH_MAY_HAVE_PC_FDC
|
config ARCH_MAY_HAVE_PC_FDC
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config ZONE_DMA
|
||||||
|
def_bool y
|
||||||
|
|
||||||
config NEED_DMA_MAP_STATE
|
config NEED_DMA_MAP_STATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
@ -216,7 +221,7 @@ config PUV3_GPIO
|
||||||
bool
|
bool
|
||||||
depends on !ARCH_FPGA
|
depends on !ARCH_FPGA
|
||||||
select GENERIC_GPIO
|
select GENERIC_GPIO
|
||||||
select GPIO_SYSFS if EXPERIMENTAL
|
select GPIO_SYSFS
|
||||||
default y
|
default y
|
||||||
|
|
||||||
if PUV3_NB0916
|
if PUV3_NB0916
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
include include/asm-generic/Kbuild.asm
|
|
||||||
|
|
||||||
generic-y += atomic.h
|
generic-y += atomic.h
|
||||||
generic-y += auxvec.h
|
generic-y += auxvec.h
|
||||||
|
|
|
@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err);
|
||||||
extern void uc32_notify_die(const char *str, struct pt_regs *regs,
|
extern void uc32_notify_die(const char *str, struct pt_regs *regs,
|
||||||
struct siginfo *info, unsigned long err, unsigned long trap);
|
struct siginfo *info, unsigned long err, unsigned long trap);
|
||||||
|
|
||||||
extern asmlinkage void __backtrace(void);
|
|
||||||
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
|
|
||||||
|
|
||||||
extern void __show_regs(struct pt_regs *);
|
|
||||||
|
|
||||||
#endif /* __UNICORE_BUG_H__ */
|
#endif /* __UNICORE_BUG_H__ */
|
||||||
|
|
|
@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
|
||||||
: "memory", "cc");
|
: "memory", "cc");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = __xchg_bad_pointer();
|
__xchg_bad_pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#include <asm-generic/kvm_para.h>
|
|
|
@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p);
|
||||||
|
|
||||||
#define cpu_relax() barrier()
|
#define cpu_relax() barrier()
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new kernel thread
|
|
||||||
*/
|
|
||||||
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
|
|
||||||
|
|
||||||
#define task_pt_regs(p) \
|
#define task_pt_regs(p) \
|
||||||
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
|
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
|
||||||
|
|
||||||
|
|
|
@ -12,80 +12,10 @@
|
||||||
#ifndef __UNICORE_PTRACE_H__
|
#ifndef __UNICORE_PTRACE_H__
|
||||||
#define __UNICORE_PTRACE_H__
|
#define __UNICORE_PTRACE_H__
|
||||||
|
|
||||||
#define PTRACE_GET_THREAD_AREA 22
|
#include <uapi/asm/ptrace.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* PSR bits
|
|
||||||
*/
|
|
||||||
#define USER_MODE 0x00000010
|
|
||||||
#define REAL_MODE 0x00000011
|
|
||||||
#define INTR_MODE 0x00000012
|
|
||||||
#define PRIV_MODE 0x00000013
|
|
||||||
#define ABRT_MODE 0x00000017
|
|
||||||
#define EXTN_MODE 0x0000001b
|
|
||||||
#define SUSR_MODE 0x0000001f
|
|
||||||
#define MODE_MASK 0x0000001f
|
|
||||||
#define PSR_R_BIT 0x00000040
|
|
||||||
#define PSR_I_BIT 0x00000080
|
|
||||||
#define PSR_V_BIT 0x10000000
|
|
||||||
#define PSR_C_BIT 0x20000000
|
|
||||||
#define PSR_Z_BIT 0x40000000
|
|
||||||
#define PSR_S_BIT 0x80000000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Groups of PSR bits
|
|
||||||
*/
|
|
||||||
#define PSR_f 0xff000000 /* Flags */
|
|
||||||
#define PSR_c 0x000000ff /* Control */
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
/*
|
|
||||||
* This struct defines the way the registers are stored on the
|
|
||||||
* stack during a system call. Note that sizeof(struct pt_regs)
|
|
||||||
* has to be a multiple of 8.
|
|
||||||
*/
|
|
||||||
struct pt_regs {
|
|
||||||
unsigned long uregs[34];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define UCreg_asr uregs[32]
|
|
||||||
#define UCreg_pc uregs[31]
|
|
||||||
#define UCreg_lr uregs[30]
|
|
||||||
#define UCreg_sp uregs[29]
|
|
||||||
#define UCreg_ip uregs[28]
|
|
||||||
#define UCreg_fp uregs[27]
|
|
||||||
#define UCreg_26 uregs[26]
|
|
||||||
#define UCreg_25 uregs[25]
|
|
||||||
#define UCreg_24 uregs[24]
|
|
||||||
#define UCreg_23 uregs[23]
|
|
||||||
#define UCreg_22 uregs[22]
|
|
||||||
#define UCreg_21 uregs[21]
|
|
||||||
#define UCreg_20 uregs[20]
|
|
||||||
#define UCreg_19 uregs[19]
|
|
||||||
#define UCreg_18 uregs[18]
|
|
||||||
#define UCreg_17 uregs[17]
|
|
||||||
#define UCreg_16 uregs[16]
|
|
||||||
#define UCreg_15 uregs[15]
|
|
||||||
#define UCreg_14 uregs[14]
|
|
||||||
#define UCreg_13 uregs[13]
|
|
||||||
#define UCreg_12 uregs[12]
|
|
||||||
#define UCreg_11 uregs[11]
|
|
||||||
#define UCreg_10 uregs[10]
|
|
||||||
#define UCreg_09 uregs[9]
|
|
||||||
#define UCreg_08 uregs[8]
|
|
||||||
#define UCreg_07 uregs[7]
|
|
||||||
#define UCreg_06 uregs[6]
|
|
||||||
#define UCreg_05 uregs[5]
|
|
||||||
#define UCreg_04 uregs[4]
|
|
||||||
#define UCreg_03 uregs[3]
|
|
||||||
#define UCreg_02 uregs[2]
|
|
||||||
#define UCreg_01 uregs[1]
|
|
||||||
#define UCreg_00 uregs[0]
|
|
||||||
#define UCreg_ORIG_00 uregs[33]
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#define user_mode(regs) \
|
#define user_mode(regs) \
|
||||||
(processor_mode(regs) == USER_MODE)
|
(processor_mode(regs) == USER_MODE)
|
||||||
|
|
||||||
|
@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs)
|
||||||
|
|
||||||
#define instruction_pointer(regs) ((regs)->UCreg_pc)
|
#define instruction_pointer(regs) ((regs)->UCreg_pc)
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
# UAPI Header export list
|
# UAPI Header export list
|
||||||
include include/uapi/asm-generic/Kbuild.asm
|
include include/uapi/asm-generic/Kbuild.asm
|
||||||
|
|
||||||
|
header-y += byteorder.h
|
||||||
|
header-y += kvm_para.h
|
||||||
|
header-y += ptrace.h
|
||||||
|
header-y += sigcontext.h
|
||||||
|
header-y += unistd.h
|
||||||
|
|
||||||
|
generic-y += kvm_para.h
|
||||||
|
|
90
arch/unicore32/include/uapi/asm/ptrace.h
Normal file
90
arch/unicore32/include/uapi/asm/ptrace.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/include/asm/ptrace.h
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef _UAPI__UNICORE_PTRACE_H__
|
||||||
|
#define _UAPI__UNICORE_PTRACE_H__
|
||||||
|
|
||||||
|
#define PTRACE_GET_THREAD_AREA 22
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PSR bits
|
||||||
|
*/
|
||||||
|
#define USER_MODE 0x00000010
|
||||||
|
#define REAL_MODE 0x00000011
|
||||||
|
#define INTR_MODE 0x00000012
|
||||||
|
#define PRIV_MODE 0x00000013
|
||||||
|
#define ABRT_MODE 0x00000017
|
||||||
|
#define EXTN_MODE 0x0000001b
|
||||||
|
#define SUSR_MODE 0x0000001f
|
||||||
|
#define MODE_MASK 0x0000001f
|
||||||
|
#define PSR_R_BIT 0x00000040
|
||||||
|
#define PSR_I_BIT 0x00000080
|
||||||
|
#define PSR_V_BIT 0x10000000
|
||||||
|
#define PSR_C_BIT 0x20000000
|
||||||
|
#define PSR_Z_BIT 0x40000000
|
||||||
|
#define PSR_S_BIT 0x80000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Groups of PSR bits
|
||||||
|
*/
|
||||||
|
#define PSR_f 0xff000000 /* Flags */
|
||||||
|
#define PSR_c 0x000000ff /* Control */
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This struct defines the way the registers are stored on the
|
||||||
|
* stack during a system call. Note that sizeof(struct pt_regs)
|
||||||
|
* has to be a multiple of 8.
|
||||||
|
*/
|
||||||
|
struct pt_regs {
|
||||||
|
unsigned long uregs[34];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UCreg_asr uregs[32]
|
||||||
|
#define UCreg_pc uregs[31]
|
||||||
|
#define UCreg_lr uregs[30]
|
||||||
|
#define UCreg_sp uregs[29]
|
||||||
|
#define UCreg_ip uregs[28]
|
||||||
|
#define UCreg_fp uregs[27]
|
||||||
|
#define UCreg_26 uregs[26]
|
||||||
|
#define UCreg_25 uregs[25]
|
||||||
|
#define UCreg_24 uregs[24]
|
||||||
|
#define UCreg_23 uregs[23]
|
||||||
|
#define UCreg_22 uregs[22]
|
||||||
|
#define UCreg_21 uregs[21]
|
||||||
|
#define UCreg_20 uregs[20]
|
||||||
|
#define UCreg_19 uregs[19]
|
||||||
|
#define UCreg_18 uregs[18]
|
||||||
|
#define UCreg_17 uregs[17]
|
||||||
|
#define UCreg_16 uregs[16]
|
||||||
|
#define UCreg_15 uregs[15]
|
||||||
|
#define UCreg_14 uregs[14]
|
||||||
|
#define UCreg_13 uregs[13]
|
||||||
|
#define UCreg_12 uregs[12]
|
||||||
|
#define UCreg_11 uregs[11]
|
||||||
|
#define UCreg_10 uregs[10]
|
||||||
|
#define UCreg_09 uregs[9]
|
||||||
|
#define UCreg_08 uregs[8]
|
||||||
|
#define UCreg_07 uregs[7]
|
||||||
|
#define UCreg_06 uregs[6]
|
||||||
|
#define UCreg_05 uregs[5]
|
||||||
|
#define UCreg_04 uregs[4]
|
||||||
|
#define UCreg_03 uregs[3]
|
||||||
|
#define UCreg_02 uregs[2]
|
||||||
|
#define UCreg_01 uregs[1]
|
||||||
|
#define UCreg_00 uregs[0]
|
||||||
|
#define UCreg_ORIG_00 uregs[33]
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _UAPI__UNICORE_PTRACE_H__ */
|
|
@ -12,3 +12,4 @@
|
||||||
|
|
||||||
/* Use the standard ABI for syscalls. */
|
/* Use the standard ABI for syscalls. */
|
||||||
#include <asm-generic/unistd.h>
|
#include <asm-generic/unistd.h>
|
||||||
|
#define __ARCH_WANT_SYS_EXECVE
|
|
@ -573,17 +573,16 @@ ENDPROC(ret_to_user)
|
||||||
*/
|
*/
|
||||||
ENTRY(ret_from_fork)
|
ENTRY(ret_from_fork)
|
||||||
b.l schedule_tail
|
b.l schedule_tail
|
||||||
get_thread_info tsk
|
|
||||||
ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing
|
|
||||||
mov why, #1
|
|
||||||
cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
|
|
||||||
beq ret_slow_syscall
|
|
||||||
mov r1, sp
|
|
||||||
mov r0, #1 @ trace exit [IP = 1]
|
|
||||||
b.l syscall_trace
|
|
||||||
b ret_slow_syscall
|
b ret_slow_syscall
|
||||||
ENDPROC(ret_from_fork)
|
ENDPROC(ret_from_fork)
|
||||||
|
|
||||||
|
ENTRY(ret_from_kernel_thread)
|
||||||
|
b.l schedule_tail
|
||||||
|
mov r0, r5
|
||||||
|
adr lr, ret_slow_syscall
|
||||||
|
mov pc, r4
|
||||||
|
ENDPROC(ret_from_kernel_thread)
|
||||||
|
|
||||||
/*=============================================================================
|
/*=============================================================================
|
||||||
* SWI handler
|
* SWI handler
|
||||||
*-----------------------------------------------------------------------------
|
*-----------------------------------------------------------------------------
|
||||||
|
@ -669,11 +668,6 @@ __cr_alignment:
|
||||||
#endif
|
#endif
|
||||||
.ltorg
|
.ltorg
|
||||||
|
|
||||||
ENTRY(sys_execve)
|
|
||||||
add r3, sp, #S_OFF
|
|
||||||
b __sys_execve
|
|
||||||
ENDPROC(sys_execve)
|
|
||||||
|
|
||||||
ENTRY(sys_clone)
|
ENTRY(sys_clone)
|
||||||
add ip, sp, #S_OFF
|
add ip, sp, #S_OFF
|
||||||
stw ip, [sp+], #4
|
stw ip, [sp+], #4
|
||||||
|
|
|
@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task)
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
|
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
|
||||||
|
asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
|
||||||
|
|
||||||
int
|
int
|
||||||
copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
|
@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
struct thread_info *thread = task_thread_info(p);
|
struct thread_info *thread = task_thread_info(p);
|
||||||
struct pt_regs *childregs = task_pt_regs(p);
|
struct pt_regs *childregs = task_pt_regs(p);
|
||||||
|
|
||||||
|
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
|
||||||
|
thread->cpu_context.sp = (unsigned long)childregs;
|
||||||
|
if (unlikely(!regs)) {
|
||||||
|
thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
|
||||||
|
thread->cpu_context.r4 = stack_start;
|
||||||
|
thread->cpu_context.r5 = stk_sz;
|
||||||
|
memset(childregs, 0, sizeof(struct pt_regs));
|
||||||
|
} else {
|
||||||
|
thread->cpu_context.pc = (unsigned long)ret_from_fork;
|
||||||
*childregs = *regs;
|
*childregs = *regs;
|
||||||
childregs->UCreg_00 = 0;
|
childregs->UCreg_00 = 0;
|
||||||
childregs->UCreg_sp = stack_start;
|
childregs->UCreg_sp = stack_start;
|
||||||
|
|
||||||
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
|
|
||||||
thread->cpu_context.sp = (unsigned long)childregs;
|
|
||||||
thread->cpu_context.pc = (unsigned long)ret_from_fork;
|
|
||||||
|
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
childregs->UCreg_16 = regs->UCreg_03;
|
childregs->UCreg_16 = regs->UCreg_03;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dump_fpu);
|
EXPORT_SYMBOL(dump_fpu);
|
||||||
|
|
||||||
/*
|
|
||||||
* Shuffle the argument into the correct register before calling the
|
|
||||||
* thread function. r1 is the thread argument, r2 is the pointer to
|
|
||||||
* the thread function, and r3 points to the exit function.
|
|
||||||
*/
|
|
||||||
asm(".pushsection .text\n"
|
|
||||||
" .align\n"
|
|
||||||
" .type kernel_thread_helper, #function\n"
|
|
||||||
"kernel_thread_helper:\n"
|
|
||||||
" mov.a asr, r7\n"
|
|
||||||
" mov r0, r4\n"
|
|
||||||
" mov lr, r6\n"
|
|
||||||
" mov pc, r5\n"
|
|
||||||
" .size kernel_thread_helper, . - kernel_thread_helper\n"
|
|
||||||
" .popsection");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a kernel thread.
|
|
||||||
*/
|
|
||||||
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
|
||||||
{
|
|
||||||
struct pt_regs regs;
|
|
||||||
|
|
||||||
memset(®s, 0, sizeof(regs));
|
|
||||||
|
|
||||||
regs.UCreg_04 = (unsigned long)arg;
|
|
||||||
regs.UCreg_05 = (unsigned long)fn;
|
|
||||||
regs.UCreg_06 = (unsigned long)do_exit;
|
|
||||||
regs.UCreg_07 = PRIV_MODE;
|
|
||||||
regs.UCreg_pc = (unsigned long)kernel_thread_helper;
|
|
||||||
regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT;
|
|
||||||
|
|
||||||
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(kernel_thread);
|
|
||||||
|
|
||||||
unsigned long get_wchan(struct task_struct *p)
|
unsigned long get_wchan(struct task_struct *p)
|
||||||
{
|
{
|
||||||
struct stackframe frame;
|
struct stackframe frame;
|
||||||
|
|
|
@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[];
|
||||||
extern void kernel_thread_helper(void);
|
extern void kernel_thread_helper(void);
|
||||||
|
|
||||||
extern void __init early_signal_init(void);
|
extern void __init early_signal_init(void);
|
||||||
|
|
||||||
|
extern asmlinkage void __backtrace(void);
|
||||||
|
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
|
||||||
|
|
||||||
|
extern void __show_regs(struct pt_regs *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||||
parent_tid, child_tid);
|
parent_tid, child_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sys_execve() executes a new program.
|
|
||||||
* This is called indirectly via a small wrapper
|
|
||||||
*/
|
|
||||||
asmlinkage long __sys_execve(const char __user *filename,
|
|
||||||
const char __user *const __user *argv,
|
|
||||||
const char __user *const __user *envp,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
struct filename *fn;
|
|
||||||
|
|
||||||
fn = getname(filename);
|
|
||||||
error = PTR_ERR(fn);
|
|
||||||
if (IS_ERR(fn))
|
|
||||||
goto out;
|
|
||||||
error = do_execve(fn->name, argv, envp, regs);
|
|
||||||
putname(fn);
|
|
||||||
out:
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int kernel_execve(const char *filename,
|
|
||||||
const char *const argv[],
|
|
||||||
const char *const envp[])
|
|
||||||
{
|
|
||||||
struct pt_regs regs;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(®s, 0, sizeof(struct pt_regs));
|
|
||||||
ret = do_execve(filename,
|
|
||||||
(const char __user *const __user *)argv,
|
|
||||||
(const char __user *const __user *)envp, ®s);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save argc to the register structure for userspace.
|
|
||||||
*/
|
|
||||||
regs.UCreg_00 = ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We were successful. We won't be returning to our caller, but
|
|
||||||
* instead to user space by manipulating the kernel stack.
|
|
||||||
*/
|
|
||||||
asm("add r0, %0, %1\n\t"
|
|
||||||
"mov r1, %2\n\t"
|
|
||||||
"mov r2, %3\n\t"
|
|
||||||
"mov r22, #0\n\t" /* not a syscall */
|
|
||||||
"mov r23, %0\n\t" /* thread structure */
|
|
||||||
"b.l memmove\n\t" /* copy regs to top of stack */
|
|
||||||
"mov sp, r0\n\t" /* reposition stack pointer */
|
|
||||||
"b ret_to_user"
|
|
||||||
:
|
|
||||||
: "r" (current_thread_info()),
|
|
||||||
"Ir" (THREAD_START_SP - sizeof(regs)),
|
|
||||||
"r" (®s),
|
|
||||||
"Ir" (sizeof(regs))
|
|
||||||
: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
|
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: used by the compat code even in 64-bit Linux. */
|
/* Note: used by the compat code even in 64-bit Linux. */
|
||||||
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
|
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
|
||||||
unsigned long, prot, unsigned long, flags,
|
unsigned long, prot, unsigned long, flags,
|
||||||
|
|
|
@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
|
static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
|
||||||
struct task_struct *tsk)
|
unsigned int flags, struct task_struct *tsk)
|
||||||
{
|
{
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
int fault;
|
int fault;
|
||||||
|
@ -194,14 +194,7 @@ good_area:
|
||||||
* If for any reason at all we couldn't handle the fault, make
|
* If for any reason at all we couldn't handle the fault, make
|
||||||
* sure we exit gracefully rather than endlessly redo the fault.
|
* sure we exit gracefully rather than endlessly redo the fault.
|
||||||
*/
|
*/
|
||||||
fault = handle_mm_fault(mm, vma, addr & PAGE_MASK,
|
fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
|
||||||
(!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
|
|
||||||
if (unlikely(fault & VM_FAULT_ERROR))
|
|
||||||
return fault;
|
|
||||||
if (fault & VM_FAULT_MAJOR)
|
|
||||||
tsk->maj_flt++;
|
|
||||||
else
|
|
||||||
tsk->min_flt++;
|
|
||||||
return fault;
|
return fault;
|
||||||
|
|
||||||
check_stack:
|
check_stack:
|
||||||
|
@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
int fault, sig, code;
|
int fault, sig, code;
|
||||||
|
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
|
||||||
|
((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
|
||||||
|
|
||||||
tsk = current;
|
tsk = current;
|
||||||
mm = tsk->mm;
|
mm = tsk->mm;
|
||||||
|
@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||||
if (!user_mode(regs)
|
if (!user_mode(regs)
|
||||||
&& !search_exception_tables(regs->UCreg_pc))
|
&& !search_exception_tables(regs->UCreg_pc))
|
||||||
goto no_context;
|
goto no_context;
|
||||||
|
retry:
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fault = __do_pf(mm, addr, fsr, tsk);
|
fault = __do_pf(mm, addr, fsr, flags, tsk);
|
||||||
|
|
||||||
|
/* If we need to retry but a fatal signal is pending, handle the
|
||||||
|
* signal first. We do not need to release the mmap_sem because
|
||||||
|
* it would already be released in __lock_page_or_retry in
|
||||||
|
* mm/filemap.c. */
|
||||||
|
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) {
|
||||||
|
if (fault & VM_FAULT_MAJOR)
|
||||||
|
tsk->maj_flt++;
|
||||||
|
else
|
||||||
|
tsk->min_flt++;
|
||||||
|
if (fault & VM_FAULT_RETRY) {
|
||||||
|
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
|
||||||
|
* of starvation. */
|
||||||
|
flags &= ~FAULT_FLAG_ALLOW_RETRY;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue