Skip to content

Commit d41ce7b

Browse files
aikmpe
authored andcommitted
powerpc/powernv/npu: Do not try invalidating 32bit table when 64bit table is enabled
GPUs and the corresponding NVLink bridges get different PEs as they have separate translation validation entries (TVEs). We put these PEs to the same IOMMU group so they cannot be passed through separately. So the iommu_table_group_ops::set_window/unset_window for GPUs do set tables to the NPU PEs as well which means that iommu_table's list of attached PEs (iommu_table_group_link) has both GPU and NPU PEs linked. This list is used for TCE cache invalidation. The problem is that NPU PE has just a single TVE and can be programmed to point to 32bit or 64bit windows while GPU PE has two (as any other PCI device). So we end up having an 32bit iommu_table struct linked to both PEs even though only the 64bit TCE table cache can be invalidated on NPU. And a relatively recent skiboot detects this and prints errors. This changes GPU's iommu_table_group_ops::set_window/unset_window to make sure that NPU PE is only linked to the table actually used by the hardware. If there are two tables used by an IOMMU group, the NPU PE will use the last programmed one which with the current use scenarios is expected to be a 64bit one. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent b574df9 commit d41ce7b

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

arch/powerpc/platforms/powernv/pci-ioda.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,14 +2681,23 @@ static struct pnv_ioda_pe *gpe_table_group_to_npe(
26812681
static long pnv_pci_ioda2_npu_set_window(struct iommu_table_group *table_group,
26822682
int num, struct iommu_table *tbl)
26832683
{
2684+
struct pnv_ioda_pe *npe = gpe_table_group_to_npe(table_group);
2685+
int num2 = (num == 0) ? 1 : 0;
26842686
long ret = pnv_pci_ioda2_set_window(table_group, num, tbl);
26852687

26862688
if (ret)
26872689
return ret;
26882690

2689-
ret = pnv_npu_set_window(gpe_table_group_to_npe(table_group), num, tbl);
2690-
if (ret)
2691+
if (table_group->tables[num2])
2692+
pnv_npu_unset_window(npe, num2);
2693+
2694+
ret = pnv_npu_set_window(npe, num, tbl);
2695+
if (ret) {
26912696
pnv_pci_ioda2_unset_window(table_group, num);
2697+
if (table_group->tables[num2])
2698+
pnv_npu_set_window(npe, num2,
2699+
table_group->tables[num2]);
2700+
}
26922701

26932702
return ret;
26942703
}
@@ -2697,12 +2706,24 @@ static long pnv_pci_ioda2_npu_unset_window(
26972706
struct iommu_table_group *table_group,
26982707
int num)
26992708
{
2709+
struct pnv_ioda_pe *npe = gpe_table_group_to_npe(table_group);
2710+
int num2 = (num == 0) ? 1 : 0;
27002711
long ret = pnv_pci_ioda2_unset_window(table_group, num);
27012712

27022713
if (ret)
27032714
return ret;
27042715

2705-
return pnv_npu_unset_window(gpe_table_group_to_npe(table_group), num);
2716+
if (!npe->table_group.tables[num])
2717+
return 0;
2718+
2719+
ret = pnv_npu_unset_window(npe, num);
2720+
if (ret)
2721+
return ret;
2722+
2723+
if (table_group->tables[num2])
2724+
ret = pnv_npu_set_window(npe, num2, table_group->tables[num2]);
2725+
2726+
return ret;
27062727
}
27072728

27082729
static void pnv_ioda2_npu_take_ownership(struct iommu_table_group *table_group)

0 commit comments

Comments
 (0)