aboutsummaryrefslogtreecommitdiff
path: root/hw/char
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2014-12-19 14:57:27 +1100
committerAmit Shah <amit.shah@redhat.com>2015-01-05 12:50:27 +0530
commit08f432aa3eb62d6d781eaa085e161e8628a9a538 (patch)
tree3c888d6b0e8e568ac6be729b94102de1e1f8f871 /hw/char
parentf2f6e00b2e27b65edaa6ce5cb01770c973cbf8fb (diff)
virtio-serial: Don't keep a persistent copy of config space
The 'config' field in the VirtIOSerial structure keeps a copy of the virtio console's config space as visible to the guest, that is to say, in guest endianness. This is fiddly to maintain, because on some targets, such as powerpc, the "guest endianness" can change when a new guest OS boots. In fact, there's no need to maintain such a guest view of config space - instead we can reconstruct it from host-format data when it is accessed with get_config. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexander Graf <agraf@suse.de> Signed-off-by: Amit Shah <amit.shah@redhat.com>
Diffstat (limited to 'hw/char')
-rw-r--r--hw/char/virtio-serial-bus.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index e0135043c3..37a6f442fa 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -482,10 +482,14 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
/* Guest requested config info */
static void get_config(VirtIODevice *vdev, uint8_t *config_data)
{
- VirtIOSerial *vser;
-
- vser = VIRTIO_SERIAL(vdev);
- memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
+ VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
+ struct virtio_console_config *config =
+ (struct virtio_console_config *)config_data;
+
+ config->cols = 0;
+ config->rows = 0;
+ config->max_nr_ports = virtio_tswap32(vdev,
+ vser->serial.max_virtserial_ports);
}
static void guest_reset(VirtIOSerial *vser)
@@ -533,10 +537,6 @@ static void vser_reset(VirtIODevice *vdev)
vser = VIRTIO_SERIAL(vdev);
guest_reset(vser);
-
- /* In case we have switched endianness */
- vser->config.max_nr_ports =
- virtio_tswap32(vdev, vser->serial.max_virtserial_ports);
}
static void virtio_serial_save(QEMUFile *f, void *opaque)
@@ -551,12 +551,13 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
VirtIOSerialPort *port;
uint32_t nr_active_ports;
unsigned int i, max_nr_ports;
+ struct virtio_console_config config;
- /* The config space */
- qemu_put_be16s(f, &s->config.cols);
- qemu_put_be16s(f, &s->config.rows);
-
- qemu_put_be32s(f, &s->config.max_nr_ports);
+ /* The config space (ignored on the far end in current versions) */
+ get_config(vdev, (uint8_t *)&config);
+ qemu_put_be16s(f, &config.cols);
+ qemu_put_be16s(f, &config.rows);
+ qemu_put_be32s(f, &config.max_nr_ports);
/* The ports map */
max_nr_ports = s->serial.max_virtserial_ports;
@@ -987,8 +988,6 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
}
- vser->config.max_nr_ports =
- virtio_tswap32(vdev, vser->serial.max_virtserial_ports);
vser->ports_map = g_malloc0(((vser->serial.max_virtserial_ports + 31) / 32)
* sizeof(vser->ports_map[0]));
/*