QEMU源码全解析 —— CPU虚拟化(11)

123 篇文章 36 订阅 ¥49.90 ¥99.00

接前一篇文章:

本文内容参考:

《趣谈 Linux操作系统 》 —— 刘超, 极客时间

QEMU /KVM》 源码 解析与应用 —— 李强,机械工业出版社

《深度探索 Linux 系统 虚拟化 原理与实现》—— 王柏生 谢广军, 机械工业出版社

特此致谢!

前边几回又再次讲了一下VMX,本回开始讲解VCPU的生命周期。

二、x86架构CPU虚拟化

4. VCPU生命周期

对于每个虚拟处理器(VCPU),VMM使用一个线程来代表VCPU这个实体 。在Guest运转过程中,每个VCPU基本都在下图所示的状态中不断地转换。

(1) 在用户空间准备好后,VCPU所在线程向(Linux)内核中KVM模块发起一个ioctl请求KVM_RUN 。告知内核中的KVM模块,用户空间的操作已经完成,可以切入Guest模式运行Guest了。

(2) 在进入内核态后,KVM模块将调用CPU提供的虚拟化指令切入Guest模式 。如果是首次运行Guest,则使用VMLaunch命令,否则使用VMResume命令。

在这个切换过程中:

1)首先,CPU的状态(即Host的状态)将被保存到VMCS中存储Host状态的区域,非CPU自动保存的状态由KVM负责保存。

2)然后,加载存储在VMCS中的Guest的状态到物理CPU,非CPU自动恢复的状态则由KVM负责恢复。

(3)物理CPU切入Guest模式,运行Guest指令。 当执行Guest指令遇到敏感指令时,CPU将从Guest模式切换回Host模式的ring 0,进入Host内核的KVM模块

在这个切换过程中:

1)首先,CPU的状态(也就是Guest的状态)将会保存到VMCS中存储Guest状态的区域。

2)然后,加载存储在VMCS中的Host的状态到物理CPU。同样的,非CPU自动保存的状态由KVM模块负责保存。

(4) 处于内核态的KVM模块从VMCS中读取虚拟机退出的原因,尝试在内核中处理 。如果内核中可以处理,那么 虚拟机 就不必再切换到Host模式的用户态了,处理完后,直接快速切回Guest。这种退出也称为 轻量级虚拟机退出

(5) 如果内核态的KVM模块不能处理虚拟机退出,那么VCPU将再进行一次上下文切换,从Host的内核态切换到Host的用户态,由VMM的用户空间部分进行处理

(6) VMM用户空间处理完毕,再次发起切入Guest模式的指令 。在整个虚拟机的运行过程中,步骤(1)~(6)循环往复。

QEMU示例代码如下(对应以上过程):

  1. while (1)
  2. {
  3. ret = ioctl(vcpufd, KVM_RUN, NULL);
  4. if (ret == -1)
  5. {
  6. printf("exit unknown\n");
  7. return -1;
  8. }
  9. switch(run->exit_reason)
  10. {
  11. case KVM_EXIT_HLT:
  12. puts("KVM_EXIT_HLT");
  13. return 0;
  14. case KVM_EXIT_IO:
  15. putchar( ((char *)run) + run->io.data_offset));
  16. break;
  17. case KVM_EXIT_FAIL_ENTRY:
  18. puts("entry error");
  19. return -1;
  20. default:
  21. puts("other error");
  22. printf("exit_reason: %d\n, run->exit_reason");
  23. return -1;
  24. }
  25. }

更多内容请看下回。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他