From patchwork Thu Jul 28 14:51:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 72970 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp894562qga; Thu, 28 Jul 2016 07:54:12 -0700 (PDT) X-Received: by 10.107.44.66 with SMTP id s63mr39229949ios.186.1469717652650; Thu, 28 Jul 2016 07:54:12 -0700 (PDT) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id 9si29527552itl.8.2016.07.28.07.54.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Jul 2016 07:54:12 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bSmfY-0003Au-76; Thu, 28 Jul 2016 14:52:16 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bSmfX-00039O-5r for xen-devel@lists.xen.org; Thu, 28 Jul 2016 14:52:15 +0000 Received: from [85.158.137.68] by server-3.bemta-3.messagelabs.com id 12/D9-23620-E1C1A975; Thu, 28 Jul 2016 14:52:14 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTVdWZla 4QeMuE4slHxezODB6HN39mymAMYo1My8pvyKBNWPShs3sBWuVKl7/6GRtYDwu0cXIxSEksIlR Ysbc44wQzmlGiUdHjjB3MXJysAloStz5/IkJxBYRkJa49vkyWBGzQDujxNr+XrAiYYEoiZVvf 7OC2CwCqhJnHj5i6WLk4OAVcJHYtFsYJCwhICdx8thkVpAwJ1D4dbcQSFhIwFli+syljBMYuR cwMqxi1ChOLSpLLdI1MtFLKspMzyjJTczM0TU0MNbLTS0uTkxPzUlMKtZLzs/dxAj0bz0DA+M OxlfH/Q4xSnIwKYnyhoXODBfiS8pPqcxILM6ILyrNSS0+xCjDwaEkwXtLala4kGBRanpqRVpm DjDQYNISHDxKIrxy0kBp3uKCxNzizHSI1ClGRSlx3hqQPgGQREZpHlwbLLgvMcpKCfMyMjAwC PEUpBblZpagyr9iFOdgVBLmZQYZz5OZVwI3/RXQYiagxcWxM0AWlyQipKQaGKv4/xm1eq3hK3 P+azJ1U4Pq1D1/ln5r1Y8xSVQ6uH5RhazXjZwvVwqrvxwpijtbueDEkY/neDfd7tV+evX7vJz u3KxZL5v2Ft7xucupmcdTl72Hx0Pz3pdVxrncDEnNJUYOujOTk7jFRdR/CbEwubzn/vb1wcEV jF9+sh7s/9Rz9uWb7qc9a5VYijMSDbWYi4oTAZ9/hQJpAgAA X-Env-Sender: julien.grall@arm.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1469717533!36206179!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.77; banners=-,-,- X-VirusChecked: Checked Received: (qmail 30873 invoked from network); 28 Jul 2016 14:52:13 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-12.tower-31.messagelabs.com with SMTP; 28 Jul 2016 14:52:13 -0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 13A43BFA; Thu, 28 Jul 2016 07:53:30 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.218.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D335C3F21A; Thu, 28 Jul 2016 07:52:11 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Date: Thu, 28 Jul 2016 15:51:38 +0100 Message-Id: <1469717505-8026-16-git-send-email-julien.grall@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1469717505-8026-1-git-send-email-julien.grall@arm.com> References: <1469717505-8026-1-git-send-email-julien.grall@arm.com> Cc: proskurin@sec.in.tum.de, Julien Grall , sstabellini@kernel.org, steve.capper@arm.com, wei.chen@linaro.org Subject: [Xen-devel] [RFC 15/22] xen/arm: p2m: Re-implement relinquish_p2m_mapping using p2m_get_entry X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" The current implementation of relinquish_p2m_mapping is modifying the page table to erase the entry one by one. However, this is not necessary because the domain is not running anymore and therefore will speed up the domain destruction. The function relinquish_p2m_mapping can be re-implemented using p2m_get_entry by iterating over the range mapped and using the mapping order given by the callee. Given that the preemption was chosen arbitrarily, it is no done on every 512 iterations. Meaning that Xen may check more often if the function is preempted when there are no mappings. Finally drop the operation RELINQUISH in apply_* as nobody is using it anymore. Note that the functions could have been dropped in one go at the end, however I find easier to drop the operations one by one avoiding a big deletion in the patch that remove the last operation. Signed-off-by: Julien Grall --- Further investigation needs to be done before applying this patch to check if someone could take advantage of this change (such modifying an entry which was relinquished). --- xen/arch/arm/p2m.c | 70 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index e7697bb..d0aba5b 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -721,7 +721,6 @@ static int p2m_mem_access_radix_set(struct p2m_domain *p2m, gfn_t gfn, enum p2m_operation { INSERT, REMOVE, - RELINQUISH, MEMACCESS, }; @@ -908,7 +907,6 @@ static int apply_one_level(struct domain *d, break; - case RELINQUISH: case REMOVE: if ( !p2m_valid(orig_pte) ) { @@ -1092,17 +1090,6 @@ static int apply_p2m_changes(struct domain *d, { switch ( op ) { - case RELINQUISH: - /* - * Arbitrarily, preempt every 512 operations or 8192 nops. - * 512*P2M_ONE_PROGRESS == 8192*P2M_ONE_PROGRESS_NOP == 0x2000 - * This is set in preempt_count_limit. - * - */ - p2m->lowest_mapped_gfn = _gfn(addr >> PAGE_SHIFT); - rc = -ERESTART; - goto out; - case MEMACCESS: { /* @@ -1508,16 +1495,63 @@ int p2m_init(struct domain *d) return rc; } +/* + * The function will go through the p2m and remove page reference when it + * is required. + * The mapping are left intact in the p2m. This is fine because the + * domain will never run at that point. + * + * XXX: Check what does it mean for other part (such as lookup) + */ int relinquish_p2m_mapping(struct domain *d) { struct p2m_domain *p2m = &d->arch.p2m; - unsigned long nr; + unsigned long count = 0; + p2m_type_t t; + int rc = 0; + unsigned int order; + + /* Convenience alias */ + gfn_t start = p2m->lowest_mapped_gfn; + gfn_t end = p2m->max_mapped_gfn; - nr = gfn_x(p2m->max_mapped_gfn) - gfn_x(p2m->lowest_mapped_gfn); + p2m_write_lock(p2m); - return apply_p2m_changes(d, RELINQUISH, p2m->lowest_mapped_gfn, nr, - INVALID_MFN, 0, p2m_invalid, - d->arch.p2m.default_access); + for ( ; gfn_x(start) < gfn_x(end); start = gfn_add(start, 1UL << order) ) + { + mfn_t mfn = p2m_get_entry(p2m, start, &t, NULL, &order); + + count++; + /* + * Arbitrarily preempt every 512 iterations. + */ + if ( !(count % 512) && hypercall_preempt_check() ) + { + rc = -ERESTART; + break; + } + + /* Skip hole and any superpage */ + if ( mfn_eq(mfn, INVALID_MFN) || order != 0 ) + /* + * The order corresponds to the order of the mapping in the + * page table. So we need to align the GFN before + * incrementing. + */ + start = _gfn(gfn_x(start) & ~((1UL << order) - 1)); + else + p2m_put_l3_page(mfn, t); + } + + /* + * Update lowest_mapped_gfn so on the next call we still start where + * we stopped. + */ + p2m->lowest_mapped_gfn = start; + + p2m_write_unlock(p2m); + + return rc; } int p2m_cache_flush(struct domain *d, gfn_t start, unsigned long nr)