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

[Xen-devel] [PATCH 16/22] vixen: pass grant table operations through to the outer Xen



From: Anthony Liguori <aliguori@xxxxxxxxxx>

The grant table is a region of guest memory that contains GMFNs
which in PV are MFNs but are PFNs in HVM.  Since a Vixen guest MFN
is an HVM PFN, we can pass this table directly through to the outer
Xen which cuts down considerably on overhead.

We do not forward most of the hypercalls since we only intend on
Vixen to be used for normal guests, not driver domains.

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
---
 xen/common/grant_table.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 250450b..b302fd0 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -39,6 +39,7 @@
 #include <xen/vmap.h>
 #include <xsm/xsm.h>
 #include <asm/flushtlb.h>
+#include <asm/guest.h>
 
 /* Per-domain grant information. */
 struct grant_table {
@@ -1199,6 +1200,9 @@ gnttab_map_grant_ref(
     int i;
     struct gnttab_map_grant_ref op;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     for ( i = 0; i < count; i++ )
     {
         if ( i && hypercall_preempt_check() )
@@ -1502,6 +1506,9 @@ gnttab_unmap_grant_ref(
     struct gnttab_unmap_grant_ref op;
     struct gnttab_unmap_common common[GNTTAB_UNMAP_BATCH_SIZE];
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     while ( count != 0 )
     {
         c = min(count, (unsigned int)GNTTAB_UNMAP_BATCH_SIZE);
@@ -1567,6 +1574,9 @@ gnttab_unmap_and_replace(
     struct gnttab_unmap_and_replace op;
     struct gnttab_unmap_common common[GNTTAB_UNMAP_BATCH_SIZE];
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     while ( count != 0 )
     {
         c = min(count, (unsigned int)GNTTAB_UNMAP_BATCH_SIZE);
@@ -1801,6 +1811,80 @@ grant_table_init(struct domain *d, struct grant_table 
*gt,
 }
 
 static long
+vixen_gnttab_setup_table(
+    XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count)
+{
+    long rc;
+
+    struct gnttab_setup_table op;
+    xen_pfn_t *frame_list = NULL;
+    static void *grant_table;
+    XEN_GUEST_HANDLE(xen_pfn_t) old_frame_list;
+
+    if ( count != 1 )
+        return -EINVAL;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+    {
+        gdprintk(XENLOG_INFO, "Fault while reading gnttab_setup_table_t.\n");
+        return -EFAULT;
+    }
+
+    if ( grant_table == NULL ) {
+        struct xen_add_to_physmap xatp;
+        struct domain *d;
+        int i;
+
+        for ( i = 0; i < max_grant_frames; i++ )
+        {
+             grant_table = alloc_xenheap_page();
+             BUG_ON(grant_table == NULL);
+             xatp.domid = DOMID_SELF;
+             xatp.idx = i;
+             xatp.space = XENMAPSPACE_grant_table;
+             xatp.gpfn = virt_to_mfn(grant_table);
+             rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+             if ( rc != 0 )
+                 printk("Add to physmap failed! %ld\n", rc);
+
+             d = rcu_lock_current_domain();
+             share_xen_page_with_guest(mfn_to_page(xatp.gpfn), d, 
XENSHARE_writable);
+             rcu_unlock_domain(d);
+        }
+    }
+
+    if ( op.nr_frames > 0 ) {
+        frame_list = xzalloc_array(xen_pfn_t, op.nr_frames);
+        if ( frame_list == NULL )
+            return -ENOMEM;
+    }
+
+    old_frame_list = op.frame_list;
+    op.frame_list.p = frame_list;
+
+    rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &op, count);
+    op.frame_list = old_frame_list;
+
+    if ( rc >= 0 ) {
+        if ( op.status == 0 && op.nr_frames &&
+             copy_to_guest(old_frame_list, frame_list, op.nr_frames) != 0 ) {
+            rc = -EFAULT;
+            goto out;
+        }
+
+        if ( unlikely(copy_to_guest(uop, &op, 1)) != 0 ) {
+            rc = -EFAULT;
+            goto out;
+        }
+    }
+
+ out:
+    xfree(frame_list);
+
+    return rc;
+}
+
+static long
 gnttab_setup_table(
     XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count,
     unsigned int limit_max)
@@ -1811,6 +1895,9 @@ gnttab_setup_table(
     struct grant_table *gt;
     unsigned int i;
 
+    if ( is_vixen() )
+        return vixen_gnttab_setup_table(uop, count);
+
     if ( count != 1 )
         return -EINVAL;
 
@@ -1892,6 +1979,26 @@ gnttab_setup_table(
 }
 
 static long
+vixen_gnttab_query_size(
+    XEN_GUEST_HANDLE_PARAM(gnttab_query_size_t) uop, unsigned int count)
+{
+    struct gnttab_query_size op;
+    int rc;
+
+    if ( count != 1 )
+        return -EINVAL;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1)) != 0)
+        return -EFAULT;
+
+    rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &op, count);
+    if (rc == 0 && unlikely(__copy_to_guest(uop, &op, 1)) )
+        rc = -EFAULT;
+
+    return rc;
+}
+
+static long
 gnttab_query_size(
     XEN_GUEST_HANDLE_PARAM(gnttab_query_size_t) uop, unsigned int count)
 {
@@ -1902,6 +2009,9 @@ gnttab_query_size(
     if ( count != 1 )
         return -EINVAL;
 
+    if ( is_vixen() )
+        return vixen_gnttab_query_size(uop, count);
+
     if ( unlikely(copy_from_guest(&op, uop, 1)) )
         return -EFAULT;
 
@@ -2015,6 +2125,9 @@ gnttab_transfer(
     unsigned int max_bitsize;
     struct active_grant_entry *act;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     for ( i = 0; i < count; i++ )
     {
         bool_t okay;
@@ -2816,6 +2929,9 @@ static long gnttab_copy(
     struct gnttab_copy_buf dest = {};
     long rc = 0;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     for ( i = 0; i < count; i++ )
     {
         if ( i && hypercall_preempt_check() )
@@ -2869,6 +2985,9 @@ 
gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
     int res;
     unsigned int i;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
@@ -3021,6 +3140,9 @@ 
gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
     if ( count != 1 )
         return -EINVAL;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
     {
         gdprintk(XENLOG_INFO,
@@ -3091,6 +3213,9 @@ 
gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop)
     struct domain *d;
     int rc;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
@@ -3186,6 +3311,9 @@ 
gnttab_swap_grant_ref(XEN_GUEST_HANDLE_PARAM(gnttab_swap_grant_ref_t) uop,
     int i;
     gnttab_swap_grant_ref_t op;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     for ( i = 0; i < count; i++ )
     {
         if ( i && hypercall_preempt_check() )
@@ -3285,6 +3413,9 @@ 
gnttab_cache_flush(XEN_GUEST_HANDLE_PARAM(gnttab_cache_flush_t) uop,
     unsigned int i;
     gnttab_cache_flush_t op;
 
+    if ( is_vixen() )
+        return -ENOSYS;
+
     for ( i = 0; i < count; i++ )
     {
         if ( i && hypercall_preempt_check() )
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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