|
1:
1003 int pci_enable_capability_support(PCIDevice *pci_dev,
1004 uint32_t config_start,
1005 PCICapConfigReadFunc *config_read,
1006 PCICapConfigWriteFunc *config_write,
1007 PCICapConfigInitFunc *config_init)
1008 {
1009 if (!pci_dev)
1010 return -ENODEV;
1011
1012 pci_dev->config[0x06] |= 0x10; // status = capabilities
1013
1014 if (config_start == 0)
1015 pci_dev->cap.start = PCI_CAPABILITY_CONFIG_DEFAULT_START_ADDR;
1016 else if (config_start >= 0x40 && config_start < 0xff)
1017 pci_dev->cap.start = config_start;
1018 else
1019 return -EINVAL;
1020
1021 if (config_read)
1022 pci_dev->cap.config_read = config_read;
1023 else
1024 pci_dev->cap.config_read = pci_default_cap_read_config;
1025 if (config_write)
1026 pci_dev->cap.config_write = config_write;
1027 else
1028 pci_dev->cap.config_write = pci_default_cap_write_config;
1029 pci_dev->cap.supported = 1;
1030 pci_dev->config[PCI_CAPABILITY_LIST] = pci_dev->cap.start;
1031 return config_init(pci_dev);
1032 }
关于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 */
版权声明:本文为博主原创文章,未经博主允许不得转载。 |
|