Example #1
0
void *kvm_create_phys_mem(kvm_context_t kvm, unsigned long phys_start,
						  unsigned long len, int slot, int log, int writable)
{
    void *ptr;
//    int r;
    int fd = kvm->vm_fd;
//    int prot = PROT_READ;
	BOOL ret;
	int retlen;
	struct winkvm_memory_region  memory;
	struct winkvm_memmap         maparea;

	fprintf(stderr, "called %s\n", __FUNCTION__);

	maparea.init.slot     = kvm->current_mapping_slot;
	maparea.init.base_gfn = phys_start >> PAGE_SHIFT;
	maparea.init.npages   = len >> PAGE_SHIFT;

	if (!SetMemmapArea(kvm, &maparea)) {
		fprintf(stderr, "Could not initialize Memmap Area: %m\n");
		return NULL;
	} else {
		kvm->current_mapping_slot++;
	}

	/*
    struct kvm_memory_region memory = {
        .slot = slot,
        .memory_size = len,
        .guest_phys_addr = phys_start,
        .flags = log ? KVM_MEM_LOG_DIRTY_PAGES : 0,
    };
	*/

    /* r = ioctl(fd, KVM_SET_MEMORY_REGION, &memory); */
    /* if (r == -1)
        return 0;
		*/

	memory.vm_fd = fd;
	memory.kvm_memory_region.slot            = slot;
	memory.kvm_memory_region.memory_size     = len;
	memory.kvm_memory_region.guest_phys_addr = phys_start;
	memory.kvm_memory_region.flags           = log ? KVM_MEM_LOG_DIRTY_PAGES : 0;

	fprintf(stderr, 
		"%s\n"
		" VM_FD : %d\n"
		" MEMORY REGION (flag) : 0x%08x\n"
		" MEMORY REGION (memory_size) : %d [bytes]\n"
		" MEMORY REGION (slot) : %d\n"
		" MEMORY REGION (guest_phys_addr) : 0x%08lx\n",
		__FUNCTION__,
		memory.vm_fd,
		memory.kvm_memory_region.flags,
		memory.kvm_memory_region.memory_size,
		memory.kvm_memory_region.slot,
		memory.kvm_memory_region.guest_phys_addr);

	ret = DeviceIoControl(
		     kvm->hnd,
			 KVM_SET_MEMORY_REGION,
			 &memory,
			 sizeof(struct winkvm_memory_region),
			 &memory,
			 sizeof(struct winkvm_memory_region),
			 &retlen,
			 NULL);

	if (!ret) {
		return 0;
	}

    kvm_memory_region_save_params(kvm, &(memory.kvm_memory_region));
	winkvm_mapping_region_save_params(kvm, &maparea);

//    if (writable)
//        prot |= PROT_WRITE;

//    ptr = mmap(0, len, prot, MAP_SHARED, fd, phys_start);
	ptr = WkVirtualAlloc(kvm, &maparea);
    if (ptr == NULL)
        return 0;

	fprintf(stderr, "Reserve memory: 0x%p\n", ptr);

    return ptr;
}
Example #2
0
int kvm_create(kvm_context_t kvm, unsigned long phys_mem_bytes, void **vm_mem)
{
	unsigned long dosmem = 0xa0000;
	unsigned long exmem = 0xc0000;
	unsigned long pcimem = 0xf0000000;
	unsigned long memory = (phys_mem_bytes + PAGE_SIZE - 1) & PAGE_MASK;
	int fd = kvm->fd;
	int zfd;
	int r;
	struct kvm_userspace_memory_region low_memory = {
		.slot = 3,
		.memory_size = memory  < dosmem ? memory : dosmem,
		.guest_phys_addr = 0,
	};
	struct kvm_userspace_memory_region extended_memory = {
		.slot = 0,
		.memory_size = memory < exmem ? 0 : memory - exmem,
		.guest_phys_addr = exmem,
	};
	struct kvm_userspace_memory_region above_4g_memory = {
		.slot = 4,
		.memory_size = memory < pcimem ? 0 : memory - pcimem,
		.guest_phys_addr = 0x100000000,
	};

	if (memory >= pcimem)
		extended_memory.memory_size = pcimem - exmem;

	kvm->vcpu_fd[0] = -1;

	fd = ioctl(fd, KVM_CREATE_VM, 0);
	if (fd == -1) {
		fprintf(stderr, "kvm_create_vm: %m\n");
		return -1;
	}
	kvm->vm_fd = fd;

	kvm->physical_memory = mmap(NULL, extended_memory.memory_size + exmem, 7, MAP_ANON|MAP_SHARED, -1, 0);

	/* 640K should be enough. */
  low_memory.userspace_addr = kvm->physical_memory;
	r = ioctl(fd, KVM_SET_USER_MEMORY_REGION, &low_memory);
	if (r == -1) {
		fprintf(stderr, "kvm_create_memory_region: %m\n");
		return -1;
	}
	if (extended_memory.memory_size) {
    extended_memory.userspace_addr = kvm->physical_memory + exmem;
		r = ioctl(fd, KVM_SET_USER_MEMORY_REGION, &extended_memory);
		if (r == -1) {
			fprintf(stderr, "kvm_create_memory_region: %m\n");
			return -1;
		}
	}

  *vm_mem = kvm->physical_memory;

	/*if (above_4g_memory.memory_size) {
    above_4g_memory.userspace_addr = mmap(NULL, above_4g_memory.memory_size, 7, MAP_ANON|MAP_SHARED, -1, 0); 
		r = ioctl(fd, KVM_SET_USER_MEMORY_REGION, &above_4g_memory);
		if (r == -1) {
			fprintf(stderr, "kvm_create_memory_region: %m\n");
			return -1;
		}
	}*/

	/*kvm_memory_region_save_params(kvm, &low_memory);
	kvm_memory_region_save_params(kvm, &extended_memory);
	kvm_memory_region_save_params(kvm, &above_4g_memory);*/

	/**vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (*vm_mem == MAP_FAILED) {
		fprintf(stderr, "mmap: %m\n");
		return -1;
	}
	kvm->physical_memory = *vm_mem;*/

	/*zfd = open("/dev/zero", O_RDONLY);
	mmap(*vm_mem + 0xa8000, 0x8000, PROT_READ|PROT_WRITE,
	     MAP_PRIVATE|MAP_FIXED, zfd, 0);
	close(zfd);*/

	//kvm->physical_memory = low_memory.userspace_addr;

	kvm->irqchip_in_kernel = 0;
	if (!kvm->no_irqchip_creation) {
		r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_IRQCHIP);
		if (r > 0) {	/* kernel irqchip supported */
			r = ioctl(fd, KVM_CREATE_IRQCHIP, NULL);
			if (r >= 0)
				kvm->irqchip_in_kernel = 1;
			else
				printf("Create kernel PIC irqchip failed\n");
		}
	}
	r = kvm_create_vcpu(kvm, 0);
	if (r < 0)
		return r;

	return 0;
}

void *kvm_create_phys_mem(kvm_context_t kvm, unsigned long phys_start, 
			  unsigned long len, int slot, int log, int writable)
{
	void *ptr;
	int r;
	int fd = kvm->vm_fd;
	int prot = PROT_READ;
	struct kvm_memory_region memory = {
		.slot = slot,
		.memory_size = len,
		.guest_phys_addr = phys_start,
		.flags = log ? KVM_MEM_LOG_DIRTY_PAGES : 0,
	};

	r = ioctl(fd, KVM_SET_MEMORY_REGION, &memory);
	if (r == -1)
	    return 0;

	kvm_memory_region_save_params(kvm, &memory);

	if (writable)
		prot |= PROT_WRITE;

	ptr = mmap(NULL, len, prot, MAP_SHARED, fd, phys_start);
	if (ptr == MAP_FAILED)
		return 0;
	return ptr;
}

/* destroy/free a whole slot.
 * phys_start, len and slot are the params passed to kvm_create_phys_mem()
 */
void kvm_destroy_phys_mem(kvm_context_t kvm, unsigned long phys_start, 
			  unsigned long len, int slot)
{
	struct kvm_memory_region *mem;

	if (slot >= KVM_MAX_NUM_MEM_REGIONS) {
		fprintf(stderr, "BUG: %s: invalid parameters (slot=%d)\n",
			__FUNCTION__, slot);
		return;
	}
	mem = &kvm->mem_regions[slot];
	if (phys_start != mem->guest_phys_addr) {
		fprintf(stderr,
			"WARNING: %s: phys_start is 0x%lx expecting 0x%llx\n",
			__FUNCTION__, phys_start, mem->guest_phys_addr);
		phys_start = mem->guest_phys_addr;
	}
	kvm_create_phys_mem(kvm, phys_start, 0, slot, 0, 0);
}

int kvm_create_memory_alias(kvm_context_t kvm,
			    int slot,
			    uint64_t phys_start,
			    uint64_t len,
			    uint64_t target_phys)
{
	struct kvm_memory_alias alias = {
		.slot = slot,
		.flags = 0,
		.guest_phys_addr = phys_start,
		.memory_size = len,
		.target_phys_addr = target_phys,
	};
	int fd = kvm->vm_fd;
	int r;

	r = ioctl(fd, KVM_SET_MEMORY_ALIAS, &alias);
	if (r == -1)
	    return -errno;

	return 0;
}

int kvm_destroy_memory_alias(kvm_context_t kvm, int slot)
{
	return kvm_create_memory_alias(kvm, slot, 0, 0, 0);
}

static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
{
	int r;
	struct kvm_dirty_log log = {
		.slot = slot,
	};

	log.dirty_bitmap = buf;

	r = ioctl(kvm->vm_fd, ioctl_num, &log);
	if (r == -1)
		return -errno;
	return 0;
}

int kvm_get_dirty_pages(kvm_context_t kvm, int slot, void *buf)
{
	return kvm_get_map(kvm, KVM_GET_DIRTY_LOG, slot, buf);
}

int kvm_get_mem_map(kvm_context_t kvm, int slot, void *buf)
{
#ifdef KVM_GET_MEM_MAP
	return kvm_get_map(kvm, KVM_GET_MEM_MAP, slot, buf);
#else /* not KVM_GET_MEM_MAP ==> fake it: all pages exist */
	unsigned long i, n, m, npages;
	unsigned char v;

	if (slot >= KVM_MAX_NUM_MEM_REGIONS) {
		errno = -EINVAL;
		return -1;
	}
	npages = kvm->mem_regions[slot].memory_size / PAGE_SIZE;
	n = npages / 8;
	m = npages % 8;
	memset(buf, 0xff, n); /* all pages exist */
	v = 0;
	for (i=0; i<=m; i++) /* last byte may not be "aligned" */
		v |= 1<<(7-i);
	if (v)
		*(unsigned char*)(buf+n) = v;
	return 0;
#endif /* KVM_GET_MEM_MAP */
}

int kvm_set_irq_level(kvm_context_t kvm, int irq, int level)
{
	struct kvm_irq_level event;
	int r;

	if (!kvm->irqchip_in_kernel)
		return 0;
	event.level = level;
	event.irq = irq;
	r = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &event);
	if (r == -1)
		perror("kvm_set_irq_level");
	return 1;
}

int kvm_get_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip)
{
	int r;

	if (!kvm->irqchip_in_kernel)
		return 0;
	r = ioctl(kvm->vm_fd, KVM_GET_IRQCHIP, chip);
	if (r == -1) {
		r = -errno;
		perror("kvm_get_irqchip\n");
	}
	return r;
}

int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip)
{
	int r;

	if (!kvm->irqchip_in_kernel)
		return 0;
	r = ioctl(kvm->vm_fd, KVM_SET_IRQCHIP, chip);
	if (r == -1) {
		r = -errno;
		perror("kvm_set_irqchip\n");
	}
	return r;
}

int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
{
	int r;
	if (!kvm->irqchip_in_kernel)
		return 0;
	r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_LAPIC, s);
	if (r == -1) {
		r = -errno;
		perror("kvm_get_lapic");
	}
	return r;
}
Example #3
0
int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
{
    unsigned long dosmem = 0xa0000;
    unsigned long exmem = 0xc0000;
    HANDLE  hnd = kvm->hnd;
	int     fd, retlen, vcpufd;
//    int zfd;	
//    int r;
	struct winkvm_memory_region  low_memory;
	struct winkvm_memory_region  extended_memory;
	struct winkvm_memmap         maparea;
	struct winkvm_create_vcpu    create_vcpu;
	BOOL   ret;
	
	kvm_context = kvm;

	memset(&low_memory, 0, sizeof(struct winkvm_memory_region));
	memset(&extended_memory, 0, sizeof(struct winkvm_memory_region));

	/* for winkvm */	
	memset(&maparea, 0, sizeof(struct winkvm_memmap));

	fprintf(stderr, "memory size: %d [mbytes]\n", memory / 1024 / 1024);

	kvm->current_mapping_slot = 0;
	maparea.init.slot      = kvm->current_mapping_slot;
	maparea.init.base_gfn  = 0 >> PAGE_SHIFT;
	maparea.init.npages    = memory >> PAGE_SHIFT;

	if (!SetMemmapArea(kvm, &maparea)) {
		fprintf(stderr, "Could not initialize Memmap Area: %m\n");
		return -1;
	} else {
		kvm->current_mapping_slot++;
	}

	/* end */

	low_memory.kvm_memory_region.slot = 3;
	low_memory.kvm_memory_region.memory_size = memory  < dosmem ? memory : dosmem;
	low_memory.kvm_memory_region.guest_phys_addr = 0;

	extended_memory.kvm_memory_region.slot = 0;
	extended_memory.kvm_memory_region.memory_size = memory < exmem ? 0 : memory - exmem;
	extended_memory.kvm_memory_region.guest_phys_addr = exmem;
	
    kvm->vcpu_fd[0] = -1;

	fprintf(stderr, "Create VM ... \n");
	ret = DeviceIoControl(
		      hnd,			  
			  KVM_CREATE_VM,
			  NULL,
			  0,
			  &fd,
			  sizeof(fd),
			  &retlen,					  
			  NULL); 
	
	//    fd = ioctl(fd, KVM_CREATE_VM, 0);	
    if (!ret && fd == -1) {
        fprintf(stderr, "winkvm_create_vm: %m\n");		
        return -1;		
    }
    kvm->vm_fd = fd;	
	fprintf(stderr, " Done\n");

	fprintf(stderr, "Set Memory Region ... \n");
	low_memory.vm_fd      = fd;
	extended_memory.vm_fd = fd;

	fprintf(stderr, 
		" VM_FD : %d\n"
		" MEMORY REGION (flag) : 0x%08x\n"
		" MEMORY REGION (memory_size) : %d [bytes]\n"
		" MEMORY REGION (slot) : %d\n"
		" MEMORY REGION (guest_phys_addr) : 0x%08lx\n",
		low_memory.vm_fd,
		low_memory.kvm_memory_region.flags,
		low_memory.kvm_memory_region.memory_size,
		low_memory.kvm_memory_region.slot,
		low_memory.kvm_memory_region.guest_phys_addr);

    /* 640K should be enough. */
	//    r = ioctl(fd, KVM_SET_MEMORY_REGION, &low_memory);
	ret = DeviceIoControl(
		       hnd,						  
			   KVM_SET_MEMORY_REGION,						  
			   &low_memory,
			   sizeof(struct winkvm_memory_region),
			   &low_memory,
			   sizeof(struct winkvm_memory_region),
			   &retlen,						  
			   NULL);

    if (!ret) {
        fprintf(stderr, "kvm_create_memory_region: %m\n");
        return -1;		
    }

	printf(" Done\n");

    if (extended_memory.kvm_memory_region.memory_size) {
//        r = ioctl(fd, KVM_SET_MEMORY_REGION, &extended_memory);

		fprintf(stderr, 
			" VM_FD : %d\n"
			" MEMORY REGION (flag) : 0x%08x\n"
			" MEMORY REGION (memory_size) : %d [bytes]\n"
			" MEMORY REGION (slot) : %d\n"
			" MEMORY REGION (guest_phys_addr) : 0x%08lx\n",
			extended_memory.vm_fd,
			extended_memory.kvm_memory_region.flags,
			extended_memory.kvm_memory_region.memory_size,
			extended_memory.kvm_memory_region.slot,
			extended_memory.kvm_memory_region.guest_phys_addr);

		ret = DeviceIoControl(
			     hnd,
				 KVM_SET_MEMORY_REGION,
				 &extended_memory,
				 sizeof(struct winkvm_memory_region),
				 &extended_memory,
				 sizeof(struct winkvm_memory_region),
				 &retlen,
				 NULL);

        if (!ret) {
            fprintf(stderr, "kvm_create_memory_region: %m\n");
            return -1; 
        }
		fprintf(stderr, " Done\n");
    }

	kvm_memory_region_save_params(kvm, &low_memory.kvm_memory_region);
	kvm_memory_region_save_params(kvm, &extended_memory.kvm_memory_region);

/*	*vm_mem = VirtualAlloc(NULL, memory, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); */
	*vm_mem = WkVirtualAlloc(kvm, &maparea);
	if (*vm_mem == NULL) {
		fprintf(stderr, "VirtualAlloc error\n");
		return -1;
	}
	kvm->physical_memory = *vm_mem;

	winkvm_mapping_region_save_params(kvm, &maparea);

	create_vcpu.vm_fd    = fd;
	create_vcpu.vcpu_fd  = 0;

	vcpufd = -1;
	fprintf(stderr, "Create VCPU ... \n");
	ret = DeviceIoControl(
		      hnd,
			  KVM_CREATE_VCPU,
			  &create_vcpu,
			  sizeof(create_vcpu),
			  &vcpufd,
			  sizeof(vcpufd),
			  &retlen,
			  NULL);

     if (vcpufd == -1) {	   
         fprintf(stderr, " kvm_create_vcpu: %m\n");
         return -1;
     }
	 fprintf(stderr, " vcpu fd : %d\n", vcpufd);
	 fprintf(stderr, " Done\n");
	 kvm->vcpu_fd[0] = vcpufd;

	 return 0;
}