Page MenuHomeFreeBSD
Authored By
akshay1994.leo_gmail.com
Aug 3 2016, 7:47 PM
Size
6 KB
Referenced Files
None
Subscribers
None

freebsd_interactive_test.c

#if defined(__linux__)
#include <stdint.h>
#include <xen/sys/gntdev.h>
#include <xen/sys/gntalloc.h>
#else
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/xen/gntdev.h>
#endif
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define PAGE_SHIFT 12
#ifndef PAGE_SIZE
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#endif
struct xengrantdevice
{
int alloc_fd;
int map_fd;
int alloc_index;
int alloc_gref;
void* alloc_addr;
int map_index;
void* map_addr;
void* map_addr2;
};
int open_device(struct xengrantdevice *xgt)
{
#if defined(__linux__)
int fd1 = open("/dev/xen/gntalloc", O_RDWR);
int fd2 = open("/dev/xen/gntdev", O_RDWR);
if (fd1 == -1 || fd2 == -1)
return -1;
xgt->alloc_fd = fd1;
xgt->map_fd = fd2;
#else
int fd = open("/dev/xen/gntdev", O_RDWR);
if (fd == -1)
return fd;
xgt->alloc_fd = xgt->map_fd = fd;
#endif
return 0;
}
int alloc_page(struct xengrantdevice *xgt, int domid)
{
#if defined(__linux__)
struct ioctl_gntalloc_alloc_gref request =
{
.domid = domid,
.flags = GNTALLOC_FLAG_WRITABLE,
.count = 1,
};
int error = ioctl(xgt->alloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, &request);
#else
struct ioctl_gntdev_alloc_gref request =
{
.domid = domid,
.flags = GNTDEV_ALLOC_FLAG_WRITABLE,
.count = 1,
};
int error = ioctl(xgt->alloc_fd, IOCTL_GNTDEV_ALLOC_GREF, &request);
#endif
if (error == -1)
{
printf("IOCTL_ALLOC failed.\n");
printf("Status: %d\n", errno);
return -1;
}
xgt->alloc_index = request.index;
xgt->alloc_gref = request.gref_ids[0];
xgt->alloc_addr = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, xgt->alloc_fd, xgt->alloc_index);
if (xgt->alloc_addr == MAP_FAILED)
{
printf("MMAP failed.\n");
printf("Status: %d\n", errno);
return -1;
}
if (munmap(xgt->alloc_addr, PAGE_SIZE) == -1)
{
printf("MUNMAP failed.\n");
printf("Status: %d\n", errno);
return -1;
}
xgt->alloc_addr = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, xgt->alloc_fd, xgt->alloc_index);
if (xgt->alloc_addr == MAP_FAILED)
{
printf("MMAP failed.\n");
printf("Status: %d\n", errno);
return -1;
}
struct ioctl_gntdev_unmap_notify notify = {
.action = UNMAP_NOTIFY_CLEAR_BYTE,
.index = (int*)xgt->alloc_index + 1,
};
error = ioctl(xgt->alloc_fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, &notify);
if (error == -1)
{
printf("IOCTL_NOTIFY failed.\n");
printf("Status: %d\n", errno);
return -1;
}
return 0;
}
int dealloc_page(struct xengrantdevice *xgt)
{
if (munmap(xgt->alloc_addr, PAGE_SIZE) == -1)
{
printf("MUNMAP failed.\n");
printf("Status: %d\n", errno);
return -1;
}
#if defined(__linux__)
struct ioctl_gntalloc_dealloc_gref request =
{
.index = xgt->alloc_index,
.count = 1,
};
if (ioctl(xgt->alloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &request) == -1)
#else
struct ioctl_gntdev_dealloc_gref request =
{
.index = xgt->alloc_index,
.count = 1,
};
if (ioctl(xgt->alloc_fd, IOCTL_GNTDEV_DEALLOC_GREF, &request) == -1)
#endif
{
printf("ioctl failed.\n");
printf("Status: %d\n", errno);
return -1;
}
return 0;
}
int map_page(struct xengrantdevice *xgt, int domid, int gref)
{
struct ioctl_gntdev_map_grant_ref request =
{
.count = 1,
};
request.refs[0].domid = domid;
request.refs[0].ref = gref;
if (ioctl(xgt->map_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &request) == -1)
return -1;
xgt->map_index = request.index;
xgt->map_addr = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, xgt->map_fd, xgt->map_index);
if(xgt->map_addr == MAP_FAILED)
return -1;
if (munmap(xgt->map_addr, PAGE_SIZE) == -1)
return -1;
xgt->map_addr = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, xgt->map_fd, xgt->map_index);
if(xgt->map_addr == MAP_FAILED)
return -1;
xgt->map_addr2 = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, xgt->map_fd, xgt->map_index);
if(xgt->map_addr2 == MAP_FAILED)
return -1;
struct ioctl_gntdev_get_offset_for_vaddr req =
{
.vaddr = xgt->map_addr,
};
if (ioctl(xgt->map_fd, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, &req) == -1)
return -1;
assert(req.offset == xgt->map_index);
assert(req.count == 1);
printf("%p %p\n", xgt->map_addr, xgt->map_addr2);
struct ioctl_gntdev_unmap_notify notify = {
.action = UNMAP_NOTIFY_CLEAR_BYTE,
.index = (int*)xgt->map_index + 1,
};
int error = ioctl(xgt->map_fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, &notify);
if (error == -1)
{
printf("IOCTL_NOTIFY failed.\n");
printf("Status: %d\n", errno);
return -1;
}
return 0;
}
int unmap_page(struct xengrantdevice *xgt)
{
if (munmap(xgt->map_addr, PAGE_SIZE) == -1)
return -1;
struct ioctl_gntdev_unmap_grant_ref request =
{
.index = xgt->map_index,
.count = 1,
};
if (ioctl(xgt->map_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &request) == -1)
return -1;
return 0;
}
void write1(int *addr, int write_zero)
{
for(int i=0; i<PAGE_SIZE/sizeof(int); i++)
addr[i] = write_zero ? 0 : i;
}
void read_verify(int *addr)
{
for(int i=0; i<PAGE_SIZE/sizeof(int); i++)
assert(addr[i] == i);
}
int main()
{
int x = -1;
struct xengrantdevice xgt;
while(x)
{
printf("0. Exit\n");
printf("1. Open\n");
printf("2. Close\n");
printf("3. Alloc\n");
printf("4. Dealloc\n");
printf("5. Map\n");
printf("6. Unmap\n");
printf("7. Write alloc\n");
printf("8. Write alloc 0\n");
printf("9. Write map\n");
printf("10. Write map 0\n");
printf("11. Read alloc\n");
printf("12. Read map\n");
printf("13. Read map2\n");
scanf("%d", &x);
switch(x)
{
case 0: break;
case 1: if(open_device(&xgt)) printf("FAIL\n"); break;
case 2: if(xgt.alloc_fd != xgt.map_fd) if(close(xgt.map_fd) == -1) printf("FAIL\n"); if(close(xgt.alloc_fd) == -1) printf("FAIL\n"); break;
case 3:
{
int y;
printf("Enter dom_id: ");
scanf("%d", &y);
if(alloc_page(&xgt, y)) printf("FAIL\n");
printf("Gref: %d\n", xgt.alloc_gref);
}
break;
case 4: if(dealloc_page(&xgt)) printf("FAIL\n"); break;
case 5:
{
int y,z;
printf("Enter dom_id: ");
scanf("%d", &y);
printf("Enter gref: ");
scanf("%d", &z);
if(map_page(&xgt, y, z)) printf("FAIL\n");
}
break;
case 6: if(unmap_page(&xgt)) printf("FAIL\n"); break;
case 7: write1(xgt.alloc_addr, 0); break;
case 8: write1(xgt.alloc_addr, 1); break;
case 9: write1(xgt.map_addr, 0); break;
case 10: write1(xgt.map_addr, 1); break;
case 11: read_verify(xgt.alloc_addr); break;
case 12: read_verify(xgt.map_addr); break;
case 13: read_verify(xgt.map_addr2); break;
}
}
return 0;
}

File Metadata

Mime Type
text/x-c
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
568898
Default Alt Text
freebsd_interactive_test.c (6 KB)

Event Timeline