X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_usr%2Fv3_guest_mem.c;h=fa398e959b35f9cfc89b24bfcba29f5b201447fc;hb=82d082daad3fe8afad4be97d97093a3dfb768e1f;hp=ed1cd443d157890112f77515d952ef66f7e83c94;hpb=c5271d17ca93ad2ca9132a39212369c5f4feb2a9;p=palacios.git diff --git a/linux_usr/v3_guest_mem.c b/linux_usr/v3_guest_mem.c index ed1cd44..fa398e9 100644 --- a/linux_usr/v3_guest_mem.c +++ b/linux_usr/v3_guest_mem.c @@ -22,6 +22,7 @@ struct v3_guest_mem_map * v3_guest_mem_get_map(char *vmdev) uint64_t start, end, num; uint64_t guest_cur; uint64_t num_regions; + uint64_t num_regions_shown; if (!(f=fopen(GUEST_FILE,"r"))) { @@ -48,10 +49,15 @@ struct v3_guest_mem_map * v3_guest_mem_get_map(char *vmdev) 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: %llu (%llu 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)); @@ -67,6 +73,7 @@ struct v3_guest_mem_map * v3_guest_mem_get_map(char *vmdev) // Now collect the region info guest_cur=0; + i=0; while (iblock[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); @@ -243,3 +250,128 @@ int v3_guest_mem_hash(struct v3_guest_mem_map *map, void *gpa, uint64_t num_byte 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;inum_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;icore[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; +} + + +