aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu_init.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-06-11 11:45:25 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-07-17 06:14:56 -0400
commit02f3b3f5449cd0d9c4fb2c6f85f2973adefb7c72 (patch)
treefc5eccc0912ae08d5cc2c09c45558e8282d3747d /drivers/iommu/amd_iommu_init.c
parent98f1ad258254d89ffb550a36d59caf9127a9d53f (diff)
iommu/amd: Use acpi_get_table instead of acpi_table_parse
This makes it easier to propagate errors while parsing the IVRS table and makes the amd_iommu_init_err hack obsolete. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu/amd_iommu_init.c')
-rw-r--r--drivers/iommu/amd_iommu_init.c118
1 files changed, 66 insertions, 52 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 55f2033ea69b..de7a6cedcc45 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -26,6 +26,8 @@
26#include <linux/msi.h> 26#include <linux/msi.h>
27#include <linux/amd-iommu.h> 27#include <linux/amd-iommu.h>
28#include <linux/export.h> 28#include <linux/export.h>
29#include <linux/acpi.h>
30#include <acpi/acpi.h>
29#include <asm/pci-direct.h> 31#include <asm/pci-direct.h>
30#include <asm/iommu.h> 32#include <asm/iommu.h>
31#include <asm/gart.h> 33#include <asm/gart.h>
@@ -122,7 +124,7 @@ struct ivmd_header {
122 124
123bool amd_iommu_dump; 125bool amd_iommu_dump;
124 126
125static int __initdata amd_iommu_detected; 127static bool amd_iommu_detected;
126static bool __initdata amd_iommu_disabled; 128static bool __initdata amd_iommu_disabled;
127 129
128u16 amd_iommu_last_bdf; /* largest PCI device id we have 130u16 amd_iommu_last_bdf; /* largest PCI device id we have
@@ -149,11 +151,6 @@ bool amd_iommu_v2_present __read_mostly;
149bool amd_iommu_force_isolation __read_mostly; 151bool amd_iommu_force_isolation __read_mostly;
150 152
151/* 153/*
152 * The ACPI table parsing functions set this variable on an error
153 */
154static int __initdata amd_iommu_init_err;
155
156/*
157 * List of protection domains - used during resume 154 * List of protection domains - used during resume
158 */ 155 */
159LIST_HEAD(amd_iommu_pd_list); 156LIST_HEAD(amd_iommu_pd_list);
@@ -457,11 +454,9 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
457 */ 454 */
458 for (i = 0; i < table->length; ++i) 455 for (i = 0; i < table->length; ++i)
459 checksum += p[i]; 456 checksum += p[i];
460 if (checksum != 0) { 457 if (checksum != 0)
461 /* ACPI table corrupt */ 458 /* ACPI table corrupt */
462 amd_iommu_init_err = -ENODEV; 459 return -ENODEV;
463 return 0;
464 }
465 460
466 p += IVRS_HEADER_LENGTH; 461 p += IVRS_HEADER_LENGTH;
467 462
@@ -1087,16 +1082,12 @@ static int __init init_iommu_all(struct acpi_table_header *table)
1087 h->mmio_phys); 1082 h->mmio_phys);
1088 1083
1089 iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); 1084 iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
1090 if (iommu == NULL) { 1085 if (iommu == NULL)
1091 amd_iommu_init_err = -ENOMEM; 1086 return -ENOMEM;
1092 return 0;
1093 }
1094 1087
1095 ret = init_iommu_one(iommu, h); 1088 ret = init_iommu_one(iommu, h);
1096 if (ret) { 1089 if (ret)
1097 amd_iommu_init_err = ret; 1090 return ret;
1098 return 0;
1099 }
1100 break; 1091 break;
1101 default: 1092 default:
1102 break; 1093 break;
@@ -1477,9 +1468,15 @@ static void __init free_on_init_error(void)
1477 */ 1468 */
1478int __init amd_iommu_init_hardware(void) 1469int __init amd_iommu_init_hardware(void)
1479{ 1470{
1471 struct acpi_table_header *ivrs_base;
1472 acpi_size ivrs_size;
1473 acpi_status status;
1480 int i, ret = 0; 1474 int i, ret = 0;
1481 1475
1482 if (!amd_iommu_detected) 1476 if (no_iommu || (iommu_detected && !gart_iommu_aperture))
1477 return -ENODEV;
1478
1479 if (amd_iommu_disabled || !amd_iommu_detected)
1483 return -ENODEV; 1480 return -ENODEV;
1484 1481
1485 if (amd_iommu_dev_table != NULL) { 1482 if (amd_iommu_dev_table != NULL) {
@@ -1487,16 +1484,21 @@ int __init amd_iommu_init_hardware(void)
1487 return 0; 1484 return 0;
1488 } 1485 }
1489 1486
1487 status = acpi_get_table_with_size("IVRS", 0, &ivrs_base, &ivrs_size);
1488 if (status == AE_NOT_FOUND)
1489 return -ENODEV;
1490 else if (ACPI_FAILURE(status)) {
1491 const char *err = acpi_format_exception(status);
1492 pr_err("AMD-Vi: IVRS table error: %s\n", err);
1493 return -EINVAL;
1494 }
1495
1490 /* 1496 /*
1491 * First parse ACPI tables to find the largest Bus/Dev/Func 1497 * First parse ACPI tables to find the largest Bus/Dev/Func
1492 * we need to handle. Upon this information the shared data 1498 * we need to handle. Upon this information the shared data
1493 * structures for the IOMMUs in the system will be allocated 1499 * structures for the IOMMUs in the system will be allocated
1494 */ 1500 */
1495 if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) 1501 if (find_last_devid_acpi(ivrs_base))
1496 return -ENODEV;
1497
1498 ret = amd_iommu_init_err;
1499 if (ret)
1500 goto out; 1502 goto out;
1501 1503
1502 dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); 1504 dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE);
@@ -1553,22 +1555,13 @@ int __init amd_iommu_init_hardware(void)
1553 * now the data structures are allocated and basically initialized 1555 * now the data structures are allocated and basically initialized
1554 * start the real acpi table scan 1556 * start the real acpi table scan
1555 */ 1557 */
1556 ret = -ENODEV; 1558 ret = init_iommu_all(ivrs_base);
1557 if (acpi_table_parse("IVRS", init_iommu_all) != 0) 1559 if (ret)
1558 goto free;
1559
1560 if (amd_iommu_init_err) {
1561 ret = amd_iommu_init_err;
1562 goto free;
1563 }
1564
1565 if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
1566 goto free; 1560 goto free;
1567 1561
1568 if (amd_iommu_init_err) { 1562 ret = init_memory_definitions(ivrs_base);
1569 ret = amd_iommu_init_err; 1563 if (ret)
1570 goto free; 1564 goto free;
1571 }
1572 1565
1573 ret = amd_iommu_init_devices(); 1566 ret = amd_iommu_init_devices();
1574 if (ret) 1567 if (ret)
@@ -1581,12 +1574,16 @@ int __init amd_iommu_init_hardware(void)
1581 register_syscore_ops(&amd_iommu_syscore_ops); 1574 register_syscore_ops(&amd_iommu_syscore_ops);
1582 1575
1583out: 1576out:
1577 /* Don't leak any ACPI memory */
1578 early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
1579 ivrs_base = NULL;
1580
1584 return ret; 1581 return ret;
1585 1582
1586free: 1583free:
1587 free_on_init_error(); 1584 free_on_init_error();
1588 1585
1589 return ret; 1586 goto out;
1590} 1587}
1591 1588
1592static int amd_iommu_enable_interrupts(void) 1589static int amd_iommu_enable_interrupts(void)
@@ -1604,6 +1601,26 @@ out:
1604 return ret; 1601 return ret;
1605} 1602}
1606 1603
1604static bool detect_ivrs(void)
1605{
1606 struct acpi_table_header *ivrs_base;
1607 acpi_size ivrs_size;
1608 acpi_status status;
1609
1610 status = acpi_get_table_with_size("IVRS", 0, &ivrs_base, &ivrs_size);
1611 if (status == AE_NOT_FOUND)
1612 return false;
1613 else if (ACPI_FAILURE(status)) {
1614 const char *err = acpi_format_exception(status);
1615 pr_err("AMD-Vi: IVRS table error: %s\n", err);
1616 return false;
1617 }
1618
1619 early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
1620
1621 return true;
1622}
1623
1607/* 1624/*
1608 * This is the core init function for AMD IOMMU hardware in the system. 1625 * This is the core init function for AMD IOMMU hardware in the system.
1609 * This function is called from the generic x86 DMA layer initialization 1626 * This function is called from the generic x86 DMA layer initialization
@@ -1663,29 +1680,26 @@ free:
1663 * IOMMUs 1680 * IOMMUs
1664 * 1681 *
1665 ****************************************************************************/ 1682 ****************************************************************************/
1666static int __init early_amd_iommu_detect(struct acpi_table_header *table)
1667{
1668 return 0;
1669}
1670
1671int __init amd_iommu_detect(void) 1683int __init amd_iommu_detect(void)
1672{ 1684{
1685
1673 if (no_iommu || (iommu_detected && !gart_iommu_aperture)) 1686 if (no_iommu || (iommu_detected && !gart_iommu_aperture))
1674 return -ENODEV; 1687 return -ENODEV;
1675 1688
1676 if (amd_iommu_disabled) 1689 if (amd_iommu_disabled)
1677 return -ENODEV; 1690 return -ENODEV;
1678 1691
1679 if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { 1692 if (!detect_ivrs())
1680 iommu_detected = 1; 1693 return -ENODEV;
1681 amd_iommu_detected = 1;
1682 x86_init.iommu.iommu_init = amd_iommu_init;
1683 1694
1684 /* Make sure ACS will be enabled */ 1695 amd_iommu_detected = true;
1685 pci_request_acs(); 1696 iommu_detected = 1;
1686 return 1; 1697 x86_init.iommu.iommu_init = amd_iommu_init;
1687 } 1698
1688 return -ENODEV; 1699 /* Make sure ACS will be enabled */
1700 pci_request_acs();
1701
1702 return 0;
1689} 1703}
1690 1704
1691/**************************************************************************** 1705/****************************************************************************