#include #include #include #include #include #include #include #include struct ioctl_gntdev_grant_ref { /* The domain ID of the grant to be mapped. */ uint32_t domid; /* The grant reference of the grant to be mapped. */ uint32_t ref; }; /* * Allocates a new page and creates a new grant reference. */ #define IOCTL_GNTALLOC_ALLOC_GREF \ _IOC(_IOC_NONE, 'G', 5, sizeof(struct ioctl_gntalloc_alloc_gref)) struct ioctl_gntalloc_alloc_gref { /* IN parameters */ /* The ID of the domain to be given access to the grants. */ uint16_t domid; /* Flags for this mapping */ uint16_t flags; /* Number of pages to map */ uint32_t count; /* OUT parameters */ /* The offset to be used on a subsequent call to mmap(). */ uint64_t index; /* The grant references of the newly created grant, one per page */ /* Variable size, depending on count */ uint32_t gref_ids[1]; }; #define GNTALLOC_FLAG_WRITABLE 1 /* * Deallocates the grant reference, allowing the associated page to be freed if * no other domains are using it. */ #define IOCTL_GNTALLOC_DEALLOC_GREF \ _IOC(_IOC_NONE, 'G', 6, sizeof(struct ioctl_gntalloc_dealloc_gref)) struct ioctl_gntalloc_dealloc_gref { /* IN parameters */ /* The offset returned in the map operation */ uint64_t index; /* Number of references to unmap */ uint32_t count; }; #define IOCTL_GNTDEV_MAP_GRANT_REF \ _IOC(_IOC_NONE, 'G', 0, sizeof(struct ioctl_gntdev_map_grant_ref)) struct ioctl_gntdev_map_grant_ref { /* IN parameters */ /* The number of grants to be mapped. */ uint32_t count; uint32_t pad; /* OUT parameters */ /* The offset to be used on a subsequent call to mmap(). */ uint64_t index; /* Variable IN parameter. */ /* Array of grant references, of size @count. */ struct ioctl_gntdev_grant_ref refs[1]; }; #define GNTDEV_MAP_WRITABLE 0x1 #define IOCTL_GNTDEV_UNMAP_GRANT_REF \ _IOC(_IOC_NONE, 'G', 1, sizeof(struct ioctl_gntdev_unmap_grant_ref)) struct ioctl_gntdev_unmap_grant_ref { /* IN parameters */ /* The offset was returned by the corresponding map operation. */ uint64_t index; /* The number of pages to be unmapped. */ uint32_t count; uint32_t pad; }; int a_fd; int d_fd; struct data { uint64_t* mem; int handle; } items[128]; 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) 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); } } void sd(int ref) { struct ioctl_gntalloc_dealloc_gref arg = { .index = ref, .count = 1 }; int rv = ioctl(a_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg); if (rv) printf("src-del error: %s (rv=%d)\n", strerror(errno), rv); } void mm(int domid, int refid) { struct ioctl_gntdev_map_grant_ref arg = { .count = 1, .refs[0].domid = domid, .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); } } void gu(int index) { struct ioctl_gntdev_unmap_grant_ref arg = { .index = index, .count = 1, }; int rv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg); if (rv) printf("gu error: %s (rv=%d)\n", strerror(errno), rv); } void mu(void* addr) { int i = 0; munmap(addr, 4096); while (i < 128) { if (items[i].mem == addr) items[i].mem = 0; i++; } } int bump; void show() { int i; 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; } printf("END\n"); } 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 return gntref, address\n" "map return index, address\n" "src-del no rv\n" "gu no rv\n" "unmap
no rv\n" "show print and change mapped items\n" " This process bumps by %x\n", bump ); while (1) { char line[80]; char word[30]; long a, b; printf("\n> "); fflush(stdout); fgets(line, 80, stdin); sscanf(line, "%s %ld %ld", word, &a, &b); if (!strcmp(word, "src-add")) { sa(a); } else if (!strcmp(word, "src-del")) { sd(a); } else if (!strcmp(word, "map")) { mm(a, b); } else if (!strcmp(word, "gu")) { gu(a); } else if (!strcmp(word, "unmap")) { mu((void*)a); } else { show(); } } }