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/intel-iommu.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/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index df69618177c5..e8eb4c5302b0 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -3390,6 +3390,151 @@ static void __init init_iommu_pm_ops(void) | |||
3390 | static inline void init_iommu_pm_ops(void) {} | 3390 | static inline void init_iommu_pm_ops(void) {} |
3391 | #endif /* CONFIG_PM */ | 3391 | #endif /* CONFIG_PM */ |
3392 | 3392 | ||
3393 | LIST_HEAD(dmar_rmrr_units); | ||
3394 | |||
3395 | static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr) | ||
3396 | { | ||
3397 | list_add(&rmrr->list, &dmar_rmrr_units); | ||
3398 | } | ||
3399 | |||
3400 | |||
3401 | int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header) | ||
3402 | { | ||
3403 | struct acpi_dmar_reserved_memory *rmrr; | ||
3404 | struct dmar_rmrr_unit *rmrru; | ||
3405 | |||
3406 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); | ||
3407 | if (!rmrru) | ||
3408 | return -ENOMEM; | ||
3409 | |||
3410 | rmrru->hdr = header; | ||
3411 | rmrr = (struct acpi_dmar_reserved_memory *)header; | ||
3412 | rmrru->base_address = rmrr->base_address; | ||
3413 | rmrru->end_address = rmrr->end_address; | ||
3414 | |||
3415 | dmar_register_rmrr_unit(rmrru); | ||
3416 | return 0; | ||
3417 | } | ||
3418 | |||
3419 | static int __init | ||
3420 | rmrr_parse_dev(struct dmar_rmrr_unit *rmrru) | ||
3421 | { | ||
3422 | struct acpi_dmar_reserved_memory *rmrr; | ||
3423 | int ret; | ||
3424 | |||
3425 | rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr; | ||
3426 | ret = dmar_parse_dev_scope((void *)(rmrr + 1), | ||
3427 | ((void *)rmrr) + rmrr->header.length, | ||
3428 | &rmrru->devices_cnt, &rmrru->devices, rmrr->segment); | ||
3429 | |||
3430 | if (ret || (rmrru->devices_cnt == 0)) { | ||
3431 | list_del(&rmrru->list); | ||
3432 | kfree(rmrru); | ||
3433 | } | ||
3434 | return ret; | ||
3435 | } | ||
3436 | |||
3437 | static LIST_HEAD(dmar_atsr_units); | ||
3438 | |||
3439 | int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr) | ||
3440 | { | ||
3441 | struct acpi_dmar_atsr *atsr; | ||
3442 | struct dmar_atsr_unit *atsru; | ||
3443 | |||
3444 | atsr = container_of(hdr, struct acpi_dmar_atsr, header); | ||
3445 | atsru = kzalloc(sizeof(*atsru), GFP_KERNEL); | ||
3446 | if (!atsru) | ||
3447 | return -ENOMEM; | ||
3448 | |||
3449 | atsru->hdr = hdr; | ||
3450 | atsru->include_all = atsr->flags & 0x1; | ||
3451 | |||
3452 | list_add(&atsru->list, &dmar_atsr_units); | ||
3453 | |||
3454 | return 0; | ||
3455 | } | ||
3456 | |||
3457 | static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru) | ||
3458 | { | ||
3459 | int rc; | ||
3460 | struct acpi_dmar_atsr *atsr; | ||
3461 | |||
3462 | if (atsru->include_all) | ||
3463 | return 0; | ||
3464 | |||
3465 | atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header); | ||
3466 | rc = dmar_parse_dev_scope((void *)(atsr + 1), | ||
3467 | (void *)atsr + atsr->header.length, | ||
3468 | &atsru->devices_cnt, &atsru->devices, | ||
3469 | atsr->segment); | ||
3470 | if (rc || !atsru->devices_cnt) { | ||
3471 | list_del(&atsru->list); | ||
3472 | kfree(atsru); | ||
3473 | } | ||
3474 | |||
3475 | return rc; | ||
3476 | } | ||
3477 | |||
3478 | int dmar_find_matched_atsr_unit(struct pci_dev *dev) | ||
3479 | { | ||
3480 | int i; | ||
3481 | struct pci_bus *bus; | ||
3482 | struct acpi_dmar_atsr *atsr; | ||
3483 | struct dmar_atsr_unit *atsru; | ||
3484 | |||
3485 | dev = pci_physfn(dev); | ||
3486 | |||
3487 | list_for_each_entry(atsru, &dmar_atsr_units, list) { | ||
3488 | atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header); | ||
3489 | if (atsr->segment == pci_domain_nr(dev->bus)) | ||
3490 | goto found; | ||
3491 | } | ||
3492 | |||
3493 | return 0; | ||
3494 | |||
3495 | found: | ||
3496 | for (bus = dev->bus; bus; bus = bus->parent) { | ||
3497 | struct pci_dev *bridge = bus->self; | ||
3498 | |||
3499 | if (!bridge || !pci_is_pcie(bridge) || | ||
3500 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | ||
3501 | return 0; | ||
3502 | |||
3503 | if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { | ||
3504 | for (i = 0; i < atsru->devices_cnt; i++) | ||
3505 | if (atsru->devices[i] == bridge) | ||
3506 | return 1; | ||
3507 | break; | ||
3508 | } | ||
3509 | } | ||
3510 | |||
3511 | if (atsru->include_all) | ||
3512 | return 1; | ||
3513 | |||
3514 | return 0; | ||
3515 | } | ||
3516 | |||
3517 | int dmar_parse_rmrr_atsr_dev(void) | ||
3518 | { | ||
3519 | struct dmar_rmrr_unit *rmrr, *rmrr_n; | ||
3520 | struct dmar_atsr_unit *atsr, *atsr_n; | ||
3521 | int ret = 0; | ||
3522 | |||
3523 | list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) { | ||
3524 | ret = rmrr_parse_dev(rmrr); | ||
3525 | if (ret) | ||
3526 | return ret; | ||
3527 | } | ||
3528 | |||
3529 | list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) { | ||
3530 | ret = atsr_parse_dev(atsr); | ||
3531 | if (ret) | ||
3532 | return ret; | ||
3533 | } | ||
3534 | |||
3535 | return ret; | ||
3536 | } | ||
3537 | |||
3393 | /* | 3538 | /* |
3394 | * Here we only respond to action of unbound device from driver. | 3539 | * Here we only respond to action of unbound device from driver. |
3395 | * | 3540 | * |
@@ -3454,6 +3599,12 @@ int __init intel_iommu_init(void) | |||
3454 | return -ENODEV; | 3599 | return -ENODEV; |
3455 | } | 3600 | } |
3456 | 3601 | ||
3602 | if (list_empty(&dmar_rmrr_units)) | ||
3603 | printk(KERN_INFO "DMAR: No RMRR found\n"); | ||
3604 | |||
3605 | if (list_empty(&dmar_atsr_units)) | ||
3606 | printk(KERN_INFO "DMAR: No ATSR found\n"); | ||
3607 | |||
3457 | if (dmar_init_reserved_ranges()) { | 3608 | if (dmar_init_reserved_ranges()) { |
3458 | if (force_on) | 3609 | if (force_on) |
3459 | panic("tboot: Failed to reserve iommu ranges\n"); | 3610 | panic("tboot: Failed to reserve iommu ranges\n"); |