From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Samuel Thibault <samuel.thibault@ens-lyon.org>,
Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PULL 07/13] linux-user: Fix sched_get/setaffinity conversion
Date: Tue, 23 Jan 2018 15:48:01 +0100 [thread overview]
Message-ID: <20180123144807.5618-8-laurent@vivier.eu> (raw)
In-Reply-To: <20180123144807.5618-1-laurent@vivier.eu>
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
sched_get/setaffinity linux-user syscalls were missing conversions for
little/big endian, which is hairy since longs may not be the same size
either.
For simplicity, this just introduces loops to convert bit by bit like is
done for select.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20180109201643.1479-1-samuel.thibault@ens-lyon.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/syscall.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 41ded90ee6..143e4a959d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7731,6 +7731,73 @@ static TargetFdTrans target_inotify_trans = {
};
#endif
+static int target_to_host_cpu_mask(unsigned long *host_mask,
+ size_t host_size,
+ abi_ulong target_addr,
+ size_t target_size)
+{
+ unsigned target_bits = sizeof(abi_ulong) * 8;
+ unsigned host_bits = sizeof(*host_mask) * 8;
+ abi_ulong *target_mask;
+ unsigned i, j;
+
+ assert(host_size >= target_size);
+
+ target_mask = lock_user(VERIFY_READ, target_addr, target_size, 1);
+ if (!target_mask) {
+ return -TARGET_EFAULT;
+ }
+ memset(host_mask, 0, host_size);
+
+ for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
+ unsigned bit = i * target_bits;
+ abi_ulong val;
+
+ __get_user(val, &target_mask[i]);
+ for (j = 0; j < target_bits; j++, bit++) {
+ if (val & (1UL << j)) {
+ host_mask[bit / host_bits] |= 1UL << (bit % host_bits);
+ }
+ }
+ }
+
+ unlock_user(target_mask, target_addr, 0);
+ return 0;
+}
+
+static int host_to_target_cpu_mask(const unsigned long *host_mask,
+ size_t host_size,
+ abi_ulong target_addr,
+ size_t target_size)
+{
+ unsigned target_bits = sizeof(abi_ulong) * 8;
+ unsigned host_bits = sizeof(*host_mask) * 8;
+ abi_ulong *target_mask;
+ unsigned i, j;
+
+ assert(host_size >= target_size);
+
+ target_mask = lock_user(VERIFY_WRITE, target_addr, target_size, 0);
+ if (!target_mask) {
+ return -TARGET_EFAULT;
+ }
+
+ for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
+ unsigned bit = i * target_bits;
+ abi_ulong val = 0;
+
+ for (j = 0; j < target_bits; j++, bit++) {
+ if (host_mask[bit / host_bits] & (1UL << (bit % host_bits))) {
+ val |= 1UL << j;
+ }
+ }
+ __put_user(val, &target_mask[i]);
+ }
+
+ unlock_user(target_mask, target_addr, target_size);
+ return 0;
+}
+
/* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
@@ -10376,6 +10443,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
mask = alloca(mask_size);
+ memset(mask, 0, mask_size);
ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
if (!is_error(ret)) {
@@ -10395,9 +10463,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = arg2;
}
- if (copy_to_user(arg3, mask, ret)) {
- goto efault;
- }
+ ret = host_to_target_cpu_mask(mask, mask_size, arg3, arg2);
}
}
break;
@@ -10415,13 +10481,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
}
mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
-
mask = alloca(mask_size);
- if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
- goto efault;
+
+ ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
+ if (ret) {
+ break;
}
- memcpy(mask, p, arg2);
- unlock_user_struct(p, arg2, 0);
ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
}
--
2.14.3
next prev parent reply other threads:[~2018-01-23 14:48 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-23 14:47 [Qemu-devel] [PULL 00/13] Linux user for 2.12 patches Laurent Vivier
2018-01-23 14:47 ` [Qemu-devel] [PULL 01/13] linux-user: Fix locking order in fork_start() Laurent Vivier
2018-01-23 14:47 ` [Qemu-devel] [PULL 02/13] linux-user: wrap fork() in a start/end exclusive section Laurent Vivier
2018-01-23 14:47 ` [Qemu-devel] [PULL 03/13] linux-user: Fix length calculations in host_to_target_cmsg() Laurent Vivier
2018-01-23 14:47 ` [Qemu-devel] [PULL 04/13] linux-user: Don't use CMSG_ALIGN(sizeof struct cmsghdr) Laurent Vivier
2018-01-23 14:47 ` [Qemu-devel] [PULL 05/13] linux-user: Translate flags argument to dup3 syscall Laurent Vivier
2018-01-23 14:48 ` [Qemu-devel] [PULL 06/13] linux-user/mmap.c: Avoid choosing NULL as start address Laurent Vivier
2018-01-23 14:48 ` Laurent Vivier [this message]
2018-01-26 18:23 ` [Qemu-devel] [PULL 07/13] linux-user: Fix sched_get/setaffinity conversion Peter Maydell
2018-01-26 18:33 ` Samuel Thibault
2018-01-23 14:48 ` [Qemu-devel] [PULL 08/13] linux-user: Add AT_SECURE auxval Laurent Vivier
2018-01-23 14:48 ` [Qemu-devel] [PULL 09/13] linux-user: Add getcpu() support Laurent Vivier
2018-01-23 14:48 ` [Qemu-devel] [PULL 10/13] linux-user: remove nmi.c and fw-path-provider.c Laurent Vivier
2018-01-23 14:48 ` [Qemu-devel] [PULL 11/13] linux-user: Propagate siginfo_t through to handle_cpu_signal() Laurent Vivier
2018-01-23 14:48 ` [Qemu-devel] [PULL 12/13] page_unprotect(): handle calls to pages that are PAGE_WRITE Laurent Vivier
2018-03-22 1:52 ` Laurent Vivier
2018-03-22 10:36 ` Laurent Vivier
2018-03-22 11:05 ` Peter Maydell
2018-03-22 11:07 ` Peter Maydell
2018-03-22 11:13 ` Laurent Vivier
2018-03-22 16:47 ` Laurent Vivier
2018-03-22 11:07 ` Laurent Vivier
2018-03-22 11:10 ` Peter Maydell
2018-01-23 14:48 ` [Qemu-devel] [PULL 13/13] linux-user: implement renameat2 Laurent Vivier
2018-01-23 19:13 ` Palmer Dabbelt
2018-01-23 20:13 ` Laurent Vivier
2018-01-23 20:55 ` Palmer Dabbelt
2018-01-25 11:37 ` [Qemu-devel] [PULL 00/13] Linux user for 2.12 patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180123144807.5618-8-laurent@vivier.eu \
--to=laurent@vivier.eu \
--cc=qemu-devel@nongnu.org \
--cc=samuel.thibault@ens-lyon.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).