From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933748AbcAYQ6L (ORCPT ); Mon, 25 Jan 2016 11:58:11 -0500 Received: from mail-bl2on0073.outbound.protection.outlook.com ([65.55.169.73]:44679 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932259AbcAYQ6H (ORCPT ); Mon, 25 Jan 2016 11:58:07 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; From: Yury Norov To: , , , , , , , CC: , , , , , , , , Yury Norov Subject: [PATCH 1/5] all: s390: move wrapper infrastructure to generic headers Date: Mon, 25 Jan 2016 19:57:23 +0300 Message-ID: <1453741047-5498-2-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> References: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [95.143.213.121] X-ClientProxiedBy: AM2PR02CA0013.eurprd02.prod.outlook.com (25.160.28.151) To BLUPR07MB612.namprd07.prod.outlook.com (10.141.207.27) X-Microsoft-Exchange-Diagnostics: 1;BLUPR07MB612;2:2fzcL8ENY/RIIQ5NAlXyWZELx4vAIdG1rjUwbrCNIyKmZOB0r86H9/rpgADxXH9mTMB6I1FXYhBKTTWv1SrTtUlCdxK0un3znHdiKDXm8X9M47eRVzK8RjCviUzPYfuNZftTE/r0xiVS92NgtihaJQ==;3:1XiYp1fUV655YebTMS346cJ5xB29TZnw7c4CwlOuzxKu4YE8hYi5VTug/ZGtksjoauc9Ci7zF09eVxChF6u/4/Ek/i49K9zQS4KvFs01wFUiIXdlHzE0TnQ8BYj60AZH;25:qXOEME7r69jQLvZDXjwWHS3H8TEGDwelp6dW7aJYvB8vXLupEK9nDwZ/ALsmMqXDhKaYORIRLV7CoeZ2yS4uBK9RnBMIvRmrp+0Gctq0n2sNNIuTRfP5nFPR0mEKvQ88QxQI8gW6rjQ02N3VwMGLNEKnuxhIQFl5jIJsRQAhaqPcnaWS5/Hubi7qP/nK0pi1GVLB5v6y/IjiA4nyXEKdxmIzWsZqPZEpzUJEZq7Eq3on9CTISjN+ZiPMXFss0ycc X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR07MB612; X-MS-Office365-Filtering-Correlation-Id: f77283e3-527d-46e2-060d-08d325a8b03a X-Microsoft-Exchange-Diagnostics: 1;BLUPR07MB612;20:fSipOH1j1Hg9rBr6cjwX6Ec6PoFk0I85UC/Wo/OJI3g62x8+91gZ8UI8Uw4ZQQo6bivUPQ+3FcJ6L5kPflMb8boBaJyC2Avbfm3uE880K2R8X4/Hfk+DP9BluHpwlZqfJDFY9i4LKg5FGmccG/80TbYfOPomFjIVT8GqR2IazOhKe6yn4pVmCspF6XMAfN8tWlL/q1215l7rUPsqwSObI/7OfV80WcsY1LA8iei0n32efRgt91mjdImOHtpnFeSmmms7v0RiAnXTwuDcGzIVNGQMFOd/LwZQIUhcayeL3yXF2TSwRmUGe3UcrbBydeAvSZtS3U7wPSbL5RJKz5U3HDtdSRZzJ4J6P/zCTmpyUmCrH9O5PK7mqmsA+3v9NfyNUi+f05VqSDxZq3Na4bx+KUy2jFPETotLU+gtz5AXuDUSt6n6IIt8Mo3CnuBIuImE+mDQY209fseA+6Dmn+OoIg7hZsS/t4nV6Y2zkQMvLxomyz6PUJRR1b6CWIhUPIqtB7asuBJzaUwHhx7g2BDjLninvEYGApSkwRflLsXUKaLck403m/G2eDh1aJD2Gxj4Jh0jEbl6PWWLWmwuksPHVE9lTbZDQNLU1KXSZWd6DcE= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(3002001)(10201501046);SRVR:BLUPR07MB612;BCL:0;PCL:0;RULEID:;SRVR:BLUPR07MB612; X-Microsoft-Exchange-Diagnostics: 1;BLUPR07MB612;4:hMe7UOE0n0AFJVFMe5p/3HSvuzgJNhU6qjZIYCHBysO9WFTWIa2zp6KY545y5WaW3oCAw+YVmbUY889fI5bPz26x+4oMWa9PPQUhO8wwiW+FfGA5Gy9gy9Y13Eg/QXkTj9bJKjtKCmYKzRLf1lgydC0L1hzFmrzHErOKpIHmAChqeRmG4b7IJ1+Ids/Sfc+ABIL3KFycM2IaMOSVkQt2OwyxVDeqvDH/6H+ouibZkbNvrWGxlz473GyfAz1sslNOamrzEwWL7yB/0TKQgO09bWAZYf3CgUJbW/ZrqS1EdsllE3uXv/ZUJfdVlzHG+qDNcMIL6e8dBhbf/fnDey0X13rQC8houBkCxiAidtV8fWZ19yaQ/IJ0D/MJB0sO2gJ8 X-Forefront-PRVS: 083289FD26 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6069001)(6009001)(189002)(199003)(5001960100002)(4001430100002)(2950100001)(3846002)(77096005)(1096002)(229853001)(107886002)(105586002)(50986999)(106356001)(76176999)(5008740100001)(586003)(97736004)(19580395003)(5001770100001)(6116002)(81156007)(48376002)(47776003)(66066001)(189998001)(101416001)(19580405001)(2906002)(2201001)(50466002)(122386002)(42186005)(76506005)(4326007)(36756003)(5003940100001)(87976001)(50226001)(5004730100002)(40100003)(92566002)(33646002)(41533002)(2101003);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR07MB612;H:localhost;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BLUPR07MB612;23:syNPcri7Dgu5skabcacQ/Acf8kIxd/k5lpLnWFR2gv?= =?us-ascii?Q?pEU5rCu6MB8h8KYetWzo3cSyLbFb8xfcgqvseNTq826vUVJU2xWgH2zzKrWe?= =?us-ascii?Q?WyIAlkkAlXjWU4jz0HgKt77xQsdA30zfEW7GHlp+sgmHri3Rl85P33cyxull?= =?us-ascii?Q?ama1Qe60VjSUZ1fHxQEV293Vo8uDnonNQ0OL/9WYAQkvRx1bGUnCZUqOSzKP?= =?us-ascii?Q?NvWr4xCUGH9f672mZa2R+GFg9oMKu/5EtIpHuwnTxYajEOZWfujeB9HqOOw5?= =?us-ascii?Q?VVu5hdRNFlcKUSMtZYZPN3Wubfu+3LxxnKduJEMY7LFZzo8TX6cn05lEf/bN?= =?us-ascii?Q?bcnzo/zbk/n+eS1uk6R2aGJcK9v/id68WWn0RT5Rj2wBqgzFFphs3/9h3LFx?= =?us-ascii?Q?jJ4zkvdwF4KaMYhmrpDWVe9QR3ZxSH86BuBnLwZ2dxfnCeY41UGuhDJlTFfY?= =?us-ascii?Q?UhzuaaI66Tonpva+TAntyJdhoW2bP583TysUm3WqvPBqYeAG52otu3aPuwP/?= =?us-ascii?Q?Nk454g2aBmbofnr0LVoL+OVXUhONTkeJhH8cd3ov9eV9Xj9a/OsyuV/kbu+j?= =?us-ascii?Q?lPYmnwfRc/FsqtjPR2j5X2lrirBLwJGUNc9xO6m9z56/NO9IhueHWBLxLB4e?= =?us-ascii?Q?TRzctXSmr7bf2MtYcYUNup9Td3EaBZeU7fp+22NgfagY/NdcuS1X5jGU1v0h?= =?us-ascii?Q?sOa1T8VGxDyaihJUOVtzubGNOZHjx6aDkq8g4EycarOem9eJ93R3djop7Tdg?= =?us-ascii?Q?Q8Z0Ytvt144ZafoFaiqThyglEiCHv3Src1wndTRkKip569E/Wkp4wSJf/4L1?= =?us-ascii?Q?DIn8OAxRg9EZcimdGXwSLANC3yL9PiDz78qlThHVUtLRqcpTTpe+0lV9Flxz?= =?us-ascii?Q?zwwaYcBPbd0x07iuvQrY3mCFm6xu7VhjW6S6uACXo833zO69TwYmVt7UhFQ1?= =?us-ascii?Q?cXwQMks6GF/MhTKKB9eL9GU95kr3jgMSybN6/0QKiN7WrASXOaS+X6dw2Pgl?= =?us-ascii?Q?bTkL22KTSii+XOlQoXI/Dsw9XXIhxF+rrzJzTMfHEd06mMLPTO6wi3zxVRAB?= =?us-ascii?Q?rgAXwwvNPQfSEqSDVAsaZ+LRqB/DqyrV8OAOOY3vxXClvpmYziWSf4T6xeSg?= =?us-ascii?Q?1ame+xnvyDR7RFqWNO+cJBEnFOhHpctQ9LFyjKcij8a3zssFStxeOA3E2HKF?= =?us-ascii?Q?JEkRRAxxZ3tS83eWy66oj2XR6NSu2srWZg?= X-Microsoft-Exchange-Diagnostics: 1;BLUPR07MB612;5:nUVbd6VjC/ytyLxpZvM7dNINL0l63YCTLlasrcrbVrY6PIfzS1Dp22mZsCaonWs8E1VmZaGnN1DdeUyC3arUGrUbhUtuk33lNsTkiC/7fD5GJq2PlpchRwu6fZKu+rB1VuHKXvhPY8fbn4IxkQrqIg==;24:jqpG/QFCI1XWEiT97gMZdmbwbJIvIruwrHHMNgK0IJjeD5NGs4eDNXM7amAhPMdAw3NifEnxOrzxmEwCDj4OFsH5dlc6xtLmGTtibEugp2k= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jan 2016 16:58:02.7729 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR07MB612 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org __SC_COMPAT_CAST for s390 is too specific due to 31-bit pointer length, so it's moved to arch/s390/include/asm/compat.h. Generic declaration assumes that long, unsigned long and pointer types are all 32-bit length. linux/syscalls_structs.h header is introduced, because from now (see next patch) structure types listed there are needed for both normal and compat mode. cond_syscall_wrapped now defined two symbols: sys_foo() and compat_sys_foo(), if compat wrappers are enabled. Here __SC_WRAP() macro is introduced as well. s390 doesn't need it as it uses asm-generated syscall table. But architectures that generate that tables with C code (ARM64/ILP32) should redefine it as '#define __SC_WRAP(name) compat_##name'. Signed-off-by: Yury Norov --- arch/s390/include/asm/compat.h | 17 +++++++++-- arch/s390/kernel/compat_wrapper.c | 51 ------------------------------- include/linux/compat.h | 63 +++++++++++++++++++++++++++++++++++++++ include/linux/syscalls.h | 57 +---------------------------------- include/linux/syscalls_structs.h | 60 +++++++++++++++++++++++++++++++++++++ include/uapi/asm-generic/unistd.h | 4 +++ kernel/sys_ni.c | 8 +++++ 7 files changed, 151 insertions(+), 109 deletions(-) create mode 100644 include/linux/syscalls_structs.h diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index d350ed9..46cb4be 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -7,13 +7,26 @@ #include #include -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) - #define __SC_DELOUSE(t,v) ({ \ BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ }) +#define __SC_COMPAT_CAST(t, a) \ +({ \ + long __ReS = a; \ + \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + if (__TYPE_IS_L(t)) \ + __ReS = (s32)a; \ + if (__TYPE_IS_UL(t)) \ + __ReS = (u32)a; \ + if (__TYPE_IS_PTR(t)) \ + __ReS = a & 0x7fffffff; \ + (t)__ReS; \ +}) + #define PSW32_MASK_PER 0x40000000UL #define PSW32_MASK_DAT 0x04000000UL #define PSW32_MASK_IO 0x02000000UL diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index fac4eed..527f75d 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -8,57 +8,6 @@ #include #include "entry.h" -#define COMPAT_SYSCALL_WRAP1(name, ...) \ - COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP2(name, ...) \ - COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP3(name, ...) \ - COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP4(name, ...) \ - COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP5(name, ...) \ - COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP6(name, ...) \ - COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) - -#define __SC_COMPAT_TYPE(t, a) \ - __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a - -#define __SC_COMPAT_CAST(t, a) \ -({ \ - long __ReS = a; \ - \ - BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ - !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ - if (__TYPE_IS_L(t)) \ - __ReS = (s32)a; \ - if (__TYPE_IS_UL(t)) \ - __ReS = (u32)a; \ - if (__TYPE_IS_PTR(t)) \ - __ReS = a & 0x7fffffff; \ - (t)__ReS; \ -}) - -/* - * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by - * compat tasks. These wrappers will only be used for system calls where only - * the system call arguments need sign or zero extension or zeroing of the upper - * 33 bits of pointers. - * Note: since the wrapper function will afterwards call a system call which - * again performs zero and sign extension for all system call arguments with - * a size of less than eight bytes, these compat wrappers only touch those - * system call arguments with a size of eight bytes ((unsigned) long and - * pointers). Zero and sign extension for e.g. int parameters will be done by - * the regular system call wrappers. - */ -#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ -asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ -{ \ - return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ -} - COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); diff --git a/include/linux/compat.h b/include/linux/compat.h index a76c917..1a761ea 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -718,4 +718,67 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, #define is_compat_task() (0) #endif /* CONFIG_COMPAT */ + +#ifdef CONFIG_COMPAT_WRAPPER + +#ifndef __TYPE_IS_PTR +#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) +#endif + +#ifndef __SC_COMPAT_TYPE +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a +#endif + +#ifndef __SC_COMPAT_CAST +#define __SC_COMPAT_CAST(t, a) ({ \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + ((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a))); \ +}) +#endif + +#ifndef SYSCALL_DEFINE_WRAPx +/* + * The SYSCALL_DEFINE_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of upper + * bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ +#define SYSCALL_DEFINE_WRAPx(x, name, ...) \ +asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ +asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(compat_SyS##name)))); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ +{ \ + return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ +} \ +SYSCALL_DEFINEx(x, name, __VA_ARGS__) +#endif + +#define SYSCALL_DEFINE_WRAP1(name, ...) SYSCALL_DEFINE_WRAPx(1, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP2(name, ...) SYSCALL_DEFINE_WRAPx(2, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP3(name, ...) SYSCALL_DEFINE_WRAPx(3, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP4(name, ...) SYSCALL_DEFINE_WRAPx(4, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP5(name, ...) SYSCALL_DEFINE_WRAPx(5, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP6(name, ...) SYSCALL_DEFINE_WRAPx(6, _##name, __VA_ARGS__) + +#else + +#define SYSCALL_DEFINE_WRAP1 SYSCALL_DEFINE1 +#define SYSCALL_DEFINE_WRAP2 SYSCALL_DEFINE2 +#define SYSCALL_DEFINE_WRAP3 SYSCALL_DEFINE3 +#define SYSCALL_DEFINE_WRAP4 SYSCALL_DEFINE4 +#define SYSCALL_DEFINE_WRAP5 SYSCALL_DEFINE5 +#define SYSCALL_DEFINE_WRAP6 SYSCALL_DEFINE6 + +#endif /* CONFIG_COMPAT_WRAPPER */ + #endif /* _LINUX_COMPAT_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c2b66a2..1942cf4 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -11,62 +11,7 @@ #ifndef _LINUX_SYSCALLS_H #define _LINUX_SYSCALLS_H -struct epoll_event; -struct iattr; -struct inode; -struct iocb; -struct io_event; -struct iovec; -struct itimerspec; -struct itimerval; -struct kexec_segment; -struct linux_dirent; -struct linux_dirent64; -struct list_head; -struct mmap_arg_struct; -struct msgbuf; -struct user_msghdr; -struct mmsghdr; -struct msqid_ds; -struct new_utsname; -struct nfsctl_arg; -struct __old_kernel_stat; -struct oldold_utsname; -struct old_utsname; -struct pollfd; -struct rlimit; -struct rlimit64; -struct rusage; -struct sched_param; -struct sched_attr; -struct sel_arg_struct; -struct semaphore; -struct sembuf; -struct shmid_ds; -struct sockaddr; -struct stat; -struct stat64; -struct statfs; -struct statfs64; -struct __sysctl_args; -struct sysinfo; -struct timespec; -struct timeval; -struct timex; -struct timezone; -struct tms; -struct utimbuf; -struct mq_attr; -struct compat_stat; -struct compat_timeval; -struct robust_list_head; -struct getcpu_cache; -struct old_linux_dirent; -struct perf_event_attr; -struct file_handle; -struct sigaltstack; -union bpf_attr; - +#include #include #include #include diff --git a/include/linux/syscalls_structs.h b/include/linux/syscalls_structs.h new file mode 100644 index 0000000..a920cbc --- /dev/null +++ b/include/linux/syscalls_structs.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_SYSCALL_STRUCTS_H +#define _LINUX_SYSCALL_STRUCTS_H + +struct epoll_event; +struct iattr; +struct inode; +struct iocb; +struct io_event; +struct iovec; +struct itimerspec; +struct itimerval; +struct kexec_segment; +struct linux_dirent; +struct linux_dirent64; +struct list_head; +struct mmap_arg_struct; +struct msgbuf; +struct user_msghdr; +struct mmsghdr; +struct msqid_ds; +struct new_utsname; +struct nfsctl_arg; +struct __old_kernel_stat; +struct oldold_utsname; +struct old_utsname; +struct pollfd; +struct rlimit; +struct rlimit64; +struct rusage; +struct sched_param; +struct sched_attr; +struct sel_arg_struct; +struct semaphore; +struct sembuf; +struct shmid_ds; +struct sockaddr; +struct stat; +struct stat64; +struct statfs; +struct statfs64; +struct __sysctl_args; +struct sysinfo; +struct timespec; +struct timeval; +struct timex; +struct timezone; +struct tms; +struct utimbuf; +struct mq_attr; +struct compat_stat; +struct compat_timeval; +struct robust_list_head; +struct getcpu_cache; +struct old_linux_dirent; +struct perf_event_attr; +struct file_handle; +struct sigaltstack; +union bpf_attr; + +#endif /* _LINUX_SYSCALL_STRUCTS_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 1324b02..a8380ad 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -29,6 +29,10 @@ #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) #endif +#ifndef __SC_WRAP +#define __SC_WRAP __SYSCALL +#endif + #define __NR_io_setup 0 __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup) #define __NR_io_destroy 1 diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0623787..8c99a45 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -16,6 +16,14 @@ asmlinkage long sys_ni_syscall(void) return -ENOSYS; } +#ifdef CONFIG_COMPAT_WRAPPER +#define cond_syscall_wrapped(name) \ + cond_syscall(name); \ + cond_syscall(compat_##name); +#else +#define cond_syscall_wrapped cond_syscall +#endif + cond_syscall(sys_quotactl); cond_syscall(sys32_quotactl); cond_syscall(sys_acct); -- 2.5.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yury Norov Subject: [PATCH 1/5] all: s390: move wrapper infrastructure to generic headers Date: Mon, 25 Jan 2016 19:57:23 +0300 Message-ID: <1453741047-5498-2-git-send-email-ynorov@caviumnetworks.com> References: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> Sender: linux-kernel-owner@vger.kernel.org List-Archive: List-Post: To: arnd@arndb.de, catalin.marinas@arm.com, heiko.carstens@de.ibm.com, schwidefsky@de.ibm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, linux-arch@vger.kernel.org Cc: Prasun.Kapoor@caviumnetworks.com, pinskia@gmail.com, agraf@suse.de, broonie@kernel.org, joseph@codesourcery.com, christoph.muellner@theobroma-systems.com, Nathan_Lynch@mentor.com, klimov.linux@gmail.com, Yury Norov List-ID: __SC_COMPAT_CAST for s390 is too specific due to 31-bit pointer length, so it's moved to arch/s390/include/asm/compat.h. Generic declaration assumes that long, unsigned long and pointer types are all 32-bit length. linux/syscalls_structs.h header is introduced, because from now (see next patch) structure types listed there are needed for both normal and compat mode. cond_syscall_wrapped now defined two symbols: sys_foo() and compat_sys_foo(), if compat wrappers are enabled. Here __SC_WRAP() macro is introduced as well. s390 doesn't need it as it uses asm-generated syscall table. But architectures that generate that tables with C code (ARM64/ILP32) should redefine it as '#define __SC_WRAP(name) compat_##name'. Signed-off-by: Yury Norov --- arch/s390/include/asm/compat.h | 17 +++++++++-- arch/s390/kernel/compat_wrapper.c | 51 ------------------------------- include/linux/compat.h | 63 +++++++++++++++++++++++++++++++++++++++ include/linux/syscalls.h | 57 +---------------------------------- include/linux/syscalls_structs.h | 60 +++++++++++++++++++++++++++++++++++++ include/uapi/asm-generic/unistd.h | 4 +++ kernel/sys_ni.c | 8 +++++ 7 files changed, 151 insertions(+), 109 deletions(-) create mode 100644 include/linux/syscalls_structs.h diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index d350ed9..46cb4be 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -7,13 +7,26 @@ #include #include -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) - #define __SC_DELOUSE(t,v) ({ \ BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ }) +#define __SC_COMPAT_CAST(t, a) \ +({ \ + long __ReS = a; \ + \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + if (__TYPE_IS_L(t)) \ + __ReS = (s32)a; \ + if (__TYPE_IS_UL(t)) \ + __ReS = (u32)a; \ + if (__TYPE_IS_PTR(t)) \ + __ReS = a & 0x7fffffff; \ + (t)__ReS; \ +}) + #define PSW32_MASK_PER 0x40000000UL #define PSW32_MASK_DAT 0x04000000UL #define PSW32_MASK_IO 0x02000000UL diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index fac4eed..527f75d 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -8,57 +8,6 @@ #include #include "entry.h" -#define COMPAT_SYSCALL_WRAP1(name, ...) \ - COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP2(name, ...) \ - COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP3(name, ...) \ - COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP4(name, ...) \ - COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP5(name, ...) \ - COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP6(name, ...) \ - COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) - -#define __SC_COMPAT_TYPE(t, a) \ - __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a - -#define __SC_COMPAT_CAST(t, a) \ -({ \ - long __ReS = a; \ - \ - BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ - !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ - if (__TYPE_IS_L(t)) \ - __ReS = (s32)a; \ - if (__TYPE_IS_UL(t)) \ - __ReS = (u32)a; \ - if (__TYPE_IS_PTR(t)) \ - __ReS = a & 0x7fffffff; \ - (t)__ReS; \ -}) - -/* - * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by - * compat tasks. These wrappers will only be used for system calls where only - * the system call arguments need sign or zero extension or zeroing of the upper - * 33 bits of pointers. - * Note: since the wrapper function will afterwards call a system call which - * again performs zero and sign extension for all system call arguments with - * a size of less than eight bytes, these compat wrappers only touch those - * system call arguments with a size of eight bytes ((unsigned) long and - * pointers). Zero and sign extension for e.g. int parameters will be done by - * the regular system call wrappers. - */ -#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ -asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ -{ \ - return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ -} - COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); diff --git a/include/linux/compat.h b/include/linux/compat.h index a76c917..1a761ea 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -718,4 +718,67 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, #define is_compat_task() (0) #endif /* CONFIG_COMPAT */ + +#ifdef CONFIG_COMPAT_WRAPPER + +#ifndef __TYPE_IS_PTR +#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) +#endif + +#ifndef __SC_COMPAT_TYPE +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a +#endif + +#ifndef __SC_COMPAT_CAST +#define __SC_COMPAT_CAST(t, a) ({ \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + ((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a))); \ +}) +#endif + +#ifndef SYSCALL_DEFINE_WRAPx +/* + * The SYSCALL_DEFINE_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of upper + * bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ +#define SYSCALL_DEFINE_WRAPx(x, name, ...) \ +asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ +asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(compat_SyS##name)))); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ +{ \ + return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ +} \ +SYSCALL_DEFINEx(x, name, __VA_ARGS__) +#endif + +#define SYSCALL_DEFINE_WRAP1(name, ...) SYSCALL_DEFINE_WRAPx(1, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP2(name, ...) SYSCALL_DEFINE_WRAPx(2, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP3(name, ...) SYSCALL_DEFINE_WRAPx(3, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP4(name, ...) SYSCALL_DEFINE_WRAPx(4, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP5(name, ...) SYSCALL_DEFINE_WRAPx(5, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP6(name, ...) SYSCALL_DEFINE_WRAPx(6, _##name, __VA_ARGS__) + +#else + +#define SYSCALL_DEFINE_WRAP1 SYSCALL_DEFINE1 +#define SYSCALL_DEFINE_WRAP2 SYSCALL_DEFINE2 +#define SYSCALL_DEFINE_WRAP3 SYSCALL_DEFINE3 +#define SYSCALL_DEFINE_WRAP4 SYSCALL_DEFINE4 +#define SYSCALL_DEFINE_WRAP5 SYSCALL_DEFINE5 +#define SYSCALL_DEFINE_WRAP6 SYSCALL_DEFINE6 + +#endif /* CONFIG_COMPAT_WRAPPER */ + #endif /* _LINUX_COMPAT_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c2b66a2..1942cf4 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -11,62 +11,7 @@ #ifndef _LINUX_SYSCALLS_H #define _LINUX_SYSCALLS_H -struct epoll_event; -struct iattr; -struct inode; -struct iocb; -struct io_event; -struct iovec; -struct itimerspec; -struct itimerval; -struct kexec_segment; -struct linux_dirent; -struct linux_dirent64; -struct list_head; -struct mmap_arg_struct; -struct msgbuf; -struct user_msghdr; -struct mmsghdr; -struct msqid_ds; -struct new_utsname; -struct nfsctl_arg; -struct __old_kernel_stat; -struct oldold_utsname; -struct old_utsname; -struct pollfd; -struct rlimit; -struct rlimit64; -struct rusage; -struct sched_param; -struct sched_attr; -struct sel_arg_struct; -struct semaphore; -struct sembuf; -struct shmid_ds; -struct sockaddr; -struct stat; -struct stat64; -struct statfs; -struct statfs64; -struct __sysctl_args; -struct sysinfo; -struct timespec; -struct timeval; -struct timex; -struct timezone; -struct tms; -struct utimbuf; -struct mq_attr; -struct compat_stat; -struct compat_timeval; -struct robust_list_head; -struct getcpu_cache; -struct old_linux_dirent; -struct perf_event_attr; -struct file_handle; -struct sigaltstack; -union bpf_attr; - +#include #include #include #include diff --git a/include/linux/syscalls_structs.h b/include/linux/syscalls_structs.h new file mode 100644 index 0000000..a920cbc --- /dev/null +++ b/include/linux/syscalls_structs.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_SYSCALL_STRUCTS_H +#define _LINUX_SYSCALL_STRUCTS_H + +struct epoll_event; +struct iattr; +struct inode; +struct iocb; +struct io_event; +struct iovec; +struct itimerspec; +struct itimerval; +struct kexec_segment; +struct linux_dirent; +struct linux_dirent64; +struct list_head; +struct mmap_arg_struct; +struct msgbuf; +struct user_msghdr; +struct mmsghdr; +struct msqid_ds; +struct new_utsname; +struct nfsctl_arg; +struct __old_kernel_stat; +struct oldold_utsname; +struct old_utsname; +struct pollfd; +struct rlimit; +struct rlimit64; +struct rusage; +struct sched_param; +struct sched_attr; +struct sel_arg_struct; +struct semaphore; +struct sembuf; +struct shmid_ds; +struct sockaddr; +struct stat; +struct stat64; +struct statfs; +struct statfs64; +struct __sysctl_args; +struct sysinfo; +struct timespec; +struct timeval; +struct timex; +struct timezone; +struct tms; +struct utimbuf; +struct mq_attr; +struct compat_stat; +struct compat_timeval; +struct robust_list_head; +struct getcpu_cache; +struct old_linux_dirent; +struct perf_event_attr; +struct file_handle; +struct sigaltstack; +union bpf_attr; + +#endif /* _LINUX_SYSCALL_STRUCTS_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 1324b02..a8380ad 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -29,6 +29,10 @@ #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) #endif +#ifndef __SC_WRAP +#define __SC_WRAP __SYSCALL +#endif + #define __NR_io_setup 0 __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup) #define __NR_io_destroy 1 diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0623787..8c99a45 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -16,6 +16,14 @@ asmlinkage long sys_ni_syscall(void) return -ENOSYS; } +#ifdef CONFIG_COMPAT_WRAPPER +#define cond_syscall_wrapped(name) \ + cond_syscall(name); \ + cond_syscall(compat_##name); +#else +#define cond_syscall_wrapped cond_syscall +#endif + cond_syscall(sys_quotactl); cond_syscall(sys32_quotactl); cond_syscall(sys_acct); -- 2.5.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: ynorov@caviumnetworks.com (Yury Norov) Date: Mon, 25 Jan 2016 19:57:23 +0300 Subject: [PATCH 1/5] all: s390: move wrapper infrastructure to generic headers In-Reply-To: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> References: <1453741047-5498-1-git-send-email-ynorov@caviumnetworks.com> Message-ID: <1453741047-5498-2-git-send-email-ynorov@caviumnetworks.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org __SC_COMPAT_CAST for s390 is too specific due to 31-bit pointer length, so it's moved to arch/s390/include/asm/compat.h. Generic declaration assumes that long, unsigned long and pointer types are all 32-bit length. linux/syscalls_structs.h header is introduced, because from now (see next patch) structure types listed there are needed for both normal and compat mode. cond_syscall_wrapped now defined two symbols: sys_foo() and compat_sys_foo(), if compat wrappers are enabled. Here __SC_WRAP() macro is introduced as well. s390 doesn't need it as it uses asm-generated syscall table. But architectures that generate that tables with C code (ARM64/ILP32) should redefine it as '#define __SC_WRAP(name) compat_##name'. Signed-off-by: Yury Norov --- arch/s390/include/asm/compat.h | 17 +++++++++-- arch/s390/kernel/compat_wrapper.c | 51 ------------------------------- include/linux/compat.h | 63 +++++++++++++++++++++++++++++++++++++++ include/linux/syscalls.h | 57 +---------------------------------- include/linux/syscalls_structs.h | 60 +++++++++++++++++++++++++++++++++++++ include/uapi/asm-generic/unistd.h | 4 +++ kernel/sys_ni.c | 8 +++++ 7 files changed, 151 insertions(+), 109 deletions(-) create mode 100644 include/linux/syscalls_structs.h diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index d350ed9..46cb4be 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -7,13 +7,26 @@ #include #include -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) - #define __SC_DELOUSE(t,v) ({ \ BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ }) +#define __SC_COMPAT_CAST(t, a) \ +({ \ + long __ReS = a; \ + \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + if (__TYPE_IS_L(t)) \ + __ReS = (s32)a; \ + if (__TYPE_IS_UL(t)) \ + __ReS = (u32)a; \ + if (__TYPE_IS_PTR(t)) \ + __ReS = a & 0x7fffffff; \ + (t)__ReS; \ +}) + #define PSW32_MASK_PER 0x40000000UL #define PSW32_MASK_DAT 0x04000000UL #define PSW32_MASK_IO 0x02000000UL diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index fac4eed..527f75d 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -8,57 +8,6 @@ #include #include "entry.h" -#define COMPAT_SYSCALL_WRAP1(name, ...) \ - COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP2(name, ...) \ - COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP3(name, ...) \ - COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP4(name, ...) \ - COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP5(name, ...) \ - COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP6(name, ...) \ - COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) - -#define __SC_COMPAT_TYPE(t, a) \ - __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a - -#define __SC_COMPAT_CAST(t, a) \ -({ \ - long __ReS = a; \ - \ - BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ - !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ - if (__TYPE_IS_L(t)) \ - __ReS = (s32)a; \ - if (__TYPE_IS_UL(t)) \ - __ReS = (u32)a; \ - if (__TYPE_IS_PTR(t)) \ - __ReS = a & 0x7fffffff; \ - (t)__ReS; \ -}) - -/* - * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by - * compat tasks. These wrappers will only be used for system calls where only - * the system call arguments need sign or zero extension or zeroing of the upper - * 33 bits of pointers. - * Note: since the wrapper function will afterwards call a system call which - * again performs zero and sign extension for all system call arguments with - * a size of less than eight bytes, these compat wrappers only touch those - * system call arguments with a size of eight bytes ((unsigned) long and - * pointers). Zero and sign extension for e.g. int parameters will be done by - * the regular system call wrappers. - */ -#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ -asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ -asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ -{ \ - return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ -} - COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); diff --git a/include/linux/compat.h b/include/linux/compat.h index a76c917..1a761ea 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -718,4 +718,67 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, #define is_compat_task() (0) #endif /* CONFIG_COMPAT */ + +#ifdef CONFIG_COMPAT_WRAPPER + +#ifndef __TYPE_IS_PTR +#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) +#endif + +#ifndef __SC_COMPAT_TYPE +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a +#endif + +#ifndef __SC_COMPAT_CAST +#define __SC_COMPAT_CAST(t, a) ({ \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + ((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a))); \ +}) +#endif + +#ifndef SYSCALL_DEFINE_WRAPx +/* + * The SYSCALL_DEFINE_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of upper + * bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ +#define SYSCALL_DEFINE_WRAPx(x, name, ...) \ +asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ +asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(compat_SyS##name)))); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)); \ +asmlinkage long compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ +{ \ + return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ +} \ +SYSCALL_DEFINEx(x, name, __VA_ARGS__) +#endif + +#define SYSCALL_DEFINE_WRAP1(name, ...) SYSCALL_DEFINE_WRAPx(1, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP2(name, ...) SYSCALL_DEFINE_WRAPx(2, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP3(name, ...) SYSCALL_DEFINE_WRAPx(3, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP4(name, ...) SYSCALL_DEFINE_WRAPx(4, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP5(name, ...) SYSCALL_DEFINE_WRAPx(5, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_WRAP6(name, ...) SYSCALL_DEFINE_WRAPx(6, _##name, __VA_ARGS__) + +#else + +#define SYSCALL_DEFINE_WRAP1 SYSCALL_DEFINE1 +#define SYSCALL_DEFINE_WRAP2 SYSCALL_DEFINE2 +#define SYSCALL_DEFINE_WRAP3 SYSCALL_DEFINE3 +#define SYSCALL_DEFINE_WRAP4 SYSCALL_DEFINE4 +#define SYSCALL_DEFINE_WRAP5 SYSCALL_DEFINE5 +#define SYSCALL_DEFINE_WRAP6 SYSCALL_DEFINE6 + +#endif /* CONFIG_COMPAT_WRAPPER */ + #endif /* _LINUX_COMPAT_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c2b66a2..1942cf4 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -11,62 +11,7 @@ #ifndef _LINUX_SYSCALLS_H #define _LINUX_SYSCALLS_H -struct epoll_event; -struct iattr; -struct inode; -struct iocb; -struct io_event; -struct iovec; -struct itimerspec; -struct itimerval; -struct kexec_segment; -struct linux_dirent; -struct linux_dirent64; -struct list_head; -struct mmap_arg_struct; -struct msgbuf; -struct user_msghdr; -struct mmsghdr; -struct msqid_ds; -struct new_utsname; -struct nfsctl_arg; -struct __old_kernel_stat; -struct oldold_utsname; -struct old_utsname; -struct pollfd; -struct rlimit; -struct rlimit64; -struct rusage; -struct sched_param; -struct sched_attr; -struct sel_arg_struct; -struct semaphore; -struct sembuf; -struct shmid_ds; -struct sockaddr; -struct stat; -struct stat64; -struct statfs; -struct statfs64; -struct __sysctl_args; -struct sysinfo; -struct timespec; -struct timeval; -struct timex; -struct timezone; -struct tms; -struct utimbuf; -struct mq_attr; -struct compat_stat; -struct compat_timeval; -struct robust_list_head; -struct getcpu_cache; -struct old_linux_dirent; -struct perf_event_attr; -struct file_handle; -struct sigaltstack; -union bpf_attr; - +#include #include #include #include diff --git a/include/linux/syscalls_structs.h b/include/linux/syscalls_structs.h new file mode 100644 index 0000000..a920cbc --- /dev/null +++ b/include/linux/syscalls_structs.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_SYSCALL_STRUCTS_H +#define _LINUX_SYSCALL_STRUCTS_H + +struct epoll_event; +struct iattr; +struct inode; +struct iocb; +struct io_event; +struct iovec; +struct itimerspec; +struct itimerval; +struct kexec_segment; +struct linux_dirent; +struct linux_dirent64; +struct list_head; +struct mmap_arg_struct; +struct msgbuf; +struct user_msghdr; +struct mmsghdr; +struct msqid_ds; +struct new_utsname; +struct nfsctl_arg; +struct __old_kernel_stat; +struct oldold_utsname; +struct old_utsname; +struct pollfd; +struct rlimit; +struct rlimit64; +struct rusage; +struct sched_param; +struct sched_attr; +struct sel_arg_struct; +struct semaphore; +struct sembuf; +struct shmid_ds; +struct sockaddr; +struct stat; +struct stat64; +struct statfs; +struct statfs64; +struct __sysctl_args; +struct sysinfo; +struct timespec; +struct timeval; +struct timex; +struct timezone; +struct tms; +struct utimbuf; +struct mq_attr; +struct compat_stat; +struct compat_timeval; +struct robust_list_head; +struct getcpu_cache; +struct old_linux_dirent; +struct perf_event_attr; +struct file_handle; +struct sigaltstack; +union bpf_attr; + +#endif /* _LINUX_SYSCALL_STRUCTS_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 1324b02..a8380ad 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -29,6 +29,10 @@ #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) #endif +#ifndef __SC_WRAP +#define __SC_WRAP __SYSCALL +#endif + #define __NR_io_setup 0 __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup) #define __NR_io_destroy 1 diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0623787..8c99a45 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -16,6 +16,14 @@ asmlinkage long sys_ni_syscall(void) return -ENOSYS; } +#ifdef CONFIG_COMPAT_WRAPPER +#define cond_syscall_wrapped(name) \ + cond_syscall(name); \ + cond_syscall(compat_##name); +#else +#define cond_syscall_wrapped cond_syscall +#endif + cond_syscall(sys_quotactl); cond_syscall(sys32_quotactl); cond_syscall(sys_acct); -- 2.5.0