Blame SOURCES/kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch

016a62
From 3a528a458d4a2ba4236e98ef3f4efe5482323972 Mon Sep 17 00:00:00 2001
016a62
From: Peter Xu <peterx@redhat.com>
016a62
Date: Wed, 9 Oct 2019 12:39:44 +0100
016a62
Subject: [PATCH 18/22] intel_iommu: Sanity check vfio-pci config on machine
016a62
 init done
016a62
016a62
RH-Author: Peter Xu <peterx@redhat.com>
016a62
Message-id: <20191009123947.21505-3-peterx@redhat.com>
016a62
Patchwork-id: 91347
016a62
O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/5] intel_iommu: Sanity check vfio-pci config on machine init done
016a62
Bugzilla: 1738440
016a62
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
016a62
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
016a62
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
016a62
016a62
This check was previously only happened when the IOMMU is enabled in
016a62
the guest.  It was always too late because the enabling of IOMMU
016a62
normally only happens during the boot of guest OS.  It means that we
016a62
can bail out and exit directly during the guest OS boots if the
016a62
configuration of devices are not supported.  Or, if the guest didn't
016a62
enable vIOMMU at all, then the user can use the guest normally but as
016a62
long as it reconfigure the guest OS to enable the vIOMMU then reboot,
016a62
the user will see the panic right after the reset when the next boot
016a62
starts.
016a62
016a62
Let's make this failure even earlier so that we force the user to use
016a62
caching-mode for vfio-pci devices when with the vIOMMU.  So the user
016a62
won't get surprise at least during execution of the guest, which seems
016a62
a bit nicer.
016a62
016a62
This will affect some user who didn't enable vIOMMU in the guest OS
016a62
but was using vfio-pci and the vtd device in the past.  However I hope
016a62
it's not a majority because not enabling vIOMMU with the device
016a62
attached is actually meaningless.
016a62
016a62
We still keep the old assertion for safety so far because the hotplug
016a62
path could still reach it, so far.
016a62
016a62
Reviewed-by: Eric Auger <eric.auger@redhat.com>
016a62
Signed-off-by: Peter Xu <peterx@redhat.com>
016a62
Message-Id: <20190916080718.3299-2-peterx@redhat.com>
016a62
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
016a62
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
016a62
(cherry picked from commit 28cf553afeb29b0c4f339c600171552a72a68cb7)
016a62
Signed-off-by: Peter Xu <peterx@redhat.com>
016a62
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
016a62
---
016a62
 hw/i386/intel_iommu.c | 39 ++++++++++++++++++++++++++++++++++++---
016a62
 1 file changed, 36 insertions(+), 3 deletions(-)
016a62
016a62
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
016a62
index 22d2e52..44d19cc 100644
016a62
--- a/hw/i386/intel_iommu.c
016a62
+++ b/hw/i386/intel_iommu.c
016a62
@@ -33,6 +33,7 @@
016a62
 #include "hw/i386/x86-iommu.h"
016a62
 #include "hw/pci-host/q35.h"
016a62
 #include "sysemu/kvm.h"
016a62
+#include "sysemu/sysemu.h"
016a62
 #include "hw/i386/apic_internal.h"
016a62
 #include "kvm_i386.h"
016a62
 #include "trace.h"
016a62
@@ -40,6 +41,13 @@
016a62
 static void vtd_address_space_refresh_all(IntelIOMMUState *s);
016a62
 static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
016a62
 
016a62
+static void vtd_panic_require_caching_mode(void)
016a62
+{
016a62
+    error_report("We need to set caching-mode=on for intel-iommu to enable "
016a62
+                 "device assignment with IOMMU protection.");
016a62
+    exit(1);
016a62
+}
016a62
+
016a62
 static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
016a62
                             uint64_t wmask, uint64_t w1cmask)
016a62
 {
016a62
@@ -2554,9 +2562,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
016a62
     IntelIOMMUState *s = vtd_as->iommu_state;
016a62
 
016a62
     if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
016a62
-        error_report("We need to set caching-mode=on for intel-iommu to enable "
016a62
-                     "device assignment with IOMMU protection.");
016a62
-        exit(1);
016a62
+        vtd_panic_require_caching_mode();
016a62
     }
016a62
 
016a62
     /* Update per-address-space notifier flags */
016a62
@@ -3303,6 +3309,32 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
016a62
     return true;
016a62
 }
016a62
 
016a62
+static int vtd_machine_done_notify_one(Object *child, void *unused)
016a62
+{
016a62
+    IntelIOMMUState *iommu = INTEL_IOMMU_DEVICE(x86_iommu_get_default());
016a62
+
016a62
+    /*
016a62
+     * We hard-coded here because vfio-pci is the only special case
016a62
+     * here.  Let's be more elegant in the future when we can, but so
016a62
+     * far there seems to be no better way.
016a62
+     */
016a62
+    if (object_dynamic_cast(child, "vfio-pci") && !iommu->caching_mode) {
016a62
+        vtd_panic_require_caching_mode();
016a62
+    }
016a62
+
016a62
+    return 0;
016a62
+}
016a62
+
016a62
+static void vtd_machine_done_hook(Notifier *notifier, void *unused)
016a62
+{
016a62
+    object_child_foreach_recursive(object_get_root(),
016a62
+                                   vtd_machine_done_notify_one, NULL);
016a62
+}
016a62
+
016a62
+static Notifier vtd_machine_done_notify = {
016a62
+    .notify = vtd_machine_done_hook,
016a62
+};
016a62
+
016a62
 static void vtd_realize(DeviceState *dev, Error **errp)
016a62
 {
016a62
     MachineState *ms = MACHINE(qdev_get_machine());
016a62
@@ -3333,6 +3365,7 @@ static void vtd_realize(DeviceState *dev, Error **errp)
016a62
     pci_setup_iommu(bus, vtd_host_dma_iommu, dev);
016a62
     /* Pseudo address space under root PCI bus. */
016a62
     pcms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC);
016a62
+    qemu_add_machine_init_done_notifier(&vtd_machine_done_notify);
016a62
 }
016a62
 
016a62
 static void vtd_class_init(ObjectClass *klass, void *data)
016a62
-- 
016a62
1.8.3.1
016a62