From nobody Tue Oct 28 01:58:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515529175122636.2602566655544; Tue, 9 Jan 2018 12:19:35 -0800 (PST) Received: from localhost ([::1]:45464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZ0Mv-0000AZ-Vw for importer@patchew.org; Tue, 09 Jan 2018 15:19:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36391) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZ0KJ-0006z1-LU for qemu-devel@nongnu.org; Tue, 09 Jan 2018 15:16:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZ0KF-00030S-CW for qemu-devel@nongnu.org; Tue, 09 Jan 2018 15:16:51 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:33120) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZ0KF-0002zN-63 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 15:16:47 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id DC4051094F; Tue, 9 Jan 2018 21:16:45 +0100 (CET) Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YY6eDRq-ki_o; Tue, 9 Jan 2018 21:16:45 +0100 (CET) Received: from var.youpi.perso.aquilenet.fr (unknown [IPv6:2a01:cb19:181:c200:3602:86ff:fe2c:6a19]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 0DDEF1080E; Tue, 9 Jan 2018 21:16:45 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.90) (envelope-from ) id 1eZ0KC-0000OY-CA; Tue, 09 Jan 2018 21:16:44 +0100 X-Virus-Scanned: Debian amavisd-new at aquilenet.fr From: Samuel Thibault To: qemu-devel@nongnu.org Date: Tue, 9 Jan 2018 21:16:43 +0100 Message-Id: <20180109201643.1479-1-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.15.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 185.233.100.1 Subject: [Qemu-devel] [PATCHv2] linux-user: Fix sched_get/setaffinity conversion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Thibault , Riku Voipio , Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Laurent Vivier --- Difference from v1: bitmask computation was separated out into target_to_host_cpu_mask()/host_to_target_cpu_mask(). 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 11c9116c4a..cac07419aa 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7716,6 +7716,73 @@ static TargetFdTrans target_inotify_trans =3D { }; #endif =20 +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 =3D sizeof(abi_ulong) * 8; + unsigned host_bits =3D sizeof(*host_mask) * 8; + abi_ulong *target_mask; + unsigned i, j; + + assert(host_size >=3D target_size); + + target_mask =3D lock_user(VERIFY_READ, target_addr, target_size, 1); + if (!target_mask) { + return -TARGET_EFAULT; + } + memset(host_mask, 0, host_size); + + for (i =3D 0 ; i < target_size / sizeof(abi_ulong); i++) { + unsigned bit =3D i * target_bits; + abi_ulong val; + + __get_user(val, &target_mask[i]); + for (j =3D 0; j < target_bits; j++, bit++) { + if (val & (1UL << j)) { + host_mask[bit / host_bits] |=3D 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 =3D sizeof(abi_ulong) * 8; + unsigned host_bits =3D sizeof(*host_mask) * 8; + abi_ulong *target_mask; + unsigned i, j; + + assert(host_size >=3D target_size); + + target_mask =3D lock_user(VERIFY_WRITE, target_addr, target_size, 0); + if (!target_mask) { + return -TARGET_EFAULT; + } + + for (i =3D 0 ; i < target_size / sizeof(abi_ulong); i++) { + unsigned bit =3D i * target_bits; + abi_ulong val =3D 0; + + for (j =3D 0; j < target_bits; j++, bit++) { + if (host_mask[bit / host_bits] & (1UL << (bit % host_bits))) { + val |=3D 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_. */ @@ -10353,6 +10420,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_lon= g arg1, mask_size =3D (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) -= 1); =20 mask =3D alloca(mask_size); + memset(mask, 0, mask_size); ret =3D get_errno(sys_sched_getaffinity(arg1, mask_size, mask)= ); =20 if (!is_error(ret)) { @@ -10372,9 +10440,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_lon= g arg1, ret =3D arg2; } =20 - if (copy_to_user(arg3, mask, ret)) { - goto efault; - } + ret =3D host_to_target_cpu_mask(mask, mask_size, arg3, arg= 2); } } break; @@ -10392,13 +10458,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_l= ong arg1, break; } mask_size =3D (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) -= 1); - mask =3D alloca(mask_size); - if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) { - goto efault; + + ret =3D target_to_host_cpu_mask(mask, mask_size, arg3, arg2); + if (ret) { + break; } - memcpy(mask, p, arg2); - unlock_user_struct(p, arg2, 0); =20 ret =3D get_errno(sys_sched_setaffinity(arg1, mask_size, mask)= ); } --=20 2.15.1