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){
37 int open(const char *path, int flags, mode_t mode)
40 DEBUG_PRINT("path %s %d %d\n", path, flags, mode);
42 __last_open_index = check_name(path,dtrack);
44 if (__last_open_index>=0) {
45 DEBUG_PRINT("In our file, \n");
46 __LocalFD = dtrack[__last_open_index].devFD;
50 // Execute open hypercall here
53 int path_length = strlen(path)+1;
54 //check if path is across a page boundary
55 //if so try to copy into a local buffer, that doesn't cross a page boundary
56 //if its greater than 4k, fail
57 if (path_length > 4096){
58 DEBUG_PRINT("Path greater than 4k, failing open\n");
61 //forcing path to be in a single page
62 my_path = (char*)((((unsigned long long)buf+4096)/4096)*4096);
63 strcpy(my_path,path); // my_path is touched via this
65 int rcFD = dev_file_syscall_hcall(SYS64_OPEN,(long long)my_path,flags,0 ,0,0,0,&sys_errno);
66 DEBUG_PRINT(" ReturnFD : %d; \n", rcFD);
68 // set global errno so caller can see
73 DEBUG_PRINT("performing original open\n");
75 return syscall(SYS64_OPEN, path, flags, mode);
79 size_t read(int fd, void *buf, size_t count)
81 //does buf+count extend pass page boundary?
82 //if so, only do up to page boundary
83 // if( (buf%4096)+count <= 4096)
86 if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)){
88 //Need to handle only up to a page boundary, can't handle contiguous pages right now
89 count = MIN(count,4096-((unsigned long long)buf%4096));
91 int ret = dev_file_syscall_hcall(SYS64_READ,fd,(long long)buf,count,0,0,0,&sys_errno);
92 DEBUG_PRINT("Read of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
96 DEBUG_PRINT("performing original read\n");
97 return syscall(SYS64_READ,fd, buf, count);
101 ssize_t write(int fd, const void *buf, size_t count)
103 if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)) {
105 //Need to handle only up to a page boundary, can't handle contiguous pages right now
106 count = MIN(count,4096-((unsigned long long)buf%4096));
107 touch_ptr((char*)buf,count);
108 int ret = dev_file_syscall_hcall(SYS64_WRITE,fd, (long long)buf,count,0,0,0,&sys_errno);
109 DEBUG_PRINT("Write of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
113 DEBUG_PRINT("performing original write\n");
114 return syscall(SYS64_WRITE,fd, buf, count);
120 int index = check_fd(fd,dtrack);
121 if (fd == __LocalFD || (index>=0)) {
123 int ret = dev_file_syscall_hcall(SYS64_CLOSE,fd,0,0,0,0,0,&sys_errno);
125 dtrack[index].devFD = -1;
128 DEBUG_PRINT("Close returned %d (errno %lld)\n",ret, sys_errno);
132 DEBUG_PRINT("performing original close\n");
133 return syscall(SYS64_CLOSE,fd);
138 int ioctl(int fd, int request, void* data) {
140 int index = check_fd(fd,dtrack);
142 // this is where a careful, device-specific decode is needed
143 // to figure out whether the argument or anything it points
145 if (fd == __LocalFD || (index>=0)) {
146 long long sys_errno=0;
148 // First cut for just the data pointer:
149 // if (data > &sign_post){
153 ret = dev_file_syscall_hcall(SYS64_IOCTL,fd,request,(unsigned long long)data,0,0,0,&sys_errno);
155 DEBUG_PRINT("ioctl(%d) returned %d (errno %lld)\n",request,ret, sys_errno);
160 return syscall(SYS64_IOCTL,fd,request,data);