Lines Matching +full:msi +full:- +full:parent
1 // SPDX-License-Identifier: GPL-2.0
15 #include <linux/msi.h>
23 * struct msi_ctrl - MSI internal management control structure
28 * than the range due to PCI/multi-MSI.
38 #define MSI_XA_MAX_INDEX (ULONG_MAX - 1)
48 * msi_alloc_desc - Allocate an initialized msi_desc
66 desc->dev = dev; in msi_alloc_desc()
67 desc->nvec_used = nvec; in msi_alloc_desc()
69 desc->affinity = kmemdup(affinity, nvec * sizeof(*desc->affinity), GFP_KERNEL); in msi_alloc_desc()
70 if (!desc->affinity) { in msi_alloc_desc()
80 kfree(desc->affinity); in msi_free_desc()
87 struct msi_device_data *md = dev->msi.data; in msi_insert_desc()
88 struct xarray *xa = &md->__domains[domid].store; in msi_insert_desc()
95 struct xa_limit limit = { .min = 0, .max = hwsize - 1 }; in msi_insert_desc()
103 desc->msi_index = index; in msi_insert_desc()
107 ret = -ERANGE; in msi_insert_desc()
111 desc->msi_index = index; in msi_insert_desc()
123 * msi_domain_insert_msi_desc - Allocate and initialize a MSI descriptor and
124 * insert it at @init_desc->msi_index
128 * @init_desc: Pointer to an MSI descriptor to initialize the new descriptor
137 lockdep_assert_held(&dev->msi.data->mutex); in msi_domain_insert_msi_desc()
139 desc = msi_alloc_desc(dev, init_desc->nvec_used, init_desc->affinity); in msi_domain_insert_msi_desc()
141 return -ENOMEM; in msi_domain_insert_msi_desc()
144 desc->pci = init_desc->pci; in msi_domain_insert_msi_desc()
146 return msi_insert_desc(dev, desc, domid, init_desc->msi_index); in msi_domain_insert_msi_desc()
155 return !desc->irq; in msi_desc_match()
157 return !!desc->irq; in msi_desc_match()
167 if (WARN_ON_ONCE(ctrl->domid >= MSI_MAX_DEVICE_IRQDOMAINS || in msi_ctrl_valid()
168 (dev->msi.domain && in msi_ctrl_valid()
169 !dev->msi.data->__domains[ctrl->domid].domain))) in msi_ctrl_valid()
172 hwsize = msi_domain_get_hwsize(dev, ctrl->domid); in msi_ctrl_valid()
173 if (WARN_ON_ONCE(ctrl->first > ctrl->last || in msi_ctrl_valid()
174 ctrl->first >= hwsize || in msi_ctrl_valid()
175 ctrl->last >= hwsize)) in msi_ctrl_valid()
186 lockdep_assert_held(&dev->msi.data->mutex); in msi_domain_free_descs()
191 xa = &dev->msi.data->__domains[ctrl->domid].store; in msi_domain_free_descs()
192 xa_for_each_range(xa, idx, desc, ctrl->first, ctrl->last) { in msi_domain_free_descs()
203 * msi_domain_free_msi_descs_range - Free a range of MSI descriptors of a device in an irqdomain
222 * msi_domain_add_simple_msi_descs - Allocate and initialize MSI descriptors
234 lockdep_assert_held(&dev->msi.data->mutex); in msi_domain_add_simple_msi_descs()
237 return -EINVAL; in msi_domain_add_simple_msi_descs()
239 for (idx = ctrl->first; idx <= ctrl->last; idx++) { in msi_domain_add_simple_msi_descs()
243 ret = msi_insert_desc(dev, desc, ctrl->domid, idx); in msi_domain_add_simple_msi_descs()
250 ret = -ENOMEM; in msi_domain_add_simple_msi_descs()
258 *msg = entry->msg; in __get_cached_msi_msg()
276 WARN_ON_ONCE(!xa_empty(&md->__domains[i].store)); in msi_device_data_release()
277 xa_destroy(&md->__domains[i].store); in msi_device_data_release()
279 dev->msi.data = NULL; in msi_device_data_release()
283 * msi_setup_device_data - Setup MSI device data
284 * @dev: Device for which MSI device data should be set up
288 * This can be called more than once for @dev. If the MSI device data is
297 if (dev->msi.data) in msi_setup_device_data()
302 return -ENOMEM; in msi_setup_device_data()
311 xa_init_flags(&md->__domains[i].store, XA_FLAGS_ALLOC); in msi_setup_device_data()
314 * If @dev::msi::domain is set and is a global MSI domain, copy the in msi_setup_device_data()
317 * architecture specific PCI/MSI support working. in msi_setup_device_data()
319 if (dev->msi.domain && !irq_domain_is_msi_parent(dev->msi.domain)) in msi_setup_device_data()
320 md->__domains[MSI_DEFAULT_DOMAIN].domain = dev->msi.domain; in msi_setup_device_data()
322 mutex_init(&md->mutex); in msi_setup_device_data()
323 dev->msi.data = md; in msi_setup_device_data()
329 * msi_lock_descs - Lock the MSI descriptor storage of a device
334 mutex_lock(&dev->msi.data->mutex); in msi_lock_descs()
339 * msi_unlock_descs - Unlock the MSI descriptor storage of a device
345 dev->msi.data->__iter_idx = MSI_XA_MAX_INDEX; in msi_unlock_descs()
346 mutex_unlock(&dev->msi.data->mutex); in msi_unlock_descs()
353 struct xarray *xa = &md->__domains[domid].store; in msi_find_desc()
356 xa_for_each_start(xa, md->__iter_idx, desc, md->__iter_idx) { in msi_find_desc()
360 md->__iter_idx = MSI_XA_MAX_INDEX; in msi_find_desc()
365 * msi_domain_first_desc - Get the first MSI descriptor of an irqdomain associated to a device
370 * Must be called with the MSI descriptor mutex held, i.e. msi_lock_descs()
373 * Return: Pointer to the first MSI descriptor matching the search
379 struct msi_device_data *md = dev->msi.data; in msi_domain_first_desc()
384 lockdep_assert_held(&md->mutex); in msi_domain_first_desc()
386 md->__iter_idx = 0; in msi_domain_first_desc()
392 * msi_next_desc - Get the next MSI descriptor of a device
400 * to be done within the same MSI mutex held region.
402 * Return: Pointer to the next MSI descriptor matching the search
408 struct msi_device_data *md = dev->msi.data; in msi_next_desc()
413 lockdep_assert_held(&md->mutex); in msi_next_desc()
415 if (md->__iter_idx >= (unsigned long)MSI_MAX_INDEX) in msi_next_desc()
418 md->__iter_idx++; in msi_next_desc()
424 * msi_domain_get_virq - Lookup the Linux interrupt number for a MSI index on a interrupt domain
427 * @index: MSI interrupt index to look for (0-based)
438 if (!dev->msi.data) in msi_domain_get_virq()
444 /* This check is only valid for the PCI default MSI domain */ in msi_domain_get_virq()
446 pcimsi = to_pci_dev(dev)->msi_enabled; in msi_domain_get_virq()
449 xa = &dev->msi.data->__domains[domid].store; in msi_domain_get_virq()
451 if (desc && desc->irq) { in msi_domain_get_virq()
453 * PCI-MSI has only one descriptor for multiple interrupts. in msi_domain_get_virq()
454 * PCI-MSIX and platform MSI use a descriptor per in msi_domain_get_virq()
458 if (index < desc->nvec_used) in msi_domain_get_virq()
459 ret = desc->irq + index; in msi_domain_get_virq()
461 ret = desc->irq; in msi_domain_get_virq()
488 /* MSI vs. MSIX is per device not per interrupt */ in msi_mode_show()
489 bool is_msix = dev_is_pci(dev) ? to_pci_dev(dev)->msix_enabled : false; in msi_mode_show()
491 return sysfs_emit(buf, "%s\n", is_msix ? "msix" : "msi"); in msi_mode_show()
496 struct device_attribute *attrs = desc->sysfs_attrs; in msi_sysfs_remove_desc()
502 desc->sysfs_attrs = NULL; in msi_sysfs_remove_desc()
503 for (i = 0; i < desc->nvec_used; i++) { in msi_sysfs_remove_desc()
505 sysfs_remove_file_from_group(&dev->kobj, &attrs[i].attr, msi_irqs_group.name); in msi_sysfs_remove_desc()
516 attrs = kcalloc(desc->nvec_used, sizeof(*attrs), GFP_KERNEL); in msi_sysfs_populate_desc()
518 return -ENOMEM; in msi_sysfs_populate_desc()
520 desc->sysfs_attrs = attrs; in msi_sysfs_populate_desc()
521 for (i = 0; i < desc->nvec_used; i++) { in msi_sysfs_populate_desc()
523 attrs[i].attr.name = kasprintf(GFP_KERNEL, "%d", desc->irq + i); in msi_sysfs_populate_desc()
525 ret = -ENOMEM; in msi_sysfs_populate_desc()
532 ret = sysfs_add_file_to_group(&dev->kobj, &attrs[i].attr, msi_irqs_group.name); in msi_sysfs_populate_desc()
547 * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device
556 if (desc->sysfs_attrs) in msi_device_populate_sysfs()
566 * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
588 lockdep_assert_held(&dev->msi.data->mutex); in msi_get_device_domain()
593 domain = dev->msi.data->__domains[domid].domain; in msi_get_device_domain()
610 info = domain->host_data; in msi_domain_get_hwsize()
611 return info->hwsize; in msi_domain_get_hwsize()
620 data->chip->irq_write_msi_msg(data, msg); in irq_chip_write_msi_msg()
625 struct msi_domain_info *info = domain->host_data; in msi_check_level()
628 * If the MSI provider has messed with the second message and in msi_check_level()
629 * not advertized that it is level-capable, signal the breakage. in msi_check_level()
631 WARN_ON(!((info->flags & MSI_FLAG_LEVEL_CAPABLE) && in msi_check_level()
632 (info->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) && in msi_check_level()
637 * msi_domain_set_affinity - Generic affinity setter function for MSI domains
642 * Intended to be used by MSI interrupt controllers which are
650 struct irq_data *parent = irq_data->parent_data; in msi_domain_set_affinity() local
654 ret = parent->chip->irq_set_affinity(parent, mask, force); in msi_domain_set_affinity()
657 msi_check_level(irq_data->domain, msg); in msi_domain_set_affinity()
670 msi_check_level(irq_data->domain, msg); in msi_domain_activate()
687 struct msi_domain_info *info = domain->host_data; in msi_domain_alloc()
688 struct msi_domain_ops *ops = info->ops; in msi_domain_alloc()
689 irq_hw_number_t hwirq = ops->get_hwirq(info, arg); in msi_domain_alloc()
693 return -EEXIST; in msi_domain_alloc()
695 if (domain->parent) { in msi_domain_alloc()
702 ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg); in msi_domain_alloc()
704 if (ops->msi_free) { in msi_domain_alloc()
705 for (i--; i > 0; i--) in msi_domain_alloc()
706 ops->msi_free(domain, info, virq + i); in msi_domain_alloc()
719 struct msi_domain_info *info = domain->host_data; in msi_domain_free()
722 if (info->ops->msi_free) { in msi_domain_free()
724 info->ops->msi_free(domain, info, virq + i); in msi_domain_free()
739 return arg->hwirq; in msi_domain_ops_get_hwirq()
752 arg->desc = desc; in msi_domain_ops_set_desc()
760 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, info->chip, in msi_domain_ops_init()
761 info->chip_data); in msi_domain_ops_init()
762 if (info->handler && info->handler_name) { in msi_domain_ops_init()
763 __irq_set_handler(virq, info->handler, 0, info->handler_name); in msi_domain_ops_init()
764 if (info->handler_data) in msi_domain_ops_init()
765 irq_set_handler_data(virq, info->handler_data); in msi_domain_ops_init()
779 struct msi_domain_ops *ops = info->ops; in msi_domain_update_dom_ops()
782 info->ops = &msi_domain_ops_default; in msi_domain_update_dom_ops()
786 if (!(info->flags & MSI_FLAG_USE_DEF_DOM_OPS)) in msi_domain_update_dom_ops()
789 if (ops->get_hwirq == NULL) in msi_domain_update_dom_ops()
790 ops->get_hwirq = msi_domain_ops_default.get_hwirq; in msi_domain_update_dom_ops()
791 if (ops->msi_init == NULL) in msi_domain_update_dom_ops()
792 ops->msi_init = msi_domain_ops_default.msi_init; in msi_domain_update_dom_ops()
793 if (ops->msi_prepare == NULL) in msi_domain_update_dom_ops()
794 ops->msi_prepare = msi_domain_ops_default.msi_prepare; in msi_domain_update_dom_ops()
795 if (ops->set_desc == NULL) in msi_domain_update_dom_ops()
796 ops->set_desc = msi_domain_ops_default.set_desc; in msi_domain_update_dom_ops()
801 struct irq_chip *chip = info->chip; in msi_domain_update_chip_ops()
803 BUG_ON(!chip || !chip->irq_mask || !chip->irq_unmask); in msi_domain_update_chip_ops()
804 if (!chip->irq_set_affinity) in msi_domain_update_chip_ops()
805 chip->irq_set_affinity = msi_domain_set_affinity; in msi_domain_update_chip_ops()
811 struct irq_domain *parent) in __msi_create_irq_domain() argument
815 if (info->hwsize > MSI_XA_DOMAIN_SIZE) in __msi_create_irq_domain()
823 if (!info->hwsize) in __msi_create_irq_domain()
824 info->hwsize = MSI_XA_DOMAIN_SIZE; in __msi_create_irq_domain()
827 if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) in __msi_create_irq_domain()
830 domain = irq_domain_create_hierarchy(parent, flags | IRQ_DOMAIN_FLAG_MSI, 0, in __msi_create_irq_domain()
834 irq_domain_update_bus_token(domain, info->bus_token); in __msi_create_irq_domain()
840 * msi_create_irq_domain - Create an MSI interrupt domain
842 * @info: MSI domain info
843 * @parent: Parent irq domain
849 struct irq_domain *parent) in msi_create_irq_domain() argument
851 return __msi_create_irq_domain(fwnode, info, 0, parent); in msi_create_irq_domain()
855 * msi_parent_init_dev_msi_info - Delegate initialization of device MSI info down
861 * @msi_child_info: The MSI domain info of the IRQ_DOMAIN_FLAG_MSI_DEVICE
866 * This is the most complex problem of per device MSI domains and the
872 * That's trivial for a simple parent->child relationship, but it gets
873 * interesting with an intermediate domain: root->parent->child. The
874 * intermediate 'parent' can expand the capabilities which the 'root'
885 struct irq_domain *parent = domain->parent; in msi_parent_init_dev_msi_info() local
887 if (WARN_ON_ONCE(!parent || !parent->msi_parent_ops || in msi_parent_init_dev_msi_info()
888 !parent->msi_parent_ops->init_dev_msi_info)) in msi_parent_init_dev_msi_info()
891 return parent->msi_parent_ops->init_dev_msi_info(dev, parent, msi_parent_domain, in msi_parent_init_dev_msi_info()
896 * msi_create_device_irq_domain - Create a device MSI interrupt domain
899 * @template: MSI domain info bundle used as template
900 * @hwsize: Maximum number of MSI table entries (0 if unknown or unlimited)
912 * The domain name and the irq chip name for a MSI device domain are
913 * composed by: "$(PREFIX)$(CHIPNAME)-$(DEVNAME)"
915 * $PREFIX: Optional prefix provided by the underlying MSI parent domain
924 * PCI-MSI-0000:00:1c.0 0-edge Parent domain has no prefix
925 * IR-PCI-MSI-0000:00:1c.4 0-edge Same with interrupt remapping prefix 'IR-'
927 * IR-PCI-MSIX-0000:3d:00.0 0-edge Hardware interrupt numbers reflect
928 * IR-PCI-MSIX-0000:3d:00.0 1-edge the real MSI-X index on that device
929 * IR-PCI-MSIX-0000:3d:00.0 2-edge
935 * The domain pointer is stored in @dev::msi::data::__irqdomains[]. All
939 * in the context of @dev::msi::data freeing, but it can also be
947 struct irq_domain *domain, *parent = dev->msi.domain; in msi_create_device_irq_domain() local
952 if (!irq_domain_is_msi_parent(parent)) in msi_create_device_irq_domain()
962 bundle->info.hwsize = hwsize; in msi_create_device_irq_domain()
963 bundle->info.chip = &bundle->chip; in msi_create_device_irq_domain()
964 bundle->info.ops = &bundle->ops; in msi_create_device_irq_domain()
965 bundle->info.data = domain_data; in msi_create_device_irq_domain()
966 bundle->info.chip_data = chip_data; in msi_create_device_irq_domain()
968 pops = parent->msi_parent_ops; in msi_create_device_irq_domain()
969 snprintf(bundle->name, sizeof(bundle->name), "%s%s-%s", in msi_create_device_irq_domain()
970 pops->prefix ? : "", bundle->chip.name, dev_name(dev)); in msi_create_device_irq_domain()
971 bundle->chip.name = bundle->name; in msi_create_device_irq_domain()
973 fwnode = irq_domain_alloc_named_fwnode(bundle->name); in msi_create_device_irq_domain()
985 if (!pops->init_dev_msi_info(dev, parent, parent, &bundle->info)) in msi_create_device_irq_domain()
988 domain = __msi_create_irq_domain(fwnode, &bundle->info, IRQ_DOMAIN_FLAG_MSI_DEVICE, parent); in msi_create_device_irq_domain()
992 domain->dev = dev; in msi_create_device_irq_domain()
993 dev->msi.data->__domains[domid].domain = domain; in msi_create_device_irq_domain()
1007 * msi_remove_device_irq_domain - Free a device MSI interrupt domain
1024 dev->msi.data->__domains[domid].domain = NULL; in msi_remove_device_irq_domain()
1025 info = domain->host_data; in msi_remove_device_irq_domain()
1027 fwnode = domain->fwnode; in msi_remove_device_irq_domain()
1037 * msi_match_device_irq_domain - Match a device irq domain against a bus token
1054 info = domain->host_data; in msi_match_device_irq_domain()
1055 ret = info->bus_token == bus_token; in msi_match_device_irq_domain()
1064 struct msi_domain_info *info = domain->host_data; in msi_domain_prepare_irqs()
1065 struct msi_domain_ops *ops = info->ops; in msi_domain_prepare_irqs()
1067 return ops->msi_prepare(domain, dev, nvec, arg); in msi_domain_prepare_irqs()
1073 struct msi_domain_info *info = domain->host_data; in msi_domain_populate_irqs()
1074 struct msi_domain_ops *ops = info->ops; in msi_domain_populate_irqs()
1078 .last = virq_base + nvec - 1, in msi_domain_populate_irqs()
1087 ret = -EINVAL; in msi_domain_populate_irqs()
1095 xa = &dev->msi.data->__domains[ctrl.domid].store; in msi_domain_populate_irqs()
1099 desc->irq = virq; in msi_domain_populate_irqs()
1101 ops->set_desc(arg, desc); in msi_domain_populate_irqs()
1112 for (--virq; virq >= virq_base; virq--) { in msi_domain_populate_irqs()
1127 .last = virq_base + nvec - 1, in msi_domain_depopulate_descs()
1136 xa = &dev->msi.data->__domains[ctrl.domid].store; in msi_domain_depopulate_descs()
1138 desc->irq = 0; in msi_domain_depopulate_descs()
1144 * dummy vector to the device. If the PCI/MSI device does not support
1150 * used. For now reservation mode is restricted to PCI/MSI.
1158 switch(domain->bus_token) { in msi_check_reservation_mode()
1168 if (!(info->flags & MSI_FLAG_MUST_REACTIVATE)) in msi_check_reservation_mode()
1175 * Checking the first MSI descriptor is sufficient. MSIX supports in msi_check_reservation_mode()
1176 * masking and MSI does so when the can_mask attribute is set. in msi_check_reservation_mode()
1179 return desc->pci.msi_attrib.is_msix || desc->pci.msi_attrib.can_mask; in msi_check_reservation_mode()
1185 switch(domain->bus_token) { in msi_handle_pci_fail()
1194 return -ENOSPC; in msi_handle_pci_fail()
1197 /* Let a failed PCI multi MSI allocation retry */ in msi_handle_pci_fail()
1198 if (desc->nvec_used > 1) in msi_handle_pci_fail()
1202 return allocated ? allocated : -ENOSPC; in msi_handle_pci_fail()
1221 * different way by using a catch-all vector. in msi_init_virq()
1250 struct xarray *xa = &dev->msi.data->__domains[ctrl->domid].store; in __msi_domain_alloc_irqs()
1251 struct msi_domain_info *info = domain->host_data; in __msi_domain_alloc_irqs()
1252 struct msi_domain_ops *ops = info->ops; in __msi_domain_alloc_irqs()
1259 ret = msi_domain_prepare_irqs(domain, dev, ctrl->nirqs, &arg); in __msi_domain_alloc_irqs()
1265 * the MSI entries before the PCI layer enables MSI in the in __msi_domain_alloc_irqs()
1266 * card. Otherwise the card latches a random msi message. in __msi_domain_alloc_irqs()
1268 if (info->flags & MSI_FLAG_ACTIVATE_EARLY) in __msi_domain_alloc_irqs()
1278 xa_for_each_range(xa, idx, desc, ctrl->first, ctrl->last) { in __msi_domain_alloc_irqs()
1282 /* This should return -ECONFUSED... */ in __msi_domain_alloc_irqs()
1283 if (WARN_ON_ONCE(allocated >= ctrl->nirqs)) in __msi_domain_alloc_irqs()
1284 return -EINVAL; in __msi_domain_alloc_irqs()
1286 if (ops->prepare_desc) in __msi_domain_alloc_irqs()
1287 ops->prepare_desc(domain, &arg, desc); in __msi_domain_alloc_irqs()
1289 ops->set_desc(&arg, desc); in __msi_domain_alloc_irqs()
1291 virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used, in __msi_domain_alloc_irqs()
1293 desc->affinity); in __msi_domain_alloc_irqs()
1297 for (i = 0; i < desc->nvec_used; i++) { in __msi_domain_alloc_irqs()
1304 if (info->flags & MSI_FLAG_DEV_SYSFS) { in __msi_domain_alloc_irqs()
1318 if (!(info->flags & MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS)) in msi_domain_alloc_simple_msi_descs()
1332 return -EINVAL; in __msi_domain_alloc_locked()
1334 domain = msi_get_device_domain(dev, ctrl->domid); in __msi_domain_alloc_locked()
1336 return -ENODEV; in __msi_domain_alloc_locked()
1338 info = domain->host_data; in __msi_domain_alloc_locked()
1344 ops = info->ops; in __msi_domain_alloc_locked()
1345 if (ops->domain_alloc_irqs) in __msi_domain_alloc_locked()
1346 return ops->domain_alloc_irqs(domain, dev, ctrl->nirqs); in __msi_domain_alloc_locked()
1361 * msi_domain_alloc_irqs_range_locked - Allocate interrupts from a MSI interrupt domain
1369 * pair. Use this for MSI irqdomains which implement their own descriptor
1381 .nirqs = last + 1 - first, in msi_domain_alloc_irqs_range_locked()
1388 * msi_domain_alloc_irqs_range - Allocate interrupts from a MSI interrupt domain
1409 * msi_domain_alloc_irqs_all_locked - Allocate all interrupts from a MSI interrupt domain
1416 * This function scans all MSI descriptors of the MSI domain and allocates interrupts
1417 * for all unassigned ones. That function is to be used for MSI domain usage where
1418 * the descriptor allocation is handled at the call site, e.g. PCI/MSI[X].
1427 .last = msi_domain_get_hwsize(dev, domid) - 1, in msi_domain_alloc_irqs_all_locked()
1435 * msi_domain_alloc_irq_at - Allocate an interrupt from a MSI interrupt domain at
1436 * a given index - or at the next free index
1445 * non-NULL the content of the cookie is stored in msi_desc::data.
1446 * Must be NULL for MSI-X allocations
1448 * This requires a MSI interrupt domain which lets the core code manage the
1449 * MSI descriptors.
1472 map.index = -ENODEV; in msi_domain_alloc_irq_at()
1478 map.index = -ENOMEM; in msi_domain_alloc_irq_at()
1483 desc->data.icookie = *icookie; in msi_domain_alloc_irq_at()
1491 ctrl.first = ctrl.last = desc->msi_index; in msi_domain_alloc_irq_at()
1498 map.index = desc->msi_index; in msi_domain_alloc_irq_at()
1499 map.virq = desc->irq; in msi_domain_alloc_irq_at()
1509 struct xarray *xa = &dev->msi.data->__domains[ctrl->domid].store; in __msi_domain_free_irqs()
1510 struct msi_domain_info *info = domain->host_data; in __msi_domain_free_irqs()
1516 xa_for_each_range(xa, idx, desc, ctrl->first, ctrl->last) { in __msi_domain_free_irqs()
1517 /* Only handle MSI entries which have an interrupt associated */ in __msi_domain_free_irqs()
1522 for (i = 0; i < desc->nvec_used; i++) { in __msi_domain_free_irqs()
1523 irqd = irq_domain_get_irq_data(domain, desc->irq + i); in __msi_domain_free_irqs()
1528 irq_domain_free_irqs(desc->irq, desc->nvec_used); in __msi_domain_free_irqs()
1529 if (info->flags & MSI_FLAG_DEV_SYSFS) in __msi_domain_free_irqs()
1531 desc->irq = 0; in __msi_domain_free_irqs()
1544 domain = msi_get_device_domain(dev, ctrl->domid); in msi_domain_free_locked()
1548 info = domain->host_data; in msi_domain_free_locked()
1549 ops = info->ops; in msi_domain_free_locked()
1551 if (ops->domain_free_irqs) in msi_domain_free_locked()
1552 ops->domain_free_irqs(domain, dev); in msi_domain_free_locked()
1556 if (ops->msi_post_free) in msi_domain_free_locked()
1557 ops->msi_post_free(domain, dev); in msi_domain_free_locked()
1559 if (info->flags & MSI_FLAG_FREE_MSI_DESCS) in msi_domain_free_locked()
1564 * msi_domain_free_irqs_range_locked - Free a range of interrupts from a MSI interrupt domain
1584 * msi_domain_free_irqs_range - Free a range of interrupts from a MSI interrupt domain
1601 * msi_domain_free_irqs_all_locked - Free all interrupts from a MSI interrupt domain
1608 * pair. Use this for MSI irqdomains which implement their own vector
1614 msi_domain_get_hwsize(dev, domid) - 1); in msi_domain_free_irqs_all_locked()
1618 * msi_domain_free_irqs_all - Free all interrupts from a MSI interrupt domain
1632 * msi_get_domain_info - Get the MSI interrupt domain info for @domain
1635 * Return: the pointer to the msi_domain_info stored in @domain->host_data.
1639 return (struct msi_domain_info *)domain->host_data; in msi_get_domain_info()
1643 * msi_device_has_isolated_msi - True if the device has isolated MSI
1646 * Isolated MSI means that HW modeled by an irq_domain on the path from the
1647 * initiating device to the CPU will validate that the MSI message specifies an
1650 * Currently authorization means the MSI vector is one assigned to the device.
1652 * This is interesting for securing VFIO use cases where a rouge MSI (eg created
1662 for (; domain; domain = domain->parent) in msi_device_has_isolated_msi()
1663 if (domain->flags & IRQ_DOMAIN_FLAG_ISOLATED_MSI) in msi_device_has_isolated_msi()