diff mbox

[v2,07/13] iommu: Make decision about needing IOMMU for hardware domains in advance

Message ID 1501003615-15274-8-git-send-email-olekstysh@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Oleksandr Tyshchenko July 25, 2017, 5:26 p.m. UTC
From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

The hardware domains require IOMMU to be used in the most cases and
a decision to use it is made at hardware domain construction time.
But, it is not the best moment for the non-shared IOMMUs due to
the necessity of retrieving all mapping which could happen in a period
of time between IOMMU per-domain initialization and this moment.

So, make a decision about needing IOMMU a bit earlier, in iommu_domain_init().
Having "d->need_iommu" flag set at the early stage we won't skip
any IOMMU mapping updates. And as the result the existing in iommu_hwdom_init()
code that goes through the list of the pages and tries to retrieve mapping
for non-shared IOMMUs won't be needed anymore and can be just dropped.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Julien Grall <julien.grall@arm.com>

---
Changes in v1:
   -

Changes in v2:
   - This is the result of reworking old patch:
     [PATCH v1 08/10] iommu: Split iommu_hwdom_init() into arch specific parts
---
 xen/drivers/passthrough/iommu.c | 44 ++++++++++-------------------------------
 1 file changed, 10 insertions(+), 34 deletions(-)

Comments

Oleksandr Tyshchenko Aug. 21, 2017, 4:30 p.m. UTC | #1
Hi, all.

Any comments?

On Tue, Jul 25, 2017 at 8:26 PM, Oleksandr Tyshchenko
<olekstysh@gmail.com> wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>
> The hardware domains require IOMMU to be used in the most cases and
> a decision to use it is made at hardware domain construction time.
> But, it is not the best moment for the non-shared IOMMUs due to
> the necessity of retrieving all mapping which could happen in a period
> of time between IOMMU per-domain initialization and this moment.
>
> So, make a decision about needing IOMMU a bit earlier, in iommu_domain_init().
> Having "d->need_iommu" flag set at the early stage we won't skip
> any IOMMU mapping updates. And as the result the existing in iommu_hwdom_init()
> code that goes through the list of the pages and tries to retrieve mapping
> for non-shared IOMMUs won't be needed anymore and can be just dropped.
>
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Julien Grall <julien.grall@arm.com>
>
> ---
> Changes in v1:
>    -
>
> Changes in v2:
>    - This is the result of reworking old patch:
>      [PATCH v1 08/10] iommu: Split iommu_hwdom_init() into arch specific parts
> ---
>  xen/drivers/passthrough/iommu.c | 44 ++++++++++-------------------------------
>  1 file changed, 10 insertions(+), 34 deletions(-)
>
> diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
> index 19c87d1..f5e5b7e 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -52,7 +52,7 @@ custom_param("iommu", parse_iommu_param);
>  bool_t __initdata iommu_enable = 1;
>  bool_t __read_mostly iommu_enabled;
>  bool_t __read_mostly force_iommu;
> -bool_t __hwdom_initdata iommu_dom0_strict;
> +bool_t __read_mostly iommu_dom0_strict;
>  bool_t __read_mostly iommu_verbose;
>  bool_t __read_mostly iommu_workaround_bios_bug;
>  bool_t __read_mostly iommu_igfx = 1;
> @@ -141,6 +141,15 @@ int iommu_domain_init(struct domain *d, bool use_iommu)
>      if ( !iommu_enabled )
>          return 0;
>
> +    if ( is_hardware_domain(d) )
> +    {
> +        if ( (paging_mode_translate(d) && !iommu_passthrough) ||
> +              iommu_dom0_strict )
> +            use_iommu = 1;
> +        else
> +            use_iommu = 0;
> +    }
> +
>      hd->platform_ops = iommu_get_ops();
>      ret = hd->platform_ops->init(d, use_iommu);
>      if ( ret )
> @@ -161,8 +170,6 @@ static void __hwdom_init check_hwdom_reqs(struct domain *d)
>      if ( iommu_passthrough )
>          panic("Dom0 uses paging translated mode, dom0-passthrough must not be "
>                "enabled\n");
> -
> -    iommu_dom0_strict = 1;
>  }
>
>  void __hwdom_init iommu_hwdom_init(struct domain *d)
> @@ -175,37 +182,6 @@ void __hwdom_init iommu_hwdom_init(struct domain *d)
>          return;
>
>      register_keyhandler('o', &iommu_dump_p2m_table, "dump iommu p2m table", 0);
> -    d->need_iommu = !!iommu_dom0_strict;
> -    if ( need_iommu(d) && !iommu_use_hap_pt(d) )
> -    {
> -        struct page_info *page;
> -        unsigned int i = 0;
> -        int rc = 0;
> -
> -        page_list_for_each ( page, &d->page_list )
> -        {
> -            unsigned long mfn = page_to_mfn(page);
> -            unsigned long gfn = mfn_to_gmfn(d, mfn);
> -            unsigned int mapping = IOMMUF_readable;
> -            int ret;
> -
> -            if ( ((page->u.inuse.type_info & PGT_count_mask) == 0) ||
> -                 ((page->u.inuse.type_info & PGT_type_mask)
> -                  == PGT_writable_page) )
> -                mapping |= IOMMUF_writable;
> -
> -            ret = hd->platform_ops->map_pages(d, gfn, mfn, 0, mapping);
> -            if ( !rc )
> -                rc = ret;
> -
> -            if ( !(i++ & 0xfffff) )
> -                process_pending_softirqs();
> -        }
> -
> -        if ( rc )
> -            printk(XENLOG_WARNING "d%d: IOMMU mapping failed: %d\n",
> -                   d->domain_id, rc);
> -    }
>
>      return hd->platform_ops->hwdom_init(d);
>  }
> --
> 2.7.4
>
diff mbox

Patch

diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 19c87d1..f5e5b7e 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -52,7 +52,7 @@  custom_param("iommu", parse_iommu_param);
 bool_t __initdata iommu_enable = 1;
 bool_t __read_mostly iommu_enabled;
 bool_t __read_mostly force_iommu;
-bool_t __hwdom_initdata iommu_dom0_strict;
+bool_t __read_mostly iommu_dom0_strict;
 bool_t __read_mostly iommu_verbose;
 bool_t __read_mostly iommu_workaround_bios_bug;
 bool_t __read_mostly iommu_igfx = 1;
@@ -141,6 +141,15 @@  int iommu_domain_init(struct domain *d, bool use_iommu)
     if ( !iommu_enabled )
         return 0;
 
+    if ( is_hardware_domain(d) )
+    {
+        if ( (paging_mode_translate(d) && !iommu_passthrough) ||
+              iommu_dom0_strict )
+            use_iommu = 1;
+        else
+            use_iommu = 0;
+    }
+
     hd->platform_ops = iommu_get_ops();
     ret = hd->platform_ops->init(d, use_iommu);
     if ( ret )
@@ -161,8 +170,6 @@  static void __hwdom_init check_hwdom_reqs(struct domain *d)
     if ( iommu_passthrough )
         panic("Dom0 uses paging translated mode, dom0-passthrough must not be "
               "enabled\n");
-
-    iommu_dom0_strict = 1;
 }
 
 void __hwdom_init iommu_hwdom_init(struct domain *d)
@@ -175,37 +182,6 @@  void __hwdom_init iommu_hwdom_init(struct domain *d)
         return;
 
     register_keyhandler('o', &iommu_dump_p2m_table, "dump iommu p2m table", 0);
-    d->need_iommu = !!iommu_dom0_strict;
-    if ( need_iommu(d) && !iommu_use_hap_pt(d) )
-    {
-        struct page_info *page;
-        unsigned int i = 0;
-        int rc = 0;
-
-        page_list_for_each ( page, &d->page_list )
-        {
-            unsigned long mfn = page_to_mfn(page);
-            unsigned long gfn = mfn_to_gmfn(d, mfn);
-            unsigned int mapping = IOMMUF_readable;
-            int ret;
-
-            if ( ((page->u.inuse.type_info & PGT_count_mask) == 0) ||
-                 ((page->u.inuse.type_info & PGT_type_mask)
-                  == PGT_writable_page) )
-                mapping |= IOMMUF_writable;
-
-            ret = hd->platform_ops->map_pages(d, gfn, mfn, 0, mapping);
-            if ( !rc )
-                rc = ret;
-
-            if ( !(i++ & 0xfffff) )
-                process_pending_softirqs();
-        }
-
-        if ( rc )
-            printk(XENLOG_WARNING "d%d: IOMMU mapping failed: %d\n",
-                   d->domain_id, rc);
-    }
 
     return hd->platform_ops->hwdom_init(d);
 }