Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


b64ab296196482de1cd2dc631098c1b62f4060fd
[palacios.git] / linux_module / memtrack.c
1 #include <linux/errno.h>
2 #include <linux/percpu.h>
3 #include <linux/sched.h>
4 #include <linux/uaccess.h>
5 #include <linux/fs.h>
6 #include <linux/poll.h>
7 #include <linux/anon_inodes.h>
8 #include <linux/file.h>
9
10 #include "palacios.h"
11 #include "memtrack.h"
12 #include "linux-exts.h"
13 #include "vm.h"
14
15
16 static int memtrack_size(struct v3_guest *guest,
17                          unsigned int ioctl,
18                          unsigned long arg,
19                          void *priv_data)
20 {
21     struct v3_mem_track_sizes size;
22     
23     v3_mem_track_get_sizes(guest->v3_ctx,&size.num_cores,&size.num_pages);
24     
25
26     if (copy_to_user((void __user *)arg, &size, sizeof(struct v3_mem_track_sizes))) {
27         ERROR("palacios: unable to copy sizes to user\n");
28         return -EFAULT;
29     }
30
31     return 0;
32
33 }
34
35 static int memtrack_cmd(struct v3_guest *guest,
36                         unsigned int ioctl,
37                         unsigned long arg,
38                         void *priv_data)
39 {
40     struct v3_mem_track_cmd cmd;
41     
42     if (copy_from_user(&cmd,(void __user *)arg,sizeof(struct v3_mem_track_cmd))) { 
43         ERROR("palacios: unable to copy memory tracking command from user\n");
44         return -EFAULT;
45     }
46     
47     if (cmd.request == V3_MEM_TRACK_START) { 
48         if (v3_mem_track_start(guest->v3_ctx, cmd.config.access_type, cmd.config.reset_type, cmd.config.period)) {
49             ERROR("palacios: unable to start memory tracking\n");
50             return -EFAULT;
51         }
52     } else if (cmd.request == V3_MEM_TRACK_STOP) { 
53         if (v3_mem_track_stop(guest->v3_ctx)) { 
54             ERROR("palacios: unable to stop memory tracking\n");
55             return -EFAULT;
56         }
57     } else {
58         ERROR("palacios: unknown memory tracking request\n");
59         return -EFAULT;
60     }
61     
62     return 0;
63
64 }
65
66
67 #define MIN(x,y) ( (x) < (y) ? (x) : (y) )
68 #define CEIL_DIV(x,y) ( ( (x) / (y) ) + !!( (x) % (y) ) )
69
70
71 static int memtrack_snap(struct v3_guest *guest,
72                          unsigned int ioctl,
73                          unsigned long arg,
74                          void *priv_data)
75 {
76     v3_mem_track_snapshot temp;
77     struct v3_core_mem_track   ctemp;
78     uint32_t num_cores;
79     uint32_t i;
80     uint64_t header_size;
81     uint64_t core_header_size;
82     uint64_t offset_to_num_cores;
83
84     v3_mem_track_snapshot *user_snap=0;
85     v3_mem_track_snapshot *sys_snap=0;
86
87     
88     offset_to_num_cores = (uint64_t)&(temp.num_cores) - (uint64_t)&temp;
89     header_size = (uint64_t)&(temp.core[0]) - (uint64_t)&temp;
90     core_header_size = (uint64_t)&(ctemp.access_bitmap) - (uint64_t)&ctemp;
91
92     //    INFO("offset_to_num_cores=%llu header_size=%llu core_header_size=%llu\n",
93     //   offset_to_num_cores, header_size, core_header_size);
94     
95     if (copy_from_user(&num_cores,((void __user *)arg) + offset_to_num_cores,sizeof(num_cores))) { 
96         ERROR("palacios: cannot copy number of cores from user\n");
97         goto fail;
98     }
99     
100     //INFO("num_cores=%u",num_cores);
101
102     if (!(user_snap=palacios_alloc(sizeof(v3_mem_track_snapshot) + num_cores * sizeof(struct v3_core_mem_track)))) {
103         ERROR("palacios: cannot allocate memory for copying user snapshot\n");
104         goto fail;
105     }
106
107     if (copy_from_user(user_snap,(void __user *)arg,sizeof(v3_mem_track_snapshot) + num_cores*sizeof(struct v3_core_mem_track))) { 
108         ERROR("palacios: cannot copy user memory track snapshot request\n");
109         goto fail;
110     }
111
112     // Now we have the user's target - note that num_pages and access_bitmap need to be supplied
113
114     if (!(sys_snap=v3_mem_track_take_snapshot(guest->v3_ctx))) { 
115         ERROR("palacios: unable to get snapshot from core\n");
116         goto fail;
117     }
118
119     //INFO("snapshot: numcores=%u, core[0].num_pages=%llu, request_numcores=%u\n", 
120     // sys_snap->num_cores, sys_snap->core[0].num_pages, num_cores);
121
122     // Copy the meta data
123     if (copy_to_user((void __user *)arg, sys_snap, header_size)) {
124         ERROR("palacios: unable to copy meta data\n");
125         goto fail;
126     }
127
128     // Now per core
129     for (i=0;i<MIN(num_cores,sys_snap->num_cores);i++) { 
130         // copy metadata
131         if (copy_to_user((void __user *)(arg + header_size + i * sizeof(struct v3_core_mem_track)),
132                          &sys_snap->core[i],
133                          core_header_size)) { 
134             ERROR("palacios: unable to copy core meta data\n");
135             goto fail;
136         }
137
138         // copy the bitmap
139         if (copy_to_user((void __user *) user_snap->core[i].access_bitmap,
140                          sys_snap->core[i].access_bitmap,
141                          CEIL_DIV(MIN(user_snap->core[i].num_pages,sys_snap->core[i].num_pages),8))) { 
142             ERROR("palacios: unable to copy core data\n");
143             return -1;
144         }
145     }
146
147     v3_mem_track_free_snapshot(sys_snap);
148     palacios_free(user_snap);
149     return 0;
150
151  fail:
152     if (sys_snap) { 
153         v3_mem_track_free_snapshot(sys_snap);
154     }
155     if (user_snap) { 
156         palacios_free(user_snap);
157     }
158     return -EFAULT;
159 }
160
161             
162     
163     
164
165
166
167
168 static int memtrack_init( void ) 
169 {
170     // nothing yet
171     return 0;
172 }
173
174
175 static int memtrack_deinit( void ) {
176
177     // nothing yet
178     return 0;
179 }
180
181
182
183 static int guest_memtrack_init(struct v3_guest * guest, void ** vm_data) 
184 {
185
186     add_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE, memtrack_size, guest);
187     add_guest_ctrl(guest, V3_VM_MEM_TRACK_CMD, memtrack_cmd, guest);
188     add_guest_ctrl(guest, V3_VM_MEM_TRACK_SNAP, memtrack_snap, guest);
189
190     return 0;
191 }
192
193
194 static int guest_memtrack_deinit(struct v3_guest * guest, void * vm_data) {
195
196     remove_guest_ctrl(guest,V3_VM_MEM_TRACK_SNAP);
197     remove_guest_ctrl(guest,V3_VM_MEM_TRACK_CMD);
198     remove_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE);
199
200     return 0;
201 }
202
203
204
205 static struct linux_ext memtrack_ext = {
206     .name = "MEMTRACK_EXTENSION",
207     .init = memtrack_init,
208     .deinit = memtrack_deinit,
209     .guest_init = guest_memtrack_init,
210     .guest_deinit = guest_memtrack_deinit
211 };
212
213
214 register_extension(&memtrack_ext);