kvm代码架构简单分析

kvm代码结构简析

(2011-03-30 16:57:28)
转载
标签:

杂谈

 
以booke500为例:

初始化;
kvmppc_e500_init===============================arch/powerpc/kvm/e500.c
    |         \
    |           \
    |           \
kvm_init     kvmppc_booke_init
    |
    |
    |
kvm_arch_init, kvm_arch_hardware_setup, register(kvm_dev)
    |
    |
    |
  kvm_sched_in   ---------------- kvm_arch_vcpu_load
  kvm_sched_out  ---------------- kvm_arch_vcpu_put


  其中register kvm_dev中提供了一ioctl操作函数:
  kvm_dev_ioctl
      |      \
      |      kvm_arch_dev_ioctl 其他对/dev/kvm的操作
  kvm_dev_ioctl_create_vm生成vm文件句柄,可以通过此句柄对vm进行操作
      |
      |
kvm_create_vm , anon_inode_getfd("kvm-vm",&kvm_vm_fops, kvm, O_RDWR)
其中anon_inode_getfd创建file fd ,其创建的所有file共享一个inode。对vm的操作
实际上就是对此file的操作,因此对其ioctl调用的是kvm_vm_fops中的成员函数:
kvm_vm_ioctl
      |
      |
      |
KVM_CREATE_VCPU:                         kvm_vm_ioctl_create_vcpu
KVM_SET_USER_MEMORY_REGION:             kvm_vm_ioctl_set_memory_region
KVM_GET_DIRTY_LOG:                       kvm_vm_ioctl_get_dirty_log
KVM_REGISTER_COALESCED_MMIO:             kvm_vm_ioctl_register_coalesced_mmio
KVM_UNREGISTER_COALESCED_MMIO:           kvm_vm_ioctl_unregister_coalesced_mmio
KVM_IRQFD:                               kvm_irqfd
KVM_IOEVENTFD:                           kvm_ioeventfd
KVM_SET_BOOT_CPU_ID:
default :                               kvm_arch_vm_ioctl,
                                          kvm_vm_ioctl_assigned_device


以下对其调用的函数关系做分析:
1.
kvm_vm_ioctl_create_vcpu
      |
      |
      |
kvm_arch_vcpu_create--kvmppc_core_vcpu_create--kvm_vcpu_init--kvm_arch_vcpu_init
                                                kvmppc_e500_tlb_init
kvm_arch_vcpu_setup--kvmppc_core_vcpu_setup--kvmppc_e500_tlb_setup
create_vcpu_fd ---anon_inode_getfd("kvm-vcpu",&kvm_vcpu_fops, vcpu, O_RDWR)
其中create_vcpu_fd生成对vcpu操作的文件fd,其ioctl调用的是kvm_vcpu_fops中的
kvm_vcpu_ioctl
      |
      |
      |
KVM_RUN:                                 kvm_arch_vcpu_ioctl_run
KVM_GET_REGS:                           kvm_arch_vcpu_ioctl_get_regs
KVM_SET_REGS:                           kvm_arch_vcpu_ioctl_set_regs
KVM_GET_SREGS:                           kvm_arch_vcpu_ioctl_get_sregs
KVM_SET_SREGS:                           kvm_arch_vcpu_ioctl_set_sregs
KVM_GET_MP_STATE:                       kvm_arch_vcpu_ioctl_get_mpstate
KVM_SET_MP_STATE:                       kvm_arch_vcpu_ioctl_set_mpstate
KVM_TRANSLATE:                           kvm_arch_vcpu_ioctl_translate
KVM_SET_GUEST_DEBUG:                     kvm_arch_vcpu_ioctl_set_guest_debug
KVM_SET_SIGNAL_MASK:                     kvm_vcpu_ioctl_set_sigmask
KVM_GET_FPU:                             kvm_arch_vcpu_ioctl_get_fpu
KVM_SET_FPU:                             kvm_arch_vcpu_ioctl_set_fpu
(ppc s390结构下)
KVM_S390_INTERRUPT:
KVM_INTERRUPT
default:                                 kvm_arch_vcpu_ioctl

其中:
kvm_arch_vcpu_ioctl_run -----__kvmppc_vcpu_run
kvm_arch_vcpu_ioctl
      |
      |
KVM_INTERRUPT:                           kvm_vcpu_ioctl_interrupt
KVM_ENABLE_CAP:                         kvm_vcpu_ioctl_enable_cap


2.
kvm_irqfd
      |
      |
      |
kvm_irqfd_assign

3
kvm_ioeventfd
      |
      |
      |
kvm_assign_ioeventfd



======================================
二、中断处理过程
以e500为例,powerpc专门分配了页用来存储中断处理入口地址
入口地址为变量kvmppc_booke_handlers

在arch/powerpc/kvm/booke_interrupt.S中定义了一些列中断处理代码:
  72 _GLOBAL(kvmppc_handlers_start)
  73 KVM_HANDLERBOOKE_INTERRUPT_CRITICAL
  74 KVM_HANDLERBOOKE_INTERRUPT_MACHINE_CHECK
  75 KVM_HANDLERBOOKE_INTERRUPT_DATA_STORAGE
  76 KVM_HANDLERBOOKE_INTERRUPT_INST_STORAGE
  77 KVM_HANDLERBOOKE_INTERRUPT_EXTERNAL
  78 KVM_HANDLERBOOKE_INTERRUPT_ALIGNMENT
  79 KVM_HANDLER BOOKE_INTERRUPT_PROGRAM
  80 KVM_HANDLERBOOKE_INTERRUPT_FP_UNAVAIL
  81 KVM_HANDLER BOOKE_INTERRUPT_SYSCALL
  82 KVM_HANDLERBOOKE_INTERRUPT_AP_UNAVAIL
  83 KVM_HANDLERBOOKE_INTERRUPT_DECREMENTER
  84 KVM_HANDLER BOOKE_INTERRUPT_FIT
  85 KVM_HANDLERBOOKE_INTERRUPT_WATCHDOG
  86 KVM_HANDLERBOOKE_INTERRUPT_DTLB_MISS
  87 KVM_HANDLERBOOKE_INTERRUPT_ITLB_MISS
  88 KVM_HANDLER BOOKE_INTERRUPT_DEBUG
  89 KVM_HANDLERBOOKE_INTERRUPT_SPE_UNAVAIL
  90 KVM_HANDLERBOOKE_INTERRUPT_SPE_FP_DATA
  91 KVM_HANDLERBOOKE_INTERRUPT_SPE_FP_ROUND
  92
  93 _GLOBAL(kvmppc_handler_len)
  94     .long kvmppc_handler_1 - kvmppc_handler_0

在kvm初始化时将kvmppc_handlers_start内容拷贝到kvmppc_booke_handlers中,例如
rch/powerpc/kvm/e500.c的kvmppc_e500_init中
149    
150     ivor[0] =mfspr(SPRN_IVOR32);
151     ivor[1] =mfspr(SPRN_IVOR33);
152     ivor[2] =mfspr(SPRN_IVOR34);
153     for (i = 0; i< 3; i++) {
154         if (ivor[i] > max_ivor)
155             max_ivor =ivor[i];
156
157         memcpy((void *)kvmppc_booke_handlers +ivor[i],
158                 kvmppc_handlers_start + (i +16) * kvmppc_handler_len,
159                 kvmppc_handler_len);
160     }

和arch/powerpc/kvm/booke.c的kvmppc_booke_init函数:
588    
590     ivor[0] =mfspr(SPRN_IVOR0);
591     ivor[1] =mfspr(SPRN_IVOR1);
592     ivor[2] =mfspr(SPRN_IVOR2);
593     ivor[3] =mfspr(SPRN_IVOR3);
594     ivor[4] =mfspr(SPRN_IVOR4);
595     ivor[5] =mfspr(SPRN_IVOR5);
596     ivor[6] =mfspr(SPRN_IVOR6);
597     ivor[7] =mfspr(SPRN_IVOR7);
598     ivor[8] =mfspr(SPRN_IVOR8);
599     ivor[9] =mfspr(SPRN_IVOR9);
600     ivor[10] =mfspr(SPRN_IVOR10);
601     ivor[11] =mfspr(SPRN_IVOR11);
602     ivor[12] =mfspr(SPRN_IVOR12);
603     ivor[13] =mfspr(SPRN_IVOR13);
604     ivor[14] =mfspr(SPRN_IVOR14);
605     ivor[15] =mfspr(SPRN_IVOR15);
606
607     for (i = 0; i< 16; i++) {
608         if (ivor[i] > max_ivor)
609             max_ivor =ivor[i];
610
611         memcpy((void *)kvmppc_booke_handlers +ivor[i],
612                 kvmppc_handlers_start + i *kvmppc_handler_len,
613                 kvmppc_handler_len);
614     }

这两个地方将kvmppc_handlers_start代码拷贝到kvmppc_booke_handlers中
kvmppc_booke_handlers 在__kvmppc_vcpu_run中告知cpu
__kvmppc_vcpu_run使得cpu进入guest执行状态



你可能感兴趣的:(kvm代码架构简单分析)