From patchwork Fri Mar 21 21:54:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 14026081 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C6C1C36008 for ; Fri, 21 Mar 2025 21:55:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 60D33280009; Fri, 21 Mar 2025 17:55:06 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5BF71280008; Fri, 21 Mar 2025 17:55:06 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 34DED280009; Fri, 21 Mar 2025 17:55:06 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 0ED53280008 for ; Fri, 21 Mar 2025 17:55:06 -0400 (EDT) Received: from smtpin30.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 8DF24B80C2 for ; Fri, 21 Mar 2025 21:55:07 +0000 (UTC) X-FDA: 83246914254.30.E098576 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by imf08.hostedemail.com (Postfix) with ESMTP id 3EDE816000A for ; Fri, 21 Mar 2025 21:55:04 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-11-20 header.b=EiP4urQ4; dkim=pass header.d=oracle.onmicrosoft.com header.s=selector2-oracle-onmicrosoft-com header.b="Rm/Q/J96"; arc=pass ("microsoft.com:s=arcselector10001:i=1"); dmarc=pass (policy=reject) header.from=oracle.com; spf=pass (imf08.hostedemail.com: domain of lorenzo.stoakes@oracle.com designates 205.220.177.32 as permitted sender) smtp.mailfrom=lorenzo.stoakes@oracle.com ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1742594104; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=R3VQ2JKT075yM5Mu8/gj6ahdUavobj6twKvRFNDdQMQ=; b=ueHBSPVotMvci+szWoSDc8hpB2fXf1oGin1GG0ptIsFtBpTkqwo9dL9f6wgP6bLrcDx2Dh hIG80yYppTALRoRAMco+QqstkMKWCFGAE+C7HVcSxjm+2cxrdcKv+sbw4G5wlv6cmQcOsN SULs8V60j2tzWL09vZiE7u8a8OlxR4E= ARC-Authentication-Results: i=2; imf08.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-11-20 header.b=EiP4urQ4; dkim=pass header.d=oracle.onmicrosoft.com header.s=selector2-oracle-onmicrosoft-com header.b="Rm/Q/J96"; arc=pass ("microsoft.com:s=arcselector10001:i=1"); dmarc=pass (policy=reject) header.from=oracle.com; spf=pass (imf08.hostedemail.com: domain of lorenzo.stoakes@oracle.com designates 205.220.177.32 as permitted sender) smtp.mailfrom=lorenzo.stoakes@oracle.com ARC-Seal: i=2; s=arc-20220608; d=hostedemail.com; t=1742594104; a=rsa-sha256; cv=pass; b=vC8V9Rjdiy1AEow5yf+c3zuvzjDG0TcemNMw+m3nmuqdN0+QcSav7lwJJryBgx/dpefN6F Z7Z6XzrCHabPjg6uxZkPOoAGNOOTnO/R/huoySg9BW269k85rR7CGbWBzaCmDLJDlFJw31 qXoPty0jnZ+OQXw+5b4Jy/EMy2iemuQ= Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52LKft0G021302; Fri, 21 Mar 2025 21:55:00 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=R3VQ2JKT075yM5Mu8/gj6ahdUavobj6twKvRFNDdQMQ=; b= EiP4urQ4ji/nvHR9OSshYivsMEsXLej90114NV9q0EjGY5HkeXgUdmBHGAp2oh2+ 85hqTjirH9OI4WjCeIbnn/UpQ+ufm6AXkac5srSb6rSAS0/qeWagmr2+Mf+tifOv fdJeQYuMyhXWlulAIriBJp2nsWcGc1f97faxjb9WlJRBXVsj7CSsHaYkIgNiyhie AtxIiO8E9mBNFwdB0aZZECI3r9DFypg/KWUZSEGHBQkx0Dwm2WcWn5KGZgDCKD+/ LZGOBy8k70jeVWv8CR1uHM8PVUNcLA0suZrDYjJba6Bqmh9zGcF1bj3mDsz6ecrI CaFkJRiDzAVqAzKyq/HCgQ== Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45d1n8sgb0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Mar 2025 21:55:00 +0000 (GMT) Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52LKZM4R022350; Fri, 21 Mar 2025 21:54:59 GMT Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2174.outbound.protection.outlook.com [104.47.57.174]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 45dxem9n0k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Mar 2025 21:54:59 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mHHgGA3t73IirT1GXWXC9x4ALCxR8p2lyzQrhqZJJP6VND2hmXDvQG0WtwbPyM1WBY7RntXWvvQ7z+bhAgD1s47kSNrt/MZjBCNsYq4SE4VL0IUxUQyoGc179bveWL7CZiU/eNX+lquisbmShMQdBBSx0ff8QN9WLIhGIUZrNSWNFZl5XRBpNIihapk6yisfH0ExttlNYFsjQAAv1yuDBMj2B8Nb8umnxYJMK+OCX6DiELwlbB4HJ4s6tHPFD+NZ9wCNs8eTS+82/28fxHFNcrItreH6KO7WmPwdZ1AeXvWc+AoGYy0W16hyLM2wEohbNdVQTIwwni/KZnTuKK24fA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=R3VQ2JKT075yM5Mu8/gj6ahdUavobj6twKvRFNDdQMQ=; b=AFSd+pJVod0P50B8uCS600AdkA14/gjdsXzBkhlJJBLFfoyG7bz3wjGhG03HnNp7PzAi+ofiNYVsa+uCzNGrWdCuotR0qoGWV122AeIyH/3kPVEKUWioyToA5OJca6QWbyp52jDcQf3uW4CNhlnlCvbtLf+7oyYs83XPY23nUe4YgLQonU1xyM+D9OazcmGQV9y6+cQL5nuidvbnaNhg/qGf6sbl4W7ANvVBfjw9/MjKaHtSadqM4Yiei6jfKlX0Zpi+0atG1wN0MzEiJ0KJ6Lmt6QQlCmJdcZUYvTjuF81hiZl1q8iwGnA4V1N82yMX8bM/8MRszCR0rRB5EfBmxg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=R3VQ2JKT075yM5Mu8/gj6ahdUavobj6twKvRFNDdQMQ=; b=Rm/Q/J96gxfCfeC13e4E+akdDEgnS9PY+Afdt9ei8wXK37+K1YzWlM3Md+CvjPtrIuS97ZXHzQchFXB8RXLX+S3mnkyS0xXUtVVgBi7X3mUHyVhlczaNXTdT5qziTZildJo5+ysh4gXbDN+yM5vjpPsSj/XxPz8wGaV1QP11i5M= Received: from DM4PR10MB8218.namprd10.prod.outlook.com (2603:10b6:8:1cc::16) by CY5PR10MB6144.namprd10.prod.outlook.com (2603:10b6:930:34::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8534.34; Fri, 21 Mar 2025 21:54:57 +0000 Received: from DM4PR10MB8218.namprd10.prod.outlook.com ([fe80::2650:55cf:2816:5f2]) by DM4PR10MB8218.namprd10.prod.outlook.com ([fe80::2650:55cf:2816:5f2%7]) with mapi id 15.20.8534.036; Fri, 21 Mar 2025 21:54:57 +0000 From: Lorenzo Stoakes To: Andrew Morton Cc: Vlastimil Babka , Jann Horn , "Liam R . Howlett" , Suren Baghdasaryan , Matthew Wilcox , David Hildenbrand , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 6/7] tools/testing/selftests: add MREMAP_RELOCATE_ANON merge test cases Date: Fri, 21 Mar 2025 21:54:35 +0000 Message-ID: <8b82838696e93d97161af4f62f9f01dc9981ec7f.1742478846.git.lorenzo.stoakes@oracle.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: X-ClientProxiedBy: LO2P265CA0296.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a5::20) To DM4PR10MB8218.namprd10.prod.outlook.com (2603:10b6:8:1cc::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM4PR10MB8218:EE_|CY5PR10MB6144:EE_ X-MS-Office365-Filtering-Correlation-Id: d82af179-a55f-4735-273f-08dd68c304ed X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|376014|1800799024; X-Microsoft-Antispam-Message-Info: cR7QUkOC5O12EGrlgvkCXn6lXhydVkAif5YKX9MKD2gu+E+gI3aRAifrgx1bwmaNqVlr2u/b2vxDrQSovrZcllncdXM/SQYv8ioWmbbiXpGxha/OwXUj6+MBe7LrO5kgaUmzJU3aQgRVPUgTrMZdzU7GxZNwc24W70icM3cCttkcfiFYySwOtTyDiHWd3z+0PhOpeoE5DsGhS+lw1VprTzqBN7nbbO0sbaM0nK50tOubZcU6DuTtmK/I3ZQLjGEHyMR9VSIsiz0GLqItmSutNC2iLpDul0l3aumsMBdlSl6wE1N02nTfLCjFUongtnpieJdkFMHGdM2gmh9nyiYcN5ogVAKzzclQ7vPu5aTo4Xey0Cxs8q2TtrguHkSGJUBDiOW73GcnwjpjlmE8GgHjKX6FIlERs+QwFQo39Ei9xKlhGPBCx7OrBNfpHjkU8Iv/fzYHE1Lzb0KPlndpzAOYJzii6+0PthntzEn5kF7cHUsGc8vyhVfMZDnzp67WqHzAbuZplRriVXL6ORAOLWaDpoVx9rzU0+SLYLvdCCSjPvivez2b+Kvpz0H9g55rD6OP+3OT6rEqEuZOAlqvWUDC/NaRO7C9H6fFhL8SJ9fNfblklUzUnx/s64Wt0bVkHYKmWvzVd0GnjKZAvWuwRdsjCqKeGJBkeYmUK2Ca9jsvGvCt9OYO8Qe+4RGFYm2aH/XGtZSoCnMgxptdpMwKcrC7rY079oFAr2lgxbjWUkNhHJAYamFFRk2mQSohGjOYGPEU7YMz9b25Jk/OY3BPnj+cCge1idckl+o70AzLbdbJwmZJsdnl+R998gZvXfUZ2N72nZvQV0Q4PyRHrUeUqhCgbgLU6vpZEIb/PsPk0mfe5/e7PnMYe9JRp4kjAOvPaxCLDOcib/QNHHFh5x3RikQE6mVIJ/NUbug0SwRIQRCFsT6KRsrkjnU6mdhXBjEp5pSiATMOqAYDGbGBbimaruUQZV0WNDCjpqLVd9JBoGWlQyfbjzzbYanr/Bi4Z2PZ2ERxL9PVzMPkuaoTQZqOGm0U7mLOz2ZGDMsnuFIajvwUUmEjTp+Hphj40P86EdyY8kCIQr6BZwN/CbWAVDRaVo0zNYxEobKuGson+LS/kin0k27s4S1B+4J5V75m9jkMAy0XyyUFzKnkIDF961j76um36dZSzV7mrPy1vctbFLNOXXDTDAC6oF570GYBlDgve8VB6hYItScaCXlcyyp43ZyOpm6Hv02XW661n9P/Ho/EW1m4z//kyCva301Hs+CZnCCo/vR2TYos0C5hoDWf4NFuQzxX6nrTCmVuQBWNjHTtEpksjV91DMT3fPaUnGJkAdZBtN4YHp9CRjumt9R5Mtp7F9TCel3v7/bUGEeLEkOjQS0nkbN7Eyv8FJNSw8kvRAQ5 X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM4PR10MB8218.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Ox2Ak00aE9SCo5vqyV5nHHMsQm5XIQCQF4AN8BN0u7zddr8QI0QJ0th78MJGAhpF5fjJwkPhZcHG57tAwJuz8LLqRgbjy3xpMiF4AMx1cqhRQc9HHpQIab55fqYRDj4TVyE/25eV9SuFoHmLZ+sQ3aANyKxKYcz3yHojWhWsiUuhiyQGGYTECXx475Jm5v41SlmsrvCaBcmdt2DxYkT+B3PIvW45DBJeupd6lg6woTEjVcP30IZwxGOb8PCYMxVPkR2N7lpD6cznPzq19T/ud9k6Q/BFUcVQw8MAJY2GJ8QIoXOL9+uXBBCHQQ/6b7P8Dqkoa4dUOTlAYWcTJ1E70oCDLeCsVHmKu/kX/SRztGU3CgUSniirkbJDOe9gSvIQgyIaYgHaep1YmvK2TyPe34s9dWSmB2sI7T0ju8TN8+60Yo80RyQZCoM58Q0VEhURS/w+y8xBYY2ThxYEgFd3WkS9tYTGxPZj15Lxf6TW3NH03DLWLcuozFj/75z0C3g29/TxF85njDC9+Fm+IWO3uV4i+9KrNzPC1U1Q0WuLU4IwLNd/aVNoWM9/cHS4n+4in3ZGHXQZYwUg4vSuLR4TkV1e47UpRGt9jt2yEvDk/IllHHRynxYt+pEhfBIQLCKo7GDCAaIL4rb9bKJEnFLPJFK3yJdYSRnv4oYVN8pfZf6TUgUZWXw2JJKoj1pUvHx0WU05KoWX/u+inSfjWvctJ6L0O6yRDvY4hQ+n8FzazOw+Ut2iiotDCSz5ZSuF9bvDM4CxmWxqfrSWUypHOULsaYP0opb32nIxNM04qZoGIS1dL4Bdw/T/gKXMdF4d3SQtVakVHNFzHDJNvoj984SeEBpkyejDiuYpk+L/TTA0lL43BNUBqDNIVS1nEBLj4K5TgEzQjmvKhbHWEyhnN5DuDYpmyA2ykWNHsZnoxA+CNMlFTCCYewkwp+chZOhWsrUqsfp2DIV45u6fn9i7iQrAv5wjzjFhqKP82kHz3nN9IIpFYPr+oyBwADCjyv1kPrlhw8Thc4e4dfcRlw34ehciyMYSCtKHrYsYzQ6/7tw1HE6NIHuYBiz6RfyuavFZC3mRpYn2LjkUgexGUxlpdO9VVOhUw+HUq17qpH+DolhXxmZEQm0iAk1ySmSsG67txpHOlTrqMVuO8cFtC92TEmN8+tIi5TlcmAzPA8NF5p4dBM9vmn6lFKqv0OMppEh3Oz8LmtunF+rv/QaXyFcJz7d/rtQmwPilWLQYF8jURULJIsTXHLvYpGKKLd0ikSfKMM45RRPOeBGU9YnViOsJs2yG2xvep1/u9IK5Nq3nrvuu7S9nkf3mAX4zpwCFX77OP3QxwtlsvUyTex9/meVk0ZNS6Z8UYcEFaIZ8hynKU9hkCnLKslzrv2Bmt3wnDoQPHAIOEc2OXWcbWTlaYyOZjVfrh3NB+/VH2GtBPaG7ifhfKQNVDiyQJTRRH4IyXdYbp2Fivw5+6YOZK6J4nD5v5gCnmaorcbtLk5Ija2f5cPGVZDMldqZrVGcNle9Ag7ENXa+t7C0LKFUl7hU+riAX/V98NGICqyPTd7kWHzmR3lQktPrphzk+fF6PbA/a4O+YFKuNcdkA8X36EV4HKF300U3fWQ== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: AWhWbLDdoZ4+c4BEgK+qTzSfwTS1RUOUHcv/T2FZQsPhSq6ANuc21RuRVZNPad5pFbJW2lXfO3HnFyoLSE3PfIkLNYcEfjVWDEmmNNtuazsJqR9x4KaG8dATqfMmA65bt/spHMQRfKaJwizNcBudQZ59+n1hN+XdNu/WCqsObkmybXjLGHedmxbMQE1Ejt4hww8jG/aegB+ccZF++HllGWiiXed5+AURjKUKHR35dDYDCGYKudxN2O/vFjqxUybj4+YoGvg+xSDkFjzMEmv2BsAMgNkcewnBFavbn6Re3C635jlnX98giG7xfEPFoeSlY1OvhsE/Am+vXbjTxKgaWaAJcexdNRJ6U1XRpwhR8+cFAUTZwgagefwCZ+Arae+deT8VlcZUyUqINEaDIJ/QqtBSEmRpiq0FuVZRl9642Log+p0JgDUQ1iSzNiAtCvKAA6Jw37ISSkhcWObewqOAKpYkuPw5PsT82gxUyAFNL1iuTkLJuh2y4UWPyyKT4uKWbi/CFv4rSCVMDU8b6fJLwa9+H+eC6xbS+azzOPYPL8eKX1UxZ9fCFcs6JRk12wI/YljLaB+uZFgXBbsblbrqjT11h+XdDnCvTKtKnTtKRsM= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: d82af179-a55f-4735-273f-08dd68c304ed X-MS-Exchange-CrossTenant-AuthSource: DM4PR10MB8218.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Mar 2025 21:54:56.9252 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: di4QFTdiJApTXj8Ct0I0E1v5LpGRVxPA2GOR35F4F7rsiRmi2xsjWWVeW0CroCIZxP8ivDTnH7Xw3pdKkYp5YeVtqAo46KL3P3DdaBKAbYU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR10MB6144 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-21_07,2025-03-21_01,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 phishscore=0 mlxscore=0 adultscore=0 mlxlogscore=999 spamscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503210160 X-Proofpoint-ORIG-GUID: kUoJPsbaZm0xmfxgQN2jzPH2HhbEZvQi X-Proofpoint-GUID: kUoJPsbaZm0xmfxgQN2jzPH2HhbEZvQi X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: 3EDE816000A X-Stat-Signature: xuifxrqbbf5r6zpdsf4x488tchd1rcmp X-Rspam-User: X-HE-Tag: 1742594104-889137 X-HE-Meta: U2FsdGVkX18L6TeF7h6ywoM6igYrV+YsLwYPbnnTZWMPh2wqQFx516GxDP3dvo5uOSA9pdnKxW4mnpHm3J0qX+rGV++BHe5bS79kVzHWLAOwj6W6W91bjUgQkJbkPrxz8koRN4adVSWn9AhJMnuB1XIB7uuRn4LoqDdxiJMcgcR3FfYWzjoqZaT8jB8orp5eHMJzgfh6sXjCY0Cchoi4E/uik6qNucKYMBDy87bZjiZJZeVe+8pe3mRrhFOBB7xi99vClteH7v57SK8WKxnkR7zdV/G/vh4YyxVhmVEIGkZ8puesIcbaA27TlwkvsRt1gaCwMFbn9q1JSg77s1ATseAi5Xitf8jbRgi7qfKAHt2wMrhMzymRZE6ko8fX7pPItfUTeK1ZOGnJzNGjVUg2B7wsQHFH/UJDriJGZ/rOZw0wCdueVw3EMOblSugXSAfOQCy3UljeXXh+ttA5XmuFYgFP6UQ1Kq6aLMNUG4oQe7+PhGwjt8wl+BtWeWoEMv/gBq5eeC3QMO0aM4mIY3HEnlWlYWELk76rJAIuSslHpOMikulZQ4R0h85iOIGS+lKxzbSEHpKGCTb+6iqtbj+i2GSViEJFijWcksRM2wEGUE/YcNGEwd6S2YLEh7ENiE0RzlrWa2b0K38TbwvPdtIazrpdAZJNB5HQjNGRCzZ7FMekMlAUDZunMNfQXavRiar1AAi93S52g9kQ4tmIPM0fQPsjYNDPnK6Tqe86RUWYrE4nsp536HkbGljR2mf+XAmuO6wg1fhkgm7I9QU0QHhbi/Wwc8bwxYmFpcjRpBIQ6Ie+n74wwlSzGfc0YekOCUgrKAgbIkY3CwY+SAZARZBF3mdjxLe/l6CD9M+ozZep6Bo2iorn1lYCuoLaZj/bhton0JpcGrvj+9i86yUfcu3dBxTtzMNVycQ8y9LVZPDemwe40T1tM3VHax40YFFOv1K5aF83dcHvn7lhHnaA0M8 VYexr1go d74i8vwvrx6EKYtgPj2X39/XvNHVLenawHXWxfp5ec5XqA2a9Ttz5xQ40pKnSzqM6M+PU8VnCZaXdLfc5iL+uuvLVGsjiLasXdmfau76dSqVqo16615vhp5D0yuFUL/ivPuZPdNLdi/OepxI/gUlmTPRau8+cy+oKKF9D51SswA2lILS5lZ49iEjQuDOyJqtAPPolbdoTyMwQgNO5HHKjPzHKMLN30oIL8iN98ibHuoYTCAf2v6B2XV9PMZ6ethOLvYgxvN82Bextn15IgPHFfA20wlwDA1O1jAh+oW3QY99BCOCFpb+TdiquqfsBUuCqYs2JK6HsX+IZwXByC+Qn4hIUuU+F6bITR3TuOLYPLXOuwm+niV1ZD02LrRdqtGx5pTwQ68eGKYzrB6A3UF5lHJ/Wfw2miQTBESsye5YYFp//uZETLqleZrSOYFmeBIkEg0B0gfYpcuvXbtHfhY89eJCnmrLKYWHUkNBc60qptQ+ui4Ubsqsg6M/hvcF3JSVyMKaA7OkCK3+RVRGz0l06wIwqyQ530O+CNxilHbcs46X/TaP5ry1AhvSi4i0hlWzn6698ymjhlWjzbROumm4tUDW29h5jzTTolrWj6XRDgVT/02F1drk532Xow/9Qn4gcJhcbbkQ6zE1cFOAVWo/aoFHvOQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add test cases to the mm self test asserting that the merge cases which the newly introduced MREMAP[_MUST]_RELOCATE_ANON results in merges occurring as expected, which otherwise without it would not succeed. This extends the newly introduced VMA merge self tests for these cases and exhaustively attempts each merge case, asserting expected behaviour. We use the MREMAP_MUST_RELOCATE_ANON variant to ensure that, should the anon relocate fail, we observe an error, as quietly demoting the move to non-relocate anon would cause unusual test failures. We carefully document each case to make clear what we are testing. Signed-off-by: Lorenzo Stoakes --- tools/testing/selftests/mm/merge.c | 730 +++++++++++++++++++++++++++++ 1 file changed, 730 insertions(+) diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c index 7c4f3f93c30d..bd1b82665348 100644 --- a/tools/testing/selftests/mm/merge.c +++ b/tools/testing/selftests/mm/merge.c @@ -1055,4 +1055,734 @@ TEST_F(merge, mremap_correct_placed_faulted) ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size); } +TEST_F(merge, mremap_relocate_anon_faulted_after_unfaulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + /* + * Map two distinct areas: + * + * |-----------| |-----------| + * | unfaulted | | unfaulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Offset ptr2 further away. Note we don't have to use + * MREMAP_RELOCATE_ANON yet. + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault ptr2 in: + * \ + * |-----------| / |-----------| + * | unfaulted | \ | faulted | + * |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr2[0] = 'x'; + + /* + * Move ptr2 after ptr, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------| + * | unfaulted | faulted | + * |-----------|-----------| + * ptr ptr2 + * + * It should merge: + * + * |-----------------------| + * | faulted | + * |-----------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 10 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_before_unfaulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + /* + * Map two distinct areas: + * + * |-----------| |-----------| + * | unfaulted | | unfaulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr = mmap(&carveout[6 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[12 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Offset ptr2 further away. Note we don't have to use + * MREMAP_RELOCATE_ANON yet. + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault ptr2 in: + * \ + * |-----------| / |-----------| + * | unfaulted | \ | faulted | + * |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr2[0] = 'x'; + + /* + * Move ptr2 before ptr, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------| + * | faulted | unfaulted | + * |-----------|-----------| + * ptr2 ptr + * + * It should merge: + * + * |-----------------------| + * | faulted | + * |-----------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &carveout[page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr2)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr2); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 10 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_between_unfaulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2, *ptr3; + + /* + * Map three distinct areas: + * + * |-----------| |-----------| |-----------| + * | unfaulted | | unfaulted | | unfaulted | + * |-----------| |-----------| |-----------| + * ptr ptr2 ptr3 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = mmap(&carveout[14 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Offset ptr2 further away, and move ptr3 into position: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | unfaulted | \ | unfaulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr3 + page_size * 2000); + ASSERT_NE(ptr3, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, &ptr[10 * page_size]); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Fault in ptr2: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | unfaulted | \ | faulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2[0] = 'x'; + + /* + * Move ptr2 between ptr, ptr3, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------|-----------| + * | unfaulted | faulted | unfaulted | + * |-----------|-----------|-----------| + * + * It should merge: + * + * |-----------------------------------| + * | faulted | + * |-----------------------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_after_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + /* + * Map two distinct areas: + * + * |-----------| |-----------| + * | unfaulted | | unfaulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Offset ptr2 further away. Note we don't have to use + * MREMAP_RELOCATE_ANON yet. + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault ptr and ptr2 in: + * \ + * |-----------| / |-----------| + * | faulted | \ | faulted | + * |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr[0] = 'x'; + ptr2[0] = 'x'; + + /* + * Move ptr2 after ptr, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------| + * | faulted | faulted | + * |-----------|-----------| + * ptr ptr2 + * + * It should merge: + * + * |-----------------------| + * | faulted | + * |-----------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 10 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_before_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + /* + * Map two distinct areas: + * + * |-----------| |-----------| + * | unfaulted | | unfaulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr = mmap(&carveout[6 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[12 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Offset ptr2 further away. Note we don't have to use + * MREMAP_RELOCATE_ANON yet. + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault ptr, ptr2 in: + * \ + * |-----------| / |-----------| + * | faulted | \ | faulted | + * |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr[0] = 'x'; + ptr2[0] = 'x'; + + /* + * Move ptr2 before ptr, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------| + * | faulted | faulted | + * |-----------|-----------| + * ptr2 ptr + * + * It should merge: + * + * |-----------------------| + * | faulted | + * |-----------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &carveout[page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr2)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr2); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 10 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_between_faulted_unfaulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2, *ptr3; + + /* + * Map three distinct areas: + * + * |-----------| |-----------| |-----------| + * | unfaulted | | unfaulted | | unfaulted | + * |-----------| |-----------| |-----------| + * ptr ptr2 ptr3 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = mmap(&carveout[14 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Offset ptr2 further away, and move ptr3 into position: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | unfaulted | \ | unfaulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr3 + page_size * 2000); + ASSERT_NE(ptr3, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, &ptr[10 * page_size]); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Fault in ptr, ptr2: + * \ + * |-----------| |-----------| / |-----------| + * | faulted | | unfaulted | \ | faulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr[0] = 'x'; + ptr2[0] = 'x'; + + /* + * Move ptr2 between ptr, ptr3, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------|-----------| + * | faulted | faulted | unfaulted | + * |-----------|-----------|-----------| + * + * It should merge: + * + * |-----------------------------------| + * | faulted | + * |-----------------------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_between_unfaulted_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2, *ptr3; + + /* + * Map three distinct areas: + * + * |-----------| |-----------| |-----------| + * | unfaulted | | unfaulted | | unfaulted | + * |-----------| |-----------| |-----------| + * ptr ptr2 ptr3 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = mmap(&carveout[14 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Offset ptr2 further away, and move ptr3 into position: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | unfaulted | \ | unfaulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr3 + page_size * 2000); + ASSERT_NE(ptr3, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, &ptr[10 * page_size]); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Fault in ptr2, ptr3: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | faulted | \ | faulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2[0] = 'x'; + ptr3[0] = 'x'; + + /* + * Move ptr2 between ptr, ptr3, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------|-----------| + * | unfaulted | faulted | faulted | + * |-----------|-----------|-----------| + * + * It should merge: + * + * |-----------------------------------| + * | faulted | + * |-----------------------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_between_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2, *ptr3; + + /* + * Map three distinct areas: + * + * |-----------| |-----------| |-----------| + * | unfaulted | | unfaulted | | unfaulted | + * |-----------| |-----------| |-----------| + * ptr ptr2 ptr3 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[7 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = mmap(&carveout[14 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Offset ptr2 further away, and move ptr3 into position: + * \ + * |-----------| |-----------| / |-----------| + * | unfaulted | | unfaulted | \ | unfaulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr2 + page_size * 1000); + ASSERT_NE(ptr2, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ptr3 + page_size * 2000); + ASSERT_NE(ptr3, MAP_FAILED); + ptr3 = sys_mremap(ptr3, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED, &ptr[10 * page_size]); + ASSERT_NE(ptr3, MAP_FAILED); + + /* + * Fault in ptr, ptr2, ptr3: + * \ + * |-----------| |-----------| / |-----------| + * | faulted | | faulted | \ | faulted | + * |-----------| |-----------| / |-----------| + * ptr ptr3 \ ptr2 + */ + ptr[0] = 'x'; + ptr2[0] = 'x'; + ptr3[0] = 'x'; + + /* + * Move ptr2 between ptr, ptr3, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------|-----------| + * | faulted | faulted | faulted | + * |-----------|-----------|-----------| + * + * It should merge, but only the latter two VMAs: + * + * |-----------|-----------------------| + * | faulted | faulted | + * |-----------|-----------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr2)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr2); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 10 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_faulted_between_correctly_placed_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + /* + * Map one larger area: + * + * |-----------------------------------| + * | unfaulted | + * |-----------------------------------| + */ + ptr = mmap(&carveout[page_size], 15 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + + /* + * Fault in ptr: + * + * |-----------------------------------| + * | faulted | + * |-----------------------------------| + */ + ptr[0] = 'x'; + + /* + * Unmap middle: + * + * |-----------| |-----------| + * | faulted | | faulted | + * |-----------| |-----------| + * + * Now the faulted areas are compatible with each other (anon_vma the + * same, vma->vm_pgoff equal to virtual page offset). + */ + ASSERT_EQ(munmap(&ptr[5 * page_size], 5 * page_size), 0); + + /* + * Map a new area, ptr2: + * \ + * |-----------| |-----------| / |-----------| + * | faulted | | faulted | \ | unfaulted | + * |-----------| |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr2 = mmap(&carveout[20 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault it in: + * \ + * |-----------| |-----------| / |-----------| + * | faulted | | faulted | \ | faulted | + * |-----------| |-----------| / |-----------| + * ptr \ ptr2 + */ + ptr2[0] = 'x'; + + /* + * Finally, move ptr2 into place, using MREMAP_MUST_RELOCATE_ANON: + * + * |-----------|-----------|-----------| + * | faulted | faulted | faulted | + * |-----------|-----------|-----------| + * ptr ptr2 ptr3 + * + * It should merge: + * + * |-----------------------------------| + * | faulted | + * |-----------------------------------| + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size); +} + +TEST_F(merge, mremap_relocate_anon_mprotect_faulted_faulted) +{ + unsigned int page_size = self->page_size; + char *carveout = self->carveout; + struct procmap_fd *procmap = &self->procmap; + char *ptr, *ptr2; + + + /* + * Map two distinct areas: + * + * |-----------| |-----------| + * | unfaulted | | unfaulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr, MAP_FAILED); + ptr2 = mmap(&carveout[12 * page_size], 5 * page_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); + ASSERT_NE(ptr2, MAP_FAILED); + + /* + * Fault in ptr, ptr2, mprotect() ptr2 read-only: + * + * RW RO + * |-----------| |-----------| + * | faulted | | faulted | + * |-----------| |-----------| + * ptr ptr2 + */ + ptr[0] = 'x'; + ptr2[0] = 'x'; + ASSERT_EQ(mprotect(ptr2, 5 * page_size, PROT_READ), 0); + + /* + * Move ptr2 next to ptr: + * + * RW RO + * |-----------|-----------| + * | faulted | faulted | + * |-----------|-----------| + * ptr ptr2 + */ + ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size, + MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_MUST_RELOCATE_ANON, + &ptr[5 * page_size]); + ASSERT_NE(ptr2, MAP_FAILED); + + /* No merge should happen. */ + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 5 * page_size); + + /* + * Now mremap ptr2 RW: + * + * RW RW + * |-----------|-----------| + * | faulted | faulted | + * |-----------|-----------| + * ptr ptr2 + * + * This should result in a merge: + * + * RW + * |-----------------------| + * | faulted | + * |-----------------------| + * ptr + */ + ASSERT_EQ(mprotect(ptr2, 5 * page_size, PROT_READ | PROT_WRITE), 0); + + ASSERT_TRUE(find_vma_procmap(procmap, ptr)); + ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr); + ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 10 * page_size); +} + TEST_HARNESS_MAIN