1 #include <linux/errno.h>
2 #include <linux/percpu.h>
3 #include <linux/sched.h>
4 #include <linux/uaccess.h>
6 #include <linux/poll.h>
7 #include <linux/anon_inodes.h>
8 #include <linux/file.h>
12 #include "linux-exts.h"
16 static int memtrack_size(struct v3_guest *guest,
21 struct v3_mem_track_sizes size;
23 v3_mem_track_get_sizes(guest->v3_ctx,&size.num_cores,&size.num_pages);
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");
35 static int memtrack_cmd(struct v3_guest *guest,
40 struct v3_mem_track_cmd cmd;
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");
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");
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");
58 ERROR("palacios: unknown memory tracking request\n");
67 #define MIN(x,y) ( (x) < (y) ? (x) : (y) )
68 #define CEIL_DIV(x,y) ( ( (x) / (y) ) + !!( (x) % (y) ) )
71 static int memtrack_snap(struct v3_guest *guest,
76 v3_mem_track_snapshot temp;
77 struct v3_core_mem_track ctemp;
81 uint64_t core_header_size;
82 uint64_t offset_to_num_cores;
84 v3_mem_track_snapshot *user_snap=0;
85 v3_mem_track_snapshot *sys_snap=0;
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;
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);
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");
100 INFO("num_cores=%u",num_cores);
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");
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");
112 // Now we have the user's target - note that num_pages and access_bitmap need to be supplied
114 if (!(sys_snap=v3_mem_track_take_snapshot(guest->v3_ctx))) {
115 ERROR("palacios: unable to get snapshot from core\n");
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);
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");
129 for (i=0;i<MIN(num_cores,sys_snap->num_cores);i++) {
131 if (copy_to_user((void __user *)(arg + header_size + i * sizeof(struct v3_core_mem_track)),
134 ERROR("palacios: unable to copy core meta data\n");
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");
147 v3_mem_track_free_snapshot(sys_snap);
148 palacios_free(user_snap);
153 v3_mem_track_free_snapshot(sys_snap);
156 palacios_free(user_snap);
168 static int memtrack_init( void )
175 static int memtrack_deinit( void ) {
183 static int guest_memtrack_init(struct v3_guest * guest, void ** vm_data)
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);
194 static int guest_memtrack_deinit(struct v3_guest * guest, void * vm_data) {
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);
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
214 register_extension(&memtrack_ext);