From 707bd8198642549595f11ef34c80094fbf7d2de1 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 29 Apr 2024 21:26:41 +0000 Subject: [PATCH] hw/arm/smmuv3: Add missing STE invalidation Multitple STEs can be invalidated in a range via SMMU_CMD_CFGI_STE_RANGE or SMMU_CMD_CFGI_ALL command. Add the missing STE invalidation in this pathway. Signed-off-by: Nicolin Chen --- hw/arm/smmu-internal.h | 1 + hw/arm/smmuv3.c | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h index 843bebb185..5a81dd1b82 100644 --- a/hw/arm/smmu-internal.h +++ b/hw/arm/smmu-internal.h @@ -142,6 +142,7 @@ typedef struct SMMUIOTLBPageInvInfo { } SMMUIOTLBPageInvInfo; typedef struct SMMUSIDRange { + SMMUState *state; uint32_t start; uint32_t end; } SMMUSIDRange; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 540831ab8e..9d44bb19bc 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1322,11 +1322,9 @@ static void smmuv3_install_nested_ste(SMMUDevice *sdev, int sid) } static gboolean -smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) +_smmuv3_invalidate_ste(SMMUDevice *sdev, SMMUSIDRange *sid_range) { - SMMUDevice *sdev = (SMMUDevice *)key; uint32_t sid = smmu_get_sid(sdev); - SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data; if (sid < sid_range->start || sid > sid_range->end) { return false; @@ -1337,6 +1335,28 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) return true; } +static gboolean +smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) +{ + return _smmuv3_invalidate_ste((SMMUDevice *)key, (SMMUSIDRange *)user_data); +} + +static void smmuv3_invalidate_nested_ste(SMMUSIDRange *sid_range) +{ + SMMUState *bs = sid_range->state; + SMMUDevice *sdev; + + if (!bs->viommu) { + return; + } + + QLIST_FOREACH(sdev, &bs->viommu->device_list, next) { + if (smmu_get_sid(sdev)) { + _smmuv3_invalidate_ste(sdev, sid_range); + } + } +} + static int smmuv3_cmdq_consume(SMMUv3State *s) { SMMUState *bs = ARM_SMMU(s); @@ -1418,12 +1438,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) } mask = (1ULL << (range + 1)) - 1; + sid_range.state = bs; sid_range.start = sid & ~mask; sid_range.end = sid_range.start + mask; trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end); g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste, &sid_range); + smmuv3_invalidate_nested_ste(&sid_range); break; } case SMMU_CMD_CFGI_CD: -- 2.41.0.windows.1