Oenhan KVM note

Part2 VM RUN

http://www.oenhan.com/kvm-src-2-vm-run

  • ioctl 介面

    • 3 介面

    • kvm: create_vm

    • kvm_vm: create_vcpu, set_user_memory_region, create_device

    • kvm_vcpu: run

  • vl.c 的 main()

  • util/module.c, util/qemu-config.c

  • atexit(), qemu_run_exit_notifier

  • kvm_init() (by type_init() + module_call_init(), read module init mechanism for detail )

  • cpu_exec_init_all()

  • cpudef_init()

  • qemu_set_log()

  • reads ./qemu_system_init.rst for machine init(e.g. pc_init1()) and device init

module init mechanism

  • module_call_init()

    • type: BLOCK, MACHINE, QAPI, QOM. (current / QEMU 2.7) MACHINE 換成 OPT 了.

    • function linked list: ModuleTypeList, image

    • foreach ModuleEntry e in ModuleTypeList: e->init()

  • ModuleTypeList 註冊

    • module_init() 處理註冊, use __attribute__((constructor)) => 在 main 之前執行.

    • block_init(f) => module_init(f, MODULE_INIT_BLOCK), register_module_init(f, MODULE_INIT_BLOCK)

    • DEFINE_I440FX_MACHINE(), DEFINE_PC_MACHINE()

      • pc_init_##suffix(), pc_machine_##suffix##_class_init()

      • pc_machine_init_##suffix()

      • pc_init1(machine)

      • type_register(&pc_machine_type_##suffix)

      • machine_init(pc_machine_init_##suffix)

  • ModuleEntry

    • 3 member: init(), next pointer, module_init_type

  • example

    • module_call_init(MODULE_INIT_QOM);

    • module_call_init(MODULE_INIT_OPTS);

    • type_init(kvm_type_init)-> kvm_accel_type -> kvm_accel_class_init -> kvm_init

  • module_init(MODULE_INIT_MACHINE) 是讓 mc->init = pc_init1. 然後當 machine_class = find_default_machine() 時, machine_class 的 init 就會執行 pc_init1()

pc_init1()

pc_cpus_init()

  • cpu_model: builtin_x86_defs

    • “SandyBridge”, x86 CPUID flags … etc.

  • for loop: pc_new_cpu() => cpu_x86_create()

    • fill in CPUX86State

  • x86_cpu_realizefn() => qemu_init_vcpu() => qemu_kvm_start_vcpu():

    //创建VPU对于的qemu线程,线程函数是qemu_kvm_cpu_thread_fn
    qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn,
                       cpu, QEMU_THREAD_JOINABLE);
    
    //如果线程没有创建成功,则一直在此处循环阻塞。说明多核vcpu的创建是顺序的
    while (!cpu->created) {
        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
    }
    
  • qemu_kvm_cpu_thread_fn(): 真正的 cpu thread 函數.

    • kvm_init_vcpu()

      • KVM_CREATE_VCPU

      • KVM_GET_VCPU_MMAP_SIZE get memory mapping of env->kvm_run.

      • kvm_arch_init_vcpu()

    • qemu_kvm_init_cpu_signals(): KVM_SET_SIGNAL_MASK

    • qemu_cond_signal(&qemu_cpu_cond) => kvm_cpu_exec(env) in while loop

    • kvm_cpu_exec(): KVM_RUN

  • sources

    • hw/i386/pc.c: pc_cpus_init(), pc_new_cpu()

    • target-i386/cpu.c: x86_cpu_realizefn()

      • (register and invoke) TypeInfo x86_cpu_type_info => x86_cpu_common_class_init() => x86_cpu_realizefn()

      • qom or qobject model

      • target-i386/cpu-qom.h: X86_CPU()

        • include/qom/object.h: OBJECT_CHECK()

    • cpus.c: qemu_init_vcpu(), qemu_kvm_start_vcpu(), qemu_kvm_cpu_thread_fn()

pc_memory_init()

Part3 CPU Virtualization

http://www.oenhan.com/kvm-src-3-cpu

  • cpu virtualization: time-sharing

    • restore state (for context switch): VMCS, VMExit reason … etc

    • resource isolation: VMX root mode

  • VMCS register

    • VM-execution controls: Determines what operations cause VM exits

    • Guest-state and Host-state area: Guest/Host OS state for context switch (save & restore)

    • VM-exit controls: Example: MSR save-load list

    • VM-entry controls: Including injecting events (interrupts, exceptions) on entry