[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 39/41] hw/arm/smmuv3: Move reset to exit phase
From: |
Michael S. Tsirkin |
Subject: |
[PULL 39/41] hw/arm/smmuv3: Move reset to exit phase |
Date: |
Fri, 21 Feb 2025 07:24:45 -0500 |
From: Eric Auger <eric.auger@redhat.com>
Currently the iommu may be reset before the devices
it protects. For example this happens with virtio-scsi-pci.
when system_reset is issued from qmp monitor: spurious
"virtio: zero sized buffers are not allowed" warnings can
be observed. This happens because outstanding DMA requests
are still happening while the SMMU gets reset.
This can also happen with VFIO devices. In that case
spurious DMA translation faults can be observed on host.
Make sure the SMMU is reset in the 'exit' phase after
all DMA capable devices have been reset during the 'enter'
or 'hold' phase.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-Id: <20250218182737.76722-4-eric.auger@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/arm/smmu-common.c | 9 +++++++--
hw/arm/smmuv3.c | 14 ++++++++++----
hw/arm/trace-events | 1 +
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index dd74c2e558..8c1b407b82 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -924,7 +924,12 @@ static void smmu_base_realize(DeviceState *dev, Error
**errp)
}
}
-static void smmu_base_reset_hold(Object *obj, ResetType type)
+/*
+ * Make sure the IOMMU is reset in 'exit' phase after
+ * all outstanding DMA requests have been quiesced during
+ * the 'enter' or 'hold' reset phases
+ */
+static void smmu_base_reset_exit(Object *obj, ResetType type)
{
SMMUState *s = ARM_SMMU(obj);
@@ -949,7 +954,7 @@ static void smmu_base_class_init(ObjectClass *klass, void
*data)
device_class_set_props(dc, smmu_dev_properties);
device_class_set_parent_realize(dc, smmu_base_realize,
&sbc->parent_realize);
- rc->phases.hold = smmu_base_reset_hold;
+ rc->phases.exit = smmu_base_reset_exit;
}
static const TypeInfo smmu_base_info = {
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index c0cf5df0f6..b49a59b64c 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1870,13 +1870,19 @@ static void smmu_init_irq(SMMUv3State *s, SysBusDevice
*dev)
}
}
-static void smmu_reset_hold(Object *obj, ResetType type)
+/*
+ * Make sure the IOMMU is reset in 'exit' phase after
+ * all outstanding DMA requests have been quiesced during
+ * the 'enter' or 'hold' reset phases
+ */
+static void smmu_reset_exit(Object *obj, ResetType type)
{
SMMUv3State *s = ARM_SMMUV3(obj);
SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
- if (c->parent_phases.hold) {
- c->parent_phases.hold(obj, type);
+ trace_smmu_reset_exit();
+ if (c->parent_phases.exit) {
+ c->parent_phases.exit(obj, type);
}
smmuv3_init_regs(s);
@@ -1999,7 +2005,7 @@ static void smmuv3_class_init(ObjectClass *klass, void
*data)
SMMUv3Class *c = ARM_SMMUV3_CLASS(klass);
dc->vmsd = &vmstate_smmuv3;
- resettable_class_set_parent_phases(rc, NULL, smmu_reset_hold, NULL,
+ resettable_class_set_parent_phases(rc, NULL, NULL, smmu_reset_exit,
&c->parent_phases);
device_class_set_parent_realize(dc, smmu_realize,
&c->parent_realize);
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index c64ad344bd..7790db780e 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -56,6 +56,7 @@ smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for
sid=0x%x"
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, int asid, int vmid, uint64_t iova,
uint8_t tg, uint64_t num_pages, int stage) "iommu mr=%s asid=%d vmid=%d
iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" stage=%d"
+smmu_reset_exit(void) ""
# strongarm.c
strongarm_uart_update_parameters(const char *label, int speed, char parity,
int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
--
MST
- [PULL 29/41] vhost-iova-tree, svq: Implement GPA->IOVA & partial IOVA->HVA trees, (continued)
- [PULL 29/41] vhost-iova-tree, svq: Implement GPA->IOVA & partial IOVA->HVA trees, Michael S. Tsirkin, 2025/02/21
- [PULL 32/41] MAINTAINERS: add more files to `vhost`, Michael S. Tsirkin, 2025/02/21
- [PULL 33/41] vdpa: Fix endian bugs in shadow virtqueue, Michael S. Tsirkin, 2025/02/21
- [PULL 30/41] vhost-iova-tree: Update documentation, Michael S. Tsirkin, 2025/02/21
- [PULL 13/41] pcie_sriov: Register VFs after migration, Michael S. Tsirkin, 2025/02/21
- [PULL 34/41] hw/virtio/virtio-nsm: Respond with correct length, Michael S. Tsirkin, 2025/02/21
- [PULL 35/41] net: vhost-user: add QAPI events to report connection state, Michael S. Tsirkin, 2025/02/21
- [PULL 36/41] vhost-user-snd: correct the calculation of config_size, Michael S. Tsirkin, 2025/02/21
- [PULL 37/41] hw/virtio/virtio-iommu: Migrate to 3-phase reset, Michael S. Tsirkin, 2025/02/21
- [PULL 38/41] hw/i386/intel-iommu: Migrate to 3-phase reset, Michael S. Tsirkin, 2025/02/21
- [PULL 39/41] hw/arm/smmuv3: Move reset to exit phase,
Michael S. Tsirkin <=
- [PULL 40/41] hw/vfio/common: Add a trace point in vfio_reset_handler, Michael S. Tsirkin, 2025/02/21
- [PULL 41/41] docs/devel/reset: Document reset expectations for DMA and IOMMU, Michael S. Tsirkin, 2025/02/21
- [PULL 21/41] hw/mem/cxl_type3: Add paired msix_uninit_exclusive_bar() call, Michael S. Tsirkin, 2025/02/21
- Re: [PULL 00/41] virtio,pc,pci: features, fixes, cleanups, Stefan Hajnoczi, 2025/02/21