qemu-kvm虚拟化 vpid 代码分析

830阅读 0评论2014-01-10 embeddedlwp
分类:LINUX

qemu-kvm虚拟化 vpid 代码分析

1.页表实现线性地址到物理地址转换。

2.ept (Extended Page Tables)实现客户机物理地址到宿主机物理地址装换。

3.tlb (Translation lookaside buffer )旁路装换缓冲区,改进虚拟地址(线性地址)到物理地址转换速度的缓存。
操作系统中我们知道每个进程都有自己页表,进程切换重新设置cr3寄存器,同时刷新tlb。但是进程切换并不一定要刷新tlb,相同页表的进程切换和内核线程与普通进程切换,其实就不需要。
对于虚拟化来说,Vm-Entry 和Vm-Exit时,会强制cpu刷新tlb,全部内容失效, 不管是VMM页表, 还是各个虚拟机的ept页表的tlb缓存。

4.vpid 就是避免tlb刷新整体失效,区分是vmm ,各个vm页表,这样提高虚拟机切换效率。要使用vpid很简单,首先判断cpu是否支持vpid(读取VMCS相应域),然后分配vcpu时同时分配vpid(设置VMCS相应域),剩下事情属于硬件事情了。
1).硬件是否支持
cat /proc/cpuinfo | grep vpid
cat /proc/cpuinfo | grep ept
2).模块是否启用
cat /sys/module/kvm_intel/parameters/ept
cat /sys/module/kvm_intel/parameters/vpid

代码分析

判断cpu是否支持vpid
static inline int cpu_has_vmx_vpid(void)
{
        return vmcs_config.cpu_based_2nd_exec_ctrl &
                SECONDARY_EXEC_ENABLE_VPID;
}  

分配vpid
static void allocate_vpid(struct vcpu_vmx *vmx)
{
        int vpid;
        
        vmx->vpid = 0;
        if (!enable_vpid)
                return;
        spin_lock(&vmx_vpid_lock);
        vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS);
        if (vpid < VMX_NR_VPIDS) {
                vmx->vpid = vpid;
                __set_bit(vpid, vmx_vpid_bitmap);
        }
        spin_unlock(&vmx_vpid_lock);
}
释放vpid
static void free_vpid(struct vcpu_vmx *vmx)
{
        if (!enable_vpid)
                return;
        spin_lock(&vmx_vpid_lock);
        if (vmx->vpid != 0)
                __clear_bit(vmx->vpid, vmx_vpid_bitmap);
        spin_unlock(&vmx_vpid_lock);
}
刷新vpid
static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx)
{
        if (vmx->vpid == 0)
                return;

        __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0);
}
上一篇:qemu-kvm 内存虚拟化
下一篇:Guest OS, Qemu, KVM工作流程