[PATCH] x86_64: Implement is_compat_task the right way
By setting a flag during a 32bit system call only Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
2966387b48
commit
bf2fcc6fdf
@@ -104,6 +104,7 @@ ENTRY(ia32_sysenter_target)
|
|||||||
.quad 1b,ia32_badarg
|
.quad 1b,ia32_badarg
|
||||||
.previous
|
.previous
|
||||||
GET_THREAD_INFO(%r10)
|
GET_THREAD_INFO(%r10)
|
||||||
|
orl $TS_COMPAT,threadinfo_status(%r10)
|
||||||
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
||||||
CFI_REMEMBER_STATE
|
CFI_REMEMBER_STATE
|
||||||
jnz sysenter_tracesys
|
jnz sysenter_tracesys
|
||||||
@@ -117,6 +118,7 @@ sysenter_do_call:
|
|||||||
cli
|
cli
|
||||||
testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
|
testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
|
||||||
jnz int_ret_from_sys_call
|
jnz int_ret_from_sys_call
|
||||||
|
andl $~TS_COMPAT,threadinfo_status(%r10)
|
||||||
/* clear IF, that popfq doesn't enable interrupts early */
|
/* clear IF, that popfq doesn't enable interrupts early */
|
||||||
andl $~0x200,EFLAGS-R11(%rsp)
|
andl $~0x200,EFLAGS-R11(%rsp)
|
||||||
RESTORE_ARGS 1,24,1,1,1,1
|
RESTORE_ARGS 1,24,1,1,1,1
|
||||||
@@ -203,6 +205,7 @@ ENTRY(ia32_cstar_target)
|
|||||||
.quad 1b,ia32_badarg
|
.quad 1b,ia32_badarg
|
||||||
.previous
|
.previous
|
||||||
GET_THREAD_INFO(%r10)
|
GET_THREAD_INFO(%r10)
|
||||||
|
orl $TS_COMPAT,threadinfo_status(%r10)
|
||||||
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
||||||
CFI_REMEMBER_STATE
|
CFI_REMEMBER_STATE
|
||||||
jnz cstar_tracesys
|
jnz cstar_tracesys
|
||||||
@@ -216,6 +219,7 @@ cstar_do_call:
|
|||||||
cli
|
cli
|
||||||
testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
|
testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
|
||||||
jnz int_ret_from_sys_call
|
jnz int_ret_from_sys_call
|
||||||
|
andl $~TS_COMPAT,threadinfo_status(%r10)
|
||||||
RESTORE_ARGS 1,-ARG_SKIP,1,1,1
|
RESTORE_ARGS 1,-ARG_SKIP,1,1,1
|
||||||
movl RIP-ARGOFFSET(%rsp),%ecx
|
movl RIP-ARGOFFSET(%rsp),%ecx
|
||||||
CFI_REGISTER rip,rcx
|
CFI_REGISTER rip,rcx
|
||||||
@@ -288,6 +292,7 @@ ENTRY(ia32_syscall)
|
|||||||
this could be a problem. */
|
this could be a problem. */
|
||||||
SAVE_ARGS 0,0,1
|
SAVE_ARGS 0,0,1
|
||||||
GET_THREAD_INFO(%r10)
|
GET_THREAD_INFO(%r10)
|
||||||
|
orl $TS_COMPAT,threadinfo_status(%r10)
|
||||||
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
|
||||||
jnz ia32_tracesys
|
jnz ia32_tracesys
|
||||||
ia32_do_syscall:
|
ia32_do_syscall:
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ int main(void)
|
|||||||
ENTRY(flags);
|
ENTRY(flags);
|
||||||
ENTRY(addr_limit);
|
ENTRY(addr_limit);
|
||||||
ENTRY(preempt_count);
|
ENTRY(preempt_count);
|
||||||
|
ENTRY(status);
|
||||||
BLANK();
|
BLANK();
|
||||||
#undef ENTRY
|
#undef ENTRY
|
||||||
#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
|
#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ int_with_check:
|
|||||||
movl threadinfo_flags(%rcx),%edx
|
movl threadinfo_flags(%rcx),%edx
|
||||||
andl %edi,%edx
|
andl %edi,%edx
|
||||||
jnz int_careful
|
jnz int_careful
|
||||||
|
andl $~TS_COMPAT,threadinfo_status(%rcx)
|
||||||
jmp retint_swapgs
|
jmp retint_swapgs
|
||||||
|
|
||||||
/* Either reschedule or signal or syscall exit tracking needed. */
|
/* Either reschedule or signal or syscall exit tracking needed. */
|
||||||
|
|||||||
@@ -154,8 +154,10 @@ struct input_event_compat {
|
|||||||
__s32 value;
|
__s32 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Note to the author of this code: did it ever occur to
|
||||||
|
you why the ifdefs are needed? Think about it again. -AK */
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
# define COMPAT_TEST test_thread_flag(TIF_IA32)
|
# define COMPAT_TEST is_compat_task()
|
||||||
#elif defined(CONFIG_IA64)
|
#elif defined(CONFIG_IA64)
|
||||||
# define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
|
# define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
|
||||||
#elif defined(CONFIG_S390)
|
#elif defined(CONFIG_S390)
|
||||||
|
|||||||
@@ -202,4 +202,9 @@ static __inline__ void __user *compat_alloc_user_space(long len)
|
|||||||
return (void __user *)regs->rsp - len;
|
return (void __user *)regs->rsp - len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int is_compat_task(void)
|
||||||
|
{
|
||||||
|
return current_thread_info()->status & TS_COMPAT;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ASM_X86_64_COMPAT_H */
|
#endif /* _ASM_X86_64_COMPAT_H */
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ static inline struct thread_info *stack_thread_info(void)
|
|||||||
* have to worry about atomic accesses.
|
* have to worry about atomic accesses.
|
||||||
*/
|
*/
|
||||||
#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
|
#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
|
||||||
|
#define TS_COMPAT 0x0002 /* 32bit syscall active */
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user