Introduce new IOMMU commands for vIOMMU for resetting virtualized MMIO registers of a particular guest. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> --- drivers/iommu/amd/amd_iommu_types.h | 1 + drivers/iommu/amd/iommu.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index d832e0c36a21..aa16a7079b5c 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -200,6 +200,7 @@ #define CMD_INV_IRT 0x05 #define CMD_COMPLETE_PPR 0x07 #define CMD_INV_ALL 0x08 +#define CMD_RESET_VMMIO 0x0A #define CMD_COMPL_WAIT_STORE_MASK 0x01 #define CMD_COMPL_WAIT_INT_MASK 0x02 diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index efced59ba8a5..b5c62bc8249c 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1133,6 +1133,18 @@ static void build_inv_irt(struct iommu_cmd *cmd, u16 devid) CMD_SET_TYPE(cmd, CMD_INV_IRT); } +static void build_reset_vmmio(struct iommu_cmd *cmd, u16 guestId, + bool vcmd, bool all) +{ + memset(cmd, 0, sizeof(*cmd)); + cmd->data[0] = guestId; + if (all) + cmd->data[0] |= (1 << 28); + if (vcmd) + cmd->data[0] |= (1 << 31); + CMD_SET_TYPE(cmd, CMD_RESET_VMMIO); +} + /* * Writes the command to the IOMMUs command buffer and informs the * hardware about the new command. @@ -1315,6 +1327,16 @@ void iommu_flush_all_caches(struct amd_iommu *iommu) } } +void iommu_reset_vmmio(struct amd_iommu *iommu, u16 guestId) +{ + struct iommu_cmd cmd; + + build_reset_vmmio(&cmd, guestId, 1, 1); + + iommu_queue_command(iommu, &cmd); + iommu_completion_wait(iommu); +} + /* * Command send function for flushing on-device TLB */ -- 2.34.1