| .. | .. | 
|---|
| 8 | 8 |   | 
|---|
| 9 | 9 |  struct pt_regs; | 
|---|
| 10 | 10 |   | 
|---|
| 11 |  | -/* Mapping of registers to parameters for syscalls on x86-64 and x32 */  | 
|---|
| 12 |  | -#define SC_X86_64_REGS_TO_ARGS(x, ...)					\  | 
|---|
| 13 |  | -	__MAP(x,__SC_ARGS						\  | 
|---|
| 14 |  | -		,,regs->di,,regs->si,,regs->dx				\  | 
|---|
| 15 |  | -		,,regs->r10,,regs->r8,,regs->r9)			\  | 
|---|
| 16 |  | -  | 
|---|
| 17 |  | -/* Mapping of registers to parameters for syscalls on i386 */  | 
|---|
| 18 |  | -#define SC_IA32_REGS_TO_ARGS(x, ...)					\  | 
|---|
| 19 |  | -	__MAP(x,__SC_ARGS						\  | 
|---|
| 20 |  | -	      ,,(unsigned int)regs->bx,,(unsigned int)regs->cx		\  | 
|---|
| 21 |  | -	      ,,(unsigned int)regs->dx,,(unsigned int)regs->si		\  | 
|---|
| 22 |  | -	      ,,(unsigned int)regs->di,,(unsigned int)regs->bp)  | 
|---|
| 23 |  | -  | 
|---|
| 24 |  | -#ifdef CONFIG_IA32_EMULATION  | 
|---|
| 25 |  | -/*  | 
|---|
| 26 |  | - * For IA32 emulation, we need to handle "compat" syscalls *and* create  | 
|---|
| 27 |  | - * additional wrappers (aptly named __ia32_sys_xyzzy) which decode the  | 
|---|
| 28 |  | - * ia32 regs in the proper order for shared or "common" syscalls. As some  | 
|---|
| 29 |  | - * syscalls may not be implemented, we need to expand COND_SYSCALL in  | 
|---|
| 30 |  | - * kernel/sys_ni.c and SYS_NI in kernel/time/posix-stubs.c to cover this  | 
|---|
| 31 |  | - * case as well.  | 
|---|
| 32 |  | - */  | 
|---|
| 33 |  | -#define __IA32_COMPAT_SYS_STUBx(x, name, ...)				\  | 
|---|
| 34 |  | -	asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs);\  | 
|---|
| 35 |  | -	ALLOW_ERROR_INJECTION(__ia32_compat_sys##name, ERRNO);		\  | 
|---|
| 36 |  | -	asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs)\  | 
|---|
| 37 |  | -	{								\  | 
|---|
| 38 |  | -		return __se_compat_sys##name(SC_IA32_REGS_TO_ARGS(x,__VA_ARGS__));\  | 
|---|
| 39 |  | -	}								\  | 
|---|
| 40 |  | -  | 
|---|
| 41 |  | -#define __IA32_SYS_STUBx(x, name, ...)					\  | 
|---|
| 42 |  | -	asmlinkage long __ia32_sys##name(const struct pt_regs *regs);	\  | 
|---|
| 43 |  | -	ALLOW_ERROR_INJECTION(__ia32_sys##name, ERRNO);			\  | 
|---|
| 44 |  | -	asmlinkage long __ia32_sys##name(const struct pt_regs *regs)	\  | 
|---|
| 45 |  | -	{								\  | 
|---|
| 46 |  | -		return __se_sys##name(SC_IA32_REGS_TO_ARGS(x,__VA_ARGS__));\  | 
|---|
| 47 |  | -	}  | 
|---|
 | 11 | +extern long __x64_sys_ni_syscall(const struct pt_regs *regs);  | 
|---|
 | 12 | +extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);  | 
|---|
| 48 | 13 |   | 
|---|
| 49 | 14 |  /* | 
|---|
| 50 |  | - * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias  | 
|---|
| 51 |  | - * named __ia32_sys_*()  | 
|---|
| 52 |  | - */  | 
|---|
| 53 |  | -  | 
|---|
| 54 |  | -#define SYSCALL_DEFINE0(sname)						\  | 
|---|
| 55 |  | -	SYSCALL_METADATA(_##sname, 0);					\  | 
|---|
| 56 |  | -	asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\  | 
|---|
| 57 |  | -	ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);		\  | 
|---|
| 58 |  | -	SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname);		\  | 
|---|
| 59 |  | -	asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)  | 
|---|
| 60 |  | -  | 
|---|
| 61 |  | -#define COND_SYSCALL(name)							\  | 
|---|
| 62 |  | -	asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused)	\  | 
|---|
| 63 |  | -	{									\  | 
|---|
| 64 |  | -		return sys_ni_syscall();					\  | 
|---|
| 65 |  | -	}									\  | 
|---|
| 66 |  | -	asmlinkage __weak long __ia32_sys_##name(const struct pt_regs *__unused)\  | 
|---|
| 67 |  | -	{									\  | 
|---|
| 68 |  | -		return sys_ni_syscall();					\  | 
|---|
| 69 |  | -	}  | 
|---|
| 70 |  | -  | 
|---|
| 71 |  | -#define SYS_NI(name)							\  | 
|---|
| 72 |  | -	SYSCALL_ALIAS(__x64_sys_##name, sys_ni_posix_timers);		\  | 
|---|
| 73 |  | -	SYSCALL_ALIAS(__ia32_sys_##name, sys_ni_posix_timers)  | 
|---|
| 74 |  | -  | 
|---|
| 75 |  | -#else /* CONFIG_IA32_EMULATION */  | 
|---|
| 76 |  | -#define __IA32_COMPAT_SYS_STUBx(x, name, ...)  | 
|---|
| 77 |  | -#define __IA32_SYS_STUBx(x, fullname, name, ...)  | 
|---|
| 78 |  | -#endif /* CONFIG_IA32_EMULATION */  | 
|---|
| 79 |  | -  | 
|---|
| 80 |  | -  | 
|---|
| 81 |  | -#ifdef CONFIG_X86_X32  | 
|---|
| 82 |  | -/*  | 
|---|
| 83 |  | - * For the x32 ABI, we need to create a stub for compat_sys_*() which is aware  | 
|---|
| 84 |  | - * of the x86-64-style parameter ordering of x32 syscalls. The syscalls common  | 
|---|
| 85 |  | - * with x86_64 obviously do not need such care.  | 
|---|
| 86 |  | - */  | 
|---|
| 87 |  | -#define __X32_COMPAT_SYS_STUBx(x, name, ...)				\  | 
|---|
| 88 |  | -	asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs);\  | 
|---|
| 89 |  | -	ALLOW_ERROR_INJECTION(__x32_compat_sys##name, ERRNO);		\  | 
|---|
| 90 |  | -	asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs)\  | 
|---|
| 91 |  | -	{								\  | 
|---|
| 92 |  | -		return __se_compat_sys##name(SC_X86_64_REGS_TO_ARGS(x,__VA_ARGS__));\  | 
|---|
| 93 |  | -	}								\  | 
|---|
| 94 |  | -  | 
|---|
| 95 |  | -#else /* CONFIG_X86_X32 */  | 
|---|
| 96 |  | -#define __X32_COMPAT_SYS_STUBx(x, name, ...)  | 
|---|
| 97 |  | -#endif /* CONFIG_X86_X32 */  | 
|---|
| 98 |  | -  | 
|---|
| 99 |  | -  | 
|---|
| 100 |  | -#ifdef CONFIG_COMPAT  | 
|---|
| 101 |  | -/*  | 
|---|
| 102 |  | - * Compat means IA32_EMULATION and/or X86_X32. As they use a different  | 
|---|
| 103 |  | - * mapping of registers to parameters, we need to generate stubs for each  | 
|---|
| 104 |  | - * of them.  | 
|---|
| 105 |  | - */  | 
|---|
| 106 |  | -#define COMPAT_SYSCALL_DEFINEx(x, name, ...)					\  | 
|---|
| 107 |  | -	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\  | 
|---|
| 108 |  | -	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\  | 
|---|
| 109 |  | -	__IA32_COMPAT_SYS_STUBx(x, name, __VA_ARGS__)				\  | 
|---|
| 110 |  | -	__X32_COMPAT_SYS_STUBx(x, name, __VA_ARGS__)				\  | 
|---|
| 111 |  | -	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\  | 
|---|
| 112 |  | -	{									\  | 
|---|
| 113 |  | -		return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));\  | 
|---|
| 114 |  | -	}									\  | 
|---|
| 115 |  | -	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))  | 
|---|
| 116 |  | -  | 
|---|
| 117 |  | -/*  | 
|---|
| 118 |  | - * As some compat syscalls may not be implemented, we need to expand  | 
|---|
| 119 |  | - * COND_SYSCALL_COMPAT in kernel/sys_ni.c and COMPAT_SYS_NI in  | 
|---|
| 120 |  | - * kernel/time/posix-stubs.c to cover this case as well.  | 
|---|
| 121 |  | - */  | 
|---|
| 122 |  | -#define COND_SYSCALL_COMPAT(name) 					\  | 
|---|
| 123 |  | -	asmlinkage __weak long __ia32_compat_sys_##name(		\  | 
|---|
| 124 |  | -		const struct pt_regs *__unused)				\  | 
|---|
| 125 |  | -	{                                                               \  | 
|---|
| 126 |  | -		return sys_ni_syscall();                                \  | 
|---|
| 127 |  | -	}								\  | 
|---|
| 128 |  | -	cond_syscall(__x32_compat_sys_##name)  | 
|---|
| 129 |  | -  | 
|---|
| 130 |  | -#define COMPAT_SYS_NI(name)						\  | 
|---|
| 131 |  | -	SYSCALL_ALIAS(__ia32_compat_sys_##name, sys_ni_posix_timers);	\  | 
|---|
| 132 |  | -	SYSCALL_ALIAS(__x32_compat_sys_##name, sys_ni_posix_timers)  | 
|---|
| 133 |  | -  | 
|---|
| 134 |  | -#endif /* CONFIG_COMPAT */  | 
|---|
| 135 |  | -  | 
|---|
| 136 |  | -  | 
|---|
| 137 |  | -/*  | 
|---|
| 138 |  | - * Instead of the generic __SYSCALL_DEFINEx() definition, this macro takes  | 
|---|
| 139 |  | - * struct pt_regs *regs as the only argument of the syscall stub named  | 
|---|
| 140 |  | - * __x64_sys_*(). It decodes just the registers it needs and passes them on to  | 
|---|
| 141 |  | - * the __se_sys_*() wrapper performing sign extension and then to the  | 
|---|
| 142 |  | - * __do_sys_*() function doing the actual job. These wrappers and functions  | 
|---|
| 143 |  | - * are inlined (at least in very most cases), meaning that the assembly looks  | 
|---|
| 144 |  | - * as follows (slightly re-ordered for better readability):  | 
|---|
 | 15 | + * Instead of the generic __SYSCALL_DEFINEx() definition, the x86 version takes  | 
|---|
 | 16 | + * struct pt_regs *regs as the only argument of the syscall stub(s) named as:  | 
|---|
 | 17 | + * __x64_sys_*()         - 64-bit native syscall  | 
|---|
 | 18 | + * __ia32_sys_*()        - 32-bit native syscall or common compat syscall  | 
|---|
 | 19 | + * __ia32_compat_sys_*() - 32-bit compat syscall  | 
|---|
 | 20 | + * __x32_compat_sys_*()  - 64-bit X32 compat syscall  | 
|---|
 | 21 | + *  | 
|---|
 | 22 | + * The registers are decoded according to the ABI:  | 
|---|
 | 23 | + * 64-bit: RDI, RSI, RDX, R10, R8, R9  | 
|---|
 | 24 | + * 32-bit: EBX, ECX, EDX, ESI, EDI, EBP  | 
|---|
 | 25 | + *  | 
|---|
 | 26 | + * The stub then passes the decoded arguments to the __se_sys_*() wrapper to  | 
|---|
 | 27 | + * perform sign-extension (omitted for zero-argument syscalls).  Finally the  | 
|---|
 | 28 | + * arguments are passed to the __do_sys_*() function which is the actual  | 
|---|
 | 29 | + * syscall.  These wrappers are marked as inline so the compiler can optimize  | 
|---|
 | 30 | + * the functions where appropriate.  | 
|---|
 | 31 | + *  | 
|---|
 | 32 | + * Example assembly (slightly re-ordered for better readability):  | 
|---|
| 145 | 33 |   * | 
|---|
| 146 | 34 |   * <__x64_sys_recv>:		<-- syscall with 4 parameters | 
|---|
| 147 | 35 |   *	callq	<__fentry__> | 
|---|
| .. | .. | 
|---|
| 162 | 50 |   * | 
|---|
| 163 | 51 |   * This approach avoids leaking random user-provided register content down | 
|---|
| 164 | 52 |   * the call chain. | 
|---|
| 165 |  | - *  | 
|---|
| 166 |  | - * If IA32_EMULATION is enabled, this macro generates an additional wrapper  | 
|---|
| 167 |  | - * named __ia32_sys_*() which decodes the struct pt_regs *regs according  | 
|---|
| 168 |  | - * to the i386 calling convention (bx, cx, dx, si, di, bp).  | 
|---|
| 169 | 53 |   */ | 
|---|
 | 54 | +  | 
|---|
 | 55 | +/* Mapping of registers to parameters for syscalls on x86-64 and x32 */  | 
|---|
 | 56 | +#define SC_X86_64_REGS_TO_ARGS(x, ...)					\  | 
|---|
 | 57 | +	__MAP(x,__SC_ARGS						\  | 
|---|
 | 58 | +		,,regs->di,,regs->si,,regs->dx				\  | 
|---|
 | 59 | +		,,regs->r10,,regs->r8,,regs->r9)			\  | 
|---|
 | 60 | +  | 
|---|
 | 61 | +/* Mapping of registers to parameters for syscalls on i386 */  | 
|---|
 | 62 | +#define SC_IA32_REGS_TO_ARGS(x, ...)					\  | 
|---|
 | 63 | +	__MAP(x,__SC_ARGS						\  | 
|---|
 | 64 | +	      ,,(unsigned int)regs->bx,,(unsigned int)regs->cx		\  | 
|---|
 | 65 | +	      ,,(unsigned int)regs->dx,,(unsigned int)regs->si		\  | 
|---|
 | 66 | +	      ,,(unsigned int)regs->di,,(unsigned int)regs->bp)  | 
|---|
 | 67 | +  | 
|---|
 | 68 | +#define __SYS_STUB0(abi, name)						\  | 
|---|
 | 69 | +	long __##abi##_##name(const struct pt_regs *regs);		\  | 
|---|
 | 70 | +	ALLOW_ERROR_INJECTION(__##abi##_##name, ERRNO);			\  | 
|---|
 | 71 | +	long __##abi##_##name(const struct pt_regs *regs)		\  | 
|---|
 | 72 | +		__alias(__do_##name);  | 
|---|
 | 73 | +  | 
|---|
 | 74 | +#define __SYS_STUBx(abi, name, ...)					\  | 
|---|
 | 75 | +	long __##abi##_##name(const struct pt_regs *regs);		\  | 
|---|
 | 76 | +	ALLOW_ERROR_INJECTION(__##abi##_##name, ERRNO);			\  | 
|---|
 | 77 | +	long __##abi##_##name(const struct pt_regs *regs)		\  | 
|---|
 | 78 | +	{								\  | 
|---|
 | 79 | +		return __se_##name(__VA_ARGS__);			\  | 
|---|
 | 80 | +	}  | 
|---|
 | 81 | +  | 
|---|
 | 82 | +#define __COND_SYSCALL(abi, name)					\  | 
|---|
 | 83 | +	__weak long __##abi##_##name(const struct pt_regs *__unused)	\  | 
|---|
 | 84 | +	{								\  | 
|---|
 | 85 | +		return sys_ni_syscall();				\  | 
|---|
 | 86 | +	}  | 
|---|
 | 87 | +  | 
|---|
 | 88 | +#define __SYS_NI(abi, name)						\  | 
|---|
 | 89 | +	SYSCALL_ALIAS(__##abi##_##name, sys_ni_posix_timers);  | 
|---|
 | 90 | +  | 
|---|
 | 91 | +#ifdef CONFIG_X86_64  | 
|---|
 | 92 | +#define __X64_SYS_STUB0(name)						\  | 
|---|
 | 93 | +	__SYS_STUB0(x64, sys_##name)  | 
|---|
 | 94 | +  | 
|---|
 | 95 | +#define __X64_SYS_STUBx(x, name, ...)					\  | 
|---|
 | 96 | +	__SYS_STUBx(x64, sys##name,					\  | 
|---|
 | 97 | +		    SC_X86_64_REGS_TO_ARGS(x, __VA_ARGS__))  | 
|---|
 | 98 | +  | 
|---|
 | 99 | +#define __X64_COND_SYSCALL(name)					\  | 
|---|
 | 100 | +	__COND_SYSCALL(x64, sys_##name)  | 
|---|
 | 101 | +  | 
|---|
 | 102 | +#define __X64_SYS_NI(name)						\  | 
|---|
 | 103 | +	__SYS_NI(x64, sys_##name)  | 
|---|
 | 104 | +#else /* CONFIG_X86_64 */  | 
|---|
 | 105 | +#define __X64_SYS_STUB0(name)  | 
|---|
 | 106 | +#define __X64_SYS_STUBx(x, name, ...)  | 
|---|
 | 107 | +#define __X64_COND_SYSCALL(name)  | 
|---|
 | 108 | +#define __X64_SYS_NI(name)  | 
|---|
 | 109 | +#endif /* CONFIG_X86_64 */  | 
|---|
 | 110 | +  | 
|---|
 | 111 | +#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)  | 
|---|
 | 112 | +#define __IA32_SYS_STUB0(name)						\  | 
|---|
 | 113 | +	__SYS_STUB0(ia32, sys_##name)  | 
|---|
 | 114 | +  | 
|---|
 | 115 | +#define __IA32_SYS_STUBx(x, name, ...)					\  | 
|---|
 | 116 | +	__SYS_STUBx(ia32, sys##name,					\  | 
|---|
 | 117 | +		    SC_IA32_REGS_TO_ARGS(x, __VA_ARGS__))  | 
|---|
 | 118 | +  | 
|---|
 | 119 | +#define __IA32_COND_SYSCALL(name)					\  | 
|---|
 | 120 | +	__COND_SYSCALL(ia32, sys_##name)  | 
|---|
 | 121 | +  | 
|---|
 | 122 | +#define __IA32_SYS_NI(name)						\  | 
|---|
 | 123 | +	__SYS_NI(ia32, sys_##name)  | 
|---|
 | 124 | +#else /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */  | 
|---|
 | 125 | +#define __IA32_SYS_STUB0(name)  | 
|---|
 | 126 | +#define __IA32_SYS_STUBx(x, name, ...)  | 
|---|
 | 127 | +#define __IA32_COND_SYSCALL(name)  | 
|---|
 | 128 | +#define __IA32_SYS_NI(name)  | 
|---|
 | 129 | +#endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */  | 
|---|
 | 130 | +  | 
|---|
 | 131 | +#ifdef CONFIG_IA32_EMULATION  | 
|---|
 | 132 | +/*  | 
|---|
 | 133 | + * For IA32 emulation, we need to handle "compat" syscalls *and* create  | 
|---|
 | 134 | + * additional wrappers (aptly named __ia32_sys_xyzzy) which decode the  | 
|---|
 | 135 | + * ia32 regs in the proper order for shared or "common" syscalls. As some  | 
|---|
 | 136 | + * syscalls may not be implemented, we need to expand COND_SYSCALL in  | 
|---|
 | 137 | + * kernel/sys_ni.c and SYS_NI in kernel/time/posix-stubs.c to cover this  | 
|---|
 | 138 | + * case as well.  | 
|---|
 | 139 | + */  | 
|---|
 | 140 | +#define __IA32_COMPAT_SYS_STUB0(name)					\  | 
|---|
 | 141 | +	__SYS_STUB0(ia32, compat_sys_##name)  | 
|---|
 | 142 | +  | 
|---|
 | 143 | +#define __IA32_COMPAT_SYS_STUBx(x, name, ...)				\  | 
|---|
 | 144 | +	__SYS_STUBx(ia32, compat_sys##name,				\  | 
|---|
 | 145 | +		    SC_IA32_REGS_TO_ARGS(x, __VA_ARGS__))  | 
|---|
 | 146 | +  | 
|---|
 | 147 | +#define __IA32_COMPAT_COND_SYSCALL(name)				\  | 
|---|
 | 148 | +	__COND_SYSCALL(ia32, compat_sys_##name)  | 
|---|
 | 149 | +  | 
|---|
 | 150 | +#define __IA32_COMPAT_SYS_NI(name)					\  | 
|---|
 | 151 | +	__SYS_NI(ia32, compat_sys_##name)  | 
|---|
 | 152 | +  | 
|---|
 | 153 | +#else /* CONFIG_IA32_EMULATION */  | 
|---|
 | 154 | +#define __IA32_COMPAT_SYS_STUB0(name)  | 
|---|
 | 155 | +#define __IA32_COMPAT_SYS_STUBx(x, name, ...)  | 
|---|
 | 156 | +#define __IA32_COMPAT_COND_SYSCALL(name)  | 
|---|
 | 157 | +#define __IA32_COMPAT_SYS_NI(name)  | 
|---|
 | 158 | +#endif /* CONFIG_IA32_EMULATION */  | 
|---|
 | 159 | +  | 
|---|
 | 160 | +  | 
|---|
 | 161 | +#ifdef CONFIG_X86_X32  | 
|---|
 | 162 | +/*  | 
|---|
 | 163 | + * For the x32 ABI, we need to create a stub for compat_sys_*() which is aware  | 
|---|
 | 164 | + * of the x86-64-style parameter ordering of x32 syscalls. The syscalls common  | 
|---|
 | 165 | + * with x86_64 obviously do not need such care.  | 
|---|
 | 166 | + */  | 
|---|
 | 167 | +#define __X32_COMPAT_SYS_STUB0(name)					\  | 
|---|
 | 168 | +	__SYS_STUB0(x32, compat_sys_##name)  | 
|---|
 | 169 | +  | 
|---|
 | 170 | +#define __X32_COMPAT_SYS_STUBx(x, name, ...)				\  | 
|---|
 | 171 | +	__SYS_STUBx(x32, compat_sys##name,				\  | 
|---|
 | 172 | +		    SC_X86_64_REGS_TO_ARGS(x, __VA_ARGS__))  | 
|---|
 | 173 | +  | 
|---|
 | 174 | +#define __X32_COMPAT_COND_SYSCALL(name)					\  | 
|---|
 | 175 | +	__COND_SYSCALL(x32, compat_sys_##name)  | 
|---|
 | 176 | +  | 
|---|
 | 177 | +#define __X32_COMPAT_SYS_NI(name)					\  | 
|---|
 | 178 | +	__SYS_NI(x32, compat_sys_##name)  | 
|---|
 | 179 | +#else /* CONFIG_X86_X32 */  | 
|---|
 | 180 | +#define __X32_COMPAT_SYS_STUB0(name)  | 
|---|
 | 181 | +#define __X32_COMPAT_SYS_STUBx(x, name, ...)  | 
|---|
 | 182 | +#define __X32_COMPAT_COND_SYSCALL(name)  | 
|---|
 | 183 | +#define __X32_COMPAT_SYS_NI(name)  | 
|---|
 | 184 | +#endif /* CONFIG_X86_X32 */  | 
|---|
 | 185 | +  | 
|---|
 | 186 | +  | 
|---|
 | 187 | +#ifdef CONFIG_COMPAT  | 
|---|
 | 188 | +/*  | 
|---|
 | 189 | + * Compat means IA32_EMULATION and/or X86_X32. As they use a different  | 
|---|
 | 190 | + * mapping of registers to parameters, we need to generate stubs for each  | 
|---|
 | 191 | + * of them.  | 
|---|
 | 192 | + */  | 
|---|
 | 193 | +#define COMPAT_SYSCALL_DEFINE0(name)					\  | 
|---|
 | 194 | +	static long							\  | 
|---|
 | 195 | +	__do_compat_sys_##name(const struct pt_regs *__unused);		\  | 
|---|
 | 196 | +	__IA32_COMPAT_SYS_STUB0(name)					\  | 
|---|
 | 197 | +	__X32_COMPAT_SYS_STUB0(name)					\  | 
|---|
 | 198 | +	static long							\  | 
|---|
 | 199 | +	__do_compat_sys_##name(const struct pt_regs *__unused)  | 
|---|
 | 200 | +  | 
|---|
 | 201 | +#define COMPAT_SYSCALL_DEFINEx(x, name, ...)					\  | 
|---|
 | 202 | +	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\  | 
|---|
 | 203 | +	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\  | 
|---|
 | 204 | +	__IA32_COMPAT_SYS_STUBx(x, name, __VA_ARGS__)				\  | 
|---|
 | 205 | +	__X32_COMPAT_SYS_STUBx(x, name, __VA_ARGS__)				\  | 
|---|
 | 206 | +	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\  | 
|---|
 | 207 | +	{									\  | 
|---|
 | 208 | +		return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));\  | 
|---|
 | 209 | +	}									\  | 
|---|
 | 210 | +	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))  | 
|---|
 | 211 | +  | 
|---|
 | 212 | +/*  | 
|---|
 | 213 | + * As some compat syscalls may not be implemented, we need to expand  | 
|---|
 | 214 | + * COND_SYSCALL_COMPAT in kernel/sys_ni.c and COMPAT_SYS_NI in  | 
|---|
 | 215 | + * kernel/time/posix-stubs.c to cover this case as well.  | 
|---|
 | 216 | + */  | 
|---|
 | 217 | +#define COND_SYSCALL_COMPAT(name) 					\  | 
|---|
 | 218 | +	__IA32_COMPAT_COND_SYSCALL(name)				\  | 
|---|
 | 219 | +	__X32_COMPAT_COND_SYSCALL(name)  | 
|---|
 | 220 | +  | 
|---|
 | 221 | +#define COMPAT_SYS_NI(name)						\  | 
|---|
 | 222 | +	__IA32_COMPAT_SYS_NI(name)					\  | 
|---|
 | 223 | +	__X32_COMPAT_SYS_NI(name)  | 
|---|
 | 224 | +  | 
|---|
 | 225 | +#endif /* CONFIG_COMPAT */  | 
|---|
 | 226 | +  | 
|---|
| 170 | 227 |  #define __SYSCALL_DEFINEx(x, name, ...)					\ | 
|---|
| 171 |  | -	asmlinkage long __x64_sys##name(const struct pt_regs *regs);	\  | 
|---|
| 172 |  | -	ALLOW_ERROR_INJECTION(__x64_sys##name, ERRNO);			\  | 
|---|
| 173 | 228 |  	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\ | 
|---|
| 174 | 229 |  	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ | 
|---|
| 175 |  | -	asmlinkage long __x64_sys##name(const struct pt_regs *regs)	\  | 
|---|
| 176 |  | -	{								\  | 
|---|
| 177 |  | -		return __se_sys##name(SC_X86_64_REGS_TO_ARGS(x,__VA_ARGS__));\  | 
|---|
| 178 |  | -	}								\  | 
|---|
 | 230 | +	__X64_SYS_STUBx(x, name, __VA_ARGS__)				\  | 
|---|
| 179 | 231 |  	__IA32_SYS_STUBx(x, name, __VA_ARGS__)				\ | 
|---|
| 180 | 232 |  	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\ | 
|---|
| 181 | 233 |  	{								\ | 
|---|
| .. | .. | 
|---|
| 193 | 245 |   * SYSCALL_DEFINEx() -- which is essential for the COND_SYSCALL() and SYS_NI() | 
|---|
| 194 | 246 |   * macros to work correctly. | 
|---|
| 195 | 247 |   */ | 
|---|
| 196 |  | -#ifndef SYSCALL_DEFINE0  | 
|---|
| 197 |  | -#define SYSCALL_DEFINE0(sname)					\  | 
|---|
| 198 |  | -	SYSCALL_METADATA(_##sname, 0);				\  | 
|---|
| 199 |  | -	asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\  | 
|---|
| 200 |  | -	ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);	\  | 
|---|
| 201 |  | -	asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)  | 
|---|
| 202 |  | -#endif  | 
|---|
 | 248 | +#define SYSCALL_DEFINE0(sname)						\  | 
|---|
 | 249 | +	SYSCALL_METADATA(_##sname, 0);					\  | 
|---|
 | 250 | +	static long __do_sys_##sname(const struct pt_regs *__unused);	\  | 
|---|
 | 251 | +	__X64_SYS_STUB0(sname)						\  | 
|---|
 | 252 | +	__IA32_SYS_STUB0(sname)						\  | 
|---|
 | 253 | +	static long __do_sys_##sname(const struct pt_regs *__unused)  | 
|---|
| 203 | 254 |   | 
|---|
| 204 |  | -#ifndef COND_SYSCALL  | 
|---|
| 205 |  | -#define COND_SYSCALL(name) 							\  | 
|---|
| 206 |  | -	asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused)	\  | 
|---|
| 207 |  | -	{									\  | 
|---|
| 208 |  | -		return sys_ni_syscall();					\  | 
|---|
| 209 |  | -	}  | 
|---|
| 210 |  | -#endif  | 
|---|
 | 255 | +#define COND_SYSCALL(name)						\  | 
|---|
 | 256 | +	__X64_COND_SYSCALL(name)					\  | 
|---|
 | 257 | +	__IA32_COND_SYSCALL(name)  | 
|---|
| 211 | 258 |   | 
|---|
| 212 |  | -#ifndef SYS_NI  | 
|---|
| 213 |  | -#define SYS_NI(name) SYSCALL_ALIAS(__x64_sys_##name, sys_ni_posix_timers);  | 
|---|
| 214 |  | -#endif  | 
|---|
 | 259 | +#define SYS_NI(name)							\  | 
|---|
 | 260 | +	__X64_SYS_NI(name)						\  | 
|---|
 | 261 | +	__IA32_SYS_NI(name)  | 
|---|
| 215 | 262 |   | 
|---|
| 216 | 263 |   | 
|---|
| 217 | 264 |  /* | 
|---|
| 218 | 265 |   * For VSYSCALLS, we need to declare these three syscalls with the new | 
|---|
| 219 | 266 |   * pt_regs-based calling convention for in-kernel use. | 
|---|
| 220 | 267 |   */ | 
|---|
| 221 |  | -asmlinkage long __x64_sys_getcpu(const struct pt_regs *regs);  | 
|---|
| 222 |  | -asmlinkage long __x64_sys_gettimeofday(const struct pt_regs *regs);  | 
|---|
| 223 |  | -asmlinkage long __x64_sys_time(const struct pt_regs *regs);  | 
|---|
 | 268 | +long __x64_sys_getcpu(const struct pt_regs *regs);  | 
|---|
 | 269 | +long __x64_sys_gettimeofday(const struct pt_regs *regs);  | 
|---|
 | 270 | +long __x64_sys_time(const struct pt_regs *regs);  | 
|---|
| 224 | 271 |   | 
|---|
| 225 | 272 |  #endif /* _ASM_X86_SYSCALL_WRAPPER_H */ | 
|---|