From patchwork Mon Apr 15 09:22:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Stefan ISAILA X-Patchwork-Id: 10900391 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 89C511800 for ; Mon, 15 Apr 2019 09:25:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7309E287EA for ; Mon, 15 Apr 2019 09:25:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 66D842886E; Mon, 15 Apr 2019 09:25:25 +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=-5.0 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0BF82287FB for ; Mon, 15 Apr 2019 09:25:23 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hFxpR-0005j0-Aq; Mon, 15 Apr 2019 09:23:05 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hFxpP-0005iv-UZ for xen-devel@lists.xenproject.org; Mon, 15 Apr 2019 09:23:04 +0000 X-Inumbo-ID: 10a58aa2-5f60-11e9-92d7-bc764e045a96 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (unknown [2a01:111:f400:fe09::71e]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 10a58aa2-5f60-11e9-92d7-bc764e045a96; Mon, 15 Apr 2019 09:23:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bitdefender.onmicrosoft.com; s=selector1-bitdefender-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Jxy4QfoHDtyenColasDT9tdcpRRabgr3dVEFOrGXPJc=; b=GWsiUOVVQhczjN0siX04r8L+71I4g2rDResnPmL5zbp1zoB7yZTlY9CESFag17+PkZ3ckIRSls1FBaLP5EESW8eK6ACuLQ3CA6DVPD4YsjF0mA6AvYFAvLatSQvlbXc9I4NsOFd3sKIh36r6GBcXMwpgyCqgiFbx1GB9+s6Dkn8= Received: from VI1PR0202MB2928.eurprd02.prod.outlook.com (10.171.103.139) by VI1PR0202MB3488.eurprd02.prod.outlook.com (52.134.17.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1792.19; Mon, 15 Apr 2019 09:22:59 +0000 Received: from VI1PR0202MB2928.eurprd02.prod.outlook.com ([fe80::8957:73b5:ea4e:f726]) by VI1PR0202MB2928.eurprd02.prod.outlook.com ([fe80::8957:73b5:ea4e:f726%10]) with mapi id 15.20.1792.018; Mon, 15 Apr 2019 09:22:59 +0000 From: Alexandru Stefan ISAILA To: "xen-devel@lists.xenproject.org" Thread-Topic: [PATCH v4] x86/mm: Aggregate get entry and populate into common funcs Thread-Index: AQHU82zR4ynsAcd8f0GUNAhaQDNEbA== Date: Mon, 15 Apr 2019 09:22:59 +0000 Message-ID: <20190415092243.3349-1-aisaila@bitdefender.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM5PR0402CA0024.eurprd04.prod.outlook.com (2603:10a6:203:90::34) To VI1PR0202MB2928.eurprd02.prod.outlook.com (2603:10a6:800:de::11) authentication-results: spf=none (sender IP is ) smtp.mailfrom=aisaila@bitdefender.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.17.1 x-originating-ip: [91.199.104.6] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: dbde1f34-f323-452a-beee-08d6c183f37a x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600140)(711020)(4605104)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:VI1PR0202MB3488; x-ms-traffictypediagnostic: VI1PR0202MB3488:|VI1PR0202MB3488: x-microsoft-antispam-prvs: x-forefront-prvs: 000800954F x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(366004)(396003)(376002)(346002)(39860400002)(189003)(199004)(6486002)(71190400001)(6116002)(3846002)(71200400001)(305945005)(5640700003)(6512007)(1076003)(105586002)(106356001)(2501003)(478600001)(86362001)(2351001)(4326008)(6916009)(8936002)(14454004)(99286004)(68736007)(8676002)(50226002)(81156014)(81166006)(25786009)(2906002)(186003)(486006)(5660300002)(256004)(14444005)(97736004)(2616005)(476003)(26005)(316002)(66066001)(36756003)(386003)(53936002)(7736002)(6436002)(52116002)(102836004)(6506007)(54906003); DIR:OUT; SFP:1102; SCL:1; SRVR:VI1PR0202MB3488; H:VI1PR0202MB2928.eurprd02.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: bitdefender.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: I787ArJFLTZxbHDijwp43j3VO9OHevQFVjkPLpyn82LigHrk0SJKKFmDJ2vHtW4XsjJpxrpXgN3KBONmlyRvOinHW+WwoSOs1yXBQCv32pcdTW9Wwc5g9fR+cyXcJ6K1wu0+ORoSXTSJZlrX0xHKQtioxrW7bxPIOaDZ+ll4nqFSQ9UO5IT/2QN5hZmc5NeNtDt63i3QTB9m0e3S7sosLt5BXSVUVheFzv5nZfMA9/N0h5MheTxMbCeWTp/VBHFi5+mg0FAvwV0rEV2nk2K99Xb8tidYh7r5FxjLqvwByKMmT1Gcj5BgObXpntYhkdYw14bCirKTPU6hOQ8G5U1CdMBhc9dfQjnm5b8uLF6JzDguNJaFx5gndcmsuCHa9bYoPzj+KxhS3o0UWhUT31Ix3m51G/2tIpgjC53mQV+o8Ys= MIME-Version: 1.0 X-OriginatorOrg: bitdefender.com X-MS-Exchange-CrossTenant-Network-Message-Id: dbde1f34-f323-452a-beee-08d6c183f37a X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Apr 2019 09:22:59.2811 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 487baf29-f1da-469a-9221-243f830c36f3 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0202MB3488 Subject: [Xen-devel] [PATCH v4] x86/mm: Aggregate get entry and populate into common funcs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: "tamas@tklengyel.com" , "wei.liu2@citrix.com" , "rcojocaru@bitdefender.com" , "george.dunlap@eu.citrix.com" , "andrew.cooper3@citrix.com" , George Dunlap , "jbeulich@suse.com" , Alexandru Stefan ISAILA , "roger.pau@citrix.com" Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP The code for getting the entry and then populating was repeated in p2m_change_altp2m_gfn() and in p2m_set_altp2m_mem_access(). The code is now in one place with a bool param that lets the caller choose if it populates after get_entry(). If remapping is being done then both the old and new gfn's should be unshared in the hostp2m for keeping things consistent. The page type of old_gfn was already checked whether it's p2m_ram_rw and bail if it wasn't so functionality-wise this just simplifies things as a user doesn't have to request unsharing manually before remapping. Now, if the new_gfn is invalid it shouldn't query the hostp2m as that is effectively a request to remove the entry from the altp2m. But provided that scenario is used only when removing entries that were previously remapped/copied to the altp2m, those entries already went through P2M_ALLOC | P2M_UNSHARE before, so it won't have an affect so the core function get_altp2m_entry() is calling __get_gfn_type_access() with P2M_ALLOC | P2M_UNSHARE. altp2m_get_entry_direct() is also called in p2m_set_suppress_ve() because on a new altp2m view the function will fail with invalid mfn if p2m->set_entry() was not called before. Signed-off-by: Alexandru Isaila Signed-off-by: George Dunlap Reviewed-by: George Dunlap --- Changes since V3: - Switched over to George's version --- xen/arch/x86/mm/mem_access.c | 30 ++----------- xen/arch/x86/mm/p2m.c | 84 ++++++++++++++++++++---------------- xen/include/asm-x86/p2m.h | 17 ++++++++ 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index a144bb0ce4..ddfe0169c0 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -262,35 +262,11 @@ int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m, mfn_t mfn; p2m_type_t t; p2m_access_t old_a; - unsigned int page_order; - unsigned long gfn_l = gfn_x(gfn); int rc; - mfn = ap2m->get_entry(ap2m, gfn, &t, &old_a, 0, NULL, NULL); - - /* Check host p2m if no valid entry in alternate */ - if ( !mfn_valid(mfn) ) - { - - mfn = __get_gfn_type_access(hp2m, gfn_l, &t, &old_a, - P2M_ALLOC | P2M_UNSHARE, &page_order, 0); - - rc = -ESRCH; - if ( !mfn_valid(mfn) || t != p2m_ram_rw ) - return rc; - - /* If this is a superpage, copy that first */ - if ( page_order != PAGE_ORDER_4K ) - { - unsigned long mask = ~((1UL << page_order) - 1); - gfn_t gfn2 = _gfn(gfn_l & mask); - mfn_t mfn2 = _mfn(mfn_x(mfn) & mask); - - rc = ap2m->set_entry(ap2m, gfn2, mfn2, page_order, t, old_a, 1); - if ( rc ) - return rc; - } - } + rc = altp2m_get_entry_prepopulate(ap2m, gfn, &mfn, &t, &old_a); + if ( rc ) + return rc; /* * Inherit the old suppress #VE bit value if it is already set, or set it diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 9e81a30cc4..6f97650313 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -478,6 +478,43 @@ void p2m_unlock_and_tlb_flush(struct p2m_domain *p2m) mm_write_unlock(&p2m->lock); } +int get_altp2m_entry(struct p2m_domain *ap2m, + gfn_t gfn, mfn_t *mfn, p2m_type_t *t, + p2m_access_t *a, bool prepopulate) +{ + *mfn = ap2m->get_entry(ap2m, gfn, t, a, 0, NULL, NULL); + + /* Check host p2m if no valid entry in alternate */ + if ( !mfn_valid(*mfn) && !p2m_is_hostp2m(ap2m) ) + { + struct p2m_domain *hp2m = p2m_get_hostp2m(ap2m->domain); + unsigned int page_order; + int rc; + + *mfn = __get_gfn_type_access(hp2m, gfn_x(gfn), t, a, + P2M_ALLOC | P2M_UNSHARE, &page_order, 0); + + rc = -ESRCH; + if ( !mfn_valid(*mfn) || *t != p2m_ram_rw ) + return rc; + + /* If this is a superpage, copy that first */ + if ( prepopulate && page_order != PAGE_ORDER_4K ) + { + unsigned long mask = ~((1UL << page_order) - 1); + gfn_t gfn_aligned = _gfn(gfn_x(gfn) & mask); + mfn_t mfn_aligned = _mfn(mfn_x(*mfn) & mask); + + rc = ap2m->set_entry(ap2m, gfn_aligned, mfn_aligned, page_order, *t, *a, 1); + if ( rc ) + return rc; + } + } + + return 0; +} + + mfn_t __get_gfn_type_access(struct p2m_domain *p2m, unsigned long gfn_l, p2m_type_t *t, p2m_access_t *a, p2m_query_t q, unsigned int *page_order, bool_t locked) @@ -2618,7 +2655,6 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, p2m_access_t a; p2m_type_t t; mfn_t mfn; - unsigned int page_order; int rc = -EINVAL; if ( idx >= MAX_ALTP2M || d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) @@ -2630,47 +2666,21 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, p2m_lock(hp2m); p2m_lock(ap2m); - mfn = ap2m->get_entry(ap2m, old_gfn, &t, &a, 0, NULL, NULL); - if ( gfn_eq(new_gfn, INVALID_GFN) ) { + mfn = ap2m->get_entry(ap2m, old_gfn, &t, &a, 0, NULL, NULL); if ( mfn_valid(mfn) ) p2m_remove_page(ap2m, gfn_x(old_gfn), mfn_x(mfn), PAGE_ORDER_4K); rc = 0; goto out; } - /* Check host p2m if no valid entry in alternate */ - if ( !mfn_valid(mfn) ) - { - mfn = __get_gfn_type_access(hp2m, gfn_x(old_gfn), &t, &a, - P2M_ALLOC, &page_order, 0); - - if ( !mfn_valid(mfn) || t != p2m_ram_rw ) - goto out; - - /* If this is a superpage, copy that first */ - if ( page_order != PAGE_ORDER_4K ) - { - gfn_t gfn; - unsigned long mask; - - mask = ~((1UL << page_order) - 1); - gfn = _gfn(gfn_x(old_gfn) & mask); - mfn = _mfn(mfn_x(mfn) & mask); - - if ( ap2m->set_entry(ap2m, gfn, mfn, page_order, t, a, 1) ) - goto out; - } - } - - mfn = ap2m->get_entry(ap2m, new_gfn, &t, &a, 0, NULL, NULL); - - if ( !mfn_valid(mfn) ) - mfn = hp2m->get_entry(hp2m, new_gfn, &t, &a, 0, NULL, NULL); + rc = altp2m_get_entry_prepopulate(ap2m, old_gfn, &mfn, &t, &a); + if ( rc ) + goto out; - /* Note: currently it is not safe to remap to a shared entry */ - if ( !mfn_valid(mfn) || (t != p2m_ram_rw) ) + rc = altp2m_get_entry_direct(ap2m, new_gfn, &mfn, &t, &a); + if ( rc ) goto out; if ( !ap2m->set_entry(ap2m, old_gfn, mfn, PAGE_ORDER_4K, t, a, @@ -3002,12 +3012,10 @@ int p2m_set_suppress_ve(struct domain *d, gfn_t gfn, bool suppress_ve, if ( ap2m ) p2m_lock(ap2m); - mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, NULL, NULL); - if ( !mfn_valid(mfn) ) - { - rc = -ESRCH; + rc = altp2m_get_entry_direct(p2m, gfn, &mfn, &t, &a); + + if ( rc ) goto out; - } rc = p2m->set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, t, a, suppress_ve); diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 2801a8ccca..7b9f035bb3 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -514,6 +514,23 @@ static inline unsigned long mfn_to_gfn(struct domain *d, mfn_t mfn) return mfn_x(mfn); } +int get_altp2m_entry(struct p2m_domain *ap2m, gfn_t gfn, mfn_t *mfn, + p2m_type_t *t, p2m_access_t *a, bool prepopulate); + +static inline int altp2m_get_entry_direct(struct p2m_domain *ap2m, + gfn_t gfn, mfn_t *mfn, + p2m_type_t *t, p2m_access_t *a) +{ + return get_altp2m_entry(ap2m, gfn, mfn, t, a, false); +} + +static inline int altp2m_get_entry_prepopulate(struct p2m_domain *ap2m, + gfn_t gfn, mfn_t *mfn, + p2m_type_t *t, p2m_access_t *a) +{ + return get_altp2m_entry(ap2m, gfn, mfn, t, a, true); +} + /* Deadlock-avoidance scheme when calling get_gfn on different gfn's */ struct two_gfns { struct domain *first_domain, *second_domain;