kvm和qemu交互处理io流程
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时也可能被阻塞。
另外,当客户机通过DMA(Direct 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的数据返回给qemu,qemu完成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、String或in指令虚拟:如果是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流程的更多相关文章
- 虚拟化技术xen,kvm,qemu区别
虚拟化类型 全虚拟化(Full Virtualization) 全虚拟化也成为原始虚拟化技术,该模型使用虚拟机协调guest操作系统和原始硬件,VMM在guest操作系统和裸硬件之间用于工作协调,一些 ...
- kvm与qemu
载请注明出处: http://www.openext.org/2014/04/kvmqemu/ http://blog.csdn.net/muge0913/article/details/245577 ...
- UED视觉交互设计与流程介绍
UED视觉交互设计与流程介绍 ------------------------------------------------------------------ 今天先到这儿,希望对您技术领导力, ...
- 小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理
学习从小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理; 1.小睿向欣方新发起呼叫请求; 2.欣方新可以通过线路发起SIP协议请求,来呼叫用户; 3.当用户接通后,将建立 ...
- KVM和QEMU简介
KVM/QEMU简介 KVM虚拟机是基于linux内核虚拟化,自linux2.6.20之后就集成在linux的各个主要发行版本中.它使用linux自身的调度器进行管理,所以相对于xen,其核心源码很少 ...
- IO流程及优化
http://blog.csdn.net/xypzwl/article/details/51416883 一.存储设备的存储原理 机械硬盘: 机械硬盘使用磁性物质作为存储介质,用N.S极性来代表0或1 ...
- Linux虚拟化技术KVM、QEMU与libvirt的关系(转)
说明:个人理解,KVM是内核虚拟化技术,而内核是不能使用在界面上使用的,那么此时QEMU提供了用户级别的使用界面,相互辅助.当然,单独使用QEMU也是可以实现一整套虚拟机,不过QEMU+KVM基本是标 ...
- kvm和qemu的关系
KVM (Kernel Virtual Machine) is a Linux kernel module that allows a user space program to utilize th ...
- KVM和QEMU的关系(转载)
From:http://blog.sina.com.cn/s/blog_605f5b4f0102uyjv.html KVM是一种基于CPU硬件辅助的全虚拟化技术,没有CPU硬件虚拟化的支持,KVM无法 ...
随机推荐
- 构建Maven父子工程
IDEA构建maven父子工程: 1.打开IDEA,Create New Project 如图: 如果没有弹出新建界面,可以先 file-->Close Project 如图: 2.创建父 ...
- (81)Wangdao.com第十六天_JavaScript 严格模式
严格模式 除了正常的运行模式,JavaScript 还有第二种运行模式:严格模式(strict mode).顾名思义,这种模式采用更加严格的 JavaScript 语法 同样的代码,在正常模式和严格模 ...
- mobile_轮播图_style_left 版本
mobile 轮播图 小圆点逻辑(排他) 1. 统一给所有 span 元素加 class=""; 2. 切换到谁,谁的 class="active"; 移动端轮 ...
- Axure软件界面及元件
Axure 软件的需求史 功能:用来制作快速原型的软件.也可以绘制中保真原型草图. (适用人群:产品经理,交互设计师,UI设计师,网页设计师, 想要自己提升的人[重]) 原型分类: 低保真原型(草图) ...
- 汇编入门——使用DOSBox写一个HelloWorld以及相关软件安装
0.0.0) 在D盘建立一个ASM文件夹 0.0.1) 放入所需要的文件 1所标示的红色框为必须要存在的文件,要处理汇编文件.百度网盘中下载. 2自己编写的汇编(asm)文件. 3编译汇编自己生成的文 ...
- Linux下提权常用小命令
有些新手朋友在拿到一个webshell后如果看到服务器是Linux或Unix操作系统的就直接放弃提权,认为Linux或Unix下的提权很难,不是大家能做的,其实Linux下的提权并没有很多人想象的那么 ...
- Swift之Swift编码规范
swift 支持的 markdown 语法. 1. 编码格式 1.1 使用二元运算符(+, -,==, 或->)的前后都需要添加空格 let value = + 1.2 在逗号后面加一个空格 l ...
- es6 中的 symbol
symbol 的引入是为了解决对象中的属性名冲突的问题 使用symbol() 函数生成的变量值不与任何的变量值相等, 所有用改变量的值做属性名是不会冲突的 symbol 可以转化为字符串, 可以转化 ...
- ant 执行jmeter脚本
环境准备 1.jdk版本:java version "1.8.0_201" 2.jmeter版本:5.0 3.ant版本:Apache Ant(TM) version 1.10.5 ...
- golang的包管理---vendor/dep等
首先关于vendor 1 提出问题 我们知道,一个工程稍大一点,通常会依赖各种各样的包.而Go使用统一的GOPATH管理依赖包,且每个包仅保留一个版本.而不同的依赖包由各自的版本工具独立管理,所以当所 ...