Chinaunix首页 | 论坛 | 博客
  • 博客访问: 547581
  • 博文数量: 183
  • 博客积分: 2650
  • 博客等级: 少校
  • 技术积分: 1427
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-22 17:02
文章分类
文章存档

2017年(1)

2015年(46)

2014年(4)

2013年(8)

2012年(2)

2011年(27)

2010年(35)

2009年(60)

分类: LINUX

2015-04-23 20:08:45

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);
}
阅读(1303) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~