diff mbox series

[RFC,3/4] pc/q35: Disallow vfio-pci hotplug without VT-d caching mode

Message ID 20190812074531.28970-4-peterx@redhat.com
State New
Headers show
Series intel_iommu: Do sanity check of vfio-pci earlier | expand

Commit Message

Peter Xu Aug. 12, 2019, 7:45 a.m. UTC
Instead of bailing out when trying to hotplug a vfio-pci device with
below configuration:

  -device intel-iommu,caching-mode=off

With this we can return a warning message to the user via QMP/HMP and
the VM will continue to work after failing the hotplug:

  (qemu) device_add vfio-pci,bus=root.3,host=05:00.0,id=vfio1
  Error: Device assignment is not allowed without enabling caching-mode=on for Intel IOMMU.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 hw/i386/pc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Eric Auger Sept. 16, 2019, 7:23 a.m. UTC | #1
Hi Peter,

On 8/12/19 9:45 AM, Peter Xu wrote:
> Instead of bailing out when trying to hotplug a vfio-pci device with
> below configuration:
> 
>   -device intel-iommu,caching-mode=off
> 
> With this we can return a warning message to the user via QMP/HMP and
> the VM will continue to work after failing the hotplug:
> 
>   (qemu) device_add vfio-pci,bus=root.3,host=05:00.0,id=vfio1
>   Error: Device assignment is not allowed without enabling caching-mode=on for Intel IOMMU.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  hw/i386/pc.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 549c437050..4ea00c7bd2 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -2905,6 +2905,26 @@ static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
>      }
>  }
>  
> +
> +static bool pc_hotplug_allowed(MachineState *ms, DeviceState *dev, Error **errp)
> +{
> +    X86IOMMUState *iommu = x86_iommu_get_default();
> +    IntelIOMMUState *intel_iommu;
> +
> +    if (iommu &&
> +        object_dynamic_cast((Object *)iommu, TYPE_INTEL_IOMMU_DEVICE) &&
> +        object_dynamic_cast((Object *)dev, "vfio-pci")) {
> +        intel_iommu = INTEL_IOMMU_DEVICE(iommu);
> +        if (!intel_iommu->caching_mode) {
> +            error_setg(errp, "Device assignment is not allowed without "
> +                       "enabling caching-mode=on for Intel IOMMU.");
> +            return false;
> +        }
> +    }
> +
> +    return true;
> +}
> +
>  static void pc_machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -2929,6 +2949,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
>      pcmc->pvh_enabled = true;
>      assert(!mc->get_hotplug_handler);
>      mc->get_hotplug_handler = pc_get_hotplug_handler;
> +    mc->hotplug_allowed = pc_hotplug_allowed;
>      mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
>      mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
>      mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
>
diff mbox series

Patch

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 549c437050..4ea00c7bd2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2905,6 +2905,26 @@  static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
     }
 }
 
+
+static bool pc_hotplug_allowed(MachineState *ms, DeviceState *dev, Error **errp)
+{
+    X86IOMMUState *iommu = x86_iommu_get_default();
+    IntelIOMMUState *intel_iommu;
+
+    if (iommu &&
+        object_dynamic_cast((Object *)iommu, TYPE_INTEL_IOMMU_DEVICE) &&
+        object_dynamic_cast((Object *)dev, "vfio-pci")) {
+        intel_iommu = INTEL_IOMMU_DEVICE(iommu);
+        if (!intel_iommu->caching_mode) {
+            error_setg(errp, "Device assignment is not allowed without "
+                       "enabling caching-mode=on for Intel IOMMU.");
+            return false;
+        }
+    }
+
+    return true;
+}
+
 static void pc_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -2929,6 +2949,7 @@  static void pc_machine_class_init(ObjectClass *oc, void *data)
     pcmc->pvh_enabled = true;
     assert(!mc->get_hotplug_handler);
     mc->get_hotplug_handler = pc_get_hotplug_handler;
+    mc->hotplug_allowed = pc_hotplug_allowed;
     mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
     mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
     mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;