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)

                              ->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
复制代码

注意如果想要退出虚拟模式,可以使用VMM运行VMXOFF指令.

                                                   

                                          ->kvm_vcpu_init

会设置vcpu->run = page_address(page);这个结构在io中会很有用,这个函数主要是初始化vcpu的数据

                                              ->kvm_arch_vcpu_init

复制代码
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)

                             ->r = vcpu_load(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相关的内容(时钟吧)

                              ->kvm_vcpu_reset

重置了一些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   Practicer..  阅读(1020)  评论(0编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示