Skip to content

Commit de28a65

Browse files
committed
Merge tag 'iommu-fixes-v5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fixes from Joerg Roedel: - Intel VT-d fixes: - RCU list handling fixes - Replace WARN_TAINT with pr_warn + add_taint for reporting firmware issues - DebugFS fixes - Fix for hugepage handling in iova_to_phys implementation - Fix for handling VMD devices, which have a domain number which doesn't fit into 16 bits - Warning message fix - MSI allocation fix for iommu-dma code - Sign-extension fix for io page-table code - Fix for AMD-Vi to properly update the is-running bit when AVIC is used * tag 'iommu-fixes-v5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/vt-d: Populate debugfs if IOMMUs are detected iommu/amd: Fix IOMMU AVIC not properly update the is_run bit in IRTE iommu/vt-d: Ignore devices with out-of-spec domain number iommu/vt-d: Fix the wrong printing in RHSA parsing iommu/vt-d: Fix debugfs register reads iommu/vt-d: quirk_ioat_snb_local_iommu: replace WARN_TAINT with pr_warn + add_taint iommu/vt-d: dmar_parse_one_rmrr: replace WARN_TAINT with pr_warn + add_taint iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint iommu/vt-d: Silence RCU-list debugging warnings iommu/vt-d: Fix RCU-list bugs in intel_iommu_init() iommu/dma: Fix MSI reservation allocation iommu/io-pgtable-arm: Fix IOVA validation for 32-bit iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page iommu/vt-d: Fix RCU list debugging warnings
2 parents d3dca69 + 1da8347 commit de28a65

File tree

8 files changed

+94
-49
lines changed

8 files changed

+94
-49
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3826,7 +3826,7 @@ int amd_iommu_activate_guest_mode(void *data)
38263826
entry->lo.fields_vapic.ga_tag = ir_data->ga_tag;
38273827

38283828
return modify_irte_ga(ir_data->irq_2_irte.devid,
3829-
ir_data->irq_2_irte.index, entry, NULL);
3829+
ir_data->irq_2_irte.index, entry, ir_data);
38303830
}
38313831
EXPORT_SYMBOL(amd_iommu_activate_guest_mode);
38323832

@@ -3852,7 +3852,7 @@ int amd_iommu_deactivate_guest_mode(void *data)
38523852
APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
38533853

38543854
return modify_irte_ga(ir_data->irq_2_irte.devid,
3855-
ir_data->irq_2_irte.index, entry, NULL);
3855+
ir_data->irq_2_irte.index, entry, ir_data);
38563856
}
38573857
EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode);
38583858

drivers/iommu/dma-iommu.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
177177
start -= iova_offset(iovad, start);
178178
num_pages = iova_align(iovad, end - start) >> iova_shift(iovad);
179179

180-
msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL);
181-
if (!msi_page)
182-
return -ENOMEM;
183-
184180
for (i = 0; i < num_pages; i++) {
185-
msi_page[i].phys = start;
186-
msi_page[i].iova = start;
187-
INIT_LIST_HEAD(&msi_page[i].list);
188-
list_add(&msi_page[i].list, &cookie->msi_page_list);
181+
msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL);
182+
if (!msi_page)
183+
return -ENOMEM;
184+
185+
msi_page->phys = start;
186+
msi_page->iova = start;
187+
INIT_LIST_HEAD(&msi_page->list);
188+
list_add(&msi_page->list, &cookie->msi_page_list);
189189
start += iovad->granule;
190190
}
191191

drivers/iommu/dmar.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/slab.h>
2929
#include <linux/iommu.h>
3030
#include <linux/numa.h>
31+
#include <linux/limits.h>
3132
#include <asm/irq_remapping.h>
3233
#include <asm/iommu_table.h>
3334

@@ -128,6 +129,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
128129

129130
BUG_ON(dev->is_virtfn);
130131

132+
/*
133+
* Ignore devices that have a domain number higher than what can
134+
* be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
135+
*/
136+
if (pci_domain_nr(dev->bus) > U16_MAX)
137+
return NULL;
138+
131139
/* Only generate path[] for device addition event */
132140
if (event == BUS_NOTIFY_ADD_DEVICE)
133141
for (tmp = dev; tmp; tmp = tmp->bus->self)
@@ -363,7 +371,8 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd)
363371
{
364372
struct dmar_drhd_unit *dmaru;
365373

366-
list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list)
374+
list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list,
375+
dmar_rcu_check())
367376
if (dmaru->segment == drhd->segment &&
368377
dmaru->reg_base_addr == drhd->address)
369378
return dmaru;
@@ -440,12 +449,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header,
440449

441450
/* Check for NUL termination within the designated length */
442451
if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
443-
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
452+
pr_warn(FW_BUG
444453
"Your BIOS is broken; ANDD object name is not NUL-terminated\n"
445454
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
446455
dmi_get_system_info(DMI_BIOS_VENDOR),
447456
dmi_get_system_info(DMI_BIOS_VERSION),
448457
dmi_get_system_info(DMI_PRODUCT_VERSION));
458+
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
449459
return -EINVAL;
450460
}
451461
pr_info("ANDD device: %x name: %s\n", andd->device_number,
@@ -471,14 +481,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)
471481
return 0;
472482
}
473483
}
474-
WARN_TAINT(
475-
1, TAINT_FIRMWARE_WORKAROUND,
484+
pr_warn(FW_BUG
476485
"Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
477486
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
478-
drhd->reg_base_addr,
487+
rhsa->base_address,
479488
dmi_get_system_info(DMI_BIOS_VENDOR),
480489
dmi_get_system_info(DMI_BIOS_VERSION),
481490
dmi_get_system_info(DMI_PRODUCT_VERSION));
491+
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
482492

483493
return 0;
484494
}
@@ -827,14 +837,14 @@ int __init dmar_table_init(void)
827837

828838
static void warn_invalid_dmar(u64 addr, const char *message)
829839
{
830-
WARN_TAINT_ONCE(
831-
1, TAINT_FIRMWARE_WORKAROUND,
840+
pr_warn_once(FW_BUG
832841
"Your BIOS is broken; DMAR reported at address %llx%s!\n"
833842
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
834843
addr, message,
835844
dmi_get_system_info(DMI_BIOS_VENDOR),
836845
dmi_get_system_info(DMI_BIOS_VERSION),
837846
dmi_get_system_info(DMI_PRODUCT_VERSION));
847+
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
838848
}
839849

840850
static int __ref

drivers/iommu/intel-iommu-debugfs.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,42 @@ struct iommu_regset {
3333

3434
#define IOMMU_REGSET_ENTRY(_reg_) \
3535
{ DMAR_##_reg_##_REG, __stringify(_reg_) }
36-
static const struct iommu_regset iommu_regs[] = {
36+
37+
static const struct iommu_regset iommu_regs_32[] = {
3738
IOMMU_REGSET_ENTRY(VER),
38-
IOMMU_REGSET_ENTRY(CAP),
39-
IOMMU_REGSET_ENTRY(ECAP),
4039
IOMMU_REGSET_ENTRY(GCMD),
4140
IOMMU_REGSET_ENTRY(GSTS),
42-
IOMMU_REGSET_ENTRY(RTADDR),
43-
IOMMU_REGSET_ENTRY(CCMD),
4441
IOMMU_REGSET_ENTRY(FSTS),
4542
IOMMU_REGSET_ENTRY(FECTL),
4643
IOMMU_REGSET_ENTRY(FEDATA),
4744
IOMMU_REGSET_ENTRY(FEADDR),
4845
IOMMU_REGSET_ENTRY(FEUADDR),
49-
IOMMU_REGSET_ENTRY(AFLOG),
5046
IOMMU_REGSET_ENTRY(PMEN),
5147
IOMMU_REGSET_ENTRY(PLMBASE),
5248
IOMMU_REGSET_ENTRY(PLMLIMIT),
49+
IOMMU_REGSET_ENTRY(ICS),
50+
IOMMU_REGSET_ENTRY(PRS),
51+
IOMMU_REGSET_ENTRY(PECTL),
52+
IOMMU_REGSET_ENTRY(PEDATA),
53+
IOMMU_REGSET_ENTRY(PEADDR),
54+
IOMMU_REGSET_ENTRY(PEUADDR),
55+
};
56+
57+
static const struct iommu_regset iommu_regs_64[] = {
58+
IOMMU_REGSET_ENTRY(CAP),
59+
IOMMU_REGSET_ENTRY(ECAP),
60+
IOMMU_REGSET_ENTRY(RTADDR),
61+
IOMMU_REGSET_ENTRY(CCMD),
62+
IOMMU_REGSET_ENTRY(AFLOG),
5363
IOMMU_REGSET_ENTRY(PHMBASE),
5464
IOMMU_REGSET_ENTRY(PHMLIMIT),
5565
IOMMU_REGSET_ENTRY(IQH),
5666
IOMMU_REGSET_ENTRY(IQT),
5767
IOMMU_REGSET_ENTRY(IQA),
58-
IOMMU_REGSET_ENTRY(ICS),
5968
IOMMU_REGSET_ENTRY(IRTA),
6069
IOMMU_REGSET_ENTRY(PQH),
6170
IOMMU_REGSET_ENTRY(PQT),
6271
IOMMU_REGSET_ENTRY(PQA),
63-
IOMMU_REGSET_ENTRY(PRS),
64-
IOMMU_REGSET_ENTRY(PECTL),
65-
IOMMU_REGSET_ENTRY(PEDATA),
66-
IOMMU_REGSET_ENTRY(PEADDR),
67-
IOMMU_REGSET_ENTRY(PEUADDR),
6872
IOMMU_REGSET_ENTRY(MTRRCAP),
6973
IOMMU_REGSET_ENTRY(MTRRDEF),
7074
IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000),
@@ -127,10 +131,16 @@ static int iommu_regset_show(struct seq_file *m, void *unused)
127131
* by adding the offset to the pointer (virtual address).
128132
*/
129133
raw_spin_lock_irqsave(&iommu->register_lock, flag);
130-
for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) {
131-
value = dmar_readq(iommu->reg + iommu_regs[i].offset);
134+
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) {
135+
value = dmar_readl(iommu->reg + iommu_regs_32[i].offset);
136+
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
137+
iommu_regs_32[i].regs, iommu_regs_32[i].offset,
138+
value);
139+
}
140+
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) {
141+
value = dmar_readq(iommu->reg + iommu_regs_64[i].offset);
132142
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
133-
iommu_regs[i].regs, iommu_regs[i].offset,
143+
iommu_regs_64[i].regs, iommu_regs_64[i].offset,
134144
value);
135145
}
136146
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
@@ -272,9 +282,16 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused)
272282
{
273283
struct dmar_drhd_unit *drhd;
274284
struct intel_iommu *iommu;
285+
u32 sts;
275286

276287
rcu_read_lock();
277288
for_each_active_iommu(iommu, drhd) {
289+
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
290+
if (!(sts & DMA_GSTS_TES)) {
291+
seq_printf(m, "DMA Remapping is not enabled on %s\n",
292+
iommu->name);
293+
continue;
294+
}
278295
root_tbl_walk(m, iommu);
279296
seq_putc(m, '\n');
280297
}
@@ -415,6 +432,7 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused)
415432
struct dmar_drhd_unit *drhd;
416433
struct intel_iommu *iommu;
417434
u64 irta;
435+
u32 sts;
418436

419437
rcu_read_lock();
420438
for_each_active_iommu(iommu, drhd) {
@@ -424,7 +442,8 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused)
424442
seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n",
425443
iommu->name);
426444

427-
if (iommu->ir_table) {
445+
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
446+
if (iommu->ir_table && (sts & DMA_GSTS_IRES)) {
428447
irta = virt_to_phys(iommu->ir_table->base);
429448
seq_printf(m, " IR table address:%llx\n", irta);
430449
ir_tbl_remap_entry_show(m, iommu);

drivers/iommu/intel-iommu.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4261,10 +4261,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
42614261

42624262
/* we know that the this iommu should be at offset 0xa000 from vtbar */
42634263
drhd = dmar_find_matched_drhd_unit(pdev);
4264-
if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
4265-
TAINT_FIRMWARE_WORKAROUND,
4266-
"BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
4264+
if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
4265+
pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
4266+
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
42674267
pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
4268+
}
42684269
}
42694270
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
42704271

@@ -4460,14 +4461,16 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
44604461
struct dmar_rmrr_unit *rmrru;
44614462

44624463
rmrr = (struct acpi_dmar_reserved_memory *)header;
4463-
if (rmrr_sanity_check(rmrr))
4464-
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
4464+
if (rmrr_sanity_check(rmrr)) {
4465+
pr_warn(FW_BUG
44654466
"Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
44664467
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
44674468
rmrr->base_address, rmrr->end_address,
44684469
dmi_get_system_info(DMI_BIOS_VENDOR),
44694470
dmi_get_system_info(DMI_BIOS_VERSION),
44704471
dmi_get_system_info(DMI_PRODUCT_VERSION));
4472+
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
4473+
}
44714474

44724475
rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
44734476
if (!rmrru)
@@ -5130,6 +5133,9 @@ int __init intel_iommu_init(void)
51305133

51315134
down_write(&dmar_global_lock);
51325135

5136+
if (!no_iommu)
5137+
intel_iommu_debugfs_init();
5138+
51335139
if (no_iommu || dmar_disabled) {
51345140
/*
51355141
* We exit the function here to ensure IOMMU's remapping and
@@ -5193,13 +5199,15 @@ int __init intel_iommu_init(void)
51935199

51945200
init_iommu_pm_ops();
51955201

5202+
down_read(&dmar_global_lock);
51965203
for_each_active_iommu(iommu, drhd) {
51975204
iommu_device_sysfs_add(&iommu->iommu, NULL,
51985205
intel_iommu_groups,
51995206
"%s", iommu->name);
52005207
iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
52015208
iommu_device_register(&iommu->iommu);
52025209
}
5210+
up_read(&dmar_global_lock);
52035211

52045212
bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
52055213
if (si_domain && !hw_pass_through)
@@ -5210,7 +5218,6 @@ int __init intel_iommu_init(void)
52105218
down_read(&dmar_global_lock);
52115219
if (probe_acpi_namespace_devices())
52125220
pr_warn("ACPI name space devices didn't probe correctly\n");
5213-
up_read(&dmar_global_lock);
52145221

52155222
/* Finally, we enable the DMA remapping hardware. */
52165223
for_each_iommu(iommu, drhd) {
@@ -5219,10 +5226,11 @@ int __init intel_iommu_init(void)
52195226

52205227
iommu_disable_protect_mem_regions(iommu);
52215228
}
5229+
up_read(&dmar_global_lock);
5230+
52225231
pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
52235232

52245233
intel_iommu_enabled = 1;
5225-
intel_iommu_debugfs_init();
52265234

52275235
return 0;
52285236

@@ -5700,8 +5708,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
57005708
u64 phys = 0;
57015709

57025710
pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
5703-
if (pte)
5704-
phys = dma_pte_addr(pte);
5711+
if (pte && dma_pte_present(pte))
5712+
phys = dma_pte_addr(pte) +
5713+
(iova & (BIT_MASK(level_to_offset_bits(level) +
5714+
VTD_PAGE_SHIFT) - 1));
57055715

57065716
return phys;
57075717
}

drivers/iommu/io-pgtable-arm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
468468
arm_lpae_iopte *ptep = data->pgd;
469469
int ret, lvl = data->start_level;
470470
arm_lpae_iopte prot;
471-
long iaext = (long)iova >> cfg->ias;
471+
long iaext = (s64)iova >> cfg->ias;
472472

473473
/* If no access, then nothing to do */
474474
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
@@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
645645
struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
646646
struct io_pgtable_cfg *cfg = &data->iop.cfg;
647647
arm_lpae_iopte *ptep = data->pgd;
648-
long iaext = (long)iova >> cfg->ias;
648+
long iaext = (s64)iova >> cfg->ias;
649649

650650
if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size))
651651
return 0;

include/linux/dmar.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,23 @@ struct dmar_pci_notify_info {
6969
extern struct rw_semaphore dmar_global_lock;
7070
extern struct list_head dmar_drhd_units;
7171

72-
#define for_each_drhd_unit(drhd) \
73-
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)
72+
#define for_each_drhd_unit(drhd) \
73+
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \
74+
dmar_rcu_check())
7475

7576
#define for_each_active_drhd_unit(drhd) \
76-
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
77+
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \
78+
dmar_rcu_check()) \
7779
if (drhd->ignored) {} else
7880

7981
#define for_each_active_iommu(i, drhd) \
80-
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
82+
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \
83+
dmar_rcu_check()) \
8184
if (i=drhd->iommu, drhd->ignored) {} else
8285

8386
#define for_each_iommu(i, drhd) \
84-
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
87+
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \
88+
dmar_rcu_check()) \
8589
if (i=drhd->iommu, 0) {} else
8690

8791
static inline bool dmar_rcu_check(void)

include/linux/intel-iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@
123123

124124
#define dmar_readq(a) readq(a)
125125
#define dmar_writeq(a,v) writeq(v,a)
126+
#define dmar_readl(a) readl(a)
127+
#define dmar_writel(a, v) writel(v, a)
126128

127129
#define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4)
128130
#define DMAR_VER_MINOR(v) ((v) & 0x0f)

0 commit comments

Comments
 (0)