From patchwork Mon Aug 27 08:40:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Hausmann X-Patchwork-Id: 10576637 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C293A139B for ; Mon, 27 Aug 2018 08:42:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE66F296BF for ; Mon, 27 Aug 2018 08:42:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A142B296CD; Mon, 27 Aug 2018 08:42:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6BB84296BF for ; Mon, 27 Aug 2018 08:42:15 +0000 (UTC) Received: from localhost ([::1]:52002 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fuD6E-0000V2-Js for patchwork-qemu-devel@patchwork.kernel.org; Mon, 27 Aug 2018 04:42:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53874) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fuD5Z-0008Mx-Vh for qemu-devel@nongnu.org; Mon, 27 Aug 2018 04:41:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fuD5W-0003fi-GM for qemu-devel@nongnu.org; Mon, 27 Aug 2018 04:41:33 -0400 Received: from mail-db5eur03on0716.outbound.protection.outlook.com ([2a01:111:f400:fe0a::716]:52208 helo=EUR03-DB5-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fuD5W-0003dJ-0B for qemu-devel@nongnu.org; Mon, 27 Aug 2018 04:41:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qtcompany.onmicrosoft.com; s=selector1-qt-io; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=livitL2pagcAuRRddSQxsHfQrvKopy/WxBItMSYpjTc=; b=jEQYZaxGaKkyCxNfjCZU6+CPK0GDX2J3Mc1930rlHsw+IbObHUinlSfLeJUuducWFDEt5Iv8OQdNUpnw2cTWhmMxjq9gL/5fPdhWYxXBAC3Q44t1FgSYeBH6aU8zrpeqKeEZCWuzHjsp+3QL8nVfuPAG4oOCwCB464pQX9Z6ZuA= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Simon.Hausmann@qt.io; Received: from effent.intra.qt.io (109.192.210.216) by HE1PR0202MB2827.eurprd02.prod.outlook.com (2603:10a6:3:ea::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1080.17; Mon, 27 Aug 2018 08:41:25 +0000 From: Simon Hausmann To: qemu-devel@nongnu.org Date: Mon, 27 Aug 2018 10:40:37 +0200 Message-Id: <20180827084037.25316-1-simon.hausmann@qt.io> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 X-Originating-IP: [109.192.210.216] X-ClientProxiedBy: AM5PR0602CA0018.eurprd06.prod.outlook.com (2603:10a6:203:a3::28) To HE1PR0202MB2827.eurprd02.prod.outlook.com (2603:10a6:3:ea::16) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4d957284-7e0d-4a23-8391-08d60bf8dfcd X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:HE1PR0202MB2827; X-Microsoft-Exchange-Diagnostics: 1; HE1PR0202MB2827; 3:ycvYd4p3mlUKwoFsjVSZVk6AiPXG07198vLZy+60q59D1t35u29zLaRH7527J1TdGZenCVnsRx1sEJL4qU7gPd7RFW2Yk+CHiogNfKLKj7ILir9Wzh2cubWzrdw1bUeiP1VkJ3cyH/0omLS/90tSfF8V8Cuq2HokMxwjgeFEMdH5gL34YFOy2FqVOwYZhYBJ/PuXADP4ZDAB3DCzMAFo7ytgGu8SuIe3l5cK3nlgBBMS79u7P+PZA3D4/YvmdUgv; 25:TFHOaabCV6rAw4k1x2mYZkEnSwGhokhiONZ/jlmMuLYyN6We5Jyh+USycipv5JG6g/K0QvvgkbedaTnhysnHlIA/C5VdC6wajqTRwmpcTYDERP521rwZEw0Rj9fJ1MWGQzE5svKyOT7fSKkDodm9jCIdWN/ZpT3lyOJuqrw93uL//pnkXVjLmMbQT1BnFmM8w5P4tHTOiaFK0cKrBQoRxiNoaHq/3NM4xHRxc4/yyNZh3Hsr2DmdC7H8itssqb4VxF+2wnwxFg8CqxET7yrTW9VPWiEZszxUtqtC0chVoXyJCE7SvfItMqJowRvhuaxqJ05Jx2DuebzqR1VHqUnYIA==; 31:JIeuObYV7wU1z/XvKkucClhI2Atc9+6zBPtyx6+nPo0Kee7kUJAUIXyDABDrHPaPs9nz1mQNMufu5o0gnJajjrIkjLFbzo2TD3ybCwJCT/76U2PU4YZGyofTWPIS8ivyDbIRindZiyH1Pi4uWiQXUA0t4L4G4YEXhOsxKqpVIxR9Syh84JVL9kmmcxovtd7QLnS+LfIcyl0mgHCcFxjXXsuM4uRYYGBlqPz0qWIWV7c= X-MS-TrafficTypeDiagnostic: HE1PR0202MB2827: X-Microsoft-Exchange-Diagnostics: 1; HE1PR0202MB2827; 20:Kji87MY6b5sn0u7m064P9cZjv/Tu9XE45PCr7USwiFu4zCEwrPTfDt8IZjwVbSZIIF5wnUqufGD2b37p0Px7YDNfDkQkU6zNZLwQODQ0gIzdsWqJekkw3et5YHg/GuALHganQnuSKXDJHaK3vRhtAPj5JqkzULExAzzklsE9jqh2uJH7r+/moUangP9twU5b+eHymcOkvmcah8R7ywe88vaLVsO95OQul4S7oGxW5RuE8czQkq5llA3KYpo2wZEX47g2fQwV8kWFdh9KLGfqP+EYFOkcEouS0oeqAwIHfp78as0LkS/FpR+A1rzVsn4vvrHht13y4o+LVbcNLWRTA+gkgMndFtnAz6QHCbuJEdk6DkpKQ/OluC7XoEJcKBYBZMPVw7SpUaCgYGQJ3Kke4JIIb7LFtN2al+H8m10oGELRwTG0oz0tJ6Qm1g9lpZdoLYe9qbkd/3FfFEMoDdLtDyOIb4MdA0mp4jAZHFTPzy9ZhL/v5VHUFewE1ybv+FKZ; 4:2BxdSp4rMq7hrvtSitsEabKuBn1UnGL+qLpPs1sxrigiNaQ4EHP+wzdnnF+Cy6cb6+AeDk8t746N8GU55Fkz5e3CpiJ2M8EJN+TF3WGz4hJ1UEPBMweMarHzxUSKaAal0/yOJ2KEUV0XJ8dR/2IZmgPc4tO87vEDyIFt5QkFz+Z/fu8KogPPhsC5xo3Ceaw10WIdusfNGz+/+LYmF13prGgPmoqTRMdzaJgXS2hD07Kpk8iHpQCAhMMguea8raEH3S/Dtntdn94WBUvYUlmazsqbK10wXSIAuOvEcyMM3j8V/kKgEVTFXgmvJ8ygGbng X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(8121501046)(5005006)(3002001)(93006095)(93001095)(10201501046)(3231311)(944501410)(52105095)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699016); SRVR:HE1PR0202MB2827; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0202MB2827; X-Forefront-PRVS: 07778E4001 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39840400004)(376002)(366004)(136003)(346002)(199004)(189003)(956004)(2906002)(44832011)(52116002)(51416003)(74482002)(7696005)(106356001)(53936002)(53416004)(36756003)(33896004)(486006)(316002)(186003)(6486002)(14444005)(97736004)(2351001)(476003)(2616005)(105586002)(86362001)(48376002)(81166006)(72206003)(8936002)(26005)(8676002)(6116002)(69596002)(81156014)(5660300001)(16526019)(50466002)(25786009)(54906003)(575784001)(386003)(16586007)(3846002)(2361001)(68736007)(1076002)(478600001)(50226002)(305945005)(4326008)(66066001)(47776003)(7736002)(6916009)(6666003); DIR:OUT; SFP:1102; SCL:1; SRVR:HE1PR0202MB2827; H:effent.intra.qt.io; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: qt.io does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HE1PR0202MB2827; 23:iTBffhEEko5VyWomfqCFE2Z8IT3fpEmeTaKiVIT?= 9tBjlimr9tmJQwI05VPu7u1F/k59Bg+JgC1qfnBhSXhNYTg1FtwUYHsK01yzvuHNpZe91o6XrhaUjLQJdz0dfESXaQNRutXzqlAIU6CKa+TPG5zUhRoOeKXnslj+OKAL4BFp6q7dyfuUTqwAXrIcm6APD7mX+SaGqCgK6ayugbakl8kFJHmaxsxzApayxV/wosQDqc6VfUFW0xWe/i+VSeinx2ZexI7nZwlQ5uItNRcuTYde34ogUIRVRZj549PhQTO9hsv6vTmHhVlcomVsFhAPqtTv7yK5K4cUhCRs3oNJT11Q0OTm926P1t5XPRLX6vimTIU6KQBeJAUvAKP97lhmTCPS2Pz1Sfzo7b+ifycbNwu6vT4HxAvup4A1JflqT1nBLHu5klpCXcQ7GETJ3DuCz6h08RTTeItmx5d24imUNsnN/+2Eq8aYQ0vxeXqAKFNfiBan+YWaldT6MZoveT9VSgZnd80kqjQOi9X0WoemZbdwuHz0X2wWI4Rtn6gRADHT+B3JlA8sitRRYunJ/xrfazYEKtMUipnhfzcdJrhc5+7Gbl9DGFJ88UXqdqIoJd6oO26cXb36Q6pz4oQx942HaZ712RVxXS8hCah/T9ygFaGXWui1PhV93XHb1PTogtsGQ8JRPY+HQM1Xp7lT4rGncUhHQpVcNLurVx4zvwiL859AG3FQmITwXvmEry1N+0jOyeI7RuiRY/v4oYJPQzOt5mYwzkgokFxINrxrKx27LUJGotCW4K9uEGrv0EaOli+A4n9Fo0AGEN2Z6/ggvArFiaFSQiezx/1Dx2ekO//Be7eiAzLaMoIE3wOb7wlsqBdnc0k7sHGcZAQ7xciqsOndEc53NCJrC2B+AGc9Td71C+sPIxeQvDzD5OLU4DOaKJdbfiV5q3NJpQK4yxs9DPtXLrS0Esd4i6HMxresdd6Vdln8INtNZbRaKOajMAEiRi+8RV2v2PcaRF7s2VJmT2Ec92aOPs1GyxRW4to32PSxOYamP/T41J6PllHn7g1wzyS0BHNE5bqjXnFJ9pGioW4rIuASvuF5J/2qo8eefVYw/Wt6hOEWGzHYpVIFqYJBYogIQ8e/Pb9Sj0LrVhYf1MhyYk9iTOUhbbaYudLrQF3iKjwTMFYEcQD2EbcoOVjW+TYYktFfpLW5uE7a/4obgYajSagtYiY2XGoGsxnovoe57uAM7ILmChWA9SHcLc+yu6qzrTQmvgfIrVzymnBcMVfUGxCpJAu9BLbxszkWZAAMYKQ5EkawEW5JBruSEwjOPurI+Q3wQQm/IR5fu4ka7Xb5y X-Microsoft-Antispam-Message-Info: MQ7ax4GUXHPTntDgZNoZjKgJAkEV6dJ08mtN7aUMG1rH/rd9BdbGy4hqRY/8RxoUAcRO2K1I05Fis5TuzbSgEfYSU+SxjDUPxNXMiZRksvxwEg8cD34ui/k4tB9V5ZeGkYnXj1sZd2rVgJOb5dj5tAWecU5Iy4EQAtOrnTkeOY/nckhgyxCHd8bWf1Fj38fiUgy0vTPNAG8IERyFguBQUSyRKtEEcOQDVk7xSlrP72XwODBtgHwir9ZX4iwVUxij5xGj8vOkY0lQ7BPMxYQzJ/xzxuRRU0iP2hY13XSVEvO2fRtpKWDSu6Q3WRVuOPXZICsH0yxO8ZCbRLb4mvWnCODqQdmvK0E9xvgVoDi9kvY= X-Microsoft-Exchange-Diagnostics: 1; HE1PR0202MB2827; 6:l2S3uBWqgYnXWsxYM9sIsOQzFYxphttoWO2zVzj+i8oWZoFbeMIVcLPyBL3fCQ3EOwvGV54C+YikJ7t1NoqTvM5A31QYU6+OGvMflGvHBlLEt0mYfzmM0+qAJqLfdZELlxn7ujk3XlYf5eo+r5aLgEz/u6ny3ImJnLCRalS8yRVEaXq3VhLMIFGGntqIwjyjxcmqF7CixqfzHB8ZxKUi/YrQNXlQCAMzaRy0kqgGGx9g6aSjOY3If3HFRigggGV1NEmfyZ+U0LcQuXaXg2EccJhYRlBU5FxjgNeWYsAQHLwDU73v00mEohDk2pFJAZEWX2KYt0fxnLZUYEBG2brW/03dP7CPFegL0SZj46qtVaMhba3kMJHqvNSGYDvc8ySMCDIJ8SMiVJ+menIVLQacyV1YctnvxaCh/Z0M3alc2wD65xev0kafnZY8i9MKyjYGYlDRW9ntDRm7lL8XyDTwBA==; 5:vjLgTHilKVJgOBwBqouFvMs93NUBsHg7M0hva1dUS9TSosLcdD1pAvveDzw7I+UDge6Y/WuCIUrmXdI6NuaYZbDef9idL7OphEM7aACxHqbREBE52R++xW9p7pRJDhwwhwiTthpALOJoyyKuHB5a3/TlOiK7SJ782VMiekr4Zp0=; 7:cDKgnqSB4tPk5P4TgYmBOEtn1k/7abs9EDNiteMrLIht7Hvr/FbwXCdNWwdxKMkSJt6zVGX8y0mqcD7AIIqzTPhxxBAjz0kF4aO+e/lNbcbk6UP6se5kt5HzXy78TUbuU2HXCOznbZAOSqY4TyPE6j0ygHB3RrfHk4i57tbVTT/NjgtBRYwcZBdErfWTfRN/bo+wCa9AEVcX9sfMw98RufNpfZDda50KYX4DtTWi8xyY5/jCK6PooqHoV/au9Q6e SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: qt.io X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Aug 2018 08:41:25.0023 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4d957284-7e0d-4a23-8391-08d60bf8dfcd X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 20d0b167-794d-448a-9d01-aaeccc1124ac X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0202MB2827 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe0a::716 Subject: [Qemu-devel] [PATCH v3] linux-user: add support for MADV_DONTNEED 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: Sami Nurmenniemi , Riku Voipio , Simon Hausmann , Laurent Vivier Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Most flags to madvise() are just hints, so typically ignoring the syscall and returning okay is fine. However applications exist that do rely on MADV_DONTNEED behavior to guarantee that upon subsequent access the mapping is refreshed from the backing file or zero for anonymous mappings. The file backed mappings this is tricky - hence the original comment - but for anonymous mappings it is safe to forward. We just need to remember which those mappings are, which is now stored in the flags. Cc: Riku Voipio Cc: Laurent Vivier Cc: Sami Nurmenniemi Signed-off-by: Simon Hausmann --- v2: - align start and len on host page size v3: - align start and len to target page size as it may be bigger than host - use immediate return in do_syscall - forward MADV_DONTNEED advice only for anonymously mapped pages - remember which mappings are anonymous in the page flags and preserve those bits across mprotect calls. --- accel/tcg/translate-all.c | 8 +++++-- bsd-user/mmap.c | 8 +++---- include/exec/cpu-all.h | 11 ++++++++- linux-user/elfload.c | 3 ++- linux-user/mmap.c | 49 +++++++++++++++++++++++++++++++++++---- linux-user/qemu.h | 1 + linux-user/syscall.c | 12 ++++------ 7 files changed, 72 insertions(+), 20 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 898c3bb3d1..467fbd9aeb 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -2481,7 +2481,8 @@ int page_get_flags(target_ulong address) /* Modify the flags of a page and invalidate the code if necessary. The flag PAGE_WRITE_ORG is positioned automatically depending on PAGE_WRITE. The mmap_lock should already be held. */ -void page_set_flags(target_ulong start, target_ulong end, int flags) +void page_set_flags(target_ulong start, target_ulong end, int flags, + enum page_set_flags_mode mode) { target_ulong addr, len; @@ -2513,7 +2514,10 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) p->first_tb) { tb_invalidate_phys_page(addr, 0); } - p->flags = flags; + if (mode == PAGE_SET_ALL_FLAGS) + p->flags = flags; + else /* PAGE_SET_PROTECTION */ + p->flags |= (p->flags & ~(PAGE_BITS - 1)) | (flags & PAGE_BITS); } } diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 17f4cd80aa..4bfac81af4 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -125,7 +125,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) if (ret != 0) goto error; } - page_set_flags(start, start + len, prot | PAGE_VALID); + page_set_flags(start, start + len, prot, PAGE_SET_PROTECTION); mmap_unlock(); return 0; error: @@ -214,7 +214,7 @@ static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) to mmap. */ page_set_flags(last_brk & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(new_brk), - PAGE_RESERVED); + PAGE_RESERVED, PAGE_SET_ALL_FLAGS); } last_brk = new_brk; @@ -397,7 +397,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } } the_end1: - page_set_flags(start, start + len, prot | PAGE_VALID); + page_set_flags(start, start + len, prot | PAGE_VALID, PAGE_SET_ALL_FLAGS); the_end: #ifdef DEBUG_MMAP printf("ret=0x" TARGET_FMT_lx "\n", start); @@ -460,7 +460,7 @@ int target_munmap(abi_ulong start, abi_ulong len) } if (ret == 0) - page_set_flags(start, start + len, 0); + page_set_flags(start, start + len, 0, PAGE_SET_ALL_FLAGS); mmap_unlock(); return ret; } diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 117d2fbbca..100388dcd4 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -249,6 +249,9 @@ extern intptr_t qemu_host_page_mask; /* FIXME: Code that sets/uses this is broken and needs to go away. */ #define PAGE_RESERVED 0x0020 #endif +#if defined(CONFIG_LINUX) && defined(CONFIG_USER_ONLY) +#define PAGE_MAP_ANONYMOUS 0x0080 +#endif #if defined(CONFIG_USER_ONLY) void page_dump(FILE *f); @@ -257,8 +260,14 @@ typedef int (*walk_memory_regions_fn)(void *, target_ulong, target_ulong, unsigned long); int walk_memory_regions(void *, walk_memory_regions_fn); +enum page_set_flags_mode { + PAGE_SET_ALL_FLAGS, + PAGE_SET_PROTECTION +}; + int page_get_flags(target_ulong address); -void page_set_flags(target_ulong start, target_ulong end, int flags); +void page_set_flags(target_ulong start, target_ulong end, int flags, + enum page_set_flags_mode); int page_check_range(target_ulong start, target_ulong len, int flags); #endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8638612aec..c59cf4359c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1702,7 +1702,8 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot) /* Ensure that the bss page(s) are valid */ if ((page_get_flags(last_bss-1) & prot) != prot) { - page_set_flags(elf_bss & TARGET_PAGE_MASK, last_bss, prot | PAGE_VALID); + page_set_flags(elf_bss & TARGET_PAGE_MASK, last_bss, prot, + PAGE_SET_PROTECTION); } if (host_start < host_map_start) { diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 41e0983ce8..fff29ee04b 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -124,7 +124,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) if (ret != 0) goto error; } - page_set_flags(start, start + len, prot | PAGE_VALID); + page_set_flags(start, start + len, prot, PAGE_SET_PROTECTION); mmap_unlock(); return 0; error: @@ -362,6 +362,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, int flags, int fd, abi_ulong offset) { abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; + int page_flags; mmap_lock(); #ifdef DEBUG_MMAP @@ -562,7 +563,11 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } } the_end1: - page_set_flags(start, start + len, prot | PAGE_VALID); + page_flags = prot | PAGE_VALID; + if (flags & MAP_ANONYMOUS) { + page_flags |= PAGE_MAP_ANONYMOUS; + } + page_set_flags(start, start + len, page_flags, PAGE_SET_ALL_FLAGS); the_end: #ifdef DEBUG_MMAP printf("ret=0x" TARGET_ABI_FMT_lx "\n", start); @@ -675,7 +680,7 @@ int target_munmap(abi_ulong start, abi_ulong len) } if (ret == 0) { - page_set_flags(start, start + len, 0); + page_set_flags(start, start + len, 0, PAGE_SET_ALL_FLAGS); tb_invalidate_phys_range(start, start + len); } mmap_unlock(); @@ -755,10 +760,44 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, } else { new_addr = h2g(host_addr); prot = page_get_flags(old_addr); - page_set_flags(old_addr, old_addr + old_size, 0); - page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); + page_set_flags(old_addr, old_addr + old_size, 0, + PAGE_SET_ALL_FLAGS); + page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID, + PAGE_SET_ALL_FLAGS); } tb_invalidate_phys_range(new_addr, new_addr + new_size); mmap_unlock(); return new_addr; } + +int target_madvise(abi_ulong start, abi_ulong len, int advice) +{ + abi_ulong end, addr; + int ret; + + len = TARGET_PAGE_ALIGN(len); + start &= TARGET_PAGE_MASK; + + if (!guest_range_valid(start, len)) { + errno = EINVAL; + return -1; + } + + /* A straight passthrough may not be safe because qemu sometimes + turns private file-backed mappings into anonymous mappings. + Most flags are hints so we ignore them. + One exception is made for MADV_DONTNEED on anonymous mappings, + that applications may rely on to zero out pages. */ + if (advice & MADV_DONTNEED) { + end = start + len; + for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) { + if (page_get_flags(addr) & PAGE_MAP_ANONYMOUS) { + ret = madvise(g2h(addr), TARGET_PAGE_SIZE, MADV_DONTNEED); + if (ret != 0) { + return ret; + } + } + } + } + return 0; +} diff --git a/linux-user/qemu.h b/linux-user/qemu.h index b4959e41c6..e5ac5e9c6a 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -437,6 +437,7 @@ int target_munmap(abi_ulong start, abi_ulong len); abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_size, unsigned long flags, abi_ulong new_addr); +int target_madvise(abi_ulong start, abi_ulong len, int advice); extern unsigned long last_brk; extern abi_ulong mmap_next_start; abi_ulong mmap_find_vma(abi_ulong, abi_ulong); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 850b72a0c7..4478de5fc8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5124,7 +5124,8 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env, page_set_flags(raddr, raddr + shm_info.shm_segsz, PAGE_VALID | PAGE_READ | - ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE)); + ((shmflg & SHM_RDONLY) ? 0 : PAGE_WRITE), + PAGE_SET_ALL_FLAGS); for (i = 0; i < N_SHM_REGIONS; i++) { if (!shm_regions[i].in_use) { @@ -5150,7 +5151,8 @@ static inline abi_long do_shmdt(abi_ulong shmaddr) for (i = 0; i < N_SHM_REGIONS; ++i) { if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { shm_regions[i].in_use = false; - page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0); + page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0, + PAGE_SET_ALL_FLAGS); break; } } @@ -11559,11 +11561,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_madvise case TARGET_NR_madvise: - /* A straight passthrough may not be safe because qemu sometimes - turns private file-backed mappings into anonymous mappings. - This will break MADV_DONTNEED. - This is a hint, so ignoring and returning success is ok. */ - return 0; + return get_errno(target_madvise(arg1, arg2, arg3)); #endif #if TARGET_ABI_BITS == 32 case TARGET_NR_fcntl64: