All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs
@ 2019-01-18 13:38 Daniel P. Berrangé
  2019-01-28 17:48 ` Eduardo Habkost
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel P. Berrangé @ 2019-01-18 13:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gonglei, Michael S. Tsirkin, Gerd Hoffmann, Eduardo Habkost,
	Daniel P. Berrangé

A number of virtio devices (gpu, crypto, mouse, keyboard, tablet) only
support the virtio-1 (aka modern) mode. Currently if the user launches
QEMU, setting those devices to enable legacy mode, QEMU will silently
create them in modern mode, ignoring the user's (mistaken) request.

This patch introduces proper data validation so that an attempt to
configure a virtio-1-only devices in legacy mode gets reported as an
error to the user.

Checking this required introduction of a new field to explicitly track
what operating model is to be used for a device, separately from the
disable_modern and disable_legacy fields that record the user's
requested configuration.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 hw/display/virtio-gpu-pci.c   |  4 +++-
 hw/display/virtio-vga.c       |  4 +++-
 hw/virtio/virtio-crypto-pci.c |  4 +++-
 hw/virtio/virtio-pci.c        | 30 +++++++++++++++++++-----------
 hw/virtio/virtio-pci.h        | 31 +++++++++++++++++++++++++------
 5 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index faf76a8bc4..a5b5ce5755 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -33,7 +33,9 @@ static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     Error *local_error = NULL;
 
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    if (!virtio_pci_force_virtio_1(vpci_dev, errp)) {
+        return;
+    }
     object_property_set_bool(OBJECT(vdev), true, "realized", &local_error);
 
     if (local_error) {
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 8db4d916f2..ae3604c576 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -144,7 +144,9 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 
     /* init virtio bits */
     qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    if (!virtio_pci_force_virtio_1(vpci_dev, errp)) {
+        return;
+    }
     object_property_set_bool(OBJECT(g), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c
index 8cc3fa3ef7..177b720458 100644
--- a/hw/virtio/virtio-crypto-pci.c
+++ b/hw/virtio/virtio-crypto-pci.c
@@ -37,7 +37,9 @@ static void virtio_crypto_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     }
 
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    if (!virtio_pci_force_virtio_1(vpci_dev, errp)) {
+        return;
+    }
     object_property_set_bool(OBJECT(vdev), true, "realized", errp);
     object_property_set_link(OBJECT(vcrypto),
                  OBJECT(vcrypto->vdev.conf.cryptodev), "cryptodev",
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index d05066deb8..75fdee40a8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1778,16 +1778,22 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
                        /* PCI BAR regions must be powers of 2 */
                        pow2ceil(proxy->notify.offset + proxy->notify.size));
 
-    if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) {
-        proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
-    }
-
-    if (!virtio_pci_modern(proxy) && !virtio_pci_legacy(proxy)) {
-        error_setg(errp, "device cannot work as neither modern nor legacy mode"
-                   " is enabled");
-        error_append_hint(errp, "Set either disable-modern or disable-legacy"
-                          " to off\n");
-        return;
+    if ((proxy->disable_legacy == ON_OFF_AUTO_ON) ||
+        ((proxy->disable_legacy == ON_OFF_AUTO_AUTO) && pcie_port)) {
+        if (proxy->disable_modern) {
+            error_setg(errp, "device cannot work as neither modern nor "
+                       "legacy mode is enabled");
+            error_append_hint(errp, "Set either disable-modern or "
+                              "disable-legacy to off\n");
+            return;
+        }
+        proxy->mode = VIRTIO_PCI_MODE_MODERN;
+    } else {
+        if (proxy->disable_modern) {
+            proxy->mode = VIRTIO_PCI_MODE_LEGACY;
+        } else {
+            proxy->mode = VIRTIO_PCI_MODE_TRANSITIONAL;
+        }
     }
 
     if (pcie_port && pci_is_express(pci_dev)) {
@@ -2663,7 +2669,9 @@ static void virtio_input_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     DeviceState *vdev = DEVICE(&vinput->vdev);
 
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    if (!virtio_pci_force_virtio_1(vpci_dev, errp)) {
+        return;
+    }
     object_property_set_bool(OBJECT(vdev), true, "realized", errp);
 }
 
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 29b4216107..d21c382702 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -15,6 +15,7 @@
 #ifndef QEMU_VIRTIO_PCI_H
 #define QEMU_VIRTIO_PCI_H
 
+#include "qapi/error.h"
 #include "hw/pci/msi.h"
 #include "hw/virtio/virtio-blk.h"
 #include "hw/virtio/virtio-net.h"
@@ -156,6 +157,12 @@ typedef struct VirtIOPCIQueue {
   uint32_t used[2];
 } VirtIOPCIQueue;
 
+typedef enum {
+    VIRTIO_PCI_MODE_LEGACY,
+    VIRTIO_PCI_MODE_TRANSITIONAL,
+    VIRTIO_PCI_MODE_MODERN,
+} VirtIOPCIMode;
+
 struct VirtIOPCIProxy {
     PCIDevice pci_dev;
     MemoryRegion bar;
@@ -180,6 +187,7 @@ struct VirtIOPCIProxy {
     bool disable_modern;
     bool ignore_backend_features;
     OnOffAuto disable_legacy;
+    VirtIOPCIMode mode;
     uint32_t class_code;
     uint32_t nvectors;
     uint32_t dfselect;
@@ -194,23 +202,34 @@ struct VirtIOPCIProxy {
 
 static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
 {
-    return !proxy->disable_modern;
+    return proxy->mode != VIRTIO_PCI_MODE_LEGACY;
 }
 
 static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy)
 {
-    return proxy->disable_legacy == ON_OFF_AUTO_OFF;
+    return proxy->mode != VIRTIO_PCI_MODE_MODERN;
 }
 
-static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy)
+static inline bool virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy,
+                                             Error **errp)
 {
-    proxy->disable_modern = false;
-    proxy->disable_legacy = ON_OFF_AUTO_ON;
+    if (proxy->disable_legacy == ON_OFF_AUTO_OFF) {
+        error_setg(errp, "Unable to set disable-legacy=off on a virtio-1.0 "
+                   "only device");
+        return false;
+    }
+    if (proxy->disable_modern == true) {
+        error_setg(errp, "Unable to set disable-modern=on on a virtio-1.0 "
+                   "only device");
+        return false;
+    }
+    proxy->mode = VIRTIO_PCI_MODE_MODERN;
+    return true;
 }
 
 static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy)
 {
-    proxy->disable_modern = true;
+    proxy->mode = VIRTIO_PCI_MODE_LEGACY;
 }
 
 /*
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs
  2019-01-18 13:38 [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs Daniel P. Berrangé
@ 2019-01-28 17:48 ` Eduardo Habkost
  2019-02-01 22:19   ` Michael S. Tsirkin
  2019-02-15 10:34   ` Daniel P. Berrangé
  0 siblings, 2 replies; 5+ messages in thread
From: Eduardo Habkost @ 2019-01-28 17:48 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: qemu-devel, Gonglei, Michael S. Tsirkin, Gerd Hoffmann

On Fri, Jan 18, 2019 at 01:38:26PM +0000, Daniel P. Berrangé wrote:
> A number of virtio devices (gpu, crypto, mouse, keyboard, tablet) only
> support the virtio-1 (aka modern) mode. Currently if the user launches
> QEMU, setting those devices to enable legacy mode, QEMU will silently
> create them in modern mode, ignoring the user's (mistaken) request.
> 
> This patch introduces proper data validation so that an attempt to
> configure a virtio-1-only devices in legacy mode gets reported as an
> error to the user.
> 
> Checking this required introduction of a new field to explicitly track
> what operating model is to be used for a device, separately from the
> disable_modern and disable_legacy fields that record the user's
> requested configuration.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

This breaks the virtio-1-only devices on pc-*-2.6:

  $ ./x86_64-softmmu/qemu-system-x86_64 -device virtio-vga -machine pc-i440fx-2.6
  qemu-system-x86_64: -device virtio-vga: Unable to set disable-legacy=off on a virtio-1.0 only device

Probably the simplest way to fix that is to append the following to
hw_compat_2_6:

  { virtio-vga,        disable-modern, off },
  { virtio-gpu-pci,    disable-modern, off },
  { virtio-input-pci,  disable-modern, off },
  { virtio-crypto-pci, disable-modern, off }

We could also remove the property completely from those devices
(e.g. by moving virtio-vga to virtio_vga_info.non_transitional_name),
but it would break compatibility in case people are explicitly
setting "disable-modern=off" on those devices.

-- 
Eduardo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs
  2019-01-28 17:48 ` Eduardo Habkost
@ 2019-02-01 22:19   ` Michael S. Tsirkin
  2019-02-04 10:05     ` Daniel P. Berrangé
  2019-02-15 10:34   ` Daniel P. Berrangé
  1 sibling, 1 reply; 5+ messages in thread
From: Michael S. Tsirkin @ 2019-02-01 22:19 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Daniel P. Berrangé, qemu-devel, Gonglei, Gerd Hoffmann

On Mon, Jan 28, 2019 at 03:48:57PM -0200, Eduardo Habkost wrote:
> On Fri, Jan 18, 2019 at 01:38:26PM +0000, Daniel P. Berrangé wrote:
> > A number of virtio devices (gpu, crypto, mouse, keyboard, tablet) only
> > support the virtio-1 (aka modern) mode. Currently if the user launches
> > QEMU, setting those devices to enable legacy mode, QEMU will silently
> > create them in modern mode, ignoring the user's (mistaken) request.
> > 
> > This patch introduces proper data validation so that an attempt to
> > configure a virtio-1-only devices in legacy mode gets reported as an
> > error to the user.
> > 
> > Checking this required introduction of a new field to explicitly track
> > what operating model is to be used for a device, separately from the
> > disable_modern and disable_legacy fields that record the user's
> > requested configuration.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> 
> This breaks the virtio-1-only devices on pc-*-2.6:
> 
>   $ ./x86_64-softmmu/qemu-system-x86_64 -device virtio-vga -machine pc-i440fx-2.6
>   qemu-system-x86_64: -device virtio-vga: Unable to set disable-legacy=off on a virtio-1.0 only device
> 
> Probably the simplest way to fix that is to append the following to
> hw_compat_2_6:
> 
>   { virtio-vga,        disable-modern, off },
>   { virtio-gpu-pci,    disable-modern, off },
>   { virtio-input-pci,  disable-modern, off },
>   { virtio-crypto-pci, disable-modern, off }

Daniel do you plan to take a stub at this approach?

> We could also remove the property completely from those devices
> (e.g. by moving virtio-vga to virtio_vga_info.non_transitional_name),
> but it would break compatibility in case people are explicitly
> setting "disable-modern=off" on those devices.
> 
> -- 
> Eduardo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs
  2019-02-01 22:19   ` Michael S. Tsirkin
@ 2019-02-04 10:05     ` Daniel P. Berrangé
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel P. Berrangé @ 2019-02-04 10:05 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Eduardo Habkost, qemu-devel, Gonglei, Gerd Hoffmann

On Fri, Feb 01, 2019 at 05:19:32PM -0500, Michael S. Tsirkin wrote:
> On Mon, Jan 28, 2019 at 03:48:57PM -0200, Eduardo Habkost wrote:
> > On Fri, Jan 18, 2019 at 01:38:26PM +0000, Daniel P. Berrangé wrote:
> > > A number of virtio devices (gpu, crypto, mouse, keyboard, tablet) only
> > > support the virtio-1 (aka modern) mode. Currently if the user launches
> > > QEMU, setting those devices to enable legacy mode, QEMU will silently
> > > create them in modern mode, ignoring the user's (mistaken) request.
> > > 
> > > This patch introduces proper data validation so that an attempt to
> > > configure a virtio-1-only devices in legacy mode gets reported as an
> > > error to the user.
> > > 
> > > Checking this required introduction of a new field to explicitly track
> > > what operating model is to be used for a device, separately from the
> > > disable_modern and disable_legacy fields that record the user's
> > > requested configuration.
> > > 
> > > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > 
> > This breaks the virtio-1-only devices on pc-*-2.6:
> > 
> >   $ ./x86_64-softmmu/qemu-system-x86_64 -device virtio-vga -machine pc-i440fx-2.6
> >   qemu-system-x86_64: -device virtio-vga: Unable to set disable-legacy=off on a virtio-1.0 only device
> > 
> > Probably the simplest way to fix that is to append the following to
> > hw_compat_2_6:
> > 
> >   { virtio-vga,        disable-modern, off },
> >   { virtio-gpu-pci,    disable-modern, off },
> >   { virtio-input-pci,  disable-modern, off },
> >   { virtio-crypto-pci, disable-modern, off }
> 
> Daniel do you plan to take a stub at this approach?

Yes, its on my todo list, just haven't got to it yet

> 
> > We could also remove the property completely from those devices
> > (e.g. by moving virtio-vga to virtio_vga_info.non_transitional_name),
> > but it would break compatibility in case people are explicitly
> > setting "disable-modern=off" on those devices.
> > 
> > -- 
> > Eduardo

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs
  2019-01-28 17:48 ` Eduardo Habkost
  2019-02-01 22:19   ` Michael S. Tsirkin
@ 2019-02-15 10:34   ` Daniel P. Berrangé
  1 sibling, 0 replies; 5+ messages in thread
From: Daniel P. Berrangé @ 2019-02-15 10:34 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: qemu-devel, Gonglei, Michael S. Tsirkin, Gerd Hoffmann

On Mon, Jan 28, 2019 at 03:48:57PM -0200, Eduardo Habkost wrote:
> On Fri, Jan 18, 2019 at 01:38:26PM +0000, Daniel P. Berrangé wrote:
> > A number of virtio devices (gpu, crypto, mouse, keyboard, tablet) only
> > support the virtio-1 (aka modern) mode. Currently if the user launches
> > QEMU, setting those devices to enable legacy mode, QEMU will silently
> > create them in modern mode, ignoring the user's (mistaken) request.
> > 
> > This patch introduces proper data validation so that an attempt to
> > configure a virtio-1-only devices in legacy mode gets reported as an
> > error to the user.
> > 
> > Checking this required introduction of a new field to explicitly track
> > what operating model is to be used for a device, separately from the
> > disable_modern and disable_legacy fields that record the user's
> > requested configuration.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> 
> This breaks the virtio-1-only devices on pc-*-2.6:
> 
>   $ ./x86_64-softmmu/qemu-system-x86_64 -device virtio-vga -machine pc-i440fx-2.6
>   qemu-system-x86_64: -device virtio-vga: Unable to set disable-legacy=off on a virtio-1.0 only device
> 
> Probably the simplest way to fix that is to append the following to
> hw_compat_2_6:
> 
>   { virtio-vga,        disable-modern, off },
>   { virtio-gpu-pci,    disable-modern, off },
>   { virtio-input-pci,  disable-modern, off },
>   { virtio-crypto-pci, disable-modern, off }

That's no sufficient, as it needs to also set disable-legacy=on

Once we add all these extra properties, it becomes pointless to
try to use the generic settings against virtio-pci in hw_compat_2_6.
So I've just turn it into a whitelist, only listing the devices
which actually support both modern+legacy modes. This makes it
obvious which devices are being affected & avoids silent surprises
like this bug you found in my patch.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-02-15 10:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18 13:38 [Qemu-devel] [PATCH] hw: report invalid disable-legacy|modern usage for virtio-1-only devs Daniel P. Berrangé
2019-01-28 17:48 ` Eduardo Habkost
2019-02-01 22:19   ` Michael S. Tsirkin
2019-02-04 10:05     ` Daniel P. Berrangé
2019-02-15 10:34   ` Daniel P. Berrangé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.