linux虚拟化之KVM

Posted 技术沉淀分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux虚拟化之KVM相关的知识,希望对你有一定的参考价值。

本文主要介绍linux虚拟化中的kvm部分。也是linux虚拟化三部马车里的最后一部。


当qemu执行kvm_vcpu_ioctl()时,进入内核态函数。具体切换至内核态是通过ioctl系统调用执行的。

linux虚拟化之KVM

linux虚拟化之KVM

ioctl系统调用sys_ioctl->ksys_ioctl->do_vfs_ioctl->vfs_ioctl->unlocked_ioctl->kvm_vcpu_ioctl

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

#define KVMIO 0xAE

linux虚拟化之KVM

linux虚拟化之KVM

kvm_vcpu_ioctl()第二个参数是int类型的,即KVM_RUN是个int,在qemu代码中KVM_RUN是个宏,看下这个宏具体是多少。

 

#define KVM_RUN                   _IO(0xAE,   0x80)

#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)

#define _IO(0xAE,0x80)        _IOC(0,(0xAE),(0x80),0)

 

_IOC也是个宏

#define _IOC(dir,type,nr,size)

   (((dir)  << _IOC_DIRSHIFT) |

    ((type) << _IOC_TYPESHIFT) |

    ((nr)   << _IOC_NRSHIFT) |

    ((size) << _IOC_SIZESHIFT))

将参数带入展开如下:

#define _IOC(0,0xAE,0x80,0)

   (((0)  << _IOC_DIRSHIFT) |

    ((0xAE) << _IOC_TYPESHIFT) |

    ((0x80)   << _IOC_NRSHIFT) |

    ((0) << _IOC_SIZESHIFT))

接下来计算下_IOC_DIRSHIFT, _IOC_TYPESHIFT, _IOC_NRSHIFT,_IOC_SIZESHIFT

#define _IOC_NRSHIFT    0

#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)

 

#define _IOC_NRBITS 8

#define _IOC_TYPEBITS   8

 

_IOC_TYPESHIFT = 0 + 8 = 8

_IOC_SIZESHIFT =_IOC_NRSHIFT+_IOC_NRBITS+_IOC_TYPEBITS = 0 + 8 + 8 = 16

_IOC_DIRSHIFT = _IOC_SIZESHIFT +_IOC_SIZEBITS = 16 + 14 = 30

 

#define _IOC(0,0xAE,0x80,0)

   (((0)  << 30) |

    ((0xAE) << 8) |

    ((0x80)   << 0) |

    ((0) << 16))

 

#define _IOC(0,0xAE,0x80,0) ((0)<<30)| ((0xAE) << 8) | ((0x80) << 0) | ((0) << 16)

因此,最后得到KVM_RUN为0xAE80(十进制是44672)

#define _IOC(0,0xAE,0x80,0) 0xAE80

linux虚拟化之KVM

 其中,type=0xAE80

 

KVM逻辑:

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

vcpu_enter_guest()函数核心逻辑是

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

kvm_x86_ops是个struct型指针。

linux虚拟化之KVM

从上面结构体可以看到,所有成员函数都是函数指针。

真正实现回调函数在arch/x86/kvm/vmx/vmx.c【注意:vmx是针对Intel VT-x,svm是针对AMD】

linux虚拟化之KVM

因此,kvm_x86_ops->run(vcpu)实际调用的函数是vmx_vcpu_run

linux虚拟化之KVM

linux虚拟化之KVM

linux虚拟化之KVM

这段汇编指令主要实现进入客户机模式以及从客户机模式退出。依赖于Intel的硬件虚拟化技术(AMD的参考svm.c的svm_vcpu_run())

下面截图是测试环境qemu进程的stack情况。

总结下qemu进入通过ioctl进入内核态和guest进行通信的逻辑图:

 


以上是关于linux虚拟化之KVM的主要内容,如果未能解决你的问题,请参考以下文章

云计算绕不开的虚拟化之KVM

Linux学习总结(七十二)虚拟化之kvm

Linux系统之虚拟化实战PVE下KVM虚拟机的嵌套安装方法

Linux 篇 | KVM

Linux实战之KVM虚拟机安装爱快软路由系统

Linux系统KVM虚拟机实战LVM逻辑卷之扩展Swap交换分区