diff options
| author | Eric Auger <eric.auger@redhat.com> | 2025-02-18 19:25:32 +0100 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2025-02-21 07:21:25 -0500 |
| commit | 2aaf48bcf27d8b3da5b30af6c1ced464d3df30f7 (patch) | |
| tree | fe7c05c2311b111aa5f0ab4f77fe08661fca9d76 /hw/i386/intel_iommu.c | |
| parent | d261b84d354a41a38336af813f92f636d3fb3f78 (diff) | |
| download | focaccia-qemu-2aaf48bcf27d8b3da5b30af6c1ced464d3df30f7.tar.gz focaccia-qemu-2aaf48bcf27d8b3da5b30af6c1ced464d3df30f7.zip | |
hw/i386/intel-iommu: Migrate to 3-phase reset
Currently the IOMMU may be reset before the devices it protects. For example this happens with virtio devices but also with VFIO devices. In this latter case this produces spurious translation faults on host. Let's use 3-phase reset mechanism and reset the IOMMU on exit phase after all DMA capable devices have been reset on 'enter' or 'hold' phase. Signed-off-by: Eric Auger <eric.auger@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Zhenzhong Duan <zhenzhong.duan@intel.com> Message-Id: <20250218182737.76722-3-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>
Diffstat (limited to 'hw/i386/intel_iommu.c')
| -rw-r--r-- | hw/i386/intel_iommu.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index f366c223d0..a5cf2d0e81 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -4697,10 +4697,11 @@ static void vtd_init(IntelIOMMUState *s) /* Should not reset address_spaces when reset because devices will still use * the address space they got at first (won't ask the bus again). */ -static void vtd_reset(DeviceState *dev) +static void vtd_reset_exit(Object *obj, ResetType type) { - IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev); + IntelIOMMUState *s = INTEL_IOMMU_DEVICE(obj); + trace_vtd_reset_exit(); vtd_init(s); vtd_address_space_refresh_all(s); } @@ -4864,8 +4865,13 @@ static void vtd_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); X86IOMMUClass *x86_class = X86_IOMMU_DEVICE_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); - device_class_set_legacy_reset(dc, vtd_reset); + /* + * Use 'exit' reset phase to make sure all DMA requests + * have been quiesced during 'enter' or 'hold' phase + */ + rc->phases.exit = vtd_reset_exit; dc->vmsd = &vtd_vmstate; device_class_set_props(dc, vtd_properties); dc->hotpluggable = false; |