aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2017-05-30 12:25:48 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-05-30 16:39:15 -0400
commita4f4fa681add289ebfec6d776376ad7a2ffda669 (patch)
treebad540deacc055ab92790af76e4e20f9107729a0
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
PCI: Cache PRI and PASID bits in pci_dev
Device drivers need to check if an IOMMU enabled ATS, PRI and PASID in order to know when they can use the SVM API. Cache PRI and PASID bits in the pci_dev structure, similarly to what is currently done for ATS. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/ats.c23
-rw-r--r--include/linux/pci.h2
2 files changed, 25 insertions, 0 deletions
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index eeb9fb2b47aa..21264976fa13 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -153,6 +153,9 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
153 u32 max_requests; 153 u32 max_requests;
154 int pos; 154 int pos;
155 155
156 if (WARN_ON(pdev->pri_enabled))
157 return -EBUSY;
158
156 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); 159 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
157 if (!pos) 160 if (!pos)
158 return -EINVAL; 161 return -EINVAL;
@@ -170,6 +173,8 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
170 control |= PCI_PRI_CTRL_ENABLE; 173 control |= PCI_PRI_CTRL_ENABLE;
171 pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); 174 pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
172 175
176 pdev->pri_enabled = 1;
177
173 return 0; 178 return 0;
174} 179}
175EXPORT_SYMBOL_GPL(pci_enable_pri); 180EXPORT_SYMBOL_GPL(pci_enable_pri);
@@ -185,6 +190,9 @@ void pci_disable_pri(struct pci_dev *pdev)
185 u16 control; 190 u16 control;
186 int pos; 191 int pos;
187 192
193 if (WARN_ON(!pdev->pri_enabled))
194 return;
195
188 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); 196 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
189 if (!pos) 197 if (!pos)
190 return; 198 return;
@@ -192,6 +200,8 @@ void pci_disable_pri(struct pci_dev *pdev)
192 pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); 200 pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
193 control &= ~PCI_PRI_CTRL_ENABLE; 201 control &= ~PCI_PRI_CTRL_ENABLE;
194 pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); 202 pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
203
204 pdev->pri_enabled = 0;
195} 205}
196EXPORT_SYMBOL_GPL(pci_disable_pri); 206EXPORT_SYMBOL_GPL(pci_disable_pri);
197 207
@@ -207,6 +217,9 @@ int pci_reset_pri(struct pci_dev *pdev)
207 u16 control; 217 u16 control;
208 int pos; 218 int pos;
209 219
220 if (WARN_ON(pdev->pri_enabled))
221 return -EBUSY;
222
210 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); 223 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
211 if (!pos) 224 if (!pos)
212 return -EINVAL; 225 return -EINVAL;
@@ -239,6 +252,9 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
239 u16 control, supported; 252 u16 control, supported;
240 int pos; 253 int pos;
241 254
255 if (WARN_ON(pdev->pasid_enabled))
256 return -EBUSY;
257
242 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); 258 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
243 if (!pos) 259 if (!pos)
244 return -EINVAL; 260 return -EINVAL;
@@ -259,6 +275,8 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
259 275
260 pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); 276 pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
261 277
278 pdev->pasid_enabled = 1;
279
262 return 0; 280 return 0;
263} 281}
264EXPORT_SYMBOL_GPL(pci_enable_pasid); 282EXPORT_SYMBOL_GPL(pci_enable_pasid);
@@ -273,11 +291,16 @@ void pci_disable_pasid(struct pci_dev *pdev)
273 u16 control = 0; 291 u16 control = 0;
274 int pos; 292 int pos;
275 293
294 if (WARN_ON(!pdev->pasid_enabled))
295 return;
296
276 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); 297 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
277 if (!pos) 298 if (!pos)
278 return; 299 return;
279 300
280 pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); 301 pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
302
303 pdev->pasid_enabled = 0;
281} 304}
282EXPORT_SYMBOL_GPL(pci_disable_pasid); 305EXPORT_SYMBOL_GPL(pci_disable_pasid);
283 306
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 33c2b0b77429..f612c1d85863 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -356,6 +356,8 @@ struct pci_dev {
356 unsigned int msix_enabled:1; 356 unsigned int msix_enabled:1;
357 unsigned int ari_enabled:1; /* ARI forwarding */ 357 unsigned int ari_enabled:1; /* ARI forwarding */
358 unsigned int ats_enabled:1; /* Address Translation Service */ 358 unsigned int ats_enabled:1; /* Address Translation Service */
359 unsigned int pasid_enabled:1; /* Process Address Space ID */
360 unsigned int pri_enabled:1; /* Page Request Interface */
359 unsigned int is_managed:1; 361 unsigned int is_managed:1;
360 unsigned int needs_freset:1; /* Dev requires fundamental reset */ 362 unsigned int needs_freset:1; /* Dev requires fundamental reset */
361 unsigned int state_saved:1; 363 unsigned int state_saved:1;