qemu-kvmから追う仮想マシンの一生
前回はLinux KVMのソースコードを読んできましたが、
qemu-kvmは、
qemu-kvmの入手先
qemu-kvmの開発プロジェクトによる一次成果物は、
- kernel virtual machine - SourceForge.
net  - URL:http://
sourceforge. net/ projects/ kvm/  
本記事は、
qemu-kvmの一生 = 仮想マシンの一生
qemu-kvmは、
qemu-kvmプロセスは、
149 int kvm_init(void)
150 {
151     int fd;
152     int r, gsi_count;
153
154
155     fd = open("/dev/kvm", O_RDWR);
156     if (fd == -1) {
157         perror("open /dev/kvm");
158         return -1;
159     }
  《中略》 
211     return kvm_create_context();
212
213   out_close:
214     close(fd);
215     return -1;
216 }
kvm_
308 int kvm_create_vm(kvm_context_t kvm)
309 {
310     int fd;
311 #ifdef KVM_CAP_IRQ_ROUTING
312     kvm->irq_routes = qemu_mallocz(sizeof(*kvm->irq_routes));
313     kvm->nr_allocated_irq_routes = 0;
314 #endif
315
316     fd = kvm_ioctl(kvm_state, KVM_CREATE_VM, 0);
317     if (fd < 0) {
318         fprintf(stderr, "kvm_create_vm: %m\n");
319         return -1;
320     }
321     kvm_state->vmfd = fd;
322     return 0;
323 }
この後、
qemu-kvmのスレッドモデル
以下に、
qemu-kvmは、
仮想プロセッサの生成
仮想プロセッサの初期化処理は、
942 void pc_cpus_init(const char *cpu_model)
943 {
944     int i;
945
946     /* init CPUs */
947     for(i = 0; i < smp_cpus; i++) {
948         pc_new_cpu(cpu_model);
949     }
950 }
pc_
265 void qemu_init_vcpu(void *_env)
266 {
267     CPUState *env = _env;
268
269     env->nr_cores = smp_cores;
270     env->nr_threads = smp_threads;
271     if (kvm_enabled())
272         kvm_init_vcpu(env);
273     return;
274 }
kvm_
1470 int kvm_init_vcpu(CPUState *env)
1471 {
1472     pthread_create(&env->kvm_cpu_state.thread, NULL, ap_main_loop, env);
1473
1474     while (env->created == 0) {
1475         qemu_cond_wait(&qemu_vcpu_cond);
1476     }
1477
1478     return 0;
1479 }
上記の過程により、
仮想プロセッサの起動
各スレッドは、
1505 static void *ap_main_loop(void *_env)
1506 {
1507     CPUState *env = _env;
  《中略》 
1527     kvm_create_vcpu(env, env->cpu_index);
  《中略》 
1533
1534     /* and wait for machine initialization */
1535     while (!qemu_system_ready)
1536         qemu_cond_wait(&qemu_system_cond);
1537
1538     /* re-initialize cpu_single_env after re-acquiring qemu_mutex */
1539     cpu_single_env = env;
1540
1541     kvm_main_loop_cpu(env);
1542     return NULL;
1543 }
仮想プロセッサのメインループ
kvm_
1486 static int kvm_main_loop_cpu(CPUState *env)
1487 {
1488     while (1) {
1489         int run_cpu = !kvm_cpu_is_stopped(env);
1490         if (run_cpu && !kvm_irqchip_in_kernel()) {
1491             process_irqchip_events(env);
1492             run_cpu = !env->halted;
1493         }
1494         if (run_cpu) {
1495             kvm_cpu_exec(env);
1496             kvm_main_loop_wait(env, 0);
1497         } else {
1498             kvm_main_loop_wait(env, 1000);
1499         }
1500     }
1501     pthread_mutex_unlock(&qemu_mutex);
1502     return 0;
1503 }
kvm_
KVM_EXIT_*発生後のイベントディスパッチ 
仮想プロセッサを実行してしばらくすると、何らかの理由により仮想プロセッサが停止し、Linux KVMからqemu-kvmに制御が戻ることになります。たとえば、仮想マシン上でデバイスI/Oが発生してLinux KVMがハードウェアエミュレーションの処理をしなければならない場合、一定時間仮想マシンの実行をしたため別の仮想マシンやプロセスへ切り替えする場合などです。
Linux KVMのカーネルモジュール内にはVMEXIT発生時のイベントハンドラが含まれていました。基本的に、
仮想マシン上でデバイスI/
kvm_
912 int kvm_cpu_exec(CPUState *env)
913 {
  《中略》 
941         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
  《中略》 
961         switch (run->exit_reason) {
962         case KVM_EXIT_IO:
963             DPRINTF("handle_io\n");
964             ret = kvm_handle_io(run->io.port,
965                                 (uint8_t *)run + run->io.data_offset,
966                                 run->io.direction,
967                                 run->io.size,
968                                 run->io.count);
969             break;
970         case KVM_EXIT_MMIO:
971             DPRINTF("handle_mmio\n");
972             cpu_physical_memory_rw(run->mmio.phys_addr,
973                                    run->mmio.data,
974                                    run->mmio.len,
975                                    run->mmio.is_write);
976             ret = 1;
977             break;
978         case KVM_EXIT_IRQ_WINDOW_OPEN:
  《中略》 
1002             }
  《中略》 
1012     } while (ret > 0);
  《中略》 
1025 }
この先でどのような処理が行われているかは、
プロセッサ仮想化のまとめ
第4回では、
そのような状況の中で、
現在x86システムの世界で使われているx86システム仮想マシンは、
今回をもって、 これまで、次回予告
