[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC v4 16/27] hw/arm/smmuv3: Notify on config changes
From: |
Eric Auger |
Subject: |
[Qemu-arm] [RFC v4 16/27] hw/arm/smmuv3: Notify on config changes |
Date: |
Mon, 27 May 2019 13:41:52 +0200 |
In case IOMMU config notifiers are attached to the
IOMMU memory region, we execute them, passing as argument
the iommu_pasid_table_config struct updated with the new
viommu translation config. Config notifiers are called on
STE changes. At physical level, they translate into
CMD_CFGI_STE_* commands.
Signed-off-by: Eric Auger <address@hidden>
---
v3 -> v4:
- fix compile issue with mingw
v2 -> v3:
- adapt to pasid_cfg field changes. Use local variable
- add trace event
- set version fields
- use CONFIG_PASID
v1 -> v2:
- do not notify anymore on CD change. Anyway the smmuv3 linux
driver is not sending any CD invalidation commands. If we were
to propagate CD invalidation commands, we would use the
CACHE_INVALIDATE VFIO ioctl.
- notify a precise config flags to prepare for addition of new
flags
---
hw/arm/smmuv3.c | 76 +++++++++++++++++++++++++++++++++++----------
hw/arm/trace-events | 1 +
2 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index f2f3724686..db03313672 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -16,6 +16,10 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef __linux__
+#include "linux/iommu.h"
+#endif
+
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "sysemu/sysemu.h"
@@ -847,6 +851,59 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int
asid,
}
}
+static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
+{
+#ifdef __linux__
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
+ SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
+ SMMUTransCfg *cfg;
+ SMMUDevice *sdev;
+
+ if (!mr) {
+ return;
+ }
+
+ sdev = container_of(mr, SMMUDevice, iommu);
+
+ /* flush QEMU config cache */
+ smmuv3_flush_config(sdev);
+
+ if (mr->iommu_notify_flags & IOMMU_NOTIFIER_CONFIG_PASID) {
+ /* force a guest RAM config structure decoding */
+ cfg = smmuv3_get_config(sdev, &event);
+
+ if (cfg) {
+ IOMMUConfig iommu_config = {
+ .pasid_cfg.version = PASID_TABLE_CFG_VERSION_1,
+ .pasid_cfg.format = IOMMU_PASID_FORMAT_SMMUV3,
+ .pasid_cfg.base_ptr = cfg->s1ctxptr,
+ .pasid_cfg.smmuv3.version = PASID_TABLE_SMMUV3_CFG_VERSION_1,
+ };
+
+ if (cfg->disabled || cfg->bypassed) {
+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_BYPASS;
+ } else if (cfg->aborted) {
+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_ABORT;
+ } else {
+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_TRANSLATE;
+ }
+
+ trace_smmuv3_notify_config_change(mr->parent_obj.name,
+ iommu_config.pasid_cfg.config,
+ iommu_config.pasid_cfg.base_ptr);
+
+ memory_region_config_notify_iommu(mr, 0,
+ IOMMU_NOTIFIER_CONFIG_PASID,
+ &iommu_config);
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s error decoding the configuration for iommu
mr=%s\n",
+ __func__, mr->parent_obj.name);
+ }
+ }
+#endif
+}
+
static int smmuv3_cmdq_consume(SMMUv3State *s)
{
SMMUState *bs = ARM_SMMU(s);
@@ -897,22 +954,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
case SMMU_CMD_CFGI_STE:
{
uint32_t sid = CMD_SID(&cmd);
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
- SMMUDevice *sdev;
if (CMD_SSEC(&cmd)) {
cmd_error = SMMU_CERROR_ILL;
break;
}
- if (!mr) {
- break;
- }
-
trace_smmuv3_cmdq_cfgi_ste(sid);
- sdev = container_of(mr, SMMUDevice, iommu);
- smmuv3_flush_config(sdev);
-
+ smmuv3_notify_config_change(bs, sid);
break;
}
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
@@ -929,14 +978,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
trace_smmuv3_cmdq_cfgi_ste_range(start, end);
for (i = start; i <= end; i++) {
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
- SMMUDevice *sdev;
-
- if (!mr) {
- continue;
- }
- sdev = container_of(mr, SMMUDevice, iommu);
- smmuv3_flush_config(sdev);
+ smmuv3_notify_config_change(bs, i);
}
break;
}
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index 3809005cba..741e645ae2 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -52,4 +52,5 @@ smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for
sid %d"
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu
mr=%s"
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu
mr=%s"
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova)
"iommu mr=%s asid=%d iova=0x%"PRIx64
+smmuv3_notify_config_change(const char *name, uint8_t config, uint64_t
s1ctxptr) "iommu mr=%s config=%d s1ctxptr=0x%"PRIx64
--
2.20.1
- Re: [Qemu-arm] [RFC v4 08/27] hw/vfio/common: Force nested if iommu requires it, (continued)
- [Qemu-arm] [RFC v4 09/27] memory: Prepare for different kinds of IOMMU MR notifiers, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 10/27] memory: Add IOMMUConfigNotifier, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 11/27] memory: Add arch_id and leaf fields in IOTLBEntry, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 12/27] hw/arm/smmuv3: Store the PASID table GPA in the translation config, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 13/27] hw/arm/smmuv3: Implement dummy replay, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 14/27] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 15/27] hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA invalidation, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 16/27] hw/arm/smmuv3: Notify on config changes,
Eric Auger <=
- [Qemu-arm] [RFC v4 17/27] hw/vfio/common: Introduce vfio_alloc_guest_iommu helper, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 18/27] hw/vfio/common: Introduce hostwin_from_range helper, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 19/27] hw/vfio/common: Introduce helpers to DMA map/unmap a RAM section, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 20/27] hw/vfio/common: Setup nested stage mappings, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 21/27] hw/vfio/common: Register a MAP notifier for MSI binding, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 22/27] vfio-pci: Expose MSI stage 1 bindings to the host, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 23/27] memory: Introduce IOMMU Memory Region inject_faults API, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 26/27] vfio-pci: Set up fault regions, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 27/27] vfio-pci: Implement the DMA fault handler, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 24/27] hw/arm/smmuv3: Implement fault injection, Eric Auger, 2019/05/27