aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h1
-rw-r--r--drivers/kvm/kvm_main.c81
-rw-r--r--include/linux/kvm.h12
3 files changed, 83 insertions, 11 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index ec5b498945ae..3eaed4dafec7 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -408,6 +408,7 @@ struct kvm_memory_slot {
408 struct page **phys_mem; 408 struct page **phys_mem;
409 unsigned long *rmap; 409 unsigned long *rmap;
410 unsigned long *dirty_bitmap; 410 unsigned long *dirty_bitmap;
411 int user_alloc; /* user allocated memory */
411}; 412};
412 413
413struct kvm { 414struct kvm {
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a1983d2d5b8f..22b143feb66d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -40,6 +40,7 @@
40#include <linux/anon_inodes.h> 40#include <linux/anon_inodes.h>
41#include <linux/profile.h> 41#include <linux/profile.h>
42#include <linux/kvm_para.h> 42#include <linux/kvm_para.h>
43#include <linux/pagemap.h>
43 44
44#include <asm/processor.h> 45#include <asm/processor.h>
45#include <asm/msr.h> 46#include <asm/msr.h>
@@ -300,19 +301,40 @@ static struct kvm *kvm_create_vm(void)
300 return kvm; 301 return kvm;
301} 302}
302 303
304static void kvm_free_userspace_physmem(struct kvm_memory_slot *free)
305{
306 int i;
307
308 for (i = 0; i < free->npages; ++i) {
309 if (free->phys_mem[i]) {
310 if (!PageReserved(free->phys_mem[i]))
311 SetPageDirty(free->phys_mem[i]);
312 page_cache_release(free->phys_mem[i]);
313 }
314 }
315}
316
317static void kvm_free_kernel_physmem(struct kvm_memory_slot *free)
318{
319 int i;
320
321 for (i = 0; i < free->npages; ++i)
322 if (free->phys_mem[i])
323 __free_page(free->phys_mem[i]);
324}
325
303/* 326/*
304 * Free any memory in @free but not in @dont. 327 * Free any memory in @free but not in @dont.
305 */ 328 */
306static void kvm_free_physmem_slot(struct kvm_memory_slot *free, 329static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
307 struct kvm_memory_slot *dont) 330 struct kvm_memory_slot *dont)
308{ 331{
309 int i;
310
311 if (!dont || free->phys_mem != dont->phys_mem) 332 if (!dont || free->phys_mem != dont->phys_mem)
312 if (free->phys_mem) { 333 if (free->phys_mem) {
313 for (i = 0; i < free->npages; ++i) 334 if (free->user_alloc)
314 if (free->phys_mem[i]) 335 kvm_free_userspace_physmem(free);
315 __free_page(free->phys_mem[i]); 336 else
337 kvm_free_kernel_physmem(free);
316 vfree(free->phys_mem); 338 vfree(free->phys_mem);
317 } 339 }
318 if (!dont || free->rmap != dont->rmap) 340 if (!dont || free->rmap != dont->rmap)
@@ -652,7 +674,9 @@ EXPORT_SYMBOL_GPL(fx_init);
652 * Discontiguous memory is allowed, mostly for framebuffers. 674 * Discontiguous memory is allowed, mostly for framebuffers.
653 */ 675 */
654static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, 676static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
655 struct kvm_memory_region *mem) 677 struct
678 kvm_userspace_memory_region *mem,
679 int user_alloc)
656{ 680{
657 int r; 681 int r;
658 gfn_t base_gfn; 682 gfn_t base_gfn;
@@ -728,11 +752,27 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
728 752
729 memset(new.phys_mem, 0, npages * sizeof(struct page *)); 753 memset(new.phys_mem, 0, npages * sizeof(struct page *));
730 memset(new.rmap, 0, npages * sizeof(*new.rmap)); 754 memset(new.rmap, 0, npages * sizeof(*new.rmap));
731 for (i = 0; i < npages; ++i) { 755 if (user_alloc) {
732 new.phys_mem[i] = alloc_page(GFP_HIGHUSER 756 unsigned long pages_num;
733 | __GFP_ZERO); 757
734 if (!new.phys_mem[i]) 758 new.user_alloc = 1;
759 down_read(&current->mm->mmap_sem);
760
761 pages_num = get_user_pages(current, current->mm,
762 mem->userspace_addr,
763 npages, 1, 1, new.phys_mem,
764 NULL);
765
766 up_read(&current->mm->mmap_sem);
767 if (pages_num != npages)
735 goto out_unlock; 768 goto out_unlock;
769 } else {
770 for (i = 0; i < npages; ++i) {
771 new.phys_mem[i] = alloc_page(GFP_HIGHUSER
772 | __GFP_ZERO);
773 if (!new.phys_mem[i])
774 goto out_unlock;
775 }
736 } 776 }
737 } 777 }
738 778
@@ -3108,11 +3148,29 @@ static long kvm_vm_ioctl(struct file *filp,
3108 break; 3148 break;
3109 case KVM_SET_MEMORY_REGION: { 3149 case KVM_SET_MEMORY_REGION: {
3110 struct kvm_memory_region kvm_mem; 3150 struct kvm_memory_region kvm_mem;
3151 struct kvm_userspace_memory_region kvm_userspace_mem;
3111 3152
3112 r = -EFAULT; 3153 r = -EFAULT;
3113 if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) 3154 if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem))
3114 goto out; 3155 goto out;
3115 r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_mem); 3156 kvm_userspace_mem.slot = kvm_mem.slot;
3157 kvm_userspace_mem.flags = kvm_mem.flags;
3158 kvm_userspace_mem.guest_phys_addr = kvm_mem.guest_phys_addr;
3159 kvm_userspace_mem.memory_size = kvm_mem.memory_size;
3160 r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 0);
3161 if (r)
3162 goto out;
3163 break;
3164 }
3165 case KVM_SET_USER_MEMORY_REGION: {
3166 struct kvm_userspace_memory_region kvm_userspace_mem;
3167
3168 r = -EFAULT;
3169 if (copy_from_user(&kvm_userspace_mem, argp,
3170 sizeof kvm_userspace_mem))
3171 goto out;
3172
3173 r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 1);
3116 if (r) 3174 if (r)
3117 goto out; 3175 goto out;
3118 break; 3176 break;
@@ -3332,6 +3390,7 @@ static long kvm_dev_ioctl(struct file *filp,
3332 case KVM_CAP_IRQCHIP: 3390 case KVM_CAP_IRQCHIP:
3333 case KVM_CAP_HLT: 3391 case KVM_CAP_HLT:
3334 case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: 3392 case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
3393 case KVM_CAP_USER_MEMORY:
3335 r = 1; 3394 r = 1;
3336 break; 3395 break;
3337 default: 3396 default:
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index d2fd973d81fe..971f465e26fa 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -23,6 +23,15 @@ struct kvm_memory_region {
23 __u64 memory_size; /* bytes */ 23 __u64 memory_size; /* bytes */
24}; 24};
25 25
26/* for KVM_SET_USER_MEMORY_REGION */
27struct kvm_userspace_memory_region {
28 __u32 slot;
29 __u32 flags;
30 __u64 guest_phys_addr;
31 __u64 memory_size; /* bytes */
32 __u64 userspace_addr; /* start of the userspace allocated memory */
33};
34
26/* for kvm_memory_region::flags */ 35/* for kvm_memory_region::flags */
27#define KVM_MEM_LOG_DIRTY_PAGES 1UL 36#define KVM_MEM_LOG_DIRTY_PAGES 1UL
28 37
@@ -348,6 +357,7 @@ struct kvm_signal_mask {
348#define KVM_CAP_IRQCHIP 0 357#define KVM_CAP_IRQCHIP 0
349#define KVM_CAP_HLT 1 358#define KVM_CAP_HLT 1
350#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2 359#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2
360#define KVM_CAP_USER_MEMORY 3
351 361
352/* 362/*
353 * ioctls for VM fds 363 * ioctls for VM fds
@@ -355,6 +365,8 @@ struct kvm_signal_mask {
355#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region) 365#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region)
356#define KVM_SET_NR_MMU_PAGES _IO(KVMIO, 0x44) 366#define KVM_SET_NR_MMU_PAGES _IO(KVMIO, 0x44)
357#define KVM_GET_NR_MMU_PAGES _IO(KVMIO, 0x45) 367#define KVM_GET_NR_MMU_PAGES _IO(KVMIO, 0x45)
368#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\
369 struct kvm_userspace_memory_region)
358/* 370/*
359 * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns 371 * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
360 * a vcpu fd. 372 * a vcpu fd.