1、IO虚拟化的分类

(1)全虚拟化:宿主机截获客户机对I/O设备的访问请求,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。

QEMU模拟I/O的情况下,当客户机中的设备驱动程序(device driver)发起I/O操作请求之时,KVM模块中的I/O操作捕获代码会拦截这次I/O请求,然后经过处理后将本次I/O请求的信息存放到I/O共享页,并通知用户控件的QEMU程序。QEMU模拟程序获得I/O操作的具体信息之后,交由硬件模拟代码来模拟出本次的I/O操作,完成之后,将结果放回到I/O共享页,并通知KVM模块中的I/O操作捕获代码。最后,由KVM模块中的捕获代码读取I/O共享页中的操作结果,并把结果返回到客户机中。当然,这个操作过程中客户机作为一个QEMU进程在等待I/O时也可能被阻塞。

另外,当客户机通过DMADirect Memory Access【DMA外接设备可以不用CPU干预,直接把数据传输到内存的技术,尽量减少CPU干预的输入/输出操作方式。(使用连续物理内存,kmalloc分配)。否则外设一有数据就要中断通知CPU,CPU去读,如果频繁就时间浪费在处理中断,IO速度慢】访问大块I/O之时,QEMU模拟程序将不会把操作结果放到I/O共享页中,而是通过内存映射的方式将结果直接写到客户机的内存中去,然后通过KVM模块告诉客户机DMA操作已经完成。

  • 优点是可以模拟出各种各样的硬件设备;
  • 缺点是每次 I/O 操作的路径比较长,需要多次上下文切换、多次数据复制和VM-Entry/Exit,性能较差。

(2)半虚拟化:通过前端驱动/后端驱动模拟实现I/O虚拟化。客户机中的驱动程序virtio-blk/net/pci/scsi为前端,宿主机提供的与客户机通信的驱动程序vhost为后端。前后端驱动通过 virtio-ring 直接通信,绕过了经过 KVM 内核模块的过程,达到提高 I/O 性能的目的。

  • 优点快。vring实现了环形缓冲区(ring buffer),用于保存前端驱动和后端处理程序执行的信息,并且它可以一次性保存前端驱动的多次I/O请求,并且交由后端去动去批量处理,最后实际调用宿主机中设备驱动实现物理上的I/O操作,这样做就可以根据约定实现批量处理而不是客户机中每次I/O请求都需要处理一次,从而提高客户机与hypervisor信息交换的效率。
  • 缺点:需要客户机中virtio相关驱动的支持(较老的系统默认没有自带这些驱动,Windows系统中需要额外安装virtio驱动),故兼容性较差,而且I/O频繁时的CPU使用率较高

(3)IO透传:直接把物理设备分配给虚拟机使用,这种方式需要硬件平台具备I/O透传技术,例如Intel VT-d技术。它能获得近乎本地的性能,并且CPU开销不高。

2、kvm和qemu的交互

Qemu创建虚拟机进入kvm:main函数通过调用kvm_init 和 machine->init来初始化kvm. 其中, machine->init会创建vcpu, 用一个线程去模拟vcpu, 该线程执行的函数为qemu_kvm_cpu_thread_fn, 并且该线程最终kvm_cpu_exec,该函数调用kvm_vcpu_ioctl切换到kvm中。

Kvm运行并因io退出:在kvm中看到参数KVM_RUN,最后调用vcpu_enter_guest,然后 vmx_vcpu_run设置好寄存器状态之后调用VM_LAUNCH或者VM_RESUME进入guest vm。如果vm进行IO操作需要访问设备时,就会触发vm exit 返回到vmx_vcpu_run, vmx保存好vmcs并且记录下VM_EXIT_REASON后返回到调用该函数的vcpu_enter_guest, 在vcpu_enter_guest函数末尾调用了r = kvm_x86_ops->handle_exit(vcpu), 该函数对应于vmx_handle_exit函数, vmx_handle_exit 调用kvm_vmx_exit_handlers[exit_reason](vcpu),该语句根据exit_reason调用不同的函数。io操作则是handle_io把数据填充到vcpu->run,就一路return到kvm_vcpu_ioctl,就ioctl返回到qemu的kvm_cpu_exec中。

从kvm返回到qemu后的处理:Qemu在kvm_cpu_exec中会看kvm_run的run->exit_reason如果是KVM_EXIT_IO就进入kvm_handle_io里处理。 当qemu完成IO操作后,会在kvm_cpu_exec函数的循环中,调用kvm_vcpu_ioctl重新进入kvm。

kvm_run,这是用于vcpu和应用层的程序(典型如qemu)通信的一个结构,user space的 程序通过KVM__VCPU_MMAP_SIZE这个ioctl得到大小,然后映射到用户空间。

3、kvm的io处理流程

static int handle_io(struct kvm_vcpu *vcpu)

{

         unsigned long exit_qualification;

         int size, in, string;

         unsigned port;

         exit_qualification = vmcs_readl(EXIT_QUALIFICATION);  //获取exit qualification

         string = (exit_qualification & ) != ; //判断是否为string io (ins, outs)

         in = (exit_qualification & ) != ; //判断io方向,是in  还是out

         ++vcpu->stat.io_exits;

         if (string || in) //如果是输入类的指令,或者是string io,就进入emulator处理

                   return emulate_instruction(vcpu, ) == EMULATE_DONE;

         port = exit_qualification >> ; //得到端口号

         size = (exit_qualification & ) + ; //大小

         skip_emulated_instruction(vcpu); //跳过这个指令

         return kvm_fast_pio_out(vcpu, size, port); //进行out操作

}

Guest执行io指令 -> 发生vmexit-> 返回qemu -> 处理io

1、out指令虚拟:虚拟单个out指令,在KVM中可以直接把out的数据返回给qemuqemu完成out操作

流程:KVM的handle_io->kvm_fast_pio_out->emulator_pio_out_emulated后面是vcpu->arch.pio.count = 0函数中非string类型的 out操作可以一步完成,所以从qemu处理完返回kvm后不需要再进入emulator。在emulator_pio_out_emulated中,将IO数据memcpy到kvm和qemu共享buffer中,然后emulator_pio_in_out,将相应数据保存到kvm_run中就返回到qemu的kvm_cpu_exec的switch看run->exit_reason,如果是KVM_EXIT_IO则进入kvm_handle_io中和设备交互。

2、Stringin指令虚拟:如果是in指令,qemu只能把得到的数据写到kvm_run中,kvm必须在下一次vmentry的时候,将qemu得到的数据放到相应的位置,所以,在handle_io中,如果是in或者string指令,没有调用skip_emulated_instruction,这样,qemu完成in或者一次out之后,还会在同样的地方发生vmexit,这样再由emulator完成相应的处理,针对string类型的指令,emulator会进行解码等操作,确认io的次数和源操作数、目的操作数等。

流程:handle_io->emulate_instruction->x86_emulate_instruction对指令的decode,在过程中会调用到em_in和em_out(这两个函数最后调用的emulator_pio_in_emulated中先通过和上面PIO一样的函数emulator_pio_in_out,正确返回表明qemu已经将模拟出的数据返回到参数val了,则可直接memcpy完成具体的将从qemu中得到的数据写到正确位置vcpu->arch.pio_data),设置如果是out,下次到KVM时直接进入emulator,如果是in,注册vcpu->arch.complete_userspace_io = complete_emulated_pio;需要在下次qemu进入kvm的时候,完成io,实际上就是将qemu得到的数据写到正确的位置。下次进入kvm,如果要完成in指令,会在函数kvm_arch_vcpu_ioctl_run中调用注册的complete_emulated_pio会再次调用emulate_instruction将数据写到正确位置(这次不用解码,而是直接em_in)。

kvm和qemu交互处理io流程的更多相关文章

  1. 虚拟化技术xen,kvm,qemu区别

    虚拟化类型 全虚拟化(Full Virtualization) 全虚拟化也成为原始虚拟化技术,该模型使用虚拟机协调guest操作系统和原始硬件,VMM在guest操作系统和裸硬件之间用于工作协调,一些 ...

  2. kvm与qemu

    载请注明出处: http://www.openext.org/2014/04/kvmqemu/ http://blog.csdn.net/muge0913/article/details/245577 ...

  3. UED视觉交互设计与流程介绍

    UED视觉交互设计与流程介绍 ------------------------------------------------------------------ 今天先到这儿,希望对您技术领导力, ...

  4. 小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理

    学习从小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理;     1.小睿向欣方新发起呼叫请求;     2.欣方新可以通过线路发起SIP协议请求,来呼叫用户;     3.当用户接通后,将建立 ...

  5. KVM和QEMU简介

    KVM/QEMU简介 KVM虚拟机是基于linux内核虚拟化,自linux2.6.20之后就集成在linux的各个主要发行版本中.它使用linux自身的调度器进行管理,所以相对于xen,其核心源码很少 ...

  6. IO流程及优化

    http://blog.csdn.net/xypzwl/article/details/51416883 一.存储设备的存储原理 机械硬盘: 机械硬盘使用磁性物质作为存储介质,用N.S极性来代表0或1 ...

  7. Linux虚拟化技术KVM、QEMU与libvirt的关系(转)

    说明:个人理解,KVM是内核虚拟化技术,而内核是不能使用在界面上使用的,那么此时QEMU提供了用户级别的使用界面,相互辅助.当然,单独使用QEMU也是可以实现一整套虚拟机,不过QEMU+KVM基本是标 ...

  8. kvm和qemu的关系

    KVM (Kernel Virtual Machine) is a Linux kernel module that allows a user space program to utilize th ...

  9. KVM和QEMU的关系(转载)

    From:http://blog.sina.com.cn/s/blog_605f5b4f0102uyjv.html KVM是一种基于CPU硬件辅助的全虚拟化技术,没有CPU硬件虚拟化的支持,KVM无法 ...

随机推荐

  1. hibernate 报query result offset is not supported

    在配置hibernate.cfg.xml时需指定使用数据库的方言: 例: <property name="dialect">org.hibernate.dialect. ...

  2. idea 常用快捷键

    =============intellij idea 快捷键============= ctrl+] 诸如{}围起来的代码块,使用该快捷键可以快速跳转至代码块的结尾处 ctrl+[ 同上,快速跳至代码 ...

  3. MySQL自动备份shell脚本

    在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分为热备和冷备,按照备份数据库文件的大小 ...

  4. Sun SPARC Enterprise M5000 启动步骤

    1.串口线与笔记本连接(需在笔记本上安装串口线的驱动程序,usb口接笔记本,网线水晶头接M5000)2.接通电源.此时XSCF卡充电,自检,前面板XSCF等闪烁.3.登录超级终端,注意波特率要跟主机匹 ...

  5. php 二维数组根据值进行排序

    // 先获取要排序的值 $createTime = array_column($data, 'create_time'); // 排序成功 array_multisort($createTime, S ...

  6. linux 服务器时间同步

    1  12 *  *  * .usr/sbin/nttpdate pool.ntp.org 分时 天 周 月 定时更同步 crontab -e 先查看是否安装 ntp这个包 没有安装的话 yum-y ...

  7. 2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解

    2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解 1. 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常 ...

  8. RoR - More Active Record

    Active Record Scope: default_scope:   默认的检索方式 #Use unscoped to break out of the default class Hobby ...

  9. [转]理解 Bias 与 Variance 之间的权衡----------bias variance tradeoff

    有监督学习中,预测误差的来源主要有两部分,分别为 bias 与 variance,模型的性能取决于 bias 与 variance 的 tradeoff ,理解 bias 与 variance 有助于 ...

  10. win10配置java环境变量,解决javac不是内部或外部命令等问题

    win10配置java环境变量,解决javac不是内部或外部命令等问题 https://www.cnblogs.com/qianji/p/6402690.html