@@ -281,9 +281,8 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev)
{
VirtIOBalloon *s;
- s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
- VIRTIO_ID_BALLOON,
- 8, sizeof(VirtIOBalloon));
+ s = VIRTIO_COMMON_INIT("virtio-balloon", VIRTIO_ID_BALLOON, 8,
+ VirtIOBalloon, vdev);
s->vdev.get_config = virtio_balloon_get_config;
s->vdev.set_config = virtio_balloon_set_config;
@@ -482,9 +482,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
int cylinders, heads, secs;
static int virtio_blk_id;
- s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
- sizeof(struct virtio_blk_config),
- sizeof(VirtIOBlock));
+ s = VIRTIO_COMMON_INIT("virtio-blk", VIRTIO_ID_BLOCK,
+ sizeof(struct virtio_blk_config),
+ VirtIOBlock, vdev);
s->vdev.get_config = virtio_blk_update_config;
s->vdev.get_features = virtio_blk_get_features;
@@ -836,9 +836,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
VirtIONet *n;
static int virtio_net_id;
- n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
- sizeof(struct virtio_net_config),
- sizeof(VirtIONet));
+ n = VIRTIO_COMMON_INIT("virtio-net", VIRTIO_ID_NET,
+ sizeof(struct virtio_net_config),
+ VirtIONet, vdev);
n->vdev.get_config = virtio_net_get_config;
n->vdev.set_config = virtio_net_set_config;
@@ -567,11 +567,11 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
if (!max_nr_ports)
return NULL;
- vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
+ vser = VIRTIO_COMMON_INIT("virtio-serial", VIRTIO_ID_CONSOLE,
sizeof(struct virtio_console_config),
- sizeof(VirtIOSerial));
+ VirtIOSerial, vdev);
- vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ vdev = &vser->vdev;
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
vser->bus = virtser_bus_new(dev);
@@ -701,12 +701,13 @@ void virtio_cleanup(VirtIODevice *vdev)
}
VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
- size_t config_size, size_t struct_size)
+ size_t config_size, size_t struct_size,
+ size_t struct_offset)
{
VirtIODevice *vdev;
int i;
- vdev = qemu_mallocz(struct_size);
+ vdev = qemu_mallocz(struct_size) + struct_offset;
vdev->device_id = device_id;
vdev->status = 0;
@@ -150,7 +150,14 @@ int virtio_queue_empty(VirtQueue *vq);
/* Host binding interface. */
VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
- size_t config_size, size_t struct_size);
+ size_t config_size, size_t struct_size,
+ size_t struct_offset);
+#define VIRTIO_COMMON_INIT(_name, _device_id, _config_size, _type, _field) \
+ container_of(virtio_common_init((_name), (_device_id), (_config_size), \
+ sizeof(_type), offsetof(_type, _field) + \
+ type_check(VirtIODevice, \
+ typeof_field(_type, _field)) \
+ ), _type, _field)
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);
This adds VIRTIO_COMMON_INIT which is type-safe and let us get rid of struct layout assumptions. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> --- hw/virtio-balloon.c | 5 ++--- hw/virtio-blk.c | 6 +++--- hw/virtio-net.c | 6 +++--- hw/virtio-serial-bus.c | 6 +++--- hw/virtio.c | 5 +++-- hw/virtio.h | 9 ++++++++- 6 files changed, 22 insertions(+), 15 deletions(-)