*(int *)((char *)(kvm->vcpus->kvm_run) + kvm->vcpus->kvm_run->io.data_offset) ); break; ... 虚拟机退出并得知原因为 KVM_EXIT_IO,模拟器得知由于设备产生了IO操作并退出,于是获取这个IO操作并打印出数据。这里其实我们就最小化的模拟了一个虚拟IO的过程,由模拟器接管这个IO。 在qemu-kvm全...
首先通过判断exit_reason是否为KVM_EXIT_IO来确定退出原因是IO端口请求。 void handle_IO(struct kvm_cpu* vcpu){ if (vcpu->kvm_run->io.direction == KVM_EXIT_IO_OUT){ u8* src = (u8*)vcpu->kvm_run; u64 offset = vcpu->kvm_run->io.data_offset; u64 tot_size = (vcpu->kvm_run->io...
DPRINTF("io window exit\n"); ret = EXCP_INTERRUPT; break; } fprintf(stderr, "error: kvm run failed %s\n", strerror(-run_ret)); abort(); } trace_kvm_run_exit(cpu->cpu_index, run->exit_reason); switch (run->exit_reason) { case KVM_EXIT_IO: DPRINTF("handle_io\n"); kvm_h...
DPRINTF("io window exit\n"); ret = EXCP_INTERRUPT; break; } fprintf(stderr,"error: kvm run failed %s\n", strerror(-run_ret)); abort(); } trace_kvm_run_exit(cpu->cpu_index, run->exit_reason); switch (run->exit_reason) { case KVM_EXIT_IO: DPRINTF("handle_io\n"); kvm_han...
IO全虚拟化使用QEMU软件模拟 1.当虚拟机进行I/O操作时,根据《也谈Intel的cpu虚拟化》我们知道,虚拟机通过VM exit将cpu控制权返回给VMM,从而陷入到root模式下的ring0内的VMM,进行”陷入模拟“。 2.将本次I/O请求的信息存放到IO共享页,QEMU从IO共享页读取信息后由硬件模拟代码来模拟出本次的IO操作,并调用内核中...
case KVM_EXIT_IO: case KVM_EXIT_HLT: } } 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. KVM内核模块本身只能提供CPU和内存的虚拟化,所以它必须结合QEMU才能构成一个完成的虚拟化技术,这就是下面要说的qemu-kvm。 qemu-kvm Qemu将KVM整合进来,通过ioctl调用/dev/kvm接口,将有关CPU指令的部分交由内核模块来...
注意exit reason是KVM_EXIT_IO,并且记录下了对应的port、count等参数。 结合一下正常的访问过程:物理机使用in、out访问port的时候,通过外部电路访问具体的设备,读取或者写入数据。 而虚拟化的场景下呢,PIO的核心就是Guest访问port的时候,并不是真正的去访问Host的物理外部电路。而是Host主动拦截对应的指令,用软件处理...
QEMU通过ioctl发出KVM_CREATE_VM、KVM_CREATE_VCPU等这种虚拟机、vCPU的创建指令,让guest投入运行。之后QEMU执行KVM_RUN这样的IOCTL,如果这个IOCTL返回,意味着VMexit。qemu根据返回的情况,确定是否是guest OS发生IO的动作,如果是,则进行IO模拟以及执行主机的系统调用来完成IO动作,伪代码类似: ...
https://github.com/iovisor/bcc/blob/master/examples/tracing/kvm_hypercall.py 运行结果如下: 这个程序使用了kvm相关的以下几个tracepoint静态跟踪点: kvm_entry:当虚拟机的vCPU(虚拟中央处理单元)从主机CPU切换到虚拟机CPU并开始执行虚拟指令时,触发kvm_entry跟踪点,vcpu_id用于标识特定的虚拟CPU。
case KVM_EXIT_IO: if (run->io.direction == KVM_EXIT_IO_OUT && run->io.size == 1 && run->io.port == 0x3f8 && run->io.count == 1) printf("exit io:%c \n", (*(((char *)run) + run->io.data_offset))); break; ...