Skip to content

Commit 190f918

Browse files
committed
Merge branch 'compat' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 compat wrapper rework from Heiko Carstens: "S390 compat system call wrapper simplification work. The intention of this work is to get rid of all hand written assembly compat system call wrappers on s390, which perform proper sign or zero extension, or pointer conversion of compat system call parameters. Instead all of this should be done with C code eg by using Al's COMPAT_SYSCALL_DEFINEx() macro. Therefore all common code and s390 specific compat system calls have been converted to the COMPAT_SYSCALL_DEFINEx() macro. In order to generate correct code all compat system calls may only have eg compat_ulong_t parameters, but no unsigned long parameters. Those patches which change parameter types from unsigned long to compat_ulong_t parameters are separate in this series, but shouldn't cause any harm. The only compat system calls which intentionally have 64 bit parameters (preadv64 and pwritev64) in support of the x86/32 ABI haven't been changed, but are now only available if an architecture defines __ARCH_WANT_COMPAT_SYS_PREADV64/PWRITEV64. System calls which do not have a compat variant but still need proper zero extension on s390, like eg "long sys_brk(unsigned long brk)" will get a proper wrapper function with the new s390 specific COMPAT_SYSCALL_WRAPx() macro: COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); which generates the following code (simplified): asmlinkage long sys_brk(unsigned long brk); asmlinkage long compat_sys_brk(long brk) { return sys_brk((u32)brk); } Given that the C file which contains all the COMPAT_SYSCALL_WRAP lines includes both linux/syscall.h and linux/compat.h, it will generate build errors, if the declaration of sys_brk() doesn't match, or if there exists a non-matching compat_sys_brk() declaration. In addition this will intentionally result in a link error if somewhere else a compat_sys_brk() function exists, which probably should have been used instead. Two more BUILD_BUG_ONs make sure the size and type of each compat syscall parameter can be handled correctly with the s390 specific macros. I converted the compat system calls step by step to verify the generated code is correct and matches the previous code. In fact it did not always match, however that was always a bug in the hand written asm code. In result we get less code, less bugs, and much more sanity checking" * 'compat' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (44 commits) s390/compat: add copyright statement compat: include linux/unistd.h within linux/compat.h s390/compat: get rid of compat wrapper assembly code s390/compat: build error for large compat syscall args mm/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types kexec/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types net/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types ipc/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types fs/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types ipc/compat: convert to COMPAT_SYSCALL_DEFINE fs/compat: convert to COMPAT_SYSCALL_DEFINE security/compat: convert to COMPAT_SYSCALL_DEFINE mm/compat: convert to COMPAT_SYSCALL_DEFINE net/compat: convert to COMPAT_SYSCALL_DEFINE kernel/compat: convert to COMPAT_SYSCALL_DEFINE fs/compat: optional preadv64/pwrite64 compat system calls ipc/compat_sys_msgrcv: change msgtyp type from long to compat_long_t s390/compat: partial parameter conversion within syscall wrappers s390/compat: automatic zero, sign and pointer conversion of syscalls s390/compat: add sync_file_range and fallocate compat syscalls ...
2 parents 176ab02 + 1e4ec62 commit 190f918

28 files changed

+835
-2004
lines changed

arch/arm64/include/asm/unistd.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
*/
1616
#ifdef CONFIG_COMPAT
17+
#define __ARCH_WANT_COMPAT_SYS_GETDENTS64
1718
#define __ARCH_WANT_COMPAT_STAT64
1819
#define __ARCH_WANT_SYS_GETHOSTNAME
1920
#define __ARCH_WANT_SYS_PAUSE

arch/mips/include/asm/unistd.h

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#ifndef __ASSEMBLY__
2626

27-
#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64
2827
#define __ARCH_WANT_OLD_READDIR
2928
#define __ARCH_WANT_SYS_ALARM
3029
#define __ARCH_WANT_SYS_GETHOSTNAME

arch/s390/include/asm/compat.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
#include <linux/thread_info.h>
99

1010
#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64))
11-
#define __SC_DELOUSE(t,v) (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v))
11+
12+
#define __SC_DELOUSE(t,v) ({ \
13+
BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \
14+
(t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \
15+
})
1216

1317
#define PSW32_MASK_PER 0x40000000UL
1418
#define PSW32_MASK_DAT 0x04000000UL

arch/s390/kernel/compat_linux.c

+63-53
Original file line numberDiff line numberDiff line change
@@ -86,48 +86,51 @@
8686
#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
8787
#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
8888

89-
asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
89+
COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename,
90+
u16, user, u16, group)
9091
{
9192
return sys_chown(filename, low2highuid(user), low2highgid(group));
9293
}
9394

94-
asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
95+
COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *,
96+
filename, u16, user, u16, group)
9597
{
9698
return sys_lchown(filename, low2highuid(user), low2highgid(group));
9799
}
98100

99-
asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
101+
COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group)
100102
{
101103
return sys_fchown(fd, low2highuid(user), low2highgid(group));
102104
}
103105

104-
asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
106+
COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid)
105107
{
106108
return sys_setregid(low2highgid(rgid), low2highgid(egid));
107109
}
108110

109-
asmlinkage long sys32_setgid16(u16 gid)
111+
COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)
110112
{
111113
return sys_setgid((gid_t)gid);
112114
}
113115

114-
asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
116+
COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
115117
{
116118
return sys_setreuid(low2highuid(ruid), low2highuid(euid));
117119
}
118120

119-
asmlinkage long sys32_setuid16(u16 uid)
121+
COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)
120122
{
121123
return sys_setuid((uid_t)uid);
122124
}
123125

124-
asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
126+
COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)
125127
{
126128
return sys_setresuid(low2highuid(ruid), low2highuid(euid),
127-
low2highuid(suid));
129+
low2highuid(suid));
128130
}
129131

130-
asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __user *suidp)
132+
COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp,
133+
u16 __user *, euidp, u16 __user *, suidp)
131134
{
132135
const struct cred *cred = current_cred();
133136
int retval;
@@ -144,13 +147,14 @@ asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __us
144147
return retval;
145148
}
146149

147-
asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
150+
COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid)
148151
{
149152
return sys_setresgid(low2highgid(rgid), low2highgid(egid),
150-
low2highgid(sgid));
153+
low2highgid(sgid));
151154
}
152155

153-
asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __user *sgidp)
156+
COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp,
157+
u16 __user *, egidp, u16 __user *, sgidp)
154158
{
155159
const struct cred *cred = current_cred();
156160
int retval;
@@ -167,12 +171,12 @@ asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __us
167171
return retval;
168172
}
169173

170-
asmlinkage long sys32_setfsuid16(u16 uid)
174+
COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)
171175
{
172176
return sys_setfsuid((uid_t)uid);
173177
}
174178

175-
asmlinkage long sys32_setfsgid16(u16 gid)
179+
COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)
176180
{
177181
return sys_setfsgid((gid_t)gid);
178182
}
@@ -215,7 +219,7 @@ static int groups16_from_user(struct group_info *group_info, u16 __user *groupli
215219
return 0;
216220
}
217221

218-
asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
222+
COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist)
219223
{
220224
const struct cred *cred = current_cred();
221225
int i;
@@ -240,7 +244,7 @@ asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
240244
return i;
241245
}
242246

243-
asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
247+
COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist)
244248
{
245249
struct group_info *group_info;
246250
int retval;
@@ -265,22 +269,22 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
265269
return retval;
266270
}
267271

268-
asmlinkage long sys32_getuid16(void)
272+
COMPAT_SYSCALL_DEFINE0(s390_getuid16)
269273
{
270274
return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
271275
}
272276

273-
asmlinkage long sys32_geteuid16(void)
277+
COMPAT_SYSCALL_DEFINE0(s390_geteuid16)
274278
{
275279
return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
276280
}
277281

278-
asmlinkage long sys32_getgid16(void)
282+
COMPAT_SYSCALL_DEFINE0(s390_getgid16)
279283
{
280284
return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
281285
}
282286

283-
asmlinkage long sys32_getegid16(void)
287+
COMPAT_SYSCALL_DEFINE0(s390_getegid16)
284288
{
285289
return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
286290
}
@@ -295,41 +299,35 @@ COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second,
295299
}
296300
#endif
297301

298-
asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
302+
COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low)
299303
{
300-
if ((int)high < 0)
301-
return -EINVAL;
302-
else
303-
return sys_truncate(path, (high << 32) | low);
304+
return sys_truncate(path, (unsigned long)high << 32 | low);
304305
}
305306

306-
asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
307+
COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low)
307308
{
308-
if ((int)high < 0)
309-
return -EINVAL;
310-
else
311-
return sys_ftruncate(fd, (high << 32) | low);
309+
return sys_ftruncate(fd, (unsigned long)high << 32 | low);
312310
}
313311

314-
asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
315-
size_t count, u32 poshi, u32 poslo)
312+
COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf,
313+
compat_size_t, count, u32, high, u32, low)
316314
{
317315
if ((compat_ssize_t) count < 0)
318316
return -EINVAL;
319-
return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
317+
return sys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low);
320318
}
321319

322-
asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
323-
size_t count, u32 poshi, u32 poslo)
320+
COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf,
321+
compat_size_t, count, u32, high, u32, low)
324322
{
325323
if ((compat_ssize_t) count < 0)
326324
return -EINVAL;
327-
return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
325+
return sys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low);
328326
}
329327

330-
asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
328+
COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count)
331329
{
332-
return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
330+
return sys_readahead(fd, (unsigned long)high << 32 | low, count);
333331
}
334332

335333
struct stat64_emu31 {
@@ -381,7 +379,7 @@ static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
381379
return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
382380
}
383381

384-
asmlinkage long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf)
382+
COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)
385383
{
386384
struct kstat stat;
387385
int ret = vfs_stat(filename, &stat);
@@ -390,7 +388,7 @@ asmlinkage long sys32_stat64(const char __user * filename, struct stat64_emu31 _
390388
return ret;
391389
}
392390

393-
asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31 __user * statbuf)
391+
COMPAT_SYSCALL_DEFINE2(s390_lstat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)
394392
{
395393
struct kstat stat;
396394
int ret = vfs_lstat(filename, &stat);
@@ -399,7 +397,7 @@ asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31
399397
return ret;
400398
}
401399

402-
asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
400+
COMPAT_SYSCALL_DEFINE2(s390_fstat64, unsigned int, fd, struct stat64_emu31 __user *, statbuf)
403401
{
404402
struct kstat stat;
405403
int ret = vfs_fstat(fd, &stat);
@@ -408,8 +406,8 @@ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * sta
408406
return ret;
409407
}
410408

411-
asmlinkage long sys32_fstatat64(unsigned int dfd, const char __user *filename,
412-
struct stat64_emu31 __user* statbuf, int flag)
409+
COMPAT_SYSCALL_DEFINE4(s390_fstatat64, unsigned int, dfd, const char __user *, filename,
410+
struct stat64_emu31 __user *, statbuf, int, flag)
413411
{
414412
struct kstat stat;
415413
int error;
@@ -435,7 +433,7 @@ struct mmap_arg_struct_emu31 {
435433
compat_ulong_t offset;
436434
};
437435

438-
asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
436+
COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg)
439437
{
440438
struct mmap_arg_struct_emu31 a;
441439

@@ -447,7 +445,7 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
447445
a.offset >> PAGE_SHIFT);
448446
}
449447

450-
asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
448+
COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg)
451449
{
452450
struct mmap_arg_struct_emu31 a;
453451

@@ -456,15 +454,15 @@ asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
456454
return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
457455
}
458456

459-
asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
457+
COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)
460458
{
461459
if ((compat_ssize_t) count < 0)
462460
return -EINVAL;
463461

464462
return sys_read(fd, buf, count);
465463
}
466464

467-
asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t count)
465+
COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count)
468466
{
469467
if ((compat_ssize_t) count < 0)
470468
return -EINVAL;
@@ -478,14 +476,13 @@ asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t cou
478476
* because the 31 bit values differ from the 64 bit values.
479477
*/
480478

481-
asmlinkage long
482-
sys32_fadvise64(int fd, loff_t offset, size_t len, int advise)
479+
COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size_t, len, int, advise)
483480
{
484481
if (advise == 4)
485482
advise = POSIX_FADV_DONTNEED;
486483
else if (advise == 5)
487484
advise = POSIX_FADV_NOREUSE;
488-
return sys_fadvise64(fd, offset, len, advise);
485+
return sys_fadvise64(fd, (unsigned long)high << 32 | low, len, advise);
489486
}
490487

491488
struct fadvise64_64_args {
@@ -495,8 +492,7 @@ struct fadvise64_64_args {
495492
int advice;
496493
};
497494

498-
asmlinkage long
499-
sys32_fadvise64_64(struct fadvise64_64_args __user *args)
495+
COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args)
500496
{
501497
struct fadvise64_64_args a;
502498

@@ -508,3 +504,17 @@ sys32_fadvise64_64(struct fadvise64_64_args __user *args)
508504
a.advice = POSIX_FADV_NOREUSE;
509505
return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
510506
}
507+
508+
COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow,
509+
u32, nhigh, u32, nlow, unsigned int, flags)
510+
{
511+
return sys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow,
512+
((u64)nhigh << 32) + nlow, flags);
513+
}
514+
515+
COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow,
516+
u32, lenhigh, u32, lenlow)
517+
{
518+
return sys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow,
519+
((u64)lenhigh << 32) + lenlow);
520+
}

0 commit comments

Comments
 (0)