|
@@ -902,6 +902,13 @@ static void build_inv_all(struct iommu_cmd *cmd)
|
|
|
CMD_SET_TYPE(cmd, CMD_INV_ALL);
|
|
|
}
|
|
|
|
|
|
+static void build_inv_irt(struct iommu_cmd *cmd, u16 devid)
|
|
|
+{
|
|
|
+ memset(cmd, 0, sizeof(*cmd));
|
|
|
+ cmd->data[0] = devid;
|
|
|
+ CMD_SET_TYPE(cmd, CMD_INV_IRT);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Writes the command to the IOMMUs command buffer and informs the
|
|
|
* hardware about the new command.
|
|
@@ -1023,12 +1030,32 @@ static void iommu_flush_all(struct amd_iommu *iommu)
|
|
|
iommu_completion_wait(iommu);
|
|
|
}
|
|
|
|
|
|
+static void iommu_flush_irt(struct amd_iommu *iommu, u16 devid)
|
|
|
+{
|
|
|
+ struct iommu_cmd cmd;
|
|
|
+
|
|
|
+ build_inv_irt(&cmd, devid);
|
|
|
+
|
|
|
+ iommu_queue_command(iommu, &cmd);
|
|
|
+}
|
|
|
+
|
|
|
+static void iommu_flush_irt_all(struct amd_iommu *iommu)
|
|
|
+{
|
|
|
+ u32 devid;
|
|
|
+
|
|
|
+ for (devid = 0; devid <= MAX_DEV_TABLE_ENTRIES; devid++)
|
|
|
+ iommu_flush_irt(iommu, devid);
|
|
|
+
|
|
|
+ iommu_completion_wait(iommu);
|
|
|
+}
|
|
|
+
|
|
|
void iommu_flush_all_caches(struct amd_iommu *iommu)
|
|
|
{
|
|
|
if (iommu_feature(iommu, FEATURE_IA)) {
|
|
|
iommu_flush_all(iommu);
|
|
|
} else {
|
|
|
iommu_flush_dte_all(iommu);
|
|
|
+ iommu_flush_irt_all(iommu);
|
|
|
iommu_flush_tlb_all(iommu);
|
|
|
}
|
|
|
}
|