diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2012-06-21 16:46:04 +0200 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-09-28 17:41:22 +0200 |
commit | 7ef2798deb695f112f25e348b199dca79eb1ea68 (patch) | |
tree | 04564334f60fd0b4d7d377f164297dcc39c026e5 /drivers/iommu/amd_iommu.c | |
parent | iommu/amd: Make sure IOMMU is not considered to translate itself (diff) | |
download | linux-7ef2798deb695f112f25e348b199dca79eb1ea68.tar.xz linux-7ef2798deb695f112f25e348b199dca79eb1ea68.zip |
iommu/amd: Add IRTE invalidation routine
Add routine to invalidate the IOMMU cache for interupt
translations. Also include the IRTE caches when flushing all
IOMMU caches.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b6a8079ff7bb..e27b354c3e9b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -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); } } |