diff options
| -rw-r--r-- | MAINTAINERS | 7 | ||||
| -rw-r--r-- | hw/ppc/spapr.c | 7 | ||||
| -rw-r--r-- | hw/ppc/spapr_cpu_core.c | 19 | ||||
| -rw-r--r-- | hw/usb/hcd-ehci.c | 31 | ||||
| -rw-r--r-- | hw/usb/host-libusb.c | 10 | ||||
| -rw-r--r-- | hw/usb/xen-usb.c | 96 | ||||
| -rw-r--r-- | hw/xen/xen_backend.c | 68 | ||||
| -rw-r--r-- | hw/xenpv/xen_machine_pv.c | 7 | ||||
| -rw-r--r-- | include/hw/xen/xen_backend.h | 1 | ||||
| -rw-r--r-- | io/channel-websock.c | 3 | ||||
| -rw-r--r-- | kvm-all.c | 8 | ||||
| -rw-r--r-- | ui/vnc.c | 10 | ||||
| -rw-r--r-- | xen-hvm.c | 4 |
13 files changed, 153 insertions, 118 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 9c88c44758..b6fb84e826 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1169,6 +1169,13 @@ F: numa.c F: include/sysemu/numa.h T: git git://github.com/ehabkost/qemu.git numa +Host Memory Backends +M: Eduardo Habkost <ehabkost@redhat.com> +M: Igor Mammedov <imammedo@redhat.com> +S: Maintained +F: backends/hostmem*.c +F: include/sysemu/hostmem.h + QAPI M: Markus Armbruster <armbru@redhat.com> M: Michael Roth <mdroth@linux.vnet.ibm.com> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fbbd0518ed..bce237189d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2376,8 +2376,11 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) int i; HotpluggableCPUList *head = NULL; sPAPRMachineState *spapr = SPAPR_MACHINE(machine); + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); int spapr_max_cores = max_cpus / smp_threads; + g_assert(smc->dr_cpu_enabled); + for (i = 0; i < spapr_max_cores; i++) { HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1); HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1); @@ -2432,7 +2435,9 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) hc->plug = spapr_machine_device_plug; hc->unplug = spapr_machine_device_unplug; mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id; - mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus; + if (smc->dr_cpu_enabled) { + mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus; + } smc->dr_lmb_enabled = true; smc->dr_cpu_enabled = true; diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ec81ee6088..170ed154a6 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -166,18 +166,11 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, int index = cc->core_id / smp_threads; int smt = kvmppc_smt_threads(); + g_assert(smc->dr_cpu_enabled); + drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt); spapr->cores[index] = OBJECT(dev); - if (!smc->dr_cpu_enabled) { - /* - * This is a cold plugged CPU core but the machine doesn't support - * DR. So skip the hotplug path ensuring that the core is brought - * up online with out an associated DR connector. - */ - return; - } - g_assert(drc); /* @@ -225,13 +218,13 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model); const char *type = object_get_typename(OBJECT(dev)); - if (strcmp(base_core_type, type)) { - error_setg(&local_err, "CPU core type should be %s", base_core_type); + if (!smc->dr_cpu_enabled) { + error_setg(&local_err, "CPU hotplug not supported for this machine"); goto out; } - if (!smc->dr_cpu_enabled && dev->hotplugged) { - error_setg(&local_err, "CPU hotplug not supported for this machine"); + if (strcmp(base_core_type, type)) { + error_setg(&local_err, "CPU core type should be %s", base_core_type); goto out; } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 43a8f7abcc..b093db729c 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2206,29 +2206,28 @@ static void ehci_advance_periodic_state(EHCIState *ehci) static void ehci_update_frindex(EHCIState *ehci, int uframes) { - int i; - if (!ehci_enabled(ehci) && ehci->pstate == EST_INACTIVE) { return; } - for (i = 0; i < uframes; i++) { - ehci->frindex++; - - if (ehci->frindex == 0x00002000) { - ehci_raise_irq(ehci, USBSTS_FLR); - } + /* Generate FLR interrupt if frame index rolls over 0x2000 */ + if ((ehci->frindex % 0x2000) + uframes >= 0x2000) { + ehci_raise_irq(ehci, USBSTS_FLR); + } - if (ehci->frindex == 0x00004000) { - ehci_raise_irq(ehci, USBSTS_FLR); - ehci->frindex = 0; - if (ehci->usbsts_frindex >= 0x00004000) { - ehci->usbsts_frindex -= 0x00004000; - } else { - ehci->usbsts_frindex = 0; - } + /* How many times will frindex roll over 0x4000 with this frame count? + * usbsts_frindex is decremented by 0x4000 on rollover until it reaches 0 + */ + int rollovers = (ehci->frindex + uframes) / 0x4000; + if (rollovers > 0) { + if (ehci->usbsts_frindex >= (rollovers * 0x4000)) { + ehci->usbsts_frindex -= 0x4000 * rollovers; + } else { + ehci->usbsts_frindex = 0; } } + + ehci->frindex = (ehci->frindex + uframes) % 0x4000; } static void ehci_frame_timer(void *opaque) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index da59c294bb..e94672c155 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -235,7 +235,7 @@ static int usb_host_init(void) #ifndef CONFIG_WIN32 const struct libusb_pollfd **poll; #endif - int i, rc; + int rc; if (ctx) { return 0; @@ -253,6 +253,7 @@ static int usb_host_init(void) ctx); poll = libusb_get_pollfds(ctx); if (poll) { + int i; for (i = 0; poll[i] != NULL; i++) { usb_host_add_fd(poll[i]->fd, poll[i]->events, ctx); } @@ -358,7 +359,7 @@ static USBHostRequest *usb_host_req_find(USBHostDevice *s, USBPacket *p) return NULL; } -static void usb_host_req_complete_ctrl(struct libusb_transfer *xfer) +static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer *xfer) { USBHostRequest *r = xfer->user_data; USBHostDevice *s = r->host; @@ -391,7 +392,7 @@ out: } } -static void usb_host_req_complete_data(struct libusb_transfer *xfer) +static void LIBUSB_CALL usb_host_req_complete_data(struct libusb_transfer *xfer) { USBHostRequest *r = xfer->user_data; USBHostDevice *s = r->host; @@ -447,7 +448,8 @@ static void usb_host_req_abort(USBHostRequest *r) /* ------------------------------------------------------------------------ */ -static void usb_host_req_complete_iso(struct libusb_transfer *transfer) +static void LIBUSB_CALL +usb_host_req_complete_iso(struct libusb_transfer *transfer) { USBHostIsoXfer *xfer = transfer->user_data; diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index 799245654a..174d715e3e 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -90,6 +90,8 @@ struct usbback_req { void *buffer; void *isoc_buffer; struct libusb_transfer *xfer; + + bool cancelled; }; struct usbback_hotplug { @@ -301,20 +303,23 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status, usbback_req->isoc_buffer = NULL; } - res = RING_GET_RESPONSE(&usbif->urb_ring, usbif->urb_ring.rsp_prod_pvt); - res->id = usbback_req->req.id; - res->status = status; - res->actual_length = actual_length; - res->error_count = error_count; - res->start_frame = 0; - usbif->urb_ring.rsp_prod_pvt++; - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify); - - if (notify) { - xen_be_send_notify(xendev); + if (usbif->urb_sring) { + res = RING_GET_RESPONSE(&usbif->urb_ring, usbif->urb_ring.rsp_prod_pvt); + res->id = usbback_req->req.id; + res->status = status; + res->actual_length = actual_length; + res->error_count = error_count; + res->start_frame = 0; + usbif->urb_ring.rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify); + + if (notify) { + xen_be_send_notify(xendev); + } } - usbback_put_req(usbback_req); + if (!usbback_req->cancelled) + usbback_put_req(usbback_req); } static void usbback_do_response_ret(struct usbback_req *usbback_req, @@ -366,15 +371,14 @@ static void usbback_set_address(struct usbback_info *usbif, } } -static bool usbback_cancel_req(struct usbback_req *usbback_req) +static void usbback_cancel_req(struct usbback_req *usbback_req) { - bool ret = false; - if (usb_packet_is_inflight(&usbback_req->packet)) { usb_cancel_packet(&usbback_req->packet); - ret = true; + QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q); + usbback_req->cancelled = true; + usbback_do_response_ret(usbback_req, -EPROTO); } - return ret; } static void usbback_process_unlink_req(struct usbback_req *usbback_req) @@ -391,7 +395,7 @@ static void usbback_process_unlink_req(struct usbback_req *usbback_req) devnum = usbif_pipedevice(usbback_req->req.pipe); if (unlikely(devnum == 0)) { usbback_req->stub = usbif->ports + - usbif_pipeportnum(usbback_req->req.pipe); + usbif_pipeportnum(usbback_req->req.pipe) - 1; if (unlikely(!usbback_req->stub)) { ret = -ENODEV; goto fail_response; @@ -406,9 +410,7 @@ static void usbback_process_unlink_req(struct usbback_req *usbback_req) QTAILQ_FOREACH(unlink_req, &usbback_req->stub->submit_q, q) { if (unlink_req->req.id == id) { - if (usbback_cancel_req(unlink_req)) { - usbback_do_response_ret(unlink_req, -EPROTO); - } + usbback_cancel_req(unlink_req); break; } } @@ -681,6 +683,33 @@ static void usbback_hotplug_enq(struct usbback_info *usbif, unsigned port) usbback_hotplug_notify(usbif); } +static void usbback_portid_drain(struct usbback_info *usbif, unsigned port) +{ + struct usbback_req *req, *tmp; + bool sched = false; + + QTAILQ_FOREACH_SAFE(req, &usbif->ports[port - 1].submit_q, q, tmp) { + usbback_cancel_req(req); + sched = true; + } + + if (sched) { + qemu_bh_schedule(usbif->bh); + } +} + +static void usbback_portid_detach(struct usbback_info *usbif, unsigned port) +{ + if (!usbif->ports[port - 1].attached) { + return; + } + + usbif->ports[port - 1].speed = USBIF_SPEED_NONE; + usbif->ports[port - 1].attached = false; + usbback_portid_drain(usbif, port); + usbback_hotplug_enq(usbif, port); +} + static void usbback_portid_remove(struct usbback_info *usbif, unsigned port) { USBPort *p; @@ -694,9 +723,7 @@ static void usbback_portid_remove(struct usbback_info *usbif, unsigned port) object_unparent(OBJECT(usbif->ports[port - 1].dev)); usbif->ports[port - 1].dev = NULL; - usbif->ports[port - 1].speed = USBIF_SPEED_NONE; - usbif->ports[port - 1].attached = false; - usbback_hotplug_enq(usbif, port); + usbback_portid_detach(usbif, port); TR_BUS(&usbif->xendev, "port %d removed\n", port); } @@ -801,7 +828,6 @@ static void usbback_process_port(struct usbback_info *usbif, unsigned port) static void usbback_disconnect(struct XenDevice *xendev) { struct usbback_info *usbif; - struct usbback_req *req, *tmp; unsigned int i; TR_BUS(xendev, "start\n"); @@ -820,11 +846,8 @@ static void usbback_disconnect(struct XenDevice *xendev) } for (i = 0; i < usbif->num_ports; i++) { - if (!usbif->ports[i].dev) { - continue; - } - QTAILQ_FOREACH_SAFE(req, &usbif->ports[i].submit_q, q, tmp) { - usbback_cancel_req(req); + if (usbif->ports[i].dev) { + usbback_portid_drain(usbif, i + 1); } } @@ -944,8 +967,7 @@ static void xen_bus_detach(USBPort *port) usbif = port->opaque; TR_BUS(&usbif->xendev, "\n"); - usbif->ports[port->index].attached = false; - usbback_hotplug_enq(usbif, port->index + 1); + usbback_portid_detach(usbif, port->index + 1); } static void xen_bus_child_detach(USBPort *port, USBDevice *child) @@ -958,9 +980,16 @@ static void xen_bus_child_detach(USBPort *port, USBDevice *child) static void xen_bus_complete(USBPort *port, USBPacket *packet) { + struct usbback_req *usbback_req; struct usbback_info *usbif; - usbif = port->opaque; + usbback_req = container_of(packet, struct usbback_req, packet); + if (usbback_req->cancelled) { + g_free(usbback_req); + return; + } + + usbif = usbback_req->usbif; TR_REQ(&usbif->xendev, "\n"); usbback_packet_complete(packet); } @@ -1037,6 +1066,7 @@ static int usbback_free(struct XenDevice *xendev) } usb_bus_release(&usbif->bus); + object_unparent(OBJECT(&usbif->bus)); TR_BUS(xendev, "finished\n"); diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index bab79b1912..69a238817e 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -321,48 +321,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, /* * release xen backend device. */ -static struct XenDevice *xen_be_del_xendev(int dom, int dev) +static void xen_be_del_xendev(struct XenDevice *xendev) { - struct XenDevice *xendev, *xnext; - - /* - * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but - * we save the next pointer in xnext because we might free xendev. - */ - xnext = xendevs.tqh_first; - while (xnext) { - xendev = xnext; - xnext = xendev->next.tqe_next; - - if (xendev->dom != dom) { - continue; - } - if (xendev->dev != dev && dev != -1) { - continue; - } - - if (xendev->ops->free) { - xendev->ops->free(xendev); - } - - if (xendev->fe) { - char token[XEN_BUFSIZE]; - snprintf(token, sizeof(token), "fe:%p", xendev); - xs_unwatch(xenstore, xendev->fe, token); - g_free(xendev->fe); - } + if (xendev->ops->free) { + xendev->ops->free(xendev); + } - if (xendev->evtchndev != NULL) { - xenevtchn_close(xendev->evtchndev); - } - if (xendev->gnttabdev != NULL) { - xengnttab_close(xendev->gnttabdev); - } + if (xendev->fe) { + char token[XEN_BUFSIZE]; + snprintf(token, sizeof(token), "fe:%p", xendev); + xs_unwatch(xenstore, xendev->fe, token); + g_free(xendev->fe); + } - QTAILQ_REMOVE(&xendevs, xendev, next); - g_free(xendev); + if (xendev->evtchndev != NULL) { + xenevtchn_close(xendev->evtchndev); } - return NULL; + if (xendev->gnttabdev != NULL) { + xengnttab_close(xendev->gnttabdev); + } + + QTAILQ_REMOVE(&xendevs, xendev, next); + g_free(xendev); } /* @@ -682,7 +662,7 @@ static void xenstore_update_be(char *watch, char *type, int dom, if (xendev != NULL) { bepath = xs_read(xenstore, 0, xendev->be, &len); if (bepath == NULL) { - xen_be_del_xendev(dom, dev); + xen_be_del_xendev(xendev); } else { free(bepath); xen_be_backend_changed(xendev, path); @@ -800,6 +780,16 @@ int xen_be_register(const char *type, struct XenDevOps *ops) return xenstore_scan(type, xen_domid, ops); } +void xen_be_register_common(void) +{ + xen_be_register("console", &xen_console_ops); + xen_be_register("vkbd", &xen_kbdmouse_ops); + xen_be_register("qdisk", &xen_blkdev_ops); +#ifdef CONFIG_USB_LIBUSB + xen_be_register("qusb", &xen_usb_ops); +#endif +} + int xen_be_bind_evtchn(struct XenDevice *xendev) { if (xendev->local_port != -1) { diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c index 48f725c9cd..79aef4ecc3 100644 --- a/hw/xenpv/xen_machine_pv.c +++ b/hw/xenpv/xen_machine_pv.c @@ -67,14 +67,9 @@ static void xen_init_pv(MachineState *machine) break; } - xen_be_register("console", &xen_console_ops); - xen_be_register("vkbd", &xen_kbdmouse_ops); + xen_be_register_common(); xen_be_register("vfb", &xen_framebuffer_ops); - xen_be_register("qdisk", &xen_blkdev_ops); xen_be_register("qnic", &xen_netdev_ops); -#ifdef CONFIG_USB_LIBUSB - xen_be_register("qusb", &xen_usb_ops); -#endif /* configure framebuffer */ if (xenfb_enabled) { diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h index 754c0a4ee6..0df282ab5f 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen_backend.h @@ -87,6 +87,7 @@ void xen_be_check_state(struct XenDevice *xendev); /* xen backend driver bits */ int xen_be_init(void); +void xen_be_register_common(void); int xen_be_register(const char *type, struct XenDevOps *ops); int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state); int xen_be_bind_evtchn(struct XenDevice *xendev); diff --git a/io/channel-websock.c b/io/channel-websock.c index 239c75a979..533bd4b3b5 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -317,14 +317,13 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc, return TRUE; } - object_ref(OBJECT(task)); trace_qio_channel_websock_handshake_reply(ioc); qio_channel_add_watch( wioc->master, G_IO_OUT, qio_channel_websock_handshake_send, task, - (GDestroyNotify)object_unref); + NULL); return FALSE; } diff --git a/kvm-all.c b/kvm-all.c index ef81ca532a..65608def36 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1047,6 +1047,14 @@ void kvm_irqchip_commit_routes(KVMState *s) { int ret; + if (kvm_gsi_direct_mapping()) { + return; + } + + if (!kvm_gsi_routing_enabled()) { + return; + } + s->irq_routes->flags = 0; trace_kvm_irqchip_commit_routes(); ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes); diff --git a/ui/vnc.c b/ui/vnc.c index 3ce3a5beec..4ce903429f 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -143,6 +143,11 @@ static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc, { SocketAddress *addr = NULL; + if (!ioc) { + error_setg(errp, "No listener socket available"); + return; + } + addr = qio_channel_socket_get_local_address(ioc, errp); if (!addr) { return; @@ -219,7 +224,7 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd) VncServerInfo *info; Error *err = NULL; - info = g_malloc(sizeof(*info)); + info = g_malloc0(sizeof(*info)); vnc_init_basic_info_from_server_addr(vd->lsock, qapi_VncServerInfo_base(info), &err); info->has_auth = true; @@ -3145,6 +3150,9 @@ void vnc_display_init(const char *id) if (!vs->kbd_layout) exit(1); + vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; + vs->connections_limit = 32; + qemu_mutex_init(&vs->mutex); vnc_start_worker_thread(); diff --git a/xen-hvm.c b/xen-hvm.c index eb577926a1..3b0343a8e6 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -1318,9 +1318,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory) error_report("xen backend core setup failed"); goto err; } - xen_be_register("console", &xen_console_ops); - xen_be_register("vkbd", &xen_kbdmouse_ops); - xen_be_register("qdisk", &xen_blkdev_ops); + xen_be_register_common(); xen_read_physmap(state); return; |