uint64_t start, end, num;
uint64_t guest_cur;
uint64_t num_regions;
+ uint64_t num_regions_shown;
if (!(f=fopen(GUEST_FILE,"r"))) {
fprintf(stderr,"Could not find number of regions for %s\n",vmdev);
return 0;
}
- if (sscanf(buf,"Regions: %llu",&num_regions)==1) {
+ if (sscanf(buf,"Regions: %lu (%lu shown)",&num_regions,&num_regions_shown)==2) {
break;
}
}
+
+ if (num_regions != num_regions_shown) {
+ fprintf(stderr,"Cannot see all regions for %s\n",vmdev);
+ return 0;
+ }
struct v3_guest_mem_map *m =
(struct v3_guest_mem_map *) malloc(sizeof(struct v3_guest_mem_map)+num_regions*sizeof(struct v3_guest_mem_block));
// Now collect the region info
guest_cur=0;
+ i=0;
while (i<num_regions) {
if (!fgets(buf,MAXLINE,f)) {
fprintf(stderr,"Did not find all regions...\n");
free(m);
return 0;
}
- if (sscanf(buf," region %d has HPAs %llx-%llx",&num,&start,&end)==3) {
+ if (sscanf(buf," region %lu has HPAs %lx-%lx",&num,&start,&end)==3) {
m->block[i].gpa = (void*)guest_cur;
m->block[i].hpa = (void*)start;
m->block[i].numpages = (end-start) / 4096 + !!((end-start) % 4096);
if ((end-start)%4096) {
- fprintf(stderr,"Odd, region %d is a non-integral number of pages");
+ fprintf(stderr,"Odd, region %d is a non-integral number of pages",i);
}
guest_cur+=end-start;
m->block[i].cumgpa=(void*)(guest_cur-1);
(off_t) (map->block[i].hpa));
if (map->block[i].uva == MAP_FAILED) {
- fprintf(stderr, "Failed to map block %llu\n",i);
+ fprintf(stderr, "Failed to map block %lu\n",i);
map->block[i].uva=0;
v3_unmap_guest_mem(map);
return -1;
return v3_guest_mem_apply(do_hash,map,gpa,num_bytes,hash);
}
+
+
+int v3_guest_mem_track_start(char *vmdev,
+ v3_mem_track_access_t access,
+ v3_mem_track_reset_t reset,
+ uint64_t period)
+{
+ struct v3_mem_track_cmd cmd;
+
+ cmd.request=V3_MEM_TRACK_START;
+ cmd.config.access_type=access;
+ cmd.config.reset_type=reset;
+ cmd.config.period=period;
+
+ return v3_vm_ioctl(vmdev,V3_VM_MEM_TRACK_CMD,&cmd);
+
+}
+
+int v3_guest_mem_track_stop(char *vmdev)
+{
+ struct v3_mem_track_cmd cmd;
+
+ cmd.request=V3_MEM_TRACK_STOP;
+
+ return v3_vm_ioctl(vmdev,V3_VM_MEM_TRACK_CMD,&cmd);
+
+}
+
+
+#define CEIL_DIV(x,y) (((x)/(y)) + !!((x)%(y)))
+
+static uint8_t *alloc_bitmap(uint64_t num_pages)
+{
+ uint8_t *b;
+
+ if (!(b = malloc(CEIL_DIV(num_pages,8)))) {
+ return NULL;
+ }
+
+ memset(b,0,CEIL_DIV(num_pages,8));
+
+ return b;
+}
+
+
+static void free_bitmap(uint8_t *b)
+{
+ if (b) {
+ free(b);
+ }
+
+}
+
+
+void v3_guest_mem_track_free_snapshot(v3_mem_track_snapshot *s)
+{
+ int i;
+
+ if (s) {
+ for (i=0;i<s->num_cores;i++) {
+ free_bitmap(s->core[i].access_bitmap);
+ }
+ free(s);
+ }
+}
+
+
+static v3_mem_track_snapshot *alloc_snapshot(uint64_t num_cores, uint64_t num_pages)
+{
+ int i;
+ v3_mem_track_snapshot *s;
+
+ s = malloc(sizeof(v3_mem_track_snapshot) + sizeof(struct v3_core_mem_track) * num_cores);
+
+ if (!s) {
+ return NULL;
+ }
+
+ memset(s,0,sizeof(v3_mem_track_snapshot) + sizeof(struct v3_core_mem_track) * num_cores);
+
+ s->num_cores=num_cores;
+
+ for (i=0;i<num_cores;i++) {
+ if (!(s->core[i].access_bitmap = alloc_bitmap(num_pages))) {
+ v3_guest_mem_track_free_snapshot(s);
+ return NULL;
+ }
+ s->core[i].num_pages=num_pages;
+ }
+
+ return s;
+}
+
+
+v3_mem_track_snapshot *v3_guest_mem_track_snapshot(char *vmdev)
+{
+ struct v3_mem_track_sizes size;
+ v3_mem_track_snapshot *s;
+ int rc;
+
+ rc = v3_vm_ioctl(vmdev,V3_VM_MEM_TRACK_SIZE,&size);
+
+ if (rc) {
+ return 0;
+ }
+
+ //printf("returned size num_cores=%u, num_pages=%llu",size.num_cores,size.num_pages);
+
+ // allocate a snapshot;
+ if (!(s=alloc_snapshot(size.num_cores,size.num_pages))) {
+ return 0;
+ }
+
+
+
+ if (v3_vm_ioctl(vmdev,V3_VM_MEM_TRACK_SNAP,s)) {
+ v3_guest_mem_track_free_snapshot(s);
+ return 0;
+ }
+
+ return s;
+}
+
+
+