From nobody Tue Oct 28 01:53:46 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 1514489785443501.7622243860643; Thu, 28 Dec 2017 11:36:25 -0800 (PST) Received: from localhost ([::1]:35620 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eUdyY-0005VZ-N7 for importer@patchew.org; Thu, 28 Dec 2017 14:36:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eUdxF-0004qD-8k for qemu-devel@nongnu.org; Thu, 28 Dec 2017 14:35:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eUdxB-0000mk-RL for qemu-devel@nongnu.org; Thu, 28 Dec 2017 14:35:01 -0500 Received: from [2a01:474::1] (port=59179 helo=hera.aquilenet.fr) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eUdxB-0000mE-Cg for qemu-devel@nongnu.org; Thu, 28 Dec 2017 14:34:57 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 135501064E; Thu, 28 Dec 2017 20:34:56 +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 gJcb2X3Jp8RD; Thu, 28 Dec 2017 20:34:55 +0100 (CET) Received: from var.youpi.perso.aquilenet.fr (LFbn-ORL-1-236-13.w92-152.abo.wanadoo.fr [92.152.80.13]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 5D301CC76; Thu, 28 Dec 2017 20:34:42 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.90_RC4) (envelope-from ) id 1eUdwv-0004uV-TX; Thu, 28 Dec 2017 20:34:41 +0100 X-Virus-Scanned: Debian amavisd-new at aquilenet.fr From: Samuel Thibault To: qemu-devel@nongnu.org, Riku Voipio , Laurent Vivier Date: Thu, 28 Dec 2017 20:34:39 +0100 Message-Id: <20171228193439.18835-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] X-Received-From: 2a01:474::1 Subject: [Qemu-devel] [PATCH] 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 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 --- linux-user/syscall.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++--= ---- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 11c9116c4a..f806cfb9a7 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7716,6 +7716,67 @@ static TargetFdTrans target_inotify_trans =3D { }; #endif =20 +static int target_to_host_cpu_mask(unsigned long *host_mask, size_t host_s= ize, 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 +10414,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 +10434,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 +10452,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