Blame SOURCES/kvm-intel_iommu-handle-invalid-ce-for-shadow-sync.patch

383d26
From 80fe503d7c126fa2be6cc424593cae6c522f65e0 Mon Sep 17 00:00:00 2001
383d26
From: Peter Xu <peterx@redhat.com>
383d26
Date: Thu, 8 Nov 2018 05:37:21 +0100
383d26
Subject: [PATCH 14/22] intel_iommu: handle invalid ce for shadow sync
383d26
MIME-Version: 1.0
383d26
Content-Type: text/plain; charset=UTF-8
383d26
Content-Transfer-Encoding: 8bit
383d26
383d26
RH-Author: Peter Xu <peterx@redhat.com>
383d26
Message-id: <20181108053721.13162-8-peterx@redhat.com>
383d26
Patchwork-id: 82958
383d26
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 7/7] intel_iommu: handle invalid ce for shadow sync
383d26
Bugzilla: 1627272
383d26
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
383d26
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
383d26
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
383d26
383d26
We should handle VTD_FR_CONTEXT_ENTRY_P properly when synchronizing
383d26
shadow page tables.  Having invalid context entry there is perfectly
383d26
valid when we move a device out of an existing domain.  When that
383d26
happens, instead of posting an error we invalidate the whole region.
383d26
383d26
Without this patch, QEMU will crash if we do these steps:
383d26
383d26
(1) start QEMU with VT-d IOMMU and two 10G NICs (ixgbe)
383d26
(2) bind the NICs with vfio-pci in the guest
383d26
(3) start testpmd with the NICs applied
383d26
(4) stop testpmd
383d26
(5) rebind the NIC back to ixgbe kernel driver
383d26
383d26
The patch should fix it.
383d26
383d26
Reported-by: Pei Zhang <pezhang@redhat.com>
383d26
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1627272
383d26
Signed-off-by: Peter Xu <peterx@redhat.com>
383d26
Reviewed-by: Eric Auger <eric.auger@redhat.com>
383d26
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
383d26
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
383d26
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
383d26
(cherry picked from commit c28b535d083d0a263d38d9ceeada83cdae8c64f0)
383d26
Signed-off-by: Peter Xu <peterx@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 hw/i386/intel_iommu.c | 17 +++++++++++++++++
383d26
 1 file changed, 17 insertions(+)
383d26
383d26
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
383d26
index c95128d..12af410 100644
383d26
--- a/hw/i386/intel_iommu.c
383d26
+++ b/hw/i386/intel_iommu.c
383d26
@@ -38,6 +38,7 @@
383d26
 #include "trace.h"
383d26
 
383d26
 static void vtd_address_space_refresh_all(IntelIOMMUState *s);
383d26
+static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
383d26
 
383d26
 static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
383d26
                             uint64_t wmask, uint64_t w1cmask)
383d26
@@ -1066,11 +1067,27 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as)
383d26
 {
383d26
     int ret;
383d26
     VTDContextEntry ce;
383d26
+    IOMMUNotifier *n;
383d26
 
383d26
     ret = vtd_dev_to_context_entry(vtd_as->iommu_state,
383d26
                                    pci_bus_num(vtd_as->bus),
383d26
                                    vtd_as->devfn, &ce);
383d26
     if (ret) {
383d26
+        if (ret == -VTD_FR_CONTEXT_ENTRY_P) {
383d26
+            /*
383d26
+             * It's a valid scenario to have a context entry that is
383d26
+             * not present.  For example, when a device is removed
383d26
+             * from an existing domain then the context entry will be
383d26
+             * zeroed by the guest before it was put into another
383d26
+             * domain.  When this happens, instead of synchronizing
383d26
+             * the shadow pages we should invalidate all existing
383d26
+             * mappings and notify the backends.
383d26
+             */
383d26
+            IOMMU_NOTIFIER_FOREACH(n, &vtd_as->iommu) {
383d26
+                vtd_address_space_unmap(vtd_as, n);
383d26
+            }
383d26
+            ret = 0;
383d26
+        }
383d26
         return ret;
383d26
     }
383d26
 
383d26
-- 
383d26
1.8.3.1
383d26