All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 8] Xen-side netchannel2 patches, take two
@ 2009-10-06 15:35 steven.smith
  2009-10-06 15:35 ` [PATCH 1 of 8] Simplify include/xen/grant_table.h a bit: steven.smith
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

This patch series includes all of the Xen and tools bits of
netchannel2.  It's essentially similar to the one I posted on Sunday,
except:

-- I've dropped the unmodified drivers support.  It'd probably be
   fairly straightforward to re-introduce it, but it's not clear that
   anyone's actually using unmodified drivers any more (they don't
   even build against a 2.6.27 kernel, for instance).

-- I've switched to using uint64_t for page numbers in the public
   structures, because uint32_t is no longer enough now that Xen
   supports sparse physical memory.

-- The gnttab_get_status_frames structure now uses a
   GUEST_HANDLE(uint64_t) for the pointer to the status frames array,
   rather than a straight uint64_t.

The problems which these changes fix were all pointed out by Jan
Beulich (thanks!).

Most of these patches are unchanged since last time, but I'm reposting
all of them just to keep everything together.  The only one with
substantial changes is number 5:

changeset:   20275:842baf721920
tag:         introduce-grant_entry_v2
user:        Steven Smith <steven.smith@eu.citrix.com>
date:        Mon Sep 22 12:23:28 2008 +0100
files:       tools/libxc/xc_linux.c tools/libxc/xc_offline_page.c tools/libxc/xenctrl.h xen/arch/x86/hvm/hvm.c xen/arch/x86/mm.c xen/common/compat/grant_table.c xen/common/grant_table.c xen/include/Makefile xen/include/asm-x86/grant_table.h xen/include/public/grant_table.h xen/include/public/memory.h xen/include/public/xen.h xen/include/xen/grant_table.h xen/include/xlat.lst
description:
Introduce a grant_entry_v2 structure.

Signed-off-by: Steven Smith <steven.smith@citrix.com>


There are also minor changes to the next two patches, mostly just
compensating for renamed fields in structures.



I've also fixed up the Linux patch queues to match the new interface,
but won't be posting the new queues, because they're rather large and
have no substantial changes from last time.  Instead, I've pushed the
changed queues to the git repos:

git://xenbits.xensource.com/people/ssmith/nc2-2.6.27.git branch
pq_for_merge (for the XCI 2.6.27 tree)

git://xenbits.xensource.com/people/ssmith/netchannel2-pvops.git branch
nc2/fixed_v2_grant_table_interface (for the upstream git tree)


If people would prefer I repost the whole series then I can do that as
well.


I think this should cover all of the review comments; please shout at
me if I've missed anything.

Steven.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1 of 8] Simplify include/xen/grant_table.h a bit:
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 2 of 8] Slightly more accurate dependency tracking for the .c and .h files in steven.smith
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 2127 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222082607 -3600
# Node ID 5f2f5565914573282437bb31f790ffac1169755c
# Parent  6f63970032a3fe5fda585beba929d2d7a5e14861
Simplify include/xen/grant_table.h a bit:

-- INITIAL_GRANT_ENTRIES is never used, so can be removed.
-- Simplify num_act_frames_from_sha_frames a little.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r 6f63970032a3 -r 5f2f55659145 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h	Fri Oct 02 09:10:27 2009 +0100
+++ b/xen/include/xen/grant_table.h	Mon Sep 22 12:23:27 2008 +0100
@@ -52,10 +52,6 @@
 #define GNTPIN_devr_shift    (24)
 #define GNTPIN_devr_inc      (1 << GNTPIN_devr_shift)
 #define GNTPIN_devr_mask     (0xFFU << GNTPIN_devr_shift)
-
-/* Initial size of a grant table. */
-#define INITIAL_NR_GRANT_ENTRIES ((INITIAL_NR_GRANT_FRAMES << PAGE_SHIFT) / \
-                                     sizeof(grant_entry_t))
 
 #ifndef DEFAULT_MAX_NR_GRANT_FRAMES /* to allow arch to override */
 /* Default maximum size of a grant table. [POLICY] */
@@ -128,16 +124,13 @@
 num_act_frames_from_sha_frames(const unsigned int num)
 {
     /* How many frames are needed for the active grant table,
-     * given the size of the shared grant table?
-     *
-     * act_per_page = PAGE_SIZE / sizeof(active_grant_entry_t);
-     * sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
-     * num_sha_entries = num * sha_per_page;
-     * num_act_frames = (num_sha_entries + (act_per_page-1)) / act_per_page;
-     */
-    return ((num * (PAGE_SIZE / sizeof(grant_entry_t))) +
-            ((PAGE_SIZE / sizeof(struct active_grant_entry))-1))
-           / (PAGE_SIZE / sizeof(struct active_grant_entry));
+     * given the size of the shared grant table? */
+    unsigned act_per_page = PAGE_SIZE / sizeof(struct active_grant_entry);
+    unsigned sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
+    unsigned num_sha_entries = num * sha_per_page;
+    unsigned num_act_frames =
+        (num_sha_entries + (act_per_page-1)) / act_per_page;
+    return num_act_frames;
 }
 
 static inline unsigned int

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2 of 8] Slightly more accurate dependency tracking for the .c and .h files in
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
  2009-10-06 15:35 ` [PATCH 1 of 8] Simplify include/xen/grant_table.h a bit: steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 3 of 8] Optimize memcpy for x86 arch. If source buffers does not start at a 64 steven.smith
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 1265 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222082607 -3600
# Node ID c630fa8e84bdb0e1a79f7ccc42733ef5ea247cd2
# Parent  5f2f5565914573282437bb31f790ffac1169755c
Slightly more accurate dependency tracking for the .c and .h files in
include/compat.  They should depend on the scripts which generate
them, as well as the inputs to those scripts.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r 5f2f55659145 -r c630fa8e84bd xen/include/Makefile
--- a/xen/include/Makefile	Mon Sep 22 12:23:27 2008 +0100
+++ b/xen/include/Makefile	Mon Sep 22 12:23:27 2008 +0100
@@ -44,7 +44,7 @@
 .PHONY: all
 all: $(headers-y)
 
-compat/%.h: compat/%.i Makefile
+compat/%.h: compat/%.i Makefile $(BASEDIR)/tools/compat-build-header.py
 	set -e; id=_$$(echo $@ | tr '[:lower:]-/.' '[:upper:]___'); \
 	echo "#ifndef $$id" >$@.new; \
 	echo "#define $$id" >>$@.new; \
@@ -60,7 +60,7 @@
 compat/%.i: compat/%.c Makefile
 	$(CPP) $(filter-out -M% .%.d,$(CFLAGS)) $(cppflags-y) -o $@ $<
 
-compat/%.c: public/%.h xlat.lst Makefile
+compat/%.c: public/%.h xlat.lst Makefile $(BASEDIR)/tools/compat-build-source.py
 	mkdir -p $(@D)
 	grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
 	$(PYTHON) $(BASEDIR)/tools/compat-build-source.py >$@.new

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3 of 8] Optimize memcpy for x86 arch. If source buffers does not start at a 64
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
  2009-10-06 15:35 ` [PATCH 1 of 8] Simplify include/xen/grant_table.h a bit: steven.smith
  2009-10-06 15:35 ` [PATCH 2 of 8] Slightly more accurate dependency tracking for the .c and .h files in steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 4 of 8] Rename the struct grant_entry to struct grant_entry_v1, so that it steven.smith
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 1568 bytes --]

# HG changeset patch
# User root@iov15.hpl.hp.com
# Date 1221082224 25200
# Node ID 999da363259a122e0c15bf28a0885ec40751e906
# Parent  c630fa8e84bdb0e1a79f7ccc42733ef5ea247cd2
Optimize memcpy for x86 arch. If source buffers does not start at a 64
bit boundary, copy a few bytes at the beginnig up to next 64-bit
boundary and then does an aligned copy for the remaining data. This
can reduce the copy cost by up to 50%.

Signed-off-by: Jose Renato Santos <jsantos@hpl.hp.com>

diff -r c630fa8e84bd -r 999da363259a xen/include/asm-x86/string.h
--- a/xen/include/asm-x86/string.h	Mon Sep 22 12:23:27 2008 +0100
+++ b/xen/include/asm-x86/string.h	Wed Sep 10 14:30:24 2008 -0700
@@ -96,13 +96,29 @@
 }
 
 #define __HAVE_ARCH_MEMCPY
+/* align source to a 64-bit boundary */
+static always_inline
+void *__var_memcpy(void *t, const void *f, size_t n)
+{
+    int off = (unsigned long)f & 0x7;
+    /* just do alignment if needed and if size is worth */
+    if ( (n > 32) && off ) {
+        size_t n1 = 8 - off;
+        __variable_memcpy(t, f, n1);
+        __variable_memcpy(t + n1, f + n1, n - n1);
+        return t;
+    } else {
+            return (__variable_memcpy(t, f, n));
+    }
+}
+
 #define memcpy(t,f,n) (__memcpy((t),(f),(n)))
 static always_inline
 void *__memcpy(void *t, const void *f, size_t n)
 {
     return (__builtin_constant_p(n) ?
             __constant_memcpy((t),(f),(n)) :
-            __variable_memcpy((t),(f),(n)));
+            __var_memcpy((t),(f),(n)));
 }
 
 /* Some version of gcc don't have this builtin. It's non-critical anyway. */

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 4 of 8] Rename the struct grant_entry to struct grant_entry_v1, so that it
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (2 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 3 of 8] Optimize memcpy for x86 arch. If source buffers does not start at a 64 steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 5 of 8] Introduce a grant_entry_v2 structure steven.smith
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 10220 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222082608 -3600
# Node ID 1df819bcf08654a2f23e88ce22295caf7806d65c
# Parent  999da363259a122e0c15bf28a0885ec40751e906
Rename the struct grant_entry to struct grant_entry_v1, so that it
isn't in the way when we introduce struct grant_entry_v2.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r 999da363259a -r 1df819bcf086 tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c	Wed Sep 10 14:30:24 2008 -0700
+++ b/tools/libxc/xc_linux.c	Mon Sep 22 12:23:28 2008 +0100
@@ -558,14 +558,14 @@
     return ret;
 }
 
-struct grant_entry *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num)
+struct grant_entry_v1 *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num)
 {
     int rc, i;
     struct gnttab_query_size query;
     struct gnttab_setup_table setup;
     unsigned long *frame_list = NULL;
     xen_pfn_t *pfn_list = NULL;
-    struct grant_entry *gnt = NULL;
+    struct grant_entry_v1 *gnt = NULL;
 
     if (!gnt_num)
         return NULL;
@@ -581,7 +581,7 @@
     }
 
     *gnt_num = query.nr_frames *
-            (PAGE_SIZE / sizeof(struct grant_entry) );
+            (PAGE_SIZE / sizeof(struct grant_entry_v1) );
 
     frame_list = malloc(query.nr_frames * sizeof(unsigned long));
     if (!frame_list || lock_pages(frame_list, query.nr_frames *
diff -r 999da363259a -r 1df819bcf086 tools/libxc/xc_offline_page.c
--- a/tools/libxc/xc_offline_page.c	Wed Sep 10 14:30:24 2008 -0700
+++ b/tools/libxc/xc_offline_page.c	Mon Sep 22 12:23:28 2008 +0100
@@ -133,7 +133,7 @@
   * There should no update to the grant when domain paused
   */
 static int xc_is_page_granted(int xc_handle, xen_pfn_t gpfn,
-                              struct grant_entry *gnttab, int gnt_num)
+                              struct grant_entry_v1 *gnttab, int gnt_num)
 {
     int i = 0;
 
@@ -549,7 +549,7 @@
     struct domain_mem_info minfo;
     struct xc_mmu *mmu = NULL;
     struct pte_backup old_ptes = {NULL, 0, 0};
-    struct grant_entry *gnttab = NULL;
+    struct grant_entry_v1 *gnttab = NULL;
     struct mmuext_op mops;
     int gnt_num, unpined = 0;
     void *old_p, *backup = NULL;
@@ -756,7 +756,7 @@
         free(backup);
 
     if (gnttab)
-        munmap(gnttab, gnt_num / (PAGE_SIZE/sizeof(struct grant_entry)));
+        munmap(gnttab, gnt_num / (PAGE_SIZE/sizeof(struct grant_entry_v1)));
 
     close_mem_info(xc_handle, &minfo);
 
diff -r 999da363259a -r 1df819bcf086 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Wed Sep 10 14:30:24 2008 -0700
+++ b/tools/libxc/xenctrl.h	Mon Sep 22 12:23:28 2008 +0100
@@ -943,7 +943,7 @@
 int xc_gnttab_op(int xc_handle, int cmd,
                  void * op, int op_size, int count);
 
-struct grant_entry *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num);
+struct grant_entry_v1 *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num);
 
 int xc_physdev_map_pirq(int xc_handle,
                         int domid,
diff -r 999da363259a -r 1df819bcf086 xen/common/compat/grant_table.c
--- a/xen/common/compat/grant_table.c	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/common/compat/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
@@ -5,9 +5,9 @@
 
 #include <compat/grant_table.h>
 
-#define xen_grant_entry grant_entry
-CHECK_grant_entry;
-#undef xen_grant_entry
+#define xen_grant_entry_v1 grant_entry_v1
+CHECK_grant_entry_v1;
+#undef xen_grant_entry_v1
 
 #define xen_gnttab_map_grant_ref gnttab_map_grant_ref
 CHECK_gnttab_map_grant_ref;
diff -r 999da363259a -r 1df819bcf086 xen/common/grant_table.c
--- a/xen/common/grant_table.c	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/common/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
@@ -105,7 +105,7 @@
 }
 
 
-#define SHGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_t))
+#define SHGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v1_t))
 #define shared_entry(t, e) \
     ((t)->shared[(e)/SHGNT_PER_PAGE][(e)%SHGNT_PER_PAGE])
 #define ACGNT_PER_PAGE (PAGE_SIZE / sizeof(struct active_grant_entry))
@@ -205,7 +205,7 @@
     unsigned int   cache_flags;
     struct active_grant_entry *act;
     struct grant_mapping *mt;
-    grant_entry_t *sha;
+    grant_entry_v1_t *sha;
     union grant_combo scombo, prev_scombo, new_scombo;
 
     /*
@@ -508,7 +508,7 @@
     domid_t          dom;
     struct domain   *ld, *rd;
     struct active_grant_entry *act;
-    grant_entry_t   *sha;
+    grant_entry_v1_t *sha;
     s16              rc = 0;
     u32              old_pin;
 
@@ -622,7 +622,7 @@
 {
     struct domain   *ld, *rd;
     struct active_grant_entry *act;
-    grant_entry_t   *sha;
+    grant_entry_v1_t *sha;
     struct page_info *pg;
 
     rd = op->rd;
@@ -1046,7 +1046,7 @@
     struct domain *rd, struct domain *ld, grant_ref_t ref)
 {
     struct grant_table *rgt;
-    struct grant_entry *sha;
+    struct grant_entry_v1 *sha;
     union grant_combo   scombo, prev_scombo, new_scombo;
     int                 retries = 0;
 
@@ -1115,7 +1115,7 @@
     struct domain *e;
     struct page_info *page;
     int i;
-    grant_entry_t *sha;
+    grant_entry_v1_t *sha;
     struct gnttab_transfer gop;
     unsigned long mfn;
     unsigned int max_bitsize;
@@ -1278,7 +1278,7 @@
 __release_grant_for_copy(
     struct domain *rd, unsigned long gref, int readonly)
 {
-    grant_entry_t *sha;
+    grant_entry_v1_t *sha;
     struct active_grant_entry *act;
     unsigned long r_frame;
 
@@ -1316,7 +1316,7 @@
     struct domain *rd, unsigned long gref, int readonly,
     unsigned long *frame)
 {
-    grant_entry_t *sha;
+    grant_entry_v1_t *sha;
     struct active_grant_entry *act;
     s16 rc = GNTST_okay;
     int retries = 0;
@@ -1654,7 +1654,7 @@
 
 static unsigned int max_nr_active_grant_frames(void)
 {
-    return (((max_nr_grant_frames * (PAGE_SIZE / sizeof(grant_entry_t))) + 
+    return (((max_nr_grant_frames * (PAGE_SIZE / sizeof(grant_entry_v1_t))) + 
                     ((PAGE_SIZE / sizeof(struct active_grant_entry))-1)) 
                    / (PAGE_SIZE / sizeof(struct active_grant_entry)));
 }
@@ -1667,7 +1667,7 @@
     int                 i;
 
     /* If this sizeof assertion fails, fix the function: shared_index */
-    ASSERT(sizeof(grant_entry_t) == 8);
+    ASSERT(sizeof(grant_entry_v1_t) == 8);
 
     if ( (t = xmalloc(struct grant_table)) == NULL )
         goto no_mem_0;
@@ -1703,7 +1703,7 @@
         t->maptrack[0][i].ref = i+1;
 
     /* Shared grant table. */
-    if ( (t->shared = xmalloc_array(struct grant_entry *,
+    if ( (t->shared = xmalloc_array(struct grant_entry_v1 *,
                                     max_nr_grant_frames)) == NULL )
         goto no_mem_3;
     memset(t->shared, 0, max_nr_grant_frames * sizeof(t->shared[0]));
@@ -1749,7 +1749,7 @@
     grant_handle_t        handle;
     struct domain        *rd;
     struct active_grant_entry *act;
-    struct grant_entry   *sha;
+    struct grant_entry_v1*sha;
     struct page_info     *pg;
 
     BUG_ON(!d->is_dying);
diff -r 999da363259a -r 1df819bcf086 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/include/public/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
@@ -90,7 +90,11 @@
  * [XEN]: This field is written by Xen and read by the sharing guest.
  * [GST]: This field is written by the guest and read by Xen.
  */
-struct grant_entry {
+#if __XEN_INTERFACE_VERSION__ < 0x0003020a
+#define grant_entry_v1 grant_entry
+#define grant_entry_v1_t grant_entry_t
+#endif
+struct grant_entry_v1 {
     /* GTF_xxx: various type and flag information.  [XEN,GST] */
     uint16_t flags;
     /* The domain being granted foreign privileges. [GST] */
@@ -101,7 +105,7 @@
      */
     uint32_t frame;
 };
-typedef struct grant_entry grant_entry_t;
+typedef struct grant_entry_v1 grant_entry_v1_t;
 
 /*
  * Type of grant entry.
diff -r 999da363259a -r 1df819bcf086 xen/include/public/xen-compat.h
--- a/xen/include/public/xen-compat.h	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/include/public/xen-compat.h	Mon Sep 22 12:23:28 2008 +0100
@@ -27,7 +27,7 @@
 #ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 #define __XEN_PUBLIC_XEN_COMPAT_H__
 
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030209
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 /* Xen is built with matching headers and implements the latest interface. */
diff -r 999da363259a -r 1df819bcf086 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/include/xen/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
@@ -80,7 +80,7 @@
     /* Table size. Number of frames shared with guest */
     unsigned int          nr_grant_frames;
     /* Shared grant table (see include/public/grant_table.h). */
-    struct grant_entry  **shared;
+    struct grant_entry_v1 **shared;
     /* Active grant table. */
     struct active_grant_entry **active;
     /* Mapping tracking table. */
@@ -117,7 +117,7 @@
 /* Number of grant table entries. Caller must hold d's grant table lock. */
 static inline unsigned int nr_grant_entries(struct grant_table *gt)
 {
-    return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_t);
+    return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v1_t);
 }
 
 static inline unsigned int
@@ -126,7 +126,7 @@
     /* How many frames are needed for the active grant table,
      * given the size of the shared grant table? */
     unsigned act_per_page = PAGE_SIZE / sizeof(struct active_grant_entry);
-    unsigned sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
+    unsigned sha_per_page = PAGE_SIZE / sizeof(grant_entry_v1_t);
     unsigned num_sha_entries = num * sha_per_page;
     unsigned num_act_frames =
         (num_sha_entries + (act_per_page-1)) / act_per_page;
diff -r 999da363259a -r 1df819bcf086 xen/include/xlat.lst
--- a/xen/include/xlat.lst	Wed Sep 10 14:30:24 2008 -0700
+++ b/xen/include/xlat.lst	Mon Sep 22 12:23:28 2008 +0100
@@ -44,7 +44,7 @@
 !	gnttab_transfer			grant_table.h
 ?	gnttab_unmap_grant_ref		grant_table.h
 ?	gnttab_unmap_and_replace	grant_table.h
-?	grant_entry			grant_table.h
+?	grant_entry_v1			grant_table.h
 ?	kexec_exec			kexec.h
 !	kexec_image			kexec.h
 !	kexec_range			kexec.h

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 5 of 8] Introduce a grant_entry_v2 structure
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (3 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 4 of 8] Rename the struct grant_entry to struct grant_entry_v1, so that it steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 6 of 8] Implement sub-page grant support steven.smith
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 55633 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222082608 -3600
# Node ID 842baf721920b032f358ad326145817b42d053a1
# Parent  1df819bcf08654a2f23e88ce22295caf7806d65c
Introduce a grant_entry_v2 structure.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r 1df819bcf086 -r 842baf721920 tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/tools/libxc/xc_linux.c	Mon Sep 22 12:23:28 2008 +0100
@@ -558,7 +558,21 @@
     return ret;
 }
 
-struct grant_entry_v1 *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num)
+int xc_gnttab_get_version(int xc_handle, int domid)
+{
+    struct gnttab_get_version query;
+    int rc;
+
+    query.dom = domid;
+    rc = xc_gnttab_op(xc_handle, GNTTABOP_get_version,
+                      &query, sizeof(query), 1);
+    if (rc < 0)
+        return rc;
+    else
+        return query.version;
+}
+
+static void *_gnttab_map_table(int xc_handle, int domid, int *gnt_num)
 {
     int rc, i;
     struct gnttab_query_size query;
@@ -638,6 +652,22 @@
     return gnt;
 }
 
+struct grant_entry_v1 *xc_gnttab_map_table_v1(int xc_handle, int domid,
+                                              int *gnt_num)
+{
+    if (xc_gnttab_get_version(xc_handle, domid) == 2)
+        return NULL;
+    return _gnttab_map_table(xc_handle, domid, gnt_num);
+}
+
+struct grant_entry_v2 *xc_gnttab_map_table_v2(int xc_handle, int domid,
+                                              int *gnt_num)
+{
+    if (xc_gnttab_get_version(xc_handle, domid) != 2)
+        return NULL;
+    return _gnttab_map_table(xc_handle, domid, gnt_num);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 1df819bcf086 -r 842baf721920 tools/libxc/xc_offline_page.c
--- a/tools/libxc/xc_offline_page.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/tools/libxc/xc_offline_page.c	Mon Sep 22 12:23:28 2008 +0100
@@ -132,8 +132,8 @@
  /*
   * There should no update to the grant when domain paused
   */
-static int xc_is_page_granted(int xc_handle, xen_pfn_t gpfn,
-                              struct grant_entry_v1 *gnttab, int gnt_num)
+static int xc_is_page_granted_v1(int xc_handle, xen_pfn_t gpfn,
+                                 struct grant_entry_v1 *gnttab, int gnt_num)
 {
     int i = 0;
 
@@ -142,6 +142,22 @@
 
     for (i = 0; i < gnt_num; i++)
         if ( ((gnttab[i].flags & GTF_type_mask) !=  GTF_invalid) &&
+             (gnttab[i].frame == gpfn) )
+             break;
+
+   return (i != gnt_num);
+}
+
+static int xc_is_page_granted_v2(int xc_handle, xen_pfn_t gpfn,
+                                 struct grant_entry_v2 *gnttab, int gnt_num)
+{
+    int i = 0;
+
+    if (!gnttab)
+        return 0;
+
+    for (i = 0; i < gnt_num; i++)
+        if ( ((gnttab[i].hdr.flags & GTF_type_mask) !=  GTF_invalid) &&
              (gnttab[i].frame == gpfn) )
              break;
 
@@ -549,7 +565,8 @@
     struct domain_mem_info minfo;
     struct xc_mmu *mmu = NULL;
     struct pte_backup old_ptes = {NULL, 0, 0};
-    struct grant_entry_v1 *gnttab = NULL;
+    struct grant_entry_v1 *gnttab_v1 = NULL;
+    struct grant_entry_v2 *gnttab_v2 = NULL;
     struct mmuext_op mops;
     int gnt_num, unpined = 0;
     void *old_p, *backup = NULL;
@@ -588,14 +605,20 @@
             goto failed;
     }
 
-    gnttab = xc_gnttab_map_table(xc_handle, domid, &gnt_num);
-    if (!gnttab)
+    gnttab_v2 = xc_gnttab_map_table_v2(xc_handle, domid, &gnt_num);
+    if (!gnttab_v2)
     {
-        ERROR("Failed to map grant table\n");
-        goto failed;
+        gnttab_v1 = xc_gnttab_map_table_v1(xc_handle, domid, &gnt_num);
+        if (!gnttab_v1)
+        {
+            ERROR("Failed to map grant table\n");
+            goto failed;
+        }
     }
 
-    if (xc_is_page_granted(xc_handle, mfn, gnttab, gnt_num))
+    if (gnttab_v1
+        ? xc_is_page_granted_v1(xc_handle, mfn, gnttab_v1, gnt_num)
+        : xc_is_page_granted_v2(xc_handle, mfn, gnttab_v2, gnt_num))
     {
         ERROR("Page %lx is granted now\n", mfn);
         goto failed;
@@ -755,8 +778,10 @@
     if (backup)
         free(backup);
 
-    if (gnttab)
-        munmap(gnttab, gnt_num / (PAGE_SIZE/sizeof(struct grant_entry_v1)));
+    if (gnttab_v1)
+        munmap(gnttab_v1, gnt_num / (PAGE_SIZE/sizeof(struct grant_entry_v1)));
+    if (gnttab_v2)
+        munmap(gnttab_v2, gnt_num / (PAGE_SIZE/sizeof(struct grant_entry_v2)));
 
     close_mem_info(xc_handle, &minfo);
 
diff -r 1df819bcf086 -r 842baf721920 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/tools/libxc/xenctrl.h	Mon Sep 22 12:23:28 2008 +0100
@@ -943,7 +943,9 @@
 int xc_gnttab_op(int xc_handle, int cmd,
                  void * op, int op_size, int count);
 
-struct grant_entry_v1 *xc_gnttab_map_table(int xc_handle, int domid, int *gnt_num);
+int xc_gnttab_get_version(int xc_handle, int domid);
+struct grant_entry_v1 *xc_gnttab_map_table_v1(int xc_handle, int domid, int *gnt_num);
+struct grant_entry_v2 *xc_gnttab_map_table_v2(int xc_handle, int domid, int *gnt_num);
 
 int xc_physdev_map_pirq(int xc_handle,
                         int domid,
diff -r 1df819bcf086 -r 842baf721920 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/arch/x86/hvm/hvm.c	Mon Sep 22 12:23:28 2008 +0100
@@ -2084,12 +2084,26 @@
     return hvm_intblk_none;
 }
 
+static int grant_table_op_is_allowed(unsigned int cmd)
+{
+    switch (cmd) {
+    case GNTTABOP_query_size:
+    case GNTTABOP_setup_table:
+    case GNTTABOP_set_version:
+    case GNTTABOP_copy:
+    case GNTTABOP_map_grant_ref:
+    case GNTTABOP_unmap_grant_ref:
+        return 1;
+    default:
+        /* all other commands need auditing */
+        return 0;
+    }
+}
+
 static long hvm_grant_table_op(
     unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count)
 {
-    if ( (cmd != GNTTABOP_query_size) && (cmd != GNTTABOP_setup_table) &&
-         (cmd != GNTTABOP_map_grant_ref) && (cmd != GNTTABOP_unmap_grant_ref) &&
-         (cmd != GNTTABOP_copy))
+    if ( !grant_table_op_is_allowed(cmd) )
         return -ENOSYS; /* all other commands need auditing */
     return do_grant_table_op(cmd, uop, count);
 }
@@ -2141,13 +2155,12 @@
 
 #else /* defined(__x86_64__) */
 
-static long hvm_grant_table_op_compat32(
-    unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count)
+static long hvm_grant_table_op_compat32(unsigned int cmd,
+                                        XEN_GUEST_HANDLE(void) uop,
+                                        unsigned int count)
 {
-    if ( (cmd != GNTTABOP_query_size) && (cmd != GNTTABOP_setup_table) &&
-         (cmd != GNTTABOP_map_grant_ref) && (cmd != GNTTABOP_unmap_grant_ref) &&
-         (cmd != GNTTABOP_copy))
-        return -ENOSYS; /* all other commands need auditing */
+    if ( !grant_table_op_is_allowed(cmd) )
+        return -ENOSYS;
     return compat_grant_table_op(cmd, uop, count);
 }
 
diff -r 1df819bcf086 -r 842baf721920 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/arch/x86/mm.c	Mon Sep 22 12:23:28 2008 +0100
@@ -4000,12 +4000,25 @@
         case XENMAPSPACE_grant_table:
             spin_lock(&d->grant_table->lock);
 
-            if ( (xatp.idx >= nr_grant_frames(d->grant_table)) &&
-                 (xatp.idx < max_nr_grant_frames) )
-                gnttab_grow_table(d, xatp.idx + 1);
-
-            if ( xatp.idx < nr_grant_frames(d->grant_table) )
-                mfn = virt_to_mfn(d->grant_table->shared[xatp.idx]);
+            if ( d->grant_table->gt_version == 0 )
+                d->grant_table->gt_version = 1;
+
+            if ( d->grant_table->gt_version == 2 &&
+                 (xatp.idx & XENMAPIDX_grant_table_status) )
+            {
+                xatp.idx &= ~XENMAPIDX_grant_table_status;
+                if ( xatp.idx < nr_status_frames(d->grant_table) )
+                    mfn = virt_to_mfn(d->grant_table->status[xatp.idx]);
+            }
+            else
+            {
+                if ( (xatp.idx >= nr_grant_frames(d->grant_table)) &&
+                     (xatp.idx < max_nr_grant_frames) )
+                    gnttab_grow_table(d, xatp.idx + 1);
+
+                if ( xatp.idx < nr_grant_frames(d->grant_table) )
+                    mfn = virt_to_mfn(d->grant_table->shared_raw[xatp.idx]);
+            }
 
             spin_unlock(&d->grant_table->lock);
             break;
diff -r 1df819bcf086 -r 842baf721920 xen/common/compat/grant_table.c
--- a/xen/common/compat/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/common/compat/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
@@ -8,6 +8,14 @@
 #define xen_grant_entry_v1 grant_entry_v1
 CHECK_grant_entry_v1;
 #undef xen_grant_entry_v1
+
+#define xen_grant_entry_header grant_entry_header
+CHECK_grant_entry_header;
+#undef xen_grant_entry_header
+
+#define xen_grant_entry_v2 grant_entry_v2
+CHECK_grant_entry_v2;
+#undef xen_grant_entry_v2
 
 #define xen_gnttab_map_grant_ref gnttab_map_grant_ref
 CHECK_gnttab_map_grant_ref;
@@ -28,6 +36,16 @@
 #define xen_gnttab_dump_table gnttab_dump_table
 CHECK_gnttab_dump_table;
 #undef xen_gnttab_dump_table
+
+#define xen_gnttab_set_version gnttab_set_version
+CHECK_gnttab_set_version;
+#undef xen_gnttab_set_version
+
+DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_compat_t);
+
+#define xen_gnttab_get_version gnttab_get_version
+CHECK_gnttab_get_version;
+#undef xen_gnttab_get_version
 
 int compat_grant_table_op(unsigned int cmd,
                           XEN_GUEST_HANDLE(void) cmp_uop,
@@ -76,6 +94,10 @@
     CASE(dump_table);
 #endif
 
+#ifndef CHECK_gnttab_get_status_frames
+    CASE(get_status_frames);
+#endif
+
 #undef CASE
     default:
         return do_grant_table_op(cmd, cmp_uop, count);
@@ -92,11 +114,13 @@
             struct gnttab_setup_table *setup;
             struct gnttab_transfer *xfer;
             struct gnttab_copy *copy;
+            struct gnttab_get_status_frames *get_status;
         } nat;
         union {
             struct compat_gnttab_setup_table setup;
             struct compat_gnttab_transfer xfer;
             struct compat_gnttab_copy copy;
+            struct compat_gnttab_get_status_frames get_status;
         } cmp;
 
         set_xen_guest_handle(nat.uop, COMPAT_ARG_XLAT_VIRT_BASE);
@@ -233,6 +257,63 @@
             }
             break;
 
+        case GNTTABOP_get_status_frames: {
+            unsigned int max_frame_list_size_in_pages =
+                (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.get_status)) /
+                sizeof(*nat.get_status->frame_list.p);
+            if ( count != 1)
+            {
+                rc = -EINVAL;
+                break;
+            }
+            if ( unlikely(__copy_from_guest(&cmp.get_status, cmp_uop, 1) ||
+                          !compat_handle_okay(cmp.get_status.frame_list,
+                                              cmp.get_status.nr_frames)) )
+            {
+                rc = -EFAULT;
+                break;
+            }
+            if ( max_frame_list_size_in_pages <
+                 grant_to_status_frames(max_nr_grant_frames) )
+            {
+                gdprintk(XENLOG_WARNING,
+                         "grant_to_status_frames(max_nr_grant_frames) is too large (%u,%u)\n",
+                         grant_to_status_frames(max_nr_grant_frames),
+                         max_frame_list_size_in_pages);
+                rc = -EINVAL;
+                break;
+            }
+
+#define XLAT_gnttab_get_status_frames_HNDL_frame_list(_d_, _s_) \
+            set_xen_guest_handle((_d_)->frame_list, (uint64_t *)(nat.get_status + 1))
+            XLAT_gnttab_get_status_frames(nat.get_status, &cmp.get_status);
+#undef XLAT_gnttab_get_status_frames_HNDL_frame_list
+
+            rc = gnttab_get_status_frames(
+                guest_handle_cast(nat.uop, gnttab_get_status_frames_t),
+                count);
+            if ( rc >= 0 )
+            {
+#define XLAT_gnttab_get_status_frames_HNDL_frame_list(_d_, _s_) \
+                do \
+                { \
+                    if ( (_s_)->status == GNTST_okay ) \
+                    { \
+                        for ( i = 0; i < (_s_)->nr_frames; ++i ) \
+                        { \
+                            uint64_t frame = (_s_)->frame_list.p[i]; \
+                            (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
+                        } \
+                    } \
+                } while (0)
+                XLAT_gnttab_get_status_frames(&cmp.get_status, nat.get_status);
+#undef XLAT_gnttab_get_status_frames_HNDL_frame_list
+                if ( unlikely(__copy_to_guest(cmp_uop, &cmp.get_status, 1)) )
+                    rc = -EFAULT;
+            }
+            break;
+        }
+
         default:
             domain_crash(current->domain);
             break;
diff -r 1df819bcf086 -r 842baf721920 xen/common/grant_table.c
--- a/xen/common/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/common/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
@@ -105,9 +105,24 @@
 }
 
 
-#define SHGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v1_t))
-#define shared_entry(t, e) \
-    ((t)->shared[(e)/SHGNT_PER_PAGE][(e)%SHGNT_PER_PAGE])
+#define SHGNT_PER_PAGE_V1 (PAGE_SIZE / sizeof(grant_entry_v1_t))
+#define shared_entry_v1(t, e) \
+    ((t)->shared_v1[(e)/SHGNT_PER_PAGE_V1][(e)%SHGNT_PER_PAGE_V1])
+#define SHGNT_PER_PAGE_V2 (PAGE_SIZE / sizeof(grant_entry_v2_t))
+#define shared_entry_v2(t, e) \
+    ((t)->shared_v2[(e)/SHGNT_PER_PAGE_V2][(e)%SHGNT_PER_PAGE_V2])
+#define STGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
+#define status_entry(t, e) \
+    ((t)->status[(e)/STGNT_PER_PAGE][(e)%STGNT_PER_PAGE])
+static grant_entry_header_t *
+shared_entry_header(struct grant_table *t, grant_ref_t ref)
+{
+    ASSERT(t->gt_version != 0);
+    if (t->gt_version == 1)
+        return (grant_entry_header_t*)&shared_entry_v1(t, ref);
+    else
+        return &shared_entry_v2(t, ref).hdr;
+}
 #define ACGNT_PER_PAGE (PAGE_SIZE / sizeof(struct active_grant_entry))
 #define active_entry(t, e) \
     ((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE])
@@ -183,6 +198,174 @@
     return handle;
 }
 
+/* Number of grant table entries. Caller must hold d's grant table lock. */
+static unsigned int nr_grant_entries(struct grant_table *gt)
+{
+    ASSERT(gt->gt_version != 0);
+    if (gt->gt_version == 1)
+        return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v1_t);
+    else
+        return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v2_t);
+}
+
+static int _set_status_v1(domid_t  domid,
+                          int readonly,
+                          grant_entry_header_t *shah, 
+                          struct active_grant_entry *act)
+{
+    int rc = GNTST_okay;
+    union grant_combo scombo, prev_scombo, new_scombo;
+    uint16_t mask = GTF_type_mask;
+
+    /*
+     * We bound the number of times we retry CMPXCHG on memory locations that
+     * we share with a guest OS. The reason is that the guest can modify that
+     * location at a higher rate than we can read-modify-CMPXCHG, so the guest
+     * could cause us to livelock. There are a few cases where it is valid for
+     * the guest to race our updates (e.g., to change the GTF_readonly flag),
+     * so we allow a few retries before failing.
+     */
+    int retries = 0;
+
+    scombo.word = *(u32 *)shah;
+
+    /*
+     * This loop attempts to set the access (reading/writing) flags
+     * in the grant table entry.  It tries a cmpxchg on the field
+     * up to five times, and then fails under the assumption that 
+     * the guest is misbehaving.
+     */
+    for ( ; ; )
+    {
+        /* If not already pinned, check the grant domid and type. */
+        if ( !act->pin &&
+             (((scombo.shorts.flags & mask) !=
+               GTF_permit_access) ||
+              (scombo.shorts.domid != domid)) )
+            PIN_FAIL(done, GNTST_general_error,
+                     "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+                     scombo.shorts.flags, scombo.shorts.domid,
+                     domid);
+
+        new_scombo = scombo;
+        new_scombo.shorts.flags |= GTF_reading;
+
+        if ( !readonly )
+        {
+            new_scombo.shorts.flags |= GTF_writing;
+            if ( unlikely(scombo.shorts.flags & GTF_readonly) )
+                PIN_FAIL(done, GNTST_general_error,
+                         "Attempt to write-pin a r/o grant entry.\n");
+        }
+
+        prev_scombo.word = cmpxchg((u32 *)shah,
+                                   scombo.word, new_scombo.word);
+        if ( likely(prev_scombo.word == scombo.word) )
+            break;
+
+        if ( retries++ == 4 )
+            PIN_FAIL(done, GNTST_general_error,
+                     "Shared grant entry is unstable.\n");
+
+        scombo = prev_scombo;
+    }
+
+done:
+    return rc;
+}
+
+static int _set_status_v2(domid_t  domid,
+                          int readonly,
+                          grant_entry_header_t *shah, 
+                          struct active_grant_entry *act,
+                          grant_status_t *status)
+{
+    int      rc    = GNTST_okay;
+    union grant_combo scombo;
+    uint16_t flags = shah->flags;
+    domid_t  id    = shah->domid;
+    uint16_t mask  = GTF_type_mask;
+
+    /* we read flags and domid in a single memory access.
+       this avoids the need for another memory barrier to
+       ensure access to these fields are not reordered */
+    scombo.word = *(u32 *)shah;
+    barrier(); /* but we still need to stop the compiler from turning
+                  it back into two reads */
+    flags = scombo.shorts.flags;
+    id = scombo.shorts.domid;
+
+    /* If not already pinned, check the grant domid and type. */
+    if ( !act->pin &&
+         (((flags & mask) != GTF_permit_access) ||
+          (id != domid)) )
+        PIN_FAIL(done, GNTST_general_error,
+                 "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+                 flags, id, domid);
+
+    if ( readonly )
+    {
+        *status |= GTF_reading;
+    }
+    else
+    {
+        if ( unlikely(flags & GTF_readonly) )
+            PIN_FAIL(done, GNTST_general_error,
+                     "Attempt to write-pin a r/o grant entry.\n");
+        *status |= GTF_reading | GTF_writing;
+    }
+
+    /* Make sure guest sees status update before checking if flags are
+       still valid */
+    mb();
+
+    scombo.word = *(u32 *)shah;
+    barrier();
+    flags = scombo.shorts.flags;
+    id = scombo.shorts.domid;
+
+    if ( !act->pin )
+    {
+        if ( ((flags & mask) != GTF_permit_access) ||
+             (id != domid) ||
+             (!readonly && (flags & GTF_readonly)) )
+        {
+            gnttab_clear_flag(_GTF_reading | _GTF_writing, status);
+            PIN_FAIL(done, GNTST_general_error,
+                     "Unstable flags (%x) or dom (%d). (expected dom %d) "
+                     "(r/w: %d)\n",
+                     flags, id, domid, !readonly);
+        }
+    }
+    else
+    {
+        if ( unlikely(flags & GTF_readonly) )
+        {
+            gnttab_clear_flag(_GTF_writing, status);
+            PIN_FAIL(done, GNTST_general_error,
+                     "Unstable grant readonly flag\n");
+        }
+    }
+
+done:
+    return rc;
+}
+
+
+static int _set_status(unsigned gt_version,
+                       domid_t  domid,
+                       int readonly,
+                       grant_entry_header_t *shah,
+                       struct active_grant_entry *act,
+                       grant_status_t *status)
+{
+
+    if (gt_version == 1)
+        return _set_status_v1(domid, readonly, shah, act);
+    else
+        return _set_status_v2(domid, readonly, shah, act, status);
+}
+
 /*
  * Returns 0 if TLB flush / invalidate required by caller.
  * va will indicate the address to be invalidated.
@@ -205,18 +388,10 @@
     unsigned int   cache_flags;
     struct active_grant_entry *act;
     struct grant_mapping *mt;
-    grant_entry_v1_t *sha;
-    union grant_combo scombo, prev_scombo, new_scombo;
-
-    /*
-     * We bound the number of times we retry CMPXCHG on memory locations that
-     * we share with a guest OS. The reason is that the guest can modify that
-     * location at a higher rate than we can read-modify-CMPXCHG, so the guest
-     * could cause us to livelock. There are a few cases where it is valid for
-     * the guest to race our updates (e.g., to change the GTF_readonly flag),
-     * so we allow a few retries before failing.
-     */
-    int retries = 0;
+    grant_entry_v1_t *sha1;
+    grant_entry_v2_t *sha2;
+    grant_entry_header_t *shah;
+    uint16_t *status;
 
     led = current;
     ld = led->domain;
@@ -262,12 +437,25 @@
 
     spin_lock(&rd->grant_table->lock);
 
+    if ( rd->grant_table->gt_version == 0 )
+        PIN_FAIL(unlock_out, GNTST_general_error,
+                 "remote grant table not yet set up");
+
     /* Bounds check on the grant ref */
     if ( unlikely(op->ref >= nr_grant_entries(rd->grant_table)))
         PIN_FAIL(unlock_out, GNTST_bad_gntref, "Bad ref (%d).\n", op->ref);
 
     act = &active_entry(rd->grant_table, op->ref);
-    sha = &shared_entry(rd->grant_table, op->ref);
+    shah = shared_entry_header(rd->grant_table, op->ref);
+    if (rd->grant_table->gt_version == 1) {
+        sha1 = &shared_entry_v1(rd->grant_table, op->ref);
+        sha2 = NULL;
+        status = &shah->flags;
+    } else {
+        sha2 = &shared_entry_v2(rd->grant_table, op->ref);
+        sha1 = NULL;
+        status = &status_entry(rd->grant_table, op->ref);
+    }
 
     /* If already pinned, check the active domid and avoid refcnt overflow. */
     if ( act->pin &&
@@ -281,54 +469,19 @@
          (!(op->flags & GNTMAP_readonly) &&
           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
     {
-        scombo.word = *(u32 *)&sha->flags;
-
-        /*
-         * This loop attempts to set the access (reading/writing) flags
-         * in the grant table entry.  It tries a cmpxchg on the field
-         * up to five times, and then fails under the assumption that 
-         * the guest is misbehaving.
-         */
-        for ( ; ; )
-        {
-            /* If not already pinned, check the grant domid and type. */
-            if ( !act->pin &&
-                 (((scombo.shorts.flags & GTF_type_mask) !=
-                   GTF_permit_access) ||
-                  (scombo.shorts.domid != ld->domain_id)) )
-                 PIN_FAIL(unlock_out, GNTST_general_error,
-                          "Bad flags (%x) or dom (%d). (expected dom %d)\n",
-                          scombo.shorts.flags, scombo.shorts.domid,
-                          ld->domain_id);
-
-            new_scombo = scombo;
-            new_scombo.shorts.flags |= GTF_reading;
-
-            if ( !(op->flags & GNTMAP_readonly) )
-            {
-                new_scombo.shorts.flags |= GTF_writing;
-                if ( unlikely(scombo.shorts.flags & GTF_readonly) )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                             "Attempt to write-pin a r/o grant entry.\n");
-            }
-
-            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
-                                       scombo.word, new_scombo.word);
-            if ( likely(prev_scombo.word == scombo.word) )
-                break;
-
-            if ( retries++ == 4 )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Shared grant entry is unstable.\n");
-
-            scombo = prev_scombo;
-        }
+        if ( (rc = _set_status(rd->grant_table->gt_version,
+                               ld->domain_id, op->flags & GNTMAP_readonly,
+                               shah, act, status) ) != GNTST_okay )
+             goto unlock_out;
 
         if ( !act->pin )
         {
-            act->domid = scombo.shorts.domid;
-            act->gfn = sha->frame;
-            act->frame = gmfn_to_mfn(rd, sha->frame);
+            act->domid = ld->domain_id;
+            if ( sha1 )
+                act->gfn = sha1->frame;
+            else
+                act->gfn = sha2->full_page.frame;
+            act->frame = gmfn_to_mfn(rd, act->gfn);
         }
     }
 
@@ -343,7 +496,7 @@
     frame = act->frame;
     act_pin = act->pin;
 
-    cache_flags = (sha->flags & (GTF_PAT | GTF_PWT | GTF_PCD) );
+    cache_flags = (shah->flags & (GTF_PAT | GTF_PWT | GTF_PCD) );
 
     spin_unlock(&rd->grant_table->lock);
 
@@ -457,7 +610,7 @@
     spin_lock(&rd->grant_table->lock);
 
     act = &active_entry(rd->grant_table, op->ref);
-    sha = &shared_entry(rd->grant_table, op->ref);
+    shah = shared_entry_header(rd->grant_table, op->ref);
 
     if ( op->flags & GNTMAP_device_map )
         act->pin -= (op->flags & GNTMAP_readonly) ?
@@ -468,10 +621,10 @@
 
     if ( !(op->flags & GNTMAP_readonly) &&
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
-        gnttab_clear_flag(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, status);
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, status);
 
  unlock_out:
     spin_unlock(&rd->grant_table->lock);
@@ -508,7 +661,6 @@
     domid_t          dom;
     struct domain   *ld, *rd;
     struct active_grant_entry *act;
-    grant_entry_v1_t *sha;
     s16              rc = 0;
     u32              old_pin;
 
@@ -556,7 +708,6 @@
     spin_lock(&rd->grant_table->lock);
 
     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 )
@@ -622,8 +773,9 @@
 {
     struct domain   *ld, *rd;
     struct active_grant_entry *act;
-    grant_entry_v1_t *sha;
+    grant_entry_header_t *sha;
     struct page_info *pg;
+    uint16_t *status;
 
     rd = op->rd;
 
@@ -642,8 +794,16 @@
     rcu_lock_domain(rd);
     spin_lock(&rd->grant_table->lock);
 
+    if ( rd->grant_table->gt_version == 0 )
+        goto unmap_out;
+
     act = &active_entry(rd->grant_table, op->map->ref);
-    sha = &shared_entry(rd->grant_table, op->map->ref);
+    sha = shared_entry_header(rd->grant_table, op->map->ref);
+
+    if ( rd->grant_table->gt_version == 1 )
+        status = &sha->flags;
+    else
+        status = &status_entry(rd->grant_table, op->map->ref);
 
     if ( unlikely(op->frame != act->frame) ) 
     {
@@ -694,10 +854,10 @@
 
     if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
          !(op->flags & GNTMAP_readonly) )
-        gnttab_clear_flag(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, status);
 
     if ( act->pin == 0 )
-        gnttab_clear_flag(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, status);
 
  unmap_out:
     spin_unlock(&rd->grant_table->lock);
@@ -829,6 +989,50 @@
     return -EFAULT;    
 }
 
+static int
+gnttab_populate_status_frames(struct domain *d, struct grant_table *gt)
+{
+    unsigned i;
+    unsigned req_status_frames;
+
+    req_status_frames = grant_to_status_frames(gt->nr_grant_frames);
+    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
+    {
+        if ( (gt->status[i] = alloc_xenheap_page()) == NULL )
+            goto status_alloc_failed;
+        clear_page(gt->status[i]);
+    }
+    /* Share the new status frames with the recipient domain */
+    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
+        gnttab_create_status_page(d, gt, i);
+
+    gt->nr_status_frames = req_status_frames;
+
+    return 0;
+
+status_alloc_failed:
+    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
+    {
+        free_xenheap_page(gt->status[i]);
+        gt->status[i] = NULL;
+    }
+    return -ENOMEM;
+}
+
+static void
+gnttab_unpopulate_status_frames(struct domain *d, struct grant_table *gt)
+{
+    int i;
+
+    for ( i = 0; i < nr_status_frames(gt); i++ )
+    {
+        page_set_owner(virt_to_page(gt->status[i]), dom_xen);
+        free_xenheap_page(gt->status[i]);
+        gt->status[i] = NULL;
+    }
+    gt->nr_status_frames = 0;
+}
+
 int
 gnttab_grow_table(struct domain *d, unsigned int req_nr_frames)
 {
@@ -855,9 +1059,9 @@
     /* Shared */
     for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
     {
-        if ( (gt->shared[i] = alloc_xenheap_page()) == NULL )
+        if ( (gt->shared_raw[i] = alloc_xenheap_page()) == NULL )
             goto shared_alloc_failed;
-        clear_page(gt->shared[i]);
+        clear_page(gt->shared_raw[i]);
     }
 
     /* Share the new shared frames with the recipient domain */
@@ -866,13 +1070,20 @@
 
     gt->nr_grant_frames = req_nr_frames;
 
+    /* Status pages - version 2 */
+    if (gt->gt_version > 1)
+    {
+        if ( gnttab_populate_status_frames(d, gt) )
+            goto shared_alloc_failed;
+    }
+
     return 1;
 
 shared_alloc_failed:
     for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
     {
-        free_xenheap_page(gt->shared[i]);
-        gt->shared[i] = NULL;
+        free_xenheap_page(gt->shared_raw[i]);
+        gt->shared_raw[i] = NULL;
     }
 active_alloc_failed:
     for ( i = nr_active_grant_frames(gt);
@@ -942,7 +1153,13 @@
 
     spin_lock(&d->grant_table->lock);
 
-    if ( (op.nr_frames > nr_grant_frames(d->grant_table)) &&
+    if ( d->grant_table->gt_version == 0 )
+        d->grant_table->gt_version = 1;
+
+    if ( (op.nr_frames > nr_grant_frames(d->grant_table) ||
+          ( (d->grant_table->gt_version > 1 ) &&
+            (grant_to_status_frames(op.nr_frames) >
+             nr_status_frames(d->grant_table))  )  ) &&
          !gnttab_grow_table(d, op.nr_frames) )
     {
         gdprintk(XENLOG_INFO,
@@ -1046,7 +1263,7 @@
     struct domain *rd, struct domain *ld, grant_ref_t ref)
 {
     struct grant_table *rgt;
-    struct grant_entry_v1 *sha;
+    grant_entry_header_t *sha;
     union grant_combo   scombo, prev_scombo, new_scombo;
     int                 retries = 0;
 
@@ -1058,6 +1275,14 @@
 
     spin_lock(&rgt->lock);
 
+    if ( rgt->gt_version == 0 )
+    {
+        gdprintk(XENLOG_INFO,
+                 "Grant table not ready for transfer to domain(%d).\n",
+                 rd->domain_id);
+        goto fail;
+    }
+
     if ( unlikely(ref >= nr_grant_entries(rd->grant_table)) )
     {
         gdprintk(XENLOG_INFO,
@@ -1066,7 +1291,7 @@
         goto fail;
     }
 
-    sha = &shared_entry(rgt, ref);
+    sha = shared_entry_header(rgt, ref);
     
     scombo.word = *(u32 *)&sha->flags;
 
@@ -1115,7 +1340,6 @@
     struct domain *e;
     struct page_info *page;
     int i;
-    grant_entry_v1_t *sha;
     struct gnttab_transfer gop;
     unsigned long mfn;
     unsigned int max_bitsize;
@@ -1248,11 +1472,21 @@
         /* Tell the guest about its new page frame. */
         spin_lock(&e->grant_table->lock);
 
-        sha = &shared_entry(e->grant_table, gop.ref);
-        guest_physmap_add_page(e, sha->frame, mfn, 0);
-        sha->frame = mfn;
+        if ( e->grant_table->gt_version == 1 )
+        {
+            grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
+            guest_physmap_add_page(e, sha->frame, mfn, 0);
+            sha->frame = mfn;
+        }
+        else
+        {
+            grant_entry_v2_t *sha = &shared_entry_v2(e->grant_table, gop.ref);
+            guest_physmap_add_page(e, sha->full_page.frame, mfn, 0);
+            sha->full_page.frame = mfn;
+        }
         wmb();
-        sha->flags |= GTF_transfer_completed;
+        shared_entry_header(e->grant_table, gop.ref)->flags |=
+            GTF_transfer_completed;
 
         spin_unlock(&e->grant_table->lock);
 
@@ -1278,15 +1512,21 @@
 __release_grant_for_copy(
     struct domain *rd, unsigned long gref, int readonly)
 {
-    grant_entry_v1_t *sha;
+    grant_entry_header_t *sha;
     struct active_grant_entry *act;
     unsigned long r_frame;
+    uint16_t *status;
 
     spin_lock(&rd->grant_table->lock);
 
     act = &active_entry(rd->grant_table, gref);
-    sha = &shared_entry(rd->grant_table, gref);
+    sha = shared_entry_header(rd->grant_table, gref);
     r_frame = act->frame;
+
+    if (rd->grant_table->gt_version == 1)
+        status = &sha->flags;
+    else
+        status = &status_entry(rd->grant_table, gref);
 
     if ( readonly )
     {
@@ -1298,11 +1538,11 @@
 
         act->pin -= GNTPIN_hstw_inc;
         if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
-            gnttab_clear_flag(_GTF_writing, &sha->flags);
+            gnttab_clear_flag(_GTF_writing, status);
     }
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, status);
 
     spin_unlock(&rd->grant_table->lock);
 }
@@ -1316,21 +1556,38 @@
     struct domain *rd, unsigned long gref, int readonly,
     unsigned long *frame)
 {
-    grant_entry_v1_t *sha;
+    grant_entry_v1_t *sha1;
+    grant_entry_v2_t *sha2;
+    grant_entry_header_t *shah;
     struct active_grant_entry *act;
+    grant_status_t *status;
     s16 rc = GNTST_okay;
-    int retries = 0;
-    union grant_combo scombo, prev_scombo, new_scombo;
 
     spin_lock(&rd->grant_table->lock);
+
+    if ( rd->grant_table->gt_version == 0 )
+        PIN_FAIL(unlock_out, GNTST_general_error,
+                 "remote grant table not ready\n");
 
     if ( unlikely(gref >= nr_grant_entries(rd->grant_table)) )
         PIN_FAIL(unlock_out, GNTST_bad_gntref,
                  "Bad grant reference %ld\n", gref);
 
     act = &active_entry(rd->grant_table, gref);
-    sha = &shared_entry(rd->grant_table, gref);
-    
+    shah = shared_entry_header(rd->grant_table, gref);
+    if ( rd->grant_table->gt_version == 1 )
+    {
+        sha1 = &shared_entry_v1(rd->grant_table, gref);
+        sha2 = NULL;
+        status = &shah->flags;
+    }
+    else
+    {
+        sha1 = NULL;
+        sha2 = &shared_entry_v2(rd->grant_table, gref);
+        status = &status_entry(rd->grant_table, gref);
+    }
+
     /* If already pinned, check the active domid and avoid refcnt overflow. */
     if ( act->pin &&
          ((act->domid != current->domain->domain_id) ||
@@ -1342,48 +1599,18 @@
     if ( !act->pin ||
          (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
     {
-        scombo.word = *(u32 *)&sha->flags;
-
-        for ( ; ; )
-        {
-            /* If not already pinned, check the grant domid and type. */
-            if ( !act->pin &&
-                 (((scombo.shorts.flags & GTF_type_mask) !=
-                   GTF_permit_access) ||
-                  (scombo.shorts.domid != current->domain->domain_id)) )
-                 PIN_FAIL(unlock_out, GNTST_general_error,
-                          "Bad flags (%x) or dom (%d). (expected dom %d)\n",
-                          scombo.shorts.flags, scombo.shorts.domid,
-                          current->domain->domain_id);
-
-            new_scombo = scombo;
-            new_scombo.shorts.flags |= GTF_reading;
-
-            if ( !readonly )
-            {
-                new_scombo.shorts.flags |= GTF_writing;
-                if ( unlikely(scombo.shorts.flags & GTF_readonly) )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                             "Attempt to write-pin a r/o grant entry.\n");
-            }
-
-            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
-                                       scombo.word, new_scombo.word);
-            if ( likely(prev_scombo.word == scombo.word) )
-                break;
-
-            if ( retries++ == 4 )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Shared grant entry is unstable.\n");
-
-            scombo = prev_scombo;
-        }
-
+        if ( (rc = _set_status(rd->grant_table->gt_version,
+                               current->domain->domain_id, 
+                               readonly, shah, act, status) ) != GNTST_okay )
+             goto unlock_out;
         if ( !act->pin )
         {
-            act->domid = scombo.shorts.domid;
-            act->gfn = sha->frame;
-            act->frame = gmfn_to_mfn(rd, sha->frame);
+            act->domid = current->domain->domain_id;
+            if ( sha1 )
+                act->gfn = sha1->frame;
+            else
+                act->gfn = sha2->full_page.frame;
+            act->frame = gmfn_to_mfn(rd, act->gfn);
         }
     }
 
@@ -1528,6 +1755,165 @@
     return 0;
 }
 
+static long
+gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop))
+{
+    gnttab_set_version_t op;
+    struct domain *d = current->domain;
+    struct grant_table *gt = d->grant_table;
+    struct active_grant_entry *act;
+    long res = 0;
+    int i;
+
+    if (copy_from_guest(&op, uop, 1))
+        return -EFAULT;
+
+    if (op.version != 1 && op.version != 2)
+        return -EINVAL;
+
+    spin_lock(&gt->lock);
+    /* Make sure that the grant table isn't currently in use when we
+       change the version number. */
+    /* (You need to change the version number for e.g. kexec.) */
+    if ( gt->gt_version != 0 )
+    {
+        for ( i = 0; i < nr_grant_entries(gt); i++ )
+        {
+            act = &active_entry(gt, i);
+            if ( act->pin != 0 )
+            {
+                gdprintk(XENLOG_WARNING,
+                         "tried to change grant table version from %d to %d, but some grant entries still in use\n",
+                         gt->gt_version,
+                         op.version);
+                res = -EBUSY;
+                goto out;
+            }
+        }
+    }
+
+    /* XXX: If we're going to version 2, we could maybe shrink the
+       active grant table here. */
+
+    if ( op.version == 2 && gt->gt_version < 2 )
+    {
+        res = gnttab_populate_status_frames(d, gt);
+        if ( res < 0)
+            goto out;
+    }
+
+    if ( op.version < 2 && gt->gt_version == 2 )
+        gnttab_unpopulate_status_frames(d, gt);
+
+    if ( op.version != gt->gt_version )
+    {
+        /* Make sure there's no crud left over in the table from the
+           old version. */
+        for ( i = 0; i < nr_grant_frames(gt); i++ )
+            memset(gt->shared_raw[i], 0, PAGE_SIZE);
+    }
+
+    gt->gt_version = op.version;
+
+out:
+    spin_unlock(&gt->lock);
+
+    return res;
+}
+
+static long
+gnttab_get_status_frames(XEN_GUEST_HANDLE(gnttab_get_status_frames_t) uop,
+                         int count)
+{
+    gnttab_get_status_frames_t op;
+    struct domain *d;
+    struct grant_table *gt;
+    uint64_t       gmfn;
+    int i;
+    int rc;
+
+    if ( count != 1 )
+        return -EINVAL;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+    {
+        gdprintk(XENLOG_INFO,
+                 "Fault while reading gnttab_get_status_frames_t.\n");
+        return -EFAULT;
+    }
+
+    rc = rcu_lock_target_domain_by_id(op.dom, &d);
+    if ( rc < 0 )
+    {
+        if ( rc == -ESRCH )
+            op.status = GNTST_bad_domain;
+        else if ( rc == -EPERM )
+            op.status = GNTST_permission_denied;
+        else
+            op.status = GNTST_general_error;
+        goto out1;
+    }
+
+    gt = d->grant_table;
+
+    if ( unlikely(op.nr_frames > nr_status_frames(gt)) ) {
+        gdprintk(XENLOG_INFO, "Guest requested addresses for %d grant status "
+                 "frames, but only %d are available.\n",
+                 op.nr_frames, nr_status_frames(gt));
+        op.status = GNTST_general_error;
+        goto out2;
+    }
+
+    op.status = GNTST_okay;
+
+    spin_lock(&gt->lock);
+
+    for ( i = 0; i < op.nr_frames; i++ )
+    {
+        gmfn = gnttab_status_gmfn(d, d->grant_table, i);
+        if (copy_to_guest_offset(op.frame_list,
+                                 i,
+                                 &gmfn,
+                                 1))
+            op.status = GNTST_bad_virt_addr;
+    }
+
+    spin_unlock(&gt->lock);
+out2:
+    rcu_unlock_domain(d);
+out1:
+    if ( unlikely(copy_to_guest(uop, &op, 1)) )
+        return -EFAULT;
+
+    return 0;
+}
+
+static long
+gnttab_get_version(XEN_GUEST_HANDLE(gnttab_get_version_t uop))
+{
+    gnttab_get_version_t op;
+    struct domain *d;
+
+    if ( copy_from_guest(&op, uop, 1) )
+        return -EFAULT;
+    d = rcu_lock_domain_by_id(op.dom);
+    if ( d == NULL )
+        return -ESRCH;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+    {
+        rcu_unlock_domain(d);
+        return -EPERM;
+    }
+    spin_lock(&d->grant_table->lock);
+    op.version = d->grant_table->gt_version;
+    spin_unlock(&d->grant_table->lock);
+
+    if ( copy_to_guest(uop, &op, 1) )
+        return -EFAULT;
+    else
+        return 0;
+}
+
 long
 do_grant_table_op(
     unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count)
@@ -1630,6 +2016,22 @@
         ASSERT(rc <= 0);
         break;
     }
+    case GNTTABOP_set_version:
+    {
+        rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t));
+        break;
+    }
+    case GNTTABOP_get_status_frames:
+    {
+        rc = gnttab_get_status_frames(
+            guest_handle_cast(uop, gnttab_get_status_frames_t), count);
+        break;
+    }
+    case GNTTABOP_get_version:
+    {
+        rc = gnttab_get_version(guest_handle_cast(uop, gnttab_get_version_t));
+        break;
+    }
     default:
         rc = -ENOSYS;
         break;
@@ -1666,9 +2068,6 @@
     struct grant_table *t;
     int                 i;
 
-    /* If this sizeof assertion fails, fix the function: shared_index */
-    ASSERT(sizeof(grant_entry_v1_t) == 8);
-
     if ( (t = xmalloc(struct grant_table)) == NULL )
         goto no_mem_0;
 
@@ -1703,19 +2102,27 @@
         t->maptrack[0][i].ref = i+1;
 
     /* Shared grant table. */
-    if ( (t->shared = xmalloc_array(struct grant_entry_v1 *,
-                                    max_nr_grant_frames)) == NULL )
+    if ( (t->shared_raw = xmalloc_array(void *, max_nr_grant_frames)) == NULL )
         goto no_mem_3;
-    memset(t->shared, 0, max_nr_grant_frames * sizeof(t->shared[0]));
+    memset(t->shared_raw, 0, max_nr_grant_frames * sizeof(t->shared_raw[0]));
     for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
     {
-        if ( (t->shared[i] = alloc_xenheap_page()) == NULL )
+        if ( (t->shared_raw[i] = alloc_xenheap_page()) == NULL )
             goto no_mem_4;
-        clear_page(t->shared[i]);
+        clear_page(t->shared_raw[i]);
     }
 
     for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
         gnttab_create_shared_page(d, t, i);
+
+    /* Status pages for grant table - for version 2 */
+    t->status = xmalloc_array(grant_status_t *,
+                              grant_to_status_frames(max_nr_grant_frames));
+    if ( t->status == NULL )
+        goto no_mem_4;
+    memset(t->status, 0,
+           grant_to_status_frames(max_nr_grant_frames) * sizeof(t->status[0]));
+    t->nr_status_frames = 0;
 
     /* Okay, install the structure. */
     d->grant_table = t;
@@ -1723,8 +2130,8 @@
 
  no_mem_4:
     for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
-        free_xenheap_page(t->shared[i]);
-    xfree(t->shared);
+        free_xenheap_page(t->shared_raw[i]);
+    xfree(t->shared_raw);
  no_mem_3:
     free_xenheap_page(t->maptrack[0]);
     xfree(t->maptrack);
@@ -1749,7 +2156,8 @@
     grant_handle_t        handle;
     struct domain        *rd;
     struct active_grant_entry *act;
-    struct grant_entry_v1*sha;
+    grant_entry_header_t *sha;
+    uint16_t             *status;
     struct page_info     *pg;
 
     BUG_ON(!d->is_dying);
@@ -1777,7 +2185,12 @@
         spin_lock(&rd->grant_table->lock);
 
         act = &active_entry(rd->grant_table, ref);
-        sha = &shared_entry(rd->grant_table, ref);
+        sha = shared_entry_header(rd->grant_table, ref);
+        if (rd->grant_table->gt_version == 1)
+            status = &sha->flags;
+        else
+            status = &status_entry(rd->grant_table, ref);
+
         pg = mfn_to_page(act->frame);
 
         if ( map->flags & GNTMAP_readonly )
@@ -1823,11 +2236,11 @@
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
-                gnttab_clear_flag(_GTF_writing, &sha->flags);
+                gnttab_clear_flag(_GTF_writing, status);
         }
 
         if ( act->pin == 0 )
-            gnttab_clear_flag(_GTF_reading, &sha->flags);
+            gnttab_clear_flag(_GTF_reading, status);
 
         spin_unlock(&rd->grant_table->lock);
 
@@ -1849,8 +2262,8 @@
         return;
     
     for ( i = 0; i < nr_grant_frames(t); i++ )
-        free_xenheap_page(t->shared[i]);
-    xfree(t->shared);
+        free_xenheap_page(t->shared_raw[i]);
+    xfree(t->shared_raw);
 
     for ( i = 0; i < nr_maptrack_frames(t); i++ )
         free_xenheap_page(t->maptrack[i]);
@@ -1859,6 +2272,10 @@
     for ( i = 0; i < nr_active_grant_frames(t); i++ )
         free_xenheap_page(t->active[i]);
     xfree(t->active);
+
+    for ( i = 0; i < nr_status_frames(t); i++ )
+        free_xenheap_page(t->status[i]);
+    xfree(t->status);
 
     xfree(t);
     d->grant_table = NULL;
diff -r 1df819bcf086 -r 842baf721920 xen/include/Makefile
--- a/xen/include/Makefile	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/Makefile	Mon Sep 22 12:23:28 2008 +0100
@@ -58,7 +58,7 @@
 	mv -f $@.new $@
 
 compat/%.i: compat/%.c Makefile
-	$(CPP) $(filter-out -M% .%.d,$(CFLAGS)) $(cppflags-y) -o $@ $<
+	$(CPP) -include public/xen-compat.h $(filter-out -M% .%.d,$(CFLAGS)) $(cppflags-y) -o $@ $<
 
 compat/%.c: public/%.h xlat.lst Makefile $(BASEDIR)/tools/compat-build-source.py
 	mkdir -p $(@D)
diff -r 1df819bcf086 -r 842baf721920 xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/asm-x86/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
@@ -21,15 +21,30 @@
 #define gnttab_create_shared_page(d, t, i)                               \
     do {                                                                 \
         share_xen_page_with_guest(                                       \
-            virt_to_page((char *)(t)->shared[i]),                        \
+            virt_to_page((char *)(t)->shared_raw[i]),                    \
             (d), XENSHARE_writable);                                     \
     } while ( 0 )
 
+#define gnttab_create_status_page(d, t, i)                               \
+    do {                                                                 \
+        share_xen_page_with_guest(                                       \
+           virt_to_page((char *)(t)->status[i]),                         \
+            (d), XENSHARE_writable);                                     \
+    } while ( 0 )
+
+
 #define gnttab_shared_mfn(d, t, i)                      \
-    ((virt_to_maddr((t)->shared[i]) >> PAGE_SHIFT))
+    ((virt_to_maddr((t)->shared_raw[i]) >> PAGE_SHIFT))
 
 #define gnttab_shared_gmfn(d, t, i)                     \
     (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i)))
+
+
+#define gnttab_status_mfn(d, t, i)                      \
+    ((virt_to_maddr((t)->status[i]) >> PAGE_SHIFT))
+
+#define gnttab_status_gmfn(d, t, i)                     \
+    (mfn_to_gmfn(d, gnttab_status_mfn(d, t, i)))
 
 #define gnttab_mark_dirty(d, f) paging_mark_dirty((d), (f))
 
diff -r 1df819bcf086 -r 842baf721920 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/public/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
@@ -90,6 +90,11 @@
  * [XEN]: This field is written by Xen and read by the sharing guest.
  * [GST]: This field is written by the guest and read by Xen.
  */
+
+/*
+ * Version 1 of the grant table entry structure is maintained purely
+ * for backwards compatibility.  New guests should use version 2.
+ */
 #if __XEN_INTERFACE_VERSION__ < 0x0003020a
 #define grant_entry_v1 grant_entry
 #define grant_entry_v1_t grant_entry_t
@@ -154,6 +159,55 @@
 #define _GTF_transfer_completed (3)
 #define GTF_transfer_completed  (1U<<_GTF_transfer_completed)
 
+/*
+ * Version 2 grant table entries.  These fulfil the same role as
+ * version 1 entries, but can represent more complicated operations.
+ * Any given domain will have either a version 1 or a version 2 table,
+ * and every entry in the table will be the same version.
+ *
+ * The interface by which domains use grant references does not depend
+ * on the grant table version in use by the other domain.
+ */
+#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
+/*
+ * Version 1 and version 2 grant entries share a common prefix.  The
+ * fields of the prefix are documented as part of struct
+ * grant_entry_v1.
+ */
+struct grant_entry_header {
+    uint16_t flags;
+    domid_t  domid;
+};
+typedef struct grant_entry_header grant_entry_header_t;
+
+/*
+ * Version 2 of the grant entry structure.
+ */
+union grant_entry_v2 {
+    grant_entry_header_t hdr;
+
+    /*
+     * This member is used for V1-style full page grants, where either:
+     *
+     * -- hdr.type is GTF_accept_transfer, or
+     * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.
+     *
+     * In that case, the frame field has the same semantics as the
+     * field of the same name in the V1 entry structure.
+     */
+    struct {
+        grant_entry_header_t hdr;
+        uint32_t pad0;
+        uint64_t frame;
+    } full_page;
+
+    uint32_t __spacer[4]; /* Pad to a power of two */
+};
+typedef union grant_entry_v2 grant_entry_v2_t;
+
+typedef uint16_t grant_status_t;
+
+#endif /* __XEN_INTERFACE_VERSION__ */
 
 /***********************************
  * GRANT TABLE QUERIES AND USES
@@ -363,6 +417,63 @@
 typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t;
 DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t);
 
+#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
+/*
+ * GNTTABOP_set_version: Request a particular version of the grant
+ * table shared table structure.  This operation can only be performed
+ * once in any given domain.  It must be performed before any grants
+ * are activated; otherwise, the domain will be stuck with version 1.
+ * The only defined versions are 1 and 2.
+ */
+#define GNTTABOP_set_version          8
+struct gnttab_set_version {
+    /* IN parameters */
+    uint32_t version;
+};
+typedef struct gnttab_set_version gnttab_set_version_t;
+DEFINE_XEN_GUEST_HANDLE(gnttab_set_version_t);
+
+
+/*
+ * GNTTABOP_get_status_frames: Get the list of frames used to store grant
+ * status for <dom>. In grant format version 2, the status is separated
+ * from the other shared grant fields to allow more efficient synchronization
+ * using barriers instead of atomic cmpexch operations.
+ * <nr_frames> specify the size of vector <frame_list>.
+ * The frame addresses are returned in the <frame_list>.
+ * Only <nr_frames> addresses are returned, even if the table is larger.
+ * NOTES:
+ *  1. <dom> may be specified as DOMID_SELF.
+ *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
+ */
+#define GNTTABOP_get_status_frames     9
+struct gnttab_get_status_frames {
+    /* IN parameters. */
+    uint32_t nr_frames;
+    domid_t  dom;
+    /* OUT parameters. */
+    int16_t  status;              /* GNTST_* */
+    XEN_GUEST_HANDLE(uint64_t) frame_list;
+};
+typedef struct gnttab_get_status_frames gnttab_get_status_frames_t;
+DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_t);
+
+/*
+ * GNTTABOP_get_version: Get the grant table version which is in
+ * effect for domain <dom>.
+ */
+#define GNTTABOP_get_version          10
+struct gnttab_get_version {
+    /* IN parameters */
+    domid_t dom;
+    uint16_t pad;
+    /* OUT parameters */
+    uint32_t version;
+};
+typedef struct gnttab_get_version gnttab_get_version_t;
+DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t);
+
+#endif /* __XEN_INTERFACE_VERSION__ */
 
 /*
  * Bitfield values for gnttab_map_grant_ref.flags.
diff -r 1df819bcf086 -r 842baf721920 xen/include/public/memory.h
--- a/xen/include/public/memory.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/public/memory.h	Mon Sep 22 12:23:28 2008 +0100
@@ -211,6 +211,8 @@
 #define XENMAPSPACE_gmfn        2 /* GMFN */
     unsigned int space;
 
+#define XENMAPIDX_grant_table_status 0x80000000
+
     /* Index into source mapping space. */
     xen_ulong_t idx;
 
diff -r 1df819bcf086 -r 842baf721920 xen/include/public/xen.h
--- a/xen/include/public/xen.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/public/xen.h	Mon Sep 22 12:23:28 2008 +0100
@@ -47,6 +47,7 @@
 __DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
 DEFINE_XEN_GUEST_HANDLE(void);
 
+DEFINE_XEN_GUEST_HANDLE(uint64_t);
 DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #endif
 
diff -r 1df819bcf086 -r 842baf721920 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/xen/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
@@ -80,7 +80,15 @@
     /* Table size. Number of frames shared with guest */
     unsigned int          nr_grant_frames;
     /* Shared grant table (see include/public/grant_table.h). */
-    struct grant_entry_v1 **shared;
+    union {
+        void **shared_raw;
+        struct grant_entry_v1 **shared_v1;
+        union grant_entry_v2 **shared_v2;
+    };
+    /* Number of grant status frames shared with guest (for version 2) */
+    unsigned int          nr_status_frames;
+    /* State grant table (see include/public/grant_table.h). */
+    grant_status_t       **status;
     /* Active grant table. */
     struct active_grant_entry **active;
     /* Mapping tracking table. */
@@ -89,6 +97,9 @@
     unsigned int          maptrack_limit;
     /* Lock protecting updates to active and shared grant tables. */
     spinlock_t            lock;
+    /* The defined versions are 1 and 2.  Set to 0 if we don't know
+       what version to use yet. */
+    unsigned              gt_version;
 };
 
 /* Create/destroy per-domain grant table context. */
@@ -114,10 +125,19 @@
     return gt->nr_grant_frames;
 }
 
-/* Number of grant table entries. Caller must hold d's grant table lock. */
-static inline unsigned int nr_grant_entries(struct grant_table *gt)
+/* Number of status grant table frames. Caller must hold d's gr. table lock.*/
+static inline unsigned int nr_status_frames(struct grant_table *gt)
 {
-    return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v1_t);
+    return gt->nr_status_frames;
+}
+
+#define GRANT_STATUS_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
+#define GRANT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v2_t))
+/* Number of grant table status entries. Caller must hold d's gr. table lock.*/
+static inline unsigned int grant_to_status_frames(int grant_frames)
+{
+    return (grant_frames * GRANT_PER_PAGE + GRANT_STATUS_PER_PAGE - 1) /
+        GRANT_STATUS_PER_PAGE;
 }
 
 static inline unsigned int
diff -r 1df819bcf086 -r 842baf721920 xen/include/xlat.lst
--- a/xen/include/xlat.lst	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/xlat.lst	Mon Sep 22 12:23:28 2008 +0100
@@ -44,7 +44,12 @@
 !	gnttab_transfer			grant_table.h
 ?	gnttab_unmap_grant_ref		grant_table.h
 ?	gnttab_unmap_and_replace	grant_table.h
+?	gnttab_set_version		grant_table.h
+?	gnttab_get_version		grant_table.h
+!	gnttab_get_status_frames	grant_table.h
 ?	grant_entry_v1			grant_table.h
+?       grant_entry_header              grant_table.h
+?	grant_entry_v2			grant_table.h
 ?	kexec_exec			kexec.h
 !	kexec_image			kexec.h
 !	kexec_range			kexec.h

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6 of 8] Implement sub-page grant support
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (4 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 5 of 8] Introduce a grant_entry_v2 structure steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 7 of 8] Transitive " steven.smith
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 9388 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222085347 -3600
# Node ID e9b623fd710f2130bcb925161abe26c6980b91c3
# Parent  842baf721920b032f358ad326145817b42d053a1
Implement sub-page grant support.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r 842baf721920 -r e9b623fd710f xen/common/grant_table.c
--- a/xen/common/grant_table.c	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/common/grant_table.c	Mon Sep 22 13:09:07 2008 +0100
@@ -210,6 +210,7 @@
 
 static int _set_status_v1(domid_t  domid,
                           int readonly,
+                          int mapflag,
                           grant_entry_header_t *shah, 
                           struct active_grant_entry *act)
 {
@@ -226,6 +227,11 @@
      * so we allow a few retries before failing.
      */
     int retries = 0;
+
+    /* if this is a grant mapping operation we should ensure GTF_sub_page
+       is not set */
+    if (mapflag)
+        mask |= GTF_sub_page;
 
     scombo.word = *(u32 *)shah;
 
@@ -276,6 +282,7 @@
 
 static int _set_status_v2(domid_t  domid,
                           int readonly,
+                          int mapflag,
                           grant_entry_header_t *shah, 
                           struct active_grant_entry *act,
                           grant_status_t *status)
@@ -294,6 +301,11 @@
                   it back into two reads */
     flags = scombo.shorts.flags;
     id = scombo.shorts.domid;
+
+    /* if this is a grant mapping operation we should ensure GTF_sub_page
+       is not set */
+    if (mapflag)
+        mask |= GTF_sub_page;
 
     /* If not already pinned, check the grant domid and type. */
     if ( !act->pin &&
@@ -355,15 +367,16 @@
 static int _set_status(unsigned gt_version,
                        domid_t  domid,
                        int readonly,
+                       int mapflag,
                        grant_entry_header_t *shah,
                        struct active_grant_entry *act,
                        grant_status_t *status)
 {
 
     if (gt_version == 1)
-        return _set_status_v1(domid, readonly, shah, act);
+        return _set_status_v1(domid, readonly, mapflag, shah, act);
     else
-        return _set_status_v2(domid, readonly, shah, act, status);
+        return _set_status_v2(domid, readonly, mapflag, shah, act, status);
 }
 
 /*
@@ -460,10 +473,11 @@
     /* If already pinned, check the active domid and avoid refcnt overflow. */
     if ( act->pin &&
          ((act->domid != ld->domain_id) ||
-          (act->pin & 0x80808080U) != 0) )
+          (act->pin & 0x80808080U) != 0 ||
+          (act->is_sub_page)) )
         PIN_FAIL(unlock_out, GNTST_general_error,
-                 "Bad domain (%d != %d), or risk of counter overflow %08x\n",
-                 act->domid, ld->domain_id, act->pin);
+                 "Bad domain (%d != %d), or risk of counter overflow %08x, or subpage %d\n",
+                 act->domid, ld->domain_id, act->pin, act->is_sub_page);
 
     if ( !act->pin ||
          (!(op->flags & GNTMAP_readonly) &&
@@ -471,7 +485,7 @@
     {
         if ( (rc = _set_status(rd->grant_table->gt_version,
                                ld->domain_id, op->flags & GNTMAP_readonly,
-                               shah, act, status) ) != GNTST_okay )
+                               1, shah, act, status) ) != GNTST_okay )
              goto unlock_out;
 
         if ( !act->pin )
@@ -482,6 +496,9 @@
             else
                 act->gfn = sha2->full_page.frame;
             act->frame = gmfn_to_mfn(rd, act->gfn);
+            act->start = 0;
+            act->length = PAGE_SIZE;
+            act->is_sub_page = 0;
         }
     }
 
@@ -1554,7 +1571,7 @@
 static int
 __acquire_grant_for_copy(
     struct domain *rd, unsigned long gref, int readonly,
-    unsigned long *frame)
+    unsigned long *frame, unsigned *page_off, unsigned *length)
 {
     grant_entry_v1_t *sha1;
     grant_entry_v2_t *sha2;
@@ -1601,21 +1618,40 @@
     {
         if ( (rc = _set_status(rd->grant_table->gt_version,
                                current->domain->domain_id, 
-                               readonly, shah, act, status) ) != GNTST_okay )
+                               readonly, 0, shah, act, status) ) != GNTST_okay )
              goto unlock_out;
+
         if ( !act->pin )
         {
             act->domid = current->domain->domain_id;
+            act->is_sub_page = 0;
+            act->start = 0;
+            act->length = PAGE_SIZE;
+
             if ( sha1 )
+            {
                 act->gfn = sha1->frame;
+            }
+            else if ( shah->flags & GTF_sub_page )
+            {
+                act->start = sha2->sub_page.page_off;
+                act->length = sha2->sub_page.length;
+                act->is_sub_page = 1;
+                act->gfn = sha2->sub_page.frame;
+            }
             else
+            {
                 act->gfn = sha2->full_page.frame;
+            }
+
             act->frame = gmfn_to_mfn(rd, act->gfn);
         }
     }
 
     act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
 
+    *page_off = act->start;
+    *length = act->length;
     *frame = act->frame;
 
  unlock_out:
@@ -1667,10 +1703,18 @@
 
     if ( src_is_gref )
     {
-        rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame);
+        unsigned source_off, source_len;
+        rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame,
+                                      &source_off, &source_len);
         if ( rc != GNTST_okay )
             goto error_out;
         have_s_grant = 1;
+        if ( op->source.offset < source_off ||
+             op->len > source_len )
+            PIN_FAIL(error_out, GNTST_general_error,
+                     "copy source out of bounds: %d < %d || %d > %d\n",
+                     op->source.offset, source_off,
+                     op->len, source_len);
     }
     else
     {
@@ -1690,10 +1734,18 @@
 
     if ( dest_is_gref )
     {
-        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame);
+        unsigned dest_off, dest_len;
+        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame,
+                                      &dest_off, &dest_len);
         if ( rc != GNTST_okay )
             goto error_out;
         have_d_grant = 1;
+        if ( op->dest.offset < dest_off ||
+             op->len > dest_len )
+            PIN_FAIL(error_out, GNTST_general_error,
+                     "copy dest out of bounds: %d < %d || %d > %d\n",
+                     op->dest.offset, dest_off,
+                     op->len, dest_len);
     }
     else
     {
diff -r 842baf721920 -r e9b623fd710f xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/public/grant_table.h	Mon Sep 22 13:09:07 2008 +0100
@@ -130,6 +130,9 @@
  *  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]
+ *  GTF_sub_page: Grant access to only a subrange of the page.  @domid
+ *                will only be allowed to copy from the grant, and not
+ *                map it. [GST]
  */
 #define _GTF_readonly       (2)
 #define GTF_readonly        (1U<<_GTF_readonly)
@@ -143,6 +146,8 @@
 #define GTF_PCD             (1U<<_GTF_PCD)
 #define _GTF_PAT            (7)
 #define GTF_PAT             (1U<<_GTF_PAT)
+#define _GTF_sub_page       (8)
+#define GTF_sub_page        (1U<<_GTF_sub_page)
 
 /*
  * Subflags for GTF_accept_transfer:
@@ -200,6 +205,18 @@
         uint32_t pad0;
         uint64_t frame;
     } full_page;
+
+    /*
+     * If the grant type is GTF_grant_access and GTF_sub_page is set,
+     * @domid is allowed to access bytes [@page_off,@page_off+@length)
+     * in frame @frame.
+     */
+    struct {
+        grant_entry_header_t hdr;
+        uint16_t page_off;
+        uint16_t length;
+        uint64_t frame;
+    } sub_page;
 
     uint32_t __spacer[4]; /* Pad to a power of two */
 };
diff -r 842baf721920 -r e9b623fd710f xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h	Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/xen/grant_table.h	Mon Sep 22 13:09:07 2008 +0100
@@ -30,10 +30,15 @@
 
 /* Active grant entry - used for shadowing GTF_permit_access grants. */
 struct active_grant_entry {
-    u32           pin;    /* Reference count information.  */
-    domid_t       domid;  /* Domain being granted access.  */
+    u32           pin;    /* Reference count information.             */
+    domid_t       domid;  /* Domain being granted access.             */
+    unsigned long frame;  /* Frame being granted.                     */
     unsigned long gfn;    /* Guest's idea of the frame being granted. */
-    unsigned long frame;  /* Frame being granted.          */
+    unsigned      is_sub_page:1; /* True if this is a sub-page grant. */
+    unsigned      start:15; /* For sub-page grants, the start offset
+                               in the page.                           */
+    unsigned      length:16; /* For sub-page grants, the length of the
+                                grant.                                */
 };
 
  /* Count of writable host-CPU mappings. */

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7 of 8] Transitive grant support
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (5 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 6 of 8] Implement sub-page grant support steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 15:35 ` [PATCH 8 of 8] Tools-side support for creating and destroying netchannel2 interfaces steven.smith
  2009-10-06 20:28 ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Pasi Kärkkäinen
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 16046 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1227887022 0
# Node ID dfa92594086745b0fac52f07c3727a1e9061eb6a
# Parent  e9b623fd710f2130bcb925161abe26c6980b91c3
Transitive grant support.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r e9b623fd710f -r dfa925940867 xen/common/grant_table.c
--- a/xen/common/grant_table.c	Mon Sep 22 13:09:07 2008 +0100
+++ b/xen/common/grant_table.c	Fri Nov 28 15:43:42 2008 +0000
@@ -309,11 +309,12 @@
 
     /* If not already pinned, check the grant domid and type. */
     if ( !act->pin &&
-         (((flags & mask) != GTF_permit_access) ||
+         ( (((flags & mask) != GTF_permit_access) &&
+            ((flags & mask) != GTF_transitive)) ||
           (id != domid)) )
         PIN_FAIL(done, GNTST_general_error,
-                 "Bad flags (%x) or dom (%d). (expected dom %d)\n",
-                 flags, id, domid);
+                 "Bad flags (%x) or dom (%d). (expected dom %d, flags %x)\n",
+                 flags, id, domid, mask);
 
     if ( readonly )
     {
@@ -338,7 +339,8 @@
 
     if ( !act->pin )
     {
-        if ( ((flags & mask) != GTF_permit_access) ||
+        if ( (((flags & mask) != GTF_permit_access) &&
+              ((flags & mask) != GTF_transitive)) ||
              (id != domid) ||
              (!readonly && (flags & GTF_readonly)) )
         {
@@ -1533,6 +1535,14 @@
     struct active_grant_entry *act;
     unsigned long r_frame;
     uint16_t *status;
+    domid_t trans_domid;
+    grant_ref_t trans_gref;
+    int released_read;
+    int released_write;
+    struct domain *trans_dom;
+
+    released_read = 0;
+    released_write = 0;
 
     spin_lock(&rd->grant_table->lock);
 
@@ -1541,9 +1551,19 @@
     r_frame = act->frame;
 
     if (rd->grant_table->gt_version == 1)
+    {
         status = &sha->flags;
+        trans_domid = rd->domain_id;
+        /* Shut the compiler up.  This'll never be used, because
+           trans_domid == rd->domain_id, but gcc doesn't know that. */
+        trans_gref = 0x1234567;
+    }
     else
+    {
         status = &status_entry(rd->grant_table, gref);
+        trans_domid = act->trans_dom;
+        trans_gref = act->trans_gref;
+    }
 
     if ( readonly )
     {
@@ -1555,13 +1575,51 @@
 
         act->pin -= GNTPIN_hstw_inc;
         if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
+        {
+            released_write = 1;
             gnttab_clear_flag(_GTF_writing, status);
+        }
     }
 
     if ( !act->pin )
+    {
         gnttab_clear_flag(_GTF_reading, status);
+        released_read = 1;
+    }
 
     spin_unlock(&rd->grant_table->lock);
+
+    if ( trans_domid != rd->domain_id )
+    {
+        if ( released_write || released_read )
+        {
+            trans_dom = rcu_lock_domain_by_id(trans_domid);
+            if ( trans_dom != NULL )
+            {
+                /* Recursive calls, but they're tail calls, so it's
+                   okay. */
+                if ( released_write )
+                    __release_grant_for_copy(trans_dom, trans_gref, 0);
+                else if ( released_read )
+                    __release_grant_for_copy(trans_dom, trans_gref, 1);
+            }
+        }
+    }
+}
+
+/* The status for a grant indicates that we're taking more access than
+   the pin requires.  Fix up the status to match the pin.  Called
+   under the domain's grant table lock. */
+/* Only safe on transitive grants.  Even then, note that we don't
+   attempt to drop any pin on the referent grant. */
+static void __fixup_status_for_pin(struct active_grant_entry *act,
+                                   uint16_t *status)
+{
+    if ( !(act->pin & GNTPIN_hstw_mask) )
+        *status &= ~_GTF_writing;
+
+    if ( !(act->pin & GNTPIN_hstr_mask) )
+        *status &= ~_GTF_reading;
 }
 
 /* Grab a frame number from a grant entry and update the flags and pin
@@ -1570,15 +1628,27 @@
    actually valid. */
 static int
 __acquire_grant_for_copy(
-    struct domain *rd, unsigned long gref, int readonly,
-    unsigned long *frame, unsigned *page_off, unsigned *length)
+    struct domain *rd, unsigned long gref, struct domain *ld, int readonly,
+    unsigned long *frame, unsigned *page_off, unsigned *length,
+    unsigned allow_transitive, struct domain **owning_domain)
 {
     grant_entry_v1_t *sha1;
     grant_entry_v2_t *sha2;
     grant_entry_header_t *shah;
     struct active_grant_entry *act;
     grant_status_t *status;
+    uint32_t old_pin;
+    domid_t trans_domid;
+    grant_ref_t trans_gref;
+    struct domain *rrd;
+    unsigned long grant_frame;
+    unsigned trans_page_off;
+    unsigned trans_length;
+    int is_sub_page;
+    struct domain *ignore;
     s16 rc = GNTST_okay;
+
+    *owning_domain = NULL;
 
     spin_lock(&rd->grant_table->lock);
 
@@ -1607,45 +1677,127 @@
 
     /* If already pinned, check the active domid and avoid refcnt overflow. */
     if ( act->pin &&
-         ((act->domid != current->domain->domain_id) ||
+         ((act->domid != ld->domain_id) ||
           (act->pin & 0x80808080U) != 0) )
         PIN_FAIL(unlock_out, GNTST_general_error,
                  "Bad domain (%d != %d), or risk of counter overflow %08x\n",
-                 act->domid, current->domain->domain_id, act->pin);
+                 act->domid, ld->domain_id, act->pin);
 
+    old_pin = act->pin;
     if ( !act->pin ||
          (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
     {
         if ( (rc = _set_status(rd->grant_table->gt_version,
-                               current->domain->domain_id, 
-                               readonly, 0, shah, act, status) ) != GNTST_okay )
+                               ld->domain_id,
+                               readonly, 0, shah, act,
+                               status) ) != GNTST_okay )
              goto unlock_out;
+
+        trans_domid = ld->domain_id;
+        trans_gref = 0;
+        if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive )
+        {
+            if ( !allow_transitive )
+                PIN_FAIL(unlock_out, GNTST_general_error,
+                         "transitive grant when transitivity not allowed\n");
+
+            trans_domid = sha2->transitive.trans_domid;
+            trans_gref = sha2->transitive.gref;
+            barrier(); /* Stop the compiler from re-loading
+                          trans_domid from shared memory */
+            if ( trans_domid == rd->domain_id )
+                PIN_FAIL(unlock_out, GNTST_general_error,
+                         "transitive grants cannot be self-referential\n");
+
+            /* We allow the trans_domid == ld->domain_id case, which
+               corresponds to a grant being issued by one domain, sent
+               to another one, and then transitively granted back to
+               the original domain.  Allowing it is easy, and means
+               that you don't need to go out of your way to avoid it
+               in the guest. */
+
+            rrd = rcu_lock_domain_by_id(trans_domid);
+            if ( rrd == NULL )
+                PIN_FAIL(unlock_out, GNTST_general_error,
+                         "transitive grant referenced bad domain %d\n",
+                         trans_domid);
+            spin_unlock(&rd->grant_table->lock);
+
+            rc = __acquire_grant_for_copy(rrd, trans_gref, rd,
+                                          readonly, &grant_frame,
+                                          &trans_page_off, &trans_length,
+                                          0, &ignore);
+
+            spin_lock(&rd->grant_table->lock);
+            if ( rc != GNTST_okay ) {
+                __fixup_status_for_pin(act, status);
+                spin_unlock(&rd->grant_table->lock);
+                return rc;
+            }
+
+            /* We dropped the lock, so we have to check that nobody
+               else tried to pin (or, for that matter, unpin) the
+               reference in *this* domain.  If they did, just give up
+               and try again. */
+            if ( act->pin != old_pin )
+            {
+                __fixup_status_for_pin(act, status);
+                spin_unlock(&rd->grant_table->lock);
+                return __acquire_grant_for_copy(rd, gref, ld, readonly,
+                                                frame, page_off, length,
+                                                allow_transitive,
+                                                owning_domain);
+            }
+
+            /* The actual remote remote grant may or may not be a
+               sub-page, but we always treat it as one because that
+               blocks mappings of transitive grants. */
+            is_sub_page = 1;
+            *owning_domain = rrd;
+            act->gfn = INVALID_GFN;
+        }
+        else if ( sha1 )
+        {
+            act->gfn = sha1->frame;
+            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            is_sub_page = 0;
+            trans_page_off = 0;
+            trans_length = PAGE_SIZE;
+            *owning_domain = rd;
+        }
+        else if ( !(sha2->hdr.flags & GTF_sub_page) )
+        {
+            act->gfn = sha2->full_page.frame;
+            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            is_sub_page = 0;
+            trans_page_off = 0;
+            trans_length = PAGE_SIZE;
+            *owning_domain = rd;
+        }
+        else
+        {
+            act->gfn = sha2->sub_page.frame;
+            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            is_sub_page = 1;
+            trans_page_off = sha2->sub_page.page_off;
+            trans_length = sha2->sub_page.length;
+            *owning_domain = rd;
+        }
 
         if ( !act->pin )
         {
-            act->domid = current->domain->domain_id;
-            act->is_sub_page = 0;
-            act->start = 0;
-            act->length = PAGE_SIZE;
-
-            if ( sha1 )
-            {
-                act->gfn = sha1->frame;
-            }
-            else if ( shah->flags & GTF_sub_page )
-            {
-                act->start = sha2->sub_page.page_off;
-                act->length = sha2->sub_page.length;
-                act->is_sub_page = 1;
-                act->gfn = sha2->sub_page.frame;
-            }
-            else
-            {
-                act->gfn = sha2->full_page.frame;
-            }
-
-            act->frame = gmfn_to_mfn(rd, act->gfn);
+            act->domid = ld->domain_id;
+            act->is_sub_page = is_sub_page;
+            act->start = trans_page_off;
+            act->length = trans_length;
+            act->trans_dom = trans_domid;
+            act->trans_gref = trans_gref;
+            act->frame = grant_frame;
         }
+    }
+    else
+    {
+        *owning_domain = rd;
     }
 
     act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
@@ -1664,6 +1816,7 @@
     struct gnttab_copy *op)
 {
     struct domain *sd = NULL, *dd = NULL;
+    struct domain *source_domain = NULL, *dest_domain = NULL;
     unsigned long s_frame, d_frame;
     char *sp, *dp;
     s16 rc = GNTST_okay;
@@ -1704,8 +1857,9 @@
     if ( src_is_gref )
     {
         unsigned source_off, source_len;
-        rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame,
-                                      &source_off, &source_len);
+        rc = __acquire_grant_for_copy(sd, op->source.u.ref, current->domain, 1,
+                                      &s_frame, &source_off, &source_len, 1,
+                                      &source_domain);
         if ( rc != GNTST_okay )
             goto error_out;
         have_s_grant = 1;
@@ -1719,11 +1873,12 @@
     else
     {
         s_frame = gmfn_to_mfn(sd, op->source.u.gmfn);
+        source_domain = sd;
     }
     if ( unlikely(!mfn_valid(s_frame)) )
         PIN_FAIL(error_out, GNTST_general_error,
                  "source frame %lx invalid.\n", s_frame);
-    if ( !get_page(mfn_to_page(s_frame), sd) )
+    if ( !get_page(mfn_to_page(s_frame), source_domain) )
     {
         if ( !sd->is_dying )
             gdprintk(XENLOG_WARNING, "Could not get src frame %lx\n", s_frame);
@@ -1735,8 +1890,9 @@
     if ( dest_is_gref )
     {
         unsigned dest_off, dest_len;
-        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame,
-                                      &dest_off, &dest_len);
+        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, current->domain, 0,
+                                      &d_frame, &dest_off, &dest_len, 1,
+                                      &dest_domain);
         if ( rc != GNTST_okay )
             goto error_out;
         have_d_grant = 1;
@@ -1750,11 +1906,13 @@
     else
     {
         d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn);
+        dest_domain = dd;
     }
     if ( unlikely(!mfn_valid(d_frame)) )
         PIN_FAIL(error_out, GNTST_general_error,
                  "destination frame %lx invalid.\n", d_frame);
-    if ( !get_page_and_type(mfn_to_page(d_frame), dd, PGT_writable_page) )
+    if ( !get_page_and_type(mfn_to_page(d_frame), dest_domain,
+                            PGT_writable_page) )
     {
         if ( !dd->is_dying )
             gdprintk(XENLOG_WARNING, "Could not get dst frame %lx\n", d_frame);
diff -r e9b623fd710f -r dfa925940867 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h	Mon Sep 22 13:09:07 2008 +0100
+++ b/xen/include/public/grant_table.h	Fri Nov 28 15:43:42 2008 +0000
@@ -85,6 +85,11 @@
  */
 
 /*
+ * Reference to a grant entry in a specified domain's grant table.
+ */
+typedef uint32_t grant_ref_t;
+
+/*
  * A grant table comprises a packed array of grant entries in one or more
  * page frames shared between Xen and a guest.
  * [XEN]: This field is written by Xen and read by the sharing guest.
@@ -118,10 +123,13 @@
  *  GTF_permit_access: Allow @domid to map/access @frame.
  *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
  *                       to this guest. Xen writes the page number to @frame.
+ *  GTF_transitive: Allow @domid to transitively access a subrange of
+ *                  @trans_grant in @trans_domid.  No mappings are allowed.
  */
 #define GTF_invalid         (0U<<0)
 #define GTF_permit_access   (1U<<0)
 #define GTF_accept_transfer (2U<<0)
+#define GTF_transitive      (3U<<0)
 #define GTF_type_mask       (3U<<0)
 
 /*
@@ -218,6 +226,22 @@
         uint64_t frame;
     } sub_page;
 
+    /*
+     * If the grant is GTF_transitive, @domid is allowed to use the
+     * grant @gref in domain @trans_domid, as if it was the local
+     * domain.  Obviously, the transitive access must be compatible
+     * with the original grant.
+     *
+     * The current version of Xen does not allow transitive grants
+     * to be mapped.
+     */
+    struct {
+        grant_entry_header_t hdr;
+        domid_t trans_domid;
+        uint16_t pad0;
+        grant_ref_t gref;
+    } transitive;
+
     uint32_t __spacer[4]; /* Pad to a power of two */
 };
 typedef union grant_entry_v2 grant_entry_v2_t;
@@ -229,11 +253,6 @@
 /***********************************
  * GRANT TABLE QUERIES AND USES
  */
-
-/*
- * Reference to a grant entry in a specified domain's grant table.
- */
-typedef uint32_t grant_ref_t;
 
 /*
  * Handle to track a mapping created via a grant reference.
diff -r e9b623fd710f -r dfa925940867 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h	Mon Sep 22 13:09:07 2008 +0100
+++ b/xen/include/xen/grant_table.h	Fri Nov 28 15:43:42 2008 +0000
@@ -32,6 +32,8 @@
 struct active_grant_entry {
     u32           pin;    /* Reference count information.             */
     domid_t       domid;  /* Domain being granted access.             */
+    domid_t       trans_dom;
+    uint32_t      trans_gref;
     unsigned long frame;  /* Frame being granted.                     */
     unsigned long gfn;    /* Guest's idea of the frame being granted. */
     unsigned      is_sub_page:1; /* True if this is a sub-page grant. */

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 8 of 8] Tools-side support for creating and destroying netchannel2 interfaces
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (6 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 7 of 8] Transitive " steven.smith
@ 2009-10-06 15:35 ` steven.smith
  2009-10-06 20:28 ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Pasi Kärkkäinen
  8 siblings, 0 replies; 16+ messages in thread
From: steven.smith @ 2009-10-06 15:35 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.fraser, joserenato.santos, JBeulich

[-- Attachment #1: xen-unstable-new.hg-8.patch --]
[-- Type: text/x-patch, Size: 15095 bytes --]

# HG changeset patch
# User Steven Smith <steven.smith@eu.citrix.com>
# Date 1222085454 -3600
# Node ID fe10d9d213ebdd43ef0c1d74689db8afec6c8494
# Parent  dfa92594086745b0fac52f07c3727a1e9061eb6a
Tools-side support for creating and destroying netchannel2 interfaces.

Signed-off-by: Steven Smith <steven.smith@citrix.com>

diff -r dfa925940867 -r fe10d9d213eb tools/hotplug/Linux/Makefile
--- a/tools/hotplug/Linux/Makefile	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/hotplug/Linux/Makefile	Mon Sep 22 13:10:54 2008 +0100
@@ -11,6 +11,7 @@
 XEN_SCRIPTS = network-bridge vif-bridge
 XEN_SCRIPTS += network-route vif-route
 XEN_SCRIPTS += network-nat vif-nat
+XEN_SCRIPTS += vif2
 XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd block-nbd
 XEN_SCRIPTS += blktap
diff -r dfa925940867 -r fe10d9d213eb tools/hotplug/Linux/vif2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vif2	Mon Sep 22 13:10:54 2008 +0100
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+. "$dir/xen-network-common.sh"
+
+bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")
+if [ -z "$bridge" ]
+    then
+    nr_bridges=$(($(brctl show | cut -f 1 | grep -v "^$" | wc -l) - 1))
+    if [ "$nr_bridges" != 1 ]
+	then
+	fatal "no bridge specified, and don't know which one to use ($nr_bridges found)"
+    fi
+    bridge=$(brctl show | cut -d "
+" -f 2 | cut -f 1)
+fi
+
+command="$1"
+shift
+
+case "$command" in
+    "online")
+	if [ "$bridge" != "-" ]
+	    then
+	    setup_bridge_port "$vif"
+	    add_to_bridge "$bridge" "$vif"
+	else
+	    # Just let the normal udev rules for interfaces handle it.
+	    true
+	fi
+	success
+	;;
+
+    "add")
+	success
+	;;
+
+    "remove")
+	;;
+
+    *)
+	echo "Unknown command: $command"
+	echo 'Valid commands are: add, remove, online'
+	exit 1
+esac
diff -r dfa925940867 -r fe10d9d213eb tools/hotplug/Linux/xen-backend.rules
--- a/tools/hotplug/Linux/xen-backend.rules	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/hotplug/Linux/xen-backend.rules	Mon Sep 22 13:10:54 2008 +0100
@@ -1,8 +1,9 @@
 SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
-SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
-SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline"
+SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="$env{script} online"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="$env{script} offline"
 SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}"
 SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
 KERNEL=="evtchn", NAME="xen/%k"
diff -r dfa925940867 -r fe10d9d213eb tools/python/xen/xend/XendDevices.py
--- a/tools/python/xen/xend/XendDevices.py	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/python/xen/xend/XendDevices.py	Mon Sep 22 13:10:54 2008 +0100
@@ -19,7 +19,7 @@
 # A collection of DevControllers 
 #
 
-from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif, vscsiif
+from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif, vscsiif, netif2
 from xen.xend.server.BlktapController import BlktapController, Blktap2Controller
 from xen.xend.server.ConsoleController import ConsoleController
 
@@ -37,6 +37,7 @@
     controllers = {
         'vbd': blkif.BlkifController,
         'vif': netif.NetifController,
+        'vif2': netif2.NetifController2,
         'vtpm': tpmif.TPMifController,
         'pci': pciif.PciController,
         'ioports': iopif.IOPortsController,
diff -r dfa925940867 -r fe10d9d213eb tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Sep 22 13:10:54 2008 +0100
@@ -1222,7 +1222,7 @@
                         break
                 self._waitForDevice_destroy(deviceClass, devid, backend)
 
-        if rm_cfg:
+        if rm_cfg and deviceClass != "vif2":
             if deviceClass == 'vif':
                 if self.domid is not None:
                     mac = ''
diff -r dfa925940867 -r fe10d9d213eb tools/python/xen/xend/server/netif2.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/netif2.py	Mon Sep 22 13:10:54 2008 +0100
@@ -0,0 +1,163 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
+# Copyright (C) 2005 XenSource Ltd
+# Copyright (C) 2008 Citrix Systems Inc.
+#============================================================================
+#
+# Based closely on netif.py.
+#
+
+"""Support for virtual network interfaces, version 2.
+"""
+
+import os
+import random
+import re
+import time
+
+from xen.xend import XendOptions
+from xen.xend.server.DevController import DevController
+from xen.xend.XendError import VmError
+from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+from xen.xend.xenstore.xstransact import xstransact
+import xen.util.xsm.xsm as security
+
+from xen.xend.XendLogging import log
+
+xoptions = XendOptions.instance()
+
+def randomMAC():
+    """Generate a random MAC address.
+
+    Uses OUI (Organizationally Unique Identifier) 00-16-3E, allocated to
+    Xensource, Inc. The OUI list is available at
+    http://standards.ieee.org/regauth/oui/oui.txt.
+
+    The remaining 3 fields are random, with the first bit of the first
+    random field set 0.
+
+    @return: MAC address string
+    """
+    mac = [ 0x00, 0x16, 0x3e,
+            random.randint(0x00, 0x7f),
+            random.randint(0x00, 0xff),
+            random.randint(0x00, 0xff) ]
+    return ':'.join(map(lambda x: "%02x" % x, mac))
+
+class NetifController2(DevController):
+    def __init__(self, vm):
+        DevController.__init__(self, vm)
+
+    def getDeviceDetails(self, config):
+        """@see DevController.getDeviceDetails"""
+
+        devid = self.allocateDeviceID()
+
+        bridge = config.get('bridge')
+        back_mac = config.get('back_mac')
+        if not back_mac:
+            if bridge:
+                back_mac = "fe:ff:ff:ff:ff:ff"
+            else:
+                back_mac = randomMAC()
+        front_mac = config.get('front_mac') or randomMAC()
+        front_trust = config.get("trusted") or "0"
+        back_trust = config.get("back_trusted") or "1"
+        max_bypasses = config.get("max_bypasses") or "5"
+        pdev = config.get('pdev')
+        front_filter = config.get("front_filter_mac")
+        if front_filter == None:
+            if back_trust == "0":
+                front_filter = "1"
+            else:
+                front_filter = "0"
+        back_filter = config.get("filter_mac")
+        if back_filter == None:
+            if front_trust == "0":
+                back_filter = "1"
+            else:
+                back_filter = "0"
+        back = { 'mac': back_mac, 'remote-mac': front_mac,
+                 'handle': "%i" % devid, 'local-trusted': back_trust,
+                 'remote-trusted': front_trust, 'filter-mac': back_filter,
+                 'max-bypasses': max_bypasses }
+
+        front = { 'mac': front_mac, 'remote-mac': back_mac,
+                  'local-trusted': front_trust, 'remote-trusted': back_trust,
+                  'filter-mac': front_filter }
+
+        if bridge:
+            back['bridge'] = bridge
+
+        if pdev:
+            back['pdev'] = pdev
+    
+        return (devid, back, front)
+
+    def getDeviceConfiguration(self, devid, transaction = None):
+        """@see DevController.configuration"""
+
+        if transaction is None:
+            read_fn = xstransact.Read
+        else:
+            read_fn = transaction.read
+        def front_read(x):
+            return read_fn(frontpath + x)
+        def back_read(x):
+            return read_fn(backpath + x)
+        
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
+
+        dev = self.convertToDeviceNumber(devid)
+        frontpath = self.frontendPath(dev) + "/"
+
+        backpath = front_read("backend") + "/"
+
+        front_mac = front_read("mac")
+        back_mac = back_read("mac")
+
+        front_trusted = back_read("remote-trusted")
+        back_trusted = back_read("local-trusted")
+        max_bypasses = back_read("max-bypasses")
+
+        bridge = back_read("bridge")
+
+        pdev = back_read("pdev")
+
+        if front_mac:
+            result["front_mac"] = front_mac
+        if back_mac:
+            result["back_mac"] = back_mac
+        if front_trusted:
+            result["front_trusted"] = front_trusted
+        if back_trusted:
+            result["back_trusted"] = back_trusted
+        if bridge:
+            result["bridge"] = bridge
+        if pdev:
+            result["pdev"] = pdev
+        if max_bypasses:
+            result["max-bypasses"] = max_bypasses
+        return result
+
+    def destroyDevice(self, devid, force):
+        dev = self.convertToDeviceNumber(devid)
+        self.writeBackend(dev, "online", "0")
+        if force:
+            self.writeBackend(dev, "shutdown-request", "force")
+        else:
+            self.writeBackend(dev, "shutdown-request", "normal")
+        self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
diff -r dfa925940867 -r fe10d9d213eb tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/python/xen/xm/create.py	Mon Sep 22 13:10:54 2008 +0100
@@ -393,6 +393,12 @@
           This option may be repeated to add more than one vif.
           Specifying vifs will increase the number of interfaces as needed.""")
 
+gopts.var('vif2', val="front_mac=MAC,back_mac=MAC,backend=DOM,pdev=PDEV,max_bypasses=N,bridge=BRIDGE,filter_mac=<0|1>,front_filter_mac=<0|1>",
+          fn=append_value, default=[],
+          use="""Add a netchannel2 network interface using given front
+          and backend MAC addresses.  Randomly generated
+          addresses will be used if either address is missing.""")
+
 gopts.var('vtpm', val="instance=INSTANCE,backend=DOM,type=TYPE",
           fn=append_value, default=[],
           use="""Add a TPM interface. On the backend side use the given
@@ -931,6 +937,8 @@
 
     vifs = vals.vif
     vifs_n = len(vifs)
+    vifs2 = vals.vif2
+    vifs2_n = len(vifs2)
 
     if hasattr(vals, 'nics'):
         if vals.nics > 0:
@@ -955,6 +963,18 @@
             config_vif.append([k, d[k]])
 
         map(f, d.keys())
+        config_devs.append(['device', config_vif])
+
+    for c in vifs2:
+        d = comma_sep_kv_to_dict(c)
+        config_vif = ['vif2']
+
+        for k in d.keys():
+            if k not in ['front_mac', 'back_mac', 'backend', 'trusted',
+                         'back_trusted', 'front_filter_mac', 'filter_mac',
+                         'bridge', 'pdev', 'max_bypasses' ]:
+                err('Invalid vif2 option: ' + k)
+            config_vif.append([k, d[k]])
         config_devs.append(['device', config_vif])
 
 
diff -r dfa925940867 -r fe10d9d213eb tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py	Fri Nov 28 15:43:42 2008 +0000
+++ b/tools/python/xen/xm/main.py	Mon Sep 22 13:10:54 2008 +0100
@@ -181,6 +181,15 @@
                         'Destroy a domain\'s virtual network device.'),
     'network-list'  :  ('<Domain> [--long]',
                         'List virtual network interfaces for a domain.'),
+    'network2-attach': ('<Domain> [front_mac=<mac>] [back_mac=<mac>] '
+                        '[backend=<BackDomain>] [trusted=<0|1>] '
+                        '[back_trusted=<0|1>] [bridge=<bridge>] '
+                        '[max_bypasses=n]'
+                        'Create a new version 2 virtual network device.'),
+    'network2-detach': ('<Domain> <DevId> [-f|--force]',
+                         'Destroy a domain\'s version 2 virtual network device.'),
+    'network2-list'  : ('<Domain> [--long]',
+                        'List version 2 virtual network interfaces for a domain.'),
     'vnet-create'   :  ('<ConfigFile>','Create a vnet from ConfigFile.'),
     'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
     'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
@@ -399,6 +408,9 @@
     "network-attach",
     "network-detach",
     "network-list",
+    "network2-attach",
+    "network2-detach",
+    "network2-list",
     "vtpm-list",
     "pci-attach",
     "pci-detach",
@@ -2436,6 +2448,35 @@
     server.xend.domain.device_configure(dom, vbd)
 
 
+def xm_network2_attach(args):
+    xenapi_unsupported()
+    arg_check(args, 'network2-attach', 1, 4)
+    dom = args[0]
+    vif = ['vif2']
+    vif_params = ['front_mac', 'back_mac', 'backend', 'trusted',
+                  'back_trusted', "front_filter_mac", "filter_mac",
+                  'bridge', 'pdev', "max_bypasses" ]
+    for a in args[1:]:
+        vif_param = a.split("=")
+        if len(vif_param) != 2 or vif_param[1] == "" or \
+           vif_param[0] not in vif_params:
+            err("Invalid argument: %s" % a)
+            usage("network2-attach")
+        vif.append(vif_param)
+    server.xend.domain.device_create(dom, vif)
+
+def xm_network2_detach(args):
+    xenapi_unsupported()
+    arg_check(args, "network2-detch", 2, 3)
+    detach(args, "vif2")
+
+def xm_network2_list(args):
+    xenapi_unsupported()
+    (use_long, params) = arg_check_for_resource_list(args, "network2-list")
+    dom = params[0]
+    devs = server.xend.domain.getDeviceSxprs(dom, 'vif2')
+    map(PrettyPrint.prettyprint, devs)
+                
 def xm_network_attach(args):
     arg_check(args, 'network-attach', 1, 11)
 
@@ -3239,6 +3280,9 @@
     "network-attach": xm_network_attach,
     "network-detach": xm_network_detach,
     "network-list": xm_network_list,
+    "network2-attach": xm_network2_attach,
+    "network2-detach": xm_network2_detach,
+    "network2-list": xm_network2_list,
     # network (as in XenAPI)
     "network-new": xm_network_new,
     "network-del": xm_network_del,

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
                   ` (7 preceding siblings ...)
  2009-10-06 15:35 ` [PATCH 8 of 8] Tools-side support for creating and destroying netchannel2 interfaces steven.smith
@ 2009-10-06 20:28 ` Pasi Kärkkäinen
  2009-10-06 20:41   ` Ian Pratt
  8 siblings, 1 reply; 16+ messages in thread
From: Pasi Kärkkäinen @ 2009-10-06 20:28 UTC (permalink / raw)
  To: steven.smith; +Cc: keir.fraser, xen-devel, joserenato.santos, JBeulich

On Tue, Oct 06, 2009 at 04:35:42PM +0100, steven.smith@citrix.com wrote:
> This patch series includes all of the Xen and tools bits of
> netchannel2.  It's essentially similar to the one I posted on Sunday,
> except:
> 
> -- I've dropped the unmodified drivers support.  It'd probably be
>    fairly straightforward to re-introduce it, but it's not clear that
>    anyone's actually using unmodified drivers any more (they don't
>    even build against a 2.6.27 kernel, for instance).

At least Redhat/Fedora guys have been thinking of shipping pv-on-hvm Xen
drivers for Fedora 12 / RHEL6.. But I don't know what's the status of that.

There's also a note about it on Xen Wiki:
http://wiki.xensource.com/xenwiki/XenParavirtOps

"Work in progress: pv-on-hvm driver support "

dunno about the status of that either :)

-- Pasi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-06 20:28 ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Pasi Kärkkäinen
@ 2009-10-06 20:41   ` Ian Pratt
  2009-10-06 21:46     ` Jeremy Fitzhardinge
  2009-10-07 19:21     ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Steven Smith
  0 siblings, 2 replies; 16+ messages in thread
From: Ian Pratt @ 2009-10-06 20:41 UTC (permalink / raw)
  To: Pasi Kärkkäinen, Steven Smith
  Cc: Ian, joserenato.santos, JBeulich, Pratt, xen-devel, Keir Fraser

> On Tue, Oct 06, 2009 at 04:35:42PM +0100, steven.smith@citrix.com wrote:
> > This patch series includes all of the Xen and tools bits of
> > netchannel2.  It's essentially similar to the one I posted on Sunday,
> > except:
> >
> > -- I've dropped the unmodified drivers support.  It'd probably be
> >    fairly straightforward to re-introduce it, but it's not clear that
> >    anyone's actually using unmodified drivers any more (they don't
> >    even build against a 2.6.27 kernel, for instance).
> 
> At least Redhat/Fedora guys have been thinking of shipping pv-on-hvm Xen
> drivers for Fedora 12 / RHEL6.. But I don't know what's the status of
> that.

Yes, this certainly isn't a feature we want to drop. In fact, it would be good to see the pv-on-hvm drivers modified to use some of the pvops functions where available. 

Ian

 
> There's also a note about it on Xen Wiki:
> http://wiki.xensource.com/xenwiki/XenParavirtOps
> 
> "Work in progress: pv-on-hvm driver support "
> 
> dunno about the status of that either :)
> 
> -- Pasi
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-06 20:41   ` Ian Pratt
@ 2009-10-06 21:46     ` Jeremy Fitzhardinge
  2009-10-07  1:58       ` [PATCH] linux-2.6.18-xen.hg: re-syncronize ring.h Dutch Meyer
  2009-10-07 19:21     ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Steven Smith
  1 sibling, 1 reply; 16+ messages in thread
From: Jeremy Fitzhardinge @ 2009-10-06 21:46 UTC (permalink / raw)
  To: Ian Pratt
  Cc: xen-devel, joserenato.santos, JBeulich, Don Dutile, Steven Smith,
	Keir Fraser

On 10/06/09 13:41, Ian Pratt wrote:
>> On Tue, Oct 06, 2009 at 04:35:42PM +0100, steven.smith@citrix.com wrote:
>>     
>>> This patch series includes all of the Xen and tools bits of
>>> netchannel2.  It's essentially similar to the one I posted on Sunday,
>>> except:
>>>
>>> -- I've dropped the unmodified drivers support.  It'd probably be
>>>    fairly straightforward to re-introduce it, but it's not clear that
>>>    anyone's actually using unmodified drivers any more (they don't
>>>    even build against a 2.6.27 kernel, for instance).
>>>       
>> At least Redhat/Fedora guys have been thinking of shipping pv-on-hvm Xen
>> drivers for Fedora 12 / RHEL6.. But I don't know what's the status of
>> that.
>>     
> Yes, this certainly isn't a feature we want to drop. In fact, it would be good to see the pv-on-hvm drivers modified to use some of the pvops functions where available. 
>   

Don Dutile from RH is actively working on this.

    J

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH] linux-2.6.18-xen.hg: re-syncronize ring.h
  2009-10-06 21:46     ` Jeremy Fitzhardinge
@ 2009-10-07  1:58       ` Dutch Meyer
  0 siblings, 0 replies; 16+ messages in thread
From: Dutch Meyer @ 2009-10-07  1:58 UTC (permalink / raw)
  To: xen-devel, Keir Fraser; +Cc: Andrew Warfield, Jake Wires

[-- Attachment #1: Type: TEXT/PLAIN, Size: 506 bytes --]


This should be applied against the linux repository.

Patch 20267:e9366bed077e modified the definition of sring in the xen 
repo's version of ring.h, but not the version in the linux kernel repo. 
That change broke pause/resume/shutdown messages from the blktap2 kernel 
module, which (for the time being) relies on pad[0] being at consistent 
location in the sring struct.  This patch fixes this regression by 
resyncronizing the two the files.

Signed off by: Jake Wires <Jake.Wires@citrix.com>

--Dutch

[-- Attachment #2: Type: TEXT/PLAIN, Size: 938 bytes --]

diff -r 4ac3e1d6605c include/xen/interface/io/ring.h
--- a/include/xen/interface/io/ring.h	Tue Sep 29 11:23:06 2009 +0100
+++ b/include/xen/interface/io/ring.h	Tue Oct 06 11:26:27 2009 -0700
@@ -97,7 +97,8 @@ struct __name##_sring {                 
 struct __name##_sring {                                                 \
     RING_IDX req_prod, req_event;                                       \
     RING_IDX rsp_prod, rsp_event;                                       \
-    uint8_t  pad[48];                                                   \
+    uint8_t  netfront_smartpoll_active;                                 \
+    uint8_t  pad[47];                                                   \
     union __name##_sring_entry ring[1]; /* variable-length */           \
 };                                                                      \
                                                                         \

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-06 20:41   ` Ian Pratt
  2009-10-06 21:46     ` Jeremy Fitzhardinge
@ 2009-10-07 19:21     ` Steven Smith
  2009-10-08  8:07       ` Pasi Kärkkäinen
  1 sibling, 1 reply; 16+ messages in thread
From: Steven Smith @ 2009-10-07 19:21 UTC (permalink / raw)
  To: Ian Pratt
  Cc: xen-devel, joserenato.santos, JBeulich, Keir Fraser, Steven Smith


[-- Attachment #1.1: Type: text/plain, Size: 1123 bytes --]

> > > This patch series includes all of the Xen and tools bits of
> > > netchannel2.  It's essentially similar to the one I posted on Sunday,
> > > except:
> > >
> > > -- I've dropped the unmodified drivers support.  It'd probably be
> > >    fairly straightforward to re-introduce it, but it's not clear that
> > >    anyone's actually using unmodified drivers any more (they don't
> > >    even build against a 2.6.27 kernel, for instance).
> > 
> > At least Redhat/Fedora guys have been thinking of shipping pv-on-hvm Xen
> > drivers for Fedora 12 / RHEL6.. But I don't know what's the status of
> > that.
> Yes, this certainly isn't a feature we want to drop. In fact, it
> would be good to see the pv-on-hvm drivers modified to use some of
> the pvops functions where available.
Okay.  If this is something which we want to keep working in the
future then it might be a good idea to sanify the build system a bit.
The current approach is an unholy mixture of 2.6.18, the host kernel,
and whatever kernel you're grabbing the actual drivers from, and is
basically just asking for trouble.

Steven.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-07 19:21     ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Steven Smith
@ 2009-10-08  8:07       ` Pasi Kärkkäinen
  2009-10-08  8:25         ` Jan Beulich
  0 siblings, 1 reply; 16+ messages in thread
From: Pasi Kärkkäinen @ 2009-10-08  8:07 UTC (permalink / raw)
  To: Steven Smith
  Cc: xen-devel, joserenato.santos, JBeulich, Ian Pratt, Keir Fraser,
	Steven Smith

On Wed, Oct 07, 2009 at 08:21:08PM +0100, Steven Smith wrote:
> > > > This patch series includes all of the Xen and tools bits of
> > > > netchannel2.  It's essentially similar to the one I posted on Sunday,
> > > > except:
> > > >
> > > > -- I've dropped the unmodified drivers support.  It'd probably be
> > > >    fairly straightforward to re-introduce it, but it's not clear that
> > > >    anyone's actually using unmodified drivers any more (they don't
> > > >    even build against a 2.6.27 kernel, for instance).
> > > 
> > > At least Redhat/Fedora guys have been thinking of shipping pv-on-hvm Xen
> > > drivers for Fedora 12 / RHEL6.. But I don't know what's the status of
> > > that.
> > Yes, this certainly isn't a feature we want to drop. In fact, it
> > would be good to see the pv-on-hvm drivers modified to use some of
> > the pvops functions where available.
> Okay.  If this is something which we want to keep working in the
> future then it might be a good idea to sanify the build system a bit.
> The current approach is an unholy mixture of 2.6.18, the host kernel,
> and whatever kernel you're grabbing the actual drivers from, and is
> basically just asking for trouble.
> 

Hmm.. Did Novell guys port/fix the unmodified drivers to SLES11 (2.6.27) ?

-- Pasi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0 of 8] Xen-side netchannel2 patches, take two
  2009-10-08  8:07       ` Pasi Kärkkäinen
@ 2009-10-08  8:25         ` Jan Beulich
  0 siblings, 0 replies; 16+ messages in thread
From: Jan Beulich @ 2009-10-08  8:25 UTC (permalink / raw)
  To: Steven Smith, Pasi Kärkkäinen
  Cc: Steven Smith, Ian Pratt, xen-devel, Keir Fraser, joserenato.santos

>>> Pasi Kärkkäinen<pasik@iki.fi> 08.10.09 10:07 >>>
>Hmm.. Did Novell guys port/fix the unmodified drivers to SLES11 (2.6.27) ?

Yes. They're building for us without extra patches afaict (I think we do
need some adjustment on even newer kernels, due to the movement
of the arch include directories, but that should be an upstreamable
patch - not sure why it didn't get submitted). Of course the whole thing
gets more complicated if you want to also consider a pv-ops-Xen-enabled
kernel config, but otoh I recall Jeremy stating now and then that he
would be working on pv driver building on pure pv-ops kernel sources.

Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2009-10-08  8:25 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-06 15:35 [PATCH 0 of 8] Xen-side netchannel2 patches, take two steven.smith
2009-10-06 15:35 ` [PATCH 1 of 8] Simplify include/xen/grant_table.h a bit: steven.smith
2009-10-06 15:35 ` [PATCH 2 of 8] Slightly more accurate dependency tracking for the .c and .h files in steven.smith
2009-10-06 15:35 ` [PATCH 3 of 8] Optimize memcpy for x86 arch. If source buffers does not start at a 64 steven.smith
2009-10-06 15:35 ` [PATCH 4 of 8] Rename the struct grant_entry to struct grant_entry_v1, so that it steven.smith
2009-10-06 15:35 ` [PATCH 5 of 8] Introduce a grant_entry_v2 structure steven.smith
2009-10-06 15:35 ` [PATCH 6 of 8] Implement sub-page grant support steven.smith
2009-10-06 15:35 ` [PATCH 7 of 8] Transitive " steven.smith
2009-10-06 15:35 ` [PATCH 8 of 8] Tools-side support for creating and destroying netchannel2 interfaces steven.smith
2009-10-06 20:28 ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Pasi Kärkkäinen
2009-10-06 20:41   ` Ian Pratt
2009-10-06 21:46     ` Jeremy Fitzhardinge
2009-10-07  1:58       ` [PATCH] linux-2.6.18-xen.hg: re-syncronize ring.h Dutch Meyer
2009-10-07 19:21     ` [PATCH 0 of 8] Xen-side netchannel2 patches, take two Steven Smith
2009-10-08  8:07       ` Pasi Kärkkäinen
2009-10-08  8:25         ` Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.