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对应的设备操作等
1 2 3 4 5 6 7 8 9 10 11 | 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)
->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);
这个函数设置相应的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 }
注意如果想要退出虚拟模式,可以使用VMM运行VMXOFF指令.
会设置vcpu->run = page_address(page);这个结构在io中会很有用,这个函数主要是初始化vcpu的数据
if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))//第一个判断是kvm中的kvm->arch.vpic是否被为空,如果为空的话执行6624 6624 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 6625 else 6626 vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; 6627 下面和上面的判断一样 if (irqchip_in_kernel(kvm)) { 6642 r = kvm_create_lapic(vcpu);//不为空的话为 vcpu->arch.apic = apic;设置新值没理解为什么要这样作. 6643 if (r < 0) 6644 goto fail_mmu_destroy; 6645 } else 6646 static_key_slow_inc(&kvm_no_apic_vcpu);//如果为空的话,增加kvm_no_apic_vcpu的值
初始化vcpu->arch里面的结构,并且会调用kvm_mmu_create(在上篇关于内存的地方有讲到)
->vmx_vcpu_put(&vmx->vcpu);(在函数vmx_create_vcpu中被调用)
->kvm_arch_vcpu_setup(vcpu)
->cpu=get_cpu();得到当前的cpu号.
->kvm_arch__vcpu_load(vcpu, cpu);
->vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)(这里为什么还要调用一次这个函数,在vmx_create_vcpu中已经调用了这个函数完成了.vmcs于cpu的匹配??)
->下面的很大一部分是处理的tsc相关的内容(时钟吧)
重置了一些vcpu.arch中的内容,例如clock
->kvm_x86_ops->vcpu_reset(vcpu);
->vcpu_put(vcpu);和上面一样最终调用的是vmx_vcpu_put
->create_vcpu_fd(struct kvm_vcpu *vcpu) 完成在用户空间定义一个kvm-vcpu的文件,利用下面的将该vcpu于该文件以及kvm_vcpu_fops结合起来。 anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, O_RDWR);
kvm_vcpu_ioctl会按照参数调用下面的函数
->kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)这里2个参数需要注意下,最后的参数可能在io 时候用到
->__vcpu_run(vcpu)
->vcpu_enter_guest(struct kvm_vcpu *vcpu)
->作一些必要的检测主要是检测requset,需要注入中断时注入终端,这里以后还在分析
->r = kvm_mmu_reload(vcpu);这里是加载相应的内存页吧.//在上篇内存中有介绍
->kvm_x86_ops->prepare_guest_switch(vcpu);这里主要是保存的host的状态位
->kvm_load_guest_xcr0(vcpu);这里还没分析好
->kvm_guest_enter(void)这里主要是设计到rcu的
->kvm_x86_ops->run(vcpu);(vmx_vcpu_run也就是这个函数)
->vmx_vcpu_run(struct kvm_vcpu *vcpu)
下面是具体进入的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <strong><em> /* Store host registers */ </em></strong> <a name= "L6316" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6316" rel= "noopener nofollow" >6316</a> <em> "push %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> "; push %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BP" rel= "noopener nofollow" >_ASM_BP</a> <em> ";" //下面要用到这些寄存器所有需要保存</em> <a name= "L6317" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6317" rel= "noopener nofollow" >6317</a> <em> "push %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_CX" rel= "noopener nofollow" >_ASM_CX</a> <em> " \n\t" </em> <strong><em> /* placeholder for guest rcx */ </em></strong> <a name= "L6318" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6318" rel= "noopener nofollow" >6318</a> <em> "push %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_CX" rel= "noopener nofollow" >_ASM_CX</a> <em> " \n\t" </em> <a name= "L6319" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6319" rel= "noopener nofollow" >6319</a> <em> "cmp %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_SP" rel= "noopener nofollow" >_ASM_SP</a> <em> ", %c[host_rsp](%0) \n\t" </em> <a name= "L6320" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6320" rel= "noopener nofollow" >6320</a> <em> "je 1f \n\t" </em> <a name= "L6321" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6321" rel= "noopener nofollow" >6321</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_SP" rel= "noopener nofollow" >_ASM_SP</a> <em> ", %c[host_rsp](%0) \n\t" </em> <a name= "L6322" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6322" rel= "noopener nofollow" >6322</a> <a href= "http://localhost/lxr/http/ident?i=__ex" rel= "noopener nofollow" >__ex</a>(<a href= "http://localhost/lxr/http/ident?i=ASM_VMX_VMWRITE_RSP_RDX" rel= "noopener nofollow" >ASM_VMX_VMWRITE_RSP_RDX</a>) <em> "\n\t" </em> <a name= "L6323" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6323" rel= "noopener nofollow" >6323</a> <em> "1: \n\t" </em> <a name= "L6324" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6324" rel= "noopener nofollow" >6324</a> <strong><em> /* Reload cr2 if changed */ </em></strong> <a name= "L6325" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6325" rel= "noopener nofollow" >6325</a> <em> "mov %c[cr2](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> " \n\t" </em> <a name= "L6326" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6326" rel= "noopener nofollow" >6326</a> <em> "mov %%cr2, %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> " \n\t" </em> <a name= "L6327" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6327" rel= "noopener nofollow" >6327</a> <em> "cmp %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> ", %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> " \n\t" </em> <a name= "L6328" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6328" rel= "noopener nofollow" >6328</a> <em> "je 2f \n\t" </em> <a name= "L6329" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6329" rel= "noopener nofollow" >6329</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a><em> ", %%cr2 \n\t" </em> <a name= "L6330" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6330" rel= "noopener nofollow" >6330</a> <em> "2: \n\t" </em> <a name= "L6331" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6331" rel= "noopener nofollow" >6331</a> <strong><em> /* Check if vmlaunch of vmresume is needed */ </em></strong> <a name= "L6332" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6332" rel= "noopener nofollow" >6332</a> <em> "cmpl $0, %c[launched](%0) \n\t" //%c对应的vmx这个结构,而lauched对应的是lauched这个结构的偏移,下面有讲到</em> <a name= "L6333" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6333" rel= "noopener nofollow" >6333</a> <strong><em> /* Load guest registers. Don't clobber flags. */ </em></strong> <a name= "L6334" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6334" rel= "noopener nofollow" >6334</a> <em> "mov %c[rax](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> " \n\t" //用vmx中的寄存器的值填充到当前的寄存器中</em> <a name= "L6335" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6335" rel= "noopener nofollow" >6335</a> <em> "mov %c[rbx](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BX" rel= "noopener nofollow" >_ASM_BX</a> <em> " \n\t" </em> <a name= "L6336" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6336" rel= "noopener nofollow" >6336</a> <em> "mov %c[rdx](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> " \n\t" </em> <a name= "L6337" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6337" rel= "noopener nofollow" >6337</a> <em> "mov %c[rsi](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_SI" rel= "noopener nofollow" >_ASM_SI</a> <em> " \n\t" </em> <a name= "L6338" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6338" rel= "noopener nofollow" >6338</a> <em> "mov %c[rdi](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DI" rel= "noopener nofollow" >_ASM_DI</a> <em> " \n\t" </em> <a name= "L6339" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6339" rel= "noopener nofollow" >6339</a> <em> "mov %c[rbp](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BP" rel= "noopener nofollow" >_ASM_BP</a> <em> " \n\t" </em> <a name= "L6340" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6340" rel= "noopener nofollow" >6340</a> #ifdef CONFIG_X86_64 <a name= "L6341" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6341" rel= "noopener nofollow" >6341</a> <em> "mov %c[r8](%0), %%r8 \n\t" </em> <a name= "L6342" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6342" rel= "noopener nofollow" >6342</a> <em> "mov %c[r9](%0), %%r9 \n\t" </em> <a name= "L6343" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6343" rel= "noopener nofollow" >6343</a> <em> "mov %c[r10](%0), %%r10 \n\t" </em> <a name= "L6344" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6344" rel= "noopener nofollow" >6344</a> <em> "mov %c[r11](%0), %%r11 \n\t" </em> <a name= "L6345" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6345" rel= "noopener nofollow" >6345</a> <em> "mov %c[r12](%0), %%r12 \n\t" </em> <a name= "L6346" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6346" rel= "noopener nofollow" >6346</a> <em> "mov %c[r13](%0), %%r13 \n\t" </em> <a name= "L6347" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6347" rel= "noopener nofollow" >6347</a> <em> "mov %c[r14](%0), %%r14 \n\t" </em> <a name= "L6348" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6348" rel= "noopener nofollow" >6348</a> <em> "mov %c[r15](%0), %%r15 \n\t" </em> <a name= "L6349" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6349" rel= "noopener nofollow" >6349</a> #endif <a name= "L6350" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6350" rel= "noopener nofollow" >6350</a> <em> "mov %c[rcx](%0), %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_CX" rel= "noopener nofollow" >_ASM_CX</a> <em> " \n\t" </em> <strong><em> /* kills %0 (ecx) */ </em></strong> <a name= "L6351" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6351" rel= "noopener nofollow" >6351</a> <a name= "L6352" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6352" rel= "noopener nofollow" >6352</a> <strong><em> /* Enter guest mode */ </em></strong> <a name= "L6353" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6353" rel= "noopener nofollow" >6353</a> <em> "jne 1f \n\t" </em> <a name= "L6354" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6354" rel= "noopener nofollow" >6354</a> <a href= "http://localhost/lxr/http/ident?i=__ex" rel= "noopener nofollow" >__ex</a>(<a href= "http://localhost/lxr/http/ident?i=ASM_VMX_VMLAUNCH" rel= "noopener nofollow" >ASM_VMX_VMLAUNCH</a>) <em> "\n\t" </em> <a name= "L6355" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6355" rel= "noopener nofollow" >6355</a> <em> "jmp 2f \n\t" </em> <a name= "L6356" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6356" rel= "noopener nofollow" >6356</a> <em> "1: " </em> <a href= "http://localhost/lxr/http/ident?i=__ex" rel= "noopener nofollow" >__ex</a>(<a href= "http://localhost/lxr/http/ident?i=ASM_VMX_VMRESUME" rel= "noopener nofollow" >ASM_VMX_VMRESUME</a>) <em> "\n\t" </em> <a name= "L6357" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6357" rel= "noopener nofollow" >6357</a> <em> "2: " //从上面开始就已经进入到了GUEST模式中</em> <a name= "L6358" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6358" rel= "noopener nofollow" >6358</a> <strong><em> /* Save guest registers, load host registers, keep flags */ </em></strong> <a name= "L6359" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6359" rel= "noopener nofollow" >6359</a> <em> "mov %0, %c[wordsize](%%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_SP" rel= "noopener nofollow" >_ASM_SP</a> <em> ") \n\t" //从这里开始退出了GUSET模式,有进入了host模式</em> <a name= "L6360" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6360" rel= "noopener nofollow" >6360</a> <em> "pop %0 \n\t" </em> <a name= "L6361" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6361" rel= "noopener nofollow" >6361</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> ", %c[rax](%0) \n\t" </em> <a name= "L6362" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6362" rel= "noopener nofollow" >6362</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BX" rel= "noopener nofollow" >_ASM_BX</a> <em> ", %c[rbx](%0) \n\t" </em> <a name= "L6363" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6363" rel= "noopener nofollow" >6363</a> <a href= "http://localhost/lxr/http/ident?i=__ASM_SIZE" rel= "noopener nofollow" >__ASM_SIZE</a>(<a href= "http://localhost/lxr/http/ident?i=pop" rel= "noopener nofollow" >pop</a>) <em> " %c[rcx](%0) \n\t" </em> <a name= "L6364" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6364" rel= "noopener nofollow" >6364</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> ", %c[rdx](%0) \n\t" </em> <a name= "L6365" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6365" rel= "noopener nofollow" >6365</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_SI" rel= "noopener nofollow" >_ASM_SI</a> <em> ", %c[rsi](%0) \n\t" </em> <a name= "L6366" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6366" rel= "noopener nofollow" >6366</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DI" rel= "noopener nofollow" >_ASM_DI</a> <em> ", %c[rdi](%0) \n\t" </em> <a name= "L6367" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6367" rel= "noopener nofollow" >6367</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BP" rel= "noopener nofollow" >_ASM_BP</a> <em> ", %c[rbp](%0) \n\t" </em> <a name= "L6368" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6368" rel= "noopener nofollow" >6368</a> #ifdef CONFIG_X86_64 <a name= "L6369" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6369" rel= "noopener nofollow" >6369</a> <em> "mov %%r8, %c[r8](%0) \n\t" </em> <a name= "L6370" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6370" rel= "noopener nofollow" >6370</a> <em> "mov %%r9, %c[r9](%0) \n\t" </em> <a name= "L6371" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6371" rel= "noopener nofollow" >6371</a> <em> "mov %%r10, %c[r10](%0) \n\t" </em> <a name= "L6372" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6372" rel= "noopener nofollow" >6372</a> <em> "mov %%r11, %c[r11](%0) \n\t" </em> <a name= "L6373" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6373" rel= "noopener nofollow" >6373</a> <em> "mov %%r12, %c[r12](%0) \n\t" </em> <a name= "L6374" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6374" rel= "noopener nofollow" >6374</a> <em> "mov %%r13, %c[r13](%0) \n\t" </em> <a name= "L6375" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6375" rel= "noopener nofollow" >6375</a> <em> "mov %%r14, %c[r14](%0) \n\t" </em> <a name= "L6376" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6376" rel= "noopener nofollow" >6376</a> <em> "mov %%r15, %c[r15](%0) \n\t" </em> <a name= "L6377" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6377" rel= "noopener nofollow" >6377</a> #endif <a name= "L6378" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6378" rel= "noopener nofollow" >6378</a> <em> "mov %%cr2, %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> " \n\t" </em> <a name= "L6379" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6379" rel= "noopener nofollow" >6379</a> <em> "mov %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_AX" rel= "noopener nofollow" >_ASM_AX</a> <em> ", %c[cr2](%0) \n\t" </em> <a name= "L6380" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6380" rel= "noopener nofollow" >6380</a> <a name= "L6381" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6381" rel= "noopener nofollow" >6381</a> <em> "pop %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_BP" rel= "noopener nofollow" >_ASM_BP</a> <em> "; pop %%" </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_DX" rel= "noopener nofollow" >_ASM_DX</a> <em> " \n\t" </em> <a name= "L6382" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6382" rel= "noopener nofollow" >6382</a> <em> "setbe %c[fail](%0) \n\t" </em> <a name= "L6383" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6383" rel= "noopener nofollow" >6383</a> <em> ".pushsection .rodata \n\t" </em> <a name= "L6384" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6384" rel= "noopener nofollow" >6384</a> <em> ".global vmx_return \n\t" </em> <a name= "L6385" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6385" rel= "noopener nofollow" >6385</a> <em> "vmx_return: " </em> <a href= "http://localhost/lxr/http/ident?i=_ASM_PTR" rel= "noopener nofollow" >_ASM_PTR</a> <em> " 2b \n\t" </em> <a name= "L6386" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6386" rel= "noopener nofollow" >6386</a> <em> ".popsection" </em> <a name= "L6387" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6387" rel= "noopener nofollow" >6387</a> : : <em> "c" </em>(vmx), <em> "d" </em>((unsigned long )HOST_RSP), <a name= "L6388" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6388" rel= "noopener nofollow" >6388</a> [launched]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, __launched)), <a name= "L6389" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6389" rel= "noopener nofollow" >6389</a> [fail]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, fail)), <a name= "L6390" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6390" rel= "noopener nofollow" >6390</a> [host_rsp]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, host_rsp)), <a name= "L6391" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6391" rel= "noopener nofollow" >6391</a> [<a href= "http://localhost/lxr/http/ident?i=rax" rel= "noopener nofollow" >rax</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RAX])), <a name= "L6392" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6392" rel= "noopener nofollow" >6392</a> [<a href= "http://localhost/lxr/http/ident?i=rbx" rel= "noopener nofollow" >rbx</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RBX])), <a name= "L6393" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6393" rel= "noopener nofollow" >6393</a> [<a href= "http://localhost/lxr/http/ident?i=rcx" rel= "noopener nofollow" >rcx</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RCX])), <a name= "L6394" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6394" rel= "noopener nofollow" >6394</a> [<a href= "http://localhost/lxr/http/ident?i=rdx" rel= "noopener nofollow" >rdx</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RDX])), <a name= "L6395" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6395" rel= "noopener nofollow" >6395</a> [<a href= "http://localhost/lxr/http/ident?i=rsi" rel= "noopener nofollow" >rsi</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RSI])), <a name= "L6396" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6396" rel= "noopener nofollow" >6396</a> [<a href= "http://localhost/lxr/http/ident?i=rdi" rel= "noopener nofollow" >rdi</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RDI])), <a name= "L6397" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6397" rel= "noopener nofollow" >6397</a> [<a href= "http://localhost/lxr/http/ident?i=rbp" rel= "noopener nofollow" >rbp</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_RBP])), <a name= "L6398" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6398" rel= "noopener nofollow" >6398</a> #ifdef CONFIG_X86_64 <a name= "L6399" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6399" rel= "noopener nofollow" >6399</a> [<a href= "http://localhost/lxr/http/ident?i=r8" rel= "noopener nofollow" >r8</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R8])), <a name= "L6400" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6400" rel= "noopener nofollow" >6400</a> [<a href= "http://localhost/lxr/http/ident?i=r9" rel= "noopener nofollow" >r9</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R9])), <a name= "L6401" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6401" rel= "noopener nofollow" >6401</a> [<a href= "http://localhost/lxr/http/ident?i=r10" rel= "noopener nofollow" >r10</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R10])), <a name= "L6402" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6402" rel= "noopener nofollow" >6402</a> [<a href= "http://localhost/lxr/http/ident?i=r11" rel= "noopener nofollow" >r11</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R11])), <a name= "L6403" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6403" rel= "noopener nofollow" >6403</a> [<a href= "http://localhost/lxr/http/ident?i=r12" rel= "noopener nofollow" >r12</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R12])), <a name= "L6404" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6404" rel= "noopener nofollow" >6404</a> [<a href= "http://localhost/lxr/http/ident?i=r13" rel= "noopener nofollow" >r13</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R13])), <a name= "L6405" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6405" rel= "noopener nofollow" >6405</a> [<a href= "http://localhost/lxr/http/ident?i=r14" rel= "noopener nofollow" >r14</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R14])), <a name= "L6406" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6406" rel= "noopener nofollow" >6406</a> [<a href= "http://localhost/lxr/http/ident?i=r15" rel= "noopener nofollow" >r15</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=regs" rel= "noopener nofollow" >regs</a>[VCPU_REGS_R15])), <a name= "L6407" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6407" rel= "noopener nofollow" >6407</a> #endif <a name= "L6408" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6408" rel= "noopener nofollow" >6408</a> [<a href= "http://localhost/lxr/http/ident?i=cr2" rel= "noopener nofollow" >cr2</a>]<em> "i" </em>(<a href= "http://localhost/lxr/http/ident?i=offsetof" rel= "noopener nofollow" >offsetof</a>( struct <a href= "http://localhost/lxr/http/ident?i=vcpu_vmx" rel= "noopener nofollow" >vcpu_vmx</a>, vcpu.<a href= "http://localhost/lxr/http/ident?i=arch" rel= "noopener nofollow" >arch</a>.<a href= "http://localhost/lxr/http/ident?i=cr2" rel= "noopener nofollow" >cr2</a>)), <a name= "L6409" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6409" rel= "noopener nofollow" >6409</a> [wordsize]<em> "i" </em>( sizeof (<a href= "http://localhost/lxr/http/ident?i=ulong" rel= "noopener nofollow" > ulong </a>)) <a name= "L6410" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6410" rel= "noopener nofollow" >6410</a> : <em> "cc" </em>, <em> "memory" </em> <a name= "L6411" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6411" rel= "noopener nofollow" >6411</a> #ifdef CONFIG_X86_64 <a name= "L6412" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6412" rel= "noopener nofollow" >6412</a> , <em> "rax" </em>, <em> "rbx" </em>, <em> "rdi" </em>, <em> "rsi" </em> <a name= "L6413" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6413" rel= "noopener nofollow" >6413</a> , <em> "r8" </em>, <em> "r9" </em>, <em> "r10" </em>, <em> "r11" </em>, <em> "r12" </em>, <em> "r13" </em>, <em> "r14" </em>, <em> "r15" </em> <a name= "L6414" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6414" rel= "noopener nofollow" >6414</a> # else <a name= "L6415" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6415" rel= "noopener nofollow" >6415</a> , <em> "eax" </em>, <em> "ebx" </em>, <em> "edi" </em>, <em> "esi" </em> <a name= "L6416" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6416" rel= "noopener nofollow" >6416</a> #endif <a name= "L6417" href= "http://localhost/lxr/http/source/arch/x86/kvm/vmx.c#L6417" rel= "noopener nofollow" >6417</a> );<br><br> |
下面的很大一部分代码都是更行vcpu的相关域主要是有关中断处理的部分.而对应的(下面3个函数是vmx_vcpu_run中的函数)
->vmx_complete_atomic_exit(vmx);
6463 ->vmx_recover_nmi_blocking(vmx); 6464 ->vmx_complete_interrupts(vmx);
则可以处理的是将相应的中断或者其他信息读入到vmx中.
->kvm_guest_exit();调用这个函数不知道有什么用处
->kvm_x86_ops->handle_exit()调用vmx_handle_exit处理相应的vcpu的中断
->long kvm_arch_vcpu_ioctl(struct file *filp,unsigned int ioctl, unsigned long arg)
2044 case KVM_SET_FPU: { 2045 fpu = memdup_user(argp, sizeof(*fpu)); 2046 if (IS_ERR(fpu)) { 2047 r = PTR_ERR(fpu); 2048 fpu = NULL; 2049 goto out; 2050 } 2051 r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu); 2052 break; 2053 } 2054 default: 2055 r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);//default的情况调用这个函数,而这个函数处理qemu注入中断的情况 2056 } 2057 out:
上面这个函数在kvm_vcpu_ioctl中被默认的调用,也就是不符合kvm_vcpu_ioctl中指定参数的情况下调用,但是这个函数非常重要,用于在用户空间的qemu对向vcpu注入中断
一篇关于内核中内存的文章,
http://blog.csdn.net/ctthuangcheng/article/details/8915146
首先,内核代码所访问的地址都是虚拟地址,因为CPU指令接收的就是虚拟地址(地址映射对于CPU指令是透明的)。但是,建立地址映射时,内核在页表里面填写的内容却是物理地址,因为地址映射的目标就是要得到物理地址。
上面的话摘自博客
smp_rmb();这个函数完成的是内存屏障的作用,也就是保证对在 LFENCE 指令前面发出的所有加载指令执行序列化操作.保证在lfence前进行的读写完成,这里会停止流水线
pic_irqchip(kvm)返回kvm->arch.vpic;
irqchip_in_kernel()返回kvm->arch.vpic是否被初始化
get_cpu()禁止抢断,并且要返回当前的cpu号
put_cpu()设置可以抢断
指令:
VMCALL --- 调用虚拟机监视器(VM Monitor)
VMCLEAR --- 清空虚拟机控制结构(VMCS)
VMLAUNCH --- 初始化(Lauch)虚拟机
VMRESUME --- 重新进入先前已经初始化(Resume)的虚拟机
VMPTRLD --- 加载指向VMCS的指针
VMPSRT --- 存储指向VMCS的指针
VMREAD --- 读取虚拟机控制结构(VMCS)中的域值
VMWRITE --- 写入虚拟机控制结构(VMCS)中的域值
VMXOFF --- 退出VMX root操作状态
VMXON --- 进入VMX root操作状态
关于MP 初始化的文章http://blog.csdn.net/zenny_chen/article/details/6060253
关于APIC的文章http://blog.csdn.net/kendyhj9999/article/details/8927709
需要查看进入linux模块的参数如何传递???????????????????????????
posted on 2013-10-29 11:16 Practicer.. 阅读(1020) 评论(0) 编辑 收藏 举报