Commit 318fe782 authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Joerg Roedel

IOMMU, AMD Family15h Model10-1Fh erratum 746 Workaround

The IOMMU may stop processing page translations due to a perceived lack
of credits for writing upstream peripheral page service request (PPR)
or event logs. If the L2B miscellaneous clock gating feature is enabled
the IOMMU does not properly register credits after the log request has
completed, leading to a potential system hang.

BIOSes are supposed to disable L2B micellaneous clock gating by setting
L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b. This
patch corrects that for those which do not enable this workaround.
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Acked-by: default avatarBorislav Petkov <bp@suse.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJoerg Roedel <joro@8bytes.org>
parent 949db153
...@@ -974,6 +974,38 @@ static void __init free_iommu_all(void) ...@@ -974,6 +974,38 @@ static void __init free_iommu_all(void)
} }
} }
/*
* Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations)
* Workaround:
* BIOS should disable L2B micellaneous clock gating by setting
* L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
*/
static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
{
u32 value;
if ((boot_cpu_data.x86 != 0x15) ||
(boot_cpu_data.x86_model < 0x10) ||
(boot_cpu_data.x86_model > 0x1f))
return;
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
pci_read_config_dword(iommu->dev, 0xf4, &value);
if (value & BIT(2))
return;
/* Select NB indirect register 0x90 and enable writing */
pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));
pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n",
dev_name(&iommu->dev->dev));
/* Clear the enable writing bit */
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
}
/* /*
* This function clues the initialization function for one IOMMU * This function clues the initialization function for one IOMMU
* together and also allocates the command buffer and programs the * together and also allocates the command buffer and programs the
...@@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu) ...@@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
iommu->stored_l2[i] = iommu_read_l2(iommu, i); iommu->stored_l2[i] = iommu_read_l2(iommu, i);
} }
amd_iommu_erratum_746_workaround(iommu);
return pci_enable_device(iommu->dev); return pci_enable_device(iommu->dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment