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

[Xen-changelog] [xen-unstable] xen: Allow granting of foreign access to iomem pages, and with



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1195579608 0
# Node ID 2e5d922b7ee3d80b513c641b6e7a50aae7d1a058
# Parent  f62e6c697eeb68a7a62f4beb87e85a68b91b3c6a
xen: Allow granting of foreign access to iomem pages, and with
arbitrary cache attributes.
Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/mm.c                |   12 ++-
 xen/arch/powerpc/mm.c                 |    7 +-
 xen/arch/x86/mm.c                     |   31 ++++-----
 xen/common/grant_table.c              |  108 ++++++++++++++++++++++------------
 xen/include/asm-ia64/grant_table.h    |    3 
 xen/include/asm-powerpc/grant_table.h |    4 -
 xen/include/asm-x86/grant_table.h     |    4 -
 xen/include/public/grant_table.h      |    7 ++
 8 files changed, 111 insertions(+), 65 deletions(-)

diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/arch/ia64/xen/mm.c    Tue Nov 20 17:26:48 2007 +0000
@@ -2144,16 +2144,18 @@ dom0vp_unexpose_foreign_p2m(struct domai
 // mfn: frame: machine page frame
 // flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte
 int
-create_grant_host_mapping(unsigned long gpaddr,
-              unsigned long mfn, unsigned int flags)
+create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
+                          unsigned int flags, unsigned int cache_flags)
 {
     struct domain* d = current->domain;
     struct page_info* page;
     int ret;
 
-    if (flags & (GNTMAP_device_map |
-                 GNTMAP_application_map | GNTMAP_contains_pte)) {
-        gdprintk(XENLOG_INFO, "%s: flags 0x%x\n", __func__, flags);
+    if ((flags & (GNTMAP_device_map | 
+                  GNTMAP_application_map | GNTMAP_contains_pte)) ||
+        (cache_flags)) {
+        gdprintk(XENLOG_INFO, "%s: flags 0x%x cache_flags 0x%x\n",
+                 __func__, flags, cache_flags);
         return GNTST_general_error;
     }
 
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/arch/powerpc/mm.c     Tue Nov 20 17:26:48 2007 +0000
@@ -168,7 +168,7 @@ static int destroy_grant_va_mapping(
 }
 
 int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags)
+    unsigned long addr, unsigned long frame, unsigned int flags, unsigned int 
cache_flags)
 {
     if (flags & GNTMAP_application_map) {
         printk("%s: GNTMAP_application_map not supported\n", __func__);
@@ -177,6 +177,11 @@ int create_grant_host_mapping(
     }
     if (flags & GNTMAP_contains_pte) {
         printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+    if (cache_flags) {
+        printk("%s: cache_flags not supported\n", __func__);
         BUG();
         return GNTST_general_error;
     }
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/arch/x86/mm.c Tue Nov 20 17:26:48 2007 +0000
@@ -645,11 +645,7 @@ get_page_from_l1e(
             return 0;
         }
 
-        /* No reference counting for out-of-range I/O pages. */
-        if ( !mfn_valid(mfn) )
-            return 1;
-
-        d = dom_io;
+        return 1;
     }
 
     /* Foreign mappings into guests in shadow external mode don't
@@ -667,9 +663,8 @@ get_page_from_l1e(
                 mfn, get_gpfn_from_mfn(mfn),
                 l1e_get_intpte(l1e), d->domain_id);
     }
-    else if ( (pte_flags_to_cacheattr(l1f) !=
-               ((page->count_info >> PGC_cacheattr_base) & 7)) &&
-              !is_iomem_page(mfn) )
+    else if ( pte_flags_to_cacheattr(l1f) !=
+              ((page->count_info >> PGC_cacheattr_base) & 7) )
     {
         uint32_t x, nx, y = page->count_info;
         uint32_t cacheattr = pte_flags_to_cacheattr(l1f);
@@ -848,13 +843,15 @@ get_page_from_l4e(
 
 void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
 {
-    unsigned long    pfn  = l1e_get_pfn(l1e);
-    struct page_info *page = mfn_to_page(pfn);
-    struct domain   *e;
-    struct vcpu     *v;
-
-    if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !mfn_valid(pfn) )
+    unsigned long     pfn = l1e_get_pfn(l1e);
+    struct page_info *page;
+    struct domain    *e;
+    struct vcpu      *v;
+
+    if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || is_iomem_page(pfn) )
         return;
+
+    page = mfn_to_page(pfn);
 
     e = page_get_owner(page);
 
@@ -2763,8 +2760,8 @@ static int destroy_grant_va_mapping(
     return replace_grant_va_mapping(addr, frame, l1e_empty(), v);
 }
 
-int create_grant_host_mapping(
-    uint64_t addr, unsigned long frame, unsigned int flags)
+int create_grant_host_mapping(uint64_t addr, unsigned long frame, 
+                              unsigned int flags, unsigned int cache_flags)
 {
     l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
 
@@ -2772,6 +2769,8 @@ int create_grant_host_mapping(
         l1e_add_flags(pte,_PAGE_USER);
     if ( !(flags & GNTMAP_readonly) )
         l1e_add_flags(pte,_PAGE_RW);
+
+    l1e_add_flags(pte, cacheattr_to_pte_flags(cache_flags >> 5));
 
     if ( flags & GNTMAP_contains_pte )
         return create_grant_pte_mapping(addr, pte, current);
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/common/grant_table.c  Tue Nov 20 17:26:48 2007 +0000
@@ -198,6 +198,7 @@ __gnttab_map_grant_ref(
     int            handle;
     unsigned long  frame = 0;
     int            rc = GNTST_okay;
+    unsigned int   cache_flags;
     struct active_grant_entry *act;
     struct grant_mapping *mt;
     grant_entry_t *sha;
@@ -326,36 +327,58 @@ __gnttab_map_grant_ref(
 
     frame = act->frame;
 
+    cache_flags = (sha->flags & (GTF_PAT | GTF_PWT | GTF_PCD) );
+
     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 ( is_iomem_page(frame) )
+    {
+        if ( !iomem_access_permitted(rd, frame, frame) )
+        {
+            gdprintk(XENLOG_WARNING,
+                     "Iomem mapping not permitted %lx (domain %d)\n", 
+                     frame, rd->domain_id);
+            rc = GNTST_general_error;
+            goto undo_out;
+        }
+
+        rc = create_grant_host_mapping(
+            op->host_addr, frame, op->flags, cache_flags);
+        if ( rc != GNTST_okay )
+            goto undo_out;
+    }
+    else
+    {
+        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));
-            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, 0);
+            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);
+            }
         }
     }
 
@@ -559,10 +582,13 @@ __gnttab_unmap_common_complete(struct gn
 
     if ( op->flags & GNTMAP_device_map ) 
     {
-        if ( op->flags & GNTMAP_readonly )
-            put_page(mfn_to_page(op->frame));
-        else
-            put_page_and_type(mfn_to_page(op->frame));
+        if ( !is_iomem_page(act->frame) )
+        {
+            if ( op->flags & GNTMAP_readonly )
+                put_page(mfn_to_page(op->frame));
+            else
+                put_page_and_type(mfn_to_page(op->frame));
+        }
     }
 
     if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) )
@@ -576,10 +602,12 @@ __gnttab_unmap_common_complete(struct gn
             goto unmap_out;
         }
 
-        if ( op->flags & GNTMAP_readonly )
+        if ( !is_iomem_page(op->frame) ) 
+        {
+            if ( !(op->flags & GNTMAP_readonly) )
+                put_page_type(mfn_to_page(op->frame));
             put_page(mfn_to_page(op->frame));
-        else
-            put_page_and_type(mfn_to_page(op->frame));
+        }
     }
 
     if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
@@ -1595,14 +1623,16 @@ gnttab_release_mappings(
             {
                 BUG_ON(!(act->pin & GNTPIN_devr_mask));
                 act->pin -= GNTPIN_devr_inc;
-                put_page(mfn_to_page(act->frame));
+                if ( !is_iomem_page(act->frame) )
+                    put_page(mfn_to_page(act->frame));
             }
 
             if ( map->flags & GNTMAP_host_map )
             {
                 BUG_ON(!(act->pin & GNTPIN_hstr_mask));
                 act->pin -= GNTPIN_hstr_inc;
-                gnttab_release_put_page(mfn_to_page(act->frame));
+                if ( !is_iomem_page(act->frame) )
+                    gnttab_release_put_page(mfn_to_page(act->frame));
             }
         }
         else
@@ -1611,14 +1641,16 @@ gnttab_release_mappings(
             {
                 BUG_ON(!(act->pin & GNTPIN_devw_mask));
                 act->pin -= GNTPIN_devw_inc;
-                put_page_and_type(mfn_to_page(act->frame));
+                if ( !is_iomem_page(act->frame) )
+                    put_page_and_type(mfn_to_page(act->frame));
             }
 
             if ( map->flags & GNTMAP_host_map )
             {
                 BUG_ON(!(act->pin & GNTPIN_hstw_mask));
                 act->pin -= GNTPIN_hstw_inc;
-                gnttab_release_put_page_and_type(mfn_to_page(act->frame));
+                if ( !is_iomem_page(act->frame) )
+                    gnttab_release_put_page_and_type(mfn_to_page(act->frame));
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-ia64/grant_table.h
--- a/xen/include/asm-ia64/grant_table.h        Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/include/asm-ia64/grant_table.h        Tue Nov 20 17:26:48 2007 +0000
@@ -8,7 +8,8 @@
 #define INITIAL_NR_GRANT_FRAMES 1
 
 // for grant map/unmap
-int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
unsigned int flags);
+int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
+                             unsigned int flags, unsigned int cache_flags);
 int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
unsigned long new_gpaddr, unsigned int flags);
 
 // for grant transfer
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-powerpc/grant_table.h
--- a/xen/include/asm-powerpc/grant_table.h     Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/include/asm-powerpc/grant_table.h     Tue Nov 20 17:26:48 2007 +0000
@@ -33,8 +33,8 @@ extern long pte_remove(ulong flags, ulon
 extern long pte_remove(ulong flags, ulong ptex, ulong avpn,
                        ulong *hi, ulong *lo);
 
-int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags);
+int create_grant_host_mapping(unsigned long addr, unsigned long frame, 
+                             unsigned int flags, unsigned int cache_flags);
 int replace_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned long new_addr,
     unsigned int flags);
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/include/asm-x86/grant_table.h Tue Nov 20 17:26:48 2007 +0000
@@ -13,8 +13,8 @@
  * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and
  * must hold a reference to the page.
  */
-int create_grant_host_mapping(
-    uint64_t addr, unsigned long frame, unsigned int flags);
+int create_grant_host_mapping(uint64_t addr, unsigned long frame,
+                             unsigned int flags, unsigned int cache_flags);
 int replace_grant_host_mapping(
     uint64_t addr, unsigned long frame, uint64_t new_addr, unsigned int flags);
 
diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Tue Nov 20 15:34:25 2007 +0000
+++ b/xen/include/public/grant_table.h  Tue Nov 20 17:26:48 2007 +0000
@@ -119,6 +119,7 @@ typedef struct grant_entry grant_entry_t
  *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
  *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
  *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
+ *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
  */
 #define _GTF_readonly       (2)
 #define GTF_readonly        (1U<<_GTF_readonly)
@@ -126,6 +127,12 @@ typedef struct grant_entry grant_entry_t
 #define GTF_reading         (1U<<_GTF_reading)
 #define _GTF_writing        (4)
 #define GTF_writing         (1U<<_GTF_writing)
+#define _GTF_PWT            (5)
+#define GTF_PWT             (1U<<_GTF_PWT)
+#define _GTF_PCD            (6)
+#define GTF_PCD             (1U<<_GTF_PCD)
+#define _GTF_PAT            (7)
+#define GTF_PAT             (1U<<_GTF_PAT)
 
 /*
  * Subflags for GTF_accept_transfer:

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


 


Rackspace

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