kvm代码架构简单分析
kvm代码结构简析(2011-03-30 16:57:28)http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif转载▼标签:杂谈
以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_vcpuKVM_SET_USER_MEMORY_REGION: kvm_vm_ioctl_set_memory_regionKVM_GET_DIRTY_LOG: kvm_vm_ioctl_get_dirty_logKVM_REGISTER_COALESCED_MMIO: kvm_vm_ioctl_register_coalesced_mmioKVM_UNREGISTER_COALESCED_MMIO: kvm_vm_ioctl_unregister_coalesced_mmioKVM_IRQFD: kvm_irqfdKVM_IOEVENTFD: kvm_ioeventfdKVM_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_initkvm_arch_vcpu_setup--kvmppc_core_vcpu_setup--kvmppc_e500_tlb_setupcreate_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_runKVM_GET_REGS: kvm_arch_vcpu_ioctl_get_regsKVM_SET_REGS: kvm_arch_vcpu_ioctl_set_regsKVM_GET_SREGS: kvm_arch_vcpu_ioctl_get_sregsKVM_SET_SREGS: kvm_arch_vcpu_ioctl_set_sregsKVM_GET_MP_STATE: kvm_arch_vcpu_ioctl_get_mpstateKVM_SET_MP_STATE: kvm_arch_vcpu_ioctl_set_mpstateKVM_TRANSLATE: kvm_arch_vcpu_ioctl_translateKVM_SET_GUEST_DEBUG: kvm_arch_vcpu_ioctl_set_guest_debugKVM_SET_SIGNAL_MASK: kvm_vcpu_ioctl_set_sigmaskKVM_GET_FPU: kvm_arch_vcpu_ioctl_get_fpuKVM_SET_FPU: kvm_arch_vcpu_ioctl_set_fpu(ppc s390结构下)KVM_S390_INTERRUPT:KVM_INTERRUPTdefault: kvm_arch_vcpu_ioctl
其中:kvm_arch_vcpu_ioctl_run -----__kvmppc_vcpu_runkvm_arch_vcpu_ioctl | |KVM_INTERRUPT: kvm_vcpu_ioctl_interruptKVM_ENABLE_CAP: kvm_vcpu_ioctl_enable_cap
2.kvm_irqfd | | |kvm_irqfd_assign
3kvm_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 =mfspr(SPRN_IVOR32);151 ivor =mfspr(SPRN_IVOR33);152 ivor =mfspr(SPRN_IVOR34);153 for (i = 0; i< 3; i++) {154 if (ivor > max_ivor)155 max_ivor =ivor;156157 memcpy((void *)kvmppc_booke_handlers +ivor,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 =mfspr(SPRN_IVOR0);591 ivor =mfspr(SPRN_IVOR1);592 ivor =mfspr(SPRN_IVOR2);593 ivor =mfspr(SPRN_IVOR3);594 ivor =mfspr(SPRN_IVOR4);595 ivor =mfspr(SPRN_IVOR5);596 ivor =mfspr(SPRN_IVOR6);597 ivor =mfspr(SPRN_IVOR7);598 ivor =mfspr(SPRN_IVOR8);599 ivor =mfspr(SPRN_IVOR9);600 ivor =mfspr(SPRN_IVOR10);601 ivor =mfspr(SPRN_IVOR11);602 ivor =mfspr(SPRN_IVOR12);603 ivor =mfspr(SPRN_IVOR13);604 ivor =mfspr(SPRN_IVOR14);605 ivor =mfspr(SPRN_IVOR15);606607 for (i = 0; i< 16; i++) {608 if (ivor > max_ivor)609 max_ivor =ivor;610611 memcpy((void *)kvmppc_booke_handlers +ivor,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执行状态
页:
[1]