WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Handle dynamic IOMMU map/unmap for guests

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Handle dynamic IOMMU map/unmap for guests
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 24 May 2008 07:00:14 -0700
Delivery-date: Sat, 24 May 2008 07:00:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1211618522 -3600
# Node ID c684cf331f94573ff5829d9701141cf17414b2b8
# Parent  62f1c837057f33e1e58f90bbe90f33335a89558f
Handle dynamic IOMMU map/unmap for guests

Perform IOMMU map/unmap when (a) frame type changes, (b) memory
reservation changes, and (c) a grant reference is newly mapped or
completely unmapped from a domain.

Signed-off-by: Espen Skoglund <espen.skoglund@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm.c        |   14 +++++++++++++
 xen/arch/x86/mm/p2m.c    |   21 +++++++++++++++++--
 xen/common/grant_table.c |   50 ++++++++++++++++++++++++++++++++++++++++-------
 xen/common/memory.c      |   17 +++++----------
 4 files changed, 82 insertions(+), 20 deletions(-)

diff -r 62f1c837057f -r c684cf331f94 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sat May 24 09:37:35 2008 +0100
+++ b/xen/arch/x86/mm.c Sat May 24 09:42:02 2008 +0100
@@ -1939,6 +1939,20 @@ int get_page_type(struct page_info *page
     }
     while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
 
+    if ( unlikely((x & PGT_type_mask) != type) )
+    {
+        /* Special pages should not be accessible from devices. */
+        struct domain *d = page_get_owner(page);
+        if ( 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)));
+            else if ( type == PGT_writable_page )
+                iommu_map_page(d, mfn_to_gmfn(d, page_to_mfn(page)),
+                               page_to_mfn(page));
+        }
+    }
+
     if ( unlikely(!(nx & PGT_validated)) )
     {
         /* Try to validate page type; drop the new reference on failure. */
diff -r 62f1c837057f -r c684cf331f94 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c     Sat May 24 09:37:35 2008 +0100
+++ b/xen/arch/x86/mm/p2m.c     Sat May 24 09:42:02 2008 +0100
@@ -325,7 +325,7 @@ p2m_set_entry(struct domain *d, unsigned
     if ( mfn_valid(mfn) && (gfn > d->arch.p2m->max_mapped_pfn) )
         d->arch.p2m->max_mapped_pfn = gfn;
 
-    if ( iommu_enabled && is_hvm_domain(d) )
+    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )
     {
         if ( p2mt == p2m_ram_rw )
             for ( i = 0; i < (1UL << page_order); i++ )
@@ -868,7 +868,12 @@ p2m_remove_page(struct domain *d, unsign
     unsigned long i;
 
     if ( !paging_mode_translate(d) )
+    {
+        if ( need_iommu(d) )
+            for ( i = 0; i < (1 << page_order); i++ )
+                iommu_unmap_page(d, mfn + i);
         return;
+    }
 
     P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
 
@@ -899,7 +904,19 @@ guest_physmap_add_entry(struct domain *d
     int rc = 0;
 
     if ( !paging_mode_translate(d) )
-        return -EINVAL;
+    {
+        if ( need_iommu(d) && t == p2m_ram_rw )
+        {
+            for ( i = 0; i < (1 << page_order); i++ )
+                if ( (rc = iommu_map_page(d, mfn + i, mfn + i)) != 0 )
+                {
+                    while ( i-- > 0 )
+                        iommu_unmap_page(d, mfn + i);
+                    return rc;
+                }
+        }
+        return 0;
+    }
 
 #if CONFIG_PAGING_LEVELS == 3
     /*
diff -r 62f1c837057f -r c684cf331f94 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Sat May 24 09:37:35 2008 +0100
+++ b/xen/common/grant_table.c  Sat May 24 09:42:02 2008 +0100
@@ -196,8 +196,9 @@ __gnttab_map_grant_ref(
     struct domain *ld, *rd;
     struct vcpu   *led;
     int            handle;
-    unsigned long  frame = 0;
+    unsigned long  frame = 0, nr_gets = 0;
     int            rc = GNTST_okay;
+    u32            old_pin;
     unsigned int   cache_flags;
     struct active_grant_entry *act;
     struct grant_mapping *mt;
@@ -318,6 +319,7 @@ __gnttab_map_grant_ref(
         }
     }
 
+    old_pin = act->pin;
     if ( op->flags & GNTMAP_device_map )
         act->pin += (op->flags & GNTMAP_readonly) ?
             GNTPIN_devr_inc : GNTPIN_devw_inc;
@@ -361,20 +363,17 @@ __gnttab_map_grant_ref(
             rc = GNTST_general_error;
             goto undo_out;
         }
-        
+
+        nr_gets++;
         if ( op->flags & GNTMAP_host_map )
         {
             rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
             if ( rc != GNTST_okay )
-            {
-                if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
-                    put_page_type(mfn_to_page(frame));
-                put_page(mfn_to_page(frame));
                 goto undo_out;
-            }
 
             if ( op->flags & GNTMAP_device_map )
             {
+                nr_gets++;
                 (void)get_page(mfn_to_page(frame), rd);
                 if ( !(op->flags & GNTMAP_readonly) )
                     get_page_type(mfn_to_page(frame), PGT_writable_page);
@@ -382,6 +381,17 @@ __gnttab_map_grant_ref(
         }
     }
 
+    if ( need_iommu(ld) &&
+         !(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) &&
+         (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
+    {
+        if ( iommu_map_page(ld, mfn_to_gmfn(ld, frame), frame) )
+        {
+            rc = GNTST_general_error;
+            goto undo_out;
+        }
+    }
+
     TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, op->dom);
 
     mt = &maptrack_entry(ld->grant_table, handle);
@@ -397,6 +407,19 @@ __gnttab_map_grant_ref(
     return;
 
  undo_out:
+    if ( nr_gets > 1 )
+    {
+        if ( !(op->flags & GNTMAP_readonly) )
+            put_page_type(mfn_to_page(frame));
+        put_page(mfn_to_page(frame));
+    }
+    if ( nr_gets > 0 )
+    {
+        if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
+            put_page_type(mfn_to_page(frame));
+        put_page(mfn_to_page(frame));
+    }
+
     spin_lock(&rd->grant_table->lock);
 
     act = &active_entry(rd->grant_table, op->ref);
@@ -451,6 +474,7 @@ __gnttab_unmap_common(
     struct active_grant_entry *act;
     grant_entry_t   *sha;
     s16              rc = 0;
+    u32              old_pin;
 
     ld = current->domain;
 
@@ -497,6 +521,7 @@ __gnttab_unmap_common(
 
     act = &active_entry(rd->grant_table, op->map->ref);
     sha = &shared_entry(rd->grant_table, op->map->ref);
+    old_pin = act->pin;
 
     if ( op->frame == 0 )
     {
@@ -532,6 +557,17 @@ __gnttab_unmap_common(
             act->pin -= GNTPIN_hstr_inc;
         else
             act->pin -= GNTPIN_hstw_inc;
+    }
+
+    if ( need_iommu(ld) &&
+         (old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) &&
+         !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
+    {
+        if ( iommu_unmap_page(ld, mfn_to_gmfn(ld, op->frame)) )
+        {
+            rc = GNTST_general_error;
+            goto unmap_out;
+        }
     }
 
     /* If just unmapped a writable mapping, mark as dirtied */
diff -r 62f1c837057f -r c684cf331f94 xen/common/memory.c
--- a/xen/common/memory.c       Sat May 24 09:37:35 2008 +0100
+++ b/xen/common/memory.c       Sat May 24 09:42:02 2008 +0100
@@ -124,12 +124,9 @@ static void populate_physmap(struct memo
         }
 
         mfn = page_to_mfn(page);
-
-        if ( unlikely(paging_mode_translate(d)) )
-        {
-            guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
-        }
-        else
+        guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+
+        if ( !paging_mode_translate(d) )
         {
             for ( j = 0; j < (1 << a->extent_order); j++ )
                 set_gpfn_from_mfn(mfn + j, gpfn + j);
@@ -436,11 +433,9 @@ static long memory_exchange(XEN_GUEST_HA
                 &gpfn, exch.out.extent_start, (i<<out_chunk_order)+j, 1);
 
             mfn = page_to_mfn(page);
-            if ( unlikely(paging_mode_translate(d)) )
-            {
-                guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
-            }
-            else
+            guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+
+            if ( !paging_mode_translate(d) )
             {
                 for ( k = 0; k < (1UL << exch.out.extent_order); k++ )
                     set_gpfn_from_mfn(mfn + k, gpfn + k);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Handle dynamic IOMMU map/unmap for guests, Xen patchbot-unstable <=