diff options
author | Laurent Vivier <laurent@vivier.eu> | 2015-06-16 00:35:28 +0200 |
---|---|---|
committer | Riku Voipio <riku.voipio@linaro.org> | 2015-06-16 09:37:17 +0300 |
commit | 45c874ebbae661238bfa3c0534480ebe2940b112 (patch) | |
tree | 83b72699bfd3d871c92606a1f1adbc05499a9c5e /linux-user | |
parent | 1d085f6cae51b1a0fb92ad03ce8bf038e29c9750 (diff) | |
download | qemu-45c874ebbae661238bfa3c0534480ebe2940b112.zip |
linux-user: ioctl() command type is int
When executing a 64bit target chroot on 64bit host,
the ioctl() command can mismatch.
It seems the previous commit doesn't solve the problem in
my case:
9c6bf9c7 linux-user: Fix ioctl cmd type mismatch on 64-bit targets
For example, a ppc64 chroot on an x86_64 host:
bash-4.3# ls
Unsupported ioctl: cmd=0x80087467
Unsupported ioctl: cmd=0x802c7415
The origin of the problem is in syscall.c:do_ioctl().
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
In this case (ppc64) abi_long is long (on the x86_64), and
cmd = 0x0000000080087467
then
if (ie->target_cmd == cmd)
target_cmd is int, so target_cmd = 0x80087467
and to compare an int with a long, the sign is extended to 64bit,
so the comparison is:
if (0xffffffff80087467 == 0x0000000080087467)
which doesn't match whereas it should.
This patch uses int in the case of the target command type
instead of abi_long.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/syscall.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5cf265cb08..f62c698948 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3346,7 +3346,7 @@ STRUCT_MAX typedef struct IOCTLEntry IOCTLEntry; typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, abi_long cmd, abi_long arg); + int fd, int cmd, abi_long arg); struct IOCTLEntry { int target_cmd; @@ -3372,7 +3372,7 @@ struct IOCTLEntry { / sizeof(struct fiemap_extent)) static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, abi_long cmd, abi_long arg) + int fd, int cmd, abi_long arg) { /* The parameter for this ioctl is a struct fiemap followed * by an array of struct fiemap_extent whose size is set @@ -3453,7 +3453,7 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, #endif static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, abi_long cmd, abi_long arg) + int fd, int cmd, abi_long arg) { const argtype *arg_type = ie->arg_type; int target_size; @@ -3547,7 +3547,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, } static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, - abi_long cmd, abi_long arg) + int cmd, abi_long arg) { void *argptr; struct dm_ioctl *host_dm; @@ -3772,7 +3772,7 @@ out: } static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, - abi_long cmd, abi_long arg) + int cmd, abi_long arg) { void *argptr; int target_size; @@ -3825,7 +3825,7 @@ out: } static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, abi_long cmd, abi_long arg) + int fd, int cmd, abi_long arg) { const argtype *arg_type = ie->arg_type; const StructEntry *se; @@ -3888,7 +3888,7 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, } static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, abi_long cmd, abi_long arg) + int fd, int cmd, abi_long arg) { int sig = target_to_host_signal(arg); return get_errno(ioctl(fd, ie->host_cmd, sig)); @@ -3905,7 +3905,7 @@ static IOCTLEntry ioctl_entries[] = { /* ??? Implement proper locking for ioctls. */ /* do_ioctl() Must return target values and target errnos. */ -static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) +static abi_long do_ioctl(int fd, int cmd, abi_long arg) { const IOCTLEntry *ie; const argtype *arg_type; |