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

[Xen-changelog] Make some basic cases of grant tables work in shadow translate mode.



# HG changeset patch
# User sos22@xxxxxxxxxxxxxxxxxxxx
# Node ID cc9bb3e0e348e6484d6fa2bc43b4900c6a40da79
# Parent  407358daf3898067df46434cb0fd8e160370d9f4
Make some basic cases of grant tables work in shadow translate mode.
This is enough to get block devices to work.

Note that this involves assigning PFNs to the machine frames used for
the grant table structures.  While I'm here, I also assigned a PFN to
the shared info frame.

Signed-off-by: Steven Smith, sos22@xxxxxxxxx

diff -r 407358daf389 -r cc9bb3e0e348 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Jan 25 16:41:22 2006
+++ b/tools/libxc/xc_linux_build.c      Wed Jan 25 17:57:44 2006
@@ -3,6 +3,7 @@
  */
 
 #include "xg_private.h"
+#include "xc_private.h"
 #include <xenctrl.h>
 
 #if defined(__i386__)
@@ -31,6 +32,8 @@
 #define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 #endif
+
+#define NR_GRANT_FRAMES 4
 
 #ifdef __ia64__
 #define get_tot_pages xc_get_max_pages
@@ -504,6 +507,8 @@
         goto error_out;
     }
 
+    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
+                                   "SHADOW=translate");
     /*
      * Why do we need this? The number of page-table frames depends on the 
      * size of the bootstrap address space. But the size of the address space 
@@ -587,7 +592,7 @@
         goto error_out;
     }
 
-    if ( (page_array = malloc((nr_pages + 1) * sizeof(unsigned long))) == NULL 
)
+    if ( (page_array = malloc((nr_pages + 1 + NR_GRANT_FRAMES) * 
sizeof(unsigned long))) == NULL )
     {
         PERROR("Could not allocate memory");
         goto error_out;
@@ -622,19 +627,23 @@
     if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
-    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
-                                   "SHADOW=translate");
-
     /* Write the phys->machine and machine->phys table entries. */
     physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
     physmap = physmap_e = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
         page_array[physmap_pfn++]);
 
-    if (shadow_mode_enabled)
-        page_array[nr_pages] = shared_info_frame;
-
-    for ( count = 0; count < nr_pages + shadow_mode_enabled; count++ )
+    page_array[nr_pages] = shared_info_frame;
+
+    if ( xc_get_gnttab_frames(xc_handle,
+                              dom,
+                              page_array + 1 + nr_pages,
+                              NR_GRANT_FRAMES) <= 0) {
+        fprintf(stderr, "cannot get grant table frames\n");
+        goto error_out;
+    }
+
+    for ( count = 0; count < nr_pages + 1 + NR_GRANT_FRAMES; count++ )
     {
         if ( xc_add_mmu_update(
             xc_handle, mmu,
diff -r 407358daf389 -r cc9bb3e0e348 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Wed Jan 25 16:41:22 2006
+++ b/tools/libxc/xc_private.c  Wed Jan 25 17:57:44 2006
@@ -314,6 +314,35 @@
     return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
 }
 
+int xc_get_gnttab_frames(int xc_handle,
+                         uint32_t domid,
+                         unsigned long *pfn_buf,
+                         unsigned long max_pfns)
+{
+    DECLARE_DOM0_OP;
+    int ret;
+    op.cmd = DOM0_GETGNTTABLIST;
+    op.u.getgnttablist.domain   = (domid_t)domid;
+    op.u.getgnttablist.max_pfns = max_pfns;
+    op.u.getgnttablist.buffer   = pfn_buf;
+
+#ifdef VALGRIND
+    memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
+#endif
+
+    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
+    {
+        PERROR("xc_get_pfn_list: pfn_buf mlock failed");
+        return -1;
+    }
+
+    ret = do_dom0_op(xc_handle, &op);
+
+    safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
+
+    return (ret < 0) ? -1 : op.u.getgnttablist.num_pfns;
+}
+
 long xc_get_tot_pages(int xc_handle, uint32_t domid)
 {
     DECLARE_DOM0_OP;
diff -r 407358daf389 -r cc9bb3e0e348 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Wed Jan 25 16:41:22 2006
+++ b/tools/libxc/xc_private.h  Wed Jan 25 17:57:44 2006
@@ -111,6 +111,9 @@
     return ret;
 }
 
+int xc_get_gnttab_frames(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
+                        unsigned long max_pfns);
+
 
 /*
  * ioctl-based mfn mapping interface
diff -r 407358daf389 -r cc9bb3e0e348 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Wed Jan 25 16:41:22 2006
+++ b/xen/arch/x86/dom0_ops.c   Wed Jan 25 17:57:44 2006
@@ -330,6 +330,38 @@
     }
     break;
 
+    case DOM0_GETGNTTABLIST:
+    {
+        int i;
+        struct domain *d = find_domain_by_id(op->u.getgnttablist.domain);
+        unsigned long max_pfns = op->u.getgnttablist.max_pfns;
+        unsigned long pfn;
+        unsigned long *buffer = op->u.getgnttablist.buffer;
+
+        ret = -EINVAL;
+        if ( d != NULL )
+        {
+            ret = 0;
+
+            for ( i = 0; i < max_pfns && i < NR_GRANT_FRAMES; i++ )
+            {
+               pfn = gnttab_shared_mfn(d, d->grant_table, i);
+                if ( put_user(pfn, buffer) )
+                {
+                    ret = -EFAULT;
+                    break;
+                }
+                buffer++;
+            }
+
+            op->u.getgnttablist.num_pfns = i;
+            copy_to_user(u_dom0_op, op, sizeof(*op));
+
+            put_domain(d);
+        }
+    }
+    break;
+
     case DOM0_GETMEMLIST:
     {
         int i;
diff -r 407358daf389 -r cc9bb3e0e348 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Jan 25 16:41:22 2006
+++ b/xen/common/grant_table.c  Wed Jan 25 17:57:44 2006
@@ -481,6 +481,7 @@
     gnttab_setup_table_t  op;
     struct domain        *d;
     int                   i;
+    unsigned long         mfn;
 
     if ( count != 1 )
         return -EINVAL;
@@ -520,9 +521,12 @@
     {
         ASSERT(d->grant_table != NULL);
         (void)put_user(GNTST_okay, &uop->status);
-        for ( i = 0; i < op.nr_frames; i++ )
-            (void)put_user(gnttab_shared_mfn(d, d->grant_table, i),
-                           &op.frame_list[i]);
+        for ( i = 0; i < op.nr_frames; i++ ) {
+            mfn = gnttab_shared_mfn(d, d->grant_table, i);
+            if (shadow_mode_translate(d))
+                mfn = __mfn_to_gpfn(d, mfn);
+            (void)put_user(mfn, &op.frame_list[i]);
+        }
     }
 
     put_domain(d);
diff -r 407358daf389 -r cc9bb3e0e348 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Wed Jan 25 16:41:22 2006
+++ b/xen/include/public/dom0_ops.h     Wed Jan 25 17:57:44 2006
@@ -430,7 +430,17 @@
     domid_t  domain;          /* domain to be affected */
     unsigned long mfn;        /* machine frame to be initialised */
 } dom0_hypercall_init_t;
- 
+
+#define DOM0_GETGNTTABLIST    49
+typedef struct {
+    /* IN variables. */
+    domid_t       domain;
+    unsigned long max_pfns;
+    void         *buffer;
+    /* OUT variables. */
+    unsigned long num_pfns;
+} dom0_getgnttablist_t;
+
 typedef struct {
     uint32_t cmd;
     uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
@@ -472,6 +482,7 @@
         dom0_irq_permission_t    irq_permission;
         dom0_iomem_permission_t  iomem_permission;
         dom0_hypercall_init_t    hypercall_init;
+        dom0_getgnttablist_t     getgnttablist;
         uint8_t                  pad[128];
     } u;
 } dom0_op_t;

_______________________________________________
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®.