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

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