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.


Cleanup and sanity-checking of integer overflow, null comparisons, dead code (Coverit...
[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     // overflow possible here, but only for an insane number of cores
103     if (!(user_snap=palacios_alloc(sizeof(v3_mem_track_snapshot) + num_cores * sizeof(struct v3_core_mem_track)))) {
104         ERROR("palacios: cannot allocate memory for copying user snapshot\n");
105         goto fail;
106     }
107
108     if (copy_from_user(user_snap,(void __user *)arg,sizeof(v3_mem_track_snapshot) + num_cores*sizeof(struct v3_core_mem_track))) { 
109         ERROR("palacios: cannot copy user memory track snapshot request\n");
110         goto fail;
111     }
112
113     // Now we have the user's target - note that num_pages and access_bitmap need to be supplied
114
115     if (!(sys_snap=v3_mem_track_take_snapshot(guest->v3_ctx))) { 
116         ERROR("palacios: unable to get snapshot from core\n");
117         goto fail;
118     }
119
120     //INFO("snapshot: numcores=%u, core[0].num_pages=%llu, request_numcores=%u\n", 
121     // sys_snap->num_cores, sys_snap->core[0].num_pages, num_cores);
122
123     // Copy the meta data
124     if (copy_to_user((void __user *)arg, sys_snap, header_size)) {
125         ERROR("palacios: unable to copy meta data\n");
126         goto fail;
127     }
128
129     // Now per core
130     for (i=0;i<MIN(num_cores,sys_snap->num_cores);i++) { 
131         // copy metadata
132         if (copy_to_user((void __user *)(arg + header_size + i * sizeof(struct v3_core_mem_track)),
133                          &sys_snap->core[i],
134                          core_header_size)) { 
135             ERROR("palacios: unable to copy core meta data\n");
136             goto fail;
137         }
138
139         // copy the bitmap
140         if (copy_to_user((void __user *) user_snap->core[i].access_bitmap,
141                          sys_snap->core[i].access_bitmap,
142                          CEIL_DIV(MIN(user_snap->core[i].num_pages,sys_snap->core[i].num_pages),8))) { 
143             ERROR("palacios: unable to copy core data\n");
144             return -1;
145         }
146     }
147
148     v3_mem_track_free_snapshot(sys_snap);
149     palacios_free(user_snap);
150     return 0;
151
152  fail:
153     if (sys_snap) { 
154         v3_mem_track_free_snapshot(sys_snap);
155     }
156     if (user_snap) { 
157         palacios_free(user_snap);
158     }
159     return -EFAULT;
160 }
161
162             
163     
164     
165
166
167
168
169 static int memtrack_init( void ) 
170 {
171     // nothing yet
172     return 0;
173 }
174
175
176 static int memtrack_deinit( void ) {
177
178     // nothing yet
179     return 0;
180 }
181
182
183
184 static int guest_memtrack_init(struct v3_guest * guest, void ** vm_data) 
185 {
186
187     add_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE, memtrack_size, guest);
188     add_guest_ctrl(guest, V3_VM_MEM_TRACK_CMD, memtrack_cmd, guest);
189     add_guest_ctrl(guest, V3_VM_MEM_TRACK_SNAP, memtrack_snap, guest);
190
191     return 0;
192 }
193
194
195 static int guest_memtrack_deinit(struct v3_guest * guest, void * vm_data) {
196
197     remove_guest_ctrl(guest,V3_VM_MEM_TRACK_SNAP);
198     remove_guest_ctrl(guest,V3_VM_MEM_TRACK_CMD);
199     remove_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE);
200
201     return 0;
202 }
203
204
205
206 static struct linux_ext memtrack_ext = {
207     .name = "MEMTRACK_EXTENSION",
208     .init = memtrack_init,
209     .deinit = memtrack_deinit,
210     .guest_init = guest_memtrack_init,
211     .guest_deinit = guest_memtrack_deinit
212 };
213
214
215 register_extension(&memtrack_ext);