diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-07-27 21:54:32 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-08-19 20:12:34 -0400 |
commit | dd90bbd5fb763ab8924135a30956030c7a7b94fc (patch) | |
tree | e8cb73517611d26b74086025958e88404994f028 /arch | |
parent | c79b29735d28d819380b584d6707b4110ee759f3 (diff) |
powerpc: Add compat_sys_truncate
The truncate syscall has a signed long parameter, so when using a 32-
bit userspace with a 64-bit kernel the argument is zero-extended
instead of sign-extended. Adding the compat_sys_truncate function
fixes the issue.
This was noticed during an LSB truncate test failure. The test was
checking for the correct error number set when truncate is called with
a length of -1. The test can be found at:
http://bzr.linuxfoundation.org/lsb/devel/runtime-test?cmd=inventory;rev=stewb%40linux-foundation.org-20090626205411-sfb23cc0tjj7jzgm;path=modules/vsx-pcts/tset/POSIX.os/files/truncate/
BenH: Added compat_sys_ftruncate() as well, same issue.
Signed-off-by: Chase Douglas <cndougla@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/systbl.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 12 |
2 files changed, 14 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 370600ca2765..ed24bd92fe49 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -95,8 +95,8 @@ SYSCALL(reboot) | |||
95 | SYSX(sys_ni_syscall,compat_sys_old_readdir,sys_old_readdir) | 95 | SYSX(sys_ni_syscall,compat_sys_old_readdir,sys_old_readdir) |
96 | SYSCALL_SPU(mmap) | 96 | SYSCALL_SPU(mmap) |
97 | SYSCALL_SPU(munmap) | 97 | SYSCALL_SPU(munmap) |
98 | SYSCALL_SPU(truncate) | 98 | COMPAT_SYS_SPU(truncate) |
99 | SYSCALL_SPU(ftruncate) | 99 | COMPAT_SYS_SPU(ftruncate) |
100 | SYSCALL_SPU(fchmod) | 100 | SYSCALL_SPU(fchmod) |
101 | SYSCALL_SPU(fchown) | 101 | SYSCALL_SPU(fchown) |
102 | COMPAT_SYS_SPU(getpriority) | 102 | COMPAT_SYS_SPU(getpriority) |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index bb1cfcfdbbbb..1cc5e9e5da96 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -343,6 +343,18 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) | |||
343 | return sys_lseek(fd, (int)offset, origin); | 343 | return sys_lseek(fd, (int)offset, origin); |
344 | } | 344 | } |
345 | 345 | ||
346 | long compat_sys_truncate(const char __user * path, u32 length) | ||
347 | { | ||
348 | /* sign extend length */ | ||
349 | return sys_truncate(path, (int)length); | ||
350 | } | ||
351 | |||
352 | long compat_sys_ftruncate(int fd, u32 length) | ||
353 | { | ||
354 | /* sign extend length */ | ||
355 | return sys_ftruncate(fd, (int)length); | ||
356 | } | ||
357 | |||
346 | /* Note: it is necessary to treat bufsiz as an unsigned int, | 358 | /* Note: it is necessary to treat bufsiz as an unsigned int, |
347 | * with the corresponding cast to a signed int to insure that the | 359 | * with the corresponding cast to a signed int to insure that the |
348 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 360 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |