From: Julien Grall <julien@xen.org>
To: xen-devel@lists.xenproject.org
Cc: hongyxia@amazon.co.uk, iwj@xenproject.org,
Julien Grall <jgrall@amazon.com>, Jan Beulich <jbeulich@suse.com>,
Paul Durrant <paul@xen.org>
Subject: [for-4.15][PATCH v3 3/3] xen/iommu: x86: Harden the IOMMU page-table allocator
Date: Wed, 17 Feb 2021 14:24:58 +0000 [thread overview]
Message-ID: <20210217142458.3769-4-julien@xen.org> (raw)
In-Reply-To: <20210217142458.3769-1-julien@xen.org>
From: Julien Grall <jgrall@amazon.com>
At the moment, we are assuming that only iommu_map() can allocate
IOMMU page-table.
Given the complexity of the IOMMU framework, it would be sensible to
have a check closer to the IOMMU allocator. This would avoid to leak
IOMMU page-tables again in the future.
iommu_alloc_pgtable() is now checking if the domain is dying before
adding the page in the list. We are relying on &hd->arch.pgtables.lock
to synchronize d->is_dying.
Take the opportunity to add an ASSERT() in arch_iommu_domain_destroy()
to check if we freed all the IOMMU page tables.
Signed-off-by: Julien Grall <jgrall@amazon.com>
---
Changes in v3:
- Rename the patch. This was originally "xen/iommu: x86: Don't leak
the IOMMU page-tables"
- Rework the commit message
- Move the patch towards the end of the series
Changes in v2:
- Rework the approach
- Move the patch earlier in the series
---
xen/drivers/passthrough/x86/iommu.c | 33 ++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/x86/iommu.c
index faa0078db595..a67075f0045d 100644
--- a/xen/drivers/passthrough/x86/iommu.c
+++ b/xen/drivers/passthrough/x86/iommu.c
@@ -149,6 +149,13 @@ int arch_iommu_domain_init(struct domain *d)
void arch_iommu_domain_destroy(struct domain *d)
{
+ /*
+ * There should be not page-tables left allocated by the time the
+ * domain is destroyed. Note that arch_iommu_domain_destroy() is
+ * called unconditionally, so pgtables may be unitialized.
+ */
+ ASSERT(dom_iommu(d)->platform_ops == NULL ||
+ page_list_empty(&dom_iommu(d)->arch.pgtables.list));
}
static bool __hwdom_init hwdom_iommu_map(const struct domain *d,
@@ -279,6 +286,9 @@ int iommu_free_pgtables(struct domain *d)
*/
hd->platform_ops->clear_root_pgtable(d);
+ /* After this barrier no new page allocations can occur. */
+ spin_barrier(&hd->arch.pgtables.lock);
+
while ( (pg = page_list_remove_head(&hd->arch.pgtables.list)) )
{
free_domheap_page(pg);
@@ -296,6 +306,7 @@ struct page_info *iommu_alloc_pgtable(struct domain *d)
unsigned int memflags = 0;
struct page_info *pg;
void *p;
+ bool alive = false;
#ifdef CONFIG_NUMA
if ( hd->node != NUMA_NO_NODE )
@@ -315,9 +326,29 @@ struct page_info *iommu_alloc_pgtable(struct domain *d)
unmap_domain_page(p);
spin_lock(&hd->arch.pgtables.lock);
- page_list_add(pg, &hd->arch.pgtables.list);
+ /*
+ * The IOMMU page-tables are freed when relinquishing the domain, but
+ * nothing prevent allocation to happen afterwards. There is no valid
+ * reasons to continue to update the IOMMU page-tables while the
+ * domain is dying.
+ *
+ * So prevent page-table allocation when the domain is dying.
+ *
+ * We relying on &hd->arch.pgtables.lock to synchronize d->is_dying.
+ */
+ if ( likely(!d->is_dying) )
+ {
+ alive = true;
+ page_list_add(pg, &hd->arch.pgtables.list);
+ }
spin_unlock(&hd->arch.pgtables.lock);
+ if ( unlikely(!alive) )
+ {
+ free_domheap_page(pg);
+ pg = NULL;
+ }
+
return pg;
}
--
2.17.1
next prev parent reply other threads:[~2021-02-17 14:25 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-17 14:24 [for-4.15][PATCH v3 0/3] xen/iommu: Collection of bug fixes for IOMMU teadorwn Julien Grall
2021-02-17 14:24 ` [for-4.15][PATCH v3 1/3] xen/iommu: x86: Clear the root page-table before freeing the page-tables Julien Grall
2021-02-17 14:54 ` Jan Beulich
2021-02-17 15:00 ` Julien Grall
2021-02-17 15:17 ` Jan Beulich
2021-02-17 16:48 ` Julien Grall
2021-02-17 14:24 ` [for-4.15][PATCH v3 2/3] xen/x86: iommu: Ignore IOMMU mapping requests when a domain is dying Julien Grall
2021-02-17 15:01 ` Jan Beulich
2021-02-17 16:07 ` Julien Grall
2021-02-18 13:05 ` Jan Beulich
2021-02-18 13:25 ` Julien Grall
2021-02-19 8:49 ` Jan Beulich
2021-02-19 9:24 ` Julien Grall
2021-02-18 14:00 ` Paul Durrant
2021-02-19 8:56 ` Jan Beulich
2021-02-17 14:24 ` Julien Grall [this message]
2021-02-17 15:13 ` [for-4.15][PATCH v3 3/3] xen/iommu: x86: Harden the IOMMU page-table allocator Jan Beulich
2021-02-17 16:29 ` Julien Grall
2021-02-18 13:10 ` Jan Beulich
2021-02-18 13:19 ` Julien Grall
2021-02-18 17:04 ` Jan Beulich
2021-02-18 17:41 ` Julien Grall
2021-02-19 8:46 ` Jan Beulich
2021-02-19 8:57 ` Julien Grall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210217142458.3769-4-julien@xen.org \
--to=julien@xen.org \
--cc=hongyxia@amazon.co.uk \
--cc=iwj@xenproject.org \
--cc=jbeulich@suse.com \
--cc=jgrall@amazon.com \
--cc=paul@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.