kvm module之create vm

3765         kvm_chardev_ops.owner = module;
3766         kvm_vm_fops.owner = module;
3767         kvm_vcpu_fops.owner = module;
3768 
3769         r = misc_register(&kvm_dev);
kvm_init 中注册的这个字符设备的file_file_operations 
3116 static struct file_operations kvm_chardev_ops = {
3117         .unlocked_ioctl = kvm_dev_ioctl,
3118         .compat_ioctl   = kvm_dev_ioctl,
3119         .llseek         = noop_llseek,
3120 };
QEMU 会调用这个ioctl来创建新的虚拟机,如3087行所示
3076 static long kvm_dev_ioctl(struct file *filp,
3077                           unsigned int ioctl, unsigned long arg)
3078 {
3079         long r = -EINVAL;
3080 
3081         switch (ioctl) {
3082         case KVM_GET_API_VERSION:
3083                 if (arg)
3084                         goto out;
3085                 r = KVM_API_VERSION;
3086                 break;
3087         case KVM_CREATE_VM:
3088                 r = kvm_dev_ioctl_create_vm(arg);
3089                 break;
3090         case KVM_CHECK_EXTENSION:
3091                 r = kvm_vm_ioctl_check_extension_generic(NULL, arg);
3092                 break;
3093         case KVM_GET_VCPU_MMAP_SIZE:
3094                 if (arg)
3095                         goto out;
3096                 r = PAGE_SIZE;     /* struct kvm_run */
3097 #ifdef CONFIG_X86
3098                 r += PAGE_SIZE;    /* pio data page */
3099 #endif
3100 #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
3101                 r += PAGE_SIZE;    /* coalesced mmio ring page */
3102 #endif
3103                 break;
3104         case KVM_TRACE_ENABLE:
3105         case KVM_TRACE_PAUSE:
3106         case KVM_TRACE_DISABLE:
3107                 r = -EOPNOTSUPP;
3108                 break;
3109         default:
3110                 return kvm_arch_dev_ioctl(filp, ioctl, arg);
3111         }
3112 out:
3113         return r;
3114 }
这个函数调用kvm_dev_ioctl_create_vm 创建虚拟机


3047 static int kvm_dev_ioctl_create_vm(unsigned long type)
3048 {
3049         int r;
3050         struct kvm *kvm;
3051 
3052         kvm = kvm_create_vm(type);
3053         if (IS_ERR(kvm))
3054                 return PTR_ERR(kvm);
3055 #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
3056         r = kvm_coalesced_mmio_init(kvm);
3057         if (r < 0) {
3058                 kvm_put_kvm(kvm);
3059                 return r;
3060         }
3061 #endif
3062         r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR | O_CLOEXEC); QEMU 会调用kvm_vm_fops来创建虚拟cpu
3063         if (r < 0) {
3064                 kvm_put_kvm(kvm);
3065                 return r;
3066         }
3067 
3068         if (kvm_create_vm_debugfs(kvm, r) < 0) {
3069                 kvm_put_kvm(kvm);
3070                 return -ENOMEM;
3071         }
3072 
3073         return r;
3074 }
继续调用kvm_create_vm 来创建虚拟机.code 比较简单就不解释了.
603 static struct kvm *kvm_create_vm(unsigned long type)
604 {
605         int r, i;
606         struct kvm *kvm = kvm_arch_alloc_vm();//申请memory
607 
608         if (!kvm)
609                 return ERR_PTR(-ENOMEM);
610 
611         spin_lock_init(&kvm->mmu_lock);
612         atomic_inc(&current->mm->mm_count);
613         kvm->mm = current->mm;
614         kvm_eventfd_init(kvm);
615         mutex_init(&kvm->lock);
616         mutex_init(&kvm->irq_lock);
617         mutex_init(&kvm->slots_lock);
618         atomic_set(&kvm->users_count, 1);
619         INIT_LIST_HEAD(&kvm->devices);
620 
621         r = kvm_arch_init_vm(kvm, type);
622         if (r)
623                 goto out_err_no_disable;
624 
625         r = hardware_enable_all();
626         if (r)
627                 goto out_err_no_disable;
628 
629 #ifdef CONFIG_HAVE_KVM_IRQFD
630         INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
631 #endif
632 
633         BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
634 
635         r = -ENOMEM;
636         for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
637                 kvm->memslots[i] = kvm_alloc_memslots();
638                 if (!kvm->memslots[i])
639                         goto out_err_no_srcu;
640         }
641 
642         if (init_srcu_struct(&kvm->srcu))
643                 goto out_err_no_srcu;
644         if (init_srcu_struct(&kvm->irq_srcu))
645                 goto out_err_no_irq_srcu;
646         for (i = 0; i < KVM_NR_BUSES; i++) {
647                 kvm->buses[i] = kzalloc(sizeof(struct kvm_io_bus),
648                                         GFP_KERNEL);
649                 if (!kvm->buses[i])
650                         goto out_err;
651         }
652 
653         r = kvm_init_mmu_notifier(kvm);
654         if (r)
655                 goto out_err;
656 
657         spin_lock(&kvm_lock);
658         list_add(&kvm->vm_list, &vm_list);
659         spin_unlock(&kvm_lock);
660 
661         preempt_notifier_inc();
662 
663         return kvm;
664 
665 out_err:
666         cleanup_srcu_struct(&kvm->irq_srcu);
667 out_err_no_irq_srcu:
668         cleanup_srcu_struct(&kvm->srcu);
669 out_err_no_srcu:
670         hardware_disable_all();
671 out_err_no_disable:
672         for (i = 0; i < KVM_NR_BUSES; i++)
673                 kfree(kvm->buses[i]);
674         for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
675                 kvm_free_memslots(kvm, kvm->memslots[i]);
676         kvm_arch_free_vm(kvm);
677         mmdrop(current->mm);
678         return ERR_PTR(r);
679 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值