Merge remote-tracking branch 'luiz/queue/qmp' into staging # By Michael Roth (1) and Zhangleiqiang (1) # Via Luiz Capitulino * luiz/queue/qmp: qapi: fix leak in unit tests qmp: fix handling of cmd with Equals in qmp-shell Message-id: 1368625179-27962-1-git-send-email-lcapitulino@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/configure b/configure index cab6332..5ae7e4a 100755 --- a/configure +++ b/configure
@@ -1346,6 +1346,7 @@ int main(void) { int val = 42; + val = __sync_val_compare_and_swap(&val, 0, 1); sfaa(&val); return val; } @@ -1948,6 +1949,8 @@ ########################################## # uuid_generate() probe, used for vdi block driver +# Note that on some systems (notably MacOSX) no extra library +# need be linked to get the uuid functions. if test "$uuid" != "no" ; then uuid_libs="-luuid" cat > $TMPC << EOF @@ -1959,7 +1962,9 @@ return 0; } EOF - if compile_prog "" "$uuid_libs" ; then + if compile_prog "" "" ; then + uuid="yes" + elif compile_prog "" "$uuid_libs" ; then uuid="yes" libs_softmmu="$uuid_libs $libs_softmmu" libs_tools="$uuid_libs $libs_tools"
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 9f18d6a..bed0822 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c
@@ -1275,6 +1275,29 @@ n->config_size = config_size; } +void virtio_net_set_netclient_name(VirtIONet *n, const char *name, + const char *type) +{ + /* + * The name can be NULL, the netclient name will be type.x. + */ + assert(type != NULL); + + if (n->netclient_name) { + g_free(n->netclient_name); + n->netclient_name = NULL; + } + if (n->netclient_type) { + g_free(n->netclient_type); + n->netclient_type = NULL; + } + + if (name != NULL) { + n->netclient_name = g_strdup(name); + } + n->netclient_type = g_strdup(type); +} + static int virtio_net_device_init(VirtIODevice *vdev) { int i; @@ -1315,8 +1338,17 @@ memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac)); n->status = VIRTIO_NET_S_LINK_UP; - n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, - object_get_typename(OBJECT(qdev)), qdev->id, n); + if (n->netclient_type) { + /* + * Happen when virtio_net_set_netclient_name has been called. + */ + n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, + n->netclient_type, n->netclient_name, n); + } else { + n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, + object_get_typename(OBJECT(qdev)), qdev->id, n); + } + peer_test_vnet_hdr(n); if (peer_has_vnet_hdr(n)) { for (i = 0; i < n->max_queues; i++) { @@ -1357,6 +1389,15 @@ unregister_savevm(qdev, "virtio-net", n); + if (n->netclient_name) { + g_free(n->netclient_name); + n->netclient_name = NULL; + } + if (n->netclient_type) { + g_free(n->netclient_type); + n->netclient_type = NULL; + } + g_free(n->mac_table.macs); g_free(n->vlans);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 540daf7..2f996d9 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c
@@ -28,6 +28,36 @@ * this allows a newer kernel to use the INTERRUPT_LINE * registers arbitrarily once it has indicated that it isn't * broken in its init code somewhere. + * + * Unfortunately we have to cope with multiple different + * variants on the broken kernel behaviour: + * phase I (before kernel commit 1bc39ac5d) kernels assume old + * QEMU behaviour, so they use IRQ 27 for all slots + * phase II (1bc39ac5d and later, but before e3e92a7be6) kernels + * swizzle IRQs between slots, but do it wrongly, so they + * work only for every fourth PCI card, and only if (like old + * QEMU) the PCI host device is at slot 0 rather than where + * the h/w actually puts it + * phase III (e3e92a7be6 and later) kernels still swizzle IRQs between + * slots wrongly, but add a fixed offset of 64 to everything + * they write to PCI_INTERRUPT_LINE. + * + * We live in hope of a mythical phase IV kernel which might + * actually behave in ways that work on the hardware. Such a + * kernel should probably start off by writing some value neither + * 27 nor 91 to slot zero's PCI_INTERRUPT_LINE register to + * disable the autodetection. After that it can do what it likes. + * + * Slot % 4 | hw | I | II | III + * ------------------------------- + * 0 | 29 | 27 | 27 | 91 + * 1 | 30 | 27 | 28 | 92 + * 2 | 27 | 27 | 29 | 93 + * 3 | 28 | 27 | 30 | 94 + * + * Since our autodetection is not perfect we also provide a + * property so the user can make us start in BROKEN or FORCE_OK + * on reset if they know they have a bad or good kernel. */ enum { PCI_VPB_IRQMAP_ASSUME_OK, @@ -56,6 +86,7 @@ /* Constant for life of device: */ int realview; uint32_t mem_win_size[3]; + uint8_t irq_mapping_prop; /* Variable state: */ uint32_t imap[3]; @@ -214,6 +245,41 @@ }, }; +static int pci_vpb_broken_irq(int slot, int irq) +{ + /* Determine whether this IRQ value for this slot represents a + * known broken Linux kernel behaviour for this slot. + * Return one of the PCI_VPB_IRQMAP_ constants: + * BROKEN : if this definitely looks like a broken kernel + * FORCE_OK : if this definitely looks good + * ASSUME_OK : if we can't tell + */ + slot %= PCI_NUM_PINS; + + if (irq == 27) { + if (slot == 2) { + /* Might be a Phase I kernel, or might be a fixed kernel, + * since slot 2 is where we expect this IRQ. + */ + return PCI_VPB_IRQMAP_ASSUME_OK; + } + /* Phase I kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + if (irq == slot + 27) { + /* Phase II kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + if (irq == slot + 27 + 64) { + /* Phase III kernel */ + return PCI_VPB_IRQMAP_BROKEN; + } + /* Anything else must be a fixed kernel, possibly using an + * arbitrary irq map. + */ + return PCI_VPB_IRQMAP_FORCE_OK; +} + static void pci_vpb_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -221,13 +287,7 @@ if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE && s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) { uint8_t devfn = addr >> 8; - if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) { - if (val == 27) { - s->irq_mapping = PCI_VPB_IRQMAP_BROKEN; - } else { - s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK; - } - } + s->irq_mapping = pci_vpb_broken_irq(PCI_SLOT(devfn), val); } pci_data_write(&s->pci_bus, addr, val, size); } @@ -311,7 +371,7 @@ s->smap[2] = 0; s->selfid = 0; s->flags = 0; - s->irq_mapping = PCI_VPB_IRQMAP_ASSUME_OK; + s->irq_mapping = s->irq_mapping_prop; pci_vpb_update_all_windows(s); } @@ -331,8 +391,6 @@ object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST); qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus)); - object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr", - NULL); /* Window sizes for VersatilePB; realview_pci's init will override */ s->mem_win_size[0] = 0x0c000000; @@ -423,6 +481,12 @@ .class_init = versatile_pci_host_class_init, }; +static Property pci_vpb_properties[] = { + DEFINE_PROP_UINT8("broken-irq-mapping", PCIVPBState, irq_mapping_prop, + PCI_VPB_IRQMAP_ASSUME_OK), + DEFINE_PROP_END_OF_LIST() +}; + static void pci_vpb_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -430,6 +494,7 @@ dc->realize = pci_vpb_realize; dc->reset = pci_vpb_reset; dc->vmsd = &pci_vpb_vmstate; + dc->props = pci_vpb_properties; } static const TypeInfo pci_vpb_info = {
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 5a3d97c..a1cdfb0 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c
@@ -152,10 +152,13 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev) { + DeviceState *qdev = DEVICE(s390_dev); VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); virtio_net_set_config_size(&dev->vdev, s390_dev->host_features); + virtio_net_set_netclient_name(&dev->vdev, qdev->id, + object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); if (qdev_init(vdev) < 0) { return -1;
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 76e6d32..5f5e267 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c
@@ -550,10 +550,13 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev) { + DeviceState *qdev = DEVICE(ccw_dev); VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]); + virtio_net_set_netclient_name(&dev->vdev, qdev->id, + object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); if (qdev_init(vdev) < 0) { return -1;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 113fbd9..70d2c6b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c
@@ -1398,10 +1398,13 @@ static int virtio_net_pci_init(VirtIOPCIProxy *vpci_dev) { + DeviceState *qdev = DEVICE(vpci_dev); VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev); DeviceState *vdev = DEVICE(&dev->vdev); virtio_net_set_config_size(&dev->vdev, vpci_dev->host_features); + virtio_net_set_netclient_name(&dev->vdev, qdev->id, + object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); if (qdev_init(vdev) < 0) { return -1;
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index ce4ab50..beeead7 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h
@@ -188,6 +188,8 @@ uint16_t max_queues; uint16_t curr_queues; size_t config_size; + char *netclient_name; + char *netclient_type; } VirtIONet; #define VIRTIO_NET_CTRL_MAC 1 @@ -255,5 +257,7 @@ DEFINE_PROP_STRING("tx", _state, _field.tx) void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features); +void virtio_net_set_netclient_name(VirtIONet *n, const char *name, + const char *type); #endif
diff --git a/include/qemu-common.h b/include/qemu-common.h index af769f5..7f18b8e 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h
@@ -448,12 +448,18 @@ /* vector definitions */ #ifdef __ALTIVEC__ #include <altivec.h> -#define VECTYPE vector unsigned char +/* The altivec.h header says we're allowed to undef these for + * C++ compatibility. Here we don't care about C++, but we + * undef them anyway to avoid namespace pollution. + */ +#undef vector +#undef pixel +#undef bool +#define VECTYPE __vector unsigned char #define SPLAT(p) vec_splat(vec_ld(0, p), 0) #define ALL_EQ(v1, v2) vec_all_eq(v1, v2) /* altivec.h may redefine the bool macro as vector type. * Reset it to POSIX semantics. */ -#undef bool #define bool _Bool #elif defined __SSE2__ #include <emmintrin.h>
diff --git a/tests/ide-test.c b/tests/ide-test.c index bdc1da7..365e995 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c
@@ -252,7 +252,10 @@ uintptr_t guest_buf = guest_alloc(guest_malloc, len); PrdtEntry prdt[] = { - { .addr = guest_buf, .size = len | PRDT_EOT }, + { + .addr = cpu_to_le32(guest_buf), + .size = cpu_to_le32(len | PRDT_EOT), + }, }; buf = g_malloc(len); @@ -304,7 +307,10 @@ uint8_t status; PrdtEntry prdt[] = { - { .addr = 0, .size = 0x10 | PRDT_EOT }, + { + .addr = 0, + .size = cpu_to_le32(0x10 | PRDT_EOT), + }, }; /* Normal request */ @@ -325,7 +331,10 @@ uint8_t status; PrdtEntry prdt[] = { - { .addr = 0, .size = 0x1000 | PRDT_EOT }, + { + .addr = 0, + .size = cpu_to_le32(0x1000 | PRDT_EOT), + }, }; /* Normal request */ @@ -355,6 +364,17 @@ ide_test_quit(); } +static void string_cpu_to_be16(uint16_t *s, size_t bytes) +{ + g_assert((bytes & 1) == 0); + bytes /= 2; + + while (bytes--) { + *s = cpu_to_be16(*s); + s++; + } +} + static void test_identify(void) { uint8_t data; @@ -389,10 +409,12 @@ assert_bit_clear(data, BSY | DF | ERR | DRQ); /* Check serial number/version in the buffer */ - ret = memcmp(&buf[10], "ettsidks ", 20); + string_cpu_to_be16(&buf[10], 20); + ret = memcmp(&buf[10], "testdisk ", 20); g_assert(ret == 0); - ret = memcmp(&buf[23], "evsroi n", 8); + string_cpu_to_be16(&buf[23], 8); + ret = memcmp(&buf[23], "version ", 8); g_assert(ret == 0); /* Write cache enabled bit */
diff --git a/ui/vnc.c b/ui/vnc.c index 89108de..dfc7459 100644 --- a/ui/vnc.c +++ b/ui/vnc.c
@@ -1601,6 +1601,7 @@ { VncState *vs = opaque; int caps, num, scr; + bool has_changed = (ledstate != current_led_state(vs)); caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0; num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0; @@ -1617,7 +1618,7 @@ } /* Sending the current led state message to the client */ - if (ledstate != current_led_state(vs)) { + if (has_changed) { vnc_led_state_change(vs); } }