qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: qemu-stable@nongnu.org, Peter Xu <peterx@redhat.com>,
	"Michael S . Tsirkin" <mst@redhat.com>
Subject: [Qemu-devel] [PATCH 55/97] intel_iommu: better handling of dmar state switch
Date: Mon,  1 Apr 2019 15:59:29 -0500	[thread overview]
Message-ID: <20190401210011.16009-56-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <20190401210011.16009-1-mdroth@linux.vnet.ibm.com>

From: Peter Xu <peterx@redhat.com>

QEMU is not handling the global DMAR switch well, especially when from
"on" to "off".

Let's first take the example of system reset.

Assuming that a guest has IOMMU enabled.  When it reboots, we will drop
all the existing DMAR mappings to handle the system reset, however we'll
still keep the existing memory layouts which has the IOMMU memory region
enabled.  So after the reboot and before the kernel reloads again, there
will be no mapping at all for the host device.  That's problematic since
any software (for example, SeaBIOS) that runs earlier than the kernel
after the reboot will assume the IOMMU is disabled, so any DMA from the
software will fail.

For example, a guest that boots on an assigned NVMe device might fail to
find the boot device after a system reboot/reset and we'll be able to
observe SeaBIOS errors if we capture the debugging log:

  WARNING - Timeout at nvme_wait:144!

Meanwhile, we should see DMAR errors on the host of that NVMe device.
It's the DMA fault that caused a NVMe driver timeout.

The correct fix should be that we do proper switching of device DMA
address spaces when system resets, which will setup correct memory
regions and notify the backend of the devices.  This might not affect
much on non-assigned devices since QEMU VT-d emulation will assume a
default passthrough mapping if DMAR is not enabled in the GCMD
register (please refer to vtd_iommu_translate).  However that's required
for an assigned devices, since that'll rebuild the correct GPA to HPA
mapping that is needed for any DMA operation during guest bootstrap.

Besides the system reset, we have some other places that might change
the global DMAR status and we'd better do the same thing there.  For
example, when we change the state of GCMD register, or the DMAR root
pointer.  Do the same refresh for all these places.  For these two
places we'll also need to explicitly invalidate the context entry cache
and iotlb cache.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1625173
CC: QEMU Stable <qemu-stable@nongnu.org>
Reported-by: Cong Li <coli@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
--
v2:
- do the same for GCMD write, or root pointer update [Alex]
- test is carried out by me this time, by observing the
  vtd_switch_address_space tracepoint after system reboot
v3:
- rewrite commit message as suggested by Alex
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2cc9ddccebcaa48b3debfc279a83761fcbb7616c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/i386/intel_iommu.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f66e93ed2c..4dfa9d5e2b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -37,6 +37,8 @@
 #include "kvm_i386.h"
 #include "trace.h"
 
+static void vtd_address_space_refresh_all(IntelIOMMUState *s);
+
 static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
                             uint64_t wmask, uint64_t w1cmask)
 {
@@ -1426,7 +1428,7 @@ static void vtd_context_global_invalidate(IntelIOMMUState *s)
         vtd_reset_context_cache_locked(s);
     }
     vtd_iommu_unlock(s);
-    vtd_switch_address_space_all(s);
+    vtd_address_space_refresh_all(s);
     /*
      * From VT-d spec 6.5.2.1, a global context entry invalidation
      * should be followed by a IOTLB global invalidation, so we should
@@ -1711,6 +1713,8 @@ static void vtd_handle_gcmd_srtp(IntelIOMMUState *s)
     vtd_root_table_setup(s);
     /* Ok - report back to driver */
     vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_RTPS);
+    vtd_reset_caches(s);
+    vtd_address_space_refresh_all(s);
 }
 
 /* Set Interrupt Remap Table Pointer */
@@ -1743,7 +1747,8 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
         vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_TES, 0);
     }
 
-    vtd_switch_address_space_all(s);
+    vtd_reset_caches(s);
+    vtd_address_space_refresh_all(s);
 }
 
 /* Handle Interrupt Remap Enable/Disable */
@@ -3022,6 +3027,12 @@ static void vtd_address_space_unmap_all(IntelIOMMUState *s)
     }
 }
 
+static void vtd_address_space_refresh_all(IntelIOMMUState *s)
+{
+    vtd_address_space_unmap_all(s);
+    vtd_switch_address_space_all(s);
+}
+
 static int vtd_replay_hook(IOMMUTLBEntry *entry, void *private)
 {
     memory_region_notify_one((IOMMUNotifier *)private, entry);
@@ -3194,11 +3205,7 @@ static void vtd_reset(DeviceState *dev)
     IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
 
     vtd_init(s);
-
-    /*
-     * When device reset, throw away all mappings and external caches
-     */
-    vtd_address_space_unmap_all(s);
+    vtd_address_space_refresh_all(s);
 }
 
 static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
-- 
2.17.1

  parent reply	other threads:[~2019-04-01 21:02 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-01 20:58 [Qemu-devel] [PATCH 00/97] Patch Round-up for stable 3.0.1, freeze on 2019-04-08 Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 01/97] target/arm: Fix sign of sve_cmpeq_ppzw/sve_cmpne_ppzw Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 02/97] target/arm: Fix typo in do_sat_addsub_64 Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 03/97] target/arm: Reorganize SVE WHILE Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 04/97] target/arm: Fix typo in helper_sve_movz_d Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 05/97] target/arm: Fix typo in helper_sve_ld1hss_r Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 06/97] target/arm: Fix sign-extension in sve do_ldr/do_str Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 07/97] target/arm: Fix offset for LD1R instructions Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 08/97] target/arm: Fix offset scaling for LD_zprr and ST_zprr Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 09/97] target/arm: Reformat integer register dump Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 10/97] target/arm: Dump SVE state if enabled Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 11/97] target/arm: Add sve-max-vq cpu property to -cpu max Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 12/97] spapr_cpu_core: vmstate_[un]register per-CPU data from (un)realizefn Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 13/97] target/arm: Adjust FPCR_MASK for FZ16 Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 14/97] target/arm: Ignore float_flag_input_denormal from fp_status_f16 Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 15/97] target/arm: Use fp_status_fp16 for do_fmpa_zpzzz_h Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 16/97] target/arm: Use FZ not FZ16 for SVE FCVT single-half and double-half Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 17/97] block/qapi: Fix memory leak in qmp_query_blockstats() Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 18/97] mirror: Fail gracefully for source == target Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 19/97] qemu-img: fix regression copying secrets during convert Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 20/97] nvme: Fix nvme_init error handling Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 21/97] aio-posix: Don't count ctx->notifier as progress when polling Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 22/97] aio: Do aio_notify_accept only during blocking aio_poll Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 23/97] monitor: fix oob command leak Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 24/97] vnc: fix memleak of the "vnc-worker-output" name Michael Roth
2019-04-01 20:58 ` [Qemu-devel] [PATCH 25/97] i386: Disable TOPOEXT by default on "-cpu host" Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 26/97] block: for jobs, do not clear user_paused until after the resume Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 27/97] block: iotest to catch abort on forced blockjob cancel Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 28/97] virtio: update MemoryRegionCaches when guest negotiates features Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 29/97] target/xtensa: fix FPU2000 bugs Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 30/97] kvm: add call to qemu_add_opts() for -overcommit option Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 31/97] slirp: Add sanity check for str option length Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 32/97] vhost: fix invalid downcast Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 33/97] pc: acpi: revert back to 1 SRAT entry for hotpluggable area Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 34/97] tests: update acpi expected files Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 35/97] block: Fix use after free error in bdrv_open_inherit() Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 36/97] job: Fix nested aio_poll() hanging in job_txn_apply Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 37/97] target/xtensa: fix s32c1i TCGMemOp flags Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 38/97] nbd/server: fix bitmap export Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 39/97] clean up callback when del virtqueue Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 40/97] block/rbd: pull out qemu_rbd_convert_options Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 41/97] block/rbd: Attempt to parse legacy filenames Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 42/97] block/rbd: add iotest for rbd legacy keyvalue filename parsing Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 43/97] block/rbd: add deprecation documentation for filename keyvalue pairs Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 44/97] target/arm: Fix cpu_get_tb_cpu_state() for non-SVE CPUs Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 45/97] ne2000: fix possible out of bound access in ne2000_receive Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 46/97] rtl8139: fix possible out of bound access Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 47/97] pcnet: fix possible buffer overflow Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 48/97] net: ignore packet size greater than INT_MAX Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 49/97] virt: Suppress external aborts on virt-2.10 and earlier Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 50/97] virtio: do not take address of packed members Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 51/97] block-backend: Set werror/rerror defaults in blk_new() Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 52/97] target/arm: Correct condition for v8M callee stack push Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 53/97] nbd/server: fix NBD_CMD_CACHE Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 54/97] intel_iommu: introduce vtd_reset_caches() Michael Roth
2019-04-01 20:59 ` Michael Roth [this message]
2019-04-01 20:59 ` [Qemu-devel] [PATCH 56/97] nbd: fix NBD_FLAG_SEND_CACHE value Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 57/97] migration: Stop postcopy fault thread before notifying Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 58/97] vhost-scsi: prevent using uninitialized vqs Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 59/97] target/xtensa: drop num_[core_]regs from dc232b/dc233c configs Michael Roth
2019-04-01 21:19   ` Max Filippov
2019-04-01 23:28     ` Michael Roth
2019-04-01 23:42       ` Max Filippov
2019-04-01 20:59 ` [Qemu-devel] [PATCH 60/97] make-release: add skiboot .version file Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 61/97] net: drop too large packet early Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 62/97] fdc: fix segfault in fdctrl_stop_transfer() when DMA is disabled Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 63/97] qemu-img: Fix typo Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 64/97] qemu-img: Fix leak Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 65/97] fmops: fix off-by-one in AR_TABLE and DR_TABLE array size Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 66/97] vfio-helpers: Fix qemu_vfio_open_pci() crash Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 67/97] i2c: Move typedef of bitbang_i2c_interface to i2c.h Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 68/97] i2c: Add a length check to the SMBus write handling Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 69/97] nbd/server: Advertise all contexts in response to bare LIST Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 70/97] nbd/client: Make x-dirty-bitmap more reliable Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 71/97] nbd/client: Send NBD_CMD_DISC if open fails after connect Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 72/97] mirror: fix dead-lock Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 73/97] iotests: simple mirror test with kvm on 1G image Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 74/97] iotests: make 235 work on s390 (and others) Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 75/97] Changes requirement for "vsubsbs" instruction Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 76/97] pcie: set link state inactive/active after hot unplug/plug Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 77/97] pc:piix4: Update smbus I/O space after a migration Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 78/97] hw/s390x: Fix bad mask in time2tod() Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 79/97] linux-user: write(fd, NULL, 0) parity with linux's treatment of same Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 80/97] linux-user: make pwrite64/pread64(fd, NULL, 0, offset) return 0 Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 81/97] s390x: Return specification exception for unimplemented diag 308 subcodes Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 82/97] exec.c: Don't reallocate IOMMUNotifiers that are in use Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 83/97] tpm: Zero-init structure to avoid uninitialized variables in valgrind log Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 84/97] tpm: use loop iterator to set sts data field Michael Roth
2019-04-01 20:59 ` [Qemu-devel] [PATCH 85/97] tpm: Make sure new locality passed to tpm_tis_prep_abort() is valid Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 86/97] tpm: Make sure the locality received from backend " Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 87/97] block: Fix invalidate_cache error path for parent activation Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 88/97] acpi: Make TPM 2.0 with TIS available as MSFT0101 Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 89/97] hw/rdma: another clang compilation fix Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 90/97] slirp: check sscanf result when emulating ident Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 91/97] tpm_tis: fix loop that cancels any seizure by a lower locality Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 92/97] bitmap: Update count after a merge Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 93/97] qga: update docs with systemd suspend support info Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 94/97] nvme: fix out-of-bounds access to the CMB Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 95/97] 9p: fix QEMU crash when renaming files Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 96/97] usb-mtp: outlaw slashes in filenames Michael Roth
2019-04-01 21:00 ` [Qemu-devel] [PATCH 97/97] usb-mtp: use O_NOFOLLOW and O_CLOEXEC Michael Roth
2019-04-02 16:22 ` [Qemu-devel] [Qemu-stable] [PATCH 00/97] Patch Round-up for stable 3.0.1, freeze on 2019-04-08 Cole Robinson
2019-04-04 21:28   ` Michael Roth
2019-04-04 22:31 ` [Qemu-devel] " Philippe Mathieu-Daudé
2019-04-04 22:31   ` Philippe Mathieu-Daudé
2019-04-05 20:28   ` Michael Roth
2019-04-05 20:28     ` Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190401210011.16009-56-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=mst@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).