设为首页 收藏本站
查看: 1241|回复: 0

[经验分享] kernel 3.10代码分析--KVM相关--虚拟机创建

[复制链接]

尚未签到

发表于 2015-12-24 14:50:09 | 显示全部楼层 |阅读模式
1、基本原理
如之前分析,kvm虚拟机通过对/dev/kvm字符设备的ioctl的
System指令KVM_CREATE_VM进行创建。
对虚拟机(VM)来说,kvm结构体是关键,一个虚拟机对应一个kvm结构体,虚拟机的创建过程实质为kvm结构体的创建和初始化过程。
本文简单解释及分析在3.10版本内核代码中的相关流程,用户态qemu-kvm部分暂不包括。

2、大致流程如下:
用户态ioctl(fd,KVM_CREATE_VM,..)
    内核态kvm_dev_ioctl()
        kvm_dev_ioctl_create_vm()
            kvm_create_vm() //实现虚拟机创建的主要函数
                kvm_arch_alloc_vm() // 分配kvm结构体
                kvm_arch_init_vm() // 初始化kvm结构中的架构相关部分,比如中断
                hardware_enable_all() // 使能硬件,架构相关操作
                    hardware_enable_nolock
                        kvm_arch_hardware_enable()
                            kvm_x86_ops->hardware_enable()
                kzalloc() // 分配memslots结构,并初始化为0
                kvm_init_memslots_id() // 初始化内存槽位(slot)的id信息
                kvm_eventfd_init() // 初始化事件通道
                kvm_init_mmu_notifier() // 初始化mmu操作的通知链
                list_add(&kvm->vm_list, &vm_list) // 将新创建的虚拟机的kvm结构,加入到全局链表vm_list中

3、代码分析
kvm结构体:



  • /*

  •   * kvm中全局的数据结构,其中包含kvm相关的重要数据信息,包括memslot等
  •   */
  • struct kvm {
  •     // 用于保护mmu的spin_lock
  •     spinlock_t mmu_lock;
  •     struct mutex slots_lock;
  •     // 指向qemu用户态进程的mm_struct?
  •     struct mm_struct *mm; /* userspace tied to this vm */
  •     /*
  •      * kvm_mem_slot是kvm内存管理相关主要数据结构,用来表示虚拟机GPA和主机HVA之间的
  •      * 映射关系,一个kvm_mem_slot表示一段内存区域(slot)的映射关系,kvm_memslots结构体是
  •      * kvm_mem_slot的封装,其中包含一个kvm_mem_slot的数组,对应于该虚拟机使用的所有
  •      * 内存区域(slot)
  •      */
  •     struct kvm_memslots *memslots;
  •     struct srcu_struct srcu;
  • #ifdef CONFIG_KVM_APIC_ARCHITECTURE
  •     u32 bsp_vcpu_id;
  • #endif
  •     // 虚拟机中包含的VCPU结构体数组,一个VCPU对应一个数组成员。
  •     struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
  •     // online的vcpu数量
  •     atomic_t online_vcpus;
  •     int last_boosted_vcpu;
  •     struct list_head vm_list;
  •     struct mutex lock;
  •     //虚拟机中包括的IO总线结构体数组,一条总线对应一个kvm_io_bus结构体,如ISA总线、PCI总线。
  •     struct kvm_io_bus *buses[KVM_NR_BUSES];
  •     // 事件通道相关
  • #ifdef CONFIG_HAVE_KVM_EVENTFD
  •     struct {
  •         spinlock_t        lock;
  •         struct list_head  items;
  •         struct list_head  resampler_list;
  •         struct mutex      resampler_lock;
  •     } irqfds;
  •     struct list_head ioeventfds;
  • #endif
  •     // 虚拟机中的运行时状态信息,比如页表、MMU等状态。
  •     struct kvm_vm_stat stat;
  •     // 架构相关的部分。
  •     struct kvm_arch arch;
  •     // 引用计数
  •     atomic_t users_count;
  • #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
  •     struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
  •     spinlock_t ring_lock;
  •     struct list_head coalesced_zones;
  • #endif

  •     struct mutex irq_lock;
  • #ifdef CONFIG_HAVE_KVM_IRQCHIP
  •     /*
  •      * Update side is protected by irq_lock and,
  •      * if configured, irqfds.lock.
  •      */
  •     // irq相关部分
  •     struct kvm_irq_routing_table __rcu *irq_routing;
  •     struct hlist_head mask_notifier_list;
  •     struct hlist_head irq_ack_notifier_list;
  • #endif

  • #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
  •     // mmu通知链
  •     struct mmu_notifier mmu_notifier;
  •     unsigned long mmu_notifier_seq;
  •     long mmu_notifier_count;
  • #endif
  •     // dirty TLB数量
  •     long tlbs_dirty;
  •     struct list_head devices;
  • };

kvm_dev_ioctl()-->kvm_dev_ioctl_create_vm()-->kvm_create_vm():



  • /*

  • * 实现虚拟机创建的主要函数
  • */
  • static struct kvm *kvm_create_vm(unsigned long type)
  • {
  •     int r, i;
  •     /*
  •      * 分配kvm结构体,一个虚拟机对应一个kvm结构,其中包括了虚拟机中的
  •      * 关键系统,比如内存、中断、VCPU、总线等信息,该结构体也是kvm的关键结
  •      * 构体之一
  •      */
  •     struct kvm *kvm = kvm_arch_alloc_vm();

  •     if (!kvm)
  •         return ERR_PTR(-ENOMEM);
  •     // 初始化kvm结构中的架构相关部分,比如中断
  •     r = kvm_arch_init_vm(kvm, type);
  •     if (r)
  •         goto out_err_nodisable;
  •     // 硬件使能,最终调用架构相关的kvm_x86_ops->hardware_enable()接口
  •     r = hardware_enable_all();
  •     if (r)
  •         goto out_err_nodisable;

  • #ifdef CONFIG_HAVE_KVM_IRQCHIP
  •     INIT_HLIST_HEAD(&kvm->mask_notifier_list);
  •     INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
  • #endif

  •     BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);

  •     r = -ENOMEM;
  •     // 分配memslots结构,并初始化为0
  •     kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
  •     if (!kvm->memslots)
  •         goto out_err_nosrcu;
  •     // 初始化内存槽位(slot)的id信息,便于后续索引
  •     kvm_init_memslots_id(kvm);
  •     if (init_srcu_struct(&kvm->srcu))
  •         goto out_err_nosrcu;
  •     // 初始化虚拟机的bus信息。
  •     for (i = 0; i buses[i] = kzalloc(sizeof(struct kvm_io_bus),
  •                     GFP_KERNEL);
  •         if (!kvm->buses[i])
  •             goto out_err;
  •     }
  •     // 初始化mmu_lock
  •     spin_lock_init(&kvm->mmu_lock);
  •     // 设置虚拟机的mm(mm_struct)为当前进程的mm
  •     kvm->mm = current->mm;
  •     atomic_inc(&kvm->mm->mm_count);
  •     // 初始化事件通道
  •     kvm_eventfd_init(kvm);
  •     mutex_init(&kvm->lock);
  •     mutex_init(&kvm->irq_lock);
  •     mutex_init(&kvm->slots_lock);
  •     atomic_set(&kvm->users_count, 1);
  •     INIT_LIST_HEAD(&kvm->devices);

  •     // 初始化mmu操作的通知链
  •     r = kvm_init_mmu_notifier(kvm);
  •     if (r)
  •         goto out_err;

  •     raw_spin_lock(&kvm_lock);
  •     // 将新创建的虚拟机的kvm结构,加入到全局链表vm_list中
  •     list_add(&kvm->vm_list, &vm_list);
  •     raw_spin_unlock(&kvm_lock);

  •     return kvm;

  • out_err:
  •     cleanup_srcu_struct(&kvm->srcu);
  • out_err_nosrcu:
  •     hardware_disable_all();
  • out_err_nodisable:
  •     for (i = 0; i buses[i]);
  •     kfree(kvm->memslots);
  •     kvm_arch_free_vm(kvm);
  •     return ERR_PTR(r);
  • }

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-155806-1-1.html 上篇帖子: KVM基本原理及架构四-内存虚拟化 下篇帖子: kernel 3.10代码分析--KVM相关--VCPU创建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表