Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1426115
  • 博文数量: 487
  • 博客积分: 161
  • 博客等级: 入伍新兵
  • 技术积分: 5064
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-01 07:37
个人简介

只有偏执狂才能生存

文章分类

全部博文(487)

文章存档

2016年(10)

2015年(111)

2014年(66)

2013年(272)

2012年(28)

分类: LINUX

2013-06-18 17:43:13

VCPU 线程的启动函数为 ap_main_loop, 其代码在 qemu-kvm.c 中,该函数的代码需要从内核中创建 VCPU 抽象及单个 VCPU 相关的硬件,然后调用 kvm_main_loop_cpu。 kvm_main_loop_cpu 中包含 while 循环,除非 VCPU 关闭,否则 VCPU 的线程就不会退出该循环。kvm_rum 中调用 ioctl(,KVM_RUN) 进入 KVM 内核,在内核代码中切换进入客操作系统的代码执行,真正运行起一个 VCPU。一般只有当有 IO 操作需要用户空间仿真时,kvm_run 才会从 ioctl(,KVM_RUN) 中返回,执行 handle_mmio 等一些 IO 操作仿真的代码。

 

在内核空间,KVM 的 ioctl 功能分派函数会调用 __vcpu_run, 该函数也是一个包含 while 循环的函数,在每次工作的开始调用 vcpu_enter_guest, vcpu_enter_guest 做一些检查工作后调用 svm 特定的 svm_vcpu_run 函数, svm_vcpu_run 是进行客主模式切换的地方, 这里调用 VMRUM 指令加载 VMCB 的内容,进入“guest”模式。 客操作系统的代码运行在“guest”模式,遇到任何中断,异常或其他需要被捕获的事件,硬件就会执行 VMEXIT 而退出“guest”模式,退出后从 svm_vcpu_run 中位于 VMRUN 后的一条语句开始执行。 退出 svm_vcpu_run 后在 vcpu_enter_guest 中会调用 svm 特定的函数 handle_exit, 做退出事件的处理。 如果 handle_exit 处理的结果表明立即需要用户空间继续处理,如外部设备 IO_Memory 的仿真, 则从 vcpu_enter_guest 返回后的代码会退出 __vcpu_run, 进而退出到用户空间,从 ioctl(,KVM_RUN) 返回,执行 handle_mmio 等用户空间的仿真工作, 并在用户空间 kvm_main_loop_cpu 的主循环中重新调用 ioctl(,KVM_RUN) 进入 KVM, 进而重新进入客操作系统。

 VCPU 的 qemu-kvm 线程的重要执行路径,如图三所示 :


图 3. 执行路径
图 3. 执行路径 

在此图中,最左侧的执行路径是 qemu-kvm 的代码建立一个虚拟机的过程, 起点是 pc_init_rhel620, 该函数的代码在 hw/pc.c 中,“rhel620”代表 qemu-kvm 对虚拟机的定义, hw/pc.c 中提供了多个虚拟机定义,“rhel620” 是保留选用的定义,“rhel620”定义采用“cpu64-rhel6” CPU 模型,支持最大 255 个虚拟 CPU。一个 CPU 模型定义了虚拟的 CPU 所支持的特征列, qemu-kvm 定义的全部 CPU 模型在 sysconfigs/target/cpu-x86_64.conf 文件下。函数 pc_init1 是 qemu-kvm 用户空间很关键的一个函数,其代码中需要创建虚拟机的 PC 硬件,如分配物理内存,加载 BIOS, 分配 IO 端口空间,创建平台设备,创建 VGA 设备等。 pc_init1 然后要做的工作就是为每个 VCPU 创建一个线程。

VCPU 线程的启动函数为 ap_main_loop, 其代码在 qemu-kvm.c 中,该函数的代码需要从内核中创建 VCPU 抽象及单个 VCPU 相关的硬件,然后调用 kvm_main_loop_cpu。 kvm_main_loop_cpu 中包含 while 循环,除非 VCPU 关闭,否则 VCPU 的线程就不会退出该循环。kvm_rum 中调用 ioctl(,KVM_RUN) 进入 KVM 内核,在内核代码中切换进入客操作系统的代码执行,真正运行起一个 VCPU。一般只有当有 IO 操作需要用户空间仿真时,kvm_run 才会从 ioctl(,KVM_RUN) 中返回,执行 handle_mmio 等一些 IO 操作仿真的代码。

在内核空间,KVM 的 ioctl 功能分派函数会调用 __vcpu_run, 该函数也是一个包含 while 循环的函数,在每次工作的开始调用 vcpu_enter_guest, vcpu_enter_guest 做一些检查工作后调用 svm 特定的 svm_vcpu_run 函数, svm_vcpu_run 是进行客主模式切换的地方, 这里调用 VMRUM 指令加载 VMCB 的内容,进入“guest”模式。 客操作系统的代码运行在“guest”模式,遇到任何中断,异常或其他需要被捕获的事件,硬件就会执行 VMEXIT 而退出“guest”模式,退出后从 svm_vcpu_run 中位于 VMRUN 后的一条语句开始执行。 退出 svm_vcpu_run 后在 vcpu_enter_guest 中会调用 svm 特定的函数 handle_exit, 做退出事件的处理。 如果 handle_exit 处理的结果表明立即需要用户空间继续处理,如外部设备 IO_Memory 的仿真, 则从 vcpu_enter_guest 返回后的代码会退出 __vcpu_run, 进而退出到用户空间,从 ioctl(,KVM_RUN) 返回,执行 handle_mmio 等用户空间的仿真工作, 并在用户空间 kvm_main_loop_cpu 的主循环中重新调用 ioctl(,KVM_RUN) 进入 KVM, 进而重新进入客操作系统。

 

阅读(2215) | 评论(0) | 转发(0) |
0

上一篇:内核虚拟化KVM——overview

下一篇:intel vt

给主人留下些什么吧!~~