ret = kvm_vm_ioctl(s, s->irq_set_ioctl, &event);将irq_set_ioctl和具体IRQ信息写入vmfd。 if (ret < 0) { perror("kvm_set_irq"); abort(); } return (s->irq_set_ioctl == KVM_IRQ_LINE) ? 1 : event.status; } 上面的ioctl对应内核中的kvm_vm_ioctl,内核首先case到KVM_IRQ_LINE。...
long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { case KVM_IRQ_LINE_STATUS: case KVM_IRQ_LINE: { struct kvm_irq_level irq_event; r = -EFAULT; if (copy_from_user(&irq_event, argp, sizeof irq_event)) goto out; if (irqchip_in_kernel(kvm)) { ...
case KVM_IRQ_LINE: { r = kvm_vm_ioctl_irq_line(kvm, &irq_event, ioctl == KVM_IRQ_LINE_STATUS); break; } #endif #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_SET_GSI_ROUTING: { r = kvm_set_irq_routing(kvm, entries, routing.nr, routing.flags); } #endif /* CONFIG_HAVE_KVM_I...
gsi是该entry对应的gsi号,一般和IRQ是一样,set方法是该IRQ关联的触发方法,通过该方法把IRQ传递给IO-APIC,;link就是连接点,连接在上面同一IRQ对应的map上; 中断注入在KVM内部流程起始于一个函数kvm_set_irq int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, bool line_status) ...
ioctl==KVM_IRQ_LINE_STATUS);if(r)gotoout; r= -EFAULT;if(ioctl ==KVM_IRQ_LINE_STATUS) {if(copy_to_user(argp, &irq_event,sizeof(irq_event)))gotoout; } r=0;break; }#endif#ifdef CONFIG_HAVE_KVM_IRQ_ROUTINGcaseKVM_SET_GSI_ROUTING: {structkvm_irq_routing routing;structkvm_irq_rout...
kvmtool根据IO地址获知是驱动通知设备处理请求, 因此调用设备处理函数完成请求 之后kvmtool会调用kvm__irq_line()向Guest发送一个中断, 通知驱动设备已经完成请求. 这个中断号保存在设备的PCI header中的interrupt_line字段中. 这里会再次进入Host的内核态, 然后切入虚拟机中 ...
#define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level) #define KVM_REGISTER_COALESCED_MMIO \ _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) #define KVM_UNREGISTER_COALESCED_MMIO \ _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone) ...
监听线程被唤醒后,完成virtio queue中的任务,并通过kvm__irq_line()向Guest注入中断,通知Guest处理完毕。这一过程在KVM的ioevent实现中展现得尤为清晰。轻量虚拟机退出的实现细节 针对轻量虚拟机退出,KVM模块提供ioctl(vm_fd, KVM_IOEVENTFD, &kvm_ioevent) API,将ioeventfd挂载到Guest内部的pmio...
return (s->irq_set_ioctl == KVM_IRQ_LINE) ? 1 : event.status; } #ifdef KVM_CAP_IRQ_ROUTING typedef struct KVMMSIRoute { struct kvm_irq_routing_entry kroute; QTAILQ_ENTRY(KVMMSIRoute) entry; } KVMMSIRoute; static void set_gsi(KVMState *s, unsigned int gsi) { s-...
@@ -49,6 +58,10 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, boolline_status) { structkvm_ioapic*ioapic=kvm->arch.vioapic; if(!ioapic) return-1; returnkvm_ioapic_set_irq(ioapic,e->irqchip.pin,irq_source_id,level, ...