Provide a helper and use that to issue the invalidation cmd to host SMMUv3. We only issue one cmd at a time for now.
Support for batching of commands will be added later after analysing the impact. Reviewed-by: Jonathan Cameron <[email protected]> Tested-by: Zhangfei Gao <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Eric Auger <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/smmuv3-accel.c | 36 ++++++++++++++++++++++++++++++++++++ hw/arm/smmuv3-accel.h | 8 ++++++++ hw/arm/smmuv3.c | 16 ++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 8f7c0cda05..a7291e75f1 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -233,6 +233,42 @@ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, return all_ok; } +/* + * This issues the invalidation cmd to the host SMMUv3. + * + * sdev is non-NULL for SID based invalidations (e.g. CFGI_CD), and NULL for + * non SID invalidations such as SMMU_CMD_TLBI_NH_ASID and SMMU_CMD_TLBI_NH_VA. + */ +bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev, + Error **errp) +{ + SMMUv3State *s = ARM_SMMUV3(bs); + SMMUv3AccelState *accel = s->s_accel; + uint32_t entry_num = 1; + + /* + * No SMMUv3AccelState means no VFIO/IOMMUFD devices, nothing to + * invalidate. + */ + if (!accel) { + return true; + } + + /* + * SID based invalidations (e.g. CFGI_CD) apply only to vfio-pci endpoints + * with a valid vIOMMU vdev. + */ + if (sdev && !container_of(sdev, SMMUv3AccelDevice, sdev)->vdev) { + return true; + } + + /* Single command (entry_num = 1); no need to check returned entry_num */ + return iommufd_backend_invalidate_cache( + accel->viommu.iommufd, accel->viommu.viommu_id, + IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3, + sizeof(Cmd), &entry_num, cmd, errp); +} + static bool smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev, Error **errp) diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h index 2d2d005658..7186817264 100644 --- a/hw/arm/smmuv3-accel.h +++ b/hw/arm/smmuv3-accel.h @@ -45,6 +45,8 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid, bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, Error **errp); bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp); +bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev, + Error **errp); void smmuv3_accel_reset(SMMUv3State *s); #else static inline void smmuv3_accel_init(SMMUv3State *s) @@ -66,6 +68,12 @@ static inline bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp) { return true; } +static inline bool +smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev, + Error **errp) +{ + return true; +} static inline void smmuv3_accel_reset(SMMUv3State *s) { } diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index f02e3ee46c..513da966a4 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1388,6 +1388,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp) trace_smmuv3_cmdq_cfgi_cd(sid); smmuv3_flush_config(sdev); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) { + cmd_error = SMMU_CERROR_ILL; + break; + } break; } case SMMU_CMD_TLBI_NH_ASID: @@ -1411,6 +1415,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp) trace_smmuv3_cmdq_tlbi_nh_asid(asid); smmu_inv_notifiers_all(&s->smmu_state); smmu_iotlb_inv_asid_vmid(bs, asid, vmid); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + cmd_error = SMMU_CERROR_ILL; + break; + } break; } case SMMU_CMD_TLBI_NH_ALL: @@ -1438,6 +1446,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp) trace_smmuv3_cmdq_tlbi_nsnh(); smmu_inv_notifiers_all(&s->smmu_state); smmu_iotlb_inv_all(bs); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + cmd_error = SMMU_CERROR_ILL; + break; + } break; case SMMU_CMD_TLBI_NH_VAA: case SMMU_CMD_TLBI_NH_VA: @@ -1446,6 +1458,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp) break; } smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + cmd_error = SMMU_CERROR_ILL; + break; + } break; case SMMU_CMD_TLBI_S12_VMALL: { -- 2.43.0
