[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC 13/20] hw/arm/smmuv3: Notify on config changes
From: |
Eric Auger |
Subject: |
[Qemu-arm] [RFC 13/20] hw/arm/smmuv3: Notify on config changes |
Date: |
Sat, 1 Sep 2018 16:23:05 +0200 |
In case IOMMU config notifiers are attached to the
IOMMU memory region, we execute them, passing as argument
the iommu_guest_stage_config struct updated with the new
viommu translation config. Config notifiers are called on
STE and CD changes. At physical level, they translate into
CMD_CFGI_STE_* and CMD_CFGI_CD_* commands.
Signed-off-by: Eric Auger <address@hidden>
---
hw/arm/smmuv3.c | 71 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 46 insertions(+), 25 deletions(-)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index ff92f802bd..a31df03d47 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"
@@ -843,6 +845,47 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int
asid, dma_addr_t iova)
}
}
+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_S1_CFG) {
+ /* force a guest RAM config structure decoding */
+ cfg = smmuv3_get_config(sdev, &event);
+
+ if (cfg) {
+ struct iommu_guest_stage_config *kcfg =
+ g_new0(struct iommu_guest_stage_config, 1);
+
+ kcfg->flags = SMMUV3_S1_CFG;
+ kcfg->smmu_s1.flags = cfg->disabled ? IOMMU_SMMU_S1_DISABLED : 0 |
+ cfg->bypassed ? IOMMU_SMMU_S1_BYPASSED : 0 |
+ cfg->aborted ? IOMMU_SMMU_S1_ABORTED : 0;
+ kcfg->smmu_s1.cdptr_dma = cfg->s1ctxptr;
+ kcfg->smmu_s1.asid_bits = 16;
+
+ memory_region_config_notify_iommu(mr, 0, kcfg);
+ g_free(kcfg);
+ } 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);
@@ -893,22 +936,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 */
@@ -925,14 +960,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;
}
@@ -940,21 +968,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
case SMMU_CMD_CFGI_CD_ALL:
{
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_cd(sid);
- sdev = container_of(mr, SMMUDevice, iommu);
- smmuv3_flush_config(sdev);
+ smmuv3_notify_config_change(bs, sid);
break;
}
case SMMU_CMD_TLBI_NH_ASID:
--
2.17.1
- [Qemu-arm] [RFC 00/20] vSMMUv3/pSMMUv3 2 stage VFIO integration, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 05/20] hw/arm/smmuv3: Implement get_attr API to report IOMMU_ATTR_VFIO_NESTED, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 20/20] hw/arm/smmuv3: Remove warning about unsupported MAP notifiers, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 04/20] memory: add IOMMU_ATTR_VFIO_NESTED IOMMU memory region attribute, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 19/20] vfio/pci: Always set up MSI route before enabling vectors, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 18/20] target/arm/kvm: Notifies IOMMU on MSI stage 1 binding, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 16/20] hw/vfio/common: Register specific nested mode notifiers and memory_listener, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 15/20] hw/vfio/common: Introduce vfio_dma_(un)map_ram_section helpers, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 17/20] hw/vfio/common: Register MAP notifier for MSI binding, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 14/20] hw/vfio/common: Introduce vfio_alloc_guest_iommu helper, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 13/20] hw/arm/smmuv3: Notify on config changes,
Eric Auger <=
- [Qemu-arm] [RFC 10/20] memory: Add IOMMUConfigNotifier, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 11/20] hw/arm/smmuv3: Store s1ctrptr in translation config data, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 12/20] hw/arm/smmuv3: Implement dummy replay, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 08/20] memory: Introduce IOMMUIOLTBNotifier, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 09/20] memory: rename memory_region notify_iommu, notify_one, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 07/20] hw/vfio/common: Force nested if iommu requires it, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 06/20] hw/vfio/common: Refactor container initialization, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 03/20] linux-headers: Partial header update, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 02/20] update-linux-headers: Import iommu.h, Eric Auger, 2018/09/01
- [Qemu-arm] [RFC 01/20] hw/arm/smmu-common: Fix the name of the iommu memory regions, Eric Auger, 2018/09/01