2 Device File Virtualization Guest Preload Library
4 (c) Akhil Guliani and William Gross, 2015
6 Adapted from MPI module (c) 2012 Peter Dinda
14 #include <sys/types.h>
19 #include "devfile_hc.h"
20 #include "devfile_guest_fd_tracker.h"
22 static int __LocalFD = 0;
23 static int __last_open_index = -1;
26 unsigned long long syscall();
28 int touch_ptr(volatile char* ptr, int size)
31 for(i=0;i<size;i+=4096){
32 // both read and write it
38 int open(const char *path, int flags, mode_t mode)
41 DEBUG_PRINT("path %s %d %d\n", path, flags, mode);
43 __last_open_index = check_name(path,dtrack);
45 if (__last_open_index>=0) {
46 DEBUG_PRINT("In our file, \n");
47 __LocalFD = dtrack[__last_open_index].devFD;
51 // Execute open hypercall here
54 int path_length = strlen(path)+1;
55 //check if path is across a page boundary
56 //if so try to copy into a local buffer, that doesn't cross a page boundary
57 //if its greater than 4k, fail
58 if (path_length > 4096){
59 DEBUG_PRINT("Path greater than 4k, failing open\n");
62 //forcing path to be in a single page
63 my_path = (char*)((((unsigned long long)buf+4096)/4096)*4096);
64 strcpy(my_path,path); // my_path is touched via this
66 int rcFD = dev_file_syscall_hcall(SYS64_OPEN,(long long)my_path,flags,0 ,0,0,0,&sys_errno);
67 DEBUG_PRINT(" ReturnFD : %d; \n", rcFD);
69 // set global errno so caller can see
74 DEBUG_PRINT("performing original open\n");
76 return syscall(SYS64_OPEN, path, flags, mode);
80 size_t read(int fd, void *buf, size_t count)
82 //does buf+count extend pass page boundary?
83 //if so, only do up to page boundary
84 // if( (buf%4096)+count <= 4096)
87 if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)){
89 //Need to handle only up to a page boundary, can't handle contiguous pages right now
90 count = MIN(count,4096-((unsigned long long)buf%4096));
92 int ret = dev_file_syscall_hcall(SYS64_READ,fd,(long long)buf,count,0,0,0,&sys_errno);
93 DEBUG_PRINT("Read of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
97 DEBUG_PRINT("performing original read\n");
98 return syscall(SYS64_READ,fd, buf, count);
102 ssize_t write(int fd, const void *buf, size_t count)
104 if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)) {
106 //Need to handle only up to a page boundary, can't handle contiguous pages right now
107 count = MIN(count,4096-((unsigned long long)buf%4096));
108 touch_ptr((char*)buf,count);
109 int ret = dev_file_syscall_hcall(SYS64_WRITE,fd, (long long)buf,count,0,0,0,&sys_errno);
110 DEBUG_PRINT("Write of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
114 DEBUG_PRINT("performing original write\n");
115 return syscall(SYS64_WRITE,fd, buf, count);
121 int index = check_fd(fd,dtrack);
122 if (fd == __LocalFD || (index>=0)) {
124 int ret = dev_file_syscall_hcall(SYS64_CLOSE,fd,0,0,0,0,0,&sys_errno);
126 dtrack[index].devFD = -1;
129 DEBUG_PRINT("Close returned %d (errno %lld)\n",ret, sys_errno);
133 DEBUG_PRINT("performing original close\n");
134 return syscall(SYS64_CLOSE,fd);
139 int ioctl(int fd, int request, void* data) {
141 int index = check_fd(fd,dtrack);
143 // this is where a careful, device-specific decode is needed
144 // to figure out whether the argument or anything it points
146 if (fd == __LocalFD || (index>=0)) {
147 long long sys_errno=0;
149 // First cut for just the data pointer:
150 // if (data > &sign_post){
154 ret = dev_file_syscall_hcall(SYS64_IOCTL,fd,request,(unsigned long long)data,0,0,0,&sys_errno);
156 DEBUG_PRINT("ioctl(%d) returned %d (errno %lld)\n",request,ret, sys_errno);
161 return syscall(SYS64_IOCTL,fd,request,data);