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无法 ...
随机推荐
- __x__(34)0908第五天__ 定位 position
position 定位 指将原始摆放到页面的任意位置. 继承性:no 默认值:static 没有定位,原始出现在正常的文档流中 可选值: static : 默认值,元素没有开启定位 ...
- __x__(42)0910第六天__表格布局 老旧的布局方法
table 布局 不易于维护,耦合太严重了. 不利于搜索引擎检索. 效果图: html代码: <!doctype html> <html> <head> <m ...
- Codeforces Round #547 (Div. 3)
我老人家走了四公里吃个汉堡还没吃成.垃圾肯德基.垃圾春分半价桶. 蜜雪冰城百香果加冰+烤串真是爽死了.原来二十多块钱可以吃的这么爽. A: #include <bits/stdc++.h> ...
- Jmeter .jmx 改为.jtl
1.cd $jmeter\bin 2. jmeter -n -t $jmeter\extras\**.jmx -l $jmeter\extras\**.jtl 3.cd $jmeter\extras ...
- 配置NTP网络时间自动校对系统时间和创建备份文件
1 案例1:配置用户和组账号 1.1 问题 本例要求创建下列用户.组以及组的成员关系: 新建用户 alex,其用户ID为3456,密码是flectrag 创建一个名为 adminuser 的组 创建一 ...
- Linux命令 at cron
at: 可以处理仅执行一次就结束排程的指令.需要atd服务 crontab: 所设定的指令将会循环地一直进行下去.需要crontab服务 at: Ubuntu16.04 默认没有安装atd服务.安装命 ...
- PHP函数ip2long转换IP时数值太大而产生负数
// 使用 sprintf 返回无符号十进制数 $long = sprintf("%u",ip2long($ip)); // 先转换为二进制然后在转换为十进制 $long = bi ...
- set和 map 数据结构
set/map数据结构 创建: var s=new Set(); 添加成员 s.add(1) 遍历 for of s.froEach 删除 s.delete() 判断存在 s.has() 清除 s. ...
- 美团笔试(web前端)
分为3部分: 1.逻辑推理.行测.找规律: 2.html css javascript的简单的选择题,以及数据结构,操作系统方面的知识: 3.两道编程题,第一道题关于竞赛报名,有限制的分组,输入N和M ...
- Oracle数据泵远程导入数据
查看现存镜像目录 select * from dba_directories; 创建镜像目录 create or replace directory my_dir as 'local_dir' ; 把 ...