aboutsummaryrefslogtreecommitdiff
path: root/system/xen/xsa/xsa346-4.13-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/xen/xsa/xsa346-4.13-2.patch')
-rw-r--r--system/xen/xsa/xsa346-4.13-2.patch204
1 files changed, 0 insertions, 204 deletions
diff --git a/system/xen/xsa/xsa346-4.13-2.patch b/system/xen/xsa/xsa346-4.13-2.patch
deleted file mode 100644
index 6371b5c3db7d2..0000000000000
--- a/system/xen/xsa/xsa346-4.13-2.patch
+++ /dev/null
@@ -1,204 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: IOMMU: hold page ref until after deferred TLB flush
-
-When moving around a page via XENMAPSPACE_gmfn_range, deferring the TLB
-flush for the "from" GFN range requires that the page remains allocated
-to the guest until the TLB flush has actually occurred. Otherwise a
-parallel hypercall to remove the page would only flush the TLB for the
-GFN it has been moved to, but not the one is was mapped at originally.
-
-This is part of XSA-346.
-
-Fixes: cf95b2a9fd5a ("iommu: Introduce per cpu flag (iommu_dont_flush_iotlb) to avoid unnecessary iotlb... ")
-Reported-by: Julien Grall <jgrall@amazon.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Julien Grall <jgrall@amazon.com>
-
---- a/xen/arch/arm/mm.c
-+++ b/xen/arch/arm/mm.c
-@@ -1407,7 +1407,7 @@ void share_xen_page_with_guest(struct pa
- int xenmem_add_to_physmap_one(
- struct domain *d,
- unsigned int space,
-- union xen_add_to_physmap_batch_extra extra,
-+ union add_to_physmap_extra extra,
- unsigned long idx,
- gfn_t gfn)
- {
-@@ -1480,10 +1480,6 @@ int xenmem_add_to_physmap_one(
- break;
- }
- case XENMAPSPACE_dev_mmio:
-- /* extra should be 0. Reserved for future use. */
-- if ( extra.res0 )
-- return -EOPNOTSUPP;
--
- rc = map_dev_mmio_region(d, gfn, 1, _mfn(idx));
- return rc;
-
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -4617,7 +4617,7 @@ static int handle_iomem_range(unsigned l
- int xenmem_add_to_physmap_one(
- struct domain *d,
- unsigned int space,
-- union xen_add_to_physmap_batch_extra extra,
-+ union add_to_physmap_extra extra,
- unsigned long idx,
- gfn_t gpfn)
- {
-@@ -4701,9 +4701,20 @@ int xenmem_add_to_physmap_one(
- rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-- /* In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top. */
-+ /*
-+ * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-+ * We also may need to transfer ownership of the page reference to our
-+ * caller.
-+ */
- if ( space == XENMAPSPACE_gmfn )
-+ {
- put_gfn(d, gfn);
-+ if ( !rc && extra.ppage )
-+ {
-+ *extra.ppage = page;
-+ page = NULL;
-+ }
-+ }
-
- if ( page )
- put_page(page);
---- a/xen/common/memory.c
-+++ b/xen/common/memory.c
-@@ -814,13 +814,12 @@ int xenmem_add_to_physmap(struct domain
- {
- unsigned int done = 0;
- long rc = 0;
-- union xen_add_to_physmap_batch_extra extra;
-+ union add_to_physmap_extra extra = {};
-+ struct page_info *pages[16];
-
- ASSERT(paging_mode_translate(d));
-
-- if ( xatp->space != XENMAPSPACE_gmfn_foreign )
-- extra.res0 = 0;
-- else
-+ if ( xatp->space == XENMAPSPACE_gmfn_foreign )
- extra.foreign_domid = DOMID_INVALID;
-
- if ( xatp->space != XENMAPSPACE_gmfn_range )
-@@ -835,7 +834,10 @@ int xenmem_add_to_physmap(struct domain
- xatp->size -= start;
-
- if ( is_iommu_enabled(d) )
-+ {
- this_cpu(iommu_dont_flush_iotlb) = 1;
-+ extra.ppage = &pages[0];
-+ }
-
- while ( xatp->size > done )
- {
-@@ -847,8 +849,12 @@ int xenmem_add_to_physmap(struct domain
- xatp->idx++;
- xatp->gpfn++;
-
-+ if ( extra.ppage )
-+ ++extra.ppage;
-+
- /* Check for continuation if it's not the last iteration. */
-- if ( xatp->size > ++done && hypercall_preempt_check() )
-+ if ( (++done > ARRAY_SIZE(pages) && extra.ppage) ||
-+ (xatp->size > done && hypercall_preempt_check()) )
- {
- rc = start + done;
- break;
-@@ -858,6 +864,7 @@ int xenmem_add_to_physmap(struct domain
- if ( is_iommu_enabled(d) )
- {
- int ret;
-+ unsigned int i;
-
- this_cpu(iommu_dont_flush_iotlb) = 0;
-
-@@ -866,6 +873,15 @@ int xenmem_add_to_physmap(struct domain
- if ( unlikely(ret) && rc >= 0 )
- rc = ret;
-
-+ /*
-+ * Now that the IOMMU TLB flush was done for the original GFN, drop
-+ * the page references. The 2nd flush below is fine to make later, as
-+ * whoever removes the page again from its new GFN will have to do
-+ * another flush anyway.
-+ */
-+ for ( i = 0; i < done; ++i )
-+ put_page(pages[i]);
-+
- ret = iommu_iotlb_flush(d, _dfn(xatp->gpfn - done), done,
- IOMMU_FLUSHF_added | IOMMU_FLUSHF_modified);
- if ( unlikely(ret) && rc >= 0 )
-@@ -879,6 +895,8 @@ static int xenmem_add_to_physmap_batch(s
- struct xen_add_to_physmap_batch *xatpb,
- unsigned int extent)
- {
-+ union add_to_physmap_extra extra = {};
-+
- if ( unlikely(xatpb->size < extent) )
- return -EILSEQ;
-
-@@ -890,6 +908,19 @@ static int xenmem_add_to_physmap_batch(s
- !guest_handle_subrange_okay(xatpb->errs, extent, xatpb->size - 1) )
- return -EFAULT;
-
-+ switch ( xatpb->space )
-+ {
-+ case XENMAPSPACE_dev_mmio:
-+ /* res0 is reserved for future use. */
-+ if ( xatpb->u.res0 )
-+ return -EOPNOTSUPP;
-+ break;
-+
-+ case XENMAPSPACE_gmfn_foreign:
-+ extra.foreign_domid = xatpb->u.foreign_domid;
-+ break;
-+ }
-+
- while ( xatpb->size > extent )
- {
- xen_ulong_t idx;
-@@ -902,8 +933,7 @@ static int xenmem_add_to_physmap_batch(s
- extent, 1)) )
- return -EFAULT;
-
-- rc = xenmem_add_to_physmap_one(d, xatpb->space,
-- xatpb->u,
-+ rc = xenmem_add_to_physmap_one(d, xatpb->space, extra,
- idx, _gfn(gpfn));
-
- if ( unlikely(__copy_to_guest_offset(xatpb->errs, extent, &rc, 1)) )
---- a/xen/include/xen/mm.h
-+++ b/xen/include/xen/mm.h
-@@ -588,8 +588,22 @@ void scrub_one_page(struct page_info *);
- &(d)->xenpage_list : &(d)->page_list)
- #endif
-
-+union add_to_physmap_extra {
-+ /*
-+ * XENMAPSPACE_gmfn: When deferring TLB flushes, a page reference needs
-+ * to be kept until after the flush, so the page can't get removed from
-+ * the domain (and re-used for another purpose) beforehand. By passing
-+ * non-NULL, the caller of xenmem_add_to_physmap_one() indicates it wants
-+ * to have ownership of such a reference transferred in the success case.
-+ */
-+ struct page_info **ppage;
-+
-+ /* XENMAPSPACE_gmfn_foreign */
-+ domid_t foreign_domid;
-+};
-+
- int xenmem_add_to_physmap_one(struct domain *d, unsigned int space,
-- union xen_add_to_physmap_batch_extra extra,
-+ union add_to_physmap_extra extra,
- unsigned long idx, gfn_t gfn);
-
- int xenmem_add_to_physmap(struct domain *d, struct xen_add_to_physmap *xatp,