1:
关于irqfd
+#ifdef KVM_CAP_IRQFD +static int _kvm_irqfd(kvm_context_t kvm, int fd, int gsi, int flags) +{ + int r; + struct kvm_irqfd data = { + .fd = fd, + .gsi = gsi, + .flags = flags, + }; + + r = ioctl(kvm->vm_fd, KVM_IRQFD, &data); + if (r == -1) + r = -errno; + return r; +} + +int kvm_create_irqfd(kvm_context_t kvm, int gsi, int flags) +{ + int r; + int fd; + + if (!kvm_check_extension(kvm, KVM_CAP_IRQFD)) + return -ENOENT; + + fd = eventfd(0, 0); + if (fd < 0) + return -errno; + + r = _kvm_irqfd(kvm, fd, gsi, 0); + if (r < 0) { + close(fd); + return -errno; + } + + return fd; +} + +int kvm_destroy_irqfd(kvm_context_t kvm, int fd, int gsi, int flags) +{ + return _kvm_irqfd(kvm, fd, gsi, KVM_IRQFD_FLAG_DEASSIGN); +} + +#else /* KVM_CAP_IRQFD */ + +int kvm_create_irqfd(kvm_context_t kvm, int gsi, int flags) +{ + return -ENOENT; +} + +int kvm_destroy_irqfd(kvm_context_t kvm, int fd, int gsi, int flags) +{ + return -ENOENT; +} + +#endif /* KVM_CAP_IRQFD */
+int kvm_assign_iofd(kvm_context_t kvm, unsigned long addr, size_t len, + int fd, int type, int flags) +{ + int r; + struct kvm_iofd data = { + .addr = addr, + .len = len, + .fd = fd, + .flags = type ? KVM_IOFD_FLAG_PIO : 0, + }; + + if (!kvm_check_extension(kvm, KVM_CAP_EVENTFD)) + return -ENOENT; + + r = ioctl(kvm->vm_fd, KVM_IOFD, &data); + if (r == -1) + r = -errno; + return r; +} + +int kvm_deassign_iofd(kvm_context_t kvm, unsigned long addr, size_t len, + int type, int flags) +{ + int r; + struct kvm_iofd data = { + .addr = addr, + .len = len, + .flags = KVM_IOFD_FLAG_DEASSIGN | (type ? KVM_IOFD_FLAG_PIO : 0), + }; + + if (!kvm_check_extension(kvm, KVM_CAP_EVENTFD)) + return -ENOENT; + + r = ioctl(kvm->vm_fd, KVM_IOFD, &data); + if (r == -1) + r = -errno; + return r; +} + #else /* KVM_CAP_EVENTFD */