[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/8] virtio: set config size using host features
From: |
Jesse Larrew |
Subject: |
[Qemu-devel] [PATCH 4/8] virtio: set config size using host features |
Date: |
Mon, 18 Feb 2013 16:22:41 -0600 |
Move the config size calculation from virtio_net_init() to
virtio_common_init() so that all virtio devices can benefit. This requires
that the host_features be passed to virtio_common_init(), and the size of
the config struct will be calculated based on which feature bits are
enabled. This calculation is performed using a per-driver table that maps
each feature bit to the size of the config struct at the time that the
feature was introduced. virtio_common_init() also takes a minimum config
size to use in the case that all feature bits are disabled.
For now, each driver contains a dummy table that uses the full size of the
config struct. These dummy tables will be replaced on a per-driver basis.
Signed-off-by: Jesse Larrew <address@hidden>
---
hw/9pfs/virtio-9p-device.c | 15 ++++++++++-----
hw/virtio-balloon.c | 15 ++++++++++++---
hw/virtio-blk.c | 14 +++++++++++---
hw/virtio-net.c | 11 +++--------
hw/virtio-rng.c | 8 +++++++-
hw/virtio-scsi.c | 10 +++++++++-
hw/virtio-serial-bus.c | 13 ++++++++++---
hw/virtio.c | 13 ++++++++++++-
hw/virtio.h | 4 +++-
9 files changed, 77 insertions(+), 26 deletions(-)
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 74155fb..24d033b 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -20,6 +20,12 @@
#include "virtio-9p-xattr.h"
#include "virtio-9p-coth.h"
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff, /* dummy table -- all features included. */
+ .end = endof(struct virtio_9p_config, tag) + MAX_TAG_LEN},
+ {}
+};
+
static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
{
features |= 1 << VIRTIO_9P_MOUNT_TAG;
@@ -54,11 +60,10 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf
*conf)
FsDriverEntry *fse;
V9fsPath path;
- s = (V9fsState *)virtio_common_init("virtio-9p",
- VIRTIO_ID_9P,
- sizeof(struct virtio_9p_config)+
- MAX_TAG_LEN,
- sizeof(V9fsState));
+ s = (V9fsState *)virtio_common_init("virtio-9p", VIRTIO_ID_9P,
+ host_features, feature_sizes,
+ sizeof(struct virtio_9p_config) +
+ MAX_TAG_LEN, sizeof(V9fsState));
/* initialize pdu allocator */
QLIST_INIT(&s->free_list);
QLIST_INIT(&s->active_list);
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 4574db6..81f27e9 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -29,6 +29,12 @@
#include <sys/mman.h>
#endif
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff, /* dummy table -- all features included. */
+ .end = sizeof(struct virtio_balloon_config)},
+ {}
+};
+
typedef struct VirtIOBalloon
{
VirtIODevice vdev;
@@ -278,7 +284,7 @@ static void virtio_balloon_get_config(VirtIODevice *vdev,
uint8_t *config_data)
config.num_pages = cpu_to_le32(dev->num_pages);
config.actual = cpu_to_le32(dev->actual);
- memcpy(config_data, &config, 8);
+ memcpy(config_data, &config, vdev->config_len);
}
static void virtio_balloon_set_config(VirtIODevice *vdev,
@@ -287,7 +293,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
VirtIOBalloon *dev = to_virtio_balloon(vdev);
struct virtio_balloon_config config;
uint32_t oldactual = dev->actual;
- memcpy(&config, config_data, 8);
+ memcpy(&config, config_data, vdev->config_len);
dev->actual = le32_to_cpu(config.actual);
if (dev->actual != oldactual) {
qemu_balloon_changed(ram_size -
@@ -356,7 +362,10 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev,
uint32_t host_features)
s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
VIRTIO_ID_BALLOON,
- 8, sizeof(VirtIOBalloon));
+ host_features, feature_sizes,
+ endof(struct virtio_balloon_config,
+ actual),
+ sizeof(VirtIOBalloon));
s->vdev.get_config = virtio_balloon_get_config;
s->vdev.set_config = virtio_balloon_set_config;
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index b3ab267..788a4c7 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -25,6 +25,12 @@
# include <scsi/sg.h>
#endif
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff, /* dummy table -- all features included */
+ .end = sizeof(struct virtio_blk_config)},
+ {}
+};
+
typedef struct VirtIOBlock
{
VirtIODevice vdev;
@@ -531,7 +537,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev,
uint8_t *config)
blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
blkcfg.alignment_offset = 0;
blkcfg.wce = bdrv_enable_write_cache(s->bs);
- memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
+ memcpy(config, &blkcfg, vdev->config_len);
}
static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
@@ -539,7 +545,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const
uint8_t *config)
VirtIOBlock *s = to_virtio_blk(vdev);
struct virtio_blk_config blkcfg;
- memcpy(&blkcfg, config, sizeof(blkcfg));
+ memcpy(&blkcfg, config, vdev->config_len);
bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
}
@@ -660,7 +666,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev,
VirtIOBlkConf *blk,
}
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
- sizeof(struct virtio_blk_config),
+ host_features, feature_sizes,
+ endof(struct virtio_blk_config,
+ blk_size),
sizeof(VirtIOBlock));
s->vdev.get_config = virtio_blk_update_config;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 78dc97d..302e93b 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1292,16 +1292,11 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf
*conf,
virtio_net_conf *net, uint32_t host_features)
{
VirtIONet *n;
- int i, config_size = 0;
-
- for (i = 0; feature_sizes[i].flags != 0; i++) {
- if (host_features & feature_sizes[i].flags) {
- config_size = MAX(feature_sizes[i].end, config_size);
- }
- }
+ int i;
n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
- config_size, sizeof(VirtIONet));
+ host_features, feature_sizes, 0,
+ sizeof(VirtIONet));
n->vdev.get_config = virtio_net_get_config;
n->vdev.set_config = virtio_net_set_config;
diff --git a/hw/virtio-rng.c b/hw/virtio-rng.c
index e063127..c53cc08 100644
--- a/hw/virtio-rng.c
+++ b/hw/virtio-rng.c
@@ -15,6 +15,12 @@
#include "virtio-rng.h"
#include "qemu/rng.h"
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff, /* dummy table -- all features included. */
+ .end = endof(struct VirtIORNGConf, default_backend)},
+ {}
+};
+
typedef struct VirtIORNG {
VirtIODevice vdev;
@@ -155,7 +161,7 @@ VirtIODevice *virtio_rng_init(DeviceState *dev,
VirtIORNGConf *conf)
VirtIODevice *vdev;
Error *local_err = NULL;
- vdev = virtio_common_init("virtio-rng", VIRTIO_ID_RNG, 0,
+ vdev = virtio_common_init("virtio-rng", VIRTIO_ID_RNG, 0, feature_sizes, 0,
sizeof(VirtIORNG));
vrng = DO_UPCAST(VirtIORNG, vdev, vdev);
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index d6db042..6c92975 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -17,6 +17,12 @@
#include <hw/scsi.h>
#include <hw/scsi-defs.h>
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff,
+ .end = sizeof(struct VirtIOSCSIConf)},
+ {}
+};
+
#define VIRTIO_SCSI_VQ_SIZE 128
#define VIRTIO_SCSI_CDB_SIZE 32
#define VIRTIO_SCSI_SENSE_SIZE 96
@@ -710,7 +716,9 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev,
VirtIOSCSIConf *proxyconf,
sz = sizeof(VirtIOSCSI) + proxyconf->num_queues * sizeof(VirtQueue *);
s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI,
- sizeof(VirtIOSCSIConfig), sz);
+ host_features, feature_sizes,
+ endof(struct VirtIOSCSIConf,
+ cmd_per_lun), sz);
s->qdev = dev;
s->conf = proxyconf;
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index d6b588f..9cd9fbd 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -25,6 +25,12 @@
#include "trace.h"
#include "virtio-serial.h"
+static VirtIOFeature feature_sizes[] = {
+ {.flags = 0xffffffff, /* dummy table -- all features included. */
+ .end = sizeof(struct virtio_console_config)},
+ {}
+};
+
/* The virtio-serial bus on top of which the ports will ride as devices */
struct VirtIOSerialBus {
BusState qbus;
@@ -523,14 +529,14 @@ static void get_config(VirtIODevice *vdev, uint8_t
*config_data)
VirtIOSerial *vser;
vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
- memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
+ memcpy(config_data, &vser->config, vdev->config_len);
}
static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
{
struct virtio_console_config config;
- memcpy(&config, config_data, sizeof(config));
+ memcpy(&config, config_data, vdev->config_len);
}
static void guest_reset(VirtIOSerial *vser)
@@ -964,7 +970,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev,
virtio_serial_conf *conf,
}
vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
- sizeof(struct virtio_console_config),
+ host_features, feature_sizes,
+ endof(struct virtio_console_config, rows),
sizeof(VirtIOSerial));
vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
diff --git a/hw/virtio.c b/hw/virtio.c
index e259348..487fdab 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -948,10 +948,21 @@ void virtio_init(VirtIODevice *vdev, const char *name,
}
VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
- size_t config_size, size_t struct_size)
+ uint32_t host_features,
+ const VirtIOFeature *feature_table,
+ size_t min_config_size, size_t struct_size)
{
+ int i, config_size = min_config_size;
VirtIODevice *vdev;
+
vdev = g_malloc0(struct_size);
+
+ for (i = 0; feature_table && feature_table[i].flags != 0; i++) {
+ if (host_features & feature_table[i].flags) {
+ config_size = MAX(feature_table[i].end, config_size);
+ }
+ }
+
virtio_init(vdev, name, device_id, config_size);
return vdev;
}
diff --git a/hw/virtio.h b/hw/virtio.h
index 17ce9c8..f3b7e28 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -229,7 +229,9 @@ 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);
+ uint32_t host_features,
+ const VirtIOFeature *feature_table,
+ size_t min_config_size, size_t struct_size);
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);
--
1.7.11.7
- [Qemu-devel] [PATCH 0/8] virtio: set config size using host features, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 1/8] virtio-net: replace redundant config_size field with config_len, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 8/8] virtio-blk: fill in the feature table, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 6/8] virtio-serial: fill in the feature table, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 7/8] virtio-scsi: fill in table of feature sizes, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 2/8] virtio: put struct VirtIOFeature in a header, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 4/8] virtio: set config size using host features,
Jesse Larrew <=
- [Qemu-devel] [PATCH 5/8] virtio-balloon: fill in the table of feature_sizes, Jesse Larrew, 2013/02/18
- [Qemu-devel] [PATCH 3/8] virtio: pass host features to driver init functions, Jesse Larrew, 2013/02/18
- Re: [Qemu-devel] [PATCH 0/8] virtio: set config size using host features, Anthony Liguori, 2013/02/19