|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 03/11] IOMMU/MMU: enhance the call trees of IOMMU unmapping and mapping
> From: Xu, Quan
> Sent: Monday, April 18, 2016 10:00 PM
>
> If IOMMU mapping and unmapping failed, the domain (with the exception of
> the hardware domain) is crashed, treated as a fatal error. Rollback can
> be lighter weight.
What do you mean by 'lighter weight"? Please clarify it.
>
> For the hardware domain, we do things on a best effort basis. When rollback
> is not feasible (in early initialization phase or trade-off of complexity),
> at least, unmap upon maps error or then throw out error message.
remove 'or'. Based on next sentence, is above specific for IOMMU mapping?
>
> IOMMU unmapping should perhaps continue despite an error, in an attempt to
> do best effort cleanup.
>
> Signed-off-by: Quan Xu <quan.xu@xxxxxxxxx>
>
> CC: Keir Fraser <keir@xxxxxxx>
> CC: Jan Beulich <jbeulich@xxxxxxxx>
> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> CC: Jun Nakajima <jun.nakajima@xxxxxxxxx>
> CC: Kevin Tian <kevin.tian@xxxxxxxxx>
> CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
> ---
> xen/arch/x86/mm.c | 13 ++++++++-----
> xen/arch/x86/mm/p2m-ept.c | 25 ++++++++++++++++++++++---
> xen/arch/x86/mm/p2m-pt.c | 22 ++++++++++++++++++----
> xen/arch/x86/mm/p2m.c | 11 +++++++++--
> xen/drivers/passthrough/iommu.c | 14 +++++++++++++-
> 5 files changed, 70 insertions(+), 15 deletions(-)
>
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index c997b53..5c4fb58 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -2467,7 +2467,7 @@ static int __get_page_type(struct page_info *page,
> unsigned
> long type,
> int preemptible)
> {
> unsigned long nx, x, y = page->u.inuse.type_info;
> - int rc = 0;
> + int rc = 0, ret = 0;
>
> ASSERT(!(type & ~(PGT_type_mask | PGT_pae_xen_l2)));
>
> @@ -2578,11 +2578,11 @@ static int __get_page_type(struct page_info *page,
> unsigned
> long type,
> if ( d && is_pv_domain(d) && unlikely(need_iommu(d)) )
> {
> if ( (x & PGT_type_mask) == PGT_writable_page )
> - iommu_unmap_page(d, mfn_to_gmfn(d, page_to_mfn(page)));
> + ret = iommu_unmap_page(d, mfn_to_gmfn(d, page_to_mfn(page)));
> else if ( type == PGT_writable_page )
> - iommu_map_page(d, mfn_to_gmfn(d, page_to_mfn(page)),
> - page_to_mfn(page),
> - IOMMUF_readable|IOMMUF_writable);
> + ret = iommu_map_page(d, mfn_to_gmfn(d, page_to_mfn(page)),
> + page_to_mfn(page),
> + IOMMUF_readable|IOMMUF_writable);
> }
> }
>
> @@ -2599,6 +2599,9 @@ static int __get_page_type(struct page_info *page,
> unsigned
> long type,
> if ( (x & PGT_partial) && !(nx & PGT_partial) )
> put_page(page);
>
> + if ( unlikely(ret) )
> + rc = ret;
> +
> return rc;
> }
>
> diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
> index 3cb6868..22c8d17 100644
> --- a/xen/arch/x86/mm/p2m-ept.c
> +++ b/xen/arch/x86/mm/p2m-ept.c
> @@ -665,7 +665,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn,
> mfn_t mfn,
> ept_entry_t *table, *ept_entry = NULL;
> unsigned long gfn_remainder = gfn;
> unsigned int i, target = order / EPT_TABLE_ORDER;
> - int ret, rc = 0;
> + int ret, err = 0, rc = 0;
> bool_t direct_mmio = (p2mt == p2m_mmio_direct);
> uint8_t ipat = 0;
> bool_t need_modify_vtd_table = 1;
> @@ -830,10 +830,26 @@ out:
> {
> if ( iommu_flags )
> for ( i = 0; i < (1 << order); i++ )
> - iommu_map_page(d, gfn + i, mfn_x(mfn) + i, iommu_flags);
> + {
> + ret = iommu_map_page(d, gfn + i, mfn_x(mfn) + i,
> iommu_flags);
> +
> + if ( unlikely(ret) )
> + {
> + while (i)
> + iommu_unmap_page(d, gfn + --i);
How about below?
while (i-- >= 0)
iommu_unmap_page(d, gfn + i);
> +
> + err = ret;
> + break;
> + }
> + }
> else
> for ( i = 0; i < (1 << order); i++ )
> - iommu_unmap_page(d, gfn + i);
> + {
> + ret = iommu_unmap_page(d, gfn + i);
> +
> + if ( unlikely(ret) )
> + err = ret;
> + }
> }
> }
>
> @@ -849,6 +865,9 @@ out:
> if ( rc == 0 && p2m_is_hostp2m(p2m) )
> p2m_altp2m_propagate_change(d, _gfn(gfn), mfn, order, p2mt, p2ma);
>
> + if ( unlikely(err) )
> + rc = err;
> +
not sure we need three return values here: rc, ret, err...
> return rc;
> }
>
> diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
> index 3d80612..db4257a 100644
> --- a/xen/arch/x86/mm/p2m-pt.c
> +++ b/xen/arch/x86/mm/p2m-pt.c
> @@ -498,7 +498,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long
> gfn,
> mfn_t mfn,
> l1_pgentry_t intermediate_entry = l1e_empty();
> l2_pgentry_t l2e_content;
> l3_pgentry_t l3e_content;
> - int rc;
> + int rc, ret;
> unsigned int iommu_pte_flags = p2m_get_iommu_flags(p2mt);
> /*
> * old_mfn and iommu_old_flags control possible flush/update needs on the
> @@ -680,11 +680,25 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long
> gfn, mfn_t mfn,
> }
> else if ( iommu_pte_flags )
> for ( i = 0; i < (1UL << page_order); i++ )
> - iommu_map_page(p2m->domain, gfn + i, mfn_x(mfn) + i,
> - iommu_pte_flags);
> + {
> + ret = iommu_map_page(p2m->domain, gfn + i, mfn_x(mfn) + i,
> + iommu_pte_flags);
> + if ( unlikely(ret) )
> + {
> + while (i)
> + iommu_unmap_page(p2m->domain, gfn + --i);
> +
> + rc = ret;
> + }
> + }
> else
> for ( i = 0; i < (1UL << page_order); i++ )
> - iommu_unmap_page(p2m->domain, gfn + i);
> + {
> + ret = iommu_unmap_page(p2m->domain, gfn + i);
> +
> + if ( unlikely(ret) )
> + rc = ret;
> + }
> }
>
> /*
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index b3fce1b..98450a4 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -610,13 +610,20 @@ p2m_remove_page(struct p2m_domain *p2m, unsigned long
> gfn, unsigned long mfn,
> mfn_t mfn_return;
> p2m_type_t t;
> p2m_access_t a;
> + int ret = 0, rc;
>
> if ( !paging_mode_translate(p2m->domain) )
> {
> if ( need_iommu(p2m->domain) )
> for ( i = 0; i < (1 << page_order); i++ )
> - iommu_unmap_page(p2m->domain, mfn + i);
> - return 0;
> + {
> + rc = iommu_unmap_page(p2m->domain, mfn + i);
> +
> + if ( unlikely(rc) )
> + ret = rc;
> + }
> +
> + return ret;
> }
>
> ASSERT(gfn_locked_by_me(p2m, gfn));
> diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
> index 850101b..c351209 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -172,6 +172,8 @@ void __hwdom_init iommu_hwdom_init(struct domain *d)
> {
> struct page_info *page;
> unsigned int i = 0;
> + int ret, rc = 0;
> +
> page_list_for_each ( page, &d->page_list )
> {
> unsigned long mfn = page_to_mfn(page);
> @@ -182,10 +184,20 @@ void __hwdom_init iommu_hwdom_init(struct domain *d)
> ((page->u.inuse.type_info & PGT_type_mask)
> == PGT_writable_page) )
> mapping |= IOMMUF_writable;
> - hd->platform_ops->map_page(d, gfn, mfn, mapping);
> +
> + ret = hd->platform_ops->map_page(d, gfn, mfn, mapping);
> +
> + if ( unlikely(ret) )
> + rc = ret;
> +
> if ( !(i++ & 0xfffff) )
> process_pending_softirqs();
> }
> +
> + if ( rc )
> + printk(XENLOG_G_ERR
> + "dom%d: IOMMU mapping is failed for hardware domain.",
> + d->domain_id);
> }
>
> return hd->platform_ops->hwdom_init(d);
> --
> 1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |