Local APIC 创建
用户态
x86_cpu_realizefn
–>x86_cpu_apic_create
(–>kvm-apic)
–>kvm_apic_realize
内核态
irqchip_in_kernel是在创建vcpu的时候创建了一个local apic
vmx_create_vcpu
–> kvm_vcpu_init
–>kvm_arch_vcpu_init
–>kvm_create_lapic
其中hrtimer_init是创建了一个时钟定时器,用来实现时钟的模拟
因为APIC Timer设备实际就是lapic的一个功能,所以在创建lapic设备同时创建了。
Local APIC访问导致的vm-exit
设置apic_base
host 的cpu和guest vcpu共享apic_base
vm-entry时需要重新恢复guest的apic_base的值
用户态
qemu_system_reset
–>cpu_synchronize_all_post_reset
–>cpu_synchronize_post_reset
–>kvm_cpu_synchronize_post_reset
–>do_kvm_cpu_synchronize_post_reset
–>kvm_arch_put_registers
–>kvm_put_apic
–>kvm_put_apic_state(apic,&kapic);
–>kvm_vcpu_ioctl(env, KVM_SET_LAPIC,&kapic);
内核态
kvm_arch_vcpu_ioctl case KVM_SET_LAPIC
–>kvm_vcpu_ioctl_set_lapic
–>kvm_apic_set_state
VM-Exit
读写apic-access page越界或跨寄存器边界时会产生vm-exit;
guest 以pha访问时直接发生vm-exit;
写入local apic version, isr, tmr, irr等寄存器时,此时发生apic-access vm-exit
kvm_x86_ops->handle_exit
–>vmx_handle_exit
–>kvm_vmx_exit_handlersexit_reason
–>handle_apic_access
–>emulate_instruction
…
–>kvm_lapic_reg_write
–>kvm_apic_set_xapic_id
–>kvm_lapic_set_reg
几组寄存器
EOI寄存器
任务优先级寄存器(TPR)
处理器优先级寄存器(PPR)
中断命令寄存器(ICR,64位)
中断请求寄存器(IRR,256位,对应每个向量一位)
中断在服务寄存器(ISR,256位)
虚拟中断delivery
kvm_irq_delivery_to_apic
–>kvm_irq_delivery_to_apic_fast(对于SELF-IPI立即调用kvm_apic_set_irq(src->vcpu,irq, dest_map);而不需要搜素了。否则则遍历vcpu, 接着判断virtual interrupt是否允许,允许条件如下: RVI[7:4] > VPPR[7:4])
–>kvm_apic_set_irq
–>__apic_accept_irq
IOAPIC 虚拟化
创建
kvm_arch_vm_ioctl
–>case KVM_CREATE_IRQCHIP
kvm_ioapic_init
set_irq
kvm_ioapic_set_irq
–>ioapic_set_irq
–>ioapic_service
–>kvm_irq_delivery_to_apic