summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--default-configs/sound.mak6
-rw-r--r--hw/char/virtio-serial-bus.c3
-rw-r--r--hw/core/qdev.c2
-rw-r--r--hw/s390x/s390-virtio-bus.c28
-rw-r--r--hw/s390x/virtio-ccw.c28
-rw-r--r--hw/scsi/esp-pci.c2
-rw-r--r--hw/scsi/esp.c2
-rw-r--r--hw/scsi/lsi53c895a.c2
-rw-r--r--hw/scsi/megasas.c2
-rw-r--r--hw/scsi/scsi-bus.c5
-rw-r--r--hw/scsi/spapr_vscsi.c2
-rw-r--r--hw/scsi/virtio-scsi.c3
-rw-r--r--hw/scsi/vmw_pvscsi.c2
-rw-r--r--hw/usb/dev-storage.c4
-rw-r--r--hw/usb/dev-uas.c2
-rw-r--r--hw/virtio/virtio-pci.c29
-rw-r--r--hw/virtio/virtio.c24
-rw-r--r--include/hw/scsi/scsi.h3
-rw-r--r--include/hw/virtio/virtio-scsi.h1
-rw-r--r--include/hw/virtio/virtio.h4
-rw-r--r--qemu-options.hx2
-rw-r--r--rules.mak6
-rw-r--r--tests/Makefile5
-rw-r--r--tests/libqos/i2c-omap.c (renamed from tests/libi2c-omap.c)2
-rw-r--r--tests/libqos/i2c.c (renamed from tests/libi2c.c)2
-rw-r--r--tests/libqos/i2c.h (renamed from tests/libi2c.h)0
-rw-r--r--tests/tmp105-test.c2
-rw-r--r--ui/vnc-tls.c61
-rw-r--r--ui/vnc-ws.c63
-rw-r--r--ui/vnc-ws.h3
-rw-r--r--ui/vnc.c86
-rw-r--r--ui/vnc.h5
33 files changed, 318 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index f91f3b0a11..7dc02042be 100644
--- a/Makefile
+++ b/Makefile
@@ -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 ff69c4d549..4f22c34b5d 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 3787ad2e1d..cc3d1dd27a 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 ab1d8f52f1..069ac9034c 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 2cff6b794d..5a3d97c037 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 c0f26460a9..76e6d32b72 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 3ca5c8c673..029789ae39 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 17adbecf8c..0c81a50398 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 c601b2943d..22b8e98697 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 14b0552045..4934a815ce 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 6239ee1465..53ea906433 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 3d322d5d1e..e8978bfef1 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 84b3ac795d..08dd3f34c3 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 4b4a58fd38..48d12f42dd 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 06f0171c46..1073901af1 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 c8c42eefb5..6efab62544 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 41bb41eb2e..ec0066b6d4 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 0f88c251c1..53a0d90468 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 3bda1c42c1..9786e00642 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 4db346b546..9a985403c2 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 ae7a4c43d3..a6c5c5380c 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/qemu-options.hx b/qemu-options.hx
index e86cc2439d..fb62b75ccb 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/rules.mak b/rules.mak
index b21383beba..44997458da 100644
--- a/rules.mak
+++ b/rules.mak
@@ -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/tests/Makefile b/tests/Makefile
index 72bf2cd220..bf41d10050 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 c52458cbd6..3d4d45d848 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 13ec85c0cb..da7592f713 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 1ce9af4053..1ce9af4053 100644
--- a/tests/libi2c.h
+++ b/tests/libqos/i2c.h
diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
index 2869129df3..fecd6dcd70 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 8d4cc8e47c..50275de64f 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 3e3020916c..df89315733 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 039a58765c..95c1b0aeae 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);
diff --git a/ui/vnc.c b/ui/vnc.c
index b90281b77b..89108de223 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -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 */
{
diff --git a/ui/vnc.h b/ui/vnc.h
index fea39adcc7..6e9921387f 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -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;