[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/3] TLB flushing and IO memory mapping



Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx> 

Allow iomem permissions to be set up through grant table ops

diff -r 749b60ccc177 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/arch/x86/mm.c Wed Jul 25 14:03:12 2007 +0100
@@ -594,6 +594,14 @@ get_##level##_linear_pagetable(         
     return 1;
\
 }
 
+
+int iomem_page_test(unsigned long mfn, struct page_info *page)
+{
+    return unlikely(!mfn_valid(mfn)) ||
+        unlikely(page_get_owner(page) == dom_io);
+}
+
+
 int
 get_page_from_l1e(
     l1_pgentry_t l1e, struct domain *d)
@@ -611,8 +619,7 @@ get_page_from_l1e(
         return 0;
     }
 
-    if ( unlikely(!mfn_valid(mfn)) ||
-         unlikely(page_get_owner(page) == dom_io) )
+    if ( iomem_page_test(mfn, page) )
     {
         /* DOMID_IO reverts to caller for privilege checks. */
         if ( d == dom_io )
diff -r 749b60ccc177 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/common/grant_table.c  Mon Jul 30 10:28:27 2007 +0100
@@ -199,6 +199,7 @@ __gnttab_map_grant_ref(
     int            handle;
     unsigned long  frame = 0;
     int            rc = GNTST_okay;
+    int            is_iomem = 0;
     struct active_grant_entry *act;
     struct grant_mapping *mt;
     grant_entry_t *sha;
@@ -327,34 +328,52 @@ __gnttab_map_grant_ref(
 
     spin_unlock(&rd->grant_table->lock);
 
-    if ( unlikely(!mfn_valid(frame)) ||
-         unlikely(!((op->flags & GNTMAP_readonly) ?
-                    get_page(mfn_to_page(frame), rd) :
-                    get_page_and_type(mfn_to_page(frame), rd,
-                                      PGT_writable_page))) )
-    {
-        if ( !rd->is_dying )
-            gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
frame);
-        rc = GNTST_general_error;
-        goto undo_out;
-    }
-
-    if ( op->flags & GNTMAP_host_map )
-    {
-        rc = create_grant_host_mapping(op->host_addr, frame, op-
>flags);
-        if ( rc != GNTST_okay )
-        {
-            if ( !(op->flags & GNTMAP_readonly) )
-                put_page_type(mfn_to_page(frame));
-            put_page(mfn_to_page(frame));
+    if ( op->flags & GNTMAP_host_map ) 
+    {
+        /* Could be an iomem page for setting up permission */
+        if( iomem_page_test(frame, mfn_to_page(frame)) ) {
+            is_iomem = 1;
+            if ( iomem_permit_access(ld, frame, frame) ) {
+                gdprintk(XENLOG_WARNING, 
+                         "Could not permit access to grant frame %lx as
iomem\n",
+                         frame);
+                rc = GNTST_general_error;
+                goto undo_out;
+            }
+        }
+    } 
+
+    if (!is_iomem ) 
+    {
+        if ( unlikely(!mfn_valid(frame)) ||
+             unlikely(!((op->flags & GNTMAP_readonly) ?
+                        get_page(mfn_to_page(frame), rd) :
+                        get_page_and_type(mfn_to_page(frame), rd,
+                                          PGT_writable_page))))
+        {
+            if ( !rd->is_dying )
+                gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx
\n", frame);
+            rc = GNTST_general_error;
             goto undo_out;
         }
-
-        if ( op->flags & GNTMAP_device_map )
-        {
-            (void)get_page(mfn_to_page(frame), rd);
-            if ( !(op->flags & GNTMAP_readonly) )
-                get_page_type(mfn_to_page(frame), PGT_writable_page);
+        
+        if ( op->flags & GNTMAP_host_map )
+        {
+            rc = create_grant_host_mapping(op->host_addr, frame, op-
>flags);
+            if ( rc != GNTST_okay )
+            {
+                if ( !(op->flags & GNTMAP_readonly) )
+                    put_page_type(mfn_to_page(frame));
+                put_page(mfn_to_page(frame));
+                goto undo_out;
+            }
+
+            if ( op->flags & GNTMAP_device_map )
+            {
+                (void)get_page(mfn_to_page(frame), rd);
+                if ( !(op->flags & GNTMAP_readonly) )
+                    get_page_type(mfn_to_page(frame),
PGT_writable_page);
+            }
         }
     }
 
@@ -474,7 +493,8 @@ __gnttab_unmap_common(
     {
         if ( unlikely(op->frame != act->frame) )
             PIN_FAIL(unmap_out, GNTST_general_error,
-                     "Bad frame number doesn't match gntref.\n");
+                     "Bad frame number doesn't match gntref. (%lx != %
lx)\n",
+                     op->frame, act->frame);
         if ( op->flags & GNTMAP_device_map )
         {
             ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
@@ -486,12 +506,21 @@ __gnttab_unmap_common(
         }
     }
 
-    if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) )
-    {
-        if ( (rc = replace_grant_host_mapping(op->host_addr,
-                                              op->frame, op->new_addr, 
-                                              op->flags)) < 0 )
-            goto unmap_out;
+    if ( op->flags & GNTMAP_host_map )
+    {
+        if ( (op->host_addr != 0) )
+        {
+            if ( (rc = replace_grant_host_mapping(op->host_addr,
+                                                  op->frame, op-
>new_addr, 
+                                                  op->flags)) < 0 )
+                goto unmap_out;
+        }
+        else if ( iomem_page_test(op->frame, mfn_to_page(op->frame)) &&
+                  iomem_access_permitted(ld, op->frame, op->frame) )
+        {
+            if ( (rc = iomem_deny_access(ld, op->frame, op->frame)) <
0 )
+                goto unmap_out;
+        }
 
         ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
         op->map->flags &= ~GNTMAP_host_map;
@@ -499,7 +528,7 @@ __gnttab_unmap_common(
             act->pin -= GNTPIN_hstr_inc;
         else
             act->pin -= GNTPIN_hstw_inc;
-    }
+    } 
 
     /* If just unmapped a writable mapping, mark as dirtied */
     if ( !(op->flags & GNTMAP_readonly) )
@@ -1538,6 +1567,7 @@ gnttab_release_mappings(
     struct domain        *rd;
     struct active_grant_entry *act;
     struct grant_entry   *sha;
+    int rc;
 
     BUG_ON(!d->is_dying);
 
@@ -1595,7 +1625,12 @@ gnttab_release_mappings(
             {
                 BUG_ON(!(act->pin & GNTPIN_hstw_mask));
                 act->pin -= GNTPIN_hstw_inc;
-                gnttab_release_put_page_and_type(mfn_to_page(act-
>frame));
+
+                if ( iomem_page_test(act->frame, mfn_to_page(act-
>frame)) &&
+                     iomem_access_permitted(rd, act->frame, act-
>frame) )
+                    rc = iomem_deny_access(rd, act->frame, act->frame);
+                else 
+                    gnttab_release_put_page_and_type(mfn_to_page(act-
>frame));
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) ==
0 )
diff -r 749b60ccc177 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/include/asm-x86/mm.h  Wed Jul 25 14:03:12 2007 +0100
@@ -197,6 +197,9 @@ static inline int get_page(struct page_i
     return 1;
 }
 
+/* Decide whether this page looks like iomem or real memory */
+int iomem_page_test(unsigned long mfn, struct page_info *page);
+
 void put_page_type(struct page_info *page);
 int  get_page_type(struct page_info *page, unsigned long type);
 int  get_page_from_l1e(l1_pgentry_t l1e, struct domain *d);

Attachment: iomem_grants
Description: Text document

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.