Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Linux / Xen 源代码片段解读 (1):函数 adjust_vmx_controls(arch/x86/kvm/vmx.c)

arch/x86/kvm/vmx.c Kernel-based Virtual Machine driver for Linux
  1. static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,  
  2.                                       u32 msr, u32 *result)  
  3. {  
  4.         u32 vmx_msr_low, vmx_msr_high;  
  5.         u32 ctl = ctl_min | ctl_opt;  
  6.   
  7.         rdmsr(msr, vmx_msr_low, vmx_msr_high);  
  8.   
  9.         ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */  
  10.         ctl |= vmx_msr_low;  /* bit == 1 in low word  ==> must be one  */  
  11.   
  12.         /* Ensure minimum (required) set of control bits are supported. */  
  13.         if (ctl_min & ~ctl)  
  14.                 return -EIO;  
  15.   
  16.         *result = ctl;  
  17.         return 0;  
  18. }  
该函数用于根据 MSR 寄存器的实际值,校正(adjust)期望的设置,这里的所谓“设置”表示为 32 位的控制字符(control),其中特定的若干位置 1 通常表明开启 CPU 的某些功能。这些值将用于设置 VM 运行时的 CPU。
参数:    ctl_min  至少需开启的设置(minimum required)    ctl_opt  可选的设置(optional)    msr      MSR 寄存器的地址,表明读取哪个 MSR 的控制字符    result   输出地址,将用于保存校正值(类型 u32 表示 32 位无符号整型)

第 5 行临时变量 ctl 对 ctl_min 和 ctl_opt 取或,保留了两个参数中的所有置 1 位,即包含了最小设置和可选设置,是期望的设置。
第 7 行读取相应的 MSR 寄存器的控制字符,该字符用 64 位表示对特定设置的要求:低 32 位保存在变量 vmx_msr_low 中,其中某位置 0 表示要求设置的相应位必须为 0;高 32 位保存在变量 vmx_msr_high 中,其中某位置 1 表示要求设置的相应位必须为 1;显然这两组要求本身保证没有冲突。
第 9 行将期望设置 ctl 与表示必须置 1 的控制字符取且,则保证所有要求置 1 的位在 ctl 中均已置 1;第 10 行将期望设置 ctl 与表示必须置 0 的控制字符取或,则保证所有要求置 0 的位在 ctl 均已置 0;至此,期望设置 ctl 已经根据 MSR 的要求进行了校正。
最后,还要判断校正后的值是否满足最初要求的最小设置(第 13 行),即判断最小设置 ctl_min 的置 1 位在校正值 ctl 中是否依然置 1. 对 ctl 取反,则其所有置 0 位变为 1,如果 ctl_min 某对应位也是 1,则 (ctl_min & ~ctl) 出现真值,此时该位在 ctl_min 中原本为 1,但经校正后在 ctl 中却被置为了 0,即不满足最低要求。 
如果满足最低要求,则在第 16 行将校正值写入输出结果,进而正常返回。