diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2011-08-23 20:05:20 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-09-21 04:21:54 -0400 |
commit | 318fe7df9d8456f778451b01913b5d0dc0a25854 (patch) | |
tree | b134ae443ed05996f98660469590034ff19f76b5 /drivers/iommu/dmar.c | |
parent | c2c7286ac6d996a8ffc8d391d782ba35570b1236 (diff) |
iommu: Move IOMMU specific code to intel-iommu.c
Move the IOMMU specific routines to intel-iommu.c leaving the
dmar.c to the common ACPI dmar code shared between DMA-remapping
and Interrupt-remapping.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: yinghai@kernel.org
Cc: youquan.song@intel.com
Cc: joerg.roedel@amd.com
Cc: tony.luck@intel.com
Cc: dwmw2@infradead.org
Link: http://lkml.kernel.org/r/20110824001456.282401285@sbsiddha-desk.sc.intel.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r-- | drivers/iommu/dmar.c | 171 |
1 files changed, 8 insertions, 163 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 17adf1ebcb13..a10ccf2432c8 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c | |||
@@ -118,8 +118,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, | |||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, | 121 | int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, |
122 | struct pci_dev ***devices, u16 segment) | 122 | struct pci_dev ***devices, u16 segment) |
123 | { | 123 | { |
124 | struct acpi_dmar_device_scope *scope; | 124 | struct acpi_dmar_device_scope *scope; |
125 | void * tmp = start; | 125 | void * tmp = start; |
@@ -217,133 +217,6 @@ static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru) | |||
217 | return ret; | 217 | return ret; |
218 | } | 218 | } |
219 | 219 | ||
220 | #ifdef CONFIG_DMAR | ||
221 | LIST_HEAD(dmar_rmrr_units); | ||
222 | |||
223 | static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr) | ||
224 | { | ||
225 | list_add(&rmrr->list, &dmar_rmrr_units); | ||
226 | } | ||
227 | |||
228 | |||
229 | static int __init | ||
230 | dmar_parse_one_rmrr(struct acpi_dmar_header *header) | ||
231 | { | ||
232 | struct acpi_dmar_reserved_memory *rmrr; | ||
233 | struct dmar_rmrr_unit *rmrru; | ||
234 | |||
235 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); | ||
236 | if (!rmrru) | ||
237 | return -ENOMEM; | ||
238 | |||
239 | rmrru->hdr = header; | ||
240 | rmrr = (struct acpi_dmar_reserved_memory *)header; | ||
241 | rmrru->base_address = rmrr->base_address; | ||
242 | rmrru->end_address = rmrr->end_address; | ||
243 | |||
244 | dmar_register_rmrr_unit(rmrru); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int __init | ||
249 | rmrr_parse_dev(struct dmar_rmrr_unit *rmrru) | ||
250 | { | ||
251 | struct acpi_dmar_reserved_memory *rmrr; | ||
252 | int ret; | ||
253 | |||
254 | rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr; | ||
255 | ret = dmar_parse_dev_scope((void *)(rmrr + 1), | ||
256 | ((void *)rmrr) + rmrr->header.length, | ||
257 | &rmrru->devices_cnt, &rmrru->devices, rmrr->segment); | ||
258 | |||
259 | if (ret || (rmrru->devices_cnt == 0)) { | ||
260 | list_del(&rmrru->list); | ||
261 | kfree(rmrru); | ||
262 | } | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static LIST_HEAD(dmar_atsr_units); | ||
267 | |||
268 | static int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr) | ||
269 | { | ||
270 | struct acpi_dmar_atsr *atsr; | ||
271 | struct dmar_atsr_unit *atsru; | ||
272 | |||
273 | atsr = container_of(hdr, struct acpi_dmar_atsr, header); | ||
274 | atsru = kzalloc(sizeof(*atsru), GFP_KERNEL); | ||
275 | if (!atsru) | ||
276 | return -ENOMEM; | ||
277 | |||
278 | atsru->hdr = hdr; | ||
279 | atsru->include_all = atsr->flags & 0x1; | ||
280 | |||
281 | list_add(&atsru->list, &dmar_atsr_units); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru) | ||
287 | { | ||
288 | int rc; | ||
289 | struct acpi_dmar_atsr *atsr; | ||
290 | |||
291 | if (atsru->include_all) | ||
292 | return 0; | ||
293 | |||
294 | atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header); | ||
295 | rc = dmar_parse_dev_scope((void *)(atsr + 1), | ||
296 | (void *)atsr + atsr->header.length, | ||
297 | &atsru->devices_cnt, &atsru->devices, | ||
298 | atsr->segment); | ||
299 | if (rc || !atsru->devices_cnt) { | ||
300 | list_del(&atsru->list); | ||
301 | kfree(atsru); | ||
302 | } | ||
303 | |||
304 | return rc; | ||
305 | } | ||
306 | |||
307 | int dmar_find_matched_atsr_unit(struct pci_dev *dev) | ||
308 | { | ||
309 | int i; | ||
310 | struct pci_bus *bus; | ||
311 | struct acpi_dmar_atsr *atsr; | ||
312 | struct dmar_atsr_unit *atsru; | ||
313 | |||
314 | dev = pci_physfn(dev); | ||
315 | |||
316 | list_for_each_entry(atsru, &dmar_atsr_units, list) { | ||
317 | atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header); | ||
318 | if (atsr->segment == pci_domain_nr(dev->bus)) | ||
319 | goto found; | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | |||
324 | found: | ||
325 | for (bus = dev->bus; bus; bus = bus->parent) { | ||
326 | struct pci_dev *bridge = bus->self; | ||
327 | |||
328 | if (!bridge || !pci_is_pcie(bridge) || | ||
329 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | ||
330 | return 0; | ||
331 | |||
332 | if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { | ||
333 | for (i = 0; i < atsru->devices_cnt; i++) | ||
334 | if (atsru->devices[i] == bridge) | ||
335 | return 1; | ||
336 | break; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | if (atsru->include_all) | ||
341 | return 1; | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | #ifdef CONFIG_ACPI_NUMA | 220 | #ifdef CONFIG_ACPI_NUMA |
348 | static int __init | 221 | static int __init |
349 | dmar_parse_one_rhsa(struct acpi_dmar_header *header) | 222 | dmar_parse_one_rhsa(struct acpi_dmar_header *header) |
@@ -484,14 +357,10 @@ parse_dmar_table(void) | |||
484 | ret = dmar_parse_one_drhd(entry_header); | 357 | ret = dmar_parse_one_drhd(entry_header); |
485 | break; | 358 | break; |
486 | case ACPI_DMAR_TYPE_RESERVED_MEMORY: | 359 | case ACPI_DMAR_TYPE_RESERVED_MEMORY: |
487 | #ifdef CONFIG_DMAR | ||
488 | ret = dmar_parse_one_rmrr(entry_header); | 360 | ret = dmar_parse_one_rmrr(entry_header); |
489 | #endif | ||
490 | break; | 361 | break; |
491 | case ACPI_DMAR_TYPE_ATSR: | 362 | case ACPI_DMAR_TYPE_ATSR: |
492 | #ifdef CONFIG_DMAR | ||
493 | ret = dmar_parse_one_atsr(entry_header); | 363 | ret = dmar_parse_one_atsr(entry_header); |
494 | #endif | ||
495 | break; | 364 | break; |
496 | case ACPI_DMAR_HARDWARE_AFFINITY: | 365 | case ACPI_DMAR_HARDWARE_AFFINITY: |
497 | #ifdef CONFIG_ACPI_NUMA | 366 | #ifdef CONFIG_ACPI_NUMA |
@@ -564,30 +433,18 @@ int __init dmar_dev_scope_init(void) | |||
564 | if (dmar_dev_scope_initialized) | 433 | if (dmar_dev_scope_initialized) |
565 | return dmar_dev_scope_initialized; | 434 | return dmar_dev_scope_initialized; |
566 | 435 | ||
436 | if (list_empty(&dmar_drhd_units)) | ||
437 | goto fail; | ||
438 | |||
567 | list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { | 439 | list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { |
568 | ret = dmar_parse_dev(drhd); | 440 | ret = dmar_parse_dev(drhd); |
569 | if (ret) | 441 | if (ret) |
570 | goto fail; | 442 | goto fail; |
571 | } | 443 | } |
572 | 444 | ||
573 | #ifdef CONFIG_DMAR | 445 | ret = dmar_parse_rmrr_atsr_dev(); |
574 | { | 446 | if (ret) |
575 | struct dmar_rmrr_unit *rmrr, *rmrr_n; | 447 | goto fail; |
576 | struct dmar_atsr_unit *atsr, *atsr_n; | ||
577 | |||
578 | list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) { | ||
579 | ret = rmrr_parse_dev(rmrr); | ||
580 | if (ret) | ||
581 | goto fail; | ||
582 | } | ||
583 | |||
584 | list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) { | ||
585 | ret = atsr_parse_dev(atsr); | ||
586 | if (ret) | ||
587 | goto fail; | ||
588 | } | ||
589 | } | ||
590 | #endif | ||
591 | 448 | ||
592 | dmar_dev_scope_initialized = 1; | 449 | dmar_dev_scope_initialized = 1; |
593 | return 0; | 450 | return 0; |
@@ -620,14 +477,6 @@ int __init dmar_table_init(void) | |||
620 | return -ENODEV; | 477 | return -ENODEV; |
621 | } | 478 | } |
622 | 479 | ||
623 | #ifdef CONFIG_DMAR | ||
624 | if (list_empty(&dmar_rmrr_units)) | ||
625 | printk(KERN_INFO PREFIX "No RMRR found\n"); | ||
626 | |||
627 | if (list_empty(&dmar_atsr_units)) | ||
628 | printk(KERN_INFO PREFIX "No ATSR found\n"); | ||
629 | #endif | ||
630 | |||
631 | return 0; | 480 | return 0; |
632 | } | 481 | } |
633 | 482 | ||
@@ -767,7 +616,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
767 | goto err_unmap; | 616 | goto err_unmap; |
768 | } | 617 | } |
769 | 618 | ||
770 | #ifdef CONFIG_DMAR | ||
771 | agaw = iommu_calculate_agaw(iommu); | 619 | agaw = iommu_calculate_agaw(iommu); |
772 | if (agaw < 0) { | 620 | if (agaw < 0) { |
773 | printk(KERN_ERR | 621 | printk(KERN_ERR |
@@ -782,7 +630,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
782 | iommu->seq_id); | 630 | iommu->seq_id); |
783 | goto err_unmap; | 631 | goto err_unmap; |
784 | } | 632 | } |
785 | #endif | ||
786 | iommu->agaw = agaw; | 633 | iommu->agaw = agaw; |
787 | iommu->msagaw = msagaw; | 634 | iommu->msagaw = msagaw; |
788 | 635 | ||
@@ -826,9 +673,7 @@ void free_iommu(struct intel_iommu *iommu) | |||
826 | if (!iommu) | 673 | if (!iommu) |
827 | return; | 674 | return; |
828 | 675 | ||
829 | #ifdef CONFIG_DMAR | ||
830 | free_dmar_iommu(iommu); | 676 | free_dmar_iommu(iommu); |
831 | #endif | ||
832 | 677 | ||
833 | if (iommu->reg) | 678 | if (iommu->reg) |
834 | iounmap(iommu->reg); | 679 | iounmap(iommu->reg); |