93 lines
2.8 KiB
Diff
93 lines
2.8 KiB
Diff
|
|
From 707bd8198642549595f11ef34c80094fbf7d2de1 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Nicolin Chen <nicolinc@nvidia.com>
|
||
|
|
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 <nicolinc@nvidia.com>
|
||
|
|
---
|
||
|
|
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
|
||
|
|
|