[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v3 16/27] hw/arm/smmuv3: Notify on config changes
From: |
Eric Auger |
Subject: |
[Qemu-devel] [RFC v3 16/27] hw/arm/smmuv3: Notify on config changes |
Date: |
Fri, 12 Apr 2019 12:03:43 +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>
---
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 | 72 ++++++++++++++++++++++++++++++++++-----------
hw/arm/trace-events | 1 +
2 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index f2f3724686..2574989f2e 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -16,6 +16,8 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "linux/iommu.h"
+
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "sysemu/sysemu.h"
@@ -847,6 +849,57 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int
asid,
}
}
+static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
+{
+ 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);
+ }
+ }
+}
+
static int smmuv3_cmdq_consume(SMMUv3State *s)
{
SMMUState *bs = ARM_SMMU(s);
@@ -897,22 +950,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 +974,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
- [Qemu-devel] [RFC v3 06/27] memory: add IOMMU_ATTR_MSI_TRANSLATE IOMMU memory region attribute, (continued)
- [Qemu-devel] [RFC v3 06/27] memory: add IOMMU_ATTR_MSI_TRANSLATE IOMMU memory region attribute, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 07/27] hw/arm/smmuv3: Advertise VFIO_NESTED and MSI_TRANSLATE attributes, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 08/27] hw/vfio/common: Force nested if iommu requires it, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 09/27] memory: Prepare for different kinds of IOMMU MR notifiers, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 10/27] memory: Add IOMMUConfigNotifier, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 12/27] hw/arm/smmuv3: Store the PASID table GPA in the translation config, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 11/27] memory: Add arch_id and leaf fields in IOTLBEntry, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 13/27] hw/arm/smmuv3: Implement dummy replay, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 14/27] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 15/27] hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA invalidation, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 16/27] hw/arm/smmuv3: Notify on config changes,
Eric Auger <=
- [Qemu-devel] [RFC v3 17/27] hw/vfio/common: Introduce vfio_alloc_guest_iommu helper, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 18/27] hw/vfio/common: Introduce hostwin_from_range helper, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 19/27] hw/vfio/common: Introduce helpers to DMA map/unap a RAM section, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 20/27] hw/vfio/common: Setup nested stage mappings, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 21/27] hw/vfio/common: Register a MAP notifier for MSI binding, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 22/27] vfio-pci: Expose MSI stage 1 bindings to the host, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 23/27] memory: Introduce IOMMU Memory Region inject_faults API, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 24/27] hw/arm/smmuv3: Implement fault injection, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 25/27] vfio-pci: register handler for iommu fault, Eric Auger, 2019/04/12
- [Qemu-devel] [RFC v3 26/27] vfio-pci: Set up fault regions, Eric Auger, 2019/04/12