Commit 6a6aa2b7e47c725b5256ff0f7462fe1247cabf5a

Authored by Linus Torvalds

Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/…

…git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86/amd-iommu: Fix rounding-bug in __unmap_single
  x86/amd-iommu: Work around S3 BIOS bug
  x86/amd-iommu: Set iommu configuration flags in enable-loop
  x86, setup: Fix earlyprintk=serial,0x3f8,115200
  x86, setup: Fix earlyprintk=serial,ttyS0,115200

Showing 6 changed files Side-by-side Diff

arch/x86/boot/early_serial_console.c
... ... @@ -58,7 +58,19 @@
58 58 if (arg[pos] == ',')
59 59 pos++;
60 60  
61   - if (!strncmp(arg, "ttyS", 4)) {
  61 + /*
  62 + * make sure we have
  63 + * "serial,0x3f8,115200"
  64 + * "serial,ttyS0,115200"
  65 + * "ttyS0,115200"
  66 + */
  67 + if (pos == 7 && !strncmp(arg + pos, "0x", 2)) {
  68 + port = simple_strtoull(arg + pos, &e, 16);
  69 + if (port == 0 || arg + pos == e)
  70 + port = DEFAULT_SERIAL_PORT;
  71 + else
  72 + pos = e - arg;
  73 + } else if (!strncmp(arg + pos, "ttyS", 4)) {
62 74 static const int bases[] = { 0x3f8, 0x2f8 };
63 75 int idx = 0;
64 76  
arch/x86/include/asm/amd_iommu_proto.h
... ... @@ -38,5 +38,11 @@
38 38  
39 39 #endif /* !CONFIG_AMD_IOMMU_STATS */
40 40  
  41 +static inline bool is_rd890_iommu(struct pci_dev *pdev)
  42 +{
  43 + return (pdev->vendor == PCI_VENDOR_ID_ATI) &&
  44 + (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
  45 +}
  46 +
41 47 #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
arch/x86/include/asm/amd_iommu_types.h
... ... @@ -368,6 +368,9 @@
368 368 /* capabilities of that IOMMU read from ACPI */
369 369 u32 cap;
370 370  
  371 + /* flags read from acpi table */
  372 + u8 acpi_flags;
  373 +
371 374 /*
372 375 * Capability pointer. There could be more than one IOMMU per PCI
373 376 * device function if there are more than one AMD IOMMU capability
... ... @@ -411,6 +414,15 @@
411 414  
412 415 /* default dma_ops domain for that IOMMU */
413 416 struct dma_ops_domain *default_dom;
  417 +
  418 + /*
  419 + * This array is required to work around a potential BIOS bug.
  420 + * The BIOS may miss to restore parts of the PCI configuration
  421 + * space when the system resumes from S3. The result is that the
  422 + * IOMMU does not execute commands anymore which leads to system
  423 + * failure.
  424 + */
  425 + u32 cache_cfg[4];
414 426 };
415 427  
416 428 /*
arch/x86/kernel/amd_iommu.c
... ... @@ -1953,6 +1953,7 @@
1953 1953 size_t size,
1954 1954 int dir)
1955 1955 {
  1956 + dma_addr_t flush_addr;
1956 1957 dma_addr_t i, start;
1957 1958 unsigned int pages;
1958 1959  
... ... @@ -1960,6 +1961,7 @@
1960 1961 (dma_addr + size > dma_dom->aperture_size))
1961 1962 return;
1962 1963  
  1964 + flush_addr = dma_addr;
1963 1965 pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
1964 1966 dma_addr &= PAGE_MASK;
1965 1967 start = dma_addr;
... ... @@ -1974,7 +1976,7 @@
1974 1976 dma_ops_free_addresses(dma_dom, dma_addr, pages);
1975 1977  
1976 1978 if (amd_iommu_unmap_flush || dma_dom->need_flush) {
1977   - iommu_flush_pages(&dma_dom->domain, dma_addr, size);
  1979 + iommu_flush_pages(&dma_dom->domain, flush_addr, size);
1978 1980 dma_dom->need_flush = false;
1979 1981 }
1980 1982 }
arch/x86/kernel/amd_iommu_init.c
... ... @@ -632,6 +632,13 @@
632 632 iommu->last_device = calc_devid(MMIO_GET_BUS(range),
633 633 MMIO_GET_LD(range));
634 634 iommu->evt_msi_num = MMIO_MSI_NUM(misc);
  635 +
  636 + if (is_rd890_iommu(iommu->dev)) {
  637 + pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
  638 + pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
  639 + pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
  640 + pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
  641 + }
635 642 }
636 643  
637 644 /*
638 645  
639 646  
640 647  
... ... @@ -649,31 +656,11 @@
649 656 struct ivhd_entry *e;
650 657  
651 658 /*
652   - * First set the recommended feature enable bits from ACPI
653   - * into the IOMMU control registers
  659 + * First save the recommended feature enable bits from ACPI
654 660 */
655   - h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
656   - iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
657   - iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
  661 + iommu->acpi_flags = h->flags;
658 662  
659   - h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
660   - iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
661   - iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
662   -
663   - h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
664   - iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
665   - iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
666   -
667   - h->flags & IVHD_FLAG_ISOC_EN_MASK ?
668   - iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
669   - iommu_feature_disable(iommu, CONTROL_ISOC_EN);
670   -
671 663 /*
672   - * make IOMMU memory accesses cache coherent
673   - */
674   - iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
675   -
676   - /*
677 664 * Done. Now parse the device entries
678 665 */
679 666 p += sizeof(struct ivhd_header);
... ... @@ -1116,6 +1103,40 @@
1116 1103 }
1117 1104 }
1118 1105  
  1106 +static void iommu_init_flags(struct amd_iommu *iommu)
  1107 +{
  1108 + iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
  1109 + iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
  1110 + iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
  1111 +
  1112 + iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
  1113 + iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
  1114 + iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
  1115 +
  1116 + iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
  1117 + iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
  1118 + iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
  1119 +
  1120 + iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
  1121 + iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
  1122 + iommu_feature_disable(iommu, CONTROL_ISOC_EN);
  1123 +
  1124 + /*
  1125 + * make IOMMU memory accesses cache coherent
  1126 + */
  1127 + iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
  1128 +}
  1129 +
  1130 +static void iommu_apply_quirks(struct amd_iommu *iommu)
  1131 +{
  1132 + if (is_rd890_iommu(iommu->dev)) {
  1133 + pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
  1134 + pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
  1135 + pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
  1136 + pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
  1137 + }
  1138 +}
  1139 +
1119 1140 /*
1120 1141 * This function finally enables all IOMMUs found in the system after
1121 1142 * they have been initialized
... ... @@ -1126,6 +1147,8 @@
1126 1147  
1127 1148 for_each_iommu(iommu) {
1128 1149 iommu_disable(iommu);
  1150 + iommu_apply_quirks(iommu);
  1151 + iommu_init_flags(iommu);
1129 1152 iommu_set_device_table(iommu);
1130 1153 iommu_enable_command_buffer(iommu);
1131 1154 iommu_enable_event_buffer(iommu);
include/linux/pci_ids.h
... ... @@ -393,6 +393,9 @@
393 393 #define PCI_DEVICE_ID_VLSI_82C147 0x0105
394 394 #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
395 395  
  396 +/* AMD RD890 Chipset */
  397 +#define PCI_DEVICE_ID_RD890_IOMMU 0x5a23
  398 +
396 399 #define PCI_VENDOR_ID_ADL 0x1005
397 400 #define PCI_DEVICE_ID_ADL_2301 0x2301
398 401