108 lines
3.9 KiB
Diff
108 lines
3.9 KiB
Diff
|
|
From de53feaa37a267a21ed30a642e1e64c5fcfbc4a4 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Eric Auger <eric.auger@redhat.com>
|
||
|
|
Date: Sun, 14 Feb 2021 12:30:57 -0500
|
||
|
|
Subject: [PATCH] hw/arm/smmuv3: Improve stage1 ASID invalidation
|
||
|
|
|
||
|
|
At the moment ASID invalidation command (CMD_TLBI_NH_ASID) is
|
||
|
|
propagated as a domain invalidation (the whole notifier range
|
||
|
|
is invalidated independently on any ASID information).
|
||
|
|
|
||
|
|
The new granularity field now allows to be more precise and
|
||
|
|
restrict the invalidation to a peculiar ASID. Set the corresponding
|
||
|
|
fields and flag.
|
||
|
|
|
||
|
|
We still keep the iova and addr_mask settings for consumers that
|
||
|
|
do not support the new fields, like VHOST.
|
||
|
|
|
||
|
|
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||
|
|
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
|
||
|
|
---
|
||
|
|
hw/arm/smmuv3.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
|
||
|
|
hw/arm/trace-events | 1 +
|
||
|
|
2 files changed, 43 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
|
||
|
|
index 94e2c658f8..da5dac1ba5 100644
|
||
|
|
--- a/hw/arm/smmuv3.c
|
||
|
|
+++ b/hw/arm/smmuv3.c
|
||
|
|
@@ -836,6 +836,31 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
|
||
|
|
memory_region_notify_iommu_one(n, &event);
|
||
|
|
}
|
||
|
|
|
||
|
|
+/**
|
||
|
|
+ * smmuv3_notify_asid - call the notifier @n for a given asid
|
||
|
|
+ *
|
||
|
|
+ * @mr: IOMMU mr region handle
|
||
|
|
+ * @n: notifier to be called
|
||
|
|
+ * @asid: address space ID or negative value if we don't care
|
||
|
|
+ */
|
||
|
|
+static void smmuv3_notify_asid(IOMMUMemoryRegion *mr,
|
||
|
|
+ IOMMUNotifier *n, int asid)
|
||
|
|
+{
|
||
|
|
+ IOMMUTLBEvent event = {};
|
||
|
|
+
|
||
|
|
+ event.type = IOMMU_NOTIFIER_UNMAP;
|
||
|
|
+ event.entry.target_as = &address_space_memory;
|
||
|
|
+ event.entry.perm = IOMMU_NONE;
|
||
|
|
+ event.entry.granularity = IOMMU_INV_GRAN_PASID;
|
||
|
|
+ event.entry.flags = IOMMU_INV_FLAGS_ARCHID;
|
||
|
|
+ event.entry.arch_id = asid;
|
||
|
|
+ event.entry.iova = n->start;
|
||
|
|
+ event.entry.addr_mask = n->end - n->start;
|
||
|
|
+
|
||
|
|
+ memory_region_notify_iommu_one(n, &event);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+
|
||
|
|
/* invalidate an asid/iova range tuple in all mr's */
|
||
|
|
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
|
||
|
|
uint8_t tg, uint64_t num_pages)
|
||
|
|
@@ -913,6 +938,22 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static void smmuv3_s1_asid_inval(SMMUState *s, uint16_t asid)
|
||
|
|
+{
|
||
|
|
+ SMMUDevice *sdev;
|
||
|
|
+
|
||
|
|
+ trace_smmuv3_s1_asid_inval(asid);
|
||
|
|
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
|
||
|
|
+ IOMMUMemoryRegion *mr = &sdev->iommu;
|
||
|
|
+ IOMMUNotifier *n;
|
||
|
|
+
|
||
|
|
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
|
||
|
|
+ smmuv3_notify_asid(mr, n, asid);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ smmu_iotlb_inv_asid(s, asid);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int smmuv3_cmdq_consume(SMMUv3State *s)
|
||
|
|
{
|
||
|
|
SMMUState *bs = ARM_SMMU(s);
|
||
|
|
@@ -1027,8 +1068,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
|
||
|
|
uint16_t asid = CMD_ASID(&cmd);
|
||
|
|
|
||
|
|
trace_smmuv3_cmdq_tlbi_nh_asid(asid);
|
||
|
|
- smmu_inv_notifiers_all(&s->smmu_state);
|
||
|
|
- smmu_iotlb_inv_asid(bs, asid);
|
||
|
|
+ smmuv3_s1_asid_inval(bs, asid);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SMMU_CMD_TLBI_NH_ALL:
|
||
|
|
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
|
||
|
|
index 2dee296c8f..1447ad5a90 100644
|
||
|
|
--- a/hw/arm/trace-events
|
||
|
|
+++ b/hw/arm/trace-events
|
||
|
|
@@ -46,6 +46,7 @@ smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x"
|
||
|
|
smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
|
||
|
|
smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
|
||
|
|
smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
|
||
|
|
+smmuv3_s1_asid_inval(int asid) "asid=%d"
|
||
|
|
smmuv3_cmdq_tlbi_nh(void) ""
|
||
|
|
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
|
||
|
|
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|