Board logo

标题: KVM 虚拟化技术在 AMD 平台上的实现(6) [打印本页]

作者: look_w    时间: 2018-4-23 12:24     标题: KVM 虚拟化技术在 AMD 平台上的实现(6)

IO 设备的虚拟化物理设备仿真    对传统物理设备进行仿真是 KVM 最早期采用的支持虚拟机 IO 的方式。 这种方式的特点是客操作系统看到的设备和通常裸机操作系统上看到的设备有相同的格式和规范,如同样格式的 PCI 配置空间,同样的 MMIO 区域尺寸和格式,同样的 PIO 寄存器和功能。 因此客操作系统能使用已有的传统物理设备的驱动来访问这些仿真的设备。这种方式的好处是不要求客操作系统做任何软件上的改变。
    设备仿真的实现过程主要是让 VMM 截取客操作系统对设备 MMIO 和 PIO 空间的访问,然后分派不同的后端来处理与 MMIO 或 PIO 访问对应的逻辑。 就 KVM 而言,一般平台型设备,如 PIT, PIC, APIC 等是直接在 KVM 内核中实现后端的代码的, 而 PCI 总线上的设备或更外围的方式连接的设备,由于其逻辑的复杂性,都是通过 qemu-kvm 在用户空间来仿真的。在 KVM 内核空间的 MMIO 和 PIO 实现比较简单, KVM 实现了一个抽象的 IO_BUS 模型,把所有的设备都按 struct kvm_io_device 抽象实现,要求每个都提供自己的 struct kvm_io_dev_ops 接口的实现, 每个平台设备的 struct kvm_io_dev_ops 的 read/write 函数的主要功能就是根据 IO 地址读写该设备内核数据结构的不同部分, 并根据数据的值变化实现一定的逻辑。
    就 qemu-kvm 用户空间而言,最重要的工作是仿真设备的 MMIO 内存和 PIO 端口。  设备的 MMIO 内存可实现成三种方式 :
   PIO 的仿真更简单。所有的 PIO 都会被 KVM 所截取,不能在内核处理的 PIO 使 KVM 跳出到 qemu-kvm 用户空间, 由 qemu-kvm 来完成 PIO 读写的仿真。 Qemu-kvm 同样是根据用户空间已经 mmap 了的每个 struct kvm_vcpu 的 struct kvm_run 区域以及 pid_data 区域知道需要仿真的 PIO 读写操作涉及的端口地址、尺寸及数据。
    当然 Qemu-kvm 设备仿真要做的更大量工作是在逻辑层,如对于网络设备,需要考虑仿真的网络包怎样经过 Host 的网络进行发送和接收, 桥接的还是 NAT 的; 对于块设备,需要考虑客操作系统写过来的磁盘块以怎样的方式组织到设备 Image 文件中, Qcow2 或 QED 的选择; 对于 VGA 设备,需要实现怎样把图像缓冲区中的内容通过远程表现处理,VNC 或 SPICE 等。 设备逻辑层所需要做的工作应该是目前开发空间比较大的地方, 这部分和 KVM 虚拟化的基本机制没太大关系,内容太多,在此就不描述了。
虚拟的功能设备    实现虚拟的功能设备是支持虚拟机 IO 的第二种方法。 虚拟的功能设备就是说虚拟机使用的 IO 设备不一定要遵守已有的设备标准如 SCSI 协议,Intel 以太网卡的规范等等, 只要实现上能完成操作系统想要的功能即可,如支持磁盘数据块的传送,TCP/IP 网络包的传送,实现 IO 完成的通知等。 这种方式由于不遵守已有的设备格式和规范,无法使用客操作系统上已有的物理设备驱动, 在 VMM 上虚拟化设备的同时,在客操作系统上也需要专有的驱动程序配合。 不同的 VMM 实现往往有自己独立的虚拟设备的实现机制,目前 KVM 采用的是称为 virtIO 的技术。 VirtIO 是 IBM 的 Rusty Russell 提出的实现虚拟设备的规范,其核心思想是通过定义一个公共的 ABI, 让客操作系统以简易的方式向 VMM 告知其数据缓冲区,并以这些缓冲区为基础承载不同类型虚拟设备的数据交换。 在 virtIO 的思想中,虽然逻辑数据是客主双方交换的,但缓冲区总是由客操作系统方面提供的。  以 Linux 客操作系统为例,VirtIO 的实现可简要描述如下 :
    目前 virtIO 设备的后端主要在 qemu-kvm 用户空间实现,但对于 virtio-net 设备,RHEL6.2 已经将后端驱动的代码移植到了内核层,称为 vhost-net, 这样做消除了不必要的用户和内核空间的交互,能明显提高 virtio-net 的性能。
   目前 KVM 上除 virtIO 外,还有其他的方式的虚拟设备的实现,如 kvmclock。 kvmclock 实现的是一个时钟源 kvm_clock, 为客操作系统提供精确的 System Time 和 Wall Clock。 kvm_clock 的实现使用了硬件的支持,如 AMD-V 的 VMCB.CONTROL 提供的 TSC_OFFSET, 以及 KVM 使用的一些技巧,如用两个定制的 MSR 寄存器 MSR_KVM_WALL_CLOCK 和 MSR_KVM_SYSTIME_TIME, 通过截取这两个定制的 MSR 让 KVM 来直接访问客操作系统的时间变量。 在 KVM 上,和时间源及定时器硬件相关的虚拟化本身可构成一个独立的话题,笔者打算以后用专门的文章介绍。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0