From patchwork Tue Dec 13 17:03:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 13072243 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0158CC4332F for ; Tue, 13 Dec 2022 17:03:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p58gg-0006Ca-6U; Tue, 13 Dec 2022 12:03:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p58gc-00066X-Ce for qemu-devel@nongnu.org; Tue, 13 Dec 2022 12:03:22 -0500 Received: from mout.gmx.net ([212.227.17.22]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p58ga-0004GZ-5A for qemu-devel@nongnu.org; Tue, 13 Dec 2022 12:03:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1670950991; bh=1TZlKM654CTTP7qEgehYkfI/qQ4VQ4bX9chbuQ584uQ=; h=X-UI-Sender-Class:Date:From:To:Subject; b=YmRPd4BITJ4uLPNpJ5nHOCPJpyHvbNBVL97m3SXfYwBAa1a1I4yXUj60dd6JTK7OF ewWDQkpq3NcwShvemzlHqoAV1nKvtLR7tOXVS6RnYWlIVSAeOtnp0+HUdxLbsNX8lU tAcAw1LO8x0XRg0nibGOvzF5ooGj4QPXk89zGnjApzObektj2LAQZYQFvrhfPVM3Co BjBy13usRFbrblYdjD4KTVfM38jH8v8mV2bUT6IY6UaGcaiG1Xj2JUE3KpWsV/MnVN 53QYrCkvFX4MWc9Jjche9dzF8p+HEsGBJgwxKaoD8+RJ3Ya0+hCIEvssD2jDy7mAHG FSl0f48xavjRQ== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from p100 ([92.116.135.201]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1Ml6qC-1odTyV2ovc-00lWOE; Tue, 13 Dec 2022 18:03:11 +0100 Date: Tue, 13 Dec 2022 18:03:09 +0100 From: Helge Deller To: Laurent Vivier , Ilya Leoshkevich , Vitaly Buka , Richard Henderson , qemu-devel@nongnu.org Subject: [PATCH v2] linux-user: Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise() Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Provags-ID: V03:K1:R6CkkXD2HdebZ9MOHzhtaPoGr4iacfrCrxPxw5VV5d/75qaGd6m qOAcXirG4KHNVS+m52D2o9mw6cZPHFsvAt1sn60dIRvZKJ67WekQRzCcQeGC3dJ45JE76ar N7HTYj7vBDgfyn0sny1pNp2c8b1bHzjH9fUI5Ovj+NxqExSPJLP+1Tf1ChhqfG3kbO+mzU2 1A78C4QlShcMvaP0myF0w== UI-OutboundReport: notjunk:1;M01:P0:i+e5qWM2TAo=;tS7vfALVdy+Dya7828TVpiXMBb4 hN/bGrajiSJ3OJxUtnWtuDz9UroU89ziraPd4AkYFBUU/hEaGOvWN3sRgfVC8U+5QXjvx156E ttznq0434io+EBtYwct/rDJKSFuF7YRZ8cE1qI57KPHr7CxZSSFWwy8Oe5cmDq8XEj7S5yAp+ NKmtSlvcM7Zr7rTiLHQDv5VuvtWgTFyAIAqcHDxsOmfTmt7zdf/uJ9wKZZl6iJOroLxQLtp3Y Ta/4F2s1TtHT15qT0+yFouDLZVlGOVJNn8DbtU/R9u0AbQYScBSuu3Yp9sjVzQXscdzI67VN6 Wz82zRVvqcPChEpLNsCnXdZOPCdkC7/i4tri3LP4Xx3zpQtDOvdHcbyvwWaAes3ylNVhl3Ifp BG/CYpwaOaR4hujXzdXQRODycIW9pvz69KwH6ked9Nq6my7n18VqL0AxIhAsgkXjiQDRkaSFL 4e6Ih5vf9tDyysK+CbfrAHue5wXjVSNEUf/stbJzaDBS9Mpi3MH2jB/KrZneMMorJbqRedMgw g0OZXGfl3O7ApY0h+WyLTBRX9dR6nOLSeOv6ZpuBkgCvZJOS/4tlmOovw+VA4jHKf2r3a6o90 jKaI5hs1SCHjIwgNvpWmfgQzT+3pDRcgXKQ7HO99vDIGrhljOBPVdnZ6Xz4axZ5GFCIAsjQMj IaCTMOBQgLIgTeL5c/6kmsa39D8i92k74L8t14G8DhbMbhwa++Nv5hewHZMViMHC0ibFHJHt+ g5aNu0BwFwEOiGO6osRi8ChnphD0wHV7W+p6GH0TyRt/+jSzx6bPzpO1hQ5POVcMPCmM7CxIU FW2XQnRJjBvctsDHN3Wu7bK4X6mFS0LiEsD/ggqXYxEb9PdfNvgvMM5jXhJhgCxm02+vNu+sO SEppXfvsMwoutL9wQlbvBUFvaNk1rmZO3qJnx8xMfY3oVOci2SkaYvXKsrl8phThalGuEb9n/ RqVYyg== Received-SPF: pass client-ip=212.227.17.22; envelope-from=deller@gmx.de; helo=mout.gmx.net X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Both parameters have a different value on the parisc platform, so first translate the target value into a host value for usage in the native madvise() syscall. Those parameters are often used by security sensitive applications (e.g. tor browser, boringssl, ...) which expect the call to return a proper return code on failure, so return -EINVAL if qemu fails to forward the syscall to the host OS. While touching this code, enhance the comments about MADV_DONTNEED. Tested with testcase of tor browser when running hppa-linux guest on x86-64 host. Signed-off-by: Helge Deller Acked-by: Ilya Leoshkevich Reviewed-by: Laurent Vivier --- v2: based on feedback from Ilya Leoshkevich - rename can_passthrough_madv_dontneed() to can_passthrough_madvise() - rephrase the comment about MADV_DONTNEED diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 10f5079331..28135c9e6a 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -857,7 +857,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, return new_addr; } -static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end) +static bool can_passthrough_madvise(abi_ulong start, abi_ulong end) { ulong addr; @@ -901,23 +901,53 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice) return -TARGET_EINVAL; } + /* Translate for some architectures which have different MADV_xxx values */ + switch (advice) { + case TARGET_MADV_DONTNEED: /* alpha */ + advice = MADV_DONTNEED; + break; + case TARGET_MADV_WIPEONFORK: /* parisc */ + advice = MADV_WIPEONFORK; + break; + case TARGET_MADV_KEEPONFORK: /* parisc */ + advice = MADV_KEEPONFORK; + break; + /* we do not care about the other MADV_xxx values yet */ + } + /* - * A straight passthrough may not be safe because qemu sometimes turns - * private file-backed mappings into anonymous mappings. + * Most advice values are hints, so ignoring and returning success is ok. + * + * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and + * MADV_KEEPONFORK are not hints and need to be emulated. * - * This is a hint, so ignoring and returning success is ok. + * A straight passthrough for those may not be safe because qemu sometimes + * turns private file-backed mappings into anonymous mappings. + * can_passthrough_madvise() helps to check if a passthrough is possible by + * comparing mappings that are known to have the same semantics in the host + * and the guest. In this case passthrough is safe. * - * This breaks MADV_DONTNEED, completely implementing which is quite - * complicated. However, there is one low-hanging fruit: mappings that are - * known to have the same semantics in the host and the guest. In this case - * passthrough is safe, so do it. + * We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and + * return failure if not. + * + * MADV_DONTNEED is passed through as well, if possible. + * If passthrough isn't possible, we nevertheless (wrongly!) return + * success, which is broken but some userspace programs fail to work + * otherwise. Completely implementing such emulation is quite complicated + * though. */ mmap_lock(); - if (advice == TARGET_MADV_DONTNEED && - can_passthrough_madv_dontneed(start, end)) { - ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED)); - if (ret == 0) { - page_reset_target_data(start, start + len); + switch (advice) { + case MADV_WIPEONFORK: + case MADV_KEEPONFORK: + ret = -EINVAL; + /* fall through */ + case MADV_DONTNEED: + if (can_passthrough_madvise(start, end)) { + ret = get_errno(madvise(g2h_untagged(start), len, advice)); + if ((advice == MADV_DONTNEED) && (ret == 0)) { + page_reset_target_data(start, start + len); + } } } mmap_unlock();