KVM循序渐进耳之原理篇
字数 1514 2025-08-23 18:31:18

KVM虚拟化技术深入解析:从原理到实践

1. KVM环境搭建与初始化

1.1 环境准备

  • 系统环境:CentOS 6 (2.6.32-754.35.1.el6.x86_64)
  • QEMU版本:0.12.1 (qemu-kvm-0.12.1.2-2.506.el6_10.8)

1.2 依赖安装

yum install pciutils-devel
yum install libpic libpic-devel

1.3 QEMU-KVM编译与安装

  1. 配置编译环境:

    ./configure
    
  2. 编译后重要可执行文件:

    • x86_64-softmmu/qemu-system-x86_64
    • qemu-io
    • qemu-nbd
    • qemu-img
  3. 安装选项:

    • 拷贝到/usr/bin
    • 创建软链接
    • 使用make install(推荐)

1.4 常见编译问题解决

  • 版本不匹配时可能需要修改gcc选项或源码
  • 复杂依赖环境可先yum安装qemu-kvm lib,然后卸载rmmod kvm/kvm-intel

2. QEMU-KVM虚拟机创建

2.1 创建虚拟机镜像

qemu-img create -f qcow2 centos6_vm1.img 10G

2.2 启动虚拟机

qemu-system-x86_64 -m 512 -smp 1 --enable-kvm -boot d -hda /kvm_vm/centos6_vm1.img -cdrom /root/CentOS-6.10-x86_64-minimal.iso

2.3 BIOS文件问题解决

  1. 查找bios.bin:

    find / -name bios.bin
    
  2. 拷贝到正确位置:

    cp /root/qemu-kvm-0.12.1.2/pc-bios/bios.bin /usr/share/seabios/
    cp /root/qemu-kvm-0.12.1.2/pc-bios/vapic.bin /usr/local/share/qemu/
    
  3. 修改源码调试路径(vl.c):

    snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
    fprintf(stderr, "[+]bios path: %s\n", buf);
    

3. KVM初始化流程分析

3.1 KVM初始化入口

if (kvm_enabled()) {
    int ret;
    ret = kvm_init(smp_cpus);
    if (ret < 0) {
        fprintf(stderr, "failed to initialize KVM\n");
        exit(1);
    }
}

3.2 KVM模块加载

insmod kvm.ko
insmod kvm-intel.ko  # 或 kvm-amd.ko

4. VMX技术深入解析

4.1 VMX检测流程

  1. 使用CPUID检测VMX支持:

    static __init int cpu_has_kvm_support(void) {
        unsigned long ecx = cpuid_ecx(1);
        return test_bit(5, &ecx);  // CPUID.1:ECX.VMX[bit 5]
    }
    
  2. BIOS设置检测:

    static __init int vmx_disabled_by_bios(void) {
        u64 msr;
        rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
        return (msr & 5) == 1;  // locked but not enabled
    }
    

4.2 VMXON操作

  1. 设置CR4.VMXE位:

    write_cr4(read_cr4() | CR4_VMXE);
    
  2. 执行VMXON指令:

    asm volatile ("vmxon %0" : : "m"(phys_addr) : "memory", "cc");
    

4.3 VMX关键点总结

  1. 检测流程

    • 检测CPUID是否支持VMX
    • 设置CR4.VMXE[bit 13] = 1
    • VMX root模式下不可清除CR4.VMXE
  2. BIOS控制

    • MSR.bit 0 lock:清除会导致常规保护异常
    • bit 1:SMX中启用VMXON
    • bit 2:SMX外启用VMXON

5. VMCS虚拟化控制结构

5.1 VMCS基本概念

  • 作用:控制VMX non-root操作和VMX转换
  • 特点
    • 每个VM可拥有不同VMCS
    • 指针必须4KB对齐
    • 包含Guest和Host状态信息

5.2 VMCS生命周期

  1. 创建:通过KVM_CREATE_VCPU ioctl申请vmcs_page
  2. 初始化:使用vmclear指令初始化Guest-vmcs区域
  3. 加载:使用vmptrld指令加载working-VMCS

5.3 VMCS区域详解

5.3.1 Guest-State区域

// 控制寄存器
vmcs_writel(GUEST_CR3, 0);

// 调试寄存器
vmcs_writel(GUEST_DR7, 0x400);

// 通用寄存器
vmcs_writel(GUEST_RFLAGS, 0x02);
vmcs_writel(GUEST_RIP, 0xfff0);
vmcs_writel(GUEST_RSP, 0);

// 段寄存器
vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
vmcs_writel(GUEST_CS_BASE, 0x000f0000);
vmcs_write32(GUEST_CS_LIMIT, 0xffff);
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);

// 段描述符
vmcs_write16(GUEST_TR_SELECTOR, 0);
vmcs_writel(GUEST_TR_BASE, 0);
vmcs_write32(GUEST_TR_LIMIT, 0xffff);
vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);

5.3.2 Host-State区域

vmcs_writel(HOST_CR0, read_cr0());
vmcs_writel(HOST_CR4, read_cr4());
vmcs_writel(HOST_CR3, read_cr3());
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS);
vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS);
vmcs_writel(HOST_RIP, (unsigned long)kvm_vmx_return);

5.4 VM-Execution控制字段

5.4.1 Pin-Based控制

vmcs_write32_fixedbits(MSR_IA32_VMX_PINBASED_CTLS_MSR, 
    PIN_BASED_VM_EXEC_CONTROL, 
    PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING);

5.4.2 Processor-Based控制

vmcs_write32_fixedbits(MSR_IA32_VMX_PROCBASED_CTLS_MSR,
    CPU_BASED_VM_EXEC_CONTROL,
    CPU_BASED_HLT_EXITING |
    CPU_BASED_CR8_LOAD_EXITING |
    CPU_BASED_CR8_STORE_EXITING |
    CPU_BASED_UNCOND_IO_EXITING |
    CPU_BASED_INVDPG_EXITING |
    CPU_BASED_MOV_DR_EXITING |
    CPU_BASED_USE_TSC_OFFSETING);

5.4.3 其他控制字段

// 异常位图
vmcs_write32(EXCEPTION_BITMAP, 1 << PF_VECTOR);

// I/O位图
vmcs_write64(IO_BITMAP_A, 0);
vmcs_write64(IO_BITMAP_B, 0);

// TSC偏移
rdtscll(tsc);
vmcs_write64(TSC_OFFSET, -tsc);

// CR0/CR4掩码
vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);

6. VM Entry/Exit控制

6.1 VM-Exit控制

vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS_MSR, 
    VM_EXIT_CONTROLS, 
    (HOST_IS_64 << 9));

6.2 VM-Entry控制

vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS_MSR,
    VM_ENTRY_CONTROLS, 0);
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);

7. 常见问题与解决方案

7.1 VM Entry失败问题

  • 错误代码:0x80000022 (MSR loading失败)
  • 解决方案
    • 检查IA32_VMX_ENTRY_CTLS(0x484)寄存器
    • 确保VM_ENTRY_CONTROLS正确设置

7.2 编译问题

  • IS_ENABLED宏错误:Linux 3.1后引入,旧内核需手动解决
  • GCC版本问题
    yum -y install compat-gcc-*
    yum -y install SDL-devel
    

8. 推荐书籍

  1. 《NewBluePill深入理解硬件虚拟机》
  2. 《QEMU/KVM源码解析应用》

9. 总结

KVM虚拟化技术核心在于:

  1. 通过VMX指令集实现硬件虚拟化
  2. 使用VMCS结构保存Guest/Host状态
  3. 精细控制VM Entry/Exit行为
  4. 完善的异常和中断处理机制

掌握这些核心原理后,可以进一步深入KVM内存虚拟化、设备虚拟化等高级主题。

KVM虚拟化技术深入解析:从原理到实践 1. KVM环境搭建与初始化 1.1 环境准备 系统环境 :CentOS 6 (2.6.32-754.35.1.el6.x86_ 64) QEMU版本 :0.12.1 (qemu-kvm-0.12.1.2-2.506.el6_ 10.8) 1.2 依赖安装 1.3 QEMU-KVM编译与安装 配置编译环境: 编译后重要可执行文件: x86_64-softmmu/qemu-system-x86_64 qemu-io qemu-nbd qemu-img 安装选项: 拷贝到 /usr/bin 创建软链接 使用 make install (推荐) 1.4 常见编译问题解决 版本不匹配时可能需要修改gcc选项或源码 复杂依赖环境可先yum安装qemu-kvm lib,然后卸载rmmod kvm/kvm-intel 2. QEMU-KVM虚拟机创建 2.1 创建虚拟机镜像 2.2 启动虚拟机 2.3 BIOS文件问题解决 查找bios.bin: 拷贝到正确位置: 修改源码调试路径(vl.c): 3. KVM初始化流程分析 3.1 KVM初始化入口 3.2 KVM模块加载 4. VMX技术深入解析 4.1 VMX检测流程 使用CPUID检测VMX支持: BIOS设置检测: 4.2 VMXON操作 设置CR4.VMXE位: 执行VMXON指令: 4.3 VMX关键点总结 检测流程 : 检测CPUID是否支持VMX 设置CR4.VMXE[ bit 13 ] = 1 VMX root模式下不可清除CR4.VMXE BIOS控制 : MSR.bit 0 lock:清除会导致常规保护异常 bit 1:SMX中启用VMXON bit 2:SMX外启用VMXON 5. VMCS虚拟化控制结构 5.1 VMCS基本概念 作用 :控制VMX non-root操作和VMX转换 特点 : 每个VM可拥有不同VMCS 指针必须4KB对齐 包含Guest和Host状态信息 5.2 VMCS生命周期 创建 :通过 KVM_CREATE_VCPU ioctl申请vmcs_ page 初始化 :使用 vmclear 指令初始化Guest-vmcs区域 加载 :使用 vmptrld 指令加载working-VMCS 5.3 VMCS区域详解 5.3.1 Guest-State区域 5.3.2 Host-State区域 5.4 VM-Execution控制字段 5.4.1 Pin-Based控制 5.4.2 Processor-Based控制 5.4.3 其他控制字段 6. VM Entry/Exit控制 6.1 VM-Exit控制 6.2 VM-Entry控制 7. 常见问题与解决方案 7.1 VM Entry失败问题 错误代码 :0x80000022 (MSR loading失败) 解决方案 : 检查IA32_ VMX_ ENTRY_ CTLS(0x484)寄存器 确保VM_ ENTRY_ CONTROLS正确设置 7.2 编译问题 IS_ ENABLED宏错误 :Linux 3.1后引入,旧内核需手动解决 GCC版本问题 : 8. 推荐书籍 《NewBluePill深入理解硬件虚拟机》 《QEMU/KVM源码解析应用》 9. 总结 KVM虚拟化技术核心在于: 通过VMX指令集实现硬件虚拟化 使用VMCS结构保存Guest/Host状态 精细控制VM Entry/Exit行为 完善的异常和中断处理机制 掌握这些核心原理后,可以进一步深入KVM内存虚拟化、设备虚拟化等高级主题。