X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_usr%2Fv3_guest_mem.c;h=fa398e959b35f9cfc89b24bfcba29f5b201447fc;hb=f240f8a3c11478abe180bd906c746c68eb8c3a3c;hp=d23acc15a228d1ffb0e1f51fefb8df71cd017f38;hpb=37c08f88840030dae5893a8ad148262f3e08e9be;p=palacios.git diff --git a/linux_usr/v3_guest_mem.c b/linux_usr/v3_guest_mem.c index d23acc1..fa398e9 100644 --- a/linux_usr/v3_guest_mem.c +++ b/linux_usr/v3_guest_mem.c @@ -7,66 +7,95 @@ #include "v3_guest_mem.h" -#warning FIX THE PARSER TO CONFORM TO NEW /proc/v3 VM output format - -#define GUEST_FILE "/proc/v3vee/v3-guests" -//#define GUEST_FILE "/441/pdinda/test.proc" +#define GUEST_FILE "/proc/v3vee/v3-guests-details" +//#define GUEST_FILE "/v-test/numa/palacios-devel/test.proc" #define MAXLINE 65536 struct v3_guest_mem_map * v3_guest_mem_get_map(char *vmdev) { FILE *f; + int rc; + int i; char buf[MAXLINE]; - char name[MAXLINE]; char dev[MAXLINE]; - char state[MAXLINE]; - uint64_t start, end; + 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,"Cannot open %s - is Palacios active?\n",GUEST_FILE); - return 0; - } - - // This is using the current "single memory region" model - // and will change when /proc convention changes to conform to - // multiple region model - while (fgets(buf,MAXLINE,f)) { - if (sscanf(buf, - "%s %s %s [0x%llx-0x%llx]", - name, - dev, - state, - &start, - &end)!=5) { - fprintf(stderr, "Cannot parse following line\n%s\n",buf); - fclose(f); + fprintf(stderr,"Cannot open %s - is Palacios active?\n",GUEST_FILE); return 0; - } - if (!strcmp(dev,vmdev)) { - struct v3_guest_mem_map *m = - (struct v3_guest_mem_map *) malloc(sizeof(struct v3_guest_mem_map)+1*sizeof(struct v3_guest_mem_block)); - if (!m) { - fprintf(stderr, "Cannot allocate space\n"); - fclose(f); - return 0; + } + + while (1) { + if (!fgets(buf,MAXLINE,f)) { + fprintf(stderr,"Could not find info for %s\n",vmdev); + return 0; } + if (sscanf(buf,"Device: %s",dev)==1) { + if (!strcmp(dev,vmdev)) { + // found our VM + break; + } + } + } + + // Now we need the number of regions + while (1) { + if (!fgets(buf,MAXLINE,f)) { + fprintf(stderr,"Could not find number of regions for %s\n",vmdev); + return 0; + } + if (sscanf(buf,"Regions: %llu (%llu shown)",&num_regions,&num_regions_shown)==2) { + break; + } + } - memset(m,0,sizeof(struct v3_guest_mem_map)+1*sizeof(struct v3_guest_mem_block)); - - m->numblocks=1; - m->block[0].gpa=0; - m->block[0].hpa=(void*)start; - m->block[0].numpages = (end-start+1) / 4096; + 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)); + if (!m) { + fprintf(stderr, "Cannot allocate space\n"); fclose(f); - return m; - } + return 0; } - fprintf(stderr,"%s not found\n",vmdev); + memset(m,0,sizeof(struct v3_guest_mem_map)+num_regions*sizeof(struct v3_guest_mem_block)); + + m->numblocks=num_regions; + + // Now collect the region info + guest_cur=0; + i=0; + while (iblock[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",i); + } + guest_cur+=end-start; + m->block[i].cumgpa=(void*)(guest_cur-1); + i++; + } + } + fclose(f); - return 0; + + return m; } @@ -88,8 +117,8 @@ int v3_map_guest_mem(struct v3_guest_mem_map *map) } for (i=0; inumblocks; i++) { - fprintf(stderr,"Mapping %llu bytes of /dev/mem offset 0x%llx\n", - map->block[i].numpages*4096, (off_t)(map->block[i].hpa)); + //fprintf(stderr,"Mapping %llu bytes of /dev/mem offset 0x%llx\n", + // map->block[i].numpages*4096, (off_t)(map->block[i].hpa)); map->block[i].uva = mmap(NULL, map->block[i].numpages*4096, PROT_READ | PROT_WRITE, @@ -125,3 +154,224 @@ int v3_unmap_guest_mem(struct v3_guest_mem_map *map) } return 0; } + + +void *v3_gpa_start(struct v3_guest_mem_map *map) +{ + return 0; // all guests start at zero for now +} + +void *v3_gpa_end(struct v3_guest_mem_map *map) +{ + struct v3_guest_mem_block *l = &(map->block[map->numblocks-1]); + + // currently, the regions are consecutive, so we just need the last block + return l->gpa+l->numpages*4096-1; +} + + +int v3_guest_mem_apply(void (*func)(void *data, uint64_t num_bytes, void *priv), + struct v3_guest_mem_map *map, void *gpa, uint64_t num_bytes, void *priv) +{ + void *cur_gpa; + void *cur_uva; + uint64_t left_bytes; + uint64_t block_bytes; + + if (!(map->fd)) { + return -1; + } + + if (gpa < v3_gpa_start(map) || gpa+num_bytes-1 > v3_gpa_end(map)) { + return -1; + } + + cur_gpa = gpa; + left_bytes = num_bytes; + + while (left_bytes) { + cur_uva = v3_gpa_to_uva(map, cur_gpa, &block_bytes); + if (!cur_uva) { + return -1; + } + if (block_bytes>left_bytes) { + block_bytes = left_bytes; + } + func(cur_uva,block_bytes,priv); + left_bytes-=block_bytes; + cur_gpa+=block_bytes; + } + + return 0; +} + + + +static void copy_out(void *uva, uint64_t num_bytes, void *curoff) +{ + memcpy(*((void**)(curoff)), uva, num_bytes); + *(void**)curoff += num_bytes; +} + +static void copy_in(void *uva, uint64_t num_bytes, void *curoff) +{ + memcpy(uva, *((void**)(curoff)), num_bytes); + *(void**)curoff += num_bytes; +} + +static void do_hash(void *uva, uint64_t num_bytes, void *priv) +{ + uint64_t i; + uint64_t *curhash = (uint64_t *)priv; + + 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; +} + + +