[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] virtio-serial: Fix endianness bug in the config
From: |
Amit Shah |
Subject: |
Re: [Qemu-devel] [PATCH] virtio-serial: Fix endianness bug in the config space |
Date: |
Wed, 20 Apr 2011 18:06:45 +0530 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On (Tue) 19 Apr 2011 [12:03:46], David Gibson wrote:
> From: Alexey Kardashevskiy <address@hidden>
>
> The virtio serial specification requres that the values in the config
> space are encoded in native endian of the guest.
>
> The qemu virtio-serial code did not do conversion to the guest endian
> format what caused problems when host and guest use different format.
>
> This patch corrects the qemu side, correctly doing host-native <->
> guest-native conversions when accessing the config space. This won't
> break any setups that aren't already broken, and fixes the case
> of different host and guest endianness.
>
> Signed-off-by: Alexey Kardashevskiy <address@hidden>
Thanks; please put your sign-off as well.
I'd also like an ACK from someone else before I push this in. Juan?
> ---
> hw/virtio-serial-bus.c | 23 +++++++++++++----------
> 1 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
> index 6227379..f10d48f 100644
> --- a/hw/virtio-serial-bus.c
> +++ b/hw/virtio-serial-bus.c
> @@ -494,7 +494,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
> VirtIOSerial *s = opaque;
> VirtIOSerialPort *port;
> uint32_t nr_active_ports;
> - unsigned int i;
> + unsigned int i, max_nr_ports;
>
> /* The virtio device */
> virtio_save(&s->vdev, f);
> @@ -506,8 +506,8 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
> qemu_put_be32s(f, &s->config.max_nr_ports);
>
> /* The ports map */
> -
> - for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
> + max_nr_ports = tswap32(s->config.max_nr_ports);
> + for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
> qemu_put_be32s(f, &s->ports_map[i]);
> }
>
> @@ -568,7 +568,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque,
> int version_id)
> qemu_get_be16s(f, &s->config.rows);
>
> qemu_get_be32s(f, &max_nr_ports);
> - if (max_nr_ports > s->config.max_nr_ports) {
> + tswap32s(&max_nr_ports);
> + if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
> /* Source could have had more ports than us. Fail migration. */
> return -EINVAL;
> }
> @@ -670,9 +671,10 @@ static void virtser_bus_dev_print(Monitor *mon,
> DeviceState *qdev, int indent)
> /* This function is only used if a port id is not provided by the user */
> static uint32_t find_free_port_id(VirtIOSerial *vser)
> {
> - unsigned int i;
> + unsigned int i, max_nr_ports;
>
> - for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
> + max_nr_ports = tswap32(vser->config.max_nr_ports);
> + for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
> uint32_t map, bit;
>
> map = vser->ports_map[i];
> @@ -720,7 +722,7 @@ static int virtser_port_qdev_init(DeviceState *qdev,
> DeviceInfo *base)
> VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
> VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
> VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus,
> qdev->parent_bus);
> - int ret;
> + int ret, max_nr_ports;
> bool plugging_port0;
>
> port->vser = bus->vser;
> @@ -750,9 +752,10 @@ static int virtser_port_qdev_init(DeviceState *qdev,
> DeviceInfo *base)
> }
> }
>
> - if (port->id >= port->vser->config.max_nr_ports) {
> + max_nr_ports = tswap32(port->vser->config.max_nr_ports);
> + if (port->id >= max_nr_ports) {
> error_report("virtio-serial-bus: Out-of-range port id specified,
> max. allowed: %u\n",
> - port->vser->config.max_nr_ports - 1);
> + max_nr_ports - 1);
> return -1;
> }
>
> @@ -863,7 +866,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev,
> virtio_serial_conf *conf)
> vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
> }
>
> - vser->config.max_nr_ports = conf->max_virtserial_ports;
> + vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
> vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
> * sizeof(vser->ports_map[0]));
> /*
> --
> 1.7.1
>
Amit