From 32b5f5b895732dbf12ab26c520fc7396df77587f Mon Sep 17 00:00:00 2001
From: KONRAD Frederic <fred.konrad@greensocs.com>
Date: Mon, 18 Mar 2013 17:37:18 +0100
Subject: [PATCH] virtio: make virtio device's structures public.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

These structures must be made public to avoid two memory allocations for
refactored virtio devices.

Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-id: 1363624648-16906-2-git-send-email-fred.konrad@greensocs.com

Changes V4 <- V3:
   * Rebased on current git.

Changes V3 <- V2:
    * Style correction spotted by Andreas (virtio-scsi.h).
    * Style correction for virtio-net.h.

Changes V2 <- V1:
    * Move the dataplane include into the header (virtio-blk).
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f1b24e840f9f85a2bb3912e4507d887e7858219d)
[BR: Fix and/or infrastructure for BSC#1020427 CVE-2016-9602]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
 hw/virtio-balloon.c    | 15 -------------
 hw/virtio-balloon.h    | 14 ++++++++++++
 hw/virtio-blk.c        | 21 ------------------
 hw/virtio-blk.h        | 20 +++++++++++++++++
 hw/virtio-net.c        | 50 ------------------------------------------
 hw/virtio-net.h        | 50 ++++++++++++++++++++++++++++++++++++++++++
 hw/virtio-rng.c        | 19 ----------------
 hw/virtio-rng.h        | 19 ++++++++++++++++
 hw/virtio-scsi.c       | 15 -------------
 hw/virtio-scsi.h       | 16 ++++++++++++++
 hw/virtio-serial-bus.c | 40 ---------------------------------
 hw/virtio-serial.h     | 41 ++++++++++++++++++++++++++++++++++
 12 files changed, 160 insertions(+), 160 deletions(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index f841e81601..6757cf45ba 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -29,21 +29,6 @@
 #include <sys/mman.h>
 #endif
 
-typedef struct VirtIOBalloon
-{
-    VirtIODevice vdev;
-    VirtQueue *ivq, *dvq, *svq;
-    uint32_t num_pages;
-    uint32_t actual;
-    uint64_t stats[VIRTIO_BALLOON_S_NR];
-    VirtQueueElement stats_vq_elem;
-    size_t stats_vq_offset;
-    QEMUTimer *stats_timer;
-    int64_t stats_last_update;
-    int64_t stats_poll_interval;
-    DeviceState *qdev;
-} VirtIOBalloon;
-
 static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev)
 {
     return (VirtIOBalloon *)vdev;
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
index b1828f4a48..579a1e52d0 100644
--- a/hw/virtio-balloon.h
+++ b/hw/virtio-balloon.h
@@ -52,4 +52,18 @@ typedef struct VirtIOBalloonStat {
     uint64_t val;
 } QEMU_PACKED VirtIOBalloonStat;
 
+typedef struct VirtIOBalloon {
+    VirtIODevice vdev;
+    VirtQueue *ivq, *dvq, *svq;
+    uint32_t num_pages;
+    uint32_t actual;
+    uint64_t stats[VIRTIO_BALLOON_S_NR];
+    VirtQueueElement stats_vq_elem;
+    size_t stats_vq_offset;
+    QEMUTimer *stats_timer;
+    int64_t stats_last_update;
+    int64_t stats_poll_interval;
+    DeviceState *qdev;
+} VirtIOBalloon;
+
 #endif
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 142970b00d..35b32ebeca 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -17,32 +17,11 @@
 #include "hw/block-common.h"
 #include "sysemu/blockdev.h"
 #include "virtio-blk.h"
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-#include "hw/dataplane/virtio-blk.h"
-#endif
 #include "scsi-defs.h"
 #ifdef __linux__
 # include <scsi/sg.h>
 #endif
 
-typedef struct VirtIOBlock
-{
-    VirtIODevice vdev;
-    BlockDriverState *bs;
-    VirtQueue *vq;
-    void *rq;
-    QEMUBH *bh;
-    BlockConf *conf;
-    VirtIOBlkConf *blk;
-    unsigned short sector_mask;
-    bool original_wce;
-    DeviceState *qdev;
-    VMChangeStateEntry *change;
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-    VirtIOBlockDataPlane *dataplane;
-#endif
-} VirtIOBlock;
-
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
 {
     return (VirtIOBlock *)vdev;
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 43ca492080..8af92debcb 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -16,6 +16,9 @@
 
 #include "virtio.h"
 #include "hw/block-common.h"
+#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
+#include "dataplane/virtio-blk.h"
+#endif
 
 /* from Linux's linux/virtio_blk.h */
 
@@ -108,6 +111,23 @@ struct VirtIOBlkConf
     uint32_t data_plane;
 };
 
+typedef struct VirtIOBlock {
+    VirtIODevice vdev;
+    BlockDriverState *bs;
+    VirtQueue *vq;
+    void *rq;
+    QEMUBH *bh;
+    BlockConf *conf;
+    VirtIOBlkConf *blk;
+    unsigned short sector_mask;
+    bool original_wce;
+    DeviceState *qdev;
+    VMChangeStateEntry *change;
+#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
+    VirtIOBlockDataPlane *dataplane;
+#endif
+} VirtIOBlock;
+
 #define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
         DEFINE_VIRTIO_COMMON_FEATURES(_state, _field)
 
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index b1c0f9cde3..b9662adee5 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -26,56 +26,6 @@
 #define MAC_TABLE_ENTRIES    64
 #define MAX_VLAN    (1 << 12)   /* Per 802.1Q definition */
 
-typedef struct VirtIONetQueue {
-    VirtQueue *rx_vq;
-    VirtQueue *tx_vq;
-    QEMUTimer *tx_timer;
-    QEMUBH *tx_bh;
-    int tx_waiting;
-    struct {
-        VirtQueueElement elem;
-        ssize_t len;
-    } async_tx;
-    struct VirtIONet *n;
-} VirtIONetQueue;
-
-typedef struct VirtIONet
-{
-    VirtIODevice vdev;
-    uint8_t mac[ETH_ALEN];
-    uint16_t status;
-    VirtIONetQueue *vqs;
-    VirtQueue *ctrl_vq;
-    NICState *nic;
-    uint32_t tx_timeout;
-    int32_t tx_burst;
-    uint32_t has_vnet_hdr;
-    size_t host_hdr_len;
-    size_t guest_hdr_len;
-    uint8_t has_ufo;
-    int mergeable_rx_bufs;
-    uint8_t promisc;
-    uint8_t allmulti;
-    uint8_t alluni;
-    uint8_t nomulti;
-    uint8_t nouni;
-    uint8_t nobcast;
-    uint8_t vhost_started;
-    struct {
-        uint32_t in_use;
-        uint32_t first_multi;
-        uint8_t multi_overflow;
-        uint8_t uni_overflow;
-        uint8_t *macs;
-    } mac_table;
-    uint32_t *vlans;
-    DeviceState *qdev;
-    int multiqueue;
-    uint16_t max_queues;
-    uint16_t curr_queues;
-    size_t config_size;
-} VirtIONet;
-
 /*
  * Calculate the number of bytes up to and including the given 'field' of
  * 'container'.
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index e654c13a9f..babddf886f 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -134,6 +134,56 @@ struct virtio_net_ctrl_mac {
     uint32_t entries;
     uint8_t macs[][ETH_ALEN];
 };
+
+typedef struct VirtIONetQueue {
+    VirtQueue *rx_vq;
+    VirtQueue *tx_vq;
+    QEMUTimer *tx_timer;
+    QEMUBH *tx_bh;
+    int tx_waiting;
+    struct {
+        VirtQueueElement elem;
+        ssize_t len;
+    } async_tx;
+    struct VirtIONet *n;
+} VirtIONetQueue;
+
+typedef struct VirtIONet {
+    VirtIODevice vdev;
+    uint8_t mac[ETH_ALEN];
+    uint16_t status;
+    VirtIONetQueue *vqs;
+    VirtQueue *ctrl_vq;
+    NICState *nic;
+    uint32_t tx_timeout;
+    int32_t tx_burst;
+    uint32_t has_vnet_hdr;
+    size_t host_hdr_len;
+    size_t guest_hdr_len;
+    uint8_t has_ufo;
+    int mergeable_rx_bufs;
+    uint8_t promisc;
+    uint8_t allmulti;
+    uint8_t alluni;
+    uint8_t nomulti;
+    uint8_t nouni;
+    uint8_t nobcast;
+    uint8_t vhost_started;
+    struct {
+        int in_use;
+        int first_multi;
+        uint8_t multi_overflow;
+        uint8_t uni_overflow;
+        uint8_t *macs;
+    } mac_table;
+    uint32_t *vlans;
+    DeviceState *qdev;
+    int multiqueue;
+    uint16_t max_queues;
+    uint16_t curr_queues;
+    size_t config_size;
+} VirtIONet;
+
 #define VIRTIO_NET_CTRL_MAC    1
  #define VIRTIO_NET_CTRL_MAC_TABLE_SET        0
  #define VIRTIO_NET_CTRL_MAC_ADDR_SET         1
diff --git a/hw/virtio-rng.c b/hw/virtio-rng.c
index e063127df6..d79aa46400 100644
--- a/hw/virtio-rng.c
+++ b/hw/virtio-rng.c
@@ -15,25 +15,6 @@
 #include "virtio-rng.h"
 #include "qemu/rng.h"
 
-typedef struct VirtIORNG {
-    VirtIODevice vdev;
-
-    DeviceState *qdev;
-
-    /* Only one vq - guest puts buffer(s) on it when it needs entropy */
-    VirtQueue *vq;
-
-    VirtIORNGConf *conf;
-
-    RngBackend *rng;
-
-    /* We purposefully don't migrate this state.  The quota will reset on the
-     * destination as a result.  Rate limiting is host state, not guest state.
-     */
-    QEMUTimer *rate_limit_timer;
-    int64_t quota_remaining;
-} VirtIORNG;
-
 static bool is_guest_ready(VirtIORNG *vrng)
 {
     if (virtio_queue_ready(vrng->vq)
diff --git a/hw/virtio-rng.h b/hw/virtio-rng.h
index f42d748eba..3711c97a70 100644
--- a/hw/virtio-rng.h
+++ b/hw/virtio-rng.h
@@ -25,4 +25,23 @@ struct VirtIORNGConf {
     RndRandom *default_backend;
 };
 
+typedef struct VirtIORNG {
+    VirtIODevice vdev;
+
+    DeviceState *qdev;
+
+    /* Only one vq - guest puts buffer(s) on it when it needs entropy */
+    VirtQueue *vq;
+
+    VirtIORNGConf *conf;
+
+    RngBackend *rng;
+
+    /* We purposefully don't migrate this state.  The quota will reset on the
+     * destination as a result.  Rate limiting is host state, not guest state.
+     */
+    QEMUTimer *rate_limit_timer;
+    int64_t quota_remaining;
+} VirtIORNG;
+
 #endif
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 3f4eb564fc..d00022aa09 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -129,21 +129,6 @@ typedef struct {
     uint32_t max_lun;
 } QEMU_PACKED VirtIOSCSIConfig;
 
-typedef struct {
-    VirtIODevice vdev;
-    DeviceState *qdev;
-    VirtIOSCSIConf *conf;
-
-    SCSIBus bus;
-    uint32_t sense_size;
-    uint32_t cdb_size;
-    int resetting;
-    bool events_dropped;
-    VirtQueue *ctrl_vq;
-    VirtQueue *event_vq;
-    VirtQueue *cmd_vqs[0];
-} VirtIOSCSI;
-
 typedef struct VirtIOSCSIReq {
     VirtIOSCSI *dev;
     VirtQueue *vq;
diff --git a/hw/virtio-scsi.h b/hw/virtio-scsi.h
index 8d9d15f093..2327aa58a2 100644
--- a/hw/virtio-scsi.h
+++ b/hw/virtio-scsi.h
@@ -16,6 +16,7 @@
 
 #include "virtio.h"
 #include "pci/pci.h"
+#include "hw/scsi.h"
 
 /* The ID for virtio_scsi */
 #define VIRTIO_ID_SCSI  8
@@ -31,6 +32,21 @@ struct VirtIOSCSIConf {
     uint32_t cmd_per_lun;
 };
 
+typedef struct VirtIOSCSI {
+    VirtIODevice vdev;
+    DeviceState *qdev;
+    VirtIOSCSIConf *conf;
+
+    SCSIBus bus;
+    uint32_t sense_size;
+    uint32_t cdb_size;
+    int resetting;
+    bool events_dropped;
+    VirtQueue *ctrl_vq;
+    VirtQueue *event_vq;
+    VirtQueue *cmd_vqs[0];
+} VirtIOSCSI;
+
 #define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _features_field, _conf_field) \
     DEFINE_VIRTIO_COMMON_FEATURES(_state, _features_field), \
     DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 1dc1addcde..74e2434a6f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -25,46 +25,6 @@
 #include "trace.h"
 #include "virtio-serial.h"
 
-/* The virtio-serial bus on top of which the ports will ride as devices */
-struct VirtIOSerialBus {
-    BusState qbus;
-
-    /* This is the parent device that provides the bus for ports. */
-    VirtIOSerial *vser;
-
-    /* The maximum number of ports that can ride on top of this bus */
-    uint32_t max_nr_ports;
-};
-
-typedef struct VirtIOSerialPostLoad {
-    QEMUTimer *timer;
-    uint32_t nr_active_ports;
-    struct {
-        VirtIOSerialPort *port;
-        uint8_t host_connected;
-    } *connected;
-} VirtIOSerialPostLoad;
-
-struct VirtIOSerial {
-    VirtIODevice vdev;
-
-    VirtQueue *c_ivq, *c_ovq;
-    /* Arrays of ivqs and ovqs: one per port */
-    VirtQueue **ivqs, **ovqs;
-
-    VirtIOSerialBus bus;
-
-    DeviceState *qdev;
-
-    QTAILQ_HEAD(, VirtIOSerialPort) ports;
-
-    /* bitmap for identifying active ports */
-    uint32_t *ports_map;
-
-    struct virtio_console_config config;
-
-    struct VirtIOSerialPostLoad *post_load;
-};
 
 VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
 {
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index f250b758c3..ea0ad125b3 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -173,6 +173,47 @@ struct VirtIOSerialPort {
     bool throttled;
 };
 
+/* The virtio-serial bus on top of which the ports will ride as devices */
+struct VirtIOSerialBus {
+    BusState qbus;
+
+    /* This is the parent device that provides the bus for ports. */
+    VirtIOSerial *vser;
+
+    /* The maximum number of ports that can ride on top of this bus */
+    uint32_t max_nr_ports;
+};
+
+typedef struct VirtIOSerialPostLoad {
+    QEMUTimer *timer;
+    uint32_t nr_active_ports;
+    struct {
+        VirtIOSerialPort *port;
+        uint8_t host_connected;
+    } *connected;
+} VirtIOSerialPostLoad;
+
+struct VirtIOSerial {
+    VirtIODevice vdev;
+
+    VirtQueue *c_ivq, *c_ovq;
+    /* Arrays of ivqs and ovqs: one per port */
+    VirtQueue **ivqs, **ovqs;
+
+    VirtIOSerialBus bus;
+
+    DeviceState *qdev;
+
+    QTAILQ_HEAD(, VirtIOSerialPort) ports;
+
+    /* bitmap for identifying active ports */
+    uint32_t *ports_map;
+
+    struct virtio_console_config config;
+
+    struct VirtIOSerialPostLoad *post_load;
+};
+
 /* Interface to the virtio-serial bus */
 
 /*
