diff options
Diffstat (limited to 'drivers/iommu/amd_iommu_init.c')
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index bb2cd29e1658..66123b911ec8 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -17,6 +17,8 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) "AMD-Vi: " fmt | ||
21 | |||
20 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
21 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
22 | #include <linux/list.h> | 24 | #include <linux/list.h> |
@@ -443,9 +445,9 @@ static void iommu_disable(struct amd_iommu *iommu) | |||
443 | static u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end) | 445 | static u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end) |
444 | { | 446 | { |
445 | if (!request_mem_region(address, end, "amd_iommu")) { | 447 | if (!request_mem_region(address, end, "amd_iommu")) { |
446 | pr_err("AMD-Vi: Can not reserve memory region %llx-%llx for mmio\n", | 448 | pr_err("Can not reserve memory region %llx-%llx for mmio\n", |
447 | address, end); | 449 | address, end); |
448 | pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n"); | 450 | pr_err("This is a BIOS bug. Please contact your hardware vendor\n"); |
449 | return NULL; | 451 | return NULL; |
450 | } | 452 | } |
451 | 453 | ||
@@ -512,7 +514,7 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h) | |||
512 | u32 ivhd_size = get_ivhd_header_size(h); | 514 | u32 ivhd_size = get_ivhd_header_size(h); |
513 | 515 | ||
514 | if (!ivhd_size) { | 516 | if (!ivhd_size) { |
515 | pr_err("AMD-Vi: Unsupported IVHD type %#x\n", h->type); | 517 | pr_err("Unsupported IVHD type %#x\n", h->type); |
516 | return -EINVAL; | 518 | return -EINVAL; |
517 | } | 519 | } |
518 | 520 | ||
@@ -553,7 +555,7 @@ static int __init check_ivrs_checksum(struct acpi_table_header *table) | |||
553 | checksum += p[i]; | 555 | checksum += p[i]; |
554 | if (checksum != 0) { | 556 | if (checksum != 0) { |
555 | /* ACPI table corrupt */ | 557 | /* ACPI table corrupt */ |
556 | pr_err(FW_BUG "AMD-Vi: IVRS invalid checksum\n"); | 558 | pr_err(FW_BUG "IVRS invalid checksum\n"); |
557 | return -ENODEV; | 559 | return -ENODEV; |
558 | } | 560 | } |
559 | 561 | ||
@@ -797,7 +799,8 @@ static int iommu_init_ga_log(struct amd_iommu *iommu) | |||
797 | entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; | 799 | entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; |
798 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, | 800 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, |
799 | &entry, sizeof(entry)); | 801 | &entry, sizeof(entry)); |
800 | entry = (iommu_virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL; | 802 | entry = (iommu_virt_to_phys(iommu->ga_log_tail) & |
803 | (BIT_ULL(52)-1)) & ~7ULL; | ||
801 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, | 804 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, |
802 | &entry, sizeof(entry)); | 805 | &entry, sizeof(entry)); |
803 | writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); | 806 | writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); |
@@ -1027,7 +1030,7 @@ static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line) | |||
1027 | if (!(entry->id == id && entry->cmd_line)) | 1030 | if (!(entry->id == id && entry->cmd_line)) |
1028 | continue; | 1031 | continue; |
1029 | 1032 | ||
1030 | pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n", | 1033 | pr_info("Command-line override present for %s id %d - ignoring\n", |
1031 | type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); | 1034 | type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); |
1032 | 1035 | ||
1033 | *devid = entry->devid; | 1036 | *devid = entry->devid; |
@@ -1060,7 +1063,7 @@ static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u16 *devid, | |||
1060 | !entry->cmd_line) | 1063 | !entry->cmd_line) |
1061 | continue; | 1064 | continue; |
1062 | 1065 | ||
1063 | pr_info("AMD-Vi: Command-line override for hid:%s uid:%s\n", | 1066 | pr_info("Command-line override for hid:%s uid:%s\n", |
1064 | hid, uid); | 1067 | hid, uid); |
1065 | *devid = entry->devid; | 1068 | *devid = entry->devid; |
1066 | return 0; | 1069 | return 0; |
@@ -1076,7 +1079,7 @@ static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u16 *devid, | |||
1076 | entry->cmd_line = cmd_line; | 1079 | entry->cmd_line = cmd_line; |
1077 | entry->root_devid = (entry->devid & (~0x7)); | 1080 | entry->root_devid = (entry->devid & (~0x7)); |
1078 | 1081 | ||
1079 | pr_info("AMD-Vi:%s, add hid:%s, uid:%s, rdevid:%d\n", | 1082 | pr_info("%s, add hid:%s, uid:%s, rdevid:%d\n", |
1080 | entry->cmd_line ? "cmd" : "ivrs", | 1083 | entry->cmd_line ? "cmd" : "ivrs", |
1081 | entry->hid, entry->uid, entry->root_devid); | 1084 | entry->hid, entry->uid, entry->root_devid); |
1082 | 1085 | ||
@@ -1172,7 +1175,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
1172 | */ | 1175 | */ |
1173 | ivhd_size = get_ivhd_header_size(h); | 1176 | ivhd_size = get_ivhd_header_size(h); |
1174 | if (!ivhd_size) { | 1177 | if (!ivhd_size) { |
1175 | pr_err("AMD-Vi: Unsupported IVHD type %#x\n", h->type); | 1178 | pr_err("Unsupported IVHD type %#x\n", h->type); |
1176 | return -EINVAL; | 1179 | return -EINVAL; |
1177 | } | 1180 | } |
1178 | 1181 | ||
@@ -1454,7 +1457,7 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) | |||
1454 | pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8)); | 1457 | pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8)); |
1455 | 1458 | ||
1456 | pci_write_config_dword(iommu->dev, 0xf4, value | 0x4); | 1459 | pci_write_config_dword(iommu->dev, 0xf4, value | 0x4); |
1457 | pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n", | 1460 | pr_info("Applying erratum 746 workaround for IOMMU at %s\n", |
1458 | dev_name(&iommu->dev->dev)); | 1461 | dev_name(&iommu->dev->dev)); |
1459 | 1462 | ||
1460 | /* Clear the enable writing bit */ | 1463 | /* Clear the enable writing bit */ |
@@ -1485,7 +1488,7 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu) | |||
1485 | /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */ | 1488 | /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */ |
1486 | iommu_write_l2(iommu, 0x47, value | BIT(0)); | 1489 | iommu_write_l2(iommu, 0x47, value | BIT(0)); |
1487 | 1490 | ||
1488 | pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n", | 1491 | pr_info("Applying ATS write check workaround for IOMMU at %s\n", |
1489 | dev_name(&iommu->dev->dev)); | 1492 | dev_name(&iommu->dev->dev)); |
1490 | } | 1493 | } |
1491 | 1494 | ||
@@ -1505,7 +1508,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) | |||
1505 | iommu->index = amd_iommus_present++; | 1508 | iommu->index = amd_iommus_present++; |
1506 | 1509 | ||
1507 | if (unlikely(iommu->index >= MAX_IOMMUS)) { | 1510 | if (unlikely(iommu->index >= MAX_IOMMUS)) { |
1508 | WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n"); | 1511 | WARN(1, "System has more IOMMUs than supported by this driver\n"); |
1509 | return -ENOSYS; | 1512 | return -ENOSYS; |
1510 | } | 1513 | } |
1511 | 1514 | ||
@@ -1673,12 +1676,12 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu) | |||
1673 | if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) || | 1676 | if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) || |
1674 | (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) || | 1677 | (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) || |
1675 | (val != val2)) { | 1678 | (val != val2)) { |
1676 | pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n"); | 1679 | pr_err("Unable to write to IOMMU perf counter.\n"); |
1677 | amd_iommu_pc_present = false; | 1680 | amd_iommu_pc_present = false; |
1678 | return; | 1681 | return; |
1679 | } | 1682 | } |
1680 | 1683 | ||
1681 | pr_info("AMD-Vi: IOMMU performance counters supported\n"); | 1684 | pr_info("IOMMU performance counters supported\n"); |
1682 | 1685 | ||
1683 | val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET); | 1686 | val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET); |
1684 | iommu->max_banks = (u8) ((val >> 12) & 0x3f); | 1687 | iommu->max_banks = (u8) ((val >> 12) & 0x3f); |
@@ -1839,11 +1842,11 @@ static void print_iommu_info(void) | |||
1839 | for_each_iommu(iommu) { | 1842 | for_each_iommu(iommu) { |
1840 | int i; | 1843 | int i; |
1841 | 1844 | ||
1842 | pr_info("AMD-Vi: Found IOMMU at %s cap 0x%hx\n", | 1845 | pr_info("Found IOMMU at %s cap 0x%hx\n", |
1843 | dev_name(&iommu->dev->dev), iommu->cap_ptr); | 1846 | dev_name(&iommu->dev->dev), iommu->cap_ptr); |
1844 | 1847 | ||
1845 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { | 1848 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { |
1846 | pr_info("AMD-Vi: Extended features (%#llx):\n", | 1849 | pr_info("Extended features (%#llx):\n", |
1847 | iommu->features); | 1850 | iommu->features); |
1848 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { | 1851 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { |
1849 | if (iommu_feature(iommu, (1ULL << i))) | 1852 | if (iommu_feature(iommu, (1ULL << i))) |
@@ -1857,11 +1860,11 @@ static void print_iommu_info(void) | |||
1857 | } | 1860 | } |
1858 | } | 1861 | } |
1859 | if (irq_remapping_enabled) { | 1862 | if (irq_remapping_enabled) { |
1860 | pr_info("AMD-Vi: Interrupt remapping enabled\n"); | 1863 | pr_info("Interrupt remapping enabled\n"); |
1861 | if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) | 1864 | if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) |
1862 | pr_info("AMD-Vi: virtual APIC enabled\n"); | 1865 | pr_info("Virtual APIC enabled\n"); |
1863 | if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE) | 1866 | if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE) |
1864 | pr_info("AMD-Vi: X2APIC enabled\n"); | 1867 | pr_info("X2APIC enabled\n"); |
1865 | } | 1868 | } |
1866 | } | 1869 | } |
1867 | 1870 | ||
@@ -2375,7 +2378,7 @@ static bool __init check_ioapic_information(void) | |||
2375 | 2378 | ||
2376 | devid = get_ioapic_devid(id); | 2379 | devid = get_ioapic_devid(id); |
2377 | if (devid < 0) { | 2380 | if (devid < 0) { |
2378 | pr_err("%sAMD-Vi: IOAPIC[%d] not in IVRS table\n", | 2381 | pr_err("%s: IOAPIC[%d] not in IVRS table\n", |
2379 | fw_bug, id); | 2382 | fw_bug, id); |
2380 | ret = false; | 2383 | ret = false; |
2381 | } else if (devid == IOAPIC_SB_DEVID) { | 2384 | } else if (devid == IOAPIC_SB_DEVID) { |
@@ -2393,11 +2396,11 @@ static bool __init check_ioapic_information(void) | |||
2393 | * when the BIOS is buggy and provides us the wrong | 2396 | * when the BIOS is buggy and provides us the wrong |
2394 | * device id for the IOAPIC in the system. | 2397 | * device id for the IOAPIC in the system. |
2395 | */ | 2398 | */ |
2396 | pr_err("%sAMD-Vi: No southbridge IOAPIC found\n", fw_bug); | 2399 | pr_err("%s: No southbridge IOAPIC found\n", fw_bug); |
2397 | } | 2400 | } |
2398 | 2401 | ||
2399 | if (!ret) | 2402 | if (!ret) |
2400 | pr_err("AMD-Vi: Disabling interrupt remapping\n"); | 2403 | pr_err("Disabling interrupt remapping\n"); |
2401 | 2404 | ||
2402 | return ret; | 2405 | return ret; |
2403 | } | 2406 | } |
@@ -2452,7 +2455,7 @@ static int __init early_amd_iommu_init(void) | |||
2452 | return -ENODEV; | 2455 | return -ENODEV; |
2453 | else if (ACPI_FAILURE(status)) { | 2456 | else if (ACPI_FAILURE(status)) { |
2454 | const char *err = acpi_format_exception(status); | 2457 | const char *err = acpi_format_exception(status); |
2455 | pr_err("AMD-Vi: IVRS table error: %s\n", err); | 2458 | pr_err("IVRS table error: %s\n", err); |
2456 | return -EINVAL; | 2459 | return -EINVAL; |
2457 | } | 2460 | } |
2458 | 2461 | ||
@@ -2605,7 +2608,7 @@ static bool detect_ivrs(void) | |||
2605 | return false; | 2608 | return false; |
2606 | else if (ACPI_FAILURE(status)) { | 2609 | else if (ACPI_FAILURE(status)) { |
2607 | const char *err = acpi_format_exception(status); | 2610 | const char *err = acpi_format_exception(status); |
2608 | pr_err("AMD-Vi: IVRS table error: %s\n", err); | 2611 | pr_err("IVRS table error: %s\n", err); |
2609 | return false; | 2612 | return false; |
2610 | } | 2613 | } |
2611 | 2614 | ||
@@ -2640,7 +2643,7 @@ static int __init state_next(void) | |||
2640 | ret = early_amd_iommu_init(); | 2643 | ret = early_amd_iommu_init(); |
2641 | init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; | 2644 | init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; |
2642 | if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) { | 2645 | if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) { |
2643 | pr_info("AMD-Vi: AMD IOMMU disabled on kernel command-line\n"); | 2646 | pr_info("AMD IOMMU disabled on kernel command-line\n"); |
2644 | free_dma_resources(); | 2647 | free_dma_resources(); |
2645 | free_iommu_resources(); | 2648 | free_iommu_resources(); |
2646 | init_state = IOMMU_CMDLINE_DISABLED; | 2649 | init_state = IOMMU_CMDLINE_DISABLED; |
@@ -2787,7 +2790,7 @@ static bool amd_iommu_sme_check(void) | |||
2787 | (boot_cpu_data.microcode <= 0x080011ff)) | 2790 | (boot_cpu_data.microcode <= 0x080011ff)) |
2788 | return true; | 2791 | return true; |
2789 | 2792 | ||
2790 | pr_notice("AMD-Vi: IOMMU not currently supported when SME is active\n"); | 2793 | pr_notice("IOMMU not currently supported when SME is active\n"); |
2791 | 2794 | ||
2792 | return false; | 2795 | return false; |
2793 | } | 2796 | } |
@@ -2872,12 +2875,12 @@ static int __init parse_ivrs_ioapic(char *str) | |||
2872 | ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); | 2875 | ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); |
2873 | 2876 | ||
2874 | if (ret != 4) { | 2877 | if (ret != 4) { |
2875 | pr_err("AMD-Vi: Invalid command line: ivrs_ioapic%s\n", str); | 2878 | pr_err("Invalid command line: ivrs_ioapic%s\n", str); |
2876 | return 1; | 2879 | return 1; |
2877 | } | 2880 | } |
2878 | 2881 | ||
2879 | if (early_ioapic_map_size == EARLY_MAP_SIZE) { | 2882 | if (early_ioapic_map_size == EARLY_MAP_SIZE) { |
2880 | pr_err("AMD-Vi: Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n", | 2883 | pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n", |
2881 | str); | 2884 | str); |
2882 | return 1; | 2885 | return 1; |
2883 | } | 2886 | } |
@@ -2902,12 +2905,12 @@ static int __init parse_ivrs_hpet(char *str) | |||
2902 | ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); | 2905 | ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); |
2903 | 2906 | ||
2904 | if (ret != 4) { | 2907 | if (ret != 4) { |
2905 | pr_err("AMD-Vi: Invalid command line: ivrs_hpet%s\n", str); | 2908 | pr_err("Invalid command line: ivrs_hpet%s\n", str); |
2906 | return 1; | 2909 | return 1; |
2907 | } | 2910 | } |
2908 | 2911 | ||
2909 | if (early_hpet_map_size == EARLY_MAP_SIZE) { | 2912 | if (early_hpet_map_size == EARLY_MAP_SIZE) { |
2910 | pr_err("AMD-Vi: Early HPET map overflow - ignoring ivrs_hpet%s\n", | 2913 | pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n", |
2911 | str); | 2914 | str); |
2912 | return 1; | 2915 | return 1; |
2913 | } | 2916 | } |
@@ -2932,7 +2935,7 @@ static int __init parse_ivrs_acpihid(char *str) | |||
2932 | 2935 | ||
2933 | ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid); | 2936 | ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid); |
2934 | if (ret != 4) { | 2937 | if (ret != 4) { |
2935 | pr_err("AMD-Vi: Invalid command line: ivrs_acpihid(%s)\n", str); | 2938 | pr_err("Invalid command line: ivrs_acpihid(%s)\n", str); |
2936 | return 1; | 2939 | return 1; |
2937 | } | 2940 | } |
2938 | 2941 | ||
@@ -2941,7 +2944,7 @@ static int __init parse_ivrs_acpihid(char *str) | |||
2941 | uid = p; | 2944 | uid = p; |
2942 | 2945 | ||
2943 | if (!hid || !(*hid) || !uid) { | 2946 | if (!hid || !(*hid) || !uid) { |
2944 | pr_err("AMD-Vi: Invalid command line: hid or uid\n"); | 2947 | pr_err("Invalid command line: hid or uid\n"); |
2945 | return 1; | 2948 | return 1; |
2946 | } | 2949 | } |
2947 | 2950 | ||