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> Message-Id: <20190215103239.28640-2-berrange@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
160 lines
4.8 KiB
C
160 lines
4.8 KiB
C
/*
|
|
* Virtio input PCI Bindings
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or
|
|
* (at your option) any later version. See the COPYING file in the
|
|
* top-level directory.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
|
|
#include "virtio-pci.h"
|
|
#include "hw/virtio/virtio-input.h"
|
|
|
|
typedef struct VirtIOInputPCI VirtIOInputPCI;
|
|
typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
|
|
|
|
/*
|
|
* virtio-input-pci: This extends VirtioPCIProxy.
|
|
*/
|
|
#define VIRTIO_INPUT_PCI(obj) \
|
|
OBJECT_CHECK(VirtIOInputPCI, (obj), TYPE_VIRTIO_INPUT_PCI)
|
|
|
|
struct VirtIOInputPCI {
|
|
VirtIOPCIProxy parent_obj;
|
|
VirtIOInput vdev;
|
|
};
|
|
|
|
#define TYPE_VIRTIO_INPUT_HID_PCI "virtio-input-hid-pci"
|
|
#define TYPE_VIRTIO_KEYBOARD_PCI "virtio-keyboard-pci"
|
|
#define TYPE_VIRTIO_MOUSE_PCI "virtio-mouse-pci"
|
|
#define TYPE_VIRTIO_TABLET_PCI "virtio-tablet-pci"
|
|
#define VIRTIO_INPUT_HID_PCI(obj) \
|
|
OBJECT_CHECK(VirtIOInputHIDPCI, (obj), TYPE_VIRTIO_INPUT_HID_PCI)
|
|
|
|
struct VirtIOInputHIDPCI {
|
|
VirtIOPCIProxy parent_obj;
|
|
VirtIOInputHID vdev;
|
|
};
|
|
|
|
static Property virtio_input_pci_properties[] = {
|
|
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
};
|
|
|
|
static void virtio_input_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
|
{
|
|
VirtIOInputPCI *vinput = VIRTIO_INPUT_PCI(vpci_dev);
|
|
DeviceState *vdev = DEVICE(&vinput->vdev);
|
|
|
|
qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
|
|
if (!virtio_pci_force_virtio_1(vpci_dev, errp)) {
|
|
return;
|
|
}
|
|
object_property_set_bool(OBJECT(vdev), true, "realized", errp);
|
|
}
|
|
|
|
static void virtio_input_pci_class_init(ObjectClass *klass, void *data)
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
|
|
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
|
|
|
|
dc->props = virtio_input_pci_properties;
|
|
k->realize = virtio_input_pci_realize;
|
|
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
|
|
|
pcidev_k->class_id = PCI_CLASS_INPUT_OTHER;
|
|
}
|
|
|
|
static void virtio_input_hid_kbd_pci_class_init(ObjectClass *klass, void *data)
|
|
{
|
|
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
|
|
|
|
pcidev_k->class_id = PCI_CLASS_INPUT_KEYBOARD;
|
|
}
|
|
|
|
static void virtio_input_hid_mouse_pci_class_init(ObjectClass *klass,
|
|
void *data)
|
|
{
|
|
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
|
|
|
|
pcidev_k->class_id = PCI_CLASS_INPUT_MOUSE;
|
|
}
|
|
|
|
static void virtio_keyboard_initfn(Object *obj)
|
|
{
|
|
VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj);
|
|
|
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
|
TYPE_VIRTIO_KEYBOARD);
|
|
}
|
|
|
|
static void virtio_mouse_initfn(Object *obj)
|
|
{
|
|
VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj);
|
|
|
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
|
TYPE_VIRTIO_MOUSE);
|
|
}
|
|
|
|
static void virtio_tablet_initfn(Object *obj)
|
|
{
|
|
VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj);
|
|
|
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
|
TYPE_VIRTIO_TABLET);
|
|
}
|
|
|
|
static const TypeInfo virtio_input_pci_info = {
|
|
.name = TYPE_VIRTIO_INPUT_PCI,
|
|
.parent = TYPE_VIRTIO_PCI,
|
|
.instance_size = sizeof(VirtIOInputPCI),
|
|
.class_init = virtio_input_pci_class_init,
|
|
.abstract = true,
|
|
};
|
|
|
|
static const TypeInfo virtio_input_hid_pci_info = {
|
|
.name = TYPE_VIRTIO_INPUT_HID_PCI,
|
|
.parent = TYPE_VIRTIO_INPUT_PCI,
|
|
.instance_size = sizeof(VirtIOInputHIDPCI),
|
|
.abstract = true,
|
|
};
|
|
|
|
static const VirtioPCIDeviceTypeInfo virtio_keyboard_pci_info = {
|
|
.generic_name = TYPE_VIRTIO_KEYBOARD_PCI,
|
|
.parent = TYPE_VIRTIO_INPUT_HID_PCI,
|
|
.class_init = virtio_input_hid_kbd_pci_class_init,
|
|
.instance_size = sizeof(VirtIOInputHIDPCI),
|
|
.instance_init = virtio_keyboard_initfn,
|
|
};
|
|
|
|
static const VirtioPCIDeviceTypeInfo virtio_mouse_pci_info = {
|
|
.generic_name = TYPE_VIRTIO_MOUSE_PCI,
|
|
.parent = TYPE_VIRTIO_INPUT_HID_PCI,
|
|
.class_init = virtio_input_hid_mouse_pci_class_init,
|
|
.instance_size = sizeof(VirtIOInputHIDPCI),
|
|
.instance_init = virtio_mouse_initfn,
|
|
};
|
|
|
|
static const VirtioPCIDeviceTypeInfo virtio_tablet_pci_info = {
|
|
.generic_name = TYPE_VIRTIO_TABLET_PCI,
|
|
.parent = TYPE_VIRTIO_INPUT_HID_PCI,
|
|
.instance_size = sizeof(VirtIOInputHIDPCI),
|
|
.instance_init = virtio_tablet_initfn,
|
|
};
|
|
|
|
static void virtio_pci_input_register(void)
|
|
{
|
|
/* Base types: */
|
|
type_register_static(&virtio_input_pci_info);
|
|
type_register_static(&virtio_input_hid_pci_info);
|
|
|
|
/* Implementations: */
|
|
virtio_pci_types_register(&virtio_keyboard_pci_info);
|
|
virtio_pci_types_register(&virtio_mouse_pci_info);
|
|
virtio_pci_types_register(&virtio_tablet_pci_info);
|
|
}
|
|
|
|
type_init(virtio_pci_input_register)
|