kvm

kvm_dev_ioctl_create_vm->kvm = kvm_create_vm(type);产生新的vm 

             ->生成相应的设备文件:r = anon_inode_getfd(“kvm-vm”, &kvm_vm_fops, kvm, O_RDWR)

kvm_create_vm->kvm_arch_init_vm->hardware_enable_all()-〉

 

 

最初的是在 __init vmx_init 中,这块代码是实际驱动模块的 开始 

1.->kvm_init->kvm_arch_init

            ->kvm_arch_hardware_setup()->kvm_x86_ops->hardware_setup()->static struct kvm_x86_ops vmx_x86_ops 是进行操作运行的->hardware_setup 在这个函数中存在很多的标志位,需要注意以后会在哪里用到

                                                                                   ->setup_vmcs_config()设置 vmcs_config

                                                                                   ->alloc_kvm_area()为每个cpu配置 vmcs,这里要注意的是vmcs对应的是虚拟地址(这里我觉得应该要注意点,内核中使用的应该也是 内核的虚拟地址 ),根据 vmcs_config设置 相应的 vmcs

            -> kvm_mmu_module_init();

            ->kvm_set_mmio_spte_mask();

            ->kvm_timer_init()上面的函数还没有分析

        ->register_cpu_notifier(&kvm_cpu_notifier);应该是对每个CPU多会调用这个函数,还没分析,应该是对事件进行处理 

        ->r = misc_register(&kvm_dev);注册kvm_dev这个设备,该设备对应的操作时 ->kvm_dev_ioctl()这个函数用来调用 kvm_dev_ioctl_create_vm生成新的vm

  下面是kvm_dev对应的设备操作等

 static struct file_operations kvm_chardev_ops = {
	.unlocked_ioctl = kvm_dev_ioctl,
	.compat_ioctl   = kvm_dev_ioctl,//这是外界 qemu和kvm内部的接口
	.llseek		= noop_llseek,
};

static struct miscdevice kvm_dev = {
	KVM_MINOR,
	"kvm",
	&kvm_chardev_ops,//操作 
};

2.处理ept相关的内容

  开启或者关闭ept,这里使用的标志位是在 hardware_setup函数内赋值的。调用 kvm_enable_tdp()

 

当用户调用 ioctl(,KVM_CREATE_VM)时生成新的vm时调用顺序:

kvm_dev_ioctl->kvm_dev_ioctl_create_vm ->kvm_create_vm(type);

                            ->kvm_arch_alloc_vm();

                            ->kvm_arch_init_vm          

                            ->hardware_enable_all()对于每个CPU调用->hardware_enable_nolock

                            ->kvm->mm = current->mm这理可以看处kvm使用的是当前进程的内存区间

 

                   ->生成相应的设备文件:r = anon_inode_getfd(“kvm-vm”, &kvm_vm_fops, kvm, O_RDWR)  kvm-vm 这个设备文件就是要进行vcpu创建等工作的。

kvm_vm_fops

static struct file_operations kvm_vm_fops = {
2308         .release        = kvm_vm_release,
2309         .unlocked_ioctl = kvm_vm_ioctl,//这里是用来操作建立vcpu等工作的
2310 #ifdef CONFIG_COMPAT
2311         .compat_ioctl   = kvm_vm_compat_ioctl,
2312 #endif
2313         .mmap           = kvm_vm_mmap,
2314         .llseek         = noop_llseek,
2315 };

 

 用户调用ioctl(“kvm-v”,KVM_CREATE_VCPU)生成新的cpu时调用下面函数:

kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)->vcpu = kvm_arch_vcpu_create(kvm, id);(这个id是vcpu的id,不是实际cpu的id)

                              ->kvm_vcpu *vmx_create_vcpu

                                          ->cpu=get_cpu()

                                          ->vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)

     将相应的vcpu对应的vmcs于id为cpu的核心进行匹配设置cpu per_cpu(current_vmcs, cpu)域,完成vmcs激活等,并且更新相应的vcpu对应的vmcs中的host域,vmx = to_vmx(vcpu);

                                        

                                          ->vmx_vcpu_setup:

     这个函数设置相应的vmcs域。Sets up the vmcs for emulated real mode.

                                           ->vmx_vcpu_put

    

static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
1604 {
1605         __vmx_load_host_state(to_vmx(vcpu));//这里是安需要重新加载host的寄存器的值,为什么要重新加载呢?
1606         if (!vmm_exclusive) {//这里是标志着什么呢?
1607                 __loaded_vmcs_clear(to_vmx(vcpu)->loaded_vmcs);
1608                 vcpu->cpu = -1;
1609                 kvm_cpu_vmxoff();
1610         }
1611 }

View Code

Related Posts

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注