virtio: make bindings typesafe
PATCH v3 1/1 virtio: make bindings typesafe
Move bindings from opaque to DeviceState.
This gives us better type safety with no performance cost. Add macros to make future QOM work easier.
Note: this code is not replacing QOM use with non QOM - it is replacing unsafe void * use with type-checked use. Switch of the implementation to QOM where feasible can be done by a follow-up patch.
---
Changes from v2:
- More comments by Anreas F\344rber:
Document which code is datapath, create wrapper to make future QOM changes easier.
- Address comment by Anthony:
use inline functions for type safety and to avoid conflicting with QOM
Changes from v1:
- Address comment by Anreas F\344rber: wrap container_of macros to make future QOM work easier
- make a couple of bindings that v1 missed typesafe:
virtio doesn't use any void * now
hw/s390-virtio-bus.c +19 -5
@@ -137,7 +137,7 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev) bus->dev_offs += dev_len; -virtio_bind_device (vdev, &virtio_s390_bindings, dev); +virtio_bind_device (vdev, &virtio_s390_bindings,DEVICE (dev)); dev->host_features = vdev->get_features (vdev, dev->host_features);s390_virtio_device_sync (dev);s390_virtio_reset_idx (dev);
@@ -364,9 +364,23 @@ VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)return NULL ; } -static void virtio_s390_notify (void *opaque,uint16_t vector) +/* DeviceState to VirtIOS390Device. Note: used on datapath, +* be careful and test performance if you change this. +*/ +static inline VirtIOS390Device *to_virtio_s390_device_fast (DeviceState *d) +{ +return container_of (d, VirtIOS390Device, qdev); +} + +/* DeviceState to VirtIOS390Device. TODO: use QOM. */ +static inline VirtIOS390Device *to_virtio_s390_device (DeviceState *d) +{ +return container_of (d, VirtIOS390Device, qdev); +} + +static void virtio_s390_notify (DeviceState *d,uint16_t vector) { -VirtIOS390Device *dev = (VirtIOS390Device *)opaque; +VirtIOS390Device *dev =to_virtio_s390_device_fast (d);uint64_t token =s390_virtio_device_vq_token (dev, vector);S390CPU *cpu =s390_cpu_addr2state (0 );CPUS390XState *env = &cpu->env;
@@ -374,9 +388,9 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)s390_virtio_irq (env,0 , token); } -static unsigned virtio_s390_get_features (void *opaque) +static unsigned virtio_s390_get_features (DeviceState *d) { -VirtIOS390Device *dev = (VirtIOS390Device *)opaque; +VirtIOS390Device *dev =to_virtio_s390_device (d);return dev->host_features; }
hw/virtio-pci.c +39 -26
160 lines not on this page · raw message
hw/virtio.c +1 -1
@@ -935,7 +935,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, }void virtio_bind_device (VirtIODevice *vdev,const VirtIOBindings *binding, -void *opaque) +DeviceState *opaque) { vdev->binding = binding; vdev->binding_opaque = opaque;
hw/virtio.h +13 -13
@@ -91,17 +91,17 @@ typedef struct VirtQueueElement } VirtQueueElement;typedef struct { -void (*notify)(void * opaque,uint16_t vector); -void (*save_config)(void * opaque,QEMUFile *f); -void (*save_queue)(void * opaque,int n,QEMUFile *f); -int (*load_config)(void * opaque,QEMUFile *f); -int (*load_queue)(void * opaque,int n,QEMUFile *f); -int (*load_done)(void * opaque,QEMUFile *f); -unsigned (*get_features)(void * opaque); -bool (*query_guest_notifiers)(void * opaque); -int (*set_guest_notifiers)(void * opaque,bool assigned); -int (*set_host_notifier)(void * opaque,int n,bool assigned); -void (*vmstate_change)(void * opaque,bool running); +void (*notify)(DeviceState *d,uint16_t vector); +void (*save_config)(DeviceState *d,QEMUFile *f); +void (*save_queue)(DeviceState *d,int n,QEMUFile *f); +int (*load_config)(DeviceState *d,QEMUFile *f); +int (*load_queue)(DeviceState *d,int n,QEMUFile *f); +int (*load_done)(DeviceState *d,QEMUFile *f); +unsigned (*get_features)(DeviceState *d); +bool (*query_guest_notifiers)(DeviceState *d); +int (*set_guest_notifiers)(DeviceState *d,bool assigned); +int (*set_host_notifier)(DeviceState *d,int n,bool assigned); +void (*vmstate_change)(DeviceState *d,bool running); }VirtIOBindings ;#define VIRTIO_PCI_QUEUE_MAX 64
@@ -128,7 +128,7 @@ struct VirtIODevicevoid (*set_status)(VirtIODevice *vdev,uint8_t val);VirtQueue *vq;const VirtIOBindings *binding; -void *binding_opaque; +DeviceState *binding_opaque;uint16_t device_id;bool vm_running;VMChangeStateEntry *vmstate;
@@ -191,7 +191,7 @@ void virtio_update_irq(VirtIODevice *vdev);int virtio_set_features (VirtIODevice *vdev,uint32_t val);void virtio_bind_device (VirtIODevice *vdev,const VirtIOBindings *binding, -void *opaque); +DeviceState *opaque);/* Base devices. */ typedef struct VirtIOBlkConf VirtIOBlkConf ;