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
, imageforeach
ModuleEntry
e inModuleTypeList
: 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