]> xenbits.xensource.com Git - xentesttools/bootstrap.git/commitdiff
Update test-gnt from [PATCH v6] Userspace grant communication
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Mon, 7 Feb 2011 22:14:58 +0000 (17:14 -0500)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Mon, 7 Feb 2011 22:15:04 +0000 (17:15 -0500)
http://www.gossamer-threads.com/lists/xen/devel/197987

root_image/tools/debug/test_gnt.c

index 6e4120626c3a385b21d30443798a0835b7a918ec..eedb192c3a3abbc703df84fb0a9dc783fa38507f 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdint.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+
 struct ioctl_gntdev_grant_ref {
        /* The domain ID of the grant to be mapped. */
        uint32_t domid;
@@ -77,31 +78,112 @@ struct ioctl_gntdev_unmap_grant_ref {
     uint32_t pad;
 };
 
+/*
+ * Sets up an unmap notification within the page, so that the other side can do
+ * cleanup if this side crashes. Required to implement cross-domain robust
+ * mutexes or close notification on communication channels.
+ *
+ * Each mapped page only supports one notification; multiple calls referring to
+ * the same page overwrite the previous notification. You must clear the
+ * notification prior to the IOCTL_GNTALLOC_DEALLOC_GREF if you do not want it
+ * to occur.
+ */
+#define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \
+_IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntdev_unmap_notify))
+struct ioctl_gntdev_unmap_notify {
+       /* IN parameters */
+       /* Index of a byte in the page */
+       uint64_t index;
+       /* Action(s) to take on unmap */
+       uint32_t action;
+       /* Event channel to notify */
+       uint32_t event_channel_port;
+};
+
+/* Clear (set to zero) the byte specified by index */
+#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
+/* Send an interrupt on the indicated event channel */
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
+
+/*
+ * Sets up an unmap notification within the page, so that the other side can do
+ * cleanup if this side crashes. Required to implement cross-domain robust
+ * mutexes or close notification on communication channels.
+ *
+ * Each mapped page only supports one notification; multiple calls referring to
+ * the same page overwrite the previous notification. You must clear the
+ * notification prior to the IOCTL_GNTALLOC_DEALLOC_GREF if you do not want it
+ * to occur.
+ */
+#define IOCTL_GNTALLOC_SET_UNMAP_NOTIFY \
+_IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntalloc_unmap_notify))
+struct ioctl_gntalloc_unmap_notify {
+       /* IN parameters */
+       /* Index of a byte in the page */
+       uint64_t index;
+       /* Action(s) to take on unmap */
+       uint32_t action;
+       /* Event channel to notify */
+       uint32_t event_channel_port;
+};
+
+/* Clear (set to zero) the byte specified by index */
+#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
+/* Send an interrupt on the indicated event channel */
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
 
 int a_fd;
 int d_fd;
 
+struct shr_page {
+       uint64_t id;
+       char buffer[64];
+       uint8_t notifies[8];
+};
+
 struct data {
-       uint64_t* mem;
+       struct shr_page* mem;
        int handle;
 } items[128];
 
-void sa(int id) {
+void sa(int id)
+{
        struct ioctl_gntalloc_alloc_gref arg = {
                .domid = id,
                .flags = GNTALLOC_FLAG_WRITABLE,
                .count = 1
        };
        int rv = ioctl(a_fd, IOCTL_GNTALLOC_ALLOC_GREF, &arg);
-       if (rv)
+       if (rv) {
                printf("src-add error: %s (rv=%d)\n", strerror(errno), rv);
-       else {
-               int i=0;
-               while (items[i].mem) i++;
-               items[i].mem = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, a_fd, arg.index);
-               items[i].handle = arg.index;
-               printf("src-add mapped %d at %d=%ld\n", arg.gref_ids[0], arg.index, items[i].mem);
+               return;
+       }
+       int i=0;
+       while (items[i].mem) i++;
+       items[i].mem = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, a_fd, arg.index);
+       if (items[i].mem == MAP_FAILED) {
+               items[i].mem = 0;
+               printf("mmap failed: SHOULD NOT HAPPEN\n");
+               return;
        }
+       items[i].handle = arg.index;
+       printf("Created shared page with domain %d, grant #%d. Mapped locally at %d=%p\n",
+               id, arg.gref_ids[0], arg.index, items[i].mem);
+
+       items[i].mem->id = rand() | ((long)(getpid()) << 32);
+       items[i].mem->notifies[0] = 1;
+       struct ioctl_gntalloc_unmap_notify uarg = {
+               .index = arg.index + offsetof(struct shr_page, notifies[0]),
+               .action = UNMAP_NOTIFY_CLEAR_BYTE
+       };
+       rv = ioctl(a_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, &uarg);
+       if (rv)
+               printf("gntalloc unmap notify error: %s (rv=%d)\n", strerror(errno), rv);
 }
 
 void sd(int ref) {
@@ -113,6 +195,8 @@ void sd(int ref) {
        int rv = ioctl(a_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg);
        if (rv)
                printf("src-del error: %s (rv=%d)\n", strerror(errno), rv);
+       else
+               printf("Stopped offering grant at offset %d\n", ref);
 }
 
 void mm(int domid, int refid) {
@@ -122,15 +206,30 @@ void mm(int domid, int refid) {
                .refs[0].ref = refid,
        };
        int rv = ioctl(d_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &arg);
-       if (rv)
-               printf("mm error: %s (rv=%d)\n", strerror(errno), rv);
-       else {
-               int i=0;
-               while (items[i].mem) i++;
-               items[i].mem = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, d_fd, arg.index);
-               items[i].handle = arg.index;
-               printf("mapped index %d at %ld\n", arg.index, items[i].mem);
+       if (rv) {
+               printf("Could not map grant %d.%d: %s (rv=%d)\n", domid, refid, strerror(errno), rv);
+               return;
        }
+       int i=0,j=1;
+       while (items[i].mem) i++;
+       items[i].mem = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, d_fd, arg.index);
+       if (items[i].mem == MAP_FAILED) {
+               items[i].mem = 0;
+               printf("Could not map grant %d.%d: %s (map failed)\n", domid, refid, strerror(errno), rv);
+               return;
+       }
+       items[i].handle = arg.index;
+       printf("Mapped grant %d.%d as %d=%p\n", domid, refid, arg.index, items[i].mem);
+
+       while (items[i].mem->notifies[j]) j++;
+       items[i].mem->notifies[j] = 1;
+       struct ioctl_gntalloc_unmap_notify uarg = {
+               .index = arg.index + offsetof(struct shr_page, notifies[j]),
+               .action = UNMAP_NOTIFY_CLEAR_BYTE
+       };
+       rv = ioctl(d_fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, &uarg);
+       if (rv)
+               printf("gntdev unmap notify error: %s (rv=%d)\n", strerror(errno), rv);
 }
 
 void gu(int index) {
@@ -141,6 +240,8 @@ void gu(int index) {
        int rv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg);
        if (rv)
                printf("gu error: %s (rv=%d)\n", strerror(errno), rv);
+       else
+               printf("Unhooked mapped grant at offset %d\n", index);
 }
 
 void mu(void* addr) {
@@ -152,19 +253,22 @@ void mu(void* addr) {
                        items[i].mem = 0;
                i++;
        }
+       printf("Unmapped page at %p\n", addr);
 }
 
-int bump;
-
-void show() {
+void show(char* word) {
        int i;
+       int wlen = strlen(word);
        for(i=0; i < 128; i++) {
                if (!items[i].mem)
                        continue;
-               uint64_t val = items[i].mem[0];
-               uint64_t repl = val + bump;
-               printf("%02d(%ld,%d): current %16lx   new %16lx\n", i, items[i].mem, items[i].handle, val, repl);
-               items[i].mem[0] = repl;
+               memmove(items[i].mem->buffer + wlen, items[i].mem->buffer, 63 - wlen);
+               memcpy(items[i].mem->buffer, word, wlen);
+               printf("%02d(%ld,%d): id %16lx n=%d%d%d%d%d%d%d%d b=%s\n",
+                       i, items[i].mem, items[i].handle, items[i].mem->id,
+                       items[i].mem->notifies[0], items[i].mem->notifies[1], items[i].mem->notifies[2], items[i].mem->notifies[3], 
+                       items[i].mem->notifies[4], items[i].mem->notifies[5], items[i].mem->notifies[6], items[i].mem->notifies[7], 
+                       items[i].mem->buffer);
        }
        printf("END\n");
 }
@@ -172,37 +276,38 @@ void show() {
 int main(int argc, char** argv) {
        a_fd = open("/dev/xen/gntalloc", O_RDWR);
        d_fd = open("/dev/xen/gntdev", O_RDWR);
-       bump = 1 << (2 * (getpid() % 12));
        printf(
-               "src-add <domid>       return gntref, address\n"
+               "add <domid>           return gntref, address\n"
                "map <domid> <ref>     return index, address\n"
-               "src-del <gntref>      no rv\n"
-               "gu <index>            no rv\n"
-               "unmap <address>       no rv\n"
-               "show                  print and change mapped items\n"
-               " This process bumps by %x\n",
-               bump
+               "adel <gntref>         delete <add> internal\n"
+               "ddel <index>          delete <map> internal\n"
+               "unmap <address>       unmap memory\n"
+               "show                  show all pages\n"
+               "<word>                append word to all mapped pages, show\n"
+               " PID %x\n", getpid()
        );
        while (1) {
                char line[80];
-               char word[30];
+               char word[80];
                long a, b;
                printf("\n> ");
                fflush(stdout);
                fgets(line, 80, stdin);
                sscanf(line, "%s %ld %ld", word, &a, &b);
-               if (!strcmp(word, "src-add")) {
+               if (!strcmp(word, "add")) {
                        sa(a);
-               } else if (!strcmp(word, "src-del")) {
-                       sd(a);
                } else if (!strcmp(word, "map")) {
                        mm(a, b);
-               } else if (!strcmp(word, "gu")) {
+               } else if (!strcmp(word, "adel")) {
+                       sd(a);
+               } else if (!strcmp(word, "ddel")) {
                        gu(a);
                } else if (!strcmp(word, "unmap")) {
                        mu((void*)a);
+               } else if (!strcmp(word, "show")) {
+                       show("");
                } else {
-                       show();
+                       show(word);
                }
        }
 }