PCI/MSI: Reject multi-MSI early
[sfrench/cifs-2.6.git] / drivers / pci / msi / irqdomain.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCI Message Signaled Interrupt (MSI) - irqdomain support
4  */
5 #include <linux/acpi_iort.h>
6 #include <linux/irqdomain.h>
7 #include <linux/of_irq.h>
8
9 #include "msi.h"
10
11 int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
12 {
13         struct irq_domain *domain;
14
15         domain = dev_get_msi_domain(&dev->dev);
16         if (domain && irq_domain_is_hierarchy(domain))
17                 return msi_domain_alloc_irqs_descs_locked(domain, &dev->dev, nvec);
18
19         return pci_msi_legacy_setup_msi_irqs(dev, nvec, type);
20 }
21
22 void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
23 {
24         struct irq_domain *domain;
25
26         domain = dev_get_msi_domain(&dev->dev);
27         if (domain && irq_domain_is_hierarchy(domain)) {
28                 msi_domain_free_irqs_descs_locked(domain, &dev->dev);
29         } else {
30                 pci_msi_legacy_teardown_msi_irqs(dev);
31                 msi_free_msi_descs(&dev->dev);
32         }
33 }
34
35 /**
36  * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space
37  * @irq_data:   Pointer to interrupt data of the MSI interrupt
38  * @msg:        Pointer to the message
39  */
40 static void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg)
41 {
42         struct msi_desc *desc = irq_data_get_msi_desc(irq_data);
43
44         /*
45          * For MSI-X desc->irq is always equal to irq_data->irq. For
46          * MSI only the first interrupt of MULTI MSI passes the test.
47          */
48         if (desc->irq == irq_data->irq)
49                 __pci_write_msi_msg(desc, msg);
50 }
51
52 /**
53  * pci_msi_domain_calc_hwirq - Generate a unique ID for an MSI source
54  * @desc:       Pointer to the MSI descriptor
55  *
56  * The ID number is only used within the irqdomain.
57  */
58 static irq_hw_number_t pci_msi_domain_calc_hwirq(struct msi_desc *desc)
59 {
60         struct pci_dev *dev = msi_desc_to_pci_dev(desc);
61
62         return (irq_hw_number_t)desc->msi_index |
63                 pci_dev_id(dev) << 11 |
64                 (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27;
65 }
66
67 static inline bool pci_msi_desc_is_multi_msi(struct msi_desc *desc)
68 {
69         return !desc->pci.msi_attrib.is_msix && desc->nvec_used > 1;
70 }
71
72 /**
73  * pci_msi_domain_check_cap - Verify that @domain supports the capabilities
74  *                            for @dev
75  * @domain:     The interrupt domain to check
76  * @info:       The domain info for verification
77  * @dev:        The device to check
78  *
79  * Returns:
80  *  0 if the functionality is supported
81  *  1 if Multi MSI is requested, but the domain does not support it
82  *  -ENOTSUPP otherwise
83  */
84 static int pci_msi_domain_check_cap(struct irq_domain *domain,
85                                     struct msi_domain_info *info,
86                                     struct device *dev)
87 {
88         struct msi_desc *desc = msi_first_desc(dev, MSI_DESC_ALL);
89
90         /* Special handling to support __pci_enable_msi_range() */
91         if (pci_msi_desc_is_multi_msi(desc) &&
92             !(info->flags & MSI_FLAG_MULTI_PCI_MSI))
93                 return 1;
94
95         if (desc->pci.msi_attrib.is_msix) {
96                 if (!(info->flags & MSI_FLAG_PCI_MSIX))
97                         return -ENOTSUPP;
98
99                 if (info->flags & MSI_FLAG_MSIX_CONTIGUOUS) {
100                         unsigned int idx = 0;
101
102                         /* Check for gaps in the entry indices */
103                         msi_for_each_desc(desc, dev, MSI_DESC_ALL) {
104                                 if (desc->msi_index != idx++)
105                                         return -ENOTSUPP;
106                         }
107                 }
108         }
109         return 0;
110 }
111
112 static void pci_msi_domain_set_desc(msi_alloc_info_t *arg,
113                                     struct msi_desc *desc)
114 {
115         arg->desc = desc;
116         arg->hwirq = pci_msi_domain_calc_hwirq(desc);
117 }
118
119 static struct msi_domain_ops pci_msi_domain_ops_default = {
120         .set_desc       = pci_msi_domain_set_desc,
121         .msi_check      = pci_msi_domain_check_cap,
122 };
123
124 static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
125 {
126         struct msi_domain_ops *ops = info->ops;
127
128         if (ops == NULL) {
129                 info->ops = &pci_msi_domain_ops_default;
130         } else {
131                 if (ops->set_desc == NULL)
132                         ops->set_desc = pci_msi_domain_set_desc;
133                 if (ops->msi_check == NULL)
134                         ops->msi_check = pci_msi_domain_check_cap;
135         }
136 }
137
138 static void pci_msi_domain_update_chip_ops(struct msi_domain_info *info)
139 {
140         struct irq_chip *chip = info->chip;
141
142         BUG_ON(!chip);
143         if (!chip->irq_write_msi_msg)
144                 chip->irq_write_msi_msg = pci_msi_domain_write_msg;
145         if (!chip->irq_mask)
146                 chip->irq_mask = pci_msi_mask_irq;
147         if (!chip->irq_unmask)
148                 chip->irq_unmask = pci_msi_unmask_irq;
149 }
150
151 /**
152  * pci_msi_create_irq_domain - Create a MSI interrupt domain
153  * @fwnode:     Optional fwnode of the interrupt controller
154  * @info:       MSI domain info
155  * @parent:     Parent irq domain
156  *
157  * Updates the domain and chip ops and creates a MSI interrupt domain.
158  *
159  * Returns:
160  * A domain pointer or NULL in case of failure.
161  */
162 struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
163                                              struct msi_domain_info *info,
164                                              struct irq_domain *parent)
165 {
166         if (WARN_ON(info->flags & MSI_FLAG_LEVEL_CAPABLE))
167                 info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
168
169         if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
170                 pci_msi_domain_update_dom_ops(info);
171         if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
172                 pci_msi_domain_update_chip_ops(info);
173
174         /* Let the core code free MSI descriptors when freeing interrupts */
175         info->flags |= MSI_FLAG_FREE_MSI_DESCS;
176
177         info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS;
178         if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
179                 info->flags |= MSI_FLAG_MUST_REACTIVATE;
180
181         /* PCI-MSI is oneshot-safe */
182         info->chip->flags |= IRQCHIP_ONESHOT_SAFE;
183         /* Let the core update the bus token */
184         info->bus_token = DOMAIN_BUS_PCI_MSI;
185
186         return msi_create_irq_domain(fwnode, info, parent);
187 }
188 EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
189
190 /**
191  * pci_msi_domain_supports - Check for support of a particular feature flag
192  * @pdev:               The PCI device to operate on
193  * @feature_mask:       The feature mask to check for (full match)
194  * @mode:               If ALLOW_LEGACY this grants the feature when there is no irq domain
195  *                      associated to the device. If DENY_LEGACY the lack of an irq domain
196  *                      makes the feature unsupported
197  */
198 bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask,
199                              enum support_mode mode)
200 {
201         struct msi_domain_info *info;
202         struct irq_domain *domain;
203
204         domain = dev_get_msi_domain(&pdev->dev);
205
206         if (!domain || !irq_domain_is_hierarchy(domain))
207                 return mode == ALLOW_LEGACY;
208         info = domain->host_data;
209         return (info->flags & feature_mask) == feature_mask;
210 }
211
212 /*
213  * Users of the generic MSI infrastructure expect a device to have a single ID,
214  * so with DMA aliases we have to pick the least-worst compromise. Devices with
215  * DMA phantom functions tend to still emit MSIs from the real function number,
216  * so we ignore those and only consider topological aliases where either the
217  * alias device or RID appears on a different bus number. We also make the
218  * reasonable assumption that bridges are walked in an upstream direction (so
219  * the last one seen wins), and the much braver assumption that the most likely
220  * case is that of PCI->PCIe so we should always use the alias RID. This echoes
221  * the logic from intel_irq_remapping's set_msi_sid(), which presumably works
222  * well enough in practice; in the face of the horrible PCIe<->PCI-X conditions
223  * for taking ownership all we can really do is close our eyes and hope...
224  */
225 static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data)
226 {
227         u32 *pa = data;
228         u8 bus = PCI_BUS_NUM(*pa);
229
230         if (pdev->bus->number != bus || PCI_BUS_NUM(alias) != bus)
231                 *pa = alias;
232
233         return 0;
234 }
235
236 /**
237  * pci_msi_domain_get_msi_rid - Get the MSI requester id (RID)
238  * @domain:     The interrupt domain
239  * @pdev:       The PCI device.
240  *
241  * The RID for a device is formed from the alias, with a firmware
242  * supplied mapping applied
243  *
244  * Returns: The RID.
245  */
246 u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
247 {
248         struct device_node *of_node;
249         u32 rid = pci_dev_id(pdev);
250
251         pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
252
253         of_node = irq_domain_get_of_node(domain);
254         rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) :
255                         iort_msi_map_id(&pdev->dev, rid);
256
257         return rid;
258 }
259
260 /**
261  * pci_msi_get_device_domain - Get the MSI domain for a given PCI device
262  * @pdev:       The PCI device
263  *
264  * Use the firmware data to find a device-specific MSI domain
265  * (i.e. not one that is set as a default).
266  *
267  * Returns: The corresponding MSI domain or NULL if none has been found.
268  */
269 struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
270 {
271         struct irq_domain *dom;
272         u32 rid = pci_dev_id(pdev);
273
274         pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
275         dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI);
276         if (!dom)
277                 dom = iort_get_device_domain(&pdev->dev, rid,
278                                              DOMAIN_BUS_PCI_MSI);
279         return dom;
280 }
281
282 /**
283  * pci_dev_has_special_msi_domain - Check whether the device is handled by
284  *                                  a non-standard PCI-MSI domain
285  * @pdev:       The PCI device to check.
286  *
287  * Returns: True if the device irqdomain or the bus irqdomain is
288  * non-standard PCI/MSI.
289  */
290 bool pci_dev_has_special_msi_domain(struct pci_dev *pdev)
291 {
292         struct irq_domain *dom = dev_get_msi_domain(&pdev->dev);
293
294         if (!dom)
295                 dom = dev_get_msi_domain(&pdev->bus->dev);
296
297         if (!dom)
298                 return true;
299
300         return dom->bus_token != DOMAIN_BUS_PCI_MSI;
301 }