diff options
39 files changed, 322 insertions, 78 deletions
@@ -172,6 +172,7 @@ version.lo: $(SRC_PATH)/version.rc config-host.h version-obj-$(CONFIG_WIN32) += version.o version-lobj-$(CONFIG_WIN32) += version.lo +Makefile: $(version-obj-y) $(version-lobj-y) ###################################################################### # Build libraries diff --git a/default-configs/sound.mak b/default-configs/sound.mak index ff69c4d..4f22c34 100644 --- a/default-configs/sound.mak +++ b/default-configs/sound.mak @@ -1,4 +1,4 @@ CONFIG_SB16=y -#CONFIG_ADLIB=y -#CONFIG_GUS=y -#CONFIG_CS4231A=y +CONFIG_ADLIB=y +CONFIG_GUS=y +CONFIG_CS4231A=y diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 3787ad2..cc3d1dd 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -911,7 +911,8 @@ static int virtio_serial_device_init(VirtIODevice *vdev) sizeof(struct virtio_console_config)); /* Spawn a new virtio-serial bus on which the ports will ride as devices */ - qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, qdev, NULL); + qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, qdev, + vdev->bus_name); vser->bus.qbus.allow_hotplug = 1; vser->bus.vser = vser; QTAILQ_INIT(&vser->ports); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index ab1d8f5..069ac90 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -208,7 +208,7 @@ void qdev_unplug(DeviceState *dev, Error **errp) { DeviceClass *dc = DEVICE_GET_CLASS(dev); - if (!dev->parent_bus->allow_hotplug) { + if (dev->parent_bus && !dev->parent_bus->allow_hotplug) { error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name); return; } diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 2cff6b7..5a3d97c 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -197,9 +197,20 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) DeviceState *qdev = DEVICE(s390_dev); VirtIOS390Bus *bus; int r; + char *bus_name; bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus); + /* + * For command line compatibility, this sets the virtio-serial-device bus + * name as before. + */ + if (qdev->id) { + bus_name = g_strdup_printf("%s.0", qdev->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } + qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); if (qdev_init(vdev) < 0) { return -1; @@ -224,6 +235,18 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) { VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *qdev = DEVICE(s390_dev); + char *bus_name; + + /* + * For command line compatibility, this sets the virtio-scsi-device bus + * name as before. + */ + if (qdev->id) { + bus_name = g_strdup_printf("%s.0", qdev->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); if (qdev_init(vdev) < 0) { @@ -669,7 +692,10 @@ static void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev) { DeviceState *qdev = DEVICE(dev); BusState *qbus; - qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_S390_BUS, qdev, NULL); + char virtio_bus_name[] = "virtio-bus"; + + qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_S390_BUS, qdev, + virtio_bus_name); qbus = BUS(bus); qbus->allow_hotplug = 1; } diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index c0f2646..76e6d32 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -593,6 +593,18 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev) { VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *proxy = DEVICE(ccw_dev); + char *bus_name; + + /* + * For command line compatibility, this sets the virtio-serial-device bus + * name as before. + */ + if (proxy->id) { + bus_name = g_strdup_printf("%s.0", proxy->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); if (qdev_init(vdev) < 0) { @@ -668,6 +680,18 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev) { VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *qdev = DEVICE(ccw_dev); + char *bus_name; + + /* + * For command line compatibility, this sets the virtio-scsi-device bus + * name as before. + */ + if (qdev->id) { + bus_name = g_strdup_printf("%s.0", qdev->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); if (qdev_init(vdev) < 0) { @@ -1062,8 +1086,10 @@ static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev) { DeviceState *qdev = DEVICE(dev); BusState *qbus; + char virtio_bus_name[] = "virtio-bus"; - qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev, NULL); + qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev, + virtio_bus_name); qbus = BUS(bus); qbus->allow_hotplug = 1; } diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index 3ca5c8c..029789a 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -354,7 +354,7 @@ static int esp_pci_scsi_init(PCIDevice *dev) pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io); s->irq = pci->dev.irq[0]; - scsi_bus_new(&s->bus, &dev->qdev, &esp_pci_scsi_info); + scsi_bus_new(&s->bus, &dev->qdev, &esp_pci_scsi_info, NULL); if (!dev->qdev.hotplugged) { return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 17adbec..0c81a50 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -681,7 +681,7 @@ static int sysbus_esp_init(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, sysbus_esp_gpio_demux, 2); - scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info); + scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info, NULL); return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index c601b29..22b8e98 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -2099,7 +2099,7 @@ static int lsi_scsi_init(PCIDevice *dev) pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io); QTAILQ_INIT(&s->queue); - scsi_bus_new(&s->bus, &dev->qdev, &lsi_scsi_info); + scsi_bus_new(&s->bus, &dev->qdev, &lsi_scsi_info, NULL); if (!dev->qdev.hotplugged) { return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 14b0552..4934a81 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -2159,7 +2159,7 @@ static int megasas_scsi_init(PCIDevice *dev) s->frames[i].state = s; } - scsi_bus_new(&s->bus, &dev->qdev, &megasas_scsi_info); + scsi_bus_new(&s->bus, &dev->qdev, &megasas_scsi_info, NULL); scsi_bus_legacy_handle_cmdline(&s->bus); return 0; } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 6239ee1..53ea906 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -72,9 +72,10 @@ static void scsi_device_unit_attention_reported(SCSIDevice *s) } /* Create a scsi bus, and attach devices to it. */ -void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info) +void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info, + const char *bus_name) { - qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, NULL); + qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, bus_name); bus->busnr = next_scsi_bus++; bus->info = info; bus->qbus.allow_hotplug = 1; diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 3d322d5..e8978bf 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -915,7 +915,7 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev) dev->crq.SendFunc = vscsi_do_crq; - scsi_bus_new(&s->bus, &dev->qdev, &vscsi_scsi_info); + scsi_bus_new(&s->bus, &dev->qdev, &vscsi_scsi_info, NULL); if (!dev->qdev.hotplugged) { scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 84b3ac7..08dd3f3 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -624,7 +624,8 @@ static int virtio_scsi_device_init(VirtIODevice *vdev) return ret; } - scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info); + scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info, vdev->bus_name); + if (!qdev->hotplugged) { scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index 4b4a58f..48d12f4 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -1088,7 +1088,7 @@ pvscsi_init(PCIDevice *pci_dev) return -ENOMEM; } - scsi_bus_new(&s->bus, &pci_dev->qdev, &pvscsi_scsi_info); + scsi_bus_new(&s->bus, &pci_dev->qdev, &pvscsi_scsi_info, NULL); pvscsi_reset_state(s); return 0; diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 06f0171..1073901 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -623,7 +623,7 @@ static int usb_msd_initfn_storage(USBDevice *dev) } usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage); + scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage, NULL); scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable, s->conf.bootindex, s->serial); if (!scsi_dev) { @@ -650,7 +650,7 @@ static int usb_msd_initfn_bot(USBDevice *dev) usb_desc_create_serial(dev); usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_bot); + scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_bot, NULL); s->bus.qbus.allow_hotplug = 0; usb_msd_handle_reset(dev); diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index c8c42ee..6efab62 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -888,7 +888,7 @@ static int usb_uas_init(USBDevice *dev) QTAILQ_INIT(&uas->requests); uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas); - scsi_bus_new(&uas->bus, &uas->dev.qdev, &usb_uas_scsi_info); + scsi_bus_new(&uas->bus, &uas->dev.qdev, &usb_uas_scsi_info, NULL); return 0; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 41bb41e..ec0066b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1106,11 +1106,23 @@ static int virtio_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev) VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev); DeviceState *vdev = DEVICE(&dev->vdev); VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); + DeviceState *proxy = DEVICE(vpci_dev); + char *bus_name; if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) { vpci_dev->nvectors = vs->conf.num_queues + 3; } + /* + * For command line compatibility, this sets the virtio-scsi-device bus + * name as before. + */ + if (proxy->id) { + bus_name = g_strdup_printf("%s.0", proxy->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); if (qdev_init(vdev) < 0) { return -1; @@ -1297,6 +1309,8 @@ static int virtio_serial_pci_init(VirtIOPCIProxy *vpci_dev) { VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(vpci_dev); DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *proxy = DEVICE(vpci_dev); + char *bus_name; if (vpci_dev->class_code != PCI_CLASS_COMMUNICATION_OTHER && vpci_dev->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */ @@ -1310,6 +1324,16 @@ static int virtio_serial_pci_init(VirtIOPCIProxy *vpci_dev) vpci_dev->nvectors = dev->vdev.serial.max_virtserial_ports + 1; } + /* + * For command line compatibility, this sets the virtio-serial-device bus + * name as before. + */ + if (proxy->id) { + bus_name = g_strdup_printf("%s.0", proxy->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); if (qdev_init(vdev) < 0) { return -1; @@ -1474,7 +1498,10 @@ static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev) { DeviceState *qdev = DEVICE(dev); BusState *qbus; - qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_PCI_BUS, qdev, NULL); + char virtio_bus_name[] = "virtio-bus"; + + qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_PCI_BUS, qdev, + virtio_bus_name); qbus = BUS(bus); qbus->allow_hotplug = 1; } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 0f88c25..53a0d90 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1087,6 +1087,18 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) return &vq->host_notifier; } +void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name) +{ + if (vdev->bus_name) { + g_free(vdev->bus_name); + vdev->bus_name = NULL; + } + + if (bus_name) { + vdev->bus_name = g_strdup(bus_name); + } +} + static int virtio_device_init(DeviceState *qdev) { VirtIODevice *vdev = VIRTIO_DEVICE(qdev); @@ -1099,11 +1111,23 @@ static int virtio_device_init(DeviceState *qdev) return 0; } +static int virtio_device_exit(DeviceState *qdev) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(qdev); + + if (vdev->bus_name) { + g_free(vdev->bus_name); + vdev->bus_name = NULL; + } + return 0; +} + static void virtio_device_class_init(ObjectClass *klass, void *data) { /* Set the default value here. */ DeviceClass *dc = DEVICE_CLASS(klass); dc->init = virtio_device_init; + dc->exit = virtio_device_exit; dc->bus_type = TYPE_VIRTIO_BUS; } diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 3bda1c4..9786e00 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -152,7 +152,8 @@ struct SCSIBus { const SCSIBusInfo *info; }; -void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info); +void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info, + const char *bus_name); static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) { diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 4db346b..9a98540 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -189,5 +189,4 @@ typedef struct { int virtio_scsi_common_init(VirtIOSCSICommon *vs); int virtio_scsi_common_exit(VirtIOSCSICommon *vs); - #endif /* _QEMU_VIRTIO_SCSI_H */ diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index ae7a4c4..a6c5c53 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -118,6 +118,7 @@ struct VirtIODevice uint16_t device_id; bool vm_running; VMChangeStateEntry *vmstate; + char *bus_name; }; typedef struct VirtioDeviceClass { @@ -149,6 +150,9 @@ void virtio_init(VirtIODevice *vdev, const char *name, uint16_t device_id, size_t config_size); void virtio_cleanup(VirtIODevice *vdev); +/* Set the child bus name. */ +void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name); + VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)); diff --git a/pc-bios/README b/pc-bios/README index eff3de7..7b4dfed 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -11,8 +11,8 @@ firmware implementation. The goal is to implement a 100% IEEE 1275-1994 (referred to as Open Firmware) compliant firmware. The included images for PowerPC (for 32 and 64 bit PPC CPUs), - Sparc32 and Sparc64 are built from OpenBIOS SVN revision - 1063. + Sparc32 and Sparc64 are built from OpenBIOS 1.1 release (SVN + revision 1136). - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc Binary files differindex 5311eca..77eb55d 100644 --- a/pc-bios/openbios-ppc +++ b/pc-bios/openbios-ppc diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32 Binary files differindex 6bd8e45..c5ba6ae 100644 --- a/pc-bios/openbios-sparc32 +++ b/pc-bios/openbios-sparc32 diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 Binary files differindex 7c06fcc..c4aaa05 100644 --- a/pc-bios/openbios-sparc64 +++ b/pc-bios/openbios-sparc64 diff --git a/qemu-options.hx b/qemu-options.hx index e86cc24..fb62b75 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1127,6 +1127,8 @@ By definition the Websocket port is 5700+@var{display}. If @var{host} is specified connections will only be allowed from this host. As an alternative the Websocket port could be specified by using @code{websocket}=@var{port}. +TLS encryption for the Websocket connection is supported if the required +certificates are specified with the VNC option @option{x509}. @item password diff --git a/roms/openbios b/roms/openbios -Subproject f095c858136896d236931357b8d597f407286f7 +Subproject 569e40c517e9623e672be38a21da7bcec046e3b @@ -22,15 +22,11 @@ QEMU_INCLUDES += -I$(<D) -I$(@D) %.o: %.rc $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@") -Makefile: $(version-obj-y) - ifeq ($(LIBTOOL),) -LIBTOOL = /bin/false LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ $(LIBS)," LINK $(TARGET_DIR)$@") else -Makefile: $(version-lobj-y) LIBTOOL += $(if $(V),,--quiet) %.lo: %.c $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," lt CC $@") @@ -74,7 +70,7 @@ quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1)) cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \ >/dev/null 2>&1 && echo OK), $2, $3) -VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi %.sh +VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi %.sh %.rc set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1))) # find-in-path diff --git a/target-arm/kvm.c b/target-arm/kvm.c index d8acace..b7bdc03 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -62,8 +62,8 @@ int kvm_arch_init_vcpu(CPUState *cs) r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31; r.addr = (uintptr_t)(&v); ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); - if (ret == ENOENT) { - return EINVAL; + if (ret == -ENOENT) { + return -EINVAL; } return ret; } diff --git a/tests/Makefile b/tests/Makefile index 72bf2cd..bf41d10 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -119,14 +119,16 @@ tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $( tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o +libqos-obj-y += tests/libqos/i2c.o libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o tests/libqos/fw_cfg-pc.o libqos-pc-obj-y += tests/libqos/malloc-pc.o +libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o tests/rtc-test$(EXESUF): tests/rtc-test.o tests/m48t59-test$(EXESUF): tests/m48t59-test.o tests/fdc-test$(EXESUF): tests/fdc-test.o tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o -tests/tmp105-test$(EXESUF): tests/tmp105-test.o +tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) @@ -137,7 +139,6 @@ QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TA check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) qtest-obj-y = tests/libqtest.o libqemuutil.a libqemustub.a -qtest-obj-y += tests/libi2c.o tests/libi2c-omap.o $(check-qtest-y): $(qtest-obj-y) .PHONY: check-help diff --git a/tests/libi2c-omap.c b/tests/libqos/i2c-omap.c index c52458c..3d4d45d 100644 --- a/tests/libi2c-omap.c +++ b/tests/libqos/i2c-omap.c @@ -6,7 +6,7 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ -#include "libi2c.h" +#include "libqos/i2c.h" #include <glib.h> #include <string.h> diff --git a/tests/libi2c.c b/tests/libqos/i2c.c index 13ec85c..da7592f 100644 --- a/tests/libi2c.c +++ b/tests/libqos/i2c.c @@ -6,7 +6,7 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ -#include "libi2c.h" +#include "libqos/i2c.h" #include "libqtest.h" void i2c_send(I2CAdapter *i2c, uint8_t addr, diff --git a/tests/libi2c.h b/tests/libqos/i2c.h index 1ce9af4..1ce9af4 100644 --- a/tests/libi2c.h +++ b/tests/libqos/i2c.h diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c index 2869129..fecd6dc 100644 --- a/tests/tmp105-test.c +++ b/tests/tmp105-test.c @@ -7,7 +7,7 @@ * See the COPYING file in the top-level directory. */ #include "libqtest.h" -#include "libi2c.h" +#include "libqos/i2c.h" #include "hw/misc/tmp105_regs.h" #include <glib.h> diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index 8d4cc8e..50275de 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -334,29 +334,38 @@ static int vnc_set_gnutls_priority(gnutls_session_t s, int x509) int vnc_tls_client_setup(struct VncState *vs, int needX509Creds) { + VncStateTLS *tls; VNC_DEBUG("Do TLS setup\n"); +#ifdef CONFIG_VNC_WS + if (vs->websocket) { + tls = &vs->ws_tls; + } else +#endif /* CONFIG_VNC_WS */ + { + tls = &vs->tls; + } if (vnc_tls_initialize() < 0) { VNC_DEBUG("Failed to init TLS\n"); vnc_client_error(vs); return -1; } - if (vs->tls.session == NULL) { - if (gnutls_init(&vs->tls.session, GNUTLS_SERVER) < 0) { + if (tls->session == NULL) { + if (gnutls_init(&tls->session, GNUTLS_SERVER) < 0) { vnc_client_error(vs); return -1; } - if (gnutls_set_default_priority(vs->tls.session) < 0) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + if (gnutls_set_default_priority(tls->session) < 0) { + gnutls_deinit(tls->session); + tls->session = NULL; vnc_client_error(vs); return -1; } - if (vnc_set_gnutls_priority(vs->tls.session, needX509Creds) < 0) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + if (vnc_set_gnutls_priority(tls->session, needX509Creds) < 0) { + gnutls_deinit(tls->session); + tls->session = NULL; vnc_client_error(vs); return -1; } @@ -364,43 +373,43 @@ int vnc_tls_client_setup(struct VncState *vs, if (needX509Creds) { gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs->vd); if (!x509_cred) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + gnutls_deinit(tls->session); + tls->session = NULL; vnc_client_error(vs); return -1; } - if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + if (gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) { + gnutls_deinit(tls->session); + tls->session = NULL; gnutls_certificate_free_credentials(x509_cred); vnc_client_error(vs); return -1; } if (vs->vd->tls.x509verify) { VNC_DEBUG("Requesting a client certificate\n"); - gnutls_certificate_server_set_request (vs->tls.session, GNUTLS_CERT_REQUEST); + gnutls_certificate_server_set_request (tls->session, GNUTLS_CERT_REQUEST); } } else { gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred(); if (!anon_cred) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + gnutls_deinit(tls->session); + tls->session = NULL; vnc_client_error(vs); return -1; } - if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_ANON, anon_cred) < 0) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; + if (gnutls_credentials_set(tls->session, GNUTLS_CRD_ANON, anon_cred) < 0) { + gnutls_deinit(tls->session); + tls->session = NULL; gnutls_anon_free_server_credentials(anon_cred); vnc_client_error(vs); return -1; } } - gnutls_transport_set_ptr(vs->tls.session, (gnutls_transport_ptr_t)vs); - gnutls_transport_set_push_function(vs->tls.session, vnc_tls_push); - gnutls_transport_set_pull_function(vs->tls.session, vnc_tls_pull); + gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)vs); + gnutls_transport_set_push_function(tls->session, vnc_tls_push); + gnutls_transport_set_pull_function(tls->session, vnc_tls_pull); } return 0; } @@ -414,6 +423,14 @@ void vnc_tls_client_cleanup(struct VncState *vs) } vs->tls.wiremode = VNC_WIREMODE_CLEAR; g_free(vs->tls.dname); +#ifdef CONFIG_VNC_WS + if (vs->ws_tls.session) { + gnutls_deinit(vs->ws_tls.session); + vs->ws_tls.session = NULL; + } + vs->ws_tls.wiremode = VNC_WIREMODE_CLEAR; + g_free(vs->ws_tls.dname); +#endif /* CONFIG_VNC_WS */ } diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 3e30209..df89315 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -20,6 +20,69 @@ #include "vnc.h" +#ifdef CONFIG_VNC_TLS +#include "qemu/sockets.h" + +static void vncws_tls_handshake_io(void *opaque); + +static int vncws_start_tls_handshake(struct VncState *vs) +{ + int ret = gnutls_handshake(vs->ws_tls.session); + + if (ret < 0) { + if (!gnutls_error_is_fatal(ret)) { + VNC_DEBUG("Handshake interrupted (blocking)\n"); + if (!gnutls_record_get_direction(vs->ws_tls.session)) { + qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, + NULL, vs); + } else { + qemu_set_fd_handler(vs->csock, NULL, vncws_tls_handshake_io, + vs); + } + return 0; + } + VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret)); + vnc_client_error(vs); + return -1; + } + + VNC_DEBUG("Handshake done, switching to TLS data mode\n"); + vs->ws_tls.wiremode = VNC_WIREMODE_TLS; + qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs); + + return 0; +} + +static void vncws_tls_handshake_io(void *opaque) +{ + struct VncState *vs = (struct VncState *)opaque; + + VNC_DEBUG("Handshake IO continue\n"); + vncws_start_tls_handshake(vs); +} + +void vncws_tls_handshake_peek(void *opaque) +{ + VncState *vs = opaque; + long ret; + + if (!vs->ws_tls.session) { + char peek[4]; + ret = qemu_recv(vs->csock, peek, sizeof(peek), MSG_PEEK); + if (ret && (strncmp(peek, "\x16", 1) == 0 + || strncmp(peek, "\x80", 1) == 0)) { + VNC_DEBUG("TLS Websocket connection recognized"); + vnc_tls_client_setup(vs, 1); + vncws_start_tls_handshake(vs); + } else { + vncws_handshake_read(vs); + } + } else { + qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs); + } +} +#endif /* CONFIG_VNC_TLS */ + void vncws_handshake_read(void *opaque) { VncState *vs = opaque; diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h index 039a587..95c1b0a 100644 --- a/ui/vnc-ws.h +++ b/ui/vnc-ws.h @@ -74,6 +74,9 @@ enum { WS_OPCODE_PONG = 0xA }; +#ifdef CONFIG_VNC_TLS +void vncws_tls_handshake_peek(void *opaque); +#endif /* CONFIG_VNC_TLS */ void vncws_handshake_read(void *opaque); long vnc_client_write_ws(VncState *vs); long vnc_client_read_ws(VncState *vs); @@ -1111,6 +1111,23 @@ void vnc_client_error(VncState *vs) vnc_disconnect_start(vs); } +#ifdef CONFIG_VNC_TLS +static long vnc_client_write_tls(gnutls_session_t *session, + const uint8_t *data, + size_t datalen) +{ + long ret = gnutls_write(*session, data, datalen); + if (ret < 0) { + if (ret == GNUTLS_E_AGAIN) { + errno = EAGAIN; + } else { + errno = EIO; + } + ret = -1; + } + return ret; +} +#endif /* CONFIG_VNC_TLS */ /* * Called to write a chunk of data to the client socket. The data may @@ -1132,17 +1149,20 @@ long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen) long ret; #ifdef CONFIG_VNC_TLS if (vs->tls.session) { - ret = gnutls_write(vs->tls.session, data, datalen); - if (ret < 0) { - if (ret == GNUTLS_E_AGAIN) - errno = EAGAIN; - else - errno = EIO; - ret = -1; + ret = vnc_client_write_tls(&vs->tls.session, data, datalen); + } else { +#ifdef CONFIG_VNC_WS + if (vs->ws_tls.session) { + ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen); + } else +#endif /* CONFIG_VNC_WS */ +#endif /* CONFIG_VNC_TLS */ + { + ret = send(vs->csock, (const void *)data, datalen, 0); } - } else +#ifdef CONFIG_VNC_TLS + } #endif /* CONFIG_VNC_TLS */ - ret = send(vs->csock, (const void *)data, datalen, 0); VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret); return vnc_client_io_error(vs, ret, socket_error()); } @@ -1240,6 +1260,22 @@ void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting) vs->read_handler_expect = expecting; } +#ifdef CONFIG_VNC_TLS +static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data, + size_t datalen) +{ + long ret = gnutls_read(*session, data, datalen); + if (ret < 0) { + if (ret == GNUTLS_E_AGAIN) { + errno = EAGAIN; + } else { + errno = EIO; + } + ret = -1; + } + return ret; +} +#endif /* CONFIG_VNC_TLS */ /* * Called to read a chunk of data from the client socket. The data may @@ -1261,17 +1297,20 @@ long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen) long ret; #ifdef CONFIG_VNC_TLS if (vs->tls.session) { - ret = gnutls_read(vs->tls.session, data, datalen); - if (ret < 0) { - if (ret == GNUTLS_E_AGAIN) - errno = EAGAIN; - else - errno = EIO; - ret = -1; + ret = vnc_client_read_tls(&vs->tls.session, data, datalen); + } else { +#ifdef CONFIG_VNC_WS + if (vs->ws_tls.session) { + ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen); + } else +#endif /* CONFIG_VNC_WS */ +#endif /* CONFIG_VNC_TLS */ + { + ret = qemu_recv(vs->csock, data, datalen, 0); } - } else +#ifdef CONFIG_VNC_TLS + } #endif /* CONFIG_VNC_TLS */ - ret = qemu_recv(vs->csock, data, datalen, 0); VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret); return vnc_client_io_error(vs, ret, socket_error()); } @@ -2761,7 +2800,16 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket) #ifdef CONFIG_VNC_WS if (websocket) { vs->websocket = 1; - qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs); +#ifdef CONFIG_VNC_TLS + if (vd->tls.x509cert) { + qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_peek, + NULL, vs); + } else +#endif /* CONFIG_VNC_TLS */ + { + qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, + NULL, vs); + } } else #endif /* CONFIG_VNC_WS */ { @@ -276,9 +276,12 @@ struct VncState VncStateSASL sasl; #endif #ifdef CONFIG_VNC_WS +#ifdef CONFIG_VNC_TLS + VncStateTLS ws_tls; +#endif /* CONFIG_VNC_TLS */ bool encode_ws; bool websocket; -#endif +#endif /* CONFIG_VNC_WS */ QObject *info; |