From patchwork Tue Apr 23 14:30:26 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: 10913201 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 75E94112C for ; Tue, 23 Apr 2019 14:32:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64F76288BD for ; Tue, 23 Apr 2019 14:32:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58FF428927; Tue, 23 Apr 2019 14:32:35 +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 9F6C62891F for ; Tue, 23 Apr 2019 14:32:34 +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 1hIwRM-0001US-4N; Tue, 23 Apr 2019 14:30:32 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hIwRL-0001UN-2c for xen-devel@lists.xenproject.org; Tue, 23 Apr 2019 14:30:31 +0000 X-Inumbo-ID: 5748cdc7-65d4-11e9-92d7-bc764e045a96 Received: from EUR03-DB5-obe.outbound.protection.outlook.com (unknown [2a01:111:f400:fe0a::713]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 5748cdc7-65d4-11e9-92d7-bc764e045a96; Tue, 23 Apr 2019 14:30:29 +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=3MQibFTAQ1T6HaRmELZ6zsQFN1XaqiAqOrtjVR7FROY=; b=XBoQLWuSeeCdzIXymZrya3EKBnAaCUAnGkpusOqCqgiAM5a50akGQECC60eWY5VXJlEDlAyJ2jb1f/H+ZFcJNHw2cYGyeRPwFDZ1YBgrKpZ0CLDSAg7FmKm+Es6cvM75Ot2Xt5FSt7Yhzy1ZPg/LVyM4AzgOzpOX3gXSa+9d7Uc= Received: from VI1PR0202MB2928.eurprd02.prod.outlook.com (10.171.103.139) by VI1PR0202MB2654.eurprd02.prod.outlook.com (10.173.80.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1813.11; Tue, 23 Apr 2019 14:30:26 +0000 Received: from VI1PR0202MB2928.eurprd02.prod.outlook.com ([fe80::89a9:54d2:cf14:66a7]) by VI1PR0202MB2928.eurprd02.prod.outlook.com ([fe80::89a9:54d2:cf14:66a7%9]) with mapi id 15.20.1835.010; Tue, 23 Apr 2019 14:30:26 +0000 From: Alexandru Stefan ISAILA To: "xen-devel@lists.xenproject.org" Thread-Topic: [PATCH v6] x86/altp2m: Aggregate get entry and populate into common funcs Thread-Index: AQHU+eEX0KNED2Ows0iCl3vatskifw== Date: Tue, 23 Apr 2019 14:30:26 +0000 Message-ID: <20190423142959.12609-1-aisaila@bitdefender.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM5P190CA0011.EURP190.PROD.OUTLOOK.COM (2603:10a6:206:14::24) 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: 441c4939-ab43-426d-55d5-08d6c7f839f0 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600141)(711020)(4605104)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:VI1PR0202MB2654; x-ms-traffictypediagnostic: VI1PR0202MB2654:|VI1PR0202MB2654: x-microsoft-antispam-prvs: x-forefront-prvs: 0016DEFF96 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(376002)(366004)(396003)(39860400002)(136003)(346002)(199004)(189003)(5640700003)(50226002)(8936002)(186003)(2501003)(99286004)(25786009)(97736004)(14454004)(36756003)(68736007)(26005)(5660300002)(81166006)(7736002)(305945005)(14444005)(256004)(81156014)(8676002)(478600001)(4326008)(6506007)(102836004)(386003)(1076003)(66476007)(54906003)(64756008)(476003)(6916009)(73956011)(2616005)(6512007)(66446008)(66946007)(66556008)(53936002)(2906002)(66066001)(6116002)(3846002)(2351001)(52116002)(6486002)(71200400001)(6436002)(86362001)(71190400001)(316002)(486006); DIR:OUT; SFP:1102; SCL:1; SRVR:VI1PR0202MB2654; H:VI1PR0202MB2928.eurprd02.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX: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: uJPfLCKHNYAedhrgoom0qU3gjL7fU6dhjG1/6dh8LJ9PQcWuU7jDC4kmILX+iCW9LPmh2HsWL7TDxacX6GT6mYubYcNYw3Hb8eMeYdJFpch0GOqJrndteK+ZAeUwyCKdPYrLgDV9wk+0RMf7e0NAjC6ZFuHXIrGKPkyUgn5fnfNX6jzgiIz+pf1sszE5a6UqIFMMgfYL6kwCybQprmKh09+i6Hyb57TeaJOI1txI1a3GUUlJv/Nky2pTOAysjmXjYVmXEaGa8hUd0PWP07KB1eQeBD28vY5/lrnyYtyHiYqMeUOhvlyPgbAd0FXsGJGKGLAv+0OguLqEX5dNR8JrHf5SjGeDxEZ+WzPXQRHGot0s2FGnm4zA8R/u4OK8LF3o15RaIzNk0UPWvyaVWQrV2xAP1AXF5yua9U4eZGY44Oo= MIME-Version: 1.0 X-OriginatorOrg: bitdefender.com X-MS-Exchange-CrossTenant-Network-Message-Id: 441c4939-ab43-426d-55d5-08d6c7f839f0 X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Apr 2019 14:30:26.0335 (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: VI1PR0202MB2654 Subject: [Xen-devel] [PATCH v6] x86/altp2m: 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 Acked-by: Tamas K Lengyel --- Changes since V5: - Change altp2m_get_entry() to altp2m_get_effective_entry() - Add comment before altp2m_get_effective_entry() - Add AP2MGET_prepopulate and AP2MGET_query defines - Remove altp2m_get_entry_direct() and altp2m_get_entry_prepopulate(). --- xen/arch/x86/mm/mem_access.c | 31 ++----------- xen/arch/x86/mm/p2m.c | 86 ++++++++++++++++++++---------------- xen/include/asm-x86/p2m.h | 12 +++++ 3 files changed, 64 insertions(+), 65 deletions(-) diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index a144bb0ce4..0144f92b98 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -262,35 +262,12 @@ 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_effective_entry(ap2m, gfn, &mfn, &t, &old_a, + AP2MGET_prepopulate); + 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..472e28ea65 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 altp2m_get_effective_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,23 @@ 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_effective_entry(ap2m, old_gfn, &mfn, &t, &a, + AP2MGET_prepopulate); + 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_effective_entry(ap2m, new_gfn, &mfn, &t, &a, + AP2MGET_query); + if ( rc ) goto out; if ( !ap2m->set_entry(ap2m, old_gfn, mfn, PAGE_ORDER_4K, t, a, @@ -3002,12 +3014,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_effective_entry(p2m, gfn, &mfn, &t, &a, AP2MGET_query); + + 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..719513f4ba 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -514,6 +514,18 @@ static inline unsigned long mfn_to_gfn(struct domain *d, mfn_t mfn) return mfn_x(mfn); } +#define AP2MGET_prepopulate true +#define AP2MGET_query false + +/* + * Looks up altp2m entry. If the entry is not found it looks up the entry in + * hostp2m. + * The prepopulate param is used to set the found entry in altp2m. + */ +int altp2m_get_effective_entry(struct p2m_domain *ap2m, gfn_t gfn, mfn_t *mfn, + p2m_type_t *t, p2m_access_t *a, + bool prepopulate); + /* Deadlock-avoidance scheme when calling get_gfn on different gfn's */ struct two_gfns { struct domain *first_domain, *second_domain;